MySQL在线DDL工具 gh-ost的原理解析

MySQL在线DDL工具 gh-ost的原理解析

简介

gh-ost是一个基于Percona OSC 原理的 MySQL online DDL 工具,它可以在线帮助MySQL用户快速升级表结构、移动数据,同时避免关闭业务及长时间占用MySQL资源等问题。此外,gh-ost的操作具有可回滚性,可以很方便的撤销变更操作。

原理

基本原理

gh-ost的原理与 Facebook 的 online schema change 工具有很多相似之处,大体上分为两个阶段:迁移阶段和同步阶段。

  • 迁移阶段通过创建一个 gh-ost 的数据表 gh-ost,并通过拷贝原表数据创建一个新表 gh-ost<suffix>suffix由当前时间戳和随机字符串组成),在新表中添加要修改的字段和索引,删除原表中的相应的字段和索引。
  • 同步阶段通过 MySQL 的 Trigger 和 Binlog,将原表中的所有操作记录到 gh-ost 表中,然后通过 DML 语句(增、删、改语句)将这些操作同步到新表。

更多详细原理

gh-ost 的运行依赖于多个 MySQL 参数设置:

  • 首先需要启用 MySQL 的 ROW 模式,以便使用 Trigger。
  • 启用 binlog_row_image = FULL,以便在 DML 中包含所有数据。
  • 设置 MySQL 参数 binlog_checksum=NONE,以避免在 binlog 传输过程中计算校验值,加快同步速度。
  • 设置 max_triggers_per_row = 1000,以便每行数据最多放置 1000 个触发器。
  • 可选设置,如果您需要将 gh-ost 运行到分布式系统上,则需要使用 MySQL Group Replication、MySQL Cluster 或 Galera Cluster。

在触发器的流程中,gh-ost 在原表添加触发器,用于捕获所有表的 DML 操作,然后将捕获到的数据记录下来写入到其记录表中。在触发器的 On Update 和 On Delete 事件中,gh-ost 需要把记录写入到两个表,分别是记录表和新表,On Insert 事件就只需要写入到新表。这样,新表的数据和原表保持同步。

一个大表修改结构批量操作时需要注意:

  • 对于大表,gh-ost 可以通过 chunk-index 参数来控制每个事务处理的数据量,以优化性能。
  • 在表上建立多个(>1)异步索引会影响gh-ost的性能,因此推荐在上一个后删除现有索引,然后添加新的索引。
  • 表上存在外键约束和触发器时,需要先将它们禁用,等结构变更完成后再启用,否则可能会执行失败。

示例

下面我们看两个使用gh-ost更改表结构的示例:

示例1:增加字段

比如原有表结构如下:

-- 表结构
CREATE TABLE `test` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(20) NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB;

-- 插入数据
INSERT INTO `test` (`id`, `name`) VALUES (1, 'xiaoming');

现在我们需要在该表中增加一个收入字段income,可以使用 gh-ost 实现在线修改:

$ gh-ost --user=root --host=127.0.0.1 --database=test \
           --table=test --alter="ADD COLUMN income INT(11)" \
           --concurrency=16 --throttle=200 --approve-renamed-columns=false \
           --chunk-size=1000 --max-load=Threads_running=25

示例2:修改字段名

比如原有表结构如下:

-- 表结构
CREATE TABLE `test` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(20) NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB;

-- 插入数据
INSERT INTO `test` (`id`, `name`) VALUES (1, 'xiaoming');

现在我们需要将该表中原有的字段 name 修改为 username,可以使用 gh-ost 实现在线修改:

$ gh-ost --user=root --host=127.0.0.1 --database=test \
           --table=test --alter="CHANGE COLUMN name username varchar(20) NOT NULL" \
           --concurrency=16 --throttle=200 --approve-renamed-columns=false \
           --chunk-size=1000 --max-load=Threads_running=25

总结

gh-ost 可以帮助 MySQL 用户更加方便和快速地修改数据库表结构,同时自带了可回滚性,非常适合大表在线修改,避免了关闭业务、占用 MySQL 资源等问题。但对于不是特别关注在线迁移的用户,可以使用 Percona Toolkit 的 pt-online-schema-change 工具或者 MySQL 官方的 ALTER TABLE 操作,二者在效率上略逊于 gh-ost,但也可以满足大多数用户的需求。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:MySQL在线DDL工具 gh-ost的原理解析 - Python技术站

(0)
上一篇 2023年5月22日
下一篇 2023年5月22日

相关文章

  • linux中tar打包指定路径文件的实现方法

    当需要将多个文件或文件夹打包成一个文件时,可以使用tar命令实现。下面是实现方法的完整攻略。 1. 指定路径打包文件 假设我们要将/home/user1/files/路径下的所有文件和文件夹打包成一个叫backup.tar的文件,则可以使用以下命令: tar -cvf backup.tar /home/user1/files/ -c: 表示创建新的打包文件;…

    database 2023年5月22日
    00
  • linux每天定时备份数据库并删除十天前数据详细步骤

    下面是针对“linux每天定时备份数据库并删除十天前数据”的详细攻略步骤: 1. 安装crontab 在linux系统下,定时任务可以使用crontab来实现。如果你的系统中没有安装crontab,则需要先安装。 使用以下命令来安装crontab: sudo apt-get install crontab 2. 编写备份脚本 首先,需要编写一个可以备份数据库…

    database 2023年5月22日
    00
  • Linux下实现C++操作Mysql数据库

    当在Linux下使用C++编写应用程序时,需要操作MySQL数据库,可以使用MySQL提供的C++ API来实现。下面是实现的完整步骤: 步骤一:安装MySQL C++ Connector 首先需要安装MySQL C++ Connector,它是MySQL官方提供的连接MySQL数据库的C++库。在Ubuntu系统下,可以使用以下命令进行安装: sudo a…

    database 2023年5月22日
    00
  • MySQL命令行导出与导入数据库

    MySQL命令行导出与导入数据库 MySQL提供了命令行工具来完成数据库的导入和导出操作。这是一种没有GUI的操作方式,可以为需要处理大量数据的开发人员提供更多的灵活性和控制权。 导出数据库 可以使用导出命令将MySQL数据库导出到一个文件: mysqldump -u [用户名] -p [密码] [数据库名称] > [导出文件名].sql 以上面的命令…

    database 2023年5月22日
    00
  • MySQL查询语句简单操作示例

    接下来我将详细讲解“MySQL查询语句简单操作示例”的完整攻略。 MySQL查询语句简单操作示例攻略 什么是MySQL查询语句 MySQL查询语句是在关系型数据库MySQL中使用的一种命令,用于从数据库中提取所需的数据。通过使用MySQL查询语句,可以很方便地从数据库中获取数据并对数据进行操作。 MySQL查询语句的基本语法 MySQL查询语句的基本语法如下…

    database 2023年5月21日
    00
  • 某大型网络公司应聘时的笔试题目附答案

    某大型网络公司应聘时的笔试题目附答案 一、考题解析 这个考题是一道面试题,主要考察应聘者的数据结构和算法掌握情况。下面我们将具体分析考题。 1. 题目描述 给定一个数组,返回该数组中第k个最大的元素。要求时间复杂度O(n),n为数组的长度。 2. 解题思路 一个数组中的元素可以用最大堆来存储,最大堆可以用数组来模拟实现。假设数组为A,第一个元素为A[0],则…

    database 2023年5月22日
    00
  • 关于MySQL中的 like操作符详情

    当我们需要对数据库表中的某一列进行模糊匹配查询时,MySQL提供了LIKE操作符。 LIKE操作符是用来匹配字符串的,它和通配符结合使用可以实现对表中字符串的模糊查询。 以下是LIKE操作符的使用语法: SELECT column_name(s) FROM table_name WHERE column_name LIKE pattern; 其中,colum…

    database 2023年5月22日
    00
  • Oracle导出文本文件的三种方法(spool,UTL_FILE,sqluldr2)

    一、spool spool的基本语法是 spool file_name sql_command; spool off 2.其中file_name指需要导出的文件名,可以是全路径也可以是部分路径,sql_command为需要执行的sql语句。 运行示例如下: spool D:\test.txt /* 指定文件名 */ SELECT empno,ename,jo…

    database 2023年5月22日
    00
合作推广
合作推广
分享本页
返回顶部