Chinaunix首页 | 论坛 | 博客
  • 博客访问: 660434
  • 博文数量: 66
  • 博客积分: 15
  • 博客等级: 民兵
  • 技术积分: 2204
  • 用 户 组: 普通用户
  • 注册时间: 2010-10-26 21:43
个人简介

曾就职于阿里巴巴担任Oracle DBA,MySQL DBA,目前在新美大担任SRE。[是普罗米修斯还是一块石头,你自己选择!] 欢迎关注微信公众号 “自己的设计师”,不定期有原创运维文章推送。

文章分类

全部博文(66)

文章存档

2017年(2)

2016年(3)

2015年(7)

2014年(12)

2013年(42)

分类: Mysql/postgreSQL

2014-10-28 10:36:24

 最近,一个同事因为有数百表已经废弃,所以打算将表drop掉已回收掉使用的空间。其实每张表的数据量很小,但是我们看到每次drop的时候大量的query 被堵塞了,用户反映超时报错的情况,所以这里对这个问题做了一个小的探讨(本帖的讨论基于mysql5.1) 。  
  由于product 环境大部分情况下设置的innodb_file_per_table=1,所以每个table一个tbs,每次删除表都要对物理文件.ibd进行delete。由于要删除物理文件,所以该物理文件对应的dirty page也要clean掉。所以这个时候,innodb触发了两个操作:

1.调用buf_LRU_invalidate_tablespace 遍历buffer pool LRU list,将所有space id为该表的page flush 到disk,并将该page移动到buffer pool LRU list 的尾端。
2. buf_LRU_invalidate_tablespace 会调用buf_LRU_block_remove_hashed_page 将该表对应的AHI(adaptive hash index) destory掉。


但上述的操作会调用一个global buffer pool mutex,避免在invalidate或者drop过程中,page发生移位(page是随时随地在变动的),防止page被遗漏。
在目前公司的生产环境中,buffer pool为40G左右,~2M的pages存在BP中,每个LRU list scan大概0.5s,单张表的操作大概就会有1s时间在scan LRU list.所以在线上库删除废弃的table,如果涉及上百/上千张表,就可能导致长时间不可用状态 。

facebook mark给出了几个可以缓解这个行为带来后果的建议

1.通过一个flush list来记录那些dirty page(通过引入buf_LRU_remove_dirty_pages_for_tablespace函数来实现),这样每次调用buf_LRU_invalidate_tablespace只需要scan flush list即可,由于flush list相比buffer pool LRU list小很多,所以每次操作持有mutex的时间会短很多。
2.每次一个batch(1024个page)来操作,操作后sleep 一段时间,然后下次继续,只到该操作完成为止。


当然对与AHI的destroy这里并没有进行更详细的优化。


所以对目前的现状,如果为了不影响业务,建议drop table 先rename掉,然后在低峰时段+sleep的方式回收 。
阅读(3384) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~