TokuDB · Savepoint漫谈

问题描述

某TokuDB实例备库发生复制中断,报错信息甚是诡异:

  Error executing row event: "Can't lock file (errno: 22 - Invalid argument)"

经过gdb core后,大体知道了发生错误的原因:

TokuDB在创建子事务的时候,由于嵌套事务过多,FT-index直接返回了错误(TokuDB的嵌套事务最多允许256个,嵌套事务数目的类型为uint8_t)导致。

比较诡异的是主库一切正常,无任何错误。

经过沟通,发现用户使用了大量的savepoint,这是一个突破点。

Savepoint机制

在TokuDB里savepoint的机制是个啥样子呢?

这里我们分两种情况来处理,先来看第一种,SQL1

set autocommit=0;
savepoint s0;
insert into tb1 values(0);
release savepoint s0;
savepoint s1;
insert into tb1 values(1);
release savepoint s1;
...
commit;

TokuDB将会这样处理:

a) savepoint s0:
创建s0子事务
b) release savepoint s0的时候:
commit当前s0事务
c) savepoint s1:
创建s1子事务(此时s0子事务已不存在,已提交)
d) release savepoint s1的时候:
commit当前s1事务

savepoint 间的事务并非嵌套,而是用完就释放,然后再重新创建,这样不会导致事务栈溢出。

再来看另外一种情况,SQL2

set autocommit=0;
savepoint s0;
insert into tb1 values(0);
savepoint s1;
insert into tb1 values(1);
savepoint s2;
insert into tb1 values(2);
...
commit;

这种SQL TokuDB的处理方式是:

a) savepoint的时候:
s1是s0的子事务,s2是s1的子事务,就这样嵌套下去直到事务栈溢出...

b) commit的时候:
会先提交s2,然后提交s1,然后提交s0,最后整个事务提交

问题解决

针对开始时的问题,TokuDB内核君进行了大胆猜测:

在主库执行的是SQL1,一切正常;
在备库执行的是SQL2,事务栈溢出了;

通过翻看 binlog 代码印证了我们的猜测,在 sql/binlog.cc 里只实现了 binlog_savepoint_set 方法,只记录savepoint event到binlog,而未记录release savepoint event!

由于savepoint实现机制不同,对InnoDB引擎来说是没有问题的,但对 TokuDB 来说就是灾难了。解决办法就是实现binlog_savepoint_release方法,记录release savepoint event到binlog。

ApsaraDB MySQL 5.6 最新版已修复这个问题,对savepoint有需求的TokuDB用户(InnoDB不受影响)做下升级即可。

本篇小文从一个用户引发的问题出发,讨论了TokuDB的savepoint机制,当然TokuDB内核组的同学每天都会处理很多类似的问题,从发现问题到解决问题,以及持续的优化,为的就是给大家提供一种“飞”的感觉。有大数据量存储的同学不妨试试我们的 TokuDB 引擎,存储成本大大降低,顺便体验一把下一代存储引擎带来的“优越感”(注意,这不是广告)。

最后广告还是来了:
我们的PB级云数据库 PetaData已开始公测,底层采用TokuDB引擎,存储介质是普通的SATA盘,有兴趣的同学可以去围观下。

时间: 2024-11-29 00:31:20

TokuDB · Savepoint漫谈的相关文章

MySQL · TokuDB · Savepoint漫谈

问题描述 某TokuDB实例备库发生复制中断,报错信息甚是诡异: Error executing row event: "Can't lock file (errno: 22 - Invalid argument)" 经过gdb core后,大体知道了发生错误的原因: TokuDB在创建子事务的时候,由于嵌套事务过多,FT-index直接返回了错误(TokuDB的嵌套事务最多允许256个,嵌套事务数目的类型为uint8_t)导致. 比较诡异的是主库一切正常,无任何错误. 经过沟通,发现

阿里数据库内核月报:2016年04月

# 01 MySQL · 参数故事 · innodb_additional_mem_pool_size # 02 GPDB · 特性分析 · Segment事务一致性与异常处理 # 03 GPDB · 特性分析 · Segment 修复指南 # 04 MySQL · 捉虫动态 · 并行复制外键约束问题二 # 05 PgSQL · 性能优化 · 如何潇洒的处理每天上百TB的数据增量 # 06 Memcached · 最佳实践 · 热点 Key 问题解决方案 # 07 MongoDB · 最佳实践 

TokuDB · 引擎特性 · HybridDB for MySQL高压缩引擎TokuDB 揭秘

HybridDB for MySQL(原名petadata)是面向在线事务(OLTP)和在线分析(OLAP)混合场景的关系型数据库.HybridDB采用一份数据存储来进行OLTP和OLAP处理,解决了以往需要把一份数据多次复制来分别进行业务交易和数据分析的问题,极大地降低了数据存储的成本,缩短了数据分析的延迟,使得实时分析决策称为可能. HybridDB for MySQL兼容MySQL的语法及函数,并且增加了对Oracle常用分析函数的支持,100%完全兼容TPC-H和TPC-DS测试标准,从

数据库内核月报 - 2015 / 09-MySQL · TokuDB · 文件目录谈

TokuDB的数据库文件组织方式比较随意,给我们一种"乱"的假象,今天就来漫谈下TokuDB数据库文件. 一个"新生"的TokuDB数据库,基础文件是这样的: tokudb.directory --表/索引文件信息 tokudb.environment --TokuDB版本号信息 tokudb.rollback --undo记录 log000000000001.tokulog27 --redo记录 __tokudb_lock_dont_delete_me_* --文

MySQL内核月报 2014.08-TokuDB·社区八卦·TokuDB团队

第一期先介绍下TokuDB团队吧. TokuDB自从开源后(更赞的是开源了所有的commits),逐渐被大家所熟悉,MariaDB 5.5系列和Percona Server 5.6的GA版本中,都以plugin的方式集成. 3位(Tokutek)创始人: Michael A. Bender , Martín Farach-Colton , Bradley C. Kuszmaul  2012年他们合发了一篇208页的pdf[Data Structures and Algorithms for Bi

认识VF--Visual FoxPro 漫谈

visual BOE.COM Article Resource News Links About US      文章标题Visual FoxPro 漫谈 作品来源BOE 数据网络工作室 创建日期 2001年02月23日 最后更新 2002年07月21日  文字数量 约22000字 作者姓名 陈纯 译者姓名 原创作品 无译者 版权声明 版权属于BOE 数据网络工作室  相关下载 --  细节描述      作为市场上最灵活和功能最强大的数据库管理系统,Visual FoxPro拥有悠久而辉煌的发

漫谈SQL Server中的标识列(一)

server 漫谈SQL Server中的标识列(一) 一.标识列的定义以及特点 SQL Server中的标识列又称标识符列,习惯上又叫自增列.该种列具有以下三种特点: 1.列的数据类型为不带小数的数值类型2.在进行插入(Insert)操作时,该列的值是由系统按一定规律生成,不允许空值3.列值不重复,具有标识表中每一行的作用,每个表只能有一个标识列. 由于以上特点,使得标识列在数据库的设计中得到广泛的使用. 二.标识列的组成创建一个标识列,通常要指定三个内容:1.类型(type)在SQL Ser

SavePoint (bzszp )

保存点(SAVEPOINT)是事务处理过程中的一个标志,与回滚命令(ROLLBACK)结合使用,主要的用途是允许用户将某一段处理回滚而不必回滚整个事务,这在PL/SQL开发中还是很有用处的.下面的例子中,把SAVEPOINT标记在INSERT语句之前,如果这条INSERT语句试图将重复的数据保存到EMP表中的话,将触发执行预先定义的DUP_VAL_ON_INDEX例外处理,在这里面的ROLLBACK TO do_insert命令将回滚上面的那条INSERT操作,而不会影响前面的任何操作. DEC

C#规范漫谈

规范 作为有关 C# 语言规范漫谈的继续,本月我们将讨论运算符重载的问题.运算符重载(除非特别指明,否则本专栏的其余部分一律将其简称为"重载")是指允许用户使用用户定义的类型编写表达式的能力.它允许用户定义的类型与预定义的类型具有相同的功能. 例如,通常需要编写类似于以下内容的代码,以将两个数字相加.很明显,sum 是两个数字之和. int i = 5;int sum = i + j; 如果可以使用代表复数的用户定义的类型来编写相同类型的表达式,那当然是最好不过了: Complex i