【问题标题】:How to restore data with PostgreSQL's "pg_restore" and zero downtime?如何使用 PostgreSQL 的“pg_restore”和零停机时间恢复数据?
【发布时间】:2020-12-04 23:13:35
【问题描述】:

我尝试恢复一个大表

pg_restore.exe -U postgres -d db_name --clean --if-exists --single-transaction F:\Backups\PostgreSQL\data.dump.gz

所以我有几分钟的读锁。如何以零停机时间恢复数据以进行读取?我只需要阅读。

【问题讨论】:

  • --clean 表示表被删除并重新创建。读者应该读什么?
  • 这也是锁进入的地方。LocksACCESS EXCLUSIVE"由 DROP TABLE 获取,..." [...] "只有 ACCESS EXCLUSIVE 锁会阻止 SELECT(没有FOR UPDATE/SHARE) 语句。”所以你将不得不告诉我们什么更重要,摆脱读锁或DROP/CREATE 循环?
  • 恢复数据的过程根据定义承认数据库或至少特定表当前处于无效/不准确状态。然后允许的任何选择都可能返回无效/不准确的结果。这比等待或根本没有结果更糟糕。您最好的方法是通知您的用户(广播消息等),然后使用锁定进行恢复。
  • @jjanes 我也用--single-transaction,所以我想旧数据应该仍然存在,我想读一下。
  • 现在我尝试了一种肮脏的方法:将表恢复到此数据库中的另一个模式,然后DROP 旧表和ALTER TABLE 新表SET SCHEMA public。通过这种方式,我的停机时间为零……但我仍在寻找更干净的解决方案。

标签: postgresql backup psql pg-restore


【解决方案1】:

您不需要执行 --clean 而是执行 --data-only,然后在 COPY 之前在同一事务中执行 DELETE from tablename。我认为没有办法让 pg_restore 为您执行此操作,但您可以将 pg_restore 的输出转储到文件并编辑它,或者使用 sed 或 perl 之类的东西来注入 DELETE。

这应该适用于不需要引用的表名,并且假设正在复制的数据都没有以“COPY”开头的第一列:

pg_restore --data-only --single-transaction dmp.dmp -f -| perl -pe 's/^COPY ([\w.]+)/delete from $1; copy $1/' | psql -U postgres -d db_name

但是,您的架构更改方法对我来说似乎并不那么肮脏。它仍然需要一个瞬时访问排他锁,因此它并不是真正的零停机时间,但如果它能够足够快地获得所述锁,它可能是不明显的停机时间。

【讨论】:

    猜你喜欢
    • 2016-12-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-09-23
    • 1970-01-01
    • 1970-01-01
    • 2020-07-07
    • 1970-01-01
    相关资源
    最近更新 更多