Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit 1c7675a

Browse files
committed
Fix wrong data table horizon computation during backend startup.
When ComputeXidHorizons() was called before MyDatabaseOid is set, e.g. because a dead row in a shared relation is encountered during InitPostgres(), the horizon for normal tables was computed too aggressively, ignoring all backends connected to a database. During subsequent pruning in a data table the too aggressive horizon could end up still being used, possibly leading to still needed tuples being removed. Not good. This is a bug in dc7420c, which the test added in 94bc27b made visible, if run with force_parallel_mode set to regress. In that case the bug is reliably triggered, because "pruning_query" is run in a parallel worker and the start of that parallel worker is likely to encounter a dead row in pg_database. The fix is trivial: Compute a more pessimistic data table horizon if MyDatabaseId is not yet known. Author: Andres Freund Discussion: https://postgr.es/m/20201029040030.p4osrmaywhqaesd4@alap3.anarazel.de
1 parent 8e90ec5 commit 1c7675a

File tree

1 file changed

+8
-1
lines changed

1 file changed

+8
-1
lines changed

src/backend/storage/ipc/procarray.c

+8-1
Original file line numberDiff line numberDiff line change
@@ -1757,9 +1757,16 @@ ComputeXidHorizons(ComputeXidHorizonsResult *h)
17571757
* the shared horizon. But in recovery we cannot compute an accurate
17581758
* per-database horizon as all xids are managed via the
17591759
* KnownAssignedXids machinery.
1760+
*
1761+
* Be careful to compute a pessimistic value when MyDatabaseId is not
1762+
* set. If this is a backend in the process of starting up, we may not
1763+
* use a "too aggressive" horizon (otherwise we could end up using it
1764+
* to prune still needed data away). If the current backend never
1765+
* connects to a database that is harmless, because
1766+
* data_oldest_nonremovable will never be utilized.
17601767
*/
17611768
if (in_recovery ||
1762-
proc->databaseId == MyDatabaseId ||
1769+
MyDatabaseId == InvalidOid || proc->databaseId == MyDatabaseId ||
17631770
proc->databaseId == 0) /* always include WalSender */
17641771
{
17651772
h->data_oldest_nonremovable =

0 commit comments

Comments
 (0)