MySQLの設定値(システム変数)は、SHOW VARIABLES で確認し、SET GLOBAL で今すぐ変え、SET PERSIST か my.cnf で再起動後にも残す、という3段で扱います。 「変えたはずなのに再起動で元に戻った」「my.cnf に書いたのに反映されない」という場面は、どの段で何が保存されるかを分けて見ると、短い時間で原因にたどり着けます。

この記事では、MySQL 8.0.46(Ubuntu 24.04 のパッケージ)を専用のデータディレクトリで起動し、確認・変更・再起動・取り消しを実際に行った結果をそのまま載せています。SET の5種類を「即時反映か・再起動後も残るか・保存先・必要な権限」で比べた表、my.cnf の場所の一覧、performance_schema.variables_info で値の出どころを調べる方法、反映されないときの再現例まで、順番に確認できます。出力中のファイルパスとデータディレクトリ名は、読みやすいように一般的な名前(/home/taro/work、/tmp/mydata)に置き換えています。

MySQLの設定確認と変更の早見表

やりたいこと 書き方 補足
値を名前で探す SHOW VARIABLES LIKE 'max_conn%'; セッション値が優先して表示される
グローバル値を見る SHOW GLOBAL VARIABLES LIKE '名前'; または SELECT @@global.名前; サーバー全体の値
自分の接続の値を見る SELECT @@session.名前; グローバル専用の変数ではエラー 1238
自分の接続だけ変える SET SESSION 名前 = 値; 権限は基本的に不要。切断で消える
サーバー全体を今すぐ変える SET GLOBAL 名前 = 値; 再起動で元に戻る
今すぐ変えて再起動後も残す SET PERSIST 名前 = 値; データディレクトリの mysqld-auto.cnf に保存
次の起動から変える SET PERSIST_ONLY 名前 = 値; 起動時にしか決められない変数に使う
保存した設定を取り消す RESET PERSIST 名前; 稼働中の値はそのまま。次の起動から外れる
値がどこから来たか調べる SELECT * FROM performance_schema.variables_info WHERE VARIABLE_NAME='名前'; COMPILED / EXPLICIT / PERSISTED / DYNAMIC など
読まれる設定ファイルを調べる mysqld --verbose --help | grep -A2 "Default options" 読み込み順とグループ名が出る
ファイルから渡される値を調べる my_print_defaults mysqld サーバーを起動せずに確認できる

SHOW VARIABLESと@@global・@@sessionの違いを確認する

システム変数には、サーバー全体の値であるグローバル値と、接続ごとの値であるセッション値があります。新しい接続は、その時点のグローバル値をコピーしてセッション値を作ります。この2つを見分けられると、「変えたのに変わっていない」という場面の大半が説明できます。

3つの確認方法を並べて実行する

SHOW GLOBAL VARIABLES LIKE 'sort_buffer_size';
SET SESSION sort_buffer_size = 524288;
SELECT @@global.sort_buffer_size, @@session.sort_buffer_size, @@sort_buffer_size;
SHOW VARIABLES LIKE 'sort_buffer_size';
SHOW GLOBAL VARIABLES LIKE 'sort_buffer_size';

実行結果(MySQL 8.0.46)です。

+------------------+--------+
| Variable_name    | Value  |
+------------------+--------+
| sort_buffer_size | 262144 |
+------------------+--------+
+---------------------------+----------------------------+--------------------+
| @@global.sort_buffer_size | @@session.sort_buffer_size | @@sort_buffer_size |
+---------------------------+----------------------------+--------------------+
|                    262144 |                     524288 |             524288 |
+---------------------------+----------------------------+--------------------+
+------------------+--------+
| Variable_name    | Value  |
+------------------+--------+
| sort_buffer_size | 524288 |
+------------------+--------+
+------------------+--------+
| Variable_name    | Value  |
+------------------+--------+
| sort_buffer_size | 262144 |
+------------------+--------+

修飾なしの SHOW VARIABLES と @@名前 は、セッション値があればセッション値を返します。 サーバー全体の値を確かめたいときは、GLOBAL を明示するのが確実です。

書き方 返す値 向いている場面
SHOW VARIABLES LIKE '...' セッション値(無ければグローバル値) 名前があいまいなときの検索
SHOW GLOBAL VARIABLES LIKE '...' グローバル値 サーバー全体の設定確認
SHOW SESSION VARIABLES LIKE '...' セッション値 自分の接続の確認
SELECT @@global.名前 グローバル値 SQLの中で値を使う、複数の変数を1行で見る
SELECT @@session.名前 セッション値 同上
SELECT @@名前 セッション値(無ければグローバル値) 手早く見る

LIKEとWHEREで絞り込む

SHOW VARIABLES LIKE 'max_conn%';
SHOW VARIABLES WHERE Variable_name IN ('port','datadir','socket');
+--------------------+-------+
| Variable_name      | Value |
+--------------------+-------+
| max_connect_errors | 100   |
| max_connections    | 222   |
+--------------------+-------+
+---------------+------------------------+
| Variable_name | Value                  |
+---------------+------------------------+
| datadir       | /tmp/mydata/           |
| port          | 8556                   |
| socket        | /tmp/mydata/mysql.sock |
+---------------+------------------------+

LIKE の % は任意の文字列、_ は任意の1文字です。変数名にはアンダースコアが多いので、max_connections と書くと _ が1文字のワイルドカードとして働きますが、名前を正確に書いていれば目的の変数は必ず含まれます。複数の変数をまとめて見たいときは WHERE ... IN が便利です。

グローバル専用の変数にセッション修飾を付けたとき

max_connections のようにサーバー全体でしか意味を持たない変数は、セッション値を持ちません。

SELECT @@session.max_connections;
ERROR 1238 (HY000) at line 1: Variable 'max_connections' is a GLOBAL variable

このエラーは「値が無い」のではなく「見る場所が違う」という案内です。@@global.max_connections に書き換えると値が返ります。

SETの5種類を「反映・保存先・権限」で比べる

設定変更の文は5種類あります。違いは「今の値を変えるか」「どこに保存するか」「どの権限が要るか」の3点です。下の表は、すべてこの記事の検証環境で実行して確かめた内容です。

文 稼働中の値 再起動後 保存先 必要な権限(実行で確認)
SET SESSION 名前=値 自分の接続だけ変わる 残らない(切断で消える) なし(メモリ) 基本は不要。一部の変数は SESSION_VARIABLES_ADMIN など
SET GLOBAL 名前=値 すぐ変わる(新しい接続から有効) 残らない なし(メモリ) SYSTEM_VARIABLES_ADMIN(または SUPER)
SET PERSIST 名前=値 すぐ変わる 残る データディレクトリの mysqld-auto.cnf SYSTEM_VARIABLES_ADMIN(または SUPER)
SET PERSIST_ONLY 名前=値 変わらない 次の起動から有効 mysqld-auto.cnf SYSTEM_VARIABLES_ADMIN と PERSIST_RO_VARIABLES_ADMIN の両方
RESET PERSIST [名前] 変わらない 保存分が外れる mysqld-auto.cnf から削除 SYSTEM_VARIABLES_ADMIN。起動時専用の変数を消すときは PERSIST_RO_VARIABLES_ADMIN も

SET GLOBAL・PERSIST・PERSIST_ONLYを続けて実行する

my.cnf で max_connections=222 を指定して起動した状態から、順に実行します。

SET GLOBAL max_connections = 300;
SELECT @@global.max_connections;

SET PERSIST max_connections = 400;
SET PERSIST_ONLY innodb_buffer_pool_instances = 2;
SET PERSIST_ONLY max_connections = 500;
SELECT @@global.max_connections, @@global.innodb_buffer_pool_instances;

SELECT * FROM performance_schema.persisted_variables;
+--------------------------+
| @@global.max_connections |
+--------------------------+
|                      300 |
+--------------------------+
+--------------------------+---------------------------------------+
| @@global.max_connections | @@global.innodb_buffer_pool_instances |
+--------------------------+---------------------------------------+
|                      400 |                                     1 |
+--------------------------+---------------------------------------+
+------------------------------+----------------+
| VARIABLE_NAME                | VARIABLE_VALUE |
+------------------------------+----------------+
| max_connections              | 500            |
| innodb_buffer_pool_instances | 2              |
+------------------------------+----------------+

読み取れることは3つです。

  • SET PERSIST は稼働中の値も 400 に変えた(SET GLOBAL の働きを含む)
  • SET PERSIST_ONLY は稼働中の値を変えない(max_connections は 400 のまま、保存値だけ 500)
  • 保存されている内容は performance_schema.persisted_variables で一覧できる

保存先のmysqld-auto.cnfの中身

SET PERSIST 系の保存先は、データディレクトリ直下の mysqld-auto.cnf です。中身は JSON で、変更した利用者と時刻も記録されます。

{"Version": 2, "mysql_static_variables": {"innodb_buffer_pool_instances": {"Value": "2", "Metadata": {"Host": "localhost", "User": "root", "Timestamp": 1791016328219695}}}, "mysql_dynamic_parse_early_variables": {"max_connections": {"Value": "500", "Metadata": {"Host": "localhost", "User": "root", "Timestamp": 1791016328221399}}}}

このファイルは手で編集せず、SET PERSIST と RESET PERSIST で操作します(MySQL 8.4 リファレンスマニュアルの Persisted System Variables のページでも、文での操作が案内されています)。同じページのサンプルは Version 1 の形式で書かれていますが、8.0.46 で実際に作られたファイルは上のとおり Version 2 でした。形式は版によって変わるので、スクリプトで直接読むより persisted_variables テーブルを参照するほうが安定します。

再起動して値が残るかを確かめる

このあと sort_buffer_size も SET PERSIST で 1048576 にし、max_connections の保存値を 510 にしてから再起動しました。再起動直後の結果です。

SELECT VARIABLE_NAME, VARIABLE_SOURCE, VARIABLE_PATH, SET_TIME, SET_USER
FROM performance_schema.variables_info
WHERE VARIABLE_NAME IN ('max_connections','sort_buffer_size','port','innodb_buffer_pool_instances');
SELECT @@global.max_connections, @@global.innodb_buffer_pool_instances, @@global.sort_buffer_size;
+------------------------------+-----------------+-----------------------------+----------------------------+----------+
| VARIABLE_NAME                | VARIABLE_SOURCE | VARIABLE_PATH               | SET_TIME                   | SET_USER |
+------------------------------+-----------------+-----------------------------+----------------------------+----------+
| innodb_buffer_pool_instances | PERSISTED       | /tmp/mydata/mysqld-auto.cnf | 2026-10-03 17:32:22.766080 | app      |
| max_connections              | PERSISTED       | /tmp/mydata/mysqld-auto.cnf | 2026-10-03 17:32:22.765280 | app      |
| port                         | COMMAND_LINE    |                             | NULL                       | NULL     |
| sort_buffer_size             | PERSISTED       | /tmp/mydata/mysqld-auto.cnf | 2026-10-03 17:32:22.766605 | app      |
+------------------------------+-----------------+-----------------------------+----------------------------+----------+
+--------------------------+---------------------------------------+---------------------------+
| @@global.max_connections | @@global.innodb_buffer_pool_instances | @@global.sort_buffer_size |
+--------------------------+---------------------------------------+---------------------------+
|                      510 |                                     1 |                   1048576 |
+--------------------------+---------------------------------------+---------------------------+

my.cnf の 222 ではなく、保存しておいた 510 と 1048576 が再起動後に有効になりました。VARIABLE_SOURCE が PERSISTED、VARIABLE_PATH が mysqld-auto.cnf になっていることから、値の出どころも確認できます。

innodb_buffer_pool_instances は、出どころが PERSISTED になった一方で値は 1 のままでした。この変数は、バッファプールが 1GiB 未満のときは 1 に調整される仕様で、検証環境のバッファプールは既定の 128MB だったためです。「保存した値が読まれたか」は VARIABLE_SOURCE で、「実際の値」は @@global で、と分けて見ると、こうした調整にも気づけます。

RESET PERSISTで保存を取り消す

RESET PERSIST max_connections;
SELECT @@global.max_connections;
SELECT * FROM performance_schema.persisted_variables;
RESET PERSIST;
SELECT * FROM performance_schema.persisted_variables;
+--------------------------+
| @@global.max_connections |
+--------------------------+
|                      510 |
+--------------------------+
+------------------------------+----------------+
| VARIABLE_NAME                | VARIABLE_VALUE |
+------------------------------+----------------+
| sort_buffer_size             | 1048576        |
| innodb_buffer_pool_instances | 2              |
+------------------------------+----------------+

RESET PERSIST は保存分を消すだけで、稼働中の値(510)は変えません。 稼働中の値も戻したいときは、SET GLOBAL を併せて実行します。名前を付けない RESET PERSIST は保存分をすべて消し、2つ目の SELECT は0行(出力なし)になりました。このとき mysqld-auto.cnf の中身は次の1行だけです。

{"Version": 2}

もう一度再起動すると、max_connections は my.cnf の 222 に戻り、出どころは EXPLICIT(設定ファイル)になりました。

| max_connections              | EXPLICIT        | /home/taro/work/my1.cnf | NULL     | NULL     |

保存していない名前を RESET PERSIST するとエラーになります。スクリプトで使うときは IF EXISTS を付けると、警告だけで先へ進めます。

実行すると、IF EXISTS なしでは「ERROR 3615 (HY000): Variable wait_timeout does not exist in persisted config file」になり、IF EXISTS ありでは同じ文面の Warning 3615 が出て処理が続きました。

必要な権限を実際のエラーで確かめる

SELECT 権限だけを持つ利用者 app を作り、権限を1つずつ足しながら実行しました。

CREATE USER app@localhost;
GRANT SELECT ON *.* TO app@localhost;

権限を足す前の結果です。

SET SESSION sort_buffer_size=300000
SET GLOBAL max_connections=10
ERROR 1227 (42000) at line 2: Access denied; you need (at least one of) the SUPER or SYSTEM_VARIABLES_ADMIN privilege(s) for this operation
SET PERSIST max_connections=10
ERROR 1227 (42000) at line 3: Access denied; you need (at least one of) the SUPER or SYSTEM_VARIABLES_ADMIN privilege(s) for this operation
SET PERSIST_ONLY max_connections=10
ERROR 3630 (42000) at line 4: Access denied; you need SYSTEM_VARIABLES_ADMIN and PERSIST_RO_VARIABLES_ADMIN privileges for this operation
RESET PERSIST max_connections
ERROR 1227 (42000) at line 5: Access denied; you need (at least one of) the SUPER or SYSTEM_VARIABLES_ADMIN privilege(s) for this operation
SET SESSION sql_log_bin=0
ERROR 1227 (42000) at line 6: Access denied; you need (at least one of) the SUPER, SYSTEM_VARIABLES_ADMIN or SESSION_VARIABLES_ADMIN privilege(s) for this operation

SET SESSION sort_buffer_size は権限なしで通りました。一方、sql_log_bin のように影響の大きいセッション変数は、SET SESSION でも権限が求められます。

続いて SYSTEM_VARIABLES_ADMIN だけを付与した結果です。

GRANT SYSTEM_VARIABLES_ADMIN ON *.* TO app@localhost;
SET GLOBAL max_connections=310
SET PERSIST max_connections=410
SET PERSIST_ONLY max_connections=510
ERROR 3630 (42000) at line 3: Access denied; you need SYSTEM_VARIABLES_ADMIN and PERSIST_RO_VARIABLES_ADMIN privileges for this operation
SET PERSIST_ONLY innodb_buffer_pool_instances=2
ERROR 3630 (42000) at line 4: Access denied; you need SYSTEM_VARIABLES_ADMIN and PERSIST_RO_VARIABLES_ADMIN privileges for this operation
RESET PERSIST innodb_buffer_pool_instances
ERROR 3630 (42000) at line 5: Access denied; you need SYSTEM_VARIABLES_ADMIN and PERSIST_RO_VARIABLES_ADMIN privileges for this operation

SET GLOBAL と SET PERSIST は通り、SET PERSIST_ONLY は対象が動的な変数(max_connections)でも PERSIST_RO_VARIABLES_ADMIN が必要でした。起動時専用の変数を RESET PERSIST で消すときも同じ権限が求められます。最後に GRANT PERSIST_RO_VARIABLES_ADMIN ON *.* TO app@localhost; を実行すると、SET PERSIST_ONLY の2文もエラーなく通りました。

設定変更を担当する利用者には、必要な範囲に合わせてこの2つの権限を付与しておくと、SUPER を渡さずに運用できます。

read only variableなどSETで出るエラーと直し方

SET で出るエラーは、文の種類と変数の種類が合っていないことを知らせる内容がほとんどです。実際に出したエラー文と直し方を並べます。

SET GLOBAL innodb_buffer_pool_instances=2
ERROR 1238 (HY000) at line 1: Variable 'innodb_buffer_pool_instances' is a read only variable
SET PERSIST innodb_buffer_pool_instances=2
ERROR 1238 (HY000) at line 2: Variable 'innodb_buffer_pool_instances' is a read only variable
SET SESSION max_connections=10
ERROR 1229 (HY000) at line 3: Variable 'max_connections' is a GLOBAL variable and should be set with SET GLOBAL
SET GLOBAL sql_log_bin=0
ERROR 1228 (HY000) at line 4: Variable 'sql_log_bin' is a SESSION variable and can't be used with SET GLOBAL
SET PERSIST datadir='/x'
ERROR 1238 (HY000) at line 5: Variable 'datadir' is a read only variable
SET PERSIST_ONLY datadir='/x'
ERROR 1238 (HY000) at line 6: Variable 'datadir' is a non persistent read only variable
SET GLOBAL max_connections='abc'
ERROR 1232 (42000) at line 7: Incorrect argument type to variable 'max_connections'
SET GLOBAL no_such_var=1
ERROR 1193 (HY000) at line 10: Unknown system variable 'no_such_var'
SET PERSIST_ONLY bind_address='127.0.0.1'
ERROR 1238 (HY000) at line 11: Variable 'bind_address' is a non persistent read only variable
エラー 意味 直し方
1238 is a read only variable 起動時にしか決められない変数 SET PERSIST_ONLY で保存して再起動、または my.cnf に書いて再起動
1238 is a non persistent read only variable 起動時専用で、保存の対象にもならない変数(datadir、bind_address など) my.cnf か起動オプションに書く
1229 is a GLOBAL variable and should be set with SET GLOBAL セッション値を持たない変数 SET GLOBAL か SET PERSIST に変える
1228 is a SESSION variable グローバル値を持たない変数 SET SESSION に変える
1232 Incorrect argument type 値の型が合わない 数値は引用符なしで書く
1193 Unknown system variable 名前の綴りが違う、またはその版に無い変数 SHOW VARIABLES LIKE で正しい名前を探す
1227 / 3630 Access denied 権限が足りない 前の章の権限を付与する

read only variable は「変えられない」ではなく「起動時に決める」という意味です。直す前と後を並べると次のとおりです。

-- 直す前:稼働中に変えようとしてエラー 1238
SET GLOBAL innodb_buffer_pool_instances = 2;

-- 直した後:保存だけして、次の起動で反映する
SET PERSIST_ONLY innodb_buffer_pool_instances = 2;

なお、SET GLOBAL max_connections=0 のように範囲外の値を渡すと、エラーにはならず「Warning 1292 Truncated incorrect max_connections value: '0'」が出て値が調整されました。SET のあとに SHOW WARNINGS と @@global を確認すると、その場で気づけます。

my.cnfの場所をOS別に確認する

設定ファイルは、OSや導入方法によって置き場所が変わります。下の表のうち、Debian系(Ubuntu 24.04)の行はこの記事の検証環境で実際に確認した内容です。それ以外の行は一般に知られた配置で、今回は未実行です。手元の環境では、次の節のコマンドで実際の場所を確かめてください。

環境 主な設定ファイル 補足 今回の確認
Linux(Debian / Ubuntu 系のパッケージ) /etc/mysql/my.cnf → /etc/mysql/mysql.conf.d/mysqld.cnf my.cnf は !includedir で conf.d と mysql.conf.d を読むだけの入口 実行して確認
Linux(RHEL 系のパッケージ) /etc/my.cnf、/etc/my.cnf.d/ 配下の .cnf 一般に知られた配置 未実行
macOS(Homebrew) Homebrew の導入先の etc/my.cnf(Apple シリコンでは /opt/homebrew/etc/my.cnf が一般的) 一般に知られた配置 未実行
Windows %WINDIR%\my.ini、C:\my.ini、インストール先の my.ini(.cnf も可) MySQL 8.4 リファレンスマニュアルの Option Files の表より。インストーラーで入れた場合の実際の位置は別途確認 未実行
Docker(公式イメージ) コンテナ内の /etc/mysql/conf.d/ に .cnf を置く方法が一般的 一般に知られた配置。外部イメージを取得できない環境のため 未実行
共通:利用者ごとの設定 ~/.my.cnf クライアントの接続設定を書くのに便利 読み込み順に表示されることを確認
共通:SET PERSIST の保存先 データディレクトリ/mysqld-auto.cnf サーバーが自動で管理する 実行して確認

MySQL 8.4 リファレンスマニュアルの Option Files のページを今回開いて確認した、Unix 系での読み込み順は次のとおりです。あとから読まれたファイルの値が優先されます。

順 ファイル 用途
1 /etc/my.cnf 全体の設定
2 /etc/mysql/my.cnf 全体の設定
3 SYSCONFDIR/my.cnf ビルド時に決まるディレクトリ
4 $MYSQL_HOME/my.cnf サーバー専用の設定
5 --defaults-extra-file で指定したファイル 追加で読むファイル
6 ~/.my.cnf 利用者ごとの設定
7 ~/.mylogin.cnf ログイン情報(クライアントのみ)
8 データディレクトリ/mysqld-auto.cnf SET PERSIST の保存分(サーバーのみ)

同じページによると、!includedir で読まれるのは、Unix 系では拡張子が .cnf のファイル、Windows では .ini か .cnf のファイルです。ディレクトリ内の読み込み順は決まっていないため、同じ変数を複数のファイルに書かないようにしておくと見通しが良くなります。

実際に読まれるファイルをmysqld --verbose --helpで調べる

mysqld --verbose --help 2>/dev/null | grep -A2 "Default options"
Default options are read from the following files in the given order:
/etc/my.cnf /etc/mysql/my.cnf ~/.my.cnf 
The following groups are read: mysqld server mysqld-8.0

1行目が読み込み順、最後の行が読まれるグループ名です。サーバー(mysqld)が読むのは [mysqld]、[server]、[mysqld-8.0] の3つだと分かります。クライアント側も同じ方法で調べられます。mysql --help | grep -A2 "Default options" を実行すると、読み込み順は同じで、グループの行が「The following groups are read: mysql client」になりました。

検証環境の /etc/mysql/my.cnf は、コメントを除くと次の2行だけでした。実際の設定は、読み込まれる先のディレクトリにあります。

!includedir /etc/mysql/conf.d/
!includedir /etc/mysql/mysql.conf.d/

my_print_defaultsでファイルから渡される値を調べる

my_print_defaults は、設定ファイルを読んで、指定したグループに渡されるオプションだけを表示します。

my_print_defaults mysqld
--user=mysql
--bind-address=127.0.0.1
--mysqlx-bind-address=127.0.0.1
--key_buffer_size=16M
--myisam-recover-options=BACKUP
--log_error=/var/log/mysql/error.log
--max_binlog_size=100M

variables_infoで値の出どころを特定する

performance_schema.variables_info は、各変数の値がどこから来たかを記録しているテーブルです。設定ファイルが複数あるとき、どのファイルの値が有効なのかを VARIABLE_PATH で特定できます。

SELECT VARIABLE_NAME, VARIABLE_SOURCE, VARIABLE_PATH, SET_TIME, SET_USER
FROM performance_schema.variables_info
WHERE VARIABLE_NAME IN ('max_connections','sort_buffer_size','port','datadir',
                        'innodb_buffer_pool_instances','max_allowed_packet');

SET GLOBAL と SET SESSION を実行した直後の結果です。

+------------------------------+-----------------+---------------+----------------------------+----------+
| VARIABLE_NAME                | VARIABLE_SOURCE | VARIABLE_PATH | SET_TIME                   | SET_USER |
+------------------------------+-----------------+---------------+----------------------------+----------+
| datadir                      | COMMAND_LINE    |               | NULL                       | NULL     |
| innodb_buffer_pool_instances | COMPILED        |               | 2026-10-03 17:32:08.219695 | root     |
| max_allowed_packet           | COMPILED        |               | NULL                       | NULL     |
| max_connections              | DYNAMIC         |               | 2026-10-03 17:32:08.218649 | root     |
| port                         | COMMAND_LINE    |               | NULL                       | NULL     |
| sort_buffer_size             | DYNAMIC         |               | 2026-10-03 17:32:08.202078 | root     |
+------------------------------+-----------------+---------------+----------------------------+----------+
VARIABLE_SOURCE 意味 今回の確認
COMPILED 組み込みの既定値 表示を確認
EXPLICIT --defaults-file で指定した設定ファイル(VARIABLE_PATH にパス) 表示を確認
COMMAND_LINE 起動時のコマンドライン引数 表示を確認
PERSISTED mysqld-auto.cnf(SET PERSIST の保存分) 表示を確認
DYNAMIC 起動後に SET で変えた値(SET_TIME と SET_USER が入る) 表示を確認
GLOBAL / SERVER / EXTRA / USER / LOGIN 既定の場所の設定ファイルなど、読み込み元の種類 今回は表示されず。未実行

max_allowed_packet が COMPILED なのは、設定ファイルで [mysql] グループ(クライアント用)に書いていたためです。サーバーは [mysql] を読まないので、既定値のままになっています。「書いたのに COMPILED」と表示されたら、グループ名か読まれるファイルを確かめる合図です。

既定値以外だけを一覧にする次のクエリは、環境の引き継ぎや、2台のサーバーの設定差を比べるときに役立ちます。

SELECT VARIABLE_NAME, VARIABLE_SOURCE, VARIABLE_PATH
FROM performance_schema.variables_info
WHERE VARIABLE_SOURCE <> 'COMPILED'
ORDER BY VARIABLE_SOURCE, VARIABLE_NAME;

my.cnfに書いたのに反映されない例を再現する

例1:セクションが[mysqld]ではない

サーバーの変数を [mysql] に書いた設定ファイルを用意しました。

[mysql]
max_connections=333

[client]
port=8556

このファイルで起動した結果です。

| max_connections              | COMPILED        |               | NULL     | NULL     |

+--------------------------+
| @@global.max_connections |
+--------------------------+
|                      151 |
+--------------------------+

サーバーは起動しましたが、max_connections は既定値の 151 のままでした。エラーも警告も出ないため、気づきにくい例です。my_print_defaults で確かめると、[mysqld] グループには何も渡されていないことが分かります。

my_print_defaults --defaults-file=/home/taro/work/my2.cnf mysqld
# (出力なし)
my_print_defaults --defaults-file=/home/taro/work/my2.cnf mysql client
--max_connections=333
--port=8556

さらに、この設定ファイルを mysql クライアントで読むと、クライアントが知らないオプションとしてエラーになります。

mysql: [ERROR] unknown variable 'max_connections=333'.

直した後は、max_connections=333 の行を [mysqld] の下に移します。サーバーが読むグループは [mysqld]・[server]・[mysqld-8.0]、mysql コマンドが読むグループは [mysql]・[client] です(前の章の --verbose --help の出力のとおり)。

例2:変数名の綴り違いでサーバーが起動を止める

[mysqld] に、存在しない名前(最後の s が無い)を書きました。

[mysqld]
max_connection=333
2026-10-03T08:32:55.877200Z 0 [ERROR] [MY-000067] [Server] unknown variable 'max_connection=333'.
2026-10-03T08:32:55.877248Z 0 [ERROR] [MY-010119] [Server] Aborting

[mysqld] 内の知らない名前は、起動時のエラーとして表示され、サーバーはそこで止まります。 エラーログにこの2行が出ていたら、綴りと、その版に存在する変数かどうかを確かめます。版をまたいで同じ設定ファイルを使いたいときは、名前の前に loose- を付けると、知らない名前でも警告だけで起動します。

[mysqld]
max_connections=222
max_connections=250
loose-no_such_option=1
2026-10-03T08:32:59.048471Z 0 [Warning] [MY-000067] [Server] unknown variable 'loose-no_such_option=1'.

+--------------------------+
| @@global.max_connections |
+--------------------------+
|                      250 |
+--------------------------+

同じ変数を2回書いた場合は、あとに書いた 250 が有効になることも、この結果で確認できます。

例3:SET PERSISTの保存分がmy.cnfより優先される

my.cnf が 250、SET PERSIST の保存分が 400 の状態で、さらに起動時のコマンドラインで --max_connections=600 を指定しました。

| max_connections              | PERSISTED       | /tmp/mydata/mysqld-auto.cnf | 2026-10-03 17:32:59.547498 | root     |

+--------------------------+
| @@global.max_connections |
+--------------------------+
|                      400 |
+--------------------------+

8.0.46 で確かめた範囲では、保存分の 400 が、my.cnf の 250 とコマンドラインの 600 のどちらよりも優先されました。動的な変数の保存分は、起動処理の終わり近くで SET GLOBAL と同じように適用されるためです。「my.cnf を直して再起動したのに値が変わらない」ときは、まず persisted_variables に同じ変数が残っていないかを確かめます。

保存分を一時的に読ませたくないときは、persisted_globals_load=OFF で起動します。

mysqld --defaults-file=/home/taro/work/my4.cnf --persisted_globals_load=OFF (ほかの引数は省略)
| max_connections              | EXPLICIT        | /home/taro/work/my4.cnf | NULL     | NULL     |

+--------------------------+
| @@global.max_connections |
+--------------------------+
|                      250 |
+--------------------------+

mysqld-auto.cnf を読まずに、my.cnf の 250 で起動しました。保存した値が原因かどうかを切り分けたいときにも使えます。

反映されないときの確認手順

flowchart TD
    A[値が期待と違う] --> B[variables_info で VARIABLE_SOURCE を見る]
    B -->|COMPILED| C[ファイルが読まれていない、またはグループ名が違う]
    C --> C1[mysqld --verbose --help で読み込み順とグループを確認]
    C1 --> C2[my_print_defaults mysqld で渡される値を確認]
    B -->|PERSISTED| D[SET PERSIST の保存分が有効]
    D --> D1[RESET PERSIST 名前 で保存分を外す]
    B -->|DYNAMIC| E[起動後に SET で変更されている]
    E --> E1[SET_USER と SET_TIME で変更者と時刻を確認]
    B -->|EXPLICIT など| F[VARIABLE_PATH のファイルが有効]
    F --> F1[そのファイルを直して再起動]
確認すること コマンド 見るところ
値の出どころ variables_info を SELECT VARIABLE_SOURCE と VARIABLE_PATH
読まれるファイルと順番 mysqld --verbose --help Default options の次の行
グループ名 my_print_defaults mysqld 目的の変数が出力に含まれるか
保存分の有無 persisted_variables を SELECT 同じ変数が残っていないか
セッション値との違い SELECT @@global.名前, @@session.名前; 既存の接続は以前の値を持ち続ける
起動時のエラー エラーログ unknown variable の行

セッション値との違いは見落としやすい点です。SET GLOBAL で変えた値は新しい接続から有効になり、すでにつながっている接続のセッション値は変わりません。コネクションプールを使っているアプリケーションでは、接続を張り直すと新しい値が使われます。

どの方法で設定を変えるかの判断表

状況 向いている方法 理由
1つのクエリやバッチだけ値を変えたい SET SESSION ほかの接続に影響しない
今すぐ試したい。合わなければ再起動で戻したい SET GLOBAL 保存されないので試しやすい
今すぐ変えて、そのまま定着させたい SET PERSIST サーバーにログインせずSQLだけで完結する。変更者と時刻も残る
起動時にしか決められない変数を変えたい SET PERSIST_ONLY + 再起動 設定ファイルを触れない環境でも変更できる
構成管理ツールやリポジトリで設定を管理したい my.cnf + 再起動(動的な変数は SET GLOBAL も併用) ファイルが設定の正本になる
datadir や bind_address を変えたい my.cnf か起動オプション 保存の対象にならない変数

SET PERSIST と my.cnf を併用するときは、同じ変数を両方に書かないと決めておくと、出どころが1つに定まって管理しやすくなります。併用する場合は、前の章の「既定値以外だけを一覧にするクエリ」を定期的に見ておくと安心です。

MySQL 8.0・8.4・9.x系での違い

今回手元で動かしたのは 8.0.46 だけです。8.4 については、MySQL 8.4 リファレンスマニュアルの「What Is New in MySQL 8.4 since MySQL 8.0」を今回開いて確認した内容を載せます。8.4 と 9.x 系での動作そのものは未実行です。

項目 8.0 8.4(マニュアルで確認)
SET PERSIST / PERSIST_ONLY / RESET PERSIST 利用できる(実行して確認) 同じ文が案内されている
innodb_io_capacity の既定値 200 10000
innodb_log_buffer_size の既定値 16MiB 64MiB
innodb_adaptive_hash_index の既定値 ON OFF
default_authentication_plugin 利用できる 削除。authentication_policy を使う
expire_logs_days 利用できる 削除。binlog_expire_logs_seconds を使う
--skip-host-cache 利用できる 削除。host_cache_size=0 を使う
mysql_native_password プラグイン 既定で有効 既定では無効。使う場合は [mysqld] に mysql_native_password=ON

版を上げるときに設定ファイルで起きやすいのは、削除された変数が [mysqld] に残っていて、例2と同じ unknown variable で起動が止まる場面です。版を上げる前に次の3点を確認しておくと、落ち着いて進められます。

  • my_print_defaults mysqld の出力を、新しい版のマニュアルにある削除済みの変数の一覧と見比べる
  • persisted_variables に、新しい版で無くなる変数が保存されていないかを見る(残っていれば RESET PERSIST で外す)
  • 既定値が変わる変数は、明示的に書いておくか、新しい既定値を受け入れるかを決める

9.x 系(イノベーションリリース)については、今回マニュアルを開いておらず、動作も未実行です。8.4 以降も変数の追加と削除は続くため、使う版のリリースノートで、設定ファイルに書いている変数を1つずつ確かめる進め方をおすすめします。

よくある質問

Q. SET GLOBAL で変えた値は、いつ元に戻りますか? A. サーバーを再起動したときです。SET GLOBAL はメモリ上の値だけを変えるため、再起動すると my.cnf や既定値に戻ります。今回の検証でも、保存分を外した状態で再起動すると、稼働中の 510 は my.cnf の 222 に戻りました。残したいときは SET PERSIST を使うか、my.cnf にも同じ値を書きます。

Q. SET PERSIST と my.cnf の両方に同じ変数があると、どちらが有効ですか? A. 8.0.46 で確かめた範囲では、SET PERSIST の保存分が有効になりました。コマンドラインで指定した値よりも保存分が優先されました。variables_info の VARIABLE_SOURCE が PERSISTED になっていれば保存分が使われています。my.cnf の値に戻したいときは RESET PERSIST で保存分を外して再起動します。

Q. my.cnf を書き換えたら、再起動なしで反映できますか? A. my.cnf は起動時に読まれるファイルなので、書き換えただけでは稼働中の値は変わりません。動的な変数であれば、my.cnf を書き換えたうえで同じ値を SET GLOBAL すると、再起動を待たずに反映でき、次の起動でも同じ値になります。read only variable と表示される変数は再起動が必要です。

Q. mysqld-auto.cnf を直接編集してもよいですか? A. SET PERSIST と RESET PERSIST で操作するのが基本です。ファイルは JSON 形式で、版によって構造が変わります。保存した値でサーバーが起動しにくくなった場合は、persisted_globals_load=OFF を付けて起動し、RESET PERSIST で該当の変数を外す手順が使えます(OFF での起動は今回確認済みです)。

まとめ

  • 確認は GLOBAL を明示する:修飾なしの SHOW VARIABLES と @@名前 はセッション値を返す
  • SET GLOBAL は再起動で戻り、SET PERSIST は mysqld-auto.cnf に残る。SET PERSIST_ONLY は稼働中の値を変えずに保存だけ行う
  • RESET PERSIST は保存分を外すだけで、稼働中の値は変わらない
  • 権限は SYSTEM_VARIABLES_ADMIN が基本。PERSIST_ONLY には PERSIST_RO_VARIABLES_ADMIN も必要
  • read only variable は起動時に決める変数。PERSIST_ONLY か my.cnf に書いて再起動する
  • my.cnf の場所は mysqld --verbose --help と my_print_defaults で確かめる。サーバーの変数は [mysqld] に書く
  • 値の出どころは performance_schema.variables_info。COMPILED・EXPLICIT・PERSISTED・DYNAMIC を見れば、次に確認する場所が決まる

参考・出典

  • MySQL 8.4 Reference Manual「Using Option Files」(dev.mysql.com/doc/refman/8.4/en/option-files.html)
  • MySQL 8.4 Reference Manual「Persisted System Variables」(dev.mysql.com/doc/refman/8.4/en/persisted-system-variables.html)
  • MySQL 8.4 Reference Manual「What Is New in MySQL 8.4 since MySQL 8.0」(dev.mysql.com/doc/refman/8.4/en/mysql-nutshell.html)

株式会社RJC ― SI事業・SES事業・AI駆動開発。RJCは一緒に成長を楽しめる会社です。

WE ARE HIRING

RJCで一緒に開発しながら、
成長を楽しみませんか?

RJCは、Web・モバイル・AIを活用した開発プロジェクトで、テックリードやPM・PMOも活躍するシステム開発会社です。会社を知る、待遇を確かめる、話を聞いてみる。気になるところ見てみてください!

  • 127日年間休日
  • 12時間平均残業時間
  • 毎日ガチャ遊びココロも大切にする福利厚生。アマギフなどの賞品ラインナップ!

ほかにも、チケットレストラン、書籍読み放題、2年ごとの慰労報奨(休暇 or 金一封)、11期連続の黒字決算。

ABOUT RJC RJCがどんな会社か知る 考え方、研修、働き方、福利厚生、社員の前職まで。RJCのことが丸わかり! RJC丸わかりページへ JOB DESCRIPTION 仕事内容・待遇を見てみる 仕事内容、給与・待遇、選考の流れ。経験者も未経験も!応募前に知りたいこと、まとめました! 募集要項を見る ENTRY エントリーする エントリーは1〜2分・履歴書不要です。まずは話を聞いてみたい、という方でも歓迎です! エントリーフォームへ

RJCで一緒に開発しながら、 成長を楽しみませんか?