过滤器定义是JSON
值。有关
JSON在 MySQL 中使用数据的信息,请参阅
第 11.5 节,“JSON 数据类型”。
过滤器定义具有这种形式,其中
actions指示过滤是如何发生的:
{ "filter": actions }以下讨论描述了过滤器定义中允许的构造。
要显式启用或禁用所有事件的日志记录,请使用
log过滤器中的一个项目:
{
"filter": { "log": true }
}
该log值可以是
true或false。
前面的过滤器启用所有事件的日志记录。它相当于:
{
"filter": { }
}
记录行为取决于log值以及是否class指定
了event项目:
如果指定,则使用
log其给定值。如果没有
log指定,则记录是true如果没有指定class或event项目,false否则(在这种情况下,class或event可以包括他们自己的log项目)。
要记录特定类的事件,请使用
class过滤器中的一个项目,其
name字段表示要记录的类的名称:
{
"filter": {
"class": { "name": "connection" }
}
}
该name值可以是
connection、general或
table_access以分别记录连接、一般或表访问事件。
前面的过滤器启用
connection类中事件的日志记录。它等效于以下带有log显式项的过滤器:
{
"filter": {
"log": false,
"class": { "log": true,
"name": "connection" }
}
}
要启用多个类的日志记录,请将
class值定义为
JSON命名类的数组元素:
{
"filter": {
"class": [
{ "name": "connection" },
{ "name": "general" },
{ "name": "table_access" }
]
}
}
当给定项目的多个实例出现在过滤器定义中的同一级别时,项目值可以组合成数组值中该项目的单个实例。前面的定义可以这样写:
{
"filter": {
"class": [
{ "name": [ "connection", "general", "table_access" ] }
]
}
}
要选择特定的事件子类,请使用
event包含
name命名子类的项目的项目。项目选择的事件的默认操作
event是记录它们。例如,此过滤器启用命名事件子类的日志记录:
{
"filter": {
"class": [
{
"name": "connection",
"event": [
{ "name": "connect" },
{ "name": "disconnect" }
]
},
{ "name": "general" },
{
"name": "table_access",
"event": [
{ "name": "insert" },
{ "name": "delete" },
{ "name": "update" }
]
}
]
}
}
该event项目还可以包含显式
log项目以指示是否记录符合条件的事件。此项event选择多个事件并明确指示它们的日志记录行为:
"event": [
{ "name": "read", "log": false },
{ "name": "insert", "log": true },
{ "name": "delete", "log": true },
{ "name": "update", "log": true }
]
从 MySQL 5.7.20 开始,该event项目还可以指示是否阻止符合条件的事件,如果它包含一个
abort项目。有关详细信息,请参阅
阻止执行特定事件。
表 6.26 “事件类和子类组合” 描述了每个事件类允许的子类值。
表 6.26 事件类和子类组合
| 事件类 | 事件子类 | 描述 |
|---|---|---|
connection |
connect |
连接启动(成功或不成功) |
connection |
change_user |
在会话期间使用不同的用户名/密码重新进行用户身份验证 |
connection |
disconnect |
连接终止 |
general |
status |
一般操作信息 |
table_access |
read |
读表语句,例如SELECTor
INSERT
INTO ... SELECT |
table_access |
delete |
表删除语句,例如DELETE
orTRUNCATE TABLE |
table_access |
insert |
表插入语句,例如INSERT
orREPLACE |
table_access |
update |
表更新语句,如UPDATE |
表 6.27,“每个事件类和子类组合的记录和中止特征”描述了每个事件子类是否可以记录或中止。
表 6.27 每个事件类和子类组合的日志和中止特征
| 事件类 | 事件子类 | 可以登录 | 可以中止 |
|---|---|---|---|
connection |
connect |
是的 | 不 |
connection |
change_user |
是的 | 不 |
connection |
disconnect |
是的 | 不 |
general |
status |
是的 | 不 |
table_access |
read |
是的 | 是的 |
table_access |
delete |
是的 | 是的 |
table_access |
insert |
是的 | 是的 |
table_access |
update |
是的 | 是的 |
过滤器可以定义为包含或独占模式:
包含模式仅记录明确指定的项目。
独占模式记录除显式指定项目之外的所有内容。
要执行包容性日志记录,请全局禁用日志记录并为特定类启用日志记录。这个过滤器日志
connect和类disconnect
中的事件connection,以及类中的事件general:
{
"filter": {
"log": false,
"class": [
{
"name": "connection",
"event": [
{ "name": "connect", "log": true },
{ "name": "disconnect", "log": true }
]
},
{ "name": "general", "log": true }
]
}
}
要执行独占日志记录,请全局启用日志记录并禁用特定类的日志记录。此过滤器记录除general
类中的事件之外的所有内容:
{
"filter": {
"log": true,
"class":
{ "name": "general", "log": false }
}
}
此过滤器记录类change_user中的事件
connection和
table_access事件,因为
不记录其他所有内容:
{
"filter": {
"log": true,
"class": [
{
"name": "connection",
"event": [
{ "name": "connect", "log": false },
{ "name": "disconnect", "log": false }
]
},
{ "name": "general", "log": false }
]
}
}
要启用基于特定事件字段值的日志记录,请在指示字段名称及其预期值
field的项目中指定一个项目
:log
{
"filter": {
"class": {
"name": "general",
"event": {
"name": "status",
"log": {
"field": { "name": "general_command.str", "value": "Query" }
}
}
}
}
}每个事件都包含特定于事件类的字段,可以从过滤器中访问这些字段以执行自定义过滤。
类中的事件connection指示在会话期间何时发生与连接相关的活动,例如用户连接到服务器或从服务器断开连接。
表 6.28,“连接事件字段”指示事件的允许字段connection。
表 6.28 连接事件字段
| 字段名称 | 字段类型 | 描述 |
|---|---|---|
status |
整数 | 事件状态: 0:好的 否则:失败 |
connection_id |
无符号整数 | 连接编号 |
user.str |
细绳 | 认证时指定的用户名 |
user.length |
无符号整数 | 用户名长度 |
priv_user.str |
细绳 | 认证用户名(账户用户名) |
priv_user.length |
无符号整数 | 认证用户名长度 |
external_user.str |
细绳 | 外部用户名(由第三方认证插件提供) |
external_user.length |
无符号整数 | 外部用户名长度 |
proxy_user.str |
细绳 | 代理用户名 |
proxy_user.length |
无符号整数 | 代理用户名长度 |
host.str |
细绳 | 连接的用户主机 |
host.length |
无符号整数 | 连接用户主机长度 |
ip.str |
细绳 | 连接用户IP地址 |
ip.length |
无符号整数 | 连接用户IP地址长度 |
database.str |
细绳 | 连接时指定的数据库名称 |
database.length |
无符号整数 | 数据库名称长度 |
connection_type |
整数 | 连接类型:
0 或
1 或
2 或
3 或
4 或
5 或 |
这些
值是可以给出的符号伪常量,而不是文字数值。它们必须作为字符串引用并且区分大小写。
"::xxx"
类中的事件general指示操作的状态代码及其详细信息。
表 6.29,“通用事件字段”指出了事件的允许字段general。
表 6.29 一般事件字段
| 字段名称 | 字段类型 | 描述 |
|---|---|---|
general_error_code |
整数 | 事件状态: 0:好的 否则:失败 |
general_thread_id |
无符号整数 | 连接/线程 ID |
general_user.str |
细绳 | 认证时指定的用户名 |
general_user.length |
无符号整数 | 用户名长度 |
general_command.str |
细绳 | 命令名称 |
general_command.length |
无符号整数 | 命令名称长度 |
general_query.str |
细绳 | SQL语句文本 |
general_query.length |
无符号整数 | SQL 语句文本长度 |
general_host.str |
细绳 | 主机名 |
general_host.length |
无符号整数 | 主机名长度 |
general_sql_command.str |
细绳 | SQL 命令类型名称 |
general_sql_command.length |
无符号整数 | SQL命令类型名称长度 |
general_external_user.str |
细绳 | 外部用户名(由第三方认证插件提供) |
general_external_user.length |
无符号整数 | 外部用户名长度 |
general_ip.str |
细绳 | 连接用户IP地址 |
general_ip.length |
无符号整数 | 连接用户IP地址长度 |
general_command.str指示命令名称:Query、Execute、
Quit或Change user。
字段设置为
或
包含设置为指定 SQL 命令类型的值
的general事件
: 、、、
等等
。可用
值可以看作是此语句显示的 Performance Schema 工具的最后一个组件:
general_command.strQueryExecutegeneral_sql_command.stralter_dbalter_db_upgradeadmin_commandsgeneral_sql_command.str
mysql> SELECT NAME FROM performance_schema.setup_instruments
WHERE NAME LIKE 'statement/sql/%' ORDER BY NAME;
+---------------------------------------+
| NAME |
+---------------------------------------+
| statement/sql/alter_db |
| statement/sql/alter_db_upgrade |
| statement/sql/alter_event |
| statement/sql/alter_function |
| statement/sql/alter_instance |
| statement/sql/alter_procedure |
| statement/sql/alter_server |
...
类中的事件table_access提供有关对表的特定类型访问的信息。
表 6.30,“表访问事件字段”
指示事件的允许字段
table_access。
表 6.30 表访问事件字段
| 字段名称 | 字段类型 | 描述 |
|---|---|---|
connection_id |
无符号整数 | 事件连接 ID |
sql_command_id |
整数 | SQL 命令编号 |
query.str |
细绳 | SQL语句文本 |
query.length |
无符号整数 | SQL 语句文本长度 |
table_database.str |
细绳 | 与事件关联的数据库名称 |
table_database.length |
无符号整数 | 数据库名称长度 |
table_name.str |
细绳 | 与事件关联的表名 |
table_name.length |
无符号整数 | 表名长度 |
以下列表显示哪些语句产生哪些表访问事件:
read事件:SELECTINSERT ... SELECTSELECT(对于子句 中引用的表格)REPLACE ... SELECTSELECT(对于子句 中引用的表格)UPDATE ... WHEREWHERE(对于子句 中引用的表格)HANDLER ... READ
delete事件:DELETETRUNCATE TABLE
insert事件:INSERTINSERT ... SELECT(对于INSERT子句中引用的表格)REPLACEREPLACE ... SELECT(对于REPLACE子句 中引用的表LOAD DATALOAD XML
update事件:UPDATEUPDATE ... WHEREUPDATE(对于子句 中引用的表格)
从 MySQL 5.7.20 开始,event项目可以包括一个abort项目,该项目指示是否阻止合格事件的执行。
abort允许编写阻止特定 SQL 语句执行的规则。
该abort项目必须出现在
event项目内。例如:
"event": {
"name": qualifying event subclass names
"abort": condition
}
对于name
项目选择的事件子类,abort动作是真还是假,取决于condition评估。如果条件评估为真,则事件被阻止。否则,事件继续执行。
condition规范可以像true或
一样简单
,false也可以更复杂,使得评估取决于事件特征。
此过滤器块INSERT,
UPDATE, 和
DELETE语句:
{
"filter": {
"class": {
"name": "table_access",
"event": {
"name": [ "insert", "update", "delete" ],
"abort": true
}
}
}
}
这个更复杂的过滤器会阻止相同的语句,但只针对特定的表 ( finances.bank_account):
{
"filter": {
"class": {
"name": "table_access",
"event": {
"name": [ "insert", "update", "delete" ],
"abort": {
"and": [
{ "field": { "name": "table_database.str", "value": "finances" } },
{ "field": { "name": "table_name.str", "value": "bank_account" } }
]
}
}
}
}
}过滤器匹配和阻止的语句向客户端返回错误:
ERROR 1045 (28000): Statement was aborted by an audit log filter并非所有事件都可以被阻止(请参阅 表 6.27,“每个事件类和子类组合的记录和中止特征”)。对于无法阻止的事件,审计日志会将警告写入错误日志而不是阻止它。
如果尝试定义
abort项目出现在项目以外的其他地方
的过滤器,event则会发生错误。
逻辑运算符 ( and,
or, not) 允许构建复杂的条件,从而可以编写更高级的过滤配置。以下
log项目仅记录
具有特定值和长度
general的字段的事件
:general_command
{
"filter": {
"class": {
"name": "general",
"event": {
"name": "status",
"log": {
"or": [
{
"and": [
{ "field": { "name": "general_command.str", "value": "Query" } },
{ "field": { "name": "general_command.length", "value": 5 } }
]
},
{
"and": [
{ "field": { "name": "general_command.str", "value": "Execute" } },
{ "field": { "name": "general_command.length", "value": 7 } }
]
}
]
}
}
}
}
}
要在条件中引用预定义变量log
,请使用一个variable项目,它采用
项目name并value测试命名变量与给定值的相等性:
"variable": {
"name": "variable_name",
"value": comparison_value
}
如果variable_name具有 value则为 true comparison_value,否则为 false。
例子:
{
"filter": {
"class": {
"name": "general",
"event": {
"name": "status",
"log": {
"variable": {
"name": "audit_log_connection_policy_value",
"value": "::none"
}
}
}
}
}
}
每个预定义变量对应一个系统变量。通过编写测试预定义变量的过滤器,您可以通过设置相应的系统变量来修改过滤器操作,而无需重新定义过滤器。例如,通过编写测试预定义变量值的
过滤器,您可以通过更改
系统变量
audit_log_connection_policy_value
的值来修改过滤器操作
。audit_log_connection_policy
系统
变量用于遗留模式审计日志(请参阅
第 6.4.5.10 节,“遗留模式审计日志过滤”)。使用基于规则的审计日志过滤,这些变量保持可见(例如,使用),但对它们的更改没有效果,除非您编写包含引用它们的构造的过滤器。
audit_log_xxx_policySHOW VARIABLES
以下列表描述了variable项目允许的预定义变量:
audit_log_connection_policy_value该变量对应于
audit_log_connection_policy系统变量的值。该值是一个无符号整数。 表 6.31 “audit_log_connection_policy_value 值” 显示了允许的值和相应的audit_log_connection_policy值。表 6.31 audit_log_connection_policy_value 值
价值 对应的 audit_log_connection_policy 值 0或者"::none"NONE1或者"::errors"ERRORS2或者"::all"ALL这些 值是可以给出的符号伪常量,而不是文字数值。它们必须作为字符串引用并且区分大小写。
"::xxx"audit_log_policy_value该变量对应于
audit_log_policy系统变量的值。该值是一个无符号整数。 表 6.32 “audit_log_policy_value 值”显示了允许的值和相应的audit_log_policy值。表 6.32 audit_log_policy_value 值
价值 对应的 audit_log_policy 值 0或者"::none"NONE1或者"::logins"LOGINS2或者"::all"ALL3或者"::queries"QUERIES这些 值是可以给出的符号伪常量,而不是文字数值。它们必须作为字符串引用并且区分大小写。
"::xxx"audit_log_statement_policy_value该变量对应于
audit_log_statement_policy系统变量的值。该值是一个无符号整数。 表 6.33,“audit_log_statement_policy_value 值” 显示了允许的值和相应的audit_log_statement_policy值。表 6.33 audit_log_statement_policy_value 值
价值 对应的 audit_log_statement_policy 值 0或者"::none"NONE1或者"::errors"ERRORS2或者"::all"ALL这些 值是可以给出的符号伪常量,而不是文字数值。它们必须作为字符串引用并且区分大小写。
"::xxx"
要在条件中引用预定义函数log
,请使用一个function项目,它采用
name和args项目分别指定函数名称及其参数:
"function": {
"name": "function_name",
"args": arguments
}
该name项目应仅指定函数名称,不带括号或参数列表。
该args项目必须满足以下条件:
如果函数没有参数,
args则不应给出任何项目。如果函数确实接受参数,
args则需要一个项目,并且参数必须按照函数描述中列出的顺序给出。参数可以引用预定义的变量、事件字段或字符串或数字常量。
如果参数数量不正确或参数不是函数所需的正确数据类型,则会发生错误。
例子:
{
"filter": {
"class": {
"name": "general",
"event": {
"name": "status",
"log": {
"function": {
"name": "find_in_include_list",
"args": [ { "string": [ { "field": "user.str" },
{ "string": "@"},
{ "field": "host.str" } ] } ]
}
}
}
}
}
}
前面的过滤器根据是否
在
系统变量
中找到当前用户来
确定是否记录general类事件。该用户是使用事件中的字段构建的。
statusaudit_log_include_accounts
以下列表描述了function项目允许的预定义功能:
audit_log_exclude_accounts_is_null()检查
audit_log_exclude_accounts系统变量是否为NULL. 在定义与遗留审计日志实现相对应的过滤器时,此功能会很有帮助。参数:
没有任何。
audit_log_include_accounts_is_null()检查
audit_log_include_accounts系统变量是否为NULL. 在定义与遗留审计日志实现相对应的过滤器时,此功能会很有帮助。参数:
没有任何。
debug_sleep(millisec)睡眠给定的毫秒数。该函数在性能测量期间使用。
debug_sleep()仅适用于调试版本。参数:
millisec:一个无符号整数,指定休眠的毫秒数。
find_in_exclude_list(account)Checks whether an account string exists in the audit log exclude list (the value of the
audit_log_exclude_accountssystem variable).Arguments:
account: A string that specifies the user account name.
find_in_include_list(account)Checks whether an account string exists in the audit log include list (the value of the
audit_log_include_accountssystem variable).Arguments:
account: A string that specifies the user account name.
string_find(text, substr)Checks whether the
substrvalue is contained in thetextvalue. This search is case-sensitive.Arguments:
text: The text string to search.substr: The substring to search for intext.
In some cases, the filter definition can be changed
dynamically. To do this, define a filter
configuration within an existing filter.
For example:
{
"filter": {
"id": "main",
"class": {
"name": "table_access",
"event": {
"name": [ "update", "delete" ],
"log": false,
"filter": {
"class": {
"name": "general",
"event" : { "name": "status",
"filter": { "ref": "main" } }
},
"activate": {
"or": [
{ "field": { "name": "table_name.str", "value": "temp_1" } },
{ "field": { "name": "table_name.str", "value": "temp_2" } }
]
}
}
}
}
}
}
A new filter is activated when the activate
item within a subfilter evaluates to true.
Using activate in a top-level
filter is not permitted.
A new filter can be replaced with the original one by using a
ref item inside the subfilter to refer to
the original filter id.
The filter shown operates like this:
The
mainfilter waits fortable_accessevents, eitherupdateordelete.If the
updateordeletetable_accessevent occurs on thetemp_1ortemp_2table, the filter is replaced with the internal one (without anid, since there is no need to refer to it explicitly).If the end of the command is signalled (
general/statusevent), an entry is written to the audit log file and the filter is replaced with themainfilter.
The filter is useful to log statements that update or delete
anything from the temp_1 or
temp_2 tables, such as this one:
UPDATE temp_1, temp_3 SET temp_1.a=21, temp_3.a=23;
该语句生成多个
table_access事件,但审计日志文件仅包含general或
status条目。
定义中使用的任何id值仅根据该定义进行评估。audit_log_filter_id它们与系统变量
的值无关
。