MySQL · 源码阅读 · Secondary Engine

本文涉及的产品
云数据库 RDS MySQL Serverless,0.5-2RCU 50GB
云数据库 RDS MySQL Serverless,价值2615元额度,1个月
简介: 背景MySQL默认的存储引擎是InnoDB,而引入Secondary Engine,用来实现同时支持第二引擎,在同一个MySQL Server上挂多个存储引擎,在支持InnoDB的同时,还可以把数据存放在其他的存储引擎上。 全量的数据都存储在Primary Engine上,某些指定数据在Secondary Engine 上也存放了一份,然后在访问这些数据的时候,会根据系统参数和cost选择存储引擎

背景

MySQL默认的存储引擎是InnoDB,而引入Secondary Engine,用来实现同时支持第二引擎,在同一个MySQL Server上挂多个存储引擎,在支持InnoDB的同时,还可以把数据存放在其他的存储引擎上。 全量的数据都存储在Primary Engine上,某些指定数据在Secondary Engine 上也存放了一份,然后在访问这些数据的时候,会根据系统参数和cost选择存储引擎,提高查询效率。

在最新版本8.0.22上还支持了启动和停止某个Secondary Engine。

MySQL官方集成了RAPID来为MySQL提供实时的数据分析服务,同时支持InnoDB和RAPID,但未开源,开源MySQL引入Secondary Engine,有助于我们集成其他存储引擎或者数据库。

本文是基于最新版本的MySQL-8.0.22源码解读的。

  • 安装一个secondary engine MOCK 使用Secondary Engine之前需要安装插件,目前源码中有模拟Secondary Engine的插件ha_mock.so
  • 与Secondary Engine有关的系统变量
SET @use_secondary_engine= "ON";
SET @use_secondary_engine= "OFF";
SET @use_secondary_engine= "FORCED";

use_secondary_engine设置为“ON”,表示在使用primary engine的cost大于Secondary engine的情况下使用secondary engine; use_secondary_engine设置为“OFF”,表示不使用Secondary engine; use_secondary_engine设置为“FORCED”,表示强制使用Secondary engine。

  • 表定义时需要指明使用Secondary Engine,如:
  • 加载和卸载数据的语法如下:
ALTER TABLE T1 SECONDARY_LOAD; 
ALTER TABLE T1 SECONDARY_UNLOAD;

内核的实现

如图所示,Secondary Engine实际上是MySQL sever上同时支持两个存储引擎,把一部分主引擎上的数据,在Secondary Engine上也保存一份,然后查询的时候会根据优化器的的选择决定在哪个引擎上处理数据。

定义和声明

Sql_cmd {
// The handlerton will be assigned in open_tables_for_query()
const handlerton *m_secondary_engine;
}
TABLE_SHARE {
/// Secondary storage engine
LEX_CSTRING secondary_engine;

/// Does this TABLE_SHARE represent a table in a secondary storage engine?
bool m_secondary_engine{false};
}
//Column has an option NOT SECONDARY
Field {
// Engine specific attributes
LEX_CSTRING m_secondary_engine_attribute;
}

加载/卸载数据

TABLE::read_set

TABLE::read_set 用来标记哪些coloum的数据需要load到Secondary Engine上。默认这个表的所有columns都需要load到Secondary Engine上,除非这个column上标记了NOT SECONDARY的属性。

  bool Sql_cmd_secondary_load_unload::mysql_secondary_load_or_unload(
    THD *thd, TABLE_LIST *table_list) {
	...
  // Omit hidden generated columns and columns marked as NOT SECONDARY from
  // read_set. It is the responsibility of the secondary engine handler to load
  // only the columns included in the read_set.
  bitmap_clear_all(table_list->table->read_set);
  for (Field **field = table_list->table->field; *field != nullptr; ++field) {
    // Skip hidden generated columns.
    if (bitmap_is_set(&table_list->table->fields_for_functional_indexes,
                      (*field)->field_index))
      continue;

    // Skip columns marked as NOT SECONDARY.
    if ((*field)->flags & NOT_SECONDARY_FLAG) continue;

    // Mark column as eligible for loading.
    table_list->table->mark_column_used(*field, MARK_COLUMNS_READ);
	//   bitmap_set_bit(read_set, field->field_index);
  }
  ...
  // Initiate loading into or unloading from secondary engine.
  const bool error =
      is_load
          ? secondary_engine_load_table(thd, *table_list->table)
          : secondary_engine_unload_table(
                thd, table_list->db, table_list->table_name, *table_def, true);
  ...

两阶段加载

加载数据到Secondary Engine的过程有两阶段组成:

  • 第一阶段, ha_prepare_load_table prepare阶段通常是很短的一段时间,需要持有一把MDL_EXCLUSIVE 表锁,持有锁的时间很短,主要是为了保证在开始数据加载之前提交对于该表的所有DML操作。
  DBUG_ASSERT(thd->mdl_context.owns_equal_or_stronger_lock(
      MDL_key::TABLE, table.s->db.str, table.s->table_name.str, MDL_EXCLUSIVE));
  DBUG_ASSERT(table.s->has_secondary_engine());

  // At least one column must be loaded into the secondary engine.
  if (bitmap_bits_set(table.read_set) == 0) {
    my_error(ER_SECONDARY_ENGINE, MYF(0),
             "All columns marked as NOT SECONDARY");
    return true;
  }
  • 第二阶段, ha_load_table 这个阶段是真正加载数据的阶段,使用InnoDB的Parallel_reader_adapter实现并行扫描数据以提高加载效率。
// InnoDB parallel scan context
Parallel_reader_adapter

struct handler {
// Parallel scan interface, could be explored to speed up offload process 
int parallel_scan_init(void *&scan_ctx, size_t &num_threads);
int parallel_scan(void *scan_ctx, void **thread_ctxs,
                  Load_init_cbk init_fn, Load_cbk load_fn, Load_end_cbk end_fn);
void parallel_scan_end(void *scan_ctx);

// Allows concurrent DML in the offload process
int ha_prepare_load_table(const TABLE &table);
int ha_load_table(const TABLE &table);
int ha_unload_table(const char *db_name, const char *table_name,
                    bool error_if_not_loaded);

void ha_set_primary_handler(handler *primary_handler);
};

优化器

一般情况下,如果访问主引擎获取这些数据的cost大于某一个特定值threshold的时候,会选择通过Secondary Engine访问这些数据,而其他只存储在主引擎的数据,还是通过主引擎访问。Secondary Engine用于Primary Engine上执行时间过长的查询,会尝试在Secondary Engine上执行。

在query执行之前,优化器的最后阶段增加了optimize_secondary_engine,但并不是所有的query都要经过optimize_secondary_engine。目的主要是避免在Primary engine上执行很快的query经过secondary engine执行。

  • 首先先走正常的优化流程  unit->optimize()
  • 然后估算当前查询的current_query_cost accumulate current_query_cost
  • 如果current_query_cost大于secondary_engine_cost_threshold If (current_query_cost < variables.secondary_engine_cost_threshold) return false; optimize_secondary_engine

Mock

Mock是为了对MySQL进行与Secondary Engine相关的功能测试而写的一个Secondary Engine的demo。他定义了用于适配Secondary Engine的接口。 mock 的源码在 router/src/mock_server目录下, 与secondary engine适配的接口在 storage/secondary_engine_mock/ha_mock.h storage/secondary_engine_mock/ha_mock.cc

系统价值

Secondary Engine是MySQL为了支持多引擎提供一种方法和实现框架。在此基础上,MySQL可以根据不同存储引擎对数据处理的特点来把不同的查询计划匹配到合适的存储引擎的上执行,从而发挥多种存储引擎各自的优点,优化整个SQL的查询效率。为多模架构和异构数据库的实现提供了一种框架。 比如,我们可以利用Secondary Engine接入ClickHouse,来承接分析型的查询。

现状

Secondary Engine的基础框架已经搭建起来了,实现了一个用于功能测试demo mock。但是还不够完善: 目前load数据只支持存量数据的加载,还不能支持增量数据的加载。不能支持实时的数据同步到secondary engine上。 目前还没有直接可以作为MySQL的Secondary Engine的存储引擎,如果接入,需要做一些适配的研发工作。

前景

随着数据库的发展,人们对处理异构数据的需求 越来越强烈,需要这种支持多引擎的数据库出现,Secondary engine还有很多事情要做 1、支持增量数据的loading,除了一次性把所有标记需要存储到Secondary Engine的数据加载过去,还需要支持实时的把主引擎产生的增量数据同步过去。 2、支持只写Secondary Engine,支持某些指定的数据只写在Secondary Engine上,而不需要先写主引擎,再同步到Secondary Engine。 3、支持hint。查询时可以通过hint指定在某个特定的Secondary Engine上执行某一部分执行计划。 4、可以使用Secondary Engine 来实现多模、异构数据库。

参考

https://downloads.mysql.com/presentations/oow2019/mysql_oow19_keynote_agarwal.pdf

相关实践学习
基于CentOS快速搭建LAMP环境
本教程介绍如何搭建LAMP环境,其中LAMP分别代表Linux、Apache、MySQL和PHP。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助 &nbsp; &nbsp; 相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
相关文章
|
3月前
|
监控 数据可视化 关系型数据库
微服务架构+Java+Spring Cloud +UniApp +MySql智慧工地系统源码
项目管理:项目名称、施工单位名称、项目地址、项目地址、总造价、总面积、施工准可证、开工日期、计划竣工日期、项目状态等。
310 6
|
4月前
|
JavaScript 关系型数据库 MySQL
基于JavaWeb和mysql实现校园订餐前后台管理系统(源码+数据库)
基于JavaWeb和mysql实现校园订餐前后台管理系统(源码+数据库)
|
4月前
|
NoSQL 关系型数据库 MySQL
基于Python和mysql开发的智慧校园答题考试系统(源码+数据库+程序配置说明书+程序使用说明书)
基于Python和mysql开发的智慧校园答题考试系统(源码+数据库+程序配置说明书+程序使用说明书)
|
14天前
|
运维 监控 安全
云HIS医疗管理系统源码——技术栈【SpringBoot+Angular+MySQL+MyBatis】
云HIS系统采用主流成熟技术,软件结构简洁、代码规范易阅读,SaaS应用,全浏览器访问前后端分离,多服务协同,服务可拆分,功能易扩展;支持多样化灵活配置,提取大量公共参数,无需修改代码即可满足不同客户需求;服务组织合理,功能高内聚,服务间通信简练。
30 4
|
4月前
|
NoSQL 关系型数据库 MySQL
基于Python和mysql开发的BBS问答社区管理系统(源码+数据库+程序配置说明书+程序使用说明书)
基于Python和mysql开发的BBS问答社区管理系统(源码+数据库+程序配置说明书+程序使用说明书)
|
4月前
|
前端开发 IDE Java
基于Springboot+MYSQL+Maven实现的宠物医院管理系统(源码+数据库+运行指导文档+项目运行指导视频)
基于Springboot+MYSQL+Maven实现的宠物医院管理系统(源码+数据库+运行指导文档+项目运行指导视频)
168 0
|
19天前
|
Java 关系型数据库 MySQL
一套java+ spring boot与vue+ mysql技术开发的UWB高精度工厂人员定位全套系统源码有应用案例
UWB (ULTRA WIDE BAND, UWB) 技术是一种无线载波通讯技术,它不采用正弦载波,而是利用纳秒级的非正弦波窄脉冲传输数据,因此其所占的频谱范围很宽。一套UWB精确定位系统,最高定位精度可达10cm,具有高精度,高动态,高容量,低功耗的应用。
33 0
一套java+ spring boot与vue+ mysql技术开发的UWB高精度工厂人员定位全套系统源码有应用案例
|
22天前
|
传感器 小程序 Java
Java+saas模式 智慧校园系统源码Java Android +MySQL+ IDEA 多校运营数字化校园云平台源码
Java+saas模式 智慧校园系统源码Java Android +MySQL+ IDEA 多校运营数字化校园云平台源码 智慧校园即智慧化的校园,也指按智慧化标准进行的校园建设,按标准《智慧校园总体框架》中对智慧校园的标准定义是:物理空间和信息空间的有机衔接,使任何人、任何时间、任何地点都能便捷的获取资源和服务。
19 1
|
26天前
|
消息中间件 Java 关系型数据库
JAVA云HIS医院管理系统源码、基于Angular+Nginx+ Java+Spring,SpringBoot+ MySQL + MyCat
JAVA云HIS医院管理系统 常规模版包括门诊管理、住院管理、药房管理、药库管理、院长查询、电子处方、物资管理、媒体管理等,为医院管理提供更有力的保障。 HIS系统以财务信息、病人信息和物资信息为主线,通过对信息的收集、存储、传递、统计、分析、综合查询、报表输出和信息共享,及时为医院领导及各部门管理人员提供全面、准确的各种数据。
32 1
|
26天前
|
消息中间件 缓存 运维
java+saas模式医院云HIS系统源码Java+Spring+MySQL + MyCat融合BS版电子病历系统,支持电子病历四级
云HIS系统是一款满足基层医院各类业务需要的健康云产品。该产品能帮助基层医院完成日常各类业务,提供病患预约挂号支持、病患问诊、电子病历、开药发药、会员管理、统计查询、医生工作站和护士工作站等一系列常规功能,还能与公卫、PACS等各类外部系统融合,实现多层机构之间的融合管理。
46 1