MySQLの設定には、SET GLOBALで即座に変更できる動的変数と、my.cnfを書き換えてサーバーを再起動しないと変更できない静的変数がある。
SHOW VARIABLESの結果だけではどちらか判別できないため、他の方法で見分ける必要がある。

参照:設定値の一覧・検索方法は【MySQL】設定値を一覧・検索する

SET GLOBALのエラーで判別する

動的変数でない設定をSET GLOBALで変更しようとすると、読み取り専用である旨のエラーになる。

mysql> SET GLOBAL port = 3307;
ERROR 1238 (HY000): Variable 'port' is a read only variable

mysql> SET GLOBAL innodb_buffer_pool_instances = 2;
ERROR 1238 (HY000): Variable 'innodb_buffer_pool_instances' is a read only variable

一方、動的変数の場合はエラーとならず、変更した値が即座に反映される。

mysql> SET GLOBAL wait_timeout = 5000;
Query OK, 0 rows affected (0.00 sec)

この方法は簡単だが、実際に変更を試みる必要があり、意図せず値を書き換えてしまうリスクがある。
確認だけしたい場合は、次のビューを参照するほうが安全である。

performance_schema.variables_infoで反映元を確認する

performance_schema.variables_infoビューのVARIABLE_SOURCE列を見ると、現在の設定値がどこから反映されたかが分かる。

mysql> SELECT VARIABLE_NAME, VARIABLE_SOURCE, SET_TIME, SET_USER
    -> FROM performance_schema.variables_info
    -> WHERE VARIABLE_NAME IN ('wait_timeout', 'max_connections', 'port');
+-----------------+-----------------+----------------------------+----------+
| VARIABLE_NAME   | VARIABLE_SOURCE | SET_TIME                   | SET_USER |
+-----------------+-----------------+----------------------------+----------+
| max_connections | COMPILED        | NULL                       | NULL     |
| port            | COMPILED        | NULL                       | NULL     |
| wait_timeout    | DYNAMIC         | 2026-08-15 09:54:40.539100 | root     |
+-----------------+-----------------+----------------------------+----------+

先にSET GLOBAL wait_timeout = 5000;を実行した後の結果であり、wait_timeoutVARIABLE_SOURCEDYNAMICになり、SET_TIMESET_USERにも変更した時刻とユーザーが記録されている。
max_connectionsportはまだ何も変更していないためCOMPILEDのままである。

VARIABLE_SOURCEの主な値は次のとおり。

意味
COMPILEDビルド時のデフォルト値のまま
COMMAND_LINE起動時のコマンドライン引数で指定
SERVER(設定ファイル系)my.cnfなど設定ファイルで指定
DYNAMIC起動後にSET GLOBALまたはSET PERSISTで変更
PERSISTEDSET PERSISTで永続化された値が、再起動後に読み込まれた
USERLOGIN接続時の認証情報などから設定

COMPILEDCOMMAND_LINE、設定ファイル由来の値はSET GLOBALで変更できるとは限らないが、DYNAMICPERSISTEDが表示される設定は動的変数であることが確定する。

SET PERSISTで永続化する

動的変数をSET GLOBALで変更しても、変更内容はmy.cnfには書き込まれないため、再起動すると元の値に戻ってしまう。
SET PERSISTを使うと、値の変更と同時に設定ファイル(mysqld-auto.cnf)への書き込みも行われ、再起動後も値が引き継がれる。

SET PERSIST max_connections = 200;

SET PERSISTは動的変数にのみ実行できる。静的変数に対して実行するとエラーになる。

mysql> SET PERSIST port = 3307;
ERROR 1238 (HY000): Variable 'port' is a read only variable

SET PERSIST_ONLYで静的変数も永続化できる

静的変数であっても、次回起動時に反映させたい場合はSET PERSIST_ONLYを使う。
SET PERSIST_ONLYは設定ファイルへの書き込みのみを行い、現在のセッションの値は変更しない。

mysql> SET PERSIST_ONLY innodb_buffer_pool_instances = 4;
Query OK, 0 rows affected (0.00 sec)

mysql> SHOW GLOBAL VARIABLES LIKE 'innodb_buffer_pool_instances';
+------------------------------+-------+
| Variable_name                | Value |
+------------------------------+-------+
| innodb_buffer_pool_instances | 1     |
+------------------------------+-------+

SHOW GLOBAL VARIABLESの値はまだ1のままだが、設定ファイルには4が書き込まれている。
再起動すると値が反映される。

mysql> SHOW GLOBAL VARIABLES LIKE 'innodb_buffer_pool_instances';
+------------------------------+-------+
| Variable_name                | Value |
+------------------------------+-------+
| innodb_buffer_pool_instances | 4     |
+------------------------------+-------+

portのように、いかなる方法でも永続化すらできない設定もある。

mysql> SET PERSIST_ONLY port = 3307;
ERROR 1238 (HY000): Variable 'port' is a non persistent read only variable

datadirinnodb_page_sizeなど、インスタンス作成時に決まり以後変更できない設定が該当する。

performance_schema.persisted_variablesで永続化済みの設定を確認する

SET PERSISTSET PERSIST_ONLYで永続化した設定はperformance_schema.persisted_variablesビューで一覧できる。

mysql> SELECT * FROM performance_schema.persisted_variables;
+------------------------------+----------------+
| VARIABLE_NAME                | VARIABLE_VALUE |
+------------------------------+----------------+
| max_connections              | 200            |
| innodb_buffer_pool_instances | 4              |
| innodb_buffer_pool_size      | 1073741824     |
+------------------------------+----------------+

永続化した設定を取り消す場合はRESET PERSISTを使う。

RESET PERSIST innodb_buffer_pool_instances;

RESET PERSISTは設定ファイルの記述を削除するだけであり、現在のセッションの値には影響しない。
削除した設定はサーバー起動時のデフォルト値、またはmy.cnfの値に、再起動後に戻る。

引数なしのRESET PERSISTを実行すると、永続化されたすべての設定を削除する。

RESET PERSIST;

mysqld-auto.cnfファイルの中身

SET PERSISTSET PERSIST_ONLYで永続化した設定は、データディレクトリ直下のmysqld-auto.cnfにJSON形式で保存される。

$ cat /var/lib/mysql/mysqld-auto.cnf
{
    "Version": 2,
    "mysql_static_variables": {
        "innodb_buffer_pool_size": {
            "Value": "1073741824",
            "Metadata": {
                "Host": "localhost",
                "User": "root",
                "Timestamp": 1786787059244160
            }
        }
    },
    "mysql_dynamic_parse_early_variables": {
        "max_connections": {
            "Value": "200",
            "Metadata": {
                "Host": "localhost",
                "User": "root",
                "Timestamp": 1786786991839335
            }
        }
    }
}

mysql_static_variablesには静的変数、mysql_dynamic_parse_early_variablesなど他のキーには起動時に早期評価を必要とする動的変数が分類されて保存される。
このファイルは手動で編集せず、必ずSET PERSIST系のコマンドを通して変更する。
直接編集すると、JSON構文エラーによってMySQLを起動できなくなる場合がある。

参考