Skip to content

Commit f7f1c57

Browse files
author
Konstantin Knizhnik
committed
Fix incorrect calls of SetLastWrittenLSNForBlockRangeInternal with shared lock
1 parent 89d27dc commit f7f1c57

File tree

1 file changed

+21
-3
lines changed
  • src/backend/access/transam

1 file changed

+21
-3
lines changed

src/backend/access/transam/xlog.c

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6711,6 +6711,8 @@ GetLastWrittenLSN(RelFileLocator rlocator, ForkNumber forknum, BlockNumber blkno
67116711
lsn = entry->lsn;
67126712
else
67136713
{
6714+
LWLockRelease(LastWrittenLsnLock);
6715+
LWLockAcquire(LastWrittenLsnLock, LW_EXCLUSIVE);
67146716
/*
67156717
* In case of statements CREATE TABLE AS SELECT... or INSERT FROM SELECT... we are fetching data from source table
67166718
* and storing it in destination table. It cause problems with prefetch last-written-lsn is known for the pages of
@@ -6764,6 +6766,7 @@ GetLastWrittenLSNv(RelFileLocator relfilenode, ForkNumber forknum,
67646766
if (relfilenode.relNumber != InvalidOid)
67656767
{
67666768
BufferTag key;
6769+
bool missed_keys = false;
67676770

67686771
key.spcOid = relfilenode.spcOid;
67696772
key.dbOid = relfilenode.dbOid;
@@ -6776,22 +6779,37 @@ GetLastWrittenLSNv(RelFileLocator relfilenode, ForkNumber forknum,
67766779
key.blockNum = blkno + i;
67776780

67786781
entry = hash_search(lastWrittenLsnCache, &key, HASH_FIND, NULL);
6779-
67806782
if (entry != NULL)
67816783
{
67826784
lsns[i] = entry->lsn;
67836785
}
67846786
else
67856787
{
6786-
lsns[i] = lsn;
6787-
SetLastWrittenLSNForBlockRangeInternal(lsn, relfilenode, forknum, key.blockNum, 1);
6788+
lsns[i] = InvalidXLogRecPtr;
6789+
missed_keys = true;
6790+
}
6791+
}
6792+
if (missed_keys)
6793+
{
6794+
LWLockRelease(LastWrittenLsnLock);
6795+
LWLockAcquire(LastWrittenLsnLock, LW_EXCLUSIVE);
6796+
6797+
lsn = XLogCtl->maxLastWrittenLsn;
6798+
6799+
for (int i = 0; i < nblocks; i++)
6800+
{
6801+
if (lsns[i] == InvalidXLogRecPtr)
6802+
{
6803+
SetLastWrittenLSNForBlockRangeInternal(lsn, relfilenode, forknum, key.blockNum, 1);
6804+
}
67886805
}
67896806
}
67906807
}
67916808
else
67926809
{
67936810
HASH_SEQ_STATUS seq;
67946811

6812+
lsn = XLogCtl->maxLastWrittenLsn;
67956813
/* Find maximum of all cached LSNs */
67966814
hash_seq_init(&seq, lastWrittenLsnCache);
67976815
while ((entry = (LastWrittenLsnCacheEntry *) hash_seq_search(&seq)) != NULL)

0 commit comments

Comments
 (0)