diff options
author | Marko Mäkelä <marko.makela@mariadb.com> | 2019-12-03 10:19:45 +0200 |
---|---|---|
committer | Marko Mäkelä <marko.makela@mariadb.com> | 2019-12-03 11:05:18 +0200 |
commit | 56f6dab1d0e5a464ea49c1e5efb0032a0f5cea3e (patch) | |
tree | e4c57ce4c3235cf512f5cf74e8031b9d041e510c /storage/innobase/include | |
parent | 504823bcce5926bd5a20b8b8f202ed479ff6d750 (diff) | |
download | mariadb-git-56f6dab1d0e5a464ea49c1e5efb0032a0f5cea3e.tar.gz |
MDEV-21174: Replace mlog_write_ulint() with mtr_t::write()
mtr_t::write(): Replaces mlog_write_ulint(), mlog_write_ull().
Optimize away writes if the page contents does not change,
except when a dummy write has been explicitly requested.
Because the member function template takes a block descriptor as a
parameter, it is possible to introduce better consistency checks.
Due to this, the code for handling file-based lists, undo logs
and user transactions was refactored to pass around buf_block_t.
Diffstat (limited to 'storage/innobase/include')
22 files changed, 439 insertions, 684 deletions
diff --git a/storage/innobase/include/btr0btr.h b/storage/innobase/include/btr0btr.h index e1b3158f997..c2d7c786bc5 100644 --- a/storage/innobase/include/btr0btr.h +++ b/storage/innobase/include/btr0btr.h @@ -541,7 +541,7 @@ inline void btr_set_min_rec_mark(rec_t *rec, const buf_block_t &block, page. We are not modifying the compressed page frame at all. */ *rec|= REC_INFO_MIN_REC_FLAG; else - mlog_write_ulint(rec, *rec | REC_INFO_MIN_REC_FLAG, MLOG_1BYTE, mtr); + mtr->write<1>(block, rec, *rec | REC_INFO_MIN_REC_FLAG); } /** Seek to the parent page of a B-tree page. diff --git a/storage/innobase/include/btr0btr.ic b/storage/innobase/include/btr0btr.ic index e06127efaa3..427bd130b79 100644 --- a/storage/innobase/include/btr0btr.ic +++ b/storage/innobase/include/btr0btr.ic @@ -30,28 +30,6 @@ Created 6/2/1994 Heikki Tuuri #include "page0zip.h" /**************************************************************//** -Sets the index id field of a page. */ -UNIV_INLINE -void -btr_page_set_index_id( -/*==================*/ - page_t* page, /*!< in: page to be created */ - page_zip_des_t* page_zip,/*!< in: compressed page whose uncompressed - part will be updated, or NULL */ - index_id_t id, /*!< in: index id */ - mtr_t* mtr) /*!< in: mtr */ -{ - if (page_zip) { - mach_write_to_8(page + (PAGE_HEADER + PAGE_INDEX_ID), id); - page_zip_write_header(page_zip, - page + (PAGE_HEADER + PAGE_INDEX_ID), - 8, mtr); - } else { - mlog_write_ull(page + (PAGE_HEADER + PAGE_INDEX_ID), id, mtr); - } -} - -/**************************************************************//** Gets the index id field of a page. @return index id */ UNIV_INLINE @@ -63,77 +41,56 @@ btr_page_get_index_id( return(mach_read_from_8(page + PAGE_HEADER + PAGE_INDEX_ID)); } -/********************************************************//** -Sets the node level field in an index page. */ -UNIV_INLINE -void -btr_page_set_level( -/*===============*/ - page_t* page, /*!< in: index page */ - page_zip_des_t* page_zip,/*!< in: compressed page whose uncompressed - part will be updated, or NULL */ - ulint level, /*!< in: level, leaf level == 0 */ - mtr_t* mtr) /*!< in: mini-transaction handle */ +/** Set PAGE_LEVEL. +@param[in,out] block buffer block +@param[in] level page level +@param[in,out] mtr mini-transaction */ +inline +void btr_page_set_level(buf_block_t *block, ulint level, mtr_t *mtr) { - ut_ad(page != NULL); - ut_ad(mtr != NULL); - ut_ad(level <= BTR_MAX_NODE_LEVEL); - - if (page_zip) { - mach_write_to_2(page + (PAGE_HEADER + PAGE_LEVEL), level); - page_zip_write_header(page_zip, - page + (PAGE_HEADER + PAGE_LEVEL), - 2, mtr); - } else { - mlog_write_ulint(page + (PAGE_HEADER + PAGE_LEVEL), level, - MLOG_2BYTES, mtr); - } + ut_ad(level <= BTR_MAX_NODE_LEVEL); + + byte *page_level= PAGE_HEADER + PAGE_LEVEL + block->frame; + + if (UNIV_LIKELY_NULL(block->page.zip.data)) + { + mach_write_to_2(page_level, level); + page_zip_write_header(&block->page.zip, page_level, 2, mtr); + } + else + mtr->write<2,mtr_t::OPT>(*block, page_level, level); } -/********************************************************//** -Sets the next index page field. */ -UNIV_INLINE -void -btr_page_set_next( -/*==============*/ - page_t* page, /*!< in: index page */ - page_zip_des_t* page_zip,/*!< in: compressed page whose uncompressed - part will be updated, or NULL */ - ulint next, /*!< in: next page number */ - mtr_t* mtr) /*!< in: mini-transaction handle */ +/** Set FIL_PAGE_NEXT. +@param[in,out] block buffer block +@param[in] next number of successor page +@param[in,out] mtr mini-transaction */ +inline void btr_page_set_next(buf_block_t *block, ulint next, mtr_t *mtr) { - ut_ad(page != NULL); - ut_ad(mtr != NULL); - - if (page_zip) { - mach_write_to_4(page + FIL_PAGE_NEXT, next); - page_zip_write_header(page_zip, page + FIL_PAGE_NEXT, 4, mtr); - } else { - mlog_write_ulint(page + FIL_PAGE_NEXT, next, MLOG_4BYTES, mtr); - } + byte *fil_page_next= block->frame + FIL_PAGE_NEXT; + if (UNIV_LIKELY_NULL(block->page.zip.data)) + { + mach_write_to_4(fil_page_next, next); + page_zip_write_header(&block->page.zip, fil_page_next, 4, mtr); + } + else + mtr->write<4>(*block, fil_page_next, next); } -/********************************************************//** -Sets the previous index page field. */ -UNIV_INLINE -void -btr_page_set_prev( -/*==============*/ - page_t* page, /*!< in: index page */ - page_zip_des_t* page_zip,/*!< in: compressed page whose uncompressed - part will be updated, or NULL */ - ulint prev, /*!< in: previous page number */ - mtr_t* mtr) /*!< in: mini-transaction handle */ +/** Set FIL_PAGE_PREV. +@param[in,out] block buffer block +@param[in] prev number of predecessor page +@param[in,out] mtr mini-transaction */ +inline void btr_page_set_prev(buf_block_t *block, ulint prev, mtr_t *mtr) { - ut_ad(page != NULL); - ut_ad(mtr != NULL); - - if (page_zip) { - mach_write_to_4(page + FIL_PAGE_PREV, prev); - page_zip_write_header(page_zip, page + FIL_PAGE_PREV, 4, mtr); - } else { - mlog_write_ulint(page + FIL_PAGE_PREV, prev, MLOG_4BYTES, mtr); - } + byte *fil_page_prev= block->frame + FIL_PAGE_PREV; + if (UNIV_LIKELY_NULL(block->page.zip.data)) + { + mach_write_to_4(fil_page_prev, prev); + page_zip_write_header(&block->page.zip, fil_page_prev, 4, mtr); + } + else + mtr->write<4>(*block, fil_page_prev, prev); } /**************************************************************//** diff --git a/storage/innobase/include/btr0bulk.h b/storage/innobase/include/btr0bulk.h index d1a8af22d68..6bed9e47b17 100644 --- a/storage/innobase/include/btr0bulk.h +++ b/storage/innobase/include/btr0bulk.h @@ -101,11 +101,25 @@ public: /** Insert a record in the page. @param[in] rec record @param[in] offsets record offsets */ - void insert(const rec_t* rec, ulint* offsets); + inline void insert(const rec_t* rec, ulint* offsets); +private: + /** Page format */ + enum format { REDUNDANT, DYNAMIC, COMPRESSED }; + /** Mark end of insertion to the page. Scan all records to set page + dirs, and set page header members. + @tparam format the page format */ + template<format> inline void finishPage(); + /** Insert a record in the page. + @tparam format the page format + @param[in] rec record + @param[in] offsets record offsets */ + template<format> inline void insertPage(const rec_t* rec, + ulint* offsets); +public: /** Mark end of insertion to the page. Scan all records to set page dirs, and set page header members. */ - void finish(); + inline void finish(); /** Commit mtr for a page @param[in] success Flag whether all inserts succeed. */ @@ -199,6 +213,8 @@ public: return(m_err); } + void set_modified() { m_mtr.set_modified(); } + /* Memory heap for internal allocation */ mem_heap_t* m_heap; diff --git a/storage/innobase/include/btr0cur.h b/storage/innobase/include/btr0cur.h index bcdbb08e81f..659232bc7fc 100644 --- a/storage/innobase/include/btr0cur.h +++ b/storage/innobase/include/btr0cur.h @@ -646,8 +646,7 @@ to free the field. */ void btr_cur_disown_inherited_fields( /*============================*/ - page_zip_des_t* page_zip,/*!< in/out: compressed page whose uncompressed - part will be updated, or NULL */ + buf_block_t* block, /*!< in/out: index page */ rec_t* rec, /*!< in/out: record in a clustered index */ dict_index_t* index, /*!< in: index of the page */ const ulint* offsets,/*!< in: array returned by rec_get_offsets() */ @@ -722,12 +721,12 @@ btr_free_externally_stored_field( page_zip_write_blob_ptr(), or NULL */ const ulint* offsets, /*!< in: rec_get_offsets(rec, index), or NULL */ - page_zip_des_t* page_zip, /*!< in: compressed page corresponding - to rec, or NULL if rec == NULL */ + buf_block_t* block, /*!< in/out: page of field_ref */ ulint i, /*!< in: field number of field_ref; ignored if rec == NULL */ bool rollback, /*!< in: performing rollback? */ - mtr_t* local_mtr); /*!< in: mtr containing the latch */ + mtr_t* local_mtr) /*!< in: mtr containing the latch */ + MY_ATTRIBUTE((nonnull(1,2,5,8))); /** Copies the prefix of an externally stored field of a record. The clustered index record must be protected by a lock or a page latch. diff --git a/storage/innobase/include/buf0buf.h b/storage/innobase/include/buf0buf.h index a8a37dfd0a2..3253b864786 100644 --- a/storage/innobase/include/buf0buf.h +++ b/storage/innobase/include/buf0buf.h @@ -717,16 +717,6 @@ inline void aligned_free(void *ptr) } /**********************************************************************//** -Gets the space id, page offset, and byte offset within page of a -pointer pointing to a buffer frame containing a file page. */ -UNIV_INLINE -void -buf_ptr_get_fsp_addr( -/*=================*/ - const void* ptr, /*!< in: pointer to a buffer frame */ - ulint* space, /*!< out: space id */ - fil_addr_t* addr); /*!< out: page offset and byte offset */ -/**********************************************************************//** Gets the hash value of a block. This can be used in searches in the lock hash table. @return lock hash value */ @@ -1094,9 +1084,9 @@ buf_block_get_frame( Gets the compressed page descriptor corresponding to an uncompressed page if applicable. */ #define buf_block_get_page_zip(block) \ - ((block)->page.zip.data ? &(block)->page.zip : NULL) + (UNIV_LIKELY_NULL((block)->page.zip.data) ? &(block)->page.zip : NULL) #define is_buf_block_get_page_zip(block) \ - ((block)->page.zip.data != 0) + UNIV_LIKELY_NULL((block)->page.zip.data) #ifdef BTR_CUR_HASH_ADAPT /** Get a buffer block from an adaptive hash index pointer. diff --git a/storage/innobase/include/buf0buf.ic b/storage/innobase/include/buf0buf.ic index 59672dc3295..45cafcdf3fe 100644 --- a/storage/innobase/include/buf0buf.ic +++ b/storage/innobase/include/buf0buf.ic @@ -759,25 +759,6 @@ buf_frame_align( } /**********************************************************************//** -Gets the space id, page offset, and byte offset within page of a -pointer pointing to a buffer frame containing a file page. */ -UNIV_INLINE -void -buf_ptr_get_fsp_addr( -/*=================*/ - const void* ptr, /*!< in: pointer to a buffer frame */ - ulint* space, /*!< out: space id */ - fil_addr_t* addr) /*!< out: page offset and byte offset */ -{ - const page_t* page = (const page_t*) ut_align_down(ptr, - srv_page_size); - - *space = mach_read_from_4(page + FIL_PAGE_ARCH_LOG_NO_OR_SPACE_ID); - addr->page = mach_read_from_4(page + FIL_PAGE_OFFSET); - addr->boffset = static_cast<uint16_t>(ut_align_offset(ptr, srv_page_size)); -} - -/**********************************************************************//** Gets the hash value of the page the pointer is pointing to. This can be used in searches in the lock hash table. @return lock hash value */ diff --git a/storage/innobase/include/dict0boot.h b/storage/innobase/include/dict0boot.h index 778471b77ae..3144303c1a1 100644 --- a/storage/innobase/include/dict0boot.h +++ b/storage/innobase/include/dict0boot.h @@ -1,7 +1,7 @@ /***************************************************************************** Copyright (c) 1996, 2016, Oracle and/or its affiliates. All Rights Reserved. -Copyright (c) 2018, MariaDB Corporation. +Copyright (c) 2018, 2019, 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 @@ -33,15 +33,8 @@ Created 4/18/1996 Heikki Tuuri #include "buf0buf.h" #include "dict0dict.h" -typedef byte dict_hdr_t; - -/**********************************************************************//** -Gets a pointer to the dictionary header and x-latches its page. -@return pointer to the dictionary header, page x-latched */ -dict_hdr_t* -dict_hdr_get( -/*=========*/ - mtr_t* mtr); /*!< in: mtr */ +/** @return the DICT_HDR block, x-latched */ +buf_block_t *dict_hdr_get(mtr_t* mtr); /**********************************************************************//** Returns a new table, index, or space id. */ void diff --git a/storage/innobase/include/fsp0fsp.h b/storage/innobase/include/fsp0fsp.h index a87f1fb2fe6..71b1ed6a3f1 100644 --- a/storage/innobase/include/fsp0fsp.h +++ b/storage/innobase/include/fsp0fsp.h @@ -101,7 +101,6 @@ see the table in fsp0types.h @{ */ #define FSP_HEADER_OFFSET FIL_PAGE_DATA /* The data structures in files are defined just as byte strings in C */ -typedef byte fsp_header_t; typedef byte xdes_t; /* SPACE HEADER @@ -207,7 +206,7 @@ typedef byte fseg_inode_t; (16 + 3 * FLST_BASE_NODE_SIZE \ + FSEG_FRAG_ARR_N_SLOTS * FSEG_FRAG_SLOT_SIZE) -#define FSEG_MAGIC_N_VALUE 97937874 +static constexpr uint32_t FSEG_MAGIC_N_VALUE= 97937874; #define FSEG_FILLFACTOR 8 /* If this value is x, then if the number of unused but reserved @@ -534,7 +533,7 @@ by repeatedly calling this function in different mini-transactions. Doing the freeing in a single mini-transaction might result in too big a mini-transaction. @return TRUE if freeing completed */ -ibool +bool fseg_free_step_func( fseg_header_t* header, /*!< in, own: segment header; NOTE: if the header resides on the first page of the frag list @@ -554,8 +553,8 @@ fseg_free_step_func( /**********************************************************************//** Frees part of a segment. Differs from fseg_free_step because this function leaves the header page unfreed. -@return TRUE if freeing completed, except the header page */ -ibool +@return true if freeing completed, except the header page */ +bool fseg_free_step_not_header_func( fseg_header_t* header, /*!< in: segment header which must reside on the first fragment page of the segment */ diff --git a/storage/innobase/include/fut0lst.h b/storage/innobase/include/fut0lst.h index d009e5b050a..d1205a41251 100644 --- a/storage/innobase/include/fut0lst.h +++ b/storage/innobase/include/fut0lst.h @@ -68,79 +68,91 @@ typedef byte flst_node_t; @param[in,out] block file page @param[in] ofs byte offset of the list base node @param[in,out] mtr mini-transaction */ -inline void flst_init(buf_block_t* block, uint16_t ofs, mtr_t* mtr) +inline void flst_init(const buf_block_t* block, uint16_t ofs, mtr_t* mtr) { - ut_ad(0 == mach_read_from_2(FLST_LEN + ofs + block->frame)); - ut_ad(0 == mach_read_from_2(FLST_FIRST + FIL_ADDR_BYTE + ofs - + block->frame)); - ut_ad(0 == mach_read_from_2(FLST_LAST + FIL_ADDR_BYTE + ofs - + block->frame)); - compile_time_assert(FIL_NULL == 0xffU * 0x1010101U); - mlog_memset(block, FLST_FIRST + FIL_ADDR_PAGE + ofs, 4, 0xff, mtr); - mlog_memset(block, FLST_LAST + FIL_ADDR_PAGE + ofs, 4, 0xff, mtr); + ut_ad(!mach_read_from_2(FLST_LEN + ofs + block->frame)); + ut_ad(!mach_read_from_2(FLST_FIRST + FIL_ADDR_BYTE + ofs + block->frame)); + ut_ad(!mach_read_from_2(FLST_LAST + FIL_ADDR_BYTE + ofs + block->frame)); + compile_time_assert(FIL_NULL == 0xffU * 0x1010101U); + mlog_memset(block, FLST_FIRST + FIL_ADDR_PAGE + ofs, 4, 0xff, mtr); + mlog_memset(block, FLST_LAST + FIL_ADDR_PAGE + ofs, 4, 0xff, mtr); } /** Write a null file address. -@param[in,out] faddr file address to be zeroed otu -@param[in,out] mtr mini-transaction */ -inline void flst_zero_addr(fil_faddr_t* faddr, mtr_t* mtr) +@param[in] b file page +@param[in,out] addr file address to be zeroed out +@param[in,out] mtr mini-transaction */ +inline void flst_zero_addr(const buf_block_t& b, fil_faddr_t *addr, mtr_t *mtr) +{ + if (mach_read_from_4(addr + FIL_ADDR_PAGE) != FIL_NULL) + mlog_memset(&b, ulint(addr - b.frame) + FIL_ADDR_PAGE, 4, 0xff, mtr); + mtr->write<2,mtr_t::OPT>(b, addr + FIL_ADDR_BYTE, 0U); +} + +/** Write a file address. +@param[in] block file page +@param[in,out] faddr file address location +@param[in] addr file address to be written out +@param[in,out] mtr mini-transaction */ +inline void flst_write_addr(const buf_block_t& block, fil_faddr_t *faddr, + fil_addr_t addr, mtr_t* mtr) +{ + ut_ad(mtr->memo_contains_page_flagged(faddr, + MTR_MEMO_PAGE_X_FIX + | MTR_MEMO_PAGE_SX_FIX)); + ut_a(addr.page == FIL_NULL || addr.boffset >= FIL_PAGE_DATA); + ut_a(ut_align_offset(faddr, srv_page_size) >= FIL_PAGE_DATA); + + mtr->write<4,mtr_t::OPT>(block, faddr + FIL_ADDR_PAGE, addr.page); + mtr->write<2,mtr_t::OPT>(block, faddr + FIL_ADDR_BYTE, addr.boffset); +} + +/** Initialize a list base node. +@param[in] block file page +@param[in,out] base base node +@param[in,out] mtr mini-transaction */ +inline void flst_init(const buf_block_t& block, byte *base, mtr_t *mtr) { - if (mach_read_from_4(faddr + FIL_ADDR_PAGE) != FIL_NULL) { - mlog_memset(faddr + FIL_ADDR_PAGE, 4, 0xff, mtr); - } - if (mach_read_from_2(faddr + FIL_ADDR_BYTE)) { - mlog_write_ulint(faddr + FIL_ADDR_BYTE, 0, MLOG_2BYTES, mtr); - } + ut_ad(mtr->memo_contains_page_flagged(base, MTR_MEMO_PAGE_X_FIX | + MTR_MEMO_PAGE_SX_FIX)); + mtr->write<4,mtr_t::OPT>(block, base + FLST_LEN, 0U); + flst_zero_addr(block, base + FLST_FIRST, mtr); + flst_zero_addr(block, base + FLST_LAST, mtr); } -/********************************************************************//** -Initializes a list base node. */ -UNIV_INLINE -void -flst_init( -/*======*/ - flst_base_node_t* base, /*!< in: pointer to base node */ - mtr_t* mtr); /*!< in: mini-transaction handle */ -/********************************************************************//** -Adds a node as the last node in a list. */ -void -flst_add_last( -/*==========*/ - flst_base_node_t* base, /*!< in: pointer to base node of list */ - flst_node_t* node, /*!< in: node to add */ - mtr_t* mtr); /*!< in: mini-transaction handle */ -/********************************************************************//** -Adds a node as the first node in a list. */ -void -flst_add_first( -/*===========*/ - flst_base_node_t* base, /*!< in: pointer to base node of list */ - flst_node_t* node, /*!< in: node to add */ - mtr_t* mtr); /*!< in: mini-transaction handle */ -/********************************************************************//** -Removes a node. */ -void -flst_remove( -/*========*/ - flst_base_node_t* base, /*!< in: pointer to base node of list */ - flst_node_t* node2, /*!< in: node to remove */ - mtr_t* mtr); /*!< in: mini-transaction handle */ -/** Get the length of a list. -@param[in] base base node -@return length */ -UNIV_INLINE -uint32_t -flst_get_len( - const flst_base_node_t* base); -/********************************************************************//** -Writes a file address. */ -UNIV_INLINE -void -flst_write_addr( -/*============*/ - fil_faddr_t* faddr, /*!< in: pointer to file faddress */ - fil_addr_t addr, /*!< in: file address */ - mtr_t* mtr); /*!< in: mini-transaction handle */ +/** Append a file list node to a list. +@param[in,out] base base node block +@param[in] boffset byte offset of the base node +@param[in,out] add block to be added +@param[in] aoffset byte offset of the node to be added +@param[in,outr] mtr mini-transaction */ +void flst_add_last(buf_block_t *base, uint16_t boffset, + buf_block_t *add, uint16_t aoffset, mtr_t *mtr) + MY_ATTRIBUTE((nonnull)); +/** Prepend a file list node to a list. +@param[in,out] base base node block +@param[in] boffset byte offset of the base node +@param[in,out] add block to be added +@param[in] aoffset byte offset of the node to be added +@param[in,outr] mtr mini-transaction */ +void flst_add_first(buf_block_t *base, uint16_t boffset, + buf_block_t *add, uint16_t aoffset, mtr_t *mtr) + MY_ATTRIBUTE((nonnull)); +/** Remove a file list node. +@param[in,out] base base node block +@param[in] boffset byte offset of the base node +@param[in,out] cur block to be removed +@param[in] coffset byte offset of the current record to be removed +@param[in,outr] mtr mini-transaction */ +void flst_remove(buf_block_t *base, uint16_t boffset, + buf_block_t *cur, uint16_t coffset, mtr_t *mtr) + MY_ATTRIBUTE((nonnull)); + +/** @return the length of a list */ +inline uint32_t flst_get_len(const flst_base_node_t *base) +{ + return mach_read_from_4(base + FLST_LEN); +} /** @return a file address */ inline fil_addr_t flst_read_addr(const fil_faddr_t *faddr) @@ -176,16 +188,10 @@ inline fil_addr_t flst_get_prev_addr(const flst_node_t *node) return flst_read_addr(node + FLST_PREV); } -/********************************************************************//** -Validates a file-based list. -@return TRUE if ok */ -ibool -flst_validate( -/*==========*/ - const flst_base_node_t* base, /*!< in: pointer to base node of list */ - mtr_t* mtr1); /*!< in: mtr */ - -#include "fut0lst.ic" +#ifdef UNIV_DEBUG +/** Validate a file-based list. */ +void flst_validate(const buf_block_t *base, uint16_t boffset, mtr_t *mtr); +#endif #endif /* !UNIV_INNOCHECKSUM */ diff --git a/storage/innobase/include/fut0lst.ic b/storage/innobase/include/fut0lst.ic deleted file mode 100644 index b672001f660..00000000000 --- a/storage/innobase/include/fut0lst.ic +++ /dev/null @@ -1,80 +0,0 @@ -/***************************************************************************** - -Copyright (c) 1995, 2014, Oracle and/or its affiliates. All Rights Reserved. -Copyright (c) 2019, 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/fut0lst.ic -File-based list utilities - -Created 11/28/1995 Heikki Tuuri -***********************************************************************/ - -#include "buf0buf.h" - -/********************************************************************//** -Writes a file address. */ -UNIV_INLINE -void -flst_write_addr( -/*============*/ - fil_faddr_t* faddr, /*!< in: pointer to file faddress */ - fil_addr_t addr, /*!< in: file address */ - mtr_t* mtr) /*!< in: mini-transaction handle */ -{ - ut_ad(faddr && mtr); - ut_ad(mtr_memo_contains_page_flagged(mtr, faddr, - MTR_MEMO_PAGE_X_FIX - | MTR_MEMO_PAGE_SX_FIX)); - ut_a(addr.page == FIL_NULL || addr.boffset >= FIL_PAGE_DATA); - ut_a(ut_align_offset(faddr, srv_page_size) >= FIL_PAGE_DATA); - - mlog_write_ulint(faddr + FIL_ADDR_PAGE, addr.page, MLOG_4BYTES, mtr); - mlog_write_ulint(faddr + FIL_ADDR_BYTE, addr.boffset, - MLOG_2BYTES, mtr); -} - -/********************************************************************//** -Initializes a list base node. */ -UNIV_INLINE -void -flst_init( -/*======*/ - flst_base_node_t* base, /*!< in: pointer to base node */ - mtr_t* mtr) /*!< in: mini-transaction handle */ -{ - ut_ad(mtr_memo_contains_page_flagged(mtr, base, - MTR_MEMO_PAGE_X_FIX - | MTR_MEMO_PAGE_SX_FIX)); - - if (mach_read_from_4(base + FLST_LEN)) { - mlog_write_ulint(base + FLST_LEN, 0, MLOG_4BYTES, mtr); - } - flst_zero_addr(base + FLST_FIRST, mtr); - flst_zero_addr(base + FLST_LAST, mtr); -} - -/** Get the length of a list. -@param[in] base base node -@return length */ -UNIV_INLINE -uint32_t -flst_get_len( - const flst_base_node_t* base) -{ - return(mach_read_from_4(base + FLST_LEN)); -} diff --git a/storage/innobase/include/mtr0log.h b/storage/innobase/include/mtr0log.h index 6ebf834456c..8742e55b51a 100644 --- a/storage/innobase/include/mtr0log.h +++ b/storage/innobase/include/mtr0log.h @@ -34,26 +34,6 @@ Created 12/7/1995 Heikki Tuuri struct dict_index_t; /********************************************************//** -Writes 1, 2 or 4 bytes to a file page. Writes the corresponding log -record to the mini-transaction log if mtr is not NULL. */ -void -mlog_write_ulint( -/*=============*/ - byte* ptr, /*!< in: pointer where to write */ - ulint val, /*!< in: value to write */ - mlog_id_t type, /*!< in: MLOG_1BYTE, MLOG_2BYTES, MLOG_4BYTES */ - mtr_t* mtr); /*!< in: mini-transaction handle */ - -/********************************************************//** -Writes 8 bytes to a file page. Writes the corresponding log -record to the mini-transaction log, only if mtr is not NULL */ -void -mlog_write_ull( -/*===========*/ - byte* ptr, /*!< in: pointer where to write */ - ib_uint64_t val, /*!< in: value to write */ - mtr_t* mtr); /*!< in: mini-transaction handle */ -/********************************************************//** Writes a string to a file page buffered in the buffer pool. Writes the corresponding log record to the mini-transaction log. */ void @@ -80,7 +60,7 @@ mlog_log_string( @param[in] val the data byte to write @param[in,out] mtr mini-transaction */ void -mlog_memset(buf_block_t* b, ulint ofs, ulint len, byte val, mtr_t* mtr); +mlog_memset(const buf_block_t* b, ulint ofs, ulint len, byte val, mtr_t* mtr); /** Initialize a string of bytes. @param[in,out] byte byte address @@ -124,14 +104,6 @@ mlog_catenate_ulint_compressed( mtr_t* mtr, /*!< in: mtr */ ulint val); /*!< in: value to write */ /********************************************************//** -Catenates a compressed 64-bit integer to mlog. */ -UNIV_INLINE -void -mlog_catenate_ull_compressed( -/*=========================*/ - mtr_t* mtr, /*!< in: mtr */ - ib_uint64_t val); /*!< in: value to write */ -/********************************************************//** Opens a buffer to mlog. It must be closed with mlog_close. @return buffer, NULL if log mode MTR_LOG_NONE */ UNIV_INLINE @@ -151,6 +123,56 @@ mlog_close( byte* ptr); /*!< in: buffer space from ptr up was not used */ +/** Write 1, 2, 4, or 8 bytes to a file page. +@param[in] block file page +@param[in,out] ptr pointer in file page +@param[in] val value to write +@tparam l number of bytes to write +@tparam w write request type +@tparam V type of val */ +template<unsigned l,mtr_t::write_type w,typename V> +inline void mtr_t::write(const buf_block_t &block, byte *ptr, V val) +{ + ut_ad(ut_align_down(ptr, srv_page_size) == block.frame); + ut_ad(m_log_mode == MTR_LOG_NONE || m_log_mode == MTR_LOG_NO_REDO || + !block.page.zip.data || + /* written by fil_crypt_rotate_page() or innodb_make_page_dirty()? */ + (w == FORCED && l == 1 && ptr == &block.frame[FIL_PAGE_SPACE_ID]) || + mach_read_from_2(block.frame + FIL_PAGE_TYPE) <= FIL_PAGE_TYPE_ZBLOB2); + static_assert(l == 1 || l == 2 || l == 4 || l == 8, "wrong length"); + + switch (l) { + case 1: + if (w == OPT && mach_read_from_1(ptr) == val) return; + ut_ad(w != NORMAL || mach_read_from_1(ptr) != val); + mach_write_to_1(ptr, val); + break; + case 2: + if (w == OPT && mach_read_from_2(ptr) == val) return; + ut_ad(w != NORMAL || mach_read_from_2(ptr) != val); + mach_write_to_2(ptr, val); + break; + case 4: + if (w == OPT && mach_read_from_4(ptr) == val) return; + ut_ad(w != NORMAL || mach_read_from_4(ptr) != val); + mach_write_to_4(ptr, val); + break; + case 8: + if (w == OPT && mach_read_from_8(ptr) == val) return; + ut_ad(w != NORMAL || mach_read_from_8(ptr) != val); + mach_write_to_8(ptr, val); + break; + } + byte *log_ptr= mlog_open(this, 11 + 2 + (l == 8 ? 9 : 5)); + if (!log_ptr) + return; + if (l == 8) + log_write(block, ptr, static_cast<mlog_id_t>(l), log_ptr, uint64_t{val}); + else + log_write(block, ptr, static_cast<mlog_id_t>(l), log_ptr, + static_cast<uint32_t>(val)); +} + /** Writes a log record about an operation. @param[in] type redo log record type @param[in] space_id tablespace identifier @@ -195,7 +217,7 @@ mlog_parse_initial_log_record( ulint* space, /*!< out: space id */ ulint* page_no);/*!< out: page number */ /********************************************************//** -Parses a log record written by mlog_write_ulint, mlog_write_ull, mlog_memset. +Parses a log record written by mtr_t::write(), mlog_memset(). @return parsed record end, NULL if not a complete record */ const byte* mlog_parse_nbytes( diff --git a/storage/innobase/include/mtr0log.ic b/storage/innobase/include/mtr0log.ic index 371d9ec905d..d493c0959a9 100644 --- a/storage/innobase/include/mtr0log.ic +++ b/storage/innobase/include/mtr0log.ic @@ -141,30 +141,6 @@ mlog_catenate_ulint_compressed( mlog_close(mtr, log_ptr); } -/********************************************************//** -Catenates a compressed 64-bit integer to mlog. */ -UNIV_INLINE -void -mlog_catenate_ull_compressed( -/*=========================*/ - mtr_t* mtr, /*!< in: mtr */ - ib_uint64_t val) /*!< in: value to write */ -{ - byte* log_ptr; - - log_ptr = mlog_open(mtr, 15); - - /* If no logging is requested, we may return now */ - if (log_ptr == NULL) { - - return; - } - - log_ptr += mach_u64_write_compressed(log_ptr, val); - - mlog_close(mtr, log_ptr); -} - /** Writes a log record about an operation. @param[in] type redo log record type @param[in] space_id tablespace identifier diff --git a/storage/innobase/include/mtr0mtr.h b/storage/innobase/include/mtr0mtr.h index ee1e3eadd71..f7df66f0ea4 100644 --- a/storage/innobase/include/mtr0mtr.h +++ b/storage/innobase/include/mtr0mtr.h @@ -425,7 +425,50 @@ struct mtr_t { static inline bool is_block_dirtied(const buf_block_t* block) MY_ATTRIBUTE((warn_unused_result)); + /** Write request types */ + enum write_type + { + /** the page is guaranteed to always change */ + NORMAL= 0, + /** optional: the page contents might not change */ + OPT, + /** force a write, even if the page contents is not changing */ + FORCED + }; + + /** Write 1, 2, 4, or 8 bytes to a file page. + @param[in] block file page + @param[in,out] ptr pointer in file page + @param[in] val value to write + @tparam l number of bytes to write + @tparam w write request type + @tparam V type of val */ + template<unsigned l,write_type w= NORMAL,typename V> + inline void write(const buf_block_t &block, byte *ptr, V val) + MY_ATTRIBUTE((nonnull)); + private: + /** + Write a log record for writing 1, 2, or 4 bytes. + @param[in] block file page + @param[in,out] ptr pointer in file page + @param[in] l number of bytes to write + @param[in,out] log_ptr log record buffer + @param[in] val value to write */ + void log_write(const buf_block_t &block, byte *ptr, mlog_id_t l, + byte *log_ptr, uint32_t val) + MY_ATTRIBUTE((nonnull)); + /** + Write a log record for writing 8 bytes. + @param[in] block file page + @param[in,out] ptr pointer in file page + @param[in] l number of bytes to write (8) + @param[in,out] log_ptr log record buffer + @param[in] val value to write */ + void log_write(const buf_block_t &block, byte *ptr, mlog_id_t l, + byte *log_ptr, uint64_t val) + MY_ATTRIBUTE((nonnull)); + /** Prepare to write the mini-transaction log to the redo log buffer. @return number of bytes to write in finish_write() */ inline ulint prepare_write(); diff --git a/storage/innobase/include/mtr0types.h b/storage/innobase/include/mtr0types.h index 7b5fd457d9f..06ac4a62e78 100644 --- a/storage/innobase/include/mtr0types.h +++ b/storage/innobase/include/mtr0types.h @@ -52,7 +52,7 @@ enum mtr_log_t { /** @name Log item types The log items are declared 'byte' so that the compiler can warn if val -and type parameters are switched in a call to mlog_write_ulint. NOTE! +and type parameters are switched in a call to mlog_write. NOTE! For 1 - 8 bytes, the flag value must give the length also! @{ */ enum mlog_id_t { /** if the mtr contains only one log record for one page, diff --git a/storage/innobase/include/page0page.h b/storage/innobase/include/page0page.h index 7c9f85c47c7..a438d111086 100644 --- a/storage/innobase/include/page0page.h +++ b/storage/innobase/include/page0page.h @@ -31,6 +31,7 @@ Created 2/2/1994 Heikki Tuuri #include "fil0fil.h" #include "buf0buf.h" #include "rem0rec.h" +#include "mach0data.h" #ifndef UNIV_INNOCHECKSUM #include "dict0dict.h" #include "data0data.h" @@ -42,8 +43,6 @@ Created 2/2/1994 Heikki Tuuri Index page header starts at the first offset left free by the FIL-module */ typedef byte page_header_t; -#else -# include "mach0data.h" #endif /* !UNIV_INNOCHECKSUM */ #define PAGE_HEADER FSEG_PAGE_DATA /* index page header starts at this @@ -393,13 +392,17 @@ inline bool page_rec_is_infimum(const rec_t* rec); -/*************************************************************//** -Returns the max trx id field value. */ -UNIV_INLINE -trx_id_t -page_get_max_trx_id( -/*================*/ - const page_t* page); /*!< in: page */ +/** Read PAGE_MAX_TRX_ID. +@param[in] page index page +@return the value of PAGE_MAX_TRX_ID or PAGE_ROOT_AUTO_INC */ +inline trx_id_t page_get_max_trx_id(const page_t *page) +{ + static_assert((PAGE_HEADER + PAGE_MAX_TRX_ID) % 8 == 0, "alignment"); + const byte *p= static_cast<const byte*> + (MY_ASSUME_ALIGNED(page + PAGE_HEADER + PAGE_MAX_TRX_ID, 8)); + return mach_read_from_8(p); +} + /*************************************************************//** Sets the max trx id field value. */ void @@ -424,7 +427,6 @@ page_update_max_trx_id( /** Persist the AUTO_INCREMENT value on a clustered index root page. @param[in,out] block clustered index root page -@param[in] index clustered index @param[in] autoinc next available AUTO_INCREMENT value @param[in,out] mtr mini-transaction @param[in] reset whether to reset the AUTO_INCREMENT @@ -433,7 +435,6 @@ page_update_max_trx_id( void page_set_autoinc( buf_block_t* block, - const dict_index_t* index MY_ATTRIBUTE((unused)), ib_uint64_t autoinc, mtr_t* mtr, bool reset) @@ -517,17 +518,12 @@ page_header_set_ptr( ulint field, /*!< in/out: PAGE_FREE, ... */ const byte* ptr); /*!< in: pointer or NULL*/ -/*************************************************************//** -Resets the last insert info field in the page header. Writes to mlog -about this operation. */ -UNIV_INLINE -void -page_header_reset_last_insert( -/*==========================*/ - page_t* page, /*!< in: page */ - page_zip_des_t* page_zip,/*!< in/out: compressed page whose - uncompressed part will be updated, or NULL */ - mtr_t* mtr); /*!< in: mtr */ +/** +Reset PAGE_LAST_INSERT. +@param[in,out] block file page +@param[in,out] mtr mini-transaction */ +inline void page_header_reset_last_insert(buf_block_t *block, mtr_t *mtr) + MY_ATTRIBUTE((nonnull)); #define page_get_infimum_rec(page) ((page) + page_get_infimum_offset(page)) #define page_get_supremum_rec(page) ((page) + page_get_supremum_offset(page)) @@ -663,14 +659,17 @@ ibool page_rec_check( /*===========*/ const rec_t* rec); /*!< in: record */ -/***************************************************************//** -Gets the record pointed to by a directory slot. +/** Get the record pointed to by a directory slot. +@param[in] slot directory slot @return pointer to record */ -UNIV_INLINE -const rec_t* -page_dir_slot_get_rec( -/*==================*/ - const page_dir_slot_t* slot); /*!< in: directory slot */ +inline rec_t *page_dir_slot_get_rec(page_dir_slot_t *slot) +{ + return page_align(slot) + mach_read_from_2(slot); +} +inline const rec_t *page_dir_slot_get_rec(const page_dir_slot_t *slot) +{ + return page_dir_slot_get_rec(const_cast<rec_t*>(slot)); +} /***************************************************************//** This is used to set the record offset in a directory slot. */ UNIV_INLINE diff --git a/storage/innobase/include/page0page.ic b/storage/innobase/include/page0page.ic index d13f5732faf..ccc76c7ce3b 100644 --- a/storage/innobase/include/page0page.ic +++ b/storage/innobase/include/page0page.ic @@ -28,25 +28,11 @@ Created 2/2/1994 Heikki Tuuri #define page0page_ic #ifndef UNIV_INNOCHECKSUM -#include "mach0data.h" #include "rem0cmp.h" #include "mtr0log.h" #include "page0zip.h" /*************************************************************//** -Returns the max trx id field value. */ -UNIV_INLINE -trx_id_t -page_get_max_trx_id( -/*================*/ - const page_t* page) /*!< in: page */ -{ - ut_ad(page); - - return(mach_read_from_8(page + PAGE_HEADER + PAGE_MAX_TRX_ID)); -} - -/*************************************************************//** Sets the max trx id field value if trx_id is bigger than the previous value. */ UNIV_INLINE @@ -115,21 +101,16 @@ page_set_ssn_id( node_seq_t ssn_id, /*!< in: transaction id */ mtr_t* mtr) /*!< in/out: mini-transaction */ { - page_t* page = buf_block_get_frame(block); - ut_ad(!mtr || mtr_memo_contains_flagged(mtr, block, MTR_MEMO_PAGE_SX_FIX | MTR_MEMO_PAGE_X_FIX)); - if (page_zip) { - mach_write_to_8(page + FIL_RTREE_SPLIT_SEQ_NUM, ssn_id); - page_zip_write_header(page_zip, - page + FIL_RTREE_SPLIT_SEQ_NUM, - 8, mtr); - } else if (mtr) { - mlog_write_ull(page + FIL_RTREE_SPLIT_SEQ_NUM, ssn_id, mtr); + byte* ssn = block->frame + FIL_RTREE_SPLIT_SEQ_NUM; + if (UNIV_LIKELY_NULL(page_zip)) { + mach_write_to_8(ssn, ssn_id); + page_zip_write_header(page_zip, ssn, 8, mtr); } else { - mach_write_to_8(page + FIL_RTREE_SPLIT_SEQ_NUM, ssn_id); + mtr->write<8,mtr_t::OPT>(*block, ssn, ssn_id); } } @@ -229,30 +210,21 @@ page_header_set_ptr( page_header_set_field(page, page_zip, field, offs); } -/*************************************************************//** -Resets the last insert info field in the page header. Writes to mlog -about this operation. */ -UNIV_INLINE -void -page_header_reset_last_insert( -/*==========================*/ - page_t* page, /*!< in/out: page */ - page_zip_des_t* page_zip,/*!< in/out: compressed page whose - uncompressed part will be updated, or NULL */ - mtr_t* mtr) /*!< in: mtr */ +/** +Reset PAGE_LAST_INSERT. +@param[in,out] block file page +@param[in,out] mtr mini-transaction */ +inline void page_header_reset_last_insert(buf_block_t *block, mtr_t *mtr) { - ut_ad(page != NULL); - ut_ad(mtr != NULL); + byte *b= &block->frame[PAGE_HEADER + PAGE_LAST_INSERT]; - if (page_zip) { - mach_write_to_2(page + (PAGE_HEADER + PAGE_LAST_INSERT), 0); - page_zip_write_header(page_zip, - page + (PAGE_HEADER + PAGE_LAST_INSERT), - 2, mtr); - } else { - mlog_write_ulint(page + (PAGE_HEADER + PAGE_LAST_INSERT), 0, - MLOG_2BYTES, mtr); - } + if (UNIV_LIKELY_NULL(block->page.zip.data)) + { + mach_write_to_2(b, 0); + page_zip_write_header(&block->page.zip, b, 2, mtr); + } + else + mtr->write<2,mtr_t::OPT>(*block, b, 0U); } /***************************************************************//** @@ -542,18 +514,6 @@ page_rec_check( } /***************************************************************//** -Gets the record pointed to by a directory slot. -@return pointer to record */ -UNIV_INLINE -const rec_t* -page_dir_slot_get_rec( -/*==================*/ - const page_dir_slot_t* slot) /*!< in: directory slot */ -{ - return(page_align(slot) + mach_read_from_2(slot)); -} - -/***************************************************************//** This is used to set the record offset in a directory slot. */ UNIV_INLINE void diff --git a/storage/innobase/include/trx0purge.h b/storage/innobase/include/trx0purge.h index 43ae66afeb5..ec445cd4d0c 100644 --- a/storage/innobase/include/trx0purge.h +++ b/storage/innobase/include/trx0purge.h @@ -184,15 +184,15 @@ public: to purge */ trx_rseg_t* rseg; /*!< Rollback segment for the next undo record to purge */ - ulint page_no; /*!< Page number for the next undo + uint32_t page_no; /*!< Page number for the next undo record to purge, page number of the log header, if dummy record */ - ulint offset; /*!< Page offset for the next undo + uint32_t hdr_page_no; /*!< Header page of the undo log where + the next record to purge belongs */ + uint16_t offset; /*!< Page offset for the next undo record to purge, 0 if the dummy record */ - ulint hdr_page_no; /*!< Header page of the undo log where - the next record to purge belongs */ - ulint hdr_offset; /*!< Header byte offset on the page */ + uint16_t hdr_offset; /*!< Header byte offset on the page */ TrxUndoRsegsIterator diff --git a/storage/innobase/include/trx0rseg.h b/storage/innobase/include/trx0rseg.h index d4fdb19a988..29405997e5d 100644 --- a/storage/innobase/include/trx0rseg.h +++ b/storage/innobase/include/trx0rseg.h @@ -36,7 +36,7 @@ Created 3/26/1996 Heikki Tuuri @param[in,out] mtr mini-transaction @return rollback segment header, page x-latched */ UNIV_INLINE -trx_rsegf_t* +buf_block_t* trx_rsegf_get(fil_space_t* space, ulint page_no, mtr_t* mtr); /** Gets a newly created rollback segment header. @@ -45,29 +45,12 @@ trx_rsegf_get(fil_space_t* space, ulint page_no, mtr_t* mtr); @param[in,out] mtr mini-transaction @return rollback segment header, page x-latched */ UNIV_INLINE -trx_rsegf_t* +buf_block_t* trx_rsegf_get_new( ulint space, ulint page_no, mtr_t* mtr); -/***************************************************************//** -Sets the file page number of the nth undo log slot. */ -UNIV_INLINE -void -trx_rsegf_set_nth_undo( -/*===================*/ - trx_rsegf_t* rsegf, /*!< in: rollback segment header */ - ulint n, /*!< in: index of slot */ - ulint page_no,/*!< in: page number of the undo log segment */ - mtr_t* mtr); /*!< in: mtr */ -/****************************************************************//** -Looks for a free slot for an undo log segment. -@return slot index or ULINT_UNDEFINED if not found */ -UNIV_INLINE -ulint -trx_rsegf_undo_find_free(const trx_rsegf_t* rsegf); - /** Create a rollback segment header. @param[in,out] space system, undo, or temporary tablespace @param[in] rseg_id rollback segment identifier @@ -155,10 +138,10 @@ struct trx_rseg_t { /** Page number of the last not yet purged log header in the history list; FIL_NULL if all list purged */ - ulint last_page_no; + uint32_t last_page_no; /** Byte offset of the last not yet purged log header */ - ulint last_offset; + uint16_t last_offset; /** trx_t::no * 2 + old_insert of the last not yet purged log */ trx_id_t last_commit; @@ -255,15 +238,13 @@ If no binlog information is present, the first byte is NUL. */ /*-------------------------------------------------------------*/ /** Read the page number of an undo log slot. -@param[in] rsegf rollback segment header -@param[in] n slot number */ -inline -uint32_t -trx_rsegf_get_nth_undo(const trx_rsegf_t* rsegf, ulint n) +@param[in] rseg_header rollback segment header +@param[in] n slot number */ +inline uint32_t trx_rsegf_get_nth_undo(const buf_block_t *rseg_header, ulint n) { - ut_ad(n < TRX_RSEG_N_SLOTS); - return mach_read_from_4(rsegf + TRX_RSEG_UNDO_SLOTS - + n * TRX_RSEG_SLOT_SIZE); + ut_ad(n < TRX_RSEG_N_SLOTS); + return mach_read_from_4(TRX_RSEG + TRX_RSEG_UNDO_SLOTS + + n * TRX_RSEG_SLOT_SIZE + rseg_header->frame); } #ifdef WITH_WSREP @@ -273,7 +254,7 @@ trx_rsegf_get_nth_undo(const trx_rsegf_t* rsegf, ulint n) @param[in,out] mtr mini-transaction */ void trx_rseg_update_wsrep_checkpoint( - trx_rsegf_t* rseg_header, + buf_block_t* rseg_header, const XID* xid, mtr_t* mtr); @@ -295,7 +276,7 @@ bool trx_rseg_read_wsrep_checkpoint(XID& xid); /** Upgrade a rollback segment header page to MariaDB 10.3 format. @param[in,out] rseg_header rollback segment header page @param[in,out] mtr mini-transaction */ -void trx_rseg_format_upgrade(trx_rsegf_t* rseg_header, mtr_t* mtr); +void trx_rseg_format_upgrade(buf_block_t *rseg_header, mtr_t *mtr); /** Update the offset information about the end of the binlog entry which corresponds to the transaction just being committed. @@ -304,8 +285,8 @@ up to which replication has proceeded. @param[in,out] rseg_header rollback segment header @param[in] trx committing transaction @param[in,out] mtr mini-transaction */ -void -trx_rseg_update_binlog_offset(byte* rseg_header, const trx_t* trx, mtr_t* mtr); +void trx_rseg_update_binlog_offset(buf_block_t *rseg_header, const trx_t *trx, + mtr_t *mtr); #include "trx0rseg.ic" diff --git a/storage/innobase/include/trx0rseg.ic b/storage/innobase/include/trx0rseg.ic index 0cff8fa1f5c..e0e8c175a5d 100644 --- a/storage/innobase/include/trx0rseg.ic +++ b/storage/innobase/include/trx0rseg.ic @@ -1,7 +1,7 @@ /***************************************************************************** Copyright (c) 1996, 2013, Oracle and/or its affiliates. All Rights Reserved. -Copyright (c) 2017, 2018, MariaDB Corporation. +Copyright (c) 2017, 2019, 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 @@ -33,7 +33,7 @@ Created 3/26/1996 Heikki Tuuri @param[in,out] mtr mini-transaction @return rollback segment header, page x-latched */ UNIV_INLINE -trx_rsegf_t* +buf_block_t* trx_rsegf_get(fil_space_t* space, ulint page_no, mtr_t* mtr) { ut_ad(space == fil_system.sys_space || space == fil_system.temp_space @@ -44,8 +44,7 @@ trx_rsegf_get(fil_space_t* space, ulint page_no, mtr_t* mtr) 0, RW_X_LATCH, mtr); buf_block_dbg_add_level(block, SYNC_RSEG_HEADER); - - return TRX_RSEG + block->frame; + return block; } /** Gets a newly created rollback segment header. @@ -54,14 +53,13 @@ trx_rsegf_get(fil_space_t* space, ulint page_no, mtr_t* mtr) @param[in,out] mtr mini-transaction @return rollback segment header, page x-latched */ UNIV_INLINE -trx_rsegf_t* +buf_block_t* trx_rsegf_get_new( ulint space, ulint page_no, mtr_t* mtr) { buf_block_t* block; - trx_rsegf_t* header; ut_ad(space <= srv_undo_tablespaces_active || space == SRV_TMP_SPACE_ID || !srv_was_started); @@ -70,54 +68,5 @@ trx_rsegf_get_new( block = buf_page_get(page_id_t(space, page_no), 0, RW_X_LATCH, mtr); buf_block_dbg_add_level(block, SYNC_RSEG_HEADER_NEW); - - header = TRX_RSEG + buf_block_get_frame(block); - - return(header); -} - -/***************************************************************//** -Sets the file page number of the nth undo log slot. */ -UNIV_INLINE -void -trx_rsegf_set_nth_undo( -/*===================*/ - trx_rsegf_t* rsegf, /*!< in: rollback segment header */ - ulint n, /*!< in: index of slot */ - ulint page_no,/*!< in: page number of the undo log segment */ - mtr_t* mtr) /*!< in: mtr */ -{ - ut_a(n < TRX_RSEG_N_SLOTS); - - mlog_write_ulint(rsegf + TRX_RSEG_UNDO_SLOTS + n * TRX_RSEG_SLOT_SIZE, - page_no, MLOG_4BYTES, mtr); -} - -/****************************************************************//** -Looks for a free slot for an undo log segment. -@return slot index or ULINT_UNDEFINED if not found */ -UNIV_INLINE -ulint -trx_rsegf_undo_find_free(const trx_rsegf_t* rsegf) -{ - ulint i; - ulint page_no; - ulint max_slots = TRX_RSEG_N_SLOTS; - -#ifdef UNIV_DEBUG - if (trx_rseg_n_slots_debug) { - max_slots = ut_min(static_cast<ulint>(trx_rseg_n_slots_debug), - static_cast<ulint>(TRX_RSEG_N_SLOTS)); - } -#endif - - for (i = 0; i < max_slots; i++) { - page_no = trx_rsegf_get_nth_undo(rsegf, i); - - if (page_no == FIL_NULL) { - return(i); - } - } - - return(ULINT_UNDEFINED); + return block; } diff --git a/storage/innobase/include/trx0types.h b/storage/innobase/include/trx0types.h index 2aaec580d65..83d6d2c0db2 100644 --- a/storage/innobase/include/trx0types.h +++ b/storage/innobase/include/trx0types.h @@ -121,8 +121,6 @@ struct trx_savept_t{ /** File objects */ /* @{ */ -/** Rollback segment header */ -typedef byte trx_rsegf_t; /** Undo segment header */ typedef byte trx_usegf_t; /** Undo log header */ diff --git a/storage/innobase/include/trx0undo.h b/storage/innobase/include/trx0undo.h index ce92e5de5e1..8dec56a5e7d 100644 --- a/storage/innobase/include/trx0undo.h +++ b/storage/innobase/include/trx0undo.h @@ -46,10 +46,10 @@ UNIV_INLINE roll_ptr_t trx_undo_build_roll_ptr( /*====================*/ - ibool is_insert, /*!< in: TRUE if insert undo log */ + bool 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 */ + uint32_t page_no, /*!< in: page number */ + uint16_t offset); /*!< in: offset of the undo entry within page */ /***********************************************************************//** Decodes a roll pointer. */ UNIV_INLINE @@ -57,16 +57,16 @@ void trx_undo_decode_roll_ptr( /*=====================*/ roll_ptr_t roll_ptr, /*!< in: roll pointer */ - ibool* is_insert, /*!< out: TRUE if insert undo log */ + bool* 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 + uint32_t* page_no, /*!< out: page number */ + uint16_t* offset); /*!< out: offset of the undo entry within page */ /***********************************************************************//** -Returns TRUE if the roll pointer is of the insert type. -@return TRUE if insert undo log */ +Determine if DB_ROLL_PTR is of the insert type. +@return true if insert */ UNIV_INLINE -ibool +bool trx_undo_roll_ptr_is_insert( /*========================*/ roll_ptr_t roll_ptr); /*!< in: roll pointer */ @@ -101,7 +101,7 @@ inline roll_ptr_t trx_read_roll_ptr(const byte* ptr) @param[in,out] mtr mini-transaction @return pointer to page x-latched */ UNIV_INLINE -page_t* +buf_block_t* trx_undo_page_get(const page_id_t page_id, mtr_t* mtr); /** Gets an undo log page and s-latches it. @@ -109,56 +109,52 @@ trx_undo_page_get(const page_id_t page_id, mtr_t* mtr); @param[in,out] mtr mini-transaction @return pointer to page s-latched */ UNIV_INLINE -page_t* +buf_block_t* trx_undo_page_get_s_latched(const page_id_t page_id, mtr_t* mtr); -/******************************************************************//** -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 */ -/***********************************************************************//** -Gets the previous record in an undo log. -@return undo log record, the page s-latched, NULL if none */ +/** Get the next record in an undo log. +@param[in] undo_page undo log page +@param[in] rec undo record offset in the page +@param[in] page_no undo log header page number +@param[in] offset undo log header offset on page +@return undo log record, the page latched, NULL if none */ +inline trx_undo_rec_t* +trx_undo_page_get_next_rec(const buf_block_t *undo_page, uint16_t rec, + uint32_t page_no, uint16_t offset); +/** Get the previous record in an undo log. +@param[in,out] block undo log page +@param[in] rec undo record offset in the page +@param[in] page_no undo log header page number +@param[in] offset undo log header offset on page +@param[in] shared latching mode: true=RW_S_LATCH, false=RW_X_LATCH +@param[in,out] mtr mini-transaction +@return undo log record, the page latched, NULL if none */ trx_undo_rec_t* -trx_undo_get_prev_rec( -/*==================*/ - trx_undo_rec_t* rec, /*!< in: undo record */ - ulint page_no,/*!< in: undo log header page number */ - ulint offset, /*!< in: undo log header offset on page */ - bool shared, /*!< in: true=S-latch, false=X-latch */ - mtr_t* mtr); /*!< in: mtr */ -/***********************************************************************//** -Gets the next record in an undo log. -@return undo log record, the page s-latched, NULL if none */ +trx_undo_get_prev_rec(buf_block_t *&block, uint16_t rec, uint32_t page_no, + uint16_t offset, bool shared, mtr_t *mtr); +/** Get the next record in an undo log. +@param[in,out] block undo log page +@param[in] rec undo record offset in the page +@param[in] page_no undo log header page number +@param[in] offset undo log header offset on page +@param[in,out] mtr mini-transaction +@return undo log record, the page latched, NULL if none */ trx_undo_rec_t* -trx_undo_get_next_rec( -/*==================*/ - trx_undo_rec_t* rec, /*!< in: undo record */ - ulint page_no,/*!< in: undo log header page number */ - ulint offset, /*!< in: undo log header offset on page */ - mtr_t* mtr); /*!< in: mtr */ - -/** Gets the first record in an undo log. -@param[in] space undo log header space -@param[in] page_no undo log header page number -@param[in] offset undo log header offset on page -@param[in] mode latching mode: RW_S_LATCH or RW_X_LATCH -@param[in,out] mtr mini-transaction +trx_undo_get_next_rec(buf_block_t *&block, uint16_t rec, uint32_t page_no, + uint16_t offset, mtr_t *mtr); + +/** Get the first record in an undo log. +@param[in] space undo log header space +@param[in] page_no undo log header page number +@param[in] offset undo log header offset on page +@param[in] mode latching mode: RW_S_LATCH or RW_X_LATCH +@param[out] block undo log page +@param[in,out] mtr mini-transaction @return undo log record, the page latched, NULL if none */ trx_undo_rec_t* -trx_undo_get_first_rec( - fil_space_t* space, - ulint page_no, - ulint offset, - ulint mode, - mtr_t* mtr); +trx_undo_get_first_rec(const fil_space_t &space, uint32_t page_no, + uint16_t offset, ulint mode, buf_block_t*& block, + mtr_t *mtr); /** Allocate an undo log page. @param[in,out] undo undo log @@ -193,8 +189,8 @@ freed, but emptied, if all the records there are below the limit. void trx_undo_truncate_start( trx_rseg_t* rseg, - ulint hdr_page_no, - ulint hdr_offset, + uint32_t hdr_page_no, + uint16_t hdr_offset, undo_no_t limit); /** Mark that an undo log header belongs to a data dictionary transaction. @param[in] trx dictionary transaction @@ -227,7 +223,7 @@ trx_undo_assign_low(trx_t* trx, trx_rseg_t* rseg, trx_undo_t** undo, /******************************************************************//** Sets the state of the undo log segment at a transaction finish. @return undo log segment header page, x-latched */ -page_t* +buf_block_t* trx_undo_set_state_at_finish( /*=========================*/ trx_undo_t* undo, /*!< in: undo log memory copy */ @@ -237,14 +233,10 @@ trx_undo_set_state_at_finish( @param[in,out] trx transaction @param[in,out] undo undo log @param[in] rollback false=XA PREPARE, true=XA ROLLBACK -@param[in,out] mtr mini-transaction -@return undo log segment header page, x-latched */ -page_t* -trx_undo_set_state_at_prepare( - trx_t* trx, - trx_undo_t* undo, - bool rollback, - mtr_t* mtr); +@param[in,out] mtr mini-transaction */ +void trx_undo_set_state_at_prepare(trx_t *trx, trx_undo_t *undo, bool rollback, + mtr_t *mtr) + MY_ATTRIBUTE((nonnull)); /** Free an old insert or temporary undo log after commit or rollback. The information is not needed after a commit or rollback, therefore @@ -281,14 +273,14 @@ trx_undo_parse_page_header_reuse( /** Parse the redo log entry of an undo log page header create. @param[in] ptr redo log record @param[in] end_ptr end of log buffer -@param[in,out] page page frame or NULL +@param[in,out] block page frame or NULL @param[in,out] mtr mini-transaction or NULL @return end of log record or NULL */ byte* trx_undo_parse_page_header( const byte* ptr, const byte* end_ptr, - page_t* page, + buf_block_t* block, mtr_t* mtr); /** Read an undo log when starting up the database. @param[in,out] rseg rollback segment @@ -296,9 +288,9 @@ trx_undo_parse_page_header( @param[in] page_no undo log segment page number @param[in,out] max_trx_id the largest observed transaction ID @return size of the undo log in pages */ -ulint -trx_undo_mem_create_at_db_start(trx_rseg_t* rseg, ulint id, ulint page_no, - trx_id_t& max_trx_id); +uint32_t +trx_undo_mem_create_at_db_start(trx_rseg_t *rseg, ulint id, uint32_t page_no, + trx_id_t &max_trx_id); #endif /* !UNIV_INNOCHECKSUM */ @@ -340,20 +332,20 @@ struct trx_undo_t { id */ trx_rseg_t* rseg; /*!< rseg where the undo log belongs */ /*-----------------------------*/ - ulint hdr_page_no; /*!< page number of the header page in + uint32_t hdr_page_no; /*!< page number of the header page in the undo log */ - ulint hdr_offset; /*!< header offset of the undo log on - the page */ - ulint last_page_no; /*!< page number of the last page in the + uint32_t last_page_no; /*!< page number of the last page in the undo log; this may differ from top_page_no during a rollback */ - ulint size; /*!< current size in pages */ + uint16_t hdr_offset; /*!< header offset of the undo log on + the page */ + uint32_t size; /*!< current size in pages */ /*-----------------------------*/ - ulint top_page_no; /*!< page number where the latest undo + uint32_t top_page_no; /*!< page number where the latest undo log record was catenated; during rollback the page from which the latest undo record was chosen */ - ulint top_offset; /*!< offset of the latest undo record, + uint16_t top_offset; /*!< offset of the latest undo record, i.e., the topmost element in the undo log if we think of it as a stack */ undo_no_t top_undo_no; /*!< undo number of the latest record diff --git a/storage/innobase/include/trx0undo.ic b/storage/innobase/include/trx0undo.ic index 6d1ec16869e..06e31eb55b3 100644 --- a/storage/innobase/include/trx0undo.ic +++ b/storage/innobase/include/trx0undo.ic @@ -34,22 +34,17 @@ UNIV_INLINE roll_ptr_t trx_undo_build_roll_ptr( /*====================*/ - ibool is_insert, /*!< in: TRUE if insert undo log */ + bool 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 */ + uint32_t page_no, /*!< in: page number */ + uint16_t offset) /*!< in: offset of the undo entry within page */ { - roll_ptr_t roll_ptr; - compile_time_assert(DATA_ROLL_PTR_LEN == 7); - 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); + compile_time_assert(DATA_ROLL_PTR_LEN == 7); + ut_ad(rseg_id < TRX_SYS_N_RSEGS); + + return 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; } /***********************************************************************//** @@ -59,35 +54,32 @@ void trx_undo_decode_roll_ptr( /*=====================*/ roll_ptr_t roll_ptr, /*!< in: roll pointer */ - ibool* is_insert, /*!< out: TRUE if insert undo log */ + bool* 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 + uint32_t* page_no, /*!< out: page number */ + uint16_t* offset) /*!< out: offset of the undo entry within page */ { - compile_time_assert(DATA_ROLL_PTR_LEN == 7); - 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 */ + compile_time_assert(DATA_ROLL_PTR_LEN == 7); + ut_ad(roll_ptr < (1ULL << 56)); + *offset= static_cast<uint16_t>(roll_ptr); + *page_no= static_cast<uint32_t>(roll_ptr >> 16); + *rseg_id= static_cast<ulint>(roll_ptr >> 48 & 0x7F); + *is_insert= static_cast<bool>(roll_ptr >> 55); } /***********************************************************************//** -Returns TRUE if the roll pointer is of the insert type. -@return TRUE if insert undo log */ +Determine if DB_ROLL_PTR is of the insert type. +@return true if insert */ UNIV_INLINE -ibool +bool trx_undo_roll_ptr_is_insert( /*========================*/ roll_ptr_t roll_ptr) /*!< in: roll pointer */ { compile_time_assert(DATA_ROLL_PTR_LEN == 7); ut_ad(roll_ptr < (1ULL << (ROLL_PTR_INSERT_FLAG_POS + 1))); - return((ibool) (roll_ptr >> ROLL_PTR_INSERT_FLAG_POS)); + return static_cast<bool>(roll_ptr >> ROLL_PTR_INSERT_FLAG_POS); } /***********************************************************************//** @@ -108,14 +100,13 @@ trx_undo_trx_id_is_insert( @param[in,out] mtr mini-transaction @return pointer to page x-latched */ UNIV_INLINE -page_t* +buf_block_t* trx_undo_page_get(const page_id_t page_id, mtr_t* mtr) { buf_block_t* block = buf_page_get(page_id, 0, RW_X_LATCH, mtr); buf_block_dbg_add_level(block, SYNC_TRX_UNDO_PAGE); - - return(buf_block_get_frame(block)); + return block; } /** Gets an undo log page and s-latches it. @@ -123,14 +114,14 @@ trx_undo_page_get(const page_id_t page_id, mtr_t* mtr) @param[in,out] mtr mini-transaction @return pointer to page s-latched */ UNIV_INLINE -page_t* +buf_block_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, 0, RW_S_LATCH, mtr); buf_block_dbg_add_level(block, SYNC_TRX_UNDO_PAGE); - return(buf_block_get_frame(block)); + return block; } /** Determine the end offset of undo log records of an undo log page. @@ -139,46 +130,29 @@ trx_undo_page_get_s_latched(const page_id_t page_id, mtr_t* mtr) @param[in] offset undo log header offset @return end offset */ inline -uint16_t -trx_undo_page_get_end(const page_t* undo_page, ulint page_no, ulint offset) +uint16_t trx_undo_page_get_end(const buf_block_t *undo_page, uint32_t page_no, + uint16_t offset) { - if (page_no == page_get_page_no(undo_page)) { - if (uint16_t end = mach_read_from_2(TRX_UNDO_NEXT_LOG - + offset + undo_page)) { - return end; - } - } - - return mach_read_from_2(TRX_UNDO_PAGE_HDR + TRX_UNDO_PAGE_FREE - + undo_page); + if (page_no == undo_page->page.id.page_no()) + if (uint16_t end = mach_read_from_2(TRX_UNDO_NEXT_LOG + offset + + undo_page->frame)) + return end; + + return mach_read_from_2(TRX_UNDO_PAGE_HDR + TRX_UNDO_PAGE_FREE + + undo_page->frame); } -/******************************************************************//** -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 */ +/** Get the next record in an undo log. +@param[in] undo_page undo log page +@param[in] rec undo record offset in the page +@param[in] page_no undo log header page number +@param[in] offset undo log header offset on page +@return undo log record, the page latched, NULL if none */ +inline trx_undo_rec_t* +trx_undo_page_get_next_rec(const buf_block_t *undo_page, uint16_t rec, + uint32_t page_no, uint16_t offset) { - page_t* undo_page; - ulint end; - ulint next; - - undo_page = (page_t*) ut_align_down(rec, srv_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); + uint16_t end= trx_undo_page_get_end(undo_page, page_no, offset); + uint16_t next= mach_read_from_2(undo_page->frame + rec); + return next == end ? nullptr : undo_page->frame + next; } |