8
0
mirror of https://github.com/FirebirdSQL/firebird.git synced 2025-01-23 18:03:04 +01:00

Improvement CORE-3536 : Garbage collection in GTT is unnecessary delayed by active transactions in another attachments

This commit is contained in:
hvlad 2011-06-24 12:49:08 +00:00
parent 7c68e15a0f
commit f2aaa12ce5
4 changed files with 39 additions and 11 deletions

View File

@ -229,6 +229,7 @@ public:
UserId* att_user; // User identification
jrd_tra* att_transactions; // Transactions belonging to attachment
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:
jrd_tra* att_sys_transaction; // system transaction

View File

@ -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)
// in the new transaction's lock.
// hvlad: for read-committed transaction put tra_number to prevent

View File

@ -232,6 +232,7 @@ public:
SLONG tra_oldest; // oldest interesting transaction
SLONG tra_oldest_active; // record versions older than this can be
// 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_sibling; // next transaction in group
MemoryPool* const tra_pool; // pool for transaction

View File

@ -546,9 +546,12 @@ bool VIO_chase_record_version(thread_db* tdbb, record_param* rpb,
*
**************************************/
SET_TDBB(tdbb);
Jrd::Attachment* attachment = transaction->tra_attachment;
const bool gcPolicyCooperative = tdbb->getDatabase()->dbb_flags & DBB_gc_cooperative;
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
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 &&
!(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)
notify_garbage_collector(tdbb, rpb);
@ -625,8 +628,6 @@ bool VIO_chase_record_version(thread_db* tdbb, record_param* rpb,
return true;
}
Jrd::Attachment* attachment = transaction->tra_attachment;
// 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
// garbage collection that seems appropriate.
@ -976,7 +977,7 @@ bool VIO_chase_record_version(thread_db* tdbb, record_param* rpb,
#endif
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))
{
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.
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;
if (cannotGC)
@ -1732,6 +1733,7 @@ bool VIO_garbage_collect(thread_db* tdbb, record_param* rpb, const jrd_tra* tran
*
**************************************/
SET_TDBB(tdbb);
Jrd::Attachment* attachment = transaction->tra_attachment;
#ifdef VIO_DEBUG
if (debug_flag > DEBUG_TRACE)
@ -1750,10 +1752,13 @@ bool VIO_garbage_collect(thread_db* tdbb, record_param* rpb, const jrd_tra* tran
}
#endif
if (transaction->tra_attachment->att_flags & ATT_no_cleanup) {
if (attachment->att_flags & ATT_no_cleanup) {
return true;
}
const SLONG oldest_snapshot =
rpb->rpb_relation->isTemporary() ? attachment->att_oldest_snapshot : transaction->tra_oldest_active;
while (true)
{
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_transaction_nr >= transaction->tra_oldest_active)
if (rpb->rpb_transaction_nr >= oldest_snapshot)
{
return true;
}
@ -1810,7 +1815,7 @@ bool VIO_garbage_collect(thread_db* tdbb, record_param* rpb, const jrd_tra* tran
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;
}
@ -3633,7 +3638,7 @@ static int check_precommitted(const jrd_tra* transaction, const record_param* rp
* Functional description
* Check if precommitted transaction which created given record version is
* 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.
*
**************************************/
@ -3981,6 +3986,7 @@ static void expunge(thread_db* tdbb, record_param* rpb, const jrd_tra* transacti
*
**************************************/
SET_TDBB(tdbb);
Jrd::Attachment* attachment = transaction->tra_attachment;
#ifdef VIO_DEBUG
if (debug_flag > DEBUG_WRITES)
@ -3992,7 +3998,7 @@ static void expunge(thread_db* tdbb, record_param* rpb, const jrd_tra* transacti
}
#endif
if (transaction->tra_attachment->att_flags & ATT_no_cleanup) {
if (attachment->att_flags & ATT_no_cleanup) {
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.
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