On Thu, Feb 20, 2020 at 4:52 AM Michael Paquier <[email protected]> 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