MySQL table_cache和Opened_tables


14

我已经看到人们使用Open_tables和Opened_tables的比较来评估table_cache在MySQL中是否太小。但是,我相信Opened_tables在正常运行时间内是累积的,因此这不是有效的比较。唯一需要注意的是,也许Opened_tables只会在未命中时发生碰撞-尽管即使每秒打开的表仍然很小,但逐渐增长它也不是问题。

如果将Open_tables与Opened_tables比较无效,是否还有另一种方法来获取测量数据?

这是在MySQL 5.0上,但也欢迎版本之间存在差异。


我喜欢这个问题,因为这是一个发人深省的问题。+1可以提醒MySQL开发人员充分利用状态变量来衡量DB Server运行状况。
RolandoMySQLDBA 2011年

Answers:


7

拥有较大的table_cache的最大原因是LOCK_open互斥锁不热。尝试打开/关闭表时,5.5之前的MySQL存在很多争用,因此您希望限制这样做,即具有大的表缓存。

因此,您不必担心命中率与未命中率的任何特定比率(实际上,您应该完全忽略比率)– 此博客文章解释了为什么)。您关心的是未命中率,因为每秒发生的次数越多,您争用的机会就越大(一个线程必须等待另一个线程释放锁)。

您如何发现未命中率?在一天中最繁忙的时间段内,您需要间隔几秒钟获取一些Opened_Tables样本,并且如果每个样本都有增加,那么看看是否可以提高table_cache可能是一个好主意。

注意:我非常不建议您将运行时间与正常运行时间进行比较。


5

首先,让我们考虑一下这些状态变量:

打开的表打开的表数。

Opened_tables:已打开的表数。如果Opened_tables大,则您的table_open_cache值可能太小。

令人惊讶的是,问题的答案就在问题本身之内。

仅当您将一个状态变量添加到混合中时,这两个变量才更有意义:正常运行时间(或FLUSH STATUS之后刷新平均值的Uptime_since_flush 状态)。

您应该比较Open_tables agsinst Opened_tables / Uptime)。如果Open_tables超过 Opened_tables / Uptime),现在您会感到担忧,应该对以下情况保持警惕:

更新美国东部时间2011-08-31 12:18

请注意为什么我还建议使用Uptime_since_flush_status而不是Uptime来获取给定时间段内固定的Opened_tables增长模式。

例如,如果您在FLUSH STATUS;每个星期一的午夜运行,则可以生成一个OpenTableFactor:

SELECT *, (Open_tables * Uptime / Opened_Tables) OpenTableFactor FROM
(SELECT variable_value Uptime FROM information_schema.global_status
WHERE variable_name = 'Uptime_since_flush_status') up,
(SELECT variable_value Open_tables FROM information_schema.global_status
WHERE variable_name = 'Open_tables') opn,
(SELECT IF(variable_value=0,1,variable_value) Opened_tables
FROM information_schema.global_status
WHERE variable_name = 'Opened_tables') opnd;

此开放表系数等于表示在任何给定时间的开放表数量相对于整个给定期间的平均打开表数量的数量。对于FLUSH HOSTS;每周/每天/主机,该平均值与每周/每天/小时相对。

以下是我的一位雇主客户的示例:

mysql> SELECT *, (Open_tables * Uptime / Opened_Tables) OpenTableFactor FROM     (SELECT variable_value Uptime FROM information_sc    hema.global_status     WHERE variable_name = 'Uptime_since_flush_status') up,     (SELECT variable_value Open_tables FROM informat    ion_schema.global_status     WHERE variable_name = 'Open_tables') opn,     (SELECT IF(variable_value=0,1,variable_value) Opened_ta    bles     FROM information_schema.global_status     WHERE variable_name = 'Opened_tables') opnd;
+----------+-------------+---------------+-------------------+
| Uptime   | Open_tables | Opened_tables | OpenTableFactor   |
+----------+-------------+---------------+-------------------+
| 14385123 | 16326       | 30429078      | 7717.996519579068 |
+----------+-------------+---------------+-------------------+
1 row in set (0.00 sec)

此客户端通常最多维护大约7745个OpenTableFactor。如果OpenTableFactor突然下降(即使略有下降),则可能表示流量模式较低,对接高中止状态等等。如果OpenTableFactor从未更改(即使有少许更改),它可能会为您提供更改以下设置的机会:

调整后,OpenTableFactor可能会不断变化或达到另一个上限或稳定水平。因此,在状态变量中使用不同的单位对于这种调整至关重要。

更新2011-08-31 12:42 EDT

我为OpenTableFactor运行的SQL查询不适用于MySQL 5.0和更高版本。如果使用MySQL AdministratorMONyog,则可以使用查询和监视中的公式来自定义图形。MONyog使用SQLLite收集历史记录,以便以后进行历史记录。可以对任何版本的MySQL执行此操作。


有一些好的建议,但是我不希望您要比较具有不同单位的两件事,而不是想要将累加值与当前值进行比较。如果这只是衡量未命中的问题,仍然存在。
山姆·布莱曼

3

table_cache文档页面上的用户评论之一中:

Opened_tables是一个状态变量,用于在table_cache中的可用文件描述符耗尽时,保持已分配的用于打开表的附加文件描述符数量的运行统计。...

这意味着当您超过自己的table_cache价值时,它就会增加。所以我通常检查这一点的方法是比较opened_tablesuptime,但这里的关键是要它在设定的时间间隔(每分钟一次在10分钟内,例如)。如果增加,可能表明您需要增加table_cache

有几点警告要提:

  • 上面该文档中的另一条评论:“每次创建临时表时,状态变量'Opened_tables'也会增加2。” 因此,如果您的查询需要许多临时表,则可能是中的快速增加的原因opened_tables。您可以使用以下查询查看临时表的使用情况:

    SHOW GLOBAL STATUS LIKE '%tmp%';

  • 不要将table_cache增加太高

    出现这种情况的原因是,如果您的号码不多。包含复杂查询的表连接到多个表并运行这些复杂查询的多个连接,您可能最终会使用所有文件描述符的缓存(table_cache),在这种情况下,MySQL使用一种算法来查找最近最少使用的描述符,然后关闭并替换它带有一个新的描述符。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.