目录
一、概述
1、MyCat是什么?
2、原理:
3、能干什么
1、读写分离
2、数据分片
3、多数据源整合
4、Mycat监控
4、安装部署
1、环境准备
2、安装
3、Mycat配置详解
1、server.xml
user 标签
2、schema.xml
schema标签:
table标签:
childTable 标签:
dataNode标签:
dataHost 标签:
heartbeat 标签:
writeHost 标签、readHost 标签:
3、rule.xml
tableRule 标签:
function 标签:
4、使用 示例
1、垂直分库
2、配置水平分表
一、概述
1、MyCat是什么?
它是一个开源的分布式数据库系统,可以理解成 Mycat 就是MySQL Server,而Mycat 后面连接的MySQL Server,就好象是MySQL 的存储引擎,如InnoDB,MyISAM 等,因此,Mycat 本身并不存储数据,数据是在后端的MySQL 上存储的,因此数据可靠性以及事务等都是MySQL 保证的。
2、原理:
最重要的就是“拦截”,他拦截了用户发送过来的SQL语句,首先对sql语句做了一些分析:如分片、路由分析、读写分离分析、缓存分析等,然后再将此sql发往后端真实数据库,并将返回结果做适当处理,再返回给客户。
3、能干什么
1、读写分离
2、数据分片
垂直拆分(分库)、水平拆分(分表)、垂直+水平拆分(分库分表)
3、多数据源整合
4、Mycat监控
- 支持对Mycat、Mysql性能监控
- 支持对Mycat的JVM内存提供监控服务
- 支持对线程的监控
- 支持对操作系统的CPU、内存、磁盘、网络的监控
4、安装部署
1、环境准备
192.168.134.132
192.168.134.133
192.168.134.134
2、安装
1、下载
http://dl.mycat.org.cn/1.6.7.5/2020-4-10/
2、上传解压到/usr/local/
[root@rabbitmq_1 local]# tar -zxvf Mycat-server-1.6.7.5-release-20200410174409-linux.tar.gz
[root@rabbitmq_1 mycat]# ls
bin catlet conf lib logs version.txt
bin 程序目录,存放了启动脚本
./mycat start 启动
./mycat stop 停止
./mycat restart 重启
./mycat status 查看mycat的启动状态
conf 目录下存放配置文件,修改配置文件,需要重启Mycat
schema.xml: 定义逻辑库,表、分片节点等内容
rule.xml: 定义分片规则
server.xml: 定义用户以及系统相关变量,如端口等
lib 目录下主要存放mycat 依赖的一些jar 文件
日志存放在logs/mycat.log 中,每天一个文件,日志的配置是在conf/log4j.xml 中
配置环境变量
vi /etc/profile
添加如下配置信息:
export MYCAT_HOME=/usr/local/mycat
export PATH=$MYCAT_HOME/bin:$PATH:$JAVA_HOME/bin
3、登录
目前mycat 有两个端口,8066 数据端口,9066 管理端口,命令行的登陆是通过9066 管理端口来操作,登录方式类似于mysql 的服务端登陆。
mysql -h127.0.0.1 -utest -ptest -P9066 [-dmycat]
4、常用管理命令
-h 后面是主机,即当前mycat 按照的主机地址,本地可用127.0.0.1 远程需要远程ip
-u Mycat server.xml 中配置的逻辑库用户
-p Mycat server.xml 中配置的逻辑库密码
-P 后面是端口默认9066,注意P 是大写
-d Mycat server.xml 中配置的逻辑库
show @@help:查看所有的命令
reload @@config;该命令用于更新配置文件,例如更新schema.xml 文件后在命令行窗口输入该命令,可不用重启即进行配置文件更新。
show @@database;该命令用于显示MyCAT 的数据库的列表,对应schema.xml 配置文件的schema 子节点
show @@datanode;该命令用于显示MyCAT 的数据节点的列表,对应schema.xml 配置文件的dataNode 节点,其中,“NAME”表示dataNode 的名称;“dataHost”表示对应dataHost 属性的值,即数据主机;“ACTIVE”表示活跃连接数;“IDLE”表示闲置连接数;“SIZE”对应总连接数量。
运行如下命令,可查找对应的schema 下面的dataNode 列表:
show @@datanode where schema = ?
show @@version该命令用于获取MyCAT 的版本
show @@connection该命令用于获取Mycat 的前端连接状态,即应用与mycat 的连接
kill @@connection id,id,id用于杀掉连接。
show @@backend查看后端连接状态。
show @@sql ; 用来记录用户通过本地8066 端口向Mycat-Server 发送的SQL 请求执行信息
show @@sql.slow ; 请求执行SQL 语句中超过慢SQL 时间阈值的(reload @@sqlslow=0 ; # 是的这条命令就是刚才提到的'如何设定慢SQL' 时间阈值的命令)
show @@sql.sum ; 执行的SQL 命令的统计信息数据
3、Mycat配置详解
1、server.xml
server.xml 几乎保存了所有mycat 需要的系统配置信息
user 标签
<user name="test" defaultAccount="true"> //对应的是mycat的用户名和密码
<property name="password">test</property>
<property name="schemas">TESTDB</property>
<property name="defaultSchema">TESTDB</property>
<!--No MyCAT Database selected 错误前会尝试使用该schema作为schema,不设置则为null,报错 -->
<!-- 表级 DML 权限设置 -->
<!--
<privileges check="false">
<schema name="TESTDB" dml="0110" >
<table name="tb01" dml="0000"></table>
<table name="tb02" dml="1111"></table>
</schema>
</privileges>
-->
</user>
详解:
用户相关配置:
name:设置用户的用户名,这里为 "root"。
defaultAccount:指定该用户是否为默认账户,这里设置为 "true"。
password:设置该用户的密码,这里密码为 "123456"。
schemas:指定该用户可访问的数据库(schema),这里用户具有访问 "TESTDB" 数据库的权限。
defaultSchema:指定用户默认使用的数据库(schema),这里设置为 "TESTDB"。
表级 DML 权限设置:
privileges 元素的 check 属性可以控制是否检查表级权限,这里设置为 "false",表示不进行检查。
在 privileges 元素内部,通过 schema 元素来配置不同的数据库(schema)的权限。
schema 元素的 name 属性指定数据库的名称,这里为 "TESTDB"。
schema 元素的 dml 属性用于设置数据库级别的 DM权限,这里设置为 "0110",表示该用户对数据库可以执行INSERT 和 UPDATE 操作。
在 schema 元素内部,通过 table 元素来配置不同表的权限。
table 元素的 name 属性指定表的名称,这里包括 "tb01" 和 "tb02"。
table 元素的 dml 属性用于设置表级别的 DML 权限,这里对于 "tb01" 表设置为 "0000",表示该用户对该表没有任何 DML 权限;对于 "tb02" 表设置为 "1111",表示该用户对该表具有 SELECT、INSERT、UPDATE 和 DELETE 的完全权限。
0和1 表示DML语句的权限,SELECT、INSERT、UPDATE、DELETE,0代表没有权限。1代表有权限。
2、schema.xml
schema.xml 作为MyCat中重要的配置文件之一,管理着MyCat的逻辑库、表、分片规则、DataNode以及DataSource。搞懂这些配置是正确使用MyCat的前提。
<?xml version="1.0"?>
<!DOCTYPE mycat:schema SYSTEM "schema.dtd">
<mycat:schema xmlns:mycat="http://io.mycat/">
<!-->schema标签用于定义MyCat示例中的逻辑库<-->
<!-->name 虚拟库的名字,对应刚刚在server.xml中设置的TESTDB <-->
<!-->randomDataNode 虚拟库对应的真实database,值为dataNode标签的name<-->
<!-->checkSQLschema 是否检查自动删除 “虚拟库名”<-->
<!-->sqlMaxLimit 允许最大查询记录数<-->
<schema name="TESTDB" checkSQLschema="true" sqlMaxLimit="100" randomDataNode="dn1"> //
<!-- 可以访问的表,只有设置在这里的表才会被MyCat管理访问 dataNode:虚拟库对应的真实database,对应<dataNode>标签。
如果做分片,则配置多个,用逗号分隔;或者使用db$0-99,代表db0到db99的database rule:分片规则,如果没有则删除
-->
<table name="customer" primaryKey="id" dataNode="dn1,dn2" rule="sharding-by-intfile" autoIncrement="true" fetchStoreNodeByJdbc="true">
<childTable name="customer_addr" primaryKey="id" joinKey="customer_id" parentKey="id"> </childTable>
</table>
</schema>
<!-- 真实的database信息,每一个dataNode就是一个数据库分片
name:虚拟名称
dataHost:真实库的主机信息,对应<dataHost>标签
database:真实MySQL中真实的物理数据库名称
-->
<dataNode name="dn1" dataHost="localhost1" database="db1" />
<dataNode name="dn2" dataHost="localhost1" database="db2" />
<dataNode name="dn3" dataHost="localhost1" database="db3" />
<!-- 真实库的主机信息
name:主机名,name属性值要与dataNode节点中的dataHost属性值对应
maxCon:最大连接, minCon:最小连接
balance:负载均衡方式:0~3四种选项。0,不开启读写分离。1~3都开启,区别是主是否参与读
writeType:写负载均衡。永远设置0
dbDriver:驱动类型,推荐native,可选jdbc
switchType:主从的自动切换
-->
<dataHost name="localhost1" maxCon="1000" minCon="10" balance="0"
writeType="0" dbType="mysql" dbDriver="jdbc" switchType="1" slaveThreshold="100">
<heartbeat>select user()</heartbeat>
<!-- 这里设置写主机信息 -->
<writeHost host="hostM1" url="jdbc:mysql://localhost:3306" user="root"
password="123456">
<!-- 这里设置读主机信息 -->
<readHost host="hostS1" url="192.168.134.132:3306" user="root" password="123456" />
</writeHost>
</dataHost>
</mycat:schema>
schema标签:
用于定义MyCat示例中的逻辑库,MyCat 可以有多个逻辑库,每个逻辑库都有自己的相关配置。可以使用schema 标签来划分这些不同的逻辑库。如果不配置schema 标签,所有的表配置,会属于同一个默认的逻辑库。
<schema name="TESTDB" checkSQLschema="true" sqlMaxLimit="100" randomDataNode="dn1">
<!-->table 标签是定义需要分片的表<-->
<table name="customer" primaryKey="id" dataNode="dn1,dn2" rule="sharding-by-intfile" autoIncrement="true" fetchStoreNodeByJdbc="true">
<childTable name="customer_addr" primaryKey="id" joinKey="customer_id" parentKey="id"> </childTable>
</table>
</schema>
相关属性:
属性名 | 值 | 数量限制 |
checkSQLschema | Boolean | 1 |
sqlMaxLimit | integer | 1 |
randomDataNode | 任意string | (0...1) |
table标签:
定义了MyCat 中的逻辑表,所有需要拆分的表都需要在这个标签中定义。
相关属性:
属性名 | 值 | 说明 |
name | string | 表名 |
dataNode | string | 数据节点,该属性的值需要和dataNode 标签中name 属性的值相互对应 |
rule | string | 分片规则名字,规则名字在rule.xml 中定义,必须与tableRule 标签中name 属性属性值一一对应。 |
ruleRequired | Boolean | 该属性用于指定表是否绑定分片规则,如果配置为true,但没有配置具体rule 的话,程序会报错。 |
primaryKey | string | 主键 |
type | string | 属性:只有全局表(global)、普通表(不知道该值为global的所有表) |
autoIncrement | Boolean | true。表示id字段将自动递增生成唯一的值 |
subTables | string | |
needAddLimit | Boolean | 是否添加limit限制,配置文件已经添加 |
fetchStoreNodeByJdbc | Boolean |
<table name="customer" primaryKey="id" dataNode="dn1,dn2" rule="sharding-by-intfile" autoIncrement="true" fetchStoreNodeByJdbc="true">
childTable 标签:
<childTable name="customer_addr" primaryKey="id" joinKey="customer_id" parentKey="id"> </childTable>
用于定义E-R 分片的子表。通过标签上的属性与父表进行关联。
相关属性:
属性名 | 值 | 说明 |
name | string | 子表名 |
primaryKey | string | 主键 |
joinKey | string | 插入子表的时候会使用这个列的值查找父表存储的数据节点。 |
parentKey | string | 一般为与父表建立关联关系的列名。程序首先获取joinkey 的值,再通过parentKey 属性指定的列名产生查询语句,通过执行该语句得到父表存储在哪个分片上。从而确定子表存储的位置。 |
dataNode标签:
<dataNode name="dn1" dataHost="localhost1" database="db1" />
:定义了MyCat中的数据节点,也就是我们通常说所的数据分片。一个dataNode 标签就是一个独立的数据分片。
例子中所表述的意思为:使用名字为localhost1 数据库实例上的db1 物理数据库,这就组成一个数据分片,最后,我们使用名字dn1 标识这个分片。
dataNode属性:
属性名 | 值 | 说明 |
name | string | 节点名称 唯一的,我们需要在table 标签上应用这个名字,来建立表与分片对应的关系。 |
dataHost | string | 数据主机,属性值是引用dataHost 标签上定义的name 属性。 |
database | string | 数据库名称 |
dataHost 标签:
作为Schema.xml 中最后的一个标签,该标签在mycat 逻辑库中也是作为最底层的标签存在,直接定义了具体的数据库实例、读写分离配置和心跳语句。
<dataHost name="localhost1" maxCon="1000" minCon="10" balance="0"
writeType="0" dbType="mysql" dbDriver="jdbc" switchType="1" slaveThreshold="100">
<heartbeat>select user()</heartbeat>
<!-- can have multi write hosts -->
<writeHost host="hostM1" url="jdbc:mysql://localhost:3306" user="root"
password="root">
</writeHost>
<!-- <writeHost host="hostM2" url="localhost:3316" user="root" password="123456"/> -->
</dataHost>
相关属性:
属性名 | 值 | 说明 |
name | string | 唯一标识dataHost 标签,供上层的标签使用。 |
maxCon | interger | 最大连接数 |
minCon | interger | 最小连接数 |
balance | interger | 负载均衡的方式, 0:不开启读写分离机制,所有读操作都发送到当前可用的writeHost 上。 1:简单的说,当双主双从模式(M1->S1,M2->S2,并且M1 与M2 互为主备),正常情况下,M2,S1,S2 都参与select 语句的负载均衡。 2:所有读操作都随机的在writeHost、readhost 上分发。 3: |
writeType | interger | 写入类型: 0:表示写入操作的类型,默认为同步写入。 |
dbType | string | 数据库类型 |
dbDriver | string | 数据库驱动 |
switchType | interger | 切换方式: -1:表示不自动切换 1:默认值,自动切换 2:基于MySQL 主从同步的状态决定是否切换 心跳语句为show slave status 3:基于MySQL galary cluster 的切换机制(适合集群) 心跳语句为show status like ‘wsrep%’ |
slaveThreshold | interger | Mycat 心跳机制通过检测show slave status 中的"Seconds_Behind_Master", "Slave_IO_Running","Slave_SQL_Running" 三个字段来确定当前主从同步的状态以及Seconds_Behind_Master 主从复制时延,当Seconds_Behind_Master>slaveThreshold 时,读写分离筛选器会过滤掉此Slave 机器,防止读到很久之前的旧数据。 |
heartbeat 标签:
这个标签内指明用于和后端数据库进行心跳检查的语句。例如,MYSQL 可以使用select user()
writeHost 标签、readHost 标签:
这两个标签都指定后端数据库的相关配置给mycat,用于实例化后端连接池。唯一不同的是,writeHost指定写的示例,readHost指定读实例,在一个dataHost 内可以定义多个writeHost 和readHost。但是,如果writeHost 指定的后端数据库宕机,那么这个writeHost 绑定的所有readHost 都将不可用。另一方面,由于这个writeHost 宕机系统会自动的检测到,并切换到备用的writeHost 上去。
两个标签的属性相同:
属性名 | 值 | 说明 |
host | string | 用于表示不同实例,一般writeHost我们用M1,readHost我们用S1 |
url | string | 连接点url |
password | string | 密码 |
user | string | 用户名 |
weight | string | 权重配置在readhost 中作为读节点的权重 |
usingDecrypt | string | 加密的,很少用 |
3、rule.xml
rule.xml 里面就定义了我们对表进行拆分所涉及到的规则定义。我们可以灵活的对表使用不同的分片算法,或者对表使用相同的算法但具体的参数不同。这个文件里面主要有tableRule 和function 这两个标签。在具体使用过程中可以按照需求添加tableRule 和function。
tableRule 标签:
<tableRule name="rule1">
<rule>
<columns>id</columns>
<algorithm>func1</algorithm>
</rule>
</tableRule>
name 属性指定唯一的名字,用于标识不同的表规则。
内嵌的rule 标签则指定对物理表中的哪一列进行拆分和使用什么路由算法。
columns 内指定要拆分的列名字。
algorithm 使用function 标签中的name 属性。连接表规则和具体路由算法。当然,多个表规则可以连接到同一个路由算法上。table 标签内使用。让逻辑表使用这个规则进行分片。
function 标签:
<function name="func1" class="io.mycat.route.function.PartitionByLong">
<property name="partitionCount">8</property>
<property name="partitionLength">128</property>
</function>
function 元素的 name 属性值为 "func1",表示这是一个名为 "func1" 的函数。
function 元素内部的 class 属性值为 "io.mycat.route.function.PartitionByLong",表示这个函数使用了 io.mycat.route.function.PartitionByLong 类来进行计算。
function 元素内部有两个 property 子元素,分别为 partitionCount 和 partitionLength。
partitionCount 属性指定了分片的数量,这里设置为 8。
partitionLength 属性指定了分片的长度,这里设置为 128。
PartitionByLong 是 MyCAT (MySQL Cluster Auto-Management Tool) 中提供的一种数据分片策略,它将数据按照 long 类型进行分库分表。使用该策略时,可以通过设置 partitionCount 属性和 partitionLength 属性来控制分片的数量和长度,从而将数据分散存储在不同的数据库或表中,实现分布式存储。
具体的分片规则百度就行,太多不做演示
4、使用 示例
启动mycat
[root@rabbitmq_1 mycat]# bin/mycat stop
Stopping Mycat-server...
Mycat-server was not running.
[root@rabbitmq_1 mycat]#
[root@rabbitmq_1 mycat]# bin/mycat start
Starting Mycat-server...
启动之后,mycat 默认会启动一个叫 8066 的端口,如果8066端口没起来,需要查看日志,分析问题
[root@rabbitmq_1 mycat]# netstat -ntl
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address Foreign Address State
tcp6 0 0 :::8066 :::* LISTEN
今天就用test 数据库做示例 演示
(root@localhost) [(none)]> show databases;
+------------------------+
| Database |
+------------------------+
| test |
+------------------------+
连接mycat ,读取的是server.xml文件
如果报错就加上这个参数 --default_auth=mysql_native_password
[root@rabbitmq_1 mycat]# mysql -h192.168.134.132 -uroot -p123456 -P8066 --default_auth=mysql_native_password
(root@192.168.134.132) [(none)]> show databases;
+----------+
| DATABASE |
+----------+
| TESTDB |
+----------+
(root@192.168.134.132) [(none)]> use TESTDB
(root@192.168.134.132) [TESTDB]> show tables;
+------------------+
| Tables in TESTDB |
+------------------+
| customer |
| customer_addr |
+------------------+
示例:
1、垂直分库
分库分表和读写分离可以同时进行
server.xml
<user name="root">
<property name="password">123456</property>
<property name="schemas">USERDB1,USERDB2</property>
</user>
配置了USERDB1、USERDB2这两个逻辑库
schema.xml
<?xml version="1.0"?>
<!DOCTYPE mycat:schema SYSTEM "schema.dtd">
<mycat:schema xmlns:mycat="http://io.mycat/">
<schema name="USERDB1" checkSQLschema="false" sqlMaxLimit="100" dataNode="dn1" />
<schema name="USERDB2" checkSQLschema="false" sqlMaxLimit="100"dataNode="dn2" />
<dataNode name="dn1" dataHost="node1" database="mytest1" />
<dataNode name="dn2" dataHost="node2" database="mytest2" />
<dataHost name="node1" maxCon="1000" minCon="10" balance="0" writeType="0" dbType="mysql" dbDriver="native">
<heartbeat>select user()</heartbeat>
<writeHost host="192.168.134.132" url="192.168.134.132:3306" user="root" password="123456" />
</dataHost>
<dataHost name="node2" maxCon="1000" minCon="10" balance="0"writeType="0" dbType="mysql" dbDriver="native">
<heartbeat>select user()</heartbeat>
<writeHost host="192.168.134.133" url="192.168.134.133:3306" user="root" password="123456" />
</dataHost>
</mycat:schema>
两个逻辑库对应两个不同的数据节点,两个数据节点对应两个不同的物理机器
mytest1和mytest2分成了不同机器上的不同的库,各包含一部分表,它们原来是合在一块的,在一台机器上,现在做了垂直的拆分。
客户端就需要去连接不同的逻辑库了,根据业务操作不同的逻辑库
然后配置了两个写库,两台机器把库平分了,分担了原来单机的压力。分库伴随着分表,从业务上对表拆分
2、配置水平分表
server.xml
<user name="root" defaultAccount="true">
<property name="password">123456</property>
<property name="schemas">test</property>
<property name="defaultSchema">test</property>
</user>
<user name="user">
<property name="password">user</property>
<property name="schemas">test</property>
<property name="readOnly">true</property>
<property name="defaultSchema">test</property>
</user>
schema.xml
<?xml version="1.0"?>
<!DOCTYPE mycat:schema SYSTEM "schema.dtd">
<mycat:schema xmlns:mycat="http://io.mycat/">
<schema name="test" checkSQLschema="false" sqlMaxLimit="100" dataNode="dn1">
<table name="user" dataNode="dn1" />
<table name="student" primaryKey="id" autoIncrement="true" dataNode="dn1,dn2" rule="mod-long"/>
</schema>
<dataNode name="dn1" dataHost="host1" database="test" />
<dataNode name="dn2" dataHost="host2" database="test" />
<dataHost name="host1" maxCon="1000" minCon="10" balance="0"
writeType="0" dbType="mysql" dbDriver="native" switchType="1" slaveThreshold="100">
<heartbeat>select user()</heartbeat>
<writeHost host="192.168.134.132" url="192.168.134.132:3306" user="root"
password="123456">
</writeHost>
</dataHost>
<dataHost name="host2" maxCon="1000" minCon="10" balance="0"
writeType="0" dbType="mysql" dbDriver="native" switchType="1" slaveThreshold="100">
<heartbeat>select user()</heartbeat>
<writeHost host="192.168.134.133" url="192.168.134.133:3306" user="root"
password="123456">
</writeHost>
</dataHost>
</mycat:schema>
此外还需要在rule.xml中配置以下拆分算法
找到算法mod-long,因为我们将逻辑表student分开映射到两台主机上,所以修改数据节点的数量为2
<tableRule name="mod-long">
<rule>
<columns>id</columns>
<algorithm>mod-long</algorithm>
</rule>
</tableRule>
<function name="mod-long" class="io.mycat.route.function.PartitionByMod">
<property name="count">2</property>
</function>
首先确保两个节点上都有test 数据库
在主库上创建 user 表和student表
(root@localhost) [test]> create table user(id int,name varchar(20));
Query OK, 0 rows affected (0.02 sec)
(root@localhost) [test]>
(root@localhost) [test]> create table student(id int primary key auto_increment,name varchar(20));
Query OK, 0 rows affected (0.01 sec)
登录到mycat的8066端口
[root@rabbitmq_1 mycat]# bin/mycat start
Starting Mycat-server...
[root@rabbitmq_1 mycat]# mysql -h192.168.134.132 -uroot -p123456 -P8066 --default_auth=mysql_native_password
mysql: [Warning] Using a password on the command line interface can be insecure.
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 1
Server version: 5.6.29-mycat-1.6.7.5-release-20200410174409 MyCat Server (OpenCloudDB)
Copyright (c) 2000, 2019, Oracle and/or its affiliates. All rights reserved.
Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
(root@192.168.134.132) [(none)]>
(root@192.168.134.132) [(none)]> show databases;
+----------+
| DATABASE |
+----------+
| test |
+----------+
1 row in set (0.00 sec)
(root@192.168.134.132) [(none)]> use test;
(root@192.168.134.132) [test]> show tables;
+----------------+
| Tables_in_test |
+----------------+
| student |
| user |
+----------------+
11 rows in set (0.00 sec)
(root@192.168.134.132) [test]> select * from user;
Empty set (0.24 sec)
通过mycat给user 表添加两条数据
(root@192.168.134.132) [test]> insert into user values(1,'aaa');
Query OK, 1 row affected (0.00 sec)
(root@192.168.134.132) [test]>
(root@192.168.134.132) [test]> insert into user values(2,'bbb');
Query OK, 1 row affected (0.00 sec)
由于schema.xml配置文件中,逻辑表user只在Linux主机的mytest1库中存在,mycat操作的逻辑表user会影响Linux主机上的物理表,
而不会影响另一台主机上的表。我们分别查看一下master和slave主机的user表:因为我搭建的主从,所以都会同步
2、我们再通过MyCat给student表插入两条数据
(root@192.168.134.132) [test]> insert into student(id,name) values(1,'aaa');
Query OK, 1 row affected (0.00 sec)
(root@192.168.134.132) [test]>
(root@192.168.134.132) [test]> insert into student(id,name) values(2,'aaa');
Query OK, 1 row affected (10.01 sec)
我们知道schema.xml配置文件中,逻辑表student对应两台主机上的1个 库 test 中的两张表,所以对逻辑表插入的两条数据,会实际影响到两张物理表(用
id%机器数,决定插入到哪张物理表)。我们分别查看一下 master 和 slave 机的student表:
(root@localhost) [test]> select * from student; //主
+----+------+
| id | name |
+----+------+
| 2 | aaa |
+----+------+
(root@localhost) [test]> select * from student; //从机
+----+------+
| id | name |
+----+------+
| 1 | aaa |
再通过MyCat插入id=3和id=4的数据,应该插入不同主机上的不同物理表
(root@192.168.134.132) [test]> insert into student(id,name) values(3,'bbb');
Query OK, 1 row affected (0.00 sec)
(root@192.168.134.132) [test]> insert into student(id,name) values(4,'ccc');
Query OK, 1 row affected (0.01 sec)
在查看
(root@localhost) [test]> select * from student; //主
+----+------+
| id | name |
+----+------+
| 2 | aaa |
| 4 | ccc |
+----+------+
(root@localhost) [test]> select * from student; //从
+----+------+
| id | name |
+----+------+
| 1 | aaa |
| 3 | bbb |
这就相当于把student表进行水平拆分了
通过MyCat查询的时候只需要正常输入就行,我们配置的是表拆分后放在这2个数据节点上,MyCat会根据配置在两个库上查询并进行数据合并
(root@192.168.134.132) [test]> select *from student;
+----+------+
| id | name |
+----+------+
| 2 | aaa |
| 4 | ccc |
| 1 | aaa |
| 3 | bbb |
+----+------+
由于刚才在测试时候 把从库给关了。
测试完之后。把相应记录删除,在把从库起来,状态会报错。因为在主库删除表操作时,会记录到日志中,从库起来会报错。
此时需要跳过当前事务,主从状态就正常了
(root@localhost) [test]> STOP SLAVE;
Query OK, 0 rows affected (0.00 sec)
(root@localhost) [test]> SET GLOBAL sql_slave_skip_counter = 2;
Query OK, 0 rows affected (0.00 sec)
(root@localhost) [test]> START SLAVE;
Query OK, 0 rows affected (0.00 sec)
--或者
(root@localhost) [test]> STOP SLAVE SQL_THREAD;
//这个过滤是基于FTID 的 如果没开GTID 就是用下一个 REPLICATE_DO_DB(是同步哪些库)REPLICATE_IGNORE_DB(是不同步哪些库)
(root@localhost) [test]> CHANGE REPLICATION FILTER REPLICATE_WILD_IGNORE_TABLE = ('cjc.t2');
(root@localhost) [test]> CHANGE REPLICATION FILTER REPLICATE_DO_DB = (db1, db2),REPLICATE_IGNORE_DB = (db3);
(root@localhost) [test]> start SLAVE SQL_THREAD;