更新时间:2024-11-20 GMT+08:00
分享

DDL工具测试对比

测试步骤

  1. 创建4张表,表结构如下:
    CREATE TABLE if not exists users
    	(
    	 `rid` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
    	  `nid` bigint(20) DEFAULT NULL,
    	  `level` int(11) DEFAULT NULL,
    	  `vip` int(11) DEFAULT NULL,
    	  `vip_exp` int(11) DEFAULT NULL,
    	  `reg_channel` int(11) DEFAULT NULL,
    	  `guild_id` bigint(20) unsigned DEFAULT '0',
    	  `guild_open` tinyint(1) DEFAULT '0',
    	  `forbid_login_time` bigint(20) DEFAULT NULL,
    	  `forbid_talk_time` bigint(20) DEFAULT NULL,
    	  `ctime` bigint(20) DEFAULT NULL,
    	  `mtime` datetime(3) DEFAULT NULL,
    	  `last_offline_time` bigint(20) DEFAULT NULL,
    	  `friend_open` tinyint(1) DEFAULT '0',
    	  `user_data_str` mediumblob,
    	  `name` varchar(64) DEFAULT NULL,
    	  `db_fix_version` int(10) DEFAULT '0',
    	  PRIMARY KEY (`rid`),
    	  KEY `idx_users_99_nid` (`nid`),
    	  KEY `idx_users_99_level` (`level`),
    	  KEY `idx_users_99_ctime` (`ctime`),
    	  KEY `idx_users_99_mtime` (`mtime`),
    	  KEY `idx_users_99_last_offline_time` (`last_offline_time`),
    	  KEY `idx_users_99_name` (`name`)
    	) ENGINE=InnoDB AUTO_INCREMENT=4393751571200 DEFAULT CHARSET=utf8mb4;
  2. 分别给每张表插入3000万行数据。
  3. 使用MySQL原生copy算法在表1中添加一列,并在执行过程中建立新会话执行select,update,insert操作10万条数据。
  4. 使用MySQL原生inplace算法在表2添加一列,并在执行过程中建立新会话执行select,update,insert操作10万条数据。
  5. 使用gh-ost工具在表3中添加一列,并在执行过程中建立新会话执行select,update,insert操作10万条数据。
  6. 记录DDL和DML语句执行时间。
表1 测试数据(单位:s)

执行操作

MySQL Copy

MySQL Inplace

gh-ost

增加一列

1294.29

755.52

1876.79

select

1.35

1.29

1.29

update

1266.78

0.19

0.11

insert

1296.19

7.47

4.49

测试结果

  1. MySQL原生copy算法:update、insert执行会阻塞,select语句可以正常执行。
  2. MySQL原生inplace算法:不会长时间阻塞DML语句,且对大表添加一列耗时最短。
  3. gh-ost工具:几乎不阻塞DML语句,DDL添加一列耗时比MySQL原生的两种算法时间长。

算法使用建议

采用Inplace算法进行DDL操作时阻塞DML的时间很短,对主从时延无严格要求的客户,推荐直接使用社区已有能力快速完成表结构变更。对主从复制延迟容忍较低的业务,推荐使用gh-ost工具来完成DDL操作。使用了MySQL 8.0.12版本及以上的用户,当满足instant算法条件时,可指定使用instant来减少DDL操作对业务的影响。

相关文档