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

Reply via email to