【华为云MySQL技术专栏】MySQL Clone介绍

举报
GaussDB 数据库 发表于 2025/12/12 15:12:49 2025/12/12
【摘要】 1、MySQL Clone简介MySQL Clone是MySQL 8.0版本开始引入的一个插件,用于从本地或远程clone数据,如图1和图2所示。图1 本地Clone图2 远程Clone简单来讲就是对数据目录取一个物理的备份快照,clone到本地或者远程,过程中源端(donor)几乎不受影响,支持DML、DDL的并发。MySQL Clone仅支持InnoDB,会clone包含database...

1、MySQL Clone简介

MySQL Clone是MySQL 8.0版本开始引入的一个插件,用于从本地或远程clone数据,如图1和图2所示。

1.png图1 本地Clone

2.png图2 远程Clone

简单来讲就是对数据目录取一个物理的备份快照,clone到本地或者远程,过程中源端(donor)几乎不受影响,支持DML、DDL的并发。

MySQL Clone仅支持InnoDB,会clone包含database、表空间、表、redo、undo、数据字典(元数据)等。Clone得到的数据目录可以用于创建备机。

2、使用方式

需要先安装MySQL Clone插件:

INSTALL PLUGIN clone SONAME 'mysql_clone.so';

然后执行clone命令:

  • 本地clone,指定目标数据目录即可

CLONE LOCAL DATA DIRECTORY '/target_clone_dir';
  • 远程clone

CLONE INSTANCE FROM 'root'@<远程MySQL Server地址>:<端口> IDENTIFIED BY '<MySQL密码>' DATA DIRECTORY '/clone_dir';

对于远程clone,命令在接收端(recipient)执行,从donor端拉取clone的数据到本地。

未指定DATA DIRECTORY的远程clone,recipient端会先删除当前的user data,包含schema和tablespace,然后clone到recipient端MySQL Server的数据目录。

Recipient端会持续循环的接收源端发来的数据,把数据写入相应文件的相应位置。

Clone完成后,对于未指定DATA DIRECTORY的场景,recipient端MySQL Server进程会自动退出,需要重启mysqld以使用新clone的数据,例如依赖mysqld_safe监控进程自动拉起。

3、Clone主要流程

MySQL Clone的流程如图3所示,主要分以下几个步骤。

  1. File copy,copy数据文件,同时开始记录copy文件过程中又有修改的page id

  2. Page copy,copy上一步过程中有修改的page,同时开始归档增量redo日志

  3. Redo copy,copy上一步过程中归档的redo日志

  4. clone完成后,接收端重启原有MySQL Server,或者启动新的MySQL Server进程,来进行恢复,开始使用新clone的数据

3.png图3 Clone的主要流程

这里有一些值得注意的点:

  • 数据字典也clone了,本质上相当于是表数据,因为也在innodb表中

  • gtid也被clone了(通过clone系统表mysql.gtid_executed),binlog pos会持久话在系统表空间,也被clone了

  • checkpoint信息在redo log文件中,也clone了

  • 还会clone ib_buffer_pool文件

所以MySQL Clone取的是一个完整的物理快照,也可以用于创建数据库的备机。

3.1 File copy

这一步copy所有的InnoDB数据文件,同时记录过程中又被修改了的数据页面的page id,保证数据的一致性。

  • 先开始记录修改的页面的ID:Page_Arch_Client_Ctx::start --> Arch_Page_Sys::start。首次执行,会启动page_archiver_thread后台线程。获取redo log的当前lsn作为track_page_lsn。做一个checkpoint,并等待其完成。对每个tablespace file进行flush,避免有数据还在os的cache中。

  • 将每个innodb tablespace的文件加入列表:Clone_Snapshot::m_data_file_vector

  • 处理每个文件的每个chunk,发送给远程,或者写到本地文件,主要调用过程如下:

#0  Clone_Handle::send_data
#1  Clone_Handle::process_chunk
#2  Clone_Handle::copy
#3  innodb_clone_copy

3.2 Page copy

对于copy数据文件过程中,又有修改的数据页面,在这一步中进行copy。同时,通过从此时开始归档新产生的redo log,来确保数据的一致性。

  • 先从此时开始归档后续新增的redo log:Log_Arch_Client_Ctx::start --> Arch_Log_Sys::start

主要代码流程如下:

int Arch_Log_Sys::start(Arch_Group *&group, lsn_t &start_lsn, byte *header,
                        bool is_durable) {
  // ...
  // 做一个checkpoint
  log_request_checkpoint(*log_sys, true);

  // ..
  // 如果是首次,启动log_archiver_thread后台线程
  if (m_state == ARCH_STATE_INIT) {
    auto err = start_log_archiver_background();

    // ...
  }

  // ...
  // 从checkpoint lsn开始归档redo log
  /* Start archiving from checkpoint LSN. */
  log_writer_mutex_enter(*log_sys); /* protects log_sys->last_checkpoint_lsn */
  log_files_mutex_enter(*log_sys);  /* protects log_sys->m_files */

  start_lsn = log_sys->last_checkpoint_lsn.load();

  const auto file = log_sys->m_files.find(start_lsn);
  // ...
}
  • 停止记录被修改的page的id,代码入口:Page_Arch_Client_Ctx::stop

  • 获取记录的每个有修改的页面,主要调用过程如下:

#0  Clone_Snapshot::get_page_for_write
#1  Clone_Snapshot::get_next_page
#2  Clone_Snapshot::get_next_block
#3  Clone_Handle::process_chunk
#4  Clone_Handle::copy
#5  innodb_clone_copy

像file copy一样,交由远程或本地写入页面所在文件的对应位置,代码入口为:Clone_Handle::send_data

3.3 Redo copy

这一步copy上一步所归档的redo log。代码入口:Clone_Snapshot::init_redo_copy。

先暂时阻塞XA事务避免binlog和innodb数据不一致,并等待binlog已prepare的事务提交或回滚,binlog位置持久化。

这里通过代码中的注释可以了解到,是为了避免GTID和持久化到InnoDB中的数据产生不一致。

/* Block external XA operations. XA prepare commit and rollback operations
are first logged to binlog and added to global gtid_executed before doing
operation in SE. Without blocking, we might persist such GTIDs from global
gtid_executed before the operations are persisted in Innodb. */

然后停止归档redo log,将donor端归档的redo log copy到远程或本地的对应文件。

3.4 基于clone的数据目录启动MySQL Server进行恢复

对于未指定数据目录的远程clone,接收端完成后会自动退出进程,如果没有类似mysqld_safe的机制拉起,则需要手动重新拉起mysqld进程。

对于其它clone场景,需要手动新启动mysqld进程来使用clone的数据目录。

从clone的redo log file读取checkpoint信息以及redo log进行恢复,与innodb恢复流程相同,主要是处理redo copy阶段所clone的redo log。

3.5 并发DDL的处理

MySQL Clone在运行过程中,实质上并不是和DDL并行,而是达到clone期间不完全禁止DDL执行的目的。可以通过参数clone_block_ddl控制,默认允许DDL并行。除了以下三种命令,都支持并发执行。

  • ALTER TABLE tbl_name DISCARD TABLESPACE;

  • ALTER TABLE tbl_name IMPORT TABLESPACE;

  • ALTER INSTANCE DISABLE INNODB REDO_LOG;

DDL执行时,在需要阻塞clone操作时,创建Clone_notify对象来通知clone模块。分如下类型:

/** Notification type. Currently used by various DDL commands. */
  enum class Type {
    /* Space is being created. */
    SPACE_CREATE,
    /* Space is being dropped. */
    SPACE_DROP,
    /* Space is being renamed. */
    SPACE_RENAME,
    /* Space is being discarded or imported. */
    SPACE_IMPORT,
    /* Space encryption property is altered. */
    SPACE_ALTER_ENCRYPT,
    /* Space encryption property of general tablespace is altered. */
    SPACE_ALTER_ENCRYPT_GENERAL,
    /* Space encryption flags of general tablespace are altered. */
    SPACE_ALTER_ENCRYPT_GENERAL_FLAGS,
    /* In place Alter general notification. */
    SPACE_ALTER_INPLACE,
    /* Inplace Alter bulk operation. */
    SPACE_ALTER_INPLACE_BULK,
    /* Special consideration is needed for UNDO as these DDLs
    don't use DDL log and needs special consideration during recovery. */
    SPACE_UNDO_DDL,
    /* Redo logging is being disabled. */
    SYSTEM_REDO_DISABLE
  };

例如clone期间进行了inplace alter table,ha_innobase::inplace_alter_table中会创建以下对象来通知clone插件。

/* Notify clone during in place operations */
Clone_notify notifier(Clone_notify::Type::SPACE_ALTER_INPLACE,
                      dict_sys_t::s_invalid_space_id, false);

Clone_notify构造函数中,对于SPACE_ALTER_INPLACE类型的DDL,不会对clone进行block。

if (fsp_is_system_temporary(space) || m_type == Type::SPACE_ALTER_INPLACE) {
  /* No need to block clone. */
  return;
}

而对于例如SPACE_CREATE,会调用Clone_Sys::begin_ddl_state --> Clone_Snapshot::begin_ddl_state来进行阻塞。

阻塞结束后,会在初始化page copy和初始化redo copy时,将DDL新建的tablespace文件加入列表进行处理。

4、总结

MySQL Clone可以对本地或远程MySQL Server的数据取一个物理快照,可以用于全量备份和创建备机,提供了mysqldump、Xtrabackup等之外的另一个选择。其通过File copy、page copy和redo copy三个阶段,保证了clone数据的完整与一致。

【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。