Elasticsearch快照备份脚本
Elasticsearch索引快照备份脚本,支持全量/指定索引备份,自动创建仓库、创建快照、清理旧快照
详细内容
#!/bin/bash
# Elasticsearch快照备份脚本
# 使用ES快照API自动备份索引数据
ES_HOST="127.0.0.1"
ES_PORT=9200
ES_USER=""
ES_PASSWORD=""
REPO_NAME="backup_repo"
REPO_LOCATION="/backup/elasticsearch"
BACKUP_PREFIX="es_snapshot"
KEEP_DAYS=7
INDEX_PATTERN=""
LOG_FILE="/var/log/es_backup.log"
mkdir -p "$REPO_LOCATION"
AUTH_PARAMS=""
if [ -n "$ES_USER" ] && [ -n "$ES_PASSWORD" ]; then
AUTH_PARAMS="-u $ES_USER:$ES_PASSWORD"
fi
ES_URL="http://$ES_HOST:$ES_PORT"
log_msg() {
echo "[$(date '+%Y-%m-%d %H:%M:%S')] $1" | tee -a "$LOG_FILE"
}
# 检查ES连接
if ! curl -s $AUTH_PARAMS "$ES_URL/_cluster/health" >/dev/null 2>&1; then
log_msg "❌ 无法连接Elasticsearch"
exit 1
fi
CLUSTER_INFO=$(curl -s $AUTH_PARAMS "$ES_URL/_cluster/health")
STATUS=$(echo "$CLUSTER_INFO" | grep -o '"status":"[^"]*"' | cut -d'"' -f4)
log_msg "集群状态: $STATUS"
DATE=$(date '+%Y%m%d_%H%M%S')
SNAPSHOT_NAME="${BACKUP_PREFIX}_${DATE}"
log_msg "===== ES备份开始: $SNAPSHOT_NAME ====="
# 1. 创建快照仓库
REPO_EXISTS=$(curl -s -o /dev/null -w "%{http_code}" $AUTH_PARAMS "$ES_URL/_snapshot/$REPO_NAME")
if [ "$REPO_EXISTS" != "200" ]; then
log_msg "创建快照仓库: $REPO_NAME"
curl -s -X PUT $AUTH_PARAMS "$ES_URL/_snapshot/$REPO_NAME" -H "Content-Type: application/json" -d "{
"type": "fs",
"settings": {"location": "$REPO_LOCATION", "compress": true}
}" >/dev/null
fi
# 2. 创建快照
if [ -n "$INDEX_PATTERN" ]; then
SNAPSHOT_BODY="{"indices": "$INDEX_PATTERN", "ignore_unavailable": true}"
else
SNAPSHOT_BODY="{"ignore_unavailable": true, "include_global_state": true}"
fi
log_msg "创建快照..."
curl -s -X PUT $AUTH_PARAMS "$ES_URL/_snapshot/$REPO_NAME/$SNAPSHOT_NAME?wait_for_completion=false" -H "Content-Type: application/json" -d "$SNAPSHOT_BODY" >/dev/null
# 3. 等待快照完成
WAIT_TIME=0
while [ $WAIT_TIME -lt 3600 ]; do
SNAPSHOT_STATUS=$(curl -s $AUTH_PARAMS "$ES_URL/_snapshot/$REPO_NAME/$SNAPSHOT_NAME")
STATE=$(echo "$SNAPSHOT_STATUS" | grep -o '"state":"[^"]*"' | cut -d'"' -f4)
case "$STATE" in
SUCCESS) log_msg "✓ 快照创建成功"; break ;;
IN_PROGRESS) sleep 10; WAIT_TIME=$((WAIT_TIME + 10)) ;;
FAILED|PARTIAL) log_msg "✗ 快照失败: $STATE"; exit 1 ;;
*) sleep 10; WAIT_TIME=$((WAIT_TIME + 10)) ;;
esac
done
SNAPSHOT_SIZE=$(du -sh "$REPO_LOCATION" 2>/dev/null | awk '{print $1}')
log_msg "快照大小: $SNAPSHOT_SIZE"
# 4. 清理旧快照
log_msg "清理旧快照..."
ALL_SNAPSHOTS=$(curl -s $AUTH_PARAMS "$ES_URL/_snapshot/$REPO_NAME/_all" | grep -o '"snapshot":"[^"]*"' | cut -d'"' -f4)
DELETED=0
for snap in $ALL_SNAPSHOTS; do
if [[ "$snap" == ${BACKUP_PREFIX}_* ]]; then
snap_date=$(echo "$snap" | grep -oE '[0-9]{8}' | head -1)
if [ -n "$snap_date" ]; then
snap_ts=$(date -d "$snap_date" +%s 2>/dev/null)
now_ts=$(date +%s)
age=$(( (now_ts - snap_ts) / 86400 ))
if [ "$age" -gt "$KEEP_DAYS" ]; then
curl -s -X DELETE $AUTH_PARAMS "$ES_URL/_snapshot/$REPO_NAME/$snap" >/dev/null
DELETED=$((DELETED + 1))
fi
fi
fi
done
log_msg "已删除 $DELETED 个旧快照"
log_msg "===== ES备份完成 ✓ ====="
适配环境
适配系统:CentOS 7+,Ubuntu 18.04+,Debian 10+
依赖环境:bash 4.0+
参数说明
[{"name": "ES_HOST", "label": "ES\u4e3b\u673a", "default": "127.0.0.1"}, {"name": "ES_PORT", "label": "ES\u7aef\u53e3", "default": "9200"}, {"name": "ES_USER", "label": "\u7528\u6237\u540d(\u53ef\u9009)", "default": ""}, {"name": "ES_PASSWORD", "label": "\u5bc6\u7801(\u53ef\u9009)", "default": ""}, {"name": "REPO_NAME", "label": "\u5feb\u7167\u4ed3\u5e93\u540d", "default": "backup_repo"}, {"name": "REPO_LOCATION", "label": "\u5feb\u7167\u5b58\u50a8\u8def\u5f84", "default": "/backup/elasticsearch"}, {"name": "INDEX_PATTERN", "label": "\u7d22\u5f15\u6a21\u5f0f(\u7559\u7a7a\u6240\u6709)", "default": ""}, {"name": "KEEP_DAYS", "label": "\u4fdd\u7559\u5929\u6570", "default": "7"}]