2026年10月21日
2026年10月21日
MySQLのInnoDB設定の見直し方|バッファプール・REDOログ・フラッシュの要点(8.4対応)
InnoDBはMySQLの標準のストレージエンジンで、WordPressのテーブルも通常はInnoDBです。InnoDBの設定項目は数多くありますが、効果が大きく、見直す価値があるのは一部です。この記事では、2026年10月時点で広く使われているMySQL 8.4(LTS)を前提に、現状の確認方法とあわせて要点を説明します。
MySQL 8.0は2026年4月にサポートが終了しています。8.0を使っている場合は、8.4への移行もあわせて検討してください。MariaDBは設定名が一部異なるので、後半で違いをまとめます。
作業の前に
まず、バージョンと現在の値を確認します。
SELECT VERSION();
SHOW VARIABLES LIKE 'innodb_buffer_pool_size';
SHOW VARIABLES LIKE 'innodb_redo_log_capacity';
SHOW VARIABLES LIKE 'innodb_flush%';
設定ファイルの場所は、インストール方法によって違います。
| 環境 | 主な設定ファイル |
|---|---|
| UbuntuやDebianのパッケージ | /etc/mysql/mysql.conf.d/mysqld.cnf |
| MySQL公式のRPM(RHEL系) | /etc/my.cnf |
| Docker公式イメージ | /etc/mysql/conf.d/ に .cnf を置く |
設定は [mysqld] セクションに書きます。変更前に設定ファイルをコピーしておき、変えるのは1回に1項目か2項目にして、効果を確かめながら進めます。データのバックアップも取っておきます。
1. バッファプール(innodb_buffer_pool_size)
バッファプールは、テーブルとインデックスのデータをメモリに置いておく領域です。InnoDBの性能に最も大きく効く設定で、既定値は128MBと小さいため、多くの環境で見直しの対象になります。
大きさの目安
- MySQLだけを動かす専用サーバー: 公式ドキュメントでは、物理メモリの80%まで設定してよいとしている
- WebサーバーやPHPと同居するVPS: PHP-FPMやNginxなどが使うメモリを差し引いて決める。メモリ4GBのVPSにWordPressを全部載せている場合、1GB〜1.5GB程度から始めて様子を見る、といった決め方になる
InnoDBは設定値より1割ほど多くメモリを確保します。大きくしすぎてスワップが起きると逆に遅くなるので、free -m で空きメモリを確認しながら決めてください。
データの総量より大きくしても効果はありません。InnoDBのデータとインデックスの合計は次で確認できます。
SELECT ROUND(SUM(data_length + index_length) / 1024 / 1024) AS innodb_total_mb
FROM information_schema.tables
WHERE engine = 'InnoDB';
足りているかを確認する
SHOW GLOBAL STATUS LIKE 'Innodb_buffer_pool_read%';
Innodb_buffer_pool_read_requests はメモリからの読み取り要求の数、Innodb_buffer_pool_reads はメモリに無くてディスクから読んだ数です。起動直後はディスクからの読み取りが多くなるので、しばらく動かしてから比べます。Innodb_buffer_pool_reads が要求数に比べて大きく、増え続けている場合は、バッファプールが足りていない可能性があります。
変更する
MySQL 5.7以降は、再起動せずに変更できます。SET PERSIST を使うと、値が mysqld-auto.cnf に保存され、再起動後も残ります。
-- 例: 2GB にする
SET PERSIST innodb_buffer_pool_size = 2147483648;
-- 変更の進み具合を確認する
SELECT variable_name, variable_value
FROM performance_schema.global_status
WHERE LOWER(variable_name) LIKE 'innodb_buffer_pool_resize%';
大きさは innodb_buffer_pool_chunk_size(既定128MB)×innodb_buffer_pool_instances の倍数に自動で切り上げられます。設定ファイルに書く場合は次のとおりです。
[mysqld]
innodb_buffer_pool_size = 2G
SET PERSIST で保存した値は、設定ファイルの値より優先されます。どちらで管理するかを決めておくと混乱しません。
2. REDOログの大きさ(innodb_redo_log_capacity)
REDOログは、コミットした変更をデータファイルに書き込む前に記録しておくログで、障害時の復旧に使われます。REDOログが小さすぎると、書き込みが多いときにデータファイルへの書き出しが頻繁に起き、性能が落ちます。
MySQL 8.0.30以降、REDOログの大きさは innodb_redo_log_capacity で指定します(既定は100MB)。以前の innodb_log_file_size と innodb_log_files_in_group は非推奨で、innodb_redo_log_capacity に置き換わりました。古い記事にある2つの設定は、MySQL 8.4では使いません。
REDOログはデータディレクトリの #innodb_redo ディレクトリに、32個のファイルに分けて置かれます。再起動せずに変更できます。
-- 例: 1GB にする
SET PERSIST innodb_redo_log_capacity = 1073741824;
-- 反映を確認する
SHOW GLOBAL STATUS LIKE 'Innodb_redo_log_capacity_resized';
大きさの決め方
書き込みの多い時間帯に、REDOログに書かれる量を測って決める方法があります。Innodb_redo_log_current_lsn は書き込んだREDOログの位置(バイト数)なので、60秒の差をとれば1分あたりの書き込み量が分かります。
SELECT VARIABLE_VALUE FROM performance_schema.global_status
WHERE VARIABLE_NAME = 'Innodb_redo_log_current_lsn';
-- 60秒待ってからもう一度実行し、差を求める
1分あたりの量に60を掛けた値(1時間分)を目安にする考え方がよく使われます。大きくするほど通常時の書き込みは安定しますが、クラッシュ後の復旧に時間がかかり、ディスクも使います。WordPressのような読み取り中心のサイトでは、既定の100MBから数百MB〜1GB程度で足りることが多いので、測ってから決めてください。
3. コミット時の書き込み(innodb_flush_log_at_trx_commit)
コミットのたびにREDOログをディスクに書き込むかを決める設定です。
| 値 | 動き | 障害時に失う可能性 |
|---|---|---|
1(既定) |
コミットごとにログを書き込み、ディスクに確定させる | 無し(ディスクが正しく動く前提) |
2 |
コミットごとにOSに渡し、ディスクへの確定はおおむね1秒ごと | OSの停止や電源断で、直近約1秒分 |
0 |
ログの書き込みと確定をおおむね1秒ごとにまとめて行う | MySQLの異常終了でも、直近約1秒分 |
2 や 0 にすると書き込みは速くなりますが、障害時にコミット済みのデータを失う可能性があります。注文や会員情報を扱うサイトでは 1 のままにします。レプリケーションやバイナリログを使う場合は、sync_binlog = 1(8.4の既定)とあわせて考えます。
4. 変えなくてよい項目・変えてはいけない項目
古い解説で勧められていても、現在は変えなくてよい項目や、誤解されやすい項目があります。
| 項目 | 内容 |
|---|---|
innodb_page_size |
既定は16KB。データディレクトリを初期化するときにしか指定できず、稼働中のサーバーで設定ファイルを書き換えると起動できなくなる。通常は変えない |
innodb_file_per_table |
既定で ON。テーブルごとに .ibd ファイルを作る設定で、性能の設定ではない |
innodb_read_only |
サーバー全体を読み取り専用にする設定(読み取り専用の媒体で動かす場合など)。読み取りの多いサイトを速くする設定ではない |
innodb_flush_method |
MySQL 8.4のLinuxでは、対応していれば既定で O_DIRECT |
innodb_io_capacity |
MySQL 8.4で既定が10000に変わった。SSDでは通常そのままでよい |
max_connections |
InnoDBの設定ではない。増やすと接続ごとのメモリも増えるので、実際の最大接続数を見てから決める |
max_connections が足りているかは、起動からの最大同時接続数で確認できます。
SHOW GLOBAL STATUS LIKE 'Max_used_connections';
SHOW VARIABLES LIKE 'max_connections';
専用サーバーなら innodb_dedicated_server
MySQLだけを動かす専用のサーバーやコンテナでは、innodb_dedicated_server = ON にすると、メモリとCPUの数からバッファプールとREDOログの大きさが自動で決まります(メモリ4GB超ならバッファプールはメモリの75%)。ほかのソフトと同居する環境では使いません。自分で値を指定した項目は、その値が優先されます。
5. 遅いときに確認すること
設定を変える前に、原因がInnoDBの設定にあるかを確かめます。多くの場合、遅さの原因は設定よりも、インデックスの無いクエリや長いトランザクションです。
長く開いたままのトランザクション
SELECT trx_id, trx_started,
TIMESTAMPDIFF(SECOND, trx_started, NOW()) AS running_sec,
trx_mysql_thread_id, trx_query
FROM information_schema.innodb_trx
ORDER BY trx_started;
running_sec が大きいものは、ロックを持ち続けてほかの処理を待たせたり、古い版のデータの削除(purge)を止めたりします。アプリケーションの処理を確認し、止めてよいものであれば KILL <trx_mysql_thread_id>; で終了させます。
ロック待ち
SHOW GLOBAL STATUS LIKE 'Innodb_row_lock%';
SHOW ENGINE INNODB STATUS\G
Innodb_row_lock_waits が増え続けている場合はロックの競合が起きています。SHOW ENGINE INNODB STATUS の LATEST DETECTED DEADLOCK には、直近のデッドロックの内容が出ます。ロック待ちの上限は innodb_lock_wait_timeout(既定50秒)で、待ちきれなかったクエリはエラーになります。この値を延ばしても競合は解消しないので、原因のクエリを直します。
遅いクエリ
スロークエリログを有効にして、時間のかかっているクエリを見つけ、EXPLAIN でインデックスが使われているかを確認します。
MariaDBとの違い
MariaDBのInnoDBは、MySQLと設定名が一部異なります。
| 項目 | MySQL 8.4 | MariaDB(10.5以降) |
|---|---|---|
| REDOログの大きさ | innodb_redo_log_capacity |
innodb_log_file_size(REDOログのファイルは1つ) |
innodb_redo_log_capacity |
あり | 無い |
innodb_dedicated_server |
あり | 無い |
# MariaDB の例
[mysqld]
innodb_buffer_pool_size = 2G
innodb_log_file_size = 512M
バッファプールの考え方と innodb_flush_log_at_trx_commit の意味は共通です。MySQL向けの設定をMariaDBに書くと、知らない設定名として起動に失敗することがあるので、使っている製品のドキュメントで設定名を確認してください。
設定例(MySQL 8.4、メモリ4GBでWebサーバーと同居)
[mysqld]
innodb_buffer_pool_size = 1536M
innodb_redo_log_capacity = 512M
innodb_flush_log_at_trx_commit = 1
ここに無い項目は既定値のままにしておき、確認したい数値(バッファプールの読み取り、ロック待ち、スロークエリ)を見ながら、1つずつ調整します。設定ファイルを変えたら、MySQLを再起動し、エラーログで起動できたことを確認します。
sudo systemctl restart mysql
sudo systemctl status mysql
RHEL系の公式パッケージでは、サービス名が mysqld です。
まとめ
- 見直す価値が大きいのはバッファプールの大きさ。専用サーバーなら物理メモリの80%まで、同居なら他のソフトの分を引いて決める
- REDOログはMySQL 8.0.30以降
innodb_redo_log_capacityで指定する。innodb_log_file_sizeとinnodb_log_files_in_groupは非推奨 innodb_flush_log_at_trx_commitは1が安全。2・0は障害時に約1秒分を失う可能性があるinnodb_page_sizeは稼働中に変えない。innodb_read_onlyは高速化の設定ではない- 遅いときは、設定より先に長いトランザクション・ロック待ち・スロークエリを確認する
関連記事: