Skip to content

Commit db45ba7

Browse files
committed
Bug#35500304 NdbFS debugging output for wrong requests
As part of debugging problem situations, NdbFS can output a list of in-flight file system requests, including how long they have been stalled. This is useful to understand the circumstances leading to an issue. The implementation of this functionality was incorrect and could return the wrong set of requests, leading to the wrong conclusions being reached in analysis. Change-Id: Icf6cab79aa604ddfec356c1d1935eeade8749796
1 parent 80a4727 commit db45ba7

File tree

3 files changed

+53
-15
lines changed

3 files changed

+53
-15
lines changed

storage/ndb/src/kernel/blocks/ndbfs/AsyncIoThread.hpp

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
/* Copyright (c) 2008, 2021, Oracle and/or its affiliates.
1+
/*
2+
Copyright (c) 2008, 2023, Oracle and/or its affiliates.
23
34
This program is free software; you can redistribute it and/or modify
45
it under the terms of the GNU General Public License, version 2.0,
@@ -142,6 +143,10 @@ class Request
142143

143144
/* More debugging info */
144145
NDB_TICKS m_startTime;
146+
147+
/* Pool members */
148+
Request* listNext;
149+
Request* listPrev;
145150
};
146151

147152
NdbOut& operator <<(NdbOut&, const Request&);

storage/ndb/src/kernel/blocks/ndbfs/Ndbfs.cpp

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
Copyright (c) 2003, 2022, Oracle and/or its affiliates.
2+
Copyright (c) 2003, 2023, 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,
@@ -1828,21 +1828,20 @@ Ndbfs::execDUMP_STATE_ORD(Signal* signal)
18281828
{
18291829
g_eventLogger->info("NDBFS: Dump requests: %u",
18301830
theRequestPool->inuse());
1831-
for (unsigned ridx=0; ridx < theRequestPool->inuse(); ridx++)
1831+
const Request* req = NULL;
1832+
while((req = theRequestPool->getNextInUseItem(req)))
18321833
{
1833-
const Request* req = theRequestPool->peekInuseItem(ridx);
18341834
Uint64 duration = 0;
18351835

18361836
if (NdbTick_IsValid(req->m_startTime))
18371837
{
18381838
duration = NdbTick_Elapsed(req->m_startTime,
1839-
getHighResTimer()).milliSec();
1839+
getHighResTimer()).microSec();
18401840
}
18411841

1842-
g_eventLogger->info("Request %u action %u %s userRef 0x%x "
1842+
g_eventLogger->info("Request action %u %s userRef 0x%x "
18431843
"userPtr %u filePtr %u bind %u "
1844-
"duration(ms) %llu filename %s",
1845-
ridx,
1844+
"duration(us) %llu filename %s",
18461845
req->action,
18471846
Request::actionName(req->action),
18481847
req->theUserReference,

storage/ndb/src/kernel/blocks/ndbfs/Pool.hpp

Lines changed: 41 additions & 7 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, 2023, 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,
@@ -202,7 +202,8 @@ class Pool
202202
theIncSize(anIncSize),
203203
theTop(0),
204204
theCurrentSize(0),
205-
theList(0)
205+
theList(0),
206+
theInUseList(NULL)
206207
{
207208
allocate(anInitSize);
208209
}
@@ -224,7 +225,7 @@ class Pool
224225
// inuse() : Return number items taken from pool
225226
unsigned inuse() const { return theCurrentSize - theTop; };
226227

227-
const T* peekInuseItem(unsigned idx) const;
228+
const T* getNextInUseItem(const T*) const;
228229

229230
protected:
230231
void allocate(int aSize)
@@ -252,6 +253,7 @@ class Pool
252253
int theCurrentSize;
253254

254255
T** theList;
256+
T* theInUseList;
255257
};
256258

257259
//******************************************************************************
@@ -264,6 +266,18 @@ template <class T> inline T* Pool<T>::get()
264266
}
265267
--theTop;
266268
tmp = theList[theTop];
269+
270+
/* Maintain inuse list */
271+
/* Add to head */
272+
if (theInUseList)
273+
{
274+
assert(theInUseList->listPrev == NULL);
275+
theInUseList->listPrev = tmp;
276+
}
277+
tmp->listNext = theInUseList;
278+
tmp->listPrev = NULL;
279+
theInUseList = tmp;
280+
267281
tmp->atGet();
268282
return tmp;
269283
}
@@ -274,13 +288,33 @@ template <class T> inline void Pool<T>::put(T* aT)
274288
{
275289
theList[theTop]= aT;
276290
++theTop;
291+
292+
/* Remove item from InUse list */
293+
T* next = aT->listNext;
294+
T* prev = aT->listPrev;
295+
296+
if (next)
297+
{
298+
next->listPrev = prev;
299+
}
300+
if (prev)
301+
{
302+
prev->listNext = next;
303+
}
304+
else
305+
{
306+
theInUseList = next;
307+
}
308+
aT->listNext = aT->listPrev = NULL;
277309
}
278310

279-
template <class T> const T* Pool<T>::peekInuseItem(unsigned idx) const
311+
template <class T> const T* Pool<T>::getNextInUseItem(const T* item) const
280312
{
281-
assert(idx <= inuse());
282-
// theTop is index of the first item in use
283-
return theList[theTop + idx];
313+
if (item)
314+
{
315+
return item->listNext;
316+
}
317+
return theInUseList;
284318
}
285319

286320

0 commit comments

Comments
 (0)