本文转自黑鹰http://hiying.net/post-40.html

目标:实现不需要锁表,利用每天凌晨的导出的文件,实现备机的扩展、恢复。

要求:表的engine必须为inndodb,这样才不需要锁表,才能将备份数据的影响降到最低  

  mysql要实现高可用性、高性能,必须实现冷备 、 热备(replication)以及负载均衡。在搭建mysql的replication时,file and position是非常重要的。

系统可通过crontab实现每天凌晨(压力最小时)自动冷备,热备当然是实时的了。那么冷备自然是用mysqldump

经过总结优化,以下是我是用的mysqldump语句

mysqldump -u user -h ip --single-transaction --master-data=1 --flush-logs --triggers --quik cmdb>cmdb_20110531.sql

通过该语句备份后,加入需要扩展slave server 或者一台备机因各种原因需要重新加入replicaton,那么直接拿这个文件(cmdb_20110531.sql)来使用就可以了

-u 

      用户名

-h 

      导出的数据库所在机器

--single-transaction

      该选项在导出数据之前提交一个 BEGIN SQL语句,BEGIN 不会阻塞任何应用程序且能保证导出时数据库的一致性状态。它只适用于事务表,例如 InnoDB 和 BDB。本选项和 --lock-tables 选项是互斥的,因为 LOCK TABLES 会使任何挂起的事务隐含提交。

--master-data 

      个参数在建立slave数据库的时候会用到,当这个参数的值为1的时候,mysqldump出来的文件就会包括CHANGE MASTER TO这个语句,CHANGE MASTER TO后面紧接着就是file和position的记录,file和position记录的位置就是slave从master端复制文件的起始位置。默认情 况下这个值是1,此处是可以方便的恢复replication的关键参数

      当这个值是2的时候,chang master to也是会写到dump文件里面去的,但是不会有上面那个作用

--flush-logs 

为结束当前日志,生成新日志文件,重新生成的文件可以方便用来增量更新的恢复。命令为:mysqlbinlog mysql-bin.000002 … | mysql -u root -p

--triggers

      导出触发器,如果不导出,则用--skip-triggers

--quik 

      该选项在导出大表时很有用,它强制 MySQLdump 从服务器查询取得记录直接输出而不是取得所有记录后将它们缓存到内存中。

--opt  

      这只是一个快捷选项,等同于同时添加 --add-drop-tables --add-locking --create-option --disable-keys --extended-insert --lock-tables --quick --set-charset 选项。本选项能让 MySQLdump 很快的导出数据,并且导出的数据能很快导回。该选项默认开启,但可以用 --skip-opt 禁用。注意,如果运行 MySQLdump 没有指定 --quick 或 --opt 选项,则会将整个结果集放在内存中。如果导出大数据库的话可能会出现问题。


测试:

创建数据库和表

create database dumptest;

use dumptest;

 

create table t1(id int) engine=innodb;

create table t2(id int) engine=innodb;


创建python程序持续插入数据,持续新增数据:

import time

import MySQLdb

conn=MySQLdb.connect(host='ip', db='dumptest', user="mysql")

cursor=conn.cursor()

for i in range(10000000):

    cursor.execute("insert into t1(id) values(%d)" % i)

    cursor.execute("insert into t2(id) values(%d)" % i)

    conn.commit()

    time.sleep(0.1)

执行这个脚本,然后,连续执行2次这个命令

 mysqldump --single-transaction --master-data=1 --flush-logs dumptest>1.sql

mysqldump --single-transaction --master-data=1 --flush-logs dumptest>2.sql

也就是说,在不断插入数据的同时,进行备份,检查是否有异常,是否会漏掉数据(主要是为了验证,并不是认为mysql不可靠)

以上两个语句会生成新的log文件:

mysql-bin.000002

mysql-bin.000003

检查两个文件是否可以顺序连接同时检查备份的sql文件与mysqlbin日志文件数据数据是否一致,

mysqlbinlog mysql-bin.000002 查看日志内容

mysql-bin.000002  对比1.sql

mysql-bin.000003 对比2.sql


1.sql中第一行可执行代码为:(不包括注释等其他信息)

第一行内容为:CHANGE MASTER TO MASTER_LOG_FILE='mysql-bin.000002', MASTER_LOG_POS=106;

注意事项:mysql导入1.sql时,要先stop slave,导入完毕后,再start slave

测试完全符合预期。good