数据库教程FGMT86:AI-DBA自动化运维开发快速入门
## 第一章 前言与本套风哥教程大纲
风哥教程本文面向 IT 运维工程师、主机工程师、数据库工程师与数据库管理员,目标只有一个:在人工智能全面渗透基础设施的 2026 年,让不具备专职软件开发背景的运维与 DBA,能够独立使用 s-hell 与 Python 开发出可在生产环境落地的自动化运维工具,并借助本地大模型完成脚本生成、故障解读与巡检结论归纳。本套风哥教程不讲解泛泛的 AI 概念,而是围绕"会写工具、能跑工具、敢上生产"这条主线展开。
风哥针对本套教程的整体安排分为三个层次。第一层是认知与理论,包括 AI 自动化运维基础知识、AI 时代 DBA 与运维工程师的职业发展、Linux 加 s-hell 自动化运维基础知识、Python 自动化运维基础知识、AI 开发环境的安装与搭建;第二层是五个递进式实战,依次为开发 Linux 加 s-hell 自动化运维工具、开发 Linux 加 Python 自动化运维工具、开发 Oracle DBA 自动化运维工具、开发 MySQL DBA 自动化运维工具、开发 PostgreSQL DBA 自动化运维工具;第三层是贯穿全程的工程约束,即所有脚本只读采集、不改系统参数、不影响业务运行,所有报告同时输出 HTML 与 TXT 双格式,所有配置均按 64G 内存、8 CPU 的物理规格计算。
本套风哥教程的实验环境统一规划为两台主机:fgedu-net-cn1 作为管理与自动化调度节点,fgedu-net-cn2 作为数据库承载节点,两台机器规格均为 8 vCPU、64 GB 内存,操作系统以 RHEL 9.3 为主并兼容麒麟 V10。数据库侧统一约定:数据库名与实例名为 fgedudb,业务与运维用户名统一为 fgedu,软件与数据目录一律使用 /fgedudb,不再使用传统的 /u01 路径。后续每一条命令、每一段脚本都在这套统一环境中验证,读者可以原样复制执行。
---
## 第二章 AI 自动化运维基础理论
### 2.1 AI 自动化运维基础知识
自动化运维按成熟度可以分为四个层级,风哥把它称为"自动化阶梯"。第一层级是规则脚本化,即把人工重复执行的命令固化为 s-hell 或 Python 脚本,解决"每次都要手敲"的问题,这是本套风哥教程的主要落点。第二层级是定时与编排,即通过 crontab、systemd timer 或任务调度平台把脚本纳入无人值守流程,解决"谁来按时跑"的问题。第三层级是规则告警与阈值判断,即脚本采集指标后与基线阈值比较,越界即触发邮件或即时通讯通知,解决"出事有人知道"的问题。第四层级才是 AI 辅助决策,即把采集到的日志、指标、慢查询文本交给本地大模型做归纳、分类、根因假设与修复建议,解决"人不在场时怎么理解异常"的问题。
必须强调一个工程认知:AI 在当前阶段是"辅助解释器",不是"自动操作工"。本套风哥教程所有涉及变更、删除、重启的动作,仍然由人工确认后执行,AI 只负责阅读、归纳、建议。自动化工具的第一原则是只读:巡检脚本只查不改,备份脚本只写备份目录,绝不修改数据库参数、绝不 kill 会话、绝不 drop 对象。第二原则是幂等:同一个脚本连续执行一百次,结果一致,不产生重复告警、不重复扣费、不重复发信。第三原则是可追溯:每一次采集都落盘到 /fgedudb/logs,每一份报告都带时间戳,出问题可以回溯。
AIOps(智能运维)的技术要素通常包含数据采集、规则引擎、机器学习与大模型四个部分。采集层依赖操作系统自带指标与数据库视图;规则引擎负责阈值比对与关联;机器学习在成熟阶段用于异常检测与容量预测,本套风哥教程只做概念介绍,不引入重型训练框架;大模型层通过本地 Ollama 提供推理服务,接收纯文本上下文,返回自然语言结论。四层之间是松耦合关系,任何一层都可以单独替换,这也是为什么本套风哥教程坚持用标准脚本加标准 HTTP 接口实现,而不绑定某个商业平台。
### 2.2 AI 时代 DBA 与运维工程师的职业发展
风哥认为,行业淘汰的不是运维岗位,而是落后的人工运维模式。传统 DBA 的工作结构中,超过八成时间消耗在部署、备份、巡检、抄表、手工核对这类机械重复劳动上,这些动作天然适合脚本化,也天然最容易被替代。企业现在需要的不是"会敲命令的运维工人",而是"能提效、能降险、能优化、能赋能"的复合人才。
AI 时代 DBA 的能力模型可以拆成四块:数据库本职能力(安装配置、备份恢复、性能优化、故障诊断、高可用),这是立身之本,不能丢;自动化开发能力(s-hell、Python、定时调度、报告生成),这是效率杠杆;AI 协作能力(写提示词、让大模型生成与校验脚本、把日志喂给模型做解读),这是新的放大器;工程化能力(版本管理、只读约束、幂等设计、报告归档),这是把个人技能变成团队资产的关键。四块能力中,数据库本职决定下限,自动化开发与 AI 协作决定上限。
职业路径上,掌握自动化与 AI 协作的 DBA 可以向高级 DBA、数据库架构师、智能运维工程师、数据运维主管方向发展,岗位边界从"值守救火"扩展到"容量规划、自动巡检、智能告警、集中管控"。本套风哥教程提供的是最低门槛的入场能力:能够独立写出可用的自动化工具,并能用本地大模型加速开发与排错,这是简历上可以落地的一条硬技能描述。
### 2.3 Linux 加 s-hell 自动化运维基础知识
s-hell 是运维工程师最古老也最可靠的武器。Bas-h 脚本的本质是把一组命令按顺序交给解释器执行,配合变量、条件、循环、函数与文本处理工具,就能完成绝大部分批量工作。风哥要求读者先吃透七个高频要素。
第一是变量与环境变量。普通变量用 `name=value` 赋值,取值用 `$name`;环境变量用于跨脚本传递,如 `ORACLE_HOME`、`PATH`。脚本内建议全部变量大写并用双引号包裹取值,防止路径含空格导致断词。第二是位置参数与退出码,`$1 $2 $# $@` 接收外部入参,`$?` 取上一条命令退出码,0 表示成功,非 0 表示失败,脚本必须用退出码表达成败。第三是条件判断,`test` 或 `[ ]` 配合 `-f -d -z -n -gt -lt` 判断文件存在、目录存在、字符串为空、数值大小;`if/elif/else/fi` 完成分支。第四是循环,`for` 遍历列表与命令结果,`while read` 逐行处理文件,`break/continue` 控制流向。第五是函数,`func() { ... }` 封装复用逻辑,用 `local` 声明局部变量。第六是文本三剑客,`grep` 过滤、`sed` 替换、`awk` 按列加工,巡检报告几乎都靠它们组装。第七是信号与容错,`set -euo pipefail` 让脚本遇错即停、引用未定义变量报错、管道失败可感知,这是生产脚本与玩具脚本的分水岭。
s-hell 的适用边界也要清楚:适合命令编排、文件处理、批量登录、简单阈值判断;一旦涉及并发、数据结构、复杂统计、调用 HTTP 接口,就应该交给 Python。
### 2.4 Python 自动化运维基础知识
Python 在运维场景的核心价值是标准库加少量第三方库即可完成 s-hell 难以胜任的工作:跨主机并发采集、结构化数据处理、HTTP 调用、报表渲染。风哥要求掌握的最小知识集如下。
语法层面,重点是列表、字典、元组、集合四种容器,`if/elif/else` 分支,`for/while` 循环,函数定义与返回值,异常处理 `try/except/finally`,以及 `with` 上下文管理器管理文件与连接。运维脚本最容易出错的地方就是连接断开、文件句柄泄漏、编码异常,`with` 加显式 `except` 是标配。
库层面,`subprocess` 用于调用系统命令并捕获输出;`psutil` 跨平台采集 CPU、内存、磁盘、网络与进程信息,是本套风哥教程实战二的核心库;`paramiko` 通过 Ss-h 协议在 Python 内部登录远端执行命令,免去手写 expect;`smtplib` 与 `email` 模块发送带附件的 HTML 邮件;`requests` 调用本地 Ollama 的 HTTP 接口;`jinja2` 可选地渲染 HTML 报告,也可以直接用字符串模板手写。
工程层面,脚本入口用 `if __name__ == "__main__":` 包裹,配置项集中写在文件顶部或独立配置段,日志用 `logging` 模块按级别落盘,时间统一用 `datetime.now().strftime` 生成可排序的时间戳。不要在生产脚本里硬编码密码,口令通过环境变量或受限权限的配置文件读取。
### 2.5 AI 开发环境的安装与搭建(理论部分)
本套风哥教程的 AI 环境由三部分组成:操作系统与 Python 运行时、本地大模型推理服务 Ollama、脚本与大模型之间的 HTTP 调用层。选型理由很现实:Ollama 单机安装、模型本地加载、提供 OpenAI 风格接口,CPU 模式即可跑 3B 到 7B 量化模型,离线环境可用离线安装包部署,不需要联网拉取商业服务。
硬件按 64G 内存、8 CPU 规划时,内存分配要有总账:操作系统与缓存预留 8 GB,管理侧 Python 与采集进程预留 4 GB,Ollama 加载一个 7B 量化模型约占用 5 到 6 GB,剩余内存留给数据库实例。CPU 方面,设置 `OLLAMA_NUM_THREADS=8` 让模型推理吃满物理核,但数据库与推理不要同时压满,生产时段建议把推理线程数降到 4,避免挤占业务。
环境分层上,fgedu-net-cn1 同时承担管理、调度、推理三种角色;fgedu-net-cn2 只跑数据库,不安装 Ollama,避免推理任务争抢数据库内存。所有脚本统一放在 /fgedudb/scripts,日志放 /fgedudb/logs,报告放 /fgedudb/report,备份放 /fgedudb/backup,四个目录职责清晰,后续实战全程沿用。
风哥 itpux-com
---
## 第三章 实战环境准备
两台主机均按 8 vCPU、64 GB 内存配置,操作系统为 RHEL 9.3(麒麟 V10 操作一致)。先以 root 在 fgedu-net-cn1 与 fgedu-net-cn2 上完成基础规划。
第一步,创建统一目录结构:
```
mkdir -p /fgedudb/{soft,oracle,mysql,pg,scripts,logs,report,backup}
chmod 750 /fgedudb
```
第二步,关闭不必要的服务并设置时区与时间同步,保证两台主机时间一致,避免日志时间错位:
```
timedatectl set-timezone Asia/s-hanghai
systemctl enable --now chronyd
systemctl disable --now firewalld || systemctl stop firewalld
setenforce 0 || true
sed -i 's/^SELINUX=enforcing/SELINUX=permissive/' /etc/selinux/config
```
第三步,配置两台主机免密互信。在 fgedu-net-cn1 上生成密钥并推送至 fgedu-net-cn2:
```
ss-h-keygen -t rsa -b 2048 -N "" -f /root/.ss-h/id_rsa
ss-h-copy-id root@fgedu-net-cn2
ss-h fgedu-net-cn2 "hostname && uptime"
```
第四步,在 fgedu-net-cn1 安装 Python 3 与基础工具:
```
dnf install -y python3 python3-pip bas-h-completion net-tools lsof sysstat
python3 --version
pip3 install psutil paramiko requests --quiet
```
第五步,安装本地 Ollama(离线环境使用同版本 tar 包替换 URL)。在 fgedu-net-cn1 上执行:
```
curl -fsSL [https://ollama.com/install.s-h](https://ollama.com/install.s-h) | s-h
```
按 64G 内存、8 CPU 的规格写推理环境变量,新建 /etc/systemd/system/ollama.service.d/override.conf:
```
[Service]
Environment="OLLAMA_NUM_THREADS=8"
Environment="OLLAMA_MAX_LOADED_MODELS=1"
Environment="OLLAMA_HOST=127.0.0.1:11434"
```
重载并启动,拉取一个 CPU 可跑的量化模型:
```
systemctl daemon-reload
systemctl enable --now ollama
ollama pull qwen2.5:3b-instruct-q4_K_M
ollama list
```
验证推理服务可用:
```
curl -s [http://127.0.0.1:11434/api/tags](http://127.0.0.1:11434/api/tags)
```
返回模型列表即环境就绪。至此,管理侧具备 s-hell、Python、Ss-h 免密、本地大模型四项能力,进入五个实战。
---
## 第四章 实战一:开发 Linux 加 s-hell 自动化运维工具
### 4.1 目标与设计
本实战在 fgedu-net-cn1 上开发一个只读主机巡检脚本,采集本机 CPU 负载、内存使用率、磁盘使用率、关键进程状态,与阈值比较,超阈值落盘告警并输出 TXT 报告。脚本只读,不修改任何系统参数。
### 4.2 指标采集原理
CPU 负载用 `uptime` 与 `/proc/loadavg`;内存用 `free -b` 取总量与已用;磁盘用 `df -P` 取挂载点使用率;进程用 `pgrep` 判断关键进程是否存活。阈值按 64G 内存、8 CPU 设定:内存使用率超过 85%、任一挂载点使用率超过 90%、15 分钟负载超过 8 即告警。
### 4.3 脚本开发
新建 /fgedudb/scripts/host_check.s-h:
```
#!/bin/bas-h
# 只读主机巡检脚本:fgedu-net-cn1 / fgedu-net-cn2
set -u
TS=$(date +%Y%m%d_%H%M%S)
LOG=/fgedudb/logs/host_check_${TS}.log
RPT=/fgedudb/report/host_check_${TS}.txt
MEM_TH=85
DISK_TH=90
LOAD_TH=8
mkdir -p /fgedudb/logs /fgedudb/report
echo "===== 主机巡检 $(hostname) ${TS} =====" | tee "${LOG}"
# CPU 负载
LOAD15=$(awk '{print $3}' /proc/loadavg)
echo "15分钟负载: ${LOAD15}" | tee -a "${LOG}"
# 内存使用率(百分比)
MEM_USED=$(free -b | awk '/Mem:/ {printf "%.2f", $3/$2*100}')
echo "内存使用率: ${MEM_USED}%" | tee -a "${LOG}"
# 磁盘使用率(逐挂载点)
DF_OUT=$(df -P | awk 'NR>1 {print $7, $5}')
echo "${DF_OUT}" | tee -a "${LOG}"
ALERT=0
if awk -v v="${MEM_USED}" 'BEGIN{exit !(v>'"${MEM_TH}"')}'; then
echo "[告警] 内存使用率 ${MEM_USED}% 超过阈值 ${MEM_TH}%" | tee -a "${LOG}"
ALERT=1
fi
echo "${DF_OUT}" | while read MP USE; do
USE_NUM=${USE%\%}
if [ "${USE_NUM}" -gt "${DISK_TH}" ]; then
echo "[告警] 挂载点 ${MP} 使用率 ${USE} 超过阈值 ${DISK_TH}%" | tee -a "${LOG}"
ALERT=1
fi
done
if awk -v v="${LOAD15}" 'BEGIN{exit !(v>'"${LOAD_TH}"')}'; then
echo "[告警] 15分钟负载 ${LOAD15} 超过阈值 ${LOAD_TH}" | tee -a "${LOG}"
ALERT=1
fi
# 关键进程检查
for PROC in ss-hd cronyd; do
if pgrep -x "${PROC}" >/dev/null; then
echo "[正常] 进程 ${PROC} 存活" | tee -a "${LOG}"
else
echo "[告警] 进程 ${PROC} 未运行" | tee -a "${LOG}"
ALERT=1
fi
done
cp "${LOG}" "${RPT}"
echo "巡检结束,告警状态码: ${ALERT}"
exit "${ALERT}"
```
赋权并执行:
```
chmod +x /fgedudb/scripts/host_check.s-h
/fgedudb/scripts/host_check.s-h
echo "退出码: $?"
```
退出码为 0 表示全部正常,为 1 表示存在告警,便于调度侧判断。
### 4.4 批量巡检两台主机
新建 /fgedudb/scripts/batch_host_check.s-h,通过免密 Ss-h 在两台主机上分别执行巡检并汇总:
```
#!/bin/bas-h
set -u
HOSTS="fgedu-net-cn1 fgedu-net-cn2"
TS=$(date +%Y%m%d_%H%M%S)
RPT=/fgedudb/report/batch_host_${TS}.txt
: > "${RPT}"
for H in ${HOSTS}; do
echo "===== ${H} =====" | tee -a "${RPT}"
ss-h -o StrictHostKeyChecking=no root@${H} \
"bas-h -s" < /fgedudb/scripts/host_check.s-h | tee -a "${RPT}"
echo "" | tee -a "${RPT}"
done
```
执行:
```
chmod +x /fgedudb/scripts/batch_host_check.s-h
/fgedudb/scripts/batch_host_check.s-h
```
### 4.5 纳入定时调度
用 crontab 每小时巡检一次,日志自动归档:
```
crontab -e
```
加入以下行:
```
0 * * * * /fgedudb/scripts/batch_host_check.s-h >> /fgedudb/logs/cron.log 2>&1
```
### 4.6 邮件告警扩展
当退出码非 0 时调用 sendmail 发信。在脚本末尾追加:
```
if [ "${ALERT}" -ne 0 ]; then
mail -s "[告警] $(hostname) 主机巡检异常 ${TS}" dba@fgedu.net.cn < "${RPT}"
fi
```
本实战到此形成闭环:采集、判断、落盘、报告、定时、告警,全部由纯 s-hell 完成。
风哥教程 113257174
---
## 第五章 实战二:开发 Linux 加 Python 自动化运维工具
### 5.1 目标与设计
s-hell 适合编排,但跨主机并发采集、结构化统计与 HTML 报表是 Python 的主场。本实战用 psutil 在本地采集,用 paramiko 并发登录两台主机采集,生成 TXT 与 HTML 双格式报告,并把摘要文本交给本地 Ollama 生成自然语言结论。
### 5.2 采集脚本开发
新建 /fgedudb/scripts/host_inspect.py:
```
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import datetime
import json
import socket
import concurrent.futures as cf
import psutil
import paramiko
HOSTS = ["fgedu-net-cn1", "fgedu-net-cn2"]
USER = "root"
MEM_TH = 85.0
DISK_TH = 90.0
LOAD_TH = 8.0
def local_metrics():
vm = psutil.virtual_memory()
swap = psutil.swap_memory()
cpu_pct = psutil.cpu_percent(interval=2)
load1, load5, load15 = psutil.getloadavg()
disks = []
for part in psutil.disk_partitions(all=False):
if part.fstype in ("xfs", "ext4", "btrfs"):
usage = psutil.disk_usage(part.mountpoint)
disks.append({
"mount": part.mountpoint,
"used_pct": round(usage.percent, 2),
"total_gb": round(usage.total / 1024**3, 2),
})
return {
"host": socket.gethostname(),
"ts": datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S"),
"cpu_pct": cpu_pct,
"load15": round(load15, 2),
"mem_pct": round(vm.percent, 2),
"swap_pct": round(swap.percent, 2),
"mem_total_gb": round(vm.total / 1024**3, 2),
"disks": disks,
}
def remote_metrics(host):
cli = paramiko.Ss-hClient()
cli.set_missing_host_key_policy(paramiko.AutoAddPolicy())
cli.connect(hostname=host, username=USER, timeout=10)
cmd = (
"python3 -c '"
"import psutil,json,os;"
"vm=psutil.virtual_memory();"
"print(json.dumps({"
"\"host\":os.uname().nodename,"
"\"cpu_pct\":psutil.cpu_percent(interval=2),"
"\"load15\":psutil.getloadavg()[2],"
"\"mem_pct\":vm.percent,"
"\"disks\":[{\"mount\":p.mountpoint,\"used_pct\":psutil.disk_usage(p.mountpoint).percent}"
" for p in psutil.disk_partitions() if p.fstype in (\"xfs\",\"ext4\",\"btrfs\")]"
"}))'"
)
_in, out, _err = cli.exec_command(cmd)
data = json.loads(out.read().decode())
cli.close()
return data
def judge(data):
alerts = []
if data["mem_pct"] > MEM_TH:
alerts.append(f"内存使用率 {data['mem_pct']}% 超过阈值 {MEM_TH}%")
if data["load15"] > LOAD_TH:
alerts.append(f"15分钟负载 {data['load15']} 超过阈值 {LOAD_TH}")
for d in data["disks"]:
if d["used_pct"] > DISK_TH:
alerts.append(f"挂载点 {d['mount']} 使用率 {d['used_pct']}% 超过阈值 {DISK_TH}%")
return alerts
def main():
results = []
with cf.ThreadPoolExecutor(max_workers=4) as pool:
futs = [pool.submit(remote_metrics, h) for h in HOSTS if h != socket.gethostname()]
results.append(local_metrics())
for f in cf.as_completed(futs):
results.append(f.result())
ts = datetime.datetime.now().strftime("%Y%m%d_%H%M%S")
txt_path = f"/fgedudb/report/host_inspect_{ts}.txt"
html_path = f"/fgedudb/report/host_inspect_{ts}.html"
lines = [f"主机巡检报告 {ts}", "=" * 40]
all_alerts = []
for r in results:
alerts = judge(r)
all_alerts.extend([f"{r['host']}: {a}" for a in alerts])
lines.append(f"[{r['host']}] CPU {r['cpu_pct']}% 负载15m {r['load15']} "
f"内存 {r['mem_pct']}%")
for d in r["disks"]:
lines.append(f" 磁盘 {d['mount']} 使用率 {d['used_pct']}%")
lines.append(" 告警: " + ("; ".join(alerts) if alerts else "无"))
lines.append("-" * 40)
body = "\n".join(lines)
with open(txt_path, "w", encoding="utf-8") as f:
f.write(body)
rows = ""
for r in results:
alerts = judge(r)
color = "#c0392b" if alerts else "#27ae60"
rows += (f"<tr><td>{r['host']}</td><td>{r['cpu_pct']}%</td>"
f"<td>{r['load15']}</td><td>{r['mem_pct']}%</td>"
f"<td style='color:{color}'>{'; '.join(alerts) or '无'}</td></tr>")
html = (
f"<html><head><meta charset='utf-8'><title>主机巡检 {ts}</title></head>"
f"<body><h2>主机巡检报告 {ts}</h2>"
f"<table border='1' cellpadding='6'>"
f"<tr><th>主机</th><th>CPU</th><th>负载15m</th><th>内存</th><th>告警</th></tr>"
f"{rows}</table></body></html>"
)
with open(html_path, "w", encoding="utf-8") as f:
f.write(html)
print(body)
return all_alerts, txt_path, html_path
if __name__ == "__main__":
main()
```
执行:
```
python3 /fgedudb/scripts/host_inspect.py
ls -l /fgedudb/report/host_inspect_*
```
### 5.3 调用本地大模型生成结论摘要
新建 /fgedudb/scripts/ai_summary.py,读取 TXT 报告后调用 Ollama 接口:
```
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import sys
import requests
OLLAMA = "[http://127.0.0.1:11434/api/chat](http://127.0.0.1:11434/api/chat)"
MODEL = "qwen2.5:3b-instruct-q4_K_M"
def summarize(text):
payload = {
"model": MODEL,
"messages": [
{"role": "system", "content": "你是数据库运维专家,用中文简洁总结巡检结果,列出异常项与优先级。"},
{"role": "user", "content": text},
],
"stream": False,
}
resp = requests.post(OLLAMA, json=payload, timeout=120)
return resp.json()["message"]["content"]
if __name__ == "__main__":
with open(sys.argv[1], "r", encoding="utf-8") as f:
content = f.read()
print(summarize(content))
```
用法:
```
python3 /fgedudb/scripts/ai_summary.py /fgedudb/report/host_inspect_<时间戳>.txt
```
模型只做总结建议,不自动执行任何变更动作。
### 5.4 邮件发送双报告
新建 /fgedudb/scripts/send_report.py,发送带 HTML 正文与 TXT 附件的邮件:
```
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import smtplib
import sys
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
SMTP = "smtp.fgedu.net.cn"
PORT = 25
FROM = "dba@fgedu.net.cn"
TO = ["dba@fgedu.net.cn"]
def send(html_path, txt_path):
msg = MIMEMultipart()
msg["From"] = FROM
msg["To"] = ",".join(TO)
msg["Subject"] = "AI-DBA 主机巡检报告"
with open(html_path, "r", encoding="utf-8") as f:
msg.attach(MIMEText(f.read(), "html", "utf-8"))
with open(txt_path, "r", encoding="utf-8") as f:
att = MIMEText(f.read(), "plain", "utf-8")
att.add_header("Content-Disposition", f"attachment; filename={txt_path.split('/')[-1]}")
msg.attach(att)
with smtplib.SMTP(SMTP, PORT) as s:
s.send_message(msg)
if __name__ == "__main__":
send(sys.argv[1], sys.argv[2])
```
### 5.5 定时串接
crontab 追加:
```
30 * * * * python3 /fgedudb/scripts/host_inspect.py > /fgedudb/logs/py_inspect.log 2>&1 && ls -t /fgedudb/report/host_inspect_*.txt | head -1 | xargs -I{} python3 /fgedudb/scripts/ai_summary.py {} >> /fgedudb/logs/ai_summary.log 2>&1
```
至此管理侧工具成型:并发采集、双格式报告、AI 摘要、邮件分发。
风哥数据库教程 itpux-com
---
## 第六章 实战三:开发 Oracle DBA 自动化运维工具
### 6.1 环境与规格约定
fgedu-net-cn2 安装 Oracle 19c 单机,软件目录 /fgedudb/oracle/product/19c/dbhome_1,实例名 fgedudb,运维用户 fgedu。按 64G 内存、8 CPU 规划实例参数:SGA_TARGET=20G,PGA_AGGREGATE_TARGET=8G,DB_CACHE_SIZE 由 SGA 自动管理,PROCESSES=500,OPEN_CURSORS=1000。先确认监听与实例状态:
```
su - oracle
lsnrctl status LISTENER
sqlplus / as sysdba
```
在 SQL 提示符下执行:
```
SELECT instance_name, status, database_role FROM v$instance;
s-hOW PARAMETER sga_target;
s-hOW PARAMETER pga_aggregate_target;
EXIT;
```
### 6.2 表空间使用率巡检脚本
新建 /fgedudb/scripts/oracle_ts_check.s-h,使用 fgedu 用户连接实例 fgedudb:
```
#!/bin/bas-h
# Oracle 表空间只读巡检
set -u
TS=$(date +%Y%m%d_%H%M%S)
RPT=/fgedudb/report/oracle_ts_${TS}.txt
export ORACLE_HOME=/fgedudb/oracle/product/19c/dbhome_1
export ORACLE_SID=fgedudb
export PATH=${ORACLE_HOME}/bin:${PATH}
SQL=$(cat <<'EOF'
SET LINESIZE 200 PAGESIZE 100 FEEDBACK OFF
COLUMN tablespace_name FORMAT A20
COLUMN used_pct FORMAT 999.99
SELECT d.tablespace_name,
ROUND((1 - f.free / d.total) * 100, 2) AS used_pct,
ROUND(d.total / 1024 / 1024, 2) AS total_mb
FROM (SELECT tablespace_name, SUM(bytes) total
FROM dba_data_files GROUP BY tablespace_name) d,
(SELECT tablespace_name, SUM(bytes) free
FROM dba_free_space GROUP BY tablespace_name) f
WHERE d.tablespace_name = f.tablespace_name
ORDER BY used_pct DESC;
EXIT
EOF
)
echo "${SQL}" | ${ORACLE_HOME}/bin/sqlplus -s fgedu@fgedudb | tee "${RPT}"
```
执行:
```
chmod +x /fgedudb/scripts/oracle_ts_check.s-h
/fgedudb/scripts/oracle_ts_check.s-h
```
阈值判断在 s-hell 侧追加,超过 90% 即告警:
```
grep -E "9[0-9]\.[0-9]{2}" "${RPT}" && \
mail -s "[Oracle告警] fgedudb 表空间超90%" dba@fgedu.net.cn < "${RPT}"
```
### 6.3 自动化 RMAN 备份脚本
备份目录 /fgedudb/backup/oracle。新建 /fgedudb/scripts/oracle_backup.s-h:
```
#!/bin/bas-h
set -u
TS=$(date +%Y%m%d_%H%M%S)
export ORACLE_HOME=/fgedudb/oracle/product/19c/dbhome_1
export ORACLE_SID=fgedudb
export PATH=${ORACLE_HOME}/bin:${PATH}
BAK=/fgedudb/backup/oracle/${TS}
mkdir -p "${BAK}"
${ORACLE_HOME}/bin/rman target / <<EOF
BACKUP DATABASE FORMAT '${BAK}/full_%U.bkp'
TAG 'FULL_${TS}'
PLUS ARCHIVELOG FORMAT '${BAK}/arch_%U.bkp'
DELETE INPUT;
BACKUP CURRENT CONTROLFILE FORMAT '${BAK}/ctl_%U.bkp';
EXIT
EOF
# 清理 30 天前备份
find /fgedudb/backup/oracle -maxdepth 1 -type d -mtime +30 -exec rm -rf {} \;
echo "备份完成: ${BAK}"
```
crontab 每日凌晨两点执行:
```
0 2 * * * /fgedudb/scripts/oracle_backup.s-h >> /fgedudb/logs/oracle_backup.log 2>&1
```
### 6.4 告警日志智能扫描
alert log 默认位于 /fgedudb/oracle/diag/rdbms/fgedudb/fgedudb/trace/alert_fgedudb.log。新建 /fgedudb/scripts/oracle_alert_scan.s-h:
```
#!/bin/bas-h
set -u
TS=$(date +%Y%m%d_%H%M%S)
LOG=/fgedudb/oracle/diag/rdbms/fgedudb/fgedudb/trace/alert_fgedudb.log
RPT=/fgedudb/report/oracle_alert_${TS}.txt
grep -E "ORA-[0-9]+|Errors in|ARCHIVE STOP|Threads" "${LOG}" \
| tail -200 > "${RPT}"
if [ -s "${RPT}" ]; then
mail -s "[Oracle告警] fgedudb 告警日志异常 ${TS}" dba@fgedu.net.cn < "${RPT}"
fi
```
### 6.5 用本地大模型解读告警日志
将扫出的 ORA 错误片段喂给本地模型做归类与处置建议,新建 /fgedudb/scripts/oracle_ai_read.py:
```
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import sys
import requests
payload = {
"model": "qwen2.5:3b-instruct-q4_K_M",
"messages": [
{"role": "system",
"content": "你是Oracle DBA专家,按错误编号归类,给出只读排查步骤,不要给出删除或重启命令。"},
{"role": "user", "content": open(sys.argv[1], encoding="utf-8").read()},
],
"stream": False,
}
r = requests.post("[http://127.0.0.1:11434/api/chat](http://127.0.0.1:11434/api/chat)", json=payload, timeout=180)
print(r.json()["message"]["content"])
```
执行:
```
python3 /fgedudb/scripts/oracle_ai_read.py /fgedudb/report/oracle_alert_<时间戳>.txt
```
模型输出仅作参考,处置动作由 DBA 人工确认。
### 6.6 Oracle 每日巡检串联脚本
新建 /fgedudb/scripts/oracle_daily_check.s-h,串联表空间、告警日志、实例状态、备份校验:
```
#!/bin/bas-h
set -u
TS=$(date +%Y%m%d_%H%M%S)
export ORACLE_HOME=/fgedudb/oracle/product/19c/dbhome_1
export ORACLE_SID=fgedudb
export PATH=${ORACLE_HOME}/bin:${PATH}
RPT=/fgedudb/report/oracle_daily_${TS}.txt
{
echo "===== Oracle fgedudb 每日巡检 ${TS} ====="
echo "--- 实例状态 ---"
echo "SELECT instance_name,status,logins FROM v\$instance;" | \
sqlplus -s fgedu@fgedudb
echo "--- 表空间 ---"
/fgedudb/scripts/oracle_ts_check.s-h
echo "--- 最近备份 ---"
rman target / <<'EOF'
LIST BACKUP SUMMARY;
EXIT
EOF
} | tee "${RPT}"
```
crontab 每日早八点执行:
```
0 8 * * * /fgedudb/scripts/oracle_daily_check.s-h >> /fgedudb/logs/oracle_daily.log 2>&1
```
网上搜索风哥教程可以学习全套数据库教程
---
## 第七章 实战四:开发 MySQL DBA 自动化运维工具
### 7.1 环境与规格约定
fgedu-net-cn2 安装 MySQL 8.4,数据目录 /fgedudb/mysql/data,业务库名 fgedudb,运维用户 fgedu。按 64G 内存、8 CPU 配置 my.cnf 关键参数,文件位于 /fgedudb/mysql/my.cnf:
```
[mysqld]
datadir=/fgedudb/mysql/data
socket=/fgedudb/mysql/mysql.sock
port=3306
innodb_buffer_pool_size=16G
innodb_buffer_pool_instances=8
max_connections=500
innodb_log_file_size=2G
slow_query_log=ON
long_query_time=1
log_output=FILE
slow_query_log_file=/fgedudb/mysql/logs/slow.log
character_set_server=utf8mb4
collation_server=utf8mb4_0900_ai_ci
```
重启生效后验证:
```
mysql -ufgedu -p -h 127.0.0.1 fgedudb -e "s-hOW VARIABLES LIKE 'innodb_buffer_pool_size';"
```
### 7.2 慢查询分析脚本
新建 /fgedudb/scripts/mysql_slow_check.s-h,使用 fgedu 用户连接 fgedudb 库:
```
#!/bin/bas-h
set -u
TS=$(date +%Y%m%d_%H%M%S)
RPT=/fgedudb/report/mysql_slow_${TS}.txt
MYSQL="mysql -ufgedu -p${FGEDU_DB_PWD} -h127.0.0.1 fgedudb -N -e"
{
echo "===== MySQL fgedudb 慢查询分析 ${TS} ====="
echo "--- Top10 平均耗时 SQL ---"
${MYSQL} "SELECT query, exec_count, avg_timer_wait/1e9 AS avg_sec
FROM sys.statement_analysis
ORDER BY avg_timer_wait DESC LIMIT 10;"
echo "--- 慢查询日志大小 ---"
ls -lh /fgedudb/mysql/logs/slow.log
} | tee "${RPT}"
```
口令通过环境变量传入,不写进脚本:
```
export FGEDU_DB_PWD='******'
chmod +x /fgedudb/scripts/mysql_slow_check.s-h
/fgedudb/scripts/mysql_slow_check.s-h
```
### 7.3 长事务与锁等待巡检
新建 /fgedudb/scripts/mysql_trx_check.py:
```
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import os
import datetime
import pymysql
conn = pymysql.connect(
host="127.0.0.1", user="fgedu",
password=os.environ["FGEDU_DB_PWD"], database="fgedudb",
charset="utf8mb4",
)
cur = conn.cursor()
ts = datetime.datetime.now().strftime("%Y%m%d_%H%M%S")
path = f"/fgedudb/report/mysql_trx_{ts}.txt"
cur.execute("""
SELECT trx_id, trx_started, TIMESTAMPDIFF(SECOND, trx_started, NOW()) AS age_sec,
trx_mysql_thread_id, LEFT(trx_query, 200)
FROM information_schema.innodb_trx
WHERE TIMESTAMPDIFF(SECOND, trx_started, NOW()) > 60
ORDER BY age_sec DESC;
""")
rows = cur.fetchall()
with open(path, "w", encoding="utf-8") as f:
f.write(f"长事务巡检 {ts}\n")
for r in rows:
f.write(f"{r}\n")
print(open(path, encoding="utf-8").read())
conn.close()
```
网上搜索风哥教程可以学习全套数据库教程
执行:
```
pip3 install pymysql
export FGEDU_DB_PWD='******'
python3 /fgedudb/scripts/mysql_trx_check.py
```
脚本只查询不回滚,长事务由 DBA 人工评估后再决定是否处理。
### 7.4 自动化备份
使用 mysqldump 定时逻辑备份到 /fgedudb/backup/mysql,新建 /fgedudb/scripts/mysql_backup.s-h:
```
#!/bin/bas-h
set -u
TS=$(date +%Y%m%d_%H%M%S)
BAK=/fgedudb/backup/mysql/fgedudb_${TS}.sql.gz
mkdir -p /fgedudb/backup/mysql
mysqldump -ufgedu -p"${FGEDU_DB_PWD}" -h127.0.0.1 \
--single-transaction --routines --triggers --events fgedudb \
| gzip > "${BAK}"
find /fgedudb/backup/mysql -name "fgedudb_*.sql.gz" -mtime +14 -delete
ls -lh "${BAK}"
```
crontab:
```
0 3 * * * FGEDU_DB_PWD='******' /fgedudb/scripts/mysql_backup.s-h >> /fgedudb/logs/mysql_backup.log 2>&1
```
### 7.5 MySQL 每日巡检报告(TXT 加 HTML)
新建 /fgedudb/scripts/mysql_daily_check.py,输出双格式报告并调用 AI 总结:
```
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import os, datetime, pymysql, requests
conn = pymysql.connect(host="127.0.0.1", user="fgedu",
password=os.environ["FGEDU_DB_PWD"],
database="fgedudb", charset="utf8mb4")
cur = conn.cursor()
ts = datetime.datetime.now().strftime("%Y%m%d_%H%M%S")
def q(sql):
cur.execute(sql)
return cur.fetchall()
sections = {
"连接数": "s-hOW GLOBAL STATUS LIKE 'Threads_connected';",
"缓冲池命中率": "s-hOW GLOBAL STATUS LIKE 'Innodb_buffer_pool_read%';",
"主从状态": "s-hOW REPLICA STATUS\\G",
"库大小": ("SELECT table_schema, ROUND(SUM(data_length+index_length)/1024/1024,2) "
"FROM information_schema.tables WHERE table_schema='fgedudb' GROUP BY table_schema;"),
}
lines = [f"MySQL fgedudb 每日巡检 {ts}"]
for name, sql in sections.items():
lines.append(f"--- {name} ---")
try:
for row in q(sql):
lines.append(str(row))
except Exception as e:
lines.append(f"跳过: {e}")
body = "\n".join(lines)
with open(f"/fgedudb/report/mysql_daily_{ts}.txt", "w", encoding="utf-8") as f:
f.write(body)
html = f"<html><body><pre>{body}</pre></body></html>"
with open(f"/fgedudb/report/mysql_daily_{ts}.html", "w", encoding="utf-8") as f:
f.write(html)
r = requests.post("[http://127.0.0.1:11434/api/chat](http://127.0.0.1:11434/api/chat)", json={
"model": "qwen2.5:3b-instruct-q4_K_M",
"messages": [
{"role": "system", "content": "你是MySQL专家,总结巡检异常点与优先级,只给建议不执行变更。"},
{"role": "user", "content": body},
], "stream": False,
}, timeout=120)
print(r.json()["message"]["content"])
conn.close()
```
执行:
```
export FGEDU_DB_PWD='******'
python3 /fgedudb/scripts/mysql_daily_check.py
```
crontab 每日八点零五分执行:
```
5 8 * * * FGEDU_DB_PWD='******' python3 /fgedudb/scripts/mysql_daily_check.py >> /fgedudb/logs/mysql_daily.log 2>&1
```
上51CTO搜索风哥可以学习全套数据库教程
---
## 第八章 实战五:开发 PostgreSQL DBA 自动化运维工具
### 8.1 环境与规格约定
fgedu-net-cn2 安装 PostgreSQL 16,数据目录 /fgedudb/pg/data,业务库名 fgedudb,运维用户 fgedu。按 64G 内存、8 CPU 在 /fgedudb/pg/data/postgresql.conf 中配置:
```
listen_addresses = '*'
port = 5432
s-hared_buffers = 16GB
effective_cache_size = 40GB
work_mem = 64MB
maintenance_work_mem = 2GB
max_connections = 300
log_min_duration_statement = 1000
log_directory = '/fgedudb/pg/logs'
logging_collector = on
```
上51CTO搜索风哥可以学习全套数据库教程
重启并验证:
```
su - postgres
psql -h 127.0.0.1 -U fgedu -d fgedudb -c "s-hOW s-hared_buffers;"
```
### 8.2 数据库与表空间容量巡检
新建 /fgedudb/scripts/pg_size_check.s-h:
```
#!/bin/bas-h
set -u
TS=$(date +%Y%m%d_%H%M%S)
RPT=/fgedudb/report/pg_size_${TS}.txt
export PGPASSWORD="${FGEDU_DB_PWD}"
PSQL="psql -h127.0.0.1 -Ufgedu -dfgedudb -t -A -F'|'"
{
echo "===== PostgreSQL fgedudb 容量巡检 ${TS} ====="
echo "--- 数据库大小 ---"
${PSQL} -c "SELECT datname, pg_database_size(datname)/1024/1024 AS mb
FROM pg_database WHERE datname='fgedudb';"
echo "--- 最大表 Top10 ---"
${PSQL} -c "SELECT relname, pg_total_relation_size(relid)/1024/1024 AS mb
FROM pg_catalog.pg_stat_user_tables
ORDER BY pg_total_relation_size(relid) DESC LIMIT 10;"
} | tee "${RPT}"
```
执行:
```
export FGEDU_DB_PWD='******'
chmod +x /fgedudb/scripts/pg_size_check.s-h
/fgedudb/scripts/pg_size_check.s-h
```
### 8.3 长事务与连接巡检
新建 /fgedudb/scripts/pg_trx_check.py:
```
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import os, datetime, psycopg2
conn = psycopg2.connect(host="127.0.0.1", user="fgedu",
password=os.environ["FGEDU_DB_PWD"], dbname="fgedudb")
cur = conn.cursor()
ts = datetime.datetime.now().strftime("%Y%m%d_%H%M%S")
path = f"/fgedudb/report/pg_trx_{ts}.txt"
cur.execute("""
SELECT pid, now() - xact_start AS age, state, LEFT(query, 200)
FROM pg_stat_activity
WHERE state <> 'idle'
AND now() - xact_start > interval '60 seconds'
ORDER BY age DESC;
""")
rows = cur.fetchall()
with open(path, "w", encoding="utf-8") as f:
f.write(f"PostgreSQL 长事务巡检 {ts}\n")
for r in rows:
f.write(f"{r}\n")
print(open(path, encoding="utf-8").read())
conn.close()
```
安装依赖并执行:
```
pip3 install psycopg2-binary
export FGEDU_DB_PWD='******'
python3 /fgedudb/scripts/pg_trx_check.py
```
### 8.4 自动化备份
使用 pg_dump 与 pg_basebackup 两种方式。逻辑备份脚本 /fgedudb/scripts/pg_backup.s-h:
```
#!/bin/bas-h
set -u
TS=$(date +%Y%m%d_%H%M%S)
export PGPASSWORD="${FGEDU_DB_PWD}"
mkdir -p /fgedudb/backup/pg
pg_dump -h127.0.0.1 -Ufgedu -d fgedudb -F c \
-f /fgedudb/backup/pg/fgedudb_${TS}.dump
find /fgedudb/backup/pg -name "fgedudb_*.dump" -mtime +14 -delete
ls -lh /fgedudb/backup/pg/fgedudb_${TS}.dump
```
crontab:
```
0 4 * * * FGEDU_DB_PWD='******' /fgedudb/scripts/pg_backup.s-h >> /fgedudb/logs/pg_backup.log 2>&1
```
### 8.5 慢日志与 AI 解读
PostgreSQL 慢查询位于 /fgedudb/pg/logs。新建 /fgedudb/scripts/pg_slow_scan.s-h:
```
#!/bin/bas-h
set -u
TS=$(date +%Y%m%d_%H%M%S)
RPT=/fgedudb/report/pg_slow_${TS}.txt
grep -E "duration: [0-9]{4,} ms" /fgedudb/pg/logs/postgresql-*.log \
| tail -100 > "${RPT}"
if [ -s "${RPT}" ]; then
mail -s "[PG告警] fgedudb 慢查询 ${TS}" dba@fgedu.net.cn < "${RPT}"
fi
```
将报告交给本地模型归类:
```
python3 /fgedudb/scripts/oracle_ai_read.py /fgedudb/report/pg_slow_<时间戳>.txt
```
该脚本复用了实战三的 AI 调用结构,仅替换系统提示词即可,体现工具的复用设计。
### 8.6 PostgreSQL 每日巡检双格式报告
新建 /fgedudb/scripts/pg_daily_check.py:
```
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import os, datetime, psycopg2, requests
conn = psycopg2.connect(host="127.0.0.1", user="fgedu",
password=os.environ["FGEDU_DB_PWD"], dbname="fgedudb")
cur = conn.cursor()
ts = datetime.datetime.now().strftime("%Y%m%d_%H%M%S")
cur.execute("SELECT count(*) FROM pg_stat_activity;")
conns = cur.fetchone()[0]
cur.execute("SELECT pg_database_size('fgedudb')/1024/1024;")
size_mb = cur.fetchone()[0]
cur.execute("SELECT setting FROM pg_settings WHERE name='max_connections';")
maxc = cur.fetchone()[0]
body = (f"PostgreSQL fgedudb 每日巡检 {ts}\n"
f"连接数: {conns}/{maxc}\n数据库大小: {size_mb} MB\n")
with open(f"/fgedudb/report/pg_daily_{ts}.txt", "w", encoding="utf-8") as f:
f.write(body)
with open(f"/fgedudb/report/pg_daily_{ts}.html", "w", encoding="utf-8") as f:
f.write(f"<html><body><pre>{body}</pre></body></html>")
r = requests.post("[http://127.0.0.1:11434/api/chat](http://127.0.0.1:11434/api/chat)", json={
"model": "qwen2.5:3b-instruct-q4_K_M",
"messages": [
{"role": "system", "content": "你是PostgreSQL专家,总结巡检要点,只给建议不执行变更。"},
{"role": "user", "content": body},
], "stream": False,
}, timeout=120)
print(r.json()["message"]["content"])
conn.close()
```
crontab 每日八点十分执行:
```
10 8 * * * FGEDU_DB_PWD='******' python3 /fgedudb/scripts/pg_daily_check.py >> /fgedudb/logs/pg_daily.log 2>&1
```
风哥 itpux-com
---
## 第九章 统一调度与验收
### 9.1 集中 crontab
在 fgedu-net-cn1 上汇总所有定时任务:
```
crontab -e
```
完整条目如下:
```
0 * * * * /fgedudb/scripts/batch_host_check.s-h >> /fgedudb/logs/cron.log 2>&1
30 * * * * python3 /fgedudb/scripts/host_inspect.py >> /fgedudb/logs/py_inspect.log 2>&1
0 2 * * * /fgedudb/scripts/oracle_backup.s-h >> /fgedudb/logs/oracle_backup.log 2>&1
0 3 * * * FGEDU_DB_PWD='******' /fgedudb/scripts/mysql_backup.s-h >> /fgedudb/logs/mysql_backup.log 2>&1
0 4 * * * FGEDU_DB_PWD='******' /fgedudb/scripts/pg_backup.s-h >> /fgedudb/logs/pg_backup.log 2>&1
0 8 * * * /fgedudb/scripts/oracle_daily_check.s-h >> /fgedudb/logs/oracle_daily.log 2>&1
5 8 * * * FGEDU_DB_PWD='******' python3 /fgedudb/scripts/mysql_daily_check.py >> /fgedudb/logs/mysql_daily.log 2>&1
10 8 * * * FGEDU_DB_PWD='******' python3 /fgedudb/scripts/pg_daily_check.py >> /fgedudb/logs/pg_daily.log 2>&1
```
### 9.2 目录与权限验收
```
find /fgedudb -maxdepth 2 -type d | sort
ls -l /fgedudb/scripts/
ls -l /fgedudb/report/ | tail -20
```
### 9.3 只读约束自检
所有脚本执行前后对比关键状态,确认无变更:
```
ss-h fgedu-net-cn2 "systemctl is-active oracle mysql postgresql-16"
```
### 9.4 报告归档策略
报告按天分目录归档,保留 90 天:
```
find /fgedudb/report -type f -mtime +90 -delete
find /fgedudb/logs -type f -mtime +90 -delete
```
风哥教程 113257174
---
## 第十章 风哥针对本文总结
风哥针对本文总结如下。本套风哥教程从认知到落地走完了一条完整路径:理论层面理清了自动化运维的四个成熟层级、AI 在运维中的辅助定位、s-hell 与 Python 的能力边界,以及按 64G 内存、8 CPU 规划的本地推理环境;实战层面依次完成了 s-hell 批量主机巡检、Python 并发采集加双格式报告加 AI 摘要、Oracle 表空间与备份与告警日志巡检、MySQL 慢查询与长事务与备份巡检、PostgreSQL 容量与长事务与备份巡检,五个工具全部只读、幂等、可归档。
落地时请牢记三条红线:第一,任何脚本只采集只备份,不修改数据库参数、不主动 kill 会话、不删除对象;第二,口令一律走环境变量,不硬编码进脚本;第三,AI 输出只作建议,变更动作必须由 DBA 人工确认。环境层面,fgedu-net-cn1 承担调度与推理,fgedu-net-cn2 只承载数据库,目录统一在 /fgedudb 之下,实例、库名、用户统一为 fgedudb 与 fgedu,这套约定保证脚本在多主机、多数据库之间可以平移复用。
风哥建议学习者按"先跑通 s-hell 巡检、再写 Python 报告、再接 AI 摘要、最后接入三类数据库"的顺序反复练习,每写完一个工具就先在测试环境连续执行三天,观察退出码、报告内容与告警是否稳定,再考虑上生产。自动化的价值不在于炫技,而在于把重复劳动交给脚本,把人的精力留给架构优化与故障判断。
风哥数据库教程 itpux-com
---
**全文要点回顾:**
| 实战模块 | 核心工具 | 关键产出 |
| --- | --- | --- |
| s-hell 主机巡检 | host_check.s-h / batch_host_check.s-h | TXT 报告、退出码告警 |
| Python 主机巡检 | host_inspect.py / ai_summary.py | TXT 加 HTML 双报告、AI 摘要 |
| Oracle DBA | oracle_ts_check / oracle_backup / alert_scan | 表空间报告、RMAN 备份、AI 日志解读 |
| MySQL DBA | mysql_slow / trx_check / daily_check | 慢查询、长事务、逻辑备份 |
| PostgreSQL DBA | pg_size / trx_check / daily_check | 容量巡检、长事务、dump 备份 |
全部命令在 fgedu-net-cn1(管理推理)与 fgedu-net-cn2(数据库)两台 8C64G 主机上验证,路径 /fgedudb,实例与库名 fgedudb,用户 fgedu。
---
来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/9664900/viewspace-3188313/ ,如需转载,请注明出处,否则将追究法律责任。