【发布时间】:2019-01-10 00:41:05
【问题描述】:
使用 Postgres 10.6
问题:
- 我的表中的某些数据违反了外键约束(不确定如何)。约束是
ON DELETE CASCADE ON UPDATE CASCADE - 在数据库的 pg_dump 上,这些外键被删除(由于处于无效状态?)
- 将
pg_restore写入一个不再有外键的空白数据库 - 新数据库已将其所有主键更新为第二个数据库中未使用的有效键。由于现在缺少约束,包含无效数据的表没有更新其外键。
- 新数据库的
pg_dump完成,然后数据库被删除 - 在将
pg_restore导入具有外键约束的第二个数据库时,数据以无效状态导入,并损坏新数据库。
我想要做的是:每隔几个小时(或一天一次,取决于查询需要多长时间)验证所有具有外键的表中的所有数据是否有效。
我已阅读有关ALTER TABLE ... VALIDATE CONSTRAINT ... 的信息,但这不能解决我的问题,因为数据当前未标记为NOT VALID。我知道可以做这样的陈述:
DELETE FROM a WHERE a.b_id NOT IN ( SELECT b.id )
但是,我有 144 个带有外键的表,所以这会相当乏味。我也可能不想立即删除数据,但记录问题并通知用户将会发生的更正。
当然,我想知道最初的损坏是如何发生的,并防止这种情况发生;但是目前我只是想阻止它传播。
示例表:
CREATE TABLE dependencies (
...
from_task int references tasks(id) ON DELETE CASCADE ON UPDATE CASCADE NOT NULL,
to_task int references tasks(id) ON DELETE CASCADE ON UPDATE CASCADE NOT NULL,
...
);
依赖关系最终会得到 to_task 和 from_task 的值,这在 tasks 表中不存在(见图)
注意:
- 试过
EXPLAINANALYZE没什么奇怪的 - pg_tablespace,只有两条记录。 pg_default 和 pg_global
- relforcerowsecurity、relispartition 在两个表上都是“假”
- pg_dump 的参数(来自 c++ 调用)
arguments << "--file=" + fileName << "--username=" + connection.userName() << databaseName << "--format=c"
【问题讨论】:
-
“我的表中的一些数据违反了外键约束(不确定如何)”不知何故我非常怀疑..为我们提供创建表语句和违反的数据
-
除非先填表,否则稍后会用
NOT VALID选项添加外键,对吧? -
外键从一开始就存在。我已编辑帖子以包含其中一张表的相关部分。
-
以下查询为您的表
SELECT relname, relrowsecurity FROM pg_class where relname='tasks'返回什么? -
relrowsecurity 为假。
标签: postgresql foreign-keys data-corruption