Skip to content

Commit 23a55f0

Browse files
committed
Improvement CORE-5434 : Read-only transactions in SuperServer could avoid immediate write of Header and TIP pages after change
1 parent 1a103a2 commit 23a55f0

File tree

1 file changed

+25
-7
lines changed

1 file changed

+25
-7
lines changed

src/jrd/tra.cpp

Lines changed: 25 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,7 @@ typedef Firebird::GenericMap<Firebird::Pair<Firebird::NonPooled<USHORT, UCHAR> >
8989
#ifdef SUPERSERVER_V2
9090
static TraNumber bump_transaction_id(thread_db*, WIN*);
9191
#else
92-
static header_page* bump_transaction_id(thread_db*, WIN*);
92+
static header_page* bump_transaction_id(thread_db*, WIN*, bool);
9393
#endif
9494
static void retain_context(thread_db* tdbb, jrd_tra* transaction, bool commit, int state);
9595
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
14451445
WIN window(DB_PAGE_SPACE, -1);
14461446
tx_inv_page* tip = fetch_inventory_page(tdbb, &window, sequence, LCK_write);
14471447

1448+
UCHAR* address = tip->tip_transactions + byte;
1449+
const int old_state = ((*address) >> shift) & TRA_MASK;
1450+
14481451
#ifdef SUPERSERVER_V2
14491452
CCH_MARK(tdbb, &window);
14501453
const ULONG generation = tip->tip_header.pag_generation;
14511454
#else
1452-
CCH_MARK_MUST_WRITE(tdbb, &window);
1455+
if (!(dbb->dbb_flags & DBB_shared) || transaction->tra_flags & TRA_write ||
1456+
old_state != tra_active || state != tra_committed)
1457+
{
1458+
CCH_MARK_MUST_WRITE(tdbb, &window);
1459+
}
1460+
else
1461+
CCH_MARK(tdbb, &window);
14531462
#endif
14541463

14551464
// set the state on the TIP page
14561465

1457-
UCHAR* address = tip->tip_transactions + byte;
14581466
*address &= ~(TRA_MASK << shift);
14591467
*address |= state << shift;
14601468

@@ -1944,7 +1952,7 @@ static TraNumber bump_transaction_id(thread_db* tdbb, WIN* window)
19441952
#else
19451953

19461954

1947-
static header_page* bump_transaction_id(thread_db* tdbb, WIN* window)
1955+
static header_page* bump_transaction_id(thread_db* tdbb, WIN* window, bool dontWrite)
19481956
{
19491957
/**************************************
19501958
*
@@ -1999,7 +2007,11 @@ static header_page* bump_transaction_id(thread_db* tdbb, WIN* window)
19992007

20002008
// Extend, if necessary, has apparently succeeded. Next, update header page
20012009

2002-
CCH_MARK_MUST_WRITE(tdbb, window);
2010+
if (dontWrite && !new_tip)
2011+
CCH_MARK(tdbb, window);
2012+
else
2013+
CCH_MARK_MUST_WRITE(tdbb, window);
2014+
20032015
dbb->dbb_next_transaction = number;
20042016

20052017
Ods::writeNT(header, number);
@@ -2391,7 +2403,10 @@ static void retain_context(thread_db* tdbb, jrd_tra* transaction, bool commit, i
23912403
new_number = dbb->dbb_next_transaction + dbb->generateTransactionId(tdbb);
23922404
else
23932405
{
2394-
const header_page* const header = bump_transaction_id(tdbb, &window);
2406+
const bool dontWrite = (dbb->dbb_flags & DBB_shared) &&
2407+
(transaction->tra_flags & TRA_readonly);
2408+
2409+
const header_page* const header = bump_transaction_id(tdbb, &window, dontWrite);
23952410
new_number = Ods::getNT(header);
23962411
}
23972412
#endif
@@ -3077,7 +3092,10 @@ static void transaction_start(thread_db* tdbb, jrd_tra* trans)
30773092
}
30783093
else
30793094
{
3080-
const header_page* header = bump_transaction_id(tdbb, &window);
3095+
const bool dontWrite = (dbb->dbb_flags & DBB_shared) &&
3096+
(trans->tra_flags & TRA_readonly);
3097+
3098+
const header_page* header = bump_transaction_id(tdbb, &window, dontWrite);
30813099
number = Ods::getNT(header);
30823100
oldest = Ods::getOIT(header);
30833101
oldest_active = Ods::getOAT(header);

0 commit comments

Comments
 (0)