一、搭建主从-gtid方式
搭建步骤查看第一篇。bin-log方式。可以进行搭建
1.1 gtid和二进制的优缺点
使用 GTID 的主从复制优点:
1、简化配置:使用 GTID 可以简化主从配置,不需要手动配置每个服务器的二进制日志文件和位置。
2、自动故障转移:GTID 可以在主从切换时自动识别和处理已复制和未复制的事务,使主从切换更加可靠和快速。
3、避免重复复制:GTID 可以避免主从复制中的重复复制问题,确保每个事务只被复制一次。
使用 GTID 的主从复制缺点:
1、兼容性:GTID 是从 MySQL 5.6 版本开始引入的特性,如果使用旧版本的 MySQL,无法使用 GTID 进行主从复制。
2、系统资源占用:启用 GTID 可能会增加一些系统资源的占用,包括存储和计算资源。
使用二进制日志的主从复制优点:
1、兼容性:二进制日志是 MySQL 自带的特性,从较早的版本开始就支持,可以在各个版本之间进行主从复制。
2、灵活性:使用二进制日志可以根据需要进行更精细的配置,如指定复制的数据库、表,过滤不需要复制的操作等。
使用二进制日志的主从复制缺点:
1、配置复杂:相对于 GTID,使用二进制日志需要手动配置主库和从库的二进制日志文件和位置,配置过程相对复杂。
2、容易出错:配置不当或操作失误可能导致主从复制出现问题,如数据不一致、延迟等。
3、复制延迟:在高写入负载的情况下,从库可能会有一定的复制延迟,导致从库数据相对于主库稍有滞后
1.2 配置master
1.
mysql> create database master1db;
Query OK, 1 row affected (0.00 sec)
mysql> CREATE TABLE `master1db`.`master1tab`( `id` INT(2) ZEROFILL NOT NULL AUTO_INCREMENT COMMENT '编号', `name` VARCHAR(255) NOT NULL COMMENT '公司名称', `location` VARCHAR(255) NOT NULL COMMENT '所在地区', PRIMARY KEY (`id`) ) CHARSET=utf8;
mysql> INSERT INTO `master1db`.`master1tab` (`name`, `location`) VALUES ('强强科技集团', '中国-北京');
mysql> INSERT INTO `master1db`.`master1tab` (`name`, `location`) VALUES ('随梦科技集团', '中国-上海');
mysql> INSERT INTO `master1db`.`master1tab` (`name`, `location`) VALUES ('阿里巴巴', '中国-杭州');
2.
[root@mysql-master ~]
log_bin=mysql-bin
server-id=1
gtid_mode=ON
enforce_gtid_consistency=1
[root@mysql-master ~]
1.3 创建复制用户
mysql> grant replication slave, replication
-> client on *.* to 'slave'@'192.168.17.%' identified by 'SqlBack@123456';
Query OK, 0 rows affected, 1 warning (0.00 sec)
1.4 备份主库
[root@mysql-master ~]
[root@mysql-master ~]
1.5 配置slave
1.配置my.cnf配置文件
[root@mysql-slave ~]
server-id=2
gtid_mode=ON
enforce_gtid_consistency=1
2.重启mysqld
[root@mysql-slave ~]
3.导入备份数据
mysql> set sql_log_bin=0;
mysql> create database master1db;
Query OK, 1 row affected (0.00 sec)
mysql> use master1db
mysql> source /root/2023-06-27-mysql-all.sql;
4.配置主从
mysql> change master to
-> master_host='192.168.17.129',
-> master_user='slave',
-> master_password='SqlBack@123456',
-> master_auto_position=1;
Query OK, 0 rows affected, 2 warnings (0.53 sec)
mysql> start slave;
mysql> show slave status\G
*************************** 1. row ***************************
Slave_IO_State: Waiting for master to send event
Master_Host: 192.168.17.129
Master_User: slave
Master_Port: 3306
Connect_Retry: 60
Master_Log_File: mysql-bin.000001
Read_Master_Log_Pos: 457
Relay_Log_File: mysql-slave-relay-bin.000002
Relay_Log_Pos: 670
Relay_Master_Log_File: mysql-bin.000001
Slave_IO_Running: Yes
Slave_SQL_Running: Yes
5.验证主从{主库操作}
mysql> INSERT INTO `master1db`.`master1tab` (`name`, `location`) VALUES ('字节跳动集团', '中国-北京');
mysql> select * from master1tab;
+----+--------------------+---------------+
| id | name | location |
+----+--------------------+---------------+
| 01 | 强强科技集团 | 中国-北京 |
| 02 | 随梦科技集团 | 中国-上海 |
| 03 | 阿里巴巴 | 中国-杭州 |
| 04 | 京东集团 | 中国-北京 |
| 05 | 字节跳动集团 | 中国-北京 |
+----+--------------------+---------------+
5 rows in set (0.00 sec)
二、模拟主从不同步(gtid)
1.1 故障描述
1.2 配置测试库
1、
mysql> create database demon;
Query OK, 1 row affected (0.00 sec)
mysql> CREATE TABLE `demon`.`t1`( `id` INT(2) NOT NULL AUTO_INCREMENT, `name` VARCHAR(255) NOT NULL, `age` INT(255) NOT NULL, PRIMARY KEY (`id`) );
2、编写脚本实现重复插入数据
values=`find /usr/ -type d | awk -F '/' '{print $NF}' | sort -u`
while true
do
age=$(($RANDOM % 100))
name=$(echo "$values" | shuf -n 1)
mysql -uroot -p123456 -e "insert into demon.t1(name,age) values ('$name',$age)"
sleep $(($RANDOM%5))
done
3、后台运行脚本模拟客户数据
[root@mysql-master ~]
1.3 模拟从库宕机
mysql> stop slave;
Query OK, 0 rows affected (0.00 sec)
mysql> SELECT * FROM demon.`t1`;
160 rows in set (0.00 sec)
1.4 恢复数据
思路:
先通过mysqldump全量备份当前的数据,由于不能影响业务,所以在mysqldump数据时不能造成锁表。要保持数据写入,由于mysqldump时数据还在写入,所以有一部分数据还是会同步不全,所以导入mysqldump的数据后,跳过dump中包含的GTID事务,再重新建立一次主从配置,开启slave线程,恢复数据并同步。
1、主库备份现在的数据。并且不锁表进行备份
mysql> SELECT * FROM demon.`t1`;
322 rows in set (0.00 sec)
[root@mysql-master ~]
mysql> SELECT * FROM demon.`t1`;
428 rows in set (0.00 sec)
2、从库恢复数据主库依然在写入数据
[root@mysql-master ~]
mysql> use demon
mysql> source /root/2023-06-28-mysql-demon.sql
source过程中会出现ERROR 1840 (HY000): @@GLOBAL.GTID_PURGED can only be set when @@GLOBAL.GTID_EXECUTED is empty.
这种报错不用管,不会影响数据的写入。接着往下走。数据正常写入了就OK!!!!!
1.5 恢复主从
mysql> start slave;
mysql> show slave status\G
Slave_IO_Running: Yes
Slave_SQL_Running: No
Last_SQL_Error: Could not execute Write_rows event on table demon.t1; Duplicate entry '161' for key 'PRIMARY', Error_code: 1062; handler error HA_ERR_FOUND_DUPP_KEY; the event's master log mysql-bin.000002, end_log_pos 27863
#存在报错。需要重新配置主从
1、当前gtid_purged不为空,所以我们要先设置它为空
mysql> show global variables like '%gtid%';
+----------------------------------+--------------------------------------------+
| Variable_name | Value |
+----------------------------------+--------------------------------------------+
| binlog_gtid_simple_recovery | ON |
| enforce_gtid_consistency | ON |
| gtid_executed | ee194423-1405-11ee-a122-000c29b3572a:1-163 |
| gtid_executed_compression_period | 1000 |
| gtid_mode | ON |
| gtid_owned | |
| gtid_purged | ee194423-1405-11ee-a122-000c29b3572a:1-163 |
| session_track_gtids | OFF |
+----------------------------------+--------------------------------------------+
mysql> reset master;
#将gtid_purged参数设为空字符
#将gtid_executed设为空字符
#清空mysql.gtid_executed表
Query OK, 0 rows affected (0.00 sec)
mysql> show global variables like '%gtid%';
+----------------------------------+-------+
| Variable_name | Value |
+----------------------------------+-------+
| binlog_gtid_simple_recovery | ON |
| enforce_gtid_consistency | ON |
| gtid_executed | |
| gtid_executed_compression_period | 1000 |
| gtid_mode | ON |
| gtid_owned | |
| gtid_purged | |
| session_track_gtids | OFF |
+----------------------------------+-------+
8 rows in set (0.00 sec)
2、重置salve
mysql> stop slave;
Query OK, 0 rows affected, 1 warning (0.00 sec)
mysql> reset slave all;
Query OK, 0 rows affected (0.01 sec)
3、查看主库当前mysqldump导出数据的GTID号
[root@mysql-slave ~]# grep GLOBAL.GTID 2023-06-28-mysql-demon.sql
SET @@GLOBAL.GTID_PURGED='ee194423-1405-11ee-a122-000c29b3572a:1-401';
4、重置后,设置跳过的GTID,并重新同步MASTER
mysql> SET @@GLOBAL.GTID_PURGED='ee194423-1405-11ee-a122-000c29b3572a:1-401';
#从库将跳过指定范围内的 GTID,确保不会重复执行已经在主库上执行过的事务,从而避免数据的重复修改。这样,主从复制可以从当前的 GTID 位置继续进行
Query OK, 0 rows affected (0.00 sec)
mysql> change master to
-> master_host='192.168.17.129',
-> master_user='slave',
-> master_password='SqlBack@123456',
-> master_auto_position=1;
Query OK, 0 rows affected, 2 warnings (0.01 sec)
5、恢复主从线程
mysql> start salve;
mysql> show slave status\G
Slave_IO_Running: Yes
Slave_SQL_Running: Yes
6、查看数据是否正常
mysql> SELECT * FROM demon.`t1`;
595 rows in set (0.01 sec)
1.6 清空主从配置
mysql> stop slave;
Query OK, 0 rows affected (0.00 sec)
mysql> reset master;
Query OK, 0 rows affected (0.01 sec)
mysql> reset slave all;
Query OK, 0 rows affected (0.00 sec)
mysql> show slave status;
Empty set (0.00 sec)