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

本文涉及的产品
云原生数据库 PolarDB 分布式版,标准版 2核8GB
RDS PostgreSQL Serverless,0.5-4RCU 50GB 3个月
推荐场景:
对影评进行热评分析
云数据库 RDS SQL Server,基础系列 2核4GB
简介:

背景

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月前
|
NoSQL 关系型数据库 MySQL
AWS Database Migration Service 助力数据库搬迁
AWS Database Migration Service 助力数据库搬迁
|
4月前
|
存储 消息中间件 人工智能
AI大模型独角兽 MiniMax 基于阿里云数据库 SelectDB 版内核 Apache Doris 升级日志系统,PB 数据秒级查询响应
早期 MiniMax 基于 Grafana Loki 构建了日志系统,在资源消耗、写入性能及系统稳定性上都面临巨大的挑战。为此 MiniMax 开始寻找全新的日志系统方案,并基于阿里云数据库 SelectDB 版内核 Apache Doris 升级了日志系统,新系统已接入 MiniMax 内部所有业务线日志数据,数据规模为 PB 级, 整体可用性达到 99.9% 以上,10 亿级日志数据的检索速度可实现秒级响应。
AI大模型独角兽 MiniMax 基于阿里云数据库 SelectDB 版内核 Apache Doris 升级日志系统,PB 数据秒级查询响应
|
4月前
|
数据库连接 网络安全 数据库
Could not create connection to database server.Attempted reconnect 3 times. Giving up.
这篇文章提供了解决数据库连接问题的方法,建议在连接字符串后添加`?serverTimezone=UTC`来指定时区,并检查网络设置、连接属性、驱动版本以及是否需要SSH或SSL连接。
Could not create connection to database server.Attempted reconnect 3 times. Giving up.
|
5月前
|
SQL 关系型数据库 MySQL
云服务器 ECS产品使用问题之出现“1044 - Access denied for user ‘root‘@‘%‘ to database ‘数据库名称‘”这样的错误,该怎么办
云服务器ECS(Elastic Compute Service)是各大云服务商阿里云提供的一种基础云计算服务,它允许用户租用云端计算资源来部署和运行各种应用程序。以下是一个关于如何使用ECS产品的综合指南。
|
5月前
|
SQL 数据库
SQL CREATE DATABASE 语句
【7月更文挑战第18天】SQL CREATE DATABASE 语句。
144 1
|
6月前
|
SQL 存储 运维
网易游戏如何基于阿里云瑶池数据库 SelectDB 内核 Apache Doris 构建全新湖仓一体架构
随着网易游戏品类及产品的快速发展,游戏数据分析场景面临着越来越多的挑战,为了保证系统性能和 SLA,要求引入新的组件来解决特定业务场景问题。为此,网易游戏引入 Apache Doris 构建了全新的湖仓一体架构。经过不断地扩张,目前已发展至十余集群、为内部上百个项目提供了稳定可靠的数据服务、日均查询量数百万次,整体查询性能得到 10-20 倍提升。
网易游戏如何基于阿里云瑶池数据库 SelectDB 内核 Apache Doris 构建全新湖仓一体架构
|
5月前
|
存储 大数据 关系型数据库
从 ClickHouse 到阿里云数据库 SelectDB 内核 Apache Doris:快成物流的数智化货运应用实践
目前已经部署在 2 套生产集群,存储数据总量达百亿规模,覆盖实时数仓、BI 多维分析、用户画像、货运轨迹信息系统等业务场景。
|
5月前
|
数据库
数据库bug-[08001] Could not create connection to database server. Attempted reconnect 3,主机名ip必须写对
数据库bug-[08001] Could not create connection to database server. Attempted reconnect 3,主机名ip必须写对
|
26天前
|
SQL 关系型数据库 MySQL
12 PHP配置数据库MySQL
路老师分享了PHP操作MySQL数据库的方法,包括安装并连接MySQL服务器、选择数据库、执行SQL语句(如插入、更新、删除和查询),以及将结果集返回到数组。通过具体示例代码,详细介绍了每一步的操作流程,帮助读者快速入门PHP与MySQL的交互。
34 1
|
28天前
|
SQL 关系型数据库 MySQL
go语言数据库中mysql驱动安装
【11月更文挑战第2天】
39 4