一条 delete 少写了 where,半张表没了。事后查到的事实都很朴素:能登机器的人有九个,谁都没被要求走过变更流程,那条命令没有留痕,备份是三天前的。问题不是"某人水平不行",是边界从来没被定义过。
生产操作的权限不是"有没有"的问题。它是三个连在一起的问题:对哪些动作、在什么条件下、留下什么证据。这篇给分级方式、配套条件与那几处最容易失效的地方。
1. 把"操作"拆成四级,而不是一档
"有生产权限"这个说法本身没有信息量。同一个账号,读一次索引统计和删一张表的风险差着量级,而它们在权限系统里往往只是"能登上去"。
| 级别 | 动作形态 | 例子 | 授权要求 | 留存要求 |
|---|---|---|---|---|
| L1 只读查询 | 不改状态 | select、explain、看日志 |
常规账号即可,但要限流限时 | 审计日志自动留存 |
| L2 可逆写 | 有明确回滚路径 | 改配置、重启单实例、灰度回滚 | 二次确认 + 回滚方案写好 | 记录执行前后状态 |
| L3 不可逆写 | 回不去或代价极高 | delete/update 大表、改数据模型、删索引 |
走变更流程,备份先行 | 完整命令 + 影响行数 |
| L4 影响面不可估 | 影响范围说不清 | 批量脚本、跨服务数据修复、改共用组件 | 不当成工单处理,当成变更项目 | 评审记录 + 分批执行记录 |
分级的判据是回滚成本,不是命令看起来的危险程度。update 一行的风险和 update 一百行万的风险不在一个级别,而它们用的是同一条语法——界定级别要看"我能不能在一分钟内把它变回去",而不是看关键字。
L4 单独列出来,是因为它最常被错当成 L3 处理:一张工单批下来,执行的人自己也不知道影响多少行。影响面不可估的动作不属于"审批"范畴,属于"论证"范畴——它需要先算出影响面,再决定做不做。
正确顺序是先量化再决定。把"影响多少行、多少服务、多少用户"先算出来,哪怕只是量级;影响面一旦能被描述,这个动作就退回 L2 或 L3,按对应要求执行。它在工单系统里最容易走样,因为工单要的是"批准",而它需要的是"算清",两件事的责任人不是同一个。
2. "能登上去"与"能执行"必须分开控制
大多数事故的前提条件不是拿到了执行权限,而是拿到了登录能力。两者是不同层次的东西:
层次一 网络与登录:能否连到这台机器(跳板、密钥、堡垒机、安全组)
层次二 身份与授权:以什么身份执行(sudo 规则、数据库账号、云 IAM)
层次三 命令限制:允许执行什么(只读账号、白名单、代理层改写)
层次四 时间限制:什么时候能执行(时段窗口、临时授权的到期时间)
只做第一层是最常见的做法,也最不解决问题:能 ssh 就意味着能做任何事,因为登录后的动作不在任何规则里。
四层里性价比最高的是第四层。它不改变任何人的能力,只在特定时段关掉可能性:比如"业务高峰时段生产写权限自动降为只读"——规则简单、实现便宜、失效时也不会造成沉默损失。反过来,第一层的成本最高(要改建网络与账号体系),收益却最小,因为它拦的是陌生人,不是同事。
只读也不是零风险。一条没走索引的聚合查询能把主库的 IO 打满,持续时间比一次重启更长:
// 只读账号必须带的护栏,缺一项就等于把主库交给报表
set statement_timeout = '10s'; // 查询侧兜底
set lock_timeout = '1s'; // 避免等待锁把连接池占满
select ... limit 1000; // 交互式查询强制带行数上限
─── 走独立只读实例或独立连接池,不与业务共用,避免慢查询挤占业务连接
这四条护栏的意义不在于防止恶意,而在于让"无心之失"的下限变高。多数高代价事故的起因是"没想到",不是"想干坏事"。
3. 配套条件:不可逆操作的三件套与留痕下限
L3/L4 的动作需要三件配套同时存在,缺一件就不该执行:
| 配套 | 具体要求 | 缺了会怎样 |
|---|---|---|
| 二次确认 | 由另一个人确认,不是同一个人再点一次 | 自己确认自己,等于没有确认 |
| 备份先行 | 备份完成且验证可读,不是"已发起备份" | 备份文件和坏数据同时存在 |
| 可回滚窗口 | 明确写清多久之内能回滚、超过怎么办 | 出问题时第一反应变成"重启试试" |
第二条要特别提醒:备份的"成功"与"可用"是两件事,前者是任务状态,后者要真读一次。把备份当作保险,就必须验过保单。
操作留痕的最低要求是六个字段,缺项的那条记录在复盘时不构成证据:
who: 执行者(真实身份,不是共享账号)
when: 起止时间戳
where: 主机名 / 实例 ID / 库名(精确到能定位)
what: 完整命令原文,不是"做了数据清理"
result: 影响行数、耗时、报错原文
basis: 依据哪个工单或变更单编号
工单编号这一项容易被当成形式。它的真实作用是把执行与决策连起来——出事时能回答"这个动作是谁批准的、当时基于什么信息",而这决定了复盘到底在查执行还是查决策。
留痕之外还要有一条前置检查,L3 的执行者自己就能做完:
// L3 执行前的检查清单,缺一项就不执行
backup_take && backup_verify_readable // 备份"已生成"不算,要能读一次
count_same_clause // 先跑同条件的 count,拿到影响行数
─── 影响行数必须落在预期区间;数量级不对,说明条件写错了
rollback_plan_readable_by_other // 回滚路径要能被别人照着执行,不是只有你会
跳板机与直连是一笔明确的交易:
| 方案 | 收益 | 代价 | 适用 |
|---|---|---|---|
| 跳板/堡垒机 | 统一留痕、集中授权、可录屏 | 摩擦大,紧急时刻会被绕过 | 多人维护、有真实用户数据 |
| 直连 + 审计日志 | 摩擦小、响应快 | 留痕分散,容易有例外 | 小团队、内部系统 |
| 混合:日常跳板、故障走应急通道 | 兼顾 | 应急通道本身要有人盯 | 大多数生产环境的实际解 |
摩擦过大的结果是绕过,不是合规。如果跳板机的登录耗时超过故障处置的容忍时间,实际行为一定是有人私留直连密钥——这时留痕体系看起来完整,实际记录的是"合规的那部分操作"。
配套里还有一条常被忽略:共享账号是留痕的敌人。只要 who 这个字段写的是 root 或一个多人共用的账号,前面五个字段的价值就全部归零。共享账号的成本不是安全,是可追溯性。
4. 紧急路径、度量与排错
"紧急情况先斩后奏"是真实需求,堵住它就等于让大家绕过整套体系。正确的做法不是禁止,而是给一条明确的事后补录路径:
紧急执行(无需事前审批)的成立条件,三条同时满足:
1) 有正在发生的用户可见故障,且处置窗口小于审批所需时间
2) 执行的动作在本轮里可逆,或已先做过备份
3) 执行者发出通知(有人知道谁在做什么),不是静默操作
─── 事后 24 小时内必须补录:工单、命令原文、影响范围、结果
─── 未补录不是"忘了",而是把这条例外变成常态——下一次紧急仍然没有记录
| 度量 | 怎么取 | 说明 |
|---|---|---|
| 生产操作次数 | 审计日志按级聚合 | 数量突然上升通常意味着某处在反复救火 |
| 临时授权存量与到期率 | 授权系统的有效期字段 | 存量只增不减,说明回收环节不存在 |
| 无工单操作数 | 审计日志与工单系统的差集 | 这是唯一能反映"真实执行路径"的指标 |
| 回滚成功率 | 回滚动作的成功次数 / 触发次数 | 低说明回滚方案写得比实际能做的乐观 |
临时授权是这套体系里最容易被"顺手永久化"的东西。它要成立,四项缺一不可:
who 被授权人,一个具体的人,不是角色名
scope 能做什么,具体到动作级别,不是"生产权限"
expires_at 到期时刻,一个具体时间点,不是"故障结束后"
revoke 回收方式,自动回收优先;人工回收必须写清谁负责
─── 没有 expires_at 的授权不是临时授权,只是永久授权的另一种写法
| 现象 | 常见原因 | 处理方向 |
|---|---|---|
| 审计日志齐全但查不到某次操作 | 走了共享账号或未接入审计的直连 | 先补接入,再讨论追责 |
| 临时授权长期存在 | 没有到期时间,或到期不自动回收 | 授时必须带 TTL,回收做成自动 |
| 紧急通道使用频繁 | 常规审批路径太慢 | 精简常规路径,而不是收紧紧急路径 |
| 回滚时发现备份不可用 | 只验证了备份任务成功 | 把"可读验证"写进 L3 的前置条件 |
| 审批人与执行人是同一人 | 权限设计上允许自批 | 从制度上拆开,不靠自觉 |
5. 边界:什么时候正式分级可以压缩
| 情况 | 可压缩到 | 保留什么 |
|---|---|---|
| 单人维护的小系统 | 一次登记 | 一次登记(谁、能做什么)+ 一条备份 |
| 纯只读分析环境 | L1 + 护栏 | 限流、超时、行数上限 |
| 无真实用户数据的内部系统 | L1/L2 合并 | 二次确认与回滚方案 |
| 故障演练与压测环境 | 按生产简化一档 | 演练范围的边界清单 |
| 已经过了停机窗口的退役系统 | 只读 + 封存 | 封存时间点与解封条件 |
压缩的原则是压缩的是流程层级,不是留痕。哪怕单人维护,也要留下"谁在什么时候做了什么"——只是它可能是一行 changelog,而不是一套审批系统。
6. 自测
- 生产操作分级的判据为什么是回滚成本,而不是命令关键字?
- L4"影响面不可估"为什么不走审批、而要走论证?
- 只读查询为什么不是零风险?护栏至少要哪四条?
- 不可逆操作的三件套里,哪一件最容易被自欺?
- 跳板机摩擦过大会导致什么后果?
- 紧急通道要成立,事后补录为什么是它的一部分而不是补充?