1. 主从复制原理

  • 主节点:

Dump Thread:每个 slave 链接到主节点后,都会对应生成一个 dump 线程,负责向从节点发送 binlog 日志

  • 从节点:

IO Thread:向主节点请求 binlog 日志并保存到中继日志(Relay log)中去。
SQL Thread:从中继日志中读取数据并更新到数据库中。
主从复制原理.jpg

2. 常见的复制结构

2.1 主从复制(异步)

主节点配置:

  1. # 修改配置文件
  2. [root@centos8 ~]#vim /etc/my.cnf.d/mysql-server.cnf
  3. server-id=1
  4. log_bin
  5. # 创建复制用账户
  6. [root@centos8 ~]#mysql
  7. mysql> create user slave@'10.0.0.%' identified by '744123';
  8. Query OK, 0 rows affected (0.00 sec)
  9. mysql> grant replication slave on *.* to slave@'10.0.0.%';
  10. Query OK, 0 rows affected (0.01 sec)
  11. # 查看binlog位置
  12. mysql> show master logs;
  13. +--------------------+-----------+-----------+
  14. | Log_name | File_size | Encrypted |
  15. +--------------------+-----------+-----------+
  16. | centos8-bin.000001 | 179 | No |
  17. | centos8-bin.000002 | 179 | No |
  18. | centos8-bin.000003 | 675 | No |
  19. +--------------------+-----------+-----------+
  20. 3 rows in set (0.00 sec)

从节点配置:

  1. # 修改配置文件
  2. [root@centos8 ~]#vim /etc/my.cnf.d/mysql-server.cnf
  3. server-id=2
  4. # 指向主节点
  5. [root@centos8 ~]#mysql
  6. mysql> CHANGE MASTER TO
  7. -> MASTER_HOST='10.0.0.85',
  8. -> MASTER_USER='slave',
  9. -> MASTER_PASSWORD='744123',
  10. -> MASTER_PORT=3306,
  11. -> MASTER_LOG_FILE='centos8-bin.000003',
  12. -> MASTER_LOG_POS=675;
  13. Query OK, 0 rows affected, 2 warnings (0.01 sec)
  14. # 开启slave复制线程
  15. mysql> start slave;
  16. Query OK, 0 rows affected (0.00 sec)

2.2 级联复制

当从节点很多时,主节点的复制压力会很大,为了解决这个问题就有了级联复制的结构。
级联复制的具体架构如下:
级联复制.png
只需要在被复制从节点 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;

  1. - 配置文件启用:
  2. - 主节点:
  3. ```bash
  4. [root@centos82 ~]#vim /etc/my.cnf.d/mysql-server.cnf
  5. [mysqld]
  6. plugin-load="rpl_semi_sync_m aster=semisync_master.so"
  7. rpl_semi_sync_master_enabled=1
  8. rpl_semi_sync_master_timeout=3000
  • 从节点:
    1. [root@centos82 ~]#vim /etc/my.cnf.d/mysql-server.cnf
    2. [mysqld]
    3. plugin-load="rpl_semi_sync_slave=semisync_slave.so"
    4. 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即可,它可以自行寻找到相应的位置开始同步。
  • 主节点配置:

    1. # 开启GTID
    2. [root@centos8 ~]#vim /etc/my.cnf.d/mysql-server.cnf
    3. server-id=1
    4. log_bin
    5. gtid_mode=ON
    6. enforce_gtid_consistency

    GTID相关参数:

    1. mysql> show variables like '%gtid%';
    2. +----------------------------------+-----------+
    3. | Variable_name | Value |
    4. +----------------------------------+-----------+
    5. | binlog_gtid_simple_recovery | ON |
    6. | enforce_gtid_consistency | ON |
    7. | gtid_executed | | # 保证GTID安全的参数
    8. | gtid_executed_compression_period | 1000 |
    9. | gtid_mode | ON | # GTID模式开启或关闭
    10. | gtid_next | AUTOMATIC |
    11. | gtid_owned | |
    12. | gtid_purged | |
    13. | session_track_gtids | OFF |
    14. +----------------------------------+-----------+
    15. 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)

  1. <a name="QtT9z"></a>
  2. # 3. 复制过滤器
  3. 不常用
  4. <a name="qmXBt"></a>
  5. # 4. 复制加密
  6. 默认的主从复制都是明文的,可以通过SSL/TLS加密的方式来提高安全性,但相对的,数据传输效率会略有下降。<br />实现过程:
  7. 1. 生成master和slave的秘钥和证书
  8. 1. 在主服务器中配置SSL
  9. 1. 创建一个需要SSL链接复制的账号
  10. 1. 从服务器change master开启SSL选项
  11. - 主节点:
  12. ```bash
  13. # 运行脚本一键生成master和slave的秘钥和证书
  14. [root@master ~]#bash cert_gen.sh
  15. 证书生成完成 [ OK ]
  16. 证书存放目录: /data/ssl
  17. 证书文件列表: cacert.pem cakey.pem client.crt client.csr client.key server.crt server.csr server.key
  18. # 修改权限
  19. [root@master ~]#chown -R mysql.mysql /data/ssl/
  20. # 更改配置
  21. [root@master ~]#vim /etc/my.cnf.d/mysql-server.cnf
  22. server-id=1
  23. log_bin
  24. ssl
  25. ssl-ca=/data/ssl/cacert.pem
  26. ssl-cert=/data/ssl/master.crt
  27. ssl-key=/data/ssl/master.key
  28. # 重启mysql服务,查看相关变量
  • 从节点:

    1. # 将主节点生成的文件证书文件夹拷贝到从节点
    2. [root@slave ~]#scp -r /data/ssl 10.0.0.84:/data/
    3. # 修改权限
    4. [root@slave ~]#chown -R mysql.mysql /data/ssl/

    5. 主从复制案例

    5.1 主库已经运行一段时间了,上面有大量的数据

  1. 先手动备份恢复数据到从服务器
  2. 再从备份位置开始建立主从关系,注意二进制日志文件及其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; ```