diff options
Diffstat (limited to 'storage/innobase/include/mtr0mtr.h')
-rw-r--r-- | storage/innobase/include/mtr0mtr.h | 945 |
1 files changed, 553 insertions, 392 deletions
diff --git a/storage/innobase/include/mtr0mtr.h b/storage/innobase/include/mtr0mtr.h index c3307985532..3526436f042 100644 --- a/storage/innobase/include/mtr0mtr.h +++ b/storage/innobase/include/mtr0mtr.h @@ -29,427 +29,588 @@ Created 11/26/1995 Heikki Tuuri #define mtr0mtr_h #include "univ.i" -#include "mem0mem.h" -#include "dyn0dyn.h" -#include "buf0types.h" -#include "sync0rw.h" -#include "ut0byte.h" +#include "log0types.h" #include "mtr0types.h" -#include "page0types.h" +#include "buf0types.h" #include "trx0types.h" +#include "dyn0buf.h" -/* Logging modes for a mini-transaction */ -#define MTR_LOG_ALL 21 /* default mode: log all operations - modifying disk-based data */ -#define MTR_LOG_NONE 22 /* log no operations */ -#define MTR_LOG_NO_REDO 23 /* Don't generate REDO */ -/*#define MTR_LOG_SPACE 23 */ /* log only operations modifying - file space page allocation data - (operations in fsp0fsp.* ) */ -#define MTR_LOG_SHORT_INSERTS 24 /* inserts are logged in a shorter - form */ - -/* Types for the mlock objects to store in the mtr memo; NOTE that the -first 3 values must be RW_S_LATCH, RW_X_LATCH, RW_NO_LATCH */ -#define MTR_MEMO_PAGE_S_FIX RW_S_LATCH -#define MTR_MEMO_PAGE_X_FIX RW_X_LATCH -#define MTR_MEMO_BUF_FIX RW_NO_LATCH -#ifdef UNIV_DEBUG -# define MTR_MEMO_MODIFY 54 -#endif /* UNIV_DEBUG */ -#define MTR_MEMO_S_LOCK 55 -#define MTR_MEMO_X_LOCK 56 - -/** @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! -For 1 - 8 bytes, the flag value must give the length also! @{ */ -#define MLOG_SINGLE_REC_FLAG 128 /*!< if the mtr contains only - one log record for one page, - i.e., write_initial_log_record - has been called only once, - this flag is ORed to the type - of that first log record */ -#define MLOG_1BYTE (1) /*!< one byte is written */ -#define MLOG_2BYTES (2) /*!< 2 bytes ... */ -#define MLOG_4BYTES (4) /*!< 4 bytes ... */ -#define MLOG_8BYTES (8) /*!< 8 bytes ... */ -#define MLOG_REC_INSERT ((byte)9) /*!< record insert */ -#define MLOG_REC_CLUST_DELETE_MARK ((byte)10) /*!< mark clustered index record - deleted */ -#define MLOG_REC_SEC_DELETE_MARK ((byte)11) /*!< mark secondary index record - deleted */ -#define MLOG_REC_UPDATE_IN_PLACE ((byte)13) /*!< update of a record, - preserves record field sizes */ -#define MLOG_REC_DELETE ((byte)14) /*!< delete a record from a - page */ -#define MLOG_LIST_END_DELETE ((byte)15) /*!< delete record list end on - index page */ -#define MLOG_LIST_START_DELETE ((byte)16) /*!< delete record list start on - index page */ -#define MLOG_LIST_END_COPY_CREATED ((byte)17) /*!< copy record list end to a - new created index page */ -#define MLOG_PAGE_REORGANIZE ((byte)18) /*!< reorganize an - index page in - ROW_FORMAT=REDUNDANT */ -#define MLOG_PAGE_CREATE ((byte)19) /*!< create an index page */ -#define MLOG_UNDO_INSERT ((byte)20) /*!< insert entry in an undo - log */ -#define MLOG_UNDO_ERASE_END ((byte)21) /*!< erase an undo log - page end */ -#define MLOG_UNDO_INIT ((byte)22) /*!< initialize a page in an - undo log */ -#define MLOG_UNDO_HDR_DISCARD ((byte)23) /*!< discard an update undo log - header */ -#define MLOG_UNDO_HDR_REUSE ((byte)24) /*!< reuse an insert undo log - header */ -#define MLOG_UNDO_HDR_CREATE ((byte)25) /*!< create an undo - log header */ -#define MLOG_REC_MIN_MARK ((byte)26) /*!< mark an index - record as the - predefined minimum - record */ -#define MLOG_IBUF_BITMAP_INIT ((byte)27) /*!< initialize an - ibuf bitmap page */ -/*#define MLOG_FULL_PAGE ((byte)28) full contents of a page */ -#ifdef UNIV_LOG_LSN_DEBUG -# define MLOG_LSN ((byte)28) /* current LSN */ -#endif -#define MLOG_INIT_FILE_PAGE ((byte)29) /*!< this means that a - file page is taken - into use and the prior - contents of the page - should be ignored: in - recovery we must not - trust the lsn values - stored to the file - page */ -#define MLOG_WRITE_STRING ((byte)30) /*!< write a string to - a page */ -#define MLOG_MULTI_REC_END ((byte)31) /*!< if a single mtr writes - several log records, - this log record ends the - sequence of these records */ -#define MLOG_DUMMY_RECORD ((byte)32) /*!< dummy log record used to - pad a log block full */ -#define MLOG_FILE_CREATE ((byte)33) /*!< log record about an .ibd - file creation */ -#define MLOG_FILE_RENAME ((byte)34) /*!< log record about an .ibd - file rename */ -#define MLOG_FILE_DELETE ((byte)35) /*!< log record about an .ibd - file deletion */ -#define MLOG_COMP_REC_MIN_MARK ((byte)36) /*!< mark a compact - index record as the - predefined minimum - record */ -#define MLOG_COMP_PAGE_CREATE ((byte)37) /*!< create a compact - index page */ -#define MLOG_COMP_REC_INSERT ((byte)38) /*!< compact record insert */ -#define MLOG_COMP_REC_CLUST_DELETE_MARK ((byte)39) - /*!< mark compact - clustered index record - deleted */ -#define MLOG_COMP_REC_SEC_DELETE_MARK ((byte)40)/*!< mark compact - secondary index record - deleted; this log - record type is - redundant, as - MLOG_REC_SEC_DELETE_MARK - is independent of the - record format. */ -#define MLOG_COMP_REC_UPDATE_IN_PLACE ((byte)41)/*!< update of a - compact record, - preserves record field - sizes */ -#define MLOG_COMP_REC_DELETE ((byte)42) /*!< delete a compact record - from a page */ -#define MLOG_COMP_LIST_END_DELETE ((byte)43) /*!< delete compact record list - end on index page */ -#define MLOG_COMP_LIST_START_DELETE ((byte)44) /*!< delete compact record list - start on index page */ -#define MLOG_COMP_LIST_END_COPY_CREATED ((byte)45) - /*!< copy compact - record list end to a - new created index - page */ -#define MLOG_COMP_PAGE_REORGANIZE ((byte)46) /*!< reorganize an index page */ -#define MLOG_FILE_CREATE2 ((byte)47) /*!< log record about creating - an .ibd file, with format */ -#define MLOG_ZIP_WRITE_NODE_PTR ((byte)48) /*!< write the node pointer of - a record on a compressed - non-leaf B-tree page */ -#define MLOG_ZIP_WRITE_BLOB_PTR ((byte)49) /*!< write the BLOB pointer - of an externally stored column - on a compressed page */ -#define MLOG_ZIP_WRITE_HEADER ((byte)50) /*!< write to compressed page - header */ -#define MLOG_ZIP_PAGE_COMPRESS ((byte)51) /*!< compress an index page */ -#define MLOG_ZIP_PAGE_COMPRESS_NO_DATA ((byte)52)/*!< compress an index page - without logging it's image */ -#define MLOG_ZIP_PAGE_REORGANIZE ((byte)53) /*!< reorganize a compressed - page */ -#define MLOG_BIGGEST_TYPE ((byte)53) /*!< biggest value (used in - assertions) */ - -#define MLOG_FILE_WRITE_CRYPT_DATA ((byte)100) /*!< log record for - writing/updating crypt data of - a tablespace */ - -#define EXTRA_CHECK_MLOG_NUMBER(x) \ - ((x) == MLOG_FILE_WRITE_CRYPT_DATA) - -/* @} */ - -/** @name Flags for MLOG_FILE operations -(stored in the page number parameter, called log_flags in the -functions). The page number parameter was originally written as 0. @{ */ -#define MLOG_FILE_FLAG_TEMP 1 /*!< identifies TEMPORARY TABLE in - MLOG_FILE_CREATE, MLOG_FILE_CREATE2 */ -/* @} */ - -/* included here because it needs MLOG_LSN defined */ -#include "log0log.h" - -/***************************************************************//** -Starts a mini-transaction. */ -UNIV_INLINE -void -mtr_start_trx( -/*======*/ - mtr_t* mtr, /*!< out: mini-transaction */ - trx_t* trx) /*!< in: transaction */ - MY_ATTRIBUTE((nonnull (1))); -/***************************************************************//** -Starts a mini-transaction. */ -UNIV_INLINE -void -mtr_start( -/*======*/ - mtr_t* mtr) /*!< out: mini-transaction */ -{ - mtr_start_trx(mtr, NULL); -} - MY_ATTRIBUTE((nonnull)) -/***************************************************************//** -Commits a mini-transaction. */ -UNIV_INTERN -void -mtr_commit( -/*=======*/ - mtr_t* mtr) /*!< in/out: mini-transaction */ - MY_ATTRIBUTE((nonnull)); -/**********************************************************//** -Sets and returns a savepoint in mtr. +/** Start a mini-transaction. */ +#define mtr_start(m) (m)->start() +/** Start a mini-transaction. */ +#define mtr_start_trx(m, t) (m)->start((t)) + +/** Start a synchronous mini-transaction */ +#define mtr_start_sync(m) (m)->start(true) + +/** Start an asynchronous read-only mini-transaction */ +#define mtr_start_ro(m) (m)->start(true, true) + +/** Commit a mini-transaction. */ +#define mtr_commit(m) (m)->commit() + +/** Set and return a savepoint in mtr. @return savepoint */ -UNIV_INLINE -ulint -mtr_set_savepoint( -/*==============*/ - mtr_t* mtr); /*!< in: mtr */ -#ifndef UNIV_HOTBACKUP -/**********************************************************//** -Releases the (index tree) s-latch stored in an mtr memo after a -savepoint. */ -UNIV_INLINE -void -mtr_release_s_latch_at_savepoint( -/*=============================*/ - mtr_t* mtr, /*!< in: mtr */ - ulint savepoint, /*!< in: savepoint */ - rw_lock_t* lock); /*!< in: latch to release */ -#else /* !UNIV_HOTBACKUP */ -# define mtr_release_s_latch_at_savepoint(mtr,savepoint,lock) ((void) 0) -#endif /* !UNIV_HOTBACKUP */ - -/**********************************************************//** -Releases a buf_page stored in an mtr memo after a +#define mtr_set_savepoint(m) (m)->get_savepoint() + +/** Release the (index tree) s-latch stored in an mtr memo after a savepoint. */ -UNIV_INTERN -void -mtr_release_buf_page_at_savepoint( -/*=============================*/ - mtr_t* mtr, /*!< in: mtr */ - ulint savepoint, /*!< in: savepoint */ - buf_block_t* block); /*!< in: block to release */ - -/***************************************************************//** -Gets the logging mode of a mini-transaction. +#define mtr_release_s_latch_at_savepoint(m, s, l) \ + (m)->release_s_latch_at_savepoint((s), (l)) + +/** Get the logging mode of a mini-transaction. @return logging mode: MTR_LOG_NONE, ... */ -UNIV_INLINE -ulint -mtr_get_log_mode( -/*=============*/ - mtr_t* mtr); /*!< in: mtr */ -/***************************************************************//** -Changes the logging mode of a mini-transaction. +#define mtr_get_log_mode(m) (m)->get_log_mode() + +/** Change the logging mode of a mini-transaction. @return old mode */ -UNIV_INLINE -ulint -mtr_set_log_mode( -/*=============*/ - mtr_t* mtr, /*!< in: mtr */ - ulint mode); /*!< in: logging mode: MTR_LOG_NONE, ... */ -/********************************************************//** -Reads 1 - 4 bytes from a file page buffered in the buffer pool. +#define mtr_set_log_mode(m, d) (m)->set_log_mode((d)) + +/** Get the flush observer of a mini-transaction. +@return flush observer object */ +#define mtr_get_flush_observer(m) (m)->get_flush_observer() + +/** Set the flush observer of a mini-transaction. */ +#define mtr_set_flush_observer(m, d) (m)->set_flush_observer((d)) + +/** Read 1 - 4 bytes from a file page buffered in the buffer pool. @return value read */ -UNIV_INTERN -ulint -mtr_read_ulint( -/*===========*/ - const byte* ptr, /*!< in: pointer from where to read */ - ulint type, /*!< in: MLOG_1BYTE, MLOG_2BYTES, MLOG_4BYTES */ - mtr_t* mtr); /*!< in: mini-transaction handle */ -#ifndef UNIV_HOTBACKUP -/*********************************************************************//** -This macro locks an rw-lock in s-mode. */ -#define mtr_s_lock(B, MTR) mtr_s_lock_func((B), __FILE__, __LINE__,\ - (MTR)) -/*********************************************************************//** -This macro locks an rw-lock in x-mode. */ -#define mtr_x_lock(B, MTR) mtr_x_lock_func((B), __FILE__, __LINE__,\ - (MTR)) -/*********************************************************************//** -NOTE! Use the macro above! -Locks a lock in s-mode. */ -UNIV_INLINE -void -mtr_s_lock_func( -/*============*/ - rw_lock_t* lock, /*!< in: rw-lock */ - const char* file, /*!< in: file name */ - ulint line, /*!< in: line number */ - mtr_t* mtr); /*!< in: mtr */ -/*********************************************************************//** -NOTE! Use the macro above! -Locks a lock in x-mode. */ -UNIV_INLINE -void -mtr_x_lock_func( -/*============*/ - rw_lock_t* lock, /*!< in: rw-lock */ - const char* file, /*!< in: file name */ - ulint line, /*!< in: line number */ - mtr_t* mtr); /*!< in: mtr */ -#endif /* !UNIV_HOTBACKUP */ - -/***************************************************//** -Releases an object in the memo stack. +#define mtr_read_ulint(p, t, m) (m)->read_ulint((p), (t)) + +/** Release an object in the memo stack. @return true if released */ -UNIV_INTERN -bool -mtr_memo_release( -/*=============*/ - mtr_t* mtr, /*!< in/out: mini-transaction */ - void* object, /*!< in: object */ - ulint type) /*!< in: object type: MTR_MEMO_S_LOCK, ... */ - MY_ATTRIBUTE((nonnull)); +#define mtr_memo_release(m, o, t) \ + (m)->memo_release((o), (t)) + #ifdef UNIV_DEBUG -# ifndef UNIV_HOTBACKUP -/**********************************************************//** -Checks if memo contains the given item. + +/** Check if memo contains the given item. */ +#define mtr_is_block_fix(m, o, t, table) mtr_memo_contains(m, o, t) + +/** Check if memo contains the given page. */ +#define mtr_is_page_fix(m, p, t, table) mtr_memo_contains_page(m, p, t) + +/** Check if memo contains the given item. @return TRUE if contains */ -UNIV_INLINE -bool -mtr_memo_contains( -/*==============*/ - mtr_t* mtr, /*!< in: mtr */ - const void* object, /*!< in: object to search */ - ulint type) /*!< in: type of object */ - MY_ATTRIBUTE((warn_unused_result, nonnull)); - -/**********************************************************//** -Checks if memo contains the given page. +#define mtr_memo_contains(m, o, t) \ + (m)->memo_contains((m)->get_memo(), (o), (t)) + +/** Check if memo contains the given page. @return TRUE if contains */ -UNIV_INTERN -ibool -mtr_memo_contains_page( -/*===================*/ - mtr_t* mtr, /*!< in: mtr */ - const byte* ptr, /*!< in: pointer to buffer frame */ - ulint type); /*!< in: type of object */ -/*********************************************************//** -Prints info of an mtr handle. */ -UNIV_INTERN -void -mtr_print( -/*======*/ - mtr_t* mtr); /*!< in: mtr */ -# else /* !UNIV_HOTBACKUP */ -# define mtr_memo_contains(mtr, object, type) TRUE -# define mtr_memo_contains_page(mtr, ptr, type) TRUE -# endif /* !UNIV_HOTBACKUP */ +#define mtr_memo_contains_page(m, p, t) \ + (m)->memo_contains_page_flagged((p), (t)) #endif /* UNIV_DEBUG */ -/*######################################################################*/ -#define MTR_BUF_MEMO_SIZE 200 /* number of slots in memo */ +/** Print info of an mtr handle. */ +#define mtr_print(m) (m)->print() -/***************************************************************//** -Returns the log object of a mini-transaction buffer. +/** Return the log object of a mini-transaction buffer. @return log */ -UNIV_INLINE -dyn_array_t* -mtr_get_log( -/*========*/ - mtr_t* mtr); /*!< in: mini-transaction */ -/***************************************************//** -Pushes an object to an mtr memo stack. */ -UNIV_INLINE +#define mtr_get_log(m) (m)->get_log() + +/** Push an object to an mtr memo stack. */ +#define mtr_memo_push(m, o, t) (m)->memo_push(o, t) + +/** Lock an rw-lock in s-mode. */ +#define mtr_s_lock(l, m) (m)->s_lock((l), __FILE__, __LINE__) + +/** Lock an rw-lock in x-mode. */ +#define mtr_x_lock(l, m) (m)->x_lock((l), __FILE__, __LINE__) + +/** Lock a tablespace in x-mode. */ +#define mtr_x_lock_space(s, m) (m)->x_lock_space((s), __FILE__, __LINE__) + +/** Lock an rw-lock in sx-mode. */ +#define mtr_sx_lock(l, m) (m)->sx_lock((l), __FILE__, __LINE__) + +#define mtr_memo_contains_flagged(m, p, l) \ + (m)->memo_contains_flagged((p), (l)) + +#define mtr_memo_contains_page_flagged(m, p, l) \ + (m)->memo_contains_page_flagged((p), (l)) + +#define mtr_release_block_at_savepoint(m, s, b) \ + (m)->release_block_at_savepoint((s), (b)) + +#define mtr_block_sx_latch_at_savepoint(m, s, b) \ + (m)->sx_latch_at_savepoint((s), (b)) + +#define mtr_block_x_latch_at_savepoint(m, s, b) \ + (m)->x_latch_at_savepoint((s), (b)) + +/** Check if a mini-transaction is dirtying a clean page. +@param b block being x-fixed +@return true if the mtr is dirtying a clean page. */ +#define mtr_block_dirtied(b) mtr_t::is_block_dirtied((b)) + +/** Forward declaration of a tablespace object */ +struct fil_space_t; + +/** Append records to the system-wide redo log buffer. +@param[in] log redo log records */ void -mtr_memo_push( -/*==========*/ - mtr_t* mtr, /*!< in: mtr */ - void* object, /*!< in: object */ - ulint type); /*!< in: object type: MTR_MEMO_S_LOCK, ... */ +mtr_write_log( + const mtr_buf_t* log); /** Mini-transaction memo stack slot. */ -struct mtr_memo_slot_t{ - ulint type; /*!< type of the stored object (MTR_MEMO_S_LOCK, ...) */ - void* object; /*!< pointer to the object */ +struct mtr_memo_slot_t { + /** pointer to the object */ + void* object; + + /** type of the stored object (MTR_MEMO_S_LOCK, ...) */ + ulint type; }; -/* Mini-transaction handle and buffer */ -struct mtr_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 - ulint state; /*!< MTR_ACTIVE, MTR_COMMITTING, MTR_COMMITTED */ -#endif - dyn_array_t memo; /*!< memo stack for locks etc. */ - dyn_array_t log; /*!< mini-transaction log */ - unsigned inside_ibuf:1; - /*!< TRUE if inside ibuf changes */ - unsigned modifications:1; - /*!< TRUE if the mini-transaction - modified buffer pool pages */ - unsigned made_dirty:1; - /*!< TRUE if mtr has made at least - one buffer pool page dirty */ - ulint n_log_recs; - /* count of how many page initial log records - have been written to the mtr log */ - ulint n_freed_pages; - /* number of pages that have been freed in - this mini-transaction */ - ulint log_mode; /* specifies which operations should be - logged; default value MTR_LOG_ALL */ - lsn_t start_lsn;/* start lsn of the possible log entry for - this mtr */ - lsn_t end_lsn;/* end lsn of the possible log entry for - this mtr */ + /** 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 - ulint magic_n; + /** For checking corruption. */ + ulint m_magic_n; #endif /* UNIV_DEBUG */ - trx_t* trx; /*!< transaction */ -}; + + /** Owning mini-transaction */ + mtr_t* m_mtr; + + /* Transaction handle */ + trx_t* m_trx; + }; + + mtr_t() + { + m_impl.m_state = MTR_STATE_INIT; + } + + ~mtr_t() { } + + /** Release the free extents that was reserved using + fsp_reserve_free_extents(). This is equivalent to calling + fil_space_release_free_extents(). This is intended for use + with index pages. + @param[in] n_reserved number of reserved extents */ + void release_free_extents(ulint n_reserved); + + /** Start a mini-transaction. + @param sync true if it is a synchronous mini-transaction + @param read_only true if read only mini-transaction */ + void start(bool sync = true, bool read_only = false); + + /** Start a mini-transaction. + @param sync true if it is a synchronous mini-transaction + @param read_only true if read only mini-transaction */ + void start(trx_t* trx, bool sync = true, bool read_only = false); + + /** @return whether this is an asynchronous mini-transaction. */ + bool is_async() const + { + return(!m_sync); + } + + /** Request a future commit to be synchronous. */ + void set_sync() + { + m_sync = true; + } + + /** Commit the mini-transaction. */ + void commit(); + + /** Commit a mini-transaction that did not modify any pages, + but generated some redo log on a higher level, such as + MLOG_FILE_NAME records and a MLOG_CHECKPOINT marker. + The caller must invoke log_mutex_enter() and log_mutex_exit(). + This is to be used at log_checkpoint(). + @param[in] checkpoint_lsn the LSN of the log checkpoint */ + void commit_checkpoint(lsn_t checkpoint_lsn); + + /** 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()); + } + + /** Release the (index tree) s-latch stored in an mtr memo after a + savepoint. + @param savepoint value returned by @see set_savepoint. + @param lock latch to release */ + inline void release_s_latch_at_savepoint( + ulint savepoint, + rw_lock_t* lock); + + /** Release the block in an mtr memo after a savepoint. */ + inline void release_block_at_savepoint( + ulint savepoint, + buf_block_t* block); + + /** SX-latch a not yet latched block after a savepoint. */ + inline void sx_latch_at_savepoint(ulint savepoint, buf_block_t* block); + + /** X-latch a not yet latched block after a savepoint. */ + inline void x_latch_at_savepoint(ulint savepoint, buf_block_t* block); + + /** Get the logging mode. + @return logging mode */ + inline mtr_log_t get_log_mode() const + MY_ATTRIBUTE((warn_unused_result)); + + /** Change the logging mode. + @param mode logging mode + @return old mode */ + inline mtr_log_t set_log_mode(mtr_log_t mode); + + /** Note that the mini-transaction is modifying the system tablespace + (for example, for the change buffer or for undo logs) + @return the system tablespace */ + fil_space_t* set_sys_modified() + { + if (!m_impl.m_sys_space) { + lookup_sys_space(); + } + return(m_impl.m_sys_space); + } + + /** Copy the tablespaces associated with the mini-transaction + (needed for generating MLOG_FILE_NAME records) + @param[in] mtr mini-transaction that may modify + the same set of tablespaces as this one */ + void set_spaces(const mtr_t& mtr) + { + ut_ad(m_impl.m_user_space_id == TRX_SYS_SPACE); + 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; + } + + /** Set the tablespace associated with the mini-transaction + (needed for generating a MLOG_FILE_NAME record) + @param[in] space_id user or system tablespace ID + @return the tablespace */ + fil_space_t* set_named_space(ulint space_id) + { + ut_ad(m_impl.m_user_space_id == TRX_SYS_SPACE); + ut_d(m_impl.m_user_space_id = space_id); + if (space_id == TRX_SYS_SPACE) { + return(set_sys_modified()); + } else { + lookup_user_space(space_id); + return(m_impl.m_user_space); + } + } + + /** Set the tablespace associated with the mini-transaction + (needed for generating a MLOG_FILE_NAME record) + @param[in] space user or system tablespace */ + void set_named_space(fil_space_t* space); #ifdef UNIV_DEBUG -# define MTR_MAGIC_N 54551 + /** Check the tablespace associated with the mini-transaction + (needed for generating a MLOG_FILE_NAME record) + @param[in] space tablespace + @return whether the mini-transaction is associated with the space */ + bool is_named_space(ulint space) const; #endif /* UNIV_DEBUG */ -#define MTR_ACTIVE 12231 -#define MTR_COMMITTING 56456 -#define MTR_COMMITTED 34676 + /** Read 1 - 4 bytes from a file page buffered in the buffer pool. + @param ptr pointer from where to read + @param type) MLOG_1BYTE, MLOG_2BYTES, MLOG_4BYTES + @return value read */ + inline ulint read_ulint(const byte* ptr, mlog_id_t type) const + MY_ATTRIBUTE((warn_unused_result)); + + /** Locks a rw-latch in S mode. + NOTE: use mtr_s_lock(). + @param lock rw-lock + @param file file name from where called + @param line line number in file */ + inline void s_lock(rw_lock_t* lock, const char* file, ulint line); + + /** Locks a rw-latch in X mode. + NOTE: use mtr_x_lock(). + @param lock rw-lock + @param file file name from where called + @param line line number in file */ + inline void x_lock(rw_lock_t* lock, const char* file, ulint line); + + /** Locks a rw-latch in X mode. + NOTE: use mtr_sx_lock(). + @param lock rw-lock + @param file file name from where called + @param line line number in file */ + inline void sx_lock(rw_lock_t* lock, const char* file, ulint line); + + /** Acquire a tablespace X-latch. + NOTE: use mtr_x_lock_space(). + @param[in] space_id tablespace ID + @param[in] file file name from where called + @param[in] line line number in file + @return the tablespace object (never NULL) */ + fil_space_t* x_lock_space( + ulint space_id, + const char* file, + ulint line); + + /** Release an object in the memo stack. + @param object object + @param type object type: MTR_MEMO_S_LOCK, ... + @return bool if lock released */ + bool memo_release(const void* object, ulint type); + /** Release a page latch. + @param[in] ptr pointer to within a page frame + @param[in] type object type: MTR_MEMO_PAGE_X_FIX, ... */ + 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; + } + + /** 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; + } + + /** Get the LSN of commit(). + @return the commit LSN + @retval 0 if the transaction only modified temporary tablespaces */ + lsn_t commit_lsn() const + { + ut_ad(has_committed()); + return(m_commit_lsn); + } + + /** Note that we are inside the change buffer code. */ + void enter_ibuf() + { + m_impl.m_inside_ibuf = true; + } + + /** Note that we have exited from the change buffer code. */ + void exit_ibuf() + { + m_impl.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); + } + + /* + @return true if the mini-transaction is active */ + bool is_active() const + { + return(m_impl.m_state == MTR_STATE_ACTIVE); + } + + /** Get flush observer + @return flush observer */ + FlushObserver* get_flush_observer() const + { + return(m_impl.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; + } + +#ifdef UNIV_DEBUG + /** Check if memo contains the given item. + @param memo memo stack + @param object, object to search + @param type type of object + @return true if contains */ + static bool memo_contains( + mtr_buf_t* memo, + const void* object, + ulint type) + MY_ATTRIBUTE((warn_unused_result)); + + /** Check if memo contains the given item. + @param object object to search + @param flags specify types of object (can be ORred) of + MTR_MEMO_PAGE_S_FIX ... values + @return true if contains */ + bool memo_contains_flagged(const void* ptr, ulint flags) const; + + /** Check if memo contains the given page. + @param[in] ptr pointer to within buffer frame + @param[in] flags specify types of object with OR of + MTR_MEMO_PAGE_S_FIX... values + @return the block + @retval NULL if not found */ + buf_block_t* memo_contains_page_flagged( + const byte* ptr, + ulint flags) const; + + /** Mark the given latched page as modified. + @param[in] ptr pointer to within buffer frame */ + void memo_modify_page(const byte* ptr); + + /** Print info of an mtr handle. */ + 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); + } + + /** @return true if mini-transaction contains modifications. */ + bool has_modifications() const + { + return(m_impl.m_modifications); + } + + /** @return the memo stack */ + const mtr_buf_t* get_memo() const + { + return(&m_impl.m_memo); + } + + /** @return the memo stack */ + mtr_buf_t* get_memo() + { + return(&m_impl.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); + } + + /** Note that a record has been added to the log */ + void added_rec() + { + ++m_impl.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); + } + + /** 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); + } + + /** Push an object to an mtr memo stack. + @param object object + @param type object type: MTR_MEMO_S_LOCK, ... */ + inline void memo_push(void* object, mtr_memo_type_t type); + + /** Check if this mini-transaction is dirtying a clean page. + @param block block being x-fixed + @return true if the mtr is dirtying a clean page. */ + static bool is_block_dirtied(const buf_block_t* block) + MY_ATTRIBUTE((warn_unused_result)); + +private: + /** Look up the system tablespace. */ + void lookup_sys_space(); + /** Look up the user tablespace. + @param[in] space_id tablespace ID */ + void lookup_user_space(ulint space_id); + + class Command; + + friend class Command; + +private: + Impl m_impl; + + /** LSN at commit time */ + volatile lsn_t m_commit_lsn; + + /** true if it is synchronous mini-transaction */ + bool m_sync; +}; #ifndef UNIV_NONINL #include "mtr0mtr.ic" -#endif +#endif /* UNIV_NOINL */ -#endif +#endif /* mtr0mtr_h */ |