12

我有一个包含大约 85 个表的 postgresql 数据库。我定期使用pg_dump(通过 php-pgadmin)在复制模式下进行备份,备份文件的大小几乎为 10-12 MB。现在我面临的问题是,每当我尝试恢复数据库时,都会出现外键约束问题。场景如下:

有两个表: 1)users和 2) zones。我已将区域的 id 存储在users表中以识别用户的区域并将其设置为外键。

当我进行 db 转储时, table 的条目zones仅在 table 之后users。我认为这是由于表名的第一个字母:u出现在之前z,因此当我恢复数据库时,会出现外键约束问题并且执行停止。当我尝试恢复 db 结构时,也会出现同样的问题,它说该表zones在数据库中不存在,因为 的结构位于转储文件中的结构zones之后。users

有什么解决办法吗?有没有其他可行的备份方法?

4

6 回答 6

9

听起来您正在获取 SQL 转储而不是来自pg_dump. 这会给你一大堆 SQL,顶部有模式(包括 FK),然后是一堆 INSERT 来重新加载数据。来自的二进制转储pg_dump会更好地为您服务,看起来您需要一些额外的配置来告诉 PhpPgAdmin 在哪里pg_dump。然后,您将该二进制转储输入pg_restorepg_restore以正确的顺序重建所有内容以避免引用完整性问题(或者更准确地说,pg_restore将恢复所有数据然后添加约束)。

PhpPgAdmin 似乎想要使用纯 SQL 转储而不是pg_restore. 我觉得这很难相信,但我在文档中找不到任何关于 invoking 的内容pg_restore。如果这是真的,那么您可能必须手动编辑 SQL 转储并将所有 FK 移到最后。

您还可以尝试SET CONSTRAINTS ALL DEFERRED;在 SQL 转储的顶部添加,这应该会将约束检查延迟到事务结束,您还需要确保整个 INSERT 块包含在事务中。

如果 PhpPgAdmin 真的无法调用pg_restore,那么您最好使用 usingpg_dumppg_restore手动,以便您对备份过程进行必要的控制。抱歉,任何无法处理使用 FK 备份数据库的数据库管理工具都比无用更糟糕。希望知道如何使用 PhpPgAdmin 的人会出现并让我们知道如何使用pg_restorePhpPgAdmin。

于 2011-03-19T19:34:51.597 回答
4

我发现您可以在 sql 的开头添加(这将停止外键检查):

SET session_replication_role = replica;

最后(恢复检查):

SET session_replication_role = origin;

于 2018-09-17T11:19:03.697 回答
3

如果它对任何人有帮助:以前建议的解决方案都不适合我(有一些 INSERT 引用了稍后转储的数据,如果它是二进制格式或纯 SQL 查询则独立)。

我做了什么:我使用了schemaspy,这是一个脚本——在其他功能中,例如一个非常有用的底层 ER 模型的 html 图——它生成了两个非常有用的列表:一个“插入顺序”(你所有的表都被列为考虑到现有的限制和依赖性,执行插入的最佳顺序)和“删除顺序”(对于 DROP 表非常有用)。

如果您想要一个示例,请查看此http://schemaspy.sourceforge.net/sample/。特别是,我在上面提到了两个示例列表(尝试发布直接链接,但垃圾邮件预防机制允许我仅发布 2 个链接)。

于 2012-07-13T03:03:10.613 回答
2

我曾经遇到过这种情况,我在单独的文件中备份了结构和数据,所以这就是我能够恢复信息的方式:

ALTER TABLE table_name DISABLE TRIGGER ALL;

从 pg Admin 恢复数据库

ALTER TABLE table_name ENABLE TRIGGER ALL;
于 2019-12-19T03:38:26.783 回答
1

使用 pgdump(通过 php-pgadmin)

您确定 PhpPgAdmin 使用 pg_dump 创建备份吗?我从未见过 pg_dump 进行的任何转储,在恢复转储时遇到外键问题。

PhpPgAdmin 只是一个 PHP 脚本,在大多数情况下它没有权限启动像 pg_dump 这样的程序。

于 2011-03-19T07:38:21.540 回答
0

我会预先删除 fk 创建并将其添加到脚本的末尾。

于 2011-03-19T18:52:03.297 回答