Skip to content

Commit e2b61c0

Browse files
author
Ole John Aske
committed
Bug#34098384 Dbacc lock handling has too much overhead when WITH_DEBUG compiled
Backport: WITH_DEBUG compiled code had some self check code which required the lockOwnersList to be fully iterated. For large transactions, holding many locks, the overhead of this becomes prohobitive. The value of these self check loops were considered to be questionable. This patch replace the lockOwnersList with a simple lockCount which enables us to verify that all locks had been released before removing a fragment. Other self-check code checking the lockOwnersList for lock not already held or release is just removed. Related methods for inserting / removing a lock into the lockOwnersList are removed as well. Change-Id: I3182c154f1afb5d1bac847432d3ec1d1b5c0d3ba
1 parent fa27e31 commit e2b61c0

File tree

2 files changed

+22
-164
lines changed

2 files changed

+22
-164
lines changed

storage/ndb/src/kernel/blocks/dbacc/Dbacc.hpp

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
Copyright (c) 2003, 2021, Oracle and/or its affiliates.
2+
Copyright (c) 2003, 2022, Oracle and/or its affiliates.
33
44
This program is free software; you can redistribute it and/or modify
55
it under the terms of the GNU General Public License, version 2.0,
@@ -420,9 +420,9 @@ struct Fragmentrec {
420420
Uint32 expSenderPageptr;
421421

422422
//-----------------------------------------------------------------------------
423-
// List of lock owners currently used only for self-check
423+
// Number of locks held on fragment, only for self-check
424424
//-----------------------------------------------------------------------------
425-
Uint32 lockOwnersList;
425+
Uint32 lockCount;
426426

427427
//-----------------------------------------------------------------------------
428428
// References to Directory Ranges (which in turn references directories, which
@@ -695,15 +695,13 @@ struct Operationrec {
695695
Uint32 fid;
696696
Uint32 fragptr;
697697
LHBits32 hashValue;
698-
Uint32 nextLockOwnerOp;
699698
Uint32 nextOp;
700699
Uint32 nextParallelQue;
701700
union {
702701
Uint32 nextSerialQue;
703702
Uint32 m_lock_owner_ptr_i; // if nextParallelQue = RNIL, else undefined
704703
};
705704
Uint32 prevOp;
706-
Uint32 prevLockOwnerOp;
707705
union {
708706
Uint32 prevParallelQue;
709707
Uint32 m_lo_last_parallel_op_ptr_i;
@@ -890,7 +888,6 @@ struct Tabrec {
890888
void initFragAdd(Signal*, FragmentrecPtr) const;
891889
void initFragPageZero(FragmentrecPtr, Page8Ptr) const;
892890
void initFragGeneral(FragmentrecPtr) const;
893-
void verifyFragCorrect(FragmentrecPtr regFragPtr) const;
894891
void releaseFragResources(Signal* signal, Uint32 fragIndex);
895892
void releaseRootFragRecord(Signal* signal, RootfragmentrecPtr rootPtr) const;
896893
void releaseRootFragResources(Signal* signal, Uint32 tableId);
@@ -1062,8 +1059,6 @@ struct Tabrec {
10621059
OperationrecPtr release_op) const;
10631060
void allocOverflowPage();
10641061
bool getfragmentrec(FragmentrecPtr&, Uint32 fragId);
1065-
void insertLockOwnersList(const OperationrecPtr&) const;
1066-
void takeOutLockOwnersList(const OperationrecPtr&) const;
10671062

10681063
void initFsOpRec(Signal* signal) const;
10691064
void initOverpage(Page8Ptr);

storage/ndb/src/kernel/blocks/dbacc/DbaccMain.cpp

Lines changed: 19 additions & 156 deletions
Original file line numberDiff line numberDiff line change
@@ -646,7 +646,7 @@ void Dbacc::releaseFragResources(Signal* signal, Uint32 fragIndex)
646646
FragmentrecPtr regFragPtr;
647647
regFragPtr.i = fragIndex;
648648
ptrCheckGuard(regFragPtr, cfragmentsize, fragmentrec);
649-
verifyFragCorrect(regFragPtr);
649+
ndbrequire(regFragPtr.p->lockCount == 0);
650650

651651
if (regFragPtr.p->expandOrShrinkQueued)
652652
{
@@ -705,11 +705,6 @@ void Dbacc::releaseFragResources(Signal* signal, Uint32 fragIndex)
705705
ndbassert(validatePageCount());
706706
}//Dbacc::releaseFragResources()
707707

708-
void Dbacc::verifyFragCorrect(FragmentrecPtr regFragPtr)const
709-
{
710-
ndbrequire(regFragPtr.p->lockOwnersList == RNIL);
711-
}//Dbacc::verifyFragCorrect()
712-
713708
void Dbacc::releaseDirResources(Signal* signal)
714709
{
715710
jam();
@@ -721,7 +716,7 @@ void Dbacc::releaseDirResources(Signal* signal)
721716
FragmentrecPtr regFragPtr;
722717
regFragPtr.i = fragIndex;
723718
ptrCheckGuard(regFragPtr, cfragmentsize, fragmentrec);
724-
verifyFragCorrect(regFragPtr);
719+
ndbrequire(regFragPtr.p->lockCount == 0);
725720

726721
DynArr256::Head* directory;
727722
ndbrequire(signal->theData[0] == ZREL_DIR);
@@ -1079,8 +1074,8 @@ void Dbacc::execACCKEYREQ(Signal* signal)
10791074
dbgWord32(elemPageptr, elemptr, eh);
10801075
elemPageptr.p->word32[elemptr] = eh;
10811076

1082-
opbits |= Operationrec::OP_LOCK_OWNER;
1083-
insertLockOwnersList(operationRecPtr);
1077+
opbits |= Operationrec::OP_LOCK_OWNER;
1078+
fragrecptr.p->lockCount++;
10841079

10851080
fragrecptr.p->
10861081
m_lockStats.req_start_imm_ok((opbits &
@@ -1598,7 +1593,8 @@ void Dbacc::insertelementLab(Signal* signal,
15981593
ndbrequire(operationRecPtr.p->tupkeylen <= fragrecptr.p->keyLength);
15991594
ndbassert(!(operationRecPtr.p->m_op_bits & Operationrec::OP_LOCK_REQ));
16001595

1601-
insertLockOwnersList(operationRecPtr);
1596+
fragrecptr.p->lockCount++;
1597+
operationRecPtr.p->m_op_bits |= Operationrec::OP_LOCK_OWNER;
16021598

16031599
operationRecPtr.p->reducedHashValue = fragrecptr.p->level.reduce(operationRecPtr.p->hashValue);
16041600
const Uint32 tidrElemhead = ElementHeader::setLocked(operationRecPtr.i);
@@ -4834,7 +4830,7 @@ void Dbacc::abortOperation(Signal* signal)
48344830

48354831
if (opbits & Operationrec::OP_LOCK_OWNER)
48364832
{
4837-
takeOutLockOwnersList(operationRecPtr);
4833+
fragrecptr.p->lockCount--;
48384834
opbits &= ~(Uint32)Operationrec::OP_LOCK_OWNER;
48394835
if (opbits & Operationrec::OP_INSERT_IS_DONE)
48404836
{
@@ -5013,7 +5009,7 @@ void Dbacc::commitOperation(Signal* signal)
50135009

50145010
if (opbits & Operationrec::OP_LOCK_OWNER)
50155011
{
5016-
takeOutLockOwnersList(operationRecPtr);
5012+
fragrecptr.p->lockCount--;
50175013
opbits &= ~(Uint32)Operationrec::OP_LOCK_OWNER;
50185014
operationRecPtr.p->m_op_bits = opbits;
50195015

@@ -5340,7 +5336,8 @@ Dbacc::release_lockowner(Signal* signal, OperationrecPtr opPtr, bool commit)
53405336
action = START_NEW;
53415337
}
53425338

5343-
insertLockOwnersList(newOwner);
5339+
fragrecptr.p->lockCount++;
5340+
newOwner.p->m_op_bits |= Operationrec::OP_LOCK_OWNER;
53445341

53455342
/**
53465343
* Copy op info, and store op in element
@@ -5497,99 +5494,6 @@ Dbacc::startNew(Signal* signal, OperationrecPtr newOwner)
54975494
return;
54985495
}
54995496

5500-
/**
5501-
* takeOutLockOwnersList
5502-
*
5503-
* Description: Take out an operation from the doubly linked
5504-
* lock owners list on the fragment.
5505-
*
5506-
*/
5507-
void Dbacc::takeOutLockOwnersList(const OperationrecPtr& outOperPtr) const
5508-
{
5509-
const Uint32 Tprev = outOperPtr.p->prevLockOwnerOp;
5510-
const Uint32 Tnext = outOperPtr.p->nextLockOwnerOp;
5511-
#ifdef VM_TRACE
5512-
// Check that operation is already in the list
5513-
OperationrecPtr tmpOperPtr;
5514-
bool inList = false;
5515-
tmpOperPtr.i = fragrecptr.p->lockOwnersList;
5516-
while (tmpOperPtr.i != RNIL){
5517-
ptrCheckGuard(tmpOperPtr, coprecsize, operationrec);
5518-
if (tmpOperPtr.i == outOperPtr.i)
5519-
inList = true;
5520-
tmpOperPtr.i = tmpOperPtr.p->nextLockOwnerOp;
5521-
}
5522-
ndbrequire(inList == true);
5523-
#endif
5524-
5525-
ndbassert(outOperPtr.p->m_op_bits & Operationrec::OP_LOCK_OWNER);
5526-
5527-
// Fast path through the code for the common case.
5528-
if ((Tprev == RNIL) && (Tnext == RNIL)) {
5529-
ndbrequire(fragrecptr.p->lockOwnersList == outOperPtr.i);
5530-
fragrecptr.p->lockOwnersList = RNIL;
5531-
return;
5532-
}
5533-
5534-
// Check previous operation
5535-
if (Tprev != RNIL) {
5536-
jam();
5537-
arrGuard(Tprev, coprecsize);
5538-
operationrec[Tprev].nextLockOwnerOp = Tnext;
5539-
} else {
5540-
fragrecptr.p->lockOwnersList = Tnext;
5541-
}//if
5542-
5543-
// Check next operation
5544-
if (Tnext == RNIL) {
5545-
return;
5546-
} else {
5547-
jam();
5548-
arrGuard(Tnext, coprecsize);
5549-
operationrec[Tnext].prevLockOwnerOp = Tprev;
5550-
}//if
5551-
5552-
return;
5553-
}//Dbacc::takeOutLockOwnersList()
5554-
5555-
/**
5556-
* insertLockOwnersList
5557-
*
5558-
* Description: Insert an operation first in the dubly linked lock owners
5559-
* list on the fragment.
5560-
*
5561-
*/
5562-
void Dbacc::insertLockOwnersList(const OperationrecPtr& insOperPtr) const
5563-
{
5564-
OperationrecPtr tmpOperPtr;
5565-
#ifdef VM_TRACE
5566-
// Check that operation is not already in list
5567-
tmpOperPtr.i = fragrecptr.p->lockOwnersList;
5568-
while(tmpOperPtr.i != RNIL){
5569-
ptrCheckGuard(tmpOperPtr, coprecsize, operationrec);
5570-
ndbrequire(tmpOperPtr.i != insOperPtr.i);
5571-
tmpOperPtr.i = tmpOperPtr.p->nextLockOwnerOp;
5572-
}
5573-
#endif
5574-
tmpOperPtr.i = fragrecptr.p->lockOwnersList;
5575-
5576-
ndbrequire(! (insOperPtr.p->m_op_bits & Operationrec::OP_LOCK_OWNER));
5577-
5578-
insOperPtr.p->m_op_bits |= Operationrec::OP_LOCK_OWNER;
5579-
insOperPtr.p->prevLockOwnerOp = RNIL;
5580-
insOperPtr.p->nextLockOwnerOp = tmpOperPtr.i;
5581-
5582-
fragrecptr.p->lockOwnersList = insOperPtr.i;
5583-
if (tmpOperPtr.i == RNIL) {
5584-
return;
5585-
} else {
5586-
jam();
5587-
ptrCheckGuard(tmpOperPtr, coprecsize, operationrec);
5588-
tmpOperPtr.p->prevLockOwnerOp = insOperPtr.i;
5589-
}//if
5590-
}//Dbacc::insertLockOwnersList()
5591-
5592-
55935497
/* --------------------------------------------------------------------------------- */
55945498
/* --------------------------------------------------------------------------------- */
55955499
/* --------------------------------------------------------------------------------- */
@@ -7043,8 +6947,7 @@ void Dbacc::initFragGeneral(FragmentrecPtr regFragPtr)const
70436947
{
70446948
new (&regFragPtr.p->directory) DynArr256::Head();
70456949

7046-
regFragPtr.p->lockOwnersList = RNIL;
7047-
6950+
regFragPtr.p->lockCount = 0;
70486951
regFragPtr.p->hasCharAttr = ZFALSE;
70496952
regFragPtr.p->dirRangeFull = ZFALSE;
70506953
regFragPtr.p->fragState = FREEFRAG;
@@ -7326,9 +7229,10 @@ void Dbacc::checkNextBucketLab(Signal* signal)
73267229
getHighResTimer());
73277230

73287231
setlock(nsPageptr, tnsElementptr);
7329-
insertLockOwnersList(operationRecPtr);
7330-
operationRecPtr.p->m_op_bits |=
7331-
Operationrec::OP_STATE_RUNNING | Operationrec::OP_RUN_QUEUE;
7232+
fragrecptr.p->lockCount++;
7233+
operationRecPtr.p->m_op_bits |=
7234+
Operationrec::OP_LOCK_OWNER |
7235+
Operationrec::OP_STATE_RUNNING | Operationrec::OP_RUN_QUEUE;
73327236
}//if
73337237
} else {
73347238
arrGuard(tnsElementptr, 2048);
@@ -8027,26 +7931,6 @@ void Dbacc::putActiveScanOp() const
80277931
*/
80287932
void Dbacc::putOpScanLockQue() const
80297933
{
8030-
8031-
#ifdef VM_TRACE
8032-
// DEBUG CODE
8033-
// Check that there are as many operations in the lockqueue as
8034-
// scanLockHeld indicates
8035-
OperationrecPtr tmpOp;
8036-
int numLockedOpsBefore = 0;
8037-
tmpOp.i = scanPtr.p->scanFirstLockedOp;
8038-
while(tmpOp.i != RNIL){
8039-
numLockedOpsBefore++;
8040-
ptrCheckGuard(tmpOp, coprecsize, operationrec);
8041-
if (tmpOp.p->nextOp == RNIL)
8042-
{
8043-
ndbrequire(tmpOp.i == scanPtr.p->scanLastLockedOp);
8044-
}
8045-
tmpOp.i = tmpOp.p->nextOp;
8046-
}
8047-
ndbrequire(numLockedOpsBefore==scanPtr.p->scanLockHeld);
8048-
#endif
8049-
80507934
OperationrecPtr pslOperationRecPtr;
80517935
ScanRec theScanRec;
80527936
theScanRec = *scanPtr.p;
@@ -8414,25 +8298,6 @@ void Dbacc::takeOutScanLockQueue(Uint32 scanRecIndex) const
84148298
TscanPtr.p->scanLastLockedOp = operationRecPtr.p->prevOp;
84158299
}//if
84168300
TscanPtr.p->scanLockHeld--;
8417-
8418-
#ifdef VM_TRACE
8419-
// DEBUG CODE
8420-
// Check that there are as many operations in the lockqueue as
8421-
// scanLockHeld indicates
8422-
OperationrecPtr tmpOp;
8423-
int numLockedOps = 0;
8424-
tmpOp.i = TscanPtr.p->scanFirstLockedOp;
8425-
while(tmpOp.i != RNIL){
8426-
numLockedOps++;
8427-
ptrCheckGuard(tmpOp, coprecsize, operationrec);
8428-
if (tmpOp.p->nextOp == RNIL)
8429-
{
8430-
ndbrequire(tmpOp.i == TscanPtr.p->scanLastLockedOp);
8431-
}
8432-
tmpOp.i = tmpOp.p->nextOp;
8433-
}
8434-
ndbrequire(numLockedOps==TscanPtr.p->scanLockHeld);
8435-
#endif
84368301
}//Dbacc::takeOutScanLockQueue()
84378302

84388303
/* --------------------------------------------------------------------------------- */
@@ -9215,15 +9080,13 @@ Dbacc::execDUMP_STATE_ORD(Signal* signal)
92159080
infoEvent("fid=%d, fragptr=%d ",
92169081
tmpOpPtr.p->fid, tmpOpPtr.p->fragptr);
92179082
infoEvent("hashValue=%d", tmpOpPtr.p->hashValue.pack());
9218-
infoEvent("nextLockOwnerOp=%d, nextOp=%d, nextParallelQue=%d ",
9219-
tmpOpPtr.p->nextLockOwnerOp, tmpOpPtr.p->nextOp,
9220-
tmpOpPtr.p->nextParallelQue);
9083+
infoEvent("nextOp=%d, nextParallelQue=%d ",
9084+
tmpOpPtr.p->nextOp, tmpOpPtr.p->nextParallelQue);
92219085
infoEvent("nextSerialQue=%d, prevOp=%d ",
92229086
tmpOpPtr.p->nextSerialQue,
92239087
tmpOpPtr.p->prevOp);
9224-
infoEvent("prevLockOwnerOp=%d, prevParallelQue=%d",
9225-
tmpOpPtr.p->prevLockOwnerOp, tmpOpPtr.p->nextParallelQue);
9226-
infoEvent("prevSerialQue=%d, scanRecPtr=%d",
9088+
infoEvent("prevParallelQue=%d, prevSerialQue=%d, scanRecPtr=%d",
9089+
tmpOpPtr.p->prevParallelQue,
92279090
tmpOpPtr.p->prevSerialQue, tmpOpPtr.p->scanRecPtr);
92289091
infoEvent("m_op_bits=0x%x, reducedHashValue=%x ",
92299092
tmpOpPtr.p->m_op_bits, tmpOpPtr.p->reducedHashValue.pack());

0 commit comments

Comments
 (0)