linux下搭建MySQL8.0.25一主一从

一、主从复制概述

1.1、概述

主从复制是指将主数据库的 DDL 和 DML 操作通过二进制日志传到从库服务器中,然后在从库上对这些日志重新执行(也叫重做),从而使得从库和主库的数据保持同步。

MySQL支持一台主库同时向多台从库进行复制, 从库同时也可以作为其他从服务器的主库,实现链状复制。

image-20240819221120685

1.2、原理

MySQL主从复制的核心就是 二进制日志,具体的过程如下:

image-20240819221812952

复制三步骤

步骤1: Master 将写操作记录到二进制日志( binlog )。

步骤2: Slave 将 Master 的binary log events拷贝到它的中继日志( relay log );

步骤3: Slave 重做中继日志中的事件,将改变应用到自己的数据库中。 MySQL复制是异步的且串行化的,而且重启后从 接入点 开始复制。

搭建主从复制的作用:

第1个作用:读写分离。

第2个作用就是数据备份。

第3个作用是具有高可用性。

复制的问题

复制的最大问题: 延时

1.3、二进制日志

二进制日志(BINLOG)记录了所有的 DDL(数据定义语言)语句和 DML(数据操纵语言)语句,但不包括数据查询(SELECT、SHOW)语句。

作用:①. 灾难时的数据恢复;②. MySQL的主从复制。在MySQL8版本中,默认二进制日志是开启着的,涉及到的参数如下:

show variables like '%log_bin%';

image-20240819222217281

1.4、中继日志(relay log)

中继日志只在主从服务器架构的从服务器上存在。从服务器为了与主服务器保持一致,要从主服务器读取二进制日志的内容,并且把读取到的信息写入本地的日志文件中,这个从服务器本地的日志文件就叫中继日志。然后,从服务器读取中继日志,并根据中继日志的内容对从服务器的数据进行更新,完成主从服务器的数据同步。

搭建好主从服务器之后,中继日志默认会保存在从服务器的数据目录下。文件名的格式是: 从服务器名 -relay-bin.序号。中继日志还有一个索引文件: 从服务器名 -relaybin.index ,用来定位当前正在使用的中继日志。

1.5、关于MySQL中的日志

我们来看看官网:

https://dev.mysql.com/doc/refman/8.0/en/server-logs.html

image-20240819223258326

MySQL有不同类型的日志文件,用来存储不同类型的日志,分为二进制日志、错误日志、通用查询日志和慢查询日志,这也是常用的4种。MySQL 8又新增两种支持的日志: 中继日志和数据定义语句日志。使用这些日志文件,可以查看MySQL内部发生的事情。这6类日志分别为:

  1. 慢查询日志:记录所有执行时间超过long_query_time的所有查询,方便我们对查询进行优化。
  2. 通用查询日志:记录所有连接的起始时间和终止时间,以及连接发送给数据库服务器的所有指令,对我们复原操作的实际场景、发现问题,甚至是对数据库操作的审计都有很大的帮助。
  3. 错误日志:记录MySQL服务的启动、运行或停止MySQL服务时出现的问题,方便我们了解服务器的状态,从而对服务器进行维护。
  4. 二进制日志:记录所有更改数据的语句,可以用于主从服务器之间的数据同步,以及服务器遇到故障时数据的无损失恢复。
  5. 中继日志:用于主从服务器架构中,从服务器用来存放主服务器二进制日志内容的一个中间文件。从服务器通过读取中继日志的内容,来同步主服务器上的操作。
  6. 数据定义语句日志:记录数据定义语句执行的元数据操作。

除二进制日志外,其他日志都是文本文件。默认情况下,所有日志创建于MySQL数据目录中。

二、一主一从架构

2.1、环境准备

两台已经已经安装好MySQL:8.0.25的Linux服务器。注意,我们为了避免不必要的一些麻烦,请将主从服务器数据库的版本保持一致

image-20240819183133630

image-20240819183139610

修改UUID,不然在某一一些的场景下会报错:

vim /var/lib/mysql/auto.cnf

image-20240819184134255

image-20240819184206040

systemctl restart mysqld

image-20240819184452311

两台服务器都已经关闭掉了防火墙:

systemctl status firewalld.service

image-20240819183424147

image-20240819183436382

2.2、主机的配置文件

vim /etc/my.cnf

image-20240819185337963

主从所有配置项都配置在 [mysqld] 节点下,且都是小写字母。具体参数配置如下:

#[必须]主服务器唯一ID
server-id=1
#[必须]启用二进制日志,指名路径。比如:自己本地的路径/log/mysqlbin
log-bin=master-bin

image-20240819185500521

image-20240819185543073

2.3、从机配置文件

vim /etc/my.cnf
server-id=2

image-20240819190907545

2.4、重启主从服务器

systemctl restart mysqld

image-20240819191059432

image-20240819191105644

2.5、主机:建立账户并授权

CREATE USER 'slave1'@'%' IDENTIFIED BY '123456';
GRANT REPLICATION SLAVE ON *.* TO 'slave1'@'%';
ALTER USER 'slave1'@'%' IDENTIFIED WITH mysql_native_password BY '123456';
flush privileges;

image-20240819191434819

查询Master的状态,并记录下File和Position的值。

show master status;
+-------------------+----------+--------------+------------------+-------------------+
| File              | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+-------------------+----------+--------------+------------------+-------------------+
| master-bin.000001 |     1139 |              |                  |                   |
+-------------------+----------+--------------+------------------+-------------------+

image-20240819191509855

注意:执行完此步骤后不要再操作主服务器MySQL,防止主服务器状态值变化。

2.6、从机:配置需要复制的主机

步骤1:从机上复制主机的命令

CHANGE MASTER TO
MASTER_HOST='主机的IP地址',
MASTER_USER='主机用户名',
MASTER_PASSWORD='主机用户名的密码',
MASTER_LOG_FILE='mysql-bin.具体数字',
MASTER_LOG_POS=具体值;
CHANGE MASTER TO
MASTER_HOST='192.168.200.129',
MASTER_USER='slave1',
MASTER_PASSWORD='123456',
MASTER_LOG_FILE='master-bin.000001',
MASTER_LOG_POS=1139;
CHANGE MASTER TO MASTER_HOST='192.168.200.129', MASTER_USER='slave1', MASTER_PASSWORD='123456', MASTER_LOG_FILE='master-bin.000001', MASTER_LOG_POS=1139;

image-20240819192301168

步骤2:启动slave同步

START SLAVE;

image-20240819192438908

查看同步状态:

SHOW SLAVE STATUS\G;

image-20240819194144289

上面两个参数都是Yes,则说明主从配置成功!

2.7、测试

主机新建库、新建表、insert记录,从机复制:

CREATE DATABASE master_slave;
use master_slave;
CREATE TABLE mytbl(id INT,NAME VARCHAR(16));
INSERT INTO mytbl VALUES(1, 'zhang3');
INSERT INTO mytbl VALUES(2,'lisi');

从机测试:

use master_slave;
select * from mytbl;

image-20240819195132557

三、读写分离

介绍:读写分离,简单地说是把对数据库的读和写操作分开,以对应不同的数据库服务器。主数据库提供写操作,从数据库提供读操作,这样能有效地减轻单台数据库的压力。

在主从架构的配置中,如果想要采取读写分离的策略,我们可以 自己编写程序 ,也可以通过 第三方的中间件

来实现。

  • 自己编写程序的好处就在于比较自主,我们可以自己判断哪些查询在从库上来执行,针对实时性要求高的需求,我们还可以考虑哪些查询可以在主库上执行。同时,程序直接连接数据库,减少了中间件层,相当于减少了性能损耗。

  • 采用中间件的方法有很明显的优势, 功能强大 , 使用简单 。但因为在客户端和数据库之间增加了中间件层会有一些 性能损耗 ,同时商业中间件也是有使用成本的。我们也可以考虑采取一些优秀的开源工具。

四、实现一主一从读写分离

CREATE TABLE `t_user` (
  `user_id` int NOT NULL COMMENT '用户id',
  `user_name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin DEFAULT NULL COMMENT '用户名称',
  PRIMARY KEY (`user_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin;

创建实体类:

package cn.rwdemo.entity;

import lombok.Data;

@Data
public class UserEntity {

    private Integer userId;

    private String userName;

}

创建Mapper类:

package cn.rwdemo.mapper;

import cn.rwdemo.entity.UserEntity;
import org.apache.ibatis.annotations.*;

@Mapper
public interface UserMapper {

    @Insert("insert into t_user(user_id,user_name) values(#{userId},#{userName})")
    void insertUserInfo(UserEntity userEntity);

    @Select("select * from t_user where user_id=#{userId}")
    @Results({
            @Result(property = "userId", column = "user_id"),
            @Result(property = "userName", column = "user_name")
    })
    UserEntity getUserInfo(Integer userId);

}

创建配置文件:

spring:
  application:
    name: rw_demo
  shardingsphere:
    datasource:
      master:
        driver-class-name: com.mysql.cj.jdbc.Driver
        password: 123456@root
        type: com.alibaba.druid.pool.DruidDataSource
        url: jdbc:mysql://192.168.200.129:3306/master_slave?useUnicode=true&characterEncoding=utf-8&autoReconnect=true&zeroDateTimeBehavior=convertToNull&allowMultiQueries=true&useSSL=false
        username: root
      names: master,slave
      slave:
        driver-class-name: com.mysql.cj.jdbc.Driver
        password: 123456@root
        type: com.alibaba.druid.pool.DruidDataSource
        url: jdbc:mysql://192.168.200.130:3306/master_slave?useUnicode=true&characterEncoding=utf-8&autoReconnect=true&zeroDateTimeBehavior=convertToNull&allowMultiQueries=true&useSSL=false
        username: root
    masterslave:
      master-data-source-name: master
      name: ms
      slave-data-source-names: slave
    props:
      sql:
        show: true

测试:

package cn.rwdemo;

import cn.rwdemo.entity.UserEntity;
import cn.rwdemo.mapper.UserMapper;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;

import javax.annotation.Resource;

@SpringBootTest
public class UserTests {

    @Resource
    private UserMapper userMapper;

    @Test
    public void insertUserInfo() {
        for (int i = 1; i <= 10; i++) {
            UserEntity userEntity = new UserEntity();
            userEntity.setUserId(i);
            userEntity.setUserName("user" + i);
            userMapper.insertUserInfo(userEntity);
        }
    }
	
    @Test
    public void getUserInfo() {
        System.out.println(userMapper.getUserInfo(1));
    }
}

image-20240819220409796

五、开发环境说明

VM虚拟机:

image-20240819134329080

 cat /etc/redhat-release

image-20240819134447365

cat /proc/version

image-20240819134546245

查看防火墙状态:

systemctl status firewalld.service

image-20240819134745185

关闭命令:

systemctl stop firewalld.service

开机禁用防火墙自启命令 :

systemctl disable firewalld.service

是否有mysql残留

rpm -qa | grep -i mysql 
systemctl status mysqld.service

image-20240821084635013

代码:

https://github.com/shixiaochuangjob/markdownfile/tree/main/20240821

image-20240821085040387

  • 9
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值