mirror of
https://github.com/FirebirdSQL/firebird.git
synced 2025-01-23 22:43:04 +01:00
Backported fix for CORE-1657: AV with long inactive read-only read-commited transaction
This commit is contained in:
parent
c73581bddc
commit
b531d60e80
@ -391,16 +391,16 @@ static ULONG cache_transactions(thread_db* tdbb, TxPageCache** tip_cache_ptr,
|
|||||||
|
|
||||||
#ifdef SUPERSERVER_V2
|
#ifdef SUPERSERVER_V2
|
||||||
const ULONG top = dbb->dbb_next_transaction;
|
const ULONG top = dbb->dbb_next_transaction;
|
||||||
oldest = MAX(oldest, dbb->dbb_oldest_transaction);
|
const ULONG hdr_oldest = dbb->dbb_oldest_transaction;
|
||||||
#else
|
#else
|
||||||
WIN window(HEADER_PAGE);
|
WIN window(HEADER_PAGE);
|
||||||
const Ods::header_page* header =
|
const Ods::header_page* header =
|
||||||
(Ods::header_page*) CCH_FETCH(tdbb, &window, LCK_read, pag_header);
|
(Ods::header_page*) CCH_FETCH(tdbb, &window, LCK_read, pag_header);
|
||||||
const ULONG top = header->hdr_next_transaction;
|
const ULONG top = header->hdr_next_transaction;
|
||||||
const ULONG hdr_oldest = (ULONG) header->hdr_oldest_transaction;
|
const ULONG hdr_oldest = (ULONG) header->hdr_oldest_transaction;
|
||||||
oldest = MAX(oldest, hdr_oldest);
|
|
||||||
CCH_RELEASE(tdbb, &window);
|
CCH_RELEASE(tdbb, &window);
|
||||||
#endif
|
#endif
|
||||||
|
oldest = MAX(oldest, hdr_oldest);
|
||||||
|
|
||||||
/* allocate TxPageCache blocks to hold all transaction states --
|
/* allocate TxPageCache blocks to hold all transaction states --
|
||||||
assign one TxPageCache block per page to simplify cache maintenance */
|
assign one TxPageCache block per page to simplify cache maintenance */
|
||||||
@ -421,11 +421,23 @@ static ULONG cache_transactions(thread_db* tdbb, TxPageCache** tip_cache_ptr,
|
|||||||
|
|
||||||
TRA_get_inventory(tdbb, NULL, oldest, top);
|
TRA_get_inventory(tdbb, NULL, oldest, top);
|
||||||
|
|
||||||
#ifdef SUPERSERVER_V2
|
// hvlad: cache_transactions returns number of oldest transaction
|
||||||
return dbb->dbb_oldest_transaction;
|
// just refreshed from header page. No need to cache TIP pages below it
|
||||||
#else
|
// Moreover out tip cache can now contain an gap between last
|
||||||
|
// cached tip page and new pages if our process was idle for long time
|
||||||
|
|
||||||
|
for (TxPageCache* tip_cache = dbb->dbb_tip_cache;
|
||||||
|
tip_cache && (tip_cache->tpc_base + trans_per_tip < hdr_oldest);
|
||||||
|
tip_cache = dbb->dbb_tip_cache)
|
||||||
|
{
|
||||||
|
dbb->dbb_tip_cache = tip_cache->tpc_next;
|
||||||
|
|
||||||
|
// hvlad: commented out in 2.0 release branch, enabled and required
|
||||||
|
// additional testing in 2.1
|
||||||
|
// delete tip_cache;
|
||||||
|
}
|
||||||
|
|
||||||
return hdr_oldest;
|
return hdr_oldest;
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -461,23 +473,6 @@ static int extend_cache(thread_db* tdbb, SLONG number)
|
|||||||
|
|
||||||
const ULONG oldest = cache_transactions(tdbb, tip_cache_ptr,
|
const ULONG oldest = cache_transactions(tdbb, tip_cache_ptr,
|
||||||
tip_cache->tpc_base + trans_per_tip);
|
tip_cache->tpc_base + trans_per_tip);
|
||||||
|
|
||||||
// hvlad: cache_transactions returns number of oldest transaction
|
|
||||||
// just refreshed from header page. No need to cache TIP pages below it
|
|
||||||
// Moreover out tip cache can now contain an gap between last
|
|
||||||
// cached tip page and new pages if our process was idle for long time
|
|
||||||
|
|
||||||
for (tip_cache = dbb->dbb_tip_cache;
|
|
||||||
tip_cache && (tip_cache->tpc_base + trans_per_tip < oldest);
|
|
||||||
tip_cache = dbb->dbb_tip_cache)
|
|
||||||
{
|
|
||||||
dbb->dbb_tip_cache = tip_cache->tpc_next;
|
|
||||||
|
|
||||||
// hvlad: commented out in 2.0 release branch, enabled and required
|
|
||||||
// additional testing in 2.1
|
|
||||||
// delete tip_cache;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (number < oldest)
|
if (number < oldest)
|
||||||
return tra_committed;
|
return tra_committed;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user