数据库管理-第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的全部权限,不能打开其他的数据库:
image.png
image.png
image.png
image.png
image.png
image.png
image.png
image.png
image.png
这里不建议配置其他权限,也不需要配置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)
IS
   l_categories gc$category_string_array;
   l_ca_obj gc$notif_corrective_action_job;
   l_categories_new VARCHAR2(1000);
BEGIN
    -- save event categories
   l_categories := s.event_payload.categories;
        IF l_categories IS NOT NULL
   THEN
     FOR c IN 1..l_categories.COUNT
     LOOP
       l_categories_new := (l_categories_new|| c || ' - ' || l_categories(c)||',');
     END LOOP;
   END IF;

   -- save event message
   IF s.msg_info.notification_type = 'NOTIF_CA' AND s.event_payload.corrective_action IS NOT NULL
   THEN
     l_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);   ELSE
      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, 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)
IS
   l_categories gc$category_string_array;
   l_ca_obj gc$notif_corrective_action_job;
   l_categories_new VARCHAR2(1000);
BEGIN
    -- save event categories
   l_categories := s.event_payload.categories;
        IF l_categories IS NOT NULL
   THEN
     FOR c IN 1..l_categories.COUNT
     LOOP
       l_categories_new := (l_categories_new|| c || ' - ' || l_categories(c)||',');
     END LOOP;
   END IF;

   -- save event message
   IF s.msg_info.notification_type = 'NOTIF_CA' AND s.event_payload.corrective_action IS NOT NULL
   THEN
     l_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);   ELSE
      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, 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与通知操作进行关联:
image.png
image.png
image.png
可以通过“测试PL/SQL过程”来测试,这里还需要注意一点,使用中可能会出现PL/SQL无法正常调用的情况,可以在EMCC或直接到资料库中重新编译该PL/SQL即可。
通知操作完成之后,我们仍然无法在表中获取告警信息,这里还需要配置意外事件规则。

3 配置意外事件规则

image.png
image.png
image.png
这里可以以各种方式配置告警的目标内容。
image.png
这里默认选项即可。
image.png
这里我们一般配置“度量告警”和“目标可用性”两种规则即可。
image.png
image.png
image.png
image.png
如果有其他类型告警动作,继续添加即可。
image.png
可以根据自己喜好改名。
image.png
image.png
完成创建后,对应的告警信息就会通过前面配置的PL/SQL正常实时刷入对应表中。
image.png

总结

本篇文章,讲解了如何配置EMCC用户和如何实现基于PL/SQL的告警。
老规矩,知道写了些啥。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Abap与eCharts

一,简介 利用html与eCharts来绘图,然后用cl_gui_html_viewer将html呈现到abap屏幕中。 二,使用eCharts画图 在一个文件夹中准备如下文件,index.html和echarts.js是必须的,data.json(作为数据源)和jquery.js如果用到就可…

问题:下列关于海关统计项目的表述,正确的有:A.进出境货物的统计重量和数量应以报关单位申报的重量和数 #笔记#职场发展#媒体

问题:下列关于海关统计项目的表述,正确的有:A.进出境货物的统计重量和数量应以报关单位申报的重量和数 下列关于海关统计项目的表述,正确的有: A.进出境货物的统计重量和数量应以报关单位申报的…

SERVLET间通信

在Web应用程序中,应用程序的servlet等各种组件之间可能需要通信以便处理客户机请求。例如,假设Web应用程序中有一个servlet显示组织的版权信息。您可以使用各种servelt通信技术将此servlet的内容纳入到需要显示版权信息的所有其他应用程序servlet中。同样,如果处理请求时发生…

2024年第三届能源与环境工程国际会议(CFEEE 2024) | Ei&Scopus双检索

会议简介 Brief Introduction 2024年第三届能源与环境工程国际会议(CFEEE 2024) 会议时间:2024年12月12日-14日 召开地点:澳大利亚凯恩斯 大会官网:CFEEE 2024-2024 International Conference on Frontiers of Energy and Environment Engine…

板块零 IDEA编译器基础:第一节 安装IDEA 来自【汤米尼克的JAVAEE全套教程专栏】

板块零 IDEA编译器基础:第一节 安装IDEA 一、为什么选择IDEA IU?(1)对比Eclipse(2)对比VScode(3)对比IDEA 社区版 二、IDEA IU 下载全过程 此套教程将全系列使用IDEA IU&#xff08…

Leetcode刷题笔记题解(C++):1863. 找出所有子集的异或总和再求和

思路如下:递归思路,依次遍历数组中的数,当前数要不要选择像二叉树一样去遍历如下图所示 0 0 (选5) 5(不选5) 0 1 0 1 0 6 …

java之spring事务管理

spring事务管理 1. 事务概念 事务是一组操作的集合,是一个不可 分割的工作单位, 这些操作,要么同时成功,要么同时失败 和mysql数据库的事务管理道理一样。开启事务 start 提交事务 commit 回滚事务 rollback2.操作实现 Transa…

[小白]Linux安装jdk1.8[超详细]

1、前言 个人博客:www.wdcdbd.com 网站挂掉了可以邮件联系哦!W17838335896163.com hello,刚学linux攻城狮们,应该也为安装jdk而烦恼吧,不过没关系,今天就像超详细的linux安装jdk1.8的详细过程发出来,争…

SpringCloud + Nacos环境下抽取Feign独立模块并支持MultipartFile

文章目录 一、前提条件和背景1. 前提2. 背景 二、Feign模块1. 依赖引入2. application.yaml配置3. 扩展支持MultipartFile4. 将media-api注册到feign 三、Media模块四、Content模块1. 引入依赖2. 启用FeignClient3. 测试 五、需要澄清的几点 一、前提条件和背景 1. 前提 已经…

计组学习笔记2024/2/5

记录每天学到了什么,同时在挪移图片过程中再次理解加深印象 学计算机最重要的是理解,而不是整齐的笔记,不要主次搞混,所以以后记笔记的模式也要改一下(主要还是自己太菜,还达不到一边做到整齐笔记的同时还能够有时间做到理解,所以只能舍弃整齐时间保留理解时间)(不过如果有现成…

JDK和Spring的SPI机制原理分析

目录 一、JDK 二、Spring框架介绍 三、SPI机制原理 一、JDK JDK是Java Development Kit的缩写,是Java开发工具包的意思。它是用于开发Java应用程序和运行Java程序的软件包。JDK包含了Java编译器(javac)和Java虚拟机(JVM&#…

SpringBoot实战第二天

今日战报 继续完善用户相关接口开发: 1.完成获取用户信息功能 2.完成更新用户信息功能 3.完成更新用户头像功能 4.完成更新用户密码功能 获取用户信息 接口文档 如接口文档所示,我们需要做的就是从header中的Authorization中读取token,解码…

浅谈QT的几种线程的使用和区别。

简介: 线程是操作系统中的基本执行单元,是一个独立的执行路径。每个线程都有自己的栈空间,用于存储本地变量和函数调用的上下文。多个线程可以在同一进程中并发执行,从而实现并发处理,提高程序的性能和响应能力。 与进…

Unet 实战分割项目、多尺度训练、多类别分割

1. 介绍 之前写了篇二值图像分割的项目,支持多尺度训练,网络采用backbone为vgg的unet网络。缺点就是没法实现多类别的分割,具体可以参考:二值图像分割统一项目 本章只对增加的代码进行介绍,其余的参考上述链接博文 本…

追觅发布多款旗舰新品,双机械臂扫地机器人X40领衔登场

2月2日,追觅科技全球首创仿生“双”机械臂新品发布会在苏州举行。会上,追觅科技中国区总裁郭人杰分享了追觅科技全球化发展的业绩成果。郭人杰称,2019-2023年,追觅科技5年复合年增长率超过100%,增速领跑智能清洁行业&a…

JAVA中的代码块

一、基本语法 [修饰符]{代码; }; {System.out.println(111); } 1.修饰符可选,要写的话也只能写static2.代码块分为两类 使用static修饰的是静态代码块 没有static修饰的叫普通代码块3.逻辑语句可以为任何逻辑语句4.;可以不写 1)静态代码块 作用是对类进行初始化…

SpringBoot源码解读与原理分析(十八)启动SpringApplication逻辑分析

文章目录 6.2 启动SpringApplication6.2.1 前置准备6.2.1.1 计时器对象的使用6.2.1.2 awt的设置6.2.1.3 对比SpringBoot 2.0.x-2.2.x6.2.1.4 对比SpringBoot 2.4.x 6.2.2 获取SpringApplicationRunListeners6.2.2.1 EventPublishingRunListener6.2.2.2 与其他版本的对比 6.2.3 …

TP框架 之think-auth权限认证

一、安装think-auth composer require 5ini99/think-auth二、数据表 -- ---------------------------- -- think_auth_rule,规则表, -- id:主键,name:规则唯一标识, title:规则中文名称 status 状态:为1正常…

我在代码随想录|写代码Day26 |回溯算法|332. 重新安排行程 , 51. N皇后 , 37. 解数独

学习目标: 博主介绍: 27dCnc 专题 : 数据结构帮助小白快速入门 👍👍👍👍👍👍👍👍👍👍👍👍 ☆*: .。. o(≧▽≦)…

私域市场如何突破?解锁高效转化的三个核心要素!

一、私域电商三要素 一是私域、二是社交、三是电商。 私域就是承载用户的地方,比如微信,然后做好私域运营。 社交就是通过内容触达用户于用户建立社交关系。 电商就是通过私域卖产品给用户。 私域电商有几个公式: 社交红利信息关系链互…
最新文章