linux mysql备份操作后发送邮件通知

基本情况:

  1. Mysql是使用Docker部署的
  2. 使用的是crontab定时执行备份脚本
  3. 将备份脚本发送到阿里云oss

需求:
linux备份Mysql的时候,如果备份出错,需要发送邮件通知
方案:
使用linux msmtp进行发送邮件

一、准备linux邮件插件

步骤一:下载msmtp

# Ubuntu/Debian
sudo apt-get update
sudo apt-get install msmtp msmtp-mta

# CentOS/RHEL
sudo yum install epel-release
sudo yum install msmtp

步骤二:配置msmtp

sudo mkdir -p /etc/msmtp
sudo vim /etc/msmtprc

msmtprc文件内容

# QQ邮箱配置
defaults
auth on
tls on
tls_starttls on
tls_certcheck off
logfile /var/log/msmtp.log

# QQ邮箱账户
account qq
host smtp.qq.com
port 587
from your-qq@qq.com
auth login
user your-qq@qq.com
password your-authorization-code

# 设置默认账户
account default : qq

重要说明:
your-qq@qq.com:替换为您的QQ邮箱

your-authorization-code:替换为QQ邮箱的授权码(不是邮箱密码)

获取方法:QQ邮箱 → 设置 → 账户 → POP3/IMAP/SMTP服务 → 开启 → 生成授权码

步骤三:设置文件权限

sudo chmod 600 /etc/msmtprc
sudo touch /var/log/msmtp.log
sudo chmod 666 /var/log/msmtp.log

步骤四:测试邮件发送

#这个虽然可以发送,但是发送的内容没有显示
echo "测试邮件内容" | msmtp --debug your-qq@qq.com

#修改一下
{
echo "From: 你猜 <123@qq.com>"
echo "To: 123@163.com" 
echo "Subject: 测试邮2件"
echo ""
echo "测试邮2件内容"
} | msmtp --debug 123@163.com

二、测试MySQL备份脚本

#!/bin/bash

app=xsfx
nowDate=`date +%Y%m%d%H%M`
path=/xsfx/no-delete-bak/
pwd=your_password # 数据库密码

dbs='xsfx_book_db xsfx_circle_db xsfx_course_db xsfx_doc_db xsfx_exam_db xsfx_family_db xsfx_fast_generator xsfx_goods_db xsfx_guide_db xsfx_im_db xsfx_join_db xsfx_live_db xsfx_product_db xsfx_siwu_db xsfx_supply_db xsfx_system_db xsfx_user_db xsfx_volunteer_db xsfx_meeting_db'
ossbucket=xsfxmysqlbackup/$app/
containerId=db.mysql	# docker数据库容器名称

docker exec -i $containerId mysqldump -uroot -p$pwd  -B $dbs --skip_add_locks --skip-lock-tables>  $path$nowDate.sql

cd $path

tar -zcvf ./$app$nowDate.tar.gz ./$nowDate.sql --remove-files

ossutil64 cp $app$nowDate.tar.gz oss://$ossbucket

rm -rf $path$app$nowDate.tar.gz

echo $path$app$nowDate.tar.gz'数据已经备份到oss:'$ossbucket

三、修改数据库备份脚本,加入邮件发送

#!/bin/bash

# 配置区域
app=xsfx
nowDate=$(date +%Y%m%d%H%M)
path=/xsfx/no-delete-bak/ # 备份脚本地址
pwd=your_password  # 替换为您的mysql容器密码
dbs='xsfx_course_db xsfx_doc_db xsfx_goods_db xsfx_guide_db xsfx_join_db xsfx_product_db xsfx_supply_db xsfx_system_db xsfx_user_db' # 需要备份的数据库
ossbucket=xsfxmysqlbackup/xsfx/	# 备份到阿里云的bucket地址

# 邮件配置
EMAIL_RECIPIENT="your_email"  # 替换为您的QQ邮箱
EMAIL_SUBJECT_PREFIX="[数据库备份告警]"

# 日志配置
LOG_DIR="/xsfx/no-delete-bak/logs"
LOG_FILE="${LOG_DIR}/mysqlback.log"
ERROR_LOG_FILE="${LOG_DIR}/error.log"

# 创建日志目录
mkdir -p "$LOG_DIR"

# 日志函数
log() {
    local level="$1"
    local message="$2"
    local timestamp=$(date '+%Y-%m-%d %H:%M:%S')
    local log_entry="[$timestamp] [$level] $message"
    
    # 输出到标准输出(会被crontab重定向到LOG_FILE)
    echo "$log_entry"
    
    # 如果是错误级别,同时记录到错误日志
    if [ "$level" = "ERROR" ]; then
        echo "$log_entry" >> "$ERROR_LOG_FILE"
    fi
}

log_info() {
    log "INFO" "$1"
}

log_error() {
    log "ERROR" "$1"
}

# 发送邮件函数
send_error_email() {
    local error_message="$1"
    local error_details="$2"
    
    local subject="${EMAIL_SUBJECT_PREFIX} 备份失败 - $(date '+%Y-%m-%d %H:%M')"
    local message="数据库备份任务执行失败!

应用名称: $app
失败时间: $(date)

错误信息: 
$error_message

错误详情:
$error_details

最近错误日志:
$(tail -20 "$ERROR_LOG_FILE")

请及时登录服务器检查处理!

备份脚本: $path/mysql_backup.sh
日志文件: $LOG_FILE"

    #echo "$message" | mail -s "$subject" "$EMAIL_RECIPIENT"
	
	{
		echo "From: xsfx <$EMAIL_RECIPIENT>"
		echo "To: $EMAIL_RECIPIENT" 
		echo "Subject: $subject"
		echo ""
		echo "$message"
	} | msmtp --debug  "$EMAIL_RECIPIENT"
	
    log_info "错误通知邮件已发送到: $EMAIL_RECIPIENT"
}

send_success_email() {
    local backup_file="$1"
    local oss_path="$2"
    
    local subject="${EMAIL_SUBJECT_PREFIX} 备份成功 - $(date '+%Y-%m-%d %H:%M')"
    local message="数据库备份任务执行成功!

应用名称: $app
备份时间: $(date)
备份文件: $backup_file
OSS路径: $oss_path

数据库列表:
$dbs

备份状态: 已完成并上传到OSS

最近操作日志:
$(tail -10 "$LOG_FILE")"

    echo "$message" | mail -s "$subject" "$EMAIL_RECIPIENT"
	
	{
		echo "From: xsfx <$EMAIL_RECIPIENT>"
		echo "To: $EMAIL_RECIPIENT" 
		echo "Subject: $subject"
		echo ""
		echo "$message"
	} | msmtp --debug  "$EMAIL_RECIPIENT"
	
    log_info "成功通知邮件已发送到: $EMAIL_RECIPIENT"
}

# 检查命令执行结果
check_command_result() {
    local command_name="$1"
    local exit_code=$?
    
    if [ $exit_code -ne 0 ]; then
        log_error "$command_name 执行失败,退出码: $exit_code"
        return 1
    fi
    return 0
}

# 检查Docker容器状态
check_docker_container() {
    if ! docker ps | grep -q "pxc-slave"; then
        log_error "Docker容器 pxc-slave 未运行或不存在"
        return 1
    fi
    return 0
}

# 检查备份文件
check_backup_file() {
    local file_path="$1"
    
    if [ ! -f "$file_path" ]; then
        log_error "备份文件不存在: $file_path"
        return 1
    fi
    
    local file_size=$(stat -c%s "$file_path" 2>/dev/null || stat -f%z "$file_path" 2>/dev/null)
    if [ "$file_size" -eq 0 ]; then
        log_error "备份文件为空: $file_path"
        return 1
    fi
    
    log_info "备份文件检查通过: $file_path (大小: ${file_size} 字节)"
    return 0
}

# 主备份函数
mysql_backup() {
    local start_time=$(date +%s)
    log_info "=== 开始数据库备份任务 ==="
    log_info "备份时间: $(date)"
    log_info "数据库列表: $dbs"
    
    # 检查Docker容器
    log_info "检查Docker容器状态..."
    if ! check_docker_container; then
        send_error_email "Docker容器检查失败" "pxc-slave容器未运行或不存在"
        exit 1
    fi
    
    # 执行数据库备份
    local backup_file="${path}${nowDate}.sql"
    log_info "开始执行数据库备份..."
    docker exec -i pxc-slave mysqldump -uroot -p$pwd -B $dbs --skip_add_locks --skip-lock-tables > "$backup_file"
    
    if ! check_command_result "mysqldump"; then
        send_error_email "数据库备份失败" "mysqldump命令执行失败,请检查数据库连接和权限"
        exit 1
    fi
    
    # 检查备份文件
    if ! check_backup_file "$backup_file"; then
        send_error_email "备份文件验证失败" "生成的SQL文件为空或不存在"
        exit 1
    fi
    
    # 压缩备份文件
    log_info "开始压缩备份文件..."
    cd "$path" || {
        log_error "无法进入目录: $path"
        send_error_email "目录切换失败" "无法进入备份目录: $path"
        exit 1
    }
    
    local compressed_file="./${app}${nowDate}.tar.gz"
    tar -zcvf "$compressed_file" "./${nowDate}.sql"
    
    if ! check_command_result "tar压缩"; then
        send_error_email "备份文件压缩失败" "tar命令执行失败"
        exit 1
    fi
    
    # 删除原始SQL文件
    rm -f "./${nowDate}.sql"
    log_info "原始SQL文件已删除"
    
    # 检查压缩文件
    if ! check_backup_file "$compressed_file"; then
        send_error_email "压缩文件验证失败" "压缩后的文件为空或不存在"
        exit 1
    fi
    
    # 上传到OSS
    log_info "开始上传到OSS..."
    ossutil64 cp "$compressed_file" "oss://${ossbucket}"
    
    if ! check_command_result "OSS上传"; then
        send_error_email "OSS上传失败" "ossutil64命令执行失败,请检查OSS配置和网络连接"
        # 不上传成功也不删除本地文件,便于手动重试
        log_error "OSS上传失败,保留本地备份文件: $compressed_file"
        exit 1
    fi
    
    # 删除本地压缩文件
    rm -rf "$compressed_file"
    log_info "本地压缩文件已删除"
    
    local end_time=$(date +%s)
    local duration=$((end_time - start_time))
    log_info "备份任务完成,总耗时: ${duration} 秒"
    
    # 发送成功通知
    send_success_email "${app}${nowDate}.tar.gz" "oss://${ossbucket}"
    
    log_info "=== 数据库备份任务结束 ==="
}

# 信号处理函数
handle_interrupt() {
    log_error "备份任务被用户中断"
    send_error_email "备份任务被手动中断" "脚本接收到中断信号,备份任务未完成"
    exit 1
}

# 设置信号处理
trap handle_interrupt INT TERM

# 主执行
main() {
    log_info "启动数据库备份脚本"
    mysql_backup
}

# 脚本入口
main "$@"

编写crontab定时器

# 每周五一点同步
1 1 * * 5 sh /xsfx/no-delete-bak/bak.sh

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值