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 1GB20030260762765742087.24
TPC-H 100GB184570593436287283732486.42
TPC-H 500GB11677951428481467230453767.96

通过GreatSQL社区的测试剖析能够看出,相较于InnoDB存储引擎,Rapid存储引擎在存储效率上取得了极大晋升。在寄存雷同的数据集时,Rapid的数据文件所须要的空间仅为InnoDB的6~7分之1,大概 升高了85% 左右。

实在生产案例测试

为了全面验证AP引擎的性能晋升,咱们胜利获取了实在生产环境下的SQL语句、表构造以及通过脱敏解决的数据。在此,特别感谢潲同学和贵司的帮助!

测试环境介绍

本次测试采纳的环境是 Arch Linux x86_64,机器配置为12C15G

$ uname -aLinux 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 -l12$  free -h     totalMem: 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 cleft join dept d on c.dept_id = d.dept_idleft join user u on c.user_id = u.user_idleft join dept_tax dt on c.dept_id = dt.dept_idleft join dept_info di on c.dept_id = di.dept_idleft join company_bank cb on di.sign_cbid = cb.idleft join company cp on cb.company_id = cp.company_idlimit 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引擎晋升查问测试。

加载数据

鉴于原始数据较为无限,为了更显著地进行测试,咱们为每张表生成了一些新数据,来看下各表数据和表空间大小是多少:

表名数据量表空间大小
dept1100010M
user10000031M
dept_tax1000088M
charge1000000184M
company1000160K
dept_info1000011M
company_bank1000176K

未革新测试

待测试的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 cleft join dept d on c.dept_id = d.dept_idleft join user u on c.user_id = u.user_idleft join dept_tax dt on c.dept_id = dt.dept_idleft join dept_info di on c.dept_id = di.dept_idleft join company_bank cb on di.sign_cbid = cb.idleft join company cp on cb.company_id = cp.company_idlimit 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: 0greatsql> 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: companyCreate 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=rapid1 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查问时指定HINTSELECT /*+ 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_namefrom _charge cleft join dept d on c.dept_id = d.dept_idleft join user u on c.user_id = u.user_idleft join dept_tax dt on c.dept_id = dt.dept_idleft join dept_info di on c.dept_id = di.dept_idleft join company_bank cb on di.sign_cbid = cb.idleft join company cp on cb.company_id = cp.company_idlimit 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: ALLpossible_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数据。

增量导入数据的限度和需要

在手册上有介绍到增量导入数据的限度和需要,如下:

  1. 须要设置表名大小写不敏感,即设置 lower_case_table_names = 1
  2. 须要开启GTID模式,即设置 gtid_mode = ONenforce_gtid_consistency = ON
  3. 须要采纳row格局的binlog event,不反对statement格局,即设置 binlog_format = ROW。增量工作运行过程中,检测到statement的DML event,可能会报错退出。
  4. 须要敞开GIPKs个性,即设置 sql_generate_invisible_primary_key = OFF。用户表不能有 invisible primary key,如果表蕴含隐式不可见的主键,在全量导入过程中会报错;同时也不反对用户表中存在任何不可见列(invisible column)。
  5. 须要先对表执行过一次全量导入后,能力启动增量导入工作,否则工作启动会报错。
  6. 不反对 PARTIAL_UPDATE_ROWS_EVENT 类型的binlog,即不要设置 binlog_row_value_options = PARTIAL_JSON
  7. 不反对 CREATE TABLE SELECT 语句,增量工作运行过程中,检测到该语句产生的binlog event时可能会报错退出。
  8. 不反对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-3808COMMITTED_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-3808COMMITTED_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 EXIT1 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社区助手微信好友,发送验证信息加群