mysql主从复制从0到1
docker启动多个mysql服务
sudo docker pull mysql:8.0.29
启动主服务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
创建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
binlog格式说明:
重启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';
-- 创建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;
执行完此步骤后不要再操作主服务器MYSQL,防止主服务器状态值变化
SHOW MASTER STATUS;
记下File和Position的值。执行完此步骤后不要再操作主服务器MYSQL,防止主服务器状态值变化。
启动从服务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
创建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
重启MySQL容器
docker restart dk-mysql-slave1
设置mysql容器在docker启动的时候启动
docker update dk-mysql-slave1 --restart=always
#进入容器:
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';
在从机上执行以下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
启动从服务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
创建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
重启MySQL容器
docker restart dk-mysql-slave2
设置mysql容器在docker启动的时候启动
docker update dk-mysql-slave2 --restart=always
#进入容器:
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';
在从机上执行以下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
启动从机的复制功能,执行SQL:
START SLAVE;
-- 查看状态(不需要分号)
SHOW SLAVE STATUS\G
状态正常后创建测试表
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);
我是idea直接创建的空白springboot项目,替换pom为下面内容
<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>
配置点主要在application.properties,一个从服务和多个不一样,所以下面分开测试
官网地址
https://shardingsphere.apache.org/document/5.1.1/cn/user-manual/shardingsphere-jdbc/spring-boot-starter/rules/readwrite-splitting/
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=
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;
}
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> {
}
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);
}
}
测试结果
从结果可以看出,已经实现了主服务插入,从服务查询
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=
其他代码同上
从图上来看,插入走master服务,查询轮询2台从服务,达到预期
如果有事务的话,都会走master服务,