搭建主库:
# 创建目录
mkdir /data/mysql/master01 -p
cd /data/mysql/master01
mkdir conf data
chmod 777 * -R
#创建配置文件
cd /data/mysql/master01/conf
vim my.cnf
#输入如下内容
[mysqld]
log-bin=mysql-bin
server-id=1
#log-bin=mysql-bin开启二进制日志
#server-id=1 服务id,不可重复
#创建容器
docker create --name percona-master01 -v /data/mysql/master01/data:/var/lib/mysql -v /data/mysql/master01/conf:/etc/my.cnf.d -p 3306:3306 -e MYSQL_ROOT_PASSWORD=root percona:5.7.23
#启动
docker start percona-master01 && docker logs -f percona-master01
#创建同步账户以及授权
create user 'itcast'@'%' identified by 'itcast';
grant replication slave on *.* to 'itcast'@'%';
flush privileges;
#出现 [Err] 1055 - Expression #1 of ORDER BY clause is not in GROUP BY clause and错误解
决方案,在my.cnf配置文件中设置
sql_mode='STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION'
#查看master状态
show master status;
#查看二进制日志相关的配置项
show global variables like 'binlog%';
#查看server相关的配置项
show global variables like 'server%';
搭建从库:
# 创建目录
mkdir /data/mysql/slave01
cd /data/mysql/slave01
mkdir conf data
chmod 777 * -R
#创建配置文件
cd /data/mysql/slave01/conf
vim my.cnf
#输入如下内容
[mysqld]
server-id=2 #服务id,不可重复
#sql_mode='STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION'
#server-id=2 服务id,不可重复
#创建容器
docker create --name percona-slave01 -v /data/mysql/slave01/data:/var/lib/mysql -v /data/mysql/slave01/conf:/etc/my.cnf.d -p 3307:3306 -e MYSQL_ROOT_PASSWORD=root percona:5.7.23
#启动
docker start percona-slave01 && docker logs -f percona-slave01
#设置master相关信息
CHANGE MASTER TO
master_host='192.168.189.11',
master_user='itcast',
master_password='itcast',
master_port=3306,
master_log_file='mysql-bin.000004',
master_log_pos=154;
#启动同步
start slave;
#查看master状态
show slave status;
其中,在主库中,
show global variables like 'binlog%';
在查看二进制日志相关参数内容中,会发现默认的模式为 ROW,其实在MySQL中提供了有3种模式,基于SQL语句的复制(statement-based replication, SBR),基于行的复制(row-based replication, RBR),混合模式复制(mixed-based replication, MBR)。对应的,binlog的格式也有三种:STATEMENT,ROW,MIXED。
STATEMENT模式(SBR)
每一条会修改数据的sql语句会记录到binlog中。
优点是并不需要记录每一条 sql语句和每一行的数据变化,减少了binlog日志量,节约IO,提高性能。
缺点是在某些情况下会导致 master-slave中的数据不一致(如sleep()函数, last_insert_id(),以及user-definedfunctions(udf)等会出现问题)
ROW模式(RBR)
不记录每条sql语句的上下文信息,仅需记录哪条数据被修改了,修改成什么样了。而且不会出现某些特定情况下的存储过程、或function、或trigger的调用和触发无法被正确复制的问题。缺点是会产生大量的日志,尤其是altertable的时候会让日志暴涨。
MIXED模式(MBR)
以上两种模式的混合使用,一般的复制使用STATEMENT模式保存binlog,对于STATEMENT模式无法复制的操作使用ROW模式保存binlog,MySQL会根据执行的SQL语句选择日志保存方式。
建议使用MIXED模式。
# 修改主库的配置
binlog_format=MIXED
即在主库的my.cnf中拼接:
[mysqld]
log-bin=mysql-bin
server-id=1
#修改主库的配置
binlog_format=MIXED
#重启
docker restart percona-master01 && docker logs -f percona-master01
#查看二进制日志相关的配置项
show global variables like 'binlog%';
在slave中:
STOP SLAVE
再重新运行:(master_log_file和master_log_pos需要更新)
CHANGE MASTER TO
master_host='192.168.189.11',
master_user='itcast',
master_password='itcast',
master_port=3306,
master_log_file='mysql-bin.000004',
master_log_pos=154;
再次启动从库:
START SLAVE
#查看master状态
show slave status;
数据库分片:
再新建一个集群:
建主库:
配置master:
# 搭建master
#创建目录
mkdir /data/mysql/master02
cd /data/mysql/master02
mkdir conf data
chmod 777 * -R
#创建配置文件
cd /data/mysql/master02/conf
vim my.cnf
#输入如下内容
[mysqld]
#开启二进制日志
log-bin=mysql-bin
#服务id,不可重复
server-id=1
sql_mode='STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERONO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION'
# 创建容器
docker create --name percona-master02 -v /data/mysql/master02/data:/var/lib/mysql -v /data/mysql/master02/conf:/etc/my.cnf.d -p 3316:3306 -e MYSQL_ROOT_PASSWORD=root percona:5.7.23
#启动
docker start percona-master02 && docker logs -f percona-master02
#创建同步账户以及授权
create user 'itcast'@'%' identified by 'itcast';
grant replication slave on *.* to 'itcast'@'%';
flush privileges;
#查看master状态
show master status;
配置slave:
# 搭建从库
#创建目录
mkdir /data/mysql/slave02
cd /data/mysql/slave02
mkdir conf data
chmod 777 * -R
#创建配置文件
cd /data/mysql/slave02/conf
vim my.cnf
#输入如下内容
[mysqld]
#服务id,不可重复
server-id=2
sql_mode='STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION'
#创建容器
docker create --name percona-slave02 -v /data/mysql/slave02/data:/var/lib/mysql -v /data/mysql/slave02/conf:/etc/my.cnf.d -p 3317:3306 -e MYSQL_ROOT_PASSWORD=root percona:5.7.23
#启动
docker start percona-slave02 && docker logs -f percona-slave02
#设置master相关信息
CHANGE MASTER TO
master_host='192.168.189.11',
master_user='itcast',
master_password='itcast',
master_port=3316,
master_log_file='mysql-bin.000003',
master_log_pos=743;
# 启动同步
start slave;
#查看master状态
show slave status;
配置MyCat
自行安装mycat,直接解压就行。
cd /usr/local/mycat/conf
vim schema.xml
替换掉该文件内容:
schema.xml:
<?xml version="1.0"?>
<!DOCTYPE mycat:schema SYSTEM "schema.dtd">
<mycat:schema xmlns:mycat="http://io.mycat/">
<!--配置数据表-->
<schema name="itcast" checkSQLschema="false" sqlMaxLimit="100">
<table name="tb_ad" dataNode="dn1,dn2" rule="mod-long" />
</schema>
<!--配置分片关系-->
<dataNode name="dn1" dataHost="cluster1" database="itcast" />
<dataNode name="dn2" dataHost="cluster2" database="itcast" />
<!--配置连接信息-->
<dataHost name="cluster1" maxCon="1000" minCon="10" balance="3"
writeType="1" dbType="mysql" dbDriver="native" switchType="1"
slaveThreshold="100">
<heartbeat>select user()</heartbeat>
<writeHost host="W1" url="192.168.189.11:3306" user="root"
password="root">
<readHost host="W1R1" url="192.168.189.11:3307" user="root"
password="root" />
</writeHost>
</dataHost>
<dataHost name="cluster2" maxCon="1000" minCon="10" balance="3"
writeType="1" dbType="mysql" dbDriver="native" switchType="1"
slaveThreshold="100">
<heartbeat>select user()</heartbeat>
<writeHost host="W2" url="192.168.189.11:3316" user="root"
password="root">
<readHost host="W2R1" url="192.168.189.11:3317" user="root"
password="root" />
</writeHost>
</dataHost>
</mycat:schema>
试图启动mycat:
./mycat console
Running Mycat-server…
wrapper | --> Wrapper Started as Console
wrapper | Launching a JVM…
jvm 1 | Java HotSpot™ 64-Bit Server VM warning: ignoring option MaxPermSize=64M; support was removed in 8.0
jvm 1 | Wrapper (Version 3.2.3) http://wrapper.tanukisoftware.org
jvm 1 | Copyright 1999-2006 Tanuki Software, Inc. All Rights Reserved.
jvm 1 |
jvm 1 |
jvm 1 | WrapperSimpleApp: Encountered an error running main: java.lang.ExceptionInInitializerError
jvm 1 | java.lang.ExceptionInInitializerError
jvm 1 | at io.mycat.MycatStartup.main(MycatStartup.java:53)
jvm 1 | at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
jvm 1 | at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
jvm 1 | at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
jvm 1 | at java.lang.reflect.Method.invoke(Method.java:498)
jvm 1 | at org.tanukisoftware.wrapper.WrapperSimpleApp.run(WrapperSimpleApp.java:240)
jvm 1 | at java.lang.Thread.run(Thread.java:748)
jvm 1 | Caused by: io.mycat.config.util.ConfigException: Illegal table conf : table [ TB_AD ] rule function [ mod-long ] partition size : 3 > table datanode size : 2, please make sure table datanode size = function partition size
jvm 1 | at io.mycat.config.loader.xml.XMLSchemaLoader.checkRuleSuitTable(XMLSchemaLoader.java:569)
jvm 1 | at io.mycat.config.loader.xml.XMLSchemaLoader.loadTables(XMLSchemaLoader.java:396)
jvm 1 | at io.mycat.config.loader.xml.XMLSchemaLoader.loadSchemas(XMLSchemaLoader.java:168)
jvm 1 | at io.mycat.config.loader.xml.XMLSchemaLoader.load(XMLSchemaLoader.java:117)
jvm 1 | at io.mycat.config.loader.xml.XMLSchemaLoader.(XMLSchemaLoader.java:78)
jvm 1 | at io.mycat.config.loader.xml.XMLSchemaLoader.(XMLSchemaLoader.java:82)
jvm 1 | at io.mycat.config.ConfigInitializer.(ConfigInitializer.java:76)
jvm 1 | at io.mycat.config.MycatConfig.(MycatConfig.java:72)
jvm 1 | at io.mycat.MycatServer.(MycatServer.java:158)
jvm 1 | at io.mycat.MycatServer.(MycatServer.java:101)
jvm 1 | … 7 more
wrapper | <-- Wrapper Stopped
如果想要试图查看mycat日志:(本步骤可忽略)
more ../logs/mycat.log
其实,这里已经说的很清楚了,
Caused by: io.mycat.config.util.ConfigException: Illegal table conf : table [ TB_AD ] rule function [ mod-long ] partition size : 3 > table datanode size : 2, please make sure table datanode size = function partition size
配置中需要3个节点,而你的schema.xml只配置了2个
你可以再增加一个节点,或者修改rule.xml,将节点数修改为2个。
rule.xml:
将此处的count标签下3修改为为2;
< function name="mod-long" class="io.mycat.route.function.PartitionByMod">
<property name="count">2</property>
</function>
再次试图启动:
./mycat console
报错:schema TESTDB refered by user root is not exist
对于schema 中,用户为:itcast
而server.xml中,
用户默认为user
将server.xml中的用户修改
<user name="itcast">
<property name="password">itcast</property>
<property name="schemas">itcast</property>
<property name="readOnly">true</property>
</user>
因为schema.xml中,只有<schema name=“itcast”
所以,所有的用户的schemas标签的值都应该为itcast。
我的所有server.xml配置:
<?xml version="1.0" encoding="UTF-8"?>
<!-- - - Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License. - You
may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0
- - Unless required by applicable law or agreed to in writing, software -
distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT
WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the
License for the specific language governing permissions and - limitations
under the License. -->
<!DOCTYPE mycat:server SYSTEM "server.dtd">
<mycat:server xmlns:mycat="http://io.mycat/">
<system>
<property name="nonePasswordLogin">0</property> <!-- 0为需要密码登陆、1为不需要密码登陆 ,默认为0,设置为1则需要指定默认账户-->
<property name="useHandshakeV10">1</property>
<property name="useSqlStat">0</property> <!-- 1为开启实时统计、0为关闭 -->
<property name="useGlobleTableCheck">0</property> <!-- 1为开启全加班一致性检测、0为关闭 -->
<property name="sequnceHandlerType">2</property>
<property name="subqueryRelationshipCheck">false</property> <!-- 子查询中存在关联查询的情况下,检查关联字段中是否有分片字段 .默认 false -->
<!-- <property name="useCompression">1</property>--> <!--1为开启mysql压缩协议-->
<!-- <property name="fakeMySQLVersion">5.6.20</property>--> <!--设置模拟的MySQL版本号-->
<!-- <property name="processorBufferChunk">40960</property> -->
<!--
<property name="processors">1</property>
<property name="processorExecutor">32</property>
-->
<!--默认为type 0: DirectByteBufferPool | type 1 ByteBufferArena | type 2 NettyBufferPool -->
<property name="processorBufferPoolType">0</property>
<!--默认是65535 64K 用于sql解析时最大文本长度 -->
<!--<property name="maxStringLiteralLength">65535</property>-->
<!--<property name="sequnceHandlerType">0</property>-->
<!--<property name="backSocketNoDelay">1</property>-->
<!--<property name="frontSocketNoDelay">1</property>-->
<!--<property name="processorExecutor">16</property>-->
<!--
<property name="serverPort">8066</property> <property name="managerPort">9066</property>
<property name="idleTimeout">300000</property> <property name="bindIp">0.0.0.0</property>
<property name="frontWriteQueueSize">4096</property> <property name="processors">32</property> -->
<!--分布式事务开关,0为不过滤分布式事务,1为过滤分布式事务(如果分布式事务内只涉及全局表,则不过滤),2为不过滤分布式事务,但是记录分布式事务日志-->
<property name="handleDistributedTransactions">0</property>
<!--
off heap for merge/order/group/limit 1开启 0关闭
-->
<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>
<!-- 全局SQL防火墙设置 -->
<!--白名单可以使用通配符%或着*-->
<!--例如<host host="127.0.0.*" user="root"/>-->
<!--例如<host host="127.0.*" user="root"/>-->
<!--例如<host host="127.*" user="root"/>-->
<!--例如<host host="1*7.*" user="root"/>-->
<!--这些配置情况下对于127.0.0.1都能以root账户登录-->
<!--
<firewall>
<whitehost>
<host host="1*7.0.0.*" user="root"/>
</whitehost>
<blacklist check="false">
</blacklist>
</firewall>
-->
<user name="root" defaultAccount="true">
<property name="password">root</property>
<property name="schemas">itcast</property>
<!-- 表级 DML 权限设置 -->
<!--
<privileges check="false">
<schema name="TESTDB" dml="0110" >
<table name="tb01" dml="0000"></table>
<table name="tb02" dml="1111"></table>
</schema>
</privileges>
-->
</user>
<user name="itcast">
<property name="password">itcast</property>
<property name="schemas">itcast</property>
<property name="readOnly">true</property>
</user>
</mycat:server>
再次启动mycat:
[root@centos7_01 bin]# ./mycat console
Running Mycat-server...
wrapper | --> Wrapper Started as Console
wrapper | Launching a JVM...
jvm 1 | Java HotSpot(TM) 64-Bit Server VM warning: ignoring option MaxPermSize=64M; support was removed in 8.0
jvm 1 | Wrapper (Version 3.2.3) http://wrapper.tanukisoftware.org
jvm 1 | Copyright 1999-2006 Tanuki Software, Inc. All Rights Reserved.
jvm 1 |
jvm 1 | MyCAT Server startup successfully. see logs in logs/mycat.log
successfully
启动mycat进行测试(本步骤可以忽略):
./startup_nowrap.sh && tail -f ../logs/mycat.log