При разработке проектов на небольших VPS часто возникает ситуация, когда процесс mysqld загружает процессор на 100%. Обычно в такие моменты приходится заходить по SSH, открывать консоль бд и вручную вводить SHOW FULL PROCESSLIST;, чтобы найти тяжелый запрос и завершить его через KILL. Если запросов много, делать это вручную через стандартный вывод не всегда удобно.

Это легковесный интерактивный CLI - менеджер процессов, который работает на базе асинхронного драйвера aiomysql. Он опрашивает системную таблицу information_schema.processlist и выводит текущую активность в терминал в виде таблицы, позволяя управлять потоками СУБД.

Как устроена утилита

Программа разделена на две параллельные асинхронные задачи:

  1. Фоновое чтение метаданных из базы данных с интервалом в 1.2 секунды.

  2. Неблокирующий перехват нажатий клавиш пользователя.

Для рендеринга интерфейса и автоматической очистки экрана используются стандартные ANSI-последовательности, что позволяет утилите работать плавно и без мерцания. Менеджер потребляет около 14 МБ оперативной памяти и практически не создает дополнительной нагрузки на центральный процессор, что делает его удобным для запуска на слабых серверах.

Тестирование

Для проверки работы скрипта в базу данных были внесены тестовые процессы, симулирующие длительные тяжелые запросы. Навигация по строкам осуществляется клавишами W (вверх) и S (вниз). Выбранная строка интерактивно подсвечивается инверсией цветов. При нажатии клавиши K скрипт отправляет команду на удаление потока.

Терминал
Терминал

Как это работает

Основная проблема большинства самописных скриптов мониторинга - они сами начинают нагружать СУБД, если опрашивать её слишком часто. Чтобы избежать этого, утилита не включает глобальные логи медленных запросов, а напрямую обращается к системной таблице метаданных.

Для изоляции процессов ввода-вывода и интерфейса в коде используются асинхронные задачи. Пока функция fetch_data ждет ответа от бд через await, управление передается функции listen_keyboard, которая проверяет буфер консоли Windows на наличие нажатых клавиш. Это исключает фризы и позволяет приложению мгновенно реагировать на команды пользователя.

Как протестировать локально

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

CREATE DATABASE IF NOT EXISTS app_monitoring; USE app_monitoring;

CREATE TABLE IF NOT EXISTS processlist ( ID BIGINT NOT NULL DEFAULT 0, USER VARCHAR(32) NOT NULL DEFAULT ‘’, HOST VARCHAR(64) NOT NULL DEFAULT ‘’, DB VARCHAR(64) NULL DEFAULT NULL, COMMAND VARCHAR(16) NOT NULL DEFAULT ‘’, TIME INT NOT NULL DEFAULT 0, STATE VARCHAR(64) NULL DEFAULT NULL, INFO LONGTEXT NULL DEFAULT NULL );

TRUNCATE TABLE processlist;

INSERT INTO processlist (ID, USER, HOST, DB, COMMAND, TIME, STATE, INFO) VALUES (1, ‘root’, ‘localhost’, ‘main_db’, ‘Query’, 120, ‘Sending data’, ‘SELECT FROM users JOIN orders ON users.id = orders.user_id WHERE orders.total > 5000 AND SLEEP(1000);’), (2, ‘analytics’, ‘192.168.1.45’, ‘stats’, ‘Query’, 85, ‘Executing’, ‘SELECT COUNT(), AVG(amount) FROM transactions WHERE SLEEP(1000) GROUP BY MONTH(created_at);’), (3, ‘bot_user’, ‘localhost’, ‘tg_bot’, ‘Query’, 45, ‘Updating’, ‘UPDATE users_state SET step = “await_payment” WHERE telegram_id = 987654321 AND SLEEP(1000);’);

После выполнения, запущенный скрипт автоматически подхватит эти строки, и вы сможете протестировать интерактивную навигацию с помощью клавиш W/S и симуляцию удаления зависшего потока по клавише K

Полный исходный код, а также подробная документация по настройке, установке зависимостей и запуску доступны в открытом репозитории на GitHub: здесь