Spec-Zone .ru
спецификации, руководства, описания, API

22.2.4.8. Запись Контрольных Плагинов

Этот раздел описывает, как записать контрольный плагин сервера, используя плагин в качестве примера, найденный в 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];};

У специфичного для типа дескриптора есть эти элементы:

Сервер использует 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 элементы следующим образом:

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;