一、概述
本文是对主从复制,读写分离的一个简单实现。
二、环境准备
Docker: mysql5.7的镜像
SpringBoot: 2.7.18
mybatis-plus: 3.5.6
shardingsphere-jdbc-core-spring-boot-starter: 5.2.0
三、 数据库搭建配置
3.1 拉取MySQL镜像
我这里用到mysql5.7版本
docker pull mysql:5.7
3.2 创建配置主库
step1: 创建配置文件 my.cnf
这里我将my.cnf放在了/root/master文件夹下。
[mysqld]
server-id=1
log-bin=mysql-bin
binlog_format=ROW
expire_logs_days=1
step2: 启动主库
docker run --name master-db -p 3306:3306 -v /root/master/my.cnf:/etc/mysql/my.cnf -e MYSQL_ROOT_PASSWORD=123456 -d mysql:5.7
step3:进入主服务器容器,给从库创建用户并授权。
docker exec -it master-db /bin/bash
mysql -uroot -proot
CREATE USER 'slave'@'%' IDENTIFIED BY '123456';
GRANT REPLICATION SLAVE, REPLICATION CLIENT ON *.* TO 'slave'@'%';
FLUSH PRIVILEGES;
step4: 查看主服务器的二进制日志状态,记录File和Position的值,用于从服务器的配置。
SHOW MASTER STATUS;
3.3 创建配置从库
step1: 创建配置文件 my.cnf
这个在/root/slave文件夹下。
[mysqld]
server-id=2
relay_log=mysql-relay-bin
step2: 启动从库
docker run --name slave-db -p 3307:3306 -v /root/slave/my.cnf:/etc/mysql/my.cnf -e MYSQL_ROOT_PASSWORD=123456 -d mysql:5.7
step3: 进入从服务器容器,配置复制
docker exec -it slave-db /bin/bash
mysql -uroot -proot
CHANGE MASTER TO
MASTER_HOST='宿主机的IP地址',
MASTER_USER='slave',
MASTER_PASSWORD='slave_password',
MASTER_PORT=3306,
MASTER_LOG_FILE='记录的主服务器File值',
MASTER_LOG_POS=记录的主服务器Position值;
START SLAVE;
step4: 查看从库的复制状态,确保Slave_IO_Running和Slave_SQL_Running都为Yes。
SHOW SLAVE STATUS;
到这里数据库的主从复制就完成了,可以试试增删改,同步看下从库变没变。
MySQL提供了几个有用的SHOW语句来帮助检查复制状态:
主服务器:
SHOW MASTER STATUS;
这个命令显示了当前的二进制日志文件名和位置。
从服务器:
SHOW SLAVE STATUS;
这个命令会显示从服务器复制状态的详细信息,包括但不限于:
- Slave_IO_Running 和 Slave_SQL_Running:这两个值应为Yes,表示复制正在运行。
- Last_Error:如果有错误发生,这里会显示最后的错误信息。
- Last_IO_Error 和 Last_SQL_Error:分别显示输入输出线程和SQL线程的最后错误。
- Master_Log_File 和 Exec_Master_Log_Pos:显示从服务器当前正在读取哪个主日志文件以及读取到了什么位置。
- Seconds_Behind_Master:显示从服务器落后于主服务器的时间。
从库配置失败可以重新去配
STOP SLAVE;
RESET SLAVE ALL;
CHANGE MASTER TO MASTER_HOST='主服务器IP',
MASTER_USER='复制用户',
MASTER_PASSWORD='复制密码',
MASTER_LOG_FILE='主服务器当前日志文件',
MASTER_LOG_POS=日志位置;
START SLAVE;
四、代码搭建
4.1 创建springboot工程
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.7.18</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.yang</groupId>
<artifactId>spring-boot-sharding-jdbc-demo</artifactId>
<version>1.0-SNAPSHOT</version>
<properties>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.5.6</version>
</dependency>
<!-- MySQL Driver -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.49</version>
</dependency>
<dependency>
<groupId>org.apache.shardingsphere</groupId>
<artifactId>shardingsphere-jdbc-core-spring-boot-starter</artifactId>
<version>5.2.0</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>RELEASE</version>
<scope>provided</scope>
</dependency>
<!-- Spring Boot Starter Test -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
4.2 添加application.yml
spring:
shardingsphere:
props:
# 打印shardingjdbc的日志 shardingsphere5之前的版本配置项是 spring.shardingsphere.props.sql.show,而这里是sql-show
sql-show: true
datasource:
names: ds-master,ds-slave
ds-master:
type: com.zaxxer.hikari.HikariDataSource
driver-class-name: com.mysql.jdbc.Driver
jdbc-url: jdbc:mysql://xxx:3306/master_slave_test_db?serverTimezone=UTC&useSSL=false
username: root
password: 123456
ds-slave:
type: com.zaxxer.hikari.HikariDataSource
driver-class-name: com.mysql.jdbc.Driver
jdbc-url: jdbc:mysql://xxx:3307/master_slave_test_db?serverTimezone=UTC&useSSL=false
username: root
password: 123456
rules:
readwrite-splitting:
data-sources:
readwrite_ds:
static-strategy:
write-data-source-name: ds-master
read-data-source-names: ds-slave
loadBalancerName: roundRobin
load-balancers:
roundRobin:
type: ROUND_ROBIN
mybatis和增删改查以后在补充,到这里主从复制,读写分离的核心已经实现