Docker版Percona Xtrabackup全量壓縮腳本方式
簡(jiǎn)單記錄一下Percona Xtrabackup常用的每天定時(shí)備份的壓縮腳本
場(chǎng)景說明
- Linux環(huán)境
- Docker容器運(yùn)行的備份目標(biāo)MySQL
- Docker容器運(yùn)行的Percona Xtrabackup
- 每天定時(shí)全量備份一次
- 使用操作系統(tǒng)自帶的cron定時(shí)任務(wù)管理器
- 使用工具鏡像版本為 percona/percona-xtrabackup:8.0.35-34.1
鏡像信息:
[root@cn1920vm0064 backup]# docker image ls | grep -E '*backup|mysql*' percona/percona-xtrabackup 8.0.35-34.1 11c6f241e3b3 6 weeks ago 1.78GB mysql 8.0.22 d4c3cafb11d5 4 years ago 545MB
運(yùn)行容器:
[root@cn1920vm0064 backup]# docker ps | grep -E '*backup|mysql*' 99c8448c9387 mysql:8.0.22 "docker-entrypoint.s…" 19 hours ago Up 18 hours mysql8
上面的 Docker容器 mysql8 為要備份的業(yè)務(wù)數(shù)據(jù)庫,已經(jīng)做了數(shù)據(jù)目錄映射,之前創(chuàng)建該業(yè)務(wù)數(shù)據(jù)庫的Docker容器命令如下:
docker run -u root \ --cap-add=SYS_NICE \ --network=host \ --restart=always \ --name mysql8 \ -v /data/apps/mysql/conf/my.cnf:/etc/mysql/my.cnf \ -v /data/apps/mysql/files:/var/lib/mysql-files \ -v /data/apps/mysql/data:/var/lib/mysql \ -e MYSQL_ROOT_PASSWORD=YourPassword \ -d mysql:8.0.22
可以看到數(shù)據(jù)庫的數(shù)據(jù)目錄映射到物理宿主機(jī)的 /data/apps/mysql/data 目錄下了,這里假設(shè)數(shù)據(jù)庫端口為3309
一、創(chuàng)建備份腳本文件
sudo touch mysqlbackup.sh sudo chmod +x mysqlbackup.sh
假設(shè)備份數(shù)據(jù)放在如下目錄中:
sudo mkdir -p /data/apps/xtrabackup/backup
假設(shè)運(yùn)行產(chǎn)生的日志放在文件/var/log/xtrabackup/backup.log 中:
sudo mkdir -p /var/log/xtrabackup sudo touch /var/log/xtrabackup/backup.log sudo chmod 644 /var/log/xtrabackup/backup.log
需要在目標(biāo)業(yè)務(wù)數(shù)據(jù)庫中創(chuàng)建專門的用于備份的賬號(hào)密碼:
CREATE USER 'xtrabackup'@'%' IDENTIFIED WITH mysql_native_password BY 'yourbackpassword'; GRANT SELECT, RELOAD, PROCESS, LOCK TABLES, REPLICATION SLAVE, REPLICATION CLIENT ON *.* TO `xtrabackup`@`%`; GRANT BACKUP_ADMIN ON *.* TO `xtrabackup`@`%`; FLUSH PRIVILEGES;
腳本內(nèi)容如下:
#!/usr/bin/env bash
#
# MySQL XtraBackup Daily Backup Script (Docker)
# 每天備份一次,保留最近3天(可調(diào))
set -euo pipefail
# 建議:限制新建文件/目錄權(quán)限,提升安全性
umask 077
########## 可配置變量 BEGIN ##########
# 備份保留天數(shù)(只保留最近多少個(gè)備份目錄)
RETENTION_DAYS=3
# Docker 鏡像
XTRABACKUP_IMAGE="percona/percona-xtrabackup:8.0.35-34.1"
# 宿主機(jī) MySQL 數(shù)據(jù)卷所在的容器名稱
MYSQL_DATA_CONTAINER="mysql8"
# 備份容器運(yùn)行時(shí)名稱(臨時(shí))
BACKUP_CONTAINER_NAME="pxb"
# 備份根目錄(宿主機(jī)路徑)
BACKUP_ROOT="/data/apps/xtrabackup/backup"
# MySQL 連接信息(從備份容器訪問 MySQL)
MYSQL_HOST="172.17.0.1"
MYSQL_PORT="3309"
MYSQL_USER="xtrabackup"
MYSQL_PASSWORD="yourbackpassword"
# MySQL 數(shù)據(jù)目錄(在 mysql8 容器里的路徑)
MYSQL_DATADIR="/var/lib/mysql"
# 備份選項(xiàng)(可按需修改壓縮等參數(shù))
XTRABACKUP_OPTIONS="--backup --compress --compress-threads=4"
# 備份目錄命名前綴
BACKUP_PREFIX="full_backup_"
# 日志文件
LOG_FILE="/var/log/xtrabackup/backup.log"
########## 可配置變量 END ##########
# 確保日志目錄存在
mkdir -p "$(dirname "$LOG_FILE")"
# 從這里開始,所有輸出(包括 docker run 的 stdout/stderr)都寫入日志
exec >> "$LOG_FILE" 2>&1
echo "==== $(date '+%F %T') 開始 MySQL XtraBackup 備份 ===="
# 安全檢查:防止 BACKUP_ROOT 為空或指向根目錄
if [[ -z "${BACKUP_ROOT:-}" || "${BACKUP_ROOT}" == "/" ]]; then
echo "ERROR: BACKUP_ROOT 未定義或?yàn)?'/',為防止誤刪數(shù)據(jù),中止執(zhí)行!"
exit 1
fi
# 創(chuàng)建備份根目錄(如不存在)
mkdir -p "${BACKUP_ROOT}"
# 生成當(dāng)日備份目錄名,例如 full_backup_2025-12-01
TODAY_DATE="$(date +%F)"
TARGET_DIR_NAME="${BACKUP_PREFIX}${TODAY_DATE}"
TARGET_DIR="${BACKUP_ROOT}/${TARGET_DIR_NAME}"
echo "== 當(dāng)日備份目錄: ${TARGET_DIR}"
# 如果當(dāng)天目錄已存在,可以選擇退出或覆蓋,這里選擇退出防止覆蓋
if [[ -d "${TARGET_DIR}" ]]; then
echo "WARN: 備份目錄已存在:${TARGET_DIR},本次備份中止以避免覆蓋。"
exit 1
fi
echo "== 啟動(dòng) Docker 容器執(zhí)行備份 =="
echo " 鏡像: ${XTRABACKUP_IMAGE}"
echo " MySQL: ${MYSQL_HOST}:${MYSQL_PORT}"
echo " 數(shù)據(jù)目錄: ${MYSQL_DATADIR}"
echo " 目標(biāo)目錄: ${TARGET_DIR}"
docker run --name "${BACKUP_CONTAINER_NAME}" \
--rm \
-u root \
--volumes-from "${MYSQL_DATA_CONTAINER}" \
-v "${BACKUP_ROOT}":/backup \
"${XTRABACKUP_IMAGE}" \
/bin/bash -c "
xtrabackup ${XTRABACKUP_OPTIONS} \
--datadir=${MYSQL_DATADIR} \
--target-dir=/backup/${TARGET_DIR_NAME} \
--host=${MYSQL_HOST} \
--port=${MYSQL_PORT} \
--user=${MYSQL_USER} \
--password=${MYSQL_PASSWORD}
"
echo "== 備份完成: ${TARGET_DIR} =="
########## 清理舊備份(安全版) ##########
echo "== 清理舊備份,保留最近 ${RETENTION_DAYS} 個(gè) =="
cd "${BACKUP_ROOT}" || {
echo "ERROR: 無法進(jìn)入備份目錄 ${BACKUP_ROOT}"
exit 1
}
# 收集所有符合前綴的備份目錄,按時(shí)間倒序排列(最新在前)
BACKUP_DIRS=( $(ls -dt ${BACKUP_PREFIX}* 2>/dev/null || true) )
TOTAL=${#BACKUP_DIRS[@]}
if (( TOTAL == 0 )); then
echo "當(dāng)前沒有任何備份目錄,無需清理。"
elif (( TOTAL <= RETENTION_DAYS )); then
echo "當(dāng)前備份數(shù)量 ${TOTAL} 個(gè),不超過保留上限 ${RETENTION_DAYS},無需刪除。"
else
TO_DELETE_COUNT=$(( TOTAL - RETENTION_DAYS ))
echo "當(dāng)前共有 ${TOTAL} 個(gè)備份,將刪除最舊的 ${TO_DELETE_COUNT} 個(gè):"
for (( i=RETENTION_DAYS; i<TOTAL; i++ )); do
OLD_BACKUP="${BACKUP_DIRS[$i]}"
# 雙重保險(xiǎn):只刪除以 BACKUP_PREFIX 開頭的目錄
if [[ -d "${OLD_BACKUP}" && "${OLD_BACKUP}" == ${BACKUP_PREFIX}* ]]; then
echo " 刪除舊備份目錄: ${OLD_BACKUP}"
rm -rf "${OLD_BACKUP}"
else
echo " 跳過(非備份目錄或不存在): ${OLD_BACKUP}"
fi
done
fi
echo "==== $(date '+%F %T') 備份及清理完成 ===="
要點(diǎn)說明:
- BACKUP_ROOT 替換實(shí)際備份文件存放的目錄
- MYSQL_USER MYSQL_PASSWORD 替換實(shí)際創(chuàng)建的備份賬號(hào)密碼
- MYSQL_DATA_CONTAINER 替換實(shí)際業(yè)務(wù)數(shù)據(jù)庫mysql容器名稱
- RETENTION_DAYS 這里設(shè)置備份保存3天,根據(jù)實(shí)際情況修改
- MYSQL_DATADIR 指的是實(shí)際mysql容器里面的數(shù)據(jù)目錄,一般默認(rèn)就是 /var/lib/mysql
二、創(chuàng)建對(duì)應(yīng)的日志管理配置
上面腳本中設(shè)置了輸出的日志歸檔到 /var/log/xtrabackup/backup.log ,為了防止日志太大太多我們需要?jiǎng)?chuàng)建一個(gè)用于日志文件自動(dòng)輪換、壓縮、刪除的工具。
Linux系統(tǒng)自帶了一個(gè)工具:Logrotate!
Logrotate 是一個(gè) Linux/Unix 系統(tǒng)工具,主要用來管理系統(tǒng)生成的日志文件,這里我們直接創(chuàng)建對(duì)應(yīng)我們腳本的日志管理配置內(nèi)容:
sudo sh -c 'echo "/var/log/xtrabackup/backup.log {
daily
rotate 7
compress
delaycompress
missingok
notifempty
copytruncate
create 644 root root
dateext
dateformat -%Y%m%d
}" | tee /etc/logrotate.d/xtrabackup'
| 配置參數(shù) | 含義說明 |
|---|---|
| 文件路徑 | 管理 /var/log/xtrabackup/backup.log 日志。 |
| daily | 每天輪換一次。 |
| rotate 7 | 保留最近 7 份舊日志。 |
| compress | 壓縮舊日志。 |
| delaycompress | 延遲壓縮舊日志。 |
| copytruncate | 復(fù)制舊日志后,清空原文件,讓程序繼續(xù)寫入。 |
| create | 創(chuàng)建新日志文件的權(quán)限和所有者。 |
| dateext | 舊日志以日期命名。 |
| missingok | 日志不存在不報(bào)錯(cuò)。 |
| notifempty | 空日志不輪換。 |
測(cè)試一下
sudo logrotate -f /etc/logrotate.d/xtrabackup
正常情況日志目錄下會(huì)生成:
backup.log-yyyymmdd backup.log
三、創(chuàng)建定時(shí)任務(wù)
創(chuàng)建定時(shí)任務(wù)可以先手動(dòng)執(zhí)行一下腳本看下
sudo ./mysqlbackup.sh
上面的腳本放在 /data/apps/xtrabackup/backup/mysqlbackup.sh
sudo crontab -e
輸入:
0 6 * * * /data/apps/xtrabackup/backup/mysqlbackup.sh
這里是每天早上6點(diǎn)執(zhí)行,可以根據(jù)實(shí)際情況修改時(shí)間。
查看定時(shí)任務(wù)
sudo crontab -l
總結(jié)
本次腳本也是借助AI工具生產(chǎn),經(jīng)過了多次修改調(diào)試,適用于中小型業(yè)務(wù)場(chǎng)景的數(shù)據(jù)庫備份操作。
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
linux中無make命令的問題(make: *** 沒有指明目標(biāo)并且找不到 makefile及make命令安裝方法)
這篇文章主要介紹了linux中無make命令的問題(make: *** 沒有指明目標(biāo)并且找不到 makefile及make命令安裝方法),本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-08-08
Docker安裝mysql教程以及解決mysqld: Can‘t read dir&nbs
本文詳細(xì)介紹了如何通過Docker來安裝和配置MySQL數(shù)據(jù)庫,包括拉取MySQL鏡像、啟動(dòng)MySQL容器、配置MySQL、解決常見錯(cuò)誤等步驟,提供了詳盡的命令和參數(shù)說明,幫助用戶順利完成MySQL的安裝和配置,文中還提到了如何處理MySQL容器啟動(dòng)時(shí)遇到的“無法讀取目錄”2024-10-10

