深度解读RDS for MySQL 审计日志功能和原理

news/2025/1/22 8:06:29/文章来源:https://www.cnblogs.com/huaweiyun/p/18512497

本文分享自华为云社区《【华为云MySQL技术专栏】RDS for MySQL 审计日志功能介绍》,作者:GaussDB数据库。

1. 背景

在生产环境中,当数据库出现故障或问题时,运维人员需要快速定位出异常或者高危的SQL语句。这时,审计日志能够提供详细的记录,帮助追踪每个数据库操作的执行者、执行时间以及受影响的数据对象,从而大大加速故障排查和恢复流程。

 

MySQL企业版提供了审计日志插件,可以对数据库操作进行细粒度的审计。该插件支持记录用户登录、查询执行、数据修改等重要操作。然而,在MySQL社区版中,只是提供了审计日志的相关插件接口定义和功能描述,并不支持原生的审计日志功能。

 

为了弥补这一功能的缺失,华为云RDS for MySQL通过集成Percona公司开源的审计日志插件,实现了MySQL审计日志功能。该功能已在RDS for MySQL 5.7和RDS for MySQL 8.0版本中开放,满足了用户对数据库安全审计的需求,同时增强了数据库的合规性和可用性。

 

本文将以RDS for MySQL为研究对象,对于审计日志进行功能介绍和原理解析。

2. 功能参数介绍

当在RDS for MySQL上开启审计日志功能,用户可以通过SHOW variables LIKE 'audit%';语句查看与审计日志功能相关的变量名和参数值。

mysql> SHOW variables LIKE 'audit%';
+-------------------------------------+---------------+
| Variable_name                       | Value         |
+-------------------------------------+---------------+
| audit_log_anonymized_ip             |               |
| audit_log_buffer_size               | 1048576       |
| audit_log_csv2_escape               | OFF           |
| audit_log_csv2_old_separated_format | OFF           |
| audit_log_csv2_truncation           | ON            |
| audit_log_exclude_accounts          |               |
| audit_log_exclude_commands          |               |
| audit_log_exclude_databases         |               |
| audit_log_file                      | audit.log     |
| audit_log_flush                     | OFF           |
| audit_log_force_rotate              | OFF           |
| audit_log_format                    | CSV2          |
| audit_log_handler                   | FILE          |
| audit_log_include_accounts          |               |
| audit_log_include_commands          |               |
| audit_log_include_databases         |               |
| audit_log_policy                    | ALL           |
| audit_log_rotate_on_size            | 104857600     |
| audit_log_rotations                 | 50            |
| audit_log_strategy                  | ASYNCHRONOUS  |
| audit_log_syslog_facility           | LOG_USER      |
| audit_log_syslog_ident              | percona-audit |
| audit_log_syslog_priority           | LOG_INFO      |
+-------------------------------------+---------------+
23 rows in set (0.01 sec)

这些参数控制着审计日志插件的整体功能,允许用户灵活调节审计日志的各个方面。通过合理设置和调整这些参数,用户可以精确确定日志的记录范围、记录级别、存储方式等。例如,用户可以通过audit_log_policy 决定审计日志的记录级别,也可以通过改变audit_log_strategy 调整审计日志的刷新策略。

 

在 RDS for MySQL中,部分变量因安全合规考虑未开放修改。下表对审计日志功能中相关变量的作用和默认值进行介绍。

表格 1 审计日志变量介绍

3. 日志内容解析

在RDS for MySQL上,audit_log_policy的默认值为ALL。在该级别下,审计日志会记录包括DML(数据操作语言)、DDL(数据定义语言)、DCL(数据控制语言)操作以及连接或断开连接等数据库活动。需要注意的是,不同类型的活动包含的日志字段有所不同。下面将从常见DDL、DML、DCL操作以及数据库连接与断开连接产生的审计日志进行内容解析。

DDL、DML和DCL

对于DDL、DML和DCL操作,所生成的审计日志格式是相同的。对于日志字段的具体含义详见如下。

  • RECORD ID:审计日志唯一ID,用来标识每条审计日志。

  • STATUS:状态码,非0表示ERROR。

  • NAME:操作命令分类,QUERY、EXECUTE、QUIT、CONNECT等。

  • TIMESTAMP:记录日志发生的时间戳。

  • COMMAND_CLASS:记录DDL、DML和DCL操作的类型,SELECT、INSERT、DELETE等。

  • SQLTEXT:执行SQL语句的内容。

  • USER:连接数据库的用户名。

  • HOST:连接数据库的主机名。

  • IP:连接数据库的客户端IP地址。

  • DATABASE:连接指定的数据库名。

Connect和Disconnect

连接或断开连接事件,在用户登录成功或登录失败时均会有日志记录。与DDL和DDL操作产生的审计日志不同,连接事件产生审计日志增加了PRIV_USER、OS_LOGIN等字段,下面对于连接或断开连接产生的审计日志进行解析。

  • RECORD ID: 审计日志唯一ID,用来标识每条审计日志。

  • STATUS:状态码,非0表示ERROR。

  • NAME: 操作命令分类,QUERY、EXECUTE、QUIT、CONNECT等。

  • TIMESTAMP:记录日志发生的时间戳

  • USER:连接数据库的用户名。

  • PRIV_USER:经过身份验证的用户名。

  • OS_LOGIN:外部用户名。

  • PROXY_USER:代理用户名。

  • HOST:连接数据库的主机名。

  • IP:连接数据库的客户端IP地址。

  • DATABASE:连接指定的数据库名。

通过对审计日志内容的解析,用户不仅可以快速地查看任意时间段数据库的活动状态,还能够准确了解每条SQL语句的详情,包括执行的用户、时间戳、查询类型等关键信息。这样详细的记录为安全审查、问题排查以及性能优化提供了强有力的支撑。

4.RDS for MySQL审计日志原理浅析

RDS for MySQL审计功能的核心是通过不同类型的事件驱动审计日志插件完成对应类型日志的记录。在RDS for MySQL中一共支持两类事件,即一般事件和连接事件。一般事件可以理解为用户执行的DDL、DML和DCL语句。连接事件则是连接数据库(Connect)和断开连接(Disconnect)数据库。审计日志插件支持事件定义的相关代码如下。

static int is_event_class_allowed_by_policy(mysql_event_class_t event_class,num audit_log_policy_t policy) {static unsigned int class_mask[] = {/* ALL */(1 << MYSQL_AUDIT_GENERAL_CLASS) | (1 << MYSQL_AUDIT_CONNECTION_CLASS),0,                                   /* NONE */(1 << MYSQL_AUDIT_CONNECTION_CLASS), /* LOGINS */(1 << MYSQL_AUDIT_GENERAL_CLASS),    /* QUERIES */};return (class_mask[policy] & (1 << event_class)) != 0;
}

当发生可审计事件时,服务器会调用相关的审计接口,以便向已注册的审计日志插件传递该事件的信息,确保审计插件在必要时能够接收到并处理该事件。

 

审计日志功能在RDS for MySQL内核的入口函数是mysql_audit_notify。通过对应事件驱动审计日志插件的工作。主要工作流程调用栈如下所示。

  do_command->dispatch_commnad->mysql_audit_notify->event_class_dispatch// 检查当前插件是否需要处理此事件->plugin_dispatch// 按事件类别下发审计任务->audit_log_notify

数据库内核在收到一条SQL的执行请求后,首先,会通过do_command函数处理该连接。处理完成后,由dispatch_command函数依据不同SQL类型进行命令分发。之后,审计入口函数mysql_audit_notify会完成审计日志记录前的准备和校验工作。如果校验通过,则后续工作会由已注册的审计日志插件中的其他函数完成。

 

通过函数调用栈可以看出,审计日志功能与数据库内核之间实现了高度解耦。二者通过预先注册的函数接口进行对接,这种设计提高了未来功能扩展的灵活性。

 

审计日志插件的校验和资源准备工作由mysql_audit_acquire_plugins函数完成,当该函数完成校验后,即审计日志插件已完成注册并且相关资源也已完成绑定,接下来将由audit_log_notify函数按照事件的类型和相关参数设定完成任务分发。audit_log_notify会调用audit_log_write函数完成审计日志的写入,audit_log_write会依据audit_log_handler变量的值来判断是写入审计日志文件还是系统日志。

 

若是写入日志文件中,此时还会判断日志的写入策略;如果audit_log_strategy是PERFORMANCE或ASYNCHRONOUS,则会调用audit_handle_file_write_buf函数,将日志内容写入审计日志插件的缓冲区中,否则会调用audit_handle_file_write_nobuf函数,将日志内容直接写入操作系统文件缓存。

 

若audit_log_handler值为SYSLOG,则意味着审计日志会直接写到系统日志中。那么则会通过调用audit_handler_syslog_write完成日志向系统日志的写入。审计日志内部函数调用流程如图所示。

图1 审计日志插件工作流程图

从图中可以看到,审计日志的落盘方式主要有两种,分别是通过文件系统完成日志落盘和利用审计日志刷盘线程不断地将缓冲区的日志写入磁盘中。审计日志的缓冲区是在审计日志插件初始化时完成相关资源的分配,其结构体如下:

struct audit_log_buffer {// 缓冲区内容char *buf;// 缓冲区大小size_t size;// 写日志位置size_t write_pos;// 日志落盘位置size_t flush_pos;// 日志落盘工作线程pthread_t flush_worker_thread;// 缓冲区是否暂停int stop;// 缓冲区满是否丢弃该日志int drop_if_full;void *write_func_data;audit_log_write_func write_func;mysql_mutex_t mutex;mysql_cond_t flushed_cond;mysql_cond_t written_cond;log_record_state_t state;
};

从审计日志缓冲区结构体可以看到,日志缓冲区主要通过日志写入函数和日志落盘线程完成其核心功能。

 

当日志需要写入缓冲区时,首先会比较日志的长度和缓冲区的大小。如果审计日志的长度大于日志缓冲区的大小,并且缓冲区满且选择不丢弃该日志时,审计日志的落盘线程暂停工作,并会绕过日志的缓冲区,直接写入文件缓冲区中。当审计日志长度小于日志缓冲区大小时,此时会将日志的内容拷贝到文件缓冲区中,并更新缓冲区write_pos等相关参数,等待日志落盘线程的工作。如果当前写入位置超过整个缓冲区大小的一半,则会立刻通知落盘线程,完成审计日志的落盘。

 

审计日志的落盘工作主要由日志落盘工作线程完成。如果日志缓冲区没有关闭并且缓冲区中还存在日志尚未落盘,则会循环调用日志落盘函数进行日志写入。

static void *audit_log_flush_worker(void *arg) {audit_log_buffer_t *log = (audit_log_buffer_t *)arg;// 线程初始化my_thread_init();// 如果日志缓冲区没有关闭并且当前还有日志未落盘while (!(log->stop && log->flush_pos == log->write_pos)) {// 进行日志的落盘工作audit_log_flush(log);}// 关闭线程my_thread_end();return nullptr;
}

对于日志落盘函数,会通过循环判断write_pos和flush_pos是否相等,如果二者相等并且日志缓冲区没有停止工作,此时会等待1秒进入循环;如果二者不相等,说明缓冲区中有新的日志需要落盘。

 

此时,若write_pos大于缓冲区的大小,日志插件会把flush_pos后的所有日志进行落盘,并将当前日志的状态设为LOG_RECORD_INCOMPLETE。若write_pos在缓冲区大小范围内,则会将该条日志完整写入审计日志文件中并将该日志状态设为LOG_RECORD_COMPLETE。在完成日志落盘操作后,与缓冲区相关变量值会同步更新,并为下次日志落盘做好准备。

5.使用说明

1)数据库实例开启审计日志

登录管理控制台,在云数据库RDS for MySQL的“实例管理”页面,单击目标实例名称,进入基本信息页面。在左侧导航栏,点击“SQL审计”,在“SQL审计”右侧点击开启按钮,在弹框中点击“确定”,打开审计日志开关。

图2 设置审计日志功能

2)审计日志的下载

开启审计日志后,数据库的相关活动都会以日志的形式记录在OBS中,用户可以在控制台界面进行审计日志的下载。

图3 控制台界面下载审计日志

6.总结

RDS for MySQL的审计日志功能在用户活动监控、权限变更追踪和性能优化等方面有着重要的作用。它不仅帮助企业提升数据库的整体安全性,满足日益严格的合规性要求,还在故障排查中提供有价值的信息。这一功能能够精确的记录用户的数据库操作,有助于识别潜在的安全威胁,并为性能瓶颈分析和优化提供详实的数据支持。

 

华为开发者空间,汇聚鸿蒙、昇腾、鲲鹏、GaussDB、欧拉等各项根技术的开发资源及工具,致力于为每位开发者提供一台云主机、一套开发工具及云上存储空间,让开发者基于华为根生态创新。

点击链接,免费领取您的专属云主机~

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/823606.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

HyperWorks的RT功能及使用技巧

在Altair(HyperWorks)里,当结构中包含 T 型、X 型或更复杂的连接特征(图 2-12 所示)时,此功能非常有效。不适用于没有 T 型连接的特征(图 2-12 右侧)。图 2-12 带有 T 型特征的模型如果 R/T(半径/厚度)大于面板指定值,这个特征不被识别为目标连接特征。 -如果某个连…

GaussDB技术解读——GaussDB架构介绍之数据持久化存取层(DataNode)关键技术方案

数据持久化存取层(DataNode)关键技术方案 Datanode节点主要负责数据的持久化和快速写入、读取。数据持久化采用物理日志wal,事务提交wal刷盘, 对外提供逻辑日志功能,反解析物理日志为SQL逻辑日志。图1 datanode数据持久化 Astore:存储格式为追加写优化设计,其多版本元组采…

GaussDB企业级AI-Native分布式数据库

华为 GaussDB 是一个企业级 AI-Native 分布式数据库。GaussDB 采用 MPP(Massive Parallel Processing)架构,支持行存储与列存储,提供 PB(Petabyte,2 的 50 次方字节)级别数据量的处理能力。 华为Gauss数据库是全球首款AI-Native数据库,能够同时支持X86、ARM、GPU、NPU 等异…

国家代码和国家地区代码有什么区别

​​国家代码和国家地区代码的区别主要体现在:1.定义及用途不同;2.格式和结构差异;3.颁发机构不同;4.应用范围有别;国家代码通常是ISO标准中定义的,如ISO 3166-1中的两位或三位字母代码,而国家地区代码可能包括电话区号、邮政编码等,且格式更为多样。了解这些差异对于处…

CNCC2024:网易伏羲主题分论坛圆满落幕,专家共论推动产学研深度融合

10月26日,为期三天的2024中国计算机大会(CNCC2024)在浙江省东阳市横店镇圆明新园顺利落下帷幕。本届大会以“发展新质生产力,计算引领未来”为主题,吸引了数万名计算领域专业人士参会。本次大会邀请到了17位国内院士,800余位国内外顶尖学者、企业技术精英,通过特邀报告、…

在TMOS系统的不同taskID间交互数据

目录 TMOS系统中,每个taskID下都预留了一个事件编号0x8000,用于在不同的taskID中传递数据。由于0x8000占据了一个事件编号,故每个taskID下,用户只能最多自定义15个事件。 不同的taskID可以用于将不同的功能划分到不同的作用域中,将代码模块化,方便管理和移植。比如说某个…

Swagger UI、RESTful简介

Swagger UI 简介Swagger UI允许任何人(无论您是开发团队还是最终用户)都可以可视化API资源并与之交互,而无需任何实现逻辑。它是根据您的OpenAPI(以前称为Swagger)规范自动生成的,具有可视化文档,可简化后端实现和客户端使用。 SwaggerUI 特点无依赖 UI可以在任何开发环…

Ubuntu QTCreator 程序打包

下载linuxdeployqt官网地址:https://github.com/probonopd/linuxdeployqt/releases安装更改名字 mv linuxdeployqt-6-x86_64.AppImage linuxdeployqtView Code修改权限 chmod 777 linuxdeployqtView Code全局访问 sudo mv linuxdeployqt /usr/local/binView Code测试 linuxdep…

❗Vue中常见的性能优化(被问到要尽可能说全呀cc!!!)

Webpack层级的优化(后面会讲) 前端通用的性能优化,如图片懒加载 使用SSR

算法与数据结构——计数排序

计数排序 计数排序(counting sort)通过统计元素数量来实现排序,通常应用于整数数组。 简单实现 给定一个长度为n的数组nums,其中的元素都是“非负整数”,计数排序的整体流程如下:遍历数组,找出其中最大的数组,记为m,然后创建一个长度为 m+1 的辅助数组counter。 借助c…

二分类结果评估指标

TP(True Positive):真正例,真值和预测值都是正例FP(False Positive):假正例,真值是负例,预测值是正例FN(False Negative):假负例,真值是正例,预测值是负例TN(True Negative):真负例,真值和预测值都是负例Accuracy(准确率):对于给定的测试数据集,分类器正…

GaussDB的行存表与列存表的选择

一、前言 行存表和列存表是数据库中两种常见的数据存储方式。随着信息技术的飞速发展,数据存储和管理以及如何高效地存储和处理大量的数据已经成为了我们的一大挑战。 为了解决这个问题,行存表与列存表应运而生,它们以其独特的优势在各个场景得到了高效的应用。GaussDB支持行…