Java跨Docker容器备份数据库数据

Java跨Docker容器备份数据库数据

    • 前置背景
    • 思路整理
    • 编写备份脚本
    • 容器启动
    • 检验效果
      • Java容器
      • MySQL容器
    • Java代码执行备份

我的个人博客:Lichg,欢迎大家访问。

前置背景

  • 在我们的开发部署场景中,通常多数使用Docker进行部署。当你的数据库和项目都使用Docker进行部署,此时我想要通过Java程序进行数据备份,那么就无法实现,因为是两个相互独立的容器。
  • 在本篇文章中,我提供我的解决方法仅供参考。

思路整理

  1. 因为你的两个Docker容器是相互独立的,你的Java容器要操作MySQL,所以你的Java容器要具备可以执行MySQL命令的能力
  2. 但是,MySQL和Java是隔离的,无法直接使用MySQL命令备份,所以就想到使用docker的exec命令去操作MySQL容器让他备份。
  3. 备份完事以后,备份的文件还在MySQL容器中,宿主机也看不到想要的备份的SQL脚本,所以MySQL容器要挂载数据卷,把备份的SQL脚本备份出来。

编写备份脚本

本脚本我是从别人那里拿的,根据自己的需求修改即可

#!/bin/bash
#备份路径
BACKUP=/backups/mysql
#当前时间
DATETIME=$(date +%Y-%m-%d)
echo "===== 备份开始 ====="#数据库名称
DATABASE=你的数据库名
#数据库地址
HOST=数据库地址
#数据库用户名
DB_USER=用户名
#数据库密码
DB_PW=密码
#创建备份目录
[ ! -d "${BACKUP}/$DATABASE" ] && mkdir -p "${BACKUP}/$DATABASE"
echo "备份文件存放于${BACKUP}/$DATABASE/$DATABASE-$DATETIME.sql"
#开始备份
mysqldump -h ${HOST} -u${DB_USER} -p${DB_PW}  ${DATABASE} > ${BACKUP}/$DATABASE/$DATABASE-$DATETIME.sqlecho "===== 导出成功,开始传输 ====="
#压缩成tar.gz包
cd $BACKUP
tar -zcvf $DATABASE.tar.gz $DATABASE
#备份到服务器B
#scp $DATABASE-$DATETIME.sql root@ip:/home/mysqlBackup
#删除备份目录  如果取消注释此命令 会删除sql脚本文件 只保留打包完成后的压缩包
# rm -rf ${BACKUP}/$DATABASE/$DATETIME#删除10天(不含)前备份的数据,这边可以自行更改
find $BACKUP -mtime +10 -name "*.tar.gz" -exec rm -rf {} \;
echo "===== 数据库备份到服务器成功 ====="

容器启动

这里如果你的容器已经启动了也没关系,直接跑一遍docker命令即可。

Java:

这里最主要的是数据卷的绑定,因为你的Java容器需要可以使用docker命令,所以你得把docker挂载进去。其他的根据自己的需求修改就行。

docker run -d \
-v $JOB_NAME-data:/tmp \
--net=host \
-e PARAMS="--spring.profiles.active=prod" \
-v /var/run/docker.sock:/var/run/docker.sock \
-v /usr/bin/docker:/usr/bin/docker \
--name $JOB_NAME $JOB_NAME

MySQL:

version: '3'services:mysql:image: mysql:5.7container_name: mysqlvolumes:- mysql-conf:/etc/mysql/conf.d- mysql-data:/var/lib/mysql# 数据库备份脚本存储路径,映射进去:这里是把你准备的备份脚本从宿主机映射到MySQL容器中,让他可以执行- /export/shell/mysql:/home/shell/mysql# 数据库的备份文件挂在地址:这里是MySQL备份完成后,将备份文件从容器中映射到宿主机中- /export/backups/mysql/57:/backups/mysql# 将宿主机的时区挂载到容器:不挂载可能导致容器内和宿主机的时间不一致,导致备份脚本文件名称的日期出错- /etc/localtime:/etc/localtime:roenvironment:- MYSQL_ROOT_PASSWORD=自行设置你的数据库密码ports:- "3306:3306"mem_limit: 512mvolumes:mysql-conf:mysql-data:

检验效果

Java容器

  1. 先进入到你的Java容器中:
docker exec -it Java容器名 bash
  1. 进来以后可以直接使用下面的命令,查看是否挂载Docker成功:
docker -v
  1. 出现版本号即为成功

image-20240527104710429

  1. 如果你出现了权限不足的问题,你需要退回到你的宿主机内,给docker.sock进行权限修改,没有的话直接省略此步骤即可:
chmod -R 777 /var/run/docker.sock
  1. Java容器中查看你的MySQL版本,如果正常出现版本号基本就没什么问题了:
# 注意这里没有 -it 参数
docker exec mysql mysql -V

image-20240527111754983

MySQL容器

  1. 进入MySQL容器:
docker exec -it mysql bash
  1. 找到你自己设置的挂载备份脚本的路径,查看脚本是否挂载成功:

image-20240527112516583

  1. 你可以直接执行下你的脚本,看下效果
sh 你的脚本名称

image-20240527113328530

  1. 可以到你的备份目录查看下备份的效果,这里有其他的是因为我的程序设置的每七天自动备份一次:

image-20240527113507659

  1. 到你的宿主机挂载的脚本备份路径查看:

image-20240527113846237

image-20240527113918053

  1. 这里还是有一个可能存在的坑:

如果你发现你备份的数据SQL脚本,分明是18号备份的但是SQL的脚本文件的名称上却是17号,这是因为:你的数据库备份脚本中,有一个参数是获取当前系统的时间,那么就说明你的MySQL容器中的时间跟宿主机的时间不一致,运行容器时没有对时区进行挂载数据卷。

image-20240527114446397

Java代码执行备份

代码执行这里我是使用了xxl-job定时任务去做,每七天备份一次,其他的实现方式可以根据你们自己的需求去进行更改。

    @XxlJob("mysqlBackup")public void mysqlBackup(){//获取Runtime实例Runtime runtime = Runtime.getRuntime();// 数据库备份命令String command = "docker exec mysql sh /home/shell/mysql/course_compete.sh";//获取命令所得的缓冲流结果BufferedReader bufferedReader = null;// 执行命令try {Process exec = runtime.exec(command);//初始化缓冲阅读器bufferedReader = new BufferedReader(new InputStreamReader(exec.getInputStream()));// 逐行读取输出String line;//此时就可以对获取的结果in进行操作了,可以使用in.readline()逐步获取每一行的结果内容while ((line = bufferedReader.readLine()) != null){log.info("获取到的行数据:{}", line);}} catch (IOException e) {log.error("竞赛模块数据库备份异常");throw new RuntimeException(e);}finally {if(bufferedReader != null){try {bufferedReader.close();} catch (IOException e) {throw new RuntimeException(e);}}}}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/16831.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【吊打面试官系列】Java高并发篇 - 什么是乐观锁和悲观锁?

大家好,我是锋哥。今天分享关于 【什么是乐观锁和悲观锁?】面试题,希望对大家有帮助; 什么是乐观锁和悲观锁? 1、乐观锁: 就像它的名字一样,对于并发间操作产生的线程安全问题持乐观状态, 乐观锁认为竞争…

ICML 2024 多视角融合驱动的通用具身操作算法SAM-E,为机器人学习复杂操作给出了可行解决方案

当我们拿起一个机械手表时,从正面会看到表盘和指针,从侧面会看到表冠和表链,打开手表背面会看到复杂的齿轮和机芯。每个视角都提供了不同的信息,将这些信息综合起来才能理解操作对象的整体三维。 想让机器人在现实生活中学会执行…

【stm32】江科协听课笔记

[3-1] GPIO输出_哔哩哔哩_bilibili 5.GPIO输出 这里,寄存器就是一段特殊的存储器,内核可以通过APB2总线队寄存器进行读写,这样就可以完成输出/读取电平的功能。寄存器的每一位对应一个引脚,stm32是32位的,这里的寄存器…

【工具】珍藏免费宝藏工具,不好用你来捶我

前言 🍊缘由 藏在我硬盘里的好东西,必须跟小伙伴们分享 东西很好,必须分享。良辰吉日,跟大家分享几款神仙级小工具,实际亲测,不好来锤。 正文 一.影刀 影刀可以使任何操作系统、桌面软件、Web程序的自动…

怎么搭建微信留言板功能

在信息爆炸的时代,微信已经成为了我们日常生活中不可或缺的一部分。它不仅仅是一个简单的聊天工具,更是一个充满无限可能的营销平台。今天,我要向大家介绍的是如何在你的微信平台上搭建一个独具特色的留言板功能,让用户能够自由发…

PyTorch的数据处理

💥今天看一下 PyTorch数据通常的处理方法~ 一般我们会将dataset用来封装自己的数据集,dataloader用于读取数据 Dataset格式说明 💬dataset定义了这个数据集的总长度,以及会返回哪些参数,模板: from tor…

51-54 Sora能制作动作大片还需要一段时间 | DrivingGaussian:周围动态自动驾驶场景的复合高斯飞溅

24年3月,北大、谷歌和加州大学共同发布了DrivingGaussian: Composite Gaussian Splatting for Surrounding Dynamic Autonomous Driving Scenes。视图合成和可控模拟可以生成自动驾驶的极端场景Corner Case,这些安全关键情况有助于以更低成本验证和增强自…

《最新出炉》系列入门篇-Python+Playwright自动化测试-42-强大的可视化追踪利器Trace Viewer

宏哥微信粉丝群:https://bbs.csdn.net/topics/618423372 有兴趣的可以扫码加入 1.简介 在我们日常执行自动化测试工作的过程中,经常会遇到一些偶发性的bug,但是因为bug是偶发性的,我们不一定每次执行都能复现,所以我…

ComfyUI 高级实战:极速稳定视频风格转绘

大家好,我是每天分享AI应用的萤火君! 重绘视频一直是短视频平台上的热点内容,流量不错。重绘视频一般是将真实视频重绘为动漫风格,或者是使用新的人物形象重放视频中的人物动作,再或者只是重绘视频中的部分内容&#…

什么样的展馆场馆才是科技满满?就差一张智慧场馆大屏

随着科技的飞速发展,传统的场馆展示方式已经无法满足现代人对信息获取和体验的需求。智慧场馆大屏作为一种新型的展示方式,应运而生。它将高清大屏显示技术、智能交互技术、数据分析技术等融为一体,为观众带来更加丰富、生动的展示体验。 一…

Hadoop3:HDFS中NameNode和SecondaryNameNode的工作机制(较复杂)

一、HDFS存储数据的机制简介 HDFS存储元数据(meta data)的时候 结果,记录在fsImage文件里 过程,记录在Edits文件里 同时fsImageEdits最终结果,这个最终结果(fsImageEdits)会保存一份在内存中,为了提升性能…

【算法】排序——加更

补充1个排序:希尔排序 思路:首先定义一个gap,从第0个数开始,每隔一个gap取出一个数,将取出来的数进行比较,方法类似插入排序。第二轮从第二个数开始,每隔一个gap取出一个数再进行插入排序。四轮就可以取完…

Vue的应届毕业生财务管理系统-计算机毕业设计源码82886

摘 要 随着互联网大趋势的到来,社会的方方面面,各行各业都在考虑利用互联网作为媒介将自己的信息更及时有效地推广出去,而其中最好的方式就是建立网络管理系统,并对其进行信息管理。由于现在网络的发达,应届毕业生财务…

面试官:讲讲为什么SpringBoot的 jar 可以直接运行?

Spring Boot 是一个用于简化 Spring 应用程序开发的框架,它通过约定优于配置和大量的自动化配置,使得开发者可以更轻松地创建和部署 Spring 应用程序。一个特别引人注目的特性是 Spring Boot 应用可以打包成一个可执行的 JAR 文件,并且可以直…

力扣:236.二叉树的最近公共祖先(C++)

文章目录 1. 题目描述2. 题目解析2.1 思路一2.1 思路二 给定一个二叉树, 找到该树中两个指定节点的最近公共祖先。 题目来源: 力扣…二叉树的最近公共祖先 1. 题目描述 百度百科中最近公共祖先的定义为:“对于有根树 T 的两个节点 p、q,最近公共祖先表…

Execel 数据分析-如何使用筛选-图表-透视图-处理多变量数据集

如果你的数据有很多个变量,比如横轴X有a,b,c,d等几个变量,Y轴也有个变量,那么这时候就用得到。 比如下面的例子,测试GPU的kernel吞吐量,其中stream cnt,grid dim,block dim 产生后面几个变量&am…

Java对象不再使用时,为什么要赋值为 null ?

在Java中,将不再使用的对象赋值为null的目的主要是为了帮助垃圾收集器(更快地释放内存。我这里有一套编程入门教程,不仅包含了详细的视频讲解,项目实战。如果你渴望学习编程,不妨点个关注,给个评论222&…

C语言指针详解(3)

前言: 强化数组指针的理解: 在C语言指针详解(2)-CSDN博客中我们模拟实现了一个二维数组,可能大家对其中的原理还有些模糊,这一章开始之前先梳理一遍。 一维数组的模拟实现: 再剖析二维数组之前…

Java整合EasyExcel实战——2 导出复杂表头

详情代码 实体类 Data public class ComplexHeadData {ExcelProperty({"主标题", "字符串标题"})private String string;ExcelProperty({"主标题", "日期标题"})private Date date;ExcelProperty({"主标题", "数字标…

AI日报|阿里8亿美元购入月之暗面36%股份,Meta首席杨立昆建议不要研究大模型...

文章推荐 阿里通义降价,百度文心免费,一图对比谁是最具性价比大模型? 阿里投资Kimi AI开发商月之暗面:8亿美元购入约36%股权 阿里巴巴在2024财年向AI初创企业月之暗面投资约8亿美元,购入其约36%股权。 月之暗面成立…