MySQL8.0 - 新特性 - 说说InnoDB Log System的隐藏参数
InnoDB在設計lock-free的log system時,除了已有的參數外,還通過宏控制隱藏了一些參數,如果你使用源碼編譯時,打開cmake選項-DENABLE_EXPERIMENT_SYSVARS=1, 就可以看到這些參數了。本文主要簡單的過一下這些隱藏的參數所代表的含義
A.
innodb_log_write_events
innodb_log_flush_events
兩者的含義類似,表示用來喚醒等待log write/flush的event的個數,默認值都是2048
比如你要等待的位置在lsnA,那么計算的slot為:
slot = (lsnA - 1) /OS_FILE_LOG_BLOCK_SIZE & (innodb_log_write/flush_events - 1)
這意味著:如果事務的commit log的end lsn落在相同block里,他們可能產生event的競爭
當然如果不在同一個block的時候,如果調大參數,就可以減少競爭,但也會有無效的喚醒
喚醒操作通常由后臺線程log_write_notifier 或者log_flush_notifier異步來做,但如果推進的log write/flush還不足一個block的話,那就log_writter/flusher
自己去喚醒了。
B.
innodb_log_recent_written_size, 默認1MB
表示recent_written這個link_buf的大小,其實控制了并發(fā)往log buffer中同時拷貝的事務日志量,向前由新的日志加入,后面由log writer通過寫日志向前推進,如果寫的慢的話,那這個link_buf很可能用滿,用戶線程就得spin等待。再慢io的系統(tǒng)上,我們可以稍微調大這個參數
innodb_Log_recent_closed_size, 默認2MB
表示recent closed這個link_buf的大小,也是維護可以并發(fā)往flush list上插入臟頁的并罰度,如果插入臟頁速度慢,或者lin_buf沒有及時合并推進,就會spin wait
C.
innodb_log_wait_for_write_spin_delay,?
innodb_log_wait_for_write_timeout
從8.0版本開始用戶線程不再自己去寫redo,而是等待后臺線程去寫,這兩個變量控制了spin以及condition wait的timeout時間,當spin一段時間還沒推進到某個想要的lsn點時,就會進入condition wait
另外兩個變量
innodb_log_wait_for_flush_spin_delay
innodb_log_wait_for_flush_timeout
含義類似,但是是等待log flush到某個指定lsn
注意在實際計算過程中,最大spin次數,會考慮到cpu利用率,以及另外兩個參數:
innodb_log_spin_cpu_abs_lwm
innodb_log_spin_cpu_pct_hwm
如果是等待flush操作的話,還收到參數innodb_log_wait_for_flush_spin_hwm限制,該參數控制了等待flush的時間上限,如果平均等待flush的時間超過了這個上限的話, 就沒必要去spin,而是直接進入condition wait
關于spin次數的計算方式在函數log_max_spins_when_waiting_in_user_thread中":
函數的參數即為配置項innodb_log_wait_for_write_spin_delay或innodb_log_wait_for_flush_spin_delay值
static inline uint64_t log_max_spins_when_waiting_in_user_thread(uint64_t min_non_zero_value) {uint64_t max_spins;/* Get current cpu usage. */const double cpu = srv_cpu_usage.utime_pct;/* Get high-watermark - when cpu usage is higher, don't spin! */const uint32_t hwm = srv_log_spin_cpu_pct_hwm;if (srv_cpu_usage.utime_abs < srv_log_spin_cpu_abs_lwm || cpu >= hwm) {/* Don't spin because either cpu usage is too high or it'salmost idle so no reason to bother. */max_spins = 0;} else if (cpu >= hwm / 2) {/* When cpu usage is more than 50% of the hwm, use the minimum allowednumber of spin rounds, not to increase cpu usage too much (risky). */max_spins = min_non_zero_value;} else {/* When cpu usage is less than 50% of the hwm, choose maximum spin roundsin range [minimum, 10*minimum]. Smaller usage of cpu is, more spin roundsmight be used. */const double r = 1.0 * (hwm / 2 - cpu) / (hwm / 2);max_spins =static_cast<uint64_t>(min_non_zero_value + r * min_non_zero_value * 9);}return (max_spins); }D. 以下幾個參數是后臺線程等待任務時spin及condition wait timeout的值
log_writer線程:
innodb_log_writer_spin_delay,
innodb_log_writer_timeout
log_flusher線程:
innodb_ log_flusher_spin_delay
innodb_log_flusher_timeout
log_write_notifier線程:
innodb_ log_write_notifier_spin_delay
innodb_log_write_notifier_timeout
log_flush_notifier線程
innodb_log_flush_notifier_spin_delay
innodb_log_flush_notifier_timeout
log_closer線程(用于推進recent_closed這個link_buf的專用線程)
innodb_log_closer_spin_delay
innodb_log_closer_timeout
E
innodb_ log_write_max_size
表示允許一個write操作最大的字節(jié)數,默認為4kb, 這個是在推進recent_written這個link buf時計算的,個人認為這個限制太小了,可以適當調大這個參數。(然而8.0的最大寫入限制還受到innodb_log_write_ahead_size限制,兩者得綜合起來看)
F
innodb_log_checkpoint_every
默認1000毫秒(1秒),表示至少每隔這么長時間log_checkpointer線程會去嘗試做一次checkpoint. 當然是否做checkpoint還受到其他因素的影響,具體見函數log_should_checkpoint:
G. 參考:
MySQL8.0.16源代碼
原文鏈接
本文為云棲社區(qū)原創(chuàng)內容,未經允許不得轉載。
總結
以上是生活随笔為你收集整理的MySQL8.0 - 新特性 - 说说InnoDB Log System的隐藏参数的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 技术人看《长安十二时辰》的正确姿势是?
- 下一篇: 如何将Elasticsearch的快照备