Java开发 - MySQL主从复制初体验

news2024/11/16 23:45:07

前言

前面已经学到了很多知识,大部分也都是偏向于应用方面,在应用实战这条路上,博主一直觉得只有实战才是学习中最快的方式。今天带来主从复制给大家,在刚刚开始动手写的时候,才想到似乎忽略了一些重要的东西,不过还好,既然想到了,就会在本文中体现出来,争取让大家学完之后明白主从复制的原理和怎么去做主从复制。

什么是主从复制

MySQL主从复制是一个异步的复制过程,底层是基于Mysql数据库自带的 二进制日志 功能。就是一台或多台MySQL数据库(slave,即从库)从另一台MySQL数据库(master,即主库)进行日志的复制,然后再解析日志并应用到自身,最终实现 从库 的数据和 主库 的数据保持一致。MySQL主从复制是MySQL数据库自带功能,无需借助第三方工具。

​二进制日志(BINLOG)记录了所有的 DDL(数据定义语言)语句和 DML(数据操纵语言)语句,但是不包括数据查询语句。此日志对于灾难时的数据恢复起着极其重要的作用,MySQL的主从复制, 就是通过该binlog实现的。默认MySQL是未开启该日志的。

主从复制分为三步完成:

  • MySQL master 将数据变更的SQL语句写入二进制日志( binary log)
  • slave将master的binary log拷贝到它的中继日志(relay log),说是拷贝,其实是读取过来,也可以理解成拷贝,内容拷贝
  • slave读取中继日志中的事件,将数据变更反映它自己的数据库中

Docker模拟多服务器准备

博主没有办法在真正的两台云端服务器上给大家做演示,所以就在本地给大家模拟一下做法,有虚拟机的使用虚拟机复制出来一个使用,没有虚拟机的可以使用Docker来模拟。

使用Docker模拟时,需要创建两个mysql的容器:

Master(主):

docker run -p 3306:3306 --name mysql -e MYSQL_ROOT_PASSWORD=123456 -d mysql

Slave(从):

docker run -p 3309:3306 --name mysql-slave -e MYSQL_ROOT_PASSWORD=123456 -d mysql

博主没有指定版本,因为博主Image内已经存在一个最新的版本,如果使用的版本略低,可手动指定: 

docker run -p 3306:3306 --name mysql -e MYSQL_ROOT_PASSWORD=123456 -d mysql:x.x.x

这里需要说明一下端口,由于非生产环境,本地模拟时,端口需要映射,不能全都用3306,所以slave中映射了3309,否则容器启动会因为端口冲突报错。

此时在Docker内,已经有两个运行中的mysql了:

docker ps可以查看运行中的容器:

配置数据库主从

配置Master

docker exec -it 8e46c78ba828 /bin/bash

输入上面的命令,进入master容器内部,8e46c78ba828是容器id,也可以使用容器名mysql进入:

docker exec -it mysql /bin/bash

输入:

cd /etc/mysql

进入mysql的配置文件目录下,对my.cnf进行编辑:

vi my.cnf

正常是会报错的,会提示:

bash: vi: command not found

需要我们在docker内安装vim,这个我们在前面的博客中有提到,为了方便,此处再写一下解决步骤:

输入

apt-get install vim

提示:

Reading package lists... Done

Building dependency tree       

Reading state information... Done

E: Unable to locate package vim

输入

apt-get update

 

然后输入

apt-get install vim

等待vim安装完成即可。

注意里面会有一个提示,输入Y。安装过程可能会有点慢,稍安勿躁。

安装完成,此时再输入以下命令:

vi my.cnf

在最下面增加配置:

log-bin=mysql-bin   #[必须]启用二进制日志
server-id=100       #[必须]服务器唯一ID(唯一即可)

然后退出保存即可。下面要重启mysql服务,让配置生效:

你可以选择使用命令行

service mysql restart

甚至你还需要重启mysql容器:

docker start mysql

但博主这里偷懒,直接在docker内部重启mysql容器,哈哈!!!

特别注意:你目前所在的文件夹是:root@8e46c78ba828:/etc/mysql

你需要通过两次cd ..回到顶端目录,然后使用:

mysql -uroot -pxxxx

u后面跟账号,p后面跟密码,登录到mysql内:

以上启动sql的命令运行在root@8e46c78ba828:/etc/mysql目录下是不行的,需要你退出docker容器运行才可以,这个是常识哈,我当大家都知道的。

下一步在Master数据库创建数据同步用户,授予slave的访问用户,比如slave,授权 REPLICATION SLAVE权限和REPLICATION CLIENT权限,用于在主从库之间同步数据,分两步完成:

CREATE USER 'slave'@'%' IDENTIFIED BY '123456';

GRANT REPLICATION SLAVE, REPLICATION CLIENT ON *.* TO 'slave'@'%';

到这里,主库的配置就算是完成了,你可以输入:

show master status;

 来查看主库的状态:此时主库什么都不要动,这里的File和Position我们后面有用。

配置Salva

接下来我们来配置从库,整体步骤和主库差不多,但是为了让大家不出错,这里还是一步步带着大家操作。

首先新开一个终端窗口:

docker exec -it e2476006aeb4 /bin/bash

输入上面的命令,进入slave容器内部,e2476006aeb4是容器id,也可以使用容器名mysql-slave进入:

docker exec -it mysql-slave /bin/bash

输入:

cd /etc/mysql

进入mysql的配置文件目录下,对my.cnf进行编辑:

vi my.cnf

不出意外的又报错了,还是和主库一样,这是因为两个容器互不相关,所以还需要在此容器安装vim,步骤一样,大家照着上面来。

安装完成,此时再输入以下命令:

vi my.cnf

在最下面增加配置:

log-bin=mysql-bin   #[必须]启用二进制日志
server-id=101       #[必须]服务器唯一ID(唯一即可)

然后退出保存即可。下面要重启mysql服务和容器,让配置生效。这里注意,id变了,主库是100,此处是101。

关联主从数据库

进入从数据库中,登陆了从数据库,执行以下命令,设置主库地址及同步位置

change master to master_host='172.17.0.2',master_user='slave',master_password='123456',master_log_file='mysql-bin.000001',master_log_pos=721;

来解释下这里的数据来源。

ip通过以下命令获得:

docker inspect --format='{{.NetworkSettings.IPAddress}}' 容器id/容器名

master_log_file='mysql-bin.000001',master_log_pos=721;还记得我们通过show master status获得的表格吗?

看看数据对不对的上。

然后执行:

start slave;

为了验证主从关联是否完成,在从库Slave中输入以下命令:

show slave status \G;

\G是因为让显示是一行一行的,否则表格太长,无法直观的看到想要的信息。 

查看SlaveIORunning 和 SlaveSQLRunning 都是Yes,说明主从复制已经开启。

 此时,SlaveIORunning一直是Connecting,则说明主从复制一直处于连接状态,查看错误:

error connecting to master 'slave@172.17.0.2:3306' - retry-time: 60 retries: 1 message: Authentication plugin 'caching_sha2_password' reported error: Authentication requires secure connection.

提示我们授权有问题,详情可查看此篇博客:Authentication plugin 'caching_sha2_password' reported error:Authentication..我们采用这篇博客说的第三种办法去解决这个问题,避免使用caching_sha2_password插件,所以我们需要重新创建一个用户:

CREATE USER 'repl'@'%' IDENTIFIED WITH 'mysql_native_password' BY '123456';

前面做的时候没有做远程授权,也会报错,所以这里加上了授权远程访问的权限: 

GRANT ALL PRIVILEGES ON *.* TO 'repl'@'%'  WITH GRANT OPTION;

我们查看下数据库中用户的列表:

一定要有远程访问的权限才可以,Grant_priv就是,虽然slave用户也授权了远程权限,但是使用了caching_sha2_password,也不可用,所以才新建了repl用户。接着,我们要查看主库的状态,重新获取关键信息:

show master status;

查看主库状态:

发现原来的 721变了,File的文件后缀名也变为02了。这里要注意,一定要用新的,到这里,主库千万不要再去动了,否则会出别的问题。

下面在从库重新关联主从,在这之前,需要先停止slave:

stop slave;
reset slave;

然后执行此命令关联:

change master to master_host='172.17.0.2',master_user='repl',master_password='123456',master_log_file='mysql-bin.000002',master_log_pos=2819;

注意参数改为2819,接着启动slave:

start slave;

 查看关联状态:

show slave status \G;

看到两个YES,就说明主从已经配置好了。  

关于mysql的授权相关命令,推荐一篇博客给大家:MySql 授权命令grant

测试主从

我们在使用Docker内部IP访问数据库的时候发现无法连接,这是因为这个IP是docker内部id,博主查了很多资料,都没有很好的解决这个问题,但是,也看到了一些说法:

如何访问docker容器ip-Docker-PHP中文网

根据这篇博客,最终得到的结论就是,虽然无法直接访问docker内部ip,但是我们已经通过端口映射到了localhost的端口上,所以,可以把docker内部ip地址换成主机地址,也可以直接用localhost,port使用映射的端口就可以。

还有另一篇博客:

 解决docker宿主机不能访问容器的问题_docker宿主机访问不到容器 

这篇博客提出在创建容器的时候,容器与宿主机共享同一个网卡,不过博主没有重新创建容器,有兴趣的小伙伴自行尝试。 

此时我们通过localhost链接主从数据库,由于主数据库源本来就存在其他的数据库,从库是新的,连接上之后,完全没有问题,俩数据库绝对是完全不一样的,我们使用localhost的做法也是正确的,这位我们测试主从提供了良好的环境。

下面开始测试,在主数据库创建数据库,并创建新表:

create database if not exists master_slave character set utf8;
use master_slave;
CREATE TABLE user (
            id bigint(20) primary key auto_increment,
            username varchar(32) not null,
            password  varchar(32) not null,
            age int(3) not null ,
            phone varchar(32) not null
)

 此时用户表已经创建完毕,我们去从库看一下这个表有没有被创建出来:

从库里面已经出现了数据库和用户表,非常棒,主从完美啊,我们在主库用户表添加点数据看看: 

insert into user value(null ,'codingfire','123456',20,'13812345678');

查看主库表:

用户信息已经插入,切换到从库查看:

从库也有了,主从复制测试成功。删除修改大家可以自行测试。 

注意:细心点,你会发现页面左上角的数据库连接对象是不一样的,所以这里连接docker使用localhost是完全没有问题的。另外,如果docker异常关机等,导致同步的游标出现错乱,需要重新配置日志游标:

stop slave;
change master to master_log_file='mysql-bin.00000x', master_log_pos=xxxx;
start slave;

结语

总的来说,mysql的主从还是没那么复杂的,没有代码操作,全都是配置,在真实的服务器上,配置也基本都是这样,这里学会了,真实的服务器也不在话下。虽然主从复制写完了,但是关于主从的只是只是还没有结束,因为还没在项目中引入主从的使用,下一篇,我们将学习主从在项目中的使用——读写分离。觉得不错,就给博主个赞吧。

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

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

相关文章

面试篇-揭开Spring Bean加载的神秘面纱

SpringBean加载完整过程 启动spring容器(创建beanfactory)->加载配置(注解、xml)->实例化bean(执行构造方法)->注入依赖->初始化bean(设置属性值)->使用->销毁 解析和读取 XML 配置文件或注解配置类&#xff0…

Linux嵌入式学习之Ubuntu入门(五)汇编语法学习

系列文章目录 一、Linux嵌入式学习之Ubuntu入门(一)基本命令、软件安装及文件结构 二、Linux嵌入式学习之Ubuntu入门(二)磁盘文件介绍及分区、格式化等 三、Linux嵌入式学习之Ubuntu入门(三)用户、用户组…

synchronized原理、偏向锁、轻量级锁、重量级锁、锁升级

文章目录Synchronized概念自增自减字节码指令临界区竞态条件基本使用原理查看synchronized的字节码指令序列Monitor对象的内存布局Mark Word是如何记录锁状态的偏向锁什么是偏向锁偏向锁延迟偏向偏向锁状态跟踪偏向锁撤销之调用对象HashCode偏向锁撤销之调用wait/notify轻量级锁…

Qt Quick - Drawer

Qt Quick - Drawer使用总结一、概述二、使用1、基础使用2、特点空间运行3、与内容转换相互挤占一、概述 Drawer提供了一个基于滑动的侧边面板,类似于经常在触控界面中使用的侧边面板,为导航提供了一个位置。 二、使用 1、基础使用 抽屉可以放置在内…

springcloud深度探索

中文官方文档:project - Spring Cloud Config - 《Spring Cloud中文文档》 - 书栈网 BookStackSpring Cloud ConfigFeaturesQuick StartSample Projects Spring Cloud为开发人员提供了工具,用以快速的在分布式系统中建立一些通用方案(例如配…

CDP思科发现协议解析及C/C++代码实现

通常,大多数网络都有几个路由器或交换机,为了便于网络管理,使用网络图或网络图来告诉网络中存在什么类型的设备,以及所有设备如何相互连接,使用的IP地址以及它们属于哪个VLAN的信息。 CDP是一种专有的第二层思科网络协…

Table Transformer做表格检测和识别实践

计算机视觉方面的三大顶级会议:ICCV,CVPR,ECCV.统称ICE CVPR 2022文档图像分析与识别相关论文26篇汇集简介 论文: PubTables-1M: Towards comprehensive table extraction from unstructured documents是发表于CVPR上的一篇论文 作者发布了两个模型&…

22级ACM 4.16 周赛 题解

这场能题解写的感觉没多少其实(真的不是因为懒),既然有人想要题解,那么就随便写一下吧,其实大部分的题都有人写出来,感觉这场真的不需要。 A 题 题解 Count Interval AtCoder - abc233_d_霾まる的博客-CS…

AI绘画王炸功能Control Net安装教程

原文:AI绘画王炸功能Control Net安装教程 - 知乎 AI绘画,最近两大王炸功能出圈了。 一个就是超真实超细节的美女图片,已经快和照片无异了,甚至有人用AI绘画的“女仆照片”开始招募游艇会了,具体教程可以查看Lora这篇…

一键生成元宇宙 AI又杀疯了

人类十几年的进步水平,AI用几个月就能轻易实现。在展示了超强的文本对话能力和一键生图功能后,AI大模型不打算停下,开始挑战搭建3D空间这一更高难度的动作。 这次,Facebook母公司Meta想当一把主导者。几天前,它的首席…

185-二35

Java185-二35单列集合顶层接口collection迭代器增强forlambda表达式list特有方法遍历数据结构数组Linkedlist集合泛型类,泛型方法,泛型结构泛型方法泛型的通配符泛型总结数据结构数据结构(二叉树)前序遍历数据结构(二叉…

crm系统有哪些?具体的功能有哪些?

市面上的CRM系统有很多,例如简道云、销售易、salesforce、纷享销客、SugarCRM等等,这些都是比较知名的,前面也有写过很多关于CRM选型的内容,大家可以点进我的主页翻阅一下。 那么,CRM具体的功能有哪些?下面…

计算机网络 - UDP协议 与 TCP协议可靠性(传输层)

前言 本篇介绍UDP报文格式,认识UDP报文,介绍TCP报文格式,了解TCP可靠性的核心机制,TCP通信中三次握手与四次挥手;如有错误,请在评论区指正,让我们一起交流,共同进步! 文…

EDA基础概念

EDA基础概念EDA和CADCAD工具EDA工具EDA技术实现目标可编程逻辑器件简称PLD发展历程FPGA简介CPLD简介FPGA和CPLD区别是否需要同时学习FPGA和CPLDXilinx(赛灵思)公司介绍(AMD收购)开发工具Xilinx产品Altera(阿尔特拉&…

Qt关于QPainter绘制1px宽度图形带来的问题思考

前言 前段时间遇到这样一个问题,使用QPainter绘制直线的时候,设置了笔宽为1像素,但是绘制出来的线条却是2px宽度,而且设置的画笔颜色很明显是降低了透明度,不是最“纯正”的颜色。 当时就感觉非常奇怪,明明…

【FPGA实验1】FPGA点灯工程师养成记

对于FPGA几个与LED相关的实验(包括按键点灯、流水灯、呼吸灯等)的记录,方便日后查看。这世界上就又多了一个FPGA点灯工程师了😏 成为一个FPGA点灯工程师分三步:一、按键点灯1、按键点灯程序2、硬件实现二、流水灯1、流…

Vue2-黑马(二)

目录: (1)vue2-基础-属性绑定 (2)vue2-事件绑定 (3)vue2-双向绑定 (4)vue2-计算属性 (1)vue2-基础-属性绑定 属性与js数据绑定: …

react-router原理

前端路由的原理 自己来监听URL的改变,改变url,渲染不同的组件(页面),但是页面不要进行强制刷新(a元素不行)。 hash模式,localhost:3000/#/abc 优势就是兼容性更好,在老版IE中都可以运行缺点是…

DNS配置

TCP/IP提供了通过IP地址来连接到设备的功能,但对用户来讲,记住某台设备的IP地址是相当困难的,因此专门设计了一种字符串形式的主机命名机制,这些主机名与IP地址相对应。 在IP地址与主机名之间需要有一种转换和查询机制&#xff0c…

CANopen | 对象字典OD 06 - 创建对象字典变量,通过TPDO定时发送

文章目录一、前言二、实验目的三、对象字典OD四、TPDO1定时发送tx_Value变量一、前言 该笔记的程序: github 二、实验目的 CANopen从站有一个变量tx_Value,映射到TPDO1上。接着,CANopen从站每1S发送一次TPDO1,将tx_Value发送出去。 三、…