文章目录
- 一、概览
- 1、案例概述
- 2、MySQL主从复制原理
- 3、MySQL读写分离原理
- 二、实验
- 实验1、MySQL主从复制
- 1、实验准备
- 2、关闭三台机器的防火墙
- 3、MySQL主服务器配置(主服务器)
- 4、重启MySQL服务(主服务器)
- 5、登录主服务器并创建帐号(主服务器)
- 6、MySQL从服务器配置(主服务器)
- 7、重启MySQL服务(从服务器)
- 8、登录数据库并指向master服务器(从服务器)
- 9、验证主从复制
- 实验2、MySQL读写分离
- 1、实验准备
- 2、关闭防火墙(amoeba服务器)
- 3、安装JDK(amoeba服务器)
- 4、修改环境变量(amoeba服务器)
- 5、解压文件(amoeba服务器)
- 6、在三台mysql上添加权限开放给amoeba访问(mysql三台服务)
- 7、编辑amoeba配置文件(amoeba服务器)
- 8、编辑配置文件(amoeba服务器)
- 9、启动服务(amoeba服务器)
- 10、客户端安装mysql(客户端)
- 11、连接amoeba服务器(客户端)
- 12、测试读写分离(客户端)
- 13、测试读写分离(从服务器)
- 14、测试(客户端)
- 15、从服务器创建表并插入数据(从服务器)
- 16、客户端测试(客户端)
- 三、问题总结
- 问题1、从服务器配置没问题,一台正常可以配置,另一台报错,错误信息如下所示ERROR 3021 (HY000): This operation cannot be performed with a running slave io thread; run STOP SLAVE IO_THREAD FOR CHANNEL '' first.
- 问题2、mysql主从同步报错Fatal error: The slave I/O thread stops because master and slave have equal MySQL server UUIDs; these UUIDs must be different for replication to work.
- 问题3、mysql5.7.20做从读写分离报错,信息如下
一、概览
1、案例概述
- 在企业应用中,成熟的业务通常数据量都比较大
- 单台MySQL在安全性、高可用性和高并发方面都无法满足实际的需求
- 配置多台主从数据库服务器以实现读写分离
2、MySQL主从复制原理
●MySQL的复制类型
1、基于语句的复制
2、基于行的复制
3、混合类型的复制
●MySQL主从复制的工作过程
先有主从复制,再有读写分离
3、MySQL读写分离原理
●只在主服务器上写,只在从服务器上读
●主数据库处理事务性查询,从数据库处理SELECT查询
●数据库复制用于将事务性查询的变更同步到集群中的从数据库
●读写分离方案
◆基于程序代码内部实现
◆基于中间代理层实现
MySQL-Proxy
Amoeba
二、实验
实验1、MySQL主从复制
1、实验准备
基于行或表的数据被锁了,所以要做读写分离。
1、主服务器开启复制帐号
2、读写分离帐号
3、访问amoeba的帐号
读数据采用轮询查询
MHA用来优化读写分离
master 192.168.235.150
slave01 192.168.235.159
slave02 192.168.235.160
这三台机器已经安装完成mysql
2、关闭三台机器的防火墙
iptables -F
setenforce 0
- 1
- 2
- 3
3、MySQL主服务器配置(主服务器)
vim /etc/my.cnf
server-id = 11
log-bin=master-bin ##主服务器日志文件
log-slave-updates=true ##从服务器更新二进制日志
- 1
- 2
- 3
- 4
- 5
4、重启MySQL服务(主服务器)
systemctl restart mysqld
- 1
5、登录主服务器并创建帐号(主服务器)
mysql -uroot -p
123123
grant replication slave on \*.* to 'myslave'@'192.168.235.%' identified by '123456';
flush privileges;
show master status;
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
6、MySQL从服务器配置(主服务器)
vim /etc/my.cnf
server-id = 22 ##一台是22,另一台是23
relay-log=relay-log-bin
relay-log-index=slave-relay-bin.index
- 1
- 2
- 3
- 4
- 5
7、重启MySQL服务(从服务器)
systemctl restart mysqld
- 1
8、登录数据库并指向master服务器(从服务器)
mysql -uroot -p ##登录
123123 ##输入密码
change master to master_host='192.168.235.150',master_user='myslave',master_password='123456',master_log_file='master-bin.000001',master_log_pos=604; ##绑定master
start slave; ##启动从服务
show slave status\G; ##查看状态
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
9、验证主从复制
主服务器创建数据库:shool,表名为:abc,其中插入两条记录;
从服务器都可以正常查询到表中的信息。
实验2、MySQL读写分离
1、实验准备
三台机器的主从复制已经完成
master 192.168.235.150
slave01 192.168.235.159
slave02 192.168.235.160
amoeba服务器 192.168.235.161
client 192.168.235.162
2、关闭防火墙(amoeba服务器)
setenforce 0
iptables -F
- 1
- 2
- 3
3、安装JDK(amoeba服务器)
上传相关的JDK安装包
cp jdk-6u14-linux-x64.bin /usr/local
cd /usr/local/
chmod +x jdk-6u14-linux-x64.bin ##加权限
./jdk-6u14-linux-x64.bin
yes
按回车
mv jdk1.6.0_14/ /usr/local/jdk1.6 ##修改文件夹名称
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
4、修改环境变量(amoeba服务器)
vim /etc/profile
export JAVA_HOME=/usr/local/jdk1.6
export CLASSPATH=$CLASSPATH:$JAVA_HOME/lib:$JAVA_HOME/jre/lib
export PATH=$JAVA_HOME/lib:$JAVE_HOME/jre/bin/:$PATH:$HOME/bin
export AMOEBA_HOME=/usr/local/amoeba
export PATH=$PATH:$AMOEBA_HOME/bin
source /etc/profile ##使配置文件重新生效
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
5、解压文件(amoeba服务器)
tar zxvf /opt/amoeba-mysql-binary-2.2.0.tar.gz -C /usr/local/amoeba/
chmod -R 755 /usr/local/amoeba/
/usr/local/amoeba/bin/amoeba
- 1
- 2
- 3
- 4
- 5
6、在三台mysql上添加权限开放给amoeba访问(mysql三台服务)
grant all on *.* to test@'192.168.235.%' identified by '';
- 1
7、编辑amoeba配置文件(amoeba服务器)
cd /usr/local/amoeba
vim conf/amoeba.xml
##30行修改内容如下所示
<property name="user">amoeba</property>
##32行修改内容如下所示
<property name="password">123456</property>
##117行去掉注释
<property name="defaultPool">master</property>
<property name="writePool">master</property>
<property name="readPool">slaves</property>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
8、编辑配置文件(amoeba服务器)
vim conf/dbServers.xml
##23行(mysql5.7,默认没有test数据库所以需要修改为mysql)
<property name="schema">mysql</property>
##26-29行去掉注释
<property name="user">test</property>
<property name="password">123.com</property>
##42行主服务器地址
<dbServer name="master" parent="abstractServer">
<property name="ipAddress">192.168.235.150</property>
##52行从服务器主机名
<dbServer name="slave1" parent="abstractServer">
##55行从服务器地址
<property name="ipAddress">192.168.235.159</property>
##末尾
<dbServer name="slaves" virtual="true">
<poolConfig class="">
##末尾
<property name="poolNames">slave1,slave2</property>
</poolConfig>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
9、启动服务(amoeba服务器)
/usr/local/amoeba/bin/amoeba start&
netstat -anpt | grep java
- 1
- 2
- 3
10、客户端安装mysql(客户端)
yum install -y mysql
- 1
11、连接amoeba服务器(客户端)
mysql -u amoeba -p123456 -h 192.168.235.161 -P8066
- 1
12、测试读写分离(客户端)
create database temp; ##创建一个数据库
##这时主从服务器都可以正常查看到这个数据库
- 1
- 2
- 3
13、测试读写分离(从服务器)
stop slave; ##两台从服务器关闭主从复制功能
show slave status\G; ##查看主从复制被关闭
- 1
- 2
- 3
14、测试(客户端)
create database student;
##主服务器可以查看到数据库,从服务器不能查看到数据库,说明主从复制功能已经关闭
- 1
- 2
- 3
15、从服务器创建表并插入数据(从服务器)
slave1服务器设置:
use temp;
create table yibiao(id int not null,name char(10));
insert into yibiao values(1,'zhangsan');
- 1
- 2
- 3
- 4
- 5
slave2服务器设置:
use temp;
create table yibiao(id int not null,name char(10));
insert into yibiao values(2,'lisi');
- 1
- 2
- 3
- 4
- 5
16、客户端测试(客户端)
use temp;
select * from yibiao;
select * from yibiao;
##发现每一次查询都要轮询slave1和slave2上查询数据,如果开启主从复制,则数据就会相同。
##读写分离验证成功
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
三、问题总结
问题1、从服务器配置没问题,一台正常可以配置,另一台报错,错误信息如下所示ERROR 3021 (HY000): This operation cannot be performed with a running slave io thread; run STOP SLAVE IO_THREAD FOR CHANNEL ‘’ first.
解决办法
1、停止已经启动的绑定
stop slave;
- 1
2、重置绑定
reset master;
- 1
3、执行复制主机命令
change master to master_host='192.168.235.150',master_user='myslave',master_password='123456',master_log_file='master-bin.000001',master_log_pos=604;
- 1
4、发现此时已经不报错
5、启动复制
start slave;
- 1
问题2、mysql主从同步报错Fatal error: The slave I/O thread stops because master and slave have equal MySQL server UUIDs; these UUIDs must be different for replication to work.
错误信息如下所示:Last_IO_Error: Fatal error: The slave I/O thread stops because master and slave have equal MySQL server UUIDs; these UUIDs must be different for replication to work.
解决:从报错信息发现是mysql的server_uuid的原因
1、检查两个mysql实例的uuid发现主从的uuid一模一样
# cat /mysql/data/
server-uuid=388c257a-f82e-11e7-aa88-000c2927fe42
2、删除从库的文件并且重启从库实例问题解决
检查从库复制状态
show slave status\G;
al error: The slave I/O thread stops because master and slave have equal MySQL server UUIDs; these UUIDs must be different for replication to work.
解决:从报错信息发现是mysql的server_uuid的原因
1、检查两个mysql实例的uuid发现主从的uuid一模一样
# cat /mysql/data/
server-uuid=388c257a-f82e-11e7-aa88-000c2927fe42
2、删除从库的文件并且重启从库实例问题解决
检查从库复制状态
show slave status\G;
主从正常
问题3、mysql5.7.20做从读写分离报错,信息如下
java.lang.Exception: poolName=slaves, no valid pools
at com.meidusa.amoeba.net.poolable.MultipleLoadBalanceObjectPool.borrowObject(MultipleLoadBalanceObjectPool.java:183)
at com.meidusa.amoeba.mysql.handler.CommandMessageHandler.startSession(CommandMessageHandler.java:633)
at com.meidusa.amoeba.mysql.handler.MySqlCommandDispatcher.handleMessage(MySqlCommandDispatcher.java:123)
at com.meidusa.amoeba.mysql.net.MysqlClientConnection$2.run(MysqlClientConnection.java:291)
at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
at java.lang.Thread.run(Thread.java:619)
java.util.NoSuchElementException: Could not create a validated object, cause: ValidateObject failed
at org.apache.commons.pool.impl.GenericObjectPool.borrowObject(GenericObjectPool.java:1191)
at com.meidusa.amoeba.net.poolable.GenericObjectPool.borrowObject(GenericObjectPool.java:381)
at com.meidusa.amoeba.mysql.handler.CommandMessageHandler.startSession(CommandMessageHandler.java:633)
at com.meidusa.amoeba.mysql.handler.MySqlCommandDispatcher.handleMessage(MySqlCommandDispatcher.java:123)
at com.meidusa.amoeba.mysql.net.MysqlClientConnection$2.run(MysqlClientConnection.java:291)
at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
at java.lang.Thread.run(Thread.java:619)
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
解决:
文件中数据库配置有问题,因为mysql5.5版本有test数据库,我们目前用的mysql5.7版本,必须把数据库修改为mysql,修改完成后重启,系统正常使用。