Отслеживание подключений к MySQL
В MySQL нет встроенных средств для отслеживания подключений, однако его легко реализовать самостоятельно с использованием опции init_connect
и функций NOW()
, CURRENT_USER()
, CONNECTION_ID()
.
Настройка
Прежде всего создадим базу данных и таблицу, в которой будем отслеживать подключения:
CREATE DATABASE admin;
USE admin;
CREATE TABLE connections (
session_user VARCHAR(50) NOT NULL,
user_grants VARCHAR(50) NOT NULL,
connect_time DATETIME NOT NULL,
PRIMARY KEY (session_user)
);
Теперь предоставим всем пользователям права на вставку записей в эту таблицу, например, с помощью следующей команды:
$ mysql mysql -BNe "SELECT CONCAT('GRANT SELECT, INSERT, UPDATE ON admin.connections TO \'', user, '\'@\'', host, '\';') FROM user WHERE user NOT IN ('root', 'mysql.session', 'mysql.sys');" | mysql
$ mysqladmin flush-privileges
Если на сервере включена опция read_only
, то вставить данные в таблицу не получится, несмотря на наличие соответствующих прав. Поэтому если она включена, её нужно отключить:
SET GLOBAL read_only = OFF;
Теперь можно выставить в опции init_connect
запрос, который будет вставлять в эту таблицу информацию об установленных подключениях:
SET GLOBAL init_connect = "INSERT INTO admin.connections (session_user, user_grants, connect_time) VALUES (SESSION_USER(), CURRENT_USER(), NOW()) ON DUPLICATE KEY UPDATE user_grants = CURRENT_USER(), connect_time = NOW();";
Для того, чтобы сделанные настройки не терялись при перезагрузке, их нужно внести в файл конфигурации:
read_only = OFF
init_connect = INSERT INTO admin.connections (session_user, user_grants, connect_time) VALUES (SESSION_USER(), CURRENT_USER(), NOW()) ON DUPLICATE KEY UPDATE user_grants = CURRENT_USER(), connect_time = NOW();
Отмена настроек
Если отслеживать подключения более не требуется, то вернуть всё к начальному состоянию можно в обратном порядке следующим образом:
Удаляем из файла конфигурации опцию init_connect
и включаем опцию read_only
, если ранее она была включена.
Меняем настройки работающего сервера:
SET GLOBAL init_connect = '';
SET GLOBAL read_only = ON;
Отнимаем у пользователей права доступа к таблице connections
в базе данных admin
:
$ mysql mysql -BNe "SELECT CONCAT('REVOKE SELECT, INSERT, UPDATE ON admin.connections FROM \'', user, '\'@\'', host, '\';') FROM user WHERE user NOT IN ('root', 'mysql.session', 'mysql.sys');" | mysql
$ mysqladmin flush-privileges
Удаляем базу данных вместе с таблицей:
DROP DATABASE admin;