Есть ли изящный или безопасный перезапуск для mysql, как для apache httpd?

29

Я хотел бы перезапустить MySQL изящно так же, как httpd, где потоки обслуживаются до перезапуска. Я не хотел бы ломать запросы.

giorgio79
источник

Ответы:

37

Любая «запрошенная» последовательность завершения работы в MySQL (если не считать kill -9) является несколько изящной , поскольку выполняемые транзакции (для таблиц транзакций) откатываются, но вот несколько способов сделать перезапуск максимально чистым.

Примечание: если вы выключаете сервер для обновления, не используйте этот процесс; вместо этого следуйте процессу, подробно описанному в этом ответе .

В противном случае, если вы просто перезапускаете исправный в противном случае сервер, чтобы вы могли изменить глобальную переменную только для чтения или что-то подобное, вот изящный путь:

Сначала включите, innodb_fast_shutdownесли это еще не так. Это не имеет прямого отношения к грациозности завершения работы, но должно быстрее вернуть ваш сервер.

mysql> SHOW VARIABLES LIKE 'innodb_fast_shutdown';
+----------------------+-------+
| Variable_name        | Value |
+----------------------+-------+
| innodb_fast_shutdown | 0     |
+----------------------+-------+
1 row in set (0.00 sec)

mysql> SET GLOBAL innodb_fast_shutdown = 1;
Query OK, 0 rows affected (0.01 sec)

Затем поручите серверу закрыть все открытые таблицы, как только на них не ссылаются ни один из запущенных в данный момент запросов. Этот шаг также не имеет ничего общего с постепенным отключением, но он сделает следующий шаг быстрее:

mysql> FLUSH LOCAL TABLES;
Query OK, 0 rows affected (41.12 sec)

FLUSH TABLESЗаявление (с опциональным LOCALключевым словом, что позволяет избежать ненужный , но в противном случае безвредного флеш любых рабов) будет блокировать и ваша подсказка не вернусь , пока все таблицы не может быть закрыт. После того, как каждая таблица «сброшена» (закрыта), если запрос впоследствии ссылается на таблицу, он будет автоматически повторно открыт, но это нормально. На этом этапе мы выполняем меньше работы для последнего этапа:

mysql> FLUSH TABLES WITH READ LOCK;
Query OK, 0 rows affected (13.74 sec)

mysql>

Этот оператор сбрасывает все таблицы (отсюда и преимущество, заключающееся в том, что некоторые из них могут быть менее разрушительными по сравнению с предыдущим шагом) и получает глобальную (общесерверную) блокировку только для чтения для них.

Вы не можете иметь глобальную блокировку чтения до тех пор, пока не будет выполнен каждый запущенный в данный момент запрос «записи» (т.е. почти все, но SELECT). Выполнение запроса блокировки позволит завершить существующие запросы, но не позволит запускать новые.

Ваше приглашение не вернется, пока вы не удержите эту глобальную блокировку, поэтому каждый запрос, который выполняется, когда вы запрашиваете блокировку, может завершиться, и вы знаете, что она завершена, потому что вы получаете приглашение обратно. Любые последующие запросы, которые пытаются что-либо записать в любую таблицу, просто останавливаются, не изменяя данные, ожидая блокировки бесконечно, пока ...

  • Вы передумали о перезагрузке и сняли блокировку вручную ( UNLOCK TABLES;)
  • вы перезапускаете сервер, или
  • вы случайно или намеренно отключаете клиента командной строки от этого потока (так что не делайте этого). Держите это окно подключенным и сидящим в приглашении mysql:

Не поддавайтесь искушению закрыть это.

mysql>

Это простое приглашение консоли - то, что держит глобальную блокировку для вас. Потерять это, потерять замок.

Из другого окна консоли перезапустите MySQL, как обычно, либо с initscripts (например, ваш локальный вариант service mysql.server restart), либо с mysqladmin shutdownпоследующим перезапуском вручную.

Майкл - sqlbot
источник
innodb_fast_shutdown = 1Действительно ли использование гарантирует, что MySQL запускается быстрее? Глядя на документы, кажется, что это улучшает скорость выключения (за счет скорости запуска?).
Крис
@ Крис в том, что идея заключается в том, что это помогает гарантировать, что все завершение работы и запуск выполняются настолько быстро, насколько это практически возможно, но это несколько анекдотично, поскольку объем выполняемой работы теоретически одинаков - просто перенесен на другую сторону последовательности - пока по какой-то причине в целом это всегда казалось более быстрым, например, возможно, что при отключении происходит некоторая неэффективность, которой нет при запуске. Сложно сказать.
Майкл - sqlbot
2

Короче говоря, некоторые из лучших практик, которые следует учитывать перед закрытием MySQL:

  1. Подтвердите экземпляр, который вы собираетесь отключить, чтобы избежать остановки другого экземпляра по ошибке.
  2. Остановите репликацию, если вы собираетесь выключить подчиненное устройство mysql> STOP SLAVE;.
  3. Промойте грязные страницы заранее, чтобы сократить время выключения mysql> SET GLOBAL innodb_max_dirty_pages_pct = 0;.
  4. Проверяйте длительные запросы mysql> SHOW PROCESSLIST;, убивайте их mysql> kill thread_id;или ждите, пока они не закончатся.
  5. Дамп буферного пула при завершении работы mysql> SET GLOBAL innodb_buffer_pool_dump_at_shutdown = ON;и перезагрузите его при запуске, # vi /etc/my.cnf innodb_buffer_pool_load_at_startup = ON чтобы прогреть буферный пул.

Затем, после подтверждения предыдущих пунктов, вы можете безопасно перезапустить MySQL shell$ service mysql restart

Для получения более подробной информации, смотрите мой пост. Проверьте эти, прежде чем выключать MySQL!

Молл
источник
Почему это было отвергнуто? Я не знаю достаточно, чтобы распознать, какие команды плохие, но я хочу знать, чтобы избежать их.
Джон
Я не знаю ничего из вышеперечисленного - плохая команда. Я следую вышеупомянутым шагам, и так много людей делают. Только шаг 4 следует соблюдать осторожность, вы не должны уничтожать какие-либо запросы до тех пор, пока не будете уверены в том, что делаете, в противном случае дождитесь окончания длительных запросов. Попробуйте, и если это помогло вам, отзовитесь, если нет, откажитесь!
Молл