当前位置: 首页 > postgresql, WAL日志 > 正文

第一道闸门:私有内存 -> wal_buffers(抢夺 WALInsertLock

【物理动作】:

业务进程在自己的私有内存(Local Memory)里,已经把 XLogRecord(核弹头)组装好了。现在,它要把这串二进制数据**拷贝(Copy)**到全局共享的 wal_buffers 环形队列里。

【争夺的锁】:WALInsertLock(WAL 插入锁)

【原厂面试绝杀考点(PG 9.4 以后的极限优化)】:

如果你在面试时说“所有进程都在抢同一把插入锁”,考官会直接把你淘汰。因为那是十几年前的老黄历了!

  • 远古时代的悲剧:以前确实只有一把独占锁。10 万个并发进程为了把数据拷进内存,全卡在这一把锁上,CPU 疯狂上下文切换,TPS 根本上不去。
  • 现在的多兵团线列阵(Partitioned Locks):为了压榨多核 CPU 的极限,原厂架构师把 WALInsertLock 劈成了一个数组(默认包含 8 把轻量级锁 LWLock)
  • 微秒级推演
    1. 进程先通过极其廉价的 CPU 原子操作(Atomic Fetch-and-Add),在 wal_buffers 里“圈地”(预留出自己需要的字节空间,比如 100 字节)。
    2. 圈好地后,它从 8 把 WALInsertLock 中随机抢一把。
    3. 抢到锁后,它把私有内存里的数据,精准地拷贝到刚才圈好的 100 字节空间里。
    4. 拷贝完成,瞬间释放插入锁。
  • 定性:这叫**“空间分配原子化,数据拷贝并发化”。它允许最多 8 个进程同时**向 wal_buffers 的不同位置写入数据!

第二道闸门:wal_buffers -> 物理硬盘(抢夺 WALWriteLock

【物理动作】:

数据已经安全躺在 wal_buffers 里了。现在,业务进程(或者 walwriter)要发起系统调用 write()fsync(),把这段内存数据砸进底层磁盘

【争夺的锁】:WALWriteLock(WAL 写锁)

【冷酷的物理法则】:

  • 绝对的独裁(排他锁):与插入锁的“多兵团并发”完全不同,向磁盘发起 I/O 请求,是一项极其沉重且必须严格保序的物理动作。因此,WALWriteLock 全局只有唯一的一把,且是绝对的排他锁(Exclusive Lock)!
  • 微秒级推演(衔接我们刚才的组提交魔法)
    1. 100 个已经完成插入(释放了 WALInsertLock)的进程,同时扑向这把唯一的 WALWriteLock
    2. 抢到这把锁的那个唯一进程,瞬间加冕为**“带头大哥”**。
    3. 没抢到锁的 99 个小弟,立刻进入操作系统的休眠队列(Sleep Queue),交出 CPU 控制权。
    4. “带头大哥”捏着这把 WALWriteLock,代表所有人,执行极其沉重的 fsync 磁盘锤击。
    5. 硬盘回执返回,落盘完成。大哥释放 WALWriteLock,并唤醒所有小弟。
  • 定性:它是整个组提交(Group Commit)魔法的物理阵眼。没有这把全局唯一的排他锁来“堵住”大军,就不可能把成百上千的并发碎 I/O 揉成一次巨大的顺序写!

了解 www.876873.xyz 的更多信息

订阅后即可通过电子邮件收到最新文章。

每个 进程 在自己的私有内存里面生产的 wal日志写入到 wal buffer里面的时候,会抢什么锁?? wdal日志由wal buffer 落盘的时候会抢夺什么锁??:等您坐沙发呢!

发表评论