好多人在调优Mysql的时候,总是对open_tables和opend_tables两个参数分别不清。 
网上好多解释都是这样的:
open_tables:当前打开表的数量
opened_tables:当前已经打开表的数量
 
很简单的解释,可是这两句话看起来有点类似。
 
下面我来解释一下:
open_tables:是当前在缓存中打开表的数量。
opened_tables:是mysql自启动起,打开表的数量。
 
我们知道,假如没有缓存的话,那么mysql服务在每次执行一个语句的时候,都会先打开一个表。当sql语句执行完成后,则把这个表关掉。这就是opend_tables中的值。
 
而open_tables这个值,是mysql在使用缓存的情况下,存储在缓存中的表的个数。
 
我们可以这样做实验:执行flush tables;这个命令是mysql用来刷新缓存的。当这个命令执行后,我们会看到
open_tables这个值被清零了。但是opened_tables这个值还是保持原来值不变。
 
但是当我们关闭mysql服务,再重启后,opened_tables这个值也被清零了。
 
由此,得出上述两个值的结论。
 
这也就是为什么说当open_tables这个值接近于table_open_cache这个值的时候,同时opened_tables的值在不断的增加,这个时候就要考虑增大table_open_cache这个缓存值了。
 
解释如下:
因为open_tables的值接近于table_open_cache,说明分配的缓存已经被用完了。而opened_tables这个值又在高速增加,说明mysql在不断的打开表。也就说明缓存中并没有这些要打开的表。所以说,缓存应该是要增加了。因为如果表在缓存中,那么打开表的时候这两个值是不会增加的。

——————————————————————————————————————————————

这段时间,监控的一个mysql数据库频繁的报警 table_cache_hitrate 小于1%

mysql> show global status like '%table%';
+-----------------------------------------+-----------+
| Variable_name                           | Value     |
+-----------------------------------------+-----------+
| Created_tmp_disk_tables                 | 1062135   |
| Created_tmp_tables                      | 34492864  |
| Open_table_definitions                  | 452       |
| Open_tables                             | 515       |
| Opened_table_definitions                | 226373    |
| Opened_tables                           | 254733    |
| Performance_schema_table_handles_lost   | 0         |
| Performance_schema_table_instances_lost | 0         |
| Slave_open_temp_tables                  | 0         |
| Table_locks_immediate                   | 188997447 |
| Table_locks_waited                      | 421288    |
+-----------------------------------------+-----------+

关于 open_tables: 当前打开的表的数量; opened_tables:服务器启动以来打开的表的数量。

关于table_open_cache 和 max_connections :

MySQL is multi-threaded, so there may be many clients issuing queries for a  given table simultaneously. To minimize the problem with multiple client  sessions having different states on the same table, the table is opened  independently by each concurrent session. This uses additional memory but  normally increases performance. With MyISAMtables,  one extra file descriptor is required for the data file for each client that has  the table open. (By contrast, the index file descriptor is shared between all  sessions.)

The and system variables affect the maximum  number of files the server keeps open. If you increase one or both of these  values, you may run up against a limit imposed by your operating system on the  per-process number of open file descriptors. Many operating systems permit you  to increase the open-files limit, although the method varies widely from system  to system. Consult your operating system documentation to determine whether it  is possible to increase the limit and how to do so.

is related to . For example, for 200 concurrent  running connections, specify a table cache size of at least 200 * N, where Nis the maximum number of tables per join  in any of the queries which you execute. You must also reserve some extra file  descriptors for temporary tables and files.

msql 5.5

设置 innodb_file_per_table =0 ,所有表使用公共的表空间。

可以看一下 open_tables 和 opened_tables的变化:

我们设置 table_open_cache 的值为30,来看一下变化的情况:

mysql> show global status like 'open%tables';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| Open_tables   | 26    |
| Opened_tables | 33    |
+---------------+-------+
2 rows in set (0.00 sec)

mysql> select * from test limit 2;
+-------+
| col   |
+-------+
| testa |
| ddd   |
+-------+
2 rows in set (0.02 sec)

mysql> show global status like 'open%tables';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| Open_tables   | 27    |
| Opened_tables | 34    |
+---------------+-------+
2 rows in set (0.00 sec)

-----------------------可以看到,打开一个表的时候,这两个状态的值是增长的---------

当open_tables 达到 table_open_cache的时候看一下变化:

mysql> show global status like 'open%tables';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| Open_tables   | 30    |
| Opened_tables | 38    |
+---------------+-------+
2 rows in set (0.00 sec)

mysql> select * from test8 limit 2;
Empty set (0.03 sec)

mysql> show global status like 'open%tables';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| Open_tables   | 30    |
| Opened_tables | 39    |
+---------------+-------+

-----------------------这时候,就只有 opened_tables 增长了-----------------

当 open_tables 达到 table_open_cache,有新的表需要打开的时候,就需要对已经存在于cache中的表 close, 具体的解释如下:

MySQL closes an unused table and removes it from the table cache under the  following circumstances:

When the cache is full and a thread tries to open a table that is not in the  cache.

When the cache contains more than entries and a table in the cache is no  longer being used by any threads.

When a table flushing operation occurs. This happens when someone issues a statement or executes a or command.

When the table cache fills up, the server uses the following procedure to  locate a cache entry to use:

Tables that are not currently in use are released, beginning with the table  least recently used.

If a new table needs to be opened, but the cache is full and no tables can be  released, the cache is temporarily extended as necessary. When the cache is in a  temporarily extended state and a table goes from a used to unused state, the  table is closed and released from the cache

我们可以手工打开超过table_open_cache 的新表,看一下是否会把之前打开的表给踢出cache:

mysql> select * from test2; 
Empty set (0.00 sec)

mysql> select * from test3; 
Empty set (0.00 sec)

mysql> select * from test4; 
Empty set (0.00 sec)

mysql> select * from test5; 
Empty set (0.00 sec)

mysql> select * from test6; 
Empty set (0.00 sec)

mysql> select * from test7; 
Empty set (0.00 sec)

mysql> select * from test8; 
Empty set (0.01 sec)

mysql> select * from test9; 
Empty set (0.00 sec)

mysql> select * from test10; 
Empty set (0.00 sec)

mysql> select * from test11; 
Empty set (0.00 sec)

mysql> select * from test12; 
Empty set (0.00 sec)

mysql> select * from test13; 
Empty set (0.00 sec)

mysql> select * from test14; 
Empty set (0.00 sec)

mysql> select * from test15; 
Empty set (0.00 sec)

mysql> select * from test16; 
Empty set (0.00 sec)

mysql> select * from test17; 
Empty set (0.00 sec)

mysql> select * from test18; 
Empty set (0.00 sec)

mysql> select * from test19; 
Empty set (0.00 sec)

mysql> select * from test20; 
Empty set (0.00 sec)

mysql> select * from test21; 
Empty set (0.00 sec)

mysql> select * from test22; 
Empty set (0.00 sec)

mysql> select * from test23; 
Empty set (0.00 sec)

mysql> select * from test24; 
Empty set (0.00 sec)

mysql> select * from test25; 
Empty set (0.00 sec)

mysql> select * from test26; 
Empty set (0.00 sec)

mysql> select * from test27; 
Empty set (0.00 sec)

mysql> select * from test28; 
Empty set (0.00 sec)

mysql> select * from test29; 
Empty set (0.00 sec)

mysql> select * from test30; 
Empty set (0.00 sec)

mysql> select * from test31; 
Empty set (0.00 sec)

mysql> select * from test32; 
Empty set (0.00 sec)

mysql> select * from test33; 
Empty set (0.00 sec)

mysql> select * from test34; 
Empty set (0.00 sec)

mysql> select * from test35; 
Empty set (0.00 sec)

mysql> select * from test36; 
Empty set (0.00 sec)

mysql> select * from test37; 
Empty set (0.00 sec)

mysql> select * from test38; 
Empty set (0.00 sec)

mysql> select * from test39; 
Empty set (0.00 sec)

mysql> select * from test40; 
Empty set (0.00 sec)

mysql> select * from test41; 
Empty set (0.00 sec)

mysql> select * from test42; 
+------+
| id   |
+------+
|    3 |
+------+
1 row in set (0.00 sec)

再次查询:

mysql> show global status like 'open%tables';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| Open_tables   | 30    |
| Opened_tables | 80    |
+---------------+-------+

mysql> select * from test limit 2;
+-------+
| col   |
+-------+
| testa |
| ddd   |
+-------+
2 rows in set (0.00 sec)

mysql> select * from test5 limit 2;
+------+-------+
| id   | name  |
+------+-------+
| 1000 | test4 |
| 1001 | test4 |
+------+-------+
2 rows in set (0.00 sec)

mysql> show global status like 'open%tables';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| Open_tables   | 30    |
| Opened_tables | 80    |
+---------------+-------+

----------这里我们新打开的表的数量远远超过了30,但是重新查询之前打开的表,open_tables 没有增长,按照上面的理论,应该是cache临时扩张,不过找不到一些直接的状态值来查看这个。

这里我们可以继续做实验,我这里重新创建了一个database,重新创建了41个表,然后对41个表执行查询,我们再看:

mysql> show global status like 'open%tables';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| Open_tables   | 30    |
| Opened_tables | 121   |

重新查询之前打开过的表:

mysql> select * from test7 limit 3;
+------+-------+
| id   | name  |
+------+-------+
|  500 | test1 |
|  501 | test1 |
|  502 | test1 |
+------+-------+

mysql> show global status like 'open%tables';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| Open_tables   | 30    |
| Opened_tables | 122   |
+---------------+-------+
2 rows in set (0.00 sec)

mysql>  select * from test6 limit 3;
+------+-------+
| id   | name  |
+------+-------+
|    1 | test4 |
|    2 | test4 |
|    3 | test4 |
+------+-------+
3 rows in set (0.00 sec)

mysql> show global status like 'open%tables';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| Open_tables   | 30    |
| Opened_tables | 123   |

--------- 这里已经可以很清楚看到 cache满之后,会按照 最近最少使用的原则 从cache中丢弃掉。

对于opened_tables 的增长,临时表也贡献了非常多。对于内部临时表,有下面的文档:

In some cases, the server creates internal temporary tables  while processing queries. Such a table can be held in memory   and processed by the MEMORYstorage engine,  or stored on disk and processed by the  MyISAMstorage engine. The server may          create a temporary table initially as an in-memory table, then  convert it to an on disk table if it becomes too large. Users  have no direct control over when the server creates an internal temporary table or which storage engine the server  uses to manage it.

临时表的创建:

Temporary tables can be created under conditions such as  these:

If there is an ORDER BYclause and a different GROUP BYclause, or if the  ORDER BYor GROUP BYcontains columns from tables other than the first table in  the join queue, a temporary table is created.

DISTINCTcombined with ORDER   BYmay require a temporary table.

If you use the SQL_SMALL_RESULToption,   MySQL uses an in-memory temporary table, unless the query   also contains elements (described later) that require  on-disk storage.To determine whether a query requires a temporary table, use  EXPLAINand check the Extracolumn to see whether it says  Using temporary. See  Section 8.8.1, “Optimizing Queries with EXPLAIN”.

如果查询中使用了 order by 、group by 、distinct 会生成内部临时表。

测试一下:

mysql> show global status like 'open%tables';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| Open_tables   | 30    |
| Opened_tables | 124   |
+---------------+-------+

mysql> select * from test42;
+------+
| id   |
+------+
|    3 |
+------+

mysql> show global status like 'open%tables';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| Open_tables   | 30    |
| Opened_tables | 124   |
+---------------+-------+

mysql> select * from test42 order by id;
+------+
| id   |
+------+
|    3 |
+------+
1 row in set (0.00 sec)

mysql> show global status like 'open%tables';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| Open_tables   | 30    |
| Opened_tables | 125   |
+---------------+-------+

opened_tables 增加了1.

mysql> select distinct name from test5;
+-------+
| name  |
+-------+
| test4 |
| test1 |
+-------+
2 rows in set (1.43 sec)

mysql> show global status like 'open%tables';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| Open_tables   | 30    |
| Opened_tables | 126   |
+---------------+-------+

mysql> select name,count(*) from test5 group by name;
+-------+----------+
| name  | count(*) |
+-------+----------+
| test1 |   217081 |
| test4 |   999000 |
+-------+----------+
2 rows in set (1.18 sec)

mysql> show global status like 'open%tables';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| Open_tables   | 30    |
| Opened_tables | 126   |
+---------------+-------+

mysql> explain select name,count(*) from test5 group by name;
+----+-------------+-------+------+---------------+------+---------+------+---------+---------------------------------+
| id | select_type | table | type | possible_keys | key  | key_len | ref  | rows    | Extra                           |
+----+-------------+-------+------+---------------+------+---------+------+---------+---------------------------------+
|  1 | SIMPLE      | test5 | ALL  | NULL          | NULL | NULL    | NULL | 1216813 | Using temporary; Using filesort |
+----+-------------+-------+------+---------------+------+---------+------+---------+---------------------------------+

可以看到,如果前一次查询使用 order by 、group by、distinct 生成了临时表,则后面使用这些语法是不会再生成新的临时表。

使用 explain 查看语句执行计划的时候,如果 Extra 中有 Using temporary 的语句,则此语句使用了内部临时表。

对于隐式的临时表的创建,可以通过状态变量:Created_tmp_tables 来查看增长。

mysql>  show global status like '%created%%table%';
+-------------------------+----------+
| Variable_name           | Value    |
+-------------------------+----------+
| Created_tmp_disk_tables | 1063051  |
| Created_tmp_tables      | 34514321 |
+-------------------------+----------+
2 rows in set (0.00 sec)

对于innodb_file_per_table=1 , 结果大致一样。

对于监控指标: table_cache_hitrate = open_tables /  opened_tables ;

在5.6 版本中,引入了状态变量:

对于这一指标的监控更加方便。

参考:

http://gym202.blog.163.com/blog/static/955432742011711319442/

http://dev.mysql.com/doc/refman/5.5/en/table-cache.html

http://dev.mysql.com/doc/refman/5.5/en/internal-temporary-tables.html

http://hi.baidu.com/chenghui_2311/item/f1b257a1086c78bf29ce9da3

转载于:https://www.cnblogs.com/xiaotengyi/p/3555001.html

open_table与opened_table相关推荐

  1. mysql 5.7 mts_MySQL:MTS和mysqldump死锁

    ###一.问题来源 这是一位客户的提供的案例如下,show processlist截图如下: ![image.png](https://upload-images.jianshu.io/upload_ ...

  2. opening tables mysql_MySQL 大量 Opening tables 案例分析-爱可生

    因为一时间没法排查出具体原因,所以针对 MySQL 进程打了个快照,方便事后详细排查. 二.分析栈帧 用 pt-pmp 工具处理下快照后,内容比较多,这里只显示一些比较重要的堆栈: 1402 pthr ...

  3. android 自定义 进度条 旋转,Android_Android ProgressBar进度条使用详解,ProgressBar进度条,分为旋转进 - phpStudy...

    Android ProgressBar进度条使用详解 ProgressBar进度条,分为旋转进度条和水平进度条,进度条的样式根据需要自定义,之前一直不明白进度条如何在实际项目中使用,网上演示进度条的案 ...

  4. python2读取excel中文处理,【Python】【源码】利用Python读取Excel文件-续

    [Python] 纯文本查看 复制代码""" ************************************************** *** Created ...

  5. mysql slave lock 跳过_slave开启MTS时执行mysqldump引发死锁案例

    出现这种问题除非手动干预,杀掉FTWRL的session,复制线程方可以继续进行.版本社区版5.7.26. 二.堵塞图 如果分析上面的堵塞可以画图如下: 三.关于woker线程w1和w3的等待 这里我 ...

  6. mysql bug_MySQL 记一次 Bug发现过程

    水平有限有误请谅解 这个问题是一位朋友@DBA-老庄的,他们使用的是PXC环境如下: MySQL:5.7.18-15 wsrep:29.20 os:Red Hat Enterprise Linux S ...

  7. mysql 设置 character_set_server_MySQL:简单记录character_set_server影响参数

    Waiting for global read lock:由于flush table with read lock调用函数lock_global_read_lock导致DML操作堵塞. Waiting ...

  8. MySQL 深潜 - MDL 锁的实现与获取机制

    简介:本文将介绍在 MDL 系统中常用的数据结构及含义,然后从实现角度讨论 MDL 的获取机制与死锁检测,最后分享在实践中如何监控 MDL 状态. 作者 | 泊歌 来源 | 阿里技术公众号 一 背景 ...

  9. mysql open table_MySQL open table

    背景: MySQL经常会遇到Too many open files,MySQL上的open_files_limit和OS层面上设置的open file limit有什么关系? 源码中也会看到不同的数据 ...

  10. rds mysql 表被删了_MySQL · 捉虫动态 · 删除索引导致表无法打开

    问题背景 最近线上遇到一个问题,用户重启实例后发现有张表打不开了,经调研后发现是用户之前的霸蛮操作导致的,下面给出复现步骤: create table t1 (id int not null prim ...

最新文章

  1. mysql 查询结果转置_转置MySQL查询 – 需要将行放入列中
  2. list对oracle结果集排序了_MySQL之排序分组优化
  3. tensorrt轻松部署高性能dnn推理_NVIDIA Triton推理服务器助力深度学习推理
  4. python 拓扑排序正确版
  5. ioca0中断 pic单片机_关于PIC单片机的一些经验总结 -单片机-电子工程世界网
  6. 可变lambda_Lambda的Lambda(如果可选)
  7. 求解这个矩阵形式的HTML5线性方程组
  8. 计算机毕设分词,毕业设计(论文)+计算机科学与技术+中文分词方法研究与实现论文全文.doc...
  9. android.net是哪个jar,【Android Clock Synchronization】Android时钟同步:基于NTP协议的第三方库Apache Commons Net......
  10. 多线程编程之优先级翻转问题
  11. 51test-day1【ofo测试第一天】
  12. 步进电机的计算机控制系统设计,步进电机控制系统的设计与实现
  13. Vue Router 路由(路由守卫)---route
  14. 书犹药也,善读之可以医愚
  15. 快速串联 RNN / LSTM / Attention / transformer / BERT / GPT
  16. 蓝桥杯省赛 走方格(多种方法)
  17. 跑步听歌用哪种耳机更合适、适合跑步专业的耳机推荐
  18. Perl中的bless的理解
  19. 基于ssm的一个一个众筹系统平台
  20. (stm32)DT35与ADS8320

热门文章

  1. spring boot打包本地idea跑能行,上线jar包跑不行 解决
  2. 《预训练周刊》第53期:代码生成、通用任务变换器
  3. webkit未能加载文件或程序集WebKitBrowser
  4. [gitlab] 解决:remote: Ask a project Owner or Maintainer to create a default branch:
  5. opc服务器组态文件已写保护_opc服务器组态文件已写保护
  6. 用esp8266做一个网络时钟
  7. R语言之几大常见概率分布
  8. 干货|遗传+禁忌混合算法(HA)算法求解柔性作业车间调度问题(FJSP)附java代码-第一部分
  9. Running “flutter pub get“ in xxx... 报错: Git error 443
  10. Postgresql - 监控 moniter - 监控日志