利用 bash 命令做 SQL 数据修补

如果是把一个 DB 或者一个 table 从一个服务器送到另一个, 那么使用 mysqldump 命令就可以了. 但有的时候, 需要的数据可能只是若干条记录, 就不能用 mysqldump 了. 奇怪的是我 google 了一番居然也没找到很方便的方法. 求人不如求自己吧, 下面是用 bash 命令的解决方法:

mysql <database> -uroot -e “select * from <table> where <condition>…” |tail -n +2 |sed -e ‘s/^/(“/g’ -e ‘s/$/”)/g’ -e ‘s/\t/”,”/g’ |while read values; do echo “insert into <table> values $values”; done

然后把输出的 SQL 在目标服务器上运行即可. 记得把< >里面的变量替换为实际需要的内容. 🙂

利用 LVM 在线抓取 MySQL 数据库快照

小试分身 MySQL Replication, 上次是按照 MySQL 教程做的, 比较死板(或者说, 安全), 但需要锁住数据库, 也就是说, 用户一端的感觉就是服务器出问题了… 而如果通知用户服务器要下线一段时间的话, 又会引起不明真相的用户的莫名猜疑. 那么就需要一种在几秒中之内完成生成镜像的操作, 于是我就想到了 LVM snapshot.

Google 了一番, 我看到已经有成功先例了, 步骤如下:

1, 确认 MySQL 的数据区(缺省 /var/lib/mysql) 是在 LVM 上, 假设是 /dev/VOLUME_GROUP/data
2, 开一个 MySQL session, 执行并记录 show master status 的输出:

flush tables with read lock;
show master status;

3, 在另一个 terminal 执行:

lvcreate -s -n snapshot_name -L5G /dev/VOLUME_GROUP/data

4, 在步骤2的 session 里继续:

unlock tables;

5, /dev/VOLUME_GROUP/snapshot_name 里面就是需要的快照了, 之后将快照复制到从属服务器上然后开启 replication 即可, 这里就略过了.

步骤2/3/4应该可以写到一个 shell script 里面, 这样数据库锁住的时间应该能在3~5秒之内, 用户可能会感觉数据更新时慢了一些, 希望不会有人因为几秒钟的耽搁而花20分钟来投诉吧 🙂

用 MariaDB 替换 MySQL

ice_logo-5dcea9e47b780ff52f75c3c3304d54827f56211e

自从 MySQL 被邪恶的 Oracle 收购后, 貌似就到了后娘手里, 基本没什么发展. 不过还好, 原创班子已另起炉灶, 在 MySQL 5.5 的基础上做出很多改良, 发布了 MariaDB 5.5. 另外一个好消息就是终于看到了国人在开源圈子里的贡献: MariaDB 10.x 分支就包含了来自淘宝的两处贡献:

https://mariadb.com/kb/en/what-is-mariadb-100/ <–在这页上找 taobao 即可.

希望这样的案例越来越多吧. 免费使用开源软件, 在事业成功之后回馈开源社区, 这是个良性循环.

目前我试用了 MariaDB 5.5, 是 MySQL 5.5 的完美替代品. 安装方法在此:

https://downloads.mariadb.org/mariadb/repositories/#mirror=aarnet_pty_ltd&distro=Debian&distro_release=squeeze&version=5.5

另外如果用 Ruby 的 mysql2 gem 的话, 需要安装 libmariadbclient-dev(debian/ubuntu). 而如果 innotop 这个小工具不灵的话, 很可能需要安装 libterm-readkey-perl.

🙂

 

小试分身 MySQL Replication

打理数据库服务器, 再怎么优化终究会面临一台再强的服务器也不够用的时候. 那就使用多台服务器做 Replication 吧. 先从2台 MySQL 服务器开始, 一台为主, 另一台为从. 基本的步骤是(装系统/装软件/配置网络连接什么的就略过了…

1, 在主服务器的配置(/etc/mysql/my.cnf)里添加

[mysqld]
log-bin=/var/log/mysql/mysql-bin.log
server-id=1

然后重新启动 mysql 服务.

2, 在从服务器的配置里添加

[mysqld]
server-id=2

然后重新启动.

3, 在主服务器上添加 replication 专用用户, 例如 repl

create user ‘repl’@’%.<domain.name>’ identified by ‘<pass>’ ;
grant replication slave on *.* to ‘repl’@’%.<domain.name>’ ;
flush privileges ;

4, 锁定主数据库, 记录 bin-log 指针位置并导出数据

flush tables with read lock;
show master status;

记录下来 show 命令的输出的 <log file> <position> 后面有用. 然后使用 mysqldump 导出数据的快照, 用另一个会话, 前面那个不要关, 否则锁定状态就失效了, 到导致数据被更新而不一致.

mysqldump –all-databases > all.sql

可以利用 md5 来验证一下磁盘上的快照文件是否有瑕疵

mysqldump –all-databases | tee all.sql | md5
md5 all.sql

5, 主数据库上的操作完成了, 解锁, 恢复上线:

unlock tables;

6, 确定从数据库还没有打开”从属”模式, 然后导入数据快照(我喜欢用pv查看进展)

slave stop;

pv -p all.sql | mysql

7, 告诉从数据库, 它的主库在哪里

change master to master_host=<host>, master_user=’repl’, master_password='<pass>’, master_log_file='<log file>’, master_log_pos=<position>, …
start slave;

8, 监视日志文件, 看看是否存在错误

tail -f /var/log/daemon.log

另外可以测试一下在主数据库里做的更新会不会出现在从数据库里面.  🙂

PS. 在 Debian + MySQL 5.5 上实验成功, 但以上笔记是过后补写的, 如有错误, 欢迎指出.

PPS. 来自 MySQL 娘家的参考 http://dev.mysql.com/doc/refman/5.5/en/replication-howto.html