【MySQL】通过SQL_Thread快速恢复binlog
将数据库回档至指定时间点或位置,常常是使用全量备份+binlog增量实现的。 而数据量很大的情况下,增量恢复binlog一直是一个苦恼的问题。 因为恢复binlog速度十分慢,并且容易出错。 p.s. 以下所有框可左右滑动 建议横屏阅读
常见binlog增量恢复方式
先解析成sql文件,再导入MySQL
mysqlbinlog mysql-bin.000001 --start-position=n > /data/add.sql
mysqlbinlog mysql-bin.000002 ... mysql-bin.n >> /data/add.sql
mysql -u -p -S < /data/add.sql
直接管道到MySQL中
mysqlbinlog mysql-bin.000001 --start-position=n | mysql -u -p -S
mysqlbinlog mysql-bin.000002 ... mysql-bin.n | mysql -u -p -S
直接管道进去的方式,并不一定安全,手册上也有指明:
If you have more than one binary log to execute on the MySQL server,
the safe method is to process them all using a single connection to the server.
关于这种方式的更多内容,可以参考: https://dev.mysql.com/doc/refman/5.7/en/point-in-time-recovery.html
然而这两种方式原理都是一样的,通过mysqlbinlog
解析成sql并导入到MySQL中。
-
优点:
- 操作方便,逻辑简单。
- 无需关闭
mysqld
。
-
缺点:
- 遇到
ERROR
难以定位位置,难以“断点恢复”。 - 特殊字符或字符集的问题。
-
max_allowed_packet
问题。 - 恢复速度慢。
- 遇到
因为relaylog和binlog本质实际上是一个东西 所以是否可以利用MySQL自身的sql_thread来增量binlog呢?
通过sql_thread恢复
-
处理思路:
1)重新初始化一个实例,恢复全量备份文件。
2)找到第一个
binlog
文件的position
,和剩下所有的binlog
。 3)将binlog
伪装成relaylog
,通过sql thread
增量恢复。
这里只介绍核心部分,即伪装成relaylog的过程。
① 将relay log info的repository改到file中,并生成这个文件。(relay_log_info_repositor
写到配置文件中)
SET GLOBAL relay_log_info_repository='FILE';
CHANGE MASTER TO master_host='1', master_password='1', master_user='1', master_log_file='1', master_log_pos=4;
通过change命令,是为了告诉MySQL自己为一个slave实例,因为无需用到IO_Thread
,故host
,password
,user
等可以随意填写。
并且通过该步骤,生成relay.info
文件。
② 关闭实例,将需要增量的binlog文件伪装成relaylog。
cp mysql-bin.000003 mysql-bin.000004 mysql-bin.000005 mysql-bin.000006 mysql-bin.000007 mysql-bin.000008 mysql-bin.000009 mysql-bin.000010 $relaylogdir
cd $relaylogdir
rename mysql-bin. mysql-relay. mysql-bin.0000*
chown mysql:mysql -R .
通过cp命令将binlog
移动到$relaylogdir
里,该变量取决于实例的选项参数,默认放在datadir
下。
再将binlog
批量改名成relaylog
,并且给予对应的权限,否则会报错OS error code 13: Permission denied
。
③ 修改relay.info文件和relay-log.index文件
将relay.info
的第二三行改成需要执行的第一个binlog
(现在是relaylog
)的文件名和position
:
/data/mysql57/relaylog/mysql-relay.000003
1276895
第二三行对应Relay_log_name
和Relay_log_pos
,等同于:
mysqlbinlog mysql-relay.000003 --start-position=1276895 | mysql -u -p -S
修改该文件是为了告诉SQL_Thread
从哪一个file
和哪一个position
开始执行events
。
再修改relay-log.index
,清空原有信息,添加以下信息,为的是告诉SQL_Thread
还有哪些relaylog
是需要执行的。
/data/mysql57/relaylog/mysql-relay.000003
/data/mysql57/relaylog/mysql-relay.000004
/data/mysql57/relaylog/mysql-relay.000005
/data/mysql57/relaylog/mysql-relay.000006
/data/mysql57/relaylog/mysql-relay.000007
/data/mysql57/relaylog/mysql-relay.000008
/data/mysql57/relaylog/mysql-relay.000009
/data/mysql57/relaylog/mysql-relay.000010
④ 启动实例,开启SQL_Thread
:
START SLAVE sql_thread ;
⑤ 检查复制状态:
mysql> SHOW SLAVE STATUSG
*************************** 1. row ***************************
Slave_IO_State:
Master_Host: 1
Master_User: 1
Master_Port: 3306
Connect_Retry: 60
Master_Log_File: 1
Read_Master_Log_Pos: 4
Relay_Log_File: mysql-relay.000003 -- 已经执行到的日志名
Relay_Log_Pos: 11529982 -- 已经执行到日志的位置
Relay_Master_Log_File: 1
Slave_IO_Running: No
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: 11529982
Relay_Log_Space: 5347038913
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: 274354 -- 若变为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: 0
Master_UUID:
Master_Info_File: /data/mysql57/master.info
SQL_Delay: 0
SQL_Remaining_Delay: NULL
Slave_SQL_Running_State: Reading event from the relay log
Master_Retry_Count: 86400
………………………………
至此,已经可以通过sql_thread
来增量恢复binlog
了。
当然,上述过程只针对于指定--start-position
的方式来恢复,比如单点MySQL实例在innodb_force_recovery=6
还无法启动的情况下,就需要通过最近一次可用的全量备份+剩下的binlog恢复。
该测试使用的版本为:MySQL 5.7.16
效果:
快速恢复到指定位置点,即通过全备文件+binlog
恢复到故障前的最后一个position
。
针对--stop-position
比如在某一时刻执行了错误的sql,如truncate等操作,同样也可以通过该办法。
但与指定--start-position
的方法有些许不同:
只需要将START SLAVE sql_thread
后添加一个UNTIL RELAY_LOG_FILE = 'log_name', RELAY_LOG_POS = log_pos
即可。
该选项用于控制SQL_Thread
执行到的最后的position,类似于mysqlbinlog mysql-bin.n --stop-position=$log_pos
。
当然,这种数据回档操作,也可以考虑带有flashback
功能的工具。
性能对比
对于同一组binlog文件增量:
通过mysqlbinlog
解析+导入的时间为69min
。
而通过SQL_Thread
的执行时间为41min
。
并且在需要增量的binlog文件越大的情况下,效果越明显。
总结
- 优点: 1)可以断点恢复,人为控制进度,比如stop slave或者遇到错误时,可以知道出错点在哪。 2)性能相对较好,在大量binlog的情况下,可以加快恢复速度。 3)在某些版本可能可以通过MTS来加快增量速度,使恢复更快。
- 缺点: 1)需要关闭mysqld。 2)手动执行过程较mysqlbinlog方式更为复杂。
mysqlbinlog --start-position
与通过修改relay.info
的第三行等效:
用途都是指定开始执行的第一个position
。
mysqlbinlog --stop-position
与通过在启动SQL_Thread
时指定UNTIL RELAY_LOG_FILE = 'log_name', RELAY_LOG_POS = log_pos
等效:
用途都是指定结束执行的最后一个position
。
全文完。
- JS魔法堂:被玩坏的innerHTML、innerText、textContent和value属性
- JavaWeb(四)EL表达式
- eclipse SWT Designer 插件
- 身份证号码验证算法
- JS读书心得:《JavaScript框架设计》——第12章 异步处理
- 被解放的姜戈04 各取所需
- PLT:说说Evaluation strategy
- 被解放的姜戈06 假作真时
- idea 创建的maven+spring+mybatis项目整合 报错无法创建bean
- 代数几何:点,线,抛物线,圆,球,弧度和角度
- 被解放的姜戈05 黑面管家
- 用数据来告诉你2018年的未来趋势
- JavaWeb(三)JSP之3个指令、6个动作、9个内置对象和4大作用域
- 被解放的姜戈03 所谓伊人
- MySQL 教程
- MySQL 安装
- MySQL 管理与配置
- MySQL PHP 语法
- MySQL 连接
- MySQL 创建数据库
- MySQL 删除数据库
- MySQL 选择数据库
- MySQL 数据类型
- MySQL 创建数据表
- MySQL 删除数据表
- MySQL 插入数据
- MySQL 查询数据
- MySQL where 子句
- MySQL UPDATE 查询
- MySQL DELETE 语句
- MySQL LIKE 子句
- mysql order by
- Mysql Join的使用
- MySQL NULL 值处理
- MySQL 正则表达式
- MySQL 事务
- MySQL ALTER命令
- MySQL 索引
- MySQL 临时表
- MySQL 复制表
- 查看MySQL 元数据
- MySQL 序列 AUTO_INCREMENT
- MySQL 处理重复数据
- MySQL 及 SQL 注入
- MySQL 导出数据
- MySQL 导入数据
- MYSQL 函数大全
- MySQL Group By 实例讲解
- MySQL Max()函数实例讲解
- mysql count函数实例
- MYSQL UNION和UNION ALL实例
- MySQL IN 用法
- MySQL between and 实例讲解
- 两段有趣的C代码
- 算法数据结构 | 三个步骤完成强连通分量分解的Kosaraju算法
- 并查集算法 详解
- SQL 中 EXISTS 用法详解
- Blazor带我重玩前端(六)
- PB 级大规模 Elasticsearch 集群运维与调优实践
- MySQL实时在线备份恢复方案
- Android通过原生请求直接获取网页内容
- matplotlib | Python强大的作图工具,让你从此驾驭图表(二)
- 设计模式 | Catalog设计模式,抵御业务方需求变动
- 【Flutter 专题】99 初识 EventBus
- LeetCode 102 | 将二叉树中同层的元素归并在一起
- Git | Git入门,成为项目管理大师(二)
- 学习|Unity3D使用协程实现减速停车效果
- R语言实现文献的批处理