1. 主从复制原理
- 主节点:
Dump Thread:每个 slave 链接到主节点后,都会对应生成一个 dump 线程,负责向从节点发送 binlog 日志
- 从节点:
IO Thread:向主节点请求 binlog 日志并保存到中继日志(Relay log)中去。
SQL Thread:从中继日志中读取数据并更新到数据库中。
2. 常见的复制结构
2.1 主从复制(异步)
主节点配置:
# 修改配置文件[root@centos8 ~]#vim /etc/my.cnf.d/mysql-server.cnfserver-id=1log_bin# 创建复制用账户[root@centos8 ~]#mysqlmysql> create user slave@'10.0.0.%' identified by '744123';Query OK, 0 rows affected (0.00 sec)mysql> grant replication slave on *.* to slave@'10.0.0.%';Query OK, 0 rows affected (0.01 sec)# 查看binlog位置mysql> show master logs;+--------------------+-----------+-----------+| Log_name | File_size | Encrypted |+--------------------+-----------+-----------+| centos8-bin.000001 | 179 | No || centos8-bin.000002 | 179 | No || centos8-bin.000003 | 675 | No |+--------------------+-----------+-----------+3 rows in set (0.00 sec)
从节点配置:
# 修改配置文件[root@centos8 ~]#vim /etc/my.cnf.d/mysql-server.cnfserver-id=2# 指向主节点[root@centos8 ~]#mysqlmysql> CHANGE MASTER TO-> MASTER_HOST='10.0.0.85',-> MASTER_USER='slave',-> MASTER_PASSWORD='744123',-> MASTER_PORT=3306,-> MASTER_LOG_FILE='centos8-bin.000003',-> MASTER_LOG_POS=675;Query OK, 0 rows affected, 2 warnings (0.01 sec)# 开启slave复制线程mysql> start slave;Query OK, 0 rows affected (0.00 sec)
2.2 级联复制
当从节点很多时,主节点的复制压力会很大,为了解决这个问题就有了级联复制的结构。
级联复制的具体架构如下:
只需要在被复制从节点 slave01 上开启 binlog 日志,然后将其他从节点指向被复制节点即可。
2.3 主主复制
两台节点互相是对方的从节点,可以认为两个都是主节点,但彼此之间又互为对方的从节点。这样做的好处是,当其中一台节点 down 后,不需要提升从节点为主节点这种额外的其他操作,恢复时毕竟方便快捷。
直接使用,可能会造成同时数据写入的错误,最好使用参数限制其中一台为 read-only,或者在代码层面控制只往一台写入数据,而读取数据可以同时进行。
2.4 半同步复制
- 命令行启动:
```bash
安装半同步插件模块
[root@centos8 ~]#mysql mysql> install plugin rpl_semi_sync_master soname ‘semisync_master.so’;
查看默认相关变量
mysql> show variables like ‘%semi%’; +—————————————————————-+——————+ | Variable_name | Value | +—————————————————————-+——————+ | rpl_semi_sync_master_enabled | OFF | # 是否启用半同步复制 | rpl_semi_sync_master_timeout | 10000 | # 超时时间 | rpl_semi_sync_master_trace_level | 32 | # 调试级别 | rpl_semi_sync_master_wait_for_slave_count | 1 | | rpl_semi_sync_master_wait_no_slave | ON | | rpl_semi_sync_master_wait_point | AFTER_SYNC | +—————————————————————-+——————+ 6 rows in set (0.00 sec)
查看相关状态变量
mysql> show status like ‘%semi%’; +——————————————————————+———-+ | Variable_name | Value | +——————————————————————+———-+ | Rpl_semi_sync_master_clients | 0 | # 半同步从节点个数 | Rpl_semi_sync_master_net_avg_wait_time | 0 | | Rpl_semi_sync_master_net_wait_time | 0 | | Rpl_semi_sync_master_net_waits | 0 | | Rpl_semi_sync_master_no_times | 0 | | Rpl_semi_sync_master_no_tx | 0 | | Rpl_semi_sync_master_status | ON | # ON表示为使用半同步复制,OFF表示使用异步复制 | Rpl_semi_sync_master_timefunc_failures | 0 | | Rpl_semi_sync_master_tx_avg_wait_time | 0 | | Rpl_semi_sync_master_tx_wait_time | 0 | | Rpl_semi_sync_master_tx_waits | 0 | | Rpl_semi_sync_master_wait_pos_backtraverse | 0 | | Rpl_semi_sync_master_wait_sessions | 0 | | Rpl_semi_sync_master_yes_tx | 0 | +——————————————————————+———-+ 14 rows in set (0.01 sec)
启用半同步复制
set global rpl_semi_sync_master_enabled = on;
- 配置文件启用:- 主节点:```bash[root@centos82 ~]#vim /etc/my.cnf.d/mysql-server.cnf[mysqld]plugin-load="rpl_semi_sync_m aster=semisync_master.so"rpl_semi_sync_master_enabled=1rpl_semi_sync_master_timeout=3000
- 从节点:
[root@centos82 ~]#vim /etc/my.cnf.d/mysql-server.cnf[mysqld]plugin-load="rpl_semi_sync_slave=semisync_slave.so"rpl_semi_sync_slave_enabled=1
2.5 GTID 复制
GTID:Global Transaction ID,mysql5.6 之后版本开始支持,传统的复制需要在 change master 的时候指定 binlog 文件和 POS 点,而开启 GTID 后,只需要执行 change master to master_auto_position=1即可,它可以自行寻找到相应的位置开始同步。
主节点配置:
# 开启GTID[root@centos8 ~]#vim /etc/my.cnf.d/mysql-server.cnfserver-id=1log_bingtid_mode=ONenforce_gtid_consistency
GTID相关参数:
mysql> show variables like '%gtid%';+----------------------------------+-----------+| Variable_name | Value |+----------------------------------+-----------+| binlog_gtid_simple_recovery | ON || enforce_gtid_consistency | ON || gtid_executed | | # 保证GTID安全的参数| gtid_executed_compression_period | 1000 || gtid_mode | ON | # GTID模式开启或关闭| gtid_next | AUTOMATIC || gtid_owned | || gtid_purged | || session_track_gtids | OFF |+----------------------------------+-----------+9 rows in set (0.00 sec)
从节点配置: ```bash
修改配置文件
[root@centos8 ~]#vim /etc/my.cnf.d/mysql-server.cnf server-id=2 gtid_mode=ON enforce_gtid_consistency
指向主节点
[root@centos8 ~]#mysql
mysql> CHANGE MASTER TO -> MASTER_HOST=’10.0.0.85’, -> MASTER_USER=’slave’, -> MASTER_PASSWORD=’744123’, -> MASTER_PORT=3306, -> MASTER_AUTO_POSITION=1; Query OK, 0 rows affected, 2 warnings (0.01 sec)
开启slave复制线程
mysql> start slave; Query OK, 0 rows affected (0.00 sec)
<a name="QtT9z"></a># 3. 复制过滤器不常用<a name="qmXBt"></a># 4. 复制加密默认的主从复制都是明文的,可以通过SSL/TLS加密的方式来提高安全性,但相对的,数据传输效率会略有下降。<br />实现过程:1. 生成master和slave的秘钥和证书1. 在主服务器中配置SSL1. 创建一个需要SSL链接复制的账号1. 从服务器change master开启SSL选项- 主节点:```bash# 运行脚本一键生成master和slave的秘钥和证书[root@master ~]#bash cert_gen.sh证书生成完成 [ OK ]证书存放目录: /data/ssl证书文件列表: cacert.pem cakey.pem client.crt client.csr client.key server.crt server.csr server.key# 修改权限[root@master ~]#chown -R mysql.mysql /data/ssl/# 更改配置[root@master ~]#vim /etc/my.cnf.d/mysql-server.cnfserver-id=1log_binsslssl-ca=/data/ssl/cacert.pemssl-cert=/data/ssl/master.crtssl-key=/data/ssl/master.key# 重启mysql服务,查看相关变量
从节点:
# 将主节点生成的文件证书文件夹拷贝到从节点[root@slave ~]#scp -r /data/ssl 10.0.0.84:/data/# 修改权限[root@slave ~]#chown -R mysql.mysql /data/ssl/
5. 主从复制案例
5.1 主库已经运行一段时间了,上面有大量的数据
- 先手动备份恢复数据到从服务器
- 再从备份位置开始建立主从关系,注意二进制日志文件及其Position
```bash
在主服务器完全备份
[root@master ~]# mysqldump -A -F —single-transaction —master-data=2 > /backup/fullbackup_ date +%F.sql
拷贝备份数据至从节点
[root@master ~]# scp /backup/fullbackup_2021-05-07.sql 192.168.0.200:/data/
查看完全备份的位置
[root@master ~]# grep ‘^CHANGE MASTER’ fullbackup_2021-05-07.sql CHANGE MASTER TO MASTER_LOG_FILE=’master-bin.000002’, MASTER_LOG_POS=154;
从库备份还原数据
[root@c7-01 ~]# mysql -uroot -p root@localhost [mysql]>source all-data-2021-05-07.sql
开启主从复制
root@localhost [(none)]>CHANGE MASTER TO -> MASTER_HOST=’192.168.0.72’, -> MASTER_USER=’slave’, -> MASTER_PASSWORD=’744123’, -> MASTER_PORT=3306, -> MASTER_LOG_FILE=’C7-02-bin.000002’, -> MASTER_LOG_POS=154; Query OK, 0 rows affected, 2 warnings (0.00 sec) root@localhost [(none)]>start slave; Query OK, 0 rows affected (0.00 sec)
查看主从复制状态
root@localhost [(none)]>start slave; ```
