设计:连续创建和删除表时运行pg_dump

时间:2019-01-23 03:41:30

标签: regex postgresql pg-dump

我们以the Kappa architecture的变体形式将PostgreSQL(v9.5)作为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

我们想到了几种解决方案,但我们都不喜欢其中的一种:

  1. 将所有结果表放入单独的架构中,并从备份中排除该架构。我们喜欢简单性,但是这种方法破坏了模块化:我们的数据库对象通过垂直切片分为模式。
  2. 编写在备份期间暂停表删除的应用程序代码。我们想知道是否有更简单的解决方案。

我们喜欢以下想法,但无法使其起作用:

  1. 我们的结果表遵循命名约定。我们可以编写一个正则表达式来确定表名是否引用结果表。理想情况下,我们将能够使用指示其跳过与此模式匹配的表的参数来运行pg_dump(请注意,选择要在备份开始时排除的表还不够好,因为可能会在pg_dump运行时创建并删除新的结果表)。这要么是不可能的,要么是我们不够聪明,无法弄清楚该怎么做。

很抱歉,背景漫长,但现在我终于想到了这个问题:

  • 有没有一种方法可以实现我们错过的3。
  • 还有更好的主意吗?

1 个答案:

答案 0 :(得分:0)

使用pg_dump-T选项应该可以实现:

  

-T table
  --exclude-table=table
  不要转储任何与table模式匹配的表。

psql文档包含有关这些模式的详细信息:

  

在一个模式中,*匹配任何字符序列(包括无字符),而?匹配任何单个字符。 (此表示法可与Unix Shell文件名模式相提并论。)例如,\dt int*显示名称以int开头的表。但是在双引号中,*?失去了这些特殊含义,只是按字面意义进行匹配。

     

包含点(.)的模式被解释为架构名称模式,后跟对象名称模式。例如,\dt foo*.*bar*显示表名包含bar的所有表,这些表的模式名以foo开头。如果没有点出现,则该模式仅匹配在当前模式搜索路径中可见的对象。同样,双引号中的圆点失去其特殊含义,并且在字面上匹配。

     

高级用户可以使用正则表达式(例如字符类),例如[0-9]来匹配任何数字。所有正则表达式特殊字符均按Section 9.7.3中的规定工作,除了.被用作上述分隔符,*被转换为正则表达式{{1} },.*(翻译为?)和.(从字面上匹配)。您可以通过为$编写?,为.编写(R+|)或为R*编写(R|)来模拟这些模式字符。不需要R?作为正则表达式字符,因为该模式必须与整个名称匹配,这与对正则表达式的通常解释不同(换句话说,$将自动附加到您的模式)。如果您不希望锚定图案,请在开头和/或结尾处写$。请注意,在双引号中,所有正则表达式特殊字符都会失去其特殊含义,并且会在字面上进行匹配。