从实现原理来看为什么 Clone 插件比 Xtrabackup 更好用?

本文主要初步的介绍 Clone Plugin 的原理以及和 Xtrabackup 的异同,以及整体实现的框架。

作者:戴骏贤(小光) 前网易游戏 计费组-资深数据库系统工程师,现天翼云数据库运维专家。

爱可生开源社区出品,原创内容未经授权不得随意使用,转载请联系小编并注明来源。

本文约 2600 字,预计阅读需要 9 分钟。

从 MySQL 8.0.17 版本开始,官方实现了 Clone 的功能,允许用户通过简单的 SQL 命令把远端或本地的数据库实例拷贝到其他实例后,快速拉起一个新的实例。

图片来源:https://lefred.be/

该功能由一些列的 WL 组成 :

  1. Clone local replica(WL#9209) :实现了数据本地 Clone。
  2. Clone remote replica(WL#9210) :在本地 Clone 的基础上,实现了远程 Clone。将数据保存到远程的一个目录中,解决跨节点部署 MySQL 的问题。
  3. Clone Remote provisioning(WL#11636) :将数据直接拷贝到需要重新初始化的 MySQL 实例中。此外这个 WL 还增加了预检查的功能。
  4. Clone Replication Coordinates(WL#9211) :完成了获取和保存 Clone 点位的功能,方便 Clone 实例正常的加入到集群中。
  5. Support cloning encrypted database (WL#9682) :最后一个 worklog 解决了数据加密情况下的数据拷贝问题。

本文主要初步的介绍 Clone Plugin 的原理以及和 Xtrabackup 的异同,以及整体实现的框架。

Xtrabackup 备份的不足

在 Xtrabackup 备份的过程中,可能遇到的最大的问题在于拷贝 Redo Log 的速度跟不上线上生产 Redo Log 的速度。

因为 Redo Log 是会循环利用的,当 CK 过后旧的 Redo Log 可能会被新的 Redo Log 覆盖,而此时如果 Xtrabackup 没有完成旧的 Redo Log 的拷贝,那么没法保证备份过程中的数据一致性。

图片来源:https://www.cnblogs.com/linuxk/p/9372990.html

Redo Log 工作原理

Clone 实现的基本原理

那么在 Clone Plugin 中如何去解决这个问题? 从 WL#9209 中可以看到官方整体的设计思路。在完成 Clone 的过程中将过程分为了 5 步:

  1. INIT: The clone object is initialized identified by a locator.

  2. FILE COPY: The state changes from INIT to "FILE COPY" when snapshot_copy interface is called. Before making the state change we start "Page Tracking" at lsn "CLONE START LSN". In this state we copy all database files and send to the caller.

  3. PAGE COPY: The state changes from "FILE COPY" to "PAGE COPY" after all files are copied and sent. Before making the state change we start "Redo Archiving" at lsn "CLONE FILE END LSN" and stop "Page Tracking". In this state, all modified pages as identified by Page IDs between "CLONE START LSN" and "CLONE FILE END LSN" are read from "buffer pool" and sent. We would sort the pages by space ID, page ID to avoid random read(donor) and random write(recipient) as much as possible.

  4. REDO COPY: The state changes from "PAGE COPY" to "REDO COPY" after all modified pages are sent. Before making the state change we stop "Redo Archiving" at lsn "CLONE LSN". This is the LSN of the cloned database. We would also need to capture the replication coordinates at this point in future. It should be the replication coordinate of the last committed transaction up to the "CLONE LSN". We send the redo logs from archived files in this state from "CLONE FILE END LSN" to "CLONE LSN" before moving to "Done" state.

  5. Done: The clone object is kept in this state till dest

在Java中,`clone()`方法是`Object`类的一个方法,用于创建对象的一个浅拷贝。浅拷贝意味着对象的结构会被复制,但对象内部所引用的其他对象则不会被复制,仅仅是复制引用。要使用`clone()`方法来实现`WmsItemKey`对象的拷贝,需要遵循以下步骤: 1. 确保`WmsItemKey`类实现`Cloneable`接口,这样才能调用`clone()`方法。 ```java public class WmsItemKey implements Cloneable { // 类成员 } ``` 2. 重写`clone()`方法,以实现对象的深拷贝或浅拷贝。如果对象内部没有引用其他对象,或者你只需要浅拷贝,可以简单地调用`super.clone()`。如果需要深拷贝,则需要对每个内部对象也执行拷贝操作。 ```java @Override public WmsItemKey clone() throws CloneNotSupportedException { return (WmsItemKey) super.clone(); } ``` 3. 调用`clone()`方法并处理可能出现的`CloneNotSupportedException`异常。 ```java public static void main(String[] args) { WmsItemKey originalItemKey = new WmsItemKey(); // 设置原始对象的属性 try { WmsItemKey clonedItemKey = originalItemKey.clone(); // 现在clonedItemKey是originalItemKey的一个拷贝 } catch (CloneNotSupportedException e) { e.printStackTrace(); } } ``` 如果`WmsItemKey`类中包含了复杂对象的引用,可能需要实现深拷贝,以确保拷贝内部对象: ```java @Override public WmsItemKey clone() throws CloneNotSupportedException { WmsItemKey cloned = (WmsItemKey) super.clone(); // 深拷贝内部对象的逻辑 // cloned.innerObject = this.innerObject.clone(); // 如果innerObject有clone方法 return cloned; } ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值