目录

【MySQL】主从复制

主备架构

MySQL的高可用架构是从一主一备的的基础上演化过来的。

所谓的主备架构,即客户端从主节点读写数据,备节点是主节点的备份,和主节点的数据保持同步。进行切换时,备库被切成主库,主库被切成备库。

readonly

通常情况下,会将备库设置为readonly模式。原因如下:

  • 备库常被用于执行一些分析语句,设为只读可防止误操作。

  • 防止切换过程中出现双写,进而导致主备不一致。

  • 常用readonly状态来判断节点的角色。

注意,readonly配置对超级权限用户无效,进行同步的线程拥有超级权限。

同步流程

主备同步的流程如下:

  1. 备库使用change master命令,设置主库的IP、端口、用户名、密码、binlog文件名和日志偏移量。

  2. 在备库执行start slave命令。之后备库会启动两类线程,io_threadsql_thread

  3. sql_thread和主库建立连接。

  4. 主库校验完用户名和密码后,根据备库指定的binlog文件名和偏移量,从本地读取日志,然后发给备库。

  5. 备库拿到binlog后,写到本地中转日志relay log

  6. sql_thread读取中转日志,然后进行解析执行。

change master

配置主从复制的时候,需要在从库上执行change master语句,才能和主库保持同步。

语法

change master语法为:

1
change master to option [, option] ...

常见选项

常见的option参数如下:

  • MASTER_HOST:主库的主机名或者ip

  • MASTER_PORT:主库的端口。

  • MASTER_USER:连接到主库的用户名。

  • MASTER_PASSWORD:连接到主库的密码。

  • MASTER_LOG_FILE:指定主库的binlog文件位置。

  • MASTER_LOG_POS:指定从binlog的该位置开始复制。

示例

1
2
3
4
5
change master to
master_host="127.0.0.1",
master_port=3306,
master_user="root",
master_password="123456";

查看 binlog

  1. 查看binlog是否开启。
1
show variables like "log_bin%";
  1. 查看第一个binlog内容。
1
show binlog events;
  1. 查看binlog文件列表。
1
show binary logs;
  1. 查看正在使用的binlog
1
show master status;
  1. 查看指定binlog内容。
1
show binlog events in 文件名;

binlog 格式

binlog有三种格式,statementrowmixed

statement

binlog_format设置为statement时,binlog里面记录的是SQL语句本身。

使用statement可能会导致主备数据不一致。因为日志记录的是sql语句,因此主库在执行时使用的索引,可能和备库执行时使用的索引不一样,从而可能会造成数据不一致。

row

row格式的binlog记录的不是语句原文,而是“操作的哪张表”和“对该表进行的操作”。如下示例中的Table_mapDelete_rows就是被记录的event

1
2
3
4
5
| binlog.000040 |  156 | Anonymous_Gtid | 1 | 235 | SET @@SESSION.GTID_NEXT= 'ANONYMOUS' |
| binlog.000040 |  235 | Query          | 1 | 310 | BEGIN                                |
| binlog.000040 |  310 | Table_map      | 1 | 366 | table_id: 88 (test.t1)               |
| binlog.000040 |  366 | Delete_rows    | 1 | 406 | table_id: 88 flags: STMT_END_F       |
| binlog.000040 |  406 | Xid            | 1 | 437 | COMMIT /* xid=14 */                  |

如果想看到日志的详细内容,可以在终端使用如下命令:

1
mysqlbinlog -vv 日志路径 -start-position=310 --stop-position=437

使用row格式,不会造成主备数据不一致。

mixed

如果使用statement,可能会导致主备不一致。如果使用row,生成的日志会占用大量的空间,消耗io资源,对语句性能造成影响。

由于上述的种种原因,从而有了mixed格式。

设置成mixed格式时,MySQL会判断语句是否会引起主备不一致。如果可能会,就用row格式,否则用statement格式。

数据恢复

因操作不当,导致数据出现错误时,还可以使用row格式的binlog将数据恢复到之前的状态。

binlog 重放

binlog的一个重要使用场景是归档。使用某个时间点的备份,和该时间点之后的binlog日志,可以让数据恢复到指定时刻。

需要注意的是,binlog重放时,不能直接执行statement格式记录的语句,因为有些语句是依赖上下文环境的,如时间等。正确做法是,使用mysqlbinlog工具解析,然后将整个解析结果发给MySQL执行。

示例如下:

1
mysqlbinlog binlog.000040 --start-position=4 | mysql -uroot -p

双主架构

在双主架构中,客户端仍旧从单个节点读写数据,另一个节点与该节点保持数据同步,但是节点之间互为主备关系。在这种架构中,如果发生了切换,就不再需要修改主备关系。

如果将参数log_slave_updates设置为on,备库执行完relay log后,会生成bin log

由于节点之间互为主备,因此可能会产生bin log循环复制的问题。为了解决这个问题,节点的server id必须互不相同。

备库收到bin log并且重放后,会生成新的bin log,新bin logserver id和原来bin logserver id一致。

备库收到主库发来的bin log时,会判断server id是否和自己的相等。如果相等,就表示这个日志是自己生成的,需要丢弃。