ZFSのデータベース最適化

この記事では ZFS にデータベースのテーブルデータを保存する場合の最適化について解説します。ストレージデバイスとして、すべてのユースケースでHDDより高速となるSSDを使用する前提の記述になります。

設定内容

  • I/Oブロックサイズの最適化
  • ダブルバッファリンクの回避
  • ファイルシステムの atime を無効にする

I/Oブロックサイズの最適化

ファイルシステムとデータベースのI/Oブロックサイズを一致させ、SSDに最適な小さなブロックサイズを指定することで、OLTP パフォーマンスを改善します。 次の例では SSDと MySQL 用に最適化したデータテーブル保存用のファイルシステムを作成しています。
zfs create -o recordsize=4k -o mountpoint=/var/db/mysql tank0/var/db/mysql
zfs set logbias=throughput tank0/var/db/mysql
zfs get recordsize,logbias  tank0/var/db/mysql
ZFS は、ディスク上に格納されているすべてのブロックにチェックサムを実行しますので、CPU負荷が高くなるようであれば、ブロックサイズを大きくして調整します。

ダブルバッファリンクの回避

キャッシュの機構は、ファイルシステムとデータベースの階層にあり、それぞれ個別に管理されていますが、同じデータが存在するケースが多くなりメモリーが無駄になるのでデータベースの方だけを利用するように設定します。従って、ZFS の ARCではなくMySQL/InnoDBのレベルでデータをキャッシュするようにします。こうすることでデータベースのレイヤーでキャッシュすると、データへたどり着くまでにより短いコードパスで済むようになり性能が改善されるはずです。 ZFS の ARCはファイルシステムごとに次の設定値を設定できます。
  • all: 全てをキャッシュする
  • metadata: メタデータのみキャッシュする
  • none: 一切キャッシュしない
zfs set primarycache=metadata tank0/var/db/mysql

ファイルシステムの atime を無効にする

atime は最後にファイルが参照された最終アクセス時刻のことですが、atime の設定が有効になっている場合では読むだけでも書き込みが発生してしまいます。一般的にデータベースでは最終アクセス時刻が更新される必要ないので、設定を無効にすることで、無駄な書き込みを無くすことで I/O 性能が向上します。 先ず、 データディレクトリの atime の 設定を確認します。
zfs get atime
該当ディレクトリの atime が on になっている場合は off にします。
zfs get atime=off database