MySQL 怼了架构师关于 optimize table 需求 与 为什么反对 optimize table

2024年 1月 10日 32.2k 0

这开头还是介绍一下群,如果感兴趣PolarDB ,MongoDB ,MySQL ,PostgreSQL ,Redis, Oceanbase, Sql Server等有问题,有需求都可以加群群内,可以解决你的问题。加群请联系 liuaustin3 ,(共1830人左右 1 + 2 + 3 + 4 +5) 4群(360+ 关闭自由申请,新入群的将默认分配达到5群),另欢迎 OpenGauss 的技术人员加入。

2024年1月某些星象的原因,导致我个人的星盘在1月大概率要和某些人要有不愉快。这不就来了,在一次关于mysql 数据库数据表清理后,关于optimize table 的问题上,我毫无悬念的和架构师们进行了一次非常不nice 的沟通。

随意就有了此篇的文章,因为我这个人比较的要通过实际的情况来说明问题,而不是用权威来压制,那样没有品。事情简单的说一下,几十个库,几百张表,要进行数据的清理,这没有问题,我们会使用自动的手段来进行,而后面一个架构师提出,希望能对表进行optimize table 的操作,并且提出这样的好处多多。 

但是,但是,但是,说话办事就怕光站在自己的角度来说问题,我对此要求是拒绝的,并且我拿出了 PG SQL SERVER ORACLE 甚至 IBM DB2 的一些理论对于对方无礼的需求进行驳斥,因为这个架构师提出,optimize table 很快,MYSQL8 有新功能,大致的意思我翻译一下,optimize table 的任何过程中,不会对表产生影响,产生锁,产生业务影响。因为我们是 7*24小时的业务,所以DB 对于表在一些操作的中,是非常忌讳,产生TABLE LOCK 并且是无预估的长时间的表不可用的情况。 

那么我们来看看到底MYSQL8  是否如这个架构师讲的,很快不会对业务有什么影响。

我们使用一个,说新不新 ,说旧不旧的MySQL数据库版本,8.031 来验证MYSQL8 对这个optimize table 并没有多少改进。

mysql> select version();
+-----------+
| version() |
+-----------+
| 8.0.31    |
+-----------+
1 row in set (0.00 sec)

1 我们验证当数据库有事务在操作数据表时,是否会对optimize table 的命令产生影响,也就是之间的操作是互斥的。结果可以参见下图,必然是互相影响。optimize table 被  一个对表进行数据插入的事务卡主了。

mysql> select * from schema_table_lock_waitsG
*************************** 1. row ***************************
               object_schema: test
                 object_name: test
           waiting_thread_id: 71
                 waiting_pid: 7
             waiting_account: db_admin@mysql830
           waiting_lock_type: SHARED_NO_READ_WRITE
       waiting_lock_duration: TRANSACTION
               waiting_query: optimize table test
          waiting_query_secs: 1245
 waiting_query_rows_affected: 0
 waiting_query_rows_examined: 0
          blocking_thread_id: 81
                blocking_pid: 8
            blocking_account: db_admin@mysql830
          blocking_lock_type: SHARED_WRITE
      blocking_lock_duration: TRANSACTION
     sql_kill_blocking_query: KILL QUERY 8
sql_kill_blocking_connection: KILL 8
1 row in set (0.01 sec)



同时在genernal log 中跟踪相关操作,这里可以看到操作本身是没有分解操作的,原子性的语句进行传递,如有从库也会进行传递到从库执行。

在MySQL 8 中越来越智能的sys 库中的lock_waits 视图可以清晰的看到,optimize table 到底上了什么锁,,那么这个锁是什么这个锁属于metadata_locks 中的其中一种

INTENTION_EXCLUSIVE, SHARED, SHARED_HIGH_PRIO, SHARED_READ, SHARED_WRITE, SHARED_UPGRADABLE, SHARED_NO_WRITE, SHARED_NO_READ_WRITE, EXCLUSIVE
那么我们在执行了这个操作后,出现什么情况,从下面的图中可以清晰的看到,我们在一个就只有1行的数据表中,进行了optimize table 的操作,然后我们毫无悬念的发现在执行完毕这个命令后,表的文件的日期更新了,这里可以证明,在8.031 版本的mysql 中与我们之前MYSQL 的版本对于optimize table 的原理毫无实质的变化。


+-----------+----------+----------+-------------------------------------------------------------------+
| Table     | Op       | Msg_type | Msg_text                                                          |
+-----------+----------+----------+-------------------------------------------------------------------+
| test.test | optimize | note     | Table does not support optimize, doing recreate + analyze instead |
| test.test | optimize | status   | OK                                                                |
+-----------+----------+----------+-------------------------------------------------------------------+

mysql> select * from test;
+----+--------------+--------------+
| id | name         | title        |
+----+--------------+--------------+
|  1 | å°æŽ       | å°æŽ       |
+----+--------------+--------------+
1 row in set (0.00 sec)

[mysql@mysql830 test]$ ll -ah
total 3.4G
drwxr-x---  2 mysql mysql  190 Nov 17 12:58 .
drwxr-x--- 11 mysql mysql 4.0K Nov 17 12:38 ..
-rw-r-----  1 mysql mysql 112K Apr 14  2023 app_user_1000.ibd
-rw-r-----  1 mysql mysql 3.4G Apr 14  2023 app_user.ibd
-rw-r-----  1 mysql mysql 112K Nov 17 05:04 bm_card_account_recharge_
-rw-r-----  1 mysql mysql 144K Apr 15  2023 orders_copy.ibd
-rw-r-----  1 mysql mysql 160K Apr 15  2023 orders.ibd
-rw-r-----  1 mysql mysql 128K Apr 14  2023 payments.ibd
-rw-r-----  1 mysql mysql 112K Nov 17 12:35 read_table.ibd
-rw-r-----  1 mysql mysql 112K Nov 17 12:58 test.ibd
[mysql@mysql830 test]$ ll -ah
total 3.4G
drwxr-x---  2 mysql mysql  190 Nov 17 13:32 .
drwxr-x--- 11 mysql mysql 4.0K Nov 17 12:38 ..
-rw-r-----  1 mysql mysql 112K Apr 14  2023 app_user_1000.ibd
-rw-r-----  1 mysql mysql 3.4G Apr 14  2023 app_user.ibd
-rw-r-----  1 mysql mysql 112K Nov 17 05:04 bm_card_account_recharge_ext.ibd
-rw-r-----  1 mysql mysql 144K Apr 15  2023 orders_copy.ibd
-rw-r-----  1 mysql mysql 160K Apr 15  2023 orders.ibd
-rw-r-----  1 mysql mysql 128K Apr 14  2023 payments.ibd
-rw-r-----  1 mysql mysql 112K Nov 17 12:35 read_table.ibd
-rw-r-----  1 mysql mysql 112K Nov 17 13:32 test.ibd

当然同样的命令还有  alter table tablename force;和 alter table tablename engine=innodb;

那么我们来说说我们为什么要反对这个事情,

1 这么多数据库,这么多表,并且这些表其中有大表,操作这个部分的时间不可控,业务是不会等你操作完 optimize table 然后在去工作,他要anytime anywhere的运行,如果进行了optimize table DB 无法控制表不可用的时间,因为有些表里面N个索引,实际上这就是重建了一张表。然后改名的原子性操作。

2  操作具有风险性,如果此时由于大量运行optimize table 导致IOPS 上升,或者等待这些表的事务持续的等待,undo log 里面的数据无法及时进行purge,最终是否有可能导致数据库出现,基于探针判定主库不可用的问题,导致的数据库切换,这个问题的责任谁来负责。

3  一组数据库有从库,你的语句在此时会直接binlog 给从库,从库也会进行此操作,主库不可用,从库也不可用,并且统统的 UP ,到时我连切换的库都没有。(当然可以在执行时禁止BINLOG 传输此命令,避免从库一起来做相关的操作)

为什么要写此篇文章,因对一些开发人员和架构师的不负责任和缺乏职业素养的问题,非常憎恶。自己一句话,将别人至于尴尬和危险的境地,你于心何忍,你一句话别人要付出什么,这次我怼你算是轻的,下次我可以更狠,你以为做一个 DB 是光看看几篇文章就可以胜任的,笑话。

附群友的一些对此事的看法

另DB 人员自己也的打铁自身重,如果你技不压人,你就只能被人家压!

最后,下面是关于这块的代码,alter table table name  engine= innodb; 

    /// Set for ALTER [COLUMN] ... SET DEFAULT ... | DROP DEFAULT
    ALTER_CHANGE_COLUMN_DEFAULT = 1ULL 

相关文章

Oracle如何使用授予和撤销权限的语法和示例
Awesome Project: 探索 MatrixOrigin 云原生分布式数据库
下载丨66页PDF,云和恩墨技术通讯(2024年7月刊)
社区版oceanbase安装
Oracle 导出CSV工具-sqluldr2
ETL数据集成丨快速将MySQL数据迁移至Doris数据库

发布评论