@@ -1610,7 +1610,13 @@ TransactionIdIsActive(TransactionId xid)
1610
1610
* relations that's not required, since only backends in my own database could
1611
1611
* ever see the tuples in them. Also, we can ignore concurrently running lazy
1612
1612
* VACUUMs because (a) they must be working on other tables, and (b) they
1613
- * don't need to do snapshot-based lookups.
1613
+ * don't need to do snapshot-based lookups. Similarly, for the non-catalog
1614
+ * horizon, we can ignore CREATE INDEX CONCURRENTLY and REINDEX CONCURRENTLY
1615
+ * when they are working on non-partial, non-expressional indexes, for the
1616
+ * same reasons and because they can't run in transaction blocks. (They are
1617
+ * not possible to ignore for catalogs, because CIC and RC do some catalog
1618
+ * operations.) Do note that this means that CIC and RC must use a lock level
1619
+ * that conflicts with VACUUM.
1614
1620
*
1615
1621
* This also computes a horizon used to truncate pg_subtrans. For that
1616
1622
* backends in all databases have to be considered, and concurrently running
@@ -1660,9 +1666,6 @@ ComputeXidHorizons(ComputeXidHorizonsResult *h)
1660
1666
bool in_recovery = RecoveryInProgress ();
1661
1667
TransactionId * other_xids = ProcGlobal -> xids ;
1662
1668
1663
- /* inferred after ProcArrayLock is released */
1664
- h -> catalog_oldest_nonremovable = InvalidTransactionId ;
1665
-
1666
1669
LWLockAcquire (ProcArrayLock , LW_SHARED );
1667
1670
1668
1671
h -> latest_completed = ShmemVariableCache -> latestCompletedXid ;
@@ -1682,6 +1685,7 @@ ComputeXidHorizons(ComputeXidHorizonsResult *h)
1682
1685
1683
1686
h -> oldest_considered_running = initial ;
1684
1687
h -> shared_oldest_nonremovable = initial ;
1688
+ h -> catalog_oldest_nonremovable = initial ;
1685
1689
h -> data_oldest_nonremovable = initial ;
1686
1690
1687
1691
/*
@@ -1752,7 +1756,7 @@ ComputeXidHorizons(ComputeXidHorizonsResult *h)
1752
1756
if (statusFlags & (PROC_IN_VACUUM | PROC_IN_LOGICAL_DECODING ))
1753
1757
continue ;
1754
1758
1755
- /* shared tables need to take backends in all database into account */
1759
+ /* shared tables need to take backends in all databases into account */
1756
1760
h -> shared_oldest_nonremovable =
1757
1761
TransactionIdOlder (h -> shared_oldest_nonremovable , xmin );
1758
1762
@@ -1773,11 +1777,26 @@ ComputeXidHorizons(ComputeXidHorizonsResult *h)
1773
1777
MyDatabaseId == InvalidOid || proc -> databaseId == MyDatabaseId ||
1774
1778
proc -> databaseId == 0 ) /* always include WalSender */
1775
1779
{
1776
- h -> data_oldest_nonremovable =
1777
- TransactionIdOlder (h -> data_oldest_nonremovable , xmin );
1780
+ /*
1781
+ * We can ignore this backend if it's running CREATE INDEX
1782
+ * CONCURRENTLY or REINDEX CONCURRENTLY on a "safe" index -- but
1783
+ * only on vacuums of user-defined tables.
1784
+ */
1785
+ if (!(statusFlags & PROC_IN_SAFE_IC ))
1786
+ h -> data_oldest_nonremovable =
1787
+ TransactionIdOlder (h -> data_oldest_nonremovable , xmin );
1788
+
1789
+ /* Catalog tables need to consider all backends in this db */
1790
+ h -> catalog_oldest_nonremovable =
1791
+ TransactionIdOlder (h -> catalog_oldest_nonremovable , xmin );
1792
+
1778
1793
}
1779
1794
}
1780
1795
1796
+ /* catalog horizon should never be later than data */
1797
+ Assert (TransactionIdPrecedesOrEquals (h -> catalog_oldest_nonremovable ,
1798
+ h -> data_oldest_nonremovable ));
1799
+
1781
1800
/*
1782
1801
* If in recovery fetch oldest xid in KnownAssignedXids, will be applied
1783
1802
* after lock is released.
@@ -1799,6 +1818,8 @@ ComputeXidHorizons(ComputeXidHorizonsResult *h)
1799
1818
TransactionIdOlder (h -> shared_oldest_nonremovable , kaxmin );
1800
1819
h -> data_oldest_nonremovable =
1801
1820
TransactionIdOlder (h -> data_oldest_nonremovable , kaxmin );
1821
+ h -> catalog_oldest_nonremovable =
1822
+ TransactionIdOlder (h -> catalog_oldest_nonremovable , kaxmin );
1802
1823
/* temp relations cannot be accessed in recovery */
1803
1824
}
1804
1825
else
@@ -1825,6 +1846,9 @@ ComputeXidHorizons(ComputeXidHorizonsResult *h)
1825
1846
h -> data_oldest_nonremovable =
1826
1847
TransactionIdRetreatedBy (h -> data_oldest_nonremovable ,
1827
1848
vacuum_defer_cleanup_age );
1849
+ h -> catalog_oldest_nonremovable =
1850
+ TransactionIdRetreatedBy (h -> catalog_oldest_nonremovable ,
1851
+ vacuum_defer_cleanup_age );
1828
1852
/* defer doesn't apply to temp relations */
1829
1853
}
1830
1854
@@ -1847,7 +1871,9 @@ ComputeXidHorizons(ComputeXidHorizonsResult *h)
1847
1871
h -> shared_oldest_nonremovable =
1848
1872
TransactionIdOlder (h -> shared_oldest_nonremovable ,
1849
1873
h -> slot_catalog_xmin );
1850
- h -> catalog_oldest_nonremovable = h -> data_oldest_nonremovable ;
1874
+ h -> catalog_oldest_nonremovable =
1875
+ TransactionIdOlder (h -> catalog_oldest_nonremovable ,
1876
+ h -> slot_xmin );
1851
1877
h -> catalog_oldest_nonremovable =
1852
1878
TransactionIdOlder (h -> catalog_oldest_nonremovable ,
1853
1879
h -> slot_catalog_xmin );
0 commit comments