V21.1.0
版本更新说明
数据库管理
延迟 GES 计算时间
计算的 GES 为 所有节点上报的最小 LES,MC 基于最小 LES 再减去 delay 作为 GES,用于绝对延迟 GES 推进。
使节点能够感知自身和其他节点的节点类型
在向 MC 获取节点信息与节点路由时,返回节点角色相关的标签字段,提供给 sqlengine 判断执行语句需要转发的节点。
扩展性与性能
Fast Online DDL 增加创建 Region 的模式
新增参数,允许提前规划好数据分布的实例在进行 Fast Online DDL 时仍然创建 Region 而不是新 RG。
Replace Into 完全 Batch 化
Replace Into 走 Batch 优化,不再受限于表的索引类型,同时存在主键和唯一索引依旧可以走 Batch 优化。
并行粒度细分支持不同级别划分粒度
并行粒度划分时,根据不同数据规模选择 SST 划分/Block 划分/行级划分。
节点扩缩容时自动将分区表均匀打散到各个节点
节点横向扩缩容后,假如没有 MC 调度分区均衡,会存在空闲节点没有分区表的情况,所以 MC 这里增加了一个接口给 shark,节点横向扩缩容后触发一次分区均衡。该特性默认关闭(flush-hyper-nodes-spec-task-enabled),因为对于庞大容量的旧版本实例一旦升级上来扩容时触发该策略的话,可能会有大量的迁移任务。
单分区主键点查不需要从 MC 获取时间戳作为读取快照
单分区主键点查不需要从 MC 获取时间戳,而使用 UINT64_T 作为快照去读取数据。 通过该优化,能够提升单分区主键点查性能。该特性默认开启(tdsql_simple_point_read_no_snapshot)。
优化简单的主键点查
主键点查可以不获取 GTS、减少执行流程中的 RPC 次数、提升性能。
新增一个会话级参数 tdsql_simple_point_read_no_snapshot 作为该优化开关。
移除多余的 condition 计算
range 查询优化为 range scan,相应的 where condition 可以 remove 掉,避免下推以及 condition 的重复计算,提升性能。
新增一个会话级参数 enable_range_condition_remove 作为优化开关。
灾备实例支持横向扩容 CDC 节点
灾备实例基于 MySQLClient 的 LogService 回放,支持 CDC 节点横向扩容。
支持语句级回滚
当 SQL 语句执行时遇到唯一索引冲突或者悲观锁超时的时候,整个事务不再需要被回滚。用户可以重新执行该 SQL,或者执行其它 SQL 以继续在当前事务中读写数据。该特性默认开启,可以通过 session 级别变量 tdsql_enable_statement_rollback 控制开启或关闭。
rg merge 优化-异步 save snapshot
rg merge 原有方案是同步 save snapshot,会增加1s 左右的耗时,且受磁盘压力影响可能增大耗时,期间会阻塞事务,会导致事务延迟增大。
异步 save snapshot 优化后,事务阻塞时间降低至少1s,rg merge 总耗时降低为 ms 级别,进一步减少了对事务的影响。
打开 RG 合并开关,允许 RG 合并
开启 merge 后,允许节点分布相同、副本角色一致的 RG 合并;允许空 RG 合并到其他 RG;允许索引合并到主键所在的 RG。
mrr 支持变长字段主键
当主键中含有变长 varchar 字段时,支持生成单表 mrr 查询,含有 mrr 的连接查询及 batched key access 连接的计划。之前当主键是变长 varchar 字段时,不能支持这些计划,现在放开。
检查 peer addr 是否一致再进行更新
更新 peerid 时判断与旧 id 不一致再进行更新,避免不必要的更新。
基于 Cost 做并行计划选择
之前是基于规则做并行计划选择,包括并行扫描表,和下推到并行 Worker 的表,这里改为基于代价(Cost)。
优化 BKA Join 生成逻辑
在 batched RPC 优化的 BKA 连接中支持条件下推场景。
语法与功能
支持通过 sql 查询 bulk load 事务信息
记录 explain plan 到 audit log
在 audit log 中记录 query 的执行 explain plan,方便进行问题回溯排查。
部分不常用的 rocksdb 相关配置参数,支持 SET PERSIST_ONLY 语法
以下参数支持了 SET PERSIST_ONLY 语法,详情:
tdstore_data_db_wal_compression
tdstore_monitor_db_wal_compression
tdstore_raft_db_wal_compression
tdstore_user_cf_default_temperature
tdstore_system_cf_default_temperature
tdstore_raft_cf_default_temperature
tdstore_monitor_cf_default_temperature
tdstore_local_cf_default_temperature
支持 returning 语法
支持 returning 语法,比如 update returning/insert returning/delete returning/replace returning,同时为了与 oracle 兼容,returning 将作为保留关键字,不能再用于命名表名,列名等。
新增控制每层 SST 大小的参数 target_file_size_multiplier_additional
新增一个 target_file_size_multiplier_additional,可以更精细地控制每一层 SST 文件的大小。Level N 层的每个 SST 文件大小的计算方式:
target_file_size_base* target_file_size_multiplier ^ (N - 1) * target_file_size_multiplier_additional[N]
只要把倍增系数 target_file_size_multiplier 固定为1,那么每一层 SST 文件的大小可以通过 target_file_size_multiplier_additional 来灵活设置。
例如,新增该参数后,user cf 的默认配置为 "1:1:1:2:2:4:8",即,当 target_file_size_base 为默认配置32M 时,L1~L6的 SST 文件大小为:32M, 32M, 64M, 64M, 128M, 256M。
Agent 支持上报日志节点的资源用量
shark 会根据 agent 上报的资源用量来进行动态变配。
RC 隔离级别 range 锁优化
与原生 MySQL 兼容,RC 隔离级别下不再加 range 锁。
同步表功能支持
广播同步表会在集群中每个节点上都创建一个副本,且每个副本均可对外提供强一致性读服务。
日志副本支持
支持2全功能副本+1日志副本架构,日志副本只保存从特定位点到最新的一段日志,不包含实际数据,在日志副本状态正常时能够提供与3全功能副本相同的可用性。
列存引擎白名单放开 TEXT 类型
对于 TEXT 类型族[TINY/MEDIUM/LONG] TEXT 默认支持使用列存引擎。
稳定性
BulkLoad 支持并发提交 raft log
BulkLoad 支持同一个 rg 并发提交 bulk load commit log,避免并发提交的场景下,有大量的事务堆积在提交阶段,影响数据导入的稳定性以及性能。
DDL 回滚逻辑加固
DDL 回滚删除数据时需要判断 tindex id 是否相同,避免在回滚 DDL 时删除同名表。
需要检查当前删除的副本是否为 leader
tdstore 执行 DoRemoveReplica 任务时,需要检查是否为 leader 自身,避免直接 remove leader。
修复 BulkLoad 提交事务遇到 leader step down 触发 core
BulkLoad 提交事务的时候,遇到 leader step down。 这种情况下,并不能马上回滚。 当前的事务处于一种未决的状态,只有当会放到写一个 term 的时候,才能明确该事务的最终状态。
ddl 对 rename,alter name 的冲突检测
并发执行 Rename table 和 Create table 时会判断是否冲突,如果冲突,则拒绝执行后提交的那个 ddl 任务。
增强 binlog log receiver 内存控制能力,杜绝 OOM
新增了参数 log_receiver_get_raft_log_from_cos_total_size 来控制 binlog log receiver 从 cos 获取 raft log 时使用的内存情况。避免从 cos 获取 raft 时占用内存过多而导致的 OOM 问题。
将 ha_rocksdb::alloc_key_buffers 申请的内存统计到 table_open_cache_max_mem_size
table_open_cache_max_mem_size 这个变量目前是记录的 table->mem_root 上申请的内存大小,然后触发内存淘汰策略。新版本将 ha_rocksdb::alloc_key_buffers 申请的内存(不在 mem_root 上的),也纳入统计,以精确统计内存占比,避免过度触发内存淘汰策略。
BulkLoad 适配 witness
BulkLoad 适配 witness 副本,对于 witness 副本不需要传输 external sst 文件。
整机迁移提供 Force-destroy 功能
整机迁移支持传入表示 force-destroy 的 option,用于跳过故障节点上的 destroy 副本任务,避免阻塞。
修复客户端和系统的字符集不一致导致的 hint 解析问题
当客户端 character_set_client 和 character_set_system 两个字符集不一致时,set_var+optimizer_switch 的 hint 设置无法生效,影响 hint 的设置及 outline 设置及命中。该问题已修复。
修复 outline 中增加分号导致不命中问题
当 outline 含有分号时,outline 无法被命中,只能在不含有分号的时候设置。该问题已修复。
优化 bulk load 期间,周期性计算 RG approximate size 或 range statistics,内存开销过大的问题
在 bulk load 数据导入期间,可能会有大批量的 SST 文件被注入到 rocksdb 的 level-0 层,在此期间,如果有周期性计算 RG approximate size 或 range statistics 请求,其估算大小的逻辑会在 level-0 层创建迭代器,由于 level-0 层 SST 文件过多,导致迭代器内存开销较大,有 OOM 的风险。对这个问题进行了优化,估算大小逻辑不再直接创建迭代器,而是改成了抽样的方式,内存表现更稳定。
修复官方 mem_root_deque 没有完善移动构造函数导致 crash
官方 mem_root_deque 没有完善移动构造函数导致 crash,move 语义用法有风险。
优化 bulk load 导数据场景,开启迭代器访问数据时因 level-0层 SST 文件过多导致内存上涨的问题
在 bulk load 导数据期间,可能会有大批量的 SST 文件被注入到 rocksdb 的 level-0 层,在此期间,如果有 scan 请求,会在 level-0 层创建迭代器,由于 level-0 层 SST 文件过多,在开启迭代器时,会同时打开 level-0 层的大量 SST 文件并将它们的 filter block 加载到内存中,导致内存消耗过高。因为主要的内存开销在 filter block,所以我们将 bulk load 产生的 SST,不再生成 filter block。
优化 log-only 节点内存开销
根据节点类型调整了一些内存的资源参数,减少日志节点不必要的内存开销,主要是:
rocksdb 相关:write_buffer_size/num、block cache 及与其相关的参数。
raft 相关:raft 流控触发阈值。
SQLEngine 一些广播的 SQL 不再发给日志节点。
备份恢复
支持增量备份并发以提高增量备份的效率
在本版本之前,增量备份只通过后台一个独立的线程进行,该线程每隔10s 使用顺序遍历本节点上的 RG leader,依次对他们进行备份(将 Rlog 传输给 agent,agent 通过文件流上传到 cos)。本版本实现了增量备份的并发化支持,通过一个可配置的线程池实现各个 RG leader 并发向 agent 传输 Rlog。新增参数 tdstore_execute_incr_backup_threads:线程池中 bthread 数量,tdstore_execute_incr_backup_interval_s:前后两轮增量备份间隔时间。
调整 Hyper-agent 退出逻辑避免增量备份日志在 agent 意外退出时丢失
hyper-agent 在退出时没有注册信号处理函数,导致内存中暂存的增量备份的 Raft 日志会在 agent 意外退出的时候丢失,调整 agent 退出逻辑,增加信号处理函数,确保退出时执行相关的 Flush 逻辑,将内存中的日志文件刷写到 cos 避免日志丢失。
优化全量恢复、增量恢复对于 etcd 的写入
全量备份以及增量恢复的过程中,将元数据都存储到 cos/nas 中,减少 etcd 的写入压力。
优化 MC 元数据的恢复
恢复元数据时 RG 分布需考虑到克隆实例的容灾模式,尽可能满足容灾的要求。
公有云提供基于 CBS 快照的备份恢复能力
基于云硬盘(CBS)的快照能力,通过快照的方式完成全量备份,并在实例回档时利用快照实现快速回档。
传统备份恢复支持恢复 witness 节点
witness 节点一般规格较小,传统备份恢复适配 witness 后,支持跳过向 witness 节点下发 ingest sst 任务和 raft log 回放任务,确保 log-onlu 2+1 规格实例可以恢复成功。
安全增强
CORRUPT DATA 的预防和报错
写入流程增加校验机制以免踩内存写入错误数据,读到 corrupt data 时打印完整的 key-value 以便定位分析。
运维
log-only 节点和列存节点指标适配
适配 2 + 1 log-only 架构下的指标,梳理调整列存节点指标。
为日志服务 MysqlClient 类型新增视图展示每条链接的实时状态
TDStore client 新增主动合并过小 SST 文件 compaction 的指令
该指令可以手动发起合并过小 SST 文件的 compaction,可以指定合并 SST 的所在 level,合并小 SST 的数量,以及执行时间(主要是考虑到带来的负载比较好控制),例如:
compact_sst_merge_small_files --input_level=3 --max_compact_files_count=5000 --max_runtime_sec=600
支持通过系统表展示历史死锁信息
LogService 的延迟查询和上报,从 replay_leader_ts 调整为 commit_ts_barrier
修改延迟上报的指标,使指标更加准确,保证 user rg 的延迟大于等于 sys rg。
工具支持 SET PERSIST_ONLY 语法
支持添加 -read-only 选项来发起 set persist_only SQL 语句,来修改符合要求节点的配置项。
问题修复
MC 切主时收到 TDStore 的心跳,有概率使 MC panic。
大事务和主动切主并发可能导致事务被误杀。
merge region job 失败时,可能导致对应 region 中的悲观锁无法工作。
部分参与者由于 write fence 校验失败进入 failed 状态,剩余参与者由于日志同步失败,没有成功同步 prepare log,叠加协调者切主,导致协调者没有被恢复,无法清理 failed 状态的参与者。
升级过程 mysql 下系统表不随着 server_sub_version 的变化而重建。
修复列存虚拟表展示错误问题,以及列存 compaction 代码隐患。
修复 INSERT IGNORE 插入重复值时结果不正确的 bug。
修复 group by 完全下推时,remote 节点并行任务划分不正确的 bug。
旧版本升级到 release-21.0.0 之后,迁移操作小概率失败并无限重试。
并行中的返回单行(非单个值)的非相关子查询,并被提前执行,并且子查询做为 <=> 运行符的参数,而且子查询结果为空集时,进程崩溃。
RG merge 后,expanded RG 如果要切主,需要检查 vanished RG 的 applied index,不能切主到 vanished rg 日志落后很多的副本所在的节点。
fast online ddl 失败时,将准确的错误信息返回到客户端。
修复 CDC 节点从 COS 拉取 Raft Log 时,因备份文件未正确关闭而导致无法获取所需日志的问题。
当 rg merge 和 leader stop 并发执行时,可能导致 rg 状态异常。
新增参数限制 SQLEngine 使用的临时文件数量,并提供状态变量查看当前临时文件 fd 使用情况。
热点调度从对等节点采集 cpu、mem 等指标,调度时将资源指标作为参考依据。
RG 数量太多,MC 开启 log-service 时存储数据量过大导致报错。
SQLEngine 启动过程,没有及时持久化 node 信息,注册成功之后因为别的原因启动失败之后,重启重新注册节点会因为地址冲突而无法启动成功。
alter table 更改表自增值支持 inplace 模式。
优化 DDL 提交受限场景(如备份阶段)的报错信息,提供更明确的原因说明。
当事务大小超过对应内存限制时,返回给客户端的报错信息不清晰。
热点调度时每次只调度一张表或者分区,会产生太多分裂任务以及 RG,需要将这些任务聚合成一个,减少 RG 分裂。
binlog:两张表联合更新时,当用一张表的列更新另外一张表,binlog 旧行主键生成错误。
当前的均衡模式容易把主键数据分裂到多个 RG,新增一种调度模式减少主键数据的分裂。
MC LogService 调度由于缺少 RG Info 导致调度卡住。
GetRegionsByKeyRange RPC 由于拿不到 HyperNodeInfo 锁而超时。
在 RocksDB 中,如果 SST 与上层 SST 没有重叠且删除比例大于阈值,可能会触发 BottommostCompaction
在表有二级索引的情况下,当 RocksDB 最高层的文件中删除比例大于阈值时,会触发对该文件的 Compaction,列存侧没有正确将删除记录消除。
灾备同步使用的 MysqlClient 模式会同步预期之外的系统表。
收集某列(e.g: c1)直方图统计信息后,列存节点上查询过滤条件中包含 where c1 is null 或者 where c1 is not null 时,产生执行计划错误,导致查询正确性问题。
在有列存分区表的场景下,查询 TDSTORE_COLUMNAR_NODE_DATA_COUNT_INFO 表会 core。
灾备同步使用的 MysqlClient 由于引入了内存限制,导致非预期的同步速度变慢。
灾备同步使用的 MysqlClient 由于引入了内存限制,产生了非预期的全局最小同步时间戳更新异常,导致灾备同步卡住。
fast online ddl 子任务失败时,整个任务及时报错退出。
show create table 发现 TABLE 和数据字典不一致时抛出错误。
扩容后进行均衡,节点容量存在抖动。
实例升级后一个节点存在多个 RG 又主 RG 标签。
mc 归档 task 时先清理缓存,再持久化,持久化失败会导致 log service 查不到这个 task。
列存节点迁移会一次性迁移大量 rg,由于 new rg 在 LoadRaftSnapshot 的时候,会等待 parent rg 的 snapshot index 位点大于等于 split index,而 parent rg 也是迁移过来的,本地的 snapshot index 是不存在的,只能等待其迁移结束。一旦 parent rg 非常大,new rg 的等待时间会非常久,直到超时。
事务执行超时抛出异常后 duckdb 有概率会出现未 Rollback 异常事务的情况,导致下一个事务开启时检测到仍有事务存在而报错。
tdstore 若干 rpc 未能完整的在 response 中返回 ret,可能导致 sqlengine 行为错误。
修复 MC 锁等待超时导致 SQLEngine 重复发送 CreateDataObjects 请求,进而对同一 DDL 操作创建多个重复任务的问题。
全量备份的过程中,如果 agent 发生重启,备份过程中生成的文件将不会被删除。
mc 退出时卡住,无主时间大概30秒左右,导致 sqlEngine 自杀。
当前如果 cos 连接失败,会进行长时间重试,有可能会阻塞给 SQLEngine 的回包导致进行 hang 住或者开启增量备份时间过长。将其修复为:只会在限流(错误码为 503 的情况下进行长时间重试,其他错误只会重试 20s)。
brpcstream 失败在初始化时,可以即时退出。
执行出错或者被 kill 时,仍然继续从存储获取统计信息。
被 Proxy 转发的 SQL 无法 apply statement outline 使用绑定的执行计划。
在分区表同一事务中大量跨区修改 pk 键时,会发生 coredump。
二级索引回表出现 corrupt data 报错时,日志本该打印 corrupt 的 key-value,但日志打印处出现 heap-use-after-free 踩内存。
online copy 期间并发 DML 获取表统计信息,会导致 DML 等待。
并行任务初始化时,某个子任务失败不会立即报错。
split rg 或者 merge rg 结束后,如果立刻触发 rg delete,可能会导致部分数据丢失。需要等待 old rg 或者 vanished rg snapshot save 执行完毕。
fast online ddl 可能会使 mc 有残留的 placeholder 未清理。
rpc 失败后 close connection,这会导致清理 thd 上的部份资源,后续 proxy executor 会继续这部份状态,导致 heap-use-after-free。
修复 Batch Put 与 DDL 并发导致的踩内存。
merge rg 和 install snaposhot 并发可能导致 follow 卡住。
批量 rename 失败时可能导致 crash。
长连接的 PS 语句查询可能会缓存过多的 cache range。
语句回滚后 WBWI rebuild index 时,dup flag 没有设置好。
修复并行查询在 audit log 打开时可能崩溃或 audit log 混乱的问题。
删除 LogService 时等待 log-recevier 就绪。
表不可见时不需要更新统计信息
语法变更
数据字典变更
|
新增 | | 用于查询历史 Bulk Load 事务以及正在执行的 Bulk Load 事务信息。 |
新增 | | 展示日志回放 MySQL 模式下每个 MySQL 连接的执行状态。 |
新增 | | 用于在执行死锁检测的节点上查询该系统表,可以得到历史所有死锁的发生时间、被回滚的事务的 ID、构成死锁环的各个事务的 ID 以及执行该事务的 SQLEngine 的 Node ID。 |