@@ -507,6 +507,10 @@ repack_one_table(const repack_table *table, const char *orderby)
507
507
*/
508
508
elog (DEBUG2 , "---- copy tuples ----" );
509
509
510
+ /* Must use SERIALIZABLE (or at least not READ COMMITTED) to avoid race
511
+ * condition between the create_table statement and rows subsequently
512
+ * being added to the log.
513
+ */
510
514
command ("BEGIN ISOLATION LEVEL SERIALIZABLE" , 0 , NULL );
511
515
/* SET work_mem = maintenance_work_mem */
512
516
command ("SELECT set_config('work_mem', current_setting('maintenance_work_mem'), true)" , 0 , NULL );
@@ -515,6 +519,12 @@ repack_one_table(const repack_table *table, const char *orderby)
515
519
res = execute (SQL_XID_SNAPSHOT , 0 , NULL );
516
520
vxid = strdup (PQgetvalue (res , 0 , 0 ));
517
521
PQclear (res );
522
+
523
+ /* Delete any existing entries in the log table now, since we have not
524
+ * yet run the CREATE TABLE ... AS SELECT, which will take in all existing
525
+ * rows from the target table; if we also included prior rows from the
526
+ * log we could wind up with duplicates.
527
+ */
518
528
command (table -> delete_log , 0 , NULL );
519
529
command (table -> create_table , 0 , NULL );
520
530
printfStringInfo (& sql , "SELECT repack.disable_autovacuum('repack.table_%u')" , table -> target_oid );
0 commit comments