diff options
| -rw-r--r-- | src/backend/commands/sequence.c | 16 | 
1 files changed, 16 insertions, 0 deletions
| diff --git a/src/backend/commands/sequence.c b/src/backend/commands/sequence.c index 292a4274493..adeb0d52d48 100644 --- a/src/backend/commands/sequence.c +++ b/src/backend/commands/sequence.c @@ -982,6 +982,22 @@ read_info(SeqTable elm, Relation rel, Buffer *buf)  	Assert(ItemIdIsNormal(lp));  	tuple.t_data = (HeapTupleHeader) PageGetItem(page, lp); +	/* +	 * Previous releases of Postgres neglected to prevent SELECT FOR UPDATE +	 * on a sequence, which would leave a non-frozen XID in the sequence +	 * tuple's xmax, which eventually leads to clog access failures or worse. +	 * If we see this has happened, clean up after it.  We treat this like a +	 * hint bit update, ie, don't bother to WAL-log it, since we can certainly +	 * do this again if the update gets lost. +	 */ +	if (HeapTupleHeaderGetXmax(tuple.t_data) != InvalidTransactionId) +	{ +		HeapTupleHeaderSetXmax(tuple.t_data, InvalidTransactionId); +		tuple.t_data->t_infomask &= ~HEAP_XMAX_COMMITTED; +		tuple.t_data->t_infomask |= HEAP_XMAX_INVALID; +		SetBufferCommitInfoNeedsSave(*buf); +	} +  	seq = (Form_pg_sequence) GETSTRUCT(&tuple);  	/* this is a handy place to update our copy of the increment */ | 
