【发布时间】:2019-06-16 14:23:05
【问题描述】:
我们将 PostgreSQL (v9.5) 作为 the Kappa architecture 的变体中的 Serving DB 运行:
- 计算作业的每个实例都会创建并填充自己的结果表,例如“t_jobResult_instanceId”。
- 一旦作业完成,其输出表就可供访问。同一作业类型的多个结果表可能同时使用。
- 当不需要输出表时,将其删除。
计算结果并不是这个数据库实例中唯一的一种表,我们需要定期进行热备份。这就是我们的问题。当表来来去去时,pg_dump 会死掉。这是一个重现我们的故障模式的简单测试(它涉及 2 个会话,S1 和 S2):
S1 : psql -U postgres -d myuser
create table t1 ( a int );
begin transaction;
drop table t1;
S2 : pg_dump -Fc -v -U postgres -d myuser -f /tmp/rs.dump
S1 : commit;
Session S2 now shows the following error:
pg_dump -Fc -U postgres -d myuser -f /tmp/rs.dump
pg_dump: [archiver (db)] query failed: ERROR: relation "public.t1" does not exist
pg_dump: [archiver (db)] query was: LOCK TABLE public.t1 IN ACCESS SHARE MODE
我们想到了几个解决方案,但我们都不喜欢其中任何一个:
- 将所有结果表放入单独的架构中,并从备份中排除该架构。我们喜欢简单,但这种方法破坏了模块化:我们的数据库对象按垂直切片分组到模式中。
- 编写在备份期间暂停表删除的应用程序代码。我们想知道是否有更简单的解决方案。
我们喜欢以下想法,但无法实现:
- 我们的结果表遵循命名约定。我们可以编写一个正则表达式来确定一个表名是否引用了一个结果表。理想情况下,我们可以运行 pg_dump 并使用参数指示它跳过与此模式匹配的表(请注意,在备份开始时选择要排除的表还不够好,因为可能会在 pg_dump 运行时创建和删除新的结果表)。这要么是不可能的,要么是我们不够聪明,无法弄清楚如何做到这一点。
抱歉背景啰嗦了,但现在我终于到了问题:
- 有没有办法实现我们错过的 3. ?
- 有更好的想法吗?
【问题讨论】:
标签: regex postgresql pg-dump