首页 > 数据库 > 国内数据库 > 达梦数据库,开启审计功能,对性能有多大损耗?
测试审计功能的性能损耗之前,需要先搞清楚,达梦的审计数据实际存储位置在哪?
1.V$AUDITRECORDS表记录审计数据,审计记录看着像是存储在达梦数据库内的;
2.有新审计数据时,又会生成或更新 AUDIT_CJC_***_2026-6-22-14-56-23.log 操作系统级别的审计文件;
那么审计数据,到底是存储在 操作系统文件?还是存储在数据库表里?还是两个地方都存储呢?
也就是 V$AUDITRECORDS 表数据来源是哪?
很好验证,把操作系统级别的审计文件重命名就可以,如果 V$AUDITRECORDS 查询不出审计数据了,就说明 审计数据仅存储在操作系统文件上:
查看审计文件:
[dmdba@cjc-db-11 audit]$ ls -lrth /dm8/audit/ total 900M -rw-r--r-- 1 dmdba dinstall 100M May 28 18:07 AUDIT_CJC_F3021903F30219036919E90E7841ABD7_2026-5-28-15-57-58.log -rw-r--r-- 1 dmdba dinstall 100M Jun 1 17:27 AUDIT_CJC_02C0502102C0502155732BE07841ABD7_2026-6-1-10-47-57.log -rw-r--r-- 1 dmdba dinstall 100M Jun 22 14:30 AUDIT_CJC_3E015A3F3E015A3F0CC06EF57841ABD7_2026-6-22-14-26-30.log -rw-r--r-- 1 dmdba dinstall 100M Jun 22 14:56 AUDIT_CJC_33A0A6F733A0A6F745E204287841ABD7_2026-6-22-14-56-23.log -rw-r--r-- 1 dmdba dinstall 100M Jun 22 15:05 AUDIT_CJC_9B4C9DE19B4C9DE1EF5B92BE7841ABD7_2026-6-22-14-56-33.log -rw-r--r-- 1 dmdba dinstall 100M Jun 22 15:06 AUDIT_CJC_8D78FFB88D78FFB808D258AA7841ABD7_2026-6-22-15-5-33.log -rw-r--r-- 1 dmdba dinstall 100M Jun 22 15:07 AUDIT_CJC_DBD2A321DBD2A32156F2C8AC7841ABD7_2026-6-22-15-6-50.log -rw-r--r-- 1 dmdba dinstall 100M Jun 22 15:09 AUDIT_CJC_EC5D2635EC5D26356E9316F87841ABD7_2026-6-22-15-7-42.log -rw-r--r-- 1 dmdba dinstall 100M Jun 22 15:17 AUDIT_CJC_8EE461368EE46136B1367EEE7841ABD7_2026-6-22-15-11-24.log
查看审计记录:
SQL> SELECT SQL_TEXT FROM V$AUDITRECORDS where username='CJC' and OBJNAME='SMALL_OPS_TEST' limit 3;
行号 SQL_TEXT
---------- -----------------------------------------------------------------------------------
1 DECLARE v_start NUMBER := DBMS_UTILITY.GET_TIME; BEGIN FOR i IN 1..100000 LOOP INSERT INTO SMALL_OPS_TEST VALUES (i, 'data_' || i); COMMIT; -- 每个 INSERT 都是一个独立的事务,产生一条审计记录 END LOOP; DBMS_OUTPUT.PUT_LINE('1 万次小事务耗时(百分秒): ' || (DBMS_UTILITY.GET_TIME - v_start)); END;
2 DECLARE v_start NUMBER := DBMS_UTILITY.GET_TIME; BEGIN FOR i IN 1..100000 LOOP INSERT INTO SMALL_OPS_TEST VALUES (i, 'data_' || i); COMMIT; -- 每个 INSERT 都是一个独立的事务,产生一条审计记录 END LOOP; DBMS_OUTPUT.PUT_LINE('1 万次小事务耗时(百分秒): ' || (DBMS_UTILITY.GET_TIME - v_start)); END;
3 DECLARE v_start NUMBER := DBMS_UTILITY.GET_TIME; BEGIN FOR i IN 1..100000 LOOP INSERT INTO SMALL_OPS_TEST VALUES (i, 'data_' || i); COMMIT; -- 每个 INSERT 都是一个独立的事务,产生一条审计记录 END LOOP; DBMS_OUTPUT.PUT_LINE('1 万次小事务耗时(百分秒): ' || (DBMS_UTILITY.GET_TIME - v_start)); END;
已用时间: 1.677(毫秒). 执行号:804.
重命名审计记录文件所在目录:
[dmdba@cjc-db-11 dm8]$ mv audit audit_bak
再次查询 V$AUDITRECORDS
SQL> SELECT SQL_TEXT FROM V$AUDITRECORDS where username='CJC' and OBJNAME='SMALL_OPS_TEST' limit 3; 未选定行 已用时间: 0.512(毫秒). 执行号:803. SQL> SELECT COUNT(*) FROM V$AUDITRECORDS; 行号 COUNT(*) ---------- -------------------- 1 0 已用时间: 0.939(毫秒). 执行号:805.
改回原名,可以查询到审计记录了
[dmdba@cjc-db-11 dm8]$ mv audit_bak audit
SQL> SELECT SQL_TEXT FROM V$AUDITRECORDS where username='CJC' and OBJNAME='SMALL_OPS_TEST' limit 3;
行号 SQL_TEXT
---------- -----------------------------------------------------------------------------------
1 DECLARE v_start NUMBER := DBMS_UTILITY.GET_TIME; BEGIN FOR i IN 1..100000 LOOP INSERT INTO SMALL_OPS_TEST VALUES (i, 'data_' || i); COMMIT; -- 每个 INSERT 都是一个独立的事务,产生一条审计记录 END LOOP; DBMS_OUTPUT.PUT_LINE('1 万次小事务耗时(百分秒): ' || (DBMS_UTILITY.GET_TIME - v_start)); END;
2 DECLARE v_start NUMBER := DBMS_UTILITY.GET_TIME; BEGIN FOR i IN 1..100000 LOOP INSERT INTO SMALL_OPS_TEST VALUES (i, 'data_' || i); COMMIT; -- 每个 INSERT 都是一个独立的事务,产生一条审计记录 END LOOP; DBMS_OUTPUT.PUT_LINE('1 万次小事务耗时(百分秒): ' || (DBMS_UTILITY.GET_TIME - v_start)); END;
3 DECLARE v_start NUMBER := DBMS_UTILITY.GET_TIME; BEGIN FOR i IN 1..100000 LOOP INSERT INTO SMALL_OPS_TEST VALUES (i, 'data_' || i); COMMIT; -- 每个 INSERT 都是一个独立的事务,产生一条审计记录 END LOOP; DBMS_OUTPUT.PUT_LINE('1 万次小事务耗时(百分秒): ' || (DBMS_UTILITY.GET_TIME - v_start)); END;
已用时间: 1.677(毫秒). 执行号:804.
SQL> SELECT COUNT(*) FROM V$AUDITRECORDS;
行号 COUNT(*)
---------- --------------------
1 200103
已用时间: 283.321(毫秒). 执行号:807.
可以看到,审计数据仅存储在 操作系统上的审计文件,没有存储在数据库内部。
测试场景如下:
启动和关闭也会记录审计日志,测试开启审计后,是否会影响达梦实例的启停速度
因为审计数据主要记录SQL文本等信息,模拟批量执行大量SQL,评估对性能的损耗
理论上开启审计,对大表查询影响很小,和数据量关系不大
理论上开启审计,对大表查询影响很小,和数据量关系不大
记录达梦数据库启动、关闭的时间:
启动:
[dmdba@cjc-db-11 ~]$ DmServiceCJC start Starting DmServiceCJC: [ OK ]
查看启动耗时:1.7 秒
[dmdba@cjc-db-11 log]$ tail -10f dm_CJC_202606.log 2026-06-22 14:32:07.525 [INFO] database P0000002507 T0000000000000002507 INI parameter DPC_2PC changed, the original value 1, new value 0 2026-06-22 14:32:07.531 [INFO] database P0000002507 T0000000000000002507 version info: enterprise ...... 2026-06-22 14:32:09.250 [INFO] database P0000002507 T0000000000000002507 local instance name is CJC, mode is NORMAL, status is OPEN. 2026-06-22 14:32:09.250 [INFO] database P0000002507 T0000000000000002507 SYSTEM IS READY. 2026-06-22 14:32:09.250 [INFO] database P0000002507 T0000000000000002507 [for dem]SYSTEM IS READY.
关闭:
SQL> shutdown immediate; 操作已执行 已用时间: 1.221(毫秒). 执行号:0.
查看关闭耗时: 9 秒
[dmdba@cjc-db-11 log]$ tail -10f dm_CJC_202606.log 2026-06-22 14:33:45.580 [INFO] database P0000002507 T0000000000000002528 Server is stopping... 2026-06-22 14:33:45.580 [INFO] database P0000002507 T0000000000000002528 listener closed and all sessions disconnected ...... 2026-06-22 14:33:54.875 [INFO] database P0000002507 T0000000000000002528 [for dem]SYSTEM SHUTDOWN SUCCESS. 2026-06-22 14:33:54.875 [INFO] database P0000002507 T0000000000000002528 DM Database Server shutdown successfully. 2026-06-22 14:33:54.875 [INFO] database P0000002507 T0000000000000002528 nsvr_notify_exit wakeup main thread to exit
-- 创建一个小型操作测试表 DROP TABLE IF EXISTS SMALL_OPS_TEST PURGE; CREATE TABLE SMALL_OPS_TEST ( ID INT PRIMARY KEY, VAL VARCHAR2(100) );
测试脚本(循环执行 10 万次单行插入,每次独立提交)
SET SERVEROUTPUT ON
DECLARE
v_start NUMBER := DBMS_UTILITY.GET_TIME;
BEGIN
FOR i IN 1..100000 LOOP
INSERT INTO SMALL_OPS_TEST VALUES (i, 'data_' || i);
COMMIT; -- 每个 INSERT 都是一个独立的事务,产生一条审计记录
END LOOP;
DBMS_OUTPUT.PUT_LINE('1 万次小事务耗时(百分秒): ' || (DBMS_UTILITY.GET_TIME - v_start));
END;
/
DMSQL 过程已成功完成
已用时间: 00:00:33.554. 执行号:523.
对 500 万行进行全表聚合计算。
SET TIMING ON; -- 清理老表 DROP TABLE IF EXISTS BIG_TABLE PURGE; DROP TABLE IF EXISTS BIG_TABLE_INSERT PURGE; DROP TABLE IF EXISTS UPDATE_BIG PURGE; -- 大表:500 万行 CREATE TABLE BIG_TABLE ( ID INT PRIMARY KEY, COL1 VARCHAR2(200), COL2 NUMBER, COL3 DATE ); INSERT INTO BIG_TABLE SELECT LEVEL, 'DATA_' || LEVEL, DBMS_RANDOM.VALUE(1, 100000), DATE '2025-01-01' + LEVEL/(24*60) FROM DUAL CONNECT BY LEVEL <= 5000000; COMMIT;
记录时间:
影响行数 5000000 已用时间: 00:00:34.044. 执行号:505. SQL> commit; 操作已执行 已用时间: 1.699(毫秒). 执行号:506.
– 收集统计信息
DBMS_STATS.GATHER_TABLE_STATS(USER, ‘BIG_TABLE’);
DMSQL 过程已成功完成
已用时间: 00:00:02.041. 执行号:507.
SELECT COUNT(*), AVG(COL2), MAX(COL3) FROM BIG_TABLE WHERE COL2 > 50000; 已用时间: 452.528(毫秒). 执行号:515.
将 500 万行全部插入到新建的空表中。
-- 创建空目标表 CREATE TABLE BIG_TABLE_INSERT AS SELECT * FROM BIG_TABLE WHERE 1=0; -- 批量写入测试 SET TIMING ON; INSERT INTO BIG_TABLE_INSERT SELECT * FROM BIG_TABLE; COMMIT;
耗时:
已用时间: 00:00:29.835. 执行号:509. SQL> commit; 操作已执行 已用时间: 1.389(毫秒). 执行号:510.
开启审计功能
CALL SP_SET_ENABLE_AUDIT(1);
配置审计策略
SQL> SP_AUDIT_STMT('ALL', 'CJC', 'ALL');
DMSQL 过程已成功完成
已用时间: 1.711(毫秒). 执行号:603.
查看审计策略
SQL> select * from SYSAUDITOR.SYSAUDIT; 行号 LEVEL UID TVPID COLID TYPE WHENEVER ---------- ----------- ----------- ----------- ----------- ----------- ----------- 1 1 -1 -1 -1 15 3 2 1 50331649 -1 -1 12 1 3 1 50331748 -1 -1 33 3 4 1 50331748 -1 -1 32 3 5 2 50331748 1049 1 50 1 6 1 50331748 -1 -1 0 3 6 rows got 已用时间: 1.247(毫秒). 执行号:602.
SELECT
"LEVEL",
CASE "LEVEL"
WHEN 1 THEN '语句级'
WHEN 2 THEN '对象级'
ELSE '其他'
END AS 审计级别,
UID AS 用户ID,
TVPID AS 对象ID,
COLID AS 列ID,
CASE "TYPE"
WHEN 0 THEN 'ALL'
WHEN 12 THEN 'SELECT'
WHEN 15 THEN 'DELETE'
WHEN 32 THEN 'EXECUTE'
WHEN 33 THEN 'INSERT'
WHEN 34 THEN 'UPDATE'
WHEN 50 THEN 'AUDIT'
ELSE '其他(' || "TYPE" || ')'
END AS 操作类型,
CASE "WHENEVER"
WHEN 1 THEN '仅成功'
WHEN 2 THEN '仅失败'
WHEN 3 THEN '不论成败'
ELSE '未知'
END AS 审计时机
FROM SYSAUDITOR.SYSAUDIT;
行号 LEVEL 审计级别 用户ID 对象ID 列ID 操作类型 审计时机
---------- ----------- ------------ ----------- ----------- ----------- ------------ ------------
1 1 语句级 -1 -1 -1 DELETE 不论成败
2 1 语句级 50331649 -1 -1 SELECT 仅成功
3 1 语句级 50331748 -1 -1 INSERT 不论成败
4 1 语句级 50331748 -1 -1 EXECUTE 不论成败
5 2 对象级 50331748 1049 1 AUDIT 仅成功
6 1 语句级 50331748 -1 -1 ALL 不论成败
6 rows got
已用时间: 0.578(毫秒). 执行号:702.
记录达梦数据库启动、关闭的时间:
启动:
[dmdba@cjc-db-11 ~]$ DmServiceCJC start Starting DmServiceCJC: [ OK ]
查看启动耗时:1.7 秒
[dmdba@cjc-db-11 log]$ tail -10f dm_CJC_202606.log 2026-06-22 14:32:07.525 [INFO] database P0000002507 T0000000000000002507 INI parameter DPC_2PC changed, the original value 1, new value 0 2026-06-22 14:32:07.531 [INFO] database P0000002507 T0000000000000002507 version info: enterprise ...... 2026-06-22 14:32:09.250 [INFO] database P0000002507 T0000000000000002507 local instance name is CJC, mode is NORMAL, status is OPEN. 2026-06-22 14:32:09.250 [INFO] database P0000002507 T0000000000000002507 SYSTEM IS READY. 2026-06-22 14:32:09.250 [INFO] database P0000002507 T0000000000000002507 [for dem]SYSTEM IS READY.
关闭:
SQL> shutdown immediate; 操作已执行 已用时间: 1.221(毫秒). 执行号:0.
耗时:8秒
2026-06-22 15:09:21.483 [INFO] database P0000003534 T0000000000000003555 Server is stopping... 2026-06-22 15:09:21.483 [INFO] database P0000003534 T0000000000000003555 listener closed and all sessions disconnected ...... 2026-06-22 15:09:29.729 [INFO] database P0000003534 T0000000000000003555 [for dem]SYSTEM SHUTDOWN SUCCESS. 2026-06-22 15:09:29.729 [INFO] database P0000003534 T0000000000000003555 DM Database Server shutdown successfully. 2026-06-22 15:09:29.729 [INFO] database P0000003534 T0000000000000003555 nsvr_notify_exit wakeup main thread to exit
– 创建一个小型操作测试表
DROP TABLE IF EXISTS SMALL_OPS_TEST PURGE; CREATE TABLE SMALL_OPS_TEST ( ID INT PRIMARY KEY, VAL VARCHAR2(100) );
测试脚本(循环执行 10 万次单行插入,每次独立提交)
SET SERVEROUTPUT ON
DECLARE
v_start NUMBER := DBMS_UTILITY.GET_TIME;
BEGIN
FOR i IN 1..100000 LOOP
INSERT INTO SMALL_OPS_TEST VALUES (i, 'data_' || i);
COMMIT; -- 每个 INSERT 都是一个独立的事务,产生一条审计记录
END LOOP;
DBMS_OUTPUT.PUT_LINE('1 万次小事务耗时(百分秒): ' || (DBMS_UTILITY.GET_TIME - v_start));
END;
/
DMSQL 过程已成功完成
已用时间: 00:00:33.560. 执行号:519.
对 500 万行进行全表聚合计算。
SET TIMING ON; -- 清理老表 DROP TABLE IF EXISTS BIG_TABLE PURGE; DROP TABLE IF EXISTS BIG_TABLE_INSERT PURGE; DROP TABLE IF EXISTS UPDATE_BIG PURGE; -- 大表:500 万行 CREATE TABLE BIG_TABLE ( ID INT PRIMARY KEY, COL1 VARCHAR2(200), COL2 NUMBER, COL3 DATE ); INSERT INTO BIG_TABLE SELECT LEVEL, 'DATA_' || LEVEL, DBMS_RANDOM.VALUE(1, 100000), DATE '2025-01-01' + LEVEL/(24*60) FROM DUAL CONNECT BY LEVEL <= 5000000; COMMIT;
记录时间:
已用时间: 00:00:39.448. 执行号:505. SQL> commit; 操作已执行 已用时间: 1.187(毫秒). 执行号:506.
– 收集统计信息
DBMS_STATS.GATHER_TABLE_STATS(USER, 'BIG_TABLE'); DMSQL 过程已成功完成 已用时间: 00:00:02.041. 执行号:507.
SELECT COUNT(*), AVG(COL2), MAX(COL3) FROM BIG_TABLE WHERE COL2 > 50000; 已用时间: 454.837(毫秒). 执行号:512.
将 500 万行全部插入到新建的空表中。
-- 创建空目标表 CREATE TABLE BIG_TABLE_INSERT AS SELECT * FROM BIG_TABLE WHERE 1=0; -- 批量写入测试 SET TIMING ON; INSERT INTO BIG_TABLE_INSERT SELECT * FROM BIG_TABLE; COMMIT;
影响行数 5000000 已用时间: 00:00:07.234. 执行号:514. SQL> commit; 操作已执行 已用时间: 1.809(毫秒). 执行号:515.
测试场景有限,仅供参考,测试的几个场景中,开启审计后,未发现有明显的性能损耗。
比较奇怪的地方是,开启审计后,大数据插入的速度反而比没开审计时变快了,重复执行了多次,都是开启审计后执行更快?

欢迎关注我的公众号《 IT小Chen》
来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/29785807/viewspace-3182995/ ,如需转载,请注明出处,否则将追究法律责任。