我们有一个多租户 SaaS 应用。我们一直为所有租户使用共享数据库,并将 TenantId 作为所有表中的外键。一切都运行良好,直到我们的业务需要每个租户架构的数据库(或模式)。
我们升级了后端 (ASP.NET Core 8) 来处理这种架构,并雄心勃勃地将所有租户迁移到集群上的单独数据库。集群上有大约 1000 个数据库,因此我们的迁移过程非常艰难。在数据量和负载相同的情况下,即使是 32 GB 4 CPUr7g.xl
实例似乎也配置过度,现在,即使是 16 CPU 128 GB r7g.4xl
AWS 实例有时也似乎配置不足。
在 1000 个数据库中,超过一半的数据甚至不会超过 100 MB。很少有数据库的数据量能达到几 GB。
由于我们一直在使用 AWS DMS(无服务器),因此复制也有一段时间处于非活动状态。因此一段时间后,出现了警告:
WARNING: oldest xmin is far in the past
当我们检查所有可能的原因时,结果发现复制槽正在持有 xmin。以下是以下查询返回的内容:
SELECT c.relnamespace::regnamespace as schema_name, c.relname as table_name,
greatest(age(c.relfrozenxid),age(t.relfrozenxid)) as age,
2^31-1000000-greatest(age(c.relfrozenxid),age(t.relfrozenxid)) as remaining
FROM pg_class c LEFT JOIN pg_class t ON c.reltoastrelid = t.oid
WHERE c.relkind IN ('r', 'm') ORDER BY 4;
结果:
该值不断增加,我们尝试删除复制槽两次,每次都导致停机,集群无法恢复,我们不得不从备份中创建新集群。因此,当我们删除不活动的复制槽时,会发生以下情况:
插入/更新查询本来运行良好,但在删除复制槽后突然开始显示 LW 锁。
现在看起来是这样的(插槽未被删除):
我们认为,每个集群拥有超过 300 个 DB 是一个错误。因此,我们将使用多个集群,每个集群拥有大约 300 个 DB。
但是我们现在应该做什么,为什么删除复制槽会触发这些锁?