实验拓扑

MySQL的异步复制和半同步复制 - 图1
MySQL主从复制

主机名 主机地址 角色
node1 192.168.2.201 Master
node2 192.168.2.202 Slave
node3 192.168.2.203 Slave

本文使用CentOS7.1,数据库:MariaDB-5.5.50
注意:本文关闭了selinux,以及iptables。

一、异步复制:

相关知识点:
  • MySQL的异步复制是MySQL自带的数据同步功能,在公司里面也是也就最为常见的。
  • Master服务器中需要开启二进制日志binlog,从服务器需要开启中继日志relay-log
  • 二进制日志binlog的主要功能是:记录令数据库内容产生改变的语句,如insert语句;二进制日志在备份还原的时候至关重要。
  • 中继日志relay-log则是从服务器中开启,作用是从主服务器的二进制日志中复制,并在在从服务器本地执行一次,达到与主服务器内容一致的效果。
  • 一般MySQL复制是放在内网中进行的,因为MySQL的同步并没有进行加密。而且相比较于在公网传输,在内网中丢包的概率较低,带宽也高。
    Master节点:Node1
  1. (1) 启动二进制日志;
  2. [mysqld]
  3. log_bin=mysql-bin
  4. (2) 为当前节点设置一个全局唯一的ID号;
  5. [mysqld]
  6. server_id=1
  7. (3) 授权创建仅有复制权限的用户账号;
  8. mysql> GRANT REPLCATION SLAVE, REPLICATION CLIENT ON *.* TO 'repuser'@'192.168.2.%' IDENTIFIED BY 'repuser';
  9. (4)查看Master端的二进制日志记录到哪里,用于决定Slave复制的起始位置
  10. MariaDB [(none)]> show master status;
  11. +-------------------+----------+--------------+------------------+
  12. | File | Position | Binlog_Do_DB | Binlog_Ignore_DB |
  13. +-------------------+----------+--------------+------------------+
  14. | Master-log.000001 | 245 | | |
  15. +-------------------+----------+--------------+------------------+
  16. #Slave服务器如果是一个空的数据库而主服务器不为空:
  17. #在同步之前可以先用Master的全量备份,恢复到Slave数据库中。
  18. #然后再从备份那一刻记录的Position开始复制。
  19. #假设Master和Slave都为空,上面的情况就表示Slave从二进制日志Master-log.000001的245开始复制

从节点:Node2设置
  1. (1) 启动中继日志;
  2. [mysqld]
  3. relay_log=relay-log
  4. relay_log_index=relay-log.index
  5. (2) 为当前节点设置一个全局惟的ID号;
  6. [mysqld]
  7. server_id=2
  8. #node3把这里改为3
  9. (3) Slave服务器打开只读模式;
  10. [mysqld]
  11. read_only = 1
  12. (4) 使用有复制权限的用户账号连接至主服务器,并启动复制线程;
  13. #注意:上面的是在/etc/my.cnf的配置文件中添加,下面mysql>的则是在mysql服务器中运行的命令
  14. mysql> CHANGE MASTER TO
  15. MASTER_HOST='192.168.2.201',
  16. MASTER_USER='repuser',
  17. MASTER_PASSWORD='repuser',
  18. MASTER_LOG_FILE='Master-log.000001',
  19. MASTER_LOG_POS=245;
  20. 5)在从服务器中开启复制线程
  21. mysql> START SLAVE;

查看从服务器的状态信息
  1. mysql> show slave status\G
  2. *************************** 1. row ***************************
  3. Slave_IO_State: Waiting for master to send event
  4. Master_Host: 192.168.2.201
  5. Master_User: repuser
  6. Master_Port: 3306
  7. Connect_Retry: 60
  8. Master_Log_File: Master-log.000003
  9. Read_Master_Log_Pos: 1379
  10. Relay_Log_File: relay-log.000002
  11. Relay_Log_Pos: 1414
  12. Relay_Master_Log_File: Master-log.000003
  13. Slave_IO_Running: Yes
  14. Slave_SQL_Running: Yes
  15. Replicate_Do_DB:
  16. Replicate_Ignore_DB:
  17. Replicate_Do_Table:
  18. Replicate_Ignore_Table:
  19. Replicate_Wild_Do_Table:
  20. Replicate_Wild_Ignore_Table:
  21. Last_Errno: 0
  22. Last_Error:
  23. Skip_Counter: 0
  24. Exec_Master_Log_Pos: 1379
  25. Relay_Log_Space: 1702
  26. Until_Condition: None
  27. Until_Log_File:
  28. Until_Log_Pos: 0
  29. Master_SSL_Allowed: No
  30. Master_SSL_CA_File:
  31. Master_SSL_CA_Path:
  32. Master_SSL_Cert:
  33. Master_SSL_Cipher:
  34. Master_SSL_Key:
  35. Seconds_Behind_Master: 0
  36. Master_SSL_Verify_Server_Cert: No
  37. Last_IO_Errno: 0
  38. Last_IO_Error:
  39. Last_SQL_Errno: 0
  40. Last_SQL_Error:
  41. Replicate_Ignore_Server_Ids:
  42. Master_Server_Id: 1
  43. 1 row in set (0.00 sec)

插入几条命令之后,从以上的状态信息中可以看得到我们的Master服务器是192.168.2.201
拥有复制功能的账号是repuser,现在复制到Master-log.000003的Position 1379这个位置;
上面的输出结果中,我在复制完成之后使用了flush logs手动地滚动了二进制日志,所以二进制去到000003

二、半同步复制

相关知识点:
  • 半同步复制是由谷歌研发的一种数据库主从复制方式。
  • 与传统的异步复制相比,半同步复制在多个Slave节点中会选取一个节点进行半同步复制。也就是说,当Master提交一个事务的时候,在这个半同步复制的Slave端返回一个同步完成的Ack包之后,服务器才会向用户返回事务提交成功,而其他的节点则是采用传统的异步复制方式进行同步。
  • 半同步是复制是基于异步复制之上进行的,也就是说配置半同步复制之前需要先配置到异步复制。
  • 半同步复制可以保证在主节点发生故障的时候,总有一个节点的数据与主节点一样。这样在进行切换的时候,可以更加快速地把这个Slave节点设置成主节点来使用。
    Master节点:Node1
    由于上面已经进行了异步复制的配置,下面仅进行半同步复制的操作。
    (1)Master安装插件并修改变量:
    mysql> INSTALL PLUGIN rpl_semi_sync_master SONAME ‘semisync_master.so’;
    插件的文件名字和路径一般在rpm -ql mariadb-server那里查看。
    这个插件的库文件是安装好之后就直接有的,只是没有默认安装。
    (2)启用选项
    mysql> SET GLOBAL VARIABLES rpl_semi_sync_master_enabled=1;
    Slave节点:Node2
    (1)slave安装插件并修改变量:
    1. mysql> INSTALL PLUGIN rpl_semi_sync_slave SONAME 'semisync_slave.so';
    2. mysql> SET GLOBAL VARIABLES rpl_semi_sync_slave_enabled=1;
    这里需要注意的是,node1作为主节点使用的是master模块。node2,node3作为从节点使用slave模块
    (2)查看半同步复制的全局变量
    1. mysql> SHOW GLOBAL VARIABLES LIKE '%semi%';
    2. +------------------------------------+-------+
    3. | Variable_name | Value |
    4. +------------------------------------+-------+
    5. | rpl_semi_sync_master_enabled | ON |
    6. | rpl_semi_sync_master_timeout | 10000 |
    7. | rpl_semi_sync_master_trace_level | 32 |
    8. | rpl_semi_sync_master_wait_no_slave | ON |
    9. +------------------------------------+-------+
    设置rpl_semi_sync_master_enabled=1的效果
    第一行是ON则表示半同步复制已经开启。
    (3)查看半同步复制的全局变量
    1. mysql> SHOW GLOBAL STATUS LIKE '%semi%';
    2. +--------------------------------------------+-------+
    3. | Variable_name | Value |
    4. +--------------------------------------------+-------+
    5. | Rpl_semi_sync_master_clients | 1 |
    6. | Rpl_semi_sync_master_net_avg_wait_time | 645 |
    7. | Rpl_semi_sync_master_net_wait_time | 645 |
    8. | Rpl_semi_sync_master_net_waits | 1 |
    9. | Rpl_semi_sync_master_no_times | 1 |
    10. | Rpl_semi_sync_master_no_tx | 5 |
    11. | Rpl_semi_sync_master_status | ON |
    12. | Rpl_semi_sync_master_timefunc_failures | 0 |
    13. | Rpl_semi_sync_master_tx_avg_wait_time | 783 |
    14. | Rpl_semi_sync_master_tx_wait_time | 783 |
    15. | Rpl_semi_sync_master_tx_waits | 1 |
    16. | Rpl_semi_sync_master_wait_pos_backtraverse | 0 |
    17. | Rpl_semi_sync_master_wait_sessions | 0 |
    18. | Rpl_semi_sync_master_yes_tx | 1 |
    19. +--------------------------------------------+-------+
    第一行Rpl_semi_sync_master_clients显示1,表示有一台主机是半同步复制的状态。

最后需要说明的是,semi复制的MySQL5.7中性能有明显的改善。
假如真的需要使用半同步复制,建议使用5.7的版本。

文章来自:https://www.jianshu.com/p/d877cbe9f0f0