Багато системних змінних MySQL динамічні - їх можна змінити на працюючому сервері. Проблема класичного SET GLOBAL: після перезапуску значення повертається до того, що у my.cnf. Хтось виправив налаштування під час інциденту, забув перенести в конфіг - і через місяць після перезапуску проблема повертається.
SET PERSIST (MySQL 8.0+) змінює значення і зараз, і назавжди:
SET PERSIST max_connections = 500;
SET PERSIST long_query_time = 0.5;
Значення зберігається у файлі mysqld-auto.cnf у каталозі даних (JSON) і застосовується при старті після my.cnf - тобто має пріоритет.
Варіанти:
SET GLOBAL- лише до перезапуску;SET PERSIST- зараз і після перезапуску (для динамічних змінних);SET PERSIST_ONLY- лише після перезапуску. Для змінних, які не можна змінити на льоту (наприклад,innodb_buffer_pool_instances): «запам'ятати й застосувати при наступному старті».
Скасувати збережене:
RESET PERSIST max_connections; -- прибрати одну змінну з mysqld-auto.cnf
RESET PERSIST; -- усі
RESET PERSIST не змінює поточного значення - лише прибирає його з файлу.
Звідки взялося поточне значення:
SELECT variable_name, variable_source, variable_path, set_time, set_user
FROM performance_schema.variables_info
WHERE variable_name = 'max_connections';
-- variable_source: COMPILED / GLOBAL (my.cnf) / PERSISTED / DYNAMIC ...
SELECT * FROM performance_schema.persisted_variables;
Видно, хто й коли змінив значення - корисно для розслідування інцидентів.
Права: SET PERSIST вимагає SYSTEM_VARIABLES_ADMIN, а PERSIST_ONLY для read-only змінних - ще й PERSIST_RO_VARIABLES_ADMIN.
Підводні камені:
- два джерела правди. Конфігурація розщеплюється між
my.cnf(під контролем Ansible, Docker-образу, Git) іmysqld-auto.cnf(зміни з консолі). Система керування конфігурацією може «не бачити» значення, яке реально діє. Практичне правило:SET PERSISTдля оперативних змін, а потім - перенести в основну конфігурацію й зробитиRESET PERSIST; - сервер може не стартувати, якщо збережено некоректне значення для
PERSIST_ONLYзмінної. Вимкнути читання файлу допомагаєpersisted_globals_load = OFF; - секрети в
mysqld-auto.cnf(наприклад, деякі змінні плагінів) можна зберігати зашифрованими через keyring; - керовані хмарні бази (RDS, Cloud SQL) зазвичай не дозволяють
SET PERSIST- там параметри змінюються через групи параметрів провайдера.
Зміни, що діють не на всіх одразу: SET GLOBAL/PERSIST змінює глобальне значення, а наявні з'єднання зберігають свої сесійні копії змінних. Нове значення sort_buffer_size побачать лише нові підключення - у постійних воркерах (Horizon, Octane) лише після їх перезапуску.