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的大小,其实控制了并发往log buffer中同时拷贝的事务日志量,向前由新的日志加入,后面由log writer通过写日志向前推进,如果写的慢的话,那这个link_buf很可能用满,用户线程就得spin等待。再慢io的系统上,我们可以稍微调大这个参数

    innodb_Log_recent_closed_size, 默认2MB 表示recent closed这个link_buf的大小,也是维护可以并发往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

    注意在实际计算过程中,最大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次数的计算方式在函数中”:

    函数的参数即为配置项innodb_log_wait_for_write_spin_delay或innodb_log_wait_for_flush_spin_delay值

    1. uint64_t min_non_zero_value) {
    2. uint64_t max_spins;
    3. /* Get current cpu usage. */
    4. const double cpu = srv_cpu_usage.utime_pct;
    5. /* Get high-watermark - when cpu usage is higher, don't spin! */
    6. const uint32_t hwm = srv_log_spin_cpu_pct_hwm;
    7. /* Don't spin because either cpu usage is too high or it's
    8. almost idle so no reason to bother. */
    9. max_spins = 0;
    10. } else if (cpu >= hwm / 2) {
    11. /* When cpu usage is more than 50% of the hwm, use the minimum allowed
    12. number of spin rounds, not to increase cpu usage too much (risky). */
    13. max_spins = min_non_zero_value;
    14. in range [minimum, 10*minimum]. Smaller usage of cpu is, more spin rounds
    15. might be used. */
    16. const double r = 1.0 * (hwm / 2 - cpu) / (hwm / 2);
    17. max_spins =
    18. static_cast<uint64_t>(min_non_zero_value + r * min_non_zero_value * 9);
    19. }
    20. }

    D. 以下几个参数是后台线程等待任务时spin及condition wait timeout的值 log_writer线程: innodb_log_writer_spin_delay, innodb_log_writer_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操作最大的字节数,默认为4kb, 这个是在推进recent_written这个link buf时计算的,个人认为这个限制太小了,可以适当调大这个参数。(然而8.0的最大写入限制还受到innodb_log_write_ahead_size限制,两者得综合起来看)

    F innodb_log_checkpoint_every 默认1000毫秒(1秒),表示至少每隔这么长时间log_checkpointer线程会去尝试做一次checkpoint. 当然是否做checkpoint还受到其他因素的影响,具体见函数: a) more than 1s elapsed since last checkpoint b) checkpoint age is greater than max_checkpoint_age_async c) it was requested to have greater checkpoint_lsn, and oldest_lsn allows to satisfy the request