MySQL · TokuDB · 让Hot Backup更完美

前言

很久很久以前,内核君发表了一篇HA方案·TokuDB热备的文章,方法很简单:

  1. SET TOKUDB_CHECKPOINT_LOCK=ON;
  2. 开始拷贝TokuDB的数据文件(不包含日志文件);
  3. FLUSH TABLES WITH READ LOCK;
  4. 记录binlog位置,拷贝最新的binlog和TokuDB的日志文件(*.tokulog);
  5. UNLOCK TABLES;
  6. SET TOKUDB_CHECKPOINT_LOCK=OFF;

这些步骤可以很方便的嵌入到Percona XtraBackup中,与InnoDB一起工作,目前看是一个比较简单可行的方案。

大实例备份恢复问题

问题来了。
当某个实例的数据量达到TB级,你会发现备库(基于备份)重搭后,启动会灰常灰常慢,因为他们都在recover redo-log,为什么呢?

  1. SET TOKUDB_CHECKPOINT_LOCK=ON;
  2. 开始拷贝TokuDB的数据文件(不包含日志文件),由于拷贝TB级的数据非常耗时,redo log持续增加甚至上万个

当TokuDB启动后,扫描和recover这几万个redo log将是灾难性的。

解决这个问题比较简单,我们稍微调整下热备的顺序即可:

  1. SET TOKUDB_CHECKPOINT_LOCK=ON;
  2. FLUSH TABLES WITH READ LOCK;
  3. 记录binlog位置,拷贝最新的binlog和TokuDB的日志文件(*.tokulog);
  4. UNLOCK TABLES;
  5. 开始拷贝TokuDB的数据文件(不包含日志文件) –移动到这里
  6. SET TOKUDB_CHECKPOINT_LOCK=OFF;

这样在拷贝TokuDB数据文件的时候,就跟redo-log没半毛钱关系了,而且拷贝的redo-log数也大大减少!

优化改进

本以为这样就可以早点下班回家,但问题还是来。

某实例有几十万个TokuDB文件(分区表文件),使用热备的数据备库重搭后,复制过程中偶尔会出现”Duplicate entry … for key ‘PRIMARY’“错误。

引起这个错误的原因比较深,触发自TokuDB内部机制。

TokuDB每个分区表有数个文件组成(想了解TokuDB数据库文件的请轻戳这里),当分区表非常多的时候,打开的文件句柄数会非常多,受限于open_files_limit配置,TokuDB底层会触发句柄关闭机制,对当前文件进行checkpoint操作(新数据被刷到磁盘且生效)再做close,这样即使拿到checkpoint锁后,还是有数据被写入,就引发了以上问题。

为了解决这个问题,我们在热备的过程中引入一个状态:in_backup = true,防止文件关闭做checkpoint操作,具体的patch见这里

这样TokuDB的热备就比较完美了,整个热备过程中,所有的数据文件均处于一个“一致性”状态,所有的操作都在redo-log里,不再污染数据文件。

时间: 2024-12-31 23:12:29

MySQL · TokuDB · 让Hot Backup更完美的相关文章

TokuDB · 让Hot Backup更完美

很久很久以前,内核君发表了一篇HA方案·TokuDB热备的文章,方法很简单: 1) SET TOKUDB_CHECKPOINT_LOCK=ON; 2) 开始拷贝TokuDB的数据文件(不包含日志文件) 3) FLUSH TABLES WITH READ LOCK; 4) 记录binlog位置,拷贝最新的binlog和TokuDB的日志文件(*.tokulog) 5) UNLOCK TABLES; 6) SET TOKUDB_CHECKPOINT_LOCK=OFF; 这些步骤可以很方便的嵌入到Pe

[2016-03]MySQL · TokuDB · 事务子系统和 MVCC 实现

前言 之前有篇月报是关于innodb事务子系统的<MySQL · 引擎特性 · InnoDB 事务子系统介绍> 里面较详细的讲述了 MySQL 如何开启一个事务,感兴趣的同学可以先阅读那篇温习一下. TokuDB 引擎也支持事务,保证一个事务内的所有操作都执行成功或者都未被执行.TokuDB中的事务由数据结构 tokutxn 表示.当开启一个 txn 时,TokuDB会创建一个 tokutxn 实例,下面只显示比较重要的字段. struct tokutxn { TXNID_PAIR txnid

MySQL · TokuDB · 日志子系统和崩溃恢复过程

TokuDB日志子系统 MySQL重启后自动加载InnoDB和其他的动态plugin,包括TokuDB.每一plugin在注册的时候指定init和deinit回调函数.TokuDB的init/deinit函数分别是tokudb_init_func和tokudb_done_func. MySQL重启过程中调用tokudb_init_func进行必要的初始化.在tokudb_init_func里面,调用db_env_create创建一个env实例,进行参数设置和callback设置.db_env_c

MySQL · TokuDB · TokuDB索引结构--Fractal Tree

背景介绍 TokuDB采用的是Fractal Tree作为索引的数据组织方式.它是一种面向磁盘I/O优化的数据结构,采用"分期偿还"策略减少在数据插入过程中从root节点到leaf节点的搜索过程.这种搜索过程可以简称为locate_position,就是寻找要插入key在Tree中位置的过程. 一般B+Tree的插入过程分为两个部分: Locate_position: 从root开始使用binary search方法递归地寻找应该插入到哪个子节点上,直到在leaf节点找到应该插入的位置

MySQL · TokuDB · 事务子系统和 MVCC 实现

前言 之前有篇月报是关于innodb事务子系统的<MySQL · 引擎特性 · InnoDB 事务子系统介绍> 里面较详细的讲述了 MySQL 如何开启一个事务,感兴趣的同学可以先阅读那篇温习一下. TokuDB 引擎也支持事务,保证一个事务内的所有操作都执行成功或者都未被执行.TokuDB中的事务由数据结构 tokutxn 表示.当开启一个 txn 时,TokuDB会创建一个 tokutxn 实例,下面只显示比较重要的字段. struct tokutxn { TXNID_PAIR txnid

MySQL · TokuDB · Cachetable 的工作线程和线程池

介绍 TokuDB也有类似InnoDB的buffer pool叫做cachetable,存储数据节点(包括叶节点和中间节点)和rollback段,本文中为了表达简单,叶节点,中间节点和rollback段统称数据节点.Cachetable是全局唯一的,它与MySQL实例存在一一对应的关系.TokuDB没有采用常见的BTREE(BTREE+,BTREE*)表示索引,而是采用Fractal Tree,简称FT.FT跟BTREE+类似,维护了一个树形的有序结构,中间节点存储pivot(TokuDB的中间

MySQL · TokuDB · TokuDB之黑科技工具

TokuDB之黑科技工具 刚过完年,美女程序员静静想学习下 TokuDB 相关技术,从何处入手呢?TokuDB的技术资料可是出了名的少! 本篇就给大家介绍下两个"黑科技"工具,来帮助我们更深入的了解TokuDB. 黑科技之tokuftdump 此工具用来dump一个Fractal-Tree结构的数据文件. 这样我们就可以很直观的知道我写入的数据在磁盘上是个什么样子(disk layout). 废话少说,一切尽在"栗子"中. 创建表t1: CREATE TABLE `

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)导致. 比较诡异的是主库一切正常,无任何错误. 经过沟通,发现

MySQL · TokuDB · TokuDB 中的行锁

前言 4月份月报有篇文章<行锁(row-lock)与区间锁(range-lock)>,介绍了 TokuDB 的行锁/区间锁是如何使用的.这篇文章是其姐妹篇,介绍TokuDB行锁的实现,大家可以对照着看. 行锁申请 与 InnoDB 类似,TokuDB 也支持行级锁用来协调多个 txn 对数据库表某一段数据的并发访问.一个表中所有已经 grant 的行锁是用一个 binary search tree 来表示的,TokuDB 的术语称它为 lock tree.lock tree 与数据库表之间是一