日常运维需要 监控CPU、内存、磁盘、数据库活动、查询性能等。需要考虑到Cloudberry是一个分布式数据库,基于PostgreSQL,通常运行在多台主机上(master和segments)。所以监控可能包括对集群的监控,使用gpstate、gpconfig等工具,也可能包括系统级别的监控。
需要写出一个shell脚本,可能收集一些关键指标并输出。由于没有具体指定监控内容,我们可以提供一个全面的脚本,检查系统资源(CPU、内存、磁盘)、Cloudberry进程状态、数据库大小、活动会话、慢查询、锁等。同时要确保脚本有适当的错误处理和输出格式。
我们需要提供代码和解释。脚本应该能够远程执行?但作为一个shell脚本,通常是在master节点运行,通过gpssh或直接本地命令。可以包含gpstate和psql查询。
以下是一个用于监控 Cloudberry 性能的 Shell 脚本。它会收集系统资源、集群状态、数据库活动等关键指标,并以易读的格式输出。适合 DBA 日常巡检或集成到监控系统中。
#!/bin/bash
# Cloudberry 性能监控脚本
# 用法: ./gp_monitor.sh [数据库名]
# 需以 gpadmin 用户运行,且所有节点已配置 SSH 免密
set -euo pipefail
# 配置参数
PGPORT=${PGPORT:-5432}
PGDATABASE=${1:-postgres} # 默认监控 postgres 库
PGUSER=${PGUSER:-gpadmin}
SEG_HOSTS_FILE=~/seg_hosts # 包含所有 segment 主机名的文件(每行一个)
LOG_DIR=/tmp/gp_monitor
TIMESTAMP=$(date +"%Y%m%d_%H%M%S")
OUTPUT_FILE="${LOG_DIR}/gp_monitor_${TIMESTAMP}.log"
# 创建日志目录
mkdir -p "${LOG_DIR}"
# 打印带时间戳的标题
print_header() {
echo "========================================" | tee -a "${OUTPUT_FILE}"
echo "$(date '+%Y-%m-%d %H:%M:%S') - $1" | tee -a "${OUTPUT_FILE}"
echo "========================================" | tee -a "${OUTPUT_FILE}"
}
# 打印小节
print_section() {
echo "" | tee -a "${OUTPUT_FILE}"
echo "--- $1 ---" | tee -a "${OUTPUT_FILE}"
}
# 收集 Master 节点系统信息
collect_system_stats_master() {
print_section "Master 节点系统状态"
echo "主机名: $(hostname)" | tee -a "${OUTPUT_FILE}"
echo "负载: $(uptime)" | tee -a "${OUTPUT_FILE}"
echo "内存:" | tee -a "${OUTPUT_FILE}"
free -h | tee -a "${OUTPUT_FILE}"
echo "CPU 使用:" | tee -a "${OUTPUT_FILE}"
top -bn1 | head -10 | tee -a "${OUTPUT_FILE}"
echo "磁盘使用:" | tee -a "${OUTPUT_FILE}"
df -h | grep -E "(/dev/|/data)" | tee -a "${OUTPUT_FILE}"
}
# 收集所有 Segment 节点系统信息(通过 gpssh)
collect_system_stats_segments() {
if [[ ! -f "${SEG_HOSTS_FILE}" ]]; then
echo "警告: Segment 主机列表文件 ${SEG_HOSTS_FILE} 不存在,跳过远程收集" | tee -a "${OUTPUT_FILE}"
return
fi
print_section "Segment 节点系统状态"
echo "--- 各节点负载 ---" | tee -a "${OUTPUT_FILE}"
gpssh -f "${SEG_HOSTS_FILE}" -e 'uptime' 2>&1 | tee -a "${OUTPUT_FILE}"
echo "--- 各节点内存 ---" | tee -a "${OUTPUT_FILE}"
gpssh -f "${SEG_HOSTS_FILE}" -e 'free -h' 2>&1 | tee -a "${OUTPUT_FILE}"
echo "--- 各节点磁盘使用 ---" | tee -a "${OUTPUT_FILE}"
gpssh -f "${SEG_HOSTS_FILE}" -e 'df -h /data' 2>&1 | tee -a "${OUTPUT_FILE}" # 假设数据目录在 /data
}
# 收集 Cloudberry 集群状态
collect_gp_state() {
print_section "Cloudberry 集群状态"
echo "Segment 状态 (gpstate):" | tee -a "${OUTPUT_FILE}"
gpstate -s 2>&1 | tee -a "${OUTPUT_FILE}"
echo "" | tee -a "${OUTPUT_FILE}"
echo "Mirror 状态 (若存在):" | tee -a "${OUTPUT_FILE}"
gpstate -m 2>&1 | tee -a "${OUTPUT_FILE}"
}
# 收集数据库级统计信息
collect_db_stats() {
print_section "数据库统计信息 (数据库: ${PGDATABASE})"
# 数据库大小
echo "数据库大小:" | tee -a "${OUTPUT_FILE}"
psql -d "${PGDATABASE}" -Atc "SELECT pg_size_pretty(sum(pg_database_size(datname))) FROM pg_database WHERE datname = current_database();" 2>&1 | tee -a "${OUTPUT_FILE}"
# 表大小 Top 10
echo "" | tee -a "${OUTPUT_FILE}"
echo "表大小 Top 10:" | tee -a "${OUTPUT_FILE}"
psql -d "${PGDATABASE}" -c "SELECT schemaname, tablename, pg_size_pretty(pg_total_relation_size(schemaname||'.'||tablename)) as total_size FROM pg_tables WHERE schemaname NOT IN ('pg_catalog','information_schema') ORDER BY pg_total_relation_size(schemaname||'.'||tablename) DESC LIMIT 10;" 2>&1 | tee -a "${OUTPUT_FILE}"
# 活动会话数
echo "" | tee -a "${OUTPUT_FILE}"
echo "当前活动会话数:" | tee -a "${OUTPUT_FILE}"
psql -d "${PGDATABASE}" -c "SELECT count(*) FROM pg_stat_activity WHERE state = 'active';" 2>&1 | tee -a "${OUTPUT_FILE}"
# 长事务(超过5分钟)
echo "" | tee -a "${OUTPUT_FILE}"
echo "运行超过5分钟的事务:" | tee -a "${OUTPUT_FILE}"
psql -d "${PGDATABASE}" -c "SELECT pid, usename, query_start, now() - query_start as duration, query FROM pg_stat_activity WHERE state = 'active' AND now() - query_start > interval '5 minutes' ORDER BY query_start;" 2>&1 | tee -a "${OUTPUT_FILE}"
# 锁等待
echo "" | tee -a "${OUTPUT_FILE}"
echo "当前锁等待:" | tee -a "${OUTPUT_FILE}"
psql -d "${PGDATABASE}" -c "SELECT pid, locktype, relation::regclass, mode, granted FROM pg_locks WHERE NOT granted;" 2>&1 | tee -a "${OUTPUT_FILE}"
# 慢查询统计(按执行时间倒序)
echo "" | tee -a "${OUTPUT_FILE}"
echo "最近慢查询(按执行时间倒序):" | tee -a "${OUTPUT_FILE}"
psql -d "${PGDATABASE}" -c "SELECT query, (now() - query_start) as duration, state FROM pg_stat_activity WHERE state = 'active' ORDER BY duration DESC LIMIT 5;" 2>&1 | tee -a "${OUTPUT_FILE}"
}
# 主函数
main() {
print_header "Cloudberry 性能监控开始"
collect_system_stats_master
collect_system_stats_segments
collect_gp_state
collect_db_stats
print_header "监控完成,日志已保存至 ${OUTPUT_FILE}"
}
# 运行主函数
main
使用说明
-
保存脚本:将以上内容保存为
gp_monitor.sh,并赋予执行权限:bash
chmod +x gp_monitor.sh
-
前置条件:
-
以
gpadmin用户执行(或具有相应权限的用户)。 -
所有 Cloudberry 节点(master 和 segments)之间已配置 SSH 免密登录(
gpssh依赖)。 -
创建一个包含所有 segment 主机名的文件,例如
~/seg_hosts,每行一个主机名。可通过gpscp或手动创建。 -
确保
psql、gpstate等 Cloudberry 命令在 PATH 中(通常已配置在 gpadmin 环境变量中)。
-
-
运行:
bash
./gp_monitor.sh [数据库名]
如果不指定数据库名,默认监控
postgres库。 -
输出:
-
监控结果实时打印到终端,同时追加保存到
/tmp/gp_monitor/gp_monitor_YYYYMMDD_HHMMSS.log。 -
日志包含时间戳和清晰的章节划分,便于后续分析。
-
监控指标说明
-
Master 节点系统状态:主机名、负载、内存、CPU 概况、磁盘使用。
-
Segment 节点系统状态:通过
gpssh并发收集所有 segment 的负载、内存、磁盘使用(需指定数据目录,示例中为/data,请根据实际修改)。 -
Cloudberry 集群状态:
gpstate -s输出 segment 状态,gpstate -m输出 mirror 状态(如果有)。 -
数据库统计:
-
当前数据库总大小。
-
占用空间最大的前 10 张表。
-
活动会话数。
-
执行超过 5 分钟的长事务。
-
当前未获授权的锁等待。
-
按耗时排序的前 5 个活跃查询。
-
扩展建议
-
如需监控更多指标,可在
collect_db_stats函数中添加自定义 SQL 查询(如索引使用情况、缓存命中率等)。 -
若希望定时运行并告警,可将脚本加入 crontab,并解析输出中的异常值(如长事务、锁等待)发送邮件或集成到 Prometheus/Grafana。
-
对于大规模集群,
gpssh并发可能产生大量输出,可根据需要调整或只收集关键指标。
此脚本为通用模板,实际环境中请根据 Cloudberry 版本、集群配置和数据目录位置适当调整。

被折叠的 条评论
为什么被折叠?



