看了其他人的blog,主要是学习下,跟着他们的blog看下对应的代码,另外也对mtr有了更多的了解。之前的mtr只是了解用来维护index的完整,用户产生的redo其实也是放在mtr中的,会将用户mtr中的redo刷到全局redo log buffer。
redo log buffer 结构体中的mutext
/** Redo log buffer */
struct log_t{
....
LogSysMutex mutex; /*!< mutex protecting the log */
LogSysMutex write_mutex; /*!< mutex protecting writing to log
file and accessing to log_group_t */
char pad3[CACHE_LINE_SIZE];/*!< Padding */
FlushOrderMutex log_flush_order_mutex;/*!< mutex to serialize access to
the flush list when we are putting
dirty blocks in the list. The idea
behind this mutex is to be able
to release log_sys->mutex during
mtr_commit and still ensure that
insertions in the flush_list happen
in the LSN order. */
mtr_t::Command::finish_write中redo records写入log buffer
刷redo log buffer到文件
This function is called, e.g., when a transaction wants to commit. It checks
that the log has been written to the log file up to the last log entry written
by the transaction. If there is a flush running, it waits and checks if the
flush flushed enough. If not, starts a new flush. */
void
log_write_up_to(
/*============*/
lsn_t lsn, /*!< in: log sequence number up to which
the log should be written, LSN_MAX if not specified */
bool flush_to_disk);
/*!< in: true if we want the written log
also to be flushed to disk */
/** write to the log file up to the last log entry.
@param[in] sync whether we want the written log
also to be flushed to disk. */
将脏块插入flush list
Inserts a modified block into the flush list. */
void
buf_flush_insert_into_flush_list
mtr的提交也是分成了2部分,一部分是prepare_write,一个是finish_writeprepare中会检查redo log buffer大小
if (len > log_sys->buf_size / 2) {
log_buffer_extend((len + 1) * 2);
}
堆栈如下
mysqld!mtr_t::Command::execute() (/Users/xiaoyu.bai/Downloads/mysql-5.7.29/storage/innobase/mtr/mtr0mtr.cc:966) mysqld!mtr_t::commit() (/Users/xiaoyu.bai/Downloads/mysql-5.7.29/storage/innobase/mtr/mtr0mtr.cc:584) mysqld!trx_undo_assign_undo(trx_t*, trx_undo_ptr_t*, unsigned long) (/Users/xiaoyu.bai/Downloads/mysql-5.7.29/storage/innobase/trx/trx0undo.cc:1839) mysqld!trx_undo_report_row_operation(unsigned long, unsigned long, que_thr_t*, dict_index_t*, dtuple_t const*, upd_t const*, unsigned long, unsigned char const*, unsigned long const*, unsigned long long*) (/Users/xiaoyu.bai/Downloads/mysql-5.7.29/storage/innobase/trx/trx0rec.cc:1939) mysqld!btr_cur_ins_lock_and_undo(unsigned long, btr_cur_t*, dtuple_t*, que_thr_t*, mtr_t*, unsigned long*) (/Users/xiaoyu.bai/Downloads/mysql-5.7.29/storage/innobase/btr/btr0cur.cc:3011) mysqld!btr_cur_optimistic_insert(unsigned long, btr_cur_t*, unsigned long**, mem_block_info_t**, dtuple_t*, unsigned char**, big_rec_t**, unsigned long, que_thr_t*, mtr_t*) (/Users/xiaoyu.bai/Downloads/mysql-5.7.29/storage/innobase/btr/btr0cur.cc:3239) mysqld!row_ins_clust_index_entry_low(unsigned long, unsigned long, dict_index_t*, unsigned long, dtuple_t*, unsigned long, que_thr_t*, bool) (/Users/xiaoyu.bai/Downloads/mysql-5.7.29/storage/innobase/row/row0ins.cc:2612) mysqld!row_ins_clust_index_entry(dict_index_t*, dtuple_t*, que_thr_t*, unsigned long, bool) (/Users/xiaoyu.bai/Downloads/mysql-5.7.29/storage/innobase/row/row0ins.cc:3299) mysqld!row_ins_index_entry(dict_index_t*, dtuple_t*, que_thr_t*) (/Users/xiaoyu.bai/Downloads/mysql-5.7.29/storage/innobase/row/row0ins.cc:3437) mysqld!row_ins_index_entry_step(ins_node_t*, que_thr_t*) (/Users/xiaoyu.bai/Downloads/mysql-5.7.29/storage/innobase/row/row0ins.cc:3587) mysqld!row_ins(ins_node_t*, que_thr_t*) (/Users/xiaoyu.bai/Downloads/mysql-5.7.29/storage/innobase/row/row0ins.cc:3725) mysqld!row_ins_step(que_thr_t*) (/Users/xiaoyu.bai/Downloads/mysql-5.7.29/storage/innobase/row/row0ins.cc:3861) mysqld!row_insert_for_mysql_using_ins_graph(unsigned char const*, row_prebuilt_t*) (/Users/xiaoyu.bai/Downloads/mysql-5.7.29/storage/innobase/row/row0mysql.cc:1746) mysqld!row_insert_for_mysql(unsigned char const*, row_prebuilt_t*) (/Users/xiaoyu.bai/Downloads/mysql-5.7.29/storage/innobase/row/row0mysql.cc:1866) mysqld!ha_innobase::write_row(unsigned char*) (/Users/xiaoyu.bai/Downloads/mysql-5.7.29/storage/innobase/handler/ha_innodb.cc:7612) mysqld!handler::ha_write_row(unsigned char*) (/Users/xiaoyu.bai/Downloads/mysql-5.7.29/sql/handler.cc:8093) mysqld!write_record(THD*, TABLE*, COPY_INFO*, COPY_INFO*) (/Users/xiaoyu.bai/Downloads/mysql-5.7.29/sql/sql_insert.cc:1895) mysqld!Sql_cmd_insert::mysql_insert(THD*, TABLE_LIST*) (/Users/xiaoyu.bai/Downloads/mysql-5.7.29/sql/sql_insert.cc:776) mysqld!Sql_cmd_insert::execute(THD*) (/Users/xiaoyu.bai/Downloads/mysql-5.7.29/sql/sql_insert.cc:3140) mysqld!mysql_execute_command(THD*, bool) (/Users/xiaoyu.bai/Downloads/mysql-5.7.29/sql/sql_parse.cc:3606)
挂载脏页到flush list上的堆栈如下
mysqld!buf_flush_insert_into_flush_list(buf_pool_t*, buf_block_t*, unsigned long long) (/Users/xiaoyu.bai/Downloads/mysql-5.7.29/storage/innobase/buf/buf0flu.cc:433) mysqld!buf_flush_note_modification(buf_block_t*, unsigned long long, unsigned long long, FlushObserver*) (/Users/xiaoyu.bai/Downloads/mysql-5.7.29/storage/innobase/include/buf0flu.ic:105) mysqld!ReleaseBlocks::add_dirty_page_to_flush_list(mtr_memo_slot_t*) const (/Users/xiaoyu.bai/Downloads/mysql-5.7.29/storage/innobase/mtr/mtr0mtr.cc:356) mysqld!ReleaseBlocks::operator()(mtr_memo_slot_t*) const (/Users/xiaoyu.bai/Downloads/mysql-5.7.29/storage/innobase/mtr/mtr0mtr.cc:368) mysqld!Iterate<ReleaseBlocks>::operator()(dyn_buf_t<512ul>::block_t*) (/Users/xiaoyu.bai/Downloads/mysql-5.7.29/storage/innobase/mtr/mtr0mtr.cc:77) mysqld!bool dyn_buf_t<512ul>::for_each_block_in_reverse<Iterate<ReleaseBlocks> >(Iterate<ReleaseBlocks>&) const (/Users/xiaoyu.bai/Downloads/mysql-5.7.29/storage/innobase/include/dyn0buf.h:375) mysqld!mtr_t::Command::release_blocks() (/Users/xiaoyu.bai/Downloads/mysql-5.7.29/storage/innobase/mtr/mtr0mtr.cc:956) mysqld!mtr_t::Command::execute() (/Users/xiaoyu.bai/Downloads/mysql-5.7.29/storage/innobase/mtr/mtr0mtr.cc:981) mysqld!mtr_t::commit() (/Users/xiaoyu.bai/Downloads/mysql-5.7.29/storage/innobase/mtr/mtr0mtr.cc:584) mysqld!trx_undo_assign_undo(trx_t*, trx_undo_ptr_t*, unsigned long) (/Users/xiaoyu.bai/Downloads/mysql-5.7.29/storage/innobase/trx/trx0undo.cc:1839) mysqld!trx_undo_report_row_operation(unsigned long, unsigned long, que_thr_t*, dict_index_t*, dtuple_t const*, upd_t const*, unsigned long, unsigned char const*, unsigned long const*, unsigned long long*) (/Users/xiaoyu.bai/Downloads/mysql-5.7.29/storage/innobase/trx/trx0rec.cc:1939) mysqld!btr_cur_ins_lock_and_undo(unsigned long, btr_cur_t*, dtuple_t*, que_thr_t*, mtr_t*, unsigned long*) (/Users/xiaoyu.bai/Downloads/mysql-5.7.29/storage/innobase/btr/btr0cur.cc:3011) mysqld!btr_cur_optimistic_insert(unsigned long, btr_cur_t*, unsigned long**, mem_block_info_t**, dtuple_t*, unsigned char**, big_rec_t**, unsigned long, que_thr_t*, mtr_t*) (/Users/xiaoyu.bai/Downloads/mysql-5.7.29/storage/innobase/btr/btr0cur.cc:3239) mysqld!row_ins_clust_index_entry_low(unsigned long, unsigned long, dict_index_t*, unsigned long, dtuple_t*, unsigned long, que_thr_t*, bool) (/Users/xiaoyu.bai/Downloads/mysql-5.7.29/storage/innobase/row/row0ins.cc:2612) mysqld!row_ins_clust_index_entry(dict_index_t*, dtuple_t*, que_thr_t*, unsigned long, bool) (/Users/xiaoyu.bai/Downloads/mysql-5.7.29/storage/innobase/row/row0ins.cc:3299) mysqld!row_ins_index_entry(dict_index_t*, dtuple_t*, que_thr_t*) (/Users/xiaoyu.bai/Downloads/mysql-5.7.29/storage/innobase/row/row0ins.cc:3437) mysqld!row_ins_index_entry_step(ins_node_t*, que_thr_t*) (/Users/xiaoyu.bai/Downloads/mysql-5.7.29/storage/innobase/row/row0ins.cc:3587) mysqld!row_ins(ins_node_t*, que_thr_t*) (/Users/xiaoyu.bai/Downloads/mysql-5.7.29/storage/innobase/row/row0ins.cc:3725) mysqld!row_ins_step(que_thr_t*) (/Users/xiaoyu.bai/Downloads/mysql-5.7.29/storage/innobase/row/row0ins.cc:3861) mysqld!row_insert_for_mysql_using_ins_graph(unsigned char const*, row_prebuilt_t*) (/Users/xiaoyu.bai/Downloads/mysql-5.7.29/storage/innobase/row/row0mysql.cc:1746)
在mtr_t::Command::execute() 中我们可以看到加锁的情况,先加log mutex,在finish write完成后,释放,然后加了log_flush_order_mutex 在进行挂载脏页写入到redo log的过程中log_write_up_to 可以看到是使用了write_mutex这个链接是mysql8.0的优化
http://mysql.taobao.org/monthly/2018/07/01/
