Skip to content
Permalink
Browse files
MDEV-28668 Recovery or backup of INSERT may be incorrect
page_cur_insert_rec_low(): When checking for common bytes with
the preceding record, exclude the header bytes of next_rec
that could have been updated by this function.

The scenario where this caused corruption was an insert of
a node pointer record. The child page number was written as
0x203 but recovered as 0x103 because the n_owned field of next_rec
was changed from 1 to 2 before the comparison was invoked.
  • Loading branch information
dr-m committed May 25, 2022
1 parent 915afdd commit a0e4853
Show file tree
Hide file tree
Showing 2 changed files with 10 additions and 8 deletions.
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 1994, 2016, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2018, 2021, MariaDB Corporation.
Copyright (c) 2018, 2022, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
@@ -154,9 +154,8 @@ page_cur_tuple_insert(
MY_ATTRIBUTE((nonnull, warn_unused_result));
/***********************************************************//**
Inserts a record next to page cursor on an uncompressed page.
Returns pointer to inserted record if succeed, i.e., enough
space available, NULL otherwise. The cursor stays at the same position.
@return pointer to record if succeed, NULL otherwise */
@return pointer to record
@retval nullptr if not enough space was available */
rec_t*
page_cur_insert_rec_low(
/*====================*/
@@ -2,7 +2,7 @@
Copyright (c) 1994, 2016, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2012, Facebook Inc.
Copyright (c) 2018, 2021, MariaDB Corporation.
Copyright (c) 2018, 2022, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
@@ -1280,9 +1280,8 @@ inline void mtr_t::page_insert(const buf_block_t &block, bool reuse,

/***********************************************************//**
Inserts a record next to page cursor on an uncompressed page.
Returns pointer to inserted record if succeed, i.e., enough
space available, NULL otherwise. The cursor stays at the same position.
@return pointer to record if succeed, NULL otherwise */
@return pointer to record
@retval nullptr if not enough space was available */
rec_t*
page_cur_insert_rec_low(
/*====================*/
@@ -1575,8 +1574,12 @@ page_cur_insert_rec_low(
const byte *r= rec;
const byte *c= cur->rec;
const byte *c_end= cur->rec + data_size;
static_assert(REC_N_OLD_EXTRA_BYTES == REC_N_NEW_EXTRA_BYTES + 1, "");
if (c <= insert_buf && c_end > insert_buf)
c_end= insert_buf;
else if (c_end < next_rec &&
c_end >= next_rec - REC_N_OLD_EXTRA_BYTES + comp)
c_end= next_rec - REC_N_OLD_EXTRA_BYTES + comp;
else
c_end= std::min<const byte*>(c_end, block->frame + srv_page_size -
PAGE_DIR - PAGE_DIR_SLOT_SIZE *

0 comments on commit a0e4853

Please sign in to comment.