MySQL怎么实现主备一致
主备切换
主备流程图
主库的后台线程通过长连接将binlog日志同步到从库,从库的io_thread接受binlog写入从库的redo log ,从库的sql_thread线程重放redo log 到数据库。
- 在备库 B 上通过 change master 命令,设置主库 A 的 IP、端口、用户名、密码,以及要从哪个位置开始请求 binlog,这个位置包含文件名和日志偏移量。
- 在备库 B 上执行 start slave 命令,这时候备库会启动两个线程,就是图中的 io_thread 和 sql_thread。其中 io_thread 负责与主库建立连接。
- 主库 A 校验完用户名、密码后,开始按照备库 B 传过来的位置,从本地读取 binlog,发给 B。
- 备库 B 拿到 binlog 后,写到本地文件,称为中转日志(relay log)。
- sql_thread 读取中转日志,解析出日志里的命令,并执行。
其他
为什么要将备库设置为只读模式
强烈将备库设置为只读模式。
原因有三
- 运营类的查询会放到备库执行,防止误操作
- 防止切换过程中出现双写,造成主备不一致
- 用readonly状态,判断节点的角色
binlog 三种格式的不同
binlog有三种格式,statement, row, mixed
- statement, 当 binlog_format=statement 时,binlog 里面记录的就是 SQL 语句的原文
- row格式会记录操作的记录的主键ID,还有默认所有的字段,
binlog_row_image=FULL
会记录操作记录的所有字段,设置binlog_row_image=MINIMAL
,则只会记录必要的信息。 - mixed, 是mysql 折衷了statement和row两种格式,mixed 格式的意思是,MySQL 自己会判断这条 SQL 语句是否可能引起主备不一致,如果有可能,就用 row 格式,否则就用 statement 格式。
xid event
redo log 和 binlog 是怎么关联起来的? 回答:它们有一个共同的数据字段,叫 XID。崩溃恢复的时候,会按顺序扫描 redo log:如果碰到既有 prepare、又有 commit 的 redo log,就直接提交;如果碰到只有 parepare、而没有 commit 的 redo log,就拿着 XID 去 binlog 找对应的事务。
设置binlog格式为ROW格式, 的一个好处是方便恢复数据。。MariaDB 的Flashback工具就是基于上面介绍的原理来回滚数据的。
双M 如何防止binlog 循环复制
- 两个库的server_id 必须不同,如果相同,不能互为主备
- 备库执行主库生成的从库binlog,server_id 设置为主库的server_id
- 每个库收到主库的日志后,如果binlog的server_id 与 自身相同,则表示日志原来是自己生成的,直接丢弃掉。
查看binlog 相关命令
-- 查看bin_log格式
show variables like 'binlog_format';
-- 查看是否开启了bin_log
show variables like 'log_bin';
-- 查看master上日志
show master logs;
-- 查看正在写入的binlog文件
show master status ;