4640 Ole John Aske 2011-11-09
SPJ Fix of buffered rows possible refering garbage after reorg'ed memory pages:
When the SPJ block buffer rows, it also convert the RowPtr from a RT_SECTION
to RT_LINEAR type as part of ::storeRow(). After ::storeRow has allocated
memory for the row itself, it is put into a 'map' by add_to_map().
However, as add:to_map() also does its own memory alloc, that may
trigger a reorg of the memory page in order to reclaim free'ed memory blocks.
Such a reorg will may cause the previously allocated row to be moved, and
the previously memory rowptr to become invalid - thus referring garbage.
Solution is to refetch the ptr after add_to_map() and fill in the
returned RowPtr& as the final action.
.... No MTR test as I am only able to reproduce this with my rewritten
calculate_batch_size() + some additional hack for testing that. These hacks
effectively force a really tiny 'BatchByteSize' to be calculated. That in
turn cause lots of repeated fetching (and buffering) from bushy scan queries.
4639 jonas oreland 2011-11-08
ndb - bump version to 7.0.29
=== modified file 'storage/ndb/src/kernel/blocks/dbspj/DbspjMain.cpp'
--- a/storage/ndb/src/kernel/blocks/dbspj/DbspjMain.cpp 2011-10-31 09:49:29 +0000
+++ b/storage/ndb/src/kernel/blocks/dbspj/DbspjMain.cpp 2011-11-09 08:39:50 +0000
@@ -2187,12 +2187,6 @@ Dbspj::storeRow(Ptr<Request> requestPtr,
- row.m_type = RowPtr::RT_LINEAR;
- row.m_row_data.m_linear.m_row_ref = ref;
- row.m_row_data.m_linear.m_header = (RowPtr::Header*)(dstptr + linklen);
- row.m_row_data.m_linear.m_data = dstptr + linklen + headlen;
memcpy(dstptr + linklen, headptr, 4 * headlen);
copy(dstptr + linklen + headlen, dataPtr);
@@ -2205,9 +2199,30 @@ Dbspj::storeRow(Ptr<Request> requestPtr,
- return add_to_map(requestPtr, treeNodePtr, row.m_src_correlation, ref);
+ Uint32 error = add_to_map(requestPtr, treeNodePtr, row.m_src_correlation, ref);
+ if (unlikely(error))
+ return error;
+ * Refetch pointer to alloc'ed row memory before creating RowPtr
+ * as above add_to_xxx may mave reorganized memory causing
+ * alloced row to be moved.
+ Uint32 * rowptr = 0;
+ if (ref.m_allocator == 0)
+ rowptr = get_row_ptr_stack(ref);
+ rowptr = get_row_ptr_var(ref);
+//ndbrequire(rowptr==dstptr); // It moved which we now do handle
+ setupRowPtr(treeNodePtr, row, ref, rowptr);
No bundle (reason: useless for push emails).
|• bzr push into mysql-5.1-telco-7.0 branch (ole.john.aske:4639 to 4640) ||Ole John Aske||11 Nov|