drop table and Lock_open mutex
在Oracle中直接删除一张大表,会导致free extent 的enqueue,会导致buffer cache 的object purge,所以我们要有很多步骤,让删表变得不影响性能。
这方面MySQL目前没有好的方法。
MySQL中在对表进行drop table 命令,实际上调度的是mysql_rm_table_part2(sql/sql_table.cc)函数,其中有一段代码。
pthread_mutex_lock(&LOCK_open); ….. error= ha_delete_table(thd, table_type, path, db, table->table_name, …. pthread_mutex_unlock(&LOCK_open);
ha_delete_table 实际调用的是每个存储引擎对应的删除表的函数,这个函数不返回,LOCK_open 这个全局的mutex 要一直持有。
要知道LOCK_open是table_cache 的全局mutex,而任何和表相关的sql都会在open_table 这个函数中锁住这个全局的mutex,于是一个删表的操作会阻塞了所有的sql语句,碰到大表删除,show processlist 看到一堆的opening tables state。
同样的alter table 也会阻塞实例中所有的sql。
个人认为LOCK_open 这个全局的mutex粒度太粗了,应该细到每个表的table_cache上,这样drop、alter仅仅影响到该表的sql。
PS: MySQL 的worklog也提到了这个问题,说会在6.x改进。
hi,LOCK_open阻塞所有的sql,所有的sql中包括与这个表无关的查询/更新操作?
是的,所有要获得table_cache的sql,和哪张表无关
什么样的sql需要获取table_cache,我刚才试验了一下,alter table的时候对其他表的DML,DDL都没有被阻塞。
同样的alter table 也会阻塞实例中所有的sql。
alter table的时候会导致该表的更新操作被阻塞,书上说是因为添加了排他锁导致的。
这个和锁没关系,是全局的table_cache的获取。你能把过程帖出来吗?
过程(往下表示时间发展,横向表示同一个时间段发生的事情):
alter table1 modify column1 varchar(100)
……修改中 alter table2 modify/update table2/insert^
……修改中 完成
……修改中
另外:什么样的sql需要获取table_cache?这个概念还不是很清楚。