搭建主库:

# 创建目录
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%';

docker 容器里的root 密码是多少_mysql


在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