在MySQL众多的集群方案中,Replication主从复制模式作为官方原生提供的功能。这里简单地介绍下并通过Docker进行实践
基本原理
在MySQL的Replication模式下,可以实现将一个数据库的数据同步到多台其他数据库。前者通常称之为主库,后者则被称从库。通过主从复制,一方面可以实现数据的容灾备份,另一方面通过读写分离(主库写、从库读)可以水平拓展数据库的负载能力。MySQL复制数据基本原理如下,默认采用异步复制的方式进行
- 在主库上发生的数据变化记录到二进制日志Binlog
- 从库的IO线程将主库的Binlog复制到自己的中继日志Relay log
- 从库的SQL线程通过读取、重放中继日志实现数据复制
基于Binlog日志坐标
全新环境下的主从模式实践
现在我们利用Docker创建两个全新的MySQL实例,并建立主从关系。以便后续向主库添加数据时,可以复制到从库上。具体地,MySQL主库、从库分别使用3316、3326端口
1 | # 拉取镜像 |
然后我们在MySQL主库上新建一个账号,并授予相关权限用于复制
1 | # 创建ip为任意值、用户名为repl、密码为p4word的用户 |
现在我们查看下账号,确认创建成功
1 | # 查看账号信息、权限 |
结果符合预期
修改MySQL主库、从库中/etc/mysql路径下的配置文件my.cnf。具体地,在主库的配置文件中添加如下配置
1 | # 启用binlog日志,并指定文件名前缀 |
在从库的配置文件中添加如下配置
1 | # 启用binlog日志,并指定文件名前缀 |
然后在从库下手动创建存放中继文件所需的相关目录,并修改其所有者、所属组均为mysql
1 | # 创建目录 |
至此,重启主库、从库。一方面可以使修改后的配置文件生效,另一方面,重启MySQL会使用新的Binlog文件。然后我们查看主库状态获取Binlog文件坐标(当前正在使用文件名及偏移量)
1 | # 查看主库的状态 |
结果如下
现在就可以让从库指向主库并开始复制了
1 | # 让从库使用指定账号连接指定主库,并从指定Binlog文件坐标进行复制 |
至此,我们的MySQL主从就已经配置完成了,可通过下面两种方式检查该模式的相关状态
1 | # 在主库上,查看是否存在从库的连接 |
现在,当我们在MySQL主库创建DataBase、Table并插入数据后,即可发现从库的也相应进行同步的数据修改
对已有数据库进行复制
上述实践是在两个数据库开始使用存放数据前先建立主从关系。但大多数情况下,我们需要对一个已有数据的数据库配置从库。这个时候,我们需要将主库已有数据先拷贝到从库中,然后再对主、从库建立同步关系。那么就如何将主库中已有数据复制到新的从库上,大致可分为两种解决方案:冷备、热备。前者需要将主库停机,然后再把主库的数据拷贝到从库上;而后者则无需关闭主库。显然生产环境下,一般不允许停止数据库。故这里我们利用mysqldump工具来实现热备,需要注意的是mysqldump工具不适用于较大数据量的场景
这里依然使用Docker启一个MySQL容器,其使用3336端口
1 | docker run -d \ |
然后类似地,按如下方式修改mysql-Slave-02的配置文件,建立中继文件所需的目录并修改其所有者、所属组均为mysql。然后重启使配置生效
1 | # 启用binlog日志,并指定文件名前缀 |
使用mysqldump工具将主库的数据导出,相关选项参数释义如下:
- -h :数据库所在服务器的IP
- -P :数据库所使用的端口
- -u :用户名
- -p :密码
- —single-transaction :对于事务型表(例如InnoDB),使用该选项可以保证获得一致性备份;而对于非事务型表(例如MyISAM),可以使用 —lock-all-tables 选项来获得一致性备份
- —all-databases:导出所有数据库
- —master-data:该选项值为1时,会将Binlog文件坐标(当前正在使用文件名及偏移量)以change master to语句的形式输出到数据文件;当该选项值为2时,会将此命令注释掉
1 | # 在MySQL容器内执行该命令导出主库数据 |
从下图可以看出,dump的数据文件中的Binlog文件坐标和我们在主库中通过SQL语句查询的结果一致
在从库mysql-Slave-02中执行dump.sql以导入数据
1 | mysql -u root -p123456 < /dump.sql |
至此,从库mysql-Slave-02的数据就已经被初始化完成。现在就可以通过change master to语句来让从库指向主库准备进行复制了。注意此时不需要指定Binlog文件坐标了,因为dump的数据文件中的change master to语句含有坐标信息,现在只需补充主库的IP、端口、账号、密码等信息即可
1 | # 让从库使用指定账号连接指定主库进行复制 |
现在,从库就可以开始复制了
1 | # 从库启动复制 |
基于GTID全局事务标示符
在传统复制方式下,对Binlog日志坐标准确性的要求非常高。一旦从库发生意外需要重新与主库建立同步,有时候很难确定出待同步部分的Binlog日志坐标。为此MySQL 5.6版本引入基于GTID全局事务标示符的复制方式,大大简化了主从的同步配置。
主库配置如下
1 | #开启GTID模式 |
从库配置如下
1 | #开启GTID模式 |
修改从库中继文件所需的目录并修改其所有者、所属组均为mysql,并重启主库、从库使配置生效。然后按如前文所述的方式在主库创建账号用于复制。现在就可以通过change master to语句来让从库指向主库准备进行复制了,当然此时就不需要指定Binlog文件坐标了。与此同时,对于在执行start slave前主库中已经存在的数据,也会被复制到从库中
1 | # 让从库使用指定账号连接指定主库进行复制 |
参考文献
- 高性能MySQL·第3版 施瓦茨、扎伊采夫、特卡琴科著