Loading [MathJax]/jax/output/CommonHTML/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >【腾讯云CDB】源码分析·MySQL online ddl日志回放解析

【腾讯云CDB】源码分析·MySQL online ddl日志回放解析

原创
作者头像
腾讯云数据库 TencentDB
修改于 2019-04-08 12:55:21
修改于 2019-04-08 12:55:21
3K00
代码可运行
举报
运行总次数:0
代码可运行

简介-online DDL过程介绍

ddl包含了copy和inplace方式,对于不支持online的ddl操作采用copy方式。对于inplace方式,mysql内部以“是否修改记录格式”为基准也分为两类,一类需要重建表(重新组织记录),比如optimize table、添加索引、添加/删除列、修改列NULL/NOT NULL属性等;另外一类是只需要修改表的元数据,比如删除索引、修改列名、修改列默认值、修改列自增值等。Mysql将这两类方式分别称为rebuild方式和no-rebuild方式。更多关于哪些DDL是否可以inplace的内容可以参考官方文档

online ddl主要包括3个阶段,prepare阶段,ddl执行阶段,commit阶段,rebuild方式比no-rebuild方式实质多了一个ddl执行阶段,prepare阶段和commit阶段类似。ddl执行过程中包括三个阶段。搜索关注“腾讯云数据库”官方微信立得10元腾讯云无门槛代金券,体验移动端一键管理数据库,学习更多数据库技术实战教程。

  • Prepare阶段:
  1. 创建新的临时frm文件
  2. 持有EXCLUSIVE-MDL锁,禁止读写
  3. 根据alter类型,确定执行方式(copy,online-rebuild,online-norebuild)
  4. 更新数据字典的内存对象
  5. 分配row_log对象记录增量
  6. 生成新的临时ibd文件
  • ddl执行阶段:
  1. 降级EXCLUSIVE-MDL锁,允许读写
  2. 扫描old_table的聚集索引每一条记录rec
  3. 遍历新表的聚集索引和二级索引,逐一处理
  4. 根据rec构造对应的索引项
  5. 将构造索引项插入sort_buffer块
  6. 将sort_buffer块插入新的索引
  7. 处理ddl执行过程中产生的增量(仅rebuild类型需要)
  • commit阶段
  1. 升级到EXCLUSIVE-MDL锁,禁止读写
  2. 重做最后row_log中最后一部分增量
  3. 更新innodb的数据字典表
  4. 提交事务(刷事务的redo日志)
  5. 修改统计信息
  6. rename临时idb文件,frm文件
  7. 变更完成

参考资料:

http://blog.itpub.net/22664653/viewspace-2056953

http://www.cnblogs.com/cchust/p/4639397.html

可以看到在ddl执行阶段第7步和commit阶段的第2步都会重做在ddl过程产生的日志增量。该文将重点讲述日志重做阶段的相关细节。

在日志重做的过程中,我们将重点关注两个问题:1. 记录日志是怎么管理及写入的; 2. 记录日志是怎么回放的。

1. 记录日志是怎么管理及写入的?

Innodb使用结构体row_log_t对DDL过程产生的增量进行管理,它是属于索引结构dict_index_t的一部份, 在DDL过程中,对该索引做的修改将会记录在row_log_t中。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
struct dict_index_t{
	...
	row_log_t*	online_log;
					/*!< the log of modifications
					during online index creation;
					valid when online_status is
					ONLINE_INDEX_CREATION */
	...
}

1.1 何时进行row_log_t的分配?

在两种情况下会进行row_log_t的分配:

1) 当需要rebuild表时,为聚蔟索引分配一个row_log_t。 2) 假如不需要重建聚蔟索引,那会为新增加的每一个索引(不包括全文索引)也都会分配一个row_log_buf_t。

调用栈为:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
mysql_alter_table-->handler::ha_prepare_inplace_alter_alter_table-->ha_innobase::prepare_inplace_alter_table-->prepare_inplace_alter_table_dict-->row_log_allocate.

在进行row_log_allocate前会调用rw_lock_x_lock函数先将对应的索引加锁,在退出row_log_allocate函数之后调用rw_lock_x_unlock进行解锁。

1.2 row_log_allocate的过程

row_log_allocate的过程就是初始化row_log_t结构体的过程,它的结构如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
struct row_log_t {
	int		fd;	/*!< file descriptor */
	ib_mutex_t	mutex;	/*!< mutex protecting error,
				max_trx and tail */
	page_no_map*	blobs;	/*!< map of page numbers of off-page columns
				that have been freed during table-rebuilding
				ALTER TABLE (row_log_table_*); protected by
				index->lock X-latch only */
	dict_table_t*	table;	/*!< table that is being rebuilt,
				or NULL when this is a secondary
				index that is being created online */
	bool		same_pk;/*!< whether the definition of the PRIMARY KEY
				has remained the same */
	const dtuple_t*	add_cols;
				/*!< default values of added columns, or NULL */
	const ulint*	col_map;/*!< mapping of old column numbers to
				new ones, or NULL if !table */
	dberr_t		error;	/*!< error that occurred during online
				table rebuild */
	trx_id_t	max_trx;/*!< biggest observed trx_id in
				row_log_online_op();
				protected by mutex and index->lock S-latch,
				or by index->lock X-latch only */
	row_log_buf_t	tail;	/*!< writer context;
				protected by mutex and index->lock S-latch,
				or by index->lock X-latch only */
	row_log_buf_t	head;	/*!< reader context; protected by MDL only;
				modifiable by row_log_apply_ops() */
	ulint		n_old_col;
				/*!< number of non-virtual column in
				old table */
	ulint		n_old_vcol;
				/*!< number of virtual column in old table */
	const char*	path;	/*!< where to create temporary file during
				log operation */
};

其中: 1) path: 该row_log_t的数据写入临时文件的地址。 2) fd: path对应的临时文件打开时的文件描述符。 3) mutex: 用于保护max_trx和tail。 4) max_trx: 在row_log_online_op函数中能观察到的最大trx_id。 5) add_cols: 新增的列的默认值。 6) col_map: 数组,存的是原表中的列id对应到新表的列id。 7) tail: 类型为row_log_buf_t,存储的是DDL期间写入的记录,后来该详细描述。 8) head: 类型也为row_log_buf_t,是replay日志时使用的上下文,后来也将详细描述。

1.3 日志增量怎么写入的?

在onlind DDL过程中,所做的对索引的修改(包括INSERT, UPDATE, DELETE操作)在完成之后,也将会记录在它的online_log中。其中涉及的函数包括:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
row_log_table_insert();
row_log_table_update();
row_log_table_delete();

其中row_log_table_insert和row_log_table_update都调用的相同的函数。此外,三者的逻辑也大体相同。以下以INSERT举例,过程:

1) 计算出要写入的日志的记录的长度。 2) 调用row_log_table_open,返回一个写入的位置b。 3) 构建记录,将记录写入位置b。 4) 调用row_log_table_close结束此次日志的写入。

在这个过程中,row_log_table_open和row_log_table_close负责操作row_buf_t结构体。搜索关注“腾讯云数据库”官方微信立得10元腾讯云无门槛代金券,体验移动端一键管理数据库,学习更多数据库技术实战教程。

回顾一下之前介绍的row_buf_t的结构,其中类型为row_log_buf_t的tail是实际写入的位置,它的结构如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
/** Log block for modifications during online ALTER TABLE */
struct row_log_buf_t {
	byte*		block;	/*!< file block buffer */
	ut_new_pfx_t	block_pfx; /*!< opaque descriptor of "block". Set
				by ut_allocator::allocate_large() and fed to
				ut_allocator::deallocate_large(). */
	mrec_buf_t	buf;	/*!< buffer for accessing a record
				that spans two blocks */
	ulint		blocks; /*!< current position in blocks */
	ulint		bytes;	/*!< current position within block */
	ulonglong	total;	/*!< logical position, in bytes from
				the start of the row_log_table log;
				0 for row_log_online_op() and
				row_log_apply(). */
};

其中: 1) block: 用来写入记录日志的buffer的位置,它的大小由参数innodb-sort-buffer-size决定,默认为1MB。 2) buf: 是个定长数组,用于处理跨越两个块的记录的buffer。 3) blocks: 当block空间使用完,会将block的数据写入临时文件中,再次利用block的空间。block字段用于记录当前处理的block的个数。 4) bytes: 用于记录当前block内已经使用的字节数。

row_log_table_open函数过程: 1) 首先获得row_log_t::mutex,保证互斥访问。 2) 当前的row_log_t::tail.block为空,即第一次使用时,申请大小为innodb-sort-buffer-size(srv_sort_buf_size)的内存,赋值row_log_t::tail.block。 3) 计算当前row_log_buf_t::block中可写入的内存的大小,计算方式是innodb-sort-buffer-size - row_log_buf_t::bytes。 4) 如果可写入的空间的大小少于当前请求的记录日志的长度,意味着这一条日志在逻辑上跨越了两个block。此时,返回定长数组row_log_buf_t::buf;否则,返回的是block中的位置,偏移量为row_log_buf_t::bytes。

记录日志写入row_log_table_open函数的内存位置之后调用row_log_table_close,过程: 1) 如果此时写入的日志总量超过srv_online_max_size,则会报错。 2) 如果写入的位置是row_log_buf_t::buf,意味着写入的记录是当前block的最后一条。此时将把row_log_buf_t::block和row_log_buf_t::buf中的数据写入临时文件中。由于最后一条记录写在了buf中,block中还有部份空余空间,将buf的前面部份的内容拷贝至buffer中空余部份。 3) 如果是第一次block空间用完,将生成一个临时文件,文件名和文件描述符将写在row_log_t::path和row_log_t::fd。 4) 通过row_log_buf_t::blocks计算文件中的偏移量offset,计算方式是row_log_buf_t::blocks × innodb-sort-buffer-size(srv_sort_buf_size)。 5) 将row_log_buf_t::block中的数据写入临时文件偏移量为offset的位置,row_log_buf_t::blocks自增一,表示写入临时文件的block数量增加一个。 6) 将buf_log_buf_t::buf在2)中未被拷贝至row_log_buf_t::block中的数据拷贝至row_log_buf_t,修改row_log_buf_t::bytes。 7) 将该条写入记录日志的长度增加到row_log_buf_t::total中。 8) 释放row_log_t::mutex。

以上将日志写入的过程介绍完毕。

2. 日志是怎么回放的?

online DDL在DDL执行阶段和commit阶段会有两次日志回放。在第一次记录回放的同时,记录日志依然在写入。怎么保证两个过程不互相干扰,其中row_log_t::head起了关键的作用。从名字上看,tail相当于当前日志的尾部,head相当于当前日志的头部。回放时,head的位置不超过tail并且不与tail同时进行读写即可。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
	row_log_buf_t	head;	/*!< reader context; protected by MDL only;
				modifiable by row_log_apply_ops() */

row_log_table_apply是回放日志时调用的函数,首先它对先对索引加X锁,再调row_log_table_apply_ops进行具体的回放逻辑,在row_log_table_apply_ops返回之类再进行解锁。row_log_table_apply_ops函数用于处理块和记录间的回放顺序的逻辑,为了避免阻塞日志的写入,在这个过程中存在多次加锁解锁过程;row_log_table_apply_op函数则是用于处理回放单条记录的逻辑。

它们的调用关系为row_log_table_apply-->row_log_table_apply_ops-->row_log_table_apply_op。

row_log_table_apply_ops函数执行过程,row_log_buf_t::head用于处理读取日志记录的上下文,此外有两对变量: 1) mrec和mrec_end,用于标志当前处理的记录日志的开头和结尾; 2) next_mrec和next_mrec_end,用于标志待处理的block的开头和结尾。

row_log_table_apply_ops函数执行过程: 1) 进入函数前持有索引的X锁,此时是阻塞写入的。

2) 判断row_log_buf_t::head是否是row_log_buf_t::tail是同处于同个block。根据不同的结果分别进入3)或者4)。

3) 如果不属于同一个block,表示数据应该从临时文件中读取。此时将索引解锁,通过row_log_buf_t::block和innodb-sort-buffer-size(srv_sort_buf_size)计算offset在临时文件中读取数据至row_log_buf_t::head.block,大小为innodb-sort-buffer-size(srv_sort_buf_size),将row_log_buf_t::head.block的头部和尾部指针赋给next_mrec和next_mrec_end。

4) 如果属于同一个block,表示当前处理的块已经是最后一个,不对索引解锁,保证在最后一个block上记录日志的写入和回放是互斥的。如果block中没有数据,表示记录日志已经处理完毕,跳至12)。否则将row_log_buf_t::block的头部指针和尾部指针赋给next_mrec和next_mrec_end。

5) 如果此时mrec不为空,表示上一个block的最后一条记录日志不完整,它的前半部份数据放置在row_log_buf_t::buf中,而mrec_end指向这条不完整的记录的尾部,后一半部份在新读的block的开头部份。此时将next_mrec的开头部份的数据拷贝至row_log_buf_t::buf中mrec_end之后将整个数组填满,调用row_log_table_apply_op处理这一条跨越两个block的记录,返回下一条记录的开头的指针并赋值给mrec。通过计算mrec - mrec_end可以得出该条记录的后半段的长度,通过该值修改next_mrec_end。搜索关注“腾讯云数据库”官方微信立得10元腾讯云无门槛代金券,体验移动端一键管理数据库,学习更多数据库技术实战教程。

6) 将next_mrec和next_mrec_end分别赋值给mrec和mrec_end。

7) 此时进入一个while循环,依次调用row_log_table_apply_op处理记录日志,返回下一条记录的头部指针赋值next_mrec。

8) 如果next_mrec与next_mrec_end相等并且当前持有索引锁,意味着处理的block已经是最后一个,记录日志处理完毕,跳到4)。

9) 如果next_mrec与next_mrec_end相等但是当前不持有索引锁,意味着处理的block不是最后一个,row_block_buf_t::block自增一,对索引加X锁,跳到2)。

10) 如果next_mrec不等于NULL但是next_mrec与next_mrec_end不相等,表示block还有记录未被处理,跳到7)。

11) 如果next_mrec等于空,表示block存在跨越两个block的记录,将该条记录的前半部份拷贝至row_log_buf_t::buf中,修改mrec和mrec_end指它们指向buf该条不完整的记录的头部和尾部。跳至9)。

12) 当所有的记录处理结束之后,如果索引没有加锁,则会为它加上X锁。调用row_log_block_free函数清理row_log_buf_t::head的内存。

row_log_table_apply_op函数用于处理单条记录日志,参数mrec和mrec_end分别表示当前处理的记录的头部和该block的尾部,返回下一条记录的开头指针。日志记录的格式大致可以分为三个主要部份:OP|Pysical Record| Virtual Record。 过程: 1) 根据mrec的第一个字节判断操作类型,分别三种:ROW_T_INSERT和ROW_T_DELETE、ROW_T_UPDATE。 2) 根据不同类型计算Pysical Record和Virtual Record的总长。 3) 当记录日志总长超过mrec_end的尾部,则返回NULL。 4) 当记录日志总长不超过mrec_end,该条记录可以被处理。根据不同的类型分别调用row_log_table_apply_insert和row_log_table_apply_delete、row_log_table_apply_update函数进行处理。

3. 总结

关于online DDL中的其它细节较多,本文只对大体实现流程做了介绍,没有对所有的细节做更为详细的介绍。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
聊聊 MySQL 的 Online DDL
日常开发我们对一条DML语句较为熟悉,很多开发人员都了解sql的执行过程,比较熟悉,但是DDL是如何执行的呢,大部分开发人员可能不太关心,也认为没必要了解,都交给DBA吧。其实不然,了解一些能尽量避开一些ddl的坑,那么下面带大家一起了解一下DDL执行的方式,也算抛砖引玉吧。如有错误,还请各位大佬们指正。
码猿技术专栏
2023/09/07
1.1K0
聊聊 MySQL 的 Online DDL
如何准确判断什么时候可以给大表加索引 - 崔笑颜的博客
以社交平台的用户表为例,随着业务的快速增长,用户表user单表数据量越来越大,此时,如果我们想给user表添加索引,数据规模对添加过程的影响势必要考虑在内,但是,单表数据规模对添加索引会产生什么样的影响呢,我们在什么样的数据库请求状态下给大表添加索引比较好呢?
崔笑颜
2021/05/06
1.3K0
如何准确判断什么时候可以给大表加索引 - 崔笑颜的博客
Mysql onlineddl vs gh-ost
Innodb早期支持通过copy table跟inplace的方式来执行DDL语句,其原理如下:
mingjie
2022/05/12
8560
Mysql onlineddl vs gh-ost
MySQL 5.7 特性:Online DDL
DDL 一向是业务的痛点,尤其是对大型表的 DDL 操作,具有操作时间久,对性能影响大,可能影响业务正常使用等问题。
王文安@DBA
2020/09/14
8.2K1
MySQL 5.7 特性:Online DDL
MySQL 实战笔记 第03期:MySQL Online DDL 三阶段初探
上一节咱们了解了元数据锁,但在 Online DDL 操作中具体是怎样加锁的呢?加几次锁呢?带着这些疑问,我们一起来学习 DDL 三阶段。
数据库交流
2022/04/25
6140
MySQL 实战笔记 第03期:MySQL Online DDL 三阶段初探
故障分析 | MySQL 执行 Online DDL 操作报错空间不足?
作者:徐文梁,爱可生 DBA 成员,一个执着于技术的数据库工程师,主要负责数据库日常运维工作。擅长 MySQL,Redis 及其他常见数据库也有涉猎;喜欢垂钓,看书,看风景,结交新朋友。
爱可生开源社区
2024/02/21
2890
故障分析 | MySQL 执行 Online DDL 操作报错空间不足?
MySQL Online DDL
serena
2017/06/01
8K0
MySQL Online DDL
MySQL 到底能不能online ddl index PG VS MYSQL
上周一篇关于MySQL 拜托加个索引能和PG一样简单吗?只能gh-ost了 烦人,的帖子引起争议,主要因为我提到 POSTGRESQL 在线添加索引是非常方便的,MySQL 在这方面不咋地,首先说结果,我对MYSQL的知识需要更新,针对高版本得MYSQL是支持online ddl index,所以写这篇来纠正一下,但是有一些同学发了一些MYSQL 支持online ddl index 的绝对论甚至有人说mysql 5.x就可以onine ddl index,这点咱们也的纠正,对就是对,错就是错。
AustinDatabases
2024/06/05
2040
MySQL  到底能不能online ddl index    PG VS MYSQL
MySQL谬误集02: DDL锁表
导语 | 本文是MySQL谬误集系列文章的第二篇,该系列旨在纠正一系列似是而非的说法。比如关于MySQL DDL操作,有很多同学认为会锁表,那是不是一定会锁表呢?是锁读还是锁写呢?锁多长时间?不同的DDL操作有差别吗?MySQL从5.5到8.0,对这个问题有什么改进呢?本文做了一个简单的总结。
DBA成江东
2023/08/19
1.6K0
MySQL谬误集02: DDL锁表
【腾讯云CDB】如何快速删除InnoDB中的大表
本文介绍了MySQL DROP TABLE操作可能存在的性能瓶颈,包括InnoDB引擎表、MyISAM引擎表、以及操作系统层面的限制。针对这些瓶颈,本文提出了相应的优化方案,包括增大InnoDB缓冲池、使用MyISAM存储引擎、以及调整操作系统相关参数。通过这些优化方案,可以有效地提升MySQL数据库的性能,减少DROP TABLE操作对数据库性能的影响。
腾讯云数据库 TencentDB
2017/12/14
4K1
MySQL DDL发展史
- 注意: 在online ddl前,inplace的方法主要在第三步大大缩短了时间,只重构了索引,没有重新copy所有数据
划水教练
2022/05/17
1.1K0
MySQL DDL发展史
MySQL 日志系统之 redo log 和 binlog
之前我们了解了一条查询语句的执行流程,并介绍了执行过程中涉及的处理模块。一条查询语句的执行过程一般是经过连接器、分析器、优化器、执行器等功能模块,最后到达存储引擎。
武培轩
2019/10/25
9690
Mysql 除了并行查询以外也可以并行索引,升级吧少年
POSTGRESQL 在 DDL DML DQL 都可以并行,之前MYSQL 在并行方面一直是软肋,MYSQL 8 已经提供了DQL的并行, DDL 的并行也支持了,从MYSQL5.X 升级到8 是必然了.
AustinDatabases
2021/12/27
1.2K0
Mysql  除了并行查询以外也可以并行索引,升级吧少年
TXSQL Parallel DDL功能建设
TXSQL Parallel DDL 功能建设 DDL(Data Definition Language)是用来修改数据库和表结构的一类操作,是数据库所有操作中最高危也是最重要的一类操作,常见的DDL操作包括:加减列、修改列类型、加减索引等。由于DDL操作涉及到数据库表结构、表数据的重构,尤其是在云数据库场景下,表的数据量急速上涨,DDL操作的效率受到了极大的挑战,一条慢速的DDL操作甚至需要花费几天的时间来完成,在这期间DDL操作持续持有锁,意味着业务可能会面临长时间等待锁的情况,几天的等待对于业务来说是
腾讯数据库技术
2023/04/25
7000
TXSQL Parallel DDL功能建设
技术分享 | Online DDL 工具 pt-osc
爱可生 DBA 团队成员,主要负责 MySQL 故障处理和公司自动化运维平台维护。对技术执着,为客户负责。
爱可生开源社区
2020/09/23
5K0
技术分享 | Online DDL 工具 pt-osc
MySQL 核心模块揭秘 | 06 期 | 事务提交之前,binlog 写到哪里?
作者:操盛春,爱可生技术专家,公众号『一树一溪』作者,专注于研究 MySQL 和 OceanBase 源码。
爱可生开源社区
2024/02/21
2330
MySQL 核心模块揭秘 | 06 期 | 事务提交之前,binlog 写到哪里?
Oracle online系列(下):online indexbuild
点击上方蓝色字关注我们~ online indexbuild (online create或者rebuild index)是Oracle的一个极其常用的online操作,我们知道当创建索引或者重建索引没有加online关键字的话,会请求表对象上的4号TM锁,而DML请求的是3号TM锁,3和4的TM锁并不兼容,所以在索引创建或者重建期间是无法进行DML操作的,等待事件为enq: TM – contention。 为了改进这一缺陷,在Oracle 8i推出了online indexbuild功能,并且在11.
数据和云
2022/03/04
1.3K0
详解MySQL原生Online DDL:从历史演进到原理及使用
MySQL Online DDL 功能从 5.6 版本开始正式引入,发展到现在的 8.0 版本,经历了多次的调整和完善。本文主要就 Online DDL 的发展过程,以及各版本的区别进行总结。其实早在 MySQL 5.5 版本中就加入了 INPLACE DDL 方式,但是因为实现的问题,依然会阻塞 INSERT、UPDATE、DELETE 操作,这也是 MySQL 早期版本长期被吐槽的原因之一。
公众号:码到三十五
2024/03/19
2K0
详解MySQL原生Online DDL:从历史演进到原理及使用
架构师技能5:深入MySQL原理-Waiting for table metadata lock引发系统崩溃
我们码农平时大多数时间都在撸码或者撸码的路上,很少关注mysql的一些底层原理,当出现问题时没能力第一时间解决问题,出现问题后不去层层剖析问题产生的原因,后续也就可能无法避免或者绕开同类的问题。因此不要单纯做Ctrl+c和Ctrl+V,而是一边仰望星空(目标规划),一边脚踏实地去分析每个问题。 在mysql系列专栏里面,我深入浅出的总结了mysql相关知识,感兴趣的话可以去阅读,有问题就可以随时相互交流学习。
黄规速
2022/04/14
9840
架构师技能5:深入MySQL原理-Waiting for table metadata lock引发系统崩溃
【腾讯云CDB】源码分析 · MySQL binlog组提交和Multi-Threaded-Slave
本文介绍了MySQL中的binlog组提交及其在MySQL Replication中的作用。binlog是MySQL中一种二进制日志,用于记录数据库的更改历史。在MySQL Replication中,通过binlog实现主从复制。当主库发生更改时,binlog会记录所有更改,并将更改发送到从库。从库根据binlog中的更改来更新自己的数据,从而保持与主库一致。在MySQL中,使用binlog可以实现多种功能,如灾难恢复、数据迁移、只读实例等。
腾讯云数据库 TencentDB
2017/12/28
3.4K0
【腾讯云CDB】源码分析 · MySQL binlog组提交和Multi-Threaded-Slave
推荐阅读
相关推荐
聊聊 MySQL 的 Online DDL
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验