Documentation Home
MySQL 8.3 Reference Manual
Related Documentation Download this Manual
PDF (US Ltr) - 40.8Mb
PDF (A4) - 40.9Mb
Man Pages (TGZ) - 294.0Kb
Man Pages (Zip) - 409.0Kb
Info (Gzip) - 4.0Mb
Info (Zip) - 4.0Mb
Excerpts from this Manual

MySQL 8.3 Reference Manual  /  ...  /  Reading Audit Log Files

8.4.5.6 审核日志文件读取

审核日志插件支持提供SQL接口来读取JSON格式的审核日志文件。(这项功能不适用于其他格式的日志文件。)

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

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

如果文件名以.enc结尾,该文件是加密的,读取其未加密的内容需要从密钥环中获取解密密码。

  • 如果.enc前面是pwd_id,则密钥环ID为audit_log-pwd_id

  • 如果.enc前面不是pwd_id,则该文件是审核日志加密密码历史记录实现之前的旧名称。密钥环ID为audit_log

有关加密审核日志文件的更多信息,请参阅加密审核日志文件

插件忽略了手动重命名的文件和不匹配模式的文件,以及使用不再可用的密码加密的文件。插件打开每个剩余的候选文件,验证文件实际包含JSON审核事件,并使用每个文件的第一个事件的时间戳对文件进行排序。结果是一个文件序列,subject to access using the log-reading functions:

audit_log_read()接受一个可选的JSON字符串参数,成功调用该函数或其他函数返回的结果是一个JSON字符串。

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

  • 调用 audit_log_read() 以从给定位置或当前位置读取事件,或者关闭读取:

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

      SELECT audit_log_read(audit_log_read_bookmark());
    • 要从当前位置继续读取,请调用 audit_log_read() 而不指定位置:

      SELECT audit_log_read();
    • 要显式关闭读取序列,请传递一个 JSON null 参数:

      SELECT audit_log_read('null');

      不需要显式关闭读取。读取将在会话结束或新读取序列被初始化时隐式关闭,例如调用 audit_log_read() 并指定开始位置。

  • 成功调用 audit_log_read() 读取事件将返回一个包含审核事件数组的 JSON 字符串:

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

    • 如果返回数组的最后一个值是 JSON null 值,则当前读取序列中没有更多事件需要读取。

    每个非 null 数组元素都是一个以 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() 之前返回了一个以 JSON null 值结尾的数组。

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

    要在这些条件下读取事件,需要首先通过调用 audit_log_read() 并指定一个位置来初始化读取序列。

要指定 audit_log_read() 的位置,需要包含一个指示从何处开始读取的参数。例如,传递一个书签,即一个包含 timestampid 元素的 JSON 哈希表,该哈希表唯一标识一个特定的事件。下面是一个通过调用 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() 的哈希表参数中,项目是可选的,控制读取操作的方面,例如从何处开始读取或读取多少事件。以下项目是重要的(其他项目将被忽略):

  • start:audit 日志中要读取的第一个事件的位置。该位置以时间戳形式给出,读取从该时间戳值或更晚的第一个事件开始。start 项的格式如下,其中 value 是一个文字时间戳值:

    "start": { "timestamp": "value" }
  • timestamp, id:audit 日志中要读取的第一个事件的位置。timestampid 项一起组成了一个书签,唯一标识一个特定的事件。如果 audit_log_read() 参数中包含任一项,必须包含两者以完全指定一个位置,否则将发生错误。

  • max_array_length:从日志中读取的最大事件数。如果省略该项,默认是读取到日志的末尾或读取缓冲区满,ichever comes first。

要指定audit_log_read()的起始位置,请传递一个哈希参数,该参数包括start项或包含timestampid项的书签。如果哈希参数同时包含start项和书签,将发生错误。

如果哈希参数不指定起始位置,读取将从当前位置继续。

如果时间戳值不包括时间部分,将假设时间部分为00:00:00

接受的audit_log_read()示例参数:

  • 从给定的时间戳开始读取事件:

    audit_log_read('{ "start": { "timestamp": "2020-05-24 12:30:00" } }')
  • 与前一个示例相同,但最多读取3个事件:

    audit_log_read('{ "start": { "timestamp": "2020-05-24 12:30:00" }, "max_array_length": 3 }')
  • 2020-05-24 00:00:00开始读取事件(时间戳不包括时间部分,因此假设为00:00:00):

    audit_log_read('{ "start": { "timestamp": "2020-05-24" } }')
  • 从具有确切时间戳和事件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 }')
  • 从当前读取序列的当前位置开始读取事件:

    audit_log_read()
  • 从当前读取序列的当前位置开始读取最多5个事件:

    audit_log_read('{ "max_array_length": 5 }')
  • 关闭当前读取序列:

    audit_log_read('null')

从任一日志读取函数返回的JSON字符串可以根据需要进行操作。假设调用以获取书签产生了以下值:

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个事件,请将字符串添加一个max_array_length项,值为该值。例如,要读取单个事件,请修改字符串如下:

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()时,将产生最多包含一个事件的结果,无论有多少事件可用。

在MySQL 8.0.19之前,审核日志函数返回的字符串值是二进制字符串。要使用二进制字符串与需要非二进制字符串的函数(例如,操作JSON值的函数),请将其转换为非二进制字符串。例如,在将书签传递给JSON_SET()之前,请将其转换为utf8mb4,如下所示:

SET @mark = CONVERT(@mark USING utf8mb4);

该语句即使在MySQL 8.3中也可以使用,对于这些版本来说,它基本上是一个no-op且无害。

如果从mysql客户端内部调用审核日志函数,二进制字符串结果将使用十六进制表示,取决于--binary-as-hex选项的值。有关该选项的更多信息,请参阅第 6.5.1 节,“mysql — MySQL 命令行客户端”

要设置audit_log_read()读取的字节数限制,可以设置audit_log_read_buffer_size系统变量。该变量的默认值为 32KB,可以在运行时设置。每个客户端都应该根据其使用audit_log_read()的情况设置适当的会话值audit_log_read_buffer_size

每次调用audit_log_read()都将返回尽可能多的可用事件,直到达到缓冲区大小。缓冲区大小不足的事件将被跳过并生成警告。因此,在评估应用程序的适当缓冲区大小时,需要考虑以下因素:

  • 在调用audit_log_read()的次数和每次调用返回的事件数之间存在权衡:

    • 使用较小的缓冲区大小,调用将返回较少的事件,因此需要更多的调用。

    • 使用较大的缓冲区大小,调用将返回更多的事件,因此需要较少的调用。

  • 使用较小的缓冲区大小,例如默认的 32KB 大小,有更高的可能性事件将超过缓冲区大小,从而被跳过。

有关审核日志读取函数的更多信息,请参阅审核日志函数