On Thu, Feb 20, 2020 at 4:52 AM Michael Paquier <mich...@paquier.xyz> wrote: > > That sounds right, as event triggers could interact with GRANT and > REFRESH of matviews, so they should be logically last. Looking at the > recent commit history, this would be similar to 3eb9a5e as we don't > really have a way to treat event triggers as dependency-sortable > objects. >
Indeed... event triggers should be the last thing to be restored. > What kind of errors did you see in this customer > environment? Errors triggered by one or more event triggers blocking > some commands based on a tag match? > By error I meant the weird behavior I described before that pg_restore create the event triggers in parallel mode and after that other objects are created then the event trigger is fired during the restore... Have a look at the new attached patch. Regards, -- Fabrízio de Royes Mello Timbira - http://www.timbira.com.br/ PostgreSQL: Consultoria, Desenvolvimento, Suporte 24x7 e Treinamento
diff --git a/src/bin/pg_dump/pg_backup_archiver.c b/src/bin/pg_dump/pg_backup_archiver.c index 77bf9edaba..faa93aaf9a 100644 --- a/src/bin/pg_dump/pg_backup_archiver.c +++ b/src/bin/pg_dump/pg_backup_archiver.c @@ -670,11 +670,13 @@ RestoreArchive(Archive *AHX) { /* * In serial mode, process everything in three phases: normal items, - * then ACLs, then matview refresh items. We might be able to skip - * one or both extra phases in some cases, eg data-only restores. + * then ACLs, matview refresh items, then event triggers. We might be + * able to skip one or both extra phases in some cases, eg data-only + * restores. */ bool haveACL = false; bool haveRefresh = false; + bool haveEventTrigger = false; for (te = AH->toc->next; te != AH->toc; te = te->next) { @@ -692,6 +694,9 @@ RestoreArchive(Archive *AHX) case RESTORE_PASS_REFRESH: haveRefresh = true; break; + case RESTORE_PASS_EVENT_TRIGGER: + haveEventTrigger = true; + break; } } @@ -714,6 +719,16 @@ RestoreArchive(Archive *AHX) (void) restore_toc_entry(AH, te, false); } } + + if (haveEventTrigger) + { + for (te = AH->toc->next; te != AH->toc; te = te->next) + { + if ((te->reqs & (REQ_SCHEMA | REQ_DATA)) != 0 && + _tocEntryRestorePass(te) == RESTORE_PASS_EVENT_TRIGGER) + (void) restore_toc_entry(AH, te, false); + } + } } if (ropt->single_txn) @@ -3084,6 +3099,8 @@ _tocEntryRestorePass(TocEntry *te) return RESTORE_PASS_ACL; if (strcmp(te->desc, "MATERIALIZED VIEW DATA") == 0) return RESTORE_PASS_REFRESH; + if (strcmp(te->desc, "EVENT TRIGGER") == 0) + return RESTORE_PASS_EVENT_TRIGGER; return RESTORE_PASS_MAIN; } diff --git a/src/bin/pg_dump/pg_backup_archiver.h b/src/bin/pg_dump/pg_backup_archiver.h index 6768f92976..204019b514 100644 --- a/src/bin/pg_dump/pg_backup_archiver.h +++ b/src/bin/pg_dump/pg_backup_archiver.h @@ -220,9 +220,10 @@ typedef enum { RESTORE_PASS_MAIN = 0, /* Main pass (most TOC item types) */ RESTORE_PASS_ACL, /* ACL item types */ - RESTORE_PASS_REFRESH /* Matview REFRESH items */ + RESTORE_PASS_REFRESH, /* Matview REFRESH items */ + RESTORE_PASS_EVENT_TRIGGER /* Event Trigger items */ -#define RESTORE_PASS_LAST RESTORE_PASS_REFRESH +#define RESTORE_PASS_LAST RESTORE_PASS_EVENT_TRIGGER } RestorePass; typedef enum