1、为什么需要搭建主从服务
由于我们平时在操作数据库的时候,大多数时候查询的操作远多于写的操作,也就是需要处理大量查询请求的场景,为了保证数据库操作的效率,我们一般把读的操作放在一个数据库执行(从库),比较耗时与频繁I/O的操作放在另一个数据库(主库)。这样通过读/写分离,有利于减轻主库操作的压力,主从库可以各行其事,从而提高了数据库的操作效率!
扩展:
通过多个服务器(MySQL)协同工作处理大量请求问题➡分布式
CAP理论:
即:在一个分布式系统(指互相连接并共享数据的节点的集合)中,当涉及读写操作时,只能保证一致性(Consistence)、可用性(Availability)、分区容错性(Partition Tolerance)三者中的两个,另外一个必须被牺牲。
2、主从复制的原理
方法:
创建两个docker容器,一主(master)一从(slave)。
具体操作:
(1)主库master执行sql,并将数据的操作记录写入到一个二进制文件中(binary log),也就是配置文件中指定的log-bin日志文件。
(2)从库slave开启IO线程读取binlog文件;
(3)从库slave将读取到的binlog日志文件写入到slave服务器的relaylog文件中;
(4)从库slave再开启SQL线程,读取relaylog中的数据,更新slave数据库中的内容,将日志文件中的记录变为执行数据操作的行为,从而实现主从数据一致性的目的。
补充:关于binlog的查询命令
查看日志是否启用
show variables like 'log_bin';
查看binlog的位置
show variables like '%datadir%';
显示所有日志文件
show binary logs;
查询binlog日志
show binlog events in 'wnhz-master-bin.000001';
3、创建mysql主从存储文件夹
结构图:
4、从容器中拷贝cp原始配置文件my.cnf
容器内位置:/etc/mysql/my.cnf
docker cp 容器名称: 文件地址 目标地址 ./ --当前位置
docker run -it --name mytest -e MYSQL_ROOT_PASSWORD=123 -d mysql
docker cp mytest:/etc/mysql/my.cnf ./
5、先搭建主(master)服务器的docker容器
docker run \
-it \
--name mysql_3306 \
--privileged \
--network **_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=123 \
-d mysql
6、搭建完连接测试
(1)进入mysql -uroot -p123
show master status;
(2)navicat客户端测试
7、连接不上的解决办法(防火墙开放指定端口)
firewall-cmd --add-port=3306/tcp --permanent
firewall-cmd --reload
firewall-cmd --list-ports
8、主master服务器配置my.cnf文件
进入conf文件夹,cat my.cnf
进入编辑,vim my.cnf
开始编辑,i(insert)
[mysqld]
pid-file = /var/run/mysqld/mysqld.pid
socket = /var/run/mysqld/mysqld.sock
datadir = /var/lib/mysql
secure-file-priv= NULL
default_authentication_plugin=mysql_native_password
# Custom config should go here
!includedir /etc/mysql/conf.d/
server-id=200 #server‘id
log_bin=wnhz-master-logbin #logbin name
binlog_format=row
退出编辑,esc
保存并退出,:wq
不保存退出,:q!
重启容器 docker restart mysql_3306
再进入容器 docker exec -it mysql_3306 bash
9、再搭建从(slave)服务器的docker容器
同样需要拷贝my.cnf文件
容器内位置:/etc/mysql/my.cnf
docker cp 容器名称: 文件地址 目标地址 ./ --当前位置
docker run -it --name mytest -e MYSQL_ROOT_PASSWORD=123 -d mysql
docker cp mytest:/etc/mysql/my.cnf ./
创建运行容器
docker run \
-it \
--name mysql_3310 \
--privileged \
--network **_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=123 \
-d mysql
配置my.cnf文件
[mysqld]
pid-file = /var/run/mysqld/mysqld.pid
socket = /var/run/mysqld/mysqld.sock
datadir = /var/lib/mysql
secure-file-priv= NULL
default_authentication_plugin=mysql_native_password
# Custom config should go here
!includedir /etc/mysql/conf.d/
server-id=201 #server‘id
log_bin=wnhz-slave-01-logbin #logbin name
relay_log=wnhz-slave-01-relay
read-only=1
master创建用户slave进行主从关联(数据库中sql语句)
create user 'slave'@'%' IDENTIFIED WITH mysql_native_password BY '123';
GRANT REPLICATION SLAVE,REPLICATION CLIENT ON *.* TO 'slave'@'%';
flush privileges;
进入slave容器,连接mysql
change master to master_host='172.18.12.2', master_user='slave',master_password='123',MASTER_LOG_FILE='wnhz-master-logbin.00000*',MASTER_LOG_POS=***;
启动从 start slave;
查看从状态 show slave status \G;
配置成功
10、常见问题
从库依然能够写数据
原因:从库使用的root用户登录,权限最高
解决方案:
从库创建一个新用户,权限只能是读
SQL语句:
主从配置出现非两个YES
- 关闭slave
stop slave;
- 重置slave
reset slave;
- 重新配置change to
show master status; #maseter
change master to master_host='172.18.12.2', master_user='slave',master_password='123',MASTER_LOG_FILE='wnhz-master-logbin.00000*',MASTER_LOG_POS=***; #slave
- 重新运行slave
start slave;
———————————————————————————————
感谢阅读,码字不易,多谢点赞!如有不当之处,欢迎反馈指出,感谢!