mysql全量+增量备份脚本及计划任务配置
一、mysql编译安装(5.7.17版本)及初始化设置
1.下载mysql压缩包
wget https://downloads.mysql.com/archives/get/p/23/file/mysql-5.7.17-linux-glibc2.5-x86_64.tar.gz
2.环境配置及源码解压
yum -y install gcc gcc-c++ ncurses ncurses-devel bison cmake
创建 MySQL 专用用户:
useradd -s /sbin/nologin mysql
源码解压:tar zxvf mysql-5.7.17-linux-glibc2.5-x86_64.tar.gz -C /opt
3.CMake编译配置
cd /opt/mysql-5.7.17/
cmake \
-DCMAKE_INSTALL_PREFIX=/usr/local/mysql \
-DMYSQL_UNIX_ADDR=/usr/local/mysql/mysql.sock \
-DSYSCONFDIR=/etc \
-DSYSTEMD_PID_DIR=/usr/local/mysql \
-DDEFAULT_CHARSET=utf8 \
-DDEFAULT_COLLATION=utf8_general_ci \
-DWITH_EXTRA_CHARSETS=all \
-DWITH_INNOBASE_STORAGE_ENGINE=1 \
-DWITH_ARCHIVE_STORAGE_ENGINE=1 \
-DWITH_BLACKHOLE_STORAGE_ENGINE=1 \
-DWITH_PERFSCHEMA_STORAGE_ENGINE=1 \
-DMYSQL_DATADIR=/usr/local/mysql/data \
-DWITH_BOOST=/usr/local/boost \
-DWITH_SYSTEMD=1
编译安装:
make -j 4 && make install(根据机器实际情况设置CPU核数)
4.配置mysql
权限管理:
chown -R mysql:mysql /usr/local/mysql/
chown mysql:mysql /etc/my.cnf
修改配置文件:/etc/my.cnf
[client]
port = 3306
socket=/usr/local/mysql/mysql.sock
default-character-set=utf8
[mysqld]
user = mysql
basedir=/usr/local/mysql
datadir=/usr/local/mysql/data
port = 3306
character-set-server=utf8
pid-file = /usr/local/mysql/mysqld.pid
socket=/usr/local/mysql/mysql.sock
bind-address = 0.0.0.0
skip-name-resolve
max_connections=2048
default-storage-engine=INNODB
max_allowed_packet=16M
server-id = 1
sql_mode=NO_ENGINE_SUBSTITUTION,STRICT_TRANS_TABLES,NO_AUTO_CREATE_USER,NO_AUTO_VALUE_ON_ZERO,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,PIPES_AS_CONCAT,ANSI_QUOTES
[mysql]
port = 3306
default-character-set=utf8
socket=/usr/local/mysql/mysql.sock
auto-rehash
5.初始化设置
环境变量设置:
echo "PATH=$PATH:/usr/local/mysql/bin" >> /etc/profile
source /etc/profile
数据库初始化:
cd /usr/local/mysql/bin/
./mysqld \
--initialize-insecure \
--user=mysql \
--basedir=/usr/local/mysql \
--datadir=/usr/local/mysql/data
添加服务管理:
cp /usr/local/mysql/usr/lib/systemd/system/mysqld.service /usr/lib/systemd/system/
systemctl daemon-reload
systemctl start mysqld.service
systemctl enable mysqld
netstat -anpt | grep 3306
账号密码管理:
设置root密码:mysqladmin -u root -p password "123456"
登录:mysql -u root -p123456
二、编写mysql全量+增量备份脚本
创建脚本所需日志文件目录及赋权:
mkdir -p /var/log/mysql
chown -R mysql:mysql /var/log/mysql
编写脚本:
cd /opt
vim mysql_back.sh
最终脚本如下:
#!/bin/bash # mysql_backup.sh - MySQL数据库备份脚本(全量+增量备份)# 配置参数 MYSQL_USER="root" MYSQL_PASSWORD="123456" MYSQL_HOST="localhost" MYSQL_PORT="3306" BACKUP_DIR="/backup/mysql" LOG_FILE="/var/log/mysql_backup.log" DATE=$(date +%Y%m%d_%H%M%S) FULL_BACKUP_DAY="Sunday" # 全量备份在周日执行# 数据库列表(可以指定多个数据库,用空格分隔) DATABASES="mydatabase projectdb testdb"# 创建备份目录 mkdir -p ${BACKUP_DIR}/{full,incremental} mkdir -p ${BACKUP_DIR}/binlogs# 日志函数 log() {echo "[$(date '+%Y-%m-%d %H:%M:%S')] $1" >> $LOG_FILE }# 检查MySQL连接 check_mysql_connection() {if ! mysql -u$MYSQL_USER -p$MYSQL_PASSWORD -h$MYSQL_HOST -P$MYSQL_PORT -e "SELECT 1;" >/dev/null 2>&1; thenlog "错误: 无法连接到MySQL服务器"exit 1fi }# 全量备份函数 full_backup() {log "开始全量备份..."# 刷新日志,开始新的二进制日志文件mysql -u$MYSQL_USER -p$MYSQL_PASSWORD -h$MYSQL_HOST -P$MYSQL_PORT -e "FLUSH LOGS;"# 备份所有指定的数据库for DB in $DATABASES; dolog "备份数据库: $DB"mysqldump -u$MYSQL_USER -p$MYSQL_PASSWORD -h$MYSQL_HOST -P$MYSQL_PORT \--single-transaction --master-data=2 --databases $DB > \${BACKUP_DIR}/full/${DB}_full_${DATE}.sql 2>>$LOG_FILEif [ $? -eq 0 ]; thenlog "数据库 $DB 全量备份成功"# 压缩备份文件gzip ${BACKUP_DIR}/full/${DB}_full_${DATE}.sqlelselog "错误: 数据库 $DB 全量备份失败"fidone# 记录当前二进制日志位置mysql -u$MYSQL_USER -p$MYSQL_PASSWORD -h$MYSQL_HOST -P$MYSQL_PORT -e "SHOW MASTER STATUS\G" > \${BACKUP_DIR}/binlogs/master_status_${DATE}.txtlog "全量备份完成" }# 增量备份函数 incremental_backup() {log "开始增量备份..."# 获取当前的二进制日志文件CURRENT_BINLOG=$(mysql -u$MYSQL_USER -p$MYSQL_PASSWORD -h$MYSQL_HOST -P$MYSQL_PORT -e "SHOW MASTER STATUS\G" | grep "File:" | awk '{print $2}')# 刷新日志,确保所有更改都写入当前二进制日志mysql -u$MYSQL_USER -p$MYSQL_PASSWORD -h$MYSQL_HOST -P$MYSQL_PORT -e "FLUSH LOGS;"# 备份二进制日志(排除当前正在使用的日志)for binlog in $(mysql -u$MYSQL_USER -p$MYSQL_PASSWORD -h$MYSQL_HOST -P$MYSQL_PORT -e "SHOW BINARY LOGS;" | grep -v "Log_name" | awk '{print $1}'); doif [ "$binlog" != "$CURRENT_BINLOG" ]; thenlog "备份二进制日志: $binlog"mysqlbinlog -u$MYSQL_USER -p$MYSQL_PASSWORD -h$MYSQL_HOST -P$MYSQL_PORT \--read-from-remote-server $binlog > \${BACKUP_DIR}/binlogs/${binlog}_${DATE}.sql 2>>$LOG_FILEif [ $? -eq 0 ]; thenlog "二进制日志 $binlog 备份成功"# 删除服务器上已备份的二进制日志(可选,谨慎使用)# mysql -u$MYSQL_USER -p$MYSQL_PASSWORD -h$MYSQL_HOST -P$MYSQL_PORT -e "PURGE BINARY LOGS TO '$binlog';"elselog "错误: 二进制日志 $binlog 备份失败"fifidonelog "增量备份完成" }# 清理旧备份文件 cleanup_old_backups() {log "清理过期备份文件..."# 保留30天的全量备份find ${BACKUP_DIR}/full -name "*.gz" -mtime +30 -delete >> $LOG_FILE 2>&1# 保留14天的增量备份find ${BACKUP_DIR}/binlogs -name "*.sql" -mtime +14 -delete >> $LOG_FILE 2>&1find ${BACKUP_DIR}/incremental -name "*.sql" -mtime +14 -delete >> $LOG_FILE 2>&1log "清理完成" }# 主函数 main() {log "=== MySQL备份任务开始 ==="check_mysql_connection# 判断今天是周几TODAY=$(date +%A)if [ "$TODAY" = "$FULL_BACKUP_DAY" ]; thenlog "今天是 $TODAY,执行全量备份"full_backup# 全量备份后也执行一次增量备份,确保数据完整性incremental_backupelselog "今天是 $TODAY,执行增量备份"incremental_backupficleanup_old_backupslog "=== MySQL备份任务完成 ===\n" }# 执行主函数 main "$@"
给予脚本执行权限:chmod +x mysql_back.sh
执行结果:
日志文件中有报错,原因如下:
错误是因为 mysqlbinlog
工具不支持 default-character-set=utf8
这个配置项,但你的 MySQL 配置文件(如 my.cnf
或你创建的 mysql_backup.cnf
)中可能包含了这个设置,导致工具执行失败。
解决方法:修改配置文件 "/etc/my.cnf"
移除 default-character-set=utf8 这一行
重启mysql执行脚本验证:
报错消失,成功完成备份。
查看备份文件:
三、计划任务配置
crontab -e
# 每周日凌晨2点执行全量备份 0 2 * * 0 /bin/bash /path/to/mysql_backup.sh# 周一到周六凌晨2点执行增量备份 0 2 * * 1-6 /bin/bash /path/to/mysql_backup.sh