8.4.5.8 编写审计日志过滤器定义
过滤器定义是JSON值。关于在 MySQL 中使用JSON数据的信息,请参见第13.5节,“JSON数据类型”。
过滤器定义有这个形式,其中actions表示过滤操作的方式:
{ "filter": actions }
下面讨论了过滤定义中的允许构造。
要明确地启用或禁用所有事件的日志记录,使用log项:
{
"filter": { "log": true }
}
log值可以是true或false
前面的过滤器启用了所有事件的日志记录。它等同于:
{
"filter": { }
}
日志行为取决于log值和是否指定了class或event项:
-
如果指定了
log,则使用其给定的值。 -
如果没有指定
log,日志记录是true,除非指定了class或event项,可以包含自己的log项。
要记录特定类别的事件,使用class项,在其name字段中指定要记录的类别名称:
{
"filter": {
"class": { "name": "connection" }
}
}
该name值可以是connection、general或table_access,分别记录连接、总体或表访问事件。
前面的过滤器启用了连接类别的事件日志。它等同于以下明确指定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 }
]
事件项还可以指示是否阻止符合条件的事件,如果包含abort项。详细信息请见阻止特定事件的执行。
表8.35,“事件类别和子类组合”描述了每个事件类别的允许子类值。
表8.35 事件类别和子类组合
| Event Class | Event Subclass | Description |
|---|---|---|
connection |
connect |
连接初始化(成功或失败) |
connection |
change_user |
会话中用户重新身份验证 |
connection |
disconnect |
连接终止 |
general |
status |
通用操作信息 |
message |
internal |
内部生成的消息 |
message |
user |
由audit_api_message_emit_udf()生成的消息 |
table_access |
read |
表读语句,例如SELECT或INSERT INTO ... SELECT |
table_access |
delete |
表删除语句,例如DELETE或TRUNCATE TABLE |
table_access |
insert |
表插入语句,例如INSERT或REPLACE |
table_access |
update |
表更新语句,例如UPDATE |
表8.36,“事件类别和子类组合的日志和中止特征”对每个事件子类描述是否可以被记录或中止。
表8.36 事件类别和子类组合的日志和中止特征
| Event Class | Event Subclass | Can be Logged | Can be Aborted |
|---|---|---|---|
connection |
connect |
是 | 否 |
connection |
change_user |
是 | 否 |
connection |
disconnect |
是 | 否 |
general |
status |
是 | 否 |
message |
internal |
是 | 是 |
message |
user |
是 | 是 |
table_access |
read |
是 | 是 |
table_access |
delete |
是 | 是 |
table_access |
insert |
是 | 是 |
table_access |
update |
是 | 是 |
过滤器可以在包容模式或排他模式下定义:
-
包容模式仅记录明确指定的项目。
-
排他模式记录除明确指定项目外的所有项目。
要执行包容式日志记录,先禁用全局日志,然后启用特定类别的日志。这款过滤器在connection类别中记录connect和disconnect事件,在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 }
}
}
这款过滤器在connection类别中记录change_user事件,在message事件和table_access事件中记录事件,因为它不记录其他事件:
{
"filter": {
"log": true,
"class": [
{
"name": "connection",
"event": [
{ "name": "connect", "log": false },
{ "name": "disconnect", "log": false }
]
},
{ "name": "general", "log": false }
]
}
}
要根据特定事件字段值启用日志记录,指定field项目,该项目指示字段名称和预期值:
{
"filter": {
"class": {
"name": "general",
"event": {
"name": "status",
"log": {
"field": { "name": "general_command.str", "value": "Query" }
}
}
}
}
}
每个事件都包含特定类别的字段,可以从过滤器中访问以执行自定义过滤。
在connection类别的事件指示会话期间连接相关活动的发生,例如用户连接到或从服务器断开。 表8.37,“连接事件字段” 指示了connection事件的允许字段。
表8.37 连接事件字段
| Field Name | Field Type | Description |
|---|---|---|
status |
事件状态: 0:OK 否则:Failed |
|
connection_id |
无符号整数 | 连接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 类中表示操作的状态码和详细信息。表 8.38,“一般事件字段” 指示了 general 事件的允许字段。
表 8.38 一般事件字段
| Field Name | Field Type | Description |
|---|---|---|
general_error_code |
整数 |
事件状态: 0:OK 否则:Failed |
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 |
无符号整数 | 命令类型名称长度 |
general_external_user.str |
字符串 | 第三方身份验证插件提供的外部用户名 |
general_external_user.length |
无符号整数 | 外部用户名长度 |
general_ip.str |
字符串 | 连接用户 IP 地址 |
general_ip.length |
无符号整数 | 连接用户 IP 地址长度 |
general_command.str 表示命令名称:Query、Execute、Quit 或 Change user。
一个general事件,general_command.str字段设置为Query或Execute,包含general_sql_command.str字段,值指定SQL命令类型:alter_db、alter_db_upgrade、admin_commands等。可用的general_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事件提供关于某个表的特定访问信息。8.39, “表访问事件字段”指示table_access事件的允许字段。
8.39 表访问事件字段
| Field Name | Field Type | Description |
|---|---|---|
connection_id |
无符号整数 | 事件连接ID |
sql_command_id |
整数 | SQL命令ID |
query.str |
字符串 | SQL语句文本 |
query.length |
无符号整数 | SQL语句文本长度 |
table_database.str |
字符串 | 与事件关联的数据库名称 |
table_database.length |
无符号整数 | 数据库名称长度 |
table_name.str |
字符串 | 与事件关联的表名称 |
table_name.length |
无符号整数 | 表名称长度 |
以下列表显示哪些语句产生哪些表访问事件:
-
read事件:-
SELECT -
INSERT ... SELECT(对SELECT子句中引用的表) -
REPLACE ... SELECT(对SELECT子句中引用的表) -
UPDATE ... WHERE(对WHERE子句中引用的表) -
HANDLER ... READ
-
-
delete事件:-
DELETE -
TRUNCATE TABLE
-
-
insert事件:-
INSERT -
INSERT ... SELECT(对INSERT子句中引用的表) -
REPLACE -
REPLACE ... SELECT(对REPLACE子句中引用的表) -
LOAD DATA -
LOAD XML
-
-
update事件:-
UPDATE -
UPDATE ... WHERE(对UPDATE子句中引用的表)
-
event 项可以包括一个abort项,指示是否阻止符合条件的事件执行。abort 可以编写规则来阻止特定的SQL语句执行。
理论上,拥有足够权限的用户可能会误创建一个在审核日志过滤器中阻止自己和其他管理员访问系统的abort项。可用AUDIT_ABORT_EXEMPT特权来允许用户账户的查询始终执行,即使abort项会阻止它们。拥有这个特权的账户可以用来恢复在审核配置错误后访问系统。该查询仍然被记录到审核日志中,但由于特权而不是被拒绝。
使用SYSTEM_USER特权创建的账户自动分配AUDIT_ABORT_EXEMPT特权。同时,在升级过程中,如果没有账户拥有这个特权,系统也会将其分配给已有的账户。
"event": {
"name": qualifying event subclass names
"abort": condition
}
在event项中必须出现abort项。例如:
条件指定可以是简单的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
不所有事件都可以被阻止(见表8.36,“事件类别和子类组合的日志和中断特征”)。对于不能被阻止的事件,审核日志写入错误日志,而不是阻止它。
对定义过滤器,其中abort项出现在非event项中,出现错误。
逻辑运算符
逻辑操作符(and, or, not) 允许构建复杂的条件,实现更高级别的过滤配置。以下log项仅记录具有特定值和长度的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具有值comparison_value,则为真,否则为假。
示例:
{
"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系统变量的值来修改过滤操作。
系统变量audit_log_用于弃用的遗留模式审核日志(见第8.4.5.10节,“遗留模式审核日志过滤”)。在基于规则的审核日志过滤中,那些变量仍然可见(例如,使用xxx_policySHOW VARIABLES),但是除非您编写包含对它们的引用构造的过滤器,否则变量更改无效。
以下是variable项目允许的预定义变量列表:
-
audit_log_connection_policy_value这个变量对应于系统变量
audit_log_connection_policy的值。该值是一个无符号整数。表 8.40, “audit_log_connection_policy_value 值”显示了允许的值和对应audit_log_connection_policy值。表 8.40 audit_log_connection_policy_value 值
Value Corresponding audit_log_connection_policy Value 0或"::none"NONE1或"::errors"ERRORS2或::all"ALL
"
::值是符号伪常量,可以代替字面值的数字值。它们必须被字符串引起来,并且大小写敏感。xxx" -
audit_log_policy_value这个变量对应于
audit_log_policy系统变量的值。该值是一个无符号整数。表 8.41, "audit_log_policy_value 值"显示了允许的值和对应的audit_log_policy值。表 8.41 audit_log_policy_value 值
Value Corresponding audit_log_policy Value 0或::none"NONE1或::logins"LOGINS2或::all"ALL3或::queries"QUERIES
"
::值是符号伪常量,可以代替字面值的数字值。它们必须被字符串引起来,并且大小写敏感。xxx" -
audit_log_statement_policy_value这个变量对应于
audit_log_statement_policy系统变量的值,值是一个无符号整数。表8.42,“audit_log_statement_policy_value 值”显示了允许的值和对应audit_log_statement_policy值。表8.42 audit_log_statement_policy_value 值
Value Corresponding audit_log_statement_policy Value 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" } ] } ]
}
}
}
}
}
}
前面的过滤器根据当前用户是否在audit_log_include_accounts系统变量中决定是否记录general类status事件。该用户使用事件字段构建。
以下是function项允许的预定义函数列表:
-
audit_log_exclude_accounts_is_null()检查
audit_log_exclude_accounts系统变量是否为NULL。这个函数可以帮助定义与legacy审核日志实现对应的过滤器。参数:
无。
-
audit_log_include_accounts_is_null()检查
audit_log_include_accounts系统变量是否为NULL。这个函数在定义与legacy audit log 实现对应的过滤器时非常有用。参数:
无。
-
debug_sleep(millisec)睡眠给定的毫秒数。这个函数用于性能测量。
debug_sleep()只在调试版本中可用。参数:
-
millisec: 无符号整数,指定睡眠的毫秒数。
-
-
find_in_exclude_list(account)检查账户字符串是否在audit log 排除列表中(
audit_log_exclude_accounts系统变量的值)。参数:
-
account: 指定用户账户名称的字符串。
-
-
find_in_include_list(account)检查账户字符串是否在audit log 包含列表中(
audit_log_include_accounts系统变量的值)。参数:
-
account: 指定用户账户名称的字符串。
-
-
query_digest([str])这个函数的行为取决于是否给出参数:
-
无参数时,
query_digest返回当前事件的语句摘要值。 -
有参数时,
query_digest返回一个布尔值,表示参数是否等于当前语句摘要。
参数:
-
str:这个参数是可选的。如果给出,它指定要与当前事件中的语句摘要进行比较。
示例:
这个
function项不包括参数,所以query_digest返回当前语句摘要作为字符串:"function": { "name": "query_digest" }这个
function项包括参数,所以query_digest返回一个布尔值,表示参数是否等于当前语句摘要:"function": { "name": "query_digest", "args": "SELECT ?" } -
-
string_find(text, substr)检查
substr值是否包含在text值中。这一搜索是大小写敏感的。参数:
-
text:要搜索的文本字符串。 -
substr:在text中搜索的子串。
-
审核过滤器定义支持将某些审核事件字段替换为特定的值,以便logged事件包含替换后的值,而不是原始值。这一能力使得logged审核记录可以包含语句摘要,而不是literal语句,这对MySQL部署非常有用,因为语句可能会暴露敏感信息。
审核事件中的字段替换工作方式如下:
-
字段替换是在审核过滤器定义中指定的,因此,必须启用审核日志 filtering,如第8.4.5.7节,“审核日志 filtering”所述。
-
不所有字段都可以被替换。表 8.43, “可替换事件字段”显示了哪些字段在哪些事件类别中可以被替换。
-
替换是条件的。每个替换规则在过滤器定义中都包含一个条件,决定是否将可替换字段更改或保持不变,取决于条件结果。
-
如果替换发生,替换规则使用允许的函数来指定替换值。
如表 8.43, “可替换事件字段”所示,当前唯一可替换的字段是包含语句文本的事件(发生在general和table_access类别中的事件),此外,唯一允许指定替换值的函数是query_digest。这意味着唯一允许的替换操作是将语句文字替换为对应的摘要。
由于字段替换在审核阶段进行(即过滤阶段),因此,无论日志格式后是否为XML或JSON输出,选择写入语句文字或摘要值都无关紧要。
字段替换可以在事件粒度不同的级别上进行:
-
要对某个事件类别中的所有事件进行字段替换,可以在类别级别过滤事件。
-
要以更细化的方式进行替换,可以包括更多的事件选择项。例如,可以只对某个事件类别的特定子类别或只有满足某些字段特征的事件进行替换。
在过滤定义中,使用print项来指定字段替换,语法如下:
"print": {
"field": {
"name": "field_name",
"print": condition,
"replace": replacement_value
}
}
在print项中,field项有三个子项来指示是否和如何进行替换:
-
name: 需要替换的字段。field_name必须在表8.43,“可替换事件字段”中显示。 -
print: 决定是否保留原始字段值或替换的条件:-
如果
condition评估为true,字段保持不变。 -
如果
condition评估为false,则进行替换,使用replace项的值。
无条件替换一个字段,指定条件如下:
"print": false -
-
replace: 当print条件评估为false时要使用的替换值,使用function项指定replacement_value。
例如,这个过滤器定义对所有事件在general类别中,替换语句文字为其摘要:
{
"filter": {
"class": {
"name": "general",
"print": {
"field": {
"name": "general_query.str",
"print": false,
"replace": {
"function": {
"name": "query_digest"
}
}
}
}
}
}
}
前面的过滤器使用这个print项无条件地将general_query.str中的语句文字替换为其摘要值:
"print": {
"field": {
"name": "general_query.str",
"print": false,
"replace": {
"function": {
"name": "query_digest"
}
}
}
}
print项可以以不同的方式编写来实现不同的替换策略。前面显示的replace项使用这个function构造返回当前语句摘要字符串:
"function": {
"name": "query_digest"
}
query_digest函数也可以以另一种方式使用,作为比较器返回布尔值,从而在print条件中使用。这样做,提供一个指定比较语句摘要的参数:
"function": {
"name": "query_digest",
"args": "digest"
}
在这种情况下,query_digest根据当前语句摘要是否与比较摘要相同返回true或false。使用query_digest这样可以使过滤器定义检测特定的摘要语句。前面的构造中的条件只对不匹配摘要的语句为真,从而只有不匹配的语句才会被替换:
"print": {
"field": {
"name": "general_query.str",
"print": {
"function": {
"name": "query_digest",
"args": "SELECT ?"
}
},
"replace": {
"function": {
"name": "query_digest"
}
}
}
}
要仅对匹配 digest 的语句执行替换,使用not来反转条件:
"print": {
"field": {
"name": "general_query.str",
"print": {
"not": {
"function": {
"name": "query_digest",
"args": "SELECT ?"
}
}
},
"replace": {
"function": {
"name": "query_digest"
}
}
}
}
假设你想让审计日志只包含语句摘要,而不是原始语句。为了实现这个目标,你必须对包含语句文本的所有事件进行替换;也就是说,需要对general和table_access类别的事件进行替换。早期的一个过滤器定义展示了如何对general事件 unconditional 地替换语句文本。要对table_access事件做同样的事情,使用一个相似的过滤器,但将类别从general改为table_access,字段名从general_query.str改为query.str:
{
"filter": {
"class": {
"name": "table_access",
"print": {
"field": {
"name": "query.str",
"print": false,
"replace": {
"function": {
"name": "query_digest"
}
}
}
}
}
}
}
将general和table_access过滤器组合起来,结果是一个单个过滤器,对所有包含语句文本的事件执行替换:
{
"filter": {
"class": [
{
"name": "general",
"print": {
"field": {
"name": "general_query.str",
"print": false,
"replace": {
"function": {
"name": "query_digest"
}
}
}
}
},
{
"name": "table_access",
"print": {
"field": {
"name": "query.str",
"print": false,
"replace": {
"function": {
"name": "query_digest"
}
}
}
}
}
]
}
}
要对某些事件类别中的某些事件执行替换,添加到过滤器中以指明更具体地何时执行替换。下面这个过滤器应用于table_access类别的事件,但仅对insert和update事件执行替换(留出read和delete事件不变):
{
"filter": {
"class": {
"name": "table_access",
"event": {
"name": [
"insert",
"update"
],
"print": {
"field": {
"name": "query.str",
"print": false,
"replace": {
"function": {
"name": "query_digest"
}
}
}
}
}
}
}
}
这个过滤器对general类别的事件,相应于列出的账户管理语句(效果是隐藏证书和数据值在语句中):
{
"filter": {
"class": {
"name": "general",
"event": {
"name": "status",
"print": {
"field": {
"name": "general_query.str",
"print": false,
"replace": {
"function": {
"name": "query_digest"
}
}
}
},
"log": {
"or": [
{
"field": {
"name": "general_sql_command.str",
"value": "alter_user"
}
},
{
"field": {
"name": "general_sql_command.str",
"value": "alter_user_default_role"
}
},
{
"field": {
"name": "general_sql_command.str",
"value": "create_role"
}
},
{
"field": {
"name": "general_sql_command.str",
"value": "create_user"
}
}
]
}
}
}
}
}
关于可能的general_sql_command.str值信息,请参见测试事件字段值。
在某些情况下,过滤定义可以动态更改。要实现这个,可以在现有的filter中定义一个filter配置。例如:
{
"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" } }
]
}
}
}
}
}
}
当activate项位于子过滤器中并评估为true时,新过滤器就被激活。使用activate在顶级filter中不允许。
可以将新的过滤器替换为原始的过滤器,通过在子过滤器中使用ref项来引用原始过滤器id。
这个过滤器的操作方式是:
-
主过滤器等待
table_access事件,包括update或delete。 -
如果在
temp_1或temp_2表上发生update或deletetable_access事件,过滤器将被替换为内部的过滤器(因为不需要明确引用)。 -
如果命令结束(
general/status事件),将写入审核日志文件,并将过滤器替换为main过滤器。
过滤器可以用来记录更新或删除temp_1或temp_2表中的语句,例如:
UPDATE temp_1, temp_3 SET temp_1.a=21, temp_3.a=23;
该语句生成多个table_access事件,但是审核日志文件中只包含general/ status条目。
id值在定义中被评估,仅与该定义相关,不与audit_log_filter_id系统变量的值相关。