数据库管理-第144期 深入使用EMCC-01(20240204)
数据库管理144期 2024-02-04
- 数据库管理-第144期 深入使用EMCC-01(20240204)
- 1 用户管理
- 2 配置告警动作
- 3 配置意外事件规则
- 总结
数据库管理-第144期 深入使用EMCC-01(20240204)
作者:胖头鱼的鱼缸(尹海文)
Oracle ACE Associate: Database(Oracle与MySQL)
网思科技 DBA总监
10年数据库行业经验,现主要从事数据库服务工作
拥有OCM 11g/12c/19c、MySQL 8.0 OCP、Exadata、CDP等认证
墨天轮MVP、认证技术专家,ITPUB认证专家,OCM讲师
圈内拥有“总监”、“保安”、“国产数据库最大敌人”等称号,非著名社恐(社交恐怖分子)
公众号:胖头鱼的鱼缸;CSDN:胖头鱼的鱼缸(尹海文);墨天轮:胖头鱼的鱼缸;ITPUB:yhw1809。
除授权转载并标明出处外,均为“非法”抄袭。
之前写过不少和EMCC相关的内容,包括安装升级及部分使用案例,但是比较零散,这里先汇总一下:
- 数据库管理-第八十一期 保姆级EMCC搭建教程(20230606)(https://www.modb.pro/db/640868)
- 数据库管理-第八十二期 EMCC升级教程(20230607)(https://www.modb.pro/db/641402)
- Oracle数据库管理每周一例-第十五期 一些工具和小技巧(https://blog.csdn.net/yhw1809/article/details/108702252)
- 数据库管理-第五十六期 监控(20230210)(https://blog.csdn.net/yhw1809/article/details/128974630)
这里准备使用若干期来讲讲EMCC的深入点的配置与使用,所有内容都源自于实际生产。
1 用户管理
这里指的是EMCC本身的用户,在生产过程中除了我们长期使用的超级管理员sysman,也可以给其他EMCC使用者配置对应权限的用户,我们这里配置的最多的就是针对某个PDB的全部权限,不能打开其他的数据库:
这里不建议配置其他权限,也不需要配置Role(主要是为了精细化权限控制)。至此用户创建完成,该用户仅对wgbak这个数据库集群下的PDB_TEST有所有权限。
这里在说明一下,这里创建的用户和sysman用户一样在EMCC的资料库也会同步创建数据库用户。
2 配置告警动作
首先EMCC是支持SNMP的,v1和v3都可以,还有email和webhook等,这些配置过程是图形化的,而且要外部对接,这里就不做演示了。但是这里也要说明一点,一些email和webhook的接口标准与咱们使用的不一定能对接的上,而且EMCC一般用于内网,是无法直接连接到对应外部接口的(即使打通也有安全风险)。
所以我的方式是自己写了个Python,定期刷EMCC资料库中的一张表,然后将表中最近N分钟的内容发送到客户内网自建的短信接口上。但是这里有一点比较麻烦的是,EMCC资料库内部记录告警的表,比较分散,而且并非所有内容都会记录在表中。EMCC官方文档给了一个解决方案Cloud Control Monitoring Guide-6 Using Notifications,在Defining a PL/SQL-based Notification Method(https://docs.oracle.com/en/enterprise-manager/cloud-control/enterprise-manager-cloud-control/13.5/emmon/using-notifications.html#GUID-FE309CE0-2ED3-460A-AA95-71A062DCC125)章节中可以通过下面的PL/SQL来实现告警内容的实时汇总至一张表:
-- 使用sysman用户创建:
CREATE TABLE event_log (notification_type VARCHAR2(32),repeat_count NUMBER,ruleset_name VARCHAR2(256),rule_owner VARCHAR2(256),rule_name VARCHAR2(256),message VARCHAR2(4000),message_url VARCHAR2(4000),event_instance_guid RAW(16),event_type VARCHAR2(20),event_name VARCHAR2(512),event_msg VARCHAR2(4000),categories VARCHAR2(4000),source_obj_type VARCHAR2(120),source_obj_name VARCHAR2(256),source_obj_url VARCHAR2(4000),severity VARCHAR2(128),severity_code VARCHAR2(32),target_name VARCHAR2(256),target_type VARCHAR2(128),target_url VARCHAR2(4000),host_name VARCHAR2(256),timezone VARCHAR2(64),occured DATE,ca_guid RAW(16),ca_name VARCHAR2(128),ca_owner VARCHAR2(256),ca_type VARCHAR2(256),ca_status VARCHAR2(64),ca_status_code NUMBER,ca_job_step_output VARCHAR2(4000),ca_execution_guid RAW(16),ca_stage_change_guid RAW(16)
)
;CREATE OR REPLACE PROCEDURE log_event(s IN GC$NOTIF_EVENT_MSG)
ISl_categories gc$category_string_array;l_ca_obj gc$notif_corrective_action_job;l_categories_new VARCHAR2(1000);
BEGIN-- save event categoriesl_categories := s.event_payload.categories;IF l_categories IS NOT NULLTHENFOR c IN 1..l_categories.COUNTLOOPl_categories_new := (l_categories_new|| c || ' - ' || l_categories(c)||',');END LOOP;END IF;-- save event messageIF s.msg_info.notification_type = 'NOTIF_CA' AND s.event_payload.corrective_action IS NOT NULLTHENl_ca_obj := s.event_payload.corrective_action;INSERT INTO event_log (notification_type, repeat_count, ruleset_name, rule_name, rule_owner, message, message_url, event_instance_guid, event_type, event_name, event_msg, categories, source_obj_type, source_obj_name, source_obj_url, severity, severity_code, target_name, target_type, target_url, host_name, timezone, occured, ca_guid, ca_name, ca_owner, ca_type, ca_status, ca_status_code, ca_job_step_output, ca_execution_guid, ca_stage_change_guid)VALUES (s.msg_info.notification_type, s.msg_info.repeat_count, s.msg_info.ruleset_name, s.msg_info.rule_name,s.msg_info.rule_owner, s.msg_info.message, s.msg_info.message_url, s.event_payload.event_instance_guid, s.event_payload.event_type, s.event_payload.event_name, s.event_payload.event_msg, l_categories_new, s.event_payload.source.source_type, s.event_payload.source.source_name, s.event_payload.source.source_url, s.event_payload.severity, s.event_payload.severity_code, s.event_payload.target.target_name, s.event_payload.target.target_type, s.event_payload.target.target_url, s.event_payload.target.host_name, s.event_payload.target.target_timezone, s.event_payload.occurrence_date, l_ca_obj.JOB_GUID, l_ca_obj.JOB_NAME, l_ca_obj.JOB_OWNER, l_ca_obj.JOB_TYPE, l_ca_obj.JOB_STATUS, l_ca_obj.JOB_STATUS_CODE, l_ca_obj.JOB_STEP_OUTPUT, l_ca_obj.JOB_EXECUTION_GUID, l_ca_obj.JOB_STATE_CHANGE_GUID); ELSEINSERT INTO event_log (notification_type, repeat_count, ruleset_name, rule_name, rule_owner, message, message_url, event_instance_guid, event_type, event_name, event_msg, categories, source_obj_type, source_obj_name, source_obj_url, severity, severity_code, target_name, target_type, target_url, host_name, timezone, occured, ca_guid, ca_name, ca_owner, ca_type, ca_status, ca_status_code, ca_job_step_output, ca_execution_guid, ca_stage_change_guid)VALUES (s.msg_info.notification_type, s.msg_info.repeat_count, s.msg_info.ruleset_name, s.msg_info.rule_name, s.msg_info.rule_owner, s.msg_info.message, s.msg_info.message_url, s.event_payload.event_instance_guid, s.event_payload.event_type, s.event_payload.event_name, s.event_payload.event_msg, l_categories_new, s.event_payload.source.source_type, s.event_payload.source.source_name, s.event_payload.source.source_url, s.event_payload.severity, s.event_payload.severity_code, s.event_payload.target.target_name, s.event_payload.target.target_type, s.event_payload.target.target_url, s.event_payload.target.host_name, s.event_payload.target.target_timezone, s.event_payload.occurrence_date, null,null,null,null,null,null,null,null,null);END IF;COMMIT;
END log_event;
/--这里由于时间记录会包含时区信息,可能会出现记录异常的现象,因此需要调整,调整后PL/SQL如下:
CREATE OR REPLACE PROCEDURE log_event(s IN GC$NOTIF_EVENT_MSG)
ISl_categories gc$category_string_array;l_ca_obj gc$notif_corrective_action_job;l_categories_new VARCHAR2(1000);
BEGIN-- save event categoriesl_categories := s.event_payload.categories;IF l_categories IS NOT NULLTHENFOR c IN 1..l_categories.COUNTLOOPl_categories_new := (l_categories_new|| c || ' - ' || l_categories(c)||',');END LOOP;END IF;-- save event messageIF s.msg_info.notification_type = 'NOTIF_CA' AND s.event_payload.corrective_action IS NOT NULLTHENl_ca_obj := s.event_payload.corrective_action;INSERT INTO event_log (notification_type, repeat_count, ruleset_name, rule_name, rule_owner, message, message_url, event_instance_guid, event_type, event_name, event_msg, categories, source_obj_type, source_obj_name, source_obj_url, severity, severity_code, target_name, target_type, target_url, host_name, timezone, occured, ca_guid, ca_name, ca_owner, ca_type, ca_status, ca_status_code, ca_job_step_output, ca_execution_guid, ca_stage_change_guid)VALUES (s.msg_info.notification_type, s.msg_info.repeat_count, s.msg_info.ruleset_name, s.msg_info.rule_name,s.msg_info.rule_owner, s.msg_info.message, s.msg_info.message_url, s.event_payload.event_instance_guid, s.event_payload.event_type, s.event_payload.event_name, s.event_payload.event_msg, l_categories_new, s.event_payload.source.source_type, s.event_payload.source.source_name, s.event_payload.source.source_url, s.event_payload.severity, s.event_payload.severity_code, s.event_payload.target.target_name, s.event_payload.target.target_type, s.event_payload.target.target_url, s.event_payload.target.host_name, s.event_payload.target.target_timezone, sysdate, l_ca_obj.JOB_GUID, l_ca_obj.JOB_NAME, l_ca_obj.JOB_OWNER, l_ca_obj.JOB_TYPE, l_ca_obj.JOB_STATUS, l_ca_obj.JOB_STATUS_CODE, l_ca_obj.JOB_STEP_OUTPUT, l_ca_obj.JOB_EXECUTION_GUID, l_ca_obj.JOB_STATE_CHANGE_GUID); ELSEINSERT INTO event_log (notification_type, repeat_count, ruleset_name, rule_name, rule_owner, message, message_url, event_instance_guid, event_type, event_name, event_msg, categories, source_obj_type, source_obj_name, source_obj_url, severity, severity_code, target_name, target_type, target_url, host_name, timezone, occured, ca_guid, ca_name, ca_owner, ca_type, ca_status, ca_status_code, ca_job_step_output, ca_execution_guid, ca_stage_change_guid)VALUES (s.msg_info.notification_type, s.msg_info.repeat_count, s.msg_info.ruleset_name, s.msg_info.rule_name, s.msg_info.rule_owner, s.msg_info.message, s.msg_info.message_url, s.event_payload.event_instance_guid, s.event_payload.event_type, s.event_payload.event_name, s.event_payload.event_msg, l_categories_new, s.event_payload.source.source_type, s.event_payload.source.source_name, s.event_payload.source.source_url, s.event_payload.severity, s.event_payload.severity_code, s.event_payload.target.target_name, s.event_payload.target.target_type, s.event_payload.target.target_url, s.event_payload.target.host_name, s.event_payload.target.target_timezone, sysdate, null,null,null,null,null,null,null,null,null);END IF;COMMIT;
END log_event;
这里还需要注意一下,在完成升级(包括大版本和补丁)或其他操作后,查询表名(或视图)可能会产生变化,变为event_log_e。
-- 每5分钟读一次该表信息,然后将查出来的内容发给外部接口
select event_type:'||event_type||',severity:'||severity||',target_name:'||target_name||',message:'||message||',occured:'||to_char(occured,'yyyy-mm-dd hh24:mi:ss') from sysman.event_log(_e) where id >0 and occured>sysdate-5/(24*60);-- 这里一般还会根据实际情况排除一些内容,比如:
host_name like 'xxx.xxx.xxx%'
message not like 'Metrics Global Cache Blocks Lost%'
message not like '%job%'
message not like '%CHA%'
message not like '%Memory%'
message not like '%SYS%'
-- 根据自身情况进行调整
接下来还需要在EMCC里面将这个PL/SQL与通知操作进行关联:
可以通过“测试PL/SQL过程”来测试,这里还需要注意一点,使用中可能会出现PL/SQL无法正常调用的情况,可以在EMCC或直接到资料库中重新编译该PL/SQL即可。
通知操作完成之后,我们仍然无法在表中获取告警信息,这里还需要配置意外事件规则。
3 配置意外事件规则
这里可以以各种方式配置告警的目标内容。
这里默认选项即可。
这里我们一般配置“度量告警”和“目标可用性”两种规则即可。
如果有其他类型告警动作,继续添加即可。
可以根据自己喜好改名。
完成创建后,对应的告警信息就会通过前面配置的PL/SQL正常实时刷入对应表中。
总结
本篇文章,讲解了如何配置EMCC用户和如何实现基于PL/SQL的告警。
老规矩,知道写了些啥。
相关文章:

数据库管理-第144期 深入使用EMCC-01(20240204)
数据库管理144期 2024-02-04 数据库管理-第144期 深入使用EMCC-01(20240204)1 用户管理2 配置告警动作3 配置意外事件规则总结 数据库管理-第144期 深入使用EMCC-01(20240204) 作者:胖头鱼的鱼缸(尹海文&am…...

flask_django_python五金电商网络营销的可视化分析研究
前面部分完成了系统需求分析,了解到新闻数据业务方面的需求,系统主要分为用户管理、五金信息管理、在线留言、系统管理等功能。销的可视化研究,并对这些数据进行处理, 然后对这些数据进行可视化分析和统计。 Python 爬虫技术目前来…...

Java并发(二十三)----同步模式之保护性暂停
1、定义 即 Guarded Suspension,用在一个线程等待另一个线程的执行结果 要点 有一个结果需要从一个线程传递到另一个线程,让他们关联同一个 GuardedObject 如果有结果不断从一个线程到另一个线程那么可以使用消息队列 JDK 中,join 的实现…...

###C语言程序设计-----C语言学习(9)#函数基础
前言:感谢您的关注哦,我会持续更新编程相关知识,愿您在这里有所收获。如果有任何问题,欢迎沟通交流!期待与您在学习编程的道路上共同进步。 一. 基础知识的学习 1.函数的定义 函数是一个完成特定工作的独立程序模块&…...

Dockerfile文件参数配置和使用
天行健,君子以自强不息;地势坤,君子以厚德载物。 每个人都有惰性,但不断学习是好好生活的根本,共勉! 文章均为学习整理笔记,分享记录为主,如有错误请指正,共同学习进步。…...

Java实现婚恋交友网站 JAVA+Vue+SpringBoot+MySQL
目录 一、摘要1.1 项目介绍1.2 项目录屏 二、功能模块2.1 数据中心模块2.2 会员管理模块2.3 新闻管理模块2.4 相亲大会管理模块2.5 留言管理模块 三、系统设计3.1 用例设计3.2 数据库设计3.2.1 会员信息表3.2.2 新闻表3.2.3 相亲大会表3.2.4 留言表 四、系统展示五、核心代码5.…...
React16源码: React中详解在渲染阶段Suspend的源码实现
Suspend 挂起详解 1 )概述 在react的更新过程当中,它的任务是可以被挂起的,也就是 Suspend关于 Suspend 字面意思就是挂起在某次更新的任务更新完成之后,暂时不提交 在 react更新中,分为两个阶段,首先是re…...
mac电脑风扇控制软件:Macs Fan Control Pro for mac 激活版
Macs Fan Control 是一款专门为 Mac 用户设计的软件,它可以帮助用户控制和监控 Mac 设备的风扇速度和温度。这款软件允许用户手动调整风扇速度,以提高设备的散热效果,减少过热造成的风险。 Macs Fan Control 可以在菜单栏上显示当前系统温度和…...
easyexcel解析跨多行的数据
在使用easyexcel解析excel文件的时候,存在某列横跨多行,那么存在解析出的对象的某些属性是没有值的,那么我们要怎么处理呢?代码如下 定义实体对应excel文件 public class EtcParkingReconciliationDailyImportModel implements S…...

双目相机立体匹配基础
双目匹配就是用左相机和右相机去拍摄同一个点,目的是找到三维世界的同一个点,也就是在左相机和右相机中的成像点之间的像素差(视差),根据视差去求解深度,那么找到左相机点到右相机的同一个对应点这个过程就…...
【图论】网络流
网络流目前只整理模板,学习的话这篇博客可能不太适合 代码参考下方博客,加了一些自己的注释 算法学习笔记(28): 网络流究级的最大流算法:ISAP与HLPP FF 和 EK 仅用作理解代码,赛时请使用 Dinic 或 ISAP 下文建图方式都基于链式…...

【Matplotlib】figure方法 你真的会了吗!?
🎈个人主页:甜美的江 🎉欢迎 👍点赞✍评论⭐收藏 🤗收录专栏:matplotlib 🤝希望本文对您有所裨益,如有不足之处,欢迎在评论区提出指正,让我们共同学习、交流进…...

[C++]继承(续)
一、基类和派生类对象赋值转换 在public继承时,父类和子类是一个“is - a”的关系。 子类对象赋值给父类对象/父类指针/父类引用,我们认为是天然的,中间不产生临时对象,也叫作父子类赋值兼容规则(切割/切片ÿ…...

恒创科技:服务器内存不足影响大吗?
服务器在为网站、应用程序和在线服务提供支持方面发挥着关键作用。这些服务器需要提供最佳性能,以确保正常无缝的用户体验,而RAM是显著影响服务器性能的关键配置之一。 RAM 是一种随机存取存储器,计算机和服务器使用它来临时存储正在使…...

深入理解网络通信和TCP/IP协议
目录 计算机网络是什么? 定义和分类 计算机网络发展简史 计算机网络体系结构 OSI 七层模型 TCP/IP 模型 TCP/IP 协议族 TCP/IP 网络传输中的数据 地址和端口号 MAC地址 IP 地址 端口号 为什么端口号有65535个? 综述 TCP 特性 TCP 三次握…...

Open CASCADE学习|分割曲线
1、通过参数进行分割 分别获得曲线的 FirstParameter 和 LastParameter ,然后对参数进行分割,获得n个ui,并对每个ui调用D0(获得这个点的坐标值)或D1(获得这个点的坐标值和切向量)。这个方法的优…...

vulhub中Adminer远程文件读取漏洞复现(CVE-2021-43008)
Adminer是一个PHP编写的开源数据库管理工具,支持MySQL、MariaDB、PostgreSQL、SQLite、MS SQL、Oracle、Elasticsearch、MongoDB等数据库。 在其版本1.12.0到4.6.2之间存在一处因为MySQL LOAD DATA LOCAL导致的文件读取漏洞。 参考链接: https://gith…...

MOS管驱动电流估算-Qg参数
MOS管驱动电流估算 例:FDH45N50F如下参数: 有人可能会这样计算: 开通电流 带入数据得 关断电流 带入数据得 于是乎得出这样的结论,驱动电流只需 250mA左右即可。仔细想想这样计算对吗? 这里必须要注意这样一个条件细…...

Vision Transfomer系列第一节---从0到1的源码实现
本专栏主要是深度学习/自动驾驶相关的源码实现,获取全套代码请参考 这里写目录标题 准备逐步源码实现数据集读取VIt模型搭建hand类别和位置编码类别编码位置编码 blocksheadVIT整体 Runner(参考mmlab)可视化 总结 准备 本博客完成Vision Transfomer(VIT)模型的搭建和flowers数…...

【CSS + ElementUI】更改 el-carousel 指示器样式且隐藏左右箭头
需求 前三条数据以走马灯形式展现,指示器 hover 时可以切换到对应内容 实现 <template><div v-loading"latestLoading"><div class"upload-first" v-show"latestThreeList.length > 0"><el-carousel ind…...
uniapp 对接腾讯云IM群组成员管理(增删改查)
UniApp 实战:腾讯云IM群组成员管理(增删改查) 一、前言 在社交类App开发中,群组成员管理是核心功能之一。本文将基于UniApp框架,结合腾讯云IM SDK,详细讲解如何实现群组成员的增删改查全流程。 权限校验…...

C++_核心编程_多态案例二-制作饮品
#include <iostream> #include <string> using namespace std;/*制作饮品的大致流程为:煮水 - 冲泡 - 倒入杯中 - 加入辅料 利用多态技术实现本案例,提供抽象制作饮品基类,提供子类制作咖啡和茶叶*//*基类*/ class AbstractDr…...
利用ngx_stream_return_module构建简易 TCP/UDP 响应网关
一、模块概述 ngx_stream_return_module 提供了一个极简的指令: return <value>;在收到客户端连接后,立即将 <value> 写回并关闭连接。<value> 支持内嵌文本和内置变量(如 $time_iso8601、$remote_addr 等)&a…...

Vue3 + Element Plus + TypeScript中el-transfer穿梭框组件使用详解及示例
使用详解 Element Plus 的 el-transfer 组件是一个强大的穿梭框组件,常用于在两个集合之间进行数据转移,如权限分配、数据选择等场景。下面我将详细介绍其用法并提供一个完整示例。 核心特性与用法 基本属性 v-model:绑定右侧列表的值&…...
腾讯云V3签名
想要接入腾讯云的Api,必然先按其文档计算出所要求的签名。 之前也调用过腾讯云的接口,但总是卡在签名这一步,最后放弃选择SDK,这次终于自己代码实现。 可能腾讯云翻新了接口文档,现在阅读起来,清晰了很多&…...

计算机基础知识解析:从应用到架构的全面拆解
目录 前言 1、 计算机的应用领域:无处不在的数字助手 2、 计算机的进化史:从算盘到量子计算 3、计算机的分类:不止 “台式机和笔记本” 4、计算机的组件:硬件与软件的协同 4.1 硬件:五大核心部件 4.2 软件&#…...
根目录0xa0属性对应的Ntfs!_SCB中的FileObject是什么时候被建立的----NTFS源代码分析--重要
根目录0xa0属性对应的Ntfs!_SCB中的FileObject是什么时候被建立的 第一部分: 0: kd> g Breakpoint 9 hit Ntfs!ReadIndexBuffer: f7173886 55 push ebp 0: kd> kc # 00 Ntfs!ReadIndexBuffer 01 Ntfs!FindFirstIndexEntry 02 Ntfs!NtfsUpda…...

wpf在image控件上快速显示内存图像
wpf在image控件上快速显示内存图像https://www.cnblogs.com/haodafeng/p/10431387.html 如果你在寻找能够快速在image控件刷新大图像(比如分辨率3000*3000的图像)的办法,尤其是想把内存中的裸数据(只有图像的数据,不包…...

6.9-QT模拟计算器
源码: 头文件: widget.h #ifndef WIDGET_H #define WIDGET_H#include <QWidget> #include <QMouseEvent>QT_BEGIN_NAMESPACE namespace Ui { class Widget; } QT_END_NAMESPACEclass Widget : public QWidget {Q_OBJECTpublic:Widget(QWidget *parent nullptr);…...
FTXUI::Dom 模块
DOM 模块定义了分层的 FTXUI::Element 树,可用于构建复杂的终端界面,支持响应终端尺寸变化。 namespace ftxui {...// 定义文档 定义布局盒子 Element document vbox({// 设置文本 设置加粗 设置文本颜色text("The window") | bold | color(…...