Drop table 出现的问题

由于应用下线,需要把数据库中相关应用的表删除,库中有一千多张表,事先已经将所有的表rename到test库中,drop table的脚步也已经准备好,所以接下来的工作本以为是很轻松的事情,但是在执行脚本的过程中,发现删除表的速度感觉有点慢,查看主机的负载也在挺高的,报警消息中thread running过高也出现了,发现大多数线程的状态是Opening Tables,但还是勉强的忍受了过去,事后想想为什么删除表也会这么的慢?

在drop table的时候有几件事情需要去做:

对目标表加上write lock,然后在将数据文件,数据字典文件从存储引擎中删除,看似简单的两个工作,但为什么会这么长?下面的代码中展示了删除过程中的工作,在删除的过程中lock_open mutex会一直用于防止任何query来访问主表;同时在删除表数据文件,数据字典文件的时候由于文件系统的原因(ext3)导致大量的随机i/o,同样会使得删除变慢。

VOID(pthread_mutex_lock(&LOCK_open));

error= mysql_rm_table_part2(thd, tables, if_exists, drop_temporary, 0, 0);

pthread_mutex_unlock(&LOCK_open);

同时在删除表的过程中,由于innodb_file_per_table=1参数的打开,每个表有一个数据文件,而不是共享一个表空间,在drop table的时候,innodb必须检查LRU链表,把该链表上属于该表的page清除,如果该数据库的buffer pool设置的很大,花费在LRU搜索的时间开销将会很大,同时上千张不同的表打开,如果table_cache设置不当,则会将table_cache充满, mysql使用LRU算法将cache中的表清除,这个时候使得其他查询很有可能看上去被阻塞了,从而导致了性能上的下降。

同时innodb在打开每一张表的时候,还需要重新计算每张表的统计信息,如果有上千张的表,当采用innodb_file_per_table方式管理表的时候,这时候对磁盘i/o,cpu的要求也是很高的,这也是为什么mysql没有像oracle一样需要手动去收集表的的统计信息,而这个操作是串行的,不能够并行处理。

综上所述,drop table的速度受制于文件系统,lock,cache,LRU等诸多因素;上面一个很重要的因素是innodb_file_per_table=1参数打开,导致文件数量的增多,如果你现在的应用中使用的innodb表是经常需要创建,删除,那么将该参数innodb_file_per_table设置为0,使得所有的表共用一个表空间,那么对性能的提升无疑很明显的(10倍?)。

参考:

Performance problem with Innodb and DROP TABLE

Slow DROP TABLE

时间: 2024-09-11 21:55:43

Drop table 出现的问题的相关文章

[MySQL 源码] MySQL drop table(压缩表)效率与流程分析

 之前发生过一起连续drop压缩表,最后长时间等待信号量crash,线上alert log里的报错是: OS WAIT ARRAY INFO: reservation count 36647199, signal count 34050225 --Thread 1331538240 has waited at row0purge.c line 680 for 950.00 seconds the semaphore: S-lock on RW-latch at 0xe60b60 '&dict_o

MySQL · 引擎特性 · DROP TABLE之binlog解析

Drop Table的特殊之处 Drop Table乍一看,与其它DDL 也没什么区别,但当你深入去研究它的时候,发现还是有很多不同.最明显的地方就是DropTable后面可以紧跟多个表,并且可以是不同类型的表,这些表还不需要显式指明其类型,比如是普通表还是临时表,是支持事务的存储引擎的表还是不支持事务的存储引擎的表等.这些特殊之处对于代码实现有什么影响呢?对于普通表,无论是创建还是删除,数据库都会产生相应的binlog日志,而对于临时表来说,记录binlog日志就不是必须的.对于采用不同存储引

mysql执行drop table 数据恢复方法

对于MySQL数据库的innodb引擎的数据库中,由于误操作删除表,或者由于sqldump自动生成语句含drop table create table语句导致数据丢失,在没有覆盖的情况下,可以实现完美恢复创建测试表 mysql> CREATE TABLE recover.`t_drop` (     ->   `messageId` varchar(30) NOT NULL,     ->   `msgContent` varchar(1000) default NULL,     -&

bug#66718 Assert from DROP TABLE concurrent with ibuf merges

http://bugs.mysql.com/bug.php?id=66718 Assert from DROP TABLE concurrent with ibuf merges A.原因: master线程发起的ibuf merge和用户线程的drop table操作可能存在竞争. 1.master线程请求文件page IO,读入内存之前,会调用buf_page_init_for_read->fil_tablespace_deleted_or_being_deleted_in_mem 如果这时

为什么drop table 后数据还存在在数据字典中(10g 回收站已关闭)

问题描述 为什么drop table 后数据还存在在数据字典中(10g 回收站已关闭) 为什么drop table 后数据还存在在数据字典中(10g 回收站已关闭)?是否有等待?如何证明有堵塞?

MySQL · 特性分析 · drop table的优化

背景 系统为了加速对象的访问,通常都会增加一层缓存,以缓解下一层IO的瓶颈,OS的page cache和数据库的buffer pool都基于此. 但对象的删除,如果同步清理对象的缓存的话,不仅大大增加了延时,同时可能因为缓存过大导致IO blooding.所以针对缓存的清理,都会采用lazy drop的优化,下面我们就来对比下percona和官方针对drop table的lazy drop 优化. 假设使用innodb_file_per_table为表创建独立的tablespace,在业务处理过

Oracle10g 回收站及彻底删除table : drop table xx purge

drop后的表被放在回收站(user_recyclebin)里,而不是直接删除掉.这样,回收站里的表信息就可以被恢复,或彻底清除. 1.通过查询回收站user_recyclebin获取被删除的表信息,然后使用语句flashback table <user_recyclebin.object_name or user_recyclebin.original_name> to before drop [rename to <new_table_name>];   将回收站里的表恢复为原

SQL Server数据库的存储过程中定义的临时表,真的有必要显式删除(drop table #tableName)吗?

原文:SQL Server数据库的存储过程中定义的临时表,真的有必要显式删除(drop table #tableName)吗?   本文出处:http://www.cnblogs.com/wy123/p/6704619.html      问题背景 在写SQL Server存储过程中,如果存储过程中定义了临时表,有些人习惯在存储过程结束的时候一个一个显式地删除过程中定义的临时表(drop table #tName),有些人又没有这个习惯,对于不明真相的群众或者喜欢思考的人会问,存储过程中定义的临

利用硬链接和truncate降低drop table对线上环境的影响

作者简介 肖鹏 微博研发中心数据库技术负责人,主要负责微博数据库(MySQL/Reids/HBase/Memcached)相关的业务保障,性能优化,架构设计以及周边的自动化系统建设.10年互联网数据库架构和管理经验,专注于数据库的高性能和高可用技术保障方向. 众所周知drop table会严重的消耗服务器IO性能,如果被drop的table容量较大,甚至会影响到线上的正常. 首先,我们看一下为什么drop容量大的table会影响线上服务 直接执行drop table,mysql会将表定义和表数据