yokuo825さんのカッコいいインタビュー記事を
読んで、この部分ですね
──例えばどのような話をしましたか? 「インストールされたばかりのMySQLがあるとして、特定テーブルに1件のレコードを最初にINSERTした場合、アクセスが発生するファイルとその理由をすべて教えてください」と質問されたのを覚えています。 具体的にどのような理由でどのファイルにアクセスするか、一連の流れを片っ端から答えていくと、彼らがすごく楽しそうにしてくれて。「そうか、LINEの環境だと○○の設定が最初から○○になっているので、そのファイルへのアクセスは考えていなかったです。確かにそれもありますね」などと答えてくれました。
でこんなツイートしたんですが
この質問聞かれたら正直ほげほげふがふがって感じだったけどまあ・・・ソース全部読むのは・・・時間無いし・・・難しそうだし・・・でスルーしていました。ただPosgreSQL側の話題だったんですが、こんな分かりやすいツイートを拝見したので全国のDBAは「特定テーブルに1件のレコードを最初にINSERTした場合、アクセスが発生するファイルとその理由をすべて教えてください」これ明日から職場で聞かれるのかな
— oranie (@oranie) 2021年8月25日
私も気になったのでクライアント・バックエンドのシステムコールをトレースしてみました。
— Noriyoshi Shinoda (@nori_shinoda) 2021年8月26日
思ったより多いです。 pic.twitter.com/0JZRbprM9C
自分でもMySQLのシステムコールを取ってみました。ちなみにstraceによる調査方法はPercona先生も分かりやすく方法を書いてくれています。
実行環境はAWS EC2上でMySQL Serverを起動 AMIはamzn2-ami-hvm-2.0.20210617.0-x86_64-gp2 Versionはmysql-community-server-8.0.26-1.el7.x86_64
結果から言うと
[ec2-user@hogehoge ~]$ cat /tmp/strace.out | egrep "open" 5701 openat(AT_FDCWD, "/var/log/mysqld.log", O_WRONLY|O_CREAT|O_APPEND, 0666) = 37 5701 openat(AT_FDCWD, "/var/log/mysqld.log", O_WRONLY|O_CREAT|O_APPEND, 0666) = 37 5701 open("./", O_RDONLY|O_NONBLOCK|O_CLOEXEC|O_DIRECTORY) = 37 5701 openat(AT_FDCWD, "./binlog.index", O_RDWR|O_CREAT, 0640) = 4 5701 openat(AT_FDCWD, "./binlog.~rec~", O_RDWR|O_CREAT, 0640) = 37 5701 openat(AT_FDCWD, "./binlog.~rec~", O_RDWR|O_CREAT, 0640) = 37 5701 openat(AT_FDCWD, "./binlog.000003", O_WRONLY|O_CREAT, 0640) = 38 5701 openat(AT_FDCWD, "./binlog.index_crash_safe", O_RDWR|O_CREAT, 0640) = 39 5701 openat(AT_FDCWD, "./binlog.index", O_RDWR|O_CREAT, 0640) = 4 5701 openat(AT_FDCWD, "./test/oranie.ibd", O_RDWR|O_CREAT|O_EXCL, 0640) = 37 5665 openat(AT_FDCWD, "./test/oranie.ibd", O_RDWR) = 37 [ec2-user@hogehoge ~]$
という結果でした。なのでログ書いてbinlog書いてすべてが終わったらibdファイルを書いているという動きのようでした。それぞれのファイルの細かい説明、特にbinlog周りは後ほど調べます・・・。.~rec~って知らなかった。 -> 昨日データ操作なのにmysqld.logに書いているのとりあえずなんかおかしいと思いながらそのまま書いていたけど、模範解答貰えたので追記。
【回答例】
— yoku0825 (@yoku0825) 2021年8月26日
まずINSERTするページをバッファプールに載せないといけないので.ibd読みます、autocommitならUNDOログはたぶんメモリの上だけで済ますような気がしますが書くならundo_001くらいに書きます、コミットしたところでib_logfileに書きます、セカンダリキーがあれば
チェンジバッファも(たぶんメモリの上で済ませる気がしますが)バッファプールが足りなければDiskに書きます、バイナリログ書きます、ここでコミット成功かな(semisyncだとバイナリログが先)
— yoku0825 (@yoku0825) 2021年8月26日
あとは非同期でページクリーナーさんがダブルライトバッファに書きます、
.ibdファイルにフラッシュします、フラッシュしたらib_logfile0(先頭のログファイル)のヘッダに「どこまでフラッシュ済」という情報を持っているのでそれを書きます、ダブルライトバッファからいらなくなったの消します、とかそんな感じだった気がします。
— yoku0825 (@yoku0825) 2021年8月26日
スローログが出力されてて閾値以上ならスローログにも書きますね :D 同ジェネラルログ、ただしジェネラルログはSQLパースの中で、スローログは実行後なのでバイナリログの後あたりです。
— yoku0825 (@yoku0825) 2021年8月26日
他にもあったら教えてください先生!