Skip to content

Commit a108a04

Browse files
committed
Move check if just created TPB block become outdated during its creation into more generic place.
Add check against CN_ACTIVE state got from obsolete re-created TPC block.
1 parent b3c9665 commit a108a04

1 file changed

Lines changed: 31 additions & 12 deletions

File tree

src/jrd/tpc.cpp

Lines changed: 31 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -215,17 +215,6 @@ CommitNumber TipCache::cacheState(TraNumber number)
215215
if (!block)
216216
return CN_PREHISTORIC;
217217

218-
// Check if the block is not obsolete at the moment
219-
oldest = header->oldest_transaction.load(std::memory_order_relaxed);
220-
221-
if (number < oldest)
222-
{
223-
gds__log("Re-created obsolete TPC block %u. For transaction %" UQUADFORMAT ", oldest %." UQUADFORMAT,
224-
blockNumber, number, oldest);
225-
226-
return CN_PREHISTORIC;
227-
}
228-
229218
// Barrier is not needed here when we are reading state from cache
230219
// because all callers of this function are prepared to handle
231220
// slightly out-dated information and will take slow path if necessary
@@ -540,9 +529,32 @@ TipCache::TransactionStatusBlock* TipCache::getTransactionStatusBlock(GlobalTpcH
540529
else
541530
{
542531
// Check if block might be too old to be created.
543-
TraNumber oldest = header->oldest_transaction.load(std::memory_order_relaxed);
532+
const TraNumber oldest = header->oldest_transaction.load(std::memory_order_relaxed);
544533
if (blockNumber >= oldest / m_transactionsPerBlock)
534+
{
545535
block = createTransactionStatusBlock(header->tpc_block_size, blockNumber);
536+
537+
// Check if the block is not obsolete at the moment
538+
const TraNumber oldest2 = header->oldest_transaction.load(std::memory_order_relaxed);
539+
540+
if (blockNumber < oldest2 / m_transactionsPerBlock)
541+
{
542+
gds__log("TPC: Re-created obsolete block %u. Oldest before %" UQUADFORMAT " (%u), oldest after %" UQUADFORMAT " (%u)",
543+
blockNumber,
544+
oldest, oldest / m_transactionsPerBlock,
545+
oldest2, oldest2 / m_transactionsPerBlock);
546+
547+
if (m_blocks_memory.locate(blockNumber))
548+
{
549+
auto data = m_blocks_memory.current();
550+
m_blocks_memory.fastRemove();
551+
delete data;
552+
}
553+
554+
sync.unlock();
555+
return nullptr;
556+
}
557+
}
546558
else
547559
sync.unlock();
548560
}
@@ -652,6 +664,13 @@ CommitNumber TipCache::setState(TraNumber number, int state)
652664
// We verified for all other cases, transaction must either be Active or in Limbo
653665
fb_assert(oldStateCn == CN_ACTIVE || oldStateCn == CN_LIMBO);
654666

667+
// Paranoid check against CN_ACTIVE state got from obsolete re-created TPC block.
668+
if ((oldStateCn == CN_ACTIVE) && (number < header->oldest_transaction.load(std::memory_order_relaxed)))
669+
{
670+
gds__log("TPC: Not generated new CN for old committed transaction %" UQUADFORMAT, number);
671+
return CN_PREHISTORIC;
672+
}
673+
655674
// Generate new commit number
656675
CommitNumber newCommitNumber = header->latest_commit_number++ + 1;
657676

0 commit comments

Comments
 (0)