sda*_*bet 5 postgresql foreign-keys corruption postgresql-9.2
我的 PostgreSQL (9.2) 数据库包含两个表registrations并attributes具有外键约束:
postgres=# \d+ registrations;
Table "public.registrations"
Column | Type | Modifiers | Storage | Stats target | Description
---------+-------+-----------+----------+--------------+-------------
name | text | not null | extended | |
parent | text | | extended | |
storage | bytea | | extended | |
Indexes:
"registrations_pkey" PRIMARY KEY, btree (name)
Referenced by:
TABLE "attributes" CONSTRAINT "attributes_cname_fkey" FOREIGN KEY (cname) REFERENCES registrations(name) ON DELETE CASCADE
Has OIDs: no
postgres=# \d+ attributes;
Table "public.attributes"
Column | Type | Modifiers | Storage | Stats target | Description
--------+-------+-----------+----------+--------------+-------------
cname | text | not null | extended | |
aname | text | not null | extended | |
tags | text | | extended | |
value | bytea | | extended | |
Indexes:
"attributes_pkey" PRIMARY KEY, btree (cname, aname)
Foreign-key constraints:
"attributes_cname_fkey" FOREIGN KEY (cname) REFERENCES registrations(name) ON DELETE CASCADE
Has OIDs: no
Run Code Online (Sandbox Code Playgroud)
在某些时候,我意识到有些行违反了外键约束:
postgres=# SELECT COUNT(*) FROM attributes LEFT JOIN registrations ON attributes.cname=registrations.name WHERE registrations.name IS NULL;
count
-------
71
(1 row)
Run Code Online (Sandbox Code Playgroud)
您能帮我理解这种腐败是如何发生的吗?
标记为 的约束NOT VALID是您可能期望看到违规的一种情况,但该NOT VALID子句将显示在 psql\d+输出中。(我相信可以在目录中手动更新此标志,但我希望为您着想,这不是问题......)
据我所知,绕过外键检查的唯一受支持的方法是SET session_replication_role TO replica在修改数据之前。这是为了复制过程的好处,在假设约束已经在主服务器上验证的情况下运行 - 尽管如果您的复制器有错误或配置错误,这肯定会出错。
超级用户也可以手动禁用约束的底层触发器(对于试图加快批量导入速度的人来说通常很诱人)。以下内容将告诉您触发器当前是否处于活动状态(tgenabled应该是'O'):
SELECT *
FROM pg_trigger
WHERE tgname ~ '^RI_ConstraintTrigger'
AND tgrelid IN ('registrations'::regclass, 'attributes'::regclass)
Run Code Online (Sandbox Code Playgroud)
我认为没有任何方法可以知道过去是否暂时更改过,但如果您启用了语句日志记录,您可能会ALTER TABLE ... DISABLE TRIGGER在某处找到一条语句。
外键执行中至少还存在一个漏洞,当然,您总是有可能发现一个错误......
| 归档时间: |
|
| 查看次数: |
4485 次 |
| 最近记录: |