Высокое время блокировки MySQL по запросу UPDATE приводит к зависанию сервера - PullRequest
0 голосов
/ 15 сентября 2018

Это убивает меня.Пожалуйста, помогите мне.Мой рабочий сервер зависает один раз в неделю.Были запросы, которые блокируют строки и блокируют другие запросы, все время потребляя 100% ресурсов ЦП.Мне нужно вручную убить эти замороженные запросы, прежде чем сервер снова заработает.

У меня есть система, которая будет показывать баннеры с самым высоким CTR на сайте в зависимости от того или иного слота.Это моя структура таблицы.

CREATE TABLE IF NOT EXISTS `banners` (
  `banner_id` int(5) NOT NULL AUTO_INCREMENT,
  `banner_slot` varchar(15) NOT NULL,
  `banner_img_path` varchar(200) NOT NULL,
  `banner_link` varchar(200) NOT NULL,
  `banner_views` int(8) NOT NULL DEFAULT '1',
  `banner_clicks` int(8) NOT NULL DEFAULT '0',
  `banner_ctr` double(5,3) NOT NULL DEFAULT '0',
  PRIMARY KEY (`banner_id`),
  KEY `banner_slot` (`banner_slot`,`banner_views`,`banner_ctr`)
) ENGINE=InnoDB  DEFAULT CHARSET=utf8 AUTO_INCREMENT=4231;

Это работает на рабочем сервере (CentOS6.3 / MySQL 5.5.28 / Apache2 / Четырехъядерный ЦП / 8 ГБ ОЗУ).Довольно старый, я знаю.

На сервере также работает еще несколько WordPress сайтов, на которых я уже использую плагин WP Super cache.Есть несколько запросов из WordPress, появляющихся в файле журнала медленных запросов, но они все меньше 5 секунд.

В последнее время я ежедневно получаю около 20K просмотров страниц.Примерно 2-3K UIP в часы пик (все домены объединены).

Это мои настройки my.cnf:

innodb_file_per_table=1
open_files_limit=10192
skip-external-locking
key_buffer_size=800M
max_allowed_packet=100M
table_open_cache=512
table_cache=500
sort_buffer_size=2M
read_buffer_size=4M
read_rnd_buffer_size=8M
thread_cache_size=4
query_cache_type=0
query_cache_size=4M
join_buffer_size=8M
tmp_table_size=512M
max_heap_table_size=256M
max_connections=200

Это мой файл журнала медленных запросов.Вы увидите, что для такого базового запроса время блокировки очень велико.

# Query_time: 84.554967  Lock_time: 37.070954 Rows_sent: 0  Rows_examined: 1
use db_name;
SET timestamp=1537010708;
UPDATE banners SET banner_views=banner_views+1 WHERE banner_id=6;
# Query_time: 84.614748  Lock_time: 37.130587 Rows_sent: 0  Rows_examined: 1
use db_name;
SET timestamp=1537010708;
UPDATE banners SET banner_views=banner_views+1 WHERE banner_id=60;
# Query_time: 54.288041  Lock_time: 0.000018 Rows_sent: 0  Rows_examined: 1
SET timestamp=1537010708;
UPDATE banners SET banner_views=banner_views+1 WHERE banner_id=884;
# Query_time: 104.154232  Lock_time: 34.661097 Rows_sent: 0  Rows_examined: 1
use db_name;
SET timestamp=1537010744;
UPDATE banners SET banner_views=banner_views+1 WHERE banner_id=60;
# Query_time: 107.847145  Lock_time: 38.354068 Rows_sent: 0  Rows_examined: 1
SET timestamp=1537010744;
UPDATE banners SET banner_views=banner_views+1 WHERE banner_id=6;
# Query_time: 81.974780  Lock_time: 26.446288 Rows_sent: 0 Rows_examined: 1
SET timestamp=1537010771;
UPDATE banners SET banner_views=banner_views+1 WHERE banner_id=6;
# Query_time: 102.331612  Lock_time: 46.507686 Rows_sent: 0  Rows_examined: 1
use db_name;
SET timestamp=1537010772;
UPDATE banners SET banner_views=banner_views+1 WHERE banner_id=60;
# Query_time: 81.808158  Lock_time: 36.196089 Rows_sent: 0  Rows_examined: 1
SET timestamp=1537010772;
UPDATE banners SET banner_views=banner_views+1 WHERE banner_id=7;

Я прошел mysql-tuner.pl, и почти все настройки отображаются зелеными в соответствии с рекомендациями.

Я также ОБЪЯСНЯЮ все запросы SELECT, и все они используют индексы.Я не мог объяснить ни по каким другим запросам, так как я работаю на MySQL 5.5.

Есть какие-нибудь рекомендации по моей проблеме?Заранее спасибо!Любая помощь приветствуется!

1 Ответ

0 голосов
/ 16 сентября 2018

Скорость в секунду = RPS

Предложения для вашего раздела my.cnf [mysqld]

# 20180916 12:30  by  mysqlservertuning.com

query_cache_size=0  # from 4M conserve RAM & CPU QC type=0 = OFF to start with
read_buffer_size=128K  # from 4M to reduce CPU busy & handler_read_next RPS
read_rnd_buffer_size=256K  # from 8M to reduce CPU busy & handler_read_rnd_next RPS
join_buffer_size=128K  # from 8M to conserve RAM
thread_cache_size=32  # from 4 to reduce threads_created & CPU overhead
max_heap_table_size=512M  # from 256M should be same as tmp_table_size always

Скопируйте существующий файл my.cnf для резервного копирования куда-нибудь (на всякий случай)затем

Строка даты и все 6 переменных, которые нужно скопировать в END раздела [mysqld] my.cnf для переопределения предыдущих запрошенных значений.

ОСТАНОВИТЬ / НАЧАТЬ ваш экземпляр или перезапустить ваш экземпляр.Пожалуйста, SKYPE меня, когда позволяет время.

...