我有一个带有大约85个表的postgresql数据库。我在复制模式下使用pg_dump
(通过php-pgadmin)定期备份,备份文件的大小几乎为10-12 MB。现在我面临的问题是,每当我尝试恢复数据库时,都会出现外键约束问题。方案如下:
有两个表:1)users
和2)zones
。我已将{id}区域的id存储在users
表中,以识别用户的区域并将其设置为外键。
当我进行数据库转储时,表zones
的条目仅在表users
之后。我认为这是由于表名的第一个字母:u
出现在z
之前,因此当我恢复数据库时,会出现外键约束问题并且执行停止。当我尝试恢复db结构时会出现同样的问题,它表示数据库中不存在表zones
,因为zones
的结构位于转储文件中users
的结构之后
这有什么解决方案吗?还有其他备用方法可行吗?
答案 0 :(得分:7)
听起来你正在从pg_dump
获得SQL转储而不是二进制转储。这将为您提供一大堆SQL,其中包含顶部的架构(包括FK),然后是一堆INSERT来重新加载数据。来自pg_dump
的二进制转储可以更好地为您服务,看起来您需要一些额外的配置来告诉PhpPgAdmin pg_dump
。然后,您将该二进制转储提供给pg_restore
,pg_restore
将以正确的顺序重建所有内容以避免引用完整性问题(或者更确切地说,pg_restore
将恢复所有数据然后添加约束)。
PhpPgAdmin seems to want to work with plain SQL dumps而不是pg_restore
。我发现这很难相信,但我在文档中找不到有关调用pg_restore
的任何内容。如果这是真的那么你可能不得不手工编辑SQL转储并将所有FK移到最后。
您还可以尝试在SQL转储的顶部添加SET CONSTRAINTS ALL DEFERRED;
,这应该延迟约束检查直到事务结束,您还需要确保整个INSERT块包含在交易。
如果PhpPgAdmin确实无法调用pg_restore
,那么您最好手动使用pg_dump
和pg_restore
,这样您就可以对备份过程进行必要的控制。抱歉,任何无法处理使用FK备份数据库的数据库管理工具都比无用更糟糕。希望知道PhpPgAdmin知道方式的人会出现并告诉我们如何将pg_restore
与PhpPgAdmin一起使用。
答案 1 :(得分:3)
如果它对任何人都有帮助:以前没有一个解决方案对我有用(有些INSERT引用了以后转储的数据,如果它是二进制格式,则是独立的,或者是纯SQL查询)。
我做了什么:我使用了schemaspy,一个脚本 - 其他功能,例如一个非常有用的基础ER模型的html图 - 它生成两个非常有用的列表:“插入顺序”(其中所有表都列为最佳顺序,以便执行插入,考虑现有的限制和依赖),以及“删除顺序”(对于DROP表非常有用)。
如果您想要样品,请检查此http://schemaspy.sourceforge.net/sample/。特别是,我刚才提到了两个样本列表(尝试发布直接链接,但垃圾邮件防范机制允许我发布2个链接)。
答案 2 :(得分:1)
使用pgdump(通过php-pgadmin)
您确定PhpPgAdmin正在使用pg_dump创建备份吗?我从未见过pg_dump进行任何转储,在恢复转储时遇到外键问题。
PhpPgAdmin只是一个PHP脚本,在大多数情况下,它无权启动像pg_dump这样的程序。
答案 3 :(得分:1)
我发现您可以在sql的开头添加(这将停止外键检查):
SET session_replication_role = replica;
,最后(恢复检查):
SET session_replication_role = origin;
答案 4 :(得分:0)
我会预先删除fk创建并将其添加到脚本的末尾。
答案 5 :(得分:0)
我曾经遇到过这种情况,我将结构和数据备份在单独的文件中,所以这就是恢复信息的方式:
ALTER TABLE table_name DISABLE TRIGGER ALL;
从pg Admin恢复数据库
ALTER TABLE table_name ENABLE TRIGGER ALL;