暂无图片
暂无图片
8
暂无图片
暂无图片
暂无图片

MySQL主从复制案例–主库备份困局

原创 DBA周技 2024-01-08
1370

##

MySQL主从复制案例–主库备份困局

1、场景描述

业务层使用了一套MySQL主从复制,但是主节点在东北,从节点在云南,且网络使用专线,且带宽仅为10MB,数据为TB级。不允许使用该网络传输数据库的备份或进行远程备份。

在主从复制搭建初期,在主库备份数据到硬盘,然后人肉带着备份集到从库,然后配置主从复制(基于binlog,没有使用GTID)。

现状:从库经常出现问题,各种各样的问题(表丢失,表损坏,数据异常等等)。急需解决问题。

思考:就像第一次搭建从库一样,人肉带数据到从库,然后重做不就完了吗???-----能不能解决问题 > 能。但是需要时间,人力以及钱。

那么怎么解决这个问题呢?

2、环境描述

主库IP:192.168.5.130

从库IP:192.168.5.140

检查从库信息

mysql> show slave hosts; +-----------+------+------+-----------+--------------------------------------+ | Server_id | Host | Port | Master_id | Slave_UUID | +-----------+------+------+-----------+--------------------------------------+ | 1823306 | | 3306 | 1813306 | d8d30f73-adf1-11ee-b6a7-000c298cdbc3 | +-----------+------+------+-----------+--------------------------------------+ 1 row in set (0.00 sec)

从库状态

mysql> show slave status\G *************************** 1. row *************************** Slave_IO_State: Waiting for master to send event Master_Host: 192.168.5.130 Master_User: repuser Master_Port: 3306 Connect_Retry: 60 Master_Log_File: mydb-binlog.000004 Read_Master_Log_Pos: 801 Relay_Log_File: mydb-relay.000006 Relay_Log_Pos: 1018 Relay_Master_Log_File: mydb-binlog.000004 Slave_IO_Running: Yes Slave_SQL_Running: Yes

测试表数据

mysql> select * from test_db.t1; +----+ | id | +----+ | 1 | | 2 | | 3 | +----+ 3 rows in set (0.00 sec)

3、场景再现(从库损坏)

3.1、备份从库

至于为什么要备份从库,后面再讲.(如果库很大,可以考虑物理备份,此处仅演示)

mysqldump -uroot -proot -h127.0.0.1 -P3306 --single-transaction --master-data=2 --flush-logs --flush-privileges --routines --events --triggers -A > /mysql/backup/alldb.sql
3.2、主库写入数据
mysql> insert into t1 values(4);commit;flush logs; Query OK, 1 row affected (0.00 sec) Query OK, 0 rows affected (0.00 sec) Query OK, 0 rows affected (0.00 sec) mysql> insert into t1 values(5);commit;flush logs; Query OK, 1 row affected (0.00 sec) Query OK, 0 rows affected (0.00 sec) Query OK, 0 rows affected (0.00 sec) mysql> insert into t1 values(6);commit;flush logs; Query OK, 1 row affected (0.00 sec) Query OK, 0 rows affected (0.01 sec) Query OK, 0 rows affected (0.01 sec)

理论上:从库在没有问题的情况下,数据是和主库一致。总共6条。

3.3、停止从库并再次初始化
systemctl stop mysql rm -fr /mysql/data/3306/data/* rm -fr /mysql/log/3306/mydb-error.err rm -fr /mysql/log/3306/binlog/* rm -fr /mysql/log/3306/relaylog/* mysqld --defaults-file=/mysql/data/3306/my.cnf --initialize --user=mysql --basedir=/mysql/app/mysql --datadir=/mysql/data/3306/data/

这里删除了从库数据目录中的所有文件,删除了binlog和relaylog。错误日志也一并删除,然后初始化数据库。

3.4、主库再次写入数据
mysql> insert into t1 values(7);commit;flush logs; Query OK, 1 row affected (0.00 sec) Query OK, 0 rows affected (0.00 sec) Query OK, 0 rows affected (0.00 sec) mysql> insert into t1 values(8);commit;flush logs; Query OK, 1 row affected (0.00 sec) Query OK, 0 rows affected (0.00 sec) Query OK, 0 rows affected (0.00 sec) mysql> insert into t1 values(9);commit;flush logs; Query OK, 1 row affected (0.00 sec) Query OK, 0 rows affected (0.01 sec) Query OK, 0 rows affected (0.01 sec) mysql> select count(*) from test_db.t1; +----------+ | count(*) | +----------+ | 9 | +----------+ 1 row in set (0.01 sec)

频繁的刷日志,写数据。此时主库的数据为9条。

4、恢复主从复制

4.1、导入从库备份的数据
[root@mydb02 ~]# mysql < /mysql/backup/alldb.sql
4.2、配置复制关系

这一步非常重要,如何找到正确的binlog和POS。这需要从mysql的参数说起。如果我们使用传统的方法去从库的备份文件找,如

[root@mydb02 ~]# head -100 /mysql/backup/alldb.sql |grep -i 'change master' -- CHANGE MASTER TO MASTER_LOG_FILE='mydb-binlog.000003', MASTER_LOG_POS=154;

当你使用这个binlog和pos时,你也许(这里只是也许,我实验了几次,有时是成功,有时会出现错误,后面解释为什么会错误)会发现主从复制能成功搭建,双Yes也在,但是数据丢失

mysql> change master to master_host='192.168.5.130',master_user='repuser',master_password='repuser123',master_port=3306,master_log_file='mydb-binlog.000003',master_log_pos=154; Query OK, 0 rows affected, 2 warnings (0.02 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.5.130 Master_User: repuser Master_Port: 3306 Connect_Retry: 60 Master_Log_File: mydb-binlog.000010 Read_Master_Log_Pos: 154 Relay_Log_File: mydb-relay.000004 Relay_Log_Pos: 371 Relay_Master_Log_File: mydb-binlog.000004 Slave_IO_Running: Yes Slave_SQL_Running: Yes

你还能遇到如下错误:

 Slave_SQL_Running: No
                   Last_Errno: 1032
                   Last_Error: Coordinator stopped because there were error(s) in the worker(s). The most recent failure being: Worker 1 failed executing transaction 'ANONYMOUS' at master log mydb-binlog.000004, end_log_pos 770. See error log and/or performance_schema.replication_applier_status_by_worker table for more details about this failure or others, if any.

错误的原因是:这个binlog和pos是从库的,而配置主从复制时需要配置主库的binlog和pos信息。

所以正确的binlog和pos在哪里呢?让我们回到 <4.1>。在我们导入数据库之后,我们会在mysql.slave_worker_info中发现如下信息,这才是我们需要的。

mysql> select * from slave_worker_info\G *************************** 1. row *************************** Id: 1 Relay_log_name: /mysql/log/3306/relaylog/mydb-relay.000006 Relay_log_pos: 1018 Master_log_name: mydb-binlog.000004 Master_log_pos: 801 Checkpoint_relay_log_name: /mysql/log/3306/relaylog/mydb-relay.000006 Checkpoint_relay_log_pos: 679 Checkpoint_master_log_name: mydb-binlog.000004 Checkpoint_master_log_pos: 462 Checkpoint_seqno: 0 Checkpoint_group_size: 64 Checkpoint_group_bitmap: Channel_name:

这些信息是如何来的呢?有两个参数非常重要

master_info_repository=table relay_log_info_repository=table

让我们继续配置主从关系

mysql> change master to master_host='192.168.5.130',master_user='repuser',master_password='repuser123',master_port=3306,master_log_file='mydb-binlog.000004',master_l Query OK, 0 rows affected, 2 warnings (0.03 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.5.130 Master_User: repuser Master_Port: 3306 Connect_Retry: 60 Master_Log_File: mydb-binlog.000010 Read_Master_Log_Pos: 154 Relay_Log_File: mydb-relay.000014 Relay_Log_Pos: 371 Relay_Master_Log_File: mydb-binlog.000010 Slave_IO_Running: Yes Slave_SQL_Running: Yes
4.3、检查数据

从库

mysql> select count(*) from test_db.t1; +----------+ | count(*) | +----------+ | 9 | +----------+ 1 row in set (0.00 sec)

数据也是9条,和主库一致,随后可以在主库写入数据测试,数据一致,且双Yes.

主库再次写入数据

mysql> insert into test_db.t1 values(10);commit;flush logs; Query OK, 1 row affected (0.00 sec) Query OK, 0 rows affected (0.01 sec) Query OK, 0 rows affected (0.01 sec) mysql> select count(*) from test_db.t1; +----------+ | count(*) | +----------+ | 10 | +----------+ 1 row in set (0.00 sec)

从库再次检查

mysql> select count(*) from test_db.t1; +----------+ | count(*) | +----------+ | 10 | +----------+ 1 row in set (0.00 sec) mysql> show slave status\G *************************** 1. row *************************** Slave_IO_State: Waiting for master to send event Master_Host: 192.168.5.130 Master_User: repuser Master_Port: 3306 Connect_Retry: 60 Master_Log_File: mydb-binlog.000013 Read_Master_Log_Pos: 154 Relay_Log_File: mydb-relay.000020 Relay_Log_Pos: 371 Relay_Master_Log_File: mydb-binlog.000013 Slave_IO_Running: Yes Slave_SQL_Running: Yes

5、总结

从结果来看,完成了最初的需求,使用从库的备份恢复主从复制关系。

6、疑问:从库的备份周期是多少

从这个案例中我们知道,我们需要使用binlog和pos位置进行主从复制的再次配置,这意味着主库的binlog必须要存在,然后才能应用日志。所以从库备份的周期应该小于主库的日志过期时间。

mysql> show variables like 'expire%'; +------------------+-------+ | Variable_name | Value | +------------------+-------+ | expire_logs_days | 7 | +------------------+-------+ 1 row in set (0.00 sec)

这就是为什么我们需要备份从库的原因。

7、其他(广告)

如果你想看这个案例的视频版,那么请移步B站,同时如果你对主从复制有兴趣,你可以在墨天伦上找到我的课程。基于MySQL8.0。

https://www.modb.pro/course/193

最后修改时间:2024-01-08 22:17:34
「喜欢这篇文章,您的关注和赞赏是给作者最好的鼓励」
关注作者
【版权声明】本文为墨天轮用户原创内容,转载时必须标注文章的来源(墨天轮),文章链接,文章作者等基本信息,否则作者和墨天轮有权追究责任。如果您发现墨天轮中有涉嫌抄袭或者侵权的内容,欢迎发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论