SHOW PROCESSLIST показує всі з'єднання з сервером і що кожне робить зараз:
SHOW FULL PROCESSLIST;
| Колонка | Значення |
|---|---|
Id |
ідентифікатор з'єднання (для KILL) |
User, Host, db |
хто й звідки |
Command |
Query - виконує запит, Sleep - чекає на наступний |
Time |
скільки секунд у поточному стані |
State |
що саме робить: Sending data, Waiting for table metadata lock, Creating sort index... |
Info |
текст запиту (FULL - без обрізання до 100 символів) |
Без привілею PROCESS користувач бачить лише власні з'єднання.
Зручніше фільтрувати через таблиці:
SELECT id, user, host, time, state, LEFT(info, 120) AS query
FROM performance_schema.processlist
WHERE command <> 'Sleep'
ORDER BY time DESC;
-- з додатковою інформацією про транзакції й блокування
SELECT * FROM sys.session WHERE command <> 'Sleep' ORDER BY time DESC;
Зупинити запит:
KILL QUERY 12345; -- перервати лише поточний запит, з'єднання лишається
KILL 12345; -- закрити з'єднання повністю
Що варто знати про KILL:
- відкіт може тривати довго. Якщо вбити
UPDATE, що змінював рядки 20 хвилин, InnoDB відкочуватиме зміни приблизно стільки ж. СтанKilledу процес-листі - це відкіт, і повторнийKILLйого не прискорить. Перезапуск сервера теж не допоможе: відкіт продовжиться після старту; - з'єднання в стані
Sleepз великимTime- це не завислі запити, а простоюючі з'єднання (пул, постійні з'єднання). Небезпечні вони лише якщо тримають відкриту транзакцію - це видно вinformation_schema.innodb_trx; - убитий запит застосунок отримає як помилку - Laravel-джоба впаде і, можливо, буде повторена.
Запобіжники, щоб не доводилося вбивати вручну:
max_execution_time(мілісекунди) - ліміт часу дляSELECT, глобально чи на сесію, або підказкою/*+ MAX_EXECUTION_TIME(5000) */в конкретному запиті;wait_timeout- закривати неактивні з'єднання;- тайм-аути в застосунку й важкі звіти на репліці.
Типова картина аварії: десятки запитів у стані Waiting for table metadata lock - шукати не їх, а довгу транзакцію чи ALTER TABLE, що стоїть у черзі першим.