复制类型
1、异步复制
默认的复制方式,主库提交事务后,立即反馈给客户端,并不关心备库是否收到该事务或者应用,和Oracle Data Guard数据保护模式中的最大性能模式类似。
2、半同步复制(旧的半同步+无损半同步)
主库提交后,不会立即反馈给客户端,二是等待备库接收到日志后,但是不管日志是否应用,和Oracle Data Guard数据保护模式中的最大可用模式类似。
3、全同步复制
主库提交后,需要等待所有从库接收并且应用完日志后才反馈给客户端,这种方式最安全,保证数据不会丢失,但是对数据库的性能影响较大,如果接收不到主库的日志,主库会宕机,和Oracle Data Guard数据保护模式中的最大保护模式类似。
事务的两阶段提交协议
1、第一阶段
在存储引擎内部进行事务的prepare操作(InnoDB prepare),写redo log并刷盘(write/fsync redo)。此时,binlog不做任何操作。
2、第二阶段
写binlog,并刷盘(write/fsync redo)。
在存储引擎内部进行事务的commit操作(InnoDB commit)。
MySQL事务的两阶段提交保证了只要事务被写入binlog,该事务就一定会再存储引擎内部进行提交。
如果实例在事务commit提交阶段崩溃,那么在实例恢复过程中,对于已经存在于binlog中的事务,会在InnoDB内部进行提交,保证了主从数据的一致性。
半同步复制原理
参数rpl_semi_sync_master_wait_point
AFTER_SYNC:无损半同步复制
AFTER_COMMIT:旧的半同步复制
半同步复制前提条件
使用半同步复制的前提条件
1、MySQL5.5及以上版本
root@node01 [(none)]> select version();
+-----------+
| version() |
+-----------+
| 8.0.33 |
+-----------+
1 row in set (0.00 sec)
2、参数值have_dynamic_loading值必须为yes
root@node01 [(none)]> select @@global.have_dynamic_loading;
+-------------------------------+
| @@global.have_dynamic_loading |
+-------------------------------+
| YES |
+-------------------------------+
1 row in set (0.01 sec)
3、gtid异步复制已经开启
root@node01 [(none)]> select @@gtid_mode;
+-------------+
| @@gtid_mode |
+-------------+
| ON |
+-------------+
1 row in set (0.02 sec)
半同步复制安装步骤
1、加载插件
分别在主从上执行
root@node01 [(none)]> install plugin rpl_semi_sync_master soname 'semisync_master.so';
ERROR 1142 (42000): INSERT command denied to user 'root'@'node01' for table 'plugin'
root@node01 [(none)]> select user();
+-------------+
| user() |
+-------------+
| root@node01 |
+-------------+
1 row in set (0.00 sec)
[root@node01 ~]# mysql -uroot -p --socket /data/mysql/3306/data/mysql.sock
root@localhost [(none)]> install plugin rpl_semi_sync_master soname 'semisync_master.so';
Query OK, 0 rows affected, 1 warning (0.10 sec)
[root@node02 ~]# mysql -uroot -p --socket /data/mysql/3306/data/mysql.sock
root@localhost [(none)]> install plugin rpl_semi_sync_slave soname 'semisync_slave.so';
Query OK, 0 rows affected, 1 warning (0.14 sec)
[root@node03 ~]# mysql -uroot -p --socket /data/mysql/3306/data/mysql.sock
root@localhost [(none)]> install plugin rpl_semi_sync_slave soname 'semisync_slave.so';
Query OK, 0 rows affected, 1 warning (0.11 sec)
2、判断插件是否安装成功
root@node01 [(none)]> show plugins;
rpl_semi_sync_master | ACTIVE | REPLICATION | semisync_master.so | GPL
root@node01 [(none)]> select plugin_name,plugin_status from information_schema.plugins where plugin_name like '%semi%';
+----------------------+---------------+
| plugin_name | plugin_status |
+----------------------+---------------+
| rpl_semi_sync_master | ACTIVE |
+----------------------+---------------+
1 row in set (0.00 sec)
root@node02 [(none)]> show plugins;
rpl_semi_sync_slave | ACTIVE | REPLICATION | semisync_slave.so | GPL
root@node03 [(none)]> select plugin_name,plugin_status from information_schema.plugins where plugin_name like '%semi%';
+---------------------+---------------+
| plugin_name | plugin_status |
+---------------------+---------------+
| rpl_semi_sync_slave | ACTIVE |
+---------------------+---------------+
1 row in set (0.00 sec)
3、启动半同步
临时开启
root@node01 [(none)]> set global rpl_semi_sync_master_enabled=1;
Query OK, 0 rows affected (0.00 sec)
root@node02 [(none)]> set global rpl_semi_sync_slave_enabled=1;
Query OK, 0 rows affected (0.00 sec)
root@node03 [(none)]> set global rpl_semi_sync_slave_enabled=1;
Query OK, 0 rows affected (0.00 sec)
配置文件开启,重启后生效
[root@node01 ~]# vim /etc/my.cnf
#semisync
plugin-load=rpl_semi_sync_master=semisync_master.so
rpl_semi_sync_master_enabled=1
[root@node02 ~]# vim /etc/my.cnf
#semisync
plugin-load=rpl_semi_sync_slave=semisync_slave.so
rpl_semi_sync_slave_enabled=1
[root@node03 ~]# vim /etc/my.cnf
#semisync
plugin-load=rpl_semi_sync_slave=semisync_slave.so
rpl_semi_sync_slave_enabled=1
一般建议如下配置
plugin-load="rpl_semi_sync_master=semisync_master.so;rpl_semi_sync_slave=semisync_slave.so"
rpl_semi_sync_master_enabled=1
rpl_semi_sync_slave_enabled=1
4、重启从库IO进程
如果没有重启IO进程,默认还是异步复制
root@node02 [(none)]> stop slave io_thread;
Query OK, 0 rows affected, 1 warning (0.00 sec)
root@node02 [(none)]> start slave io_thread;
Query OK, 0 rows affected, 1 warning (0.00 sec)
root@node03 [(none)]> stop slave io_thread;
Query OK, 0 rows affected, 1 warning (0.00 sec)
root@node03 [(none)]> start slave io_thread;
Query OK, 0 rows affected, 1 warning (0.00 sec)
5、查看半同步复制状态
root@node01 [(none)]> show status like 'Rpl_semi_sync_master_status';
+-----------------------------+-------+
| Variable_name | Value |
+-----------------------------+-------+
| Rpl_semi_sync_master_status | ON |
+-----------------------------+-------+
1 row in set (0.01 sec)
root@node02 [(none)]> show status like 'Rpl_semi_sync_slave_status';
+----------------------------+-------+
| Variable_name | Value |
+----------------------------+-------+
| Rpl_semi_sync_slave_status | ON |
+----------------------------+-------+
1 row in set (0.14 sec)
root@node03 [(none)]> show status like 'Rpl_semi_sync_slave_status';
+----------------------------+-------+
| Variable_name | Value |
+----------------------------+-------+
| Rpl_semi_sync_slave_status | ON |
+----------------------------+-------+
1 row in set (0.04 sec)
至此,半同步复制搭建完成