【MySQL】主从复制
主备架构
MySQL的高可用架构是从一主一备的的基础上演化过来的。
所谓的主备架构,即客户端从主节点读写数据,备节点是主节点的备份,和主节点的数据保持同步。进行切换时,备库被切成主库,主库被切成备库。
readonly
通常情况下,会将备库设置为readonly模式。原因如下:
-
备库常被用于执行一些分析语句,设为只读可防止误操作。
-
防止切换过程中出现双写,进而导致主备不一致。
-
常用
readonly状态来判断节点的角色。
注意,readonly配置对超级权限用户无效,进行同步的线程拥有超级权限。
同步流程
主备同步的流程如下:
-
备库使用
change master命令,设置主库的IP、端口、用户名、密码、binlog文件名和日志偏移量。 -
在备库执行
start slave命令。之后备库会启动两类线程,io_thread和sql_thread。 -
sql_thread和主库建立连接。 -
主库校验完用户名和密码后,根据备库指定的
binlog文件名和偏移量,从本地读取日志,然后发给备库。 -
备库拿到
binlog后,写到本地中转日志relay log。 -
sql_thread读取中转日志,然后进行解析执行。
change master
配置主从复制的时候,需要在从库上执行change master语句,才能和主库保持同步。
语法
change master语法为:
|
|
常见选项
常见的option参数如下:
-
MASTER_HOST:主库的主机名或者ip。 -
MASTER_PORT:主库的端口。 -
MASTER_USER:连接到主库的用户名。 -
MASTER_PASSWORD:连接到主库的密码。 -
MASTER_LOG_FILE:指定主库的binlog文件位置。 -
MASTER_LOG_POS:指定从binlog的该位置开始复制。
示例
|
|
查看 binlog
- 查看
binlog是否开启。
|
|
- 查看第一个
binlog内容。
|
|
- 查看
binlog文件列表。
|
|
- 查看正在使用的
binlog。
|
|
- 查看指定
binlog内容。
|
|
binlog 格式
binlog有三种格式,statement、row和mixed。
statement
binlog_format设置为statement时,binlog里面记录的是SQL语句本身。
使用statement可能会导致主备数据不一致。因为日志记录的是sql语句,因此主库在执行时使用的索引,可能和备库执行时使用的索引不一样,从而可能会造成数据不一致。
row
row格式的binlog记录的不是语句原文,而是“操作的哪张表”和“对该表进行的操作”。如下示例中的Table_map和Delete_rows就是被记录的event。
|
|
如果想看到日志的详细内容,可以在终端使用如下命令:
|
|
使用row格式,不会造成主备数据不一致。
mixed
如果使用statement,可能会导致主备不一致。如果使用row,生成的日志会占用大量的空间,消耗io资源,对语句性能造成影响。
由于上述的种种原因,从而有了mixed格式。
设置成mixed格式时,MySQL会判断语句是否会引起主备不一致。如果可能会,就用row格式,否则用statement格式。
数据恢复
因操作不当,导致数据出现错误时,还可以使用row格式的binlog将数据恢复到之前的状态。
binlog 重放
binlog的一个重要使用场景是归档。使用某个时间点的备份,和该时间点之后的binlog日志,可以让数据恢复到指定时刻。
需要注意的是,binlog重放时,不能直接执行statement格式记录的语句,因为有些语句是依赖上下文环境的,如时间等。正确做法是,使用mysqlbinlog工具解析,然后将整个解析结果发给MySQL执行。
示例如下:
|
|
双主架构
在双主架构中,客户端仍旧从单个节点读写数据,另一个节点与该节点保持数据同步,但是节点之间互为主备关系。在这种架构中,如果发生了切换,就不再需要修改主备关系。
如果将参数log_slave_updates设置为on,备库执行完relay log后,会生成bin log。
由于节点之间互为主备,因此可能会产生bin log循环复制的问题。为了解决这个问题,节点的server id必须互不相同。
备库收到bin log并且重放后,会生成新的bin log,新bin log的server id和原来bin log的server id一致。
备库收到主库发来的bin log时,会判断server id是否和自己的相等。如果相等,就表示这个日志是自己生成的,需要丢弃。