宿主机中定时全量备份docker中的mysql数据库

宿主机中定时全量备份docker中的mysql数据库

数据备份

1、所有数据库

  • 备份-所有数据库的表结构及数据
#方法一:所有表结构及数据
docker exec -it mysql5 mysqldump -uroot -proot --all-databases > \
~/data/backup_2022.sql

#方法二:所有表结构及数据
docker exec mysql5 sh -c 'exec mysqldump -uroot -proot --all-databases' > \
~/data/backup_2022.sql

2、 单个数据库

  • 备份-单个数据库的表结构及数据到宿主机
#1.备份backupdb到宿主机
docker exec -it mysql5 mysqldump -uroot -proot backupdb > ~/data/backup_2022.sql

3、 只导数据不导结构

docker exec -it mysql5 mysqldump -t -uroot -proot backupdb > \
~/data/backup_2022.sql

4、 只导结构不导数据

docker exec -it mysql5 mysqldump --opt -d -uroot -proot backupdb > \
~/data/backup_2022.sql

5、导出特定表的结构

docker exec -it mysql5 mysqldump --single-transaction -uroot -proot backupdb sys_user \
> ~/data/backup_2022.sql

定时备份实现过程

1.创建脚本

cd /mnt/app/usr/docker/mysql
touch mysql_dump_script.sh
vi mysql_dump_script.sh

脚本内容

#!/bin/bash

# 定义工作路径
BASE_DIR=/usr/local/mysql
 
# 备份文件存放地址(根据实际情况填写)
backup_location=$BASE_DIR/backup
echo "$(date "+%Y-%m-%d %H:%M:%S") 备份路径:$backup_location"

# 判断路径是否存在
if [ ! -d "$backup_location" ]; then
    mkdir -p $backup_location
fi

# 设置mysql的登录用户名和密码(根据实际情况填写)
mysql_user="root"
mysql_password="password"
mysql_host="localhost"
mysql_port="3306"
mysql_charset="utf8"
# 多个数据库间用空格分隔
mysql_database=(db1 dk2 db3 db4)


# 是否删除过期数据
expire_backup_delete="ON"
expire_days=7
backup_time=`date +%Y%m%d%H%M`
backup_dir=$backup_location
welcome_msg="Welcome to use MySQL backup tools!"

# docker容器名称
dockerName=mysql-test

time=$(date "+%Y-%m-%d %H:%M:%S")
echo -e "\r\n\r\n\r\n--------------------------------" >> $LOGFILE

# 备份数据库中数据
for dbName in ${mysql_database[*]}
do 
	# 增加日志路径 #时间格式DATE=`date '+%Y%m%d-%H%M'`
	LOGFILE=$backup_location/$dbName-backup.log
	echo "$(date "+%Y-%m-%d %H:%M:%S") 日志路径:$LOGFILE"
	mysql_database_backup_file=${dbName}_backup-${backup_time}.sql
	
	
	# 查看 docker进程中是否有  mysql 容器
	# -q: docker ps 命令的一部分,展示ids
	runningDocker=$(docker ps --filter="name=$dockerName" -q | xargs)
	if [[ ! -n $runningDocker ]]
	then
	  echo " ${time}  mysql docker not found .........."
	  echo " ${time}  mysql docker not found .......... ">> $backup_location/docker.log
	  continue
	fi

	echo "${time} START BACKUP"
	echo "${time} START BACKUP ">> $LOGFILE
	echo "${time} docker exec -it ${runningDocker} mysqldump -h${mysql_host} -P${mysql_port} -u${mysql_user} -p${mysql_password} -B ${dbName} > ${backup_dir}/${mysql_database_backup_file}"  >> $LOGFILE

	# 报错解决:the input device is not a TTY 原因是后台linux执行的时候没有终端设备一般来说我们启动容器后要与容器进行交互操作,这时,就要加上"-it"这个参数,而在重启过重中或定时任务中,如果让脚本在后台运行,就没有可交互的终端,这就会引发如题所示错误,解决办法就是去掉“-it”这个参数

	docker exec $runningDocker mysqldump -h$mysql_host -P$mysql_port -u$mysql_user -p$mysql_password -B $dbName > $backup_dir/$mysql_database_backup_file

	time=$(date "+%Y-%m-%d %H:%M:%S")
	if [ $? -ne 0 ]; then
		echo '${time} FINISH ERROR'
		echo '${time} FINISH ERROR'  >> $LOGFILE
		exit
		EOF
	fi
	echo "${time} FINISH BACKUP"
	echo "${time} FINISH BACKUP" >> $LOGFILE
done

# 删除过期数据
if [ "$expire_backup_delete" == "ON" -a  "$backup_location" != "" ];then
		#删除7天以上的备份 find /home/ywtg/backup/ -type f -mtime +7 -exec rm {} ;
        `find $backup_location/ -type f -mtime +$expire_days | xargs rm -rf`
        echo ${time}' Expired backup data delete complete!'
fi

脚本验证

./mysql_dump_script.sh

执行确定脚本是否正确.

期间碰到的问题:

mysqldump: [Warning] Using a password on the command line interface can be insecure.

解决方法
1.docker容器中任意位置创建 my.cnf 文件(名称随意),内容如下

[client]
user=root
password=password
host=localhost
port=3306

2.shell脚本中删除数据库密码相关信息,将-h$mysql_host -P$mysql_port -u$mysql_user -p$mysql_password替换为--defaults-extra-file=上面my.cnf文件路径 注意是 (两个横线),并该参数需放在首位. 血的教训~~
参考博客

https://blog.csdn.net/coco3600/article/details/100231952

另参照下文链接使用 –defaults-file= / --defaults-extra-file= 参数,

mysqldump相关命令参数

另附常见故障排除,以及大表转储相关设置博客

https://www.11meigui.com/?p=3349

2.添加crontab定时任务

1.  crontab -e
2. 新加定时任务,保存退出
3. crontab -l 查看定时任务是否添加成功

例:

crontab -e
# 每分钟执行一次数据库备份
* * * * * /mnt/app/usr/docker/mysql/mysql_dump_script.sh
:wq

以上操作,均在root用户下进行.


crontab相关

Linux下的任务调度分为两类: 系统任务调度用户任务调度

系统任务调度:系统周期性所要执行的工作,比如写缓存数据到硬盘、日志清理等。在/etc目录下有一个crontab文件,这个就是系统任务调度的配置文件。

用户任务调度:用户定期要执行的工作,比如用户数据备份、定时邮件提醒等。用户可以使用 crontab 工具来定制自己的计划任务。所有用户定义的crontab 文件都被保存在 /var/spool/cron目录中。其文件名与用户名一致。

crontab文件的含义

用户所建立的crontab文件中,每一行都代表一项任务,每行的每个字段代表一项设置,它的格式共分为六个字段,前五段是时间设定段,第六段是要执行的命令段,格式如下:

minute  hour  day  month  week  command

其中:

minute: 表示分钟,可以是从0到59之间的任何整数。

hour:表示小时,可以是从0到23之间的任何整数。

day:表示日期,可以是从1到31之间的任何整数。

month:表示月份,可以是从1到12之间的任何整数。

week:表示星期几,可以是从0到7之间的任何整数,这里的0或7代表星期日。

command:要执行的命令,可以是系统命令,也可以是自己编写的脚本文件。

宿主机中定时全量备份docker中的mysql数据库_第1张图片

在以上各个字段中,还可以使用以下特殊字符:

  • 星号(*):代表所有可能的值,例如month字段如果是星号,则表示在满足其它字段的制约条件后每月都执行该命令操作。
  • 逗号(,):可以用逗号隔开的值指定一个列表范围,例如,“1,2,5,7,8,9”
  • 中杠(-):可以用整数之间的中杠表示一个整数范围,例如“2-6”表示“2,3,4,5,6”
  • 正斜线(/):可以用正斜线指定时间的间隔频率,例如“0-23/2”表示每两小时执行一次。同时正斜线可以和星号一起使用,例如*/10,如果用在minute字段,表示每十分钟执行一次。

crontab服务操作说明

/sbin/service crond start //启动服务

/sbin/service crond stop //关闭服务

/sbin/service crond restart //重启服务

/sbin/service crond reload //重新载入配置

查看crontab服务状态

service crond status

手动启动crontab服务

service crond start

查看crontab服务是否已设置为开机启动,执行命令

ntsysv

加入开机自动启动

chkconfig –level 35 crond on

更多crontab详情

https://www.cnblogs.com/yezigege/p/13503795.html

数据还原

1.将宿主机数据文件复制到docker容器中

docker cp 宿主机文件路径 容器ID/容器NAME:容器内路径

2.还原数据

mysql -uroot -p db1 < /tmp/db_backup-202207191011.sql

参考博客:

https://blog.csdn.net/Blueeyedboy521/article/details/124704918

https://blog.csdn.net/weixin_46540009/article/details/122011530

你可能感兴趣的:(mysql,数据库,mysql,docker)