草庐IT

✨Linux定时备份mysql中的数据库(包括Docker)

汪杰杰杰杰 2023-08-16 原文

文章目录


前言

数据库定时备份是开发中的刚需,就如同我们公司之前数据库植入病毒勒索比特币…


一、Linux中定时备份mysql

基本逻辑就是通过定时轮询执行shell脚本去备份数据库形成脚本文件存放在服务器文件夹中

1.先上效果图

2.创建目录

先找到自己存放脚本的目录下面,我放在 root/BeiFen文件夹下

//进入root目录下
cd /root
//创建BeiFen文件夹
mkdir BeiFen
//因为我备份了三个数据库 所以我创建了三个文件夹
mkdir jeecg-boot nacos xxl_job 
//创建存放日志的logs文件夹 我把shell脚本也存放在了该目录下
mkdir logs

文件夹创建完毕效果展示

3.开写shell脚本

//创建shell脚本文件

vim jeecgboot-back.sh

脚本里注释写的也很清楚 同学们可以细细看一下

#ip
dbserver='127.0.0.1'
#数据库用户名
dbuser='root'
#数据密码
dbpasswd='root'
#数据库,如有多个库用空格分开
dbname='jeecg-boot nacos xxl_job'
#备份时间
backtime=`date +%Y%m%d-%H:%M`
#备份输出日志路径
logpath='/root/BeiFen'


echo "################## ${backtime} #############################"
echo "${dbname} 开始备份 备份时间 ${backtime} "
#日志记录头部
echo "" >> ${logpath}/logs/mysql-back.log
#echo "-------------------------------------------------" >> ${logpath}/logs/mysql-back.log
#echo "备份时间为${backtime},备份数据库表 ${dbname} 开始" >> ${logpath}/logs/mysql-back.log
#正式备份数据库
for table in $dbname; do
source=`mysqldump -h ${dbserver} -u ${dbuser} -p${dbpasswd} ${table} > ${logpath}/${table}/${table}_${backtime}.sql` 2>> ${logpath}/logs/mysql-back.log;
#备份成功以下操作
if [ "$?" == 0 ];then
cd ${logpath}
#删除七天前备份,也就是只保存7天内的备份
find $logpath -name "*.sql" -type f -mtime +7 -exec rm -rf {} \; > ${logpath} 2>&1
echo "数据库表 ${dbname} 备份成功!!" >> ${logpath}/logs/mysql-back.log
else
#备份失败则进行以下操作
echo "数据库表 ${dbname} 备份失败!!" >> ${logpath}/logs/mysql-back.log
fi
done
echo "完成备份"
echo "################## ${backtime} #############################"

代码如下(示例):

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
import warnings
warnings.filterwarnings('ignore')
import  ssl
ssl._create_default_https_context = ssl._create_unverified_context
# 二、使用步骤
## 1.引入库
代码如下(示例):

```c
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
import warnings
warnings.filterwarnings('ignore')
import  ssl
ssl._create_default_https_context = ssl._create_unverified_context

我们手动执行一下 看一下效果

sh jeecgboot-back.sh

备份成功 very nice!

4.定时执行

1、crond和crontab

crond和crontab是密不可分的

  • crond

crond 是 Linux 系统下用来周期性地执行某种任务或等待处理某些事件的一个守护进程。当安装完成操作系统后,默认会安装此服务工具,并且会自动启动 crond 进程,crond 进程每分钟会定期检查是否有要执行的任务,如果有要执行的任务,则自动执行该任务。

  • crontab
    linux提供给使用者自己定义任务,crontab依赖crond进程,crond进程每分钟回去扫描crontab中的定时任务

查看crond进程的状态,默认是根据系统自启动的

2、新建任务

  • 00 00 * * * 每天凌晨执行一次
#新建定时任务命令
crontab -e

#写入该命令
00 00 * * * cd /root/BeiFen/logs; sh jeecgboot-back.sh >> mysql-back.log 2>>mysql-back.log

3、查看任务

#查看定时任务命令
crontab -l

4、删除所有任务

#crontab -r 删除任务 没有提示 谨慎操作! 谨慎操作! 谨慎操作!(重要的事情说三遍!!!)
crontab -r

二、Docker中定时备份mysql

docker中备份数据库的逻辑跟上面的差不多 也是通过定时轮询shell脚本从而实现数据库的备份

1、方法一: 备份是通过如下命令实现

docker exec -it mysql(镜像号) mysqldump -h$mysql_host -P$mysql_port -u$mysql_user -p$mysql_password -B test1(数据库名称)(中间是有一个空格的)> $backup_dir/mysql_backup_test-$backup_time.sql
# 如果需要压缩
docker exec 301520ed7b07 mysqldump -uroot -p123456 leyeoa | gzip > ${backup_dir}/leyeoa_${backup_time}.sql.gz
# 解压gz压缩包
gzip -d FileName.gz

参考:http://t.zoukankan.com/Hello-TomCat-p-13231783.html

2、方法二: 进入容器执行

#获取容器id
mysqlid=`/usr/local/bin/docker ps -aqf "name=mysql5.7"`
 
#进入mysql容器
/usr/local/bin/docker exec -i ${mysqlid} bash<<'EOF'
# 执行备份
mysqldump --single-transaction -u root -h 127.0.0.1 --password=123456 --all-databases > /backup/db.sql
#将容器内sql文件导出到服务器
docker cp ${mysqlid}:/backup/db.sql ${backup_dir}/db_${now}.sql

参考:https://www.cnblogs.com/wangtaobiu/p/15624238.html

3、实现

#进入脚本存放文件夹
cd /root/BeiFen/
#创建存放备份文件的文件夹
mkdir LIFETREEBACKUP
mkdir Jeecg
#创建脚本文件
touch LIFE_jeecg_backup.sh
#编写脚本文件
vim LIFE_jeecg_backup.sh

脚本内容(如遇到问题注意看shell里的注释)

#!/bin/bash

# 定义工作路径
BASE_DIR=/root/BeiFen

# 备份文件存放地址(根据实际情况填写)
backup_location=$BASE_DIR/LIFETREEBACKUP/Jeecg
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="root"
mysql_host="172.17.0.1"
mysql_port="3306"
mysql_charset="utf8"
mysql_database=jeecg-boot

# 增加日志路径 #时间格式DATE=`date '+%Y%m%d-%H%M'`
LOGFILE=$backup_location/$mysql_database-backup.log
echo "$(date "+%Y-%m-%d %H:%M:%S") 日志路径:$LOGFILE"

# 是否删除过期数据
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!"
mysql_database_backup_file=${mysql_database}_backup-${backup_time}.sql

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

echo "${time} START BACKUP"
echo "${time} START BACKUP ">> $LOGFILE
echo "${time} docker exec -it mysql mysqldump -h${mysql_host} -P${mysql_port} -u${mysql_user} -p${mysql_password} -B ${mysql_database} > ${backup_dir}/${mysql_database_backup_file}"  >> $LOGFILE
# docker exec -it mysql mysqldump -h$mysql_host -P$mysql_port -u$mysql_user -p$mysql_password -B $mysql_database > $backup_dir/$mysql_database_backup_file
# 报错解决:the input device is not a TTY 原因是后台linux执行的时候没有终端设备一般来说我们启动容器后要与容器进行交互操作,这是,就要加上"-it"这个参数
,而在重启过重中或定时任务中,如果让脚本在后台运行,就没有可交互的终端,这就会引发如题所示错误,解决办法就是去掉“-it”这个参数
docker exec mysql mysqldump -h$mysql_host -P$mysql_port -u$mysql_user -p$mysql_password -B $mysql_database > $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

1、执行脚本

#给脚本文件赋权限
chmod +x LIFE_jeecg_backup.sh
#执行脚本方法一
sh LIFE_jeecg_backup.sh
#执行脚本方法二
./LIFE_jeecg_backup.sh

2.看效果

3.定时执行(同是使用crontab命令,可参考上方)

00 00 * * * 每天凌晨12点执行一次

00 00 * * * cd /root/BeiFen;sh LIFE_jeecg_backup.sh >> back_task.log 2>>back_task.log

4、我把Nacos和XxlJob的备份脚本文件也贴出来,可以直接Copy使用

#进入脚本存放文件夹
cd /root/BeiFen/LIFETREEBACKUP
#创建用于存放备份Nacos数据库脚本的文件夹
mkdir Nacos
#创建用于存放备份Xxljob数据库的文件夹
mkdir XxlJob

1、创建Nacos shell脚本文件

vim LIFE_nacos_backup.sh

脚本代码

#!/bin/bash

# 定义工作路径
BASE_DIR=/root/BeiFen

# 备份文件存放地址(根据实际情况填写)
backup_location=$BASE_DIR/LIFETREEBACKUP/Nacos
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="root"
mysql_host="172.17.0.1"
mysql_port="3306"
mysql_charset="utf8"
mysql_database=nacos

# 增加日志路径 #时间格式DATE=`date '+%Y%m%d-%H%M'`
LOGFILE=$backup_location/$mysql_database-backup.log
echo "$(date "+%Y-%m-%d %H:%M:%S") 日志路径:$LOGFILE"

# 是否删除过期数据
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!"
mysql_database_backup_file=${mysql_database}_backup-${backup_time}.sql

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

echo "${time} START BACKUP"
echo "${time} START BACKUP ">> $LOGFILE
echo "${time} docker exec -it mysql mysqldump -h${mysql_host} -P${mysql_port} -u${mysql_user} -p${mysql_password} -B ${mysql_database} > ${backup_dir}/${mysql_database_backup_file}"  >> $LOGFILE
# docker exec -it mysql mysqldump -h$mysql_host -P$mysql_port -u$mysql_user -p$mysql_password -B $mysql_database > $backup_dir/$mysql_database_backup_file
# 报错解决:the input device is not a TTY 原因是后台linux执行的时候没有终端设备一般来说我们启动容器后要与容器进行交互操作,这是,就要加上"-it"这个参数
,而在重启过重中或定时任务中,如果让脚本在后台运行,就没有可交互的终端,这就会引发如题所示错误,解决办法就是去掉“-it”这个参数
docker exec mysql mysqldump -h$mysql_host -P$mysql_port -u$mysql_user -p$mysql_password -B $mysql_database > $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

2、创建XxlJob shell脚本文件

vim LIFE_xxljob_backup.sh

脚本代码

#!/bin/bash

# 定义工作路径
BASE_DIR=/root/BeiFen

# 备份文件存放地址(根据实际情况填写)
backup_location=$BASE_DIR/LIFETREEBACKUP/XxlJob
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="root"
mysql_host="172.17.0.1"
mysql_port="3306"
mysql_charset="utf8"
mysql_database=xxl_job

# 增加日志路径 #时间格式DATE=`date '+%Y%m%d-%H%M'`
LOGFILE=$backup_location/$mysql_database-backup.log
echo "$(date "+%Y-%m-%d %H:%M:%S") 日志路径:$LOGFILE"

# 是否删除过期数据
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!"
mysql_database_backup_file=${mysql_database}_backup-${backup_time}.sql

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

echo "${time} START BACKUP"
echo "${time} START BACKUP ">> $LOGFILE
echo "${time} docker exec -it mysql mysqldump -h${mysql_host} -P${mysql_port} -u${mysql_user} -p${mysql_password} -B ${mysql_database} > ${backup_dir}/${mysql_database_backup_file}"  >> $LOGFILE
# docker exec -it mysql mysqldump -h$mysql_host -P$mysql_port -u$mysql_user -p$mysql_password -B $mysql_database > $backup_dir/$mysql_database_backup_file
# 报错解决:the input device is not a TTY 原因是后台linux执行的时候没有终端设备一般来说我们启动容器后要与容器进行交互操作,这是,就要加上"-it"这个参数
,而在重启过重中或定时任务中,如果让脚本在后台运行,就没有可交互的终端,这就会引发如题所示错误,解决办法就是去掉“-it”这个参数
docker exec mysql mysqldump -h$mysql_host -P$mysql_port -u$mysql_user -p$mysql_password -B $mysql_database > $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

3、添加定时任务

00 01 * * * cd /root/BeiFen;sh LIFE_xxljob_backup.sh >> back_task.log 2 >>back_task.log
00 01 * * * cd /root/BeiFen;sh LIFE_nacos_backup.sh >> back_task.log 2>>back_task.log

有关✨Linux定时备份mysql中的数据库(包括Docker)的更多相关文章

  1. ruby - 如何从 ruby​​ 中的字符串运行任意对象方法? - 2

    总的来说,我对ruby​​还比较陌生,我正在为我正在创建的对象编写一些rspec测试用例。许多测试用例都非常基础,我只是想确保正确填充和返回值。我想知道是否有办法使用循环结构来执行此操作。不必为我要测试的每个方法都设置一个assertEquals。例如:describeitem,"TestingtheItem"doit"willhaveanullvaluetostart"doitem=Item.new#HereIcoulddotheitem.name.shouldbe_nil#thenIcoulddoitem.category.shouldbe_nilendend但我想要一些方法来使用

  2. ruby - 其他文件中的 Rake 任务 - 2

    我试图在一个项目中使用rake,如果我把所有东西都放到Rakefile中,它会很大并且很难读取/找到东西,所以我试着将每个命名空间放在lib/rake中它自己的文件中,我添加了这个到我的rake文件的顶部:Dir['#{File.dirname(__FILE__)}/lib/rake/*.rake'].map{|f|requiref}它加载文件没问题,但没有任务。我现在只有一个.rake文件作为测试,名为“servers.rake”,它看起来像这样:namespace:serverdotask:testdoputs"test"endend所以当我运行rakeserver:testid时

  3. ruby-on-rails - Ruby net/ldap 模块中的内存泄漏 - 2

    作为我的Rails应用程序的一部分,我编写了一个小导入程序,它从我们的LDAP系统中吸取数据并将其塞入一个用户表中。不幸的是,与LDAP相关的代码在遍历我们的32K用户时泄漏了大量内存,我一直无法弄清楚如何解决这个问题。这个问题似乎在某种程度上与LDAP库有关,因为当我删除对LDAP内容的调用时,内存使用情况会很好地稳定下来。此外,不断增加的对象是Net::BER::BerIdentifiedString和Net::BER::BerIdentifiedArray,它们都是LDAP库的一部分。当我运行导入时,内存使用量最终达到超过1GB的峰值。如果问题存在,我需要找到一些方法来更正我的代

  4. ruby-on-rails - Rails 3 中的多个路由文件 - 2

    Rails2.3可以选择随时使用RouteSet#add_configuration_file添加更多路由。是否可以在Rails3项目中做同样的事情? 最佳答案 在config/application.rb中:config.paths.config.routes在Rails3.2(也可能是Rails3.1)中,使用:config.paths["config/routes"] 关于ruby-on-rails-Rails3中的多个路由文件,我们在StackOverflow上找到一个类似的问题

  5. ruby - 解析 RDFa、微数据等的最佳方式是什么,使用统一的模式/词汇(例如 schema.org)存储和显示信息 - 2

    我主要使用Ruby来执行此操作,但到目前为止我的攻击计划如下:使用gemsrdf、rdf-rdfa和rdf-microdata或mida来解析给定任何URI的数据。我认为最好映射到像schema.org这样的统一模式,例如使用这个yaml文件,它试图描述数据词汇表和opengraph到schema.org之间的转换:#SchemaXtoschema.orgconversion#data-vocabularyDV:name:namestreet-address:streetAddressregion:addressRegionlocality:addressLocalityphoto:i

  6. ruby-on-rails - Rails - 一个 View 中的多个模型 - 2

    我需要从一个View访问多个模型。以前,我的links_controller仅用于提供以不同方式排序的链接资源。现在我想包括一个部分(我假设)显示按分数排序的顶级用户(@users=User.all.sort_by(&:score))我知道我可以将此代码插入每个链接操作并从View访问它,但这似乎不是“ruby方式”,我将需要在不久的将来访问更多模型。这可能会变得很脏,是否有针对这种情况的任何技术?注意事项:我认为我的应用程序正朝着单一格式和动态页面内容的方向发展,本质上是一个典型的网络应用程序。我知道before_filter但考虑到我希望应用程序进入的方向,这似乎很麻烦。最终从任何

  7. ruby-on-rails - Rails 3.2.1 中 ActionMailer 中的未定义方法 'default_content_type=' - 2

    我在我的项目中添加了一个系统来重置用户密码并通过电子邮件将密码发送给他,以防他忘记密码。昨天它运行良好(当我实现它时)。当我今天尝试启动服务器时,出现以下错误。=>BootingWEBrick=>Rails3.2.1applicationstartingindevelopmentonhttp://0.0.0.0:3000=>Callwith-dtodetach=>Ctrl-CtoshutdownserverExiting/Users/vinayshenoy/.rvm/gems/ruby-1.9.3-p0/gems/actionmailer-3.2.1/lib/action_mailer

  8. ruby-on-rails - Rails 应用程序中的 Rails : How are you using application_controller. rb 是新手吗? - 2

    刚入门rails,开始慢慢理解。有人可以解释或给我一些关于在application_controller中编码的好处或时间和原因的想法吗?有哪些用例。您如何为Rails应用程序使用应用程序Controller?我不想在那里放太多代码,因为据我了解,每个请求都会调用此Controller。这是真的? 最佳答案 ApplicationController实际上是您应用程序中的每个其他Controller都将从中继承的类(尽管这不是强制性的)。我同意不要用太多代码弄乱它并保持干净整洁的态度,尽管在某些情况下ApplicationContr

  9. ruby-on-rails - form_for 中不在模型中的自定义字段 - 2

    我想向我的Controller传递一个参数,它是一个简单的复选框,但我不知道如何在模型的form_for中引入它,这是我的观点:{:id=>'go_finance'}do|f|%>Transferirde:para:Entrada:"input",:placeholder=>"Quantofoiganho?"%>Saída:"output",:placeholder=>"Quantofoigasto?"%>Nota:我想做一个额外的复选框,但我该怎么做,模型中没有一个对象,而是一个要检查的对象,以便在Controller中创建一个ifelse,如果没有检查,请帮助我,非常感谢,谢谢

  10. ruby - rspec 需要 .rspec 文件中的 spec_helper - 2

    我注意到像bundler这样的项目在每个specfile中执行requirespec_helper我还注意到rspec使用选项--require,它允许您在引导rspec时要求一个文件。您还可以将其添加到.rspec文件中,因此只要您运行不带参数的rspec就会添加它。使用上述方法有什么缺点可以解释为什么像bundler这样的项目选择在每个规范文件中都需要spec_helper吗? 最佳答案 我不在Bundler上工作,所以我不能直接谈论他们的做法。并非所有项目都checkin.rspec文件。原因是这个文件,通常按照当前的惯例,只

随机推荐