文章目录

  • 延时从库
  • 一、延时从库的搭建原因
  • 二、延时从库的配置
  • 三、出现逻辑故障如何恢复?
  • 1、处理逻辑损坏的思路
  • 2、进行逻辑损坏的故障处理


延时从库

延时从库是一种比较特殊的从库,是在主库执行完操作后几分钟或者几小时,从库再进行相应的操作,也能够人为的配置,一般的话多用在比较重要的架构中,可以一定程度上解决数据库的逻辑损坏。

一、延时从库的搭建原因

为什么需要延时从库?
因为在主从环境下,主库和从库的操作一般情况下的话是很少会有延迟的,所以主从能解决物理层面的损坏,比如说主库的文件被删除,主库无法启动等等,都可以拿从库去进行恢复。但是在逻辑层面下却出现问题了,因为主库如果执行drop等操作,从库也会跟着执行,这种就叫逻辑损坏,无法有效的防止逻辑损坏,所以延时从库的概念就诞生了。
延时从库也是为了来解决主从复制逻辑损坏的这一问题的。如果说一个主从架构里面做了延时从库,主库数据被删除后,发现这个数据很重要,但是从库却要好几分钟,甚至几个小时后进行执行,现在就可以去这个延时从库把录入进去还未删除的数据给拿出来,恢复到主库中,这样就能有效的防止逻辑损坏。
延时从库配置延时的时间最好是6小时左右,如果发生问题,能有6个小时的反应时间,不致于到时候手忙脚乱,具体还是要看公司的反应时间。

二、延时从库的配置

从库配置内容

[t1]>stop slave;
Query OK, 0 rows affected (0.00 sec)
[t1]>change master to master_delay=30;	设置主库延时30秒
Query OK, 0 rows affected (0.01 sec)
[t1]>start slave ;
Query OK, 0 rows affected (0.00 sec)
[t1]>show slave status\G;
SQL_Delay: 30			  延时30秒
SQL_Remaining_Delay: NULL 到达执行下一个SQL的时间还有多久

主库操作

[(none)]>create database delay1 charset utf8mb4;
Query OK, 1 row affected (0.00 sec)
[(none)]>show master status;
+------------------+----------+--------------+------------------+-------------------+
| File             | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+------------------+----------+--------------+------------------+-------------------+
| mysql-bin.000003 |      486 |              |                  |                   |
+------------------+----------+--------------+------------------+-------------------+
1 row in set (0.00 sec)

从库查看
表示创建库的操作将在27秒后进行执行,虽然需要27秒后执行,但是主库的日志其实已经到达从库了,只是延时了SQL_thread执行时间。

Master_Log_File: mysql-bin.000003
Read_Master_Log_Pos: 486
SQL_Delay: 30
SQL_Remaining_Delay: 27

三、出现逻辑故障如何恢复?

1、处理逻辑损坏的思路

(1)及时的去发现主库发生了逻辑层面的损坏。
(2)需要停止延时从库的SQL线程,防止它继续执行relaylog日志内的操作。
(3)线上生产项目如果是网站类,需要挂维护页或者提示用户正在进行维护中。
(4)需要通过relaylog日志去恢复数据,截取起点和终点,在从库中进行。
(5)日志起点即为stop slave时的relaylog位置点,因为stop后,SQL线程就停止执行日志。
(6)日志终点截取到逻辑损坏(drop)之前一条为止。
(7)截取的日志直接恢复到从库,检查从库数据是否有问题,没有问题的话替代主库进行工作。

2、进行逻辑损坏的故障处理

准备好主从环境
开始模拟逻辑损坏的故障恢复
1、开启延时从库

[(none)]>change master to master_delay=300;
[(none)]>start slave ;
[(none)]>show slave status \G;
SQL_Delay: 300

2、故障模拟

主库:
[(none)]>create database delay charset utf8;
[(none)]>use delay;
[delay]>create table test(id int );
[delay]>insert into test values (1),(2),(3),(34);
[delay]>commit;
[delay]>drop database delay;
从库:
[(none)]>stop slave sql_thread;		停止SQL线程
一般的话300秒足够以上操作进行完成了,所以这边只设置了300秒,能更好的来演示模拟故障。

3、截取relaylog日志(从库)

起点:应为relaylog记录的position号
Relay_Log_File: hdfeng-relay-bin.000002
Relay_Log_Pos: 320
终点:查看relaylog的事件信息,看最后被误操作的内容
查看relaylog只需要关注开始的pos即可,后面的是master中的pos
[(none)]>show relaylog events in 'hdfeng-relay-bin.000002';
+-------------------------+-----+----------------+-----------+-------------+-----------------------------------------+
| Log_name                | Pos | Event_type     | Server_id | End_log_pos | Info                                    |
+-------------------------+-----+----------------+-----------+-------------+-----------------------------------------+
| hdfeng-relay-bin.000002 |   4 | Format_desc    |        20 |         123 | Server ver: 5.7.20, Binlog ver: 4       |
| hdfeng-relay-bin.000002 | 123 | Previous_gtids |        20 |         154 |                                         |
| hdfeng-relay-bin.000002 | 154 | Rotate         |        10 |           0 | mysql-bin.000003;pos=486                |
| hdfeng-relay-bin.000002 | 201 | Format_desc    |        10 |           0 | Server ver: 5.7.20-log, Binlog ver: 4   |
| hdfeng-relay-bin.000002 | 320 | Anonymous_Gtid |        10 |         551 | SET @@SESSION.GTID_NEXT= 'ANONYMOUS'    |
| hdfeng-relay-bin.000002 | 385 | Query          |        10 |         661 | create database delay charset utf8      |
| hdfeng-relay-bin.000002 | 495 | Anonymous_Gtid |        10 |         726 | SET @@SESSION.GTID_NEXT= 'ANONYMOUS'    |
| hdfeng-relay-bin.000002 | 560 | Query          |        10 |         828 | use `delay`; create table test(id int ) |
| hdfeng-relay-bin.000002 | 662 | Anonymous_Gtid |        10 |         893 | SET @@SESSION.GTID_NEXT= 'ANONYMOUS'    |
| hdfeng-relay-bin.000002 | 727 | Query          |        10 |         966 | BEGIN                                   |
| hdfeng-relay-bin.000002 | 800 | Table_map      |        10 |        1014 | table_id: 220 (delay.test)              |
| hdfeng-relay-bin.000002 | 848 | Write_rows     |        10 |        1069 | table_id: 220 flags: STMT_END_F         |
| hdfeng-relay-bin.000002 | 903 | Xid            |        10 |        1100 | COMMIT /* xid=63 */                     |
| hdfeng-relay-bin.000002 | 934 | Anonymous_Gtid |        10 |        1165 | SET @@SESSION.GTID_NEXT= 'ANONYMOUS'    |
| hdfeng-relay-bin.000002 | 999 | Query          |        10 |        1260 | drop database delay                     |
+-------------------------+-----+----------------+-----------+-------------+-----------------------------------------+
15 rows in set (0.00 sec)
所以这次截取的日志应该是从320——999,因为999其实是drop操作的起点,drop操作是还没有做的。
[root@hdfeng mysql]# mysqlbinlog --start-position=320 --stop-position=999 /opt/mysql-replication/mysql3320/mysql/hdfeng-relay-bin.000002 >/tmp/relay.sql  
截取完成!

4、进行relaylog的日志恢复(从库)
如果被误删除的数据库数量过大,则可以直接把从库更改为主库,这样不需要再把恢复的数据导到主库中去了,非常的方便。如果数据量比较小,则把从库的这个单个库备份到主库即可。

[root@hdfeng mysql]# mysql -uroot -p -S /opt/mysql-replication/mysql3320/mysql/mysql.sock
[(none)]>source /tmp/relay.sql;
[delay]>show tables;
+-----------------+
| Tables_in_delay |
+-----------------+
| test            |
+-----------------+
1 row in set (0.00 sec)
[delay]>select * from test;
+------+
| id   |
+------+
|    1 |
|    2 |
|    3 |
|   34 |
+------+
4 rows in set (0.00 sec)
恢复成功!
如果需要把从库变成主库需要:
[delay]>stop slave;
[delay]>reset slave all;
然后在原来的主库进行change master to 操作,主从就更换完成了!