Temos um aplicativo SaaS multilocatário. Estávamos usando um banco de dados compartilhado para todos os nossos locatários com TenantId como chave estrangeira em todas as tabelas. Tudo estava funcionando bem, até que nosso negócio exigia arquitetura de banco de dados (ou esquema) por locatário.
Atualizamos nosso back-end (ASP.NET Core 8) para lidar com essa arquitetura e migramos ambiciosamente todos os nossos locatários para um banco de dados separado em um cluster. Temos cerca de 1.000 bancos de dados no cluster e desde então nossa vida de migração tem sido muito difícil. Onde, com a mesma quantidade de dados e carga, até mesmo r7g.xl
instâncias de 32 GB e 4 CPUs pareciam superprovisionadas, agora até r7g.4xl
instâncias AWS de 16 CPUs e 128 GB às vezes parecem subprovisionadas.
Dos 1.000 bancos de dados, mais da metade não terá mais de 100 MB de dados. Poucos podem ter dados em poucos GB.
Como estávamos usando AWS DMS (sem servidor), a replicação também estava inativa há algum tempo. Então vieram os avisos no vácuo depois de algum tempo:
WARNING: oldest xmin is far in the past
Quando verificamos todos os motivos possíveis, descobrimos que os slots de replicação estão retendo o xmin. Aqui está o que a seguinte consulta retorna:
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;
Resultado:
O valor está aumentando, tentamos excluir os slots de replicação duas vezes, e cada vez isso causou um tempo de inatividade e o cluster não conseguiu se recuperar e tivemos que recorrer à criação de um novo cluster a partir do backup. Então, no momento em que excluímos os slots de replicação inativos, isso acontece:
As consultas de inserção/atualização que, de outra forma, funcionam bem, de repente, logo após a exclusão dos slots de replicação, começam a mostrar bloqueios LW.
Esta é a aparência agora (slots não excluídos):
Passamos a acreditar que é um erro ter mais de 300 bancos de dados por cluster. Portanto, usaremos vários clusters com cerca de 300 bancos de dados por cluster.
Mas o que devemos fazer agora e por que a exclusão dos slots de replicação aciona esses bloqueios?