MYSQL 中操作一个MYSQL的副本是一件不是很简单的问题,当然如果你使用XTRABACKUP,当然也不麻烦,但如果有更简单的方法谁又不愿意去用,MYSQL 8.017 提供这个功能,以插件的方式,他可以产生一个本地的clone 或者远程传输文件到一个目的端,这样的方式其实等待了多年,别的数据库其实操作这样的事情,还是比较简单的,例如PG pg_basebackup,或者安装了REPMGR 的PG ,分分钟就自动生成一个副本,并建立了连接,相对MYSQL来说是简单的多。
那等了这么多年的功能,到底怎么样,到底我们是不是已经可以升级到MYSQL 8 ,目前看还是的等等,主要是最近MYSQL 8 的更新速度太快,很多新功能还在发布中,如果莽然升级会遗漏更多的好功能,例如HASH JOIN。
但知识的更新时必须的,所以 let's go
MySQL 8.0.17引入了克隆SQL语句,使当前MySQL服务器成为在不同节点上运行的另一个MySQL服务器的“克隆”。我们将执行克隆语句的服务器实例称为“收件人”。要从中克隆数据的源服务器实例称为“Donor”。捐助方以一致的快照克隆其存储在InnoDB存储引擎中的所有数据和元数据,以替换接收方中的数据。成功执行克隆SQL语句后,将自动重新启动接收服务器。重新启动涉及到恢复克隆的快照数据,就像以旧方式复制数据一样。一旦恢复完成,接收者就是捐献者的克隆。
下面我们选择两台机器,205 210 ,我们将210上的数据库的内容clone 到205上,
1 首先在两台机器上都要安装 clone 插件 INSTALL PLUGIN CLONE SONAME "mysql_clone.so";
2 创建操作的账户,建议为了降低操作的复杂度,可以设置为super ,实际一边需要备份的权限,另一个边CLONE_ADMIN 的权限。
这里就简单了
3 在接受者创建donor_list 然后直接执行命令开始克隆
SET GLOBAL clone_valid_donor_list = "192.168.198.210:3306";
clone instance from clone@192.168.198.210:3306 identified by "1234.Com";
4 另外可以在接收者这边执行下面的语句来获取复制的进度
select STAGE, STATE, CAST(BEGIN_TIME AS TIME) as "START TIME", CASE WHEN END_TIME IS NULL THEN LPAD(sys.format_time(POWER(10,12) * (UNIX_TIMESTAMP(now()) - UNIX_TIMESTAMP(BEGIN_TIME))), 10, ' ') ELSE LPAD(sys.format_time(POWER(10,12) * (UNIX_TIMESTAMP(END_TIME) - UNIX_TIMESTAMP(BEGIN_TIME))), 10, ' ') END as DURATION, LPAD(CONCAT(FORMAT(ROUND(ESTIMATE/1024/1024,0), 0), " MB"), 16, ' ') as "Estimate", CASE WHEN BEGIN_TIME IS NULL THEN LPAD('0%', 7, ' ') WHEN ESTIMATE > 0 THEN LPAD(CONCAT(CAST(ROUND(DATA*100/ESTIMATE, 0) AS BINARY), "%"), 7, ' ') WHEN END_TIME IS NULL THEN LPAD('0%', 7, ' ') ELSE LPAD('100%', 7, ' ') END as "Done(%)" from performance_schema.clone_progress;
所以从mysql 8.017开始,复制一个MYSQL 相对来别的数据库来说,那是最最最简单的一件事。
从克隆的progress中来说,主要的流程 删除数据,份文件拷贝,page 拷贝,redo 拷贝, 文件同步 重启接受者,然后是重执行在拷贝中没有执行的日志的数据。
操作简单,问题是到底原理是什么这个是很重要,并需要了解的
大致可以分析一下,一般来说拷贝文件进行数据复制都是简单的事情,麻烦的事情就是怎么确认在拷贝文件,时继续写入的数据,CLONE并不禁止数据的写入。
所以一定会根据日志 LSN号在开始文件拷贝作为一个基点,记录LSN号,当文件拷贝完毕后,在记录一个LSN 号,在这之间会记录在内存中的脏页,未刷新到数据日志中数据。当文件拷贝完毕后(其实这之间是有缓存的,缓存中记录的未check point 的space_id 和 page_id会一直被修改),到文件拷贝结束,记录的LSN号,以及这一个时刻未被checkpoint 的数据将重新落入到物理文件中,在刷新这一时刻的checkpoint 的数据 到应用checkpoint 的数据这段时间也会继续有数据写入,所以在应用完文件拷贝这段时间的日志后,还需要记录这个点,并且将这个点之间redo 日志进行拷贝,在应用,达到整体拷贝数据结束时,与数据的捐助者是一致的。(还得研究)
大致原理与 XTRBACKUP 有类似的地方,但又不完全相同。
采用这样的技术也是有限制的
1 在操作中是不允许有 DDL 的操作的
2 一次只能克隆一个实例
3 克隆的方式是不支持MY,CNF 文件的拷贝,(这和PG 的pg_basebackup相比,PG 的CLONE 方式是可以将配置文件直接拷贝过来的)
4 会重启MYSQL 接受者的MYSQL 服务,但不保证在任何情况下可以重启
这样的功能使用的场景也很明确,MGR ,未来的MGR 可能是最好的数据库分布式,免维护的方法,通过CLONE 可以已最快的方式自动产生一个MYSQL的副本,并自动的加入到MGR集群中,这在传统的 ORACLE 和 SQL SERVER 是不大能想象出来的。
MYSQL 8 已经不再是那个从前单薄的MYSQL ,各方面都在提升,与其他三位竞争对手相比,已经有比其他数据库有特点的地方,虽然并行,以及查询的方式还有待进步,但也千万别小看MYSQL 8 单库的力量,的确可以和其他的数据库较量一番。