6.4.5.6 读取审核日志文件

审核日志插件支持用户定义的功能,这些功能提供了用于读取 JSON 格式的审核日志文件的 SQL 接口。 (此功能不适用于以其他格式编写的日志文件.)

当审核日志插件初始化并配置为 JSON 日志记录时,它将使用包含当前审核日志文件的目录作为搜索可读审核日志文件的位置。该插件从audit_log_file系统变量的值确定文件位置,基本名称和后缀,然后查找名称与以下模式匹配的文件,其中[...]table 示可选文件名部分:

basename[.timestamp].suffix[.gz][.enc]

如果文件名以.enc结尾,则文件将被加密,读取其未加密内容需要从密钥环获得解密密码。有关加密的审核日志文件的更多信息,请参见加密审核日志文件

插件将忽略已手动重命名且与模式不匹配的文件,以及使用密钥环中不再可用的密码加密的文件。插件会打开每个剩余的候选文件,验证文件是否实际包含JSON个审核事件,并使用每个文件的第一个事件的时间戳对文件进行排序。结果是一系列文件,这些文件可以使用日志读取用户定义的函数(UDF)进行访问:

audit_log_read()使用可选的JSON字符串参数,成功调用任一函数返回的结果为JSON字符串。

要使用这些功能来读取审核日志,请遵循以下原则:

  • 呼叫audit_log_read()以读取从给定位置或当前位置开始的事件,或关闭读取:

  • 要初始化审核日志读取序列,请传递一个参数,该参数指示开始的位置。一种方法是传递audit_log_read_bookmark()返回的书签:

SELECT audit_log_read(audit_log_read_bookmark());
  • 要 continue 从序列中的当前位置读取,请在未指定位置的情况下调用audit_log_read()
SELECT audit_log_read();
  • 要显式关闭读取序列,请传递JSON null参数:
SELECT audit_log_read('null');

不必明确地关闭阅读。当会话结束或通过使用 table 示开始位置的参数调用audit_log_read()初始化新的读取序列时,将隐式关闭读取。

  • 成功调用audit_log_read()以读取事件将返回JSON字符串,其中包含审计事件数组:

  • 如果返回的数组的最终值不是JSON null值,则在刚刚读取的事件之后还有更多事件,可以再次调用audit_log_read()以读取更多事件。

    • 如果返回的数组的最终值为JSON null值,则在当前读取序列中不再有其他事件需要读取。

每个非null数组元素都是一个 table 示为JSON哈希的事件。例如:

[
  {
    "timestamp": "2020-05-18 13:39:33", "id": 0,
    "class": "connection", "event": "connect",
    ...
  },
  {
    "timestamp": "2020-05-18 13:39:33", "id": 1,
    "class": "general", "event": "status",
    ...
  },
  {
    "timestamp": "2020-05-18 13:39:33", "id": 2,
    "class": "connection", "event": "disconnect",
    ...
  },
  null
]

有关 JSON 格式审核事件的内容的更多信息,请参见JSON 审核日志文件格式

  • 在以下任何情况下,对未指定位置的事件进行audit_log_read()调用都会产生错误:

  • 尚未通过将位置传递到audit_log_read()来初始化读取序列。

    • 当前读取序列中没有其他事件需要读取。也就是说,audit_log_read()先前返回了一个以JSON null值结尾的数组。

    • 通过将JSON null值传递给audit_log_read()已关闭了最近的读取序列。

要在这些条件下读取事件,必须首先通过使用指定位置的参数调用audit_log_read()来初始化读取序列。

要指定audit_log_read()的位置,请传递书签,书签是JSON哈希,其中包含唯一标识特定事件的timestampid元素。这是通过调用audit_log_read_bookmark()函数获得的示例书签:

mysql> SELECT audit_log_read_bookmark();
+-------------------------------------------------+
| audit_log_read_bookmark()                       |
+-------------------------------------------------+
| { "timestamp": "2020-05-18 21:03:44", "id": 0 } |
+-------------------------------------------------+

将当前书签传递给audit_log_read()会初始化从书签位置开始的事件读取:

mysql> SELECT audit_log_read(audit_log_read_bookmark());
+-----------------------------------------------------------------------+
| audit_log_read(audit_log_read_bookmark())                             |
+-----------------------------------------------------------------------+
| [ {"timestamp":"2020-05-18 22:41:24","id":0,"class":"connection", ... |
+-----------------------------------------------------------------------+

audit_log_read()的参数是可选的。如果存在,则可以是JSON null值以关闭读取序列,也可以是JSON哈希。

audit_log_read()的哈希参数中,项目是可选的,并且控制读取操作的方面,例如开始读取的位置或要读取的事件数。以下各项很重要(其他项目将被忽略):

  • timestampid:要读取的第一个事件在审核日志中的位置。如果从参数中省略该位置,则从当前位置 continue 读取。 timestampid项一起构成唯一标识特定事件的书签。如果audit_log_read()参数包含任何一项,则它必须同时包含两者以完全指定位置,否则会发生错误。

  • max_array_length:要从日志中读取的最大事件数。如果省略此项,则默认设置为读取到日志末尾或直到读取缓冲区已满(以先到者为准)。

audit_log_read()接受的示例参数:

  • 从具有确切时间戳和事件 ID 的事件开始读取事件:
audit_log_read('{ "timestamp": "2020-05-24 12:30:00", "id": 0 }')
  • 与前面的示例类似,但最多读取 3 个事件:
audit_log_read('{ "timestamp": "2020-05-24 12:30:00", "id": 0, "max_array_length": 3 }')
  • 从读取 Sequences 中的当前位置读取事件:
audit_log_read()
  • 从读取序列中的当前位置开始读取最多 5 个事件:
audit_log_read('{ "max_array_length": 5 }')
  • 关闭当前的读取序列:
audit_log_read('null')

要将二进制JSON字符串与需要非二进制字符串的函数一起使用(例如,处理JSON值的函数),请转换为utf8mb4。假设调用获取书签会产生以下值:

mysql> SET @mark := audit_log_read_bookmark();
mysql> SELECT @mark;
+-------------------------------------------------+
| @mark                                           |
+-------------------------------------------------+
| { "timestamp": "2020-05-18 16:10:28", "id": 2 } |
+-------------------------------------------------+

使用该参数调用audit_log_read()可以返回多个事件。要限制audit_log_read()最多读取* N *事件,请将字符串转换为utf8mb4,然后向其中添加一个具有该值的max_array_length项。例如,要读取单个事件,请按如下所示修改字符串:

mysql> SET @mark = CONVERT(@mark USING utf8mb4);
mysql> SET @mark := JSON_SET(@mark, '$.max_array_length', 1);
mysql> SELECT @mark;
+----------------------------------------------------------------------+
| @mark                                                                |
+----------------------------------------------------------------------+
| {"id": 2, "timestamp": "2020-05-18 16:10:28", "max_array_length": 1} |
+----------------------------------------------------------------------+

修改后的字符串传递给audit_log_read()时,无论是否有多少事件,产生的结果最多包含一个事件。

要读取从当前位置开始的特定数量的事件,请传递包含max_array_length值但不包含位置的JSON哈希。每次重复调用此语句都会返回五个事件,直到没有更多事件可用为止:

SELECT audit_log_read('{"max_array_length": 5}');

要设置audit_log_read()读取的字节数限制,请设置audit_log_read_buffer_size系统变量。从 MySQL 5.7.23 开始,此变量的默认值为 32KB,可以在运行时设置。每个 Client 端应将其会话值audit_log_read_buffer_size适当地设置为使用audit_log_read()。在 MySQL 5.7.23 之前,audit_log_read_buffer_size的默认值为 1MB,会影响所有 Client 端,并且只能在服务器启动时进行更改。

有关审核日志读取功能的其他信息,请参见审核日志功能