mirror of
https://github.com/FirebirdSQL/firebird.git
synced 2025-01-23 22:03:03 +01:00
Improvement CORE-3536 : Garbage collection in GTT is unnecessary delayed by active transactions in another attachments
This commit is contained in:
parent
7c68e15a0f
commit
f2aaa12ce5
@ -229,6 +229,7 @@ public:
|
|||||||
UserId* att_user; // User identification
|
UserId* att_user; // User identification
|
||||||
jrd_tra* att_transactions; // Transactions belonging to attachment
|
jrd_tra* att_transactions; // Transactions belonging to attachment
|
||||||
jrd_tra* att_dbkey_trans; // transaction to control db-key scope
|
jrd_tra* att_dbkey_trans; // transaction to control db-key scope
|
||||||
|
SLONG att_oldest_snapshot; // GTT's record versions older than this can be gargage-collected
|
||||||
|
|
||||||
private:
|
private:
|
||||||
jrd_tra* att_sys_transaction; // system transaction
|
jrd_tra* att_sys_transaction; // system transaction
|
||||||
|
@ -3432,6 +3432,23 @@ static jrd_tra* transaction_start(thread_db* tdbb, jrd_tra* temp)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Calculate attachment-local oldest active and oldest snapshot numbers
|
||||||
|
// looking at current attachment's transactions only. Calculated values
|
||||||
|
// are used to determine garbage collection treshold for attachment-local
|
||||||
|
// data such as temporary tables (GTT's).
|
||||||
|
|
||||||
|
trans->tra_att_oldest_active = number;
|
||||||
|
SLONG att_oldest_active = number;
|
||||||
|
SLONG att_oldest_snapshot = number;
|
||||||
|
for (jrd_tra* tx_att = attachment->att_transactions; tx_att; tx_att = tx_att->tra_next)
|
||||||
|
{
|
||||||
|
att_oldest_active = MIN(att_oldest_active, tx_att->tra_number);
|
||||||
|
att_oldest_snapshot = MIN(att_oldest_snapshot, tx_att->tra_att_oldest_active);
|
||||||
|
}
|
||||||
|
trans->tra_att_oldest_active = (trans->tra_flags & TRA_read_committed) ? number : att_oldest_active;
|
||||||
|
if (attachment->att_oldest_snapshot < att_oldest_snapshot)
|
||||||
|
attachment->att_oldest_snapshot = att_oldest_snapshot;
|
||||||
|
|
||||||
// Put the TID of the oldest active transaction (just calculated)
|
// Put the TID of the oldest active transaction (just calculated)
|
||||||
// in the new transaction's lock.
|
// in the new transaction's lock.
|
||||||
// hvlad: for read-committed transaction put tra_number to prevent
|
// hvlad: for read-committed transaction put tra_number to prevent
|
||||||
|
@ -232,6 +232,7 @@ public:
|
|||||||
SLONG tra_oldest; // oldest interesting transaction
|
SLONG tra_oldest; // oldest interesting transaction
|
||||||
SLONG tra_oldest_active; // record versions older than this can be
|
SLONG tra_oldest_active; // record versions older than this can be
|
||||||
// gargage-collected by this tx
|
// gargage-collected by this tx
|
||||||
|
SLONG tra_att_oldest_active; // oldest active transaction in the same attachment
|
||||||
jrd_tra* tra_next; // next transaction in database
|
jrd_tra* tra_next; // next transaction in database
|
||||||
jrd_tra* tra_sibling; // next transaction in group
|
jrd_tra* tra_sibling; // next transaction in group
|
||||||
MemoryPool* const tra_pool; // pool for transaction
|
MemoryPool* const tra_pool; // pool for transaction
|
||||||
|
@ -546,9 +546,12 @@ bool VIO_chase_record_version(thread_db* tdbb, record_param* rpb,
|
|||||||
*
|
*
|
||||||
**************************************/
|
**************************************/
|
||||||
SET_TDBB(tdbb);
|
SET_TDBB(tdbb);
|
||||||
|
Jrd::Attachment* attachment = transaction->tra_attachment;
|
||||||
|
|
||||||
const bool gcPolicyCooperative = tdbb->getDatabase()->dbb_flags & DBB_gc_cooperative;
|
const bool gcPolicyCooperative = tdbb->getDatabase()->dbb_flags & DBB_gc_cooperative;
|
||||||
const bool gcPolicyBackground = tdbb->getDatabase()->dbb_flags & DBB_gc_background;
|
const bool gcPolicyBackground = tdbb->getDatabase()->dbb_flags & DBB_gc_background;
|
||||||
|
const SLONG oldest_snapshot =
|
||||||
|
rpb->rpb_relation->isTemporary() ? attachment->att_oldest_snapshot : transaction->tra_oldest_active;
|
||||||
|
|
||||||
#ifdef VIO_DEBUG
|
#ifdef VIO_DEBUG
|
||||||
if (debug_flag > DEBUG_TRACE_ALL)
|
if (debug_flag > DEBUG_TRACE_ALL)
|
||||||
@ -617,7 +620,7 @@ bool VIO_chase_record_version(thread_db* tdbb, record_param* rpb,
|
|||||||
|
|
||||||
if ((state == tra_committed || state == tra_us) && !forceBack &&
|
if ((state == tra_committed || state == tra_us) && !forceBack &&
|
||||||
!(rpb->rpb_flags & (rpb_deleted | rpb_damaged)) &&
|
!(rpb->rpb_flags & (rpb_deleted | rpb_damaged)) &&
|
||||||
(rpb->rpb_b_page == 0 || rpb->rpb_transaction_nr >= transaction->tra_oldest_active))
|
(rpb->rpb_b_page == 0 || rpb->rpb_transaction_nr >= oldest_snapshot))
|
||||||
{
|
{
|
||||||
if (gcPolicyBackground && rpb->rpb_b_page)
|
if (gcPolicyBackground && rpb->rpb_b_page)
|
||||||
notify_garbage_collector(tdbb, rpb);
|
notify_garbage_collector(tdbb, rpb);
|
||||||
@ -625,8 +628,6 @@ bool VIO_chase_record_version(thread_db* tdbb, record_param* rpb,
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
Jrd::Attachment* attachment = transaction->tra_attachment;
|
|
||||||
|
|
||||||
// OK, something about the record is fishy. Loop thru versions until a
|
// OK, something about the record is fishy. Loop thru versions until a
|
||||||
// satisfactory version is found or we run into a brick wall. Do any
|
// satisfactory version is found or we run into a brick wall. Do any
|
||||||
// garbage collection that seems appropriate.
|
// garbage collection that seems appropriate.
|
||||||
@ -976,7 +977,7 @@ bool VIO_chase_record_version(thread_db* tdbb, record_param* rpb,
|
|||||||
#endif
|
#endif
|
||||||
if (rpb->rpb_flags & rpb_deleted)
|
if (rpb->rpb_flags & rpb_deleted)
|
||||||
{
|
{
|
||||||
if (rpb->rpb_transaction_nr < transaction->tra_oldest_active &&
|
if (rpb->rpb_transaction_nr < oldest_snapshot &&
|
||||||
!(attachment->att_flags & ATT_no_cleanup))
|
!(attachment->att_flags & ATT_no_cleanup))
|
||||||
{
|
{
|
||||||
if (!gcPolicyCooperative && (attachment->att_flags & ATT_notify_gc) &&
|
if (!gcPolicyCooperative && (attachment->att_flags & ATT_notify_gc) &&
|
||||||
@ -1003,7 +1004,7 @@ bool VIO_chase_record_version(thread_db* tdbb, record_param* rpb,
|
|||||||
// That might be the reason for the rpb_chained check.
|
// That might be the reason for the rpb_chained check.
|
||||||
|
|
||||||
const bool cannotGC =
|
const bool cannotGC =
|
||||||
rpb->rpb_transaction_nr >= transaction->tra_oldest_active || rpb->rpb_b_page == 0 ||
|
rpb->rpb_transaction_nr >= oldest_snapshot || rpb->rpb_b_page == 0 ||
|
||||||
rpb->rpb_flags & rpb_chained || attachment->att_flags & ATT_no_cleanup;
|
rpb->rpb_flags & rpb_chained || attachment->att_flags & ATT_no_cleanup;
|
||||||
|
|
||||||
if (cannotGC)
|
if (cannotGC)
|
||||||
@ -1732,6 +1733,7 @@ bool VIO_garbage_collect(thread_db* tdbb, record_param* rpb, const jrd_tra* tran
|
|||||||
*
|
*
|
||||||
**************************************/
|
**************************************/
|
||||||
SET_TDBB(tdbb);
|
SET_TDBB(tdbb);
|
||||||
|
Jrd::Attachment* attachment = transaction->tra_attachment;
|
||||||
|
|
||||||
#ifdef VIO_DEBUG
|
#ifdef VIO_DEBUG
|
||||||
if (debug_flag > DEBUG_TRACE)
|
if (debug_flag > DEBUG_TRACE)
|
||||||
@ -1750,10 +1752,13 @@ bool VIO_garbage_collect(thread_db* tdbb, record_param* rpb, const jrd_tra* tran
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (transaction->tra_attachment->att_flags & ATT_no_cleanup) {
|
if (attachment->att_flags & ATT_no_cleanup) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const SLONG oldest_snapshot =
|
||||||
|
rpb->rpb_relation->isTemporary() ? attachment->att_oldest_snapshot : transaction->tra_oldest_active;
|
||||||
|
|
||||||
while (true)
|
while (true)
|
||||||
{
|
{
|
||||||
if (rpb->rpb_flags & rpb_damaged)
|
if (rpb->rpb_flags & rpb_damaged)
|
||||||
@ -1800,7 +1805,7 @@ bool VIO_garbage_collect(thread_db* tdbb, record_param* rpb, const jrd_tra* tran
|
|||||||
{
|
{
|
||||||
if (rpb->rpb_flags & rpb_deleted)
|
if (rpb->rpb_flags & rpb_deleted)
|
||||||
{
|
{
|
||||||
if (rpb->rpb_transaction_nr >= transaction->tra_oldest_active)
|
if (rpb->rpb_transaction_nr >= oldest_snapshot)
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -1810,7 +1815,7 @@ bool VIO_garbage_collect(thread_db* tdbb, record_param* rpb, const jrd_tra* tran
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (rpb->rpb_transaction_nr >= transaction->tra_oldest_active || rpb->rpb_b_page == 0)
|
if (rpb->rpb_transaction_nr >= oldest_snapshot || rpb->rpb_b_page == 0)
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -3633,7 +3638,7 @@ static int check_precommitted(const jrd_tra* transaction, const record_param* rp
|
|||||||
* Functional description
|
* Functional description
|
||||||
* Check if precommitted transaction which created given record version is
|
* Check if precommitted transaction which created given record version is
|
||||||
* current transaction or it is a still active and belongs to the current
|
* current transaction or it is a still active and belongs to the current
|
||||||
* attachment. This is needed to detect visibility of records modified by
|
* attachment. This is needed to detect visibility of records modified in
|
||||||
* temporary tables in read-only transactions.
|
* temporary tables in read-only transactions.
|
||||||
*
|
*
|
||||||
**************************************/
|
**************************************/
|
||||||
@ -3981,6 +3986,7 @@ static void expunge(thread_db* tdbb, record_param* rpb, const jrd_tra* transacti
|
|||||||
*
|
*
|
||||||
**************************************/
|
**************************************/
|
||||||
SET_TDBB(tdbb);
|
SET_TDBB(tdbb);
|
||||||
|
Jrd::Attachment* attachment = transaction->tra_attachment;
|
||||||
|
|
||||||
#ifdef VIO_DEBUG
|
#ifdef VIO_DEBUG
|
||||||
if (debug_flag > DEBUG_WRITES)
|
if (debug_flag > DEBUG_WRITES)
|
||||||
@ -3992,7 +3998,7 @@ static void expunge(thread_db* tdbb, record_param* rpb, const jrd_tra* transacti
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (transaction->tra_attachment->att_flags & ATT_no_cleanup) {
|
if (attachment->att_flags & ATT_no_cleanup) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -4021,7 +4027,10 @@ static void expunge(thread_db* tdbb, record_param* rpb, const jrd_tra* transacti
|
|||||||
|
|
||||||
// Make sure it looks kosher and delete the record.
|
// Make sure it looks kosher and delete the record.
|
||||||
|
|
||||||
if (!(rpb->rpb_flags & rpb_deleted) || rpb->rpb_transaction_nr >= transaction->tra_oldest_active)
|
const SLONG oldest_snapshot =
|
||||||
|
rpb->rpb_relation->isTemporary() ? attachment->att_oldest_snapshot : transaction->tra_oldest_active;
|
||||||
|
|
||||||
|
if (!(rpb->rpb_flags & rpb_deleted) || rpb->rpb_transaction_nr >= oldest_snapshot)
|
||||||
{
|
{
|
||||||
|
|
||||||
// expunge
|
// expunge
|
||||||
|
Loading…
Reference in New Issue
Block a user