关于数据库:AP引擎助力加速生产SQL运行

54次阅读

共计 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 数据。

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

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

  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-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 社区助手 微信好友,发送验证信息 加群

正文完
 0