在线上truncate 了一张2000w 的表:

mysql [localhost:5724] {root} (test) > truncate table t1;
Query OK, 0 rows affected (1 min 37.19 sec)

 

发现全局系统都慢了一下,processlist 中发现truncate操作处于system lock

mysql [localhost:5724] {root} ((none)) > show processlist;
+--------+------+-----------+------+---------+------+-------------+-------------------+
| Id     | User | Host      | db   | Command | Time | State       | Info              |
+--------+------+-----------+------+---------+------+-------------+-------------------+
| 104077 | root | localhost | test | Query   |   54 | System lock | truncate table t1 |
| 104078 | root | localhost | NULL | Query   |    0 | starting    | show processlist  |
+--------+------+-----------+------+---------+------+-------------+-------------------+
2 rows in set (0.03 sec)


mysql [localhost:5724] {root} ((none)) > show processlist;
+--------+------+-----------+------+---------+------+-------------+-------------------+
| Id     | User | Host      | db   | Command | Time | State       | Info              |
+--------+------+-----------+------+---------+------+-------------+-------------------+
| 104077 | root | localhost | test | Query   |   60 | System lock | truncate table t1 |
| 104078 | root | localhost | NULL | Query   |    0 | starting    | show processlist  |
+--------+------+-----------+------+---------+------+-------------+-------------------+
2 rows in set (0.00 sec)

mysql [localhost:5724] {root} ((none)) > show processlist;
+--------+------+-----------+------+---------+------+-------------+-------------------+
| Id     | User | Host      | db   | Command | Time | State       | Info              |
+--------+------+-----------+------+---------+------+-------------+-------------------+
| 104077 | root | localhost | test | Query   |   61 | System lock | truncate table t1 |
| 104078 | root | localhost | NULL | Query   |    0 | starting    | show processlist  |
+--------+------+-----------+------+---------+------+-------------+-------------------+
2 rows in set (0.00 sec)

 

关于 System lock 官方的解释,

The thread has called mysql_lock_tables() and the thread state has not been updated since. This is a very general state that can occur for many reasons.

For example, the thread is going to request or is waiting for an internal or external system lock for the table. This can occur when InnoDB waits for a table-level lock during execution of LOCK TABLES. If this state is being caused by requests for external locks and you are not using multiple mysqld servers that are accessing the same MyISAM tables, you can disable external system locks with the --skip-external-locking option. However, external locking is disabled by default, so it is likely that this option will have no effect. For SHOW PROFILE, this state means the thread is requesting the lock (not waiting for it).

关于system lock 的解释官方说明也是不够多,核心就是表锁,也就是在drop 操作时申请的表锁

 

#####
https://dev.mysql.com/doc/refman/5.7/en/truncate-table.html


mysql drop 操作的原理:
Truncate operations drop and re-create the table, It requires the DROP privilege.

mysql 5.7 如果有大bp 情况下,truncate table 会导致性能临时骤降,mysql 5.7 的truncate 操作在业务期间需要极其谨慎啊
On a system with a large InnoDB buffer pool and innodb_adaptive_hash_index enabled, 
TRUNCATE TABLE operations may cause a temporary drop in system performance due to an LRU scan that occurs
 when removing an InnoDB table's adaptive hash index entries.
  The problem was addressed for DROP TABLE in MySQL 5.5.23 (Bug #13704145, Bug #64284) 
  but remains a known issue for TRUNCATE TABLE (Bug #68184)

 

 

##Kind of problems seen in previous MySQL Server versions

During tablespace deletion and truncation one of the steps was to purge the buffer pool of the pages used by the deleted/truncated tablespace. The bigger the buffer pool the more pages it had to traverse and hold internal latches for longer, which would impact the foreground/query threads, this is what caused the stalls. Any parallel DML transaction needed to wait for this internal structure update to finish, before continuing its own work. This effectively was causing the Server to stall for multiple seconds or more, which was very painful on huge Buffer Pools that had multiple hundreds of GB of memory assigned.
What is important, the length of the stall does not relate to size of the deleted tablespace. Deleting large or small, even empty tablespace would stall the server for the same time because the entire buffer pool had to be traversed to check for stale pages.

 

The size of the LRU list and Flush list that needed to be updated in previous versions can be checked with the following query:

1

SELECT sum(pool_size)*16/1024/1024 as "BP size in GB", sum(modified_database_pages) as "flush list size", sum(database_pages) as "LRU list size" FROM INFORMATION_SCHEMA.INNODB_BUFFER_POOL_STATS;

 

Logo

腾讯云面向开发者汇聚海量精品云计算使用和开发经验,营造开放的云计算技术生态圈。

更多推荐