Як правильно вбити 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 явним чином не включений. За замовчуванням mysqld вибере найменший шлях опору та підключиться root@127.0.0.1до root@localhostфайлу socket. Однак, якщо файлу сокета немає, root@localhostвін ніколи не підключиться.

Навіть документація MySQL на mysqladmin говорить про це:

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

Ось чому необхідно ввімкнути TCP / IP:

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

Повернувшись 30 вересня 2011 року, я написав власну версію mysqld_multiзакликаного 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тому, що має аніме, старше встановленого порогу.
Michael - sqlbot

Дякую, @ Michael-sqlbot, нарешті, мені потрібно було це почути від когось. Я думаю, тому хтось із MySQL AB (pre-Oracle, pre-Sun) вирішив додати привілей SHUTDOWN, щоб уникнути mysql.userподібних головних болів.
RolandoMySQLDBA

У Debian або Ubuntu використовуйте mysqladmin --defaults-file=/etc/mysql/debian.cnf shutdown... цей файл містить облікові дані для кореневого акаунта MySQL.
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 в одному вікні терміналу під час перегляду журналу помилок (хвіст -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

Стандартна реалізація сценарію init-скрипту MySQL передає MySQL за допомогою SIGTERM і чекає певного часу, коли MySQL вимкнеться.

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

Якщо після вашого запиту на відключення MySQL потребує тривалого часу, щоб завершити роботу, цілком можливо, що один або кілька цих етапів потребує тривалого часу. Якщо у вас є час, я настійно рекомендую дочекатися завершення процесу (це дозволить уникнути втрати даних або тривалих процесів відновлення при повторному запуску екземпляра бази даних).

На жаль, у вашому запитанні недостатньо інформації, яка б дозволила мені запропонувати правильне рішення вашої проблеми. Сподіваюсь, це допоможе зрозуміти проблему.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.