前提,先搭建好MySQL的主从配置,登录MyCAT 2在MyCAT2里面操作,也就是连接8066这个端口

创建数据源

 # 都在MyCAT2机器上执行
 mysql -uroot -p123456 -P8066 -h127.0.0.1
 ​
 #登陆后进行操作
 -- 重置配置
 /*+ mycat:resetConfig{} */;
 ​
 -- 添加主库数据源(读写)
 /*+ mycat:createDataSource
 {
     "dbType": "mysql",
     "idleTimeout": 60000,
     "initSqls": [],
     "initSqlsGetConnection": true,
     "instanceType": "READ_WRITE",
     "maxCon": 1000,
     "maxConnectTimeout": 3000,
     "maxRetryCount": 5,
     "minCon": 1,
     "name": "m1",
     "password": "123456",
     "type": "JDBC",
     "url": "jdbc:mysql://192.168.7.31:3306?useUnicode=true&serverTimezone=UTC&characterEncoding=UTF-8",
     "user": "root",
     "weight": 0
 }
 */;
 ​
 -- 添加从库数据源(只读)
 /*+ mycat:createDataSource
 {
     "dbType": "mysql",
     "idleTimeout": 60000,
     "initSqls": [],
     "initSqlsGetConnection": true,
     "instanceType": "READ",
     "maxCon": 1000,
     "maxConnectTimeout": 3000,
     "maxRetryCount": 5,
     "minCon": 1,
     "name": "m1s1",
     "password": "123456",
     "type": "JDBC",
     "url": "jdbc:mysql://192.168.7.32:3306?useUnicode=true&serverTimezone=UTC&characterEncoding=UTF-8",
     "user": "root",
     "weight": 0
 }
 */;

拆解创建数据源

整体作用

步骤

命令

作用

1

resetConfig

清空所有配置,恢复到初始状态

2

createDataSource (name: m1)

添加 主库(写库),IP 为 192.168.7.31

3

createDataSource (name: m1s1)

添加 从库(读库),IP 为 192.168.7.32

两个数据源对比

配置项

m1(主库)

m1s1(从库)

IP 地址

192.168.7.31

192.168.7.32

instanceType

READ_WRITE(可读写)

READ(只读)

作用

处理 操作(INSERT/UPDATE/DELETE)

处理 操作(SELECT)

账号/密码

root / 123456

root / 123456

最终效果

配置完成后,MyCAT 会自动实现 读写分离

 应用程序 → MyCAT (8066) → 
     ├── 写操作 → m1 (192.168.7.31 主库)
     └── 读操作 → m1s1 (192.168.7.32 从库)

修改数据源方式

停止 MyCAT

 /usr/local/mycat/bin/mycat stop

编辑数据源配置文件

主库配置:/usr/local/mycat/conf/datasources/m1.datasource.json

 {
   "dbType":"mysql",
   "idleTimeout":60000,
   "initSqls":[],
   "initSqlsGetConnection":true,
   "instanceType":"READ_WRITE",
   "maxCon":1000,
   "maxConnectTimeout":3000,
   "maxRetryCount":5,
   "minCon":1,
   "name":"m1",
   "password":"你的正确密码",
   "type":"JDBC",
   "url":"jdbc:mysql://192.168.7.31:3306?useUnicode=true&serverTimezone=UTC&characterEncoding=UTF-8",
   "user":"root",
   "weight":0
 }

从库配置:/usr/local/mycat/conf/datasources/m1s1.datasource.json

 {
   "dbType":"mysql",
   "idleTimeout":60000,
   "initSqls":[],
   "initSqlsGetConnection":true,
   "instanceType":"READ",
   "maxCon":1000,
   "maxConnectTimeout":3000,
   "maxRetryCount":5,
   "minCon":1,
   "name":"m1s1",
   "password":"你的正确密码",
   "type":"JDBC",
   "url":"jdbc:mysql://192.168.7.32:3306?useUnicode=true&serverTimezone=UTC&characterEncoding=UTF-8",
   "user":"root",
   "weight":0
 }

启动 MyCAT

 /usr/local/mycat/bin/mycat start

查询数据源(验证是否成功)

 /*+ mycat:showDataSources{} */;
 ​
 注:如果看到 m1 和 m1s1 两条记录,就说明数据源创建成功了。

创建集群

 /*! mycat:createCluster{
   "clusterType":"MASTER_SLAVE",
   "heartbeat":{
     "heartbeatTimeout":1000,
     "maxRetry":3,
     "minSwitchTimeInterval":300,
     "slaveThreshold":0
   },
   "masters":[
     "m1"
   ],
   "maxCon":2000,
   "name":"prototype",
   "readBalanceType":"BALANCE_ALL",
   "replicas":[
     "m1s1"
   ],
   "switchType":"SWITCH"
 } */;

拆解创建集群

配置参数详解

配置项

作用

clusterType

MASTER_SLAVE

集群类型:主从模式

masters

["m1"]

指定 主库 数据源是 m1(192.168.7.31)

replicas

["m1s1"]

指定 从库 数据源是 m1s1(192.168.7.32)

readBalanceType

BALANCE_ALL

读请求均衡分发到所有从库

switchType

SWITCH

主库故障时自动切换到从库

name

prototype

集群名称(后面配置逻辑库时会引用)

心跳和高可用配置

配置项

作用

heartbeatTimeout

1000

心跳超时时间(毫秒),超过则判定节点故障

maxRetry

3

故障检测最大重试次数

minSwitchTimeInterval

300

主从切换最小时间间隔(秒),防止频繁切换

slaveThreshold

0

从库延迟阈值(秒),0 表示不限制

执行后的效果

  • 写入操作 → 自动路由到 m1(主库)

  • 读取操作 → 自动分发到 m1s1(从库)

  • 主库故障 → 自动切换到从库(高可用)

 应用程序 → MyCAT (8066)
               │
               ▼
         prototype 集群
               │
     ┌─────────┴─────────┐
     ▼                   ▼
   m1 (主库)          m1s1 (从库)
   192.168.7.31       192.168.7.32
   [读写]             [只读,负载均衡]

查询集群

 /*! mycat:showClusters{} */;

创建逻辑库

逻辑库是 MyCAT 暴露给应用程序的“虚拟数据库”,它把后端一个或多个 MySQL 物理库“包装”成一个统一的入口

 CREATE DATABASE db1 DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;

打个比方 🍽️

角色

比喻

MyCAT 逻辑库

餐厅的 菜单

后端 MySQL 物理库

餐厅的 后厨

  • 客人(应用程序)只看菜单(逻辑库),点菜(发 SQL)

  • 服务员(MyCAT)根据菜单,去后厨(MySQL)拿菜

  • 客人不需要知道后厨有几个厨师、几个灶台

为什么需要逻辑库?

1. 屏蔽底层复杂性

 应用程序只看到:
 ┌─────────────────────────┐
 │   MyCAT 逻辑库: db1      │  ← 应用程序只连接这个
 └─────────────────────────┘
             │
             ▼
     ┌───────┴───────┐
     ▼               ▼
  主库 7.31      从库 7.32    ← 应用程序不知道有两个库

2. 实现读写分离

 -- 应用程序执行
 INSERT INTO users VALUES (1, '张三');   → 自动去主库 (7.31)
 SELECT * FROM users;                    → 自动去从库 (7.32)

3. 支持分库分表(未来扩展)

 逻辑库: db1
     │
     ├── 物理库: db1_0 (192.168.7.31)   ← 存 0-5000 万条数据
     ├── 物理库: db1_1 (192.168.7.32)   ← 存 5000 万-1 亿条数据
     └── 物理库: db1_2 (192.168.7.33)   ← 存 1 亿-1.5 亿条数据

修改逻辑库的数据源

 # 修改 
 vim /usr/local/mycat/conf/schemas/db1.schema.json
 ​
 ## 在里面添加集群的名称,作用是让该集群生成并管理这个库的物理库
 "targetName":"prototype"
 ​
 ## 例:
 {
     "customTables": {},
     "globalTables": {},
     "normalProcedures": {},
     "normalTables": {},
     "schemaName": "db1",
     "shardingTables": {},
     "views": {},
     "targetName": "prototype"           # 添加这一行
 }
 ​
 # 重启 MyCAT
 /usr/local/mycat/bin/mycat restart

测试读写分离是否成功(在MyCAT里面测试)

在MyCAT里面创建一个sys_user表

 -- 1. 查看逻辑库
 /*+ mycat:showSchemas{} */;
 ​
 -- 2. 切换到 db1
 USE db1;
 ​
 -- 3. 建表
 CREATE TABLE sys_user(
     id BIGINT PRIMARY KEY, 
     username VARCHAR(200) NOT NULL,  
     address VARCHAR(500)
 );
 ​
 -- 4. 插入数据
 INSERT INTO sys_user VALUES (1, '张三', '北京市朝阳区');
 ​
 -- 5. 查询数据
 SELECT * FROM sys_user;
 ​
 ## 尝试修复 MyCAT 元数据与后端 MySQL 物理表结构之间的一致性
 /*+ mycat:repairPhysicalTable{} */;
 ​