summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarko Mäkelä <marko.makela@mariadb.com>2020-02-17 10:49:42 +0200
committerMarko Mäkelä <marko.makela@mariadb.com>2020-02-17 15:32:24 +0200
commit09feb176e94f1cbdb213e8824abc0baa903921a0 (patch)
tree64aff786148664c6ac26c4a887b3daf31f3ef5b7
parent0683c8f7a23f598b12b9f472b27e51e4173e3ff1 (diff)
downloadmariadb-git-09feb176e94f1cbdb213e8824abc0baa903921a0.tar.gz
MDEV-12353: Optimize page_cur_delete_rec() logging further
page_mem_free(): When deleting the very last record of the page, even if the record did not fully utilize all bytes in a former PAGE_FREE record, truncate the PAGE_HEAP_TOP and reduce PAGE_GARBAGE by the saved amount.
-rw-r--r--storage/innobase/page/page0cur.cc33
1 files changed, 26 insertions, 7 deletions
diff --git a/storage/innobase/page/page0cur.cc b/storage/innobase/page/page0cur.cc
index ddc6db5a69a..d58c63a6c86 100644
--- a/storage/innobase/page/page0cur.cc
+++ b/storage/innobase/page/page0cur.cc
@@ -1788,15 +1788,19 @@ static void page_mem_free(buf_block_t *block, rec_t *rec,
}
const uint16_t n_heap= page_header_get_field(block->frame, PAGE_N_HEAP) - 1;
+ ut_ad(page_get_n_recs(block->frame) < (n_heap & 0x7fff));
alignas(4) byte page_header[6];
const bool deleting_last= n_heap == ((n_heap & 0x8000)
- ? (rec_get_heap_no_new(rec) | 0x8000)
- : rec_get_heap_no_old(rec)) &&
- page_offset(rec_get_end(rec, offsets)) ==
- page_header_get_offs(block->frame, PAGE_HEAP_TOP);
+ ? (rec_get_heap_no_new(rec) | 0x8000)
+ : rec_get_heap_no_old(rec));
if (deleting_last)
{
+ const uint16_t heap_top= page_header_get_offs(block->frame, PAGE_HEAP_TOP);
+ const size_t extra_savings= heap_top -
+ page_offset(rec_get_end(rec, offsets));
+ ut_ad(extra_savings < heap_top);
+
/* When deleting the last record, do not add it to the PAGE_FREE list.
Instead, decrement PAGE_HEAP_TOP and PAGE_N_HEAP. */
mach_write_to_2(page_header, page_offset(rec_get_start(rec, offsets)));
@@ -1804,9 +1808,24 @@ static void page_mem_free(buf_block_t *block, rec_t *rec,
static_assert(PAGE_N_HEAP == PAGE_HEAP_TOP + 2, "compatibility");
mtr->memcpy(*block, my_assume_aligned<4>(PAGE_HEAP_TOP + PAGE_HEADER +
block->frame), page_header, 4);
- mtr->write<2,mtr_t::OPT>(*block, my_assume_aligned<2>(PAGE_LAST_INSERT +
- PAGE_HEADER +
- block->frame), 0U);
+ if (extra_savings)
+ {
+ uint16_t garbage= page_header_get_field(block->frame, PAGE_GARBAGE);
+ mach_write_to_2(page_header, garbage - extra_savings);
+ size_t len= 2;
+ if (page_header_get_field(block->frame, PAGE_LAST_INSERT))
+ {
+ memset_aligned<2>(page_header + 2, 0, 2);
+ len= 4;
+ }
+ mtr->memcpy(*block, my_assume_aligned<2>(PAGE_GARBAGE + PAGE_HEADER +
+ block->frame),
+ page_header, len);
+ }
+ else
+ mtr->write<2,mtr_t::OPT>(*block, my_assume_aligned<2>
+ (PAGE_LAST_INSERT + PAGE_HEADER + block->frame),
+ 0U);
}
else
{