提交 2747889d authored 作者: 陈泽健's avatar 陈泽健

docs(scripts): 添加新统一平台日志备份与服务监控需求文档

- 新增 MySQL 日志备份需求文档,包含自动化备份、压缩存储和权限保持功能
- 新增 Nginx 日志备份需求文档,支持日志轮转和容器服务通知机制
- 新增 Redis 服务监控需求文档,实现连续失败阈值判断和自动恢复功能
- 添加 Nginx 日志备份脚本,具备自动压缩、清空原日志和过期清理功能
上级 e8861898
# _PRD_新统一平台MySQL日志备份需求文档.md
> 版本:V1.2
> 更新日期:2026-03-30
> 适用范围:新统一平台MySQL日志文件定时备份与压缩
> 实现脚本:`自动化部署脚本\x86架构\新统一平台\定时脚本\backup_mysql_logs.sh`
---
## 1. 背景与目标
### 1.1 背景
MySQL数据库产生的日志文件(错误日志、慢查询日志等)会持续增长,占用大量磁盘空间,需要定期备份和清理。
### 1.2 目标
实现MySQL日志文件的自动化定时备份功能,具备:
- 日志文件的自动发现和备份
- 备份文件的压缩存储以节省空间
- 原始文件权限的完整保留
- 过期备份的自动清理机制
- 完整的操作日志记录
---
## 2. 总体范围
### 2.1 纳入备份对象
- **日志目录**`/data/middleware/mysql/log`
- **备份目录**`/data/bakup/mysql/logs/backup`
- **备份目标**
- *.log 文件(通用日志文件)
- *.slow 文件(慢查询日志)
- error.log(错误日志)
- slow.log(慢查询日志)
- mysqld.log(MySQL服务日志)
### 2.2 日志文件类型
脚本自动查找以下类型的日志文件:
```bash
find "$MYSQL_LOG_DIR" -maxdepth 1 \( -name "*.log" -o -name "*.slow" -o -name "error.log" -o -name "slow.log" -o -name "mysqld.log" \) -type f
```
### 2.2 不在本期范围
- 日志内容分析和告警
- 日志文件的实时监控
- 备份文件的远程传输
- 日志级别的动态调整
---
## 3. 术语说明
- **权限保存恢复**:备份前后保持文件的权限、属主、属组信息不变
- **临时权限文件**:用于存储文件权限信息的临时文件,格式为`filename.permissions.tmp`
- **备份目录结构**:按日期创建子目录,格式为`/data/bakup/mysql/logs/backup/YYYYMMDD/`
- **日志轮转**:当日志文件大小超过5MB时,自动将当前日志文件重命名并创建新文件
---
## 4. 功能需求
### 4.1 备份流程
#### 4.1.1 初始化检查
- 检查MySQL日志目录是否存在
- 创建今日备份目录
- 初始化日志文件
#### 4.1.2 日志文件发现
使用find命令查找所有符合条件的日志文件:
```bash
find "$MYSQL_LOG_DIR" -maxdepth 1 \( -name "*.log" -o -name "*.slow" -o -name "error.log" -o -name "slow.log" -o -name "mysqld.log" \) -type f
```
#### 4.1.3 权限保存机制
对每个日志文件执行:
1. 获取当前文件权限信息(chmod、chown)
2. 保存到临时权限文件
3. 执行备份操作
4. 恢复原始权限
5. 清理临时权限文件
#### 4.1.4 备份执行
对每个发现的日志文件:
1. 保存权限信息到临时文件
2. 使用gzip压缩并复制到备份目录
3. 文件命名格式:`原文件名_YYYYMMDD.gz`
4. 验证备份文件完整性
5. 恢复原始文件权限
### 4.2 清理机制
#### 4.2.1 过期备份清理
- 自动删除超过30天的备份目录
- 按日期格式化目录进行清理
- 保留完整的备份历史记录
#### 4.2.2 临时文件清理
- 备份完成后清理所有权限临时文件
- 防止临时文件堆积占用空间
### 4.3 日志与审计
#### 4.3.1 日志文件
- 主日志:`/data/logs/backup_mysql_logs.log`
- 日志轮转:超过5MB自动轮转,保留30天
#### 4.3.2 日志轮转机制
- **触发条件**:日志文件大小超过5MB (MAX_LOG_SIZE=5242880字节)
- **轮转操作**
1. 将当前日志文件重命名为`backup_mysql_logs.log.YYYYMMDDHHMMSS`
2. 创建新的空日志文件
3. 记录轮转操作日志
- **清理操作**:删除超过30天的轮转日志文件
#### 4.3.2 日志内容格式
每行必须包含:
- 时间戳:`YYYY-MM-DD HH:MM:SS`
- 操作类型:开始/成功/失败/跳过/警告
- 文件名称和操作结果
示例:
```
[2026-03-30 02:00:00] 开始备份日志文件: error.log
[2026-03-30 02:00:05] ✅ 日志备份并压缩成功: error.log -> error.log_20260330.gz
[2026-03-30 02:00:10] ⚠️ 备份文件已存在,跳过: slow.log
```
### 4.4 错误处理
#### 4.4.1 目录访问异常
- 日志目录不存在:记录错误并退出
- 无法进入目录:记录错误并退出
#### 4.4.2 文件操作异常
- 权限获取失败:记录警告但继续处理
- 压缩备份失败:记录错误并尝试恢复权限
- 文件复制失败:记录错误并清理不完整文件
#### 4.4.3 权限恢复异常
- 权限恢复失败:记录警告信息
- 临时文件删除失败:记录但不影响主流程
---
## 5. 配置参数
| 配置项 | 默认值 | 说明 |
|--------|--------|------|
| MYSQL_LOG_DIR | /data/middleware/mysql/log | MySQL日志目录 |
| BACKUP_DIR | /data/bakup/mysql/logs/backup | 备份根目录 |
| LOG_FILE | /data/logs/backup_mysql_logs.log | 日志文件路径 |
| MAX_LOG_SIZE | 5242880 (5MB) | 日志文件大小限制 |
| LOG_RETENTION_DAYS | 30 | 日志文件保留天数 |
| RETENTION_DAYS | 30 | 备份保留天数 |
| DATE_FORMAT | %Y%m%d | 日期格式 |
---
## 6. 执行要求
### 6.1 执行时机
- 建议:每日凌晨2点执行
- cron配置:`0 2 * * * /data/services/scripts/backup_mysql_logs.sh`
### 6.2 执行环境
- 需要对MySQL日志目录的读取权限
- 需要对备份目录的写入权限
- 需要gzip命令支持
### 6.3 资源要求
- 磁盘空间:预留足够空间存储压缩后的日志文件
- 内存:压缩操作会占用临时内存
- CPU:gzip压缩会占用一定CPU资源
---
## 7. 验收标准
1. **备份完整性**
- 所有符合条件的日志文件都被正确备份
- 备份文件可以正常解压
- 原始日志文件权限保持不变
2. **权限保持**
- 备份前后文件权限一致
- 属主和属组信息正确保留
- 临时权限文件被正确清理
3. **日志完整性**
- 每次执行都有完整的操作记录
- 成功和失败操作都有明确标识
- 包含具体的文件名称和操作结果
4. **清理机制**
- 超过30天的备份目录被正确删除
- 临时权限文件被彻底清理
- 不影响正常的日志文件使用
---
## 8. 故障排查
### 8.1 常见问题
1. **目录不存在**
```
❌ MySQL日志目录不存在: /data/middleware/mysql/log
```
解决:检查MySQL配置或创建日志目录
2. **权限不足**:
```
❌ 无法进入目录: /data/middleware/mysql/log
```
解决:检查目录访问权限
3. **压缩失败**:
```
❌ 日志备份失败: error.log
```
解决:检查磁盘空间和文件权限
### 8.2 日志检查
```bash
# 查看最近备份日志
tail -f /data/logs/backup_mysql_logs.log
# 检查备份文件
ls -la /data/bakup/mysql/logs/backup/$(date +%Y%m%d)/
# 验证权限保持
ls -l /data/middleware/mysql/log/error.log
ls -l /data/bakup/mysql/logs/backup/20260330/error.log_20260330.gz
```
---
## 需求规范
代码规范:Docs/PRD/01规范文档/_PRD_规范文档_代码规范.md
问题总结:Docs/PRD/01规范文档/_PRD_问题总结_记录文档.md
方法总结:Docs/PRD/01规范文档/_PRD_方法总结_记录文档.md
文档规范:Docs/PRD/01规范文档/_PRD_规范文档_文档规范.md
测试规范:Docs/PRD/01规范文档/_PRD_规范文档_测试规范.md
\ No newline at end of file
# _PRD_新统一平台_Nginx日志备份需求文档.md
> 版本:V1.2
> 更新日期:2026-03-30
> 适用范围:新统一平台Nginx日志文件定时备份与轮转
> 实现脚本:`自动化部署脚本/x86架构/新统一平台/定时脚本/backup_nginx_logs.sh`
---
## 1. 背景与目标
### 1.1 背景
Nginx作为新统一平台的反向代理和Web服务器,产生的访问日志和错误日志会持续增长,需要定期备份并进行日志轮转以控制系统磁盘使用。
### 1.2 目标
实现Nginx日志文件的自动化定时备份功能,具备:
- 访问日志和错误日志的定期备份
- 备份文件的压缩存储以节省空间
- 原始日志文件的清空实现日志轮转
- Nginx服务的日志文件重新打开通知
- 过期备份的自动清理机制
- 完整的操作日志记录
- **脚本自身的日志轮转功能**(5MB自动轮转、保留30天)
---
## 2. 总体范围
### 2.1 纳入备份对象
- **日志目录**`/data/middleware/nginx/log`
- **备份目标**
- access.log(访问日志)
- error.log(错误日志)
- **脚本日志文件**`/data/logs/backup_nginx_logs.log`(支持自动轮转)
### 2.2 不在本期范围
- 日志内容分析和访问统计
- 日志级别的动态调整
- 备份文件的远程传输
- 日志格式的自定义处理
---
## 3. 术语说明
- **日志轮转**:备份后清空原始日志文件内容,但保持文件存在
- **Nginx信号通知**:向Nginx进程发送reopen信号,使其重新打开日志文件
- **容器内执行**:在unginx容器内执行Nginx命令
- **脚本日志轮转**:脚本自身的日志文件达到5MB时自动轮转,保留30天
---
## 4. 功能需求
### 4.1 备份流程
#### 4.1.1 初始化检查
- 检查Nginx日志目录是否存在
- 创建今日备份目录
- 初始化日志文件
#### 4.1.2 日志文件处理
对每个目标日志文件(access.log, error.log)执行:
1. 检查文件是否存在
2. 保存原始权限信息
3. 使用gzip压缩并复制到备份目录
4. 文件命名格式:`原文件名_YYYYMMDD.gz`
5. 验证备份文件完整性
6. 清空原始日志文件内容(> filename)
7. 恢复原始文件权限
#### 4.1.3 Nginx服务通知
备份完成后向Nginx发送reopen信号:
1. 优先尝试直接执行 `nginx -s reopen` 命令
2. 如果失败,尝试在unginx容器内执行 `docker exec unginx nginx -s reopen`
3. 如果nginx命令不存在但容器存在,则在容器内执行
4. 记录通知结果到日志
#### 4.1.4 脚本自身日志轮转
在执行备份任务前,检查并执行脚本日志文件的轮转:
1. 检查日志文件大小是否超过5MB
2. 如果超过,将当前日志重命名为 `backup_nginx_logs.log.YYYYMMDDHHMMSS`
3. 创建新的空日志文件
4. 清理超过30天的旧轮转日志文件
### 4.2 权限管理
#### 4.2.1 权限保存机制
- 备份前获取文件权限信息(chmod、chown)
- 保存到临时权限文件
- 备份后恢复原始权限
- 清理临时权限文件
#### 4.2.2 文件操作安全
- 使用原子操作清空日志文件
- 权限恢复失败时记录警告
- 确保Nginx可以继续正常写入日志
### 4.3 日志与审计
#### 4.3.1 日志文件
- 主日志:`/data/logs/backup_nginx_logs.log`
- 日志轮转大小:5MB
- 日志保留天数:30天
#### 4.3.2 日志内容格式
每行必须包含:
- 时间戳:`YYYY-MM-DD HH:MM:SS`
- 操作类型:开始/成功/失败/跳过/警告
- 文件名称和操作结果
示例:
```
[2026-01-29 03:00:00] 开始备份日志文件: access.log
[2026-01-29 03:00:05] ✅ 日志备份并压缩成功: access.log -> access.log_20260129.gz
[2026-01-29 03:00:06] ✅ 原始日志文件已清空: access.log
[2026-01-29 03:00:10] ⚠️ 无法向Nginx发送reopen信号
```
### 4.4 错误处理
#### 4.4.1 目录访问异常
- 日志目录不存在:记录错误并退出
- 无法进入目录:记录错误并退出
#### 4.4.2 文件操作异常
- 日志文件不存在:记录警告并跳过
- 压缩备份失败:记录错误并尝试恢复权限
- 文件清空失败:记录错误但不影响主流程
#### 4.4.3 服务通知异常
- Nginx命令不存在:记录警告
- 信号发送失败:记录警告但不影响备份流程
---
## 5. 配置参数
| 配置项 | 默认值 | 说明 |
|--------|--------|------|
| NGINX_LOG_DIR | /data/middleware/nginx/log | Nginx日志目录 |
| BACKUP_DIR | /data/middleware/nginx/log/backup | 备份根目录 |
| LOG_FILE | /data/logs/backup_nginx_logs.log | 脚本日志文件路径 |
| MAX_LOG_SIZE | 5242880 (5MB) | 脚本日志文件大小限制 |
| LOG_RETENTION_DAYS | 30 | 脚本日志保留天数 |
| RETENTION_DAYS | 30 | 备份保留天数 |
| DATE_FORMAT | %Y%m%d | 日期格式 |
---
## 6. 执行要求
### 6.1 执行时机
- 建议:每日凌晨3点执行
- cron配置:`0 3 * * * /data/services/scripts/backup_nginx_logs.sh`
### 6.2 执行环境
- 需要对Nginx日志目录的读写权限
- 需要nginx命令或docker执行权限
- 需要gzip命令支持
- 需要stat命令支持(用于获取文件大小)
### 6.3 资源要求
- 磁盘空间:预留足够空间存储压缩后的日志文件
- 内存:压缩操作会占用临时内存
- 注意:执行时Nginx会短暂停止写入日志
---
## 7. 验收标准
1. **备份完整性**
- access.log和error.log都被正确备份
- 备份文件可以正常解压
- 原始日志文件被正确清空
2. **日志轮转效果**
- 原始日志文件大小变为0字节
- Nginx继续正常记录新日志
- 备份文件命名格式正确
3. **服务连续性**
- Nginx服务不受备份操作影响
- 服务通知信号正确发送
- 日志记录不出现中断
4. **日志完整性**
- 每次执行都有完整的操作记录
- 成功和失败操作都有明确标识
- 包含具体的文件名称和操作结果
---
## 8. 故障排查
### 8.1 常见问题
1. **目录不存在**
```
❌ Nginx日志目录不存在: /data/middleware/nginx/log
```
解决:检查Nginx配置或创建日志目录
2. **文件不存在**:
```
⚠️ 在 /data/middleware/nginx/log 中未找到Nginx日志文件
```
解决:检查Nginx日志配置
3. **权限不足**:
```
❌ 日志备份失败: access.log
```
解决:检查文件权限和磁盘空间
4. **脚本日志轮转**:
```
日志文件超过 5MB,已自动轮转。
```
说明:脚本日志文件已自动轮转,旧日志被重命名
### 8.2 日志检查
```bash
# 查看最近备份日志
tail -f /data/logs/backup_nginx_logs.log
# 检查备份文件
ls -la /data/middleware/nginx/log/backup/$(date +%Y%m%d)/
# 验证日志轮转效果
ls -lh /data/middleware/nginx/log/access.log
# 应该显示文件大小为0
# 检查Nginx是否正常记录新日志
echo "test" >> /data/middleware/nginx/log/access.log
tail /data/middleware/nginx/log/access.log
# 检查脚本日志轮转文件
ls -la /data/logs/backup_nginx_logs.log.*
```
---
## 需求规范
代码规范:Docs/PRD/01规范文档/_PRD_规范文档_代码规范.md
问题总结:Docs/PRD/01规范文档/_PRD_问题总结_记录文档.md
方法总结:Docs/PRD/01规范文档/_PRD_方法总结_记录文档.md
文档规范:Docs/PRD/01规范文档/_PRD_规范文档_文档规范.md
测试规范:Docs/PRD/01规范文档/_PRD_规范文档_测试规范.md
\ No newline at end of file
#!/bin/bash
#===============================================================================
# 脚本名称:backup_nginx_logs.sh
# 功能描述:Nginx日志文件定时备份与压缩脚本
# 版本:V1.2
# 创建日期:2026-01-27
# 更新日期:2026-03-30
# 基于文档:_PRD_新统一平台_Nginx日志备份需求文档.md
#
# 备份对象:
# 1. Nginx访问日志(access.log)
# 2. Nginx错误日志(error.log)
# 3. 自动压缩并清空原日志文件
# 4. 向Nginx发送reopen信号重新打开日志
# 5. 自动清理过期备份
# 6. 日志文件自动轮转(5MB轮转、保留30天)
#
# 使用方法:
# chmod +x backup_nginx_logs.sh
# ./backup_nginx_logs.sh
#
# 定时任务示例:
# 0 3 * * * /data/services/scripts/backup_nginx_logs.sh
#===============================================================================
# ==================== 配置区 ====================
NGINX_LOG_DIR="/data/middleware/nginx/log" # Nginx日志目录
BACKUP_DIR="$NGINX_LOG_DIR/backup" # 备份目录
LOG_FILE="/data/logs/backup_nginx_logs.log" # 日志文件路径
MAX_LOG_SIZE=$((5*1024*1024)) # 5MB 日志大小限制
LOG_RETENTION_DAYS=30 # 日志保留天数
RETENTION_DAYS=30 # 备份保留天数
DATE=$(date +"%Y%m%d") # 当前日期格式 YYYYMMDD
TODAY_DIR="$BACKUP_DIR/$DATE" # 今天的备份目录
# ==================== 日志函数 ====================
log() {
echo "[$(date '+%Y-%m-%d %H:%M:%S')] $1" | tee -a "$LOG_FILE"
}
# ==================== 日志轮转函数 ====================
rotate_logs() {
if [ -f "$LOG_FILE" ]; then
FILE_SIZE=$(stat -c%s "$LOG_FILE" 2>/dev/null || echo 0)
if [ "$FILE_SIZE" -ge "$MAX_LOG_SIZE" ]; then
mv "$LOG_FILE" "$LOG_FILE.$(date '+%Y%m%d%H%M%S')"
touch "$LOG_FILE"
log "日志文件超过 5MB,已自动轮转。"
fi
fi
# 清理超过保留天数的旧日志文件
find "$(dirname "$LOG_FILE")" -name "backup_nginx_logs.log.*" -mtime +$LOG_RETENTION_DAYS -exec rm -f {} \; 2>/dev/null
}
# ==================== 权限保存和恢复函数 ====================
save_permissions() {
local file="$1"
# 获取文件权限和属主信息
local perms owner group
perms=$(stat -c %a "$file" 2>/dev/null)
owner=$(stat -c %U "$file" 2>/dev/null)
group=$(stat -c %G "$file" 2>/dev/null)
# 存储到临时文件
echo "$perms $owner $group" > "$file.permissions.tmp"
}
restore_permissions() {
local file="$1"
local perm_file="$file.permissions.tmp"
if [ -f "$perm_file" ]; then
local perms owner group
read -r perms owner group < "$perm_file"
# 恢复权限和属主(增加空值检查)
if [ -n "$owner" ] && [ -n "$group" ]; then
chown "$owner:$group" "$file" 2>/dev/null
fi
if [ -n "$perms" ]; then
chmod "$perms" "$file" 2>/dev/null
fi
# 删除临时权限文件
rm -f "$perm_file"
fi
}
# ==================== 主要功能 ====================
# 创建日志目录并确保存在
mkdir -p "$(dirname "$LOG_FILE")"
touch "$LOG_FILE"
# 执行日志轮转
rotate_logs
log "===== 开始备份Nginx日志 (日期: $DATE) ====="
# 创建备份目录
mkdir -p "$TODAY_DIR"
# 检查Nginx日志目录是否存在
if [ ! -d "$NGINX_LOG_DIR" ]; then
log "❌ Nginx日志目录不存在: $NGINX_LOG_DIR"
exit 1
fi
# 进入日志目录
cd "$NGINX_LOG_DIR" || {
log "❌ 无法进入目录: $NGINX_LOG_DIR"
exit 1
}
# 查找所有日志文件(access.log 和 error.log)
LOG_FILES=""
if [ -f "access.log" ]; then
LOG_FILES="$LOG_FILES access.log"
fi
if [ -f "error.log" ]; then
LOG_FILES="$LOG_FILES error.log"
fi
if [ -z "$LOG_FILES" ]; then
log "⚠️ 在 $NGINX_LOG_DIR 中未找到Nginx日志文件"
exit 0
fi
# 备份并压缩每个日志文件
SUCCESS_COUNT=0
for log_file in $LOG_FILES; do
source_path="$NGINX_LOG_DIR/$log_file"
# 跳过已经备份过的文件(如果同名备份已存在)
if [ -f "$TODAY_DIR/${log_file}_${DATE}.gz" ]; then
log "⚠️ 备份文件已存在,跳过: $log_file"
continue
fi
log "开始备份日志文件: $log_file"
# 保存原始权限信息
save_permissions "$source_path"
# 复制文件到备份目录并压缩
if gzip -c "$source_path" > "$TODAY_DIR/${log_file}_${DATE}.gz"; then
log "✅ 日志备份并压缩成功: $log_file -> ${log_file}_${DATE}.gz"
((SUCCESS_COUNT++))
# 清空原始日志文件内容,但保持文件存在
> "$source_path"
log "✅ 原始日志文件已清空: $log_file"
else
log "❌ 日志备份失败: $log_file"
# 如果备份失败,仍需要恢复权限信息
restore_permissions "$source_path"
fi
# 恢复原始文件权限
restore_permissions "$source_path"
done
log "本次共成功备份 $SUCCESS_COUNT 个日志文件"
# ==================== 清理超过30天的旧备份 ====================
log "开始清理超过 $RETENTION_DAYS 天的旧备份..."
find "$BACKUP_DIR" -maxdepth 1 -type d -name "????????" -mtime +$RETENTION_DAYS -exec rm -rf {} + 2>/dev/null
# 清理权限临时文件(以防万一)
find "$NGINX_LOG_DIR" -name "*.permissions.tmp" -type f -delete 2>/dev/null
# 发送HUP信号给nginx进程,使其重新打开日志文件
if command -v nginx &> /dev/null; then
nginx -s reopen 2>/dev/null || {
# 如果直接执行失败,尝试通过docker向unginx容器发送信号
docker exec unginx nginx -s reopen 2>/dev/null || log "⚠️ 无法向Nginx发送reopen信号"
}
elif docker ps --format '{{.Names}}' | grep -q "unginx"; then
# 如果nginx命令不存在,但容器存在,则尝试在容器内执行
docker exec unginx nginx -s reopen 2>/dev/null || log "⚠️ 无法向Nginx发送reopen信号"
fi
log "===== Nginx日志备份任务结束 ====="
\ No newline at end of file
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论