1. 为什么我们需要一个手搓的Oracle巡检系统?
作为一名运维老兵,我经历过太多凌晨三点被报警电话叫醒的噩梦。Oracle数据库作为企业核心系统的"心脏",其健康状态直接关系到业务连续性。传统巡检方式存在三大痛点:
- 人工操作低效耗时:每天要检查数十项指标(表空间、会话数、锁等待等),手动执行SQL脚本至少需要30分钟
- 环境差异导致遗漏:Windows和Linux平台下的检查项存在差异,容易漏掉关键指标
- 问题发现滞后:等收到报警时往往已经影响业务,缺乏预防性监控
我开发的这套巡检系统通过SSH协议实现跨平台操作,用Python脚本封装了Oracle巡检的核心逻辑。经过半年生产环境验证,已稳定运行在8个Oracle 11g/12c环境(含3个Windows Server和5个RHEL系统),平均每周发现潜在问题2-3个,将严重故障率降低了76%。
关键突破点:通过动态适配机制,同一套脚本可自动识别Windows/Linux环境差异,智能调整检查策略。比如在Windows下会额外检查Oracle服务状态,而Linux环境则重点关注ASM磁盘组状态。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 系统架构设计与核心技术栈
2.1 整体架构图
mermaid复制graph TD
A[巡检客户端] -->|SSH| B(目标服务器)
B --> C{Oracle环境检测}
C -->|Windows| D[执行WMIC查询]
C -->|Linux| E[执行Shell命令]
D/E --> F[SQL*Plus执行巡检]
F --> G[生成HTML报告]
2.2 关键技术选型
-
连接层:
- Paramiko(Python SSH库)实现跨平台连接
- 支持密码和密钥两种认证方式
- 会话保持技术避免重复登录
-
命令执行层:
- Windows平台:封装WMIC和PowerShell命令
powershell复制Get-WmiObject -Query "select Status from Win32_Service where Name='OracleServiceORCL'"- Linux平台:封装标准Shell命令
bash复制ps -ef | grep -v grep | grep ora_pmon | wc -l -
Oracle检查层:
- 使用SQL*Plus批处理模式执行预置SQL
sql复制set heading off feedback off select tablespace_name,round(used_percent,2) from dba_tablespace_usage_metrics; exit -
报告生成层:
- Jinja2模板引擎生成HTML报告
- 关键指标用颜色区分(红/黄/绿)
- 历史数据对比功能
3. Windows环境专项适配方案
3.1 服务状态监控
Windows平台需要特别关注Oracle服务的运行状态。我们通过WMI查询获取服务详情:
python复制def check_windows_service(ssh):
stdin, stdout, stderr = ssh.exec_command(
'wmic service where "name like \'OracleService%\'" get Name,State'
)
services = [line.split() for line in stdout if 'Oracle' in line]
return {s[0]: s[1] for s in services}
3.2 注册表检查
Oracle在Windows下的关键配置存储在注册表中:
python复制def check_registry(ssh):
cmd = r'reg query "HKLM\SOFTWARE\ORACLE" /s | findstr ORACLE_HOME'
_, stdout, _ = ssh.exec_command(cmd)
return stdout.read().decode('gbk')
3.3 磁盘空间检查
Windows的磁盘空间检查需要特殊处理:
python复制def check_disk_windows(ssh):
cmd = 'wmic logicaldisk get DeviceID,FreeSpace,Size'
_, stdout, _ = ssh.exec_command(cmd)
disks = []
for line in stdout:
if ':' in line:
parts = line.split()
disks.append({
'drive': parts[0],
'free': int(parts[1])//(1024*1024*1024),
'total': int(parts[2])//(1024*1024*1024)
})
return disks
4. Linux环境专项处理策略
4.1 进程检查
Linux下需要验证关键Oracle进程:
python复制def check_linux_process(ssh):
commands = [
'ps -ef | grep -v grep | grep ora_pmon | wc -l',
'ps -ef | grep -v grep | grep tnslsnr | wc -l'
]
results = {}
for cmd in commands:
_, stdout, _ = ssh.exec_command(cmd)
results[cmd.split('|')[2].strip()] = int(stdout.read())
return results
4.2 ASM磁盘组检查
对于使用ASM的Linux环境:
python复制def check_asm_diskgroups(ssh):
asm_sql = """
set heading off feedback off
select name,total_mb,free_mb
from v$asm_diskgroup;
exit
"""
stdin, stdout, stderr = ssh.exec_command(
f'sqlplus -S / as sysdba <<EOF\n{asm_sql}\nEOF'
)
return [line.split() for line in stdout if '%' in line]
4.3 内核参数验证
检查关键的Linux内核参数:
python复制def check_kernel_params(ssh):
params = [
'kernel.shmall', 'kernel.shmmax',
'fs.file-max', 'net.ipv4.ip_local_port_range'
]
results = {}
for param in params:
cmd = f'sysctl {param}'
_, stdout, _ = ssh.exec_command(cmd)
results[param] = stdout.read().decode().strip()
return results
5. 核心巡检项实现细节
5.1 表空间监控
通过动态SQL获取表空间使用率:
python复制def check_tablespaces(ssh, oracle_home):
sql = """
set lines 200 pages 1000
col tablespace_name for a30
select
tablespace_name,
round(used_percent,2) pct_used,
round(bytes/1024/1024,2) total_mb,
round(bytes*(1-used_percent/100)/1024/1024,2) free_mb
from dba_tablespace_usage_metrics
order by used_percent desc;
"""
cmd = f'export ORACLE_HOME={oracle_home};echo "{sql}" | sqlplus -S / as sysdba'
_, stdout, _ = ssh.exec_command(cmd)
return parse_tablespace_output(stdout)
5.2 会话和锁监控
识别阻塞会话和锁等待:
python复制def check_locks(ssh):
sql = """
select
blocking_session, sid, serial#,
seconds_in_wait, wait_time
from v$session
where blocking_session is not null;
"""
stdin, stdout, stderr = ssh.exec_command(
f'sqlplus -S / as sysdba <<EOF\n{sql}\nEOF'
)
return [line.split() for line in stdout if len(line.split())==5]
5.3 性能指标采集
收集AWR核心指标:
python复制def get_awr_metrics(ssh, days=1):
sql = f"""
select
metric_name,
round(average,2) avg_val,
round(maximum,2) max_val
from dba_hist_sysmetric_summary
where begin_time > sysdate-{days}
order by metric_name;
"""
stdin, stdout, _ = ssh.exec_command(
f'sqlplus -S / as sysdba <<EOF\n{sql}\nEOF'
)
return parse_awr_output(stdout)
6. 报告生成与告警机制
6.1 HTML报告模板
使用Jinja2生成可视化报告:
html复制<div class="metric-card {% if tablespace.pct_used > 90 %}critical{% elif tablespace.pct_used > 80 %}warning{% endif %}">
<h3>{{ tablespace.tablespace_name }}</h3>
<div class="progress-bar">
<div style="width: {{ tablespace.pct_used }}%"></div>
</div>
<p>{{ "%.2f"|format(tablespace.pct_used) }}% 已用</p>
</div>
6.2 阈值告警配置
yaml复制alert_rules:
tablespace_usage:
warning: 80
critical: 90
session_count:
warning: 100
critical: 150
lock_wait:
warning: 60
critical: 300
6.3 邮件通知集成
python复制def send_alert(receivers, subject, content):
msg = MIMEMultipart()
msg['From'] = 'oracle-monitor@company.com'
msg['To'] = ', '.join(receivers)
msg['Subject'] = f'[Oracle告警] {subject}'
body = MIMEText(content, 'html')
msg.attach(body)
with smtplib.SMTP('smtp.server.com', 587) as server:
server.starttls()
server.login('user', 'pass')
server.send_message(msg)
7. 部署与使用指南
7.1 环境准备
bash复制# 安装Python依赖
pip install paramiko jinja2 pyyaml
# 配置目标服务器信息
servers:
- host: db-server1
os_type: linux
oracle_home: /u01/app/oracle/product/12.2.0/dbhome_1
- host: db-win1
os_type: windows
oracle_home: C:\app\oracle\product\12.2.0\dbhome_1
7.2 执行巡检
python复制python oracle_inspector.py \
--config config.yaml \
--output ./reports \
--mail-to dba-team@company.com
7.3 定时任务配置
Linux使用crontab:
bash复制0 8,20 * * * /usr/bin/python3 /opt/oracle_inspector/main.py
Windows使用任务计划程序:
powershell复制$action = New-ScheduledTaskAction -Execute 'python.exe' -Argument 'C:\scripts\oracle_inspector\main.py'
$trigger = New-ScheduledTaskTrigger -Daily -At 8am,8pm
Register-ScheduledTask -TaskName "Oracle巡检" -Action $action -Trigger $trigger
8. 实战避坑指南
-
SSH连接超时问题:
- 在Paramiko的Transport层设置keepalive
python复制transport = ssh.get_transport() transport.set_keepalive(60) # 每60秒发送心跳 -
Oracle环境变量加载:
- Linux下需要先source oraenv
bash复制source $ORACLE_HOME/bin/oraenv <<< $ORACLE_SID -
Windows编码问题:
- 强制使用GBK解码命令输出
python复制output = stdout.read().decode('gbk', errors='ignore') -
SQL*Plus输出格式化:
- 在SQL脚本中添加set命令避免多余输出
sql复制set heading off feedback off verify off term off -
权限问题处理:
- 创建专用巡检账号并授权
sql复制CREATE USER inspector IDENTIFIED BY password; GRANT SELECT_CATALOG_ROLE TO inspector; GRANT SELECT ON v_$session TO inspector;
这套系统最让我自豪的是它的自适应能力——同一套代码可以在Windows和Linux环境下无缝运行,自动识别环境差异并调整检查策略。经过三个月的迭代优化,现在每天只需5分钟就能完成过去需要人工耗时1小时的巡检工作,真正实现了"让运维更简单"的目标。
