简体   繁体   English

pg_restore 没有禁用触发器

[英]pg_restore is not disabling triggers

Using PostgreSQL 9.2.8, I'm trying to restore just my data from one database into another but the triggers seem to still be running.使用 PostgreSQL 9.2.8,我试图将我的数据从一个数据库恢复到另一个数据库,但触发器似乎仍在运行。 I've written the script, shown below, to do the copy.我已经编写了如下所示的脚本来进行复制。

Basically I have dts as my production database, and I have DigitalTrafficSystem as my development database.基本上我有dts作为我的生产数据库,我有DigitalTrafficSystem作为我的开发数据库。 The table structures are the same, but the dev one has very different stored procedures.表结构是相同的,但 dev 有非常不同的存储过程。

When the restore runs, the DigitalTrafficSystem database ends up with a bunch of extra table rows that don't exist in the dts database, so I'm assuming those are getting created by triggers.当恢复运行时, DigitalTrafficSystem数据库以一堆额外的表行结束,这些行在dts数据库中不存在,所以我假设这些行是由触发器创建的。

The messages I get related to triggers, for each table, look like so:对于每个表,我收到的与触发器相关的消息如下所示:

pg_restore: [archiver (db)] could not execute query: ERROR:  permission denied: "RI_ConstraintTrigger_c_136691" is a system trigger
Command was: ALTER TABLE usage ENABLE TRIGGER ALL;

I'm assuming (wrongly?) that the triggers are off, but just that system level trigger couldn't get disabled.我假设(错误地?)触发器已关闭,但只是无法禁用系统级触发器。

Here's my script:这是我的脚本:

#!/bin/sh

PGUSER=dts
FILE=/tmp/.dts.db.$$

# Dump the schema of the DB as we want this to keep
pg_dump -s DigitalTrafficSystem -f $FILE

dropdb -U _postgres DigitalTrafficSystem
if [ $? -ne 0 ]; then
    exit;
fi

createdb -U _postgres -O dts DigitalTrafficSystem
if [ $? -ne 0 ]; then
    exit;
fi

# Restore the schema
psql -d DigitalTrafficSystem -f $FILE

# Dump the data of the real production database
pg_dump -Fc -a dts -f $FILE > /dev/null
if [ $? -ne 0 ]; then
    exit;
fi

# Restore only the data from the real database to our development one
pg_restore -a -d DigitalTrafficSystem --disable-triggers -S dts $FILE

rm $FILE

I'm assuming (wrongly?) that the triggers are off, but just that system level trigger couldn't get disabled. 我假设(错误?)触发器已关闭,但无法禁用系统级触发器。

No, because the success of an SQL command is an all-or-nothing matter. 不可以,因为SQL命令的成功与否无关紧要。 The command that fails is presumably of the form: 失败的命令大概是以下形式:

ALTER TABLE usage DISABLE TRIGGER ALL;

and should it fail, it will fail entirely, as opposed to doing half the job, which would be disabling the user-level trigger and leaving the RI-constraints triggers enabled. 并且如果失败,它将完全失败,而不是完成一半的工作,这将禁用用户级别的触发器,并使RI约束触发器保持启用状态。

pg_restore doc says: pg_restore doc说:

  Presently, the commands emitted for --disable-triggers must be done as superuser. So you should also specify a superuser name with -S or, preferably, run pg_restore as a PostgreSQL superuser. 

and

  -S username, --superuser=username Specify the superuser user name to use when disabling triggers. This is relevant only if --disable-triggers is used. 

But your dts is not superuser. 但是您的dts不是超级用户。 It seems that _postgres is a superuser, according to the rest of the script. 根据脚本的其余部分,看来_postgres是超级用户。 In that case, why not pass it to -S ? 在那种情况下,为什么不将其传递给-S呢?

Another point is, like @wildplasser notes in comments, it's a bit weird to be bothered by triggers in a brand new database, since your script creates a database and immediately runs a data-only import. 另一点是,就像@wildplasser注释中的注释一样,由于您的脚本创建了一个数据库并立即运行仅数据导入,因此被全新数据库中的触发器所困扰有点奇怪。 Can we assume that it's the template1 database that contain these objects, with these triggers? 我们是否可以假设是包含这些对象和这些触发器的template1数据库? But then, note that the data in the tables from template1 are imported as well into the newly created database, so they must also be taken into account for any additional row found between the source of the dump and the final result in the destination database. 但是,然后请注意, template1的表中的数据也被导入到新创建的数据库中,因此对于转储的源与目标数据库的最终结果之间发现的任何其他行,也必须考虑它们。

What is needed is an option on pg_restore to only disable user triggers, instead of all triggers.需要的是 pg_restore 上的一个选项来仅禁用用户触发器,而不是所有触发器。

pg_restore issues: ALTER TABLE <table> DISABLE TRIGGER ALL pg_restore 问题: ALTER TABLE <table> DISABLE TRIGGER ALL

What is needed is for pg_restore to issue this: ALTER TABLE <table> DISABLE TRIGGER USER pg_restore 需要的是发出这个: ALTER TABLE <table> DISABLE TRIGGER USER

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM