我已经看到人们使用Open_tables和Opened_tables的比较来评估table_cache在MySQL中是否太小。但是,我相信Opened_tables在正常运行时间内是累积的,因此这不是有效的比较。唯一需要注意的是,也许Opened_tables只会在未命中时发生碰撞-尽管即使每秒打开的表仍然很小,但逐渐增长它也不是问题。
如果将Open_tables与Opened_tables比较无效,是否还有另一种方法来获取测量数据?
这是在MySQL 5.0上,但也欢迎版本之间存在差异。
我已经看到人们使用Open_tables和Opened_tables的比较来评估table_cache在MySQL中是否太小。但是,我相信Opened_tables在正常运行时间内是累积的,因此这不是有效的比较。唯一需要注意的是,也许Opened_tables只会在未命中时发生碰撞-尽管即使每秒打开的表仍然很小,但逐渐增长它也不是问题。
如果将Open_tables与Opened_tables比较无效,是否还有另一种方法来获取测量数据?
这是在MySQL 5.0上,但也欢迎版本之间存在差异。
Answers:
拥有较大的table_cache的最大原因是LOCK_open互斥锁不热。尝试打开/关闭表时,5.5之前的MySQL存在很多争用,因此您希望限制这样做,即具有大的表缓存。
因此,您不必担心命中率与未命中率的任何特定比率(实际上,您应该完全忽略比率)– 此博客文章解释了为什么)。您关心的是未命中率,因为每秒发生的次数越多,您争用的机会就越大(一个线程必须等待另一个线程释放锁)。
您如何发现未命中率?在一天中最繁忙的时间段内,您需要间隔几秒钟获取一些Opened_Tables样本,并且如果每个样本都有增加,那么看看是否可以提高table_cache可能是一个好主意。
注意:我非常不建议您将运行时间与正常运行时间进行比较。
首先,让我们考虑一下这些状态变量:
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 Administrator或MONyog,则可以使用查询和监视中的公式来自定义图形。MONyog使用SQLLite收集历史记录,以便以后进行历史记录。可以对任何版本的MySQL执行此操作。
在table_cache文档页面上的用户评论之一中:
Opened_tables是一个状态变量,用于在table_cache中的可用文件描述符耗尽时,保持已分配的用于打开表的附加文件描述符数量的运行统计。...
这意味着当您超过自己的table_cache价值时,它就会增加。所以我通常检查这一点的方法是比较opened_tables有uptime,但这里的关键是要它在设定的时间间隔(每分钟一次在10分钟内,例如)。如果增加,可能表明您需要增加table_cache。
有几点警告要提:
上面该文档中的另一条评论:“每次创建临时表时,状态变量'Opened_tables'也会增加2。” 因此,如果您的查询需要许多临时表,则可能是中的快速增加的原因opened_tables。您可以使用以下查询查看临时表的使用情况:
SHOW GLOBAL STATUS LIKE '%tmp%';
出现这种情况的原因是,如果您的号码不多。包含复杂查询的表连接到多个表并运行这些复杂查询的多个连接,您可能最终会使用所有文件描述符的缓存(table_cache),在这种情况下,MySQL使用一种算法来查找最近最少使用的描述符,然后关闭并替换它带有一个新的描述符。