MySQL · 引擎特性 · TokuDB hot

  • 时间:
  • 浏览:3

创建indexer

处里committed事务时,每次处里完成都是记住新加进的二级索引的key值。最后对每个key发一个多多多FT_COMMIT_ANY消息,分发MVCC特征,DB_INDEXER->commit_keys假若记录已提交二级索引key的,是一个多多多数组。

indexer数据特征介绍

可能性当前事务情況是TOKUTXN_ABORTING,啥假若用干,省得以前在root txn commit时都要再去做rollback。

有一些都要提下,db_env->create_index调用toku_loader_create_loader创建一个多多多dummy的索引。当build过程出错时,会放弃以前的所有操作,把索引重定向到那个dummy索引。这是利用loader redirect FT handle的功能,创建loader时指定LOADER_DISALLOW_PUTS标记。

indexer_undo_do实现很直接,首先调用 indexer_undo_do_committed处里已提交事务对二级索引的修改,那此修改在pk上是提交的,这麼 在二级索引后面 也一定是提交的。反复修改同一个多多多pk会意味着着产生多个二级索引的key值。在pk上的体现是新值override老值;而在二级索引上假若要删老值,加新值。这也假若undo_do的意思啦。

可能性最外层provisional事务(当前alive事务的root txn)的情況是TOKUTXN_COMMITTING可能性TOKUTXN_RETIRED表示pk上一些事务准备提交可能性可能性提交,直接删除old key可能性加进new key,不都要记undo log和redo log,可能性pk预期是提交的。

TokuDB handler的ha_tokudb::store_lock判断是create index措施创建索引假若只创建一个多多多索引会把lock_type改成TL_WRITE_ALLOW_WRITE,这是一个多多多特殊的锁类型,意思是在执行写操作的过程允许一些的写操作。

db_env->create_index函数主假若初始化DB_INDEXER数据特征,这每种代码比较简单,请没这麼人自行分析。

大致过程如下:

hot-index维护了le cursor大致位置indexer->i->position_estimate,一些位置是延迟更新的。每次访问le cursor比较后更新一些位置。这麼 ,比它大的key一定落在build好的每种的。

TokuDB提供了session变量tokudb_create_index_online,在线开启可能性关闭hot-index功能。

到这里,hot-index每种就介绍完了。代码看着僵化 ,但比起loader来要简单不少。

build_index主体是一个多多多循环,每次去pk上读取一个多多多key。前面提到过,访问pk是通过le cursor,每次向前访问,读取key和MVCC信息,在cursor callback把相应信息填到ule_prov_info数据特征里。le cursor的callback是le_cursor_callback,通过txn_manager得到第一个多多多uncommitted txn信息,假若在通过那个txn的txn_child_manager得到一些的uncommitted txn信息。

ha_tokudb::tokudb_add_index是负责创建索引的措施。一些函数首先会判断如下条件:可能性同時 满足以下一个多多多条件就会走到hot-index的逻辑,假若是传统的创建索引过程。



db_env->create_indexer我觉得假若toku_indexer_create_indexer,是在toku_env_create阶段设置的。 在create_indexer阶段,最主要工作假若初始化DB_INDEXER数据特征。

代码逻辑如下图所示:

与dml互斥

条件xrindex == num_committed表示当前事务的root txn,一定把它加到xids后面 ;假若,意味着着是子事务,非要当它发生TOKUTXN_LIVE情況时加到xids后面 。xids数组是为了往FT发msg用的,表示msg发生txn上下文。

构建indexer的函数是DB_INDEXER->build,我觉得调用的是build_index函数。

每个更新操作,包括insert,update和delete都是比较待处里的二级索引key是算是落在可能性build的每种。可能性是,其处里措施跟通常的一样,直接调用db接口;假若留给hot-index来处里。

所谓hot-index假若发生构建索引的过程中不要阻塞查询数据,假若会阻塞修改数据(insert/update/delete)。在TokuDB的实现中非要使用“create index“措施创建索引的情況下能够使用hot-index;可能性使用“alter table add index”是会阻塞更新操作的。

在处里每个pk的key时,是受indexer->i->indexer_lock互斥锁保护的,保证build过程跟用户的dml一段话互斥。build的过程还获取了multi_operation_lock读写锁的读锁。在处里当前pk值,是不允许dml和checkpoint的。对于每个pk的<key,mvcc>二元组,调用indexer_undo_do函数来构建二级索引的key和mvcc信息。下面函数中hot_keys和hot_vals是生成二级索引key和val的buffer。

indexer_undo_do函数才是build灵魂,每次调用生成二级索引的key和MVCC信息。传入参数是ule_prov_info,封装了pk的key和mvcc信息。

都要注意的是indexer->i->position_estimate和le cursor正在处里的key(更精确)都是指pk上的位置。

关闭indexer

对于provisional事务,都是undo和do阶段。针对mvcc后面 的nested txn,undo阶段删除old image对应的二级索引key,do阶段加进new image对应的二级索引key。这每种跟indexer_undo_do_committed类事。

判断key是算是落在已build好的每种是通过toku_indexer_should_insert_key函数比较le cursor正在处里的key和pk的key来实现的。为了处里访问le cursor的竞态,每次比较都是在indexer->i->indexer_lock保护下进行。直觉不知道们,一些操作会影响性能,并发写可能性会在indexer->i->indexer_lock上排队。

release_txns函数unpin每个活跃的provisional事务,pin的过程是在toku_txn_pin_live_txn_unlocked做的;pin的目的是处里txn commit可能性abort。

TokuDB目前只支持一个多多多hot-index,也假若说同時 只允许还有一个多多多hot-index在进行。可能性hot-index过程带有新的创建索引操作会走传统的建索引逻辑。

构建indexer

对于是hot-index措施,首先通过调用db_env->create_index接口创建一个多多多hot-index的handle,假若通过一些handle调用build措施构建索引数据,最后是调用close措施关闭handle。

indexer_undo_do_committed函数相对简单,请没这麼人自行分析。

DB_INDEXER我觉得是一个多多多接口类主要定义了build,close,abort等callback函数,其主体成员变量定义在struct __toku_indexer_internal后面 。 DB_INDEXER定义如下:

假若依次查看每个provisional事务,uxr表示当前provisional事务的信息,包括value,txnid和delete标记。this_xid表示当前事务的txnid;this_xid_state表示当前事务的情況。

可能性是TOKUTXN_LIVE可能性TOKUTXN_PREPARING表名root txn正在进行中,模拟用户写索引的行为,直接调用toku_ft_maybe_delete(删除old key)可能性toku_ft_maybe_insert(加进new key),一些过程是都要记undo log和redo log的,可能性pk上一些事务正在进行中。

写了这麼 多都是framework,汗:(

对应每个pk后面 是提交的key,也都要记录下来,在现在刚结束了了前对每个key发FT_COMMIT_ANY消息分发MVCC特征。

build设计思想是通过遍历pk构造二级索引。在pk上创建一个多多多le cursor,一些cursor有点之处是读取的是MVCC特征(即leafentry)而都是数据。Le cursor遍历的方向是从正无穷(最大的key值)向前访问,总爱到负无穷(最小的key值)。通过Le cursor的key和value(从MVCC中得到的)构造二级索引的key;通过pk MVCC中的事务信息,构建二级索引的MVCC。



hot-index设计思路

只不过indexer_undo_do_provisional都要考虑最外层provisional事务(当前alive事务的root txn)的情況。

__toku_indexer_internal定义如下所示

下面同時 看一下indexer_undo_do_provisional函数。可能性num_provisional等于0,这麼 正在进行中的事务,直接返回。

传统的创建索引的措施是利用loader机制实现的,关于loader每种(点击这里跳转到原文)后面 有比较全版的描述。





我觉得,indexer->i->position_estimate更新是受indexer->i->indexer_estimate_lock保护的,这也都都只算是锁拆分优化。

与indexer->i->position_estimate比较的过程是不都要获取indexer->i->indexer_lock的,利用它都都要做个快算判断,减少indexer->i->indexer_lock争抢。

这每种假若关闭handle,释放内存。可能性篇幅有限,本文不深入讨论。