简体   繁体   中英

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. 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. The table structures are the same, but the dev one has very different stored procedures.

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.

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. 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.

pg_restore doc says:

  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. It seems that _postgres is a superuser, according to the rest of the script. In that case, why not pass it to -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. Can we assume that it's the template1 database that contain these objects, with these triggers? 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.

What is needed is an option on pg_restore to only disable user triggers, instead of all triggers.

pg_restore issues: ALTER TABLE <table> DISABLE TRIGGER ALL

What is needed is for pg_restore to issue this: ALTER TABLE <table> DISABLE TRIGGER USER

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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