前面的文章中,我们已经完成了mycat的读写分离、垂直拆分、水平拆分的实验,请参考如下文章链接:
[MyCat入门篇-使用案例1:读写分离(part1)]
[MyCat入门篇-使用案例1:读写分离(part2)]
[MyCat入门篇-使用案例1:读写分离(part3)]
[MyCat入门篇-使用案例1:读写分离(part4)]
[MyCat入门篇-使用案例2:垂直拆分]
[MyCat入门篇-使用案例3:水平拆分]
接下来我们进行mycat和MySQL集成的全局表水平拆分的实验部分。
水平拆分-全局表的配置
需求背景:
当我们把一个数据量特别大的大表水平的拆分到了同步的数据库节点之后,这些数据就会被均匀的分摊到不同的数据库节点。当我们查询表中的数据的时候,查询语句会通过mycat分别发送的不同的数据节点上,在所有的数据库节点上都执行一下我们的SQL语句,然后返回结果到mycat,mycat收到结果后汇总一下再返回给我们。
现在有这样一个问题,如果我们水平拆分的表中,有某个字段,它是需要关联到另外一表才能获取到其真正的含义。比如订单状态字段,这个字段一般我们在订单表中都是存储一个字母或者一个整型的数字。我们查询出来的结果中并不知道这个状态字段的值具体是什么含义,需要关联一个状态字典表才能知道具体的状态含义。
那我们该如何让水平拆分的表和我们的状态字段进行关联呢?
mycat支持一种水平拆分的方式:全局表。就是说把一个表中的数据,在每一个水平拆分存储数据的数据库节点上都存储一份,在每一个数据库节点上,这个表的数据都是相同的。它是一个字典表,数据量不大。所以在每一个数据节点上都存储一份,不会对数据库操作很大的压力,并且可以让其和做水平拆分的大表进行关联查询,返回我们希望得到的关联后的结果。
结合到我们的实际例子当中,我们的order_info_detail_history
表中有一个字段STATUS_CODE
,这个字段就是代表当前订单的状态的字段,它需要和一个订单状态字典表关联查询后才能得到具体每一个状态code的具体含义。为了方便和水平拆分的order_info_detail_history
表进行关联,我们需要把这个订单状态字典表定义为一个全局表来进行水平拆分。
结果就是在M2、M3
两个数据库节点上都有一个这样的订单状态字典表,并且字典表的数据内容完全一致。
接下来我们来进行mycat配置文件的修改,来完成全局表的水平拆分示例。
修改schema.xml配置文件
在schema.xml
配置文件的schema
标签中增加如下配置。如果有多个字电表需要配置为全局表,则在这里配置多个table
标签即可。
<!--全局表(字典表)-->
<table name="order_status" dataNode="ordernode,ordernode2" type="global" />
重启mycat服务
为了是配置文件生效,我们需要重启mycat
服务。因为我们是使用的容器启动的mycat
服务,所以我们重启mycat
容器就可以完成对mycat
服务的重启。
使用如下命令重启mycat
容器
docker restart mycat-mycat1
重启完成之后,验证mycat
容器正常启动没有错误信息。
验证的方式如下:
- 去看logs目录下面的日志信息是否有
ERROR
信息输出, - 或者是使用
ps -ef | grep mycat
命令查看mycat
进程是否存在。
创建表和插入测试数据
当mycat服务正常启动之后,我们就可以通过mycat命令行窗口去创建我们的全局表。
建表SQL语句和初始化测试的SQL语句如下所示:
- 创建订单状态全局表
create table order_status(id int primary key auto_increment, status_code varchar(16), status_desc varchar(32));
- 插入测试数据
-- 插入全局表数据,该数据会在定义的dataNode中都创建一份
insert into order_status(status_code,status_desc) values('A',concat('待支付-',@@hostname));
insert into order_status(status_code,status_desc) values('B',concat('已支付-',@@hostname));
insert into order_status(status_code,status_desc) values('C',concat('配送中-',@@hostname));
insert into order_status(status_code,status_desc) values('D',concat('已签收-',@@hostname));
验证表创建结果
- 使用命令登录到mycat的命令行窗口。
mysql -umycat -pmycat -P8041 -h127.0.0.1 --default-auth=mysql_native_password
- 然后切换到
mycat
的逻辑库mycat_db
下面。 - 执行上面提到的创建全局表的SQL语句和插入测数据的SQL语句。
- 然后使用如下命令来验证表
order_status
全局表是否创建成功。show tables
desc order_status
- 使用如下命令,查询一下
order_status
表中的数据可以正常展示出来。从下面的语句可以看出,返回来的结果中,通过status_desc
列中的值可以看出有时候是从S2
上面返回的结果,有点时候是从S3
上返回的结果。(注意:S2
和S3
的数据分布来自于M2
和M3
)select * from order_status;
- 使用如下命令分别登录
M2、M3、S2、S3
数据节点,验证全局表order_status
在M2、M3、S2、S3
的mysql_db
下面是否创建成功。因为存在M2->S2,M3->S3
的同步关系,所以S2和S3的mysql_db
下面也会有order_status
表的存在。mysql -uroot -proot -P3321 -h127.0.0.1 -e 'use mysql_db; show tables; desc order_status; select * from order_status;'
mysql -uroot -proot -P3331 -h127.0.0.1 -e 'use mysql_db; show tables; desc order_status; select * from order_status;'
mysql -uroot -proot -P3322 -h127.0.0.1 -e 'use mysql_db; show tables; desc order_status; select * from order_status;'
mysql -uroot -proot -P3332 -h127.0.0.1 -e 'use mysql_db; show tables; desc order_status; select * from order_status;'
- 具体验证过程中的输出如下:
➜ ~ mysql -umycat -pmycat -P8041 -h127.0.0.1 --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-20200422133810 MyCat Server (OpenCloudDB)
Copyright (c) 2000, 2020, 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.
mysql>
mysql>
mysql> show databases;
+----------+
| DATABASE |
+----------+
| mycat_db |
+----------+
1 row in set (0.01 sec)
mysql> use mycat_db;
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A
Database changed
mysql> show tables;
+---------------------------+
| Tables_in_mysql_db |
+---------------------------+
| order_info |
| order_info_detail |
| order_info_detail_history |
| order_info_history |
| order_status |
+---------------------------+
5 rows in set (0.01 sec)
mysql> drop table order_status;
Query OK, 0 rows affected (0.05 sec)
mysql> create table order_status(id int primary key auto_increment, status_code varchar(16), status_desc varchar(32));
Query OK, 0 rows affected (0.12 sec)
mysql> -- 插入全局表数据,该数据会在定义的dataNode中都创建一份
mysql> insert into order_status(status_code,status_desc) values('A',concat('待支付-',@@hostname));
Query OK, 1 row affected (0.05 sec)
mysql> insert into order_status(status_code,status_desc) values('B',concat('已支付-',@@hostname));
Query OK, 1 row affected (0.03 sec)
mysql> insert into order_status(status_code,status_desc) values('C',concat('配送中-',@@hostname));
Query OK, 1 row affected (0.09 sec)
mysql> insert into order_status(status_code,status_desc) values('D',concat('已签收-',@@hostname));
Query OK, 1 row affected (0.02 sec)
mysql> desc order_status
-> ;
+----------------+-------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+----------------+-------------+------+-----+---------+----------------+
| ID | int(11) | NO | PRI | NULL | auto_increment |
| STATUS_CODE | varchar(16) | YES | | NULL | |
| STATUS_DESC | varchar(32) | YES | | NULL | |
| _MYCAT_OP_TIME | bigint(20) | YES | | NULL | |
+----------------+-------------+------+-----+---------+----------------+
4 rows in set (0.02 sec)
mysql> select * from order_status;
+----+-------------+-------------------------+----------------+
| ID | STATUS_CODE | STATUS_DESC | _MYCAT_OP_TIME |
+----+-------------+-------------------------+----------------+
| 2 | A | 待支付-master2.mysql | 1604216485305 |
| 4 | B | 已支付-master2.mysql | 1604216485348 |
| 6 | C | 配送中-master2.mysql | 1604216485378 |
| 8 | D | 已签收-master2.mysql | 1604216485911 |
+----+-------------+-------------------------+----------------+
4 rows in set (0.02 sec)
mysql> select * from order_status;
+----+-------------+-------------------------+----------------+
| ID | STATUS_CODE | STATUS_DESC | _MYCAT_OP_TIME |
+----+-------------+-------------------------+----------------+
| 1 | A | 待支付-master3.mysql | 1604216485305 |
| 3 | B | 已支付-master3.mysql | 1604216485348 |
| 5 | C | 配送中-master3.mysql | 1604216485378 |
| 7 | D | 已签收-master3.mysql | 1604216485911 |
+----+-------------+-------------------------+----------------+
4 rows in set (0.02 sec)
mysql>
- 验证全局表在MySQL实例中是否创建成功已经表中的数据是否存在。这里只贴出了在
M2
数据节点的验证过程,其他S2、M3、S3
的验证过程不再贴出来了。
➜ ~ mysql -uroot -proot -P3321 -h127.0.0.1 -e 'use mysql_db; show tables; desc order_status; select * from order_status;'
mysql: [Warning] Using a password on the command line interface can be insecure.
+---------------------------+
| Tables_in_mysql_db |
+---------------------------+
| ORDER_INFO |
| ORDER_INFO_DETAIL |
| ORDER_INFO_DETAIL_HISTORY |
| ORDER_INFO_HISTORY |
| order_info_detail_history |
| order_info_history |
| order_status |
+---------------------------+
+----------------+-------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+----------------+-------------+------+-----+---------+----------------+
| ID | int(11) | NO | PRI | NULL | auto_increment |
| STATUS_CODE | varchar(16) | YES | | NULL | |
| STATUS_DESC | varchar(32) | YES | | NULL | |
| _MYCAT_OP_TIME | bigint(20) | YES | | NULL | |
+----------------+-------------+------+-----+---------+----------------+
+----+-------------+-------------------------+----------------+
| ID | STATUS_CODE | STATUS_DESC | _MYCAT_OP_TIME |
+----+-------------+-------------------------+----------------+
| 2 | A | 待支付-master2.mysql | 1604216485305 |
| 4 | B | 已支付-master2.mysql | 1604216485348 |
| 6 | C | 配送中-master2.mysql | 1604216485378 |
| 8 | D | 已签收-master2.mysql | 1604216485911 |
+----+-------------+-------------------------+----------------+
➜ ~
验证关联查询是否生效
全局表已经在所有参与水平拆分的数据库节点上创建完成,那么我现在来和order_info_history
表关联查询一下,看是否可以正常关联查询并展示出正确的数据内容。
以下命令需要在mycat的命令行窗口中执行。
mysql -umycat -pmycat -P8041 -h127.0.0.1 --default-auth=mysql_native_password -e 'use mycat_db; select * from order_info_history as x left join order_status as y on x.status_code = y.status_code;'
- 验证结果如下:
➜ ~ mysql -umycat -pmycat -P8041 -h127.0.0.1 --default-auth=mysql_native_password -e 'use mycat_db; select * from order_info_history as x left join order_status as y on x.status_code = y.status_code;'
mysql: [Warning] Using a password on the command line interface can be insecure.
+----+---------------+-------------+---------------+------+-------------+-------------------------+----------------+
| ID | CUSTOMER_CODE | STATUS_CODE | HOSTNAME | ID | STATUS_CODE | STATUS_DESC | _MYCAT_OP_TIME |
+----+---------------+-------------+---------------+------+-------------+-------------------------+----------------+
| 2 | 10 | A | master2.mysql | 2 | A | 待支付-master2.mysql | 1604216485305 |
| 6 | 14 | A | master2.mysql | 2 | A | 待支付-master2.mysql | 1604216485305 |
| 4 | 12 | C | master2.mysql | 6 | C | 配送中-master2.mysql | 1604216485378 |
| 1 | 11 | B | master3.mysql | 3 | B | 已支付-master3.mysql | 1604216485348 |
| 5 | 15 | B | master3.mysql | 3 | B | 已支付-master3.mysql | 1604216485348 |
| 3 | 13 | D | master3.mysql | 7 | D | 已签收-master3.mysql | 1604216485911 |
+----+---------------+-------------+---------------+------+-------------+-------------------------+----------------+
➜ ~
以上验证结果OK,所有的数据都可以关联上。
微信搜索“coder-home”或扫一扫下面的二维码,
关注公众号,第一时间了解更多干货分享,还有各类视频教程资源。扫描它,带走我