diff --git a/src/test/isolation/README b/src/test/isolation/README
index dc96242883ab850e4883780b2f8893bd6eb64844..69095778c6c4c331c6d72e4d4dbcd48b8edd9b3d 100644
--- a/src/test/isolation/README
+++ b/src/test/isolation/README
@@ -49,8 +49,12 @@ subdirectory. A test specification consists of four parts, in this order:
 setup { <SQL> }
 
   The given SQL block is executed once, in one session only, before running
-  the test. Create any test tables or other required objects here. This
-  part is optional.
+  the test.  Create any test tables or other required objects here.  This
+  part is optional.  Multiple setup blocks are allowed if needed; each is
+  run separately, in the given order.  (The reason for allowing multiple
+  setup blocks is that each block is run as a single PQexec submission,
+  and some statements such as VACUUM cannot be combined with others in such
+  a block.)
 
 teardown { <SQL> }
 
diff --git a/src/test/isolation/isolationtester.c b/src/test/isolation/isolationtester.c
index 98f89da6bff842bfbc21be3f92691561c9b23f3a..4c4556654b390b8520289a942f8454f867bbbe51 100644
--- a/src/test/isolation/isolationtester.c
+++ b/src/test/isolation/isolationtester.c
@@ -512,9 +512,9 @@ run_permutation(TestSpec * testspec, int nsteps, Step ** steps)
 	printf("\n");
 
 	/* Perform setup */
-	if (testspec->setupsql)
+	for (i = 0; i < testspec->nsetupsqls; i++)
 	{
-		res = PQexec(conns[0], testspec->setupsql);
+		res = PQexec(conns[0], testspec->setupsqls[i]);
 		if (PQresultStatus(res) != PGRES_COMMAND_OK)
 		{
 			fprintf(stderr, "setup failed: %s", PQerrorMessage(conns[0]));
diff --git a/src/test/isolation/isolationtester.h b/src/test/isolation/isolationtester.h
index 1f61c6f1275df2d2e0516311eb7ee7e135181401..4c986bb52334be6bae4c9561d425cb6bf0fdc0ff 100644
--- a/src/test/isolation/isolationtester.h
+++ b/src/test/isolation/isolationtester.h
@@ -42,7 +42,8 @@ typedef struct
 
 typedef struct
 {
-	char	   *setupsql;
+	char	  **setupsqls;
+	int         nsetupsqls;
 	char	   *teardownsql;
 	Session   **sessions;
 	int			nsessions;
diff --git a/src/test/isolation/specparse.y b/src/test/isolation/specparse.y
index 9d2b1a277f03a5e2ddc05b4c5dc408f961bb12bf..bf3a9f3b5058c4c08b06870b39e4bc9fa458b205 100644
--- a/src/test/isolation/specparse.y
+++ b/src/test/isolation/specparse.y
@@ -35,7 +35,9 @@ TestSpec		parseresult;			/* result of parsing is left here */
 	}			ptr_list;
 }
 
+%type <ptr_list> setup_list
 %type <str>  opt_setup opt_teardown
+%type <str> setup
 %type <ptr_list> step_list session_list permutation_list opt_permutation_list
 %type <ptr_list> string_list
 %type <session> session
@@ -48,12 +50,13 @@ TestSpec		parseresult;			/* result of parsing is left here */
 %%
 
 TestSpec:
-			opt_setup
+			setup_list
 			opt_teardown
 			session_list
 			opt_permutation_list
 			{
-				parseresult.setupsql = $1;
+				parseresult.setupsqls = (char **) $1.elements;
+				parseresult.nsetupsqls = $1.nelements;
 				parseresult.teardownsql = $2;
 				parseresult.sessions = (Session **) $3.elements;
 				parseresult.nsessions = $3.nelements;
@@ -62,9 +65,28 @@ TestSpec:
 			}
 		;
 
+setup_list:
+			/* EMPTY */
+			{
+				$$.elements = NULL;
+				$$.nelements = 0;
+			}
+			| setup_list setup
+			{
+				$$.elements = realloc($1.elements,
+									  ($1.nelements + 1) * sizeof(void *));
+				$$.elements[$1.nelements] = $2;
+				$$.nelements = $1.nelements + 1;
+			}
+		;
+
 opt_setup:
 			/* EMPTY */			{ $$ = NULL; }
-			| SETUP sqlblock	{ $$ = $2; }
+			| setup				{ $$ = $1; }
+		;
+
+setup:
+			SETUP sqlblock		{ $$ = $2; }
 		;
 
 opt_teardown: