/************************************************************//** 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 */ { dyn_array_t* mlog; dyn_block_t* block; ulint data_size; ibool success; byte* first_data; ut_ad(mtr); mlog = &(mtr->log); first_data = dyn_block_get_data(mlog); if (mtr->n_log_recs > 1) { mlog_catenate_ulint(mtr, MLOG_MULTI_REC_END, MLOG_1BYTE); } else { *first_data = (byte)((ulint)*first_data | MLOG_SINGLE_REC_FLAG); } if (mlog->heap == NULL) { mtr->end_lsn = log_reserve_and_write_fast( first_data, dyn_block_get_used(mlog), &(mtr->start_lsn), &success); if (success) { return; } } data_size = dyn_array_get_data_size(mlog); /* Open the database log for log_write_low */ mtr->start_lsn = log_reserve_and_open(data_size); if (mtr->log_mode == MTR_LOG_ALL) { block = mlog; while (block != NULL) { log_write_low(dyn_block_get_data(block), dyn_block_get_used(block)); block = dyn_array_get_next_block(mlog, block); } } else { ut_ad(mtr->log_mode == MTR_LOG_NONE); /* Do nothing */ } mtr->end_lsn = log_close(); }
/************************************************************//** 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 */ { dyn_array_t* mlog; dyn_block_t* block; ulint data_size; byte* first_data; ut_ad(mtr); mlog = &(mtr->log); first_data = dyn_block_get_data(mlog); if (mtr->n_log_recs > 1) { mlog_catenate_ulint(mtr, MLOG_MULTI_REC_END, MLOG_1BYTE); } else { *first_data = (byte)((ulint)*first_data | MLOG_SINGLE_REC_FLAG); } if (mlog->heap == NULL) { mtr->end_lsn = log_reserve_and_write_fast( first_data, dyn_block_get_used(mlog), &mtr->start_lsn); if (mtr->end_lsn) { /* Success. We have the log mutex. Add pages to flush list and exit */ goto func_exit; } } data_size = dyn_array_get_data_size(mlog); /* Open the database log for log_write_low */ mtr->start_lsn = log_reserve_and_open(data_size); if (mtr->log_mode == MTR_LOG_ALL) { block = mlog; while (block != NULL) { log_write_low(dyn_block_get_data(block), dyn_block_get_used(block)); block = dyn_array_get_next_block(mlog, block); } } else { ut_ad(mtr->log_mode == MTR_LOG_NONE); /* Do nothing */ } mtr->end_lsn = log_close(); func_exit: 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); } log_flush_order_mutex_exit(); }