简介
StarRocks 支持轻量级表结构变更,开始被称为 Light Schema Change 后修改为 Fast Schema Evolution,加减列或者修改列类型无需停服务,无需重导历史数据。最常见的是增加索引、修改分区、修改表属性等,尤其在分布式表中限制会比较多甚至是比较重的操作。
需要在建表时通过 fast_schema_evolution=true
指定,或者配置 enable_fast_schema_evolution
的 FE 全局配置。
将表结构变更分成三种:
- Sorted Schema Change 这里会改变列的排序方式,例如删除排序列中的一列
ALTER TABLE foobar DROP COLUMN col
。 - Direct Schema Change 无需调整排序,只需要对数据进行转换,例如修改列类型
ALTER TABLE foobar MODIFY COLUMN col VARCHAR(64)
。 - Linked Schema Change 无需转换可以直接完成,新数据按照新的 Schema 处理,旧数据直接用默认值填充,例如添加列
ALTER TABLE foobar ADD COLUMN col BITINT SUM DEFAULT 0
。
而 Online/Light 实际上针对的是 Linked 的优化实现。
如下是常见的 SQL 语句。
CREATE TABLE user_info(
id STRING,
name STRING,
gender STRING,
age INT,
addr STRING
)
DUPLICATE KEY(id)
DISTRIBUTED BY HASH(`id`) BUCKETS 1
PROPERTIES (
"fast_schema_evolution" = "true",
"replication_num" = "1"
);
SHOW TABLETS FROM user_info\G
ALTER TABLE user_info
ADD COLUMN col1 INT DEFAULT "1",
ADD COLUMN col2 INT DEFAULT "2";
ALTER TABLE user_info
DROP COLUMN col1,
DROP COLUMN col2;
----- 所有表结构变更是异步操作,可以通过如下命令查看当前状态
SHOW ALTER TABLE COLUMN ORDER BY CreateTime DESC LIMIT 10;
----- 查看修改任务超时时间,默认是 86400 秒,也就是一天
ADMIN SHOW FRONTEND CONFIG LIKE 'alter_table_timeout_second%';
ADMIN SET FRONTEND CONFIG("alter_table_timeout_second"="86400");
----- 可以手动取消任务
CANCEL ALTER TABLE COLUMN FROM foobar;
源码解析
语句通过 AlterTableStmt
解析处理,最终会调用 AlterJobMgr.processAlterTable()
实现,然后创建 AlterJobV2
任务。
真正运行是在 SchemaChangeHandler.runAfterCatalogReady()
中执行。
Light Schema Change
https://github.com/StarRocks/starrocks/issues/24341
https://my.oschina.net/u/5735652/blog/5591562
导入数据时会通过 tablet_writer_open() 接口调用,同时会将 Schema 通过 PTabletWriterOpenRequest 参数传入,详见 NodeChannel::_open() 实现。
其中 _parent 对应了 OlapTableSink 对象,其中包含了
// gensrc/thrift/Planner.thrift
struct TPlanFragment {
5: optional DataSinks.TDataSink output_sink
}
// gensrc/thrift/DataSinks.thrift
struct TDataSink {
1: required TDataSinkType type
2: optional TDataStreamSink stream_sink
3: optional TResultSink result_sink
5: optional TMysqlTableSink mysql_table_sink
6: optional TExportSink export_sink
7: optional TOlapTableSink olap_table_sink
8: optional TMemoryScratchSink memory_scratch_sink
9: optional TMultiCastDataStreamSink multi_cast_stream_sink
10: optional TSchemaTableSink schema_table_sink
11: optional TIcebergTableSink iceberg_table_sink
12: optional THiveTableSink hive_table_sink
13: optional TTableFunctionTableSink table_function_table_sink
14: optional TDictionaryCacheSink dictionary_cache_sink
}
struct TOlapTableSink {
1: required Types.TUniqueId load_id
2: required i64 txn_id
3: required i64 db_id
4: required i64 table_id
5: required i32 tuple_id
6: required i32 num_replicas
7: required bool need_gen_rollup // Deprecated
8: optional string db_name
9: optional string table_name
10: required Descriptors.TOlapTableSchemaParam schema <--- 关键
11: required Descriptors.TOlapTablePartitionParam partition
12: required Descriptors.TOlapTableLocationParam location
13: required Descriptors.TNodesInfo nodes_info
14: optional i64 load_channel_timeout_s // the timeout of load channels in second
15: optional bool is_lake_table
16: optional string txn_trace_parent
17: optional Types.TKeysType keys_type
18: optional Types.TWriteQuorumType write_quorum_type
19: optional bool enable_replicated_storage
20: optional string merge_condition
21: optional bool null_expr_in_auto_increment
22: optional bool miss_auto_increment_column
23: optional bool abort_delete // Deprecated
24: optional i32 auto_increment_slot_id
25: optional Types.TPartialUpdateMode partial_update_mode
26: optional string label
// enable colocated for sync mv
27: optional bool enable_colocate_mv_index
28: optional i64 automatic_bucket_size
}
OlapTable.getUseFastSchemaEvolution() 确认是否支持
PropertyAnalyzer.analyzeUseFastSchemaEvolution()