MySQL Replication--复制基本工作原理
复制工作原理
(1) master将改变记录到二进制日志(binary log)中(这些记录叫做二进制日志事件,binary log events);
(2) slave将master的binary log events拷贝到它的中继日志(relay log);
(3) slave重做中继日志中的事件,将改变反映它自己的数据。
复制的本质就是一个完全备份+二进制日志备份还原。由主库将二进制日志"推送"给从库,然后从库应用这些"二进制日志",以实现主从数据同步
当主从复制配置完成后,各复制线程启动顺序如下:
1> 从库上启动复制,在从库上创建I/O线程,I/O线程连接到主库
2> 主库创建binlog dump线程读取数据库事件并发送给IO线程
3> 从库上的I/O线程接收到事件数据,将事件数据更新到中继日志(relay log)中
4> 从库上SQL线程读取中继日志中更新的事件数据并应用到从库上。
PS:MYSQL 库只应用和自己ServerID不同的binlog日志,MYSQL通过判断Binlog事件中的不同ServerID即可判断当前库是否是事件的初始发生Server,因此双住复制+多级复制不会出现循环复制。
使用文件存储复制进度信息
在早期的MySQL中,为保证从库Crash重启后,从库的IO线程和SQL线程仍能正常工作,从库上会默认创建两个日志文件master.info和relay-log.info来保存复制的进度,如下图所示:
在存放中继日志时,先更新复制元数据Receiver Meta-data,再将二进制日志写入中继日志文件中;
在应用中继日志时,先更新复制元数据Applier Meta-data,在将二进制日志应用到数据库中;
当从库发生宕机恢复后,会根据复制元数据来判断从哪个位置点开始恢复,但由于更新元数据和应用二进制不在一个事务中,因此Applier Meta-data无法有效的反应应用日志的重做状态。
使用表存放复制进度信息
在MySQL 5.6版本后,在存储进度信息方面做了增强,可以使用表mysql.slave_master_info和mysql.slave_relay_log_info来存放复制进度。
使用表来存放复制元数据的好处:
1>可以将数据库数据和复制元数据一起提交或回滚。
2>无需再使用文件来存放元数据
3>灾难恢复时从库可以找到一个有效的位置来恢复
缺陷:如果表使用非事务性存储引擎,将无法进行回滚
配置表方式存放复制进度信息:
##配置从库使用表来存放复制元数据
STOP SLAVE;
SET @@GLOBAL.master_info_repository='TABLE';
SET @@GLOBAL.relay_log_info_repository='TABLE';
SELECT @@GLOBAL.master_info_repository,@@GLOBAL.relay_log_info_repository;
START SLAVE;
SELECT * FROM mysql.slave_master_info \G
SELECT * FROM mysql.slave_relay_log_info \G;
##注意修改配置文件以保证复制重启后仍使用表来存放元数据
relay_log_info_repository='TABLE'
master_info_repository='TABLE'
PS:从库上使用的复制账号和密码都明文存放在元数据中。