MYSQL 毛病那么多,optimize table 为什么做不了

开头还是介绍一下群,如果感兴趣PolarDB ,MongoDB ,MySQL ,PostgreSQL ,Redis, Oceanbase, Sql Server等有问题,有需求都可以加群群内有各大数据库行业大咖,CTO,可以解决你的问题。加群请联系 liuaustin3 ,(共2150人左右 1 + 2 + 3 + 4 +5) 新人直接分配到5群,另欢迎 OpenGauss 的技术人员加入。

1915557ce5457fea9ac2c36115a7875f.png

MySQL 在数据增长中,会遇到一个问题数据在清理后,无法将数据表空间回收,大多数的人员在处理这个问题的时候,可以通过optimize table 的方案来解决.

CREATE TABLE `test` (
  `id` int NOT NULL AUTO_INCREMENT,
  `name` varchar(50) COLLATE utf8mb4_general_ci DEFAULT NULL,
  `empid` int DEFAULT NULL,
  PRIMARY KEY (`id`),
  UNIQUE KEY `name` (`name`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci
optimize table test.test;
+-----------+----------+----------+-------------------------------------------------------------------+
| Table     | Op       | Msg_type | Msg_text                                                          |
+-----------+----------+----------+-------------------------------------------------------------------+
| test.test | optimize | note     | Table does not support optimize, doing recreate + analyze instead |
| test.test | optimize | status   | OK                                                                |
+-----------+----------+----------+-------------------------------------------------------------------+
2 rows in set (0.03 sec)

但在某些情况下,optimize table 的操作会遇到失败的情况,而引起这个问题的主要原因是,数据表中有唯一索引,而具备唯一索引的表,正在出入重复的数据时,导致的optimize table 的执行错误。

通过存储过程我们插入数据,在此同时我们写另一个存储过程不断的往test表中插入重复的数据,持续的插入,然后我们在另一个连接中,持续的运行optimize table。

mysql: [Warning] Using a password on the command line interface can be insecure.
+-----------+----------+----------+-------------------------------------------------------------------+
| Table     | Op       | Msg_type | Msg_text                                                          |
+-----------+----------+----------+-------------------------------------------------------------------+
| test.test | optimize | note     | Table does not support optimize, doing recreate + analyze instead |
| test.test | optimize | error    | Duplicate entry '100' for key 'test.name'                         |
| test.test | optimize | status   | Operation failed                                                  |
+-----------+----------+----------+-------------------------------------------------------------------+
mysql> delimiter //
mysql> CREATE PROCEDURE dotest()
    -> BEGIN
    -> DECLARE i INT DEFAULT 1;
    -> WHILE (i <= 2000000) DO
    -> INSERT INTO `test` (id, name, empid) values (i, i, i);
    -> SET i = i+1;
    -> END WHILE;
    -> END
    -> //
Query OK, 0 rows affected (0.01 sec)

mysql> delimiter ;
mysql> call dotest();

上图中可以看到在optimize table 的时候,有报错信息,其中在操作失败前面,会提示Duplicate entry 操作,然后operation failed。

简单解释是因为,在optimize table 操作时会对唯一索引进行重新的整理,并且重新生成索引会对数据进行检查,当插入重复数据的时候,无法满足唯一约束条件,而导致OT操作失败。

运行DDL操作时,运行ALTER TABLE或optimize table语句的线程会应用来自其他连接线程并发运行在相同表上的DML操作的在线日志。当应用DML操作时,可能会遇到重复键条目错误(ERROR 1062 (23000):Duplicate entry),即使重复条目只是临时的,并且稍后会被在线日志中的另一个条目回滚。这类似于InnoDB中的外键约束检查的概念,约束必须在事务期间保持。

同样更换了 alter table engine=innodb; 产生的结果是一致的,都是无法进行。

8646aa4f696373223eace5b769a9874c.png

3ca58cf32c511ecd3d62b3675d991ad2.png

  • 4
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值