一、基本原理

MySQL支持单向、异步复制,复制过程中一个服务器充当主服务器,而一个或多个其它服务器充当从服务器。MySQL复制基于主服务器在二进制日志中跟踪所有对数据库的更改(更新、删除等等)。因此,要进行复制,必须在主服务器上启用二进制日志。每个从服务器从主服务器接收主服务器已经记录到其二进制日志的保存的更新。当一个从服务器连接主服务器时,它通知主服务器从服务器在日志中读取的最后一次成功更新的位置。从服务器接收从那时起发生的任何更新,并在本机上执行相同的更新。然后封锁并等待主服务器通知新的更新。从服务器执行备份不会干扰主服务器,在备份过程中主服务器可以继续处理更新。


二、具体步骤

1. 确认MySQL版本兼容

在进行mysql主从备份时,最好确保主从服务器的版本兼容。从服务器至少与主服务器版本相同或更高。


2. 修改主机(master)配置:

修改mysql配置文件

在[mysqld]标签下添加以下几行

[mysqld]

#开启二进制日志[必须]
log-bin=mysql-bin 

#服务器唯一ID,默认是1,一般取IP最后一段 [必须]
server-id=111

#指定对db_nameA记录二进制日志(有一个隐患,跨库更新时会出错)
binlog-do-db=db_nameA 

#指定不对db_namB记录二进制日志(有一个隐患,跨库更新时会出错)
binlog-ignore-db=db_namB

log_bin指定日志文件,如果不提供文件名,mysql将自己产生缺省文件名。mysql会在文件名后面自动添加数字引,每次启动服务时,都会重新生成一个新的二进制文件。此外,使用log-bin-index可以指定索引文件;

注意的是:binlog-do-db和binlog-ignore-db一次只指定一个数据库,指定多个数据库需要多个语句。而且,MySQL会将所有的数据库名称改成小写,在指定数据库时必须全部使用小写名字,否则不会起作用。


2. 修改从机(slave)配置:

修改mysql配置文件

在[mysqld]标签下添加以下几行

[mysqld]

#开启二进制日志[非必须]
log-bin=mysql-bin 

#服务器唯一ID,默认是1,一般取IP最后一段 [必须]
server-id=112

#配置中继日志[非必须]
relay_log=mysql-relay-bin

#表示slave将复制事件写进自己的二进制日志[非必须]
log_slave_updates=1

#防止改变数据(除了特殊的线程)[非必须]
read_only=1

#使用replicate_do_db和replicate_ignore_db时有一个隐患,跨库更新时会出错。
#可以在Slave上使用 replicate_wild_do_table 和 replicate_wild_ignore_table 来解决跨库更新的问题
#5.5以上,下面的这些表都建议过滤掉,只复制生产环境数据。[非必须]
replicate-wild-ignore-table =mysql.%
replicate-wild-ignore-table =test.%
replicate-wild-ignore-table =log.%
replicate-wild-ignore-table =information_schema.%
replicate-wild-ignore-table =performance_schema.%


3、在主服务器上建立帐户并授权slave:

mysql>grant replication slave on *.* to '帐号' @ '从服务器IP' identified by '密码';

一般不用root帐号,%表示所有客户端都可能连,此处可用具体客户端IP代替,如192.168.1.123,加强安全。

然后在mysql库的user表中使用:

select * from user where user = '帐号' \G;

可以看到Repl_slave_priv项对应的值为Y。


4、查看两台Mysql Server当前bin log的位置(因为我们只需要同步两个server从当前状态之后的操作),要保证mysql没有读写操作;

mysql>show master status;
 +------------------+----------+--------------+------------------+
 | File             | Position | Binlog_Do_DB | Binlog_Ignore_DB |
 +------------------+----------+--------------+------------------+
 | mysql-bin.000001 |      218 |              |                  |
 +------------------+----------+--------------+------------------+


5、设置Slave Replication(在从服务器上操作);

mysql>stop slave
mysql>CHANGE MASTER TO
MASTER_HOST='192.168.1.127',//主服务器地址
MASTER_USER='repl',//备份用户
MASTER_PASSWORD='repl',//备份用户密码
MASTER_LOG_FILE='mysql-bin.000001',//主服务器二进制日志文件名
Master_Port=3306,//主服务器端口
MASTER_LOG_POS=218;//日志的开始位置


7、启动Slave

mysql>start slave;


8、查看slave的状态

mysql>show slave status\G;
*************************** 1. row ***************************
Slave_IO_State: Waiting for master to send event
Master_Host: 192.168.1.127
Master_User: repl
Master_Port: 3306
Connect_Retry: 60
Master_Log_File: mysql-bin.000001//主机上用于主备同步的日志文件名,
Read_Master_Log_Pos: 179 //从库读取主库的二进制日志的位置,是IO线程
Relay_Log_File: mysql-bin.000001
Relay_Log_Pos: 171//相对于从库,是从库的sql线程执行到的位置
Relay_Master_Log_File: mysql-bin.000001////相对于主库,是从库的sql线程执行到
Slave_IO_Running: Yes
Slave_SQL_Running: Yes
……

对部分参数的解释:

Slave_IO_State: Waiting for master to send event 

Slave_IO_Running: Yes (必须为Yes)

Slave_SQL_Running: Yes(必须为Yes)

以上参数说听slave正常运行,正等待主服务器发来的消息。


9. 发现mysql slave服务器经常因为一些特殊字符或者符号产生的更新语句报错,整个同步也会因此而卡在那,当错误修复后,只需用stop slave和start slave重启下同步。Slave_SQL线程会重新的尝试工作。如果是无关紧要的错误则可以手动去出错的机器执行下面三条SQL语句,跳过错误即可。

 mysql>slave stop;
 mysql>set GLOBAL SQL_SLAVE_SKIP_COUNTER=1;
 mysql>slave start;


三、添加新slave服务器

假如master已经运行很久了,想对新安装的slave进行数据同步,甚至它没有master的数据。此时,有几种方法可以使slave从另一个服务开始,例如,从master拷贝数据,从另一个slave克隆,从最近的备份开始一个slave。

Slave与master同步时,需要三样东西:

  1. master的某个时刻的数据快照;

  2. master当前的日志文件、以及生成快照时的字节偏移。这两个值可以叫做日志文件坐标(log file coordinate),因为它们确定了一个二进制日志的位置,你可以用SHOW MASTER STATUS命令找到日志文件的坐标;

  3. master的二进制日志文件。


可以通过以下几中方法来克隆一个slave:

(1) 冷拷贝(cold copy)

停止master,将master的文件拷贝到slave;然后重启master。缺点很明显。


(2) 热拷贝(warm copy)

如果你仅使用MyISAM表,你可以使用mysqlhotcopy拷贝,即使服务器正在运行。


(3) 使用mysqldump

使用mysqldump来得到一个数据快照可分为以下几步:

<1>锁表:如果你还没有锁表,你应该对表加锁,防止其它连接修改数据库,否则,你得到的数据可以是不一致的。

<2>在另一个连接用mysqldump创建一个你想进行复制的数据库的转储:

mysqldump -h[127.0.0.1] -u[username] -p[password] db_name > backupfile.sql

<3>对表释放锁。


四、 其他常用命令

  • 导出数据库sql备份(命令行执行

mysqldump -h127.0.0.1 -uroot -p123456 db_name > backupfile_%date:~,4%%date:~5,2%%date:~8,2%.sql


  • 日志生成sql(命令行执行

mysqlbinlog --start-datetime="2016-07-08 12:00:00" --stop-datetime="2016-07-08 13:00:00" d:\\mysql-bin.000001 >d:\\sql-000001.sql


  • 查看日志现在的位置(mysql执行

mysql>show master status;


  • 启用新的日志文件,一般备份完数据库后执行mysql执行

mysql>flush logs;


  • 清空现有的所用bin-log mysql执行

mysql>reset master;


  • 通过日志还原数据命令行执行

mysqlbinlog --start-datetime="2016-07-08 12:00:00" --stop-datetime="2016-07-08 13:00:00" d:\\mysql-bin.000001 | mysql -uroot -p123456


五、其他参考资料

  1. mysql主从复制搭建中几种log和pos详解

  2. mysqldump使用方法

  3. MySQL的主从复制步骤详解及常见错误解决方法

  4. show slave status判断主从同步状态

  5. MYSQL主从同步故障一例及解决过程!


注意:本文归作者所有,未经作者允许,不得转载