Docker 导出 mysql 数据

本贴最后更新于 1884 天前,其中的信息可能已经天翻地覆

前言

  前几天无意中在社区看到一个帖子(记一次清空数据仓库的过程),讲的是自己无意中删库的经历。如文中所讲,大多时候删库这件事我们只是耳闻,并没有遇到过,可要是万一呢,到时候恐怕是追悔莫及,而且 mysql 也没有 oracle 的恢复机制,所以备份就成了一个非常有必要的操作。

  由于没有相关操作经验,所以从零开始讲如何数据,毕竟我还是比较珍惜我的小博客的。

具体操作

  以前也导出过 sql 文件,但是都是直接用 Navicat 导出就完事了,但是这次我想实现的是自动备份,最好写成脚本的方式。

  基本思路:使用命令将数据库数据从 docker 容器中导出来,以时间戳命名。最多保持 7 天,过期文件自动删除。

导出 mysql 数据

间接导出

  mysql 导出数据的命令还是蛮简单的:mysqldump -u 用户名 -p 数据库名 > 导出的文件名,但这是 linux 里面执行的,我们的放在 docker 里面,所以要先进入容器,然后执行上述命令。然后你就会惊讶的发现,导出的文件在你的容器里面,然后你再从容器里面 copy 到你的主机上。这样做会在容器上产生大量 sql 文件,写定时任务是需要及时清理。

直接导出

  上述方法是可行的,但是过于麻烦,有没有一步到位的呢?很显然是有的,命令是这个样子的:docker exec -it [docker容器名称/ID] mysqldump -u[数据库用户名] -p[数据库密码] [数据库名称] > [导出表格路径],比如我的 docker exec -it mysql mysqldump -uroot -p123456 solo > /var/www/solo.sql。没有报错的话,导出的数据库文件就会到你指定的目录下了。

写成脚本方式运行

博主是不会写 Shell 脚本的,所以现学了下,参考 Shell 脚本编程 30 分钟入门

间接导出(间接导出时请先创建相关文件目录)

#!/bin/sh
# 进入容器
docker exec -i mysql bash<<'EOF'
# solo 为数据库的名称
 XXX为数据库密码
mysqldump -uroot -pXXX solo > /mysqlData/$(date +%Y%m%d).sql
#删除超过1天的数据
find /mysqlData/ -mtime +1 -type f | xargs rm -rf
exit
EOF
# 将docker中的备份的数据拷贝到宿主机上。
docker cp mysql:/mysqlData/$(date +%Y%m%d).sql /var/www/html/solo/sqlData/
#删除超过7天的数据
find /var/www/html/solo/sqlData -mtime +7 -type f | xargs rm -rf

直接导出(导出时 exec 不需指定参数 -it)

#!/bin/sh
# 进入你要保持数据的文件
cd /var/www/html/solo/sqlData
# 导出今日的sql
docker exec mysql mysqldump -uroot -p123123 solo >`date +%Y%m%d%H%M%S`.sql
# 删除7天前的sql(+号后面跟天数,N天前,find后指定目录)
find . -mtime +7 -type f | xargs rm -rf

后记

  导出的 sql 文件中会出现一些版本备注信息等,这样的 sql 文件导入时有时会出现问题,会报错,导入之前需要将 sql 文件中的无用信息删除。

/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
/*!40101 SET NAMES utf8 */;
/*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */;
/*!40103 SET TIME_ZONE='+00:00' */;
/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */;
/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;
/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;

这样的内容在 sql 中还不是一两句,到处都是。这里提供一段正则,可快速匹配到 sql 文件中所有 /*!40101XXXXX*/;,通过正则 \/\*\![0-9]+\s[\s\S]+?\s\*\/;\n 实现快速替换。
替换完后的效果如下所示,多舒服。
image.png

  • MySQL

    MySQL 是一个关系型数据库管理系统,由瑞典 MySQL AB 公司开发,目前属于 Oracle 公司。MySQL 是最流行的关系型数据库管理系统之一。

    690 引用 • 535 回帖
  • Docker

    Docker 是一个开源的应用容器引擎,让开发者可以打包他们的应用以及依赖包到一个可移植的容器中,然后发布到任何流行的操作系统上。容器完全使用沙箱机制,几乎没有性能开销,可以很容易地在机器和数据中心中运行。

    491 引用 • 917 回帖
  • Solo

    Solo 是一款小而美的开源博客系统,专为程序员设计。Solo 有着非常活跃的社区,可将文章作为帖子推送到社区,来自社区的回帖将作为博客评论进行联动(具体细节请浏览 B3log 构思 - 分布式社区网络)。

    这是一种全新的网络社区体验,让热爱记录和分享的你不再感到孤单!

    1434 引用 • 10054 回帖 • 490 关注
  • Shell

    Shell 脚本与 Windows/Dos 下的批处理相似,也就是用各类命令预先放入到一个文件中,方便一次性执行的一个程序文件,主要是方便管理员进行设置或者管理用的。但是它比 Windows 下的批处理更强大,比用其他编程程序编辑的程序效率更高,因为它使用了 Linux/Unix 下的命令。

    123 引用 • 74 回帖

相关帖子

欢迎来到这里!

我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。

注册 关于
请输入回帖内容 ...