Oracle对数据库行和数据库的监控

前言:


  Oracle对表的监控分为数据行修改DML的监控、对表的DDL监控
 

1、对表的DML监控(数据的增删改)


-- 创建测试表
create table tab_test01(
id varchar2(100) default sys_guid(),
name varchar2(100),
insert_date date default sysdate
);

drop table tab_test01_his purge;

create table tab_test01_his(
id_his varchar2(100) ,
name_his varchar2(100),
insert_date_his date ,
insert_date date,
dml_type varchar2(10)
);


insert into tab_test01(name)
select 'bbbbb' from dual;
commit;

select * from tab_test01_his;

select * from tab_test01;

update tab_test01 set name ='dddd' where id ='1DF67A1619850FA3E06540BE7B5E5EA3';
commit;


-- 创建触发器,
create or replace trigger tri_tab_test01
after insert or update or delete on c##djj.tab_test01
    for each row
  begin
    if inserting then
      insert into tab_test01_his values(:new.id,:new.name,:new.insert_date, sysdate, 'insert');
    elsif updating then
      insert into tab_test01_his values(:old.id,:old.name,:old.insert_date, sysdate, 'update');
    else
      insert into tab_test01_his values(:old.id,:old.name,:old.insert_date, sysdate, 'delete');
    end if;
  end;

CREATE OR REPLACE TRIGGER your_trigger_name
AFTER INSERT OR UPDATE OR DELETE ON your_table_name
FOR EACH ROW
DECLARE
    action_taken VARCHAR2(30);
BEGIN
    IF INSERTING THEN
        action_taken := 'INSERT';
    ELSIF UPDATING THEN
        action_taken := 'UPDATE';
    ELSE
        action_taken := 'DELETE';
    END IF;
 
    INSERT INTO audit_table (table_name, row_id, action, user_name, timestamp)
    VALUES ('YOUR_TABLE_NAME', :NEW.id, action_taken, USER, SYSTIMESTAMP);
END;


2、对表的DDL操作的监控

-- 创建用户和授权
#需要使用sys用户授权

create user c##djj identified by abcABC123##  
default tablespace org12c  
temporary tablespace org12c_temp;  

GRANT CONNECT TO c##djj;
GRANT RESOURCE TO c##djj;
GRANT CREATE VIEW TO c##djj;
GRANT UNLIMITED TABLESPACE TO c##djj;
GRANT SELECT ANY TABLE TO c##djj;
ALTER USER c##djj DEFAULT ROLE ALL;
GRANT select on SYS.V_$OPEN_CURSOR TO c##djj;


-- 建日志表
DROP SEQUENCE SEQ_DDL_VERSION;
CREATE SEQUENCE SEQ_DDL_VERSION INCREMENT BY 1 START WITH 1 NOMAXVALUE NOMINVALUE NOCYCLE NOCACHE;

CREATE TABLE TB_SYSTEM_DDL_LOGS 
(
   EVENT_ID             VARCHAR2(32)         DEFAULT SYS_GUID() NOT NULL,
   EVENT_NAME           VARCHAR2(20),
   TERMINAL             VARCHAR2(50),
   DB_NAME              VARCHAR2(50),
   OBJECT_NAME          VARCHAR2(30),
   OBJECT_NAME_LIST     VARCHAR(300),
   OBJECT_OWNER         VARCHAR2(30),
   OBJECT_TYPE          VARCHAR2(20),
   IS_ALTER_COLUMN      VARCHAR(10),
   IS_DROP_COLUMN       VARCHAR(10),
   SQL_ID               VARCHAR(13),
   SQL_TEXT             CLOB,
   CURRENT_USER         VARCHAR(30),
   CURRENT_USERID       NUMBER,
   SESSION_USER         VARCHAR(10),
   SESSION_USERID       NUMBER,
   PROXY_USER           VARCHAR(30),
   PROXY_USERID         NUMBER,
   CURRENT_SCHEMA       VARCHAR(30),
   HOST                 VARCHAR(100),
   OS_USER              VARCHAR(60),
   IP_ADDRESS           VARCHAR(32),
   DDL_TIME             DATE                 DEFAULT SYSDATE,
   SESSION_ID           VARCHAR(32),
   VERSION_NO           NUMBER,
   CONSTRAINT PK_TB_SYSTEM_DDL_LOGS PRIMARY KEY (EVENT_ID)
);

COMMENT ON TABLE TB_SYSTEM_DDL_LOGS IS
'【数据库日志】DDL日志表';

COMMENT ON COLUMN TB_SYSTEM_DDL_LOGS.EVENT_ID IS
'事件ID自动生成';

COMMENT ON COLUMN TB_SYSTEM_DDL_LOGS.EVENT_NAME IS
'事件名称';

COMMENT ON COLUMN TB_SYSTEM_DDL_LOGS.TERMINAL IS
'客户端操作系统终端的名称';

COMMENT ON COLUMN TB_SYSTEM_DDL_LOGS.DB_NAME IS
'数据库名称';

COMMENT ON COLUMN TB_SYSTEM_DDL_LOGS.OBJECT_NAME IS
'DDL发生的对象名称';

COMMENT ON COLUMN TB_SYSTEM_DDL_LOGS.OBJECT_NAME_LIST IS
'对象列表';

COMMENT ON COLUMN TB_SYSTEM_DDL_LOGS.OBJECT_OWNER IS
'DDL发生对象的宿主';

COMMENT ON COLUMN TB_SYSTEM_DDL_LOGS.OBJECT_TYPE IS
'对象类别';

COMMENT ON COLUMN TB_SYSTEM_DDL_LOGS.IS_ALTER_COLUMN IS
'当列被修改的时候为真,否则为假 ';

COMMENT ON COLUMN TB_SYSTEM_DDL_LOGS.IS_DROP_COLUMN IS
'当列被DROP的时候为真,否则为假 ';

COMMENT ON COLUMN TB_SYSTEM_DDL_LOGS.SQL_ID IS
'SQL_ID';

COMMENT ON COLUMN TB_SYSTEM_DDL_LOGS.SQL_TEXT IS
'SQL语句';

COMMENT ON COLUMN TB_SYSTEM_DDL_LOGS.CURRENT_USER IS
'当前SESSION拥有权限的用户的名称(比如说当前SESSION是SYS,但是正在执行system.myproc,那么current_user就是system)';

COMMENT ON COLUMN TB_SYSTEM_DDL_LOGS.CURRENT_USERID IS
'当前SESSION拥有的权限的用户的ID';

COMMENT ON COLUMN TB_SYSTEM_DDL_LOGS.SESSION_USER IS
'session所属的用户名';

COMMENT ON COLUMN TB_SYSTEM_DDL_LOGS.SESSION_USERID IS
'当前SESSION所属的用户id';

COMMENT ON COLUMN TB_SYSTEM_DDL_LOGS.PROXY_USER IS
'打开当前SESSION的用户的名称';

COMMENT ON COLUMN TB_SYSTEM_DDL_LOGS.PROXY_USERID IS
'打开当前SESSION的用户的ID';

COMMENT ON COLUMN TB_SYSTEM_DDL_LOGS.CURRENT_SCHEMA IS
'当前SESSION缺省的SCHEMA名称,可以用SESSION SET CURRENT_SCHEMA语句修改';

COMMENT ON COLUMN TB_SYSTEM_DDL_LOGS.HOST IS
'客户端的主机名称';

COMMENT ON COLUMN TB_SYSTEM_DDL_LOGS.OS_USER IS
'客户端的操作系统用户名';

COMMENT ON COLUMN TB_SYSTEM_DDL_LOGS.IP_ADDRESS IS
'客户端的IP地址';

COMMENT ON COLUMN TB_SYSTEM_DDL_LOGS.DDL_TIME IS
'修改时间';

COMMENT ON COLUMN TB_SYSTEM_DDL_LOGS.SESSION_ID IS
'SESSION_ID';

COMMENT ON COLUMN TB_SYSTEM_DDL_LOGS.VERSION_NO IS
'版本号';


select * from TB_SYSTEM_DDL_LOGS

-- 创建触发器,在dba的用户下执行
CREATE OR REPLACE TRIGGER TRIG_MONITOR_SYSTEM_DDL
AFTER DDL ON DATABASE
/**
 * 创建时间:2024年7月24日 16:46:38
 * 描述:监控DDL操作并将DDL操作及DDL语句记录到日志表中
   */
   DECLARE
     PRAGMA AUTONOMOUS_TRANSACTION;
     TR_EVENT_ID VARCHAR2(32);
     TR_TERMINAL VARCHAR2(50);
     TR_IPADDR VARCHAR2(30);
     TR_CUR_USER VARCHAR2(30);
     TR_CUR_USERID NUMBER;
     TR_SE_USER VARCHAR2(30);
     TR_SE_USERID NUMBER;
     TR_PROXY_USER VARCHAR2(30);
     TR_PROXY_USERID NUMBER;
     TR_CUR_SC VARCHAR2(30);
     TR_HOST VARCHAR2(100);
     TR_OS_USER VARCHAR2(60);
 TR_SESSIONID VARCHAR2(32);
     TR_SQL_ID VARCHAR2(13);
     TR_SQL VARCHAR2(60);
     TR_VERSION_NO NUMBER;
     TR_N NUMBER;
     TR_STMT CLOB := NULL;
     TR_SQL_TEXT ORA_NAME_LIST_T;
   BEGIN
     TR_EVENT_ID := SYS_GUID();
     --获取用户信息
     SELECT NVL(SYS_CONTEXT('USERENV','TERMINAL'),''),--客户端操作系统终端的名称
            NVL(SYS_CONTEXT('USERENV','IP_ADDRESS'),''),--客户端操作系统终端的名称
            NVL(SYS_CONTEXT('USERENV','CURRENT_USER'),''),--当前SESSION拥有权限的用户的名称(比如说当前SESSION是SYS,但是正在执行SYSTEM.MYPROC,那么CURRENT_USER就是SYSTEM)
            NVL(SYS_CONTEXT('USERENV','CURRENT_USERID'),''),--当前SESSION拥有的权限的用户的ID
            NVL(SYS_CONTEXT('USERENV','SESSION_USER'),''),--SESSION所属的用户名
            NVL(SYS_CONTEXT('USERENV','SESSION_USERID'),''),--当前SESSION所属的用户ID
            NVL(SYS_CONTEXT('USERENV','PROXY_USER'),''),--打开当前SESSION的用户的名称
            NVL(SYS_CONTEXT('USERENV','PROXY_USERID'),''),--打开当前SESSION的用户的ID
        NVL(SYS_CONTEXT('USERENV','CURRENT_SCHEMA'),''),--当前SESSION缺省的SCHEMA名称
            NVL(SYS_CONTEXT('USERENV','HOST'),''),--客户端的主机名称
            NVL(SYS_CONTEXT('USERENV','OS_USER'),''),--客户端的操作系统用户名
            NVL(SYS_CONTEXT('USERENV','SESSIONID'),'')--SESSION的ID
     INTO TR_TERMINAL,TR_IPADDR,TR_CUR_USER,TR_CUR_USERID,TR_SE_USER,TR_SE_USERID,TR_PROXY_USER,TR_PROXY_USERID,
          TR_CUR_SC,TR_HOST,TR_OS_USER,TR_SESSIONID
     FROM DUAL;

 --获取DDL SQL语句,如果语句过长无法全部获得,可以根据SQL_ID查询
     BEGIN
      SELECT SQL_TEXT,SQL_ID INTO TR_SQL,TR_SQL_ID
          FROM SYS.V_$OPEN_CURSOR
          WHERE UPPER(SQL_TEXT) LIKE 'ALTER%'
                OR UPPER(SQL_TEXT) LIKE 'CREATE%'
            OR UPPER(SQL_TEXT) LIKE 'DROP%';

          TR_N := ORA_SQL_TXT(TR_SQL_TEXT);
       
          FOR I IN 1 .. TR_N LOOP
        TR_STMT := TR_STMT || TR_SQL_TEXT(I);
          END LOOP;
       
         EXCEPTION WHEN OTHERS THEN
          TR_SQL_ID := NULL;
          TR_STMT := NULL;

     END;

     --向TB_SYSTEM_DDL_LOGS日志表中插入DDL操作记录
     IF ORA_SYSEVENT <> 'TRUNCATE' AND ORA_DICT_OBJ_NAME NOT LIKE 'SYS_C%' THEN
       SELECT SEQ_DDL_VERSION.NEXTVAL INTO TR_VERSION_NO FROM DUAL;
       INSERT INTO C##DJJ.TB_SYSTEM_DDL_LOGS
             (EVENT_ID,EVENT_NAME,TERMINAL,DB_NAME,OBJECT_NAME,OBJECT_OWNER,OBJECT_TYPE,
             IS_ALTER_COLUMN,IS_DROP_COLUMN,SQL_ID,SQL_TEXT,SESSION_ID,
             CURRENT_USER,CURRENT_USERID,SESSION_USER,SESSION_USERID,
         PROXY_USER,PROXY_USERID,CURRENT_SCHEMA,HOST,OS_USER,IP_ADDRESS,VERSION_NO)
   VALUES (TR_EVENT_ID,ORA_SYSEVENT,TR_TERMINAL,ORA_DATABASE_NAME,ORA_DICT_OBJ_NAME,ORA_DICT_OBJ_OWNER,ORA_DICT_OBJ_TYPE,
         NULL,NULL,TR_SQL_ID,TR_STMT,TR_SESSIONID,
         TR_CUR_USER,TR_CUR_USERID,TR_SE_USER,TR_SE_USERID,
          TR_PROXY_USER,TR_PROXY_USERID,TR_CUR_SC,TR_HOST,TR_OS_USER,TR_IPADDR,TR_VERSION_NO
    );
    COMMIT;
  END IF;
END;


-- 测试
create table test_a 
  (
   EVENT_ID             VARCHAR2(32)   
  );
  
--查看日志表
SELECT * FROM TB_SYSTEM_DDL_LOGS ORDER BY VERSION_NO;

SELECT * FROM TB_SYSTEM_DDL_LOGS;

-- 将监控结果,写入本地文件
-- 在oracle中创建java sources
create or replace and compile java source named ddl_write as
import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.IOException;
public class OracleDDLWrite {
  public static void writeDDL(String path, String data) {
    BufferedWriter writer = null;
    if (data == null || data.length() == 0) {
      return;
    }
    try {
      writer = new BufferedWriter(new FileWriter(path, true));
      System.out.println("开始写文件,文件名称全路径 :" + path);
      writer.write(data);
      writer.newLine();
      System.out.println("写文件结束");
    } catch (IOException e) {
      e.printStackTrace();
    } finally {
      if (writer != null) {
        try {
          writer.close();
        } catch (IOException e) {
          e.printStackTrace();
        }
      }
    }
  }
}

--创建存储过程
create or replace procedure ddl_writer_procedure(path varchar2,data varchar2)

as language java name

'OracleDDLWrite.writeDDL(java.lang.String,java.lang.String)';


 

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

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

相关文章

学习日记:数据类型2

目录 1.转义字符 2.隐式类型转换 2.1 强制类型转换 2.2 不同类型间赋值 3.运算符 表达式 3.1 算术运算符 3.2 算术运算优先级 3.3 赋值运算 3.3.1 不同类型间混合赋值 3.4 逗号运算 4.生成随机数 5. 每日一练 1.转义字符 \n 表示换行 \t …

基于JSP、java、Tomcat三者的项目实战--校园交易网(1)-项目搭建(前期准备工作)

这是项目的初始页面 接下来我先写下我的初始项目搭建 技术支持&#xff1a;JAVA、JSP 服务器&#xff1a;TOMCAT 7.0.86 编程软件&#xff1a;IntelliJ IDEA 2021.1.3 x64 首先我们打开页面&#xff0c;准备搭建项目的初始准备 1.New Project 2.随后点击Next&#xff0c;勾…

Easy es问题总结

官网教程&#xff1a;https://www.easy-es.cn/pages/ac41f0/#settings 一 测试项目 1 pom <dependencies><!-- 排除springboot中内置的es依赖,以防和easy-es中的依赖冲突--><dependency><groupId>org.springframework.boot</groupId><artifa…

【Golang 面试基础题】每日 5 题(七)

✍个人博客&#xff1a;Pandaconda-CSDN博客 &#x1f4e3;专栏地址&#xff1a;http://t.csdnimg.cn/UWz06 &#x1f4da;专栏简介&#xff1a;在这个专栏中&#xff0c;我将会分享 Golang 面试中常见的面试题给大家~ ❤️如果有收获的话&#xff0c;欢迎点赞&#x1f44d;收藏…

脊髓小伙伴必看!超全维生素补给站,助力你的每一天活力满满✨

今天咱们来聊聊一个既严肃又暖心的话题——脊髓损伤后的维生素大补帖&#xff01;&#x1f31f; 记住&#xff0c;身体是革命的本钱&#xff0c;补充对的维生素&#xff0c;就是给自己的小宇宙加油哦&#xff01;&#x1f680; 首先&#xff0c;维生素D小太阳&#x1f31e;来啦…

Nestjs使用Redis的最佳实践

前几天在项目中有用到Redis JWT实现服务端对token的主动删除(退出登录功能)。故此介绍下如何在Nestjs中使用Redis&#xff0c;并做下总结。 知识准备 了解Redis - 网上很多简介。了解Nestjs如何使用jwt生成token - 可移步看下我之前的文章 效果展示 一、mac安装与使用 示…

在Webpack中,常见的loader有哪些?

在Webpack中&#xff0c;有许多常见的Loader用于处理不同类型的文件。以下是一些常见的Loader及其主要作用&#xff1a; babel-loader&#xff1a;用于将ES6/ES7等新版本的JavaScript代码转换为向后兼容的旧版本JavaScript代码&#xff0c;以确保在不支持新特性的浏览器…

【矩阵微分】在不涉及张量的前提下计算矩阵对向量的导数并写出二阶泰勒展开

本篇内容摘自CMU 16-745最优控制的第10讲 “Nonlinear Trajectory Optimization”。 如何在不涉及张量运算的前提下&#xff0c;计算矩阵对向量的导数并写出二阶泰勒展开 在多维微积分中&#xff0c;计算矩阵对向量的导数和二阶泰勒展开是一项重要的任务。本文将介绍如何在不涉…

使用命令快速删除项目中的node_modules

描述 直接调用了系统自带的命令行工具&#xff0c;无需额外安装任何第三方库或工具。 同时&#xff0c;这些命令经过优化&#xff0c;能够快速处理大量文件&#xff0c;从而实现快速删除。 步骤 1、进入项目文件夹&#xff1b; 2、如果是Mac/Linux 环境下&#xff0c;执行&a…

php--序列化与反序列化

&#x1f3bc;个人主页&#xff1a;金灰 &#x1f60e;作者简介:一名简单的大一学生;易编橙终身成长社群的嘉宾.✨ 专注网络空间安全服务,期待与您的交流分享~ 感谢您的点赞、关注、评论、收藏、是对我最大的认可和支持&#xff01;❤️ &#x1f34a;易编橙终身成长社群&#…

机器学习 | 计算分类算法的ROC和AUC曲线以随机森林为例

受试者工作特征&#xff08;ROC&#xff09;曲线和曲线下面积&#xff08;AUC&#xff09;是常用的分类算法评价指标&#xff0c;本文将讨论如何计算随机森林分类器的ROC 和 AUC。 ROC 和 AUC是量化二分类区分阳性和阴性类别能力的度量。ROC曲线是针对不同分类阈值的真阳性率&…

云计算day13

一、Git 概述 Git 是一种分布式版本控制系统&#xff0c;用于跟踪和管理代码的变更。它是由 Linus Torvalds 创建的&#xff0c;最初被设计用于 Linux 内核的开发。Git 允许开发 人员跟踪和管理代码的版本&#xff0c;并且可以在不同的开发人员之间进行协作。 Github 用的就…

C#:通用方法总结—第4集

大家好&#xff0c;今天接着写我们的通用方法总结分享。 下面是今天要分享的通用方法&#xff1a; &#xff08;1&#xff09;通过输入信息&#xff0c;返回合并的单元格内容。这个方法比较好用&#xff0c;适合在有合并的单元格时候使用。 /// <summary> /// 返回合并…

LabVIEW座舱照明测控系统

用LabVIEW开发飞机座舱照明测控系统。系统通过集成可靠的硬件与软件技术&#xff0c;提高了测试的效率和自动化水平&#xff0c;确保了飞行安全性和舒适性。体现了系统的设计思路、主要组成部分、工作原理及实际应用效果。 项目背景 飞机座舱照明系统是航空电子系统中至关重要…

【Spring Boot教程:从入门到精通】掌握Spring Boot开发技巧与窍门(三)-配置git环境和项目创建

主要介绍了如何创建一个Springboot项目以及运行Springboot项目访问内部的html页面&#xff01;&#xff01;&#xff01; 文章目录 前言 配置git环境 创建项目 ​编辑 在SpringBoot中解决跨域问题 配置Vue 安装Nodejs 安装vue/cli 启动vue自带的图形化项目管理界面 总结 前言 …

数组常见的实例方法

这里写目录标题 一级目录二级目录三级目录 一、数组中map方法&#xff0c;迭代数组1.作用&#xff1a;2.语法&#xff1a;3.注意: 二、遍历数组foreach方法三、筛选数组filter1.语法2.主要使用场景3.例子 四、累计器reduce五、数组中join方法1.作用&#xff1a;2.语法:3.参数 六…

谷粒商城实战笔记-63-商品服务-API-品牌管理-OSS获取服务端签名

文章目录 一&#xff0c;创建第三方服务模块thrid-party1&#xff0c;创建一个名为gulimall-third-party的模块2&#xff0c;nacos上创建third-party命名空间&#xff0c;用来管理这个服务的所有配置3&#xff0c;配置pom文件4&#xff0c;配置文件5&#xff0c;单元测试6&…

oracle登录报“ORA-27101: shared memory realm does not exist”

oracle登录报“ORA-27101: shared memory realm does not exist” 问题&#xff1a; 1、使用ip:1521/服务名方式连库报错" ORA-27101: shared memory realm does not exist Linux-x86_64 Error: 2: No such file or directory" 2、sqlplus XX/密码 可以登录数据库 …

Gateway网关分布式微服务认证鉴权

文章目录 学习链接微服务认证方案 学习链接 实战干货&#xff01;Spring Cloud Gateway 整合 OAuth2.0 实现分布式统一认证授权&#xff01; spring-cloud-gateway-oauth2的github代码地址 - 已克隆到gitee 微服务权限终极解决方案&#xff0c;Spring Cloud Gateway Oauth2…

【Apache Doris】数据副本问题排查指南

【Apache Doris】数据副本问题排查指南 一、问题现象二、问题定位三、问题处理 本文主要分享Doris中数据副本异常的问题现象、问题定位以及如何处理此类问题。 一、问题现象 问题日志 查询报错 Failed to initialize storage reader, tablet{tablet_id}.xxx.xxx问题说明 查…