编写审核插件
本节介绍如何使用plugin/audit_null
MySQL源代码分发目录中的示例插件编写服务器端审核插件。该目录中的audit_null.c
和audit_null_variables.h
源文件实现了名为的审核插件NULL_AUDIT
。
注意使用审核插件API的插件的其他示例是查询重写插件(请参见“MySQL服务器重写器查询重写插件”)和版本令牌插件(请参见“版本令牌”)。
在服务器内部,可插入审核接口在MySQL源代码分发目录的sql_audit.h
和sql_audit.cc
文件中实现sql
。此外,发生可审核事件时,服务器中的多个位置会调用审核接口,以便在必要时可以向注册的审核插件通知该事件。要参见发生此类调用的位置,请在服务器源文件中搜索形式为的函数调用。发生以下服务器操作的审核通知:mysql_audit_xxx()
- 客户端连接和断开事件
- 将消息写入常规查询日志(如果已启用日志)
- 将消息写入错误日志
- 发送查询结果给客户端
要编写审核插件,请在插件源文件中包含以下头文件。根据插件的功能和要求,可能还需要其他MySQL或常规头文件。
#include <mysql/plugin_audit.h>
plugin_audit.h
include plugin.h
,因此您无需显式包括后者。plugin.h
定义MYSQL_AUDIT_PLUGIN
服务器插件类型和声明插件所需的数据结构。plugin_audit.h
定义特定于审核插件的数据结构。
- 审核插件通用描述符
- 审核插件类型专用描述符
- 审核插件通知功能
- 审核插件错误处理
- 审核插件使用情况
审核插件通用描述符
审核插件与任何MySQL服务器插件一样,具有通用的插件描述符(请参见“服务器插件库和插件描述符”)和特定于类型的插件描述符。在中audit_null.c
,的一般描述符audit_null
如下所示:
mysql_declare_plugin(audit_null) { MYSQL_AUDIT_PLUGIN, /* type */ &audit_null_descriptor, /* descriptor */ "NULL_AUDIT", /* name */ "Oracle Corporation", /* 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 */ system_variables, /* system variables */ NULL, 0, } mysql_declare_plugin_end;
第一个成员MYSQL_AUDIT_PLUGIN
标识此插件为审核插件。
audit_null_descriptor
指向特定于类型的插件描述符,稍后将进行描述。
所述name
构件(NULL_AUDIT
)指示要用于如在语句中的插件的引用名称INSTALL PLUGIN
或UNINSTALL PLUGIN
。这也是由INFORMATION_SCHEMA.PLUGINS
或显示的名称SHOW PLUGINS
。
该audit_null_plugin_init
被加载插件时初始化函数执行插件初始化。audit_null_plugin_deinit
插件卸载后,该函数执行清理。
通用插件描述符还引用simple_status
和system_variables
,它们公开了一些状态和系统变量。启用插件后,可以使用SHOW
语句(SHOW STATUS
,SHOW VARIABLES
)或适当的Performance Schema表检查这些变量。
该simple_status
结构声明了几个状态变量,其形式为。为收到的每个通知增加状态变量。其他状态变量则更具体,仅针对特定事件的通知将其递增。Audit_null_xxx
NULL_AUDIT
Audit_null_called
NULL_AUDIT
system_variables
是系统变量元素的数组,每个元素都是使用宏定义的。这些系统变量的名称为形式。这些变量可用于在运行时与插件通信。MYSQL_THDVAR_xxx
null_audit_xxx
审核插件类型专用描述符
audit_null_descriptor
常规插件描述符中的值指向特定于类型的插件描述符。对于审核插件,此描述符具有以下结构(在中定义plugin_audit.h
):
struct st_mysql_audit {int interface_version;void (*release_thd)(MYSQL_THD);int (*event_notify)(MYSQL_THD, mysql_event_class_t,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
:服务器调用此功能以通知插件已发生可审核的事件。这个功能不应该NULL
;这是没有意义的,因为不会进行审核。class_mask
:MYSQL_AUDIT_CLASS_MASK_SIZE
元素数组。每个元素为给定的事件类指定一个位掩码,以指示插件要为其通知的子类。(这是插件“订阅”感兴趣事件的方式。)元素应为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_ALL, (unsigned long ) MYSQL_AUDIT_CONNECTION_ALL, (unsigned long ) MYSQL_AUDIT_PARSE_ALL, (unsigned long ) MYSQL_AUDIT_AUTHORIZATION_ALL, (unsigned long ) MYSQL_AUDIT_TABLE_ACCESS_ALL, (unsigned long ) MYSQL_AUDIT_GLOBAL_VARIABLE_ALL, (unsigned long ) MYSQL_AUDIT_SERVER_STARTUP_ALL, (unsigned long ) MYSQL_AUDIT_SERVER_SHUTDOWN_ALL, (unsigned long ) MYSQL_AUDIT_COMMAND_ALL, (unsigned long ) MYSQL_AUDIT_QUERY_ALL, (unsigned long ) MYSQL_AUDIT_STORED_PROGRAM_ALL } };
服务器调用audit_null_notify()
以将审核事件信息传递给插件。插件没有release_thd
功能。
所述class_mask
构件是一个数组指示哪些事件类插件订阅了。如图所示,数组内容订阅了所有可用事件类的所有子类。要忽略给定事件类的所有通知,请将相应的class_mask
元素指定为0。
的数目class_mask
的元素对应于事件类,其中的每一个列在数量mysql_event_class_t
枚举所定义plugin_audit.h
:
typedef enum { MYSQL_AUDIT_GENERAL_CLASS = 0, MYSQL_AUDIT_CONNECTION_CLASS = 1, MYSQL_AUDIT_PARSE_CLASS = 2, MYSQL_AUDIT_AUTHORIZATION_CLASS = 3, MYSQL_AUDIT_TABLE_ACCESS_CLASS = 4, MYSQL_AUDIT_GLOBAL_VARIABLE_CLASS = 5, MYSQL_AUDIT_SERVER_STARTUP_CLASS = 6, MYSQL_AUDIT_SERVER_SHUTDOWN_CLASS = 7, MYSQL_AUDIT_COMMAND_CLASS = 8, MYSQL_AUDIT_QUERY_CLASS = 9, MYSQL_AUDIT_STORED_PROGRAM_CLASS = 10, /* This item must be last in the list. */ MYSQL_AUDIT_CLASS_MASK_SIZE } mysql_event_class_t;
对于任何给定的事件类,都plugin_audit.h
为各个事件子类定义位掩码符号,以及作为xxx_ALL
所有子类位掩码的并集的符号。例如,对于MYSQL_AUDIT_CONNECTION_CLASS
(涵盖connect和disconnect事件的类),plugin_audit.h
定义以下符号:
typedef enum { /** occurs after authentication phase is completed. */ MYSQL_AUDIT_CONNECTION_CONNECT = 1 << 0, /** occurs after connection is terminated. */ MYSQL_AUDIT_CONNECTION_DISCONNECT = 1 << 1, /** occurs after COM_CHANGE_USER RPC is completed. */ MYSQL_AUDIT_CONNECTION_CHANGE_USER = 1 << 2, /** occurs before authentication. */ MYSQL_AUDIT_CONNECTION_PRE_AUTHENTICATE = 1 << 3 } mysql_event_connection_subclass_t; #define MYSQL_AUDIT_CONNECTION_ALL (MYSQL_AUDIT_CONNECTION_CONNECT | \ MYSQL_AUDIT_CONNECTION_DISCONNECT | \ MYSQL_AUDIT_CONNECTION_CHANGE_USER | \ MYSQL_AUDIT_CONNECTION_PRE_AUTHENTICATE)
要订阅连接事件类的所有子类(如NULL_AUDIT
插件一样),插件将MYSQL_AUDIT_CONNECTION_ALL
在相应的class_mask
元素中指定(class_mask[1]
在这种情况下)。要仅订阅某些子类,插件会将class_mask
元素设置为感兴趣的子类的并集。例如,仅订阅connect和change-user子类,插件将设置class_mask[1]
为以下值:
MYSQL_AUDIT_CONNECTION_CONNECT | MYSQL_AUDIT_CONNECTION_CHANGE_USER
审核插件通知功能
审核插件的大部分工作都在通知功能(event_notify
特定于类型的插件描述符的成员)中进行。服务器为每个可审核事件调用此函数。审核插件通知功能具有以下原型:
int (*event_notify)(MYSQL_THD, mysql_event_class_t,const void *);
event_notify
函数原型的第二个和第三个参数表示事件类和指向事件结构的通用指针。(不同类中的事件具有不同的结构。通知函数可以使用事件类的值来确定采用哪种事件结构。)该函数处理事件并返回一个状态,指示服务器是应继续处理该事件还是终止该事件。
对于NULL_AUDIT
,通知功能为audit_null_notify()
。此函数增加一个全局事件计数器(插件将其公开为Audit_null_called
状态值),然后检查事件类以确定如何处理事件结构:
static int audit_null_notify(MYSQL_THD thd __attribute__((unused)), mysql_event_class_t event_class,const void *event) { ... number_of_calls++;if (event_class == MYSQL_AUDIT_GENERAL_CLASS) {const struct mysql_event_general *event_general= (const struct mysql_event_general *)event; ... }else if (event_class == MYSQL_AUDIT_CONNECTION_CLASS) {const struct mysql_event_connection *event_connection= (const struct mysql_event_connection *) event; ... }else if (event_class == MYSQL_AUDIT_PARSE_CLASS) {const struct mysql_event_parse *event_parse = (const struct mysql_event_parse *)event; ... } ... }
通知函数event
根据的值解释参数event_class
。该event
参数是指向事件记录的通用指针,事件记录的结构因事件类而异。(该plugin_audit.h
文件包含定义每个事件类内容的结构。)对于每个类,audit_null_notify()
将事件强制转换为适当的类特定结构,然后检查其子类以确定要递增的子类计数器。例如,用于处理connection-event类中的事件的代码如下所示:
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 ;case MYSQL_AUDIT_CONNECTION_PRE_AUTHENTICATE: number_of_calls_connection_pre_authenticate++;break ;default :break ; } }
注意一般事件类(
MYSQL_AUDIT_GENERAL_CLASS
)已弃用,并将在以后的MySQL版本中删除。为了减少插件开销,最好只订阅感兴趣的特定事件类。
对于某些事件类,该NULL_AUDIT
插件除了增加计数器外,还执行其他处理。无论如何,当通知功能完成事件处理后,它应返回一个状态,指示服务器是应继续处理该事件还是终止该事件。
审核插件错误处理
审核插件通知功能可以通过两种方式报告当前事件的状态值:
- 使用通知函数的返回值。在这种情况下,如果服务器应继续处理事件,则该函数将返回零;如果服务器应终止该事件,则该函数将返回非零。
my_message()
从通知功能返回之前,请调用该功能以设置错误状态。在这种情况下,通知函数的返回值将被忽略,服务器将中止事件并以错误终止事件处理。这些my_message()
参数指示要报告的错误及其消息。例如:my_message(ER_AUDIT_API_ABORT, "This is my error message.", MYF(0));
某些事件无法中止。不考虑非零返回值,并且
my_message()
错误调用必须遵循is_error()
检查。例如:if (!thd->get_stmt_da()->is_error()) { my_message(ER_AUDIT_API_ABORT, "This is my error message.", MYF(0)); }
这些事件不能中止:
MYSQL_AUDIT_CONNECTION_DISCONNECT
:服务器无法阻止客户端断开连接。MYSQL_AUDIT_COMMAND_END
:此事件提供已完成执行的命令的状态,因此无意终止它。
如果审核插件针对不可确定的事件返回非零状态,则服务器将忽略状态并继续处理该事件。如果审核插件使用该my_message()
函数终止不可确定的事件,则也是如此。
审核插件使用情况
要编译和安装插件库文件,请使用“编译和安装插件库”中的说明。要使该库文件可供使用,请将其安装在插件目录(由plugin_dir
系统变量命名的目录)中。对于该NULL_AUDIT
插件,当您从源代码构建MySQL时,将对其进行编译和安装。它也包含在二进制发行版中。构建过程将生成一个共享对象库,其名称为adt_null.so
(.so
后缀可能因平台而异)。
要在运行时注册插件,请使用以下语句(.so
根据需要调整平台的后缀):
INSTALL PLUGIN NULL_AUDITSONAME 'adt_null.so';
有关插件加载的更多信息,请参见“MySQL服务器插件”。
要验证插件安装,请检查INFORMATION_SCHEMA.PLUGINS
表或使用以下SHOW PLUGINS
语句。请参见“获取服务器插件信息”。
虽然NULL_AUDIT
安装了审计插件,它暴露状态变量将指示该插件被称为事件:
mysql>SHOW STATUS LIKE 'Audit_null%'; +---------------------------------------- +-------- + | Variable_name | Value | +---------------------------------------- +-------- + | Audit_null_authorization_column | 0 | | Audit_null_authorization_db | 0 | | Audit_null_authorization_procedure | 0 | | Audit_null_authorization_proxy | 0 | | Audit_null_authorization_table | 0 | | Audit_null_authorization_user | 0 | | Audit_null_called | 185547 | | Audit_null_command_end | 20999 | | Audit_null_command_start | 21001 | | Audit_null_connection_change_user | 0 | | Audit_null_connection_connect | 5823 | | Audit_null_connection_disconnect | 5818 | | Audit_null_connection_pre_authenticate | 5823 | | Audit_null_general_error | 1 | | Audit_null_general_log | 26559 | | Audit_null_general_result | 19922 | | Audit_null_general_status | 21000 | | Audit_null_global_variable_get | 0 | | Audit_null_global_variable_set | 0 | | Audit_null_message_internal | 0 | | Audit_null_message_user | 0 | | Audit_null_parse_postparse | 14648 | | Audit_null_parse_preparse | 14648 | | Audit_null_query_nested_start | 6 | | Audit_null_query_nested_status_end | 6 | | Audit_null_query_start | 14648 | | Audit_null_query_status_end | 14647 | | Audit_null_server_shutdown | 0 | | Audit_null_server_startup | 1 | | Audit_null_table_access_delete | 104 | | Audit_null_table_access_insert | 2839 | | Audit_null_table_access_read | 97842 | | Audit_null_table_access_update | 278 | +---------------------------------------- +-------- +
Audit_null_called
计算所有事件,其他变量计算特定事件子类的实例。例如,SHOW STATUS
如果启用了该语句,则上述语句使服务器将结果发送给客户端,并向通用查询日志中写入一条消息。因此,客户端发出的声明重复导致Audit_null_called
,Audit_null_general_result
以及Audit_null_general_log
将每次递增。无论是否启用该日志,都会发生通知。
状态变量值是全局的,并且在所有会话中汇总。没有用于单个会话的计数器。
NULL_AUDIT
公开几个可在运行时与插件通信的系统变量:
mysql>SHOW VARIABLES LIKE 'null_audit%'; +--------------------------------------------------- +------- + | Variable_name | Value | +--------------------------------------------------- +------- + | null_audit_abort_message | | | null_audit_abort_value | 1 | | null_audit_event_order_check | | | null_audit_event_order_check_consume_ignore_count | 0 | | null_audit_event_order_check_exact | 1 | | null_audit_event_order_started | 0 | | null_audit_event_record | | | null_audit_event_record_def | | +--------------------------------------------------- +------- +
该NULL_AUDIT
系统变量有下列含义:
null_audit_abort_message
:事件中止时使用的自定义错误消息。null_audit_abort_value
:事件中止时使用的自定义错误代码。null_audit_event_order_check
:事件匹配之前,预期的事件顺序。事件匹配后,匹配结果。null_audit_event_order_check_consume_ignore_count
:事件匹配不应消耗匹配事件的次数。null_audit_event_order_check_exact
:事件匹配是否必须精确。禁用此变量将启用跳过事件null_audit_event_order_check
顺序匹配期间未列出的事件。在指定的事件中,它们仍必须按照给定的顺序进行匹配。null_audit_event_order_started
:供内部使用。null_audit_event_record
:发生事件记录后记录的事件。null_audit_event_record_def
:记录事件时要匹配的开始和结束事件的名称,以分号分隔。必须在每个记录事件的语句之前设置该值。
为了演示这些系统变量的用法,假设db1.t1
存在一个表,其创建如下:
CREATE DATABASE db1;CREATE TABLE db1.t1 (a VARCHAR(255));
为了进行测试,可以记录通过插件传递的事件。要开始记录,请在null_audit_event_record_def
变量中指定开始和结束事件。例如:
SET @@null_audit_event_record_def = 'MYSQL_AUDIT_COMMAND_START;MYSQL_AUDIT_COMMAND_END';
在发生与那些开始和结束事件匹配的语句之后,null_audit_event_record
系统变量将包含结果事件序列。例如,在记录SELECT 1
语句的事件之后,null_audit_event_record
是一个字符串,其值包含一组事件字符串:
MYSQL_AUDIT_COMMAND_START;command_id="3"; MYSQL_AUDIT_PARSE_PREPARSE;; MYSQL_AUDIT_PARSE_POSTPARSE;; MYSQL_AUDIT_GENERAL_LOG;; MYSQL_AUDIT_QUERY_START;sql_command_id="0"; MYSQL_AUDIT_QUERY_STATUS_END;sql_command_id="0"; MYSQL_AUDIT_GENERAL_RESULT;; MYSQL_AUDIT_GENERAL_STATUS;; MYSQL_AUDIT_COMMAND_END;command_id="3";
记录事件的INSERT INTO db1.t1 VALUES('some data')
语句后,null_audit_event_record
具有以下值:
MYSQL_AUDIT_COMMAND_START;command_id="3"; MYSQL_AUDIT_PARSE_PREPARSE;; MYSQL_AUDIT_PARSE_POSTPARSE;; MYSQL_AUDIT_GENERAL_LOG;; MYSQL_AUDIT_QUERY_START;sql_command_id="5"; MYSQL_AUDIT_TABLE_ACCESS_INSERT;db="db1" table="t1"; MYSQL_AUDIT_QUERY_STATUS_END;sql_command_id="5"; MYSQL_AUDIT_GENERAL_RESULT;; MYSQL_AUDIT_GENERAL_STATUS;; MYSQL_AUDIT_COMMAND_END;command_id="3";
每个事件字符串都有这种格式,用分号分隔字符串部分:
event_name;event_data;command
事件字符串包含以下部分:
event_name
:事件名称(以开头的符号MYSQL_AUDIT_
)。event_data
:为空,或如稍后所述,与事件相关的数据。command
:为空,或如稍后所述,在事件匹配时执行的命令。
注意该
NULL_AUDIT
插件的局限性在于事件记录仅适用于单个会话。在给定会话中记录事件后,后续会话中的事件记录将产生null_audit_event_record
值NULL
。要再次记录事件,必须重新启动插件。
要检查审核API调用的顺序,请将null_audit_event_order_check
变量设置为特定操作的预期事件顺序,列出一个或多个事件字符串,每个事件字符串内部包含两个分号,其他分号分隔相邻的事件字符串:
event_name;event_data;command [;event_name;event_data;command] ...
例如:
SET @@null_audit_event_order_check = 'MYSQL_AUDIT_CONNECTION_PRE_AUTHENTICATE;;;' 'MYSQL_AUDIT_GENERAL_LOG;;;' 'MYSQL_AUDIT_CONNECTION_CONNECT;;';
为了提高可读性,该语句利用了SQL语法,该语法将相邻的字符串连接为单个字符串。
将null_audit_event_order_check
变量设置为事件字符串列表之后,下一个匹配操作将变量值替换为指示操作结果的值:
- 如果成功匹配了预期的事件顺序,则结果
null_audit_event_order_check
值为EVENT-ORDER-OK
。 - 如果
null_audit_event_order_check
指定的值中止匹配的事件(如稍后所述),则结果null_audit_event_order_check
值为EVENT-ORDER-ABORT
。 - 如果预期事件顺序因意外数据而失败,则结果
null_audit_event_order_check
值为EVENT-ORDER-INVALID-DATA
。例如,如果将事件指定为预期影响表t1
但实际受影响,则会发生这种情况t2
。
将null_audit_event_order_check
事件分配给要匹配的事件列表时,应使用event_data
事件字符串的非空部分指定一些事件。下表显示了event_data
这些事件的格式。如果事件使用多个数据值,则必须按照显示的顺序指定它们。可替代地,可以指定一个event_data
值<IGNORE>
来忽略事件数据的内容。在这种情况下,事件是否具有数据并不重要。
适用事件 | 事件数据格式 |
---|---|
| command_box-sizing:inherit;margin:0px;padding:0px;border:0px;outline:0px;font-size:13.5432px;vertical-align:baseline;background:transparent;">id_value" |
| box-sizing:inherit;margin:0px;padding:0px;border:0px;outline:0px;font-size:13.5432px;vertical-align:baseline;background:transparent;">var_value" value="var_value" |
| sql_command_box-sizing:inherit;margin:0px;padding:0px;border:0px;outline:0px;font-size:13.5432px;vertical-align:baseline;background:transparent;">id_value" |
| db="db_name" table="table_name" |
在该null_audit_event_order_check
值中,通过ABORT_RET
在command
事件字符串的一部分中指定,可以中止对指定事件的审核API调用。(假定该事件是可以中止的事件。那些先前无法描述的事件。)例如,如前所示,这是插入以下内容的预期事件顺序t1
:
MYSQL_AUDIT_COMMAND_START;command_id="3"; MYSQL_AUDIT_PARSE_PREPARSE;; MYSQL_AUDIT_PARSE_POSTPARSE;; MYSQL_AUDIT_GENERAL_LOG;; MYSQL_AUDIT_QUERY_START;sql_command_id="5"; MYSQL_AUDIT_TABLE_ACCESS_INSERT;db="db1" table="t1"; MYSQL_AUDIT_QUERY_STATUS_END;sql_command_id="5"; MYSQL_AUDIT_GENERAL_RESULT;; MYSQL_AUDIT_GENERAL_STATUS;; MYSQL_AUDIT_COMMAND_END;command_id="3";
要INSERT
在MYSQL_AUDIT_QUERY_STATUS_END
事件发生时中止语句执行,请这样设置null_audit_event_order_check
(切记在相邻事件字符串之间添加分号分隔符):
SET @@null_audit_event_order_check = 'MYSQL_AUDIT_COMMAND_START;command_id="3";;' 'MYSQL_AUDIT_PARSE_PREPARSE;;;' 'MYSQL_AUDIT_PARSE_POSTPARSE;;;' 'MYSQL_AUDIT_GENERAL_LOG;;;' 'MYSQL_AUDIT_QUERY_START;sql_command_id="5";;' 'MYSQL_AUDIT_TABLE_ACCESS_INSERT;db="db1" table="t1";;' 'MYSQL_AUDIT_QUERY_STATUS_END;sql_command_id="5";ABORT_RET';
不必列出预期在包含command
值的事件字符串之后发生的事件ABORT_RET
。
审计插件与前面的序列匹配后,它将中止事件处理并将错误消息发送给客户端。它还设置null_audit_event_order_check
为EVENT-ORDER-ABORT
:
mysql> INSERT INTO db1.t1 VALUES ('some data'); ERROR 3164 (HY000): Aborted by Audit API ('MYSQL_AUDIT_QUERY_STATUS_END';1). mysql> SELECT @@null_audit_event_order_check; +--------------------------------+ | @@null_audit_event_order_check | +--------------------------------+ | EVENT-ORDER-ABORT | +--------------------------------+
从审核API通知例程返回非零值是中止事件执行的标准方法。通过将null_audit_abort_value
变量设置为通知例程应返回的值,也可以指定自定义错误代码:
SET @@null_audit_abort_value = 123;
中止序列会产生带有自定义错误代码的标准消息。假设您将这样的审核日志系统变量设置为在匹配SELECT 1
语句发生的事件时中止:
SET @@null_audit_abort_value = 123;SET @@null_audit_event_order_check = 'MYSQL_AUDIT_COMMAND_START;command_id="3";;' 'MYSQL_AUDIT_PARSE_PREPARSE;;;' 'MYSQL_AUDIT_PARSE_POSTPARSE;;;' 'MYSQL_AUDIT_GENERAL_LOG;;;' 'MYSQL_AUDIT_QUERY_START;sql_command_id="0";ABORT_RET';
然后SELECT 1
在包含自定义错误代码的错误消息中执行结果:
mysql> SELECT 1; ERROR 3164 (HY000): Aborted by Audit API ('MYSQL_AUDIT_QUERY_START';123). mysql> SELECT @@null_audit_event_order_check; +--------------------------------+ | @@null_audit_event_order_check | +--------------------------------+ | EVENT-ORDER-ABORT | +--------------------------------+
也可以通过设置null_audit_abort_message
变量指定的自定义消息中止事件。假设您这样设置审核日志系统变量:
SET @@null_audit_abort_message = 'Custom error text.';SET @@null_audit_event_order_check = 'MYSQL_AUDIT_COMMAND_START;command_id="3";;' 'MYSQL_AUDIT_PARSE_PREPARSE;;;' 'MYSQL_AUDIT_PARSE_POSTPARSE;;;' 'MYSQL_AUDIT_GENERAL_LOG;;;' 'MYSQL_AUDIT_QUERY_START;sql_command_id="0";ABORT_RET';
然后中止序列会导致以下错误消息:
mysql> SELECT 1; ERROR 3164 (HY000): Custom error text. mysql> SELECT @@null_audit_event_order_check; +--------------------------------+ | @@null_audit_event_order_check | +--------------------------------+ | EVENT-ORDER-ABORT | +--------------------------------+
要NULL_AUDIT
在测试插件后禁用它,请使用以下语句将其卸载:
UNINSTALL PLUGIN NULL_AUDIT;