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

达梦数据库巡检脚本优化

老柴杂货铺 2025-03-28
11

在上一篇写一个简单的达梦数据库巡检脚本的基础上进行如下优化

模块化设计:

每个检查项独立函数,便于维护

关键步骤添加错误处理

安全性增强:

密码不直接显示在命令行历史中

敏感操作前进行验证

专业内容优化:

包括实例状态、表空间、用户状态等核心指标

增加Top SQL和等待事件分析

备份和事务状态检查

输出优化:

使用Markdown格式,支持代码块语法

自动高亮关键问题

自动化程度:

自动检测服务端口

自动获取当前日期作为报告名

使用说明:

保存为dm_md.sh

修改头部配置参数

添加执行权限:chmod +x dm_md.sh

运行:./dm_md.sh

    #!/bin/bash
    # 达梦数据库专业巡检脚本
    # 作者:Chkov
    # 版本:1.2
    # 最后更新:2025-03-27


    # 配置区 ====================================================================
    DB_USER="SYSDBA"
    DB_PASSWORD="SYSDBA"  # 建议改为从安全方式获取
    INSPECTION_DATE=$(date +%Y%m%d)
    REPORT_FILE="dm_inspection_${INSPECTION_DATE}.md"
    DM_HOME="/opt/dmdbms"  # 达梦安装目录
    DATA_DIR="/dmdata"     # 数据文件目录
    LOG_DIR="${DM_HOME}/log" # 日志目录
    PORT=5236              # 默认端口,可自动检测


    # 工具检查 ==================================================================
    check_utils() {
      REQUIRED_UTILS=("disql" "dmrman" "ss" "awk" "grep")
      for util in "${REQUIRED_UTILS[@]}"do
        if ! command -v "$util" &> dev/null; then
          echo "[错误] 缺少必要工具: $util" | tee -a $REPORT_FILE
          exit 1
        fi
      done
    }


    # 自动检测达梦端口 ==========================================================
    detect_port() {
      PORT=$(ss -tnlp | grep dmserver | grep LISTEN | awk '{print $4}' | cut -d: -f2)
      [[ -z "$PORT" ]] && PORT=5236
      echo "检测到达梦服务运行端口: $PORT"
    }


    # 数据库连接检查 ============================================================
    check_db_connection() {
      if ! disql "${DB_USER}/${DB_PASSWORD}@localhost:${PORT}" -e "SELECT 1 FROM DUAL;" &> dev/null; then
        echo "[严重错误] 无法连接到达梦数据库!请检查:"
        echo "- 服务状态: systemctl status DmServicedmdbms"
        echo "- 连接字符串: disql ${DB_USER}/***@localhost:${PORT}"
        exit 1
      fi
    }


    # 系统资源检查 ==============================================================
    check_system_resources() {
      echo -e "\n### 1. 系统资源概览"
      echo -e "#### 1.1 存储使用 (df -h)"
      echo '```'
      df -h | grep -E "${DATA_DIR}|${DM_HOME}"
      echo '```'


      echo -e "\n#### 1.2 内存使用 (free -m)"
      echo '```'
      free -m
      echo '```'


      echo -e "\n#### 1.3 CPU负载 (uptime)"
      echo '```'
      uptime
      echo '```'


      echo -e "\n#### 1.4 关键进程状态"
      echo '```'
      ps -ef | grep -E "dmserver|dmmonitor" | grep -v grep
      echo '```'
    }


    # 网络连接检查 ==============================================================
    check_network() {
      echo -e "\n### 2. 网络连接状态"
      echo -e "#### 2.1 达梦服务端口"
      echo '```'
      ss -tnlp | grep -E "${PORT}|dmserver"
      echo '```'


      echo -e "\n#### 2.2 活跃数据库连接(Top20)"
      echo '```'
      netstat -anp | grep ":${PORT}" | awk '{print $5}' | cut -d: -f1 | sort | uniq -c | sort -nr | head -20
      echo '```'
    }


    # 数据库状态检查 ============================================================
    check_database_status() {
      local SQL_BASIC="
        SELECT name AS 实例名称, 
               status\$ AS 实例状态, 
               startup_time AS 启动时间,
               (SELECT COUNT(*) FROM V\$SESSION WHERE STATE='ACTIVE') AS 活跃会话数
        FROM V\$INSTANCE;


        SELECT tablespace_name AS 表空间, 
               ROUND(SUM(bytes)/1024/1024,2) AS 大小_MB,
               '=>' AS 使用率,
               ROUND(SUM(bytes)/SUM(maxbytes)*100,2)||'%' AS 使用百分比
        FROM DBA_DATA_FILES 
        GROUP BY tablespace_name
        ORDER BY 4 DESC;


        SELECT username AS 用户名,
               account_status AS 账户状态,
               TO_CHAR(expiry_date,'YYYY-MM-DD') AS 过期时间
        FROM DBA_USERS
        WHERE account_status != 'OPEN';
      "


      local SQL_PERFORMANCE="
        SELECT sql_text AS Top_SQL, 
               elapsed_time/1000 AS 耗时_MS, 
               executions AS 执行次数
        FROM V\$SQL_HISTORY 
        ORDER BY elapsed_time DESC 
        FETCH FIRST 5 ROWS ONLY;


        SELECT event AS 等待事件, 
               COUNT(*) AS 等待次数
        FROM V\$SESSION_WAIT 
        WHERE wait_class != 'Idle'
        GROUP BY event
        ORDER BY 2 DESC
        FETCH FIRST 5 ROWS ONLY;
      "


      local SQL_SAFETY="
        SELECT backup_type AS 备份类型, 
               TO_CHAR(start_time,'YYYY-MM-DD HH24:MI') AS 开始时间,
               ROUND(bytes/1024/1024,2) AS 大小_MB,
               status AS 状态
        FROM V\$BACKUPSET
        ORDER BY start_time DESC
        FETCH FIRST 2 ROWS ONLY;


        SELECT '存在' AS 最长未提交事务,
               TO_CHAR(MIN(start_time),'YYYY-MM-DD HH24:MI:SS') AS 开始时间,
               EXTRACT(SECOND FROM (SYSDATE - MIN(start_time))) AS 持续时间_秒
        FROM V\$TRANSACTION;
      "


      echo -e "\n### 3. 数据库核心指标"
      echo -e "#### 3.1 基础信息"
      echo '```sql'
      disql "${DB_USER}/${DB_PASSWORD}@localhost:${PORT}" -e "$SQL_BASIC"
      echo '```'


      echo -e "\n#### 3.2 性能指标"
      echo '```sql'
      disql "${DB_USER}/${DB_PASSWORD}@localhost:${PORT}" -e "$SQL_PERFORMANCE"
      echo '```'


      echo -e "\n#### 3.3 安全指标"
      echo '```sql'
      disql "${DB_USER}/${DB_PASSWORD}@localhost:${PORT}" -e "$SQL_SAFETY"
      echo '```'
    }


    # 日志检查 ==================================================================
    check_logs() {
      echo -e "\n### 4. 日志分析"
      echo -e "#### 4.1 错误日志统计(最近24小时)"
      echo '```'
      grep -i error "${LOG_DIR}/dm_${INSPECTION_DATE}.log" | tail -20
      echo '```'


      echo -e "\n#### 4.2 日志文件大小"
      echo '```'
      ls -lh "${LOG_DIR}"/*.log | awk '{print $5,$9}'
      echo '```'
    }


    # 生成报告 ==================================================================
    generate_report() {
      {
        echo "# 达梦数据库专业巡检报告"
        echo "## 系统名称: $(hostname)"
        echo "## 巡检时间: $(date '+%Y-%m-%d %H:%M:%S')"
        echo "## 达梦版本: $(disql ${DB_USER}/${DB_PASSWORD}@localhost:${PORT} -e "SELECT version FROM V\$INSTANCE;" -s | grep -v "^$")"


        check_system_resources
        check_network
        check_database_status
        check_logs


        echo -e "\n### 5. 检查结论与建议"
        echo -e "\n**关键指标评语:**"
        echo -e "- [ ] 表空间使用率超过90%需要关注"
        echo -e "- [ ] 存在非OPEN状态用户需要确认"
        echo -e "- [ ] 备份状态需要验证有效性\n"


        echo "**建议后续操作:**"
        echo "1. 重要表空间扩容规划"
        echo "2. 过期账户清理"
        echo "3. 备份恢复测试验证"
      } > "$REPORT_FILE"


      echo -e "\n报告已生成至: \033[1;32m$(pwd)/${REPORT_FILE}\033[0m"
    }


    # 主流程 ===================================================================
    main() {
      check_utils
      detect_port
      check_db_connection
      generate_report
    }


    # 执行入口
    main
    复制

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

    评论