为什么搭建MySQL主从数据库?
在实际生产环境下,MySQL可能会面临同一时间处理大量数据的压力,如果使用单一数据库来处理增删改查所有请求,会造成性能下降的问题。
这一问题对应了分布式计算的“CAP定律”中的A,高可用性。
主从数据库原理
采用创建两个docker容器扮演主(master)从(slave)
- 请求mysql在book_tab中添加一条数据 insert
- master:执行sql,写入到binlog–二进制文件,记录master的数据库操作
- slave:开启IO线程读取binlog文件
- slave: 开启写线程写入slave服务器的Relaylog文件中
- slave: 开启SQL线程,读取relaylog中的数据,更新slave数据库中的内容
- slave:也添加了一条数据。
搭建和配置
创建存储文件夹
-
在/usr/local 下面创建software目录
-
在里面创建一个mysql目录
-
在mysql文件夹中创建3306、3310两个目录(或者再创建一个3311,一主二从)
-
在上述几个目录下分别创建data文件夹还有conf文件夹
mkdir -p 3306/conf mkdir -p 3306/data
具体的结构如图所示:
准备配置文件
从容器中拷贝一个my.cnf文件到3306/conf,然后在里面写需要的相关配置。(也可以自己创建)
docker run -it --name mytest -e MYSQL_ROOT_PASSWORD=root -d mysql 创建一个docker(用于拷贝my.cnf) docker cp mytest:/etc/mysql/my.cnf ./ /etc/mysql/my.cnf 容器内my.cnf的位置 docker cp 容器名称: 文件地址 目标地址 ./ ---当前位置
修改my.cnf(这是主需要的配置)写在文档下方
server-id=200 log_bin=xxx-master-logbin binlog_format=row
搭建主(master)服务器
docker run \
-it \
--name mysql_3306 \
--privileged \
--network wn_docker_net \
--ip 172.18.12.2 \
-p 3306:3306 \
-v /usr/local/software/mysql/3306/conf/my.cnf:/etc/mysql/my.cnf \
-v /usr/local/software/mysql/3306/data:/var/lib/mysql \
-v /usr/local/software/mysql/3306/mysql-files:/var/lib/mysql-files \
-e MYSQL_ROOT_PASSWORD=root \
-d mysql
搭建完后可以在Navicat进行连接测试
为避免连接问题,可以先将防火墙开启(指定端口)
firewall-cmd --add-ports=3306/tcp --permanent
firewall-cmd --reload
firewall-cmd --list-ports
创建从(slave)服务器
拷贝一个my.cnf文件到3306/conf,然后在里面写需要的相关配置,配置内容与主(master)不同。
server-id=202
log_bin=wn-slave02-logbin
relay_log=wn-slave02-relaylog
read-only=1
创建slave容器
docker run \
-it \
--name mysql_3310 \
--privileged \
--network wn_docker_net \
--ip 172.18.12.3 \
-p 3310:3306 \
-v /usr/local/software/mysql/3310/conf/my.cnf:/etc/mysql/my.cnf \
-v /usr/local/software/mysql/3310/data:/var/lib/mysql \
-v /usr/local/software/mysql/3310/mysql-files:/var/lib/mysql-files \
-e MYSQL_ROOT_PASSWORD=root \
-d mysql
实现主从关联
在master中创建用户slave
create user 'slave'@'%' IDENTIFIED WITH mysql_native_password BY 'root';
GRANT REPLICATION SLAVE,REPLICATION CLIENT ON *.* TO 'slave'@'%';
flush privileges;
进入slave容器中连接主服务器
change master to master_host='172.18.12.2', master_user='slave',master_password='123',MASTER_LOG_FILE='wn-master-logbin.000001',MASTER_LOG_POS=156;
最后启动slave服务器
start slave;
验证是否实现(这里是否为两个YES)
show slave status \G;
补充问题
从数据库为什么还能写数据?
因为创建用户时没有对权限进行设置。
create user 'slave'@'%' IDENTIFIED WITH mysql_native_password BY 'root';
GRANT SELECT ON *.* TO 'slave'@'%';
flush privileges;
可以将从数据库设置为只能读。