avatar

目录
MySQL Replication 主从同步

需求

  • 实现一主两从

主从同步概论

主从同步的定义

主从同步使得数据可以从一个数据库服务器复制到其他服务器上,在复制数据时,一个服务器充当主服务器(master), 其余的服务器充当从服务器(slave)。通过配置文件,可以指定复制所有的数据库/某个数据库/某个数据库的某个表。

使用主从同步的好处:

  • 通过增加从服务器来提高数据库服务的性能,在主服务器上执行写入和更新,在从服务器上执行查询(需配置读写分离)。在小型项目中,查询操作的次数要远大于写入和更新的次数,因此可以动态调整从服务器的数量,从而调节整个数据库服务的性能。
  • 提高数据安全性。在从服务器上执行start slave;命令开始同步数据,执行stop slave;命令结束同步,在从服务器上能够控制同步的开始和结束。
  • 虽然不能保持主从数据的绝对实时同步,但是在一定程度上也起到了容灾备份作用。

主从同步的机制

图片来源51CTO博主阿泽Aze
  • 主从同步是 MySQL 的一个内置功能,我们只需要配置即可。
  • MySQL 服务器之间进行主从同步是基于二进制日志机制,主服务器使用二进制日志记录数据库变动情况,从服务器通过读取该日志和转化为 SQL 语句执行从而保证与主服务器数据的一致性。
  • 在使用二进制日志时,主服务器的所有操作记录都会被记录下来,从服务器会受到操作记录日志的副本。从服务器可以指定执行该日志中的哪一类事件(譬如只插入数据或者只更新数据),默认会执行日志中的所有语句。
  • 每一个从服务器会记录关于二进制日志的信息:文件名和已经处理过的语句,这样意味着不同的从服务器可以分别执行同一个二进制日志的不同部分,并且从服务器可以随时连接或者中断和服务器的连接。
  • 主服务器和每一个从服务器都必须配置一个唯一的 ID 号(在 my.cnf 文件的[mysqld]模块下有一个 server-id 配置项)。
  • 每一个从服务器还需要通过 CHANGE MASTER TO 语句来配置它要连接的主服务器的 ip 地址,日志文件名称和该日志里面的位置(这些信息存储在主服务器的数据库里)。

MySQL Replication 实现原理

MySQL 的复制(replication)是一个异步的复制,从一个 MySQLinstace(称之为 Master)复制到另一个 MySQLinstance(称之 Slave)。整个复制操作主要由三个进程完成的,其中两个进程在 Slave(Sql 进程和 IO 进程),另外一个进程在 Master(IO 进程)上。

要实施复制,首先必须打开 Master 端的 binarylog(bin-log)功能,否则无法实现。因为整个复制过程实际上就是 Slave 从 Master 端获取该日志然后再在自己身上完全顺序的执行日志中所记录的各种操作。复制的基本过程如下:

  • (1)Slave 上面的 IO 进程连接上 Master,并请求从指定日志文件的指定位置(或者从最开始的日志)之后的日志内容;
  • (2)Master 接收到来自 Slave 的 IO 进程的请求后,通过负责复制的 IO 进程根据请求信息读取指定日志指定位置之后的日志信息,返回给 Slave 的 IO 进程。返回信息中除了日志所包含的信息之外,还包括本次返回的信息已经到 Master 端的 bin-log 文件的名称以及 bin-log 的位置;
  • (3)Slave 的 IO 进程接收到信息后,将接收到的日志内容依次添加到 Slave 端的 relay-log 文件的最末端,并将读取到的 Master 端的 bin-log 的文件名和位置记录到 master-info 文件中,以便在下一次读取的时候能够清楚的告诉 Master“我需要从某个 bin-log 的某个位置开始往后的日志内容,请发给我”;
  • (4)Slave 的 Sql 进程检测到 relay-log 中新增加了内容后,会马上解析 relay-log 的内容成为在 Master 端真实执行时候的那些可执行的内容,并在自身执行。

实验环境

  • Win10 VMware Workstation11
  • 虚拟机: CentOS Linux release 7.9.2009 (Core) x 3
  • MySQL 5.7.34
  • 主从服务的server-id使用IP地址的最后一段编号,方便维护
主机名 IP 地址 主/从服务器 mysql server-id
server1 192.168.18.128 master 128
server2 192.168.18.129 slave 129
server3 192.168.18.130 slave 130

  • 为了实验方便,我们往往会新建一台虚拟机,装好 centos7 和 MySQL,配置 MySQL 相关参数,然后复制该虚拟机若干份。此时我们应该注意修改 MySQL 的 server-uuid,server-uuid 需要全局唯一。附页有关于 server-uuid 的修改方法。
  • 在生产环境往往需要配置静态 IP,需要每一台虚拟机单独配置,不能配置好一台复制若干份,否则会造成开机后 IP 地址冲突。这里使用 VMware 虚拟机实验,网络 IP 自动分配且不发生变化,因此无需配置静态 IP。

主库(192.169.18.128)的配置

在主服务器上建立帐户并授权 slave,一般不用 root 账户,不安全。
账户为 rep1,密码为 rep1-123456,授权的 IP 为实验环境下的两台从服务器,指定可以连接的服务器比较安全。

bash
1
2
3
GRANT REPLICATION SLAVE ON *.* TO 'rep1'@'192.168.18.129' IDENTIFIED BY 'rep1-123456';
GRANT REPLICATION SLAVE ON *.* TO 'rep1'@'192.168.18.130' IDENTIFIED BY 'rep1-123456';
FLUSH PRIVILEGES; # 刷新MySQL的系统权限相关表


bash
1
2
GRANT REPLICATION SLAVE ON *.* TO 'rep1'@'192.168.18.%' IDENTIFIED BY 'rep1-123456';
FLUSH PRIVILEGES; # 刷新MySQL的系统权限相关表

配置 MySQL 主服务的配置文件

bash
1
vi /etc/my.cnf
vim
1
2
3
4
server-id=128 # master服务器ID-用服务器的IP地址最后一段
log-bin=/var/lib/mysql/binlog # 需要有MySQL的写入权限
binlog-do-db=testsync # 同步的数据库名
:wq
  • binlog-do-db=需要复制的数据库名,如果复制多个数据库,重复设置这个选项即可

重启 MySQL 主服务

bash
1
service mysqld restart
bash
1
2
3
4
5
6
7
8
[root@192 ~]# mysql -uroot -p
mysql> show master status;
+---------------+----------+--------------+------------------+-------------------+
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+---------------+----------+--------------+------------------+-------------------+
| binlog.000002 | 207797 | testsync | | |
+---------------+----------+--------------+------------------+-------------------+
1 row in set (0.00 sec)

从库(192.169.18.%)的配置

从服务器的配置方式均相同,配置两次即可

  • 192.169.18.129
  • 192.169.18.129

配置 MySQL 从服务的配置文件

bash
1
vi /etc/my.cnf
vim
1
2
3
server-id=129 # 服务器ID-用服务器的IP地址最后一段
replicate-do-db=testsync # 同步testsync数据库
:wq
  • replicate-do-db=需要复制的数据库名,如果复制多个数据库,重复设置这个选项即可

重启 MySQL 从服务

bash
1
systemctl restart mysqld.service

配置连接主服务的参数

bash
1
2
3
4
5
6
7
8
[root@192 ~]# mysql -uroot -p
mysql>
CHANGE MASTER TO MASTER_HOST='192.168.18.128',
MASTER_PORT=3306,
MASTER_USER='rep1',
MASTER_PASSWORD='rep1-123456',
MASTER_LOG_FILE='binlog.000002',
MASTER_LOG_POS=207797;

启动并查看 slave 服务状态

bash
1
2
mysql> start slave; # 启动slave服务
mysql> show slave status\G; # 查看slave服务状态
  • Slave_IO_Running: Yes
  • Slave_SQL_Running: Yes

Slave_IO_Running、Slave_SQL_Running 均为 YES 即启动 slave 成功

测试

查看主库 192.168.18.128

两个从库会自动建库建表,同步初始数据。

从库 192.168.18.129

从库 192.168.18.130

此时尝试修改选中行的 real_name 字段,在主库将测试主从改成测试主从同步,再查看两个从库的情况。



测试成功

附页

Slave_IO_Running: NO 解决。导致这个原因的问题有很多,这里是因为用虚拟机做实验时,直接复制了整个虚拟机,导致 MySQL 的 server-uuid 重复

bash
1
2
3
4
5
6
7
8
9
10
11
find / -iname "auto.cnf"

vi /var/lib/mysql/auto.cnf

# 原内容
[auto]
server-uuid=a660602f-e4d2-11eb-9270-000c2963539a

# 调整后内容,自定义即可,把最后一位a替换为b
[auto]
server-uuid=a660602f-e4d2-11eb-9270-000c2963539b

参考资料

文章作者: Bill
文章链接: http://blog.webpro.ltd/2021/07/19/mysql-master-slave/
版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 Bill's blog

评论