主备同步
- 在备库B上通过change master命令设置主库的IP、端口、用户名、密码,以及从哪个位置开始请求binlog;
- 在备库B上执行start slave命令,备库会启动两个线程,即io_thread和sql_thread,io_thread负责与主库建立连接;
- 主库A校验用户名和密码后,开始按照备库B请求的位置,从本地读取binlog,通过dump_thread发送给B;
- 备库B获得binlog后,写到本地文件relay log;
- sql_thread读取relay log,解析日志并执行。
主备延迟
show slave status;
返回结果中seconds_behind_master表示备库延迟了多少秒。
主备延迟最直接的表现就是备库消费relay log的速度跟不上主库生产binlog的速度。
主备延迟可能的原因有哪些?
- 备库机器性能差
- 备库承接了大量读请求
- 大事务,比如一次删除太多数据
- 单线程复制,MySQL 5.6版本前,只支持单线程处理relay log,当主库并发高时可能出现严重的主备延迟
并行复制
从MySQL 5.6开始,MySQL开始支持并行复制,已经迭代了多种并行复制策略,具体暂略。
主备切换
可靠性优先策略
切换流程如下:
- 检查备库B的延迟时间,直到小于某个值再继续下一步;
- 把主库A修改为只读状态;
- 检查备库B的延迟时间,直到变为0;
- 把备库B修改为读写状态;
- 把业务请求切到备库B。
注意,可靠性优先策略切换是有系统不可用时间的。在满足数据可靠性的前提下,MySQL高可用系统的可用性,是依赖于主备延迟的。延迟的时间越小,在主库故障的时候,服务恢复需要的时间就越短,可用性就越高。
可用性优先策略
- 把备库B修改为读写状态;
- 把业务请求切到备库B;
- 把主库A修改为只读状态。
注意,可用性优先策略可能导致数据不一致。
可靠性 vs 可用性
一般的,数据的可靠性是优先于可用性的,应当在可靠性的基础上,通过降低主备延迟来提高可用性。
如何判断主库是不是出问题了?
select 1,不准确,select 1成功返回只能说明这个库的进程还在,并不能说明库没有问题。比如,并发查询数超出了innodb_thread_concurrency的限制,系统已经不可用,但select 1成功返回。
查询判断,可以检测出由于并发查询过多导致的数据库不可用,但依然不准确,比如,当binlog所在磁盘的空间占用率达到100%,那么所有的更新语句和事务提交都会被堵住,但查询数据没有问题。
更新判断,相对比较常用的方案,缺点是可能不能及时发现系统不可用。
MySQL 5.6开始提供的performance_schema库,相关统计信息也可以用于辅助判断数据库的健康状态。
读写分离
直连
proxy
主从延迟
- 强制走主库
专栏里介绍的其他几种方式,有的不可靠,有的我觉得太复杂,如果有专门的中间件团队研发维护可能还好,这里就暂略了。