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)';
相关文章:
Oracle对数据库行和数据库的监控
前言: Oracle对表的监控分为数据行修改DML的监控、对表的DDL监控 1、对表的DML监控(数据的增删改) -- 创建测试表 create table tab_test01( id varchar2(100) default sys_guid(), name varchar2(100), insert_date date default sysdate…...

论文阅读:面向自动驾驶场景的多目标点云检测算法
论文地址:面向自动驾驶场景的多目标点云检测算法 概要 点云在自动驾驶系统中的三维目标检测是关键技术之一。目前主流的基于体素的无锚框检测算法通常采用复杂的二阶段修正模块,虽然在算法性能上有所提升,但往往伴随着较大的延迟。单阶段无锚框点云检测算法简化了检测流程,…...

Vite + Vue3 + TS项目配置前置路由守卫
在现代前端开发中,使用 Vue 3 和 TypeScript 的组合是一种流行且高效的开发方式。Vite 是一个极速的构建工具,可以显著提升开发体验。本文博主将指导你如何在 Vite Vue 3 TypeScript 项目中配置前置路由守卫(Navigation Guards)…...
设计模式-备忘录
备忘录(Memento)设计模式是为了保存对象当前状态,并在需要的时候恢复到之前保存的状态。以下是一个简单的C#备忘录模式的实现: // Originator 类,负责创建和恢复备忘录 class Originator {private string state;publi…...

openEuler安装docker,加速镜像拉取
文章目录 文章来源1.配置镜像源2.编辑配置文件3.安装想要的版本4. ~ 原神!5.由于很多镜像无法拉取配置镜像源 文章来源 http://t.csdnimg.cn/zYDYy 原文连接 由于之前的仓库不让用且 1.配置镜像源 由于 国外的镜像仓库好多不让用 所以配置阿里的镜像源 yum-confi…...

angular入门基础教程(七)系统路由
路由的实现 当我们系统越来复杂,功能越来越多,路由也就是必须的了。在 ng 中如何实现路由呢? 启用路由 在 app 目录下,新建一个 router 目录,把 app.routers.ts 文件拷贝过来,并修改一下。 import { Ro…...
Unity Canvas动画:UI元素的动态展示
在Unity中,Canvas是用于管理和展示用户界面(UI)元素的系统。Canvas动画是UI设计中的重要组成部分,它能够提升用户体验,使界面更加生动和响应用户操作。本文将探讨Unity Canvas动画的基本概念、实现方法以及一些实用的技…...
apache.commons.pool2 使用指南
apache.commons.pool2 使用指南 为什么要使用池 创建对象耗时较长,多线程频繁调用等因素限制了我们不能每次使用时都重新创建对象,使用池化思想将对象放进池内,不同线程使用同一个池来获取对象,极大的减少每次业务的调用时间。 …...

【Python面试题收录】Python编程基础练习题②(数据类型+文件操作+时间操作)
本文所有代码打包在Gitee仓库中https://gitee.com/wx114/Python-Interview-Questions 一、数据类型 第一题 编写一个函数,实现:先去除左右空白符,自动检测输入的数据类型,如果是整数就转换成二进制形式并返回出结果;…...
typescript 定义类型
type infoType string; let name: infoType "全易"; let location: infoType "北京"; // let age: infoType 18; // 报错 infoType string|number 就不报错了 let job: infoType "开发"; let love: infoType "吃喝玩乐&q…...

基于Java+SpringBoot+Vue的的课程作业管理系统
前言 ✌全网粉丝20W,csdn特邀作者、博客专家、CSDN[新星计划]导师、java领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ 🍅文末获取项目下载方式🍅 哈喽兄弟们,好久不见哦࿵…...

分布式日志分析系统--ELK
文章目录 ELK概述ELK主要特点ELK应用架构 Elasticsearch原理JSON格式倒排索引 ES与关系型数据库ES相关概念ES安装说明1.环境初始化2.优化系统资源限制配置3.编辑ES服务文件elasticsearch. yml 优化ELK集群安装脚本scp的使用集群安装成功 Shell命令API使用创建索引创建Type创建分…...
Linux初学基本命令
linux文件目录 1、bin->usr/bin binary存放命令 所有账户可以使用 Linux可以执行的文件,我们称之为命令command 2、boot 存放系统启动文件 3、dev device存放设备文件 4、etc 存放配置文件的目录 configration files 5、home home家目录 存…...

如何优化PyTorch以加快模型训练速度?
PyTorch是当今生产环境中最流行的深度学习框架之一。随着模型变得日益复杂、数据集日益庞大,优化模型训练性能对于缩短训练时间和提高生产力变得至关重要。 本文将分享几个最新的性能调优技巧,以加速跨领域的机器学习模型的训练。这些技巧对任何想要使用…...
用最简单的方法对大数据进行处理 vs spark(不需要安装大数据处理工具)
一、大文件处理策略 (一)、难点 内存管理: 大文件无法一次性加载到内存中,因为这可能会导致内存溢出(OutOfMemoryError)。 因此,需要使用流(Stream)或缓冲区(…...
非线性校正算法在红外测温中的应用
非线性校正算法在红外测温中用于修正传感器输出与实际温度之间的非线性关系。红外传感器的输出信号(通常是电压或电流)与温度的关系理论上是线性的,但在实际应用中,由于传感器特性的限制,这种关系往往呈现出非线性。非…...
python----线程、进程、协程的区别及多线程详解
文章目录 一、线程、进程、协程区别二、创建线程1、函数创建2、类创建 三、线程锁1、Lock2、死锁2.1加锁之后处理业务逻辑,在释放锁之前抛出异常,这时的锁没有正常释放,当前的线程因为异常终止了,就会产生死锁。2.2开启两个或两个…...

将 magma example 改写成 cusolver example eqrf
1,简单安装Magma 1.1 下载编译 OpenBLAS $ git clone https://github.com/OpenMathLib/OpenBLAS.git $ cd OpenBLAS/ $ make -j DEBUG1 $ make install PREFIX/home/hipper/ex_magma/local_d/OpenBLAS/1.2 下载编译 magma $ git clone https://bitbucket.org/icl…...
微信小程序教程007:数据绑定
文章目录 数据绑定1、数据绑定原则2、在data中定义页面数据3、Mustache语法的格式4、Mustache应用场景5、绑定属性6、三元运算8、算数运算数据绑定 1、数据绑定原则 在data中定义数据在WXML中使用数据2、在data中定义页面数据 在页面对应的.js文件中,把数据定义到data对象中…...
Git -- git stash 暂存
使用 git 或多或少都会了解到 git stash 命令,但是可能未曾经常使用,下面简单介绍两种使用场景。 场景一:分支A开发,分支B解决bug 我们遇到最常见的例子就是,在当前分支 A 上开发写需求,但是 B 分支上有…...
从零实现富文本编辑器#5-编辑器选区模型的状态结构表达
先前我们总结了浏览器选区模型的交互策略,并且实现了基本的选区操作,还调研了自绘选区的实现。那么相对的,我们还需要设计编辑器的选区表达,也可以称为模型选区。编辑器中应用变更时的操作范围,就是以模型选区为基准来…...
Qt Widget类解析与代码注释
#include "widget.h" #include "ui_widget.h"Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget) {ui->setupUi(this); }Widget::~Widget() {delete ui; }//解释这串代码,写上注释 当然可以!这段代码是 Qt …...

selenium学习实战【Python爬虫】
selenium学习实战【Python爬虫】 文章目录 selenium学习实战【Python爬虫】一、声明二、学习目标三、安装依赖3.1 安装selenium库3.2 安装浏览器驱动3.2.1 查看Edge版本3.2.2 驱动安装 四、代码讲解4.1 配置浏览器4.2 加载更多4.3 寻找内容4.4 完整代码 五、报告文件爬取5.1 提…...

使用 SymPy 进行向量和矩阵的高级操作
在科学计算和工程领域,向量和矩阵操作是解决问题的核心技能之一。Python 的 SymPy 库提供了强大的符号计算功能,能够高效地处理向量和矩阵的各种操作。本文将深入探讨如何使用 SymPy 进行向量和矩阵的创建、合并以及维度拓展等操作,并通过具体…...

C++:多态机制详解
目录 一. 多态的概念 1.静态多态(编译时多态) 二.动态多态的定义及实现 1.多态的构成条件 2.虚函数 3.虚函数的重写/覆盖 4.虚函数重写的一些其他问题 1).协变 2).析构函数的重写 5.override 和 final关键字 1&#…...
Java毕业设计:WML信息查询与后端信息发布系统开发
JAVAWML信息查询与后端信息发布系统实现 一、系统概述 本系统基于Java和WML(无线标记语言)技术开发,实现了移动设备上的信息查询与后端信息发布功能。系统采用B/S架构,服务器端使用Java Servlet处理请求,数据库采用MySQL存储信息࿰…...

处理vxe-table 表尾数据是单独一个接口,表格tableData数据更新后,需要点击两下,表尾才是正确的
修改bug思路: 分别把 tabledata 和 表尾相关数据 console.log() 发现 更新数据先后顺序不对 settimeout延迟查询表格接口 ——测试可行 升级↑:async await 等接口返回后再开始下一个接口查询 ________________________________________________________…...

深入浅出深度学习基础:从感知机到全连接神经网络的核心原理与应用
文章目录 前言一、感知机 (Perceptron)1.1 基础介绍1.1.1 感知机是什么?1.1.2 感知机的工作原理 1.2 感知机的简单应用:基本逻辑门1.2.1 逻辑与 (Logic AND)1.2.2 逻辑或 (Logic OR)1.2.3 逻辑与非 (Logic NAND) 1.3 感知机的实现1.3.1 简单实现 (基于阈…...
API网关Kong的鉴权与限流:高并发场景下的核心实践
🔥「炎码工坊」技术弹药已装填! 点击关注 → 解锁工业级干货【工具实测|项目避坑|源码燃烧指南】 引言 在微服务架构中,API网关承担着流量调度、安全防护和协议转换的核心职责。作为云原生时代的代表性网关,Kong凭借其插件化架构…...

热门Chrome扩展程序存在明文传输风险,用户隐私安全受威胁
赛门铁克威胁猎手团队最新报告披露,数款拥有数百万活跃用户的Chrome扩展程序正在通过未加密的HTTP连接静默泄露用户敏感数据,严重威胁用户隐私安全。 知名扩展程序存在明文传输风险 尽管宣称提供安全浏览、数据分析或便捷界面等功能,但SEMR…...