文档主页
MySQL 9.0 参考手册
相关文档 下载本手册
PDF (US Ltr) - 40.0Mb
PDF (A4) - 40.1Mb
手册页 (TGZ) - 258.2Kb
手册页 (Zip) - 365.3Kb
信息 (Gzip) - 4.0Mb
信息 (Zip) - 4.0Mb


MySQL 9.0 参考手册  /  ...  /  编写审计日志过滤器定义

8.4.5.8 编写审计日志过滤器定义

过滤器定义是 JSON 值。有关在 MySQL 中使用 JSON 数据的信息,请参见 第 13.5 节,“JSON 数据类型”.

过滤器定义具有以下形式,其中 actions 指示过滤的发生方式

{ "filter": actions }

以下讨论描述了过滤器定义中允许的结构。

记录所有事件

要显式启用或禁用所有事件的日志记录,请在过滤器中使用 log

{
  "filter": { "log": true }
}

log 值可以是 truefalse

前面的过滤器启用所有事件的日志记录。它等效于

{
  "filter": { }
}

日志记录行为取决于 log 值以及是否指定了 classevent

  • 指定了 log 后,将使用其给定值。

  • 未指定 log 时,如果未指定 classevent 项,日志记录为 true,否则为 false(在这种情况下,classevent 可以包含自己的 log 项)。

记录特定事件类

要记录特定类的事件,请在过滤器中使用 class 项,其 name 字段表示要记录的类的名称

{
  "filter": {
    "class": { "name": "connection" }
  }
}

name 值可以是 connectiongeneraltable_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" ] }
    ]
  }
}
记录特定事件子类

要选择特定的事件子类,请使用包含 name 项的 event 项,该项命名这些子类。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 }
]

event 项还可以指示是否阻止符合条件的事件,如果它包含 abort 项。有关详细信息,请参见 阻止特定事件的执行.

表 8.34,“事件类和子类组合” 描述了每个事件类允许的子类值。

表 8.34 事件类别和子类别组合

事件类别 事件子类别 描述
connection connect 连接启动(成功或失败)
connection change_user 会话期间使用不同的用户/密码重新验证用户
connection disconnect 连接终止
general status 一般操作信息
message internal 内部生成的 message
message user audit_api_message_emit_udf() 生成的 message
table_access read 表读取语句,例如 SELECTINSERT INTO ... SELECT
table_access delete 表删除语句,例如 DELETETRUNCATE TABLE
table_access insert 表插入语句,例如 INSERTREPLACE
table_access update 表更新语句,例如 UPDATE

表 8.35,“每个事件类别和子类别组合的日志和中止特性” 描述了每个事件子类别是否可以记录或中止。

表 8.35 每个事件类别和子类别组合的日志和中止特性

事件类别 事件子类别 可以记录 可以中止
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 类中的 connectdisconnect 事件,以及 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 }
    ]
  }
}
测试事件字段值

要根据特定事件字段值启用日志记录,请在 log 项目中指定一个 field 项目,该项目指示字段名称及其预期值。

{
  "filter": {
    "class": {
    "name": "general",
      "event": {
        "name": "status",
        "log": {
          "field": { "name": "general_command.str", "value": "Query" }
        }
      }
    }
  }
}

每个事件都包含特定于事件类别的字段,这些字段可以在过滤器中访问以执行自定义过滤。

一个 connection 类中的事件指示在会话期间何时发生与连接相关的活动,例如用户连接到或断开与服务器的连接。表 8.36,“连接事件字段” 指示 connection 事件的允许字段。

表 8.36 连接事件字段

字段名称 字段类型 描述
status integer

事件状态

0: 正常

其他:失败

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 integer

连接类型

0 或 "::undefined": 未定义

1 或 "::tcp/ip": TCP/IP

2 或 "::socket": 套接字

3 或 "::named_pipe": 命名管道

4 或 "::ssl": 使用加密的 TCP/IP

5 或 "::shared_memory": 共享内存


"::xxx" 是符号伪常量,可以用作文字数字值的替代。它们必须用引号括起来并区分大小写。

一个 general 类中的事件指示操作的状态代码及其详细信息。表 8.37,“一般事件字段” 指示 general 事件的允许字段。

表 8.37 一般事件字段

字段名称 字段类型 描述
general_error_code integer

事件状态

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 指示命令名称:QueryExecuteQuitChange user

一个 general 事件,其 general_command.str 字段设置为 QueryExecute,将包含 general_sql_command.str 设置为一个值,该值指定 SQL 命令的类型:alter_dbalter_db_upgradeadmin_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.38,“表访问事件字段” 指示 table_access 事件的允许字段。

表 8.38 表访问事件字段

字段名称 字段类型 描述
connection_id 无符号整数 事件连接 ID
sql_command_id integer 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 权限。当您执行升级过程时,如果现有的帐户未分配该权限,则也会将 AUDIT_ABORT_EXEMPT 权限分配给具有 SYSTEM_USER 权限的现有帐户。

abort 项目必须出现在 event 项目中。例如

"event": {
  "name": qualifying event subclass names
  "abort": condition
}

对于由 name 项目选择的事件子类别,abort 操作为真或假,具体取决于 condition 的评估。如果该条件的评估结果为真,则该事件将被阻止。否则,该事件将继续执行。

condition 规范可以像 truefalse 一样简单,也可以更复杂,以便评估取决于事件特征。

此过滤器会阻止 INSERTUPDATEDELETE 语句。

{
  "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.35,“每个事件类别和子类别组合的日志和中止特性”)。对于无法阻止的事件,审核日志会将警告写入错误日志,而不是阻止它。

对于在 event 项目以外的位置出现 abort 项目的过滤器定义尝试,将发生错误。

逻辑运算符

逻辑运算符 (andornot) 允许构建复杂的条件,从而能够编写更高级的过滤配置。以下 log 项目仅记录具有特定值和长度的 general_command 字段的 general 事件。

{
  "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 项目,该项目接受 namevalue 项目,并测试命名变量与给定值的相等性。

"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_xxx_policy 系统变量用于已弃用的传统模式审计日志(参见 第 8.4.5.10 节,“传统模式审计日志过滤”)。使用基于规则的审计日志过滤,这些变量仍然可见(例如,使用 SHOW VARIABLES),但对它们的更改不会生效,除非编写包含引用它们的构造的过滤器。

以下列表描述了 variable 项目中允许的预定义变量

  • audit_log_connection_policy_value

    此变量对应于 audit_log_connection_policy 系统变量的值。该值是一个无符号整数。 表 8.39,“audit_log_connection_policy_value 值” 显示了允许的值和相应的 audit_log_connection_policy 值。

    表 8.39 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 系统变量的值。该值是一个无符号整数。 表 8.40,“audit_log_policy_value 值” 显示了允许的值和相应的 audit_log_policy 值。

    表 8.40 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 系统变量的值。该值是一个无符号整数。 表 8.41,“audit_log_statement_policy_value 值” 显示了允许的值和相应的 audit_log_statement_policy 值。

    表 8.41 audit_log_statement_policy_value 值

    对应的 audit_log_statement_policy 值
    0"::none" NONE
    1"::errors" ERRORS
    2"::all" ALL

    "::xxx" 是符号伪常量,可以用作文字数字值的替代。它们必须用引号括起来并区分大小写。

引用预定义函数

要在 log 条件中引用预定义函数,请使用 function 项目,该项目采用 nameargs 项目分别指定函数名称及其参数。

"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 系统变量中找到来记录 generalstatus 事件。该用户是使用事件中的字段构建的。

以下列表描述了 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)

    检查帐户字符串是否存在于审计日志排除列表(audit_log_exclude_accounts 系统变量的值)中。

    参数

    • account:一个指定用户帐户名称的字符串。

  • find_in_include_list(account)

    检查帐户字符串是否存在于审计日志包含列表(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 中搜索的子字符串。

替换事件字段值

审计过滤器定义支持替换某些审计事件字段,以便记录的事件包含替换值而不是原始值。此功能使记录的审计记录能够包含语句摘要而不是文字语句,这对于语句可能会暴露敏感值的 MySQL 部署非常有用。

审计事件中的字段替换的工作原理如下

  • 字段替换在审计过滤器定义中指定,因此必须如 第 8.4.5.7 节,“审计日志过滤” 中所述启用审计日志过滤。

  • 并非所有字段都可以替换。 表 8.42,“可替换事件字段” 显示了哪些字段在哪些事件类中可替换。

    表 8.42 可替换事件字段

    事件类别 字段名称
    general general_query.str
    table_access query.str

  • 替换是有条件的。过滤器定义中的每个替换规范都包含一个条件,允许根据条件结果更改可替换字段或保持不变。

  • 如果发生替换,替换规范将使用允许用于该目的的函数来指示替换值。

表 8.42,“可替换事件字段” 所示,目前唯一可替换的字段是包含语句文本的字段(出现在 generaltable_access 类的事件中)。此外,唯一允许用于指定替换值的函数是 query_digest。这意味着唯一允许的替换操作是将语句文字文本替换为其相应的摘要。

由于字段替换发生在审计的早期阶段(在过滤期间),因此无论稍后写入的日志格式如何(也就是说,审计日志插件是否生成 XML 或 JSON 输出),选择是写入语句文字文本还是摘要值的决定都适用。

字段替换可以在不同的事件粒度级别进行

  • 要对类中的所有事件执行字段替换,请在类级别过滤事件。

  • 要以更细粒度的基础执行替换,请包含其他事件选择项目。例如,您只能对给定事件类的特定子类或仅在字段具有某些特征的事件中执行字段替换。

在过滤器定义中,通过包含一个 print 项目来指定字段替换,该项目具有以下语法

"print": {
  "field": {
    "name": "field_name",
    "print": condition,
    "replace": replacement_value
  }
}

print 项目中,它的 field 项目采用这三个项目来指示是否以及如何进行替换

  • name:要进行替换(可能)的字段。 field_name 必须是 表 8.42,“可替换事件字段” 中显示的字段之一。

  • 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 返回 truefalse,具体取决于当前语句摘要是否与比较摘要相同。使用 query_digest 这种方式使过滤器定义能够检测与特定摘要匹配的语句。以下构造中的条件仅对具有与 SELECT ? 相同摘要的语句为真,因此仅对与摘要不匹配的语句进行替换

"print": {
  "field": {
    "name": "general_query.str",
    "print": {
      "function": {
        "name": "query_digest",
        "args": "SELECT ?"
      }
    },
    "replace": {
      "function": {
        "name": "query_digest"
      }
    }
  }
}

要仅对与摘要匹配的语句执行替换,请使用 not 反转条件

"print": {
  "field": {
    "name": "general_query.str",
    "print": {
      "not": {
        "function": {
          "name": "query_digest",
          "args": "SELECT ?"
        }
      }
    },
    "replace": {
      "function": {
        "name": "query_digest"
      }
    }
  }
}

假设您希望审计日志仅包含语句摘要,而不是字面语句。 为此,您必须对所有包含语句文本的事件执行替换; 也就是说,generaltable_access 类中的事件。 之前的过滤器定义展示了如何无条件地替换 general 事件的语句文本。 要对 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"
            }
          }
        }
      }
    }
  }
}

generaltable_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 类中的事件,但仅对 insertupdate 事件执行替换(将 readdelete 事件保持不变)

{
  "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 时,将激活一个新过滤器。 在顶级 filter 中使用 activate 是不允许的。

可以通过在子过滤器中使用 ref 项目来引用原始过滤器 id,从而将新过滤器替换为原始过滤器。

显示的过滤器按以下方式操作

  • main 过滤器等待 table_access 事件,无论是 update 还是 delete

  • 如果 updatedelete table_access 事件发生在 temp_1temp_2 表上,则将过滤器替换为内部过滤器(没有 id,因为不需要显式引用它)。

  • 如果命令结束信号发出(general / status 事件),则将条目写入审计日志文件,并将过滤器替换为 main 过滤器。

此过滤器用于记录从 temp_1temp_2 表更新或删除任何内容的语句,例如以下语句

UPDATE temp_1, temp_3 SET temp_1.a=21, temp_3.a=23;

该语句生成多个 table_access 事件,但审计日志文件仅包含 general / status 条目。

注意

定义中使用的任何 id 值仅相对于该定义进行评估。 它们与 audit_log_filter_id 系统变量的值无关。