diff options
Diffstat (limited to 'storage/innobase/include/trx0undo.inl')
-rw-r--r-- | storage/innobase/include/trx0undo.inl | 352 |
1 files changed, 352 insertions, 0 deletions
diff --git a/storage/innobase/include/trx0undo.inl b/storage/innobase/include/trx0undo.inl new file mode 100644 index 00000000000..2e26e6547c3 --- /dev/null +++ b/storage/innobase/include/trx0undo.inl @@ -0,0 +1,352 @@ +/***************************************************************************** + +Copyright (c) 1996, 2013, Oracle and/or its affiliates. All Rights Reserved. +Copyright (c) 2017, 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 +Foundation; version 2 of the License. + +This program is distributed in the hope that it will be useful, but WITHOUT +ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License along with +this program; if not, write to the Free Software Foundation, Inc., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1335 USA + +*****************************************************************************/ + +/**************************************************//** +@file include/trx0undo.ic +Transaction undo log + +Created 3/26/1996 Heikki Tuuri +*******************************************************/ + +#include "data0type.h" +#include "page0page.h" + +/***********************************************************************//** +Builds a roll pointer. +@return roll pointer */ +UNIV_INLINE +roll_ptr_t +trx_undo_build_roll_ptr( +/*====================*/ + ibool is_insert, /*!< in: TRUE if insert undo log */ + ulint rseg_id, /*!< in: rollback segment id */ + ulint page_no, /*!< in: page number */ + ulint offset) /*!< in: offset of the undo entry within page */ +{ + roll_ptr_t roll_ptr; +#if DATA_ROLL_PTR_LEN != 7 +# error "DATA_ROLL_PTR_LEN != 7" +#endif + ut_ad(is_insert == 0 || is_insert == 1); + ut_ad(rseg_id < TRX_SYS_N_RSEGS); + ut_ad(offset < 65536); + + roll_ptr = (roll_ptr_t) is_insert << ROLL_PTR_INSERT_FLAG_POS + | (roll_ptr_t) rseg_id << ROLL_PTR_RSEG_ID_POS + | (roll_ptr_t) page_no << ROLL_PTR_PAGE_POS + | offset; + return(roll_ptr); +} + +/***********************************************************************//** +Decodes a roll pointer. */ +UNIV_INLINE +void +trx_undo_decode_roll_ptr( +/*=====================*/ + roll_ptr_t roll_ptr, /*!< in: roll pointer */ + ibool* is_insert, /*!< out: TRUE if insert undo log */ + ulint* rseg_id, /*!< out: rollback segment id */ + ulint* page_no, /*!< out: page number */ + ulint* offset) /*!< out: offset of the undo + entry within page */ +{ +#if DATA_ROLL_PTR_LEN != 7 +# error "DATA_ROLL_PTR_LEN != 7" +#endif +#if TRUE != 1 +# error "TRUE != 1" +#endif + ut_ad(roll_ptr < (1ULL << 56)); + *offset = (ulint) roll_ptr & 0xFFFF; + roll_ptr >>= 16; + *page_no = (ulint) roll_ptr & 0xFFFFFFFF; + roll_ptr >>= 32; + *rseg_id = (ulint) roll_ptr & 0x7F; + roll_ptr >>= 7; + *is_insert = (ibool) roll_ptr; /* TRUE==1 */ +} + +/***********************************************************************//** +Returns TRUE if the roll pointer is of the insert type. +@return TRUE if insert undo log */ +UNIV_INLINE +ibool +trx_undo_roll_ptr_is_insert( +/*========================*/ + roll_ptr_t roll_ptr) /*!< in: roll pointer */ +{ +#if DATA_ROLL_PTR_LEN != 7 +# error "DATA_ROLL_PTR_LEN != 7" +#endif +#if TRUE != 1 +# error "TRUE != 1" +#endif + ut_ad(roll_ptr < (1ULL << 56)); + return((ibool) (roll_ptr >> 55)); +} + +/***********************************************************************//** +Returns true if the record is of the insert type. +@return true if the record was freshly inserted (not updated). */ +UNIV_INLINE +bool +trx_undo_trx_id_is_insert( +/*======================*/ + const byte* trx_id) /*!< in: DB_TRX_ID, followed by DB_ROLL_PTR */ +{ +#if DATA_TRX_ID + 1 != DATA_ROLL_PTR +# error +#endif + return(static_cast<bool>(trx_id[DATA_TRX_ID_LEN] >> 7)); +} + +/*****************************************************************//** +Writes a roll ptr to an index page. In case that the size changes in +some future version, this function should be used instead of +mach_write_... */ +UNIV_INLINE +void +trx_write_roll_ptr( +/*===============*/ + byte* ptr, /*!< in: pointer to memory where + written */ + roll_ptr_t roll_ptr) /*!< in: roll ptr */ +{ +#if DATA_ROLL_PTR_LEN != 7 +# error "DATA_ROLL_PTR_LEN != 7" +#endif + mach_write_to_7(ptr, roll_ptr); +} + +/*****************************************************************//** +Reads a roll ptr from an index page. In case that the roll ptr size +changes in some future version, this function should be used instead of +mach_read_... +@return roll ptr */ +UNIV_INLINE +roll_ptr_t +trx_read_roll_ptr( +/*==============*/ + const byte* ptr) /*!< in: pointer to memory from where to read */ +{ +#if DATA_ROLL_PTR_LEN != 7 +# error "DATA_ROLL_PTR_LEN != 7" +#endif + return(mach_read_from_7(ptr)); +} + +/** Gets an undo log page and x-latches it. +@param[in] page_id page id +@param[in,out] mtr mini-transaction +@return pointer to page x-latched */ +UNIV_INLINE +page_t* +trx_undo_page_get(const page_id_t page_id, mtr_t* mtr) +{ + buf_block_t* block = buf_page_get(page_id, univ_page_size, + RW_X_LATCH, mtr); + + buf_block_dbg_add_level(block, SYNC_TRX_UNDO_PAGE); + + return(buf_block_get_frame(block)); +} + +/** Gets an undo log page and s-latches it. +@param[in] page_id page id +@param[in,out] mtr mini-transaction +@return pointer to page s-latched */ +UNIV_INLINE +page_t* +trx_undo_page_get_s_latched(const page_id_t page_id, mtr_t* mtr) +{ + buf_block_t* block = buf_page_get(page_id, univ_page_size, + RW_S_LATCH, mtr); + + buf_block_dbg_add_level(block, SYNC_TRX_UNDO_PAGE); + + return(buf_block_get_frame(block)); +} + +/******************************************************************//** +Returns the start offset of the undo log records of the specified undo +log on the page. +@return start offset */ +UNIV_INLINE +ulint +trx_undo_page_get_start( +/*====================*/ + page_t* undo_page,/*!< in: undo log page */ + ulint page_no,/*!< in: undo log header page number */ + ulint offset) /*!< in: undo log header offset on page */ +{ + ulint start; + + if (page_no == page_get_page_no(undo_page)) { + + start = mach_read_from_2(offset + undo_page + + TRX_UNDO_LOG_START); + } else { + start = TRX_UNDO_PAGE_HDR + TRX_UNDO_PAGE_HDR_SIZE; + } + + return(start); +} + +/******************************************************************//** +Returns the end offset of the undo log records of the specified undo +log on the page. +@return end offset */ +UNIV_INLINE +ulint +trx_undo_page_get_end( +/*==================*/ + page_t* undo_page,/*!< in: undo log page */ + ulint page_no,/*!< in: undo log header page number */ + ulint offset) /*!< in: undo log header offset on page */ +{ + trx_ulogf_t* log_hdr; + ulint end; + + if (page_no == page_get_page_no(undo_page)) { + + log_hdr = undo_page + offset; + + end = mach_read_from_2(log_hdr + TRX_UNDO_NEXT_LOG); + + if (end == 0) { + end = mach_read_from_2(undo_page + TRX_UNDO_PAGE_HDR + + TRX_UNDO_PAGE_FREE); + } + } else { + end = mach_read_from_2(undo_page + TRX_UNDO_PAGE_HDR + + TRX_UNDO_PAGE_FREE); + } + + return(end); +} + +/******************************************************************//** +Returns the previous undo record on the page in the specified log, or +NULL if none exists. +@return pointer to record, NULL if none */ +UNIV_INLINE +trx_undo_rec_t* +trx_undo_page_get_prev_rec( +/*=======================*/ + trx_undo_rec_t* rec, /*!< in: undo log record */ + ulint page_no,/*!< in: undo log header page number */ + ulint offset) /*!< in: undo log header offset on page */ +{ + page_t* undo_page; + ulint start; + + undo_page = (page_t*) ut_align_down(rec, UNIV_PAGE_SIZE); + + start = trx_undo_page_get_start(undo_page, page_no, offset); + + if (start + undo_page == rec) { + + return(NULL); + } + + return(undo_page + mach_read_from_2(rec - 2)); +} + +/******************************************************************//** +Returns the next undo log record on the page in the specified log, or +NULL if none exists. +@return pointer to record, NULL if none */ +UNIV_INLINE +trx_undo_rec_t* +trx_undo_page_get_next_rec( +/*=======================*/ + trx_undo_rec_t* rec, /*!< in: undo log record */ + ulint page_no,/*!< in: undo log header page number */ + ulint offset) /*!< in: undo log header offset on page */ +{ + page_t* undo_page; + ulint end; + ulint next; + + undo_page = (page_t*) ut_align_down(rec, UNIV_PAGE_SIZE); + + end = trx_undo_page_get_end(undo_page, page_no, offset); + + next = mach_read_from_2(rec); + + if (next == end) { + + return(NULL); + } + + return(undo_page + next); +} + +/******************************************************************//** +Returns the last undo record on the page in the specified undo log, or +NULL if none exists. +@return pointer to record, NULL if none */ +UNIV_INLINE +trx_undo_rec_t* +trx_undo_page_get_last_rec( +/*=======================*/ + page_t* undo_page,/*!< in: undo log page */ + ulint page_no,/*!< in: undo log header page number */ + ulint offset) /*!< in: undo log header offset on page */ +{ + ulint start; + ulint end; + + start = trx_undo_page_get_start(undo_page, page_no, offset); + end = trx_undo_page_get_end(undo_page, page_no, offset); + + if (start == end) { + + return(NULL); + } + + return(undo_page + mach_read_from_2(undo_page + end - 2)); +} + +/******************************************************************//** +Returns the first undo record on the page in the specified undo log, or +NULL if none exists. +@return pointer to record, NULL if none */ +UNIV_INLINE +trx_undo_rec_t* +trx_undo_page_get_first_rec( +/*========================*/ + page_t* undo_page,/*!< in: undo log page */ + ulint page_no,/*!< in: undo log header page number */ + ulint offset) /*!< in: undo log header offset on page */ +{ + ulint start; + ulint end; + + start = trx_undo_page_get_start(undo_page, page_no, offset); + end = trx_undo_page_get_end(undo_page, page_no, offset); + + if (start == end) { + + return(NULL); + } + + return(undo_page + start); +} |