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 は高速化の設定ではない
  • 遅いときは、設定より先に長いトランザクション・ロック待ち・スロークエリを確認する

関連記事:

お気軽にご相談ください

お見積りへ お問い合わせへ
▲