数据库内核月报 - 2015 / 10-TokuDB · 捉虫动态 · CREATE DATABASE 导致crash问题

本文涉及的产品
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
云原生数据库 PolarDB MySQL 版,Serverless 5000PCU 100GB
云原生数据库 PolarDB 分布式版,标准版 2核8GB
简介:

背景

TokuDB在启动的时候,会对datadir目录下的文件(和文件夹)进行遍历,根据规则找到所有的redo log文件,然后进行recover操作。
redo文件的命名规则是:log[index].toku[version],比如log000000000002.tokulog27。

问题

这个bug说起来有点“谜之”,因为它还跟编译器的版本有关。

如果使用gcc 4.8.2编译出一个TokuDB(加-O3编译参数),进行如下操作:

CREATE DATABASE log0002;

然后重启,整个TokuDB就可能凌乱了,出现如下crash信息:

storage/tokudb/ft-index/ft/logger/logfilemgr.cc:159 toku_logfilemgr_init: Assertion 'r==2' failed (errno=2)
Backtrace: (Note: toku_do_assert=0x0xcd50d0)
mysqld(_Z20toku_logfilemgr_initP15toku_logfilemgrPKcPm+0x26c)[0xc40cdc]
mysqld(_Z30toku_logger_open_with_last_xidPKcP10tokuloggerm+0x51)[0xc10ba1]
mysqld(_Z14tokuft_recover)

原因

先来看下TokuDB判断一个文件是否为redo log的代码:

static bool is_a_logfile_any_version (const char *name, uint64_t *number_result, uint32_t *version_of_log) {
	bool rval = true;
	uint64_t result;
	int n;
	int r;
	uint32_t version;
	r = sscanf(name, "log%" SCNu64 ".tokulog%" SCNu32 "%n", &result, &version, &n);
	if (r!=2 || name[n]!='\0' || version <= TOKU_LOG_VERSION_1) {
		//Version 1 does NOT append 'version' to end of '.tokulog'
		version = TOKU_LOG_VERSION_1;
		r = sscanf(name, "log%" SCNu64 ".tokulog%n", &result, &n);
		if (r!=1 || name[n]!='\0') {
			rval = false;
		}
	}
	if (rval) {
		*number_result  = result;
		*version_of_log = version;
	}

	return rval;
}

这段代码的逻辑很简单,调用sscanf函数获取相关参数, 高能区域为:

r = sscanf(name, "log%" SCNu64 ".tokulog%" SCNu32 "%n", &result, &version, &n);

如果name为log0002,调用完sscanf函数后,n和version的值是不确定的(因为函数内变量未被初始化),就可能导致函数 is_a_logfile_any_version 把log0002文件夹误认为是一个redo log。
toku_logfilemgr_init函数加载名称“log0002”时做二次校验,获取version值失败从而触发assert。

修复

大体思路是:

  1. 由于redo log不可能是文件夹,所以增加只对文件进行判断的逻辑,遇到文件夹直接跳过;
  2. is_a_logfile_any_version函数内变量进行初始化。

阿里云RDS TokuDB最新版本已经修复此问题,使用TokuDB的用户可以进行下小版本升级,以避免此问题影响业务。

目录
相关文章
|
2月前
|
缓存 安全 Java
阿里云数据库 SelectDB 内核 Apache Doris 2.0.6 版本正式发布
阿里云数据库 SelectDB 内核 Apache Doris 2.0.6 版本正式发布
|
2月前
|
SQL 存储 JSON
阿里云数据库 SelectDB 内核 Apache Doris 2.1.0 版本发布:开箱盲测性能大幅优化,复杂查询性能提升 100%
亲爱的社区小伙伴们,Apache Doris 2.1.0 版本已于 2024 年 3 月 8 日正式发布,新版本开箱盲测性能大幅优化,在复杂查询性能方面提升100%,新增Arrow Flight接口加速数据读取千倍,支持半结构化数据类型与分析函数。异步多表物化视图优化查询并助力仓库分层建模。引入自增列、自动分区等存储优化,提升实时写入效率。Workload Group 资源隔离强化及运行时监控功能升级,保障多负载场景下的稳定性。新版本已经上线,欢迎大家下载使用!
阿里云数据库 SelectDB 内核 Apache Doris 2.1.0 版本发布:开箱盲测性能大幅优化,复杂查询性能提升 100%
|
22天前
|
关系型数据库 Apache 流计算
手把手教你实现 OceanBase 数据到阿里云数据库 SelectDB 内核版 Apache Doris 的便捷迁移|实用指南
本文介绍了如何将数据从 OceanBase 迁移到阿里云数据库 SelectDB 内核版 Apache Doris。提供 3 种数据同步方法 1. 使用 DataX,下载 DataX 并编写配置文件,通过 OceanBaseReader 和 DorisWriter 进行数据迁移。 2. 利用 Apache Doris 的 Catalog功 能,将 OceanBase 表映射到 Doris 并插入数据。 3. 通过Flink CDC,设置 OceanBase 环境,配置 Flink 连接器,实现实时数据同步。
手把手教你实现 OceanBase 数据到阿里云数据库 SelectDB 内核版 Apache Doris 的便捷迁移|实用指南
|
3月前
|
存储 监控 安全
360 企业安全浏览器基于阿里云数据库 SelectDB 版内核 Apache Doris 的数据架构升级实践
为了提供更好的日志数据服务,360 企业安全浏览器设计了统一运维管理平台,并引入 Apache Doris 替代了 Elasticsearch,实现日志检索与报表分析架构的统一,同时依赖 Doris 优异性能,聚合分析效率呈数量级提升、存储成本下降 60%....为日志数据的可视化和价值发挥提供了坚实的基础。
360 企业安全浏览器基于阿里云数据库 SelectDB 版内核 Apache Doris 的数据架构升级实践
|
6天前
|
关系型数据库 分布式数据库 数据库
|
8天前
|
存储 监控 Apache
查询提速11倍、资源节省70%,阿里云数据库内核版 Apache Doris 在网易日志和时序场景的实践
网易的灵犀办公和云信利用 Apache Doris 改进了大规模日志和时序数据处理,取代了 Elasticsearch 和 InfluxDB。Doris 实现了更低的服务器资源消耗和更高的查询性能,相比 Elasticsearch,查询速度提升至少 11 倍,存储资源节省达 70%。Doris 的列式存储、高压缩比和倒排索引等功能,优化了日志和时序数据的存储与分析,降低了存储成本并提高了查询效率。在灵犀办公和云信的实际应用中,Doris 显示出显著的性能优势,成功应对了数据增长带来的挑战。
查询提速11倍、资源节省70%,阿里云数据库内核版 Apache Doris 在网易日志和时序场景的实践
|
15天前
|
存储 SQL Apache
阿里云数据库内核 Apache Doris 基于 Workload Group 的负载隔离能力解读
阿里云数据库内核 Apache Doris 基于 Workload Group 的负载隔离能力解读
阿里云数据库内核 Apache Doris 基于 Workload Group 的负载隔离能力解读
|
19天前
|
SQL 调度 数据库
【Database】Sqlserver如何定时备份数据库和定时清除
【Database】Sqlserver如何定时备份数据库和定时清除
26 2
|
1月前
|
Java 数据处理 调度
更高效准确的数据库内部任务调度实践,阿里云数据库SelectDB 内核 Apache Doris 内置 Job Scheduler 的实现与应用
Apache Doris 2.1 引入了内置的 Job Scheduler,旨在解决依赖外部调度系统的问题,提供秒级精确的定时任务管理。
|
2月前
|
存储 SQL 数据管理
阿里云数据库 SelectDB 内核 Apache Doris 如何基于自增列满足高效字典编码等典型场景需求|Deep Dive 系列
自增列的实现,使得 Apache Doris 可以在处理大规模时展示出更高的稳定性和可靠性。通过自增列,用户能够高效进行字典编码,显著提升了字符串精确去重以及查询的性能。使用自增列作为主键来存储明细数据,可以完美的解决明细数据更新的问题。同时,基于自增列,用户可以实现高效的分页机制,轻松应对深分页场景,有效过滤掉大量非必需数据,从而减轻数据库的负载压力,为用户带来了更加流畅和高效的数据处理体验。