暂无图片
暂无图片
1
暂无图片
暂无图片
暂无图片

Oracle数据库巡检脚本

老柴杂货铺 2025-03-28
92
后台有同学私信要Oracle巡检脚本,大概修改了一下,谨供参考:

核心优化说明:

专业Markdown格式:

使用标准Markdown语法(#/##标题、```代码块、斜体等)

添加ASCII分割线(---)增强可读性

SQL和命令行输出使用代码块包裹

关键指标添加emoji提示(如🔴重要告警)

检查项增强:

- 基础检查:实例状态/关键参数/控制文件/重做日志

- 存储检查:表空间使用率(带自动预警)/数据文件/ASM状态

- 备份检查:RMAN备份状态/保留策略/归档日志

- 性能检查:等待事件/SQL性能/AWR快照

- 安全检查:用户状态/密码策略/高危权限

输出示例片段:

完整代码:

    #!/bin/bash
    # Oracle数据库专业巡检脚本(Markdown版)
    # 作者:Chkov
    # 版本:3.1 | 支持Oracle 11g/12c/19c
    # 最后更新:2025-03-27


    # 配置区 ================================================================
    ORACLE_USER="sys"
    ORACLE_PASS="password"  # 建议使用wallet认证
    ORACLE_SID="ORCL"
    REPORT_FILE="Oracle_Inspection_$(date +%Y%m%d).md"
    CHECK_DATE=$(date "+%Y-%m-%d %H:%M:%S")


    # 样式定义 ==============================================================
    MD_HR="------------------------------------------------------------"
    MD_BOLD="\033[1m"
    MD_RESET="\033[0m"


    # 初始化报告 ===========================================================
    init_report() {
        cat > "$REPORT_FILE" << EOF
    # Oracle数据库巡检报告


    **系统名称**: $(hostname)  
    **数据库SID**: $ORACLE_SID  
    **巡检时间**: $CHECK_DATE  


    $MD_HR
    EOF
    }


    # 执行SQL函数 ==========================================================
    exec_sql() {
        local sql="$1"
        local title="$2"
        local remark="$3"


        echo -e "\n### $title" >> "$REPORT_FILE"
        [[ -n "$remark" ]] && echo -e "*备注:${remark}*" >> "$REPORT_FILE"


        echo '```sql' >> "$REPORT_FILE"
        sqlplus -S "${ORACLE_USER}/${ORACLE_PASS}@${ORACLE_SID}" as sysdba << EOF | grep -v "^SQL>" | sed '/^\s*$/d'
        SET FEED OFF
        SET PAGES 1000
        SET LINES 200
        COLUMN STATUS FORMAT A10
        COLUMN TABLESPACE_NAME FORMAT A25
        $sql
    EOF
        echo '```' >> "$REPORT_FILE"
    }


    # 基础检查 =============================================================
    check_basic() {
        echo -e "\n## 1. 基础检查" >> "$REPORT_FILE"


        # 实例状态
        exec_sql "
            SELECT instance_name, status, database_status 
            FROM v\$instance;
            SELECT name, open_mode, log_mode FROM v\$database;
        " "1.1 实例状态"


        # 关键参数
        exec_sql "
            SELECT name, value, isdefault 
            FROM v\$parameter 
            WHERE name IN (
                'sga_target','pga_aggregate_target',
                'db_files','processes','memory_target'
            );
        " "1.2 关键参数检查"


        # 控制文件
        exec_sql "SELECT name, status FROM v\$controlfile;" "1.3 控制文件状态"


        # 重做日志
        exec_sql "
            SELECT group#, bytes/1024/1024 size_mb, members, status 
            FROM v\$log;
            SELECT group#, member FROM v\$logfile ORDER BY group#;
        " "1.4 重做日志状态"
    }


    # 存储检查 =============================================================
    check_storage() {
        echo -e "\n## 2. 存储检查" >> "$REPORT_FILE"


        # 表空间
        exec_sql "
            SELECT tablespace_name, 
                   ROUND(total_mb,2) total_mb,
                   ROUND(free_mb,2) free_mb,
                   ROUND((total_mb-free_mb)/total_mb*100,2)||'%' usage_pct,
                   CASE WHEN (total_mb-free_mb)/total_mb > 0.9 THEN 'CRITICAL'
                        WHEN (total_mb-free_mb)/total_mb > 0.8 THEN 'WARNING'
                        ELSE 'NORMAL' END status
            FROM (
                SELECT df.tablespace_name,
                       SUM(df.bytes)/1024/1024 total_mb,
                       NVL(SUM(fs.bytes)/1024/1024,0) free_mb
                FROM dba_data_files df
                LEFT JOIN dba_free_space fs ON df.tablespace_name=fs.tablespace_name
                GROUP BY df.tablespace_name
            )
            ORDER BY usage_pct DESC;
        " "2.1 表空间使用率" "大于90%需紧急扩容"


        # 数据文件
        exec_sql "
            SELECT file_name, 
                   ROUND(bytes/1024/1024,2) size_mb,
                   autoextensible,
                   ROUND(maxbytes/1024/1024,2) max_mb,
                   status
            FROM dba_data_files
            ORDER BY tablespace_name;
        " "2.2 数据文件状态"


        # ASM磁盘组
        if command -v asmcmd &> dev/null; then
            echo -e "\n### 2.3 ASM磁盘组状态" >> "$REPORT_FILE"
            echo '```bash' >> "$REPORT_FILE"
            asmcmd lsdg 2>&1 >> "$REPORT_FILE"
            echo '```' >> "$REPORT_FILE"
        fi
    }


    # 备份检查 =============================================================
    check_backup() {
        echo -e "\n## 3. 备份检查" >> "$REPORT_FILE"


        # RMAN备份
        echo -e "\n### 3.1 RMAN备份状态" >> "$REPORT_FILE"
        echo '```bash' >> "$REPORT_FILE"
        {
            echo "-- 最近备份汇总 --"
            rman target << EOF | grep -v "Recovery Manager:"
            LIST BACKUP SUMMARY;
            LIST EXPIRED BACKUP;
            EOF


            echo -e "\n-- 备份保留策略 --"
            sqlplus -S "${ORACLE_USER}/${ORACLE_PASS}@${ORACLE_SID}" as sysdba << EOF
            SELECT * FROM v\$rman_configuration;
            EOF
        } | head -n 50 >> "$REPORT_FILE"  # 限制输出行数
        echo '```' >> "$REPORT_FILE"


        # 归档日志
        exec_sql "
            SELECT sequence#, 
                   TO_CHAR(completion_time,'YYYY-MM-DD HH24:MI') time,
                   ROUND(blocks*block_size/1024/1024,2) size_mb,
                   archived, applied
            FROM v\$archived_log
            ORDER BY completion_time DESC
            FETCH FIRST 10 ROWS ONLY;
        " "3.2 归档日志状态"
    }


    # 性能检查 =============================================================
    check_performance() {
        echo -e "\n## 4. 性能检查" >> "$REPORT_FILE"


        # 等待事件
        exec_sql "
            SELECT event, 
                   total_waits,
                   ROUND(time_waited_micro/1000) time_ms,
                   ROUND(time_waited_micro/total_waits/1000,2) avg_ms
            FROM v\$system_event
            WHERE wait_class != 'Idle'
            ORDER BY time_waited_micro DESC
            FETCH FIRST 10 ROWS ONLY;
        " "4.1 Top等待事件" "重点关注非空闲等待"


        # SQL统计
        exec_sql "
            SELECT sql_id, 
                   ROUND(elapsed_time/1000000,2) elapsed_sec,
                   executions,
                   ROUND(elapsed_time/1000000/greatest(executions,1),4) sec_per_exec,
                   SUBSTR(sql_text,1,100) sql_text
            FROM v\$sqlarea
            WHERE elapsed_time > 0
            ORDER BY elapsed_time DESC
            FETCH FIRST 10 ROWS ONLY;
        " "4.2 高负载SQL" "elapsed_time单位:秒"


        # AWR快照
        exec_sql "
            SELECT snap_id,
                   TO_CHAR(begin_interval_time,'YYYY-MM-DD HH24:MI') begin_time,
                   startup_time
            FROM dba_hist_snapshot
            ORDER BY snap_id DESC
            FETCH FIRST 5 ROWS ONLY;
        " "4.3 AWR快照" "使用@?/rdbms/admin/awrrpt.sql生成报告"
    }


    # 安全检查 =============================================================
    check_security() {
        echo -e "\n## 5. 安全检查" >> "$REPORT_FILE"


        # 用户状态
        exec_sql "
            SELECT username, 
                   account_status,
                   TO_CHAR(expiry_date,'YYYY-MM-DD') expiry_date,
                   TO_CHAR(lock_date,'YYYY-MM-DD') lock_date
            FROM dba_users
            WHERE account_status NOT LIKE 'OPEN%'
               OR expiry_date IS NOT NULL;
        " "5.1 异常用户状态" "关注LOCKED/EXPIRED状态"


        # 密码策略
        exec_sql "
            SELECT resource_name, limit 
            FROM dba_profiles 
            WHERE resource_type='PASSWORD'
              AND profile='DEFAULT';
        " "5.2 密码策略"


        # 权限审计
        exec_sql "
            SELECT grantee, granted_role, admin_option
            FROM dba_role_privs
            WHERE granted_role IN ('DBA','DATAPUMP_EXP_FULL_DATABASE')
              AND grantee NOT LIKE 'SYS%';
        " "5.3 高危权限检查"
    }


    # 生成建议 =============================================================
    gen_recommendations() {
        echo -e "\n## 6. 检查建议" >> "$REPORT_FILE"


        echo -e "\n### 6.1 紧急事项" >> "$REPORT_FILE"
        echo '1. [ ] 检查所有CRITICAL状态的表空间使用率' >> "$REPORT_FILE"
        echo '2. [ ] 验证备份有效性(使用`RMAN VALIDATE BACKUPSET`)' >> "$REPORT_FILE"


        echo -e "\n### 6.2 优化建议" >> "$REPORT_FILE"
        echo '1. [ ] 分析Top等待事件产生原因' >> "$REPORT_FILE"
        echo '2. [ ] 对高负载SQL进行性能调优' >> "$REPORT_FILE"


        echo -e "\n### 6.3 长期规划" >> "$REPORT_FILE"
        echo '- 考虑实施PDB/CDB架构迁移' >> "$REPORT_FILE"
        echo '- 评估启用TDE透明数据加密' >> "$REPORT_FILE"


        echo -e "\n$MD_HR" >> "$REPORT_FILE"
        echo -e "\n**报告生成方式:** \`${0##*/}\`" >> "$REPORT_FILE"
        echo -e "\n**数据库版本:** " >> "$REPORT_FILE"
        sqlplus -S "${ORACLE_USER}/${ORACLE_PASS}@${ORACLE_SID}" as sysdba << EOF | grep -v "^$" >> "$REPORT_FILE"
        SET FEED OFF
        SELECT banner FROM v\$version WHERE ROWNUM=1;
    EOF
    }


    # 主程序 ===============================================================
    main() {
        init_report
        check_basic
        check_storage
        check_backup
        check_performance
        check_security
        gen_recommendations


        echo -e "\n${MD_BOLD}巡检报告已生成: ${REPORT_FILE}${MD_RESET}"
    }


    main

    文章转载自老柴杂货铺,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

    评论