Как правильно убить MySQL?


28

У меня CentOS 64bit с установленным CPanel и я использую:

service mysql stop

Он просто тикает и никогда не останавливается. В журналах просто публикуется много сообщений:

130303 17:42:38 [Warning] /usr/sbin/mysqld: Forcing close of thread

В err.logфайле я вижу много таких:

[Warning] /usr/sbin/mysqld: Forcing close of thread

Раньше было мгновенно. Есть идеи, почему это так и как это исправить?

Прямо сейчас я должен сделать, killall -9 mysqlно есть ли лучший способ?

Сервер также очень и очень активен.

Это проблема с конфигурацией? У меня слишком высокие настройки памяти?

[mysqld]
default-storage-engine=MyISAM
local-infile=0
symbolic-links=0
skip-networking
max_connections = 500
max_user_connections = 20
key_buffer = 512M
myisam_sort_buffer_size = 64M
join_buffer_size = 64M
read_buffer_size = 12M
sort_buffer_size = 12M
read_rnd_buffer_size = 12M
table_cache = 2048
thread_cache_size = 16K
wait_timeout = 30
connect_timeout = 15
tmp_table_size = 64M
max_heap_table_size = 64M
max_allowed_packet = 64M
max_connect_errors = 10
query_cache_limit = 1M
query_cache_size = 64M
query_cache_type = 1
low_priority_updates=1
concurrent_insert=ALWAYS
log-error=/var/log/mysql/error.log
tmpdir=/home/mysqltmp
myisam_repair_threads=4
[mysqld_safe]
open_files_limit = 8192
log-error=/var/log/mysql/error.log

[mysqldump]
quick
max_allowed_packet = 512M

[myisamchk]
key_buffer = 64M
sort_buffer = 64M
read_buffer = 16M
write_buffer = 16M

Ответы:


37

Самый простой способ выключить MySQL - просто запустить

mysqladmin -uroot -p -h127.0.0.1 --protocol=tcp shutdown

Вот почему:

Сервисный файл mysql ( /etc/init.d/mysql) зависит от наличия файла сокета. Исторически говоря, возвращаясь к MySQL 4.0, файл сокета иногда исчезает необъяснимым образом. Это мешает стандарту service mysql stopработать.

Недостаточно сказать

mysqladmin -uroot -p -h127.0.0.1 shutdown

потому что туздЫ будет маршрутизировать пользователь подходит как root@127.0.0.1для , root@localhostесли TCP / IP явным образом не включен. По умолчанию туздЫ будет выбирать наименьший путь сопротивления и подключиться root@127.0.0.1к root@localhostчерез файл сокета. Тем не менее, если нет файла сокета, root@localhostникогда не будет подключаться.

Даже Документация MySQL на mysqladmin говорит это:

Если вы выполняете завершение работы mysqladmin при подключении к локальному серверу с помощью файла сокета Unix, mysqladmin будет ждать, пока файл идентификатора процесса сервера не будет удален, чтобы убедиться, что сервер остановился правильно.

Вот почему необходимо включить TCP / IP:

mysqladmin -uroot -p -h127.0.0.1 --protocol=tcp shutdown

Вернувшись 30 сентября 2011 года, я написал собственную версию mysqld_multicall mysqlservice(см. Мой пост: запуск нескольких экземпляров на одном хосте ). Он служит виртуальным движком для подключения к mysqld из разных портов. Вы просто должны принести свой собственный my.cnfс настроенными параметрами. В этом сценарии я выполняю выключения, как это:

stop() {
  ${ECHO} -n $"Stopping ${PROGNAME}"
  ${MYSQLD_STOP}
  ATTEMPTS=0
  STOPPING_MYSQLD=1
  MINUTES_TO_TRY=10
  (( TICKS_TO_TRY = MINUTES_TO_TRY*240 ))
  while [ ${STOPPING_MYSQLD} -eq 1 ]
  do
    ${ECHO} -n "."
    ${SLEEP} 0.25
    MYSQLD_HAS_BEEN_SHUTDOWN=`${TAIL} ${MYSQL_ERROR_LOG} | ${GREP} -c "Shutdown complete$"`
    (( ATTEMPTS++ ))
    if [ ${ATTEMPTS} -eq ${TICKS_TO_TRY}   ] ; then STOPPING_MYSQLD=0 ; fi
    if [ ${MYSQLD_HAS_BEEN_SHUTDOWN} -eq 1 ] ; then STOPPING_MYSQLD=2 ; fi
  done
  ${ECHO}
  if [ ${STOPPING_MYSQLD} -eq 2 ]
  then
    ${ECHO} "Stopped ${PROGNAME}"
  else
    ${TAIL} -30 ${MYSQL_ERROR_LOG}
  fi
}

Но что это ${MYSQLD_STOP}?

MYSQL_CONN="-uroot -p<rootpassword> -P${MYSQLD_PORT} -h127.0.0.1 --protocol=tcp"
MYSQLD_STOP="${MYSQLADMIN} ${MYSQL_CONN} shutdown"

Обратите внимание, я использую 127.0.0.1и явный порт. Таким образом, я не полагаюсь на файл сокета.

Я всегда использовал mysqladmin --protocol=tcp shtudownкак правильную альтернативу отключениям mysql, если service mysql stopзависает. Делать kill -9дальше mysqldи mysqld_safeследует последним из последних из последних курортов. (Да, я сказал последние три раза).

Много раз mysqld удалял mysql.sock без предупреждения. У других людей была эта проблема также за эти годы:

Эпилог

Секрет в том, что я уже говорил: подключитесь к mysql с помощью mysqladmin через TCP / IP ( --protocol=tcp) и выполните команду shutdown. Это должно работать , потому что отключение привилегии находятся в mysql.userисключительно с целью удостоверенных остановов. Это несколько раз спасло мой рабочий день, когда я смог выполнить удаленное отключение с моего компьютера с Windows при завершении работы mysqld на сервере Linux.

ОБНОВЛЕНИЕ 2013-03-06 22:48 EST

Если вы беспокоитесь о том, что происходит во время выключения, есть способ манипулировать временем выключения и способом переноса данных на диск, особенно если у вас много данных InnoDB в пуле буферов

ПРЕДЛОЖЕНИЕ № 1

Если у вас много грязных страниц, вы можете понизить innodb_max_dirty_pages_pct до 0:

SET GLOBAL innodb_max_dirty_pages_pct = 0;

Установите это примерно за 15-30 минут до выключения. Это даст mysqld минимально возможное количество грязных страниц для записи на диск.

ПРЕДЛОЖЕНИЕ № 2

По умолчанию innodb_fast_shutdown равен 1. Для этой опции есть три значения

  • 0: InnoDB выполняет медленное выключение, полную очистку и объединение буфера вставки перед выключением.
  • 1: InnoDB пропускает эти операции при завершении работы, процесс, известный как быстрое завершение работы.
  • 2: InnoDB сбрасывает свои журналы и выключается, как будто MySQL потерпел крах; зафиксированные транзакции не теряются, но операция восстановления после сбоя делает следующий запуск более длительным.

Документация далее говорит это:

Медленное отключение может занять минуты или даже часы в крайних случаях, когда значительные объемы данных все еще буферизируются. Используйте метод медленного завершения работы перед обновлением или понижением версии между основными выпусками MySQL, чтобы все файлы данных были полностью подготовлены на случай, если процесс обновления обновит формат файла.

Используйте innodb_fast_shutdown = 2 в экстренных ситуациях или при устранении неполадок, чтобы получить максимально быстрое отключение, если данные подвергаются риску повреждения.

Значения по умолчанию для innodb_max_dirty_pages_pct и innodb_fast_shutdown должны быть очень хорошими в большинстве случаев.


2
Файл сокета исчезает в производных Red Hat, потому что tmpwatchудаляет его вместе со всем остальным /tmp, у которого время больше заданного порога.
Майкл - sqlbot

Спасибо, @ Michael-sqlbot Мне наконец-то нужно было это услышать. Наверное, поэтому кто-то из MySQL AB (до Oracle, до Sun) решил добавить привилегию SHUTDOWN, mysql.userчтобы обойти подобные головные боли.
RolandoMySQLDBA

В Debian или Ubuntu mysqladmin --defaults-file=/etc/mysql/debian.cnf shutdown... этот файл содержит учетные данные для учетной записи MySQL, похожей на root.
0xC0000022L

Как обычно, @RolandoMySQLDBA вы - один из лучших ресурсов DBA на сайтах Stack Exchange. Отличная работа, которая помогла мне 6+ лет спустя.
JakeGould

5

Звучит так, как будто ваш вопрос не столько о том, «как» закрыть MySQL, сколько о том, почему ваш закрывается так медленно.

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

Если вы не являетесь частым пользователем SHOW FULL PROCESSLIST;этого пункта № 1, потому что вам нужно иметь представление о том, что происходит на вашем сервере, что делает отключение таким медленным. Если есть длительные запросы, которые безопасно прерывать, вы можете их убить KILL <thread-id>.

Резюмируя другие предложения:

Установка глобальной переменной innodb_fast_shutdown = 1(по умолчанию) ускорит часть отключения InnoDB. Это только безопасным, однако, если вы выключая сервер по причинам , не связанным с выполнением обновления. Если вы закрываетесь для обновления, это должно быть установлено в 0.

Использование FLUSH TABLES;изящно закрывает все открытые таблицы. Они будут открыты, если на них ссылаются последующие запросы, но это действие должно в конечном итоге сократить время, которое проходит между временем, когда вы запрашиваете завершение работы, и временем, когда оно завершается, потому что оно выполняет некоторую раннюю служебную работу и, что более важно, устанавливает этап для последнего шага ...

FLUSH TABLES WITH READ LOCK;закрывает все открытые таблицы и получает эксклюзивную блокировку, принадлежащую вашему текущему клиентскому соединению, которая предотвращает запись любого другого соединения в любую таблицу на всем сервере. Вы не получите свое mysql>приглашение обратно, пока не получите эту блокировку, после чего вы сможете отправить запрос на отключение, но не отключайтесь от этого сеанса.

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


2

Вероятно, MySQL не просто заблокирован, а выполняет операции очистки (откаты и т. Д.) При завершении работы. Если вы не позволяете ему делать все это при выключении, часто вам придется ждать при запуске.

Вот что посмотреть: Завершите работу mysql в одном окне терминала, одновременно просматривая журнал ошибок (tail -f [yourerror.log]) в другом окне терминала. Журнал ошибок покажет вам, что делает MySQL.


1

Мне жаль слышать о вашем опыте и надеюсь, что мой опыт с глупыми сценариями MySQL, подобный этому, может вам помочь.

Вместо того, чтобы пытаться выяснить, как отключить службу MySQL с сервера, в некоторых случаях вам потребуется проверить работоспособность вашей системы с помощью следующего, чтобы определить, есть ли злоупотребление службой ( предположение основано на понятии для Среда CentOS / RHEL ):

 /usr/bin/iostat
 /usr/bin/uptime
 top -c

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

Вам также необходимо установить, mytopчтобы получить общее представление об операторах SQL, которые обрабатываются системой.

Для установки mytopпросто выполните следующее:

 cd /root
 wget http://jeremy.zawodny.com/mysql/mytop/mytop-1.6.tar.gz
 tar -zxvf /root/mytop-1.6.tar.gz
 cd /root/mytop-1.6
 perl Makefile.pl
 make
 make install
 chmod 644 /usr/local/bin/mytop
 vi /usr/local/bin/mytop 

(используйте любой текстовый редактор, который вы предпочитаете)

Искать "long|!" => \$config{long_nums},

Прокомментируйте это как #"long|!" => \$config{long_nums},

chmod 555 /usr/local/bin/mytop

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

Выполнение вышеуказанных инструкций предоставит вам следующие возможности:

  • Диагностика состояния / здоровья вашего сервера
  • Диагностика причины узкого места

Как только вы устранили причину узкого места, у вас должен быть более легкий день, когда вы пытаетесь перезапустить службу MySQL. Я надеюсь, что вы найдете вышеуказанную информацию полезной.

Примечание: mytop древний и не поддерживается. Вы, вероятно, должны использовать innotopв современной системе.


0

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

MySQL после получения SIGTERM сначала прекратит прием новых подключений, затем завершит выполнение тех запросов, которые все еще находятся на рассмотрении (это может занять некоторое время, в зависимости от рабочей нагрузки и числа одновременно работающих клиентов), а затем начнет сбрасывать данные на диск (это может занять долгое время, опять же в зависимости от вашей рабочей нагрузки, конфигурации, доступной памяти и выбора механизма хранения). После завершения очистки данных MySQL затем освободит всю память, выделенную на этапе инициализации (это также может занять некоторое время, в зависимости от объема памяти, выделенной MySQL), закроет все открытые дескрипторы файлов и затем вызовет "выход (0)".

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

К сожалению, в вашем вопросе недостаточно информации, чтобы я мог предложить правильное решение вашей проблемы. Я надеюсь, что это помогает понять проблему.

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.