| name | data-operations-safety |
| description | 生产数据操作、备份恢复、批量修复、数据导出和高风险变更前使用。适用于上线门禁、恢复验证、脱敏边界和操作风险评估。融合 SRE 双人复核 + 灰度执行 + 三层备份 + GDPR 脱敏。 |
数据操作安全(Data Operations Safety)
参考来源:Google《Site Reliability Engineering》Postmortem 文化、AWS Well-Architected Framework、PostgreSQL Backup 文档、MySQL Operational Best Practices、GDPR / CCPA 合规规范。
适用场景
- 生产 DDL、索引、回填、批量 UPDATE / DELETE 前检查
- 数据修复脚本、导入导出、脱敏处理
- 备份、恢复、恢复演练和验证
- 高风险变更影响面评估
- 输出上线前数据库门禁清单
- 紧急数据修复(生产事故)
核心原则
1. 能恢复,才允许变更
未验证恢复的备份 = 没有备份
2. 双人复核(4-eyes principle)
生产 DELETE / UPDATE / DROP 必须 2 人确认
3. 灰度先于全量
1 行 → 100 行 → 10000 行 → 全部
4. 影响面预估必须做
COUNT 受影响行数 / 锁表时长 / 磁盘增量
5. 每次操作有审计
谁、何时、对什么、为什么、结果如何
6. 不可逆操作必须备份
DROP TABLE / DROP COLUMN / DELETE 大批
7. 脱敏永不可逆
测试 / 开发环境的生产数据必须脱敏
8. 操作脚本进版本控制
不在 production console 即兴写
操作前检查清单(必填)
□ 1. 授权
□ 操作目的
□ 操作人 + 审批人
□ 目标环境(dev / staging / prod)
□ 业务方知悉
□ 2. 影响面
□ 受影响表 / 行数
□ 锁表预估时间
□ 磁盘增量预估
□ 复制延迟影响
□ 受影响业务(哪些 API / 用户)
□ 3. 备份
□ 最近备份时间(< 24h)
□ 备份是否已验证恢复
□ 备份恢复 RTO(多久能恢复)
□ 必要时新建备份点
□ 4. 脚本质量
□ 脚本幂等
□ 脚本可暂停
□ 脚本可恢复
□ 分批 + 限速
□ 进度可观测
□ 5. 监控
□ 数据库 CPU / IO / 锁等待
□ 主从复制延迟
□ 磁盘空间
□ 业务指标(错误率 / P99)
□ 6. 回滚
□ 回滚条件清晰(错误率 > X / 延迟 > Y)
□ 回滚步骤可执行
□ 数据恢复路径
□ 7. 灰度
□ 1 行测试(dry-run)
□ 100 行
□ 10000 行
□ 全部
高风险操作清单
| 操作 | 必备检查 | 灰度策略 |
|---|
| DDL 变更 | 锁表风险、兼容性、回滚路径 | dev → staging → prod |
| 大表回填 | 分批、限速、幂等、进度记录 | 1k → 10k → 100k → 全部 |
| 批量 UPDATE | WHERE 复核、影响行数、备份 | 1 行 → 100 → 10000 → 全 |
| 批量 DELETE | 同 UPDATE + 强制备份 | 同上 |
| 索引变更 | 建索引耗时、磁盘、写入影响 | CONCURRENTLY 单表 |
| 数据导出 | 授权、脱敏、保存位置、销毁策略 | 小样 → 全量 |
| 恢复操作 | 备份有效性、恢复点、数据一致性 | 隔离环境先验证 |
| TRUNCATE | 备份 + 三人确认 | 无(不可逆) |
灰度执行模板
BEGIN;
SELECT COUNT(*) FROM orders
WHERE status = 'unknown' AND created_at < '2025-01-01';
ROLLBACK;
BEGIN;
UPDATE orders SET status = 'archived'
WHERE id = (SELECT id FROM orders WHERE status = 'unknown' LIMIT 1);
SELECT * FROM orders WHERE status = 'archived' LIMIT 5;
COMMIT;
BEGIN;
UPDATE orders SET status = 'archived'
WHERE id IN (
SELECT id FROM orders
WHERE status = 'unknown' AND created_at < '2025-01-01'
LIMIT 100
);
COMMIT;
DO $$
DECLARE
rows_updated INT;
total INT := 0;
BEGIN
LOOP
UPDATE orders SET status = 'archived'
WHERE id IN (
SELECT id FROM orders
WHERE status = 'unknown' AND created_at < '2025-01-01'
LIMIT 1000
);
GET DIAGNOSTICS rows_updated = ROW_COUNT;
total := total + rows_updated;
RAISE NOTICE 'Updated total: %', total;
EXIT WHEN rows_updated = 0;
PERFORM pg_sleep(0.1);
END LOOP;
END $$;
备份策略
三层备份
1. 物理备份(每天)
- PostgreSQL: pg_basebackup / pgBackRest
- MySQL: xtrabackup / mysqlbackup
- 用途:完整恢复、克隆环境
2. 逻辑备份(每周或按需)
- PostgreSQL: pg_dump
- MySQL: mysqldump
- 用途:单表恢复、跨版本迁移
3. 持续归档(实时)
- PostgreSQL: WAL 归档(PITR 基础)
- MySQL: binlog
- 用途:Point-In-Time Recovery
备份验证(关键)
#!/bin/bash
restore_backup_to_test_env
psql -h test_env -c "SELECT COUNT(*) FROM critical_tables"
psql -h test_env -c "SELECT COUNT(*) FROM orders WHERE created_at > now() - INTERVAL '1 day'"
echo "Backup test: PASS, RTO=15min, RPO=5min" >> /var/log/backup-test.log
Point-In-Time Recovery(PITR)
pg_basebackup -D /backup/base/
archive_mode = on
archive_command = 'cp %p /backup/wal/%f'
restore_command = 'cp /backup/wal/%f %p'
recovery_target_time = '2026-05-18 14:30:00'
数据导出和脱敏
脱敏规则
UPDATE users SET email = MD5(email) || '@test.example.com';
UPDATE users SET phone = SUBSTRING(phone, 1, 3) || '****' || SUBSTRING(phone, 8);
UPDATE users SET name = SUBSTRING(name, 1, 1) || '****';
UPDATE users SET id_card = SUBSTRING(id_card, 1, 6) || '********' || SUBSTRING(id_card, 15);
UPDATE users SET address = REGEXP_REPLACE(address, '(.*?[市县区]).*', '\1');
UPDATE users SET card_number = SUBSTRING(card_number, 1, 6) || '******' || SUBSTRING(card_number, -4);
UPDATE users SET
password = NULL,
api_token = NULL,
refresh_token = NULL,
notes = NULL;
DELETE FROM users WHERE last_login_at > now() - INTERVAL '30 days';
导出审计
CREATE TABLE export_audit (
id bigserial PRIMARY KEY,
exported_by varchar(64) NOT NULL,
exported_at timestamptz DEFAULT now(),
table_name varchar(64) NOT NULL,
row_count bigint,
destination varchar(255) NOT NULL,
reason text,
approved_by varchar(64) NOT NULL,
retention_days integer DEFAULT 30
);
数据修复(生产事故)
修复流程(必须)
1. 评估影响
- 影响行数 / 用户数
- 业务影响
- 是否需要客户沟通
2. 备份当前状态
- 即使数据已损坏,备份是修复依据
- CREATE TABLE backup_before_fix AS SELECT * FROM ...
3. 在 staging 验证修复脚本
- 完整 dry-run
4. 双人复核
- 第二人 review SQL
- 第二人执行(如可能)
5. 生产执行(灰度)
- 1 行 → 100 行 → 全量
6. 验证
- 修复后状态符合预期
- 业务指标恢复
7. 通知
- 业务方
- 受影响用户(如适用)
8. 复盘
- 写 postmortem
- 沉淀到 field-journal
- 评估流程改进
修复脚本示例
CREATE TABLE _backup_orders_2026_05_18 AS
SELECT * FROM orders
WHERE id IN (...)
;
SELECT id, status, expected_status
FROM (
SELECT id, status,
CASE WHEN ... THEN 'paid' ELSE 'cancelled' END AS expected_status
FROM orders
WHERE id IN (...)
) sub
WHERE status != expected_status;
UPDATE orders SET status = 'paid'
WHERE id = (SELECT id FROM ... LIMIT 1);
BEGIN;
UPDATE orders SET status = ... WHERE id IN (...);
SELECT COUNT(*), status FROM orders WHERE id IN (...) GROUP BY status;
COMMIT;
DROP TABLE _backup_orders_2026_05_18;
操作命令模板
改 SQL 前必跑
EXPLAIN (ANALYZE FALSE)
UPDATE orders SET status = 'archived'
WHERE created_at < '2025-01-01';
BEGIN;
UPDATE orders SET status = 'archived'
WHERE created_at < '2025-01-01' LIMIT 100;
SELECT COUNT(*) FROM orders WHERE status = 'archived';
ROLLBACK;
MySQL 安全模式
SET sql_safe_updates = 1;
DELETE FROM orders;
DELETE FROM orders WHERE id = 123;
配套模板
templates/db-change-safety-checklist-template.md — 操作前完整检查 + 影响评估 + 备份确认 + 灰度方案 + 回滚 + 审计
质量自检
□ 明确环境、授权范围和负责人
□ 双人复核(生产 DELETE / DROP)
□ 备份和恢复验证
□ 估算影响行数、锁、磁盘、耗时
□ 脚本幂等、分批、可重试、可停止
□ 设置监控和回滚条件
□ 灰度执行(1 → 100 → 10k → 全部)
□ 避免泄露敏感数据
□ 记录执行结果和复盘项
□ 操作脚本进版本控制
□ 不在 production console 即兴写 SQL
□ 修复脚本在 staging 验证过
常见坑
- 没 WHERE 复核就 UPDATE/DELETE——一秒清空全表
- 备份存在但从未验证恢复——真要恢复时备份损坏
- 回填脚本不可暂停——失败后无法续跑
- 导出生产数据未脱敏——PII 泄露
- 导出生产数据无销毁策略——测试环境永久保留 PII
- DDL 风险只交给应用发布流程——DBA 没权审 SQL
- 修复脚本不留备份——修错无法回退
- TRUNCATE 不三人确认——不可逆
- DROP TABLE 当作普通操作——级联删除引发灾难
- 大表加索引不监控——磁盘满 / 主从断
- 生产 console 即兴写 SQL——无版本控制、无审计
- 修复脚本没 dry run——直接全量错
- 跨租户操作无审计——后期追溯困难
- 脱敏脚本不彻底——昵称 / 备注 / metadata 仍含 PII
与其他 skill 的协作
上游:
migration-rollout → 提供迁移计划
consistency-multitenancy → 提供租户和权限边界
schema-design → 提供 DDL
下游:
devops-engineer → 执行窗口、监控、CI/CD
sre-ops → 监控、告警、恢复
security-engineer → 敏感数据和权限审查
field-journal → 记录真实操作经验
qa-engineer → 数据修复后的回归
相关参考
references/data-operations-safety-guide.md — SRE Postmortem、生产事故案例库、备份恢复演练、脱敏脚本完整库、双人复核流程