场景描述
一台mycat:
192.168.81.129:8066
两台mysql:
Master:192.168.81.129:3306【主(写)数据库】
Slave :192.168.81.130:3306【从(读)数据库】
注意
1.在用mycat实现读写分离之前需要先对两台mysql进行主从同步配置
2.两台数据库服务器的的 selinux 都要 disable(永久关闭 selinux,请修改/etc/selinux/config,将 SELINUX 改为 disabled)
mysql配置主从同步
修改Master的配置文件vi /etc/mycnf
:
主要参数:server_id、log-bin
关于路径的参数根据自身服务器路径配置
[client]
port = 3306
[mysqld]
## 设置 server_id
server_id=1
## 复制过滤:需要备份的数据库,输出 binlog
binlog-do-db=test1
binlog-do-db=test2
## 复制过滤:不需要备份的数据库,不输出(mysql 库一般不同步)
#binlog-ignore-db=test3
## 开启二进制日志功能,可以随便取,最好有含义
log-bin=mysql-bin
## 为每个 session 分配的内存,在事务过程中用来存储二进制日志的缓存
binlog_cache_size=1M
## 主从复制的格式(mixed,statement,row,默认格式是 statement)
binlog_format=mixed
## 二进制日志自动删除/过期的天数。默认值为 0,表示不自动删除。
expire_logs_days=7
## 跳过主从复制中遇到的所有错误或指定类型的错误,避免 slave 端复制中断。
## 如:1062 错误是指一些主键重复,1032 错误是因为主从数据库数据不一致
slave_skip_errors=1062
修改Slave的配置文件vi /etc/mycnf
:
主要参数:server_id、log-bin、relay_log、read_only
关于路径的参数根据自身服务器路径配置
[client]
port = 3306
[mysqld]
## 设置 server_id
server_id=2
## 复制过滤:需要备份的数据库,输出 binlog
binlog-do-db=test1
binlog-do-db=test2
## 复制过滤:不需要备份的数据库,不输出(mysql 库一般不同步)
#binlog-ignore-db=test3
## 开启二进制日志,以备 Slave 作为其它 Slave 的 Master 时使用
log-bin=mysql-slave-bin
## 为每个 session 分配的内存,在事务过程中用来存储二进制日志的缓存
binlog_cache_size = 1M
## 主从复制的格式(mixed,statement,row,默认格式是 statement)
binlog_format=mixed
## 二进制日志自动删除/过期的天数。默认值为 0,表示不自动删除。
expire_logs_days=7
## 跳过主从复制中遇到的所有错误或指定类型的错误,避免 slave 端复制中断。
## 如:1062 错误是指一些主键重复,1032 错误是因为主从数据库数据不一致
slave_skip_errors=1062
## relay_log 配置中继日志
relay_log=mysql-relay-bin
## log_slave_updates 表示 slave 将复制事件写进自己的二进制日志
log_slave_updates=1
## 防止改变数据(除了特殊的线程)
read_only=1
分别重启Master和Slave的mysql服务service mysql restart
Master授权数据同步用户:
[root@mysql-01 ~]# mysql -uroot -p
Enter password:
##创建数据同步用户,并授予相应的权限
mysql> grant replication slave, replication client on *.* to '用户名'@'192.168.81.130' identified by '密码';
## 刷新授权表信息
mysql> flush privileges;
mysql> show master status;
记下 File和Position(Slave需要用到):
File: mysql-bin.000003
Posittion: 2832
备份Master数据库的数据(这里只备份test1数据库的数据):
## 先临时锁表
mysql> flush tables with read lock;
## 备份test1数据库
[root@localhost /]# mysqldump -p3306 -uroot -p --add-drop-table test1 > /tmp/test1.sql
## 解锁表
mysql> unlock tables;
## 将Master上备份的数据远程传送到Slave上,以用于Slave配置时恢复数据
[root@localhost /]# scp /tmp/test1.sql root@192.168.81.130:/tmp/
root@192.168.81.130's password:
test1.sql 100% 2123 2.1KB/s 00:00
Slave数据库还原上面备份的数据(需要先创建test1数据库):
## 导入数据
[root@localhost /]# mysql -uroot -p test1 < /tmp/test1.sql
Enter password:
登录Slave数据库,添加相关参数
[root@localhost /]# mysql -uroot -p
Enter password:
mysql>change master to master_host='192.168.81.129',
master_user='用户名',
master_password='同步用户的密码',
master_port=3306,
master_log_file='mysql-bin.000003',
master_log_pos=2832,
master_connect_retry=30;
Query OK, 0 rows affected, 2 warnings (0.01 sec)
## 查看主从同步状态
## Slave_IO_Running 和 Slave_SQL_Running 是 No,表明 Slave 还没有开始复制过程。
mysql> show slave status\G;
## 开启主从同步
mysql> start slave;
Query OK, 0 rows affected (0.00 sec)
## 再次查看主从同步状态
## Slave_IO_Running 和 Slave_SQL_Running 是 Yes,表明 Slave 已经开始复制过程
mysql> show slave status\G;
清除slave信息(需要修改上面参数时用):
mysql> stop slave;
mysql> reset slave all;
参数描述:
master_host:Master的IP地址
master_user:用于同步数据的用户(在 Master 中授权的用户)
master_password: 同步数据用户的密码
master_port=3306:Master数据库服务的端口
master_log_file:指定Slave从哪个日志文件开始读复制数据(show master status 查询到的File)
master_log_pos:从哪个Posittion号开始读(show master status 查询到的Posittion)
master_connect_retry:当重新建立主从连接时,如果连接建立失败,间隔多久后重试。单位为秒,默认设置为60秒。
mycat配置读写分离
schema.xml:
<?xml version="1.0"?>
<!DOCTYPE mycat:schema SYSTEM "schema.dtd">
<mycat:schema xmlns:mycat="http://io.mycat/">
<!-- 有几个数据库,就有几个schema标签 -->
<schema name="test1" checkSQLschema="false" sqlMaxLimit="100" dataNode="dn1"></schema>
<schema name="test2" checkSQLschema="false" sqlMaxLimit="100" dataNode="dn2"></schema>
<dataNode name="dn1" dataHost="localhost1" database="test1" />
<dataNode name="dn2" dataHost="localhost1" database="test2" />
<dataHost name="localhost1" maxCon="1000" minCon="10" balance="1"
writeType="0" dbType="mysql" dbDriver="native" switchType="-1" slaveThreshold="100">
<heartbeat>select user()</heartbeat>
<!-- 写数据库-->
<writeHost host="hostM1" url="192.168.81.129:3306" user="root" password="123456">
<!-- 读数据库-->
<readHost host="HostS1" url="192.168.81.130:3306" user="root" password="123456" />
</writeHost>
</dataHost>
</mycat:schema>
server.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mycat:server SYSTEM "server.dtd">
<mycat:server xmlns:mycat="http://io.mycat/">
<system>
<!-- 0为需要密码登陆、1为不需要密码登陆 ,默认为0,设置为1则需要指定默认账户-->
<property name="nonePasswordLogin">0</property>
<property name="useHandshakeV10">1</property>
<!-- 1为开启实时统计、0为关闭 -->
<property name="useSqlStat">0</property>
<!-- 1为开启全加班一致性检测、0为关闭 -->
<property name="useGlobleTableCheck">0</property>
<property name="sequnceHandlerType">2</property>
<!-- 子查询中存在关联查询的情况下,检查关联字段中是否有分片字段 .默认 false -->
<property name="subqueryRelationshipCheck">false</property>
<!--默认为type 0: DirectByteBufferPool | type 1 ByteBufferArena | type 2 NettyBufferPool -->
<property name="processorBufferPoolType">0</property>
<!--分布式事务开关,0为不过滤分布式事务,1为过滤分布式事务(如果分布式事务内只涉及全局表,则不过滤),2为不过滤分布式事务,但是记录分布式事务日志-->
<!--off heap for merge/order/group/limit 1开启 0关闭-->
<property name="handleDistributedTransactions">0</property>
<property name="useOffHeapForMerge">1</property>
<!--单位为m-->
<property name="memoryPageSize">64k</property>
<!--单位为k-->
<property name="spillsFileBufferSize">1k</property>
<property name="useStreamOutput">0</property>
<!--单位为m-->
<property name="systemReserveMemorySize">384m</property>
<!--是否采用zookeeper协调切换 -->
<property name="useZKSwitch">false</property>
<!-- XA Recovery Log日志路径 -->
<!--<property name="XARecoveryLogBaseDir">./</property>-->
<!-- XA Recovery Log日志名称 -->
<!--<property name="XARecoveryLogBaseName">tmlog</property>-->
<!--如果为 true的话 严格遵守隔离级别,不会在仅仅只有select语句的时候在事务中切换连接-->
<property name="strictTxIsolation">false</property>
<property name="useZKSwitch">true</property>
</system>
<!-- 创建mycat的root用户 -->
<user name="root" defaultAccount="true">
<!-- 连接mycat的密码 -->
<property name="password">123456</property>
<!-- 指向schemas.xml中的schemas标签的name,多个schemas用逗号分隔 -->
<property name="schemas">test1,test2</property>
</user>
<!-- 创建mycat的只读用户 -->
<user name="user">
<!-- 连接mycat的密码 -->
<property name="password">user</property>
<!-- 指向schemas.xml中的schemas标签的name,多个schemas用逗号分隔 -->
<property name="schemas">test1,test2</property>
<property name="readOnly">true</property>
</user>
</mycat:server>
mycat环境配置
修改conf/wrapper.conf文件,wrapper.java.command设置为java的路径
[root@localhost /]# vi /usr/local/mycat/conf/wrapper.conf
/usr/local/jdk/bin/java
建立软件连接
ln -s /安装目录/bin/mycat /etc/init.d/mycat
加入开机启动
chkconfig --add mycat
启动mycat
mycat start
测试
-
分别连接mycat和两台mysql
-
在mycat中添加一条记录
结论:在mycat中添加一条记录,在Master和Slave中都查询到了相同的数据。
-
在Masrter中手动修改记录中的字段
结论:在Masrter中修改一条记录,mycat和Slave中的数据都发生了改变。 -
在Slave中手动修改记录中的字段
结论:在Slave中修改一条记录,mycat中的数据发生了改变,但是Masrter中的数据没有改变,说明mycat的读操作调用的是Slave数据库。
安装mycat参考:https://www.cnblogs.com/linjiqin/p/7879903.html
主从同步相关配置参考:https://www.cnblogs.com/gaogaoyanjiu/p/10236582.html
mycat实现分库分表:https://blog.csdn.net/weixin_43625121/article/details/111668984