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

Design: running pg_dump when tables are continuously created and dropped

我们 运行 PostgreSQL (v9.5) 作为服务数据库 the Kappa architecture:

计算结果并不是这个数据库实例中唯一的一种table,我们需要定期进行热备份。这就是我们的问题。当 table 来来去去,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. 将所有结果 table 放入单独的架构中,并从备份中排除该架构。我们喜欢简单性,但这种方法打破了模块化:我们的数据库对象按垂直切片分组到模式中。
  2. 编写在备份期间暂停 table 删除的应用程序代码。我们想知道是否有更简单的解决方案。

我们喜欢以下想法,但无法实现:

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

对不起,冗长的背景,但现在我终于到了问题:

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

-T <strong><em>table</em></strong>
--exclude-table=<strong><em>table</em></strong>
   Do not dump any tables matching the <strong><em>table</em></strong> pattern.

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

Within a pattern, * matches any sequence of characters (including no characters) and ? matches any single character. (This notation is comparable to Unix shell file name patterns.) For example, \dt int* displays tables whose names begin with int. But within double quotes, * and ? lose these special meanings and are just matched literally.

A pattern that contains a dot (.) is interpreted as a schema name pattern followed by an object name pattern. For example, \dt foo*.*bar* displays all tables whose table name includes bar that are in schemas whose schema name starts with foo. When no dot appears, then the pattern matches only objects that are visible in the current schema search path. Again, a dot within double quotes loses its special meaning and is matched literally.

Advanced users can use regular-expression notations such as character classes, for example [0-9] to match any digit. All regular expression special characters work as specified in Section 9.7.3, except for . which is taken as a separator as mentioned above, * which is translated to the regular-expression notation .*, ? which is translated to ., and $ which is matched literally. You can emulate these pattern characters at need by writing ? for ., (R+|) for R*, or (R|) for R?. $ is not needed as a regular-expression character since the pattern must match the whole name, unlike the usual interpretation of regular expressions (in other words, $ is automatically appended to your pattern). Write * at the beginning and/or end if you don't wish the pattern to be anchored. Note that within double quotes, all regular expression special characters lose their special meanings and are matched literally.