共计 12526 个字符,预计需要花费 32 分钟才能阅读完成。
Rapid 存储引擎简介
从 GreatSQL 8.0.32-25 版本开始,新增 Rapid 存储引擎,该引擎使得 GreatSQL 能满足联机剖析(OLAP)查问申请。
Rapid 引擎采纳插件(Plugin)形式嵌入 GreatSQL 中,能够在线动静装置或卸载。
Rapid 引擎不会间接面对客户端和应用程序,用户无需批改原有的数据拜访形式。它是一个无共享、内存化、混合列式存储的查询处理引擎,其设计目标是为了高性能的解决剖析型查问。
并且在 TPC- H 性能体现优异在 32C64G 测试机环境下,TPC-H 100G 测试中 22 条 SQL 总耗时 仅需不到 80 秒
上面是几个不同 TPC- H 数据量级的压缩率数据:
TPC- H 仓库大小 | InnoDB 引擎数据文件大小 | Rapid 引擎数据文件大小 | 压缩率 |
---|---|---|---|
TPC-H 1GB | 2003026076 | 276574208 | 7.24 |
TPC-H 100GB | 184570593436 | 28728373248 | 6.42 |
TPC-H 500GB | 1167795142848 | 146723045376 | 7.96 |
通过 GreatSQL 社区的测试剖析能够看出,相较于 InnoDB 存储引擎,Rapid 存储引擎在存储效率上取得了极大晋升。在寄存雷同的数据集时,Rapid 的数据文件所须要的空间仅为 InnoDB 的 6~7 分之 1,大概 升高了 85% 左右。
实在生产案例测试
为了全面验证 AP 引擎的性能晋升,咱们胜利获取了实在生产环境下的 SQL 语句、表构造以及通过脱敏解决的数据。在此,特别感谢潲同学和贵司的帮助!
测试环境介绍
本次测试采纳的环境是 Arch Linux x86_64,机器配置为 12C15G
$ uname -a
Linux myarch 6.6.3-arch1-1 #1 SMP PREEMPT_DYNAMIC Wed, 29 Nov 2023 00:37:40 +0000 x86_64 GNU/Linux
$ cat /proc/cpuinfo | grep "processor" | wc -l
12
$ free -h
total
Mem: 15Gi
采纳的 GreatSQL 版本为 GreatSQL 8.0.32-25 版本
$ mysql --version
mysql Ver 8.0.32-25 for Linux on x86_64 (GreatSQL, Release 25, Revision 79f57097e3f)
实在生产 SQL
展现行将进行测试的生产 SQL(这里不深刻探讨该 SQL 是否存在优化的可能性):
select c.id, c.dept_id, c.user_id, c.type, c.source, c.charge_no, c.amount, c.from_bank, c.to_bank, c.receipt,c.status, c.remark, c.create_by, c.create_time, c.update_by, c.update_time,c.reason,c.fr_no
, d.dept_name, dt.company_name, cp.company_name
from charge c
left join dept d on c.dept_id = d.dept_id
left join user u on c.user_id = u.user_id
left join dept_tax dt on c.dept_id = dt.dept_id
left join dept_info di on c.dept_id = di.dept_id
left join company_bank cb on di.sign_cbid = cb.id
left join company cp on cb.company_id = cp.company_id
limit 3313445,10;
实在生产表构造
生产 SQL 波及 7 张表,咱们将逐个展现每张表的表构造。为了爱护隐衷,咱们对局部字段进行了脱敏解决以及一些微调
dept 表
CREATE TABLE `dept` (`dept_id` bigint(20) NOT NULL AUTO_INCREMENT,
`parent_id` bigint(20) DEFAULT '0',
`ancestors` varchar(50) DEFAULT '',
`dept_name` varchar(30) DEFAULT '',
......
`create_time` datetime DEFAULT NULL,
`update_by` varchar(64) DEFAULT '',
`update_time` datetime DEFAULT NULL,
PRIMARY KEY (`dept_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='部门表'
user 表
CREATE TABLE `user` (`user_id` bigint(20) NOT NULL AUTO_INCREMENT,
`dept_id` bigint(20) DEFAULT NULL,
`fans_id` bigint(20) DEFAULT NULL,
`login_name` varchar(30) NOT NULL,
`user_name` varchar(30) NOT NULL,
`alias` varchar(100) DEFAULT NULL,
`user_type` varchar(2) DEFAULT '00',
`email` varchar(50) DEFAULT '',
`phonenumber` varchar(11) DEFAULT '',
`sex` char(1) DEFAULT '0',
......
`create_by` varchar(64) DEFAULT '',
`create_time` datetime DEFAULT NULL,
`update_by` varchar(64) DEFAULT '',
`update_time` datetime DEFAULT NULL,
`remark` varchar(500) DEFAULT NULL,
PRIMARY KEY (`user_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='用户表'
dept_tax 表
CREATE TABLE `dept_tax` (`id` bigint(20) NOT NULL AUTO_INCREMENT,
`dept_id` bigint(20) NOT NULL,
`company_name` varchar(50) NOT NULL,
`tax_no` varchar(50) DEFAULT NULL,
`tax_type` varchar(30) DEFAULT NULL,
......
`create_by` varchar(50) DEFAULT '',
`create_time` datetime DEFAULT NULL,
`update_by` varchar(50) DEFAULT '',
`update_time` datetime DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='信息表'
dept_info 表
CREATE TABLE `dept_info` (`id` bigint(20) NOT NULL AUTO_INCREMENT,
`dept_id` bigint(20) NOT NULL,
`customer_id` bigint(20) DEFAULT NULL,
`dept_type` char(1) DEFAULT '1',
`industry_type` char(1) DEFAULT '0',
`dept_flag` char(1) DEFAULT '1',
`dept_kind` char(1) DEFAULT '0',
`bus_scope` varchar(10) DEFAULT '1',
`channel_id` bigint(20) DEFAULT NULL,
......
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='信息表'
company_bank 表
CREATE TABLE `company_bank` (`id` bigint(20) NOT NULL AUTO_INCREMENT,
`company_id` bigint(20) DEFAULT NULL,
`bank_name` varchar(50) DEFAULT NULL,
`bank_card` varchar(30) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4
company 表
CREATE TABLE `company` (`company_id` bigint(20) NOT NULL AUTO_INCREMENT,
`company_name` varchar(100) DEFAULT NULL,
PRIMARY KEY (`company_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4
charge 表
CREATE TABLE `charge` (`id` bigint(20) NOT NULL AUTO_INCREMENT,
`dept_id` bigint(20) NOT NULL,
`user_id` bigint(20) DEFAULT NULL,
`type` char(1) DEFAULT NULL,
......
`create_time` datetime DEFAULT NULL,
`update_by` varchar(50) DEFAULT '',
`update_time` datetime DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4
不深入探讨 SQL 和表构造是否存在优化的可能性,只验证 AP 引擎晋升查问测试。
加载数据
鉴于原始数据较为无限,为了更显著地进行测试,咱们为每张表生成了一些新数据,来看下各表数据和表空间大小是多少:
表名 | 数据量 | 表空间大小 |
---|---|---|
dept | 11000 | 10M |
user | 100000 | 31M |
dept_tax | 10000 | 88M |
charge | 1000000 | 184M |
company | 1000 | 160K |
dept_info | 10000 | 11M |
company_bank | 1000 | 176K |
未革新测试
待测试的 SQL 语句:
select c.id, c.dept_id, c.user_id, c.type, c.source, c.charge_no, c.amount, c.from_bank, c.to_bank, c.receipt,c.status, c.remark, c.create_by, c.create_time, c.update_by, c.update_time,c.reason,c.fr_no
, d.dept_name, dt.company_name, cp.company_name
from _charge c
left join dept d on c.dept_id = d.dept_id
left join user u on c.user_id = u.user_id
left join dept_tax dt on c.dept_id = dt.dept_id
left join dept_info di on c.dept_id = di.dept_id
left join company_bank cb on di.sign_cbid = cb.id
left join company cp on cb.company_id = cp.company_id
limit 3313445,10;
先不应用 AP 引擎测试查问五次:
测试次数 | 耗时 |
---|---|
第一次 | 10 rows in set (12.64 sec) |
第二次 | 10 rows in set (12.77 sec) |
第三次 | 10 rows in set (12.60 sec) |
第四次 | 10 rows in set (12.61 sec) |
第五次 | 10 rows in set (12.59 sec) |
能够看到五次测试后果都是稳固在 12 秒左右,均匀耗时 12.64/s:
应用 Rapid 引擎测试
启用 Rapid 引擎
greatsql> INSTALL PLUGIN Rapid SONAME 'ha_rapid.so';
greatsql> SHOW PLUGINS;
+----------------------------------+----------+--------------------+----------------------+---------+
| Name | Status | Type | Library | License |
+----------------------------------+----------+--------------------+----------------------+---------+
| binlog | ACTIVE | STORAGE ENGINE | NULL | GPL |
...
| Rapid | ACTIVE | STORAGE ENGINE | ha_rapid.so | GPL |
+----------------------------------+----------+--------------------+----------------------+---------+
55 rows in set (0.00 sec)
加上 Rapid 辅助引擎
greatsql> ALTER TABLE dept SECONDARY_ENGINE = rapid;
Query OK, 0 rows affected (0.02 sec)
Records: 0 Duplicates: 0 Warnings: 0
greatsql> ALTER TABLE user SECONDARY_ENGINE = rapid;
greatsql> ALTER TABLE charge SECONDARY_ENGINE = rapid;
greatsql> ALTER TABLE company SECONDARY_ENGINE = rapid;
greatsql> ALTER TABLE company_bank SECONDARY_ENGINE = rapid;
greatsql> ALTER TABLE dept_info SECONDARY_ENGINE = rapid;
greatsql> ALTER TABLE dept_tax SECONDARY_ENGINE = rapid;
查看建表 DDL,发现减少了 SECONDARY_ENGINE=rapid
greatsql> SHOW CREATE TABLE _company\G
*************************** 1. row ***************************
Table: company
Create Table: CREATE TABLE `company` (
`company_id` bigint NOT NULL AUTO_INCREMENT COMMENT '序号 ID',
`company_name` varchar(100) DEFAULT NULL COMMENT '签约主体',
PRIMARY KEY (`company_id`)
) ENGINE=InnoDB AUTO_INCREMENT=1001 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci SECONDARY_ENGINE=rapid
1 row in set (0.00 sec)
数据全量导入 Rapid 引擎中
greatsql> ALTER TABLE dept SECONDARY_LOAD;
greatsql> ALTER TABLE user SECONDARY_LOAD;
greatsql> ALTER TABLE charge SECONDARY_LOAD;
greatsql> ALTER TABLE company SECONDARY_LOAD;
greatsql> ALTER TABLE company_bank SECONDARY_LOAD;
greatsql> ALTER TABLE dept_info SECONDARY_LOAD;
greatsql> ALTER TABLE dept_tax SECONDARY_LOAD;
开始测试 Rapid 引擎
有两种形式启用 Rapid 引擎
形式一
-- 设置 use_secondary_engine=ON 的时候,为保障查问语句可能应用 rapid,-- 通常须要设置 secondary_engine_cost_threshold = 0,或一个较小的阈值
SET use_secondary_engine = ON;
SET secondary_engine_cost_threshold = 0;
形式二(不倡议)
-- 批改会话变量,设置强制应用 Rapid 引擎
SET use_secondary_engine = FORCED;
-- 或执行 SQL 查问时指定 HINT
SELECT /*+ SET_VAR(use_secondary_engine=forced) */ ... 省略 FROM from charge c;
先应用计划二,执行 SQL 查问时指定 HINT 测试五次看看体现如何
待测试的 SQL 语句:
select /*+ SET_VAR(use_secondary_engine=forced) */ c.id, c.dept_id, c.user_id, c.type, c.source, c.charge_no, c.amount, c.from_bank, c.to_bank, c.receipt,c.status, c.remark, c.create_by, c.create_time, c.update_by, c.update_time,c.reason,c.fr_no
, d.dept_name, dt.company_name, cp.company_name
from _charge c
left join dept d on c.dept_id = d.dept_id
left join user u on c.user_id = u.user_id
left join dept_tax dt on c.dept_id = dt.dept_id
left join dept_info di on c.dept_id = di.dept_id
left join company_bank cb on di.sign_cbid = cb.id
left join company cp on cb.company_id = cp.company_id
limit 3313445,10;
同样测试查问五次:
测试次数 | 耗时 |
---|---|
第一次 | 10 rows in set (0.48 sec) |
第二次 | 10 rows in set (0.47 sec) |
第三次 | 10 rows in set (0.46 sec) |
第四次 | 10 rows in set (0.48 sec) |
第五次 | 10 rows in set (0.46 sec) |
能够看到 Rapid 引擎出手即是秒杀,均匀耗时 0.47/s:
革新前(均匀耗时 12.64/s)和革新后(均匀耗时 0.47/s)比照测试后果:
总体来说革新后约晋升了 26.9 倍:
如果咱们抉择应用 HINT 进行革新,就须要对原 SQL 语句进行相应批改。因而,咱们将采纳计划一来进行试验
greatsql> SET use_secondary_engine = ON;
greatsql> secondary_engine_cost_threshold = 0;
# 查看下执行打算
greatsql> explain select c.id, c.dept_id, c.user_id, c.type, c.source, c.charge_no, c.amount, c.from_bank, c.to_bank, c.receipt,c.status, c.remark, c.create_by, c.create_time, c.update_by, c.update_time,c.reason,c.fr_no , d.dept_name, dt.company_name, cp.company_name from charge c left join dept d on c.dept_id = d.dept_id left join user u on c.user_id = u.user_id left join dept_tax dt on c.dept_id = dt.dept_id left join dept_info di on c.dept_id = di.dept_id left join company_bank cb on di.sign_cbid = cb.id left join company cp on cb.company_id = cp.company_id limit 3313445,10\G
*************************** 1. row ***************************
id: 1
select_type: SIMPLE
table: c
partitions: NULL
type: ALL
possible_keys: NULL
key: NULL
key_len: NULL
ref: NULL
rows: 905486
filtered: 100.00
Extra: Using secondary engine RAPID # 证实用到 RAPID 引擎
# 下方省略,证实有用到 RAPID 引擎即可
能够看到默认的应用了 RAPID 引擎
数据导入
在上方咱们执行过 ALTER TABLE xxx SECONDARY_LOAD
这个操作,会将 InnoDB 主引擎中的数据全量加载到 Rapid 引擎中,这个过程称为全量导入。全量导入胜利后,Rapid 引擎中的数据是动态的,当向主引擎表中持续插入、删除、批改数据时,并不会导入到 Rapid 引擎中。
那数据会更新会批改要怎么办呢?总不能每次都全量导入吧?
所以此时能够利用 binlog 个性,能够在全量导入胜利后,启动增量导入工作。增量工作会读取自全量导入胜利之后的 binlog 数据,将 binlog 解析并利用到 rapid 引擎中,这个过程称为 增量导入。
不同于全量导入,增量导入会启动一个常驻的后盾线程,实时读取和利用增量 binlog 数据。
增量导入数据的限度和需要
在手册上有介绍到增量导入数据的限度和需要,如下:
- 须要设置表名大小写不敏感,即设置
lower_case_table_names = 1
。 - 须要开启 GTID 模式,即设置
gtid_mode = ON
和enforce_gtid_consistency = ON
。 - 须要采纳 row 格局的 binlog event,不反对 statement 格局,即设置
binlog_format = ROW
。增量工作运行过程中,检测到 statement 的 DML event,可能会报错退出。 - 须要敞开 GIPKs 个性,即设置
sql_generate_invisible_primary_key = OFF
。用户表不能有 invisible primary key,如果表蕴含隐式不可见的主键,在全量导入过程中会报错;同时也不反对用户表中存在任何不可见列(invisible column)。 - 须要先对表执行过一次全量导入后,能力启动增量导入工作,否则工作启动会报错。
- 不反对 PARTIAL_UPDATE_ROWS_EVENT 类型的 binlog,即不要设置
binlog_row_value_options = PARTIAL_JSON
。 - 不反对
CREATE TABLE SELECT
语句,增量工作运行过程中,检测到该语句产生的 binlog event 时可能会报错退出。 - 不反对 XA 事务,运行过程中查看到 XA 事务会报错退出。
开启增量导入
增量导入有两个零碎函数别离是
START_SECONDARY_ENGINE_INCREMENT_LOAD_TASK()
:启动工作STOP_SECONDARY_ENGINE_INCREMENT_LOAD_TASK()
:进行工作
执行 SQL 命令 SELECT START_SECONDARY_ENGINE_INCREMENT_LOAD_TASK()
即可启动增量工作,依据函数返回信息能够确认是否工作启动胜利。如果启动失败,能够从谬误日志中查看具体失败的起因。
该函数蕴含 3 个参数:
- db_name,必选项,指定增量导入工作对应的数据库名。
- table_name,必选项,指定增量导入工作对应的数据表名。
- gtid,可选项,指定开始增量导入工作的起始 gtid_set 值。默认不须要指定,工作会主动依据
ALTER TABLE ... SECONDARY_LOAD
全量导入时刻的gtid_executed
进行计算和判断。
-- 对 user 表启动增量导入工作
greatsql> SELECT START_SECONDARY_ENGINE_INCREMENT_LOAD_TASK('aptest', 'user');
+------------------------------------------------------------------+
| START_SECONDARY_ENGINE_INCREMENT_LOAD_TASK('aptest', 'user') |
+------------------------------------------------------------------+
| success |
+------------------------------------------------------------------+
1 row in set (0.00 sec)
-- 查看增量导入工作状态
greatsql> SELECT * FROM information_schema.SECONDARY_ENGINE_INCREMENT_LOAD_TASK\G
*************************** 1. row ***************************
DB_NAME: aptest
TABLE_NAME: user
START_TIME: 2024-02-21 09:33:55
START_GTID: 9548406d-8ff1-11ee-97ec-ec5c6826bca3:1-3808
COMMITTED_GTID_SET: 9548406d-8ff1-11ee-97ec-ec5c6826bca3:1-3821
READ_GTID: 9548406d-8ff1-11ee-97ec-ec5c6826bca3:3821
READ_BINLOG_FILE: ./binlog.000023
READ_BINLOG_POS: 596312770
DELAY: 0
STATUS: RUNNING
END_TIME:
INFO:
1 row in set (0.00 sec)
当然如果想进行也能够应用以下操作进行增量同步
greatsql> SELECT STOP_SECONDARY_ENGINE_INCREMENT_LOAD_TASK('aptest', 'user');
greatsql> SELECT STOP_SECONDARY_ENGINE_INCREMENT_LOAD_TASK('aptest', 'user');
+-----------------------------------------------------------------+
| STOP_SECONDARY_ENGINE_INCREMENT_LOAD_TASK('aptest', 'user') |
+-----------------------------------------------------------------+
| success |
+-----------------------------------------------------------------+
1 row in set (0.21 sec)
greatsql> SELECT * FROM information_schema.SECONDARY_ENGINE_INCREMENT_LOAD_TASK\G
*************************** 1. row ***************************
DB_NAME: aptest
TABLE_NAME: user
START_TIME: 2024-02-21 09:33:55
START_GTID: 9548406d-8ff1-11ee-97ec-ec5c6826bca3:1-3808
COMMITTED_GTID_SET: 9548406d-8ff1-11ee-97ec-ec5c6826bca3:1-3821
READ_GTID: 9548406d-8ff1-11ee-97ec-ec5c6826bca3:3821
READ_BINLOG_FILE: ./binlog.000023
READ_BINLOG_POS: 596312770
DELAY: 60
STATUS: NOT RUNNING
END_TIME: 2024-02-21 09:35:46
INFO: NORMAL EXIT
1 row in set (0.00 sec)
更多 Rapid 存储引擎介绍请返回 GreatSQL 用户手册上查看 Rapid 引擎(Rapid Engine)https://greatsql.cn/docs/8032-25/user-manual/5-enhance/5-1-hi…
总结
对于在不革新 SQL 的前提下,查问速度晋升了 26.9 倍 的这一后果,潲同学示意十分诧异。然而,令人遗憾的是,他们尚未迁徙到 GreatSQL 数据库。因而,他目前正紧锣密鼓地向总监提议,争取尽快实现迁徙并采纳 GreatSQL 数据库:)
目前 Rapid 存储引擎曾经凋谢测试了,欢送各位来体验测试~
GreatSQL 手册:https://greatsql.cn/docs/8032-25/
GreatSQL 下载地址:https://gitee.com/GreatSQL/GreatSQL/releases/tag/GreatSQL-8.0…
Enjoy GreatSQL :)
对于 GreatSQL
GreatSQL 数据库是一款 开源收费 数据库,可在一般硬件上满足金融级利用场景,具备 高可用 、 高性能 、 高兼容 、 高平安 等个性,可作为 MySQL 或 Percona Server for MySQL 的现实可选替换。
相干链接
GreatSQL 社区
Gitee
Github
Bilibili
技术交换群
微信:增加 GreatSQL 社区助手
好友,微信号 wanlidbc
发送验证信息 加群
QQ 群:533341697
Enjoy GreatSQL :)
## 对于 GreatSQL
GreatSQL 是实用于金融级利用的国内自主开源数据库,具备高性能、高牢靠、高易用性、高平安等多个外围个性,能够作为 MySQL 或 Percona Server 的可选替换,用于线上生产环境,且完全免费并兼容 MySQL 或 Percona Server。
相干链接:GreatSQL 社区 Gitee GitHub Bilibili
GreatSQL 社区:
社区博客有奖征稿详情:https://greatsql.cn/thread-100-1-1.html
技术交换群:
微信:扫码增加
GreatSQL 社区助手
微信好友,发送验证信息加群
。