Browse Source

Add files via upload

dufsh 6 years ago
parent
commit
c503914cf4

+ 137 - 0
程序/FM_FREQ_PRD.sql

@@ -0,0 +1,137 @@
+--/
+CREATE PROCEDURE FM_FREQ_PRD
+AS
+
+-- create by duf 2017-11-30   产品:梁梅
+--四川_20171115_智能网与EPC重大故障预警需求描述文档V1.3 以下章节的 “同一网元30分钟内3次及以上闪断,每次闪断条数大于等于10条” 判断
+--3.1.3.5	智能网场景五
+--3.1.3.7	彩信场景二
+
+-- 需求要求30秒轮巡一次,sch job 调度
+
+v_time date:=sysdate;
+v_title varchar2(128);
+v_ne_id varchar2(128);
+v_first_time date;
+v_max_event_id number;
+
+v_device_class varchar2(64);
+v_first_time_cur date;  -- 发现时间-当前
+
+v_cnt number;   -- 1分钟内内断的告警数量
+v_rn number;    --告警排序
+v_num number:=0;--闪断次数计次
+
+BEGIN
+
+        
+        dbms_output.put_line('v_time='||to_char(v_time,'yyyy-mm-dd hh24:mi:ss'));
+        for cur_1 in (
+        
+                -- 只需要告警 与SIPFEP链路中断,由于这个告警少,暂时加了一个告警 告警指示信号(LP-AIS) 做验证
+                select * from 
+                (
+                        select count(*) over(partition by e.ne_id,e.title,e.device_class) cnt,
+                        row_number() over(partition by e.ne_id,e.title,e.device_class order by e.first_occurrence_time) rn,
+                        max(e.event_id) over(partition by e.ne_id,e.title,e.device_class) max_event_id,
+                        e.*
+                        from fm_alarm_recent e
+                        where e.is_cleared=1
+                        and e.title in ('与SIPFEP链路中断')
+                        and e.first_occurrence_time>=v_time-30/1440
+                        and e.first_occurrence_time<v_time
+                        and e.first_occurrence_time>e.clear_time-1/1440
+                        and e.construct_alarm_flag=0
+                        and e.device_class in ('SCP','彩铃','SDH')
+                        and not exists (select 1 from fm_alarm_freq f where e.ne_id=f.ne_id and e.title=f.title and e.device_class=f.device_class and e.first_occurrence_time<=f.first_occurrence_time)
+                ) where cnt>=30
+                order by ne_id,title,rn
+        )loop
+                v_title:=cur_1.title;
+                v_ne_id:=cur_1.ne_id;
+                v_device_class:=cur_1.device_class;
+                v_max_event_id:=cur_1.max_event_id;
+                v_rn:=cur_1.rn;
+                v_first_time:=cur_1.first_occurrence_time;
+                
+                if v_rn=1
+                then 
+                        -- 闪断计次初始化
+                        v_num:=0;
+                        v_first_time_cur:=v_first_time;
+                      --  dbms_output.put_line('new ne_id --------------------------');
+                        dbms_output.put_line('ne_id='||v_ne_id);
+
+                        -- 新的ne_id+title 告警组开始
+                        select count(*) into v_cnt
+                        from fm_alarm_recent e
+                        where e.is_cleared=1 
+                        and e.title=v_title
+                        and e.ne_id=v_ne_id
+                        and e.first_occurrence_time>=v_time-30/1440
+                        and e.first_occurrence_time<v_time
+                        and e.first_occurrence_time>e.clear_time-1/1440
+                        and e.first_occurrence_time>=v_first_time
+                        and e.first_occurrence_time<=v_first_time+1/1440;
+                        
+                        if v_cnt>=10
+                        then
+                             dbms_output.put_line(to_char(v_first_time,'yyyy-mm-dd hh24:mi:ss')||'-'||to_char(v_first_time+1/1440,'yyyy-mm-dd hh24:mi:ss')||'  1分钟内闪断达到'||v_cnt||',计闪断1次');
+                             v_first_time_cur:=v_first_time+1/1440;
+                             v_num:=v_num+1;
+                        end if;
+                 else
+                        
+                        if v_num>=3
+                        then
+                            continue;
+                        end if;
+                        
+                        if v_first_time_cur>=v_first_time
+                        then 
+                        -- 这个是已经被计为闪断的告警
+                            continue;
+                        else
+                            -- 这个是没有被计为闪断的告警,重新按这个告警的时间再统计1分钟内闪断次数据是否达到要求
+                                select count(*) into v_cnt
+                                from fm_alarm_recent e
+                                where e.is_cleared=1 
+                                and e.title=v_title
+                                and e.ne_id=v_ne_id
+                                and e.first_occurrence_time>=v_time-30/1440
+                                and e.first_occurrence_time<v_time
+                                and e.first_occurrence_time>e.clear_time-1/1440
+                                and e.first_occurrence_time>=v_first_time
+                                and e.first_occurrence_time<=v_first_time+1/1440;
+                                
+                                if v_cnt>=10
+                                then
+                                     dbms_output.put_line(to_char(v_first_time,'yyyy-mm-dd hh24:mi:ss')||'-'||to_char(v_first_time+1/1440,'yyyy-mm-dd hh24:mi:ss')||'  1分钟内闪断达到'||v_cnt||',计闪断1次');
+                                     v_first_time_cur:=v_first_time+1/1440;
+                                     v_num:=v_num+1;
+                                     if v_num=3 
+                                     then
+                                                dbms_output.put_line('闪断次数已达到3次');
+                                                insert into fm_alarm_freq(ne_id,title,first_occurrence_time,device_class,event_id) values (v_ne_id,v_title,v_time,v_device_class,v_max_event_id);
+                                                commit;
+                                                v_num:=v_num+1;
+                                                continue;
+                                     end if;
+                                     
+                                end if;
+                        end if;
+                  end if;
+        end loop;
+                
+        -- 清除闪断告警
+        update fm_alarm_freq e set e.is_cleared=1,e.clear_time=sysdate
+        where not exists (select 1 from fm_alarm_freq e1 where e.ne_id=e1.ne_id and e.title=e1.title and e1.first_occurrence_time>sysdate-30/1440)
+        and e.is_cleared=0;
+        commit;
+        
+        -- 只保留3天的数据
+        delete from fm_alarm_freq where first_occurrence_time<trunc(sysdate-3);
+        commit;
+        
+END;
+/

File diff suppressed because it is too large
+ 403 - 0
程序/FM_SYNC_ENODEB_PRD.sql


File diff suppressed because it is too large
+ 499 - 0
程序/FM_SYNC_NMS_PRD.sql


+ 104 - 0
程序/GATHER_INDEX_STATS_PRD.sql

@@ -0,0 +1,104 @@
+--/
+CREATE PROCEDURE GATHER_INDEX_STATS_PRD
+(in_table varchar2, in_indexes IN VARCHAR2)
+
+-- create by dufs 2019-01-10 用于索引的统计信息收集
+AS
+
+v_cnt     number;
+v_is_part varchar2(32);
+v_is_lock varchar2(32);
+v_index   varchar2(32);
+
+v_table   varchar2(32);
+v_indexes varchar2(4000);
+
+BEGIN
+
+        v_table:=upper(in_table);
+        v_indexes:=upper(in_indexes);
+        
+        select count(*) into v_cnt from user_tables where table_name=v_table;
+        if v_cnt = 0 
+        then
+                dbms_output.put_line('not found table' || v_table);
+                return; 
+        end if;
+        
+        if v_indexes is null
+        then
+                -- 如果传入参数中,索引为空,则取该表所有索引进行统计信息收集
+                dbms_output.put_line('v_indexes is null , get all indexes on table ||' || v_table);    
+                select listagg(index_name,',') within group(order by index_name) into v_indexes from user_indexes where table_name=v_table;
+        end if;
+        
+        for cur in (select COLUMN_VALUE as index_name from table(str2varlist_new(v_indexes))
+        )
+        loop
+                v_index:=cur.index_name;
+
+                select PARTITIONED into v_is_part from user_indexes where index_name=v_index and table_name=v_table;
+        
+                if v_is_part is null
+                then
+                        dbms_output.put_line('not found v_index' || v_index);
+                        continue;        
+                elsif v_is_part='NO'
+                then
+                        dbms_output.put_line('v_index ' || v_index || ' is not PARTITIONED');
+                        
+                        select max(stattype_locked) into v_is_lock from user_tab_statistics where table_name=v_table and stattype_locked is not null;
+                        if v_is_lock is not null
+                        then
+                                dbms_output.put_line('table' || v_table || ' is locked :'||v_is_lock);
+                                --表处理锁定状态,需要先解锁                                
+                                DBMS_STATS.UNLOCK_TABLE_STATS(OWNNAME => user, TABNAME => v_table);
+                        else
+                                dbms_output.put_line('table' || v_table || ' is not locked :'||v_is_lock);
+                        end if;
+                                        
+                        DBMS_STATS.GATHER_index_STATS(OWNNAME     => user,
+                                                      indname     => v_index,
+                                                      estimate_percent => 10,
+                                                      DEGREE      => 3);
+
+                        if v_is_lock is not null
+                        then
+                                --锁定表的统计信息,避免自动任务分析表
+                                DBMS_STATS.LOCK_TABLE_STATS(OWNNAME => user, TABNAME => v_table);   
+                        end if;             
+                elsif v_is_part='YES'
+                then
+                        dbms_output.put_line('index' || v_index || ' is PARTITIONED');
+                        select max(stattype_locked) into v_is_lock from user_tab_statistics where table_name=v_table and stattype_locked is not null;
+                        if v_is_lock is not null
+                        then
+                                dbms_output.put_line('table' || v_table || ' is locked :'||v_is_lock);
+                                --表处理锁定状态,需要先解锁
+                                DBMS_STATS.UNLOCK_TABLE_STATS(OWNNAME => user, TABNAME => v_table);
+                        else
+                                dbms_output.put_line('table' || v_table || ' is not locked :'||v_is_lock);
+                        end if;
+                                
+                        for cur_1 in (select partition_name from user_ind_partitions where index_name=v_index
+                        )
+                        loop
+                                DBMS_STATS.GATHER_index_STATS(OWNNAME     => user,
+                                                              indname     => v_index,
+                                                              PARTNAME    => cur_1.partition_name,
+                                                              GRANULARITY => 'PARTITION',
+                                                              estimate_percent => 10,
+                                                              DEGREE      => 3);
+                        end loop; 
+                                
+                        if v_is_lock is not null
+                        then
+                                --锁定表的统计信息,避免自动任务分析表
+                                DBMS_STATS.LOCK_TABLE_STATS(OWNNAME => user, TABNAME => v_table);
+                        end if;                                 
+                else
+                        dbms_output.put_line('table' || v_table || ' paritions gived is null');
+                end if;
+        end loop;
+END;
+/

+ 85 - 0
程序/GATHER_TABLE_STATS_PRD.sql

@@ -0,0 +1,85 @@
+--/
+CREATE PROCEDURE GATHER_TABLE_STATS_PRD
+(in_table IN VARCHAR2, in_partitions IN VARCHAR2)
+
+-- create by dufs 2019-01-10 用于表的统计信息收集
+
+AS
+
+v_is_part varchar2(32);
+v_is_lock varchar2(32);
+
+
+v_table   varchar2(32);
+v_partitions varchar2(4000);
+
+BEGIN
+        
+        v_table:=upper(in_table);
+        v_partitions:=upper(in_partitions);
+        
+        select PARTITIONED into v_is_part from user_tables where table_name=v_table;
+        
+        if v_is_part is null
+        then
+                dbms_output.put_line('not found table' || v_table);
+                return;        
+        elsif v_is_part='NO'
+        then
+                dbms_output.put_line('table' || v_table || ' is not PARTITIONED');
+                select stattype_locked into v_is_lock from user_tab_statistics where table_name=v_table;
+                if v_is_lock is not null
+                then
+                        dbms_output.put_line('table' || v_table || ' is locked :'||v_is_lock);
+                        --表处理锁定状态,需要先解锁
+                        DBMS_STATS.UNLOCK_TABLE_STATS(OWNNAME => user, TABNAME => v_table);                  
+                else
+                        dbms_output.put_line('table' || v_table || ' is not locked :'||v_is_lock);
+                end if;
+
+                DBMS_STATS.GATHER_TABLE_STATS(OWNNAME     => user,
+                                        TABNAME     => v_table,
+                                        estimate_percent => 10,
+                                        DEGREE      => 3);
+                                        
+                if v_is_lock is not null
+                then
+                        --锁定表的统计信息,避免自动任务分析表
+                        DBMS_STATS.LOCK_TABLE_STATS(OWNNAME => user, TABNAME => v_table);
+                end if;                
+        elsif v_is_part='YES'
+        then
+                dbms_output.put_line('table' || v_table || ' is PARTITIONED');
+                if v_partitions is not null
+                then
+                        select max(stattype_locked) into v_is_lock from user_tab_statistics where table_name=v_table and stattype_locked is not null;
+                        if v_is_lock is not null
+                        then
+                                dbms_output.put_line('table' || v_table || ' is locked :'||v_is_lock);
+                                --表处理锁定状态,需要先解锁
+                                DBMS_STATS.UNLOCK_TABLE_STATS(OWNNAME => user, TABNAME => v_table);
+                        else
+                                dbms_output.put_line('table' || v_table || ' is not locked :'||v_is_lock);
+                        end if; 
+                        
+                        for cur in ( select partition_name from user_tab_partitions where table_name=v_table and  partition_name in (select COLUMN_VALUE from table(str2varlist_new(v_partitions)))
+                        )loop 
+                                DBMS_STATS.GATHER_TABLE_STATS(OWNNAME     => user,
+                                                TABNAME     => v_table,
+                                                PARTNAME    => cur.partition_name,
+                                                GRANULARITY => 'PARTITION',
+                                                DEGREE      => 3,
+                                                CASCADE     => TRUE);
+                        end loop;                          
+
+                        if v_is_lock is not null
+                        then
+                                --锁定表的统计信息,避免自动任务分析表
+                                DBMS_STATS.LOCK_TABLE_STATS(OWNNAME => user, TABNAME => v_table);
+                        end if;                                 
+                else
+                        dbms_output.put_line('table' || v_table || ' paritions gived is null');
+                end if;
+        end if;
+END;
+/

+ 126 - 0
程序/P_TRUNCATE_TABLES_DAY.sql

@@ -0,0 +1,126 @@
+--/
+CREATE PROCEDURE P_TRUNCATE_TABLES_DAY IS
+  V_END_DATE   DATE;
+  V_PARTVALUE  DATE;
+  V_TABLENAME  VARCHAR2(200);
+  V_PARTNAME   VARCHAR2(200);
+  V_SQL        VARCHAR2(2000);
+  V_HIGH_VALUE VARCHAR2(2000);
+  V_MONTH      NUMBER;
+  V_CURR_DATE  DATE := SYSDATE;
+  V_ERR        VARCHAR2(200);
+
+  /*每日1点定时清理表表T_TRUNCATE_TABLES_DAY中表的数据*/
+BEGIN
+
+  UPDATE T_TRUNCATE_TABLES_DAY SET SQLTEXT = NULL, TRUN_DATE = NULL;
+  COMMIT;
+
+  FOR CUR_TABLES IN (SELECT TABLE_NAME, TYPE_CODE, TYPE_NUM, PART
+                       FROM T_TRUNCATE_TABLES_DAY
+                      WHERE ISDELETE = 1) LOOP
+  
+    V_MONTH     := CUR_TABLES.TYPE_NUM;
+    V_TABLENAME := CUR_TABLES.TABLE_NAME;
+  
+    --取得需要清理的数据的日期范围
+    IF CUR_TABLES.TYPE_CODE = 'MONTH' THEN
+      SELECT TRUNC(ADD_MONTHS(V_CURR_DATE, -V_MONTH))
+        INTO V_END_DATE
+        FROM DUAL;
+    ELSIF CUR_TABLES.TYPE_CODE = 'DAY' THEN
+      SELECT TRUNC(V_CURR_DATE - V_MONTH) INTO V_END_DATE FROM DUAL;
+    END IF;
+  
+    --删除分区表数据
+    IF CUR_TABLES.PART = 0 THEN
+      --取得分区表的分区名称
+      FOR CUR_PARTNAME IN (SELECT PARTITION_NAME, HIGH_VALUE
+                             FROM USER_TAB_PARTITIONS
+                            WHERE TABLE_NAME = V_TABLENAME
+                              AND (PARTITION_NAME LIKE 'SYS_P%' 
+                              --OR PARTITION_NAME LIKE 'FM_ALARM_HISTORY%'
+                                  )
+                            ORDER BY PARTITION_NAME) LOOP
+      
+        V_HIGH_VALUE := CUR_PARTNAME.HIGH_VALUE;
+        V_PARTVALUE  := TO_DATE(SUBSTR(V_HIGH_VALUE, 11, 10), 'YYYY-MM-DD');
+        V_PARTNAME   := CUR_PARTNAME.PARTITION_NAME;
+      
+        
+        IF V_PARTVALUE <= V_END_DATE then
+        
+          --表被锁定,等2秒后重试10次
+          FOR I IN 1 .. 20 LOOP
+            BEGIN
+              V_SQL := 'ALTER TABLE ' || V_TABLENAME || ' DROP PARTITION ' || V_PARTNAME || ' UPDATE INDEXES PARALLEL 3';
+            
+            
+            /*
+               add by dufs 2018-10-20 由于 FM_ALARM_HISTORY、FM_ALARM_PERMANENT表访问频率很高,且不断有超期数据要写入
+              如果直接drop超期的分区,写入超期数据时要新增分区,而且数量极大, FM_ALARM_HISTORY 每天要删除的达到400多个,删了400多个后,还要陆续增加上来
+              如果改为truncate,不用新增分区,但积累的分区会越来越多,每次操作耗时、锁表会越来越严重
+              改成分区设置时间与结束时间相告,即每次只清刚好超期的那一个分区,既可以达到清空分区减少存储数据的目标,又能降低操作次数,从几百次操作减少到1次
+            */
+              if V_TABLENAME='FM_ALARM_HISTORY' or V_TABLENAME='FM_ALARM_PERMANENT'
+              then
+                     --dbms_output.put_line('V_PARTVALUE '||to_char(V_PARTVALUE,'yyyy-mm-dd hh24:mi:ss'));
+                     --dbms_output.put_line('V_END_DATE-1'||to_char(V_END_DATE-1,'yyyy-mm-dd hh24:mi:ss'));
+
+                     if V_PARTVALUE <= V_END_DATE-1
+                     then
+                        exit;
+                     end if;
+
+                     V_SQL := 'ALTER TABLE ' || V_TABLENAME || ' TRUNCATE PARTITION ' || V_PARTNAME || ' UPDATE GLOBAL INDEXES PARALLEL 3';
+              end if;
+              
+              dbms_output.put_line(V_SQL);
+              
+              EXECUTE IMMEDIATE V_SQL;
+            
+              UPDATE T_TRUNCATE_TABLES_DAY
+                 SET SQLTEXT   =  V_PARTNAME ,
+                     TRUN_DATE = V_CURR_DATE
+               WHERE TABLE_NAME = V_TABLENAME;
+              COMMIT;
+              EXIT;
+            EXCEPTION
+              WHEN OTHERS THEN
+                V_ERR := SUBSTR(SQLERRM, 1, 200);
+                IF SUBSTR(V_ERR, 1, 9) = 'ORA-00054' THEN
+                  IF I = 10 THEN
+                    INSERT INTO T_ISS_SQLERRM VALUES (SEQ_T_ISS_SQLERRM.NEXTVAL,'P_TRUNCATE_TABLES_DAY',V_ERR,SYSDATE);
+                    COMMIT;
+                  END IF;
+                  DBMS_LOCK.SLEEP(2);
+                  CONTINUE;
+                ELSE
+                  INSERT INTO T_ISS_SQLERRM VALUES (SEQ_T_ISS_SQLERRM.NEXTVAL,'P_TRUNCATE_TABLES_DAY',V_ERR,SYSDATE);
+                  COMMIT;
+                  EXIT;
+                END IF;
+            END;
+          
+          END LOOP;
+        END IF;
+      
+      END LOOP;
+    
+    END IF;
+  
+  END LOOP;
+
+
+EXCEPTION
+  WHEN OTHERS THEN
+    V_ERR := SUBSTR(SQLERRM, 1, 200);
+    ROLLBACK;
+    INSERT INTO T_ISS_SQLERRM
+    VALUES
+      (SEQ_T_ISS_SQLERRM.NEXTVAL, 'P_TRUNCATE_TABLES_DAY', V_ERR, SYSDATE);
+    COMMIT;
+ 
+END;
+
+/

File diff suppressed because it is too large
+ 630 - 0
程序/TS_COLLECT_PRD.sql