从删库到不跑路
—之变更回滚
上 期 回 顾
上期我们介绍了数据库备份,但随着数据库实例大小增加,恢复速度会越来越慢,往往TB级实例 传输-解压-解密-应用-恢复 一套动作下来一天甚至几天就过去了,这种情况下可以搭建延时从库加快恢复速度。
实际上更常见的是变更/误删,比如执行 delete/update 不带where,这种回滚一般需要回滚数据量相对较小,但比较紧急,一般使用 Flashback(闪回) 工具处理。
01 MySQL Flashback(闪回)原理解析
闪回最早是淘宝彭立勋贡献在 mysqlbinlog 的一个功能,可以快速实现变更的回滚。同样的工具实现还有 python的binlog2sql,唯品会开源的 go语言的 binlog_inspector 等等。
这些工具的原理均是基于rows格式的binlog,通过解析binlog,可以进行逆向操作。delete反向生成insert,update生成反向的update,insert反向生成delete。
binlog 即MySQL数据库的二进制日志,用于记录用户对数据库变更操作的SQL语句(如delete/insert/update等等),MySQL主从就是基于binlog回放。binlog的格式有三种:STATEMENT、ROW、MIXED,通常情况推荐使用 ROW 格式, 我们可以用自带的 mysqlbinlog 工具进行查看。
1.1 基于 ROW格式的 binlog
以上就是MySQL rows 格式的binlog,由于binlog包含变更前后值,所以解析binlog就能还原变更前的状态,也就是实现闪回。
解析binlog需要对其数据结构有一定了解,这里简单介绍一下:对MySQL binlog最开始的4bytes(BinLogFileHeader) 必然是固定的 '\xfebin',这个Header主要用来标识这是否一个binlog文件。
从第5 bytes开始为binlog event内容,每个binlog event由event header+event data组成,通常来说 position 4-107为format description event (FDE事件)。MySQL 5.0以后是V4 版本的binlog(V1/V3版本一般不需要关注了),结构如下:
上面的
WriteRowsEvent/UpdateRowsEvent/UpdateRowsEvent也属于binlog event 的一种。更多的类型定义可以在 log_event.h/log_event.cc 源码中查看。
1.2 闪回工具使用
实际 Java/Python/Go 等都有开源的binlog解析包提供,python版本的 binlog2sql 闪回工具便是基于 pymysqlreplication binlog解析包封装的。
下图为
pymysqlreplication.row_event.UpdateRowsEvent 对象包含的信息,可以看到对象中已经包含 after_value/before_values 字典,这大大减少了闪回工具的开发难度。
1.3 闪回工具存在的限制
只能对DML进行回滚,DDL语句binlog包含的信息太少,无法进行回滚。
回滚理论上能回滚至任意时间点,任意binlog位置的数据库状态,问题是这个时间点通常是模糊的,需要DBA在binlog里面确认的,这一步耗时通常会较长。
为了能直接定位变更的范围,我们尝试在变更前后注入 Pseudo GTID, 这样就能确认需要回滚的变更内容。
02 关于 Pseudo GTID(下简称P-GTID)
是 Shlomi Noach 提出的一种理论技术,周期性往主库binlog注入 "不可见事件"(如DROP VIEW/DROP TABLE),通过原生复制流入从库从而为拓扑发现、复制延迟、集群扩容等操作提供唯一标识的手段。
Shlomi Noach 是Github的大神员工,大名鼎鼎的在线变更工具 gh-ost 就是他开源的, 同时还开源了 orchestrator 等项目。
P-GTID 核心是利用 drop view if exists `.*?_pseudo_gtid_hint__` 这种SQL "在binlog可见但实际不影响数据的" 特性注入MySQL集群。
通过注入 P-GTID 可以确定一个变更单的变更起止范围, 下面是结合OPS的变更流程:
总 结
本文对误变更这种场景下的处理思路、闪回原理及工具做了介绍。在实际应用中我们重写了binlog2sql工具,结合P-GTID确认变更binlog位置,封装在ops平台(运维平台)上, 当变更需要回滚只需要在ops上点击确认,就能快速回滚至变更前的状态
参考文献
[pseudo-gtid-manual-injection](https://github.com/github/orchestrator/blob/master/docs/pseudo-gtid-manual-injection.md)
—The End—
以下技术文章,你可能也感兴趣:
排版:川芮