diff options
author | Marko Mäkelä <marko.makela@mariadb.com> | 2019-11-12 15:46:57 +0200 |
---|---|---|
committer | Marko Mäkelä <marko.makela@mariadb.com> | 2019-11-12 15:46:57 +0200 |
commit | 2570cb8b91711b38e4a448cc92b95e49abb218b4 (patch) | |
tree | f27747621ef8829f0c1b63236cebe3de0747baa1 | |
parent | dc8380b65da2071735129c829a3ea7bca006bf5c (diff) | |
download | mariadb-git-2570cb8b91711b38e4a448cc92b95e49abb218b4.tar.gz |
MDEV-12353 preparation: Clean up mtr_t
mtr_t::Impl, mtr_t::Command: Merge to mtr_t.
MTR_MAGIC_N: Remove.
MTR_STATE_COMMITTING: Remove. This state was only being set
internally during mtr_t::commit().
mtr_t::Command::m_locks_released: Remove (set-and-never-read member).
mtr_t::Command::m_start_lsn: Replaced with the return value of
finish_write() and a parameter to release_blocks().
mtr_t::Command::m_end_lsn: Removed as a duplicate of mtr_t::m_commit_lsn.
mtr_t::Command::prepare_write(): Replace a switch () with a
comparison against 0. Only 2 m_log_mode are allowed.
-rw-r--r-- | storage/innobase/include/mtr0mtr.h | 248 | ||||
-rw-r--r-- | storage/innobase/include/mtr0mtr.ic | 55 | ||||
-rw-r--r-- | storage/innobase/include/mtr0types.h | 19 | ||||
-rw-r--r-- | storage/innobase/mtr/mtr0mtr.cc | 427 |
4 files changed, 254 insertions, 495 deletions
diff --git a/storage/innobase/include/mtr0mtr.h b/storage/innobase/include/mtr0mtr.h index 4f518071bfb..30d2e937f1f 100644 --- a/storage/innobase/include/mtr0mtr.h +++ b/storage/innobase/include/mtr0mtr.h @@ -2,7 +2,7 @@ Copyright (c) 1995, 2017, Oracle and/or its affiliates. All Rights Reserved. Copyright (c) 2012, Facebook Inc. -Copyright (c) 2013, 2018, MariaDB Corporation. +Copyright (c) 2013, 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 @@ -146,68 +146,7 @@ struct mtr_memo_slot_t { /** Mini-transaction handle and buffer */ struct mtr_t { - - /** State variables of the mtr */ - struct Impl { - - /** memo stack for locks etc. */ - mtr_buf_t m_memo; - - /** mini-transaction log */ - mtr_buf_t m_log; - - /** true if mtr has made at least one buffer pool page dirty */ - bool m_made_dirty; - - /** true if inside ibuf changes */ - bool m_inside_ibuf; - - /** true if the mini-transaction modified buffer pool pages */ - bool m_modifications; - - /** Count of how many page initial log records have been - written to the mtr log */ - ib_uint32_t m_n_log_recs; - - /** specifies which operations should be logged; default - value MTR_LOG_ALL */ - mtr_log_t m_log_mode; -#ifdef UNIV_DEBUG - /** Persistent user tablespace associated with the - mini-transaction, or 0 (TRX_SYS_SPACE) if none yet */ - ulint m_user_space_id; -#endif /* UNIV_DEBUG */ - /** User tablespace that is being modified by the - mini-transaction */ - fil_space_t* m_user_space; - /** Undo tablespace that is being modified by the - mini-transaction */ - fil_space_t* m_undo_space; - /** System tablespace if it is being modified by the - mini-transaction */ - fil_space_t* m_sys_space; - - /** State of the transaction */ - mtr_state_t m_state; - - /** Flush Observer */ - FlushObserver* m_flush_observer; - -#ifdef UNIV_DEBUG - /** For checking corruption. */ - ulint m_magic_n; -#endif /* UNIV_DEBUG */ - - /** Owning mini-transaction */ - mtr_t* m_mtr; - }; - - mtr_t() - { - m_impl.m_state = MTR_STATE_INIT; - } - - ~mtr_t() { } + mtr_t() : m_state(MTR_STATE_INIT) {} /** Release the free extents that was reserved using fsp_reserve_free_extents(). This is equivalent to calling @@ -236,14 +175,7 @@ struct mtr_t { /** Return current size of the buffer. @return savepoint */ - ulint get_savepoint() const - MY_ATTRIBUTE((warn_unused_result)) - { - ut_ad(is_active()); - ut_ad(m_impl.m_magic_n == MTR_MAGIC_N); - - return(m_impl.m_memo.size()); - } + ulint get_savepoint() const {ut_ad(is_active()); return m_memo.size();} /** Release the (index tree) s-latch stored in an mtr memo after a savepoint. @@ -279,10 +211,10 @@ struct mtr_t { @return the system tablespace */ fil_space_t* set_sys_modified() { - if (!m_impl.m_sys_space) { + if (!m_sys_space) { lookup_sys_space(); } - return(m_impl.m_sys_space); + return m_sys_space; } /** Copy the tablespaces associated with the mini-transaction @@ -291,15 +223,15 @@ struct mtr_t { the same set of tablespaces as this one */ void set_spaces(const mtr_t& mtr) { - ut_ad(!m_impl.m_user_space_id); - ut_ad(!m_impl.m_user_space); - ut_ad(!m_impl.m_undo_space); - ut_ad(!m_impl.m_sys_space); - - ut_d(m_impl.m_user_space_id = mtr.m_impl.m_user_space_id); - m_impl.m_user_space = mtr.m_impl.m_user_space; - m_impl.m_undo_space = mtr.m_impl.m_undo_space; - m_impl.m_sys_space = mtr.m_impl.m_sys_space; + ut_ad(!m_user_space_id); + ut_ad(!m_user_space); + ut_ad(!m_undo_space); + ut_ad(!m_sys_space); + + ut_d(m_user_space_id = mtr.m_user_space_id); + m_user_space = mtr.m_user_space; + m_undo_space = mtr.m_undo_space; + m_sys_space = mtr.m_sys_space; } /** Set the tablespace associated with the mini-transaction @@ -308,13 +240,13 @@ struct mtr_t { @return the tablespace */ fil_space_t* set_named_space(ulint space_id) { - ut_ad(!m_impl.m_user_space_id); - ut_d(m_impl.m_user_space_id = space_id); + ut_ad(!m_user_space_id); + ut_d(m_user_space_id = space_id); if (!space_id) { return(set_sys_modified()); } else { lookup_user_space(space_id); - return(m_impl.m_user_space); + return m_user_space; } } @@ -381,18 +313,12 @@ struct mtr_t { void release_page(const void* ptr, mtr_memo_type_t type); /** Note that the mini-transaction has modified data. */ - void set_modified() - { - m_impl.m_modifications = true; - } + void set_modified() { m_modifications = true; } /** Set the state to not-modified. This will not log the changes. This is only used during redo log apply, to avoid logging the changes. */ - void discard_modifications() - { - m_impl.m_modifications = false; - } + void discard_modifications() { m_modifications = false; } /** Get the LSN of commit(). @return the commit LSN @@ -404,45 +330,28 @@ struct mtr_t { } /** Note that we are inside the change buffer code. */ - void enter_ibuf() - { - m_impl.m_inside_ibuf = true; - } + void enter_ibuf() { m_inside_ibuf = true; } /** Note that we have exited from the change buffer code. */ - void exit_ibuf() - { - m_impl.m_inside_ibuf = false; - } + void exit_ibuf() { m_inside_ibuf = false; } /** @return true if we are inside the change buffer code */ - bool is_inside_ibuf() const - { - return(m_impl.m_inside_ibuf); - } + bool is_inside_ibuf() const { return m_inside_ibuf; } /* @return true if the mini-transaction is active */ - bool is_active() const - { - return(m_impl.m_state == MTR_STATE_ACTIVE); - } + bool is_active() const { return m_state == MTR_STATE_ACTIVE; } /** Get flush observer @return flush observer */ - FlushObserver* get_flush_observer() const - { - return(m_impl.m_flush_observer); - } + FlushObserver* get_flush_observer() const { return m_flush_observer; } /** Set flush observer @param[in] observer flush observer */ void set_flush_observer(FlushObserver* observer) { - ut_ad(observer == NULL - || m_impl.m_log_mode == MTR_LOG_NO_REDO); - - m_impl.m_flush_observer = observer; + ut_ad(observer == NULL || m_log_mode == MTR_LOG_NO_REDO); + m_flush_observer = observer; } #ifdef UNIV_DEBUG @@ -482,65 +391,31 @@ struct mtr_t { void print() const; /** @return true if the mini-transaction has committed */ - bool has_committed() const - { - return(m_impl.m_state == MTR_STATE_COMMITTED); - } - - /** @return true if the mini-transaction is committing */ - bool is_committing() const - { - return(m_impl.m_state == MTR_STATE_COMMITTING); - } + bool has_committed() const { return m_state == MTR_STATE_COMMITTED; } /** @return true if mini-transaction contains modifications. */ - bool has_modifications() const - { - return(m_impl.m_modifications); - } + bool has_modifications() const { return m_modifications; } /** @return the memo stack */ - const mtr_buf_t* get_memo() const - { - return(&m_impl.m_memo); - } + const mtr_buf_t* get_memo() const { return &m_memo; } /** @return the memo stack */ - mtr_buf_t* get_memo() - { - return(&m_impl.m_memo); - } + mtr_buf_t* get_memo() { return &m_memo; } #endif /* UNIV_DEBUG */ /** @return true if a record was added to the mini-transaction */ - bool is_dirty() const - { - return(m_impl.m_made_dirty); - } + bool is_dirty() const { return m_made_dirty; } /** Note that a record has been added to the log */ - void added_rec() - { - ++m_impl.m_n_log_recs; - } + void added_rec() { ++m_n_log_recs; } /** Get the buffered redo log of this mini-transaction. @return redo log */ - const mtr_buf_t* get_log() const - { - ut_ad(m_impl.m_magic_n == MTR_MAGIC_N); - - return(&m_impl.m_log); - } + const mtr_buf_t* get_log() const { return &m_log; } /** Get the buffered redo log of this mini-transaction. @return redo log */ - mtr_buf_t* get_log() - { - ut_ad(m_impl.m_magic_n == MTR_MAGIC_N); - - return(&m_impl.m_log); - } + mtr_buf_t* get_log() { return &m_log; } /** Push an object to an mtr memo stack. @param object object @@ -560,15 +435,60 @@ private: @param[in] space_id tablespace ID */ void lookup_user_space(ulint space_id); - class Command; + /** 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(); - friend class Command; + /** Append the redo log records to the redo log buffer. + @param[in] len number of bytes to write + @return start_lsn */ + inline lsn_t finish_write(ulint len); -private: - Impl m_impl; + /** Release the resources */ + inline void release_resources(); + + /** memo stack for locks etc. */ + mtr_buf_t m_memo; + + /** mini-transaction log */ + mtr_buf_t m_log; + + /** true if mtr has made at least one buffer pool page dirty */ + bool m_made_dirty; + + /** true if inside ibuf changes */ + bool m_inside_ibuf; + + /** true if the mini-transaction modified buffer pool pages */ + bool m_modifications; + + /** Count of how many page initial log records have been + written to the mtr log */ + ib_uint32_t m_n_log_recs; + + /** specifies which operations should be logged; default + value MTR_LOG_ALL */ + mtr_log_t m_log_mode; +#ifdef UNIV_DEBUG + /** Persistent user tablespace associated with the + mini-transaction, or 0 (TRX_SYS_SPACE) if none yet */ + ulint m_user_space_id; +#endif /* UNIV_DEBUG */ + /** User tablespace that is being modified by the mini-transaction */ + fil_space_t* m_user_space; + /** Undo tablespace that is being modified by the mini-transaction */ + fil_space_t* m_undo_space; + /** System tablespace if being modified by the mini-transaction */ + fil_space_t* m_sys_space; + + /** State of the transaction */ + mtr_state_t m_state; + + /** Flush Observer */ + FlushObserver* m_flush_observer; /** LSN at commit time */ - volatile lsn_t m_commit_lsn; + lsn_t m_commit_lsn; }; #include "mtr0mtr.ic" diff --git a/storage/innobase/include/mtr0mtr.ic b/storage/innobase/include/mtr0mtr.ic index 574d0de24a5..7175ede0d6a 100644 --- a/storage/innobase/include/mtr0mtr.ic +++ b/storage/innobase/include/mtr0mtr.ic @@ -49,7 +49,6 @@ mtr_t::memo_push(void* object, mtr_memo_type_t type) ut_ad(object != NULL); ut_ad(type >= MTR_MEMO_PAGE_S_FIX); ut_ad(type <= MTR_MEMO_SX_LOCK); - ut_ad(m_impl.m_magic_n == MTR_MAGIC_N); ut_ad(ut_is_2pow(type)); /* If this mtr has x-fixed a clean page then we set @@ -58,15 +57,13 @@ mtr_t::memo_push(void* object, mtr_memo_type_t type) can insert the dirtied page to the flush list. */ if ((type == MTR_MEMO_PAGE_X_FIX || type == MTR_MEMO_PAGE_SX_FIX) - && !m_impl.m_made_dirty) { + && !m_made_dirty) { - m_impl.m_made_dirty = is_block_dirtied( + m_made_dirty = is_block_dirtied( reinterpret_cast<const buf_block_t*>(object)); } - mtr_memo_slot_t* slot; - - slot = m_impl.m_memo.push<mtr_memo_slot_t*>(sizeof(*slot)); + mtr_memo_slot_t* slot = m_memo.push<mtr_memo_slot_t*>(sizeof(*slot)); slot->type = type; slot->object = object; @@ -81,11 +78,9 @@ mtr_t::release_s_latch_at_savepoint( rw_lock_t* lock) { ut_ad(is_active()); - ut_ad(m_impl.m_magic_n == MTR_MAGIC_N); - - ut_ad(m_impl.m_memo.size() > savepoint); + ut_ad(m_memo.size() > savepoint); - mtr_memo_slot_t* slot = m_impl.m_memo.at<mtr_memo_slot_t*>(savepoint); + mtr_memo_slot_t* slot = m_memo.at<mtr_memo_slot_t*>(savepoint); ut_ad(slot->object == lock); ut_ad(slot->type == MTR_MEMO_S_LOCK); @@ -104,8 +99,7 @@ mtr_t::sx_latch_at_savepoint( buf_block_t* block) { ut_ad(is_active()); - ut_ad(m_impl.m_magic_n == MTR_MAGIC_N); - ut_ad(m_impl.m_memo.size() > savepoint); + ut_ad(m_memo.size() > savepoint); ut_ad(!memo_contains_flagged( block, @@ -113,9 +107,7 @@ mtr_t::sx_latch_at_savepoint( | MTR_MEMO_PAGE_X_FIX | MTR_MEMO_PAGE_SX_FIX)); - mtr_memo_slot_t* slot; - - slot = m_impl.m_memo.at<mtr_memo_slot_t*>(savepoint); + mtr_memo_slot_t* slot = m_memo.at<mtr_memo_slot_t*>(savepoint); ut_ad(slot->object == block); @@ -124,8 +116,8 @@ mtr_t::sx_latch_at_savepoint( rw_lock_sx_lock(&block->lock); - if (!m_impl.m_made_dirty) { - m_impl.m_made_dirty = is_block_dirtied(block); + if (!m_made_dirty) { + m_made_dirty = is_block_dirtied(block); } slot->type = MTR_MEMO_PAGE_SX_FIX; @@ -140,8 +132,7 @@ mtr_t::x_latch_at_savepoint( buf_block_t* block) { ut_ad(is_active()); - ut_ad(m_impl.m_magic_n == MTR_MAGIC_N); - ut_ad(m_impl.m_memo.size() > savepoint); + ut_ad(m_memo.size() > savepoint); ut_ad(!memo_contains_flagged( block, @@ -149,9 +140,7 @@ mtr_t::x_latch_at_savepoint( | MTR_MEMO_PAGE_X_FIX | MTR_MEMO_PAGE_SX_FIX)); - mtr_memo_slot_t* slot; - - slot = m_impl.m_memo.at<mtr_memo_slot_t*>(savepoint); + mtr_memo_slot_t* slot = m_memo.at<mtr_memo_slot_t*>(savepoint); ut_ad(slot->object == block); @@ -160,8 +149,8 @@ mtr_t::x_latch_at_savepoint( rw_lock_x_lock(&block->lock); - if (!m_impl.m_made_dirty) { - m_impl.m_made_dirty = is_block_dirtied(block); + if (!m_made_dirty) { + m_made_dirty = is_block_dirtied(block); } slot->type = MTR_MEMO_PAGE_X_FIX; @@ -176,11 +165,8 @@ mtr_t::release_block_at_savepoint( buf_block_t* block) { ut_ad(is_active()); - ut_ad(m_impl.m_magic_n == MTR_MAGIC_N); - - mtr_memo_slot_t* slot; - slot = m_impl.m_memo.at<mtr_memo_slot_t*>(savepoint); + mtr_memo_slot_t* slot = m_memo.at<mtr_memo_slot_t*>(savepoint); ut_a(slot->object == block); @@ -198,10 +184,10 @@ Gets the logging mode of a mini-transaction. mtr_log_t mtr_t::get_log_mode() const { - ut_ad(m_impl.m_log_mode >= MTR_LOG_ALL); - ut_ad(m_impl.m_log_mode <= MTR_LOG_SHORT_INSERTS); + ut_ad(m_log_mode >= MTR_LOG_ALL); + ut_ad(m_log_mode <= MTR_LOG_SHORT_INSERTS); - return(m_impl.m_log_mode); + return m_log_mode; } /** @@ -214,7 +200,7 @@ mtr_t::set_log_mode(mtr_log_t mode) ut_ad(mode >= MTR_LOG_ALL); ut_ad(mode <= MTR_LOG_SHORT_INSERTS); - const mtr_log_t old_mode = m_impl.m_log_mode; + const mtr_log_t old_mode = m_log_mode; switch (old_mode) { case MTR_LOG_NO_REDO: @@ -233,9 +219,8 @@ mtr_t::set_log_mode(mtr_log_t mode) case MTR_LOG_ALL: /* MTR_LOG_NO_REDO can only be set before generating any redo log records. */ - ut_ad(mode != MTR_LOG_NO_REDO - || m_impl.m_n_log_recs == 0); - m_impl.m_log_mode = mode; + ut_ad(mode != MTR_LOG_NO_REDO || m_n_log_recs == 0); + m_log_mode = mode; return(old_mode); } diff --git a/storage/innobase/include/mtr0types.h b/storage/innobase/include/mtr0types.h index 1179da6d926..985ad7b81ea 100644 --- a/storage/innobase/include/mtr0types.h +++ b/storage/innobase/include/mtr0types.h @@ -1,7 +1,7 @@ /***************************************************************************** Copyright (c) 1995, 2015, Oracle and/or its affiliates. All Rights Reserved. -Copyright (c) 2017, 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 @@ -36,18 +36,18 @@ struct mtr_t; /** Logging modes for a mini-transaction */ enum mtr_log_t { /** Default mode: log all operations modifying disk-based data */ - MTR_LOG_ALL = 21, + MTR_LOG_ALL = 0, /** Log no operations and dirty pages are not added to the flush list. Set when applying log in crash recovery or when a modification of a ROW_FORMAT=COMPRESSED page is attempted. */ - MTR_LOG_NONE = 22, + MTR_LOG_NONE, /** Don't generate REDO log but add dirty pages to flush list */ - MTR_LOG_NO_REDO = 23, + MTR_LOG_NO_REDO, /** Inserts are logged in a shorter form */ - MTR_LOG_SHORT_INSERTS = 24 + MTR_LOG_SHORT_INSERTS }; /** @name Log item types @@ -267,15 +267,10 @@ enum mtr_memo_type_t { }; #endif /* !UNIV_CHECKSUM */ -#ifdef UNIV_DEBUG -# define MTR_MAGIC_N 54551 -#endif /* UNIV_DEBUG */ - enum mtr_state_t { MTR_STATE_INIT = 0, - MTR_STATE_ACTIVE = 12231, - MTR_STATE_COMMITTING = 56456, - MTR_STATE_COMMITTED = 34676 + MTR_STATE_ACTIVE, + MTR_STATE_COMMITTED }; #endif /* mtr0types_h */ diff --git a/storage/innobase/mtr/mtr0mtr.cc b/storage/innobase/mtr/mtr0mtr.cc index fc6f3321164..533b10b861e 100644 --- a/storage/innobase/mtr/mtr0mtr.cc +++ b/storage/innobase/mtr/mtr0mtr.cc @@ -343,6 +343,7 @@ struct ReleaseAll { } }; +#ifdef UNIV_DEBUG /** Check that all slots have been handled. */ struct DebugCheck { /** @return true always. */ @@ -352,6 +353,7 @@ struct DebugCheck { return(true); } }; +#endif /** Release a resource acquired by the mini-transaction. */ struct ReleaseBlocks { @@ -404,59 +406,6 @@ struct ReleaseBlocks { FlushObserver* m_flush_observer; }; -class mtr_t::Command { -public: - /** Constructor. - Takes ownership of the mtr->m_impl, is responsible for deleting it. - @param[in,out] mtr mini-transaction */ - explicit Command(mtr_t* mtr) : m_impl(&mtr->m_impl), m_locks_released() - {} - - /** Destructor */ - ~Command() - { - ut_ad(m_impl == 0); - } - - /** Write the redo log record, add dirty pages to the flush list and - release the resources. */ - void execute(); - - /** Release the blocks used in this mini-transaction. */ - void release_blocks(); - - /** Release the latches acquired by the mini-transaction. */ - void release_latches(); - - /** Release both the latches and blocks used in the mini-transaction. */ - void release_all(); - - /** Release the resources */ - void release_resources(); - - /** Append the redo log records to the redo log buffer. - @param[in] len number of bytes to write */ - void finish_write(ulint len); - -private: - /** Prepare to write the mini-transaction log to the redo log buffer. - @return number of bytes to write in finish_write() */ - ulint prepare_write(); - - /** The mini-transaction state. */ - mtr_t::Impl* m_impl; - - /** Set to 1 after the user thread releases the latches. The log - writer thread must wait for this to be set to 1. */ - volatile ulint m_locks_released; - - /** Start lsn of the possible log entry for this mtr */ - lsn_t m_start_lsn; - - /** End lsn of the possible log entry for this mtr */ - lsn_t m_end_lsn; -}; - /** Write the block contents to the REDO log */ struct mtr_write_log_t { /** Append a block to the redo log buffer. @@ -490,78 +439,77 @@ mtr_write_log( /** Start a mini-transaction. */ void mtr_t::start() { - UNIV_MEM_INVALID(this, sizeof(*this)); - - UNIV_MEM_INVALID(&m_impl, sizeof(m_impl)); - - m_commit_lsn = 0; - - new(&m_impl.m_log) mtr_buf_t(); - new(&m_impl.m_memo) mtr_buf_t(); - - m_impl.m_mtr = this; - m_impl.m_log_mode = MTR_LOG_ALL; - m_impl.m_inside_ibuf = false; - m_impl.m_modifications = false; - m_impl.m_made_dirty = false; - m_impl.m_n_log_recs = 0; - m_impl.m_state = MTR_STATE_ACTIVE; - ut_d(m_impl.m_user_space_id = TRX_SYS_SPACE); - m_impl.m_user_space = NULL; - m_impl.m_undo_space = NULL; - m_impl.m_sys_space = NULL; - m_impl.m_flush_observer = NULL; - - ut_d(m_impl.m_magic_n = MTR_MAGIC_N); + UNIV_MEM_INVALID(this, sizeof *this); + + new(&m_memo) mtr_buf_t(); + new(&m_log) mtr_buf_t(); + + m_made_dirty= false; + m_inside_ibuf= false; + m_modifications= false; + m_n_log_recs= 0; + m_log_mode= MTR_LOG_ALL; + ut_d(m_user_space_id= TRX_SYS_SPACE); + m_user_space= NULL; + m_undo_space= NULL; + m_sys_space= NULL; + m_state= MTR_STATE_ACTIVE; + m_flush_observer= NULL; + m_commit_lsn= 0; } /** Release the resources */ -void -mtr_t::Command::release_resources() +inline void mtr_t::release_resources() { - ut_ad(m_impl->m_magic_n == MTR_MAGIC_N); - - /* Currently only used in commit */ - ut_ad(m_impl->m_state == MTR_STATE_COMMITTING); - - ut_d(m_impl->m_memo.for_each_block_in_reverse(CIterate<DebugCheck>())); - - /* Reset the mtr buffers */ - m_impl->m_log.erase(); - - m_impl->m_memo.erase(); - - m_impl->m_state = MTR_STATE_COMMITTED; - - m_impl = 0; + ut_d(m_memo.for_each_block_in_reverse(CIterate<DebugCheck>())); + m_log.erase(); + m_memo.erase(); + m_state= MTR_STATE_COMMITTED; } /** Commit a mini-transaction. */ void mtr_t::commit() { - ut_ad(is_active()); - ut_ad(!is_inside_ibuf()); - ut_ad(m_impl.m_magic_n == MTR_MAGIC_N); - m_impl.m_state = MTR_STATE_COMMITTING; + ut_ad(is_active()); + ut_ad(!is_inside_ibuf()); - /* This is a dirty read, for debugging. */ - ut_ad(!m_impl.m_modifications || !recv_no_log_write); + /* This is a dirty read, for debugging. */ + ut_ad(!m_modifications || !recv_no_log_write); + ut_ad(!m_modifications || m_log_mode != MTR_LOG_NONE); - Command cmd(this); + if (m_modifications + && (m_n_log_recs || m_log_mode == MTR_LOG_NO_REDO)) + { + ut_ad(!srv_read_only_mode || m_log_mode == MTR_LOG_NO_REDO); - if (m_impl.m_modifications - && (m_impl.m_n_log_recs > 0 - || m_impl.m_log_mode == MTR_LOG_NO_REDO)) { + lsn_t start_lsn; - ut_ad(!srv_read_only_mode - || m_impl.m_log_mode == MTR_LOG_NO_REDO); + if (const ulint len= prepare_write()) + start_lsn= finish_write(len); + else + start_lsn= m_commit_lsn; - cmd.execute(); - } else { - cmd.release_all(); - cmd.release_resources(); - } + if (m_made_dirty) + log_flush_order_mutex_enter(); + + /* It is now safe to release the log mutex because the + flush_order mutex will ensure that we are the first one + to insert into the flush list. */ + log_mutex_exit(); + + m_memo.for_each_block_in_reverse(CIterate<const ReleaseBlocks> + (ReleaseBlocks(start_lsn, m_commit_lsn, + m_flush_observer))); + if (m_made_dirty) + log_flush_order_mutex_exit(); + + m_memo.for_each_block_in_reverse(CIterate<ReleaseLatches>()); + } + else + m_memo.for_each_block_in_reverse(CIterate<ReleaseAll>()); + + release_resources(); } /** Commit a mini-transaction that did not modify any pages, @@ -580,37 +528,31 @@ mtr_t::commit_checkpoint( ut_ad(log_mutex_own()); ut_ad(is_active()); ut_ad(!is_inside_ibuf()); - ut_ad(m_impl.m_magic_n == MTR_MAGIC_N); ut_ad(get_log_mode() == MTR_LOG_ALL); - ut_ad(!m_impl.m_made_dirty); - ut_ad(m_impl.m_memo.size() == 0); + ut_ad(!m_made_dirty); + ut_ad(m_memo.size() == 0); ut_ad(!srv_read_only_mode); - ut_d(m_impl.m_state = MTR_STATE_COMMITTING); - ut_ad(write_mlog_checkpoint || m_impl.m_n_log_recs > 1); + ut_ad(write_mlog_checkpoint || m_n_log_recs > 1); - switch (m_impl.m_n_log_recs) { + switch (m_n_log_recs) { case 0: break; case 1: - *m_impl.m_log.front()->begin() |= MLOG_SINGLE_REC_FLAG; + *m_log.front()->begin() |= MLOG_SINGLE_REC_FLAG; break; default: - mlog_catenate_ulint( - &m_impl.m_log, MLOG_MULTI_REC_END, MLOG_1BYTE); + mlog_catenate_ulint(&m_log, MLOG_MULTI_REC_END, MLOG_1BYTE); } if (write_mlog_checkpoint) { - byte* ptr = m_impl.m_log.push<byte*>(SIZE_OF_MLOG_CHECKPOINT); -#if SIZE_OF_MLOG_CHECKPOINT != 9 -# error SIZE_OF_MLOG_CHECKPOINT != 9 -#endif + byte* ptr = m_log.push<byte*>(SIZE_OF_MLOG_CHECKPOINT); + compile_time_assert(SIZE_OF_MLOG_CHECKPOINT == 1 + 8); *ptr = MLOG_CHECKPOINT; mach_write_to_8(ptr + 1, checkpoint_lsn); } - Command cmd(this); - cmd.finish_write(m_impl.m_log.size()); - cmd.release_resources(); + finish_write(m_log.size()); + release_resources(); if (write_mlog_checkpoint) { DBUG_PRINT("ib_log", @@ -627,18 +569,12 @@ mtr_t::commit_checkpoint( bool mtr_t::is_named_space(ulint space) const { - ut_ad(!m_impl.m_sys_space - || m_impl.m_sys_space->id == TRX_SYS_SPACE); - ut_ad(!m_impl.m_undo_space - || m_impl.m_undo_space->id != TRX_SYS_SPACE); - ut_ad(!m_impl.m_user_space - || m_impl.m_user_space->id != TRX_SYS_SPACE); - ut_ad(!m_impl.m_sys_space - || m_impl.m_sys_space != m_impl.m_user_space); - ut_ad(!m_impl.m_sys_space - || m_impl.m_sys_space != m_impl.m_undo_space); - ut_ad(!m_impl.m_user_space - || m_impl.m_user_space != m_impl.m_undo_space); + ut_ad(!m_sys_space || m_sys_space->id == TRX_SYS_SPACE); + ut_ad(!m_undo_space || m_undo_space->id != TRX_SYS_SPACE); + ut_ad(!m_user_space || m_user_space->id != TRX_SYS_SPACE); + ut_ad(!m_sys_space || m_sys_space != m_user_space); + ut_ad(!m_sys_space || m_sys_space != m_undo_space); + ut_ad(!m_user_space || m_user_space != m_undo_space); switch (get_log_mode()) { case MTR_LOG_NONE: @@ -646,7 +582,7 @@ mtr_t::is_named_space(ulint space) const return(true); case MTR_LOG_ALL: case MTR_LOG_SHORT_INSERTS: - return(m_impl.m_user_space_id == space + return(m_user_space_id == space || is_predefined_tablespace(space)); } @@ -666,17 +602,16 @@ mtr_t::x_lock_space(ulint space_id, const char* file, unsigned line) { fil_space_t* space; - ut_ad(m_impl.m_magic_n == MTR_MAGIC_N); ut_ad(is_active()); if (space_id == TRX_SYS_SPACE) { - space = m_impl.m_sys_space; + space = m_sys_space; if (!space) { - space = m_impl.m_sys_space = fil_space_get(space_id); + space = m_sys_space = fil_space_get(space_id); } - } else if ((space = m_impl.m_user_space) && space_id == space->id) { - } else if ((space = m_impl.m_undo_space) && space_id == space->id) { + } else if ((space = m_user_space) && space_id == space->id) { + } else if ((space = m_undo_space) && space_id == space->id) { } else if (get_log_mode() == MTR_LOG_NO_REDO) { space = fil_space_get(space_id); ut_ad(space->purpose == FIL_TYPE_TEMPORARY @@ -685,7 +620,7 @@ mtr_t::x_lock_space(ulint space_id, const char* file, unsigned line) || srv_is_tablespace_truncated(space->id)); } else { /* called from trx_rseg_create() */ - space = m_impl.m_undo_space = fil_space_get(space_id); + space = m_undo_space = fil_space_get(space_id); } ut_ad(space); @@ -701,9 +636,9 @@ mtr_t::x_lock_space(ulint space_id, const char* file, unsigned line) void mtr_t::lookup_sys_space() { - ut_ad(!m_impl.m_sys_space); - m_impl.m_sys_space = fil_space_get(TRX_SYS_SPACE); - ut_ad(m_impl.m_sys_space); + ut_ad(!m_sys_space); + m_sys_space = fil_space_get(TRX_SYS_SPACE); + ut_ad(m_sys_space); } /** Look up the user tablespace. @@ -712,10 +647,10 @@ void mtr_t::lookup_user_space(ulint space_id) { ut_ad(space_id != TRX_SYS_SPACE); - ut_ad(m_impl.m_user_space_id == space_id); - ut_ad(!m_impl.m_user_space); - m_impl.m_user_space = fil_space_get(space_id); - ut_ad(m_impl.m_user_space); + ut_ad(m_user_space_id == space_id); + ut_ad(!m_user_space); + m_user_space = fil_space_get(space_id); + ut_ad(m_user_space); } /** Set the tablespace associated with the mini-transaction @@ -724,14 +659,13 @@ mtr_t::lookup_user_space(ulint space_id) void mtr_t::set_named_space(fil_space_t* space) { - ut_ad(m_impl.m_user_space_id == TRX_SYS_SPACE); - ut_d(m_impl.m_user_space_id = space->id); + ut_ad(m_user_space_id == TRX_SYS_SPACE); + ut_d(m_user_space_id = space->id); if (space->id == TRX_SYS_SPACE) { - ut_ad(m_impl.m_sys_space == NULL - || m_impl.m_sys_space == space); - m_impl.m_sys_space = space; + ut_ad(!m_sys_space || m_sys_space == space); + m_sys_space = space; } else { - m_impl.m_user_space = space; + m_user_space = space; } } @@ -740,16 +674,15 @@ mtr_t::set_named_space(fil_space_t* space) bool mtr_t::memo_release(const void* object, ulint type) { - ut_ad(m_impl.m_magic_n == MTR_MAGIC_N); ut_ad(is_active()); /* We cannot release a page that has been written to in the middle of a mini-transaction. */ - ut_ad(!m_impl.m_modifications || type != MTR_MEMO_PAGE_X_FIX); + ut_ad(!m_modifications || type != MTR_MEMO_PAGE_X_FIX); Iterate<Find> iteration(Find(object, type)); - if (!m_impl.m_memo.for_each_block_in_reverse(iteration)) { + if (!m_memo.for_each_block_in_reverse(iteration)) { memo_slot_release(iteration.functor.m_slot); return(true); } @@ -763,16 +696,15 @@ mtr_t::memo_release(const void* object, ulint type) void mtr_t::release_page(const void* ptr, mtr_memo_type_t type) { - ut_ad(m_impl.m_magic_n == MTR_MAGIC_N); ut_ad(is_active()); /* We cannot release a page that has been written to in the middle of a mini-transaction. */ - ut_ad(!m_impl.m_modifications || type != MTR_MEMO_PAGE_X_FIX); + ut_ad(!m_modifications || type != MTR_MEMO_PAGE_X_FIX); Iterate<FindPage> iteration(FindPage(ptr, type)); - if (!m_impl.m_memo.for_each_block_in_reverse(iteration)) { + if (!m_memo.for_each_block_in_reverse(iteration)) { memo_slot_release(iteration.functor.get_slot()); return; } @@ -783,27 +715,20 @@ mtr_t::release_page(const void* ptr, mtr_memo_type_t type) /** Prepare to write the mini-transaction log to the redo log buffer. @return number of bytes to write in finish_write() */ -ulint -mtr_t::Command::prepare_write() +inline ulint mtr_t::prepare_write() { ut_ad(!recv_no_log_write); - switch (m_impl->m_log_mode) { - case MTR_LOG_SHORT_INSERTS: - ut_ad(0); - /* fall through (write no redo log) */ - case MTR_LOG_NO_REDO: - case MTR_LOG_NONE: - ut_ad(m_impl->m_log.size() == 0); + if (UNIV_UNLIKELY(m_log_mode != MTR_LOG_ALL)) { + ut_ad(m_log_mode == MTR_LOG_NO_REDO); + ut_ad(m_log.size() == 0); log_mutex_enter(); - m_end_lsn = m_start_lsn = log_sys->lsn; - return(0); - case MTR_LOG_ALL: - break; + m_commit_lsn = log_sys->lsn; + return 0; } - ulint len = m_impl->m_log.size(); - ulint n_recs = m_impl->m_n_log_recs; + ulint len = m_log.size(); + ulint n_recs = m_n_log_recs; ut_ad(len > 0); ut_ad(n_recs > 0); @@ -811,9 +736,9 @@ mtr_t::Command::prepare_write() log_buffer_extend((len + 1) * 2); } - ut_ad(m_impl->m_n_log_recs == n_recs); + ut_ad(m_n_log_recs == n_recs); - fil_space_t* space = m_impl->m_user_space; + fil_space_t* space = m_user_space; if (space != NULL && is_predefined_tablespace(space->id)) { /* Omit MLOG_FILE_NAME for predefined tablespaces. */ @@ -822,35 +747,32 @@ mtr_t::Command::prepare_write() log_mutex_enter(); - if (fil_names_write_if_was_clean(space, m_impl->m_mtr)) { + if (fil_names_write_if_was_clean(space, this)) { /* This mini-transaction was the first one to modify this tablespace since the latest checkpoint, so some MLOG_FILE_NAME records were appended to m_log. */ - ut_ad(m_impl->m_n_log_recs > n_recs); - mlog_catenate_ulint( - &m_impl->m_log, MLOG_MULTI_REC_END, MLOG_1BYTE); - len = m_impl->m_log.size(); + ut_ad(m_n_log_recs > n_recs); + mlog_catenate_ulint(&m_log, MLOG_MULTI_REC_END, MLOG_1BYTE); + len = m_log.size(); } else { /* This was not the first time of dirtying a tablespace since the latest checkpoint. */ - ut_ad(n_recs == m_impl->m_n_log_recs); + ut_ad(n_recs == m_n_log_recs); if (n_recs <= 1) { ut_ad(n_recs == 1); /* Flag the single log record as the only record in this mini-transaction. */ - *m_impl->m_log.front()->begin() - |= MLOG_SINGLE_REC_FLAG; + *m_log.front()->begin() |= MLOG_SINGLE_REC_FLAG; } else { /* Because this mini-transaction comprises multiple log records, append MLOG_MULTI_REC_END at the end. */ - mlog_catenate_ulint( - &m_impl->m_log, MLOG_MULTI_REC_END, - MLOG_1BYTE); + mlog_catenate_ulint(&m_log, MLOG_MULTI_REC_END, + MLOG_1BYTE); len++; } } @@ -862,98 +784,37 @@ mtr_t::Command::prepare_write() } /** Append the redo log records to the redo log buffer -@param[in] len number of bytes to write */ -void -mtr_t::Command::finish_write( - ulint len) +@param[in] len number of bytes to write +@return start_lsn */ +inline lsn_t mtr_t::finish_write(ulint len) { - ut_ad(m_impl->m_log_mode == MTR_LOG_ALL); + ut_ad(m_log_mode == MTR_LOG_ALL); ut_ad(log_mutex_own()); - ut_ad(m_impl->m_log.size() == len); + ut_ad(m_log.size() == len); ut_ad(len > 0); - if (m_impl->m_log.is_small()) { - const mtr_buf_t::block_t* front = m_impl->m_log.front(); + lsn_t start_lsn; + + if (m_log.is_small()) { + const mtr_buf_t::block_t* front = m_log.front(); ut_ad(len <= front->used()); - m_end_lsn = log_reserve_and_write_fast( - front->begin(), len, &m_start_lsn); + m_commit_lsn = log_reserve_and_write_fast(front->begin(), len, + &start_lsn); - if (m_end_lsn > 0) { - return; + if (m_commit_lsn) { + return start_lsn; } } /* Open the database log for log_write_low */ - m_start_lsn = log_reserve_and_open(len); + start_lsn = log_reserve_and_open(len); mtr_write_log_t write_log; - m_impl->m_log.for_each_block(write_log); - - m_end_lsn = log_close(); -} + m_log.for_each_block(write_log); -/** Release the latches and blocks acquired by this mini-transaction */ -void -mtr_t::Command::release_all() -{ - m_impl->m_memo.for_each_block_in_reverse(CIterate<ReleaseAll>()); - - /* Note that we have released the latches. */ - m_locks_released = 1; -} - -/** Release the latches acquired by this mini-transaction */ -void -mtr_t::Command::release_latches() -{ - m_impl->m_memo.for_each_block_in_reverse(CIterate<ReleaseLatches>()); - - /* Note that we have released the latches. */ - m_locks_released = 1; -} - -/** Release the blocks used in this mini-transaction */ -void -mtr_t::Command::release_blocks() -{ - m_impl->m_memo.for_each_block_in_reverse( - CIterate<const ReleaseBlocks>( - ReleaseBlocks(m_start_lsn, m_end_lsn, - m_impl->m_flush_observer))); -} - -/** Write the redo log record, add dirty pages to the flush list and release -the resources. */ -void -mtr_t::Command::execute() -{ - ut_ad(m_impl->m_log_mode != MTR_LOG_NONE); - - if (const ulint len = prepare_write()) { - finish_write(len); - } - - if (m_impl->m_made_dirty) { - log_flush_order_mutex_enter(); - } - - /* It is now safe to release the log mutex because the - flush_order mutex will ensure that we are the first one - to insert into the flush list. */ - log_mutex_exit(); - - m_impl->m_mtr->m_commit_lsn = m_end_lsn; - - release_blocks(); - - if (m_impl->m_made_dirty) { - log_flush_order_mutex_exit(); - } - - release_latches(); - - release_resources(); + m_commit_lsn = log_close(); + return start_lsn; } /** Release the free extents that was reserved using @@ -966,23 +827,22 @@ mtr_t::release_free_extents(ulint n_reserved) { fil_space_t* space; - ut_ad(m_impl.m_undo_space == NULL); + ut_ad(!m_undo_space); - if (m_impl.m_user_space != NULL) { + if (m_user_space) { - ut_ad(m_impl.m_user_space->id - == m_impl.m_user_space_id); - ut_ad(memo_contains(get_memo(), &m_impl.m_user_space->latch, + ut_ad(m_user_space->id == m_user_space_id); + ut_ad(memo_contains(get_memo(), &m_user_space->latch, MTR_MEMO_X_LOCK)); - space = m_impl.m_user_space; + space = m_user_space; } else { - ut_ad(m_impl.m_sys_space->id == TRX_SYS_SPACE); - ut_ad(memo_contains(get_memo(), &m_impl.m_sys_space->latch, + ut_ad(m_sys_space->id == TRX_SYS_SPACE); + ut_ad(memo_contains(get_memo(), &m_sys_space->latch, MTR_MEMO_X_LOCK)); - space = m_impl.m_sys_space; + space = m_sys_space; } space->release_free_extents(n_reserved); @@ -1084,10 +944,9 @@ struct FlaggedCheck { bool mtr_t::memo_contains_flagged(const void* ptr, ulint flags) const { - ut_ad(m_impl.m_magic_n == MTR_MAGIC_N); - ut_ad(is_committing() || is_active()); + ut_ad(is_active()); - return !m_impl.m_memo.for_each_block_in_reverse( + return !m_memo.for_each_block_in_reverse( CIterate<FlaggedCheck>(FlaggedCheck(ptr, flags))); } @@ -1103,7 +962,7 @@ mtr_t::memo_contains_page_flagged( ulint flags) const { Iterate<FindPage> iteration(FindPage(ptr, flags)); - return m_impl.m_memo.for_each_block_in_reverse(iteration) + return m_memo.for_each_block_in_reverse(iteration) ? NULL : iteration.functor.get_block(); } @@ -1126,7 +985,7 @@ void mtr_t::print() const { ib::info() << "Mini-transaction handle: memo size " - << m_impl.m_memo.size() << " bytes log size " + << m_memo.size() << " bytes log size " << get_log()->size() << " bytes"; } |