Jeremy Schneider:Postgres 索引、分区和 LWLock:锁管理器的可扩展性

Jeremy Schneider:Postgres 索引、分区和 LWLock:锁管理器的可扩展性

💡 原文英文,约3900词,阅读约需14分钟。
📝

内容提要

PostgreSQL用户在Lock Manager方面遇到了争用问题,导致性能下降。这个问题已经被GitLab和Midjourney等多家公司观察到。问题与轻量级锁有关,高事务率和分区数量等因素加剧了问题。缓解策略包括增加容量,应用层缓存,删除不必要的索引,并确保对分区表进行适当的查询优化。尽管出现了这些问题,PostgreSQL仍然是一种受欢迎且可扩展的数据库,正在进行改进Lock Manager可扩展性的讨论。

🔎

延伸解读

问题根源:轻量级锁与分区

文章指出,LWLock:LockManager 争用主要源于轻量级锁,用于保护锁管理器。高事务率和大量分区会加剧争用,因为每个查询需要获取更多锁。GitLab 和 Midjourney 的案例表明,在分区表上运行高并发查询时,锁管理器可能成为瓶颈。

实际影响与缓解措施

GitLab 和 Midjourney 都经历了严重的生产性能下降。缓解策略包括增加容量(如读副本)、应用层缓存、删除不必要的索引、确保分区修剪。连接池和限制动态池增长也能减少负载。监控平均活动会话有助于快速识别问题。

复现与测试

文章提供了复现 LWLock:LockManager 争用的方法,例如使用 pgbench 并强制通用计划。测试显示,强制通用计划时,75,000 tps 下锁争用高达 70% AAS,而默认设置下可达 245,000 tps。这表明查询计划选择对锁争用有显著影响。

架构选择与最佳实践

文章强调,在考虑 NoSQL 之前,应先优化 PostgreSQL 使用。最佳实践包括:使用连接池、限制动态池增长、控制表大小和索引数量、谨慎分区或分片、监控活动会话并设置告警。这些措施有助于避免锁管理器争用,提升可扩展性。

❓

Q&A

PostgreSQL 的 LWLock:LockManager 等待事件是什么?为什么它会导致性能问题?

LWLock:LockManager 是 PostgreSQL 中一种轻量级锁(LWLock)的等待事件,用于保护 Lock Manager 在并发访问时的内存结构。当多个会话同时访问 Lock Manager 时,这个轻量级锁可能成为争用点,导致大量会话等待,从而引发性能下降。高事务率、大量分区或索引等因素会加剧这种争用。

哪些公司遇到了 PostgreSQL LockManager 争用问题?他们是如何应对的?

GitLab 和 Midjourney 等公司公开报告了 LockManager 争用问题。GitLab 在 2023 年 4 月硬件升级后遭遇严重性能下降,调查发现与 LockManager 轻量级锁有关,他们通过增加容量、应用层缓存、删除不必要的索引和优化查询来缓解。Midjourney 在数据库负载增加时也遇到该问题,实施了按天分区策略,后来将每日分区改为每周分区以减少锁开销。

如何复现 PostgreSQL 的 LWLock:LockManager 争用?

可以使用 Fujii Masao 提供的复现步骤:1. pgbench -i -s 100 --partitions=100;2. psql -c "alter user $PGUSER set plan_cache_mode=force_generic_plan";3. pgbench -c 80 -S -M prepared -T 60。这通过强制使用通用计划来触发争用。也可以使用不包含分区键的查询在默认设置下复现。

有哪些缓解 PostgreSQL LockManager 争用的策略?

缓解策略包括:增加容量(如添加只读副本)、在应用层缓存以减少查询率、删除频繁查询表中不必要的索引、确保分区表查询与分区修剪兼容、使用连接池并限制动态池增长、监控平均活动会话、对平均活动会话设置告警。此外,将每日分区改为每周分区可减少锁开销。

PostgreSQL 的 LockManager 争用问题与分区和索引有什么关系?

分区和索引数量会加剧 LockManager 争用。每个分区或索引都可能增加锁的需求,例如查询一个包含 57 个索引的表需要 58 个锁。高事务率下,大量分区会导致轻量级锁争用。Midjourney 通过将每日分区改为每周分区减少了锁开销。GitLab 的争用可能更多由索引数量驱动。

PostgreSQL 社区正在讨论哪些改进 LockManager 可扩展性的方向?

社区正在讨论的改进方向包括:减少执行器的分区锁定、增加 LockManager 分区数、增加快速路径锁槽位(fastpath slots)。这些改进旨在提升 LockManager 的可扩展性,以应对高并发场景下的争用问题。

🏷️

标签

➡️

继续阅读