在备份 MySQL 数据库时,可以使用 mysqldump
提供的参数来防止长时间的表锁定,尤其是在生产环境中有持续的写操作时。以下是一些推荐的参数来减少对数据库的锁定影响:
--single-transaction
:
- 这个选项会在
mysqldump
开始时启动一个事务,并在事务隔离级别为 REPEATABLE READ
的情况下备份数据,从而避免全局锁定(适用于 InnoDB 存储引擎)。这个选项非常适合用于不需要全库一致性的逻辑备份。
- 注意: 对于 MyISAM 表,这个参数不起作用,因为 MyISAM 不支持事务。
--quick
:
- 这个选项会使
mysqldump
一次一行地从数据库中读取数据,而不是将整个结果集读入内存,减少内存消耗,特别适合大表的备份。
--lock-tables=false
:
- 在默认情况下,
mysqldump
会对所有表加全表锁以确保数据一致性。使用 --lock-tables=false
可以避免加锁。对于支持事务的引擎(如 InnoDB),配合 --single-transaction
可以达到类似效果。
修改后的脚本:
我们将这些参数加入到脚本中,避免锁定库表。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37
| #!/bin/bash
DB_USER="your_db_user" DB_PASSWORD="your_db_password" DB_HOST="your_db_host_ip" DB_PORT=3306 DB_NAMES=("db1" "db2" "db3") BACKUP_DIR="/path/to/backup" DATE=$(date +"%Y%m%d") MAX_RATE=1M RETENTION_DAYS=30
mkdir -p "${BACKUP_DIR}"
for DB_NAME in "${DB_NAMES[@]}"; do BACKUP_FILE="${BACKUP_DIR}/${DB_NAME}_backup_${DATE}.sql.gz" echo "开始备份数据库:${DB_NAME} (服务器:${DB_HOST},端口:${DB_PORT})" mysqldump -h"${DB_HOST}" -P"${DB_PORT}" -u"${DB_USER}" -p"${DB_PASSWORD}" --single-transaction --quick --lock-tables=false "${DB_NAME}" | pv -qL ${MAX_RATE} | gzip > "${BACKUP_FILE}" if [[ $? -eq 0 ]]; then echo "数据库 ${DB_NAME} 备份成功,保存为 ${BACKUP_FILE}" else echo "数据库 ${DB_NAME} 备份失败!" fi done
find "${BACKUP_DIR}" -type f -name "*_backup_*.sql.gz" -mtime +${RETENTION_DAYS} -exec rm {} \;
echo "所有数据库备份完成。旧备份(超过 ${RETENTION_DAYS} 天)已被删除。"
|
参数解释:
--single-transaction
:
- 确保在备份时启动一个一致性事务,防止全库锁定,适用于 InnoDB 存储引擎。
--quick
:
- 每次从数据库中读取一行数据,减少内存占用,适合大表的备份。
--lock-tables=false
:
使用这些参数,备份过程将对生产环境的影响降到最低。对于 InnoDB 表,几乎不会有锁库的现象发生。