023、半同步复制+GTID复制

半同步复制

半同步复制 mysql 5.5之后,异步复制的基础之上,(已搭好主从的基础上)搭建半同步复制。
1、主库安装插件
mysql> install plugin rpl_semi_sync_master soname 'semisync_master.so';
Query OK, 0 rows affected (0.12 sec)
--若卸载:uninstall plugin rpl_semi_sync_master.
2、从库安装插件
mysql> install plugin rpl_semi_sync_slave soname 'semisync_slave.so';
Query OK, 0 rows affected (0.09 sec)
3、开启半同步复制开关
主库执行:
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_no_slave | ON    |
+------------------------------------+-------+
4 rows in set (0.08 sec)

mysql> set global rpl_semi_sync_master_enabled=on;
Query OK, 0 rows affected (0.02 sec)
从库执行:
mysql> show variables like '%semi%';
+---------------------------------+-------+
| Variable_name                   | Value |
+---------------------------------+-------+
| rpl_semi_sync_slave_enabled     | OFF   |
| rpl_semi_sync_slave_trace_level | 32    |
+---------------------------------+-------+
2 rows in set (0.01 sec)

mysql> set global rpl_semi_sync_slave_enabled=on;
4、查看参数状态
主库查看状态:
mysql> show global 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    |
| 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.09 sec)
从库查看状态:
mysql> show global status like '%semi%';
+----------------------------+-------+
| Variable_name              | Value |
+----------------------------+-------+
| Rpl_semi_sync_slave_status | OFF   |
+----------------------------+-------+
1 row in set (0.05 sec)
状态是off,原因是:未激活,需要重启主从。
从库重启主从之后再查看:
mysql> stop slave;
Query OK, 0 rows affected (0.02 sec)

mysql> start slave;
Query OK, 0 rows affected (0.06 sec)

mysql> show global status like '%semi%';
+----------------------------+-------+
| Variable_name              | Value |
+----------------------------+-------+
| Rpl_semi_sync_slave_status | ON    |
+----------------------------+-------+
1 row in set (0.00 sec)
主库查看:
mysql> show global status like '%semi%';
+--------------------------------------------+-------+
| Variable_name                              | Value |
+--------------------------------------------+-------+
| Rpl_semi_sync_master_clients               | 1     |
| 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    |
| 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.00 sec)
--连接数为1
5、验证
从库执行:
mysql> stop slave io_thread;
Query OK, 0 rows affected (0.01 sec)

mysql> show slave status \G;
*************************** 1. row ***************************
               Slave_IO_State: 
                  Master_Host: 192.168.100.111
                  Master_User: uslave
                  Master_Port: 3306
                Connect_Retry: 60
              Master_Log_File: mysql-bin.000008
          Read_Master_Log_Pos: 949
               Relay_Log_File: localhost-relay-bin.000003
                Relay_Log_Pos: 283
        Relay_Master_Log_File: mysql-bin.000008
             Slave_IO_Running: No
            Slave_SQL_Running: Yes
该操作会导致binlog内容无法传递。
主库执行插入操作:
mysql> insert into t select 2;
Query OK, 1 row affected (10.21 sec)
Records: 1  Duplicates: 0  Warnings: 0
可以看到,简单的插入操作,等待了10秒。
半同步复制关闭:
mysql> show global status like '%semi%';
+--------------------------------------------+-------+
| Variable_name                              | Value |
+--------------------------------------------+-------+
| Rpl_semi_sync_master_clients               | 1     |
| Rpl_semi_sync_master_net_avg_wait_time     | 655   |
| Rpl_semi_sync_master_net_wait_time         | 655   |
| Rpl_semi_sync_master_net_waits             | 1     |
| Rpl_semi_sync_master_no_times              | 1     |
| Rpl_semi_sync_master_no_tx                 | 1     |
| Rpl_semi_sync_master_status                | 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.00 sec)
从库开启io thread之后,恢复正常:
mysql> start slave io_thread;
Query OK, 0 rows affected (0.00 sec)
mysql> show global status like '%semi%';
+----------------------------+-------+
| Variable_name              | Value |
+----------------------------+-------+
| Rpl_semi_sync_slave_status | ON    |
+----------------------------+-------+
1 row in set (0.00 sec)
这也是半同步复制的缺点,网络不好时,与异步复制互相切换,影响业务。

查看主从延迟

1、从库查看主从同步状态
mysql> show slave status \G;
*************************** 1. row ***************************
               Slave_IO_State: Waiting for master to send event
                  Master_Host: 192.168.100.111
                  Master_User: uslave
                  Master_Port: 3306
                Connect_Retry: 60
              Master_Log_File: mysql-bin.000006
          Read_Master_Log_Pos: 120
               Relay_Log_File: localhost-relay-bin.000012
                Relay_Log_Pos: 283
        Relay_Master_Log_File: mysql-bin.000006
             Slave_IO_Running: Yes
            Slave_SQL_Running: Yes
              Replicate_Do_DB: 
          Replicate_Ignore_DB: 
           Replicate_Do_Table: 
       Replicate_Ignore_Table: 
      Replicate_Wild_Do_Table: 
  Replicate_Wild_Ignore_Table: 
                   Last_Errno: 0
                   Last_Error: 
                 Skip_Counter: 0
          Exec_Master_Log_Pos: 120
              Relay_Log_Space: 623
              Until_Condition: None
               Until_Log_File: 
                Until_Log_Pos: 0
           Master_SSL_Allowed: No
           Master_SSL_CA_File: 
           Master_SSL_CA_Path: 
              Master_SSL_Cert: 
            Master_SSL_Cipher: 
               Master_SSL_Key: 
        Seconds_Behind_Master: 0
Master_SSL_Verify_Server_Cert: No
                Last_IO_Errno: 0
                Last_IO_Error: 
               Last_SQL_Errno: 0
               Last_SQL_Error: 
  Replicate_Ignore_Server_Ids: 
             Master_Server_Id: 3
                  Master_UUID: d11d7e9d-a69e-11eb-ac06-080027d46e3d
             Master_Info_File: /u01/data/mysql/master.info
                    SQL_Delay: 0
          SQL_Remaining_Delay: NULL
      Slave_SQL_Running_State: Slave has read all relay log; waiting for the slave I/O thread to update it
           Master_Retry_Count: 86400
                  Master_Bind: 
      Last_IO_Error_Timestamp: 
     Last_SQL_Error_Timestamp: 
               Master_SSL_Crl: 
           Master_SSL_Crlpath: 
           Retrieved_Gtid_Set: 
            Executed_Gtid_Set: 
                Auto_Position: 0
1 row in set (0.00 sec)
主要看两个参数:Read_Master_Log_Pos,Exec_Master_Log_Pos,若前者比较大,则有延迟。若两个参数值相同,则没有延迟。
次要看参数:Seconds_Behind_Master,该参数供参考,不太准确。若该参数值很大,则证明有延迟的存在。
2、使用percona工具的命令
工具下载地址:https://www.percona.com/downloads/percona-toolkit/LATEST/
安装该工具:
[root@localhost soft]# yum install percona-toolkit-3.3.1-1.el7.x86_64.rpm
3、使用工具监控延迟
主库执行
[root@localhost ~]# pt-heartbeat --database=test --update --create-table --daemonize -uroot -proot
意思是:在test库下创建心跳表,并实时更新。
mysql> select * from heartbeat;
+----------------------------+-----------+------------------+----------+-----------------------+---------------------+
| ts                         | server_id | file             | position | relay_master_log_file | exec_master_log_pos |
+----------------------------+-----------+------------------+----------+-----------------------+---------------------+
| 2021-05-11T17:05:00.001120 |         3 | mysql-bin.000010 |    37435 | NULL                  |                NULL |
+----------------------------+-----------+------------------+----------+-----------------------+---------------------+
1 row in set (0.00 sec)
从库执行
[root@localhost ~]# pt-heartbeat --master-server-id=3 --monitor --database=test -uroot -proot --defaults-file=/etc/my.cnf
需要指定主库的server id,指定行为为监控。
:每秒钟刷新一次,结果显示了延时的时间。

GTID复制

GTID(Global Transaction ID)是对于一个已提交事务的编号,并且是一个全局唯一的编号。GTID实际上是由UUID+TID组成的。其中UUID是一个MySQL实例的唯一标识,保存在mysql数据目录下的auto.cnf文件里。TID代表了该实例上已经提交的事务数量,并且随着事务提交单调递增。
MySQL 5.6.10之后,出现了GTID复制,区别于传统复制(binlog+posititon),使用全局事务号进行标识。
借助GTID,在发生主备切换的情况下,MySQL的其它Slave可以自动在新主上找到正确的复制位置,这大大简化了复杂复制拓扑下集群的维护,也减少了人为设置复制位置发生误操作的风险。另外,基于GTID的复制可以忽略已经执行过的事务,减少了数据发生不一致的风险。
搭建GTID复制,建议不要在现有的主从基础上搭建,建议在新环境搭建。
初始化从库前,主库的备份就不需要加--master-data参数了,因为GTID不支持binlog+position号。
GTID的相关参数,需要修改配置文件,并重启数据库才生效(5.7之后可以动态修改)。
GTID的工作原理:
  • master更新数据时,会在事务前产生GTID,一同记录到binlog日志中。
  • slave端的i/o线程将变更的binlog,写入到本地的relay log中。
  • sql线程从relay log中获取GTID,然后对比slave端的binlog是否有记录。
  • 如果有记录,说明该GTID的事务已经执行,slave会忽略。
  • 如果没有记录,slave就会从relay log中执行该GTID的事务,并记录到binlog。
  • 在解析过程中会判断是否有主键,如果没有就用二级索引,如果没有就用全部扫描。
1、清理环境,从库执行
[root@localhost ~]# pkill mysql
[root@localhost ~]# rm -rf /u01/data/mysql/
2、初始化数据库
[root@localhost ~]# mkdir -p /u01/data/mysql
[root@localhost ~]# chown -R mysql:mysql /u01/data/mysql/
[root@localhost ~]# /usr/local/mysql/scripts/mysql_install_db --defaults-file=/etc/my.cnf --user=mysql --basedir=/usr/local/mysql --datadir=/u01/data/mysql
[root@localhost ~]# mysqld_safe --defaults-file=/etc/my.cnf &
3、主库备份,从库恢复
[root@localhost ~]# mysqldump --single-transaction -uroot -proot -A > /u01/bakdata/mysqldump/all_for_slave.sql 
Warning: Using a password on the command line interface can be insecure.
--不需要加--master-data,因为GTID不支持binlog+position号
[root@localhost ~]# scp /u01/bakdata/mysqldump/all_for_slave.sql 192.168.100.112:/u01/bakdata/mysqldump/
root@192.168.100.112's password: 
all_for_slave.sql                                                               100%  639KB  20.7MB/s   00:00
[root@localhost ~]# mysql < /u01/bakdata/mysqldump/all_for_slave.sql
4、修改参数文件,并重启数据库
添加以下参数:
[root@localhost ~]# vi /etc/my.cnf
gtid_mode=on
log_slave_updates=1
enforce_gtid_consistency=1
重启数据库生效(5.7之后可以动态修改):
[root@localhost ~]# pkill mysql
[root@localhost ~]# mysqld_safe --defaults-file=/etc/my.cnf &
4、搭建主库
主库赋权:
mysql> grant replication slave on *.* to 'uslave'@'192.168.100.%' identified by 'uslave';
Query OK, 0 rows affected (0.02 sec)

mysql> flush privileges;
Query OK, 0 rows affected (0.04 sec)
从库执行,注意不要忘记参数master_auto_position=1
mysql> CHANGE MASTER TO MASTER_HOST='192.168.100.111',MASTER_USER='uslave',MASTER_PASSWORD='uslave',MASTER_PORT=3306,master_auto_position=1;
Query OK, 0 rows affected, 2 warnings (0.07 sec)
mysql> start slave;
Query OK, 0 rows affected (0.01 sec)
从库查看状态:
mysql> show slave status \G;
*************************** 1. row ***************************
               Slave_IO_State: Waiting for master to send event
                  Master_Host: 192.168.100.111
                  Master_User: uslave
                  Master_Port: 3306
                Connect_Retry: 60
              Master_Log_File: mysql-bin.000012
          Read_Master_Log_Pos: 88357
               Relay_Log_File: localhost-relay-bin.000002
                Relay_Log_Pos: 88567
        Relay_Master_Log_File: mysql-bin.000012
             Slave_IO_Running: Yes
            Slave_SQL_Running: Yes
              Replicate_Do_DB: 
          Replicate_Ignore_DB: 
           Replicate_Do_Table: 
       Replicate_Ignore_Table: 
      Replicate_Wild_Do_Table: 
  Replicate_Wild_Ignore_Table: 
                   Last_Errno: 0
                   Last_Error: 
                 Skip_Counter: 0
          Exec_Master_Log_Pos: 88357
              Relay_Log_Space: 88775
              Until_Condition: None
               Until_Log_File: 
                Until_Log_Pos: 0
           Master_SSL_Allowed: No
           Master_SSL_CA_File: 
           Master_SSL_CA_Path: 
              Master_SSL_Cert: 
            Master_SSL_Cipher: 
               Master_SSL_Key: 
        Seconds_Behind_Master: 0
Master_SSL_Verify_Server_Cert: No
                Last_IO_Errno: 0
                Last_IO_Error: 
               Last_SQL_Errno: 0
               Last_SQL_Error: 
  Replicate_Ignore_Server_Ids: 
             Master_Server_Id: 3
                  Master_UUID: e1fe2aff-afc8-11eb-a7c9-08002765b4fe
             Master_Info_File: /u01/data/mysql/master.info
                    SQL_Delay: 0
          SQL_Remaining_Delay: NULL
      Slave_SQL_Running_State: Slave has read all relay log; waiting for the slave I/O thread to update it
           Master_Retry_Count: 86400
                  Master_Bind: 
      Last_IO_Error_Timestamp: 
     Last_SQL_Error_Timestamp: 
               Master_SSL_Crl: 
           Master_SSL_Crlpath: 
           Retrieved_Gtid_Set: e1fe2aff-afc8-11eb-a7c9-08002765b4fe:1-241
            Executed_Gtid_Set: e1fe2aff-afc8-11eb-a7c9-08002765b4fe:1-241
                Auto_Position: 1
1 row in set (0.00 sec)
--最后可以看到事务ID

GTID局限性

主库执行:
mysql> create table t1 as select * from t;
ERROR 1786 (HY000): CREATE TABLE ... SELECT is forbidden when @@GLOBAL.ENFORCE_GTID_CONSISTENCY = 1.
GTID复制不支持这种sql语句。
  • 不支持 CREATE TABLE … SELECT 语句。 因为在 ROW 格式下,该语句将会被记录为具有不同 GTID 的两个事务,此时从服务器将无法正确处理。
  • 事务,过程,函数和触发器内部的 CREATE TEMPORARY TABLE 和 DROP TEMPORARY TABLE 语句均不受支持。
为防止执行不受支持的语句,建议配置和上文配置一样,开启 enforce-gtid-consistency 属性, 开启后在主库上执行以上不受支持的语句都将抛出异常并提示。
GTID的优点:
1.根据GTID可以知道事务最初是在哪个实例上提交的
2.GTID的存在方便了Replication的Failover





posted @ 2021-07-26 14:34  有点菜大人  阅读(107)  评论(0)    收藏  举报