在日常数据库运维中,有时候需要溯源某部分数据的操作记录,而普通环境一般不会纳入外置审计系统,加之应用数据涉及人员/范围广,可能难以直观定位,此时我们可以通过一些小技巧来帮助我们追踪数据使用情况
以TEST.T1表的部分数据记录被删除为例,下面例举3种排查思路(以下措施均须提前开启,已删除的数据无法追踪)
达梦数据库内置数据库审计功能(默认关闭),由SYSAUDITOR进行审计策略配置。
从功能上可分为普通审计、实时审计,普通审计可以记录指定审计策略内的数据库历史操作,而实时审计能在此基础上对审计策略内的数据库行为进行分析,并加以干预;从粒度上可分为系统级、语句级、对象级,系统级主要记录数据库启停、升级等事件(开启审计功能即自动记录),语句级针对用户,记录指定类型的sql操作,对象级则针对数据库对象/用户,记录相关数据库行为。
由于我们有明确的审计对象(TEST.T1表)和明确的审计行为(delete语句),因此我们只需开启普通审计后记录对TEST.T1表的删除操作
登陆审计管理员账号
SYSAUDITOR/SYSAUDITOR
开启普通审计功能
SP_SET_ENABLE_AUDIT (1);
配置对应审计策略
--语句格式: SP_AUDIT_OBJECT (TYPE,USERNAME,SCHNAME,TVNAME,WHENEVER);
-- NULL 表示所有用户
SP_AUDIT_OBJECT('DELETE', 'NULL', 'TEST', 'T1', 'SUCCESSFUL');
开启后默认会在数据目录生成审计日志文件(可以通过配置文件更改),可以通过工具分析日志文件;
也可以通过系统表查询对应记录;
SELECT * FROM SYSAUDITOR.V$AUDITRECORDS where SCHNAME='TEST' and OBJNAME='T1';
达梦数据库开启慢日志功能后,默认是记录全部数据操作的,可以在sqllog.ini文件中进行配置,同时需要注意,慢日志只针对sql类型、执行时间、用户进行记录。
此种场景下我们选择记录执行时间大于0s的删除操作
登陆管理员账号
SYSDBA/SYSDBA
开启慢日志功能
SP_SET_PARA_VALUE(1,'SVR_LOG',1);
修改慢日志配置文件
vi sqllog
[SLOG_DEL]
FILE_PATH = /data/log #文件路径
SQL_TRACE_MASK = 5:28 # 5:del类型语句 ,28:参数值
修改慢日志记录的配置模块(默认存在SLOG_ALL,可以补充,也可以直接替换)
SP_SET_PARA_STRING_VALUE(1,'SVR_LOG_NAME','SLOG_DEL');
更新慢日志配置
SP_REFRESH_SVR_LOG_CONFIG();
设置完成后在配置的路径下找到对应的慢日志文件,可以通过工具分析日志文件;
可以利用触发器的特性,在T1表进行删除操作时,将删除相关的数据和操作人、时间等信息插入到一张表中,查询也能直观的通过表记录看出来,与审计、慢日志相比,触发器的功能更灵活,但是需要我们自己去设计触发的时机、动作。
登陆业务账号(需要有创建对象、查询系统视图权限)
先创建记录表,具体的字段取决于需要的信息,这里假设需额外记录T1表的C1字段
CREATE TABLE TEST.T1_DMLLOG(
LOGID INT PRIMARY KEY AUTO_INCREMENT,
DML_USER VARCHAR(128),
DML_CLIENT_IP VARCHAR(128),
DML_APPNAME VARCHAR(128),
DML_TIME TIMESTAMP(0),
DML_C1 VARCHAR(128),
DML_SQL_TEXT VARCHAR(1000)
);
创建触发器
CREATE OR REPLACE TRIGGER TEST.LOGDEL_T1
AFTER INSERT OR DELETE OR UPDATE ON TEST.T1 FOR EACH ROW
DECLARE
V_USER VARCHAR(128);
V_CLIENT_IP VARCHAR(128);
V_APPNAME VARCHAR(128);
V_C1 VARCHAR(128);
V_SQL_TEXT VARCHAR(1000);
BEGIN
-- 从V$SESSIONS找到操作的user/ip/原始sql等信息
SELECT USER_NAME,CLNT_IP,APPNAME,SQL_TEXT
INTO V_USER,V_CLIENT_IP,V_APPNAME,V_SQL_TEXT
FROM V$SESSIONS
WHERE SESS_ID = SYS_CONTEXT('USERENV', 'SESSIONID');
-- 这里可以补充插入和更新的操作,用来和删除记录做对照
IF INSERTING OR UPDATING THEN
INSERT TEST.T1_DMLLOG(DML_USER,DML_CLIENT_IP,DML_APPNAME,DML_TIME,DML_SQL_TEXT) VALUES(
V_USER,V_CLIENT_IP,V_APPNAME,SYSDATE,V_SQL_TEXT
);
-- 通过OLD关键字来找原始记录
ELSIF DELETING THEN
V_C1 := :OLD.C1;
INSERT TEST.T1_DMLLOG(DML_USER,DML_CLIENT_IP,DML_APPNAME,DML_TIME,DML_C1,DML_SQL_TEXT) VALUES(
V_USER,V_CLIENT_IP,V_APPNAME,SYSDATE,V_C1,V_SQL_TEXT
);
END IF;
END ;
通过我们创建的表查询对应记录;
select * from TEST.T1_DMLLOG;
文章
阅读量
获赞