MySQL主从的应用

说明:本文介绍MySQL主从在实际中的应用。主从搭建和问题参考下面两篇文章:

  • MySQL主从结构搭建

  • 搭建MySQL主从结构时的问题

数据迁移

当我们搭建完MySQL主从,第一步当然是把历史数据导入到主从结构中。有以下两种方式:

  • 开启主从同步,将数据导入主节点,让从节点同步;

  • 将数据分别导入主从节点,让主从节点数据一致后,建立连接,开启同步;

不论哪种方式,都需要导出/导入数据。为了节省时间,可以采用mysql命令的方式导出/导入,而不是用数据库连接工具来操作。以xxl-job数据库为例:

数据导出为sql文件

mysqldump -u username -p xxl_job > xxl-job.sql

在这里插入图片描述

在这里插入图片描述

将xxl-job.sql文件上传到MySQL主从的服务器上,导入数据库,这里我导入到test数据库中

mysql -u username -p test < xxl-job.sql

在这里插入图片描述

使用navicat查看,主库里test数据库里面有xxl-job相关的表了,同样的从库也同步过去了。

在这里插入图片描述

应用

一般来说,MySQL主从可以有以下两个应用。

(1)数据备份

就是啥也不做,从库仅做数据备份,另外当主库宕机时,可以修改配置文件,改为从库。但这又会有一个问题,主从库的数据一致性怎么保证。会不会出现一种情况,主库写入的数据,还没来得及同步到从库,然后宕机了。这段时间内的数据是从库中没有的。切换到从库,从库跑了一段时间后又有数据写入。结果就是,主从库之间各自有对方没有的数据,事后怎么同步数据又是问题。

总之,MySQL主从用来做数据备份是OK的,但如果用来做灾备,需要考虑以下问题:

  • 切换从库后,数据一致性怎么保证(看主库日志,看是怎么时候宕机的,这个时间段有没有会话连接,对数据库操作量大不大)

  • 缺失的数据对系统的影响大不大(经验之谈,可能主库宕机,但binlog都推送给从库了,主从库数据一致,完全没影响)

  • 事后主从数据库之间的数据同步怎么搞(能否将各自的数据导出来,各自导入执行一遍或者导出来做比对,针对缺失的数据做导入)

(2)读写分离

读写分离,顾名思义,就是将对数据库的操作分开,读操作分给从库,主库压力会小很多。在博主前面介绍的主从搭建中,有分别对主从配置文件添加下面这行配置:

(主数据库)

# 是否只读,1 代表只读,0代表读写,主数据库需要读写,设置0
read-only=0

(从数据库)

# 是否只读,1 代表只读,0代表读写,从数据库仅读,设置1
read-only=1

但在我实际操作来看,似乎没有生效。从数据库该添加数据还是能添加数据,真正做到读写分离,需要从MySQL账户入手,设置从库的MySQL账户仅有查询操作,然后项目里配置的就是这个账户才行。相关SQL如下:

MySQL权限相关命令

# 创建admin用户
create user 'admin'@'%' identified by 'MySQL@3306';# 赋予该账户select权限
GRANT SELECT ON *.* TO 'admin'@'%';# 刷新
flush privileges;

创建一个仅有select权限的用户,用户名为admin;

在这里插入图片描述

其他命令

# 移除用户的所有权限
REVOKE ALL PRIVILEGES ON *.* FROM 'admin'@'%';
# 根据用户名查询主机设置
select user,host from mysql.user where user = 'admin';

写入测试,提示错误

在这里插入图片描述

读写分离也需要考虑数据一致性问题,为此我们可以考虑如下方案:

  • 当读取返回结果为空时,再读一遍主库;

  • 写操作紧跟着的读操作,访问主库;

  • 核心业务读写主库,非核心业务读从库;

dynamic-datasource组件

该组件提供了多数据源场景的一些功能,包括切换数据源、多数据源事务、多从库的负载均衡策略等,以下介绍一下这个组件的基础功能;

(0)准备工作

首先创建一个Spring Boot项目,文件如下:

(pom.xml文件)

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"><modelVersion>4.0.0</modelVersion><parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.7.12</version><relativePath/></parent><groupId>com.hezy</groupId><artifactId>multiple_databases_demo</artifactId><version>1.0-SNAPSHOT</version><name>Archetype - multiple_databases_demo</name><url>http://maven.apache.org</url><dependencies><!--web--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><!--lombok--><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId></dependency><!--dynamic-datasource--><dependency><groupId>com.baomidou</groupId><artifactId>dynamic-datasource-spring-boot-starter</artifactId><version>3.5.1</version></dependency><!--druid--><dependency><groupId>com.alibaba</groupId><artifactId>druid-spring-boot-starter</artifactId><version>1.2.8</version></dependency><!--mybatis--><dependency><groupId>org.mybatis.spring.boot</groupId><artifactId>mybatis-spring-boot-starter</artifactId><version>2.2.2</version></dependency><!--msyql驱动--><dependency><groupId>com.mysql</groupId><artifactId>mysql-connector-j</artifactId><scope>runtime</scope></dependency></dependencies>
</project>

(创建两个接口,一个读,一个写)

@RestController
@RequestMapping("/user")
public class UserController {@Autowiredprivate UserService userService;@GetMapping("/{id}")public User getUser(@PathVariable String id) {return userService.getUser(id);}@PostMapping("/add")public void addUser(@RequestBody User user) {userService.addUser(user);}
}

(1)切换数据库

使用dynamic-datasource组件切换数据库非常简单,首先配置文件里,配置多个数据源,如我搭建的是主从MySQL,则配置如下:

server:port: 8080# 1.数据源的配置
spring:datasource:dynamic:datasource:master:url: jdbc:mysql://主节点IP:3306/test?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=GMT%2B8username: adminpassword: MySQL@3306driver-class-name: com.mysql.cj.jdbc.Driverslave:url: jdbc:mysql://从节点IP:3306/test?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=GMT%2B8username: adminpassword: MySQL@3306driver-class-name: com.mysql.cj.jdbc.Driver# 2.mybatis配置
mybatis:configuration:# 显示SQL日志配置log-impl: org.apache.ibatis.logging.stdout.StdOutImpl# 驼峰命名配置map-underscore-to-camel-case: true# 设置mapper.xml文件所在的路径mapper-locations: classpath:mapper/*.xml

使用时,在对应的方法上加上@DS(数据源名称)即可,如下,读操作给从库(slave),写操作给主库(master)

import com.baomidou.dynamic.datasource.annotation.DS;
import com.hezy.pojo.User;
import org.apache.ibatis.annotations.Insert;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Select;@Mapper
public interface UserMapper {@DS("slave")@Select("select * from i_user where id = #{id}")User getUser(String id);@DS("master")@Insert("insert into i_user(id, username, password) values(#{id}, #{username}, #{password})")void addUser(User user);
}

(读操作,走从库)

在这里插入图片描述

(写操作,走主库)

在这里插入图片描述

在这里插入图片描述

更换一下,将写操作分给主库,

import com.baomidou.dynamic.datasource.annotation.DS;
import com.hezy.pojo.User;
import org.apache.ibatis.annotations.Insert;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Select;@Mapper
public interface UserMapper {@DS("master")@Select("select * from i_user where id = #{id}")User getUser(String id);@DS("slave")@Insert("insert into i_user(id, username, password) values(#{id}, #{username}, #{password})")void addUser(User user);
}

重启测试,读操作,没问题

在这里插入图片描述

写操作,报错

在这里插入图片描述

在这里插入图片描述

多数据源切换实现原理是AOP,官方推荐@DS注解加载Service实现类对应的方法上。

(2)数据库配置加密

使用该组件,可以实现对数据库配置的加密,让配置文件中数据库配置显示的是密文。实现如下:

    public static void main(String[] args) throws Exception {// 明文配置String password = "MySQL@3306";// 加密显示String encodePassword = CryptoUtils.encrypt(password);System.out.println(encodePassword);}

将下面这段密文复制下来;

在这里插入图片描述

在配置文件中,如下:

在这里插入图片描述

实现原理是,私钥加密,公钥解密。用以上方法实际上用的是组件自带的私公钥。

在这里插入图片描述

推荐使用下面的方法,随机生成私公钥;

    public static void main(String[] args) throws Exception {// 生成私公钥String[] arr = CryptoUtils.genKeyPair(512);System.out.println("privateKey:  " + arr[0]);System.out.println("publicKey:  " + arr[1]);// 使用私钥加密数据库相关配置System.out.println("username:  " + CryptoUtils.encrypt(arr[0], "admin"));System.out.println("password:  " + CryptoUtils.encrypt(arr[0], "MySQL@3306"));}

在这里插入图片描述

把上面两个配置复制到配置文件中,同时附带上public-key,如下:

spring:datasource:dynamic:datasource:master:url: jdbc:mysql://主库IP:3306/test?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=GMT%2B8username: ENC(oM2ceVnn3KOTEv9Ci4yI4QKwfaSzHZpb26SWQuxlgtcMtYpbr5HYK30TT+jtI+IOsZJHqSaWhhPPlfM40rnYrw==)password: ENC(TvstWlvbEKqPzJrek8fx3+Si6c6OeoiZVE7Njbf+fYwjqb/Tr3v0YevMfdG8FAB32U3xda5J7AdRhAcWA0A1rg==)driver-class-name: com.mysql.cj.jdbc.Driverslave:url: jdbc:mysql://从库IP:3306/test?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=GMT%2B8username: ENC(oM2ceVnn3KOTEv9Ci4yI4QKwfaSzHZpb26SWQuxlgtcMtYpbr5HYK30TT+jtI+IOsZJHqSaWhhPPlfM40rnYrw==)password: ENC(TvstWlvbEKqPzJrek8fx3+Si6c6OeoiZVE7Njbf+fYwjqb/Tr3v0YevMfdG8FAB32U3xda5J7AdRhAcWA0A1rg==)driver-class-name: com.mysql.cj.jdbc.Driverpublic-key: MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBAL2RM3JnCjtTogh3LrwN/meyWaWpSGCn7CaYRo6spLaeAhcguhi3XQrfLa7W4LQrJTENm+yA52YJfk+mWtjyl0ECAwEAAQ==

如果你主从库是分开生成的,则在每个数据源里写各自的公钥配置,如果是一样的,如上,主从库用户名、密码一样,就在外层全局设置即可。

另外,提醒一点,用上面的方法每次都会生成新的私公钥,所以需要加密的数据库配置需要是同一次操作生成的,不能跑一遍把username、password加密了,后面感觉url也要加密,就单独把url加密,然后复制到配置里,这样启动时会报解密错误的。

(3)更多

dynamic-datasource组件更丰富的功能,参考官方文档:https://www.kancloud.cn/tracy5546/dynamic-datasource/2264611

总结

本文介绍了MySQL主从的应用,及应用时需要考虑的问题。

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

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

相关文章

CST Studio初级教程 一

本教程将详细介绍CST Studio Project创建。 新建Project 1. 点击New and Recent&#xff0c;然后点击New Template。 然后依据我们的仿真属类&#xff0c;在下图中做选择需要的模板。 如果做高频连接器信号完整性&#xff08;SI&#xff09;仿真&#xff0c;我们就选Microwaves…

数据结构之二叉搜索树底层实现洞若观火!

目录 题外话 正题 二叉搜索树 底层实现 二叉搜索树查找操作 查找操作思路 查找代码实现详解 二叉搜索树插入操作 插入操作思路 插入代码详解 二叉搜索树删除操作 删除操作思路 删除代码详解 小结 题外话 我的一切都是党给的,都是人民给的,都是家人们给的!! 十分感…

Docker的数据管理、网络通信和dockerfile

目录 一、Docker的数据管理 1. 数据卷 1.1 数据卷定义 1.2 数据卷配置 2. 数据卷容器 2.1 创建数据卷容器 2.2 使用--volume-from来挂载test1 二、端口映射 三、容器互联 1. 创建容器互联 ​编辑2. 进入test2测试&#xff08;ping 容器名/别名&#xff09; 四、Dock…

c++11详解

目录 1.列表初始化 2.声明 3.右值引用和移动语句 4. c11新的类功能 5. 可变参数模板 6.lambda表达式 7.包装器 8. 后言 1. 列表初始化 1.1 {}的初始化 (1) c98标准规定可以使用{}对数组以及结构体进行统一的列表初始化. struct Point {int _x;int _y; };int main() {in…

【Unity】shader中参数传递

1、前言 unity shader这个对于我来说是真的有点难&#xff0c;今天这篇文章主要还是总结下最近学习到的一些东西&#xff0c;避免过段时间忘记了&#xff0c;可能有不对&#xff0c;欢迎留言纠正。 2、参数传递的两种方式 2.1 语义传递 语义传递这个相对来说是简单的 shad…

数组模拟几种基本的数据结构

文章目录 数组模拟单链表数组模拟双链表数组实现栈数组模拟队列总结 数组模拟单链表 首先类比结构体存储单链表&#xff0c;我们需要一个存放下一个节点下标的数组&#xff0c;还需要一个存储当前节点的值的数组&#xff0c;其次就是一个int类型的索引&#xff0c;这个索引指向…

Python 实现视频去抖动技术

&#x1f47d;发现宝藏 前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。【点击进入巨牛的人工智能学习网站】。 视频去抖动是视频处理中的一项重要技术&#xff0c;它可以有效地减少视频中由于相机震动或手…

嵌入式开发学习--进程、线程

什么是进程 进程和程序的区别 概念 程序&#xff1a;编译好的可执行文件&#xff0c;存放在磁盘上的指令和数据的有序集合&#xff08;文件&#xff09;&#xff0c;程序是静态的&#xff0c;没有任何执行的概念。 进程&#xff1a;一个独立的可调度的任务&#xff0c;执行一…

恶补《操作系统》3_1——王道学习笔记

3内存管理 3.1_1 内存的基础知识 1、什么是内存&#xff0c;作用 &#xff08;1&#xff09;内存&#xff1a;内存用来存放数据。程序执行前需要先放到内存中才能被CPU处理――缓和CPU与硬盘之间的速度矛盾。 &#xff08;2&#xff09;内存存储单元&#xff1a;每个地址对应…

AIGC技术的发展现状和未来趋势

AIGC&#xff08;人工智能生成内容&#xff09;技术是指利用人工智能算法自动生成文本、图像、音频、视频等各类内容的技术。随着深度学习等技术的快速发展&#xff0c;AIGC技术在最近几年取得了显著进步&#xff0c;并在多个领域展现出巨大的潜力。 ​ 编辑 发展现状&#x…

ARM功耗管理背景及挑战

安全之安全(security)博客目录导读

服务器网站漏洞怎么修复

服务器网站漏洞的修复是一个关键且复杂的过程&#xff0c;涉及到多个层面的安全加固。以下是一个关于如何修复服务器网站漏洞的详细指南。安全狗专业做服务器安全&#xff0c;有任何服务器安全问题都可以找安全狗哦. ​一、识别和分析漏洞 首先&#xff0c;要确定服务器网站存在…

Linux下的基本指令(1)

嗨喽大家好呀&#xff01;今天阿鑫给大家带来Linux下的基本指令&#xff08;1&#xff09;&#xff0c;下面让我们一起进入Linux的学习吧&#xff01; Linux下的基本指令 ls 指令pwd命令cd 指令touch指令mkdir指令(重要)rmdir指令 && rm 指令(重要)man指令(重要)cp指…

基于 NXP iMX8MM 测试 Secure Boot 功能

By Toradex秦海 1). 简介 嵌入式设备对于网络安全的要求越来越高&#xff0c;而 Secure boot就是其中重要的一部分。 NXP i.MX8MM/i.MX8MP 处理器基于 HABv4 特性来提供 Secure boot 启动过程中的 Chain of Trust&#xff1b; HABv4 是基于公共密钥加密 (Public Key Cryptogr…

C语言进阶:指针的进阶(上)

首先 在学习新知识之前 我们先来回顾下之前的学习的内容 1 指针是个变量 用来存放地址 地址唯一标识的一块内存空间 2 指针的大小是固定的4/8字节&#xff08;32位平台/64位平台&#xff09; 3 指针有类型的 指针的类型决定了两点 一个是指针操作的权限以及整数的步长 4 指针的…

神经网络项目:全连接网络和卷积网络实现水果三分类项目

水果三分类项目 Git源码&#xff1a;传送门 水果种类&#xff1a;草莓、树莓、桑葚 0&#xff1a;草莓 strawberry1&#xff1a;树莓 raspberry2&#xff1a;桑葚 mulberry 项目设计 获取数据 spider.py数据清洗 cleaner.py自定义数据集 dataset.py网络构建 net.py训练模型 t…

git工具简单使用

文章目录 git上传克隆README.gitignore常用指令冲突 git 进行版本控制的版本控制器。安装git yum install -y git 配置git git config --global user.email "youexample.com" 告诉git你的邮箱是什么&#xff1f;最好输入你的gitee的注册邮箱git config --global …

人工智能(pytorch)搭建模型28-基于Transformer的端到端目标检测DETR模型的实际应用,DETR的原理与结构

大家好&#xff0c;我是微学AI&#xff0c;今天给大家介绍一下人工智能(pytorch)搭建模型28-基于Transformer的端到端目标检测DETR模型的实际应用&#xff0c;DETR的原理与结构。DETR&#xff08;Detected Transformers&#xff09;是一种基于Transformer的端到端目标检测模型&…

把 KubeBlocks 跑在 Kata 上,真的可行吗?

背景 容器的安全性一直是广受关注的话题。这个领域也产生了很多不错的开源项目。Kata就是其中之一。 Kata Containers&#xff08;简称 Kata&#xff09;是一种开源项目&#xff0c;它提供了一种安全而高性能的容器运行时环境。Kata Containers 利用虚拟化技术&#xff08;通常…

【算法刷题 | 贪心算法03】4.25(最大子数组和、买卖股票的最佳时机|| )

文章目录 4.最大子数组和4.1题目4.2解法一&#xff1a;暴力4.2.1暴力思路4.2.2代码实现 4.3解法二&#xff1a;贪心4.3.1贪心思路4.3.2代码实现 5.买卖股票的最佳时机||5.1题目5.2解法&#xff1a;贪心5.2.1贪心思路5.2.2代码实现 4.最大子数组和 4.1题目 给你一个整数数组 n…