我正在尝试通过优化Mysql服务器来提高网站的性能。 除了一般的优化之外,我还是觉得有些写操作需要很长的时间。
该服务器是Mac OS X服务器10.5.8(我认为这是一个32位的操作系统)与2×2.8 GHz的四核心英特尔至强和8 GB RAM。
有2个InnoDB表很less使用,另外45个表是MyISAM。
整个数据库是1.2 GB,其中包括一个400 MB的日志表,只有写入和应用程序永远不会读取。
我会假设在RAM中拥有整个数据库会提高性能。 另外我会假设在系统故障的情况下容忍一些数据丢失可以提高写入性能,但我不知道如何configuration它来利用这一点。 可能丢失的数据并不重要,如果丢失,可以由用户重新创build。
该网站有大约1或2个同时访问者。
我已经运行了一些mysqltuner.pl的迭代。 以下是目前的结果:
>> MySQLTuner 1.2.0 - Major Hayden <[email protected]> -------- General Statistics -------------------------------------------------- [--] Skipped version check for MySQLTuner script [OK] Currently running supported MySQL version 5.0.92-log [!!] Switch to 64-bit OS - MySQL cannot currently use all of your RAM -------- Storage Engine Statistics ------------------------------------------- [--] Status: -Archive -BDB -Federated +InnoDB -ISAM -NDBCluster [!!] InnoDB is enabled but isn't being used [OK] Total fragmented tables: 0 -------- Security Recommendations ------------------------------------------- ERROR 1142 (42000) at line 1: SELECT command denied to user ''@'localhost' for table 'user' [OK] All database users have passwords assigned -------- Performance Metrics ------------------------------------------------- [--] Up for: 16m 57s (4K q [4.126 qps], 122 conn, TX: 6M, RX: 1M) [--] Reads / Writes: 97% / 3% [--] Total buffers: 922.0M global + 12.4M per thread (100 max threads) [!!] Allocating > 2GB RAM on 32-bit systems can cause system instability [!!] Maximum possible memory usage: 2.1G (26% of installed RAM) [OK] Slow queries: 0% (0/4K) [OK] Highest usage of available connections: 2% (2/100) [!!] Cannot calculate MyISAM index size - re-run script as root user [OK] Query cache efficiency: 42.5% (1K cached / 3K selects) [OK] Query cache prunes per day: 0 [OK] Sorts requiring temporary tables: 0% (0 temp sorts / 36 sorts) [OK] Temporary tables created on disk: 8% (6 on disk / 68 total) [OK] Thread cache hit rate: 98% (2 created / 122 connections) [OK] Table cache hit rate: 53% (58 open / 109 opened) [OK] Open file limit used: 4% (103/2K) [OK] Table locks acquired immediately: 100% (3K immediate / 3K locks) -------- Recommendations ----------------------------------------------------- General recommendations: Add skip-innodb to MySQL configuration to disable InnoDB MySQL started within last 24 hours - recommendations may be inaccurate
这是我的my.cnf
# The MySQL server [mysqld] port = 3306 socket = /var/mysql/mysql.sock skip-locking key_buffer = 384M max_allowed_packet = 1M table_cache = 1024 sort_buffer_size = 2M read_buffer_size = 2M read_rnd_buffer_size = 8M myisam_sort_buffer_size = 64M thread_cache_size = 8 query_cache_size = 512M # Try number of CPU's*2 for thread_concurrency thread_concurrency = 8 skip-thread-priority log_slow_queries = 1 long_query_time = 1
重新启动mysql之前,我有3个缓慢的查询可能100K查询,但我在哪里可以find与这些查询日志?
//
你说过,你“有一种写作经验花了很长时间”的感觉。 什么让你有这种感觉? 你有没有试图衡量它?
如果你在OS X上, dtrace是衡量这类事情的绝佳工具。 有些人为你做了一些 工作 。 至less,请使用vmstat , iostat或iotop来确定您是否看到磁盘时序显着减速。
你的query_cache_size可能太大了。 写入必须使查询caching中该表的所有条目无效。 查询caching越大,需要的时间越长 ,这可能会让写入速度变慢。 该手册build议“几十兆字节”。 你应该逐步改变它,并在每次改变之后衡量performance,以确定你应该有多大。
Table locks acquired immediately: 100% (3K immediate / 3K locks)值表明,MyISAM表locking对你来说不是问题。 这可能会成为MyISAM表的一个重大问题,经历更高的写入和读取比例。
查询写入磁盘包含在缓慢的查询跟踪中,所以如果你看到INSERT,UPDATE,REPLACE,DELETE,TRUNCATE等缓慢的查询,这将是一个暗示,你有问题。
慢查询日志可以是一个文件或一个表或两者。 由于您似乎没有指定位置,因此应使用默认设置。 从慢查询日志的手册 部分和日志位置的部分 :
如果您为慢查询日志文件指定了没有名称,则默认名称是host_name-slow.log。 服务器在数据目录中创build文件,除非给出绝对path名来指定不同的目录。
鉴于你提到的这些因素
这很快就排除了使用InnoDB,因为MySQL 5.0没有可以使用多个内核的InnoDB(具有InnoDB参与多个内核的最旧版本的MySQL是InnoDB插件)。
你不能在RAM中拥有整个数据库,因为MyISAM只caching索引。 但是,您可以将所有MyISAM索引加载到密钥缓冲区中。
你需要做的第一件事是计算正确大小的key_buffer_size 。 这是一个查询来为你计算:
SELECT CONCAT(ROUND(KBS/POWER(1024, IF(PowerOf1024<0,0,IF(PowerOf1024>3,0,PowerOf1024)))+0.4999), SUBSTR(' KMG',IF(PowerOf1024<0,0, IF(PowerOf1024>3,0,PowerOf1024))+1,1)) recommended_key_buffer_size FROM (SELECT LEAST(POWER(2,31),KBS1) KBS FROM (SELECT SUM(index_length) KBS1 FROM information_schema.tables WHERE engine='MyISAM' AND table_schema NOT IN ('information_schema','mysql')) AA ) A, (SELECT 2 PowerOf1024) B;
请注意,如果所有MyISAM指标的总和超过2G,build议将上限为2G。 还要注意这一点:SQL语句包含子句(SELECT 2 PowerOf1024) B 。 这将以MB为单位输出build议。 使用(SELECT 1 PowerOf1024) B输出(以KB为单位)。 使用(SELECT 3 PowerOf1024) B GB输出。
好吧,你现在知道什么大小,使MyISAM密钥缓冲区。 你如何加载它?
运行这个:
SELECT DISTINCT CONCAT('SELECT ',ndxcollist,' FROM ', db,'.',tb,' ORDER BY ',ndxcollist,';') SelectQueryToLoadCache FROM (SELECT engine,table_schema db,table_name tb,index_name, GROUP_CONCAT(column_name ORDER BY seq_in_index) ndxcollist FROM (SELECT B.engine,A.table_schema,A.table_name,A.index_name, A.column_name,A.seq_in_index FROM information_schema.statistics A INNER JOIN (SELECT engine,table_schema,table_name FROM information_schema.tables WHERE engine='MyISAM' AND table_schema NOT IN ('information_schema','mysql')) B USING (table_schema,table_name) WHERE A.index_type <> 'FULLTEXT' ORDER BY table_schema,table_name,index_name,seq_in_index) A GROUP BY table_schema,table_name,index_name) AA ORDER BY db,tb;
此查询将显示您需要运行的每个查询,以强制所有MYI索引页进入关键缓冲区。 将此查询输出到脚本并运行该输出:
SQLSTMT="SELECT DISTINCT CONCAT('SELECT ',ndxcollist,' FROM ',db,'.',tb,' ORDER BY ',ndxcollist,';') SelectQueryToLoadCache FROM (SELECT engine,table_schema db,table_name tb,index_name,GROUP_CONCAT(column_name ORDER BY seq_in_index) ndxcollist FROM (SELECT B.engine,A.table_schema,A.table_name,A.index_name,A.column_name,A.seq_in_index FROM information_schema.statistics A INNER JOIN (SELECT engine,table_schema,table_name FROM information_schema.tables WHERE engine='MyISAM' AND table_schema NOT IN ('information_schema','mysql')) B USING (table_schema,table_name) WHERE A.index_type <> 'FULLTEXT' ORDER BY table_schema,table_name,index_name,seq_in_index) A GROUP BY table_schema,table_name,index_name) AA ORDER BY db,tb;" mysql -u... -p.... -AN -e"${SQLSTMT}" > MyISAMIndexPreload.sql mysql -u... -p.... -A < MyISAMIndexPreload.sql
试一试 !!!
如果你有8Gb的内存,这并不意味着把你的整个数据库放在RAM中。内存操作也使用一些内存。
我会build议在my.cnf设置他们可能会为你工作
Increase your `key_buffer` from 384M to some high value may be to 512MB as you have sufficien RAM
密钥缓冲区的大小,用于cachingMyISAM表的索引块。 请不要将其设置为大于可用内存的30%,因为操作系统还需要某些内存来caching行。 即使你没有使用MyISAM表格,你也应该把它设置为8-64M,因为它也可以用于内部临时磁盘表格。
set table_open_cache to 2048
UPDATE
要正确configuration你的my.cnf,请访问my.cnf优化
尝试它可能会帮助你…