「fsync()を待つべきなのに待ってないから」
只の不正と判明。
動作としては、
innodb_flush_log_at_trx_commit = 1
でも
innodb_flush_log_at_trx_commit = 2
でも並列度が上がると多くのトランザクションが
innodb_flush_log_at_trx_commit = 0
の動作と同等となってしまうようです。待たないのだから速いに決まってる。こんな不正なものと比較されるのは腹立たしいです。
指定のLSNまでのwriteやflushを終わらせる log_write_up_to() という関数があるのですが、 そこに下記のような assertion codeを入れて動かせば直ぐに落ちると思います。
mariadb-10.5.9> diff -up storage/innobase/log/log0log.cc.orig storage/innobase/log/log0log.cc
--- storage/innobase/log/log0log.cc.orig 2021-03-02 12:04:30.167590939 +0900
+++ storage/innobase/log/log0log.cc 2021-03-03 10:34:30.113416497 +0900
@@ -797,6 +797,8 @@ void log_write_up_to(lsn_t lsn, bool flu
if (flush_to_disk &&
flush_lock.acquire(lsn) != group_commit_lock::ACQUIRED)
{
+ /* should be flushed enough */
+ ut_a(lsn <= log_sys.get_flushed_lsn());
return;
}
@@ -812,6 +814,9 @@ void log_write_up_to(lsn_t lsn, bool flu
write_lock.release(write_lsn);
}
+ /* should be written enough */
+ ut_a(lsn <= log_sys.write_lsn);
+
if (!flush_to_disk)
{
return;
誰かの処理が「終わる」のを待つのではなく、
誰かがwrite/flushしてる「最中」であれば先に進んでしまう構造みたいです。MariaDB 10.5 が速いなんて率先して言ってるベンチマークは怪しい意図を感じますね。
(追記)
log_write_up_to()はWAL(Write Ahead Log)の原則を守るためにデータページの書き出し前にも呼ばれます。これが破綻しているということは、ログを書く前にデータページを書く可能性があるということでクラッシュするとログを書いてるLSNまでも再現できずにデータが壊れる可能性があります。