• ShardingSphere主从复制


    数据库主从复制配置:

    mysql主从复制从0到1
    docker启动多个mysql服务

    安装指定版本mysql

    sudo docker pull mysql:8.0.29

    主服务master-3307

    启动主服务3307

    docker run -d \
    -p 3307:3306 \
    -v /study/shardingsphere/mysql/master/conf:/etc/mysql/conf.d \
    -v /study/shardingsphere/mysql/master/data:/var/lib/mysql \
    -e MYSQL_ROOT_PASSWORD=123456 \
    --name dk-mysql-master \
    mysql:8.0.29
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    创建MySQL主服务器配置文件:
    默认情况下MySQL的binlog日志是自动开启的,可以通过如下配置定义一些可选配置

    vim /study/shardingsphere/mysql/master/conf/my.cnf

    配置如下内容

    [mysqld]
    # 服务器唯一id,默认值1
    server-id=1
    # 设置日志格式,默认值ROW
    binlog_format=STATEMENT
    # 二进制日志名,默认binlog
    # log-bin=binlog
    # 设置需要复制的数据库,默认复制全部数据库
    #binlog-do-db=mytestdb
    # 设置不需要复制的数据库
    #binlog-ignore-db=mysql
    #binlog-ignore-db=infomation_schema
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    binlog格式说明:

    • binlog_format=STATEMENT:日志记录的是主机数据库的写指令,性能高,但是now()之类的函数以及获取系统参数的操作会出现主从数据不同步的问题。
    • binlog_format=ROW(默认):日志记录的是主机数据库的写后的数据,批量操作时性能较差,解决now()或者 user()或者 @@hostname 等操作在主从机器上不一致的问题。
    • binlog_format=MIXED:是以上两种level的混合使用,有函数用ROW,没函数用STATEMENT,但是无法识别系统变量

    重启MySQL容器

    docker restart dk-mysql-master

    设置mysql容器在docker启动的时候启动

    docker update dk-mysql-master --restart=always

    使用命令行登录MySQL主服务器:

    #进入容器:env LANG=C.UTF-8 避免容器中显示中文乱码
    docker exec -it dk-mysql-master env LANG=C.UTF-8 /bin/bash
    #进入容器内的mysql命令行
    mysql -uroot -p
    #修改默认密码校验方式(不执行,navicat无法连接
    ALTER USER 'root'@'%' IDENTIFIED WITH mysql_native_password BY '123456';
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 主机中创建slave用户:
    -- 创建slave用户
    CREATE USER 'dk_slave'@'%';
    -- 设置密码
    ALTER USER 'dk_slave'@'%' IDENTIFIED WITH mysql_native_password BY '123456';
    -- 授予复制权限
    GRANT REPLICATION SLAVE ON *.* TO 'dk_slave'@'%';
    -- 刷新权限
    FLUSH PRIVILEGES;
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 主机中查询master状态:

    执行完此步骤后不要再操作主服务器MYSQL,防止主服务器状态值变化
    SHOW MASTER STATUS;
    记下File和Position的值。执行完此步骤后不要再操作主服务器MYSQL,防止主服务器状态值变化。

    image.png

    从服务slave1-3308

    启动从服务slave1-3308

    docker run -d \
    -p 3308:3306 \
    -v /study/shardingsphere/mysql/slave1/conf:/etc/mysql/conf.d \
    -v /study/shardingsphere/mysql/slave1/data:/var/lib/mysql \
    -e MYSQL_ROOT_PASSWORD=123456 \
    --name dk-mysql-slave1 \
    mysql:8.0.29
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    创建MySQL主服务器配置文件:
    默认情况下MySQL的binlog日志是自动开启的,可以通过如下配置定义一些可选配置

    vim /study/shardingsphere/mysql/slave1/conf/my.cnf

    配置如下内容:

    [mysqld]
    # 服务器唯一id,每台服务器的id必须不同,如果配置其他从机,注意修改id
    server-id=2
    # 中继日志名,默认xxxxxxxxxxxx-relay-bin
    #relay-log=relay-bin
    
    • 1
    • 2
    • 3
    • 4
    • 5

    重启MySQL容器

    docker restart dk-mysql-slave1

    设置mysql容器在docker启动的时候启动

    docker update dk-mysql-slave1 --restart=always

    • step3:使用命令行登录MySQL从服务器:
    #进入容器:
    docker exec -it dk-mysql-slave1 env LANG=C.UTF-8 /bin/bash
    #进入容器内的mysql命令行
    mysql -uroot -p
    #修改默认密码校验方式
    ALTER USER 'root'@'%' IDENTIFIED WITH mysql_native_password BY '123456';
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • step4:在从机上配置主从关系:

    从机上执行以下SQL操作

    CHANGE MASTER TO MASTER_HOST='192.168.229.128', 
    MASTER_USER='dk_slave',MASTER_PASSWORD='123456', MASTER_PORT=3307,
    MASTER_LOG_FILE='binlog.000003',MASTER_LOG_POS=1342;
    
    SHOW MASTER STATUS;
    
    STOP SLAVE;
    CHANGE MASTER TO MASTER_HOST='192.168.229.128', 
    MASTER_USER='dk_slave',MASTER_PASSWORD='123456', MASTER_PORT=3307,
    MASTER_LOG_FILE='binlog.000003',MASTER_LOG_POS=1342;
    
    START SLAVE;
    
    -- 查看同步状态(不需要分号)
    SHOW SLAVE STATUS\G
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    image.png

    从服务slave2-3309

    启动从服务slave2-3309

    docker run -d \
    -p 3309:3306 \
    -v /study/shardingsphere/mysql/slave2/conf:/etc/mysql/conf.d \
    -v /study/shardingsphere/mysql/slave2/data:/var/lib/mysql \
    -e MYSQL_ROOT_PASSWORD=123456 \
    --name dk-mysql-slave2 \
    mysql:8.0.29
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    创建MySQL主服务器配置文件:
    默认情况下MySQL的binlog日志是自动开启的,可以通过如下配置定义一些可选配置

    vim /study/shardingsphere/mysql/slave2/conf/my.cnf

    配置如下内容:

    [mysqld]
    # 服务器唯一id,每台服务器的id必须不同,如果配置其他从机,注意修改id
    server-id=3
    # 中继日志名,默认xxxxxxxxxxxx-relay-bin
    #relay-log=relay-bin
    
    • 1
    • 2
    • 3
    • 4
    • 5

    重启MySQL容器

    docker restart dk-mysql-slave2

    设置mysql容器在docker启动的时候启动

    docker update dk-mysql-slave2 --restart=always

    • step3:使用命令行登录MySQL从服务器:
    #进入容器:
    docker exec -it dk-mysql-slave2 env LANG=C.UTF-8 /bin/bash
    #进入容器内的mysql命令行
    mysql -uroot -p
    #修改默认密码校验方式
    ALTER USER 'root'@'%' IDENTIFIED WITH mysql_native_password BY '123456';
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • step4:在从机上配置主从关系:

    从机上执行以下SQL操作

    CHANGE MASTER TO MASTER_HOST='192.168.229.128', 
    MASTER_USER='dk_slave',MASTER_PASSWORD='123456', MASTER_PORT=3307,
    MASTER_LOG_FILE='binlog.000003',MASTER_LOG_POS=1342;
    
    SHOW MASTER STATUS;
    
    STOP SLAVE;
    CHANGE MASTER TO MASTER_HOST='192.168.229.128', 
    MASTER_USER='dk_slave',MASTER_PASSWORD='123456', MASTER_PORT=3307,
    MASTER_LOG_FILE='binlog.000003',MASTER_LOG_POS=1342;
    START SLAVE;
    
    
    -- 查看同步状态(不需要分号)
    SHOW SLAVE STATUS\G
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    启动从机的复制功能,执行SQL:

    START SLAVE;
    -- 查看状态(不需要分号)
    SHOW SLAVE STATUS\G
    
    • 1
    • 2
    • 3

    状态正常后创建测试表

    CREATE DATABASE db_user;
    USE db_user;
    CREATE TABLE t_user (
    id BIGINT AUTO_INCREMENT,
    uname VARCHAR(30),
    PRIMARY KEY (id)
    );
    INSERT INTO t_user(uname) VALUES(‘zhang3’);
    INSERT INTO t_user(uname) VALUES(@@hostname);

    ShardingSphere接入主从数据库

    我是idea直接创建的空白springboot项目,替换pom为下面内容

    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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
      <modelVersion>4.0.0modelVersion>
      <groupId>com.dkgroupId>
      <artifactId>ShardingJdbcDemoartifactId>
      <version>0.0.1-SNAPSHOTversion>
      <name>ShardingJdbcDemoname>
      <description>Demo project for Spring Bootdescription>
      <properties>
        <java.version>1.8java.version>
        <project.build.sourceEncoding>UTF-8project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8project.reporting.outputEncoding>
        <spring-boot.version>2.3.12.RELEASEspring-boot.version>
      properties>
    
      <dependencies>
        <dependency>
          <groupId>org.springframework.bootgroupId>
          <artifactId>spring-boot-starter-webartifactId>
        dependency>
    
        <dependency>
          <groupId>org.apache.shardingspheregroupId>
          <artifactId>shardingsphere-jdbc-core-spring-boot-starterartifactId>
          <version>5.1.1version>
        dependency>
    
        <dependency>
          <groupId>mysqlgroupId>
          <artifactId>mysql-connector-javaartifactId>
          <scope>runtimescope>
        dependency>
    
        <dependency>
          <groupId>com.baomidougroupId>
          <artifactId>mybatis-plus-boot-starterartifactId>
          <version>3.3.1version>
        dependency>
    
        <dependency>
          <groupId>org.projectlombokgroupId>
          <artifactId>lombokartifactId>
          <optional>trueoptional>
        dependency>
    
        <dependency>
          <groupId>org.springframework.bootgroupId>
          <artifactId>spring-boot-starter-testartifactId>
          <scope>testscope>
          <exclusions>
            <exclusion>
              <groupId>org.junit.vintagegroupId>
              <artifactId>junit-vintage-engineartifactId>
            exclusion>
          exclusions>
        dependency>
      dependencies>
    
    
      <dependencyManagement>
        <dependencies>
          <dependency>
            <groupId>org.springframework.bootgroupId>
            <artifactId>spring-boot-dependenciesartifactId>
            <version>${spring-boot.version}version>
            <type>pomtype>
            <scope>importscope>
          dependency>
        dependencies>
      dependencyManagement>
    
      <build>
        <plugins>
          <plugin>
            <groupId>org.apache.maven.pluginsgroupId>
            <artifactId>maven-compiler-pluginartifactId>
            <version>3.8.1version>
            <configuration>
              <source>1.8source>
              <target>1.8target>
              <encoding>UTF-8encoding>
            configuration>
              plugin>
              <plugin>
              <groupId>org.springframework.bootgroupId>
              <artifactId>spring-boot-maven-pluginartifactId>
              <version>${spring-boot.version}version>
              <configuration>
              <mainClass>com.dk.shardingjdbcdemo.ShardingJdbcDemoApplicationmainClass>
              <skip>trueskip>
              configuration>
              <executions>
              <execution>
              <id>repackageid>
              <goals>
              <goal>repackagegoal>
              goals>
              execution>
              executions>
              plugin>
              plugins>
              build>
    
              project>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105

    配置点主要在application.properties,一个从服务和多个不一样,所以下面分开测试
    官网地址
    https://shardingsphere.apache.org/document/5.1.1/cn/user-manual/shardingsphere-jdbc/spring-boot-starter/rules/readwrite-splitting/

    一主一从

    application.properties
    spring.application.name=ShardingJdbcDemo
    server.servlet.context-path=/shardingJdbcDemo
    
    spring.shardingsphere.props.sql-show=true
    
    #内存模式
    spring.shardingsphere.mode.type=Memory
    
    # 配置真实数据源
    spring.shardingsphere.datasource.names=master,slave1
    
    # 配置第 1 个数据源
    spring.shardingsphere.datasource.master.type=com.zaxxer.hikari.HikariDataSource
    spring.shardingsphere.datasource.master.driver-class-name=com.mysql.jdbc.Driver
    spring.shardingsphere.datasource.master.jdbc-url=jdbc:mysql://192.168.229.128:3307/db_user
    spring.shardingsphere.datasource.master.username=root
    spring.shardingsphere.datasource.master.password=123456
    
    # 配置第 2 个数据源
    spring.shardingsphere.datasource.slave1.type=com.zaxxer.hikari.HikariDataSource
    spring.shardingsphere.datasource.slave1.driver-class-name=com.mysql.jdbc.Driver
    spring.shardingsphere.datasource.slave1.jdbc-url=jdbc:mysql://192.168.229.128:3308/db_user
    spring.shardingsphere.datasource.slave1.username=root
    spring.shardingsphere.datasource.slave1.password=123456
    
    # 读写分离类型,如: Static,Dynamic
    spring.shardingsphere.rules.readwrite-splitting.data-sources.myds.type=Static
    # 自动发现数据源名称(与数据库发现配合使用)
    spring.shardingsphere.rules.readwrite-splitting.data-sources.myds.props.auto-aware-data-source-name=
    # 写数据源名称
    spring.shardingsphere.rules.readwrite-splitting.data-sources.myds.props.write-data-source-name=master
    # 读数据源名称,多个从数据源用逗号分隔
    spring.shardingsphere.rules.readwrite-splitting.data-sources.myds.props.read-data-source-names=slave1
    # 负载均衡算法名称
    spring.shardingsphere.rules.readwrite-splitting.data-sources.myds.load-balancer-name=round-balancer
    
    # 负载均衡算法配置
    # 负载均衡算法类型
    spring.shardingsphere.rules.readwrite-splitting.load-balancers.round-balancer.type=ROUND_ROBIN
    # 负载均衡算法属性配置
    #spring.shardingsphere.rules.readwrite-splitting.load-balancers.round-balancer.props.xxx=
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    实体类UserPo
    import com.baomidou.mybatisplus.annotation.IdType;
    import com.baomidou.mybatisplus.annotation.TableId;
    import com.baomidou.mybatisplus.annotation.TableName;
    import lombok.Builder;
    import lombok.Data;
    
    @Data
        @TableName("t_user")
        @Builder
        public class UserPo {
            /**
    * id BIGINT AUTO_INCREMENT,
    * uname VARCHAR(30),
    * PRIMARY KEY (id)
    */
            @TableId(type = IdType.AUTO)
            private Long id;
            private String uname;
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    UserMapper
    import com.baomidou.mybatisplus.core.mapper.BaseMapper;
    import com.dk.shardingjdbcdemo.dto.UserPo;
    import org.apache.ibatis.annotations.Mapper;
    
    @Mapper
        public interface UserMapper extends BaseMapper<UserPo> {
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    测试类
    import com.dk.shardingjdbcdemo.dto.UserPo;
    import org.junit.jupiter.api.Test;
    import org.springframework.boot.test.context.SpringBootTest;
    
    import javax.annotation.Resource;
    
    @SpringBootTest
    public class UserMapperTest {
        @Resource
        private  UserMapper userMapper;
    
        @Test
        public void testInsertUser(){
            userMapper.insert(UserPo.builder().uname("李四").build());
            userMapper.insert(UserPo.builder().uname("李四2").build());
            userMapper.insert(UserPo.builder().uname("李四3").build());
            userMapper.insert(UserPo.builder().uname("李四4").build());
    
            userMapper.selectList(null);
            userMapper.selectList(null);
            userMapper.selectList(null);
            userMapper.selectList(null);
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24

    测试结果
    image.png
    从结果可以看出,已经实现了主服务插入,从服务查询

    一主两从

    application.properties
    spring.application.name=ShardingJdbcDemo
    server.servlet.context-path=/shardingJdbcDemo
    
    spring.shardingsphere.props.sql-show=true
    
    #内存模式
    spring.shardingsphere.mode.type=Memory
    
    # 配置真实数据源
    spring.shardingsphere.datasource.names=master,slave1,slave2
    
    # 配置第 1 个数据源
    spring.shardingsphere.datasource.master.type=com.zaxxer.hikari.HikariDataSource
    spring.shardingsphere.datasource.master.driver-class-name=com.mysql.jdbc.Driver
    spring.shardingsphere.datasource.master.jdbc-url=jdbc:mysql://192.168.229.128:3307/db_user
    spring.shardingsphere.datasource.master.username=root
    spring.shardingsphere.datasource.master.password=123456
    
    # 配置第 2 个数据源
    spring.shardingsphere.datasource.slave1.type=com.zaxxer.hikari.HikariDataSource
    spring.shardingsphere.datasource.slave1.driver-class-name=com.mysql.jdbc.Driver
    spring.shardingsphere.datasource.slave1.jdbc-url=jdbc:mysql://192.168.229.128:3308/db_user
    spring.shardingsphere.datasource.slave1.username=root
    spring.shardingsphere.datasource.slave1.password=123456
    
    # 配置第 2 个数据源
    spring.shardingsphere.datasource.slave2.type=com.zaxxer.hikari.HikariDataSource
    spring.shardingsphere.datasource.slave2.driver-class-name=com.mysql.jdbc.Driver
    spring.shardingsphere.datasource.slave2.jdbc-url=jdbc:mysql://192.168.229.128:3309/db_user
    spring.shardingsphere.datasource.slave2.username=root
    spring.shardingsphere.datasource.slave2.password=123456
    
    # 读写分离类型,如: Static,Dynamic
    spring.shardingsphere.rules.readwrite-splitting.data-sources.myds.type=Static
    # 自动发现数据源名称(与数据库发现配合使用)
    spring.shardingsphere.rules.readwrite-splitting.data-sources.myds.props.auto-aware-data-source-name=
    # 写数据源名称
    spring.shardingsphere.rules.readwrite-splitting.data-sources.myds.props.write-data-source-name=master
    # 读数据源名称,多个从数据源用逗号分隔
    spring.shardingsphere.rules.readwrite-splitting.data-sources.myds.props.read-data-source-names=slave1,slave2
    # 负载均衡算法名称
    spring.shardingsphere.rules.readwrite-splitting.data-sources.myds.load-balancer-name=round-balancer
    
    # 负载均衡算法配置
    # 负载均衡算法类型
    spring.shardingsphere.rules.readwrite-splitting.load-balancers.round-balancer.type=ROUND_ROBIN
    # 负载均衡算法属性配置
    #spring.shardingsphere.rules.readwrite-splitting.load-balancers.round-balancer.props.xxx=
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48

    其他代码同上

    测试结果
    image.png

    从图上来看,插入走master服务,查询轮询2台从服务,达到预期

    事务

    如果有事务的话,都会走master服务,

  • 相关阅读:
    回调函数方式方法完整学习
    【力扣hot100】day2
    Feign-Hystrix 熔断降级,一文看透本质
    ORACLE数据恢复(误操作delete或update如何恢复?)
    正点原子[第二期]ARM(I.MX6U)裸机篇学习笔记-1.2
    你了解TCP协议吗(一)?
    MATLAB:线性系统的建模与仿真(含完整程序)
    软件测试(一)概念
    Android图形-Hardware Composer HAL
    剑指 Offer II 064. 神奇的字典
  • 原文地址:https://blog.csdn.net/qq_41082640/article/details/131097769