一:审计数据的真实存储位置
测试审计功能的性能损耗之前,需要先搞清楚,达梦的审计数据实际存储位置在哪?
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.
可以看到,审计数据仅存储在 操作系统上的审计文件,没有存储在数据库内部。
二:开启审计记录的性能损耗
测试场景如下:
1.数据库启动和关闭
启动和关闭也会记录审计日志,测试开启审计后,是否会影响达梦实例的启停速度
2.执行大量SQL
因为审计数据主要记录SQL文本等信息,模拟批量执行大量SQL,评估对性能的损耗
3.大表查询
理论上开启审计,对大表查询影响很小,和数据量关系不大
4.大数据插入
理论上开启审计,对大表查询影响很小,和数据量关系不大
三:测试步骤如下:
未开启审计
1.数据库启动和关闭
记录达梦数据库启动、关闭的时间:
启动:
[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
2.执行大量SQL(执行10万条SQL)
-- 创建一个小型操作测试表
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.
3.大表查询
对 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.
4.大数据插入
将 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.
1.数据库启动和关闭
记录达梦数据库启动、关闭的时间:
启动:
[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
2.执行大量SQL(执行10万条SQL)
– 创建一个小型操作测试表
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.
3.大表查询
对 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.
4.大数据插入
将 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》




