Klustron 扩展的DDL和utility 语法
Klustron 扩展的DDL和utility 语法
自Klustron-1.2 开始,支持一下1,2,3项功能。 第 4 项功能在Klustron 1.0 开始的所有版本都支持。自1.3.1 开始新增语法如下5、6、7、8、9项功能。多数语法都是MySQL中支持的语法。
CREATE TABLE
1. 设置存储节点表选项
Klustron 支持在CREATE TABLE语句的with子句中设置以下选项,这些选项都会加到发送给存储节点的CREATE TABLE语句中,让存储节点上建的表具备用户指定的属性。用户可以指定其中任何一个或者多个存储选项,每个选项的合法选项值如无特别说明则与MySQL-8.0.26定义的值完全相同, 选项写法大小写无关。参加MySQL文档了解这些选项的更多信息。
- ENGINE,存储引擎种类,合法值: Innodb, RocksDB.
- COMPRESSION,Innodb 独立表文件页级压缩方式, 合法值: zlib, lz4, none
- ROW_FORMAT ,InnoDB引擎的行格式, 合法值: DYNAMIC, COMPRESSED, COMPACT
- ENCRYPTION,Innodb 表文件页级加密,合法值:'Y','N'
- AUTOEXTEND_SIZE,InnoDB表文件动态扩展大小, 合法值参加MySQL文档。此选项的设置规则较复杂,除非专业用户否则不建议显式设置,使用默认值即可。
- COLUMN_FAMILY, 仅适用于RocksDB 引擎,显式指定该表所在的Column Family。
create table t(a int, b text) with (
  engine=innodb,
  compression=lz4,
  row_format= COMPACT,
  ENCRYPTION = 'N',
  AUTOEXTEND_SIZE = '128M')
其中如果要启用加密,则需要安装加密插件在存储节点中。
可以使用MySQL的CREATE TABLE语法设置上述表选项,例外之处就是指定COLUMN_FAMILY 的方法不是在COMMENT中设置。
create table t1(a int, b text) 
  engine=innodb,
  compression=lz4,
  row_format= COMPACT,
  ENCRYPTION = 'N',
  AUTOEXTEND_SIZE = '128M',
  COLUMN_FAMILY = 'cf_t1',
  SHARD = 1
;
自Klustron-1.3版本开始,如果设置engine=rocksdb, 那么还需要设置default_backend_trx_isolation参数:
 set default_backend_trx_isolation='read committed'; 
这个参数用于控制计算节点与存储节点之间的对应于每个客户会话的连接中的隔离级别,默认是'repeatable read'级别。由于RocksDB不支持gap lock,所以无法支持MySQL所要求的repeatable read隔离级别。所以只要一个事务会UPDATE/DELETE RocksDB中的表,那么必须把default_backend_trx_isolation 设置为 'read committed'。
另外,可以在CREATE TABLE之前设置 default_storage_engine='rocksdb' (该参数默认是'innodb'),这样即使不在CREATE TABLE语句中设置engine选项,那么创建的表也是RocksDB的。
2. 修改上述存储节点的表选项
暂时不能修改ENGINE选项, 即不能用这个ALTER TABLE语句来替换存储引擎。如果要替换存储引擎需要使用Klustron的online DDL功能。修改这些选项完毕后,新的选项值不会立即生效,而是在 OPTIMIZE TABLE之后才生效。
alter table t set( compression=none,
 row_format=DYNAMIC,
 encryption='N', -- 加密需要存储节点加载加密插件,暂时只能为N
 autoextend_size='8M');
3. optimize table
执行该语句语句,让存储节点重建表分片,从而真正应用修改的存储选项值。
optimize table t;
4. 安排表分片到特定的存储shard
CREATE TABLE 语句中的with子句的 shard=N 选项,把这个表分片或者单表创建到ID=N的shard中。这个ID值就是计算节点的pg_shard 表的某个shard的id 值,也是元数据集群中Klustron_metadata_db.shards表中该集群的某个shard ID值。
create table t(a int, b text) with (
  engine=innodb, shard=3)
不可以在alter table中修改这个shard值,如果要搬动表分片到另一个shard,需要使用Klustron的scale-out功能。
5. 新增兼容mysql的show命令
除了支持MySQL常用的SHOW命令还增加了一些SHOW命令
- 列出数据库对象的基本信息
SHOW CREATE DATABASE db_name;
SHOW CREATE SCHEMA schema_name;
SHOW CREATE TABLE table_name;
SHOW CREATE VIEW name;
SHOW CREATE SEQUENCE name;
- SHOW [SESSION|GLOBAL] VARIABLES [LIKE pattern] [WHERE expr]显示存储节点中的部分会话级(当前session)或者全局变量的值。关于查询和设置存储节点中的变量的更多信息。
可以使用pattern字符串来匹配和过滤目标行,pattern可以使用%和_ 来做通配符,例如 'ab%cd_ef%g' ;也可以使用WHERE 子句的expr条件表达式来过滤,该表达式可以引用该show语句输出结果集的各个列名。pattern和WHERE 表达式的用法对下列其他SHOW 语句类似,下文不再逐一赘述。
- SHOW DATABASES [LIKE pattern] [WHERE expr]列出集群中所有符合过滤条件的数据库
- SHOW SCHEMAS [LIKE pattern] [WHERE expr]列出当前会话所连接的数据库中所有符合过滤条件的schema。在PostgreSQL和Klustron中,schema相当于一个名字空间,通常可以用于在逻辑上分组表、视图等数据库对象,比如按照应用系统的功能模块来分组。一个session连接到一个database,可以访问其中所有schema中的表、存储过程等数据库对象。在MySQL中,schema 等价于database,那是一种简单情况。
- SHOW [FULL] TABLES [[IN|FROM] schema_name] [LIKE pattern] [WHERE expr]列出当前会话所连接的数据库中符合过滤条件的表。如指定了schema_name, 那么 列出位于指定的schema中的表 ; 如指定了FULL 选项,可以列出每个表的种类,包括分区表,普通表,序列,视图等
- SHOW [FULL] COLUMNS [[IN|FROM] table_name] [[IN|FROM] schema_name] [LIKE pattern] [WHERE expr]列出当前会话所连接的数据库中符合过滤条件的列。如指定了table_name,那么列出指定表的列;如指定了schema_name, 那么 列出位于指定的schema中的列; 如指定了FULL 选项,可以列出每个表的权限和COMMENT
- SHOW TABLE STATUS [[IN|FROM] schema_name] [LIKE pattern] [WHERE expr]列出当前会话所连接的数据库中符合过滤条件的表的状态。如指定了schema_name, 那么 列出位于指定的schema中的表 ;
- SHOW INDEX IN table_name [ WHERE expr ];
例如:
mysql> show index in t1;
+-------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+---------+------------+
| table | non_unique | key_name | seq_in_index | column_name | collation | cardinality | sub_part | packed | null | index_type | comment | index_comment | visible | expression |
+-------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+---------+------------+
| t1    | 1          | t1_a_idx | 1            | a           | A         | 0           | NULL     | NULL   | YES  | BTREE      |         |               | YES     | NULL       |
+-------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+---------+------------+
1 row in set (0.00 sec)
- SHOW PROCESSLIST [LOCAL] [LIKE pattern] [WHERE expr]
列出当前计算节点中(指定了LOCAL选项)或者集群中的所有计算节点中(不指定LOCAL选项)的符合过滤条件的活跃会话的状态。输出结果中的ClusterSessionId是集群范围内标识一个会话的唯一的ID,可以用在KILL语句中来关闭集群中任何一个计算节点中的连接或者其中正在执行的语句。输出结果中的Pid列是服务这个会话的进程ID,此ID也是在存储节点中的日志记录以及SHOW PROCESSLIST命令结果中的Global_conn_id.
- SHOW COLLATION [LIKE pattern] [WHERE expr]查询存储节点中的COLLATION。也可以直接查询pg_collation 。
- SHOW {CHARSET|CHARACTER SET} [LIKE pattern] [WHERE expr]查询存储节点中的字符集。
- SHOW MEMORY列出当前会话的内存消耗情况。
- SHOW ERRORS; SHOW WARNINGS 显示上一条语句执行时发生的错误或者告警 
- SHOW STATUS [SHARD name] [LIKE pattern]
查询指定shard或者全部shard主节点中符合过滤条件的状态变量
6. 生成列(Generated Columns)
一个生成列是表的特殊类型的列,它被定义为使用一行的若干个字段的表达式。该表达式计算出该生成列的字段值。如果使用stored选项, 那么这个字段值可以持久存储在行中;也可以使用virtual选项,这样不存储该列的字段值而是每次都在查询时才计算出来。 无论是否存储,生成列的字段值都可以用于创建索引,并且如果在virtual的生成列创建索引,那么这个字段虽然在主数据行没有存储,但是在索引字段中是存储着的。
下面是一个定义生成列的例子。
create table t1(a int,
	b int generated always as (a+1) virtual,
	c int generated always as (a+2) stored);
对于JSON字段,必须使用生成列创建路径索引,并且在查询条件中使用这个生成列,从而确保JSON列的路径索引被使用到。如果需要对JSON列的很多个不同的路径创建索引,那么最好创建virtual而不是stored的生成列,避免对数据行增加大量字段,浪费存储空间。使用产生列创建和使用JSON路径索引的用法示例参考在Klustron中管理JSON数据 。
7. 序列新增属性cache_method。用来控制cache size是否根据负载动态变化
CREATE [ TEMPORARY | TEMP ] SEQUENCE [ IF NOT EXISTS ] name
    [ AS data_type ]
    [ INCREMENT [ BY ] increment ]
    [ MINVALUE minvalue | NO MINVALUE | NOMINVALUE ] [ MAXVALUE maxvalue | NO MAXVALUE | NOMAXVALUE ]
    [ { START | STARTS } [ WITH ] start ] [ NOCACHE | CACHE cache ] [ [ NO ] CYCLE | NOCYCLE ] [CACHE METHOD cache_method]
    [ ORDER | NOORDER ] [ SHARD  shard ]
    [ OWNED BY { table_name.column_name | NONE } ]
where cache_method can be one of:
    'STATIC'
    'DYNAMIC'
8. 支持EXPLAIN的别名DESC、DESCRIBE。例如:
mysql> desc select * From t1;
+----------------------------------------------------------------+
| QUERY PLAN                                                     |
+----------------------------------------------------------------+
| RemotePlan  (cost=101.02..101.02 rows=1 width=4)               |
|   Shard: 1    Remote SQL: SELECT t1.a FROM  `abc_$$_public`.`t1`  |
+----------------------------------------------------------------+
2 rows in set (0.00 sec)
9. 支持"DESC table_name"查看表结构:
mysql> desc t1;
+-------+---------+------+------+---------+-------+
| field | type    | null | key  | default | extra |
+-------+---------+------+------+---------+-------+
| a     | integer | YES  |      | NULL    |       |
+-------+---------+------+------+---------+-------+
1 row in set (0.00 sec)
10. 创建database时指定其所在的分区
自1.3版本开始,Klustron支持了在创建database时,指定其中的数据表所在的shard的集合。这样,在这个database中创建的数据表,都会位于指定的若干个shard中。这种用法非常适用于规模较大的集群,比如搭建一个集群用于创建 DBaaS Serverless 数据库服务,限制每个租户的数据只分布到这个集群的少量几个shard中。这样对于每个租户的数据访问性能,以及集群整体的资源利用效率,都有好处。
如果后期需要让这个database扩展到更多shard上面,可以通过如下ALTER DATABASE语句完成扩展或者收缩。不过需要注意的是,如果要收缩到更少的shard上面,那么必须确保少掉的shard不含有该database的数据表。
CREATE DATABASE [IF NOT EXISTS ] dbname [WITH] SHARDS='1 2 3';
ALTER DATABASE dbname [WITH] SHARDS='1 2 3 4'
例如,把Klustron集群部署为一个私有机房的DBaaS 数据库服务,该集群有10 个shard,编号分别是1,2,3,4,5,6,7,8,9,10. 现在要为租户designers 创建名为designers 的database,并且限制该租户只使用编号为1,2,3的3个shard,SQL语法就是:
CREATE DATABASE designers WITH SHARDS='1 2 3';
如果要扩展designers到更多shard:
ALTER DATABASE designers WITH SHARDS='1 2 3 4';
相反,如果要收缩designers到shard 1和2,要先把designers在shard 3上面的表搬迁到shard 1或者2,然后执行:
ALTER DATABASE designers WITH SHARDS='1 2'
查询shard编号的方法是连接Klustron集群任意一个计算节点,然后执行此语句:
select id from pg_shard;
11. 表组 tablegroup
表组功能让用户可以把一组表或者表分区绑定起来,保持它们始终位于同一个shard,如果要扩容时搬迁表分区,那么一个表组中所有的表必须整体搬迁,禁止只搬迁其中一部分表分区到其他shard。 具体功能语法见TABLE GROUP 语法说明
12. SEND 命令
SEND命令用于直接发送SQL语句到一个或者多个存储节点。
- SEND 'SQL statement'
该语句发送 SQL statement到本集群的所有storage shard的主节点. 例如 :
SEND 'SELECT * FROM performance_schema.metadata_locks' 
会列出所有shard 主节点中的所有元数据锁。
- SEND shard1,shard2 'SQL statement'
该语句发送 SQL statement到shard1 和shard2 这两个shard的主节点. 指定的shard名称必须存在否则会报错。
13. KILL 命令
KILL [QUERY] cluster_session_id
关闭集群中任意一个计算节点中的任何一个会话或者终止其正在执行的语句。cluster_session_id 是SHOW PROCESSLIST 的ClusterSessionId 字段,也是客户端连接库获取的连接ID。
