dble官网
https://opensource.actionsky.com/
本文指定的dble版本是官网最新版本,dble-3.21.10.3-20220331093302
前提
需要提前安装好docker,jdk及mysql。mysql可以先不做主从配置。这两者可以去参考系统安装手册,或者网上的博客,此处不做详述。
环境
10.11.33.211 、10.11.33.212
Docker安装
下载
- 用docker拉取最新版本镜像并生成dble.tar文件
# docker pull actiontech/dble:latest
# docker save -o dble.tar actiontech/dble:latest - 加载镜像
# docker load -i dble.tar
启动dble
- 首次配置挂载目录并启动dble
docker run -d -it --name dble-server -v /home/app/dble/conf:/opt/dble/conf -v /home/app/dble/logs:/opt/dble/logs -p 8066:8066 -p 9066:9066 actiontech/dble:latest - 后续启动dble容器命令
docker run -d -it --name dble-server -v /home/app/dble/conf:/opt/dble/conf -p 8066:8066 -p 9066:9066 actiontech/dble:latest
修改配置文件
所有的配置文件具体配置说明可以参考文档: https://actiontech.github.io/dble-docs-cn/
配置user.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE dble:user SYSTEM "user.dtd">
<dble:user xmlns:dble="http://dble.cloud/" version="4.0">
<managerUser name="admin" password="admin"/>
<shardingUser name="test" password="123456" schemas="testdb" readOnly="false" maxCon="20"/>
</dble:user>
说明:managerUser是属于dble的管理员账号,用于管理元数据库。shardingUser是分库⽤⼾配置账号,可以用于登录创建虚拟数据库和表。shardingUser中的schemas要和sharding.xml中的scema的name对应。readOnly是否只读用户,可配置true/false, 默认false,如果设置成true,则只能进行show或select,不能进行运维管理。
配置db.xml
<?xml version="1.0"?>
<!DOCTYPE dble:db SYSTEM "db.dtd">
<dble:db xmlns:dble="http://dble.cloud/" version="4.0">
<dbGroup name="host_1" rwSplitMode="0" delayThreshold="100">
<heartbeat >select 1</heartbeat>
<dbInstance name="hostM1" url="10.11.33.211:3306" user="root" password="1017~Fulin" maxCon="1000" minCon="1000" primary="true" />
</dbGroup>
<dbGroup name="host_2" rwSplitMode="0" delayThreshold="100">
<heartbeat >select 1</heartbeat>
<dbInstance name="hostM2" url="10.11.33.212:3306" user="root" password="1017~Fulin" maxCon="1000" minCon="1000" primary="true" />
</dbGroup>
</dble:db>
说明:主要是要指定dbInstance,url为已搭建mysql的节点ip和端口。user是mysql登录用户名,password是mysql登录密码。其他参数可以参考官网文档 https://actiontech.github.io/dble-docs-cn/
配置sharding.xml
<?xml version="1.0"?>
<!DOCTYPE dble:sharding SYSTEM "sharding.dtd">
<dble:sharding xmlns:dble="http://dble.cloud/" version="4.0">
<schema name="testdb" shardingNode="dn1">
<shardingTable name="user" shardingNode="dn1,dn2" function="mod" shardingColumn="id" incrementColumn="id" />
</schema>
<shardingNode name="dn1" dbGroup="host_1" database="user1"/>
<shardingNode name="dn2" dbGroup="host_2" database="user2"/>
<function name="mod" class="Hash">
<property name="partitionCount">2</property>
<property name="partitionLength">1</property>
</function>
</dble:sharding>
说明:schema对应的name表示在分库用户端存在的数据库名。配置的shardingTable的name对应分库用户端存在的数据表名。其他说明如下:
<schema name="testdb">
<shardingTable name="user" shardingNode="dn1,dn2" function="mod" shardingColumn="id" incrementColumn="id" />
</schema>
<!-#- 里表示使用dble分库用户登录后,可以看到会自动创建testdb数据库,user表需要自己手动创建,shardingNode="dn1,dn2":表示在 <shardingNode name="dn1" dbGroup="host_1" database="user1"/>
<shardingNode name="dn2" dbGroup="host_2" database="user2"/>这两个数据点分库
function="mod":表示将使用mod拆分规则进行分表。
shardingColumn="id":表示拆分列名为id
incrementColumn="id":表格⾃增列。需要配置全局自增方式
-->
<shardingNode name="dn1" dbGroup="host_1" database="user1"/>
<shardingNode name="dn2" dbGroup="host_2" database="user2"/>
<!--
shardingNode name对应上面shardingTable中的shardingNode配置。dbGroup对应db.xml中的dbGroup name,也就是真实物理数据库节点。database的值,对应物理数据库中的表名。
-->
<function name="mod" class="Hash">
<property name="partitionCount">2</property>
<property name="partitionLength">1</property>
</function>
<!--这个function就是具体的分库分表规则,class=Hash-->
修改全局自增配置
-
修改$working_dir/conf/cluster.conf
sequenceHandlerType=1 ## 修改成1
sequenceStartTime=2022-04-12 11:23:28 -
修改$working_dir/conf/sequence_db_conf.properties文件,添加最后一行。
#sequence stored in shardingnode
TESTDB
.GLOBAL
=dn1
TESTDB
.COMPANY
=dn1
TESTDB
.CUSTOMER
=dn1
TESTDB
.ORDERS
=dn1
TESTDB
.myauto_test
=dn1
#testdb
表示使⽤全局序列的dble表所属的dble库名,在user.xml中指定的"的testdb
#user
使⽤全局序列dble的dble表名。即sharding.xml的
#dn1实现序列功能的数据节点名。sharding.xml的schema 中的shardingTable 中配置"的dn1。如果没有配置shardingNode=“dn1”,则使用shardingTable中的shardingNode的一个testdb
.user
=dn1
登录dble管理账号
修改完配置文件后,记得重新加载配置文件。使用管理员账号登录dble,先使用dryrun,进行配置文件检查,没有问题再执行reload @@config重新加载文件。
## 登录dble管理账号,账号用户名和密码对应user.xml中的<managerUser name="admin" password="admin"/>
docker exec -it mysql mysql -uadmin -padmin -P9066 -h 10.11.33.211
## 检查配置文件是否有误
mysql> dryrun;
+---------+---------+-------------------------------------------------+
| TYPE | LEVEL | DETAIL |
+---------+---------+-------------------------------------------------+
| Meta | WARNING | Database user2 doesn't exists in dbGroup[host_2] |
| Meta | WARNING | Database user1 doesn't exists in dbGroup[host_1] |
| Xml | NOTICE | There is No RWSplit User |
| Cluster | NOTICE | Dble is in single mod |
+---------+---------+-------------------------------------------------+
4 rows in set (1 min 0.11 sec)
## 列名含义:
## TYPE: 错误类型, ⽐如XML表⽰xml配置错误, BACKEND表⽰后端连接错误
## LEVAL:错误级别: 分为WARNNING 和ERROR表,⼀般来说WARNNING错误不影响启动和使⽤, 但需要注意。
## DETAIL :错误详情
## 配置文件没有问题,则重新加载配置生效
mysql> reload @@config;
Query OK, 1 row affected (0.12 sec)
Reload config success
## 创建分片
create database @@shardingnode='dn$1-2';
# 创建完成后,可以登录到两个物理数据库中查看已建库user1,user2
## mysql节点1已经创建user1
mysql> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| mysql |
| performance_schema |
| sys |
| user1 |
+--------------------+
5 rows in set (0.00 sec)
## mysql节点2已经创建user2
mysql> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| mysql |
| performance_schema |
| sys | |
| user2 |
+--------------------+
5 rows in set (0.00 sec)
执行dbsql.sql
- 登录对应dn1和dn2数据库节点,执行创建脚本dbsql.sql(在$working_dir/dble/conf/目录下有)但是需要修改最后一行:INSERT INTO DBLE_SEQUENCE VALUES (‘testdb.`user’, 0, 1);,这里需要指定testdb,和user表
-
use user1; DROP TABLE IF EXISTS DBLE_SEQUENCE; CREATE TABLE DBLE_SEQUENCE ( name VARCHAR(64) NOT NULL, current_value BIGINT(20) NOT NULL, increment INT NOT NULL DEFAULT 1, PRIMARY KEY (name) ) ENGINE=InnoDB; -- ---------------------------- -- Function structure for `dble_seq_nextval` -- ---------------------------- DROP FUNCTION IF EXISTS `dble_seq_nextval`; DELIMITER ;; CREATE FUNCTION `dble_seq_nextval`(seq_name VARCHAR(64)) RETURNS varchar(64) CHARSET latin1 DETERMINISTIC BEGIN DECLARE retval VARCHAR(64); DECLARE val BIGINT; DECLARE inc INT; DECLARE seq_lock INT; set val = -1; set inc = 0; SET seq_lock = -1; SELECT GET_LOCK(seq_name, 15) into seq_lock; if seq_lock = 1 then SELECT current_value + increment, increment INTO val, inc FROM DBLE_SEQUENCE WHERE name = seq_name for update; if val != -1 then UPDATE DBLE_SEQUENCE SET current_value = val WHERE name = seq_name; end if; SELECT RELEASE_LOCK(seq_name) into seq_lock; end if; SELECT concat(CAST((val - inc + 1) as CHAR),",",CAST(inc as CHAR)) INTO retval; RETURN retval; END ;; DELIMITER ; INSERT INTO DBLE_SEQUENCE VALUES ('`testdb`.`user`', 0, 1);
测试数据分库分表
首先使用dble分库账号登录,该账号在user.xml中对应
#登录使用用户
docker exec -it mysql mysql -utest -p123456 -P8066 -h 10.11.33.211
## 可以先查看当前已经存在的databases;
mysql> show databases;
+----------+
| DATABASE |
+----------+
| testdb |
+----------+
1 row in set (0.01 sec)
#使用schemas的表
use testdb;
# 创建表
CREATE TABLE `user` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`user_name` varchar(20) DEFAULT NULL,
`nick` varchar(20) DEFAULT NULL,
`phone` varchar(20) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
## 创建完成后可以在两个数据库对应的user1和user2库下已经创建了user表。
mysql> show tables;
+-----------------+
| Tables_in_user1 |
+-----------------+
| dble_sequence |
| user |
+-----------------+
2 rows in set (0.00 sec)
mysql> show tables;
+-----------------+
| Tables_in_user2 |
+-----------------+
| dble_sequence |
| user |
+-----------------+
2 rows in set (0.00 sec)
## 插入数据观察,多插入些,方便观察
INSERT INTO `user`(`user_name`, `nick`, `phone`) VALUES ("zhangsan", "zs", "13746767633");
mysql> INSERT INTO `user`(`user_name`, `nick`, `phone`) VALUES ("zhangsan", "zs", "13746767633");
Query OK, 1 row affected (0.11 sec)
## 登录两个物理数据库节点,分别查看分表结果,可以发现,id为奇数的数据在user2库的user表中,id为偶数的数据则在user1的user表中
mysql> select * from user;
+----+-----------+------+-------------+
| id | user_name | nick | phone |
+----+-----------+------+-------------+
| 1 | zhangsan | zs | 13746767633 |
| 3 | zhangsan | zs | 13746767633 |
+----+-----------+------+-------------+
2 rows in set (0.00 sec)
mysql> select * from user;
+----+-----------+------+-------------+
| id | user_name | nick | phone |
+----+-----------+------+-------------+
| 2 | zhangsan | zs | 13746767633 |
| 4 | zhangsan | zs | 13746767633 |
+----+-----------+------+-------------+
2 rows in set (0.00 sec)
至此,dble的简单测试分库分表完成。
普通安装
下载并安装
- 去dble官网( https://github.com/actiontech/dble/releases )下载最新release包,上传到linux服务器
- 解压并安装dble到指定文件夹中,并修改部分template文件为正式文件
mkdir -p $working_dir
cd $working_dir
tar -xvf dble-3.21.10.3-20220331093302-java1.8.0_151-linux.tar.gz
cd $working_dir/dble/conf
mv cluster_template.cnf cluster.cnf
mv bootstrap_template.cnf bootstrap.cnf
mv db_template.xml db.xml
mv user_template.xml user.xml
mv sharding_template.xml sharding.xml
启动dble
cd $working_dir/dble/bin
## 启动命令
bash dble start
## 停止命令
# bash dble stop
## 重启命令
# bash dble restart
如果启动失败请使用此命令查看失败的详细原因 tail -f logs/wrapper.log
或者dble.log。如果没有看到日志,可以修改log4j.xml的日志打印级别为debug。修改完配置必须要重启dble
<asyncRoot level="debug" includeLocation="true">
<!--<AppenderRef ref="Console" />-->
<AppenderRef ref="RollingFile"/>
</asyncRoot>
修改配置文件
参考docker修改配置文件
使用mysql客户端直接连接dble管理端口
mysql -uadmin -padmin -P9066 -h 10.11.33.211
您可以使用mysql一样的方式执行以下语句用于在实例上建立虚拟结点对应的schema
mysql> create database @@shardingnode='dn$1-2';
Query OK, 1 row affected (0.12 sec)
执行完后,可以在两个物理数据库节点看到已经创建user1和user2库。
## mysql节点1已经创建user1
mysql> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| mysql |
| performance_schema |
| sys |
| user1 |
+--------------------+
5 rows in set (0.00 sec)
## mysql节点2已经创建user2
mysql> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| mysql |
| performance_schema |
| sys | |
| user2 |
+--------------------+
5 rows in set (0.00 sec)
-
再在dble节点登录使用用户
#登录使用用户
mysql -utest -p123456 -P8066 -h 10.11.33.211
# 查询虚拟结点库testdb,也就是sharding.xml中指定的testdb,系统会自动创建
mysql> show databases;
±---------+
| DATABASE |
±---------+
| testdb |
±---------+
1 row in set (0.00 sec)mysql> use testdb; Database changed ## 创建user表,这个表名是根据sharding.xml的schema name来确定的 mysql> CREATE TABLE `user` ( -> `id` int(11) NOT NULL , -> `user_name` varchar(20) DEFAULT NULL, -> `nick` varchar(20) DEFAULT NULL, -> `phone` varchar(20) DEFAULT NULL, -> PRIMARY KEY (`id`) -> ) ENGINE=InnoDB DEFAULT CHARSET=latin1; Query OK, 0 rows affected (0.40 sec) ## 这步创建user后,可以在mysql两个数据节点看到user1和user2库下已经创建了user表 ## mySql节点1 mysql> show tables; +-----------------+ | Tables_in_user2 | +-----------------+ | user | +-----------------+ 1 row in set (0.00 sec) ## mySql节点2 mysql> show tables; +-----------------+ | Tables_in_user1 | +-----------------+ | user | +-----------------+ 1 row in set (0.00 sec) ## 插入数据 mysql> INSERT INTO `user`(`user_name`, `nick`, `phone`) VALUES ("zs", "sea", "121212122"); ERROR 1264 (22003): Out of range value for column 'id' at row 1 ## 可以看到报错了,具体报错信息可以在dble.log中看到,具体报错如下:很明显,插入的id值是以时间戳的格式,超过id的最大值。说明主键自增没有设置成功,接下来需要修改全局配置自增方式。 with session NonBlockSession with target INSERT INTO `user`(`user_name`, `nick`, `phone`) VALUES ("zs", "sea", "121212122"), route={ 1 -> dn2-{testdb.user}.0-{INSERT INTO `user` (`user_name`, `nick`, `phone`, `ID`) VALUES ('zs', 'sea', '121212122', 2186138370442175)}
修改全局配置参考docker下的配置
验证
重新登录dble分库⽤⼾账号,插入user表数据,到mysql两个数据库节点查看是否有对应的数据,并满足分表规则。可以参考docker的创建。