一、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; then
log "错误: 无法连接到MySQL服务器"
exit 1
fi
}
# 全量备份函数
full_backup() {
log "开始全量备份..."
# 刷新日志,开始新的二进制日志文件
mysql -u$MYSQL_USER -p$MYSQL_PASSWORD -h$MYSQL_HOST -P$MYSQL_PORT -e "FLUSH LOGS;"
# 备份所有指定的数据库
for DB in $DATABASES; do
log "备份数据库: $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_FILE
if [ $? -eq 0 ]; then
log "数据库 $DB 全量备份成功"
# 压缩备份文件
gzip ${BACKUP_DIR}/full/${DB}_full_${DATE}.sql
else
log "错误: 数据库 $DB 全量备份失败"
fi
done
# 记录当前二进制日志位置
mysql -u$MYSQL_USER -p$MYSQL_PASSWORD -h$MYSQL_HOST -P$MYSQL_PORT -e "SHOW MASTER STATUS\G" > \
${BACKUP_DIR}/binlogs/master_status_${DATE}.txt
log "全量备份完成"
}
# 增量备份函数
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}'); do
if [ "$binlog" != "$CURRENT_BINLOG" ]; then
log "备份二进制日志: $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_FILE
if [ $? -eq 0 ]; then
log "二进制日志 $binlog 备份成功"
# 删除服务器上已备份的二进制日志(可选,谨慎使用)
# mysql -u$MYSQL_USER -p$MYSQL_PASSWORD -h$MYSQL_HOST -P$MYSQL_PORT -e "PURGE BINARY LOGS TO '$binlog';"
else
log "错误: 二进制日志 $binlog 备份失败"
fi
fi
done
log "增量备份完成"
}
# 清理旧备份文件
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>&1
find ${BACKUP_DIR}/incremental -name "*.sql" -mtime +14 -delete >> $LOG_FILE 2>&1
log "清理完成"
}
# 主函数
main() {
log "=== MySQL备份任务开始 ==="
check_mysql_connection
# 判断今天是周几
TODAY=$(date +%A)
if [ "$TODAY" = "$FULL_BACKUP_DAY" ]; then
log "今天是 $TODAY,执行全量备份"
full_backup
# 全量备份后也执行一次增量备份,确保数据完整性
incremental_backup
else
log "今天是 $TODAY,执行增量备份"
incremental_backup
fi
cleanup_old_backups
log "=== 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