MyCat 作為基於 MySQL 協議的資料庫中間件,核心價值在於透明化分庫分表。本文記錄從安裝配置、Schema 定義、建表分片、數據寫入到路由驗證的完整實戰流程。
# 解壓安裝包 (假設已配置 JDK 1.8+)
tar -zxvf Mycat-server-1.6-RELEASE-*.tar.gz
cd mycat
# 啟動
bin/mycat start
# 登入測試 (預設用戶 test/test, 端口 8066, 邏輯庫 TESTDB)
mysql -u test -p test -h 127.0.0.1 -P 8066 -D TESTDB
conf/schema.xml 定義邏輯庫、邏輯表、分片節點、分片規則:
<?xml version="1.0"?>
<!DOCTYPE mycat:schema SYSTEM "schema.dtd">
<mycat:schema xmlns:mycat="https://io.mycat/">
<!-- 邏輯庫定義 -->
<schema name="TESTDB" checkSQLschema="false" sqlMaxLimit="100">
<!-- 分片表定義:dataNode 指向分片節點,rule 指定分片規則 -->
<table name="travelrecord" dataNode="dn1,dn2,dn3" rule="sharding-by-id" primaryKey="id" autoIncrement="true"/>
</schema>
<!-- 分片節點:對應後端 MySQL 實例的具體資料庫 -->
<dataNode name="dn1" dataHost="localhost1" database="db1" />
<dataNode name="dn2" dataHost="localhost1" database="db2" />
<dataNode name="dn3" dataHost="localhost1" database="db3" />
<!-- 數據主機:後端 MySQL 連線池配置 -->
<dataHost name="localhost1" maxCon="1000" minCon="10" balance="0" writeType="0" dbType="mysql" dbDriver="native" switchType="1" slaveThreshold="100">
<heartbeat>SELECT 1</heartbeat>
<writeHost host="hostM1" url="127.0.0.1:3306" user="root" password="123456"/>
</dataHost>
<!-- 分片規則:按 ID 範圍分片 -->
<function name="sharding-by-id" class="io.mycat.route.function.AutoPartitionByLong">
<property name="mapFile">partition-hash.txt</property>
</function>
</mycat:schema>
關鍵點:partition-hash.txt 定義 ID 範圍到節點映射,如 1-1000000=dn1, 1000001-2000000=dn2...。
mysql> CREATE TABLE travelrecord (
id BIGINT NOT NULL PRIMARY KEY,
user_id VARCHAR(100),
traveldate DATE,
fee DECIMAL(10,2),
days INT
);
MyCat 會自動路由至 3 個分片節點 (dn1/db1, dn2/db2, dn3/db3) 同步建表。
-- 分片 0 (dn1) : ID 100001
mysql> EXPLAIN INSERT INTO travelrecord (id, user_id, traveldate, fee, days) VALUES (100001, 'xiaohong', '2014-01-06', 510.5, 3);
+------+-------+-----------+--------------------------------------------------+
| ID | NODE | TYPE | SQL |
+------+-------+-----------+--------------------------------------------------+
| 0 | dn1 | INSERT | INSERT INTO travelrecord (...) VALUES (...) |
+------+-------+-----------+--------------------------------------------------+
mysql> INSERT INTO travelrecord (id, user_id, traveldate, fee, days) VALUES (100001, 'xiaohong', '2014-01-06', 510.5, 3);
-- 分片 1 (dn2) : ID 8000004
mysql> EXPLAIN INSERT INTO travelrecord (id, user_id, traveldate, fee, days) VALUES (8000004, 'mazi', '2014-01-06', 510.5, 3);
-- 路由至 dn2
mysql> INSERT ... (8000004, 'mazi', ...);
-- 分片 2 (dn3) : ID 10000004
mysql> EXPLAIN INSERT INTO travelrecord (id, user_id, traveldate, fee, days) VALUES (10000004, 'suqi', '2014-01-06', 510.5, 3);
-- 路由至 dn3
mysql> INSERT ... (10000004, 'suqi', ...);
-- 全表掃描:路由至所有分片
mysql> EXPLAIN SELECT * FROM travelrecord;
+------+------------+-------+----------------------------------+
| ID | NODE | TYPE | SQL |
+------+------------+-------+----------------------------------+
| 0 | dn1,dn2,dn3| SELECT| SELECT * FROM travelrecord |
+------+------------+-------+----------------------------------+
-- 單點查詢:精確路由至單分片 (需 WHERE 條件含分片鍵 id)
mysql> EXPLAIN SELECT * FROM travelrecord WHERE id = 100001;
-- 僅路由至 dn1
[root@host ~]# mysql -u root -p -e "SELECT * FROM db1.travelrecord;"
+--------+-----------+------------+-------+------+
| id | user_id | traveldate | fee | days |
+--------+-----------+------------+-------+------+
| 100001 | xiaohong | 2014-01-06 | 510.5 | 3 |
+--------+-----------+------------+-------+------+
[root@host ~]# mysql -u root -p -e "SELECT * FROM db2.travelrecord;"
+---------+----------+------------+-------+------+
| id | user_id | traveldate | fee | days |
+---------+----------+------------+-------+------+
| 8000004 | mazi | 2014-01-06 | 510.5 | 3 |
+---------+----------+------------+-------+------+
[root@host ~]# mysql -u root -p -e "SELECT * FROM db3.travelrecord;"
+----------+---------+------------+-------+------+
| id | user_id | traveldate | fee | days |
+----------+---------+------------+-------+------+
| 10000004 | suqi | 2014-01-06 | 510.5 | 3 |
+----------+---------+------------+-------+------+
確認數據確實按分片規則落地至不同物理庫。
-- 連線 MyCat 管理端口 (預設 9066)
mysql -u test -p test -h 127.0.0.1 -P 9066
-- 查看分片路由狀態
SHOW @@datanode;
SHOW @@cache;
SHOW @@sql.slow;
-- 查看特定表分片分佈
SELECT * FROM information_schema.tables WHERE table_schema='TESTDB' AND table_name='travelrecord';
autoIncrement="true" 由 MyCat 協調 (雪花算法/全局序列),或業務層生成唯一 ID (Snowflake)。MyCat 透過 schema.xml 定義邏輯庫/表/分片節點/規則,實現應用透明分庫分表。核心驗證流程:**EXPLAIN 觀察路由 → 寫入測試 → 後端直連確認落地**。生產落地需重點解決全局唯一 ID、跨分片查詢限制、分片演進、監控告警等工程化課題。