mysql主从复制实际上基于二进制日志,原理可以用一张图来表示:
分为四步走:
1. 主库对所有ddl和dml产生的日志写进binlog;
2. 主库生成一个 log dump 线程,用来给从库i/o线程读取binlog;
3. 从库的i/o thread去请求主库的binlog,并将得到的binlog日志写到relay log文件中;
4. 从库的sql thread会读取relay log文件中的日志解析成具体操作,将主库的ddl和dml操作事件重放。
关于ddl和dml
sql语言共分为四大类:查询语言dql,控制语言dcl,操纵语言dml,定义语言ddl。
dql:可以简单理解为select语句;
dcl:grant、rollback和commit一类语句;
dml:可以理解为create一类的语句;
ddl:insert、update和delete语句都是;
二、主从复制存在的问题
1. 主库宕机后,数据可能丢失;
2. 主从同步延迟。
三、mysql数据库主从同步延迟产生原因
原因分析:mysql的主从复制都是单线程的操作,主库对所有ddl和dml产生的日志写进binlog,由于binlog是顺序写,所以效率很高。slave的sql thread线程将主库的ddl和dml操作事件在slave中重放。dml和ddl的io操作是随即的,不是顺序的,成本高很多。另一方面,由于sql thread也是单线程的,当主库的并发较高时,产生的dml数量超过slave的sql thread所能处理的速度,或者当slave中有大型query语句产生了锁等待那么延时就产生了。
常见原因:master负载过高、slave负载过高、网络延迟、机器性能太低、mysql配置不合理。
四、主从延时排查方法
通过监控 show slave status 命令输出的seconds_behind_master参数的值来判断:
null,表示io_thread或是sql_thread有任何一个发生故障;
0,该值为零,表示主从复制良好;
正值,表示主从已经出现延时,数字越大表示从库延迟越严重。
五、解决方案
解决数据丢失的问题:
1. 半同步复制
从mysql5.5开始,mysql已经支持半同步复制了,半同步复制介于异步复制和同步复制之间,主库在执行完事务后不立刻返回结果给客户端,需要等待至少一个从库接收到并写到relay log中才返回结果给客户端。相对于异步复制,半同步复制提高了数据的安全性,同时它也造成了一个tcp/ip往返耗时的延迟。
2. 主库配置sync_binlog=1,innodb_flush_log_at_trx_commit=1
sync_binlog的默认值是0,mysql不会将binlog同步到磁盘,其值表示每写多少binlog同步一次磁盘。
innodb_flush_log_at_trx_commit为1表示每一次事务提交或事务外的指令都需要把日志flush到磁盘。
注意:将以上两个值同时设置为1时,写入性能会受到一定限制,只有对数据安全性要求很高的场景才建议使用,比如涉及到钱的订单支付业务,而且系统i/o能力必须可以支撑!
解决从库复制延迟的问题:
1. 优化网络
2. 升级slave硬件配置
3. slave调整参数,关闭binlog,修改innodb_flush_log_at_trx_commit参数值
4. 升级mysql版本到5.7,使用并行复制