@@ -164,7 +164,10 @@ prepare_new_cluster(migratorContext *ctx)
164164check_ok (ctx );
165165
166166/*
167- * We do freeze after analyze so pg_statistic is also frozen
167+ * We do freeze after analyze so pg_statistic is also frozen.
168+ * template0 is not frozen here, but data rows were frozen by initdb,
169+ * and we set its datfrozenxid and relfrozenxids later to match the
170+ * new xid counter later.
168171 */
169172prep_status (ctx ,"Freezing all rows on the new cluster" );
170173exec_prog (ctx , true,
@@ -292,48 +295,72 @@ void
292295set_frozenxids (migratorContext * ctx )
293296{
294297int dbnum ;
295- PGconn * conn ;
298+ PGconn * conn , * conn_template1 ;
296299PGresult * dbres ;
297300int ntups ;
301+ int i_datname ;
302+ int i_datallowconn ;
298303
299304prep_status (ctx ,"Setting frozenxid counters in new cluster" );
300305
301- conn = connectToServer (ctx ,"template1" ,CLUSTER_NEW );
306+ conn_template1 = connectToServer (ctx ,"template1" ,CLUSTER_NEW );
302307
303308/* set pg_database.datfrozenxid */
304- PQclear (executeQueryOrDie (ctx ,conn ,
309+ PQclear (executeQueryOrDie (ctx ,conn_template1 ,
305310"UPDATE pg_catalog.pg_database "
306- "SETdatfrozenxid = '%u' "
307- "WHERE datallowconn = true" ,
311+ "SETdatfrozenxid = '%u'" ,
308312ctx -> old .controldata .chkpnt_nxtxid ));
309313
310314/* get database names */
311- dbres = executeQueryOrDie (ctx ,conn ,
312- "SELECTdatname "
313- "FROMpg_catalog.pg_database "
314- "WHERE datallowconn = true" );
315+ dbres = executeQueryOrDie (ctx ,conn_template1 ,
316+ "SELECTdatname, datallowconn "
317+ "FROMpg_catalog.pg_database" );
315318
316- /* free dbres below */
317- PQfinish ( conn );
319+ i_datname = PQfnumber ( dbres , "datname" );
320+ i_datallowconn = PQfnumber ( dbres , "datallowconn" );
318321
319322ntups = PQntuples (dbres );
320323for (dbnum = 0 ;dbnum < ntups ;dbnum ++ )
321324{
322- conn = connectToServer (ctx ,PQgetvalue (dbres ,dbnum ,0 ),CLUSTER_NEW );
325+ char * datname = PQgetvalue (dbres ,dbnum ,i_datname );
326+ char * datallowconn = PQgetvalue (dbres ,dbnum ,i_datallowconn );
327+
328+ /*
329+ *We must update databases where datallowconn = false, e.g.
330+ *template0, because autovacuum increments their datfrozenxids and
331+ *relfrozenxids even if autovacuum is turned off, and even though
332+ *all the data rows are already frozen To enable this, we
333+ *temporarily change datallowconn.
334+ */
335+ if (strcmp (datallowconn ,"f" )== 0 )
336+ PQclear (executeQueryOrDie (ctx ,conn_template1 ,
337+ "UPDATE pg_catalog.pg_database "
338+ "SETdatallowconn = true "
339+ "WHERE datname = '%s'" ,datname ));
340+
341+ conn = connectToServer (ctx ,datname ,CLUSTER_NEW );
323342
324343/* set pg_class.relfrozenxid */
325344PQclear (executeQueryOrDie (ctx ,conn ,
326345"UPDATEpg_catalog.pg_class "
327346"SETrelfrozenxid = '%u' "
328347/* only heap and TOAST are vacuumed */
329- "WHERErelkind = 'r' OR "
330- "relkind = 't'" ,
348+ "WHERErelkind IN ('r', 't')" ,
331349ctx -> old .controldata .chkpnt_nxtxid ));
332350PQfinish (conn );
351+
352+ /* Reset datallowconn flag */
353+ if (strcmp (datallowconn ,"f" )== 0 )
354+ PQclear (executeQueryOrDie (ctx ,conn_template1 ,
355+ "UPDATE pg_catalog.pg_database "
356+ "SETdatallowconn = false "
357+ "WHERE datname = '%s'" ,datname ));
333358}
334359
335360PQclear (dbres );
336361
362+ PQfinish (conn_template1 );
363+
337364check_ok (ctx );
338365}
339366