主备同步
M-S结构
一主一备,不允许切换
建议将备库设置为只读:
1、设置只读可以防止误操作
2、防止切换逻辑有bug:比如切换过程出现双写,导致主备不一致
3、可以用readonly来判断角色
4、readonly对super权限是无效的,同步进程是超级权限
双M结构
可以互相切换
循环复制问题:在A执行update语句时,生成binlog并发送给B,而B同步完成后,也会生成binlog (log-slave-updates设置为on,表示备库会生成binlog)。而当A也是B的备库时,则B也会把binlog发送给A,造成循环复制。
解决方案: 为每个节点设置server-id。当备库收到binlog后,比较server-id,如果相同,则丢弃
同步过程
备库B跟主库A之间维持了一个长连接。主库A内部有一个线程,专门用于服务备库B的这个长连接。一个事务日志同步的完整过程是这样的:
- 在备库B上通过change master命令,设置主库A的IP、端口、用户名、密码,以及要从哪个位置开始请求binlog,这个位置包含文件名和日志偏移量。
- 在备库B上执行start slave命令,这时候备库会启动两个线程,就是图中的io thread和sql thread。其中io_thread负责与主库建立连接。
- 主库A校验完用户名、密码后,开始按照备库B传过来的位置,从本地读取binlog,发给B。
- 备库B拿到binlog后,写到本地文件,称为中转日志(relaylog)。
- sql_thread读取中转日志,解析出日志里的命令,并执行。
主备延迟
- 主库A执行完成一个事务,写入binlog,我们把这个时刻记为T1;
- 之后传给备库B,我们把备库B接收完这个binlog的时刻记为T2;
- 备库B执行完成这个事务,我们把这个时刻记为T3;
- 所谓主备延迟,就是同一个事务,在备库执行完成的时间和主库执行完成的时间之间的差值,也就是T3-T1.
在备库上执行show slave status命令,它的返回结果里面会显示
seconds_behind_master,用于表示当前备库延迟了多少秒
延迟来源
1、备库与主库机器差距大
2、备库压力大
- 有查询语句在备库上执行。最好使用一主多从;或者通过binlog输出到外部系统,比如Hadoop这类系统,让外部系统提供统计类查询的能力
- 大事务。大量delete或大表DDL
3、备库的并行复制能力不足(很早之前是单线程)或空间不足
4、备库正在进行备份操作
可靠性优先策略:会出现一段时间不可写
1、判断备库的seconds_behind_master值如果小于某个值就继续下一步,否则继续判断;
2、将主库改为只读状态(readonly设为true)
3、判断备库的seconds_behind_master的值,直到变成0
4、将备库改为可读写状态(readonly设为false)
可用性优先策略:可能会导致数据不一致
1、直接将备库改为可读写状态