mongodb巡检
·
#!/bin/bash
# MongoDB巡检脚本
# 支持单机、副本集和分片集群
set -euo pipefail
# 默认配置
MONGO_HOST="localhost"
MONGO_PORT="27017"
MONGO_USER=""
MONGO_PASSWORD=""
MONGO_AUTH_DB="admin"
MONGO_SSL=false
CHECK_REPLICA=true
CHECK_SHARDING=true
OUTPUT_DIR="/tmp/mongodb_healthcheck_$(date +%Y%m%d_%H%M%S)"
REPORT_FILE="${OUTPUT_DIR}/mongodb_health_report.txt"
JSON_FILE="${OUTPUT_DIR}/mongodb_details.json"
# 颜色输出
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
CYAN='\033[0;36m'
NC='\033[0m' # No Color
# 显示用法
usage() {
echo "用法: $0 [选项]"
echo "选项:"
echo " -h, --host <host> MongoDB主机 (默认: localhost)"
echo " -p, --port <port> MongoDB端口 (默认: 27017)"
echo " -u, --user <username> MongoDB用户名"
echo " -p, --password <password> MongoDB密码"
echo " -a, --auth-db <db> 认证数据库 (默认: admin)"
echo " --ssl 使用SSL连接"
echo " --no-replica 不检查副本集"
echo " --no-shard 不检查分片"
echo " -o, --output <dir> 输出目录"
echo " --help 显示帮助信息"
echo ""
echo "示例:"
echo " $0 -h 127.0.0.1 -p 27017 -u admin -p password"
echo " $0 --ssl --no-shard"
}
# 构建mongo连接字符串
build_mongo_uri() {
local uri="mongodb://"
if [ -n "$MONGO_USER" ] && [ -n "$MONGO_PASSWORD" ]; then
uri="${uri}${MONGO_USER}:${MONGO_PASSWORD}@"
fi
uri="${uri}${MONGO_HOST}:${MONGO_PORT}"
if [ -n "$MONGO_AUTH_DB" ]; then
uri="${uri}/?authSource=${MONGO_AUTH_DB}"
fi
if [ "$MONGO_SSL" = true ]; then
uri="${uri}&ssl=true"
fi
echo "$uri"
}
# 执行MongoDB命令
run_mongo_command() {
local command="$1"
local uri=$(build_mongo_uri)
if [ "$MONGO_SSL" = true ]; then
mongo --quiet --ssl --host "$uri" --eval "$command"
else
mongo --quiet "$uri" --eval "$command"
fi
}
# 检查MongoDB连接
check_connection() {
echo -e "${BLUE}=== 检查MongoDB连接 ===${NC}"
if ! result=$(run_mongo_command "db.adminCommand('ping')" 2>/dev/null); then
echo -e "${RED}错误: 无法连接到MongoDB${NC}"
exit 1
fi
if echo "$result" | grep -q '"ok" : 1'; then
echo -e "${GREEN}✓ MongoDB连接成功${NC}"
else
echo -e "${RED}✗ MongoDB连接失败${NC}"
exit 1
fi
}
# 获取服务器信息
get_server_info() {
echo -e "${BLUE}=== 服务器信息 ===${NC}"
local info=$(run_mongo_command "db.hostInfo()")
local version=$(run_mongo_command "db.version()")
local build_info=$(run_mongo_command "db.serverBuildInfo()")
echo "MongoDB版本: $version"
echo "主机名: $(echo "$info" | grep 'hostname' | cut -d'"' -f4)"
echo "CPU架构: $(echo "$info" | grep 'architecture' | cut -d'"' -f4)"
echo "操作系统: $(echo "$info" | grep 'name' | cut -d'"' -f4)"
echo "内存: $(echo "$info" | grep 'memSizeMB' | awk '{print $3}') MB"
echo "启动时间: $(run_mongo_command "db.serverStatus().uptimeEstimate") 秒"
}
# 检查副本集状态
check_replica_set() {
if [ "$CHECK_REPLICA" = false ]; then
return
fi
echo -e "${BLUE}=== 副本集状态检查 ===${NC}"
local rs_status=$(run_mongo_command "rs.status()" 2>/dev/null || echo "NOT_REPLICA_SET")
if echo "$rs_status" | grep -q "NOT_REPLICA_SET"; then
echo -e "${YELLOW}⚠ 未配置副本集${NC}"
return
fi
local rs_config=$(run_mongo_command "rs.conf()")
local primary=$(echo "$rs_status" | grep '"stateStr" : "PRIMARY"' -B5 | grep 'name' | cut -d'"' -f4)
local secondaries=$(echo "$rs_status" | grep '"stateStr" : "SECONDARY"' -B5 | grep 'name' | cut -d'"' -f4)
echo "副本集名称: $(echo "$rs_config" | grep '_id' | cut -d'"' -f4)"
echo "主节点: ${primary:-无}"
echo "从节点: ${secondaries:-无}"
# 检查副本集健康状态
local healthy_members=$(echo "$rs_status" | grep '"health" : 1' | wc -l)
local total_members=$(echo "$rs_status" | grep '"name" :' | wc -l)
if [ "$healthy_members" -eq "$total_members" ]; then
echo -e "${GREEN}✓ 所有副本集成员健康${NC}"
else
echo -e "${RED}✗ 有副本集成员不健康${NC}"
fi
}
# 检查分片状态
check_sharding() {
if [ "$CHECK_SHARDING" = false ]; then
return
fi
echo -e "${BLUE}=== 分片集群状态检查 ===${NC}"
local sharding_status=$(run_mongo_command "sh.status()" 2>/dev/null || echo "NOT_SHARDED")
if echo "$sharding_status" | grep -q "NOT_SHARDED"; then
echo -e "${YELLOW}⚠ 未启用分片${NC}"
return
fi
local shards=$(run_mongo_command "db.adminCommand({ listShards: 1 })")
local shard_count=$(echo "$shards" | grep '"host" :' | wc -l)
echo "分片数量: $shard_count"
echo "分片列表:"
echo "$shards" | grep '"host" :' | cut -d'"' -f4
# 检查配置服务器
local config_status=$(run_mongo_command "db.adminCommand({ getCmdLineOpts: 1 })")
if echo "$config_status" | grep -q "configsvr"; then
echo -e "${GREEN}✓ 配置服务器运行中${NC}"
else
echo -e "${YELLOW}⚠ 未检测到配置服务器${NC}"
fi
}
# 检查数据库状态
check_databases() {
echo -e "${BLUE}=== 数据库状态检查 ===${NC}"
local dbs=$(run_mongo_command "show dbs")
local db_count=$(echo "$dbs" | grep -v "admin\|config\|local" | wc -l)
echo "数据库数量: $db_count"
echo "数据库列表:"
echo "$dbs" | awk '{print " " $1 " - " $2}'
}
# 检查集合状态
check_collections() {
echo -e "${BLUE}=== 集合状态检查 ===${NC}"
local dbs=$(run_mongo_command "show dbs" | grep -v "admin\|config\|local" | awk '{print $1}')
for db in $dbs; do
echo "数据库: $db"
local collections=$(run_mongo_command "use $db; show collections")
local coll_count=$(echo "$collections" | wc -l)
echo " 集合数量: $coll_count"
if [ "$coll_count" -gt 10 ]; then
echo " 前10个集合:"
echo "$collections" | head -10 | awk '{print " " $1}'
else
echo "$collections" | awk '{print " " $1}'
fi
done
}
# 检查性能指标
check_performance() {
echo -e "${BLUE}=== 性能指标检查 ===${NC}"
local server_status=$(run_mongo_command "db.serverStatus()")
# 连接数
local connections=$(echo "$server_status" | grep '"current" :' | head -1 | awk '{print $3}')
local available=$(echo "$server_status" | grep '"available" :' | awk '{print $3}')
echo "当前连接数: $connections / $available"
# 内存使用
local memory=$(echo "$server_status" | grep '"resident" :' | awk '{print $3}')
echo "常驻内存: ${memory}MB"
# 操作计数器
local inserts=$(echo "$server_status" | grep '"insert" :' | awk '{print $3}')
local queries=$(echo "$server_status" | grep '"query" :' | awk '{print $3}')
local updates=$(echo "$server_status" | grep '"update" :' | awk '{print $3}')
local deletes=$(echo "$server_status" | grep '"delete" :' | awk '{print $3}')
echo "操作统计 - 插入: $inserts, 查询: $queries, 更新: $updates, 删除: $deletes"
}
# 检查索引状态
check_indexes() {
echo -e "${BLUE}=== 索引状态检查 ===${NC}"
local dbs=$(run_mongo_command "show dbs" | grep -v "admin\|config\|local" | awk '{print $1}')
for db in $dbs; do
echo "数据库: $db"
local collections=$(run_mongo_command "use $db; show collections")
for coll in $collections; do
local indexes=$(run_mongo_command "use $db; db.$coll.getIndexes().length")
echo " 集合: $coll - 索引数: ${indexes:-0}"
done
done
}
# 检查慢查询
check_slow_queries() {
echo -e "${BLUE}=== 慢查询检查 ===${NC}"
local profile_status=$(run_mongo_command "db.getProfilingStatus()")
local level=$(echo "$profile_status" | grep '"was" :' | awk '{print $3}')
local slowms=$(echo "$profile_status" | grep '"slowms" :' | awk '{print $3}')
echo "Profiling级别: $level"
echo "慢查询阈值: ${slowms}ms"
if [ "$level" -gt 0 ]; then
local slow_queries=$(run_mongo_command "db.system.profile.find({ millis: { \\\$gt: 100 } }).count()")
echo "超过100ms的慢查询数量: $slow_queries"
else
echo -e "${YELLOW}⚠ Profiling未启用,无法统计慢查询${NC}"
fi
}
# 检查备份状态
check_backup() {
echo -e "${BLUE}=== 备份状态检查 ===${NC}"
# 检查是否配置了OPLOG(副本集)
local oplog_size=$(run_mongo_command "db.getReplicationInfo().logSizeMB" 2>/dev/null || echo "0")
if [ "$oplog_size" -gt 0 ]; then
echo "OPLOG大小: ${oplog_size}MB"
else
echo -e "${YELLOW}⚠ 未检测到OPLOG(可能不是副本集)${NC}"
fi
# 检查数据目录权限
local data_dir=$(run_mongo_command "db.serverCmdLineOpts().parsed.storage.dbPath" 2>/dev/null || echo "未知")
echo "数据目录: $data_dir"
}
# 生成详细报告
generate_detailed_report() {
echo -e "${BLUE}=== 生成详细报告 ===${NC}"
local commands=(
"db.serverStatus()"
"db.stats()"
"db.adminCommand({ getCmdLineOpts: 1 })"
"db.adminCommand({ hostInfo: 1 })"
"db.adminCommand({ buildInfo: 1 })"
)
for cmd in "${commands[@]}"; do
echo "执行: $cmd" >> "$JSON_FILE"
run_mongo_command "printjson($cmd)" >> "$JSON_FILE"
echo "" >> "$JSON_FILE"
done
echo -e "${GREEN}✓ 详细报告已保存到: $JSON_FILE${NC}"
}
# 汇总检查结果
summary() {
echo -e "${CYAN}=== 巡检总结 ===${NC}"
echo "检查时间: $(date)"
echo "MongoDB主机: $MONGO_HOST:$MONGO_PORT"
echo "报告文件: $REPORT_FILE"
echo "详细数据: $JSON_FILE"
echo -e "${GREEN}MongoDB巡检完成!${NC}"
}
# 主函数
main() {
# 创建输出目录
mkdir -p "$OUTPUT_DIR"
# 重定向输出到报告文件
exec > >(tee "$REPORT_FILE") 2>&1
echo -e "${GREEN}开始MongoDB巡检...${NC}"
echo "开始时间: $(date)"
echo "输出目录: $OUTPUT_DIR"
echo ""
# 执行各项检查
check_connection
echo ""
get_server_info
echo ""
check_replica_set
echo ""
check_sharding
echo ""
check_databases
echo ""
check_collections
echo ""
check_performance
echo ""
check_indexes
echo ""
check_slow_queries
echo ""
check_backup
echo ""
generate_detailed_report
echo ""
summary
}
# 解析参数
while [[ $# -gt 0 ]]; do
case $1 in
-h|--host)
MONGO_HOST="$2"
shift 2
;;
-p|--port)
MONGO_PORT="$2"
shift 2
;;
-u|--user)
MONGO_USER="$2"
shift 2
;;
-p|--password)
MONGO_PASSWORD="$2"
shift 2
;;
-a|--auth-db)
MONGO_AUTH_DB="$2"
shift 2
;;
--ssl)
MONGO_SSL=true
shift
;;
--no-replica)
CHECK_REPLICA=false
shift
;;
--no-shard)
CHECK_SHARDING=false
shift
;;
-o|--output)
OUTPUT_DIR="$2"
shift 2
;;
--help)
usage
exit 0
;;
*)
echo "未知选项: $1"
usage
exit 1
;;
esac
done
# 执行主函数
main "$@"
#使用。
# 赋予执行权限
chmod +x mongodb_healthcheck.sh
# 基本用法(无认证)
./mongodb_healthcheck.sh
# 带认证连接
./mongodb_healthcheck.sh -h 127.0.0.1 -p 27017 -u admin -p password
# 使用SSL连接
./mongodb_healthcheck.sh --ssl -h mongodb.example.com
# 跳过分片检查
./mongodb_healthcheck.sh --no-shard
# 指定输出目录
./mongodb_healthcheck.sh -o /path/to/report
巡检内容:
✅ 连接检查 - 测试MongoDB连接状态
✅ 服务器信息 - 版本、主机信息、运行时间
✅ 副本集状态 - 主从节点、健康状态
✅ 分片状态 - 分片数量、配置服务器
✅ 数据库状态 - 数据库列表和大小
✅ 集合状态 - 集合数量和列表
✅ 性能指标 - 连接数、内存使用、操作统计
✅ 索引状态 - 各集合索引数量
✅ 慢查询 - Profiling状态和慢查询统计
✅ 备份状态 - OPLOG大小、数据目录
输出文件:
mongodb_health_report.txt - 文本格式巡检报告
mongodb_details.json - JSON格式详细数据
依赖要求:
MongoDB客户端工具 (mongo)
连接到MongoDB的权限
读取服务器状态命令的权限
这个脚本提供了全面的MongoDB健康检查,可以帮助DBA和运维人员快速了解数据库状态。
更多推荐



所有评论(0)