一.Mysql的集群搭建(使用docker搭建省事)
1、关闭防火墙,重启docker**
#关闭docker
systemctl stop docker
#关闭防火墙
systemctl stop firewalld
#启动docker
systemctl start docker
2.1、准备主服务器
解释:
端口号是3306,
指定宿主机配置文件对应docker上mysql的配置文件,
同时指定宿主机日志信息对应docker上mysql的日志信息
指定密码默认123456
指定容器名字
privileged=true代表docker容器具备更多的权限
版本号
docker run -d \
-p 3306:3306 \
-v /renxh/mysql/master/conf:/etc/mysql/conf.d \
-v /renxh/mysql/master/data:/var/lib/mysql \
-e MYSQL_ROOT_PASSWORD=123456 \
--name renxh-mysql-master \
--privileged=true \
mysql:8.0.29
2.2创建MySQL主服务器配置文件:
vim /renxh/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
重启MySQL容器
docker restart renxh-mysql-master
2.3使用命令行登录MySQL主服务器
#进入容器:env LANG=C.UTF-8 避免容器中显示中文乱码
docker exec -it atguigu-mysql-master env LANG=C.UTF-8 /bin/bash
#进入容器内的mysql命令行
mysql -uroot -p
#修改默认密码校验方式 因为mysql默认密码太简单了,这里简单设置下,不需要设置太复杂密码
ALTER USER 'root'@'%' IDENTIFIED WITH mysql_native_password BY '123456';
2.4主机中创建slave用户:
-- 创建slave用户
CREATE USER 'renxh_slave'@'%';
-- 设置密码
ALTER USER 'renxh_slave'@'%' IDENTIFIED WITH mysql_native_password BY '123456';
-- 授予复制权限
GRANT REPLICATION SLAVE ON *.* TO 'renxh_slave'@'%';
-- 刷新权限
FLUSH PRIVILEGES;
2.5主机中查询master状态
SHOW MASTER STATUS;
记下File
和Position
的值。执行完此步骤后不要再操作主服务器MYSQL,防止主服务器状态值变化
3.1准备从服务器
在docker中创建并启动MySQL从服务器:**端口3307
docker run -d \
-p 3307:3307 \
-v /renxh/mysql/slave1/conf:/etc/mysql/conf.d \
-v /renxh/mysql/slave1/data:/var/lib/mysql \
-e MYSQL_ROOT_PASSWORD=123456 \
--name renxh-mysql-slave1 \
--privileged=true \
mysql:8.0.29
3.2 创建MySQL从服务器配置文件
vim /renxh/mysql/slave1/conf/my.cnf
配置如下内容
[mysqld]
# 服务器唯一id,每台服务器的id必须不同,如果配置其他从机,注意修改id
server-id=2
# 中继日志名,默认xxxxxxxxxxxx-relay-bin
#relay-log=relay-bin
3.3使用命令行登录MySQL从服务器
#进入容器:
docker exec -it renxh-mysql-slave1 env LANG=C.UTF-8 /bin/bash
#进入容器内的mysql命令行
mysql -uroot -p
#修改默认密码校验方式
ALTER USER 'root'@'%' IDENTIFIED WITH mysql_native_password BY '123456';
3.4在从机上配置主从关系
从机上执行以下SQL操作
MASTER_HOST对应ip地址,实际是master的mysql
MASTER_USER配置的master上的从用户,
MASTER_PASSWORD是密码
MASTER_PORT端口号
MASTER_LOG_FILE对应的二进制日志,看2.5
MASTER_LOG_POS对应的游标,从哪复制主数据,看2.5
CHANGE MASTER TO MASTER_HOST='192.168.85.200',
MASTER_USER='renxh_slave',MASTER_PASSWORD='123456', MASTER_PORT=3306,
MASTER_LOG_FILE='binlog.000003',MASTER_LOG_POS=1357;
4.1启动主从同步
启动从机的复制功能,执行SQL:
START SLAVE;
-- 查看状态(不需要分号)
SHOW SLAVE STATUS\G
4.2自此实现了主从复制
在主机中执行以下SQL,在从机中查看数据库、表和数据是否已经被同步
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);
4.3停止和重置
-- 在从机上执行。功能说明:停止I/O 线程和SQL线程的操作。
stop slave;
-- 在从机上执行。功能说明:用于删除SLAVE数据库的relaylog日志文件,并重新启用新的relaylog文件。
reset slave;
-- 在主机上执行。功能说明:删除所有的binglog日志文件,并将日志索引文件清空,重新开始所有新的日志文件。
-- 用于第一次进行搭建主从库时,进行主库binlog初始化工作;
reset master;
二.多数据源管理
MyBatis-Plus框架的开发者就开发了这样的一个框架DynamicDataSource,可以简化多数据源访问的过程
引入依赖
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>dynamic-datasource-spring-boot-starter</artifactId>
<version>3.5.0</version>
</dependency>
配置yaml,表名两个数据源,一个read一个write
spring:
datasource:
type: com.alibaba.druid.pool.DruidDataSource
#使用dynamicDatasource框架
dynamic:
#设置默认的数据源或者数据源组,read
primary: read
#严格匹配数据源,默认false. true未匹配到指定数据源时抛异常,false使用默认数据源
strict: false
datasource:
read:
url: jdbc:mysql://localhost:3306/coursedb?serverTimezone=UTC
username: root
password: root
initial-size: 1
min-idle: 1
max-active: 20
test-on-borrow: true
driver-class-name: com.mysql.cj.jdbc.Driver
write:
url: jdbc:mysql://localhost:3306/coursedb2?serverTimezone=UTC
username: root
password: root
initial-size: 1
min-idle: 1
max-active: 20
test-on-borrow: true
driver-class-name: com.mysql.cj.jdbc.Driver
server:
port: 8081
在service层加入注解就可以了
不足:dynamic数据源无法保证多个事务情况,但是我们自己也可以拓展,查看源码,他只是针对一个数据源的链接执行的提交事务或者回滚事务,我们可以拓展获取到所有的数据源事务,一起提交或者回滚,
shardingsphere实现了这个功能
还可以根据session获取数据源
解释:当将数据源放到session里面后,在业务层,根据#session可以读取对应的数据源,源码如下
还有其他几种,根据请求头读取,或者根据spel表达式读取