MySQL Flush导致的等待问题tables 参数关闭所有打开的表,同时该操作将会清空查询缓存中的内容

FLUSH TABLES WITH READ LOCK   关闭所有打开的表,同时对于所有数据库中的表都加一个读锁,

直到显示地执行unlock tables,该操作常常用于数据备份的时候。

链接:http://wangqiaowqo.iteye.com/blog/1627985

前言

在实际生产环境中有时会发现大量的sql语句处于waiting for table.. 状态中,有时候看起来会让人觉得困惑,本文将讲解此状态产生的原因及解决办法。

正文

本文中用到了lock table来模拟实际情况, 首先介绍一个lock tables需要注意的事项,如果在一个session中使用了lock tables,那么在此session中将只能访问获取到lock的表。官方解释:

If the LOCK TABLES statement must wait due to locks held by other sessions on any of the tables, it blocks until all locks can be acquired.

A session that requires locks must acquire all the locks that it needs in a single LOCK TABLES statement. While the locks thus obtained are held, the session can access only the locked tables. For example, in the following sequence of statements, an error occurs for the attempt to access t2 because it was not locked in the LOCK TABLES statement:

Tables in the INFORMATION_SCHEMA database are an exception. They can be

accessed without being locked explicitly even while a session holds

table locks obtained with LOCK TABLES.

基于这样的原因,往往在备份时选择flush table with read lock;是个不错的选择,如果成功,它会锁住所有表。

Closes all open tables, forces all tables in use to be closed, and

flushes the query cache. FLUSH TABLES also removes all query results

from the query cache, like the RESET QUERY CACHE statement.

模拟Flush操作导致的waiting tables等待问题。

a) 在终端1中执行lock table锁住jackjhu库中的一张表

mysql> lock table t1 read;

Query OK, 0 rows affected (0.00 sec)

b) 在终端2中执行flush tables

mysql> flush tables;       --无返回,被阻塞..

c) 此时终端3欲连接到jackjhu库,如果mysql连接时没有使用-A,将出现阻塞。

mysql> use jackjhu

Reading table information for completion of table and column names

You can turn off this feature to get a quicker startup with -A

--无返回,被阻塞

重新使用-A选项连接终端3执行select jackjhu库中表t1,阻塞。

mysql> select * from t1;      --无返回,被阻塞..

d) 新建终端4,使用-A选项连接mysql,到jackjhu库中查询其他表 --无返回,被阻塞..

mysql> select * from t2;

+----+---------+

| id | name    |

+----+---------+

|  5 | mysql   |

|  6 | test    |

+----+---------+

2 rows in set (0.01 sec)

退出终端,重新使用不带-A选项连接mysql,选中jackjhu。

mysql> use jackjhu

Reading table information for completion of table and column names

You can turn off this feature to get a quicker startup with -A

--无返回,被阻塞..

查看现在的线程情况,并分析阻塞的原因。

mysql> show full processlist;

+----+------+-----------+---------+------------+------+-------------------------+-----------------------+

| Id | User | Host      | db      | Command    | Time | State                   | Info                  |

+----+------+-----------+---------+------------+------+-------------------------+-----------------------+

|  2 | root | localhost | jackjhu | Query      |    0 | init                    | show full processlist |

|  3 | root | localhost | jackjhu | Query      |   33 | Waiting for table flush | flush tables          |

|  7 | root | localhost | jackjhu | Query      |   20 | Waiting for table flush | select * from t1      |

| 12 | root | localhost | jackjhu | Field List |   10 | Waiting for table flush |                       |

+----+------+-----------+---------+------------+------+-------------------------+-----------------------+4 rows in set (0.00 sec)首先查看waiting for table ..的官方解释:

The thread got a notification that the underlying structure for a table has changed and it needs to reopen the table to get the new structure. However, to reopen the table, it must wait until all other threads have closed the table in question.

This notification takes place if another thread has used FLUSH TABLES or one of the following statements on the table in question: FLUSH TABLES tbl_name, ALTER TABLE, RENAME TABLE, REPAIR TABLE, ANALYZE TABLE, orOPTIMIZE TABLE.

分析

ID 3:终端2,由于t1被终端1锁住(lock table t1 read),flush操作中需要刷新表t1缓冲并关闭表,被阻塞,表被锁无法关闭。

ID:6:终端3,查询t1表的内容,由于查询前有flush操作,flush操作会发出表需要被重新打开的信号。终端3的查询需要重新打开t1表,显然也被阻塞,由我们上面的实验知道,打开其他没有被锁定的表是可以的,他们已经完成flush并可以被打开。

不使用-A连接mysql,被阻塞。线程状态:Field List。解释:

The thread is retrieving information for table columns.

由于表t1需要被reopen阻塞,所以这里也被阻塞。

从show full processlist这个表象上看,好像是flush tables引起的问题,其实问题的根源在于这个操作被阻塞,也就是表t1被锁住,或无法释放被关闭。

发生条件:同样ALTER TABLE, RENAME TABLE, REPAIR TABLE, ANALYZE TABLE,  OPTIMIZE TABLE等操作也会出现这样的问题,这面是实验结果。

条件1:lock table t1 read

repair table, alter table(create index…),rename table,optimize table

以上操作和之后的select出现 Waiting for table metadata lock

analyze table t1操作正常,但是后面的select出现 Waiting for table metadata lock

--无field List锁

条件2:lock table t1 write

仅仅说一下和条件1中情况不同的,其他一样。

analyze table

以上操作和之后的select出现 Waiting for table metadata lock

--无field List锁

注意这里使用了lock table .. read简单的进行了模拟,实际上生产环境中大多数是由于长查询,导致flush table一直等待无法关闭该表导致。

MySQL Flush操作的bug

现象:如上文模拟的情况,如果在生产环境中发现waiting for table flush,阻塞了大量的sql。这时候为了解决问题,kill掉flush tables这个操作,这并不能解决问题, 需要reopen的标记依然会存在而没有被清除,后面的select依然没能被继续。

MySQL Bug:       http://bugs.mysql.com/bug.php?id=44884

出现waiting for table.. 的解决办法

找到阻塞FLUSH TABLES, ALTER TABLE, RENAME TABLE, REPAIR TABLE, ANALYZE TABLE, OPTIMIZE TABLE等操作的源头,或许是lock table操作和有表锁,或许是一个长长的查询(可以从proceelist的time列找到),总之,我们可以很容易定位到哪张表引起的问题,再去定位sql语句,从这个方向去思考,可以比较容易的解决这样的问题。

最后看看flush tables with read lock的行为,先看看官方解释:

Closes all open tables and locks all tables for all databases with a global read lock.

关闭打开的表。

mysql> flush table with read lock;

Query OK, 0 rows affected (0.00 sec)

mysql> show global status like ‘%open%‘;

+--------------------------+-------+

| Variable_name            | Value |

+--------------------------+-------+

| Com_ha_open              | 0     |

| Com_show_open_tables     | 0     |

| Open_files               | 7     |

| Open_streams             | 0     |

| Open_table_definitions   | 0     |       --表结构文件被关闭

| Open_tables              | 0     |       --表被关闭

| Opened_files             | 561   |

| Opened_table_definitions | 101   |

| Opened_tables            | 101   |

| Slave_open_temp_tables   | 0     |

+--------------------------+-------+

10 rows in set (0.00 sec)

给mysql全局的读锁。

mysql> flush table with read lock;

Query OK, 0 rows affected (0.00 sec)

mysql> show global status like ‘%open%‘;

+--------------------------+-------+

| Variable_name            | Value |

+--------------------------+-------+

| Com_ha_open              | 0     |

| Com_show_open_tables     | 0     |

| Open_files               | 7     |

| Open_streams             | 0     |

| Open_table_definitions   | 0     |

| Open_tables              | 0     |

| Opened_files             | 561   |

| Opened_table_definitions | 101   |

| Opened_tables            | 101   |

| Slave_open_temp_tables   | 0     |

+--------------------------+-------+

10 rows in set (0.00 sec)

对于写入操作近些阻塞,写入操作被锁等待

mysql> insert into t3 values(3,‘uncommit‘);--无返回,等待,processlist中状态如下:

|Query   |    37 | Waiting for global read lock                                                  | insert into t3 values(3,‘uncommit‘) |

如果事务在flush with read lock前已经有数据写入,但是还没有提交,此时提交的话也会被阻塞。

Query   |     3 | Waiting for commit lock                                                       | commit

转载:http://bubuko.com/infodetail-254680.html

flush table mysql_MySQL flush table 导致的锁问题相关推荐

  1. mysql关于FLUSH TABLES和FLUSH TABLES WITH READ LOCK的理解

    总结 1.FLUSH TABLES关闭所有打开的表,强制关闭所有正在使用的表,并刷新查询缓存和预准备语句缓存,不会刷新脏块 2.FLUSH TABLES WITH READ LOCK关闭所有打开的表并 ...

  2. mysql ddl 锁_MySQL Online DDL导致全局锁表案例分析

    MySQL Online DDL导致全局锁表案例分析 我这边遇到了什么问题? 线上给某个表执行新增索引SQL, 然后整个数据CPU打到100%, 连接数暴增到极限, 最后导致所有访问数据库的应用都奔溃 ...

  3. R语言之read.table与write.table详解

    2019独角兽企业重金招聘Python工程师标准>>> ‍数据的各种形式 一般而言, 数据的每一行的不同元素可由tab键(txt文件), 逗号(csv文件), 空格等隔开. 另外, ...

  4. mysql中flush用法_mysql flush用法

    今天仔细看了下Flush语法,同时在工作中也经常使用Flush命令,在这儿汇总下.MySQL的FLUSH句法(清除或者重新加载内部缓存) FLUSH flush_option [,flush_opti ...

  5. mysql truncate 大表_MySQL删除大表时潜在的问题(drop table,truncate table)

    case1,删除大表时,因为清理自适应hash索引占用的内容导致的MySQL服务挂起 case2,大表的随意Drop或者truncate导致MySQL服务的挂起 按照本文中的结论就是 MySQL5.6 ...

  6. optimize table、analyze table、alter table、gh-ost

    MySQL系列 第一章:sql_mode模式 第二章:optimize table.analyze table.alter table.gh-ost 文章目录 MySQL系列 一.alter tabl ...

  7. mysql create table()_MySQL Create Table创建表

    表的创建命令需要: 表的名称 字段名称 定义每个字段(类型.长度等) 语法 下面是通用的SQL语法用来创建MySQL表: CREATE TABLE table_name (column_name co ...

  8. R语言使用table函数计算单分类变量的频率表(frequency table)、使用prop.table函数将table函数计算获得的频率表转化为比率表、返回单分类变量每一个类别的比率、或者百分比

    R语言使用table函数计算单分类变量的频率表(frequency table).使用prop.table函数将table函数计算获得的频率表转化为比率表.返回单分类变量每一个类别的比率.或者百分比. ...

  9. 怎么操作会导致MySQL锁表

    怎么操作会导致MySQL锁表 转载于:https://www.cnblogs.com/luao/p/10867785.html

  10. matlab如何创建table,table,matlab,中table数据类型,创建,调用,访问

    MATLAB table数据结构 目录: ?关于作者 ?table简介 o为什么需要table数据结构 o通过导入数据构造table对象 o调用table构造函数来构造table对象 o通过转换函数构 ...

最新文章

  1. 没学数模电可以玩单片机吗
  2. python全局变量有缩进吗_Python全局变量和局部变量的问题 400 请求报错 -问答-阿里云开发者社区-阿里云...
  3. 程序员工资为什么高?
  4. 独家 | 如何“扰乱”科技巨头用来监视你的数据
  5. 2021全国大学生智能汽车竞赛中小学组国赛获奖名单
  6. mysql 5.6.14安装_MySQL5.6.14下载、安装及配置安装图文教程
  7. 24行代码AC_蓝桥杯2019省赛 试题 D: 数的分解
  8. 推荐一个一分钟就可以搭建好的静态文件服务器,基于nodejs
  9. Tushare数据的绘图操作
  10. 前端又要失失失失失失失失失业了!
  11. JAVA高并发工作笔记0001---高并发编程之ConcurrentLinkedDeque
  12. [专题练习] Part1 搜索
  13. 计算机专业专业课代号408,计算机408有多难
  14. 参数化三维管网建模系统MagicPipe3D
  15. unity 安装踩坑
  16. 高速串行总线技术发展与应用分析
  17. 部落战争COC免费获得绿宝石 内购农民攻略
  18. 快速拷贝文件经验及工具分享 - 天缘博客
  19. win10 jdk1.8迅雷下载
  20. 习题3-4 统计学生成绩(15 分)

热门文章

  1. uboot驱动模型(DM)分析(二)
  2. 交叉编译中libtool相关的问题
  3. qt写的在ok6410上的密码锁
  4. 1146 Topological Order(25 分)
  5. B - I Hate It(单点更新)(区间求最大值)
  6. Python模块受欢迎排行榜Top200
  7. HUSTOJ(2019)在线判题系统的搭建
  8. python应聘要求_python爬取招聘要求等信息实例
  9. mysql 字符串 反转_MySQL笔记之字符串函数的应用
  10. tp3.2 缓存cache