- VisualStudio2022插件的安装及使用-编程手把手系列文章
- pprof-在现网场景怎么用
- C#实现的下拉多选框,下拉多选树,多级节点
- 【学习笔记】基础数据结构:猫树
最近帮客户排查某问题时,因为怀疑应用对某张配置表有变更,所以需要对这张表的所有操作进行审计.
原本Oracle对某张表的审计是非常方便的,一条命令就可以实现,也不需要费心自定义审计表.
-- 启用对表DEPT的插入、更新和删除操作的审计
AUDIT INSERT, UPDATE, DELETE ON DEPT BY ACCESS;
-- 查看对DEPT表的所有审计记录
SELECT * FROM DBA_AUDIT_TRAIL WHERE OBJ_NAME = 'DEPT';
-- 停用对表DEPT的审计
NOAUDIT INSERT, UPDATE, DELETE ON DEPT;
但不幸的是,因为客户当前环境已经把默认开启的audit_trail给关闭了。(默认开启,默认值是DB,关闭就是NONE) 笔者已经在实验环境验证过:
尤其注意要检查这个参数的设置情况,因为这里比较坑的一点是,上述审计命令,即便你关了这个参数,开启表审计的命令执行也并不会报错,只是实际上无法记录.
相信大家都知道,生产环境的重启申请流程非常麻烦,因此只能用手工的方式,比如自定义触发器的方式来监控这张表的DML操作.
还好因为这个配置表正常情况下,并不会被频繁修改,所以使用触发器也不会带来什么性能问题.
下面就进入到hands-on环节,我们模拟下这个客户的需求,假设dept这张表
-- 创建示例表DEPT
CREATE TABLE dept (
deptno NUMBER(2) PRIMARY KEY,
dname VARCHAR2(14),
loc VARCHAR2(13)
);
-- 插入示例数据到DEPT表
INSERT INTO dept VALUES (10, 'ACCOUNTING', 'NEW YORK');
INSERT INTO dept VALUES (20, 'RESEARCH', 'DALLAS');
INSERT INTO dept VALUES (30, 'SALES', 'CHICAGO');
INSERT INTO dept VALUES (40, 'OPERATIONS', 'BOSTON');
commit;
针对dept表建立触发器如下:
-- CREATE TABLE
CREATE TABLE dml_audit(
modiy_time DATE,
table_name VARCHAR2(30),
deptno NUMBER(2),
modiy_type VARCHAR2(14),
dname VARCHAR2(14),
loc VARCHAR2(13)
);
CREATE OR REPLACE TRIGGER dept_trg
BEFORE INSERT OR DELETE OR UPDATE ON dept
FOR EACH ROW
BEGIN
IF inserting THEN
INSERT INTO dml_audit (modiy_time, table_name, deptno, modiy_type, dname, loc)
VALUES (sysdate, 'dept', :NEW.deptno, 'insert', :NEW.dname, :NEW.loc);
END IF;
IF deleting THEN
INSERT INTO dml_audit (modiy_time, table_name, deptno, modiy_type, dname, loc)
VALUES (sysdate, 'dept', :OLD.deptno, 'delete', :OLD.dname, :OLD.loc);
END IF;
IF updating THEN
INSERT INTO dml_audit (modiy_time, table_name, deptno, modiy_type, dname, loc)
VALUES (sysdate, 'dept', :OLD.deptno, 'update_before', :OLD.dname, :OLD.loc);
INSERT INTO dml_audit (modiy_time, table_name, deptno, modiy_type, dname, loc)
VALUES (sysdate, 'dept', :NEW.deptno, 'update_after', :NEW.dname, :NEW.loc);
END IF;
END;
/
测试下,确认delete、insert、update都可以监测到:
08:17:58 PRIMARY @DB0913_9DF_IAD -> JINGYU @DEMO2> select * from dml_audit;
no rows selected
Elapsed: 00:00:00.02
08:18:05 PRIMARY @DB0913_9DF_IAD -> JINGYU @DEMO2> delete from dept where deptno=10;
1 row deleted.
Elapsed: 00:00:00.22
08:18:41 PRIMARY @DB0913_9DF_IAD -> JINGYU @DEMO2> INSERT INTO dept VALUES (10, 'ACCOUNTING', 'NEW YORK');
1 row created.
Elapsed: 00:00:00.00
08:18:56 PRIMARY @DB0913_9DF_IAD -> JINGYU @DEMO2> update dept set LOC='China' where deptno=40;
1 row updated.
Elapsed: 00:00:00.04
08:19:25 PRIMARY @DB0913_9DF_IAD -> JINGYU @DEMO2> select * from dml_audit;
MODIY_TIME TABLE_NAME DEPTNO MODIY_TYPE DNAME LOC
------------------ ------------------------------ ---------- -------------- -------------- -------------
07-AUG-24 dept 10 delete ACCOUNTING NEW YORK
07-AUG-24 dept 10 insert ACCOUNTING NEW YORK
07-AUG-24 dept 40 update_before OPERATIONS BOSTON
07-AUG-24 dept 40 update_after OPERATIONS China
Elapsed: 00:00:00.01
是否万事大吉了呢?
其实不是,因为客户问题是怀疑这个表有被改动,而改动其实不仅仅局限于DML操作.
我们假设一种极端场景,如果一个操作是将这张表drop后重建,然后插入一样的数据.
这样的场景,仅靠上面的触发器就无法记录到。因为表被drop时,对应的触发器也会被删除。 因为触发器是依赖于表存在的对象,当表被删除时,触发器也会失去作用的对象.
比如有这样一个init的脚本,功能是直接对配置表进行了drop删除然后重新创建初始化数据:
@init
那要如何做才能监控到这种极端情况呢? 也不难,再建立一个针对DDL的触发器,如果对dept表有ddl操作也记录到指定日志表.
-- 创建审计表
CREATE TABLE ddl_audit (
event_time TIMESTAMP,
username VARCHAR2(30),
userhost VARCHAR2(30),
object_type VARCHAR2(30),
object_name VARCHAR2(30),
action VARCHAR2(30)
);
-- 创建 DDL 触发器
CREATE OR REPLACE TRIGGER ddl_trigger
AFTER CREATE OR DROP ON SCHEMA
DECLARE
v_username VARCHAR2(30);
v_userhost VARCHAR2(30);
BEGIN
SELECT USER, SYS_CONTEXT('USERENV', 'HOST') INTO v_username, v_userhost FROM DUAL;
IF ORA_DICT_OBJ_NAME = 'DEPT' THEN
INSERT INTO ddl_audit (
event_time, username, userhost, object_type, object_name, action
) VALUES (
SYSTIMESTAMP, v_username, v_userhost, ORA_DICT_OBJ_TYPE, ORA_DICT_OBJ_NAME, ORA_SYSEVENT
);
END IF;
END;
/
这样,如果真有这种DDL操作,也可以审计到,但需要注意,这个DDL的触发器的影响相对要大些,非必要情况先不要建。定位完问题后,及时删掉.
08:26:49 PRIMARY @DB0913_9DF_IAD -> JINGYU @DEMO2> select * from ddl_audit;
EVENT_TIME USERNAME USERHOST OBJECT_TYPE OBJECT_NAME ACTION
------------------------------ --------------- --------------- ------------------------------ --------------- ------------------------------
07-AUG-24 08.25.11.885875 AM JINGYU demo TABLE DEPT DROP
07-AUG-24 08.25.12.167304 AM JINGYU demo TABLE DEPT CREATE
07-AUG-24 08.25.59.989356 AM JINGYU demo TABLE DEPT DROP
07-AUG-24 08.26.00.061629 AM JINGYU demo TABLE DEPT CREATE
Elapsed: 00:00:00.01
可以看到,这样触发器的方式,虽然比审计笨重,但也可以实现对表无论是DDL还是DML的跟踪记录,有了这些操作痕迹,自然就方便客户去进一步排查问题了.
最后此篇关于使用触发器来审计表的DML、DDL操作的文章就讲到这里了,如果你想了解更多关于使用触发器来审计表的DML、DDL操作的内容请搜索CFSDN的文章或继续浏览相关文章,希望大家以后支持我的博客! 。
首先,我使用的是 11gR2 SQL> select * from v$version; BANNER ------------------------------------------------
在我的例子中,我有一个包含 2,976,977 条记录的 Mysql 表。该表在两列上有索引,我在更新和插入来自多个客户端的记录时使用了这两列。问题是更新或插入值花费了太多时间。有什么办法可以加快速度
按照目前的情况,这个问题不适合我们的问答形式。我们希望答案得到事实、引用或专业知识的支持,但这个问题可能会引发辩论、争论、投票或扩展讨论。如果您觉得这个问题可以改进并可能重新打开,visit the
我无法说服为什么我不能在 中添加 DML 操作Oracle 函数 特别是里面游标循环 .我觉得 Oracle 不支持游标循环内的 DML 操作。 如果我需要在游标循环内插入表格,我该怎么办?在其中创建
这个问题在这里已经有了答案: Solution to "cannot perform a DML operation inside a query"? (3 个答案) 关闭 9 年前。 我收到这个错
我正在使用数组 DML 操作来加速将大量记录插入 SQL 数据库。原理描述here 。如何使用此功能的示例代码: TFDQuery *FDQuery1; ... FDQuery1->SQL->Text
我对 Oracle 11g 上的 BULK COLLECT 逻辑有疑问。 存储过程中的原始逻辑是: PROCEDURE FOO(IN_FOO IN VARCHAR2) IS BEGIN FOR C
我正在从这样的批量插入操作中捕获错误: begin --bulk insert forall i in v_data.first .. v_data.last save excepti
这是我第一次发布问题,对于任何格式问题深表歉意。 我这里有一段代码: Code 但我不断收到错误:“在没有 GROUP BY 的聚合查询中,SELECT 列表的表达式 #1 包含非聚合列 'mysql
我已经在 MySQL 中创建了一个表 create table bittest (id int(11),constant bit(1) default b'0' ); 然后, insert into
对于给定的时间段(包括两个给定日期),例如 2002 年 12 月 1 日至 2003 年 7 月 31 日,找到在指定时间内至少拥有一张 EZ link 卡的人的集合。为了集合中的每个人,列出 (i
我的 MySQL 5.5 服务器已设置 autocommit=1。 我的存储过程有几个 DML,但没有明确的事务管理。 当我从 MySQL CLI 发出 call the_procedure() 时(
我有一个严重依赖 MySQL 回滚进行单元测试的 Spring/JDBC 应用程序。我发现,如果我在这些事务中执行某些 DDL 操作(即使是在临时表上),即使在正常的 DML 语句上,回滚也会失败。例
我正在尝试建立一个数据库,该数据库将根据 ID 号存储故事信息。现在我正在努力将上述信息放入表格中。我正在学习 python 和 sql,所以请耐心等待。 Pylint 告诉我在引用 title.in
我正在寻找一种使用 Pl/SQL 来检查由“立即执行”执行的语句是否为 dml 语句的方法。 最佳答案 可能有一个解决方案来检查查询字符串是否包含“INSERT”或“UPDATE”或... 但我认为这
我听说过有关数据库的术语 DDL 和 DML,但我不明白它们是什么。 它们是什么以及它们与 SQL 有何关系? 最佳答案 以下内容改编自这里MySQL What is DDL, DML and DCL
我听说过有关数据库的术语 DDL 和 DML,但我不明白它们是什么。 它们是什么以及它们与 SQL 有何关系? 最佳答案 以下内容改编自此处MySQL What is DDL, DML and DCL
hive :-创建表,AlterTable等完成需要一些后端DML(MetaStore)。 哪个类的人会做这些? 哪个类将从MetaStore获取数据库凭证? 最佳答案 您可以查看org.apache
我需要导出特定对象及其对 DML 的引用,然后另一个应用程序将使用 DML 获取文件并将其导入。数据库模式当然是相同的。 是否有一些工具可以做到这一点,或者我必须使用带选项的 mysql 转储? 我感
仅供引用 - 我不是开发人员,但在必须时编写代码:) 尝试编写一些 java 代码以批量方式更新数据库的多个记录。当我插入新行时,我正在查询另一个表以查找相关数据以添加相关日期。 代码似乎可以工作,但
我是一名优秀的程序员,十分优秀!