MySQL redo log最佳化

aoerqileng發表於2022-08-30

看了其他人的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_write

prepare中會檢查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的最佳化

 





來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/25719946/viewspace-2912211/,如需轉載,請註明出處,否則將追究法律責任。

相關文章