From 23a55f0b452d280dcf2edc82844a9329da7de5fd Mon Sep 17 00:00:00 2001 From: hvlad Date: Tue, 3 Jan 2017 18:42:32 +0200 Subject: [PATCH] Improvement CORE-5434 : Read-only transactions in SuperServer could avoid immediate write of Header and TIP pages after change --- src/jrd/tra.cpp | 32 +++++++++++++++++++++++++------- 1 file changed, 25 insertions(+), 7 deletions(-) diff --git a/src/jrd/tra.cpp b/src/jrd/tra.cpp index 109c3f34cd..ea8fd2359c 100644 --- a/src/jrd/tra.cpp +++ b/src/jrd/tra.cpp @@ -89,7 +89,7 @@ typedef Firebird::GenericMap > #ifdef SUPERSERVER_V2 static TraNumber bump_transaction_id(thread_db*, WIN*); #else -static header_page* bump_transaction_id(thread_db*, WIN*); +static header_page* bump_transaction_id(thread_db*, WIN*, bool); #endif static void retain_context(thread_db* tdbb, jrd_tra* transaction, bool commit, int state); static void expand_view_lock(thread_db* tdbb, jrd_tra*, jrd_rel*, UCHAR lock_type, @@ -1445,16 +1445,24 @@ void TRA_set_state(thread_db* tdbb, jrd_tra* transaction, TraNumber number, int WIN window(DB_PAGE_SPACE, -1); tx_inv_page* tip = fetch_inventory_page(tdbb, &window, sequence, LCK_write); + UCHAR* address = tip->tip_transactions + byte; + const int old_state = ((*address) >> shift) & TRA_MASK; + #ifdef SUPERSERVER_V2 CCH_MARK(tdbb, &window); const ULONG generation = tip->tip_header.pag_generation; #else - CCH_MARK_MUST_WRITE(tdbb, &window); + if (!(dbb->dbb_flags & DBB_shared) || transaction->tra_flags & TRA_write || + old_state != tra_active || state != tra_committed) + { + CCH_MARK_MUST_WRITE(tdbb, &window); + } + else + CCH_MARK(tdbb, &window); #endif // set the state on the TIP page - UCHAR* address = tip->tip_transactions + byte; *address &= ~(TRA_MASK << shift); *address |= state << shift; @@ -1944,7 +1952,7 @@ static TraNumber bump_transaction_id(thread_db* tdbb, WIN* window) #else -static header_page* bump_transaction_id(thread_db* tdbb, WIN* window) +static header_page* bump_transaction_id(thread_db* tdbb, WIN* window, bool dontWrite) { /************************************** * @@ -1999,7 +2007,11 @@ static header_page* bump_transaction_id(thread_db* tdbb, WIN* window) // Extend, if necessary, has apparently succeeded. Next, update header page - CCH_MARK_MUST_WRITE(tdbb, window); + if (dontWrite && !new_tip) + CCH_MARK(tdbb, window); + else + CCH_MARK_MUST_WRITE(tdbb, window); + dbb->dbb_next_transaction = number; Ods::writeNT(header, number); @@ -2391,7 +2403,10 @@ static void retain_context(thread_db* tdbb, jrd_tra* transaction, bool commit, i new_number = dbb->dbb_next_transaction + dbb->generateTransactionId(tdbb); else { - const header_page* const header = bump_transaction_id(tdbb, &window); + const bool dontWrite = (dbb->dbb_flags & DBB_shared) && + (transaction->tra_flags & TRA_readonly); + + const header_page* const header = bump_transaction_id(tdbb, &window, dontWrite); new_number = Ods::getNT(header); } #endif @@ -3077,7 +3092,10 @@ static void transaction_start(thread_db* tdbb, jrd_tra* trans) } else { - const header_page* header = bump_transaction_id(tdbb, &window); + const bool dontWrite = (dbb->dbb_flags & DBB_shared) && + (trans->tra_flags & TRA_readonly); + + const header_page* header = bump_transaction_id(tdbb, &window, dontWrite); number = Ods::getNT(header); oldest = Ods::getOIT(header); oldest_active = Ods::getOAT(header);