离线作业失败下游已出报表——数据故障止损与回滚SOP
本文目录
先说结论
数据故障处理黄金五步法:①止血(阻止扩散)→ ②评估(影响面+严重度)→ ③通知(业务+管理层)→ ④修复(数据+流程)→ ⑤复盘(预防再次)。每一步都有明确的SLA。
最容易做错的是顺序:很多人发现问题第一反应是「我赶紧改」,结果改的过程中下游又消费了错误数据,影响面扩大3倍。先止血再修复,这是铁律。
先把这段讲顺;面试官追问时,再展开下面的原理和细节。
详细讲解
「凌晨3点ETL跑挂了,老板早上要看的报表已经发到群里了,数字是错的——怎么办?」这是数据团队最高压的场景。这道题考的不是技术,是应急能力。处理对了能体现Tech Lead级别的判断力,处理错了直接让事故升级。我在当前出海短剧公司值班期间处理过几次P0级数据故障,今天梳理一套实战SOP。
第一步:止血(5分钟内)
发现问题后第一件事不是修,是阻止扩散。三个动作并行:
# 1. 阻断下游调度
block_downstream_tasks(faulty_table)
# DataWorks/DolphinScheduler都有「冻结下游」操作
# 2. 撤回已经分发的报表(如果可能)
if report_already_sent:
notify_business_to_disregard(report_id)
# 钉钉/邮件撤回
# 3. 标记数据为「不可消费」状态
mark_table_status(faulty_table, 'INVALID')
# 通过元数据系统让BI/服务API感知到
我在出海硬件公司处理过一次故障:发现的时候已经凌晨5点,立刻联系运营团队不要发早会PPT、把昨晚提前定时发出的Email标记「数据有误请勿使用」。这一步比修数据重要——错误数据一旦被业务用于决策就回不了头了。
第二步:评估(10-15分钟)
止血之后立刻评估三个问题:
| 维度 | 评估内容 | 工具 |
|---|---|---|
| 影响面 | 哪些下游表/报表/服务被污染 | 数据血缘 |
| 严重度 | 影响是否触及P0业务(财务/合规/对外) | 业务关键性矩阵 |
| 可恢复性 | 数据能不能修复,需要多久 | 故障类型分析 |
-- 用血缘快速找到下游影响面
WITH RECURSIVE downstream AS (
SELECT downstream_table AS tbl, 1 AS depth
FROM lineage WHERE upstream_table = 'dwd_order' -- 故障源表
UNION ALL
SELECT l.downstream_table, d.depth + 1
FROM lineage l JOIN downstream d ON l.upstream_table = d.tbl
WHERE d.depth < 5
)
SELECT tbl, depth, owner, business_criticality
FROM downstream JOIN table_meta ON tbl = table_name
ORDER BY business_criticality DESC, depth ASC;
-- 优先级:高criticality + 浅depth = 最先要修复的
第三步:通知(20分钟内)
通知不是越早越好,是「评估清楚后立刻」。一份合格的故障通知必须包含:
# 故障通知模板
【数据故障通报-P1】
故障时间:2024-03-15 03:00 至 排查中
故障表:dwd_order
影响范围:
- 下游15张表(详见附件)
- 涉及报表:日订单看板、GMV周报、运营投放ROI
- 影响业务:订单中心、广告投放团队
已采取措施:
- 已阻断所有下游调度
- 已通知报表使用方暂不使用今日数据
预计修复时间:上午11点前
影响评估:业务可使用昨日数据替代,无重大决策依赖
联系人:Wood(数据团队值班)
通知的关键不是「我们出事了」,是「我们知道范围、我们在处理、什么时候修复」——给业务方明确预期。最忌讳的是「我们在查」这种没有信息量的回复。
第四步:修复(按故障类型)
| 故障类型 | 典型表现 | 修复方式 |
|---|---|---|
| 数据丢失 | 数据量比基线少30%+ | 重跑分区/补数 |
| 数据重复 | 主键去重后量级翻倍 | INSERT OVERWRITE重写 |
| 数据错误 | 金额/状态字段值不对 | 修复SQL+回算下游 |
| 数据延迟 | 数据没到 | 等上游恢复+重算 |
| 数据污染 | 脏数据混入历史 | 回滚到上一稳定版本 |
修复时的关键原则:
• 永远先在测试环境验证修复SQL再上生产
• 修复脚本必须幂等(重跑多次结果一致)
• 修复完一张表立刻DQC校验通过再放下游
-- 标准修复模板:先备份、再OVERWRITE、最后DQC
-- 1. 备份当前异常分区
CREATE TABLE dwd_order_backup_20240315 AS
SELECT * FROM dwd_order WHERE dt = '20240315';
-- 2. 用修正逻辑OVERWRITE
INSERT OVERWRITE TABLE dwd_order PARTITION(dt='20240315')
SELECT order_id, user_id, amount,
/* 修正状态字段:NULL → 'unknown' */
COALESCE(status, 'unknown') AS status
FROM ods_order WHERE dt = '20240315';
-- 3. DQC校验
SELECT COUNT(*) AS total,
COUNT(*) FILTER (WHERE status IS NULL) AS null_status
FROM dwd_order WHERE dt = '20240315';
-- 必须全部=0通过才能放开下游
-- 4. 触发下游重跑
-- DataWorks: 「补数据」操作,按血缘顺序重跑
第五步:复盘(24小时内)
故障处理完不算结束,必须复盘。一份合格的复盘报告含5要素:
1. 时间线(精确到分钟)
2. 根因分析(5 Whys)
3. 影响评估(量化损失)
4. 改进措施(防止再次发生)
5. ActionItems(含负责人和DDL)
我在出海硬件公司养成习惯——每次P1+故障都写复盘文档放Confluence,半年累积30+篇,新人入职先读。比任何培训都有效。
故障的预防性回滚机制
最优秀的故障处理是「能秒级回滚」。两种实现方式:
-- 方式1:Delta Lake/Iceberg的Time Travel
-- 任何错误写入都可以一行SQL回滚
RESTORE TABLE dwd_order TO VERSION AS OF 42;
-- 或按时间
RESTORE TABLE dwd_order TO TIMESTAMP AS OF '2024-03-14 23:00:00';
-- 方式2:每次OVERWRITE前自动备份
-- 通过自定义UDF或调度系统钩子实现
-- 例如:dwd_order_history 表保留最近7天每个版本
面试高频追问
追问一:怎么判断要不要回滚?
看「修复成本 vs 数据损失」。如果修复时间>2小时且影响面大,立刻回滚到上一稳定版本(接受少量数据损失);如果影响小且明确知道修复方式,就地修复。生产实践中我用的判断标准:影响P0业务且修复时间不可预估 → 回滚;影响P1+修复路径明确 → 修复。
追问二:业务方一直追着问,怎么和他们沟通?
永远主动通知比被问强。固定节奏:发现5分钟、评估完20分钟、每30分钟更新一次进展、修复完立刻通知。哪怕「还在查」也要每30分钟说一次「还在查,目前看是XX方向」。沉默是事故升级的最大原因。
追问三:怎么避免下次再发生?
三个层次:①补DQC规则(这次没拦住的下次能拦);②加监控(基础设施层、数据层、业务层);③改流程(review、灰度、上线检查)。复盘报告里的Action Items必须落到这三个层次至少各一项,否则不算合格复盘。
实战踩坑:一次「修着修着把好的数据也覆盖了」
出海硬件公司有次发现某表昨天分区数据量异常少(只有平时1/3)。我火急火燎写了修复SQL,写完没仔细检查WHERE条件,直接INSERT OVERWRITE跑下去——结果把过去7天的分区全覆盖了,因为我那条SQL的WHERE条件少了一个分区限定。
-- 我跑的错误SQL(SQL正确,但WHERE条件没限定分区)
INSERT OVERWRITE TABLE dwd_order -- 没指定 PARTITION(dt='20240315')
SELECT ... FROM ods_order WHERE dt >= '20240310';
-- 结果:把20240310-20240315全部分区覆盖
-- 之前没问题的6天数据全被错误SQL覆盖
解决方案:紧急切到Delta Lake的Time Travel回滚到出问题前的版本,损失30分钟数据但避免了7天数据全毁。事后定了三条铁律:
1)所有手动修复SQL必须有reviewer +1才能跑
2)OVERWRITE分区表必须显式写PARTITION子句
3)核心表全部接Delta Lake/Iceberg保留Time Travel历史
教训:故障处理的二次伤害比首次故障更严重。越是高压越要冷静,必要时多花5分钟review SQL,比快速跑错代价低100倍。
总结
数据故障五步法:止血→评估→通知→修复→复盘。核心是顺序——先阻止扩散再修复。配合Time Travel等预防性回滚机制,把故障MTTR控制在小时级。面试时按五步法+真实故障故事讲,能秀出实战水平和Tech Lead思维。
下一篇聊一个补数最容易翻车的话题:补数/回刷把历史数据搞乱了——重跑机制怎么设计才安全?
你们经历过最严重的数据故障是什么?怎么处理的?评论区聊聊~
关注「Wood聊大数据」| 9年大数据老兵,聊技术、聊职场、聊成长