11漏过的水:10 条铁律与真实事故目录
墙上这些条子不是"最佳实践",是事故之后补上去的封条——每一条下面都压着一个现场。
机房那面墙,谁也没刷过漆。上面钉着一张张纸条,有的边角已经卷了。老工程师带你路过时会停一下:这条别碰,当年有人碰过。你不用知道那个人叫什么,你只要知道——他碰完那天,这张纸才被钉上去。
先对个数坊间常说"13 条红线",但能在文档里逐条查到的只有 10 条(出处:复盘第 13 节 + .memsearch\PINNED.md 铁律段)。另外 3 条属口头约定、没有落到文件。所以这一页只写这 10 条,一条不编、一条不凑。

一、先说人话:红线是事故记录,不是公司规定

红线这个词容易误会。它听着像"公司规定",其实是事故记录的另一种写法。

规定是商量出来的,写的时候客客气气;红线是出完事补的,写的时候只剩一句"不许"。

所以读红线有个技巧:别读它禁了什么,读它在防什么。每一条的背面都写着一个具体的动作、一个具体的时间、一个具体坏掉的东西。

你把这层翻过来,它就不再是"限制",而是"有人替你试过了,此路不通"。

这一页的读法固定四行:原话、人话、为什么有这条、踩了会怎样。原话是能拿去跟人争的那一句,可以不好懂;人话是你自己记着用的那一句。

二、墙上这 10 条,一条一条看

先看图。十张纸条钉在墙上,其中三张是红的——红的那三张,就是第三部分要讲的三个事故现场。

它们的共同点后面会讲:没有一个报了错。这也是红线最不讲道理的地方——它防的常常不是崩溃,是"一切正常"。

机房那面墙:每张条子底下都有人栽过 共 10 张 1 生产 SQL 2 Hudi 建表 3 Kyuubi 门牌 4 并行分支 事故二 5 Doris 摆法 6 23:00 停手 7 依赖检查 事故一 8 删分区 事故三 9 回读定义 10 临时权限 红的三张=本章的三个事故现场 证据 > 直觉 运行状态说了算

编号沿用墙上原来的顺序,不是按严重程度排的。第 1 条最常被顺手违反,第 8 条最贵,第 7 条最会骗人——它骗人的方式正好是"一切正常"。

每条都按四行写。原话可以不好懂,但它是唯一能拿去跟人、跟审批、跟复盘会争的一句;人话是你自己记着用的。

🩸 01 · 别在生产上动结构

原话:生产 SQL 禁 CREATE/DROP,禁读写 _sit/_uat/temp_db/default(import_db 只读)。

人话:生产库是给业务出货的,不是练习场。建表删表这种改结构的动作,走建表平台,别在 SQL 里手写。

_sit 是测试库、_uat 是验收库,temp_db 和 default 是谁都能写的公共堆放区。

这四个名字出现在生产连接里,就说明你把测试的东西接到了出货管线上。import_db 只准看,不准写。

为什么有这条:改结构是不可逆的,删错一次没有 Ctrl+Z;而测试库和生产库在同一个 Kyuubi 入口里,库名只差一个后缀,肉眼最容易看串。

踩了会怎样:脚本里一个 DROP 手滑,删掉的是生产表;反过来,数据全写进了 _sit,生产那张表一整天空着,页面数字停在昨天,没有任何人报错。

🩸 02 · 表要和它的文件住在同一本账上

原话:Hudi 必须管理表,建表 SQL 不能带 Location;字段不能以 _ 开头;表和字段必须有备注。

人话:管理表 = 表和它的文件归同一个管家管,删表的时候文件跟着走。

带上 Location,等于把文件寄存在别人家:表是表、文件是文件,两本账。

字段不能以 _ 开头,因为下划线开头是框架留给自己的位置。备注不是客套话,是货架上的标签——没标签的货,没人敢动。

为什么有这条:湖里上千张表,靠人记文件在哪是不可能的。表和文件一旦分家,后面三件事全对不上:删表、清文件、对账。

踩了会怎样:删表只删了名册,文件还躺在盘上占地方,账上"已经删了"、盘上"还在";没备注的表等于匿名表,半年后没人知道那列是什么,也没人敢删。

拦在哪:建表平台 ddls 会逐条报——Location 检查、表备注、字段备注、字段名称检查,一条不过就不许发布。

🩸 03 · 进门先挂牌,别自己改水压

原话:Kyuubi 必须带 subdomain tag,不许用 SQL 注释或 SET 冒充;SQL 里不 SET 引擎参数。

人话:Kyuubi 是所有人共用的一个总闸,谁连上来都要在门牌上写清自己是谁(subdomain tag)。

用注释假装、用 SET 冒充,等于把门牌摘了:出了事查不到人。

引擎参数(内存、并行度这些)是平台统一配的,个人不该在 SQL 里 SET。自己 SET 一下,等于偷偷把总闸的水压调高——你这一单快了,整栋楼的水都小了。

为什么有这条:一套 Kyuubi 后面挂的是共享的 Spark 资源。一个人 SET 大并行度,全项目一起排队;要定位是谁的会话,靠的就是那个 tag。

踩了会怎样:跑挂了不知道是谁的,跑慢了也不知道是谁把资源吃掉的。查不到人,最后只能整组一起背。

🩸 04 · 一个格子,只许一个人倒

原话:同一张表不能拆并行分支——INSERT OVERWRITE 会互相覆盖。

人话:INSERT OVERWRITE 是"先清空、再写满":把这格子的货全铲出去,再倒新的进来。

同一张表拆两条分支一起跑,就是两把铲子同时伸进同一格:各铲各的、各倒各的,谁后倒完算谁的。

先倒的那批,直接没了。

为什么有这条:并行是为了快,但快的前提是两边写的地方不重叠。同一张表拆分支,省下来的时间是拿数据换的。

踩了会怎样:两个任务状态都是成功,一条错都没有,表里却少了一半行或者一半分区。这种错最难查,因为没有任何东西报错——见事故二。

🩸 05 · 仓里摆货的三条硬规矩

原话:Doris 不用 Auto Bucket;副本 3;亿级表禁 select *。

人话:Auto Bucket 是让系统替你估"分几个桶"。桶估多了,一张表被切成一大堆 tablet,小文件一片,导入越跑越慢。

副本 3 是同一份货存三个仓库,坏一个还能卖。亿级表 select * 是把整仓货搬到门口,只为看其中两箱。

为什么有这条:Doris 是出货层,所有人都在上面查。桶分错、副本少、乱扫全表,坏的从来不是一个人的查询,是所有人的响应时间。

规范原话就一句:Auto Bucket 会造成 tablet 数量过多、大量小文件。

踩了会怎样:Auto Bucket 平时看不出来,等数据涨上来,导入开始一天比一天慢。副本不是 3 的表平时也看不出来;等一台机器挂了,页面不是慢,是没数。

select * 打到亿级表上,会把整个集群的查询队列堵住。

🩸 06 · 23 点收工,别跨日续跑

原话:23:00 后停 Hudi 写与查,不跨日续跑。

真名
Hudi(湖里的表)——写和查两个动作都归这条管

人话:湖里的数据按天分格子,格子的名字来自分区里的日期。

23 点以后还在写,很容易跨过零点;一跨零点再续跑,昨天的数据就倒进了今天的格子,或者今天的任务先占了明天的格子。

日子这东西,写错一天就是一辈子。

为什么有这条:零点前后正是分区换日的时候,也是最容易把"哪天"写错的时候。宁可停一小时,不要错一天。

踩了会怎样:分区错一天,当天的数就是错的,而且不报错。时间字段看着完全正常,只是对不上任何一天的账——对账那天才发现,已经错了半个月。

🩸 07 · 绿灯只说明"上次成功过"

原话:依赖检查只认"上次成功",不认"今天跑没跑"。

真名:被检查的那条上游是 ads_supp_di_daily_update_limited(编码 182733687384832,定时 33028)。

原话后面还有半句现场记录:所以 08:00:05 就放行,上游 10-03 下线后仍天天搬旧数据。

人话:调度看上游,看到"上次成功"就放行,它不问这次是不是今天成功的。

上游 10 月 3 号之后再没跑过,那条"上次成功"的印章还盖在 10 月 3 日——灯一直绿着。

这条红线的重点不是"调度有 bug",是你得自己确认今天这次到底跑没跑。

为什么有这条:这条是事故之后补进去的,见事故一。它防的不是机器出错,是人把绿灯当证据。

踩了会怎样:42 家供应商天天拿到 10 月 3 日之前的旧数,日志一条错都没有。所有人都以为今天是正常的。

🩸 08 · 删大表:慢是正常的,狠是要命的

原话:大表分区删除:16–32 万分区用普通 DROP TABLE ≈ 23–26 分钟;PURGE 不可恢复。

人话:删一张 16–32 万分区的大表,正常删也要二十多分钟;这二十多分钟它不是卡住,是它真的在一个一个地干活。

PURGE 是"连回收站一起删":既没更快,又把后悔的余地一起删了。

为什么有这条:删数据最容易被当成"一秒钟的事",于是很少有人在按下去之前先问一句"删错了怎么办"。这条红线就是替你先问这一句。

踩了会怎样:见事故三。删的时候不疼,第二天要用数据的时候才疼——那时候没有后悔药。

🩸 09 · 发布完不算完,要读回来

原话:发布生产前必须 GET 回读整份定义,确认没有 _sit 残留——正式定义不得引用 SIT 运行对象。

人话:发布完要多做一步:把系统里真正生效的那份定义读回来,通读一遍,重点看有没有 _sit 字样。

注意读回来的不是你手里那份稿子——稿子是你以为的,回读才是它现在真正在跑的。

为什么有这条:复制粘贴改库名是最常见的开发动作,改漏一处,稿子里看不出来,因为你看的永远是稿子。

踩了会怎样:生产任务读着测试库的表。测试库一停,生产就停;测试库一改,生产跟着变。

而生产这边看不到任何异常——生产的定义本身"没有错",错在它引用了谁。

🩸 10 · 借来的钥匙,只借一小时

原话:临时管理员权限 1 小时,理由要写具体场景,不能只写"下线"。

真名
项目级临时管理员权限,一次 1 小时

人话:临时管理员权限是借来的钥匙,一次只借一小时。

申请理由要写清"哪个项目、为哪件事、改什么",比如"库存趋势场景 5 月 6 月数据异常调整重刷"。

只写"下线"两个字等于没写:审批的人不知道你要动什么,事后也没人知道这一小时里发生了什么。

为什么有这条:管理员权限能改的东西太多。写不清场景的申请,既是给自己留隐患,也是给别人留口子。

踩了会怎样:轻的理由含糊被卡住,活干不完;重的批下来一小时到期,改到一半的工作流停在半路,谁也不知道它缺了哪一步。

三、三个事故现场,加一条迟早要出的事

下面三个都是真事,表名、编码、日期、分钟数照记录抄的,一个数没改。它们的共同点很奇怪:没有一个是"报错"引起的。

这一点值得单独说。近 8 天里,这套体系跑出 45,571 次成功、296 次失败、529 次被杀,失败率 0.65%。

失败能看见,所以失败好办。而这三个事故全都落在"成功"那 45,571 次里——它们长得跟正常任务一模一样。

会出事 · 事故一:天天搬旧数据

上游任务 ads_supp_di_daily_update_limited(编码 182733687384832,定时 33028)在 2026-10-03 10:46:50 下线。之后没有恢复。

结果:42 家供应商每天搬的都是 10 月 3 日之前的旧数据,页面每天都能打开,数字每天都"对"。

教训:绿灯不等于对。绿灯只回答"上次成功过吗",不回答"今天跑的是哪天的数"。

会出事 · 事故二:两把铲子倒同一格

一张大表跑得慢,有人把它拆成两条并行分支,两条分支写同一张表,都用 INSERT OVERWRITE。

教训:分区是格子,只能一个人倒。要并行就并行到不同的格子里去;同一格上并行,省下的时间是拿数据换的。

会出事 · 事故三:PURGE 之后没有后悔药

大表 16–32 万分区。这种表正常删一遍要多久,实测了四个;同一批里还有一张,试过 PURGE:

对象方式用时
_p1普通 DROP TABLE23.8 分钟
_p2普通 DROP TABLE25.7 分钟
_p4普通 DROP TABLE24.8 分钟
_p8普通 DROP TABLE22.9 分钟
_p7PURGE48 分钟,不可恢复

23–26 分钟不是卡了,是它真的在干活。而 PURGE 那次花掉 48 分钟——时间没省下,后悔的余地先没了。

这不是"删得干净",这是"删得没法回头"。

教训:删数据之前先问一句"要不要能恢复"。答"要",就走普通删,老老实实等那二十多分钟。

注意 · 不是事故,是迟早的事

单项目 756 个任务压在 10 台 worker 上。其中 10.160.10.26 一台扛 218 个,排队 3.8 分钟;其余 9 台基本空闲。

这不是故障,今天还跑得动。但一台机器扛了全项目将近三成的任务(218 / 756),它一咳嗽,全项目一起等。

负载不均不算错,算欠账——欠账不还会加息。

三个事故让墙上多了三张红条子;第四件事还没出事,只是账还没到期。这就是那面墙的真相:纸条不是一次贴完的,是一次一次贴上去的。

四、出事之后,先别改 SQL

页面数字不对,第一反应通常是"去改 SQL"。这是最贵的第一反应,因为十次里有六次根本不是 SQL 的事。

事故一里那条 SQL 一个字都没错,错在上游没人跑;事故二里两条 SQL 也都对,错在它们不该同时跑。

这时候去改 SQL,等于把对的改成错的,然后接着查。

  1. 先确认是"没跑"还是"跑错":看实例,不看页面。实例什么时候开始、什么时候结束、状态是什么、是不是今天这一次。这一步就能排掉一半问题。
  2. 再确认是"数据错"还是"同步错":湖(Hudi)里有没有数?仓(Doris)里有没有数?两边一比就知道断在哪一段——湖里就没有,往上游和入湖查;湖里有、仓里没有,是同步那一段;两边都有,才轮到 SQL 口径。
  3. 最后才改 SQL:前两步都排除了,再动代码。动之前先把现在生效的定义读回来存一份,改坏了还能对照。
小窍门 · 证据优先级运行状态 > 仓库数据 > 页面展示。页面是链条的最后一环,也是最会骗人的一环:缓存、昨天留下的结果、口径没对齐,都能让页面显示一个"看起来很有道理"的数。

这三步的顺序不是礼貌,是省钱。跳过第一步直接改 SQL,最常见的结局是改三天,最后发现上游压根没跑。

而那个结论,八十秒就能看出来。

五、一句话记住

做对了这些红线不是限制你,是替你把别人交过的学费省下来。

换个说法:红线上写的是"别做",底下压着的是别人的一天、一周、或者一整张表。

你照着做,等于这些账已经有人替你付过了。

下次你在生产上准备敲下那条 DROP、或者准备把一张表拆成两条并行分支、或者看见一片绿灯准备收工的时候,停三秒,想想墙上那三张红的。

事实来源:复盘第 13 节(红线原文 10 条)· 第 11 节(现状规模)· 三个事故与实测分钟数出自 .memsearch\PROJECT.md 与 PINNED.md 的 10-28 / 10-29 记录这一关只讲"别做什么"下一关:入口地图