diff options
Diffstat (limited to 'storage/innobase/mtr/mtr0mtr.cc')
-rw-r--r-- | storage/innobase/mtr/mtr0mtr.cc | 107 |
1 files changed, 61 insertions, 46 deletions
diff --git a/storage/innobase/mtr/mtr0mtr.cc b/storage/innobase/mtr/mtr0mtr.cc index 4832e8c7710..10b4686b720 100644 --- a/storage/innobase/mtr/mtr0mtr.cc +++ b/storage/innobase/mtr/mtr0mtr.cc @@ -142,9 +142,9 @@ mtr_memo_slot_note_modification( mtr_t* mtr, /*!< in: mtr */ mtr_memo_slot_t* slot) /*!< in: memo slot */ { - ut_ad(mtr); - ut_ad(mtr->magic_n == MTR_MAGIC_N); ut_ad(mtr->modifications); + ut_ad(!srv_read_only_mode); + ut_ad(mtr->magic_n == MTR_MAGIC_N); if (slot->object != NULL && slot->type == MTR_MEMO_PAGE_X_FIX) { buf_block_t* block = (buf_block_t*) slot->object; @@ -170,7 +170,7 @@ mtr_memo_note_modifications( dyn_array_t* memo; ulint offset; - ut_ad(mtr); + ut_ad(!srv_read_only_mode); ut_ad(mtr->magic_n == MTR_MAGIC_N); ut_ad(mtr->state == MTR_COMMITTING); /* Currently only used in commit */ @@ -191,19 +191,51 @@ mtr_memo_note_modifications( } /************************************************************//** +Append the dirty pages to the flush list. */ +static +void +mtr_add_dirtied_pages_to_flush_list( +/*================================*/ + mtr_t* mtr) /*!< in/out: mtr */ +{ + ut_ad(!srv_read_only_mode); + + /* No need to acquire log_flush_order_mutex if this mtr has + not dirtied a clean page. log_flush_order_mutex is used to + ensure ordered insertions in the flush_list. We need to + insert in the flush_list iff the page in question was clean + before modifications. */ + if (mtr->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_release(); + + if (mtr->modifications) { + mtr_memo_note_modifications(mtr); + } + + if (mtr->made_dirty) { + log_flush_order_mutex_exit(); + } +} + +/************************************************************//** Writes the contents of a mini-transaction log, if any, to the database log. */ static void mtr_log_reserve_and_write( /*======================*/ - mtr_t* mtr) /*!< in: mtr */ + mtr_t* mtr) /*!< in/out: mtr */ { dyn_array_t* mlog; - dyn_block_t* block; ulint data_size; byte* first_data; - ut_ad(mtr); + ut_ad(!srv_read_only_mode); mlog = &(mtr->log); @@ -217,14 +249,21 @@ mtr_log_reserve_and_write( } if (mlog->heap == NULL) { + ulint len; + + len = mtr->log_mode != MTR_LOG_NO_REDO + ? dyn_block_get_used(mlog) : 0; + mtr->end_lsn = log_reserve_and_write_fast( - first_data, dyn_block_get_used(mlog), - &mtr->start_lsn); + first_data, len, &mtr->start_lsn); + if (mtr->end_lsn) { /* Success. We have the log mutex. Add pages to flush list and exit */ - goto func_exit; + mtr_add_dirtied_pages_to_flush_list(mtr); + + return; } } @@ -235,43 +274,24 @@ mtr_log_reserve_and_write( if (mtr->log_mode == MTR_LOG_ALL) { - block = mlog; + for (dyn_block_t* block = mlog; + block != 0; + block = dyn_array_get_next_block(mlog, block)) { - while (block != NULL) { - log_write_low(dyn_block_get_data(block), - dyn_block_get_used(block)); - block = dyn_array_get_next_block(mlog, block); + log_write_low( + dyn_block_get_data(block), + dyn_block_get_used(block)); } + } else { - ut_ad(mtr->log_mode == MTR_LOG_NONE); + ut_ad(mtr->log_mode == MTR_LOG_NONE + || mtr->log_mode == MTR_LOG_NO_REDO); /* Do nothing */ } mtr->end_lsn = log_close(); -func_exit: - - /* No need to acquire log_flush_order_mutex if this mtr has - not dirtied a clean page. log_flush_order_mutex is used to - ensure ordered insertions in the flush_list. We need to - insert in the flush_list iff the page in question was clean - before modifications. */ - if (mtr->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_release(); - - if (mtr->modifications) { - mtr_memo_note_modifications(mtr); - } - - if (mtr->made_dirty) { - log_flush_order_mutex_exit(); - } + mtr_add_dirtied_pages_to_flush_list(mtr); } #endif /* !UNIV_HOTBACKUP */ @@ -294,6 +314,7 @@ mtr_commit( ut_ad(!recv_no_log_write); if (mtr->modifications && mtr->n_log_recs) { + ut_ad(!srv_read_only_mode); mtr_log_reserve_and_write(mtr); } @@ -376,14 +397,8 @@ mtr_read_ulint( ut_ad(mtr->state == MTR_ACTIVE); ut_ad(mtr_memo_contains_page(mtr, ptr, MTR_MEMO_PAGE_S_FIX) || mtr_memo_contains_page(mtr, ptr, MTR_MEMO_PAGE_X_FIX)); - if (type == MLOG_1BYTE) { - return(mach_read_from_1(ptr)); - } else if (type == MLOG_2BYTES) { - return(mach_read_from_2(ptr)); - } else { - ut_ad(type == MLOG_4BYTES); - return(mach_read_from_4(ptr)); - } + + return(mach_read_ulint(ptr, type)); } #ifdef UNIV_DEBUG |