【发布时间】:2022-01-10 06:10:22
【问题描述】:
上下文
我们在 Postgres 数据库中进行基于模式的多租户。每个架构都与不同的租户相关联,并且将具有完全相同的结构除了一个名为 public 的架构。
要获取所有相关模式的列表,我们可以使用:
SELECT tenant_schema FROM public.tenant_schema_mappings;
问题
我们需要定期清理所有租户的特定表:
DELETE FROM a_tenant_schema.parent WHERE expiration_date_time < NOW();
(实际查询要复杂一些,因为我们还需要删除与parent 关联的链接children 条目,但为了这个问题,让我们保持简单。)
约束
- 我们无法使用
pg_cron,因为我们的数据库服务器托管在 Azure 上,并且尚不支持该扩展。 - 我们不希望仅仅为了执行 cron 作业而部署整个服务/应用程序。
- 因此,我们决定使用部署在 k8s 命名空间中的
CronJobpod,从而可以通过 shell 命令使用psql客户端直接与数据库通信。
问题
在 shell 中使用 psql 对所有相关架构执行给定的 DELETE 语句的最佳方法是什么?
请记住:由于可能有数百个租户,因此为每个租户并行运行清理查询可能会很有趣。
当前的潜在解决方案
到目前为止,似乎主要有 2 种方法可能很有趣(尽管我不太确定如何并行化查询执行):
- 弄清楚如何在单个存储过程中执行所有操作,然后使用
psql -c简单地调用该 SP。 - 使用
psql -c "SELECT tenant_schema FROM public.tenant_schema_mappings;"收集所有相关租户模式的列表,然后使用shell 命令通过动态构造适当的查询来遍历该列表。使用查询结果集,使用psql -c一个一个地运行它们。
其他部分解决方案
我认为我们实际上可以使用以下 SQL 构造查询:
SELECT 'DELETE * FROM ' || tenant_schema || '.parent WHERE expiration_date_time < NOW();' AS query
FROM public.tenant_schema_mappings;
也许有办法告诉 Postgres 执行所有结果字符串?
【问题讨论】:
标签: sql postgresql shell psql