Spec-Zone .ru
спецификации, руководства, описания, API
|
Этот раздел описывает, как записать контрольный плагин сервера, используя плагин в качестве примера, найденный в
plugin/audit_null
каталог исходных дистрибутивов MySQL. audit_null.c
исходный файл в том каталоге реализует простой названный плагин аудита в качестве примера NULL_AUDIT
.
В пределах сервера сменный контрольный интерфейс реализуется в sql_audit.h
и sql_audit.cc
файлы в sql
каталог исходных
дистрибутивов MySQL. Дополнительно, несколько мест в сервере изменяются, чтобы вызвать контрольный интерфейс,
когда auditable событие имеет место, так, чтобы зарегистрированные контрольные плагины могли быть уведомлены о
событии в случае необходимости. Чтобы видеть, где такие вызовы происходят, ищите вызовы функций с именами формы
mysql_audit_
. Контрольное
уведомление происходит для операций сервера, таких как они:xxx
()
Запись сообщения к общему журналу запросов (если журнал включается),
Запись сообщения к журналу ошибок
Отправка запроса заканчивается клиенту
Клиент соединяет и разъединяет события
Чтобы записать контрольный плагин, включайте следующий заголовочный файл в сменный исходный файл. Другой MySQL или общие заголовочные файлы могли бы также быть необходимы.
#include <mysql/plugin_audit.h>
plugin_audit.h
включает plugin.h
, таким образом, Вы
не должны включать последний файл явно. plugin.h
определяет MYSQL_AUDIT_PLUGIN
тип плагина сервера и структуры данных должны были объявить плагин. plugin_audit.h
определяет структуры данных, определенные, чтобы контролировать плагины.
У контрольного плагина, как любой плагин сервера MySQL, есть общий сменный дескриптор (см. Раздел
22.2.4.2.1, "Библиотека Плагина сервера и Сменные Дескрипторы"). В audit_null.c
,
общий дескриптор похож на это:
mysql_declare_plugin(audit_null){ MYSQL_AUDIT_PLUGIN, /* type */ &audit_null_descriptor, /* descriptor */ "NULL_AUDIT", /* name */ "Oracle Corp", /* author */ "Simple NULL Audit", /* description */ PLUGIN_LICENSE_GPL, audit_null_plugin_init, /* init function (when loaded) */ audit_null_plugin_deinit, /* deinit function (when unloaded) */ 0x0003, /* version */ simple_status, /* status variables */ NULL, /* system variables */ NULL, 0,}mysql_declare_plugin_end;
name
элемент (NULL_AUDIT
) указывает на имя, чтобы
использовать для ссылок на плагин в операторах такой как INSTALL PLUGIN
или UNINSTALL PLUGIN
. Это - также имя, выведенное на экран INFORMATION_SCHEMA.PLUGINS
или SHOW PLUGINS
.
Общий дескриптор также обращается к simple_status
, структура, которая представляет
несколько переменных состояния SHOW STATUS
оператор:
static struct st_mysql_show_var simple_status[]={ { "Audit_null_called", (char *) &number_of_calls, SHOW_INT }, { "Audit_null_general_log", (char *) &number_of_calls_general_log, SHOW_INT }, { "Audit_null_general_error", (char *) &number_of_calls_general_error, SHOW_INT }, { "Audit_null_general_result", (char *) &number_of_calls_general_result, SHOW_INT }, { "Audit_null_general_status", (char *) &number_of_calls_general_status, SHOW_INT }, { "Audit_null_connection_connect", (char *) &number_of_calls_connection_connect, SHOW_INT }, { "Audit_null_connection_disconnect", (char *) &number_of_calls_connection_disconnect, SHOW_INT }, { "Audit_null_connection_change_user", (char *) &number_of_calls_connection_change_user, SHOW_INT }, { 0, 0, 0}};
audit_null_plugin_init
функция инициализации обнуляет переменные состояния, когда
плагин загружается. audit_null_plugin_deinit
функция выполняет уборку с плагином,
разгружается. Во время работы плагин постепенно увеличивает первую переменную состояния для каждого уведомления,
которое это получает. Это также постепенно увеличивает другие согласно событию class и подклассу. В
действительности первая переменная является агрегатом счетов для подклассов события.
audit_null_descriptor
значение в общем дескрипторе указывает на специфичный для типа
дескриптор. Для контрольных плагинов у этого дескриптора есть следующая структура:
struct st_mysql_audit{ int interface_version; void (*release_thd)(MYSQL_THD); void (*event_notify)(MYSQL_THD, unsigned int, const void *); unsigned long class_mask[MYSQL_AUDIT_CLASS_MASK_SIZE];};
У специфичного для типа дескриптора есть эти элементы:
interface_version
: Условно, специфичные для типа
сменные дескрипторы начинаются с версии интерфейса для данного сменного типа. Проверки сервера interface_version
когда это загружает плагин, чтобы видеть, является ли
плагин совместимым с этим. Для контрольных плагинов, значения interface_version
элемент MYSQL_AUDIT_INTERFACE_VERSION
(определенный в plugin_audit.h
).
release_thd
: Функция, которую сервер вызывает, чтобы
сообщить плагину, что это отделяется от его контекста потока. Это должно быть NULL
если нет такой функции.
event_notify
: Функция, которую сервер вызывает, чтобы
уведомить плагин, что auditable событие имело место. Эта функция не должна быть NULL
;
это не имело бы смысла, потому что никакой контроль не произойдет.
class_mask
: Немного маски, которая указывает на классы
событий, для которых плагин хочет получить уведомление. Если это значение 0, сервер не передает событий
к плагину.
Сервер использует event_notify
и release_thd
функции
вместе. Их вызывают в пределах контекста определенного потока, и поток мог бы выполнить действие, которое
производит несколько уведомлений о событии. В первый раз вызовы сервера event_notify
для потока это создает привязку плагина к потоку. Плагин не может
быть удален, в то время как эта привязка существует. Когда больше событий для потока не будет иметь место,
сервер сообщает плагину об этом, вызывая release_thd
функция, и затем уничтожает
привязку. Например, когда клиент делает заявление, поток, обрабатывающий оператор, мог бы уведомить контрольные
плагины о наборе результатов, произведенном оператором и о зарегистрированном операторе. После того, как эти
уведомления происходят, сервер выпускает плагин прежде, чем поместить поток, чтобы спать, пока клиент не делает
другое заявление.
Этот проект позволяет плагину выделить ресурсы, необходимые для данного потока в первом звонке event_notify
функционируйте и выпустите их в release_thd
функция:
event_notify function: if memory is needed to service the thread allocate memory ... rest of notification processing ...release_thd function: if memory was allocated release memory ... rest of release processing ...
Это более эффективно чем выделение и выпуск памяти неоднократно в функции уведомления.
Для NULL_AUDIT
плагин аудита в качестве примера, специфичный для типа дескриптор
похож на это:
static struct st_mysql_audit audit_null_descriptor={ MYSQL_AUDIT_INTERFACE_VERSION, /* interface version */ NULL, /* release_thd function */ audit_null_notify, /* notify function */ { (unsigned long) MYSQL_AUDIT_GENERAL_CLASSMASK | MYSQL_AUDIT_CONNECTION_CLASSMASK } /* class mask */};
Вызовы сервера audit_null_notify
передать информацию о событии аудита к плагину.
Есть нет release_thd
функция.
Маска события class указывает на интерес ко всем событиям "общих"
классов и классов "соединения". plugin_audit.h
определяет символы для этих классов и их соответствующих масок class:
#define MYSQL_AUDIT_GENERAL_CLASS 0#define MYSQL_AUDIT_GENERAL_CLASSMASK (1 << MYSQL_AUDIT_GENERAL_CLASS)#define MYSQL_AUDIT_CONNECTION_CLASS 1#define MYSQL_AUDIT_CONNECTION_CLASSMASK (1 << MYSQL_AUDIT_CONNECTION_CLASS)
В специфичном для типа дескрипторе, вторых и третьих параметрах event_notify
прототип функции представляет событие class и универсальный указатель на структуру события:
void (*event_notify)(MYSQL_THD, unsigned int, const void *);
У событий в различных классах могут быть различные структуры, таким образом, функция уведомления должна использовать значение события class, чтобы определить, как интерпретировать указатель на структуру события.
Если сервер вызывает функцию уведомления с событием class MYSQL_AUDIT_GENERAL_CLASS
,
это передает структуру события как указатель на a mysql_event_general
структура:
struct mysql_event_general{ unsigned int event_subclass; int general_error_code; unsigned long general_thread_id; const char *general_user; unsigned int general_user_length; const char *general_command; unsigned int general_command_length; const char *general_query; unsigned int general_query_length; struct charset_info_st *general_charset; unsigned long long general_time; unsigned long long general_rows; MYSQL_LEX_STRING general_host; MYSQL_LEX_STRING general_sql_command; MYSQL_LEX_STRING general_external_user; MYSQL_LEX_STRING general_ip;};
Контрольные плагины могут интерпретировать mysql_event_general
элементы следующим
образом:
event_subclass
: Подкласс события, одно из следующих
значений:
#define MYSQL_AUDIT_GENERAL_LOG 0#define MYSQL_AUDIT_GENERAL_ERROR 1#define MYSQL_AUDIT_GENERAL_RESULT 2#define MYSQL_AUDIT_GENERAL_STATUS 3
general_error_code
: Код ошибки. Это - значение как
возвращенный mysql_errno()
C
API-функция; 0 не означает "ошибки."
general_thread_id
: ID потока, для которого событие
имело место.
general_user
: Текущий пользователь для события.
general_user_length
: Длина general_user
,
в байтах.
general_command
: Для общих событий журнала запросов,
типа работы. Примеры: Connect
, Query
, Shutdown
. Для событий журнала ошибок, сообщения об ошибке. Это - значение
как возвращенный mysql_error()
C
API-функция; пустая строка не означает "ошибки."
Для событий результата это пусто.
general_command_length
: Длина general_command
,
в байтах.
general_query
: SQL-оператор, который был
зарегистрирован или приводил к результату.
general_query_length
: Длина general_query
,
в байтах.
general_charset
: Информация о наборе символов для
события.
general_time
: A TIMESTAMP
значение, указывающее время как раз перед функцией уведомления,
вызвали.
general_rows
: Для общих событий журнала запросов, нуля.
Для событий журнала ошибок, номера строки, в котором произошла ошибка. Для событий результата, числа
строк в результате плюс один. Для операторов, которые не производят набора результатов, значение 0. Это
кодирование включает операторам, которые не производят набора результатов, который отличат от тех,
которые производят пустой набор результатов. Например, для a DELETE
оператор, это значение 0. Для a SELECT
, результат всегда 1 или больше, где 1 представляет пустой
набор результатов.
general_host
: Для общих событий журнала запросов,
строка, представляющая имя хоста клиента.
general_sql_command
: Для общих событий журнала
запросов, строка, которая указывает на тип выполняемого действия, такой как connect
или drop_table
.
general_external_user
: Для общих событий журнала
запросов, строка, представляющая внешнего пользователя (пустой, если ни один).
general_ip
: Для общих событий журнала запросов, строка,
представляющая клиентский IP-адрес.
general_host
, general_sql_command
, general_external_user
, и general_ip
элементы новы в
MySQL 5.7. Они MYSQL_LEX_STRING
структуры, которые соединяют строку и ее длину.
Например, если event_general
указатель на общее событие, можно получить доступ к
элементам general_host
значение следующим образом:
event_general->general_host.lengthevent_general->general_host.str
Если сервер вызывает функцию уведомления с событием class MYSQL_AUDIT_CONNECTION_CLASS
, это передает структуру события как указатель на a mysql_event_connection
структура, которая подобна и интерпретировала почти такой же
путь как mysql_event_general
структура.
NULL_AUDIT
сменная функция уведомления довольно проста. Это постепенно увеличивает
глобальный счетчик события, определяет событие class, затем смотрит на подкласс события, чтобы определить
который подкласс в противоречии с инкрементом:
static void audit_null_notify(MYSQL_THD thd __attribute__((unused)), unsigned int event_class, const void *event){ /* prone to races, oh well */ number_of_calls++; if (event_class == MYSQL_AUDIT_GENERAL_CLASS) { const struct mysql_event_general *event_general= (const struct mysql_event_general *) event; switch (event_general->event_subclass) { case MYSQL_AUDIT_GENERAL_LOG: number_of_calls_general_log++; break; case MYSQL_AUDIT_GENERAL_ERROR: number_of_calls_general_error++; break; case MYSQL_AUDIT_GENERAL_RESULT: number_of_calls_general_result++; break; case MYSQL_AUDIT_GENERAL_STATUS: number_of_calls_general_status++; break; default: break; } } else if (event_class == MYSQL_AUDIT_CONNECTION_CLASS) { const struct mysql_event_connection *event_connection= (const struct mysql_event_connection *) event; switch (event_connection->event_subclass) { case MYSQL_AUDIT_CONNECTION_CONNECT: number_of_calls_connection_connect++; break; case MYSQL_AUDIT_CONNECTION_DISCONNECT: number_of_calls_connection_disconnect++; break; case MYSQL_AUDIT_CONNECTION_CHANGE_USER: number_of_calls_connection_change_user++; break; default: break; } }}
Чтобы скомпилировать и установить сменный объектный файл библиотеки, используйте инструкции в Разделе
22.2.4.3, "Компилируя и Устанавливая Сменные Библиотеки". Чтобы использовать файл библиотеки, это
должно быть установлено в сменном каталоге (каталог, названный plugin_dir
системная переменная). Для AUDIT_NULL
плагин, это компилируется и устанавливается, когда Вы создаете MySQL из источника. Это также включается в
двоичные дистрибутивы. Процесс сборки производит совместно используемую библиотеку объектов с именем adt_null.so
(суффикс мог бы отличаться в зависимости от Вашей платформы).
Чтобы зарегистрировать плагин во времени выполнения, используйте этот оператор (измените суффикс по мере необходимости):
mysql> INSTALL PLUGIN NULL_AUDIT SONAME
'adt_null.so';
Для дополнительной информации о сменной загрузке см. Раздел 5.1.8.1, "Устанавливая и Удаляя Плагины".
Чтобы проверить сменную установку, исследуйте INFORMATION_SCHEMA.PLUGINS
таблица или использование SHOW PLUGINS
оператор.
В то время как контрольный плагин устанавливается, он представляет переменные состояния, которые указывают на события, для которых вызвали плагин:
mysql> SHOW STATUS LIKE
'Audit_null%';
+-----------------------------------+-------+| Variable_name | Value |+-----------------------------------+-------+| Audit_null_called | 1388 || Audit_null_connection_change_user | 0 || Audit_null_connection_connect | 22 || Audit_null_connection_disconnect | 21 || Audit_null_general_error | 1 || Audit_null_general_log | 513 || Audit_null_general_result | 415 || Audit_null_general_status | 416 |+-----------------------------------+-------+
Audit_null_called
количества все события, и другие переменные считают экземпляры
подклассов события. Например, предыдущее SHOW
STATUS
оператор заставляет сервер отправлять результат клиенту и писать сообщение в общий журнал
запросов, если тот журнал включается. Таким образом клиент, который делает заявление неоднократно, вызывает
Audit_null_called
и Audit_null_general_result
быть
постепенно увеличенным каждый раз, и Audit_null_general_log
быть постепенно
увеличенным, если журнал включается.
Чтобы отключить плагин после тестирования этого, используйте этот оператор, чтобы разгрузить это:
mysql> UNINSTALL PLUGIN
NULL_AUDIT;