ShardingSphere 元数据能力增强解读与实战

Apache ShardingSphere 元数据介绍

Apache ShardingSphere 的元数据主要包括规则、数据源、表结构等信息。规则信息可能包含分片、加密、读写分离、事务、高可用等。 数据源信息存储的是需要通过 ShardingSphere 来进行管理的底层数据库资源。表结构信息主要就是底层数据源的表结构,包括表的 column 信息、索引信息等。

Apache ShardingSphere 通过这些元数据信息配合治理中心的能力,例如 zookeeper、etcd 的存储和通知能力,可以实现集群内配置的共享和变更,从而实现计算节点的水平扩展。同时元数据信息对于 ShardingSphere 而言也是至关重要的,以表的数据结构为例,ShardingSphere 利用表的数据结构可以对采用了加密规则的 SQL 进行正确的改写,内核中的 federation 引擎也会利用表结构信息进行 SQL 优化。

既然 ShardingSphere 的元数据如此重要,那么我们该怎么入手了解元数据呢?

Apache ShardingSphere 三层元数据结构

ShardingSphere 的三层元数据结构是个了解元数据信息的很好入口。我们可以启动 ShardingSphere–proxy 的 cluster 模式,这样可以在 zookeeper 中直观的看到 ShardingSphere 的三层元数据结构。 如下结构展示了 ShardingSphere 元数据在 zookeeper 中的结构

DataTTL 相关调研

TiDB

使用

创建表时可以设置数据过期时间,然后后台定时任务删除相关数据

产品文档:https://docs.pingcap.com/zh/tidb/dev/time-to-live

功能列表

功能 备注
create 语句中增加 TTL 属性,指定表中数据的过期时间
create 语句中增加注释信息(兼容 MySQL),包含 TTL 属性
alter 语句修改 TTL 属性
TTL 可以配合表中其它列的属性来使用
可以指定 TTL 任务时间间隔

PolarDB-X

创建 TTL 表,按照时间分区,定期删除和创建相关分区表

产品文档: https://help.aliyun.com/document_detail/403528.html

功能列表

功能 备注
对按照时间进行 range 分区的表,定时失效过期分区,定时提前创建分区 仅用在自动模式下的分区表上
支持通过 DDL 语句来定义相关分区的 TTL TTL表支持的时间分区列类型为:date、datetime; 所有的唯一键(包括主键)必须包含TTL表的local partition by range时间分区列;所有的唯一键(包括主键)必须包含TTL表的local partition by range时间分区列
支持查看分区信息以及过期时间等 information_schema.local_partitions
支持校验物理表的物理分区的完整性
支持 Alter 语句手动创建新分区表/删除过期分区表
支持普通表和 TTL 表互相转换
支持创建、查看、删除 TTL 定时任务

Google Spanner

创建表时可以设置行删除策略,后台任务扫描表并删除相关行

ShardingSphere 内置数据库设计

目标

  • 新增 SS 默认系统库,初步支持全局静态元数据(编码、事务隔离级别)管理
  • 设计元数据调度收集功能,支持 ShardingSphere 动态元数据管理(数据分布等信息)

现状

当前 ss 缺乏自己的元数据信息,例如分片的数据分布、编码等等。

之前为了解决各个客户端连接报错的问题,设计了各个数据库方言的模拟库。 只有用户表会从真实数据库获取,其他表都是通过 yaml 文件来模拟存储到 zk 的。

元数据存储调研

MySQL

Mysql 将相关参数放在 variables_info 并将相关值设置在全局或 session 级别对应的表中

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
mysql> show tables like '%variables%';
+--------------------------------------------+
| Tables_in_performance_schema (%variables%) |
+--------------------------------------------+
| global_variables                           |
| persisted_variables                        |
| session_variables                          |
| user_variables_by_thread                   |
| variables_by_thread                        |
| variables_info                             |
+--------------------------------------------+

查询隔离级别

ShardingSphere PostgreSQL openGauss \d 支持方案

PG \d 支持

\d 的现状

\d 实际执行的语句如下

SELECT n.nspname as "Schema",
  c.relname as "Name",
  CASE c.relkind WHEN 'r' THEN 'table' WHEN 'v' THEN 'view' WHEN 'i' THEN 'index' WHEN 'I' THEN 'global partition index' WHEN 'S' THEN 'sequence' WHEN 'L' THEN 'large sequence' WHEN 'f' THEN 'foreign table' WHEN 'm' THEN 'materialized view'  WHEN 'e' THEN 'stream' WHEN 'o' THEN 'contview' END as "Type",
  pg_catalog.pg_get_userbyid(c.relowner) as "Owner",
  c.reloptions as "Storage"
FROM pg_catalog.pg_class c
     LEFT JOIN pg_catalog.pg_namespace n ON n.oid = c.relnamespace
WHERE c.relkind IN ('r','v','m','S','L','f','e','o','')
      AND n.nspname <> 'pg_catalog'
      AND n.nspname <> 'db4ai'
      AND n.nspname <> 'information_schema'
      AND n.nspname !~ '^pg_toast'
      AND c.relname not like 'matviewmap\_%'
      AND c.relname not like 'mlog\_%'
  AND pg_catalog.pg_table_is_visible(c.oid)
ORDER BY 1,2;

查询结果如下

Pisanix protocol

最近想写一下 mysql 前后端协议。

看看能否参照 pisanix 来写一个简单版本的协议。

发现一个同事写的最小化 MySQL Rust 代理实现