diff options
author | Marko Mäkelä <marko.makela@mariadb.com> | 2020-02-17 10:49:42 +0200 |
---|---|---|
committer | Marko Mäkelä <marko.makela@mariadb.com> | 2020-02-17 15:32:24 +0200 |
commit | 09feb176e94f1cbdb213e8824abc0baa903921a0 (patch) | |
tree | 64aff786148664c6ac26c4a887b3daf31f3ef5b7 | |
parent | 0683c8f7a23f598b12b9f472b27e51e4173e3ff1 (diff) | |
download | mariadb-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.cc | 33 |
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 { |