MySQL 内核实战(5):redo log、undo log 与崩溃恢复
问题背景上一篇把写路径的锁与死锁讲完留了一个尾巴事务排队改完只是内存里的事它到底怎么变成磁盘上摔不碎的事实这正是崩溃恢复要回答的。相关的一线现场你大概率遇到过mysqld 被 OOM killer 杀掉或kill -9重启后数据一行没丢一行没多——谁做的账innodb_flush_log_at_trx_commit设成 1 和设成 2压测 TPS 差出一倍生产到底该选哪个还有一改就心里发毛的redo log 满了SHOW ENGINE INNODB STATUS里 log 区报错整个实例瞬间冻住只出不进。这些现象背后是同一条主线WALWrite-Ahead Logging提前写日志协议、LSN 水位线、checkpoint 推进以及 redo/undo 两本方向相反的账。本篇回答五个问题为什么改一个字节要写一条日志而不是直接改页redo 与 undo 各自负责什么、和 430 篇的 MVCC 版本链什么关系checkpoint 如何决定重启要恢复多久trx_commit0/1/2分别丢什么数据以及 torn page撕页这个 fsync 都防不住的坑。核心原理第一WAL把随机写变顺序写的协议。一个事务改 3 行可能涉及 5 个 16KB 页若提交时同步把这些页写回磁盘就是把页在哪就得写哪的随机 IO 压进提交路径——机械盘上几毫秒一次再摊上并发就全堵死。WAL 的换法改动先以紧凑记录追加进 redo log顺序写、一块内存 log buffer 攒批页允许留在 Buffer Pool 做脏页晚点再写协议只要求一条铁律——提交返回客户端之前这笔事务的 redo 必须先落盘。于是提交成本从多次随机页写降为一次顺序日志 fsync。redo 记录是物理为主的页号 偏移 改成什么严格说是 logical-physicalMLOG 类型自带幂等判断恢复时不需要理解 SQL 语义。第二redo 与 undo 是同一枚硬币的两面。每条 undo 记录也走 redo 通道落盘undo 的修改本身也要可恢复。分工上redo 管已发生的别丢——崩溃后从 checkpoint 水位起重放把已提交、页却没来得及写回的改动补上undo 管不该发生的别留——回滚未提交事务以及 430 篇讲过的 MVCC 版本链供快照读走。两者串在同一条 LSN逻辑日志序列号全局单调递增时间轴上页头记着我最后被哪条日志改过page LSN日志记录自带 LSNcheckpoint 记哪之前的脏页都已落盘——三个数字对齐重放不多不少。第三checkpoint恢复时间的调节阀。重放 redo 的代价与上次 checkpoint 之后累积的脏改动成正比所以 InnoDB 后台持续把脏页刷盘并推进 checkpoint 水位LSN。SHOW ENGINE INNODB STATUS的 LOG 区里Log sequence number与Last checkpoint at的差值就是此刻崩溃后需要重放的量差值小秒级拉起差值逼近 redo 文件总容量则触发最凶的机制——redo 写满即全局冻结log 是环形文件新日志要覆盖旧区间而旧区间必须先靠 checkpoint 把对应脏页刷完才能复用刷不上就只能让所有事务排队等 IO表现是整个库只读都不利索。redo 容量innodb_redo_log_capacity8.0.30旧版为innodb_log_file_size × 组数本质是允许的脏页水位 × 写峰值扛度不是越大越好——太大时 checkpoint 更懒崩溃恢复更久还容易养成刷盘线程的慢性怠工。第四提交点持久性的三档取舍与撕页。innodb_flush_log_at_trx_commit精确规定提交那一刻做什么1提交线程同步 writefsync 才回 OK——已回 OK 的事务对任何崩溃免疫对进程崩溃与断电都成立2提交只 write 到 OS page cache后台每秒 fsync——进程崩溃不丢OS 会把 cache 落盘整机断电丢掉已回 OK 但 fsync 未及的约一秒0提交什么都不做每秒由后台 writefsync——进程崩溃也丢约一秒。而就算 1 也有一个 fsync 防不住的坑torn page。盘以 512B/4KB 扇区为原子单位InnoDB 的 16KB 页写可能被撕成半新半旧这样的页 redo 重放都会出错。解法是 doublewrite buffer脏页先顺序写进一个 2MB 中转区再写目的地重启时拿中转区副本校验修复——用一次额外顺序写换页级原子性innodb_doublewriteON是绝对不该关的默认值它同时是 primary/replica 半同步之类无关的机制。第一次代码实验及输出下面是确定性 WAL 模拟纯 Python 内存模型非真 mysqldEngine 维护磁盘页、脏页表、带 LSN 的 redo 流与 undo 前像表。剧本T1 提交T2 改了但未提交checkpoint 把未提交的脏页也冲下磁盘真实 InnoDB 的 page cleaner 正是如此回滚交给 undoT3 提交但页仍脏在内存此时崩溃。恢复阶段从日志重建提交名单checkpoint 之后的已提交记录做 REDO未提交事务按 undo 前像做 UNDO。# InnoDB 日志体系最小模型: redo(带 LSN 的物理改动, 循环追加) undo(逻辑前像)# WAL 铁律: 事务提交前 redo 必须落盘, 脏页允许滞留内存晚写classEngine:def__init__(self):self.disk_pages{acct_A:100,acct_B:50}# 磁盘上的页self.dirty{}# Buffer Pool 脏页self.redo[]# 已落盘 redo: (lsn, trx, page, val)self.redo_buf[]# log buffer(未落盘)self.undo{}# trx - [(page, 前像, 后像)] 供回滚self.lsn0self.ckpt_lsn0defupdate(self,trx,page,val):self.lsn1self.undo.setdefault(trx,[]).append((page,self.cur(page),val))self.redo_buf.append((self.lsn,trx,page,val))self.dirty[page]valdefcur(self,page):returnself.dirty.get(page,self.disk_pages[page])defcommit(self,trx):self.lsn1self.redo_buf.append((self.lsn,trx,COMMIT,None))# WAL: 提交返回客户端之前, 同步把 log buffer 刷到磁盘(trx_commit 1 的语义)self.redoself.redo_buf self.redo_buf[]deflog_writer(self):# log_writer 线程持续把 log buffer 写入日志文件(写不等 fsync)self.redoself.redo_buf self.redo_buf[]defcheckpoint(self):forp,vinself.dirty.items():# 脏页全部写回(含未提交事务的!)self.disk_pages[p]v self.dirty.clear()self.log_writer()self.ckpt_lsnself.lsndefcrash(self):self.dirty,self.redo_buf{},[]# 内存全丢, 未落盘日志蒸发defrecover(self):committed{tfor_,t,p,_inself.redoifpCOMMIT}# 从日志重建提交名单plan[]forlsn,trx,page,valinself.redo:# 1) REDO 阶段: 重放 ckpt 后的已提交改动iflsnself.ckpt_lsnandtrxincommittedandpage!COMMIT:self.disk_pages[page]val plan.append(redo lsn%d %s.%s%s%(lsn,trx,page,val))fortrxinsorted({tfor_,t,_,_inself.redo}-committed):forpage,old,newinreversed(self.undo.get(trx,[])):# 2) UNDO 阶段ifself.disk_pages.get(page)new:self.disk_pages[page]old plan.append(undo %s.%s%s 回滚到前像 %s%(trx,page,new,old))returnplan eEngine()e.update(T1,acct_A,130);e.commit(T1)print(T1: acct_A 100-130 已提交, lsn%d%e.lsn)e.update(T2,acct_B,70)print(T2: acct_B 50-70 改完未提交)e.checkpoint()print(checkpoint: 脏页写回磁盘 acct_A%d acct_B%d (未提交的也被冲下去了!), ckpt_lsn%d%(e.disk_pages[acct_A],e.disk_pages[acct_B],e.ckpt_lsn))e.update(T3,acct_A,999);e.commit(T3)print(T3: acct_A 130-999 已提交, redo 落盘但页还脏在内存)e.crash()print(---- mysqld 崩溃(内存全丢) ----)forstepine.recover():print(恢复: step)print(恢复后磁盘: acct_A%d acct_B%d | 期望: A999(T3不丢) B50(T2未提交须消失)%(e.disk_pages[acct_A],e.disk_pages[acct_B]))运行输出T1: acct_A 100-130 已提交, lsn2 T2: acct_B 50-70 改完未提交 checkpoint: 脏页写回磁盘 acct_A130 acct_B70 (未提交的也被冲下去了!), ckpt_lsn3 T3: acct_A 130-999 已提交, redo 落盘但页还脏在内存 ---- mysqld 崩溃(内存全丢) ---- 恢复: redo lsn4 T3.acct_A999 恢复: undo T2.acct_B70 回滚到前像 50 恢复后磁盘: acct_A999 acct_B50 | 期望: A999(T3不丢) B50(T2未提交须消失)整个剧本里最反直觉的是 checkpoint 那一行未提交事务 T2 的脏改动也会被写到数据文件里。这不是 bug 而是设计——page cleaner 只认页的水位、不认事务边界如果恢复只会 REDO磁盘上就永远留着 T2 的罪证。所以恢复必须两阶段先按 redo 把所有痕迹补齐到崩溃瞬间的最大世界再用 undo 把未提交事务的修改逐条抹去真实 InnoDB 里这步是 rollback segments 上的持久化 undo 链 purge 收尾模型简化为前像表。注意 T3 的两世身份它的 redo 在提交时已落盘WAL 铁律但它的页到崩溃仍是脏的——重放 lsn4 那一条就一分不差。已提交不丢、未提交不留不是魔法是这两条流水线的合取。工程化改进第一步参数基线金融/交易库双 1可容忍秒级丢失的报表库才谈 2。innodb_flush_log_at_trx_commit1sync_binlog1下一篇的主角是默认即正确的基线动它们之前先问业务已告诉用户成功的操作重启后能不能少一笔2 省下的是每次提交的 fsync 调用机械盘时代收益巨大NVMe/带电容保护写缓存的 RAID 上往往只换来 10%~30% 吞吐——用一次断电丢一批订单去换这点数字多数业务不划算。云盘注意宿主掉电时实例内看是 2和云盘自己的持久化语义是两层账确认云厂商文档对 fsync 的承诺再下结论。第二步给 redo 做容量与水位监控。看两个数SHOW ENGINE INNODB STATUSLOG 区Log sequence number - Last checkpoint at的差值占 redo 总容量的比例逼近 100% 就是冻结前夜以及innodb_data_written的分钟级增速推断写峰值能否在 redo 转一圈内被 checkpoint 消化。innodb_redo_log_capacity经验值取高峰期 1 小时的 redo 产量量级并至少给几个 GB8.0.30 支持在线调整该参数大促前的扩容不必再重启。第三步别给恢复制造人祸。崩溃重启时Streaming recovery ... in progress日志刷几分钟是正常重放中途绝不再 kill——二次崩溃只会从头再来恢复慢的根治是 redo 容量与 checkpoint 调优第二步不是 force。真遇到页损坏拉不起checksum errorinnodb_force_recovery1..6按最小级别逐个试、且只为把数据mysqldump/SELECT INTO OUTFILE抢救出来级别 3 以上禁止写业务库事先准备好 HA 切换与备份回放的预案比事后调 force 参数体面得多。第四步把 undo 纳入日常巡检。undo 表空间8.0 默认 2 个独立 undo 表空间自动回收大小与 430 篇的 purge lag 直接挂钩information_schema.INNODB_METRICS里trx_rseg_history_len历史链表长度持续上涨就是长事务钉住了旧版本redo/undo 都会跟着膨胀还会拉长崩溃恢复时要回滚的量。治理动作与 430 一致告警 kill 超时事务这是同一颗药。第二次代码实验及输出把三档 trx_commit × 两种灾难做成损失矩阵确定性模拟trx1~trx8 在 t1~8 依次提交并收到客户端 OKt5.5 突发灾难模式 0/2 的后台周期 fsync 近似为每秒末一次。对比进程崩溃OS 存活、内存丢失与整机断电OS cache 也丢下各自吞掉了哪些已回 OK的提交。# innodb_flush_log_at_trx_commit 三档 x 两种灾难: 谁丢已回 OK的提交?# 时间以 tick 计, trx1..trx8 在 t1..8 提交并回 OK; t5.5 突发灾难# 设后台每秒末(t0.75)做一次周期 fsync(模式2/0 的 flush 节奏近似)COMMIT_T{t:trx%d%tfortinrange(1,9)}NOW5.5acked[cfort,cinsorted(COMMIT_T.items())iftNOW]print(断电前已提交并回 OK: %s%acked)print((trx6..8 提交在灾难之后, 客户端只会看到失败, 不算丢失)\n)deflost(mode,disaster):ifmode1:# 提交点同步 fsync, 回 OK 即持久return[]ifmode2:# 提交只 write() 进 OS page cacheifdisaster进程崩溃:return[]# OS 还活着, cache 稍后自然落盘# mode 0: 提交留在 InnoDB log buffer; 0/2 的断电都只剩周期 flush 追上的部分last_flushmax((kforkinrange(1,9)ifk0.75NOW),default0)return[cforcinackedifint(c[3:])last_flush]formodein(1,2,0):print(trx_commit%d 进程崩溃丢: %-14s 整机断电丢: %s%(mode,lost(mode,进程崩溃)or无,lost(mode,断电)or无))print()print(双 1 配置 (trx_commit1 sync_binlog1):)print( redo 与 binlog 各自独立 fsync, XID 两阶段提交对齐, 任一单边崩溃都不丢已回 OK 的事务)运行输出断电前已提交并回 OK: [trx1, trx2, trx3, trx4, trx5] (trx6..8 提交在灾难之后, 客户端只会看到失败, 不算丢失) trx_commit1 进程崩溃丢: 无 整机断电丢: 无 trx_commit2 进程崩溃丢: 无 整机断电丢: [trx5] trx_commit0 进程崩溃丢: [trx5] 整机断电丢: [trx5] 双 1 配置 (trx_commit1 sync_binlog1): redo 与 binlog 各自独立 fsync, XID 两阶段提交对齐, 任一单边崩溃都不丢已回 OK 的事务矩阵要横着读2 与 0 的差别只发生在进程崩、机器活着时——2 的数据已在 OS page cache内核会替它落盘0 还躺在 mysqld 自己的内存里人死账消。而断电时两者殊途同归都丢最近一个 flush 周期所以我设了 2 所以比 0 安全是半对的直觉它只在进程级灾难里成立。1 两列全零是因为它在回 OK这个动作和fsync 完成之间画了等号——承诺的边界就是持久性的边界。最后一行提醒这条链还有另一半redo 落盘只保证 InnoDB 自身一致事务若还要进 binlog 供从库/订阅消费两边各有一次 fsync、各崩各的对齐靠 XID 两阶段提交——这正是下一篇的主菜。常见陷阱其一把 1 当万能保险转头innodb_doublewriteOFF提性能fsync 防不了 16KB 页被 4KB 扇区撕开redo 重放遇半新半旧页直接起不来——省那点写放大换来的是数据文件级损坏。其二redo 配小了只看到暂时没事日常低峰 checkpoint 勉强跟得上一次批量导数/大事务 UPDATE 直接把Log sequence number - checkpoint打满全库冻结等刷盘故障现场却是什么都没做就是卡容量按写峰值算不要按默认值躺平。其三恢复中反复 killrecovery 无断点续传每次都是全量重来越 kill 越起不来耐心等日志里的恢复进度同时查备份与从库。其四autocommit0配 1 却感觉不到 fsync 开销日志只在事务提交时刷一个开着 40 分钟未提交的事务等于给 39 分钟的改动免了持久化承诺还倒贴长事务锁与 purge 债——框架层的事务边界要与参数假设对齐。其五以为 binlog 能代替 redo 做崩溃恢复binlog 是 server 层的逻辑/行事件按语句序消费、没有页概念拿它恢复等于从 checkpoint 起重放整个业务的逻辑变更慢几个数量级且无法定位页——两套日志的层次不同谁也替不了谁。落地清单生产基线双 1innodb_flush_log_at_trx_commit1sync_binlog1innodb_doublewriteON降级须业务书面确认丢失窗口监控SHOW ENGINE INNODB STATUS的 LSN-checkpoint 差值占 redo 容量比例70% 告警按写峰值配innodb_redo_log_capacity崩溃恢复期间禁止再次 kill页损坏走innodb_force_recovery只做抢救导出平时演练备份回放巡检INNODB_METRICS.trx_rseg_history_len与 undo 表空间水位长事务治理与 430 共用同一告警大事务/批量导数前评估 redo 消化能力分片提交、错峰把冻结风险拆成小口本篇把 InnoDB 自己的账本闭合了redo 保已提交不丢undo 保未提交不留checkpoint 控制恢复时长。但 MySQL 其实有两套日志——server 层的 binlog 不参与崩溃恢复却决定从库有没有数据、订阅能不能回放、误删能不能闪回。两本账各自 fsync 就有主库提交了、从库丢了的缝隙于是才有了两阶段提交、位点与 GTID。下一篇《MySQL 内核实战6binlog 与主从复制原理》把复制链路和丢数据窗口讲透。参考来源MySQL 8.0 Reference Manualinnodb_flush_log_at_trx_commit 系统变量https://dev.mysql.com/doc/refman/8.0/en/server-system-variables.html#sysvar_innodb_flush_log_at_trx_commitMySQL 8.0 Reference ManualForcing InnoDB Recoveryhttps://dev.mysql.com/doc/refman/8.0/en/forcing-innodb-recovery.htmlMySQL 8.0 Reference ManualInnoDB Undo Tablespaceshttps://dev.mysql.com/doc/refman/8.0/en/innodb-undo-tablespaces.htmlWikipediaWrite-ahead logginghttps://en.wikipedia.org/wiki/Write-ahead_loggingWikipediaUninterruptible power supply磁盘写缓存的电池保护备份https://en.wikipedia.org/wiki/Uninterruptible_power_supply 觉得有用就点个赞 收藏方便回头查阅有疑问直接在评论区留言我看到都会回。 本文属于《MySQL 内核实战》系列持续更新关注不迷路。 文章里的代码都能直接跑。想要可直接 clone 的完整工程 配套部署脚本 / 踩坑清单评论一声或发邮件到cj2664qq.com我免费发你。如果你正好在做类似系统、或有工程化难题想找人做也欢迎邮件聊一句——我按实际情况评估能落地的就接单或出方案。评论和邮件都能直接找到我不用跳别的平台。

相关新闻

Rust+Tauri数据库工具dbx:80+驱动静态集成与本地AI SQL实践

Rust+Tauri数据库工具dbx:80+驱动静态集成与本地AI SQL实践

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/9/24 1:28:16 阅读更多 →
EtherCAT CIA402模式选型实战:CSP、CSV、CST如何正确选择

EtherCAT CIA402模式选型实战:CSP、CSV、CST如何正确选择

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/9/24 1:28:16 阅读更多 →
Proton Native 快速上手指南:用 React 语法与热重载构建跨平台桌面应用

Proton Native 快速上手指南:用 React 语法与热重载构建跨平台桌面应用

桌面应用前端UI组件 【免费下载链接】proton-native A React environment for cross platform desktop apps 项目地址: https://gitcode.com/gh_mirrors/pr/proton-native 点击查看 免费下载 本指南基于 docs/quickstart.md 编写,带你从零开始安装 Prot…

2026/9/24 1:28:16 阅读更多 →

最新新闻

LPC2388实战指南:AMBA总线与ARM7嵌入式开发深度解析

LPC2388实战指南:AMBA总线与ARM7嵌入式开发深度解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/9/24 4:28:13 阅读更多 →
定制柜背板 5 毫米、9 毫米、18 毫米,各用在哪

定制柜背板 5 毫米、9 毫米、18 毫米,各用在哪

背板用 5 毫米、9 毫米还是 18 毫米,先看柜子挂在哪个房间、柜深多少、跨度多长,不是越厚越合适。这是做海口全屋定制时容易被一句话带过去的构件,也容易被"加厚就是升级"的直觉带偏。欧派大家居在海口是有实体门店的连锁体系&…

2026/9/24 4:28:13 阅读更多 →
nginx-ui MCP 配置管理工具详解:让 AI Agent 安全读写 Nginx 配置文件

nginx-ui MCP 配置管理工具详解:让 AI Agent 安全读写 Nginx 配置文件

后端前端运维MCP 服务 【免费下载链接】nginx-ui Yet another WebUI for Nginx 项目地址: https://gitcode.com/gh_mirrors/ngi/nginx-ui 点击查看 免费下载 导读 本文聚焦 nginx-ui 内置的 MCP(Model Context Protocol)配置管理模块&#…

2026/9/24 4:28:13 阅读更多 →
Talos Linux ResolverConfig 配置指南:nameservers、searchDomains 与 hostDNS 全解析

Talos Linux ResolverConfig 配置指南:nameservers、searchDomains 与 hostDNS 全解析

云原生操作系统容器编排 【免费下载链接】talos Talos Linux is a modern Linux distribution built for Kubernetes. 项目地址: https://gitcode.com/gh_mirrors/ta/talos 点击查看 免费下载 本文基于 Talos Linux(v1.15 参考文档与源码)系…

2026/9/24 4:28:13 阅读更多 →
Storm 与机器学习:在线模型更新、实时预测与特征工程管道

Storm 与机器学习:在线模型更新、实时预测与特征工程管道

Storm 与机器学习:在线模型更新、实时预测与特征工程管道本文探讨了如何利用 Apache Storm 构建机器学习在线模型更新、实时预测与特征工程管道。从基础架构到具体实现,详细介绍了 Storm 与机器学习系统的集成方案,包括在线模型更新机制、实时…

2026/9/24 4:28:13 阅读更多 →
高通骁龙865救砖指南:QPST与9008模式底层刷机实战

高通骁龙865救砖指南:QPST与9008模式底层刷机实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/9/24 4:27:12 阅读更多 →

日新闻

基于YOLOv8的渔船作业监控系统:从环境搭建到边缘部署全流程

基于YOLOv8的渔船作业监控系统:从环境搭建到边缘部署全流程

简介:这是一套面向计算机、人工智能、自动化等专业学生与教师的毕业设计级项目资源,围绕YOLOv8实现渔船作业监控系统,可用于毕设、课程设计、大作业或项目立项演示。压缩包共97个文件,约24.21MB,以70个Python源码文件为…

2026/9/24 0:00:19 阅读更多 →
单细胞注释实战:基于Scanpy的标记基因与参考映射流程解析

单细胞注释实战:基于Scanpy的标记基因与参考映射流程解析

简介:一份基于单细胞RNA测序数据的细胞类型注释算法研究Python毕业设计源码,针对计算机相关专业正在做毕设或需要项目实战的学习者,可用于课程设计与期末大作业。项目代码完整、经导师指导评审通过,可直接运行,覆盖数据…

2026/9/24 0:00:19 阅读更多 →
C#源生成器实战:用增量生成器替代反射,告别AOT崩溃

C#源生成器实战:用增量生成器替代反射,告别AOT崩溃

第一次在项目里被反射卡住,是在一个老旧的WinForms模块里:几十个类依赖PropertyChanged通知,运行时反射读属性、发通知,每次启动慢半拍不说,一上.NET Native/AOT裁剪模式几乎全面崩盘。后来我把这段逻辑全部改成C#源生…

2026/9/24 0:00:19 阅读更多 →

周新闻

Flutter for OpenHarmony游戏卡片渐变背景实战:从原理到性能优化

Flutter for OpenHarmony游戏卡片渐变背景实战:从原理到性能优化

直接铺开项目本身吧。这几个月我一直在折腾一件事:用Flutter给OpenHarmony做一款游戏集合类的App,说白了就是把若干小游戏塞进一个壳里,用统一入口分发。这个方向本身不算新鲜,真正让我花了不少心思的,是首页那堆游戏卡…

2026/9/23 4:55:02 阅读更多 →
Word表格编号全攻略:从列表编号到题注交叉引用

Word表格编号全攻略:从列表编号到题注交叉引用

写Word文档,最让人头疼的往往是那些“看起来不起眼”的小问题。比如表格编号这事:今天在表后面多加了两个空白行,明天给客户交稿前发现整个章节的编号全部错位,光是挨个改序号就能耗掉大半个下午。我前阵子帮人整理一份上百页的技…

2026/9/23 4:49:06 阅读更多 →
从第一个站到第二个站:独立开发者的静态网站选型与落地实践

从第一个站到第二个站:独立开发者的静态网站选型与落地实践

1. 项目概述1.1 核心需求解析做独立开发者这几年,说实话,第一个网站上线的那天晚上我兴奋得没睡着。但等它跑了半年,流量惨淡、功能臃肿、代码自己都懒得看第二遍之后,我才慢慢琢磨明白一个道理:第一个网站是练手&…

2026/9/23 9:53:41 阅读更多 →

月新闻

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能分类:[AI/大模型]细分主题:AI 增强型 CI/CD 流水线自动化与 GitOps 实践:Agent 工作流、工具调用与任务拆解:从原型到生产的验收清单很多团队在尝试用大…

2026/9/23 9:53:40 阅读更多 →
容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场

容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场

容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场分类:[工程技术]细分主题:Kubernetes 生产环境运维与排障实战:可复制的项目复盘模板与决策记录大部分团队的事故复盘报告,最后都变成了躺在 Confluence 或钉…

2026/9/23 9:53:40 阅读更多 →
容器 容器化技术与镜像安全管理:核心链路应该先拆哪一步

容器 容器化技术与镜像安全管理:核心链路应该先拆哪一步

容器 容器化技术与镜像安全管理:核心链路应该先拆哪一步分类:[工程技术]细分主题:Docker 容器化技术与镜像安全管理:核心链路的逐步实现与关键代码取舍面对一个积累了五六年历史包袱的单体架构应用(包含 Web 接口、后台…

2026/9/23 9:53:40 阅读更多 →