<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"><channel><title>木匠钉子 · 博客</title><description>Neil Chen 的个人博客。</description><link>https://cznail.github.io/my-blog/</link><item><title>从索引命中到查询结果</title><link>https://cznail.github.io/my-blog/posts/%E4%BB%8E%E7%B4%A2%E5%BC%95%E5%91%BD%E4%B8%AD%E5%88%B0%E6%9F%A5%E8%AF%A2%E7%BB%93%E6%9E%9C/</link><guid isPermaLink="true">https://cznail.github.io/my-blog/posts/%E4%BB%8E%E7%B4%A2%E5%BC%95%E5%91%BD%E4%B8%AD%E5%88%B0%E6%9F%A5%E8%AF%A2%E7%BB%93%E6%9E%9C/</guid><description>索引找到候选位置后，查询还要处理版本可见性、必要的条件复验和剩余过滤。从几份执行计划出发，看 Bitmap、Index Only Scan 和 GIN 怎样通过 AM 接口接上这些工作。</description><pubDate>Fri, 23 Oct 2026 16:00:00 GMT</pubDate></item><item><title>国产数据库，最后靠什么赢得信任？</title><link>https://cznail.github.io/my-blog/posts/%E5%9B%BD%E4%BA%A7%E6%95%B0%E6%8D%AE%E5%BA%93%E6%9C%80%E5%90%8E%E9%9D%A0%E4%BB%80%E4%B9%88%E8%B5%A2%E5%BE%97%E4%BF%A1%E4%BB%BB/</link><guid isPermaLink="true">https://cznail.github.io/my-blog/posts/%E5%9B%BD%E4%BA%A7%E6%95%B0%E6%8D%AE%E5%BA%93%E6%9C%80%E5%90%8E%E9%9D%A0%E4%BB%80%E4%B9%88%E8%B5%A2%E5%BE%97%E4%BF%A1%E4%BB%BB/</guid><description>从一张感冒处方，想到国产数据库的信任问题：客户花的钱，到底买到了什么？</description><pubDate>Sun, 18 Oct 2026 16:00:00 GMT</pubDate></item><item><title>B-tree 里的重复 Key 与旧记录的清理</title><link>https://cznail.github.io/my-blog/posts/b-tree-%E9%87%8C%E7%9A%84%E9%87%8D%E5%A4%8D-key-%E4%B8%8E%E6%97%A7%E8%AE%B0%E5%BD%95%E7%9A%84%E6%B8%85%E7%90%86/</link><guid isPermaLink="true">https://cznail.github.io/my-blog/posts/b-tree-%E9%87%8C%E7%9A%84%E9%87%8D%E5%A4%8D-key-%E4%B8%8E%E6%97%A7%E8%AE%B0%E5%BD%95%E7%9A%84%E6%B8%85%E7%90%86/</guid><description>从一次阻止了 HOT 的普通 UPDATE 出发，解释 Unique Index 为什么允许重复 Key、B-tree 如何在插入路径上清理旧版本，以及 VACUUM 清理完成之后，空间为什么仍可能留在 Index 文件里。</description><pubDate>Fri, 16 Oct 2026 16:00:00 GMT</pubDate></item><item><title>B-tree 的并发搜索与页面分裂</title><link>https://cznail.github.io/my-blog/posts/b-tree-%E7%9A%84%E5%B9%B6%E5%8F%91%E6%90%9C%E7%B4%A2%E4%B8%8E%E9%A1%B5%E9%9D%A2%E5%88%86%E8%A3%82/</link><guid isPermaLink="true">https://cznail.github.io/my-blog/posts/b-tree-%E7%9A%84%E5%B9%B6%E5%8F%91%E6%90%9C%E7%B4%A2%E4%B8%8E%E9%A1%B5%E9%9D%A2%E5%88%86%E8%A3%82/</guid><description>一个 Backend 拿着过期的 Downlink 走进旧 Page，另一个刚好完成了 Split。High Key、Rightlink 以及 Incomplete Split，如何让这次并发搜索继续找到正确的 Key。</description><pubDate>Fri, 09 Oct 2026 16:00:00 GMT</pubDate></item><item><title>Heap Page 里的旧版本，什么时候会被清理</title><link>https://cznail.github.io/my-blog/posts/heap-page-%E9%87%8C%E7%9A%84%E6%97%A7%E7%89%88%E6%9C%AC%E4%BB%80%E4%B9%88%E6%97%B6%E5%80%99%E4%BC%9A%E8%A2%AB%E6%B8%85%E7%90%86/</link><guid isPermaLink="true">https://cznail.github.io/my-blog/posts/heap-page-%E9%87%8C%E7%9A%84%E6%97%A7%E7%89%88%E6%9C%AC%E4%BB%80%E4%B9%88%E6%97%B6%E5%80%99%E4%BC%9A%E8%A2%AB%E6%B8%85%E7%90%86/</guid><description>从一个 DELETE 留下的死元组出发，看它经过 Visibility Horizon、Page Pruning、LP_DEAD 和 Index Cleanup，最后能变成什么样；以及 VACUUM FULL 为什么要重新造一份 Heap。</description><pubDate>Wed, 30 Sep 2026 16:00:00 GMT</pubDate></item><item><title>PostgreSQL 是怎么把 Tuple 写进 Heap 的</title><link>https://cznail.github.io/my-blog/posts/postgresql-%E6%98%AF%E6%80%8E%E4%B9%88%E6%8A%8A-tuple-%E5%86%99%E8%BF%9B-heap-%E7%9A%84/</link><guid isPermaLink="true">https://cznail.github.io/my-blog/posts/postgresql-%E6%98%AF%E6%80%8E%E4%B9%88%E6%8A%8A-tuple-%E5%86%99%E8%BF%9B-heap-%E7%9A%84/</guid><description>顺着一次 Tuple 写入，看看 FSM、Visibility Map、Buffer Lock 和 WAL 是怎么在 Heap AM 里接到一起的。</description><pubDate>Thu, 24 Sep 2026 16:00:00 GMT</pubDate></item><item><title>Checkpoint 调优，到底在调什么？</title><link>https://cznail.github.io/my-blog/posts/checkpoint-%E8%B0%83%E4%BC%98%E5%88%B0%E5%BA%95%E5%9C%A8%E8%B0%83%E4%BB%80%E4%B9%88/</link><guid isPermaLink="true">https://cznail.github.io/my-blog/posts/checkpoint-%E8%B0%83%E4%BC%98%E5%88%B0%E5%BA%95%E5%9C%A8%E8%B0%83%E4%BB%80%E4%B9%88/</guid><description>Checkpoint 引起的 I/O 尖峰和延迟抖动，可能来自触发太频繁，也可能来自某一轮写得太重。把一次 Checkpoint 拆成 trigger、write、sync 三段，再顺着 WAL、pg_wal 和 Recovery 往下看，这几个参数各自管什么就清楚了。</description><pubDate>Sat, 19 Sep 2026 16:00:00 GMT</pubDate></item><item><title>Checkpoint、BgWriter、WAL Writer，PG 的三个后台写进程</title><link>https://cznail.github.io/my-blog/posts/checkpointbgwriterwal-writerpg-%E7%9A%84%E4%B8%89%E4%B8%AA%E5%90%8E%E5%8F%B0%E5%86%99%E8%BF%9B%E7%A8%8B/</link><guid isPermaLink="true">https://cznail.github.io/my-blog/posts/checkpointbgwriterwal-writerpg-%E7%9A%84%E4%B8%89%E4%B8%AA%E5%90%8E%E5%8F%B0%E5%86%99%E8%BF%9B%E7%A8%8B/</guid><description>Checkpointer、Background Writer 和 WAL Writer 都会在后台写盘，但它们守的是三个不同的边界：Recovery 从哪里开始、Buffer 能不能顺利复用、WAL 推进到了哪里。这三个边界之间，又一直在互相借力。</description><pubDate>Fri, 18 Sep 2026 16:00:00 GMT</pubDate></item><item><title>WAL 已经可以相信了，Data Page 呢？</title><link>https://cznail.github.io/my-blog/posts/wal-%E5%B7%B2%E7%BB%8F%E5%8F%AF%E4%BB%A5%E7%9B%B8%E4%BF%A1%E4%BA%86data-page-%E5%91%A2/</link><guid isPermaLink="true">https://cznail.github.io/my-blog/posts/wal-%E5%B7%B2%E7%BB%8F%E5%8F%AF%E4%BB%A5%E7%9B%B8%E4%BF%A1%E4%BA%86data-page-%E5%91%A2/</guid><description>COMMIT 返回时，被修改的 Data Page 往往还留在 Shared Buffers 里。WAL Flush 已经把 fsync 算进自己的语义，Data Page 却把 write 和 sync 拆成两步，中间还隔着一次责任交接。</description><pubDate>Fri, 11 Sep 2026 16:00:00 GMT</pubDate></item><item><title>COMMIT 返回之前，PostgreSQL 到底在等什么？</title><link>https://cznail.github.io/my-blog/posts/commit-%E8%BF%94%E5%9B%9E%E4%B9%8B%E5%89%8Dpostgresql-%E5%88%B0%E5%BA%95%E5%9C%A8%E7%AD%89%E4%BB%80%E4%B9%88/</link><guid isPermaLink="true">https://cznail.github.io/my-blog/posts/commit-%E8%BF%94%E5%9B%9E%E4%B9%8B%E5%89%8Dpostgresql-%E5%88%B0%E5%BA%95%E5%9C%A8%E7%AD%89%E4%BB%80%E4%B9%88/</guid><description>COMMIT 返回之前，PostgreSQL 要等 WAL 持久化到自己的 Commit LSN。可这条有序日志是一群并发 Backend 写出来的，这条线比想象中曲折。</description><pubDate>Fri, 04 Sep 2026 16:00:00 GMT</pubDate></item><item><title>WAL 里面存的是 Page Diff 吗？</title><link>https://cznail.github.io/my-blog/posts/wal-%E9%87%8C%E9%9D%A2%E5%AD%98%E7%9A%84%E6%98%AF-page-diff-%E5%90%97/</link><guid isPermaLink="true">https://cznail.github.io/my-blog/posts/wal-%E9%87%8C%E9%9D%A2%E5%AD%98%E7%9A%84%E6%98%AF-page-diff-%E5%90%97/</guid><description>一个 Page 在 Shared Buffers 里被修改以后，PostgreSQL 到底往 WAL 里留下了什么？从 Heap Insert 一路看到 B-tree Split、FPI 和 rmgr。</description><pubDate>Fri, 28 Aug 2026 16:00:00 GMT</pubDate></item><item><title>围棋、AI 与软件设计：真正重要的也许不是多算几步</title><link>https://cznail.github.io/my-blog/posts/%E5%9B%B4%E6%A3%8Bai-%E4%B8%8E%E8%BD%AF%E4%BB%B6%E8%AE%BE%E8%AE%A1%E7%9C%9F%E6%AD%A3%E9%87%8D%E8%A6%81%E7%9A%84%E4%B9%9F%E8%AE%B8%E4%B8%8D%E6%98%AF%E5%A4%9A%E7%AE%97%E5%87%A0%E6%AD%A5/</link><guid isPermaLink="true">https://cznail.github.io/my-blog/posts/%E5%9B%B4%E6%A3%8Bai-%E4%B8%8E%E8%BD%AF%E4%BB%B6%E8%AE%BE%E8%AE%A1%E7%9C%9F%E6%AD%A3%E9%87%8D%E8%A6%81%E7%9A%84%E4%B9%9F%E8%AE%B8%E4%B8%8D%E6%98%AF%E5%A4%9A%E7%AE%97%E5%87%A0%E6%AD%A5/</guid><description>如果下棋只是比谁算得多，业余玩家是不是从一开始就输了？顺着这个疑问查了一圈，发现围棋要训练的，和做数据库设计要训练的，原来是同一件事。</description><pubDate>Sun, 23 Aug 2026 13:00:00 GMT</pubDate></item><item><title>Shared Buffers 不是一个 Cache</title><link>https://cznail.github.io/my-blog/posts/shared-buffers-%E4%B8%8D%E6%98%AF%E4%B8%80%E4%B8%AA-cache/</link><guid isPermaLink="true">https://cznail.github.io/my-blog/posts/shared-buffers-%E4%B8%8D%E6%98%AF%E4%B8%80%E4%B8%AA-cache/</guid><description>Shared Buffers 会缓存 Page，但沿着一个 Buffer Slot 的生命周期看下去，里面还有 identity、pin、I/O、dirty 和 eviction 组成的一整套协议。</description><pubDate>Fri, 21 Aug 2026 16:00:00 GMT</pubDate></item><item><title>一个 Backend 想睡一觉，为什么这么麻烦？</title><link>https://cznail.github.io/my-blog/posts/%E4%B8%80%E4%B8%AA-backend-%E6%83%B3%E7%9D%A1%E4%B8%80%E8%A7%89%E4%B8%BA%E4%BB%80%E4%B9%88%E8%BF%99%E4%B9%88%E9%BA%BB%E7%83%A6/</link><guid isPermaLink="true">https://cznail.github.io/my-blog/posts/%E4%B8%80%E4%B8%AA-backend-%E6%83%B3%E7%9D%A1%E4%B8%80%E8%A7%89%E4%B8%BA%E4%BB%80%E4%B9%88%E8%BF%99%E4%B9%88%E9%BA%BB%E7%83%A6/</guid><description>条件不满足就睡，别人做完了再叫醒。听起来很简单，但并发系统最麻烦的地方，往往就藏在&quot;决定要睡&quot;和&quot;真正睡下去&quot;之间。</description><pubDate>Fri, 14 Aug 2026 16:00:00 GMT</pubDate></item><item><title>一个 Backend 是怎么进入 PostgreSQL“共享世界”的？</title><link>https://cznail.github.io/my-blog/posts/%E4%B8%80%E4%B8%AA-backend-%E6%98%AF%E6%80%8E%E4%B9%88%E8%BF%9B%E5%85%A5-postgresql%E5%85%B1%E4%BA%AB%E4%B8%96%E7%95%8C%E7%9A%84/</link><guid isPermaLink="true">https://cznail.github.io/my-blog/posts/%E4%B8%80%E4%B8%AA-backend-%E6%98%AF%E6%80%8E%E4%B9%88%E8%BF%9B%E5%85%A5-postgresql%E5%85%B1%E4%BA%AB%E4%B8%96%E7%95%8C%E7%9A%84/</guid><description>有了 PID，为什么还要 PGPROC？有了 PGPROC，为什么还要 ProcArray？顺着 backend 的生命周期，看它怎么在共享内存里建立身份、发布状态，再安全退场。</description><pubDate>Fri, 07 Aug 2026 16:00:00 GMT</pubDate></item><item><title>事务都结束了，PostgreSQL 为什么还不能立刻释放锁？</title><link>https://cznail.github.io/my-blog/posts/%E4%BA%8B%E5%8A%A1%E9%83%BD%E7%BB%93%E6%9D%9F%E4%BA%86postgresql-%E4%B8%BA%E4%BB%80%E4%B9%88%E8%BF%98%E4%B8%8D%E8%83%BD%E7%AB%8B%E5%88%BB%E9%87%8A%E6%94%BE%E9%94%81/</link><guid isPermaLink="true">https://cznail.github.io/my-blog/posts/%E4%BA%8B%E5%8A%A1%E9%83%BD%E7%BB%93%E6%9D%9F%E4%BA%86postgresql-%E4%B8%BA%E4%BB%80%E4%B9%88%E8%BF%98%E4%B8%8D%E8%83%BD%E7%AB%8B%E5%88%BB%E9%87%8A%E6%94%BE%E9%94%81/</guid><description>不是 PG 拖拖拉拉不想放锁，是放锁这件事本身就是在告诉其他人&quot;我弄完了，你们可以进来了&quot;。</description><pubDate>Fri, 31 Jul 2026 01:00:00 GMT</pubDate></item><item><title>PostgreSQL 为什么宁愿重启，也不让共享内存随便长大？</title><link>https://cznail.github.io/my-blog/posts/postgresql%E4%B8%BA%E4%BB%80%E4%B9%88%E5%AE%81%E6%84%BF%E9%87%8D%E5%90%AF%E4%B9%9F%E4%B8%8D%E8%AE%A9%E5%85%B1%E4%BA%AB%E5%86%85%E5%AD%98%E9%9A%8F%E4%BE%BF%E9%95%BF%E5%A4%A7/</link><guid isPermaLink="true">https://cznail.github.io/my-blog/posts/postgresql%E4%B8%BA%E4%BB%80%E4%B9%88%E5%AE%81%E6%84%BF%E9%87%8D%E5%90%AF%E4%B9%9F%E4%B8%8D%E8%AE%A9%E5%85%B1%E4%BA%AB%E5%86%85%E5%AD%98%E9%9A%8F%E4%BE%BF%E9%95%BF%E5%A4%A7/</guid><description>改个 shared_buffers 就要重启？不是不能动态扩，是不想为所有状态都背上在线迁移的债。</description><pubDate>Sun, 26 Jul 2026 06:09:37 GMT</pubDate></item><item><title>Contributor 有什么了不起的？</title><link>https://cznail.github.io/my-blog/posts/contributor%E6%9C%89%E4%BB%80%E4%B9%88%E4%BA%86%E4%B8%8D%E8%B5%B7%E7%9A%84/</link><guid isPermaLink="true">https://cznail.github.io/my-blog/posts/contributor%E6%9C%89%E4%BB%80%E4%B9%88%E4%BA%86%E4%B8%8D%E8%B5%B7%E7%9A%84/</guid><description>AI 能写 Patch，但能替我们成为贡献者吗？</description><pubDate>Thu, 16 Jul 2026 13:00:00 GMT</pubDate></item></channel></rss>