【发布时间】:2014-07-28 02:39:16
【问题描述】:
问题
我使用pg_dump 创建我们数据库的仅模式存档文件。我想通过省略转储中的一组分区表中的一个来减小此文件的大小(并减少恢复时间)。
例如,数据库中有以下分区表(按日期)。我只想保留最后一个。
awp_partition.awp_text_search_history_201209
awp_partition.awp_text_search_history_201210
awp_partition.awp_text_search_history_201211
awp_partition.awp_text_search_history_201212
plus hundreds more...
我创建了一个 pg_dump 命令(在 bash 脚本中调用),旨在排除所有这些表,但使用负前瞻正则表达式的最新表除外:
pg_dump -h 11.111.11.11 -p 5432 -U username -F c -s \
-T 'awp_partition.awp_text_search_history_(?!201212)\d{6}' \
dbname > /home/me/tmp/prod3.backup
但是,当我运行此命令时,所有表都从转储文件中排除。
我尝试过的
我尝试使用表包含和排除参数的组合,但尝试排除所有表同时包含一个匹配排除模式的表 - 导致整个转储失败。
我使用 Postgres regexp_matches() 函数测试了我的正则表达式,它正确匹配了我期望的表。但是,根据文档: pg_dump documentation
仅转储匹配表的表(或视图或序列或外部表)。可以通过编写多个 -t 开关来选择多个表。此外,table 参数根据 psql 的 \d 命令使用的相同规则被解释为模式(请参阅模式),因此也可以通过在模式中写入通配符来选择多个表。使用通配符时,如果需要,请小心引用模式,以防止 shell 扩展通配符;
以及相关文档psql patterns documentation
高级用户可以使用诸如字符类之类的正则表达式表示法,例如 [0-9] 来匹配任何数字。除 .如上所述,它被用作分隔符,* 被转换为正则表达式符号 ., ?它被翻译成 .,而 $ 则按字面意思匹配。您可以在需要时通过编写来模拟这些模式字符?为.,(R+|) 为 R,或 (R|) 为 R?。 $ 不需要作为正则表达式字符,因为模式必须匹配整个名称,这与正则表达式的通常解释不同(换句话说,$ 会自动附加到您的模式中)。如果您不希望模式被锚定,请在开头和/或结尾写上 *。请注意,在双引号内,所有正则表达式特殊字符都失去了它们的特殊含义,并按字面意思匹配。此外,正则表达式特殊字符在运算符名称模式中按字面意思匹配(即 \do 的参数)。
我意识到此操作可能不支持负前瞻运算符的语法。
怎么办?
看来我需要更改我的模式匹配策略,并且我正在努力想一种方法来排除使用 psql \d 模式的所有表,但其中一个表除外。有什么想法吗?
【问题讨论】:
-
测试你的正则表达式,我得到前 3 行匹配的结果。我认为这是你想要的行为......所以我的猜测是问题出在 pg_dump
-
另外,我发现 psql 模式文档非常混乱!这肯定是问题的根源,因为他们搞乱了不同的正则表达式字符的含义
-
同意。 \d 模式匹配中可用的功能子集令人沮丧。我也发现很难测试。在 psql 命令行中工作的一些 \d 模式不适用于 pg_dump。我仍在尝试找出一种可靠的方法来测试它,而不必经历整个转储恢复周期。
标签: regex postgresql pg-dump