我有一个有InnoDB和MyISAM表的MySQL服务器。 InnoDB表空间在4 GB以下是相当小的。 MyISAM总共大约250GB,其中50GB用于索引。
我们的服务器有32 GB的RAM,但通常只使用〜8GB。 我们的key_buffer_size只有2GB。 但是我们的关键caching命中率是〜95%。 我觉得很难相信..
这是我们的关键统计数据:
| Key_blocks_not_flushed | 1868 | | Key_blocks_unused | 109806 | | Key_blocks_used | 1714736 | | Key_read_requests | 19224818713 | | Key_reads | 60742294 | | Key_write_requests | 1607946768 | | Key_writes | 64788819 |
key_cache_block_size默认为1024。
我们有52 GB的索引数据和2 GB的密钥caching足以达到95%的命中率。 那可能吗? 另一方面,数据集是200GB,并且由于MyISAM使用OS(Centos)caching,我期望它使用更多的内存来caching访问的myisam数据。 但在这个阶段,我看到key_buffer被完全使用了,我们的innodb的缓冲池大小是4GB,并且也被完全使用,总计达到了6GB。 这意味着数据仅使用1 GB进行caching?
我的问题是如何检查所有可用内存的使用位置? 我如何检查MyISAM是否访问OScaching而不是磁盘?
我可以轻易相信95%的关键caching命中率。 收听您的统计信息:
你说你有50GB的MyISAM表索引
密钥caching旨在cachingMyISAM表的索引页。 该选项由key_buffer_size选项设置
你说的是2G。 难怪命中率是95%。 索引块不断地在密钥caching中进出。 在MySQLfind索引(.MYI)信息后,需要特定行的数十个查询被加载到keycache中。 所有后续的查询需要相同的.MYI信息查找数据(.MYD)将在第一个查询加载后被caching。 MySQL不会在自己的caching中cachingMyISAM数据。
你应该可以将key_buffer_size设置为8G。
这是http://dev.mysql.com/doc/refman/5.5/en/server-system-variables.html#sysvar_key_buffer_size的摘录:
您可以增加该值以获得对所有读取和多次写入的更好的索引处理; 在其主要function是使用MyISAM存储引擎运行MySQL的系统上,该机器总内存的25%是该variables的可接受值。 但是,您应该意识到,如果使值太大(例如,超过机器总内存的50%),系统可能会开始分页并变得非常慢。 这是因为MySQL依靠操作系统为数据读取执行文件系统caching,所以您必须为文件系统caching留出一些空间。 除了MyISAM之外,您还应该考虑您可能使用的任何其他存储引擎的内存要求。
这个相同的URL说明了32位OS的最大key_buffer_size是4G。 您不应该通过给定的服务器configuration通过8G的key_buffer_size。
至于你的数据读取,你需要的唯一状态variables是Key_reads。 这给出了一个索引页必须从.MYI文件中获取的频率。
你需要监视的关键caching命中率如下
KRR_NOW = Key_read_requests Now KRR_SEC = Key_read_requests one ago KRD_NOW = Key_reads Now KRD_SEC = Key_reads one second ago KRR_DELTA = KRR_NOW - KRR_SEC KRD_DELTA = KRD_NOW - KRD_SEC
KeyCache命中率(KHR)就是这个公式
KHR = 100 * (KRR_DELTA - KRD_DELTA) / KRR_DELTA
你想要一个KeyCache命中率99 +%
现在谈谈事情,让我们来讨论一下InnoDB。
你的innodb_buffer_pool_size应该设置为4G。 这是因为InnoDB缓冲池caching数据和索引页面。 你可以给innodb_buffer_pool一个更具体的数字,使用下面的四舍五入:
SELECT CONCAT(CEILING(ibbytes / POWER(1024,3)),'G') FROM (SELECT SUM(data_length+index_length) ibbytes FROM information_schema.tables where engine='InnoDB') A;