提问:作为DBA运维的你是否遇到过这些烦恼
1、你是否因为UPDATE误操作,导致关键数据丢失?
2、尝试了多种方案,但都无法在短时间内紧急恢复数据?
心中有章,遇事不慌
作为DBA的你,遇到问题无从下手,除了在问题面前徘徊,还能如何选择?如果你一次或多次遇到该问题还是无法解决,又很懊恼,该如何排忧呢?关注公众号,关注《包拯断案》专栏,让小编为你排忧解难~

一整套故障排错及应对策略送给你,让你像包拯一样断案如神:
#首先
遇到此类问题后,我们要做到心中有章(章程),遇事不慌。一定要冷静,仔细了解故障现象(与研发/用户仔细沟通其反馈的问题,了解故障现象、操作流程、数据库架构等信息)
#其次
我们要根据故障现象进行初步分析。心中要想:误操作后能通过什么办法紧急恢复数据?例如:是通过binlog进行数据回滚,还是基于最新的数据进行备份恢复?
#然后
针对上述思考,我们需要逐步验证并排除,确定问题排查方向。
#接着
确定了问题方向,进行具体分析。通过现象得出部分结论,通过部分结论继续排查并论证。
#最后
针对问题有了具体分析后,再进行线下复现,最终梳理故障报告。
真刀实战,我们能赢
说了这么多理论,想必实战更让你心动。那我们就拿一个真实案例进行分析——某金融客户的业务系统临近发版,客户方技术人员却因误操作导致整个normal表邮箱列被更新为相同的邮箱地址,遇到这种情况该怎么办?
故障发生场景
在项目现场兢兢业业进行数据库部署的你,突然接到某金融客户的紧急电话:客户业务系统在一个重大节假日前准备发版,但客户方技术人员却误执行了一条未带WHERE条件的UPDATE语句,导致整个normal表的邮箱列被更新为相同的邮箱地址。由于即将发版,客户非常着急,紧急联系到万里数据库的DBA技术人员,希望在发版前恢复误操作前的数据。
环境信息
操作系统版本:BigCloud Enterprise Linux release 8.2.2107 (Core)
数据库版本:greatdb-cluster-6.1.0-GA-1-f4dae0e3-Linux-glibc2.17-x86_64.tar.xz
架构:GreatDB分布式集群
方案分析
根据客户方反馈,该表的数据量约为5万行,更新频率较低,每日新增数据不足100条,但客户要求在短时间内恢复数据。接到客户方需求后,万里数据库技术团队第一时间启动紧急预案,召集人员讨论并梳理恢复方案,得出以下几种可行方案。
数据恢复可行方案
1、使用binlog文件进行数据回滚:该方案需要确认并解析binlog文件,找到误操作语句并将其转换为正确的UPDATE语句执行。虽然该方案可行,但时间上无法满足业务要求,因此放弃;
2、基于最新备份恢复:在其他环境中恢复整体数据,并通过应用binlog恢复备份后的新增数据。此方案风险最小,但耗时较长,因此不优先考虑;
3、使用ibd文件进行数据恢复:利用最新备份找到对应表的ibd文件,通过DISCARD和IMPORT操作恢复数据,备份后的新增数据可通过binlog恢复。该方案恢复时间最短。由于表更新频率低,且客户每日新增数据有记录,恢复至最新备份后,客户技术人员可手动插入新增数据。
经过综合考虑,万里数据库技术团队决定采用第三个方案帮助客户进行数据恢复。
问题产生原因:
由于客户方技术人员在执行UPDATE语句时,未加WHERE条件,导致整张表的某一列数据被全部修改。
解决步骤:
(以下操作为测试环境以及测试数据,供参考)
1.step1:将误操作的表备份一份
rename table test.data_ibd to test.data_ibd_20240918bak1;
2.step2:创建新表
create table test.data_ibd_20240918bak2 like test.data_ibd_20240918bak1;
3.step3:删除新表test.data_ibd_20240918bak2的表空间
alter table test.data_ibd_20240918bak2 discard tablespace;

4.step4:找到原表对应的shard分布
select * from information_schema.GREATDB_TABLE_DISTRIBUTION where table_name = 'data_ibd';
找到对应shard最新的备份 ibd文件,传到数据目录并改名
cd greatdb/backupset/full_backup_20241021-154036_99/shard-shard2/testcp data_ibd.ibd greatdb/mysqldata/dbdata/testmv data_ibd.ibd data_ibd_20240918bak2.ibd
同一shard节点也同样传到对应数据目录
5.step5:修改文件权限
chown -R greatdb.greatdb data_ibd_20240918bak2.ibd
6.step6:恢复表空间(同一shard节点各自执行)
alter table test.data_ibd_20240918bak2 import tablespace;

7.step7:数据对比
误操作之后的表数据为:

恢复最新备份的数据为:

误操作的列为STAFFNAME。
复盘总结
此次通过ibd文件恢复备份数据,从确认方案到完成,累计耗时约10分钟,效率较高且操作简单,完全满足客户紧急恢复数据的要求,需要注意的是要备份原表。
幸运的是,目标表为normal表,且更新频率较低。如果表的数据量达到数亿级,恢复时间将会大幅增加(例如,ibd文件大小为500多GB时,IMPORT操作可能需要约50分钟)。
对于此类误操作,作为DBA技术人员,我们能做的是加强提醒并确保备份文件的可用性。

番外篇-展昭答疑解惑
怎么排除这类误操作带来的隐患呢?
1.根据客户侧的业务量制定合理的数据备份策略,确保备份可用性;
2.提醒客户方技术人员在执行SQL语句前,严格检查语句的正确性;
3.根据客户方业务需求,启用sql_safe_updates参数。启用后,未加WHERE条件的DELETE和UPDATE语句将会直接报错,以此避免误操作。







