我的编程空间,编程开发者的网络收藏夹
学习永远不晚

案例 - optimize table 的一些坑

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

案例 - optimize table 的一些坑

线上IM消息的数据库,磁盘空间使用率已到达96%


  1. 没申请到扩容的新机器,无法做数据库迁移

  2. 保留的是全量聊天记录,一条都不许删


在这种场景下,为了减少空间容量,只能对表做碎片整理来释放空间, optimize table


当我们使用mysql进行delete数据,delete完以后,发现空间文件ibd并没有减少,这是因为碎片空间的存在,举个例子,一共公司有10号员工,10个座位,被开除了7个员工,但这些座位还是保留的,碎片整理就像,让剩下的3个员工都靠边坐,然后把剩下的7个作为给砸掉,这样就能释放出空间了


OPTIMIZE TABLE reorganizes the physical storage of table data and associated index data, to reduce storage space and improve I/O efficiency when accessing the table. 

好处除了减少表数据与表索引的物理空间,还能降低访问表时的IO,这个比较理解,整理之前,取数据需要跨越很多碎片空间,这时需要时间的,整理后,想要的数据都放在一起了,直接拿就拿到了,效率提高


拿一张大表做碎片整理,整理之前是96G

[root@localhost myshard]# du -ch tbl_immsg_bigo_96.ibd |grep total
3.5G    total


当执行命令时

optimise table tbl_immsg_bigo_96;


整理完后,剩下2.9G

myshard> optimize no_write_to_binlog table tbl_immsg_bigo_96;
+---------------------------+----------+----------+-------------------------------------------------------------------+
| Table                     | Op       | Msg_type | Msg_text                                                          |
+---------------------------+----------+----------+-------------------------------------------------------------------+
| myshard.tbl_immsg_bigo_96 | optimize | note     | Table does not support optimize, doing recreate + analyze instead |
| myshard.tbl_immsg_bigo_96 | optimize | status   | OK                                                                |
+---------------------------+----------+----------+-------------------------------------------------------------------+
2 rows in set (3 min 21.66 sec) 

[root@localhost myshard]# du -ch tbl_immsg_bigo_96.ibd |grep total
2.9G    total



整理期间会有很多慢查询的告警,在告一个waiting for table metadata lock的状态


ID: 121                                                  

USER: db_myshard_rw                                            

HOST: 127.0.0.1:56326                                         

DB: myshard                                               

COMMAND: Execute                                                

TIME: 1214                                                  

STATE: Waiting for table metadata lock                                

INFO: insert into myshard.tbl_immsg_bigo_0 (touid,fromuid,fromseqid,appid


案例 - optimize table 的一些坑


这是因为optimize table的本质,是alter table


mysql 5.5 的改表过程如下

1.创建一张新的临时表 tmp 

2.把旧表锁住,禁止插入删除,只允许读写 (这就是为什么上面的insert语句都停留在waiting for table metadata lock)

3.把数据不断的从旧表,拷贝到新的临时表,(这就是上面报copy to tmp table)

4.等表拷贝完后,进行瞬间的rename操作

5.旧表删除掉


所以optimize最大的问题是锁表,锁表会导致insert,delete,update语句堵住,上面等待了1214秒,还在继续,所以第一个结论:在使用optimize table的时候,确保不要有任何dml语句,确保业务切走,否则可能会出事故


为什么要锁表呢?

alter过程里,数据不停从旧表拷贝到新表,如果这个时候旧表被delete了数据了,那旧表与新表的数据就不一致了,到最后rename 新表 to 旧表表名 时候,数据量就多了


如果在拷贝数据的过程中,对旧表数据的delete,同时对新表也做delete,那数据就一致了,对于update和insert也一样,这个功能可以通过 insert触发器,delete触发器,update触发器实现


pt-online-schema-change就利用3个触发器完成在线改表,也能完成在线碎片整理,命令使用 

--alter="ENGINE=InnoDB"


相当于optimize table的效果


具体命令如下,最好放在脚本里面实现,因为一次不止整理一个表,可以把整个数据库的表都碎片整理

 pt-online-schema-change  
  -h地址
  -P端口号
  -u用户名
  -p密码   
  --database=数据库
  t=表名字
  --charset=utf8 
  --max-lag=300 
  --check-interval=5 
  --alter="ENGINE=InnoDB" 
  --max-load="Threads_running:400" 
  --critical-load="Threads_running:400" 
  --nocheck-replication-filters 
  --alter-foreign-keys-method=auto  
  --execute


使用pt-online-schema-change可以跳过锁表的坑




为了保持两张表的数据一致性,拷贝的那部分数据需要上锁,使用共享锁share_mode来锁行,可以通过show full processlist看到一次大概对10万行,每次拷贝1秒不到


 INSERT LOW_PRIORITY IGNORE INTO `myshard`.`_tbl_immsg_bigo_128_new` (`sid`, `tm_timestamp`, `tm_lasttime`, `gid`, `group_name`, `default_flag`, `group_attr`, `group_owner`, `group_extension`, `is_del`, `app_id`, `mic_seat`, `invite_perm`, `invite_media_perm`, `pub_id_search`, `apply_verify`, `public_id`, `introduc`, `family_id`, `__version`, `__deleted`) SELECT `sid`, `tm_timestamp`, `tm_lasttime`, `gid`, `group_name`, `default_flag`, `group_attr`, `group_owner`, `group_extension`, `is_del`, `app_id`, `mic_seat`, `invite_perm`, `invite_media_perm`, `pub_id_search`, `apply_verify`, `public_id`, `introduc`, `family_id`, `__version`, `__deleted` FROM `myshard`.`tbl_immsg_bigo_128` FORCE INDEX(`PRIMARY`) WHERE ((`sid` >= '2112908055')) AND ((`sid` <= '2112916949')) LOCK IN SHARE MODE



本来使用碎片整理是因为磁盘使用率96%,但碎片整理时发现磁盘使用率变成99%,差点就爆了

Filesystem      Size  Used Avail Use% Mounted on
/dev/sda2        58G  2.7G   53G   5% /
tmpfs         24G     0   24G   0% /dev/shm
/dev/sda1       485M   32M  428M   7% /boot
/dev/sda5       1.6T  452G  1.1T  31% /data
/dev/sdb1       1.3T  1.2T   25G  99% /data1


这是因为在把旧表拷贝到临时表的时,会把表数据复制一份数据,10G的表,可能复制出来是7G,这个过程磁盘会快速消耗,不小心就会把磁盘撑满造成数据丢失了


为了避免这个坑,应该把整个数据库的表,按照体积从小到大排序,并且把索引文件,表结构去掉,为了方便显示出体积,这里加了一个l参数,实际上是不加的,只获取表名字,然后重定向一个文件里,碎片整理就按照这个顺序

ls -lSr --ignore="*.frm"
-rw-rw---- 1 mysql mysql   4096 Jul 25 12:33 tables_priv.MYI
-rw-rw---- 1 mysql mysql   4096 Jul 25 12:33 procs_priv.MYI
-rw-rw---- 1 mysql mysql   4096 Jul 25 12:33 columns_priv.MYI
-rw-rw---- 1 mysql mysql   5120 Jul 25 12:33 proxies_priv.MYI
-rw-rw---- 1 mysql mysql   5120 Jul 25 12:43 db.MYI
-rw-rw---- 1 mysql mysql   8928 Jul 25 12:33 help_relation.MYD
-rw-rw---- 1 mysql mysql  16384 Jul 25 12:33 help_keyword.MYI
-rw-rw---- 1 mysql mysql  18432 Jul 25 12:33 help_relation.MYI
-rw-rw---- 1 mysql mysql  20480 Jul 25 12:33 help_topic.MYI
-rw-rw---- 1 mysql mysql  22078 Jul 25 12:33 help_category.MYD
-rw-rw---- 1 mysql mysql  89241 Jul 25 12:33 help_keyword.MYD
-rw-rw---- 1 mysql mysql 419392 Jul 25 12:33 help_topic.MYD


可以写一个脚本,统计每个表整理的时间,整理前后的体积比较,效果如下


正在对表tbl_immsg_bigo_128进行碎片整理...第9张,还剩93张
+----------------------------+----------+----------+-------------------------------------------------------------------+
| Table                      | Op       | Msg_type | Msg_text                                                          |
+----------------------------+----------+----------+-------------------------------------------------------------------+
| myshard.tbl_immsg_bigo_128 | optimize | note     | Table does not support optimize, doing recreate + analyze instead |
| myshard.tbl_immsg_bigo_128 | optimize | status   | OK                                                                |
+----------------------------+----------+----------+-------------------------------------------------------------------+
表:tbl_immsg_bigo_128, 整理前:3373M, 整理后:2729M, 节省空间:-644M,耗时:143秒
----------------------------------------------------------------------------------------------
正在对表tbl_immsg_bigo_132进行碎片整理...第10张,还剩92张
+----------------------------+----------+----------+-------------------------------------------------------------------+
| Table                      | Op       | Msg_type | Msg_text                                                          |
+----------------------------+----------+----------+-------------------------------------------------------------------+
| myshard.tbl_immsg_bigo_132 | optimize | note     | Table does not support optimize, doing recreate + analyze instead |
| myshard.tbl_immsg_bigo_132 | optimize | status   | OK                                                                |
+----------------------------+----------+----------+-------------------------------------------------------------------+
表:tbl_immsg_bigo_132, 整理前:3541M, 整理后:2889M, 节省空间:-652M,耗时:153秒


全部表整理完以后,96%的空间,碎片整理完后变成85%,腾出130G的空间


免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

案例 - optimize table 的一些坑

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

mybatis-plus QueryWrapper排序的坑案例分析

这篇文章主要介绍了mybatis-plus QueryWrapper排序的坑案例分析的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇mybatis-plus QueryWrapper排序的坑案例分析文章都会有所收
2023-06-29

解决element-uiel-checkbox的一些坑

这篇文章主要介绍了解决element-uiel-checkbox的一些坑,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
2023-05-16

使用RxJava中遇到的一些”坑“

前言大家越用RxJava,越觉得它好用,所以不知不觉地发现代码里到处都是RxJava的身影。然而,RxJava也不是银弹,其中仍然有很多问题需要解决。这里,我简单地总结一下自己遇到的一些“坑”,内容上可能会比较松散。一、考虑主线程的切换Rx
2023-05-31

iOs迁至WKWebView跨过的一些坑

前言在iOS中有两种网页视图可以加载网页除了系统的那个控制器。一种是UIWebView,另一种是WKWebView,其实WKWebView就是想替代UIWebView的,因为我们都知道UIWebView非常占内存等一些问题,但是现在很多人还
2022-05-25

Android WebView使用的技巧与一些坑

随着手机性能的提高,以及iOS和Android两个平台的普及,更多的App都会选择两个平台的App都进行开发,在有些时候,为了更加快速的开发,我们会采用hybird方式开发,这个时候我们需要使用webview并且自己进行一些配置。Andro
2022-06-06

vant3中使用List组件的一些坑

这篇文章主要介绍了vant3中使用List组件的一些坑及解决,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
2023-01-18

Vueel-table默认展开某一行的实例

这篇文章主要介绍了Vueel-table默认展开某一行的实例,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
2022-11-13

go中make用法及常见的一些坑

golang分配内存主要有内置函数new和make,下面这篇文章主要给大家介绍了关于go中make用法及常见的一些坑,文中通过示例代码介绍的非常详细,需要的朋友可以参考下
2022-12-26

Android中使用LayoutInflater要注意的一些坑

前言在平时的开发过程中,我们经常会用LayoutInflater这个类,比如说在Fragment$onCreateView和RecyclerView.Adapter$onCreateViewHolder中都会用到。它的用法也无非就是Layo
2023-05-31

编程热搜

目录