Skip to content

Commit 99940f7

Browse files
committed
Bug#35783683 Ndb table reorganize modifies tuple header after checksum calculated
Any changes to a tuple header must be done before the checksum is recalculated. Fix regression from 8.0 Query Threads feature resulting in checksum calculation being moved before and not considering Reorg bit setting. Problem visibly fixed when running forthcoming testcase exercising multiple operations on rows undergoing reorg. Change-Id: I743765bf022c471ba4cb3f72796de30481aef0e0
1 parent 2d790ef commit 99940f7

File tree

1 file changed

+36
-26
lines changed

1 file changed

+36
-26
lines changed

storage/ndb/src/kernel/blocks/dbtup/DbtupExecQuery.cpp

Lines changed: 36 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1895,30 +1895,31 @@ int Dbtup::handleReadReq(Signal* signal,
18951895
}
18961896

18971897
static
1898-
void
1899-
handle_reorg(Dbtup::KeyReqStruct * req_struct,
1900-
Dbtup::Fragrecord::FragState state)
1898+
Uint32
1899+
get_reorg_flag(Dbtup::KeyReqStruct * req_struct,
1900+
Dbtup::Fragrecord::FragState state)
19011901
{
19021902
Uint32 reorg = req_struct->m_reorg;
19031903
switch(state){
19041904
case Dbtup::Fragrecord::FS_FREE:
19051905
case Dbtup::Fragrecord::FS_REORG_NEW:
19061906
case Dbtup::Fragrecord::FS_REORG_COMMIT_NEW:
19071907
case Dbtup::Fragrecord::FS_REORG_COMPLETE_NEW:
1908-
return;
1908+
return 0;
19091909
case Dbtup::Fragrecord::FS_REORG_COMMIT:
19101910
case Dbtup::Fragrecord::FS_REORG_COMPLETE:
19111911
if (reorg != ScanFragReq::REORG_NOT_MOVED)
1912-
return;
1912+
return 0;
19131913
break;
19141914
case Dbtup::Fragrecord::FS_ONLINE:
19151915
if (reorg != ScanFragReq::REORG_MOVED)
1916-
return;
1916+
return 0;
19171917
break;
19181918
default:
1919-
return;
1919+
return 0;
19201920
}
1921-
req_struct->m_tuple_ptr->m_header_bits |= Dbtup::Tuple_header::REORG_MOVE;
1921+
1922+
return Dbtup::Tuple_header::REORG_MOVE;
19221923
}
19231924

19241925
/* ---------------------------------------------------------------- */
@@ -2093,7 +2094,8 @@ int Dbtup::handleUpdateReq(Signal* signal,
20932094

20942095
if (req_struct->m_reorg != ScanFragReq::REORG_ALL)
20952096
{
2096-
handle_reorg(req_struct, regFragPtr->fragStatus);
2097+
req_struct->m_tuple_ptr->m_header_bits |=
2098+
get_reorg_flag(req_struct, regFragPtr->fragStatus);
20972099
}
20982100

20992101
req_struct->m_tuple_ptr->set_tuple_version(tup_version);
@@ -2909,6 +2911,13 @@ int Dbtup::handleInsertReq(Signal* signal,
29092911

29102912
disk_ptr->set_base_record_ref(ref);
29112913
}
2914+
2915+
if (req_struct->m_reorg != ScanFragReq::REORG_ALL)
2916+
{
2917+
req_struct->m_tuple_ptr->m_header_bits |=
2918+
get_reorg_flag(req_struct, regFragPtr->fragStatus);
2919+
}
2920+
29122921
setChecksum(req_struct->m_tuple_ptr, regTabPtr);
29132922
/**
29142923
* At this point we hold the fragment mutex to ensure that TUP scans
@@ -2924,6 +2933,7 @@ int Dbtup::handleInsertReq(Signal* signal,
29242933
}
29252934
else
29262935
{
2936+
/* ! mem_insert */
29272937
if (ERROR_INSERTED(4020))
29282938
{
29292939
c_lqh->upgrade_to_exclusive_frag_access();
@@ -2947,11 +2957,23 @@ int Dbtup::handleInsertReq(Signal* signal,
29472957
* finalizing the writes on the row.
29482958
*/
29492959
m_base_header_bits &= ~(Uint32)Tuple_header::FREE;
2950-
}
29512960

2952-
if (req_struct->m_reorg != ScanFragReq::REORG_ALL)
2953-
{
2954-
handle_reorg(req_struct, regFragPtr->fragStatus);
2961+
if (req_struct->m_reorg != ScanFragReq::REORG_ALL)
2962+
{
2963+
m_base_header_bits |=
2964+
get_reorg_flag(req_struct, regFragPtr->fragStatus);
2965+
}
2966+
2967+
/**
2968+
* Fragment-locking :
2969+
* No need to protect this checksum write, we only perform it here for
2970+
* non-first inserts since first insert operations are handled above
2971+
* while holding the mutex. For non-first operations the row is not
2972+
* visible to other threads at this time, copy rows are not even visible to
2973+
* TUP scans, thus no need to protect it here. The row becomes visible
2974+
* when inserted into the active list after returning from this call.
2975+
*/
2976+
setChecksum(req_struct->m_tuple_ptr, regTabPtr);
29552977
}
29562978

29572979
/* Have been successful with disk + mem, update ACC to point to
@@ -2974,19 +2996,7 @@ int Dbtup::handleInsertReq(Signal* signal,
29742996
{
29752997
* accminupdateptr = 0; // No accminupdate should be performed
29762998
}
2977-
if (!mem_insert)
2978-
{
2979-
/**
2980-
* No need to protect this checksum write, we only perform it here for
2981-
* non-first inserts since first insert operations are handled above
2982-
* while holding the mutex. For non-first operations the row is not
2983-
* visible to others at this time, copy rows are not even visible to
2984-
* TUP scans, thus no need to protect it here. The row becomes visible
2985-
* when inserted into the active list after returning from this call.
2986-
*/
2987-
jamDebug();
2988-
setChecksum(req_struct->m_tuple_ptr, regTabPtr);
2989-
}
2999+
29903000
set_tuple_state(regOperPtr.p, TUPLE_PREPARED);
29913001
return 0;
29923002

0 commit comments

Comments
 (0)