过滤器定义是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 |
读表语句,例如SELECT or
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.str
Query
Execute
general_sql_command.str
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
提供有关对表的特定类型访问的信息。
表 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
事件: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
(对于子句 中引用的表格)
从 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"
NONE
1
或者"::errors"
ERRORS
2
或者"::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"
NONE
1
或者"::logins"
LOGINS
2
或者"::all"
ALL
3
或者"::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"
NONE
1
或者"::errors"
ERRORS
2
或者"::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
类事件。该用户是使用事件中的字段构建的。
status
audit_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_accounts
system 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_accounts
system variable).Arguments:
account
: A string that specifies the user account name.
string_find(text, substr)
Checks whether the
substr
value is contained in thetext
value. 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
main
filter waits fortable_access
events, eitherupdate
ordelete
.If the
update
ordelete
table_access
event occurs on thetemp_1
ortemp_2
table, 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
/status
event), an entry is written to the audit log file and the filter is replaced with themain
filter.
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
它们与系统变量
的值无关
。