MySQL優化經驗

同時在線訪問量繼續增大 對於1G內存的服務器明顯感受到吃力嚴重時甚至天天都會死機 或者時不時的服務器卡一下 這個問題曾經困擾了我半個多月MySQL使用是很具伸縮性的算法,所以你一般能用不多的內存運行或給MySQL更多的被存以獲得更好的性能。

安裝好mysql後,配製文件應該在/usr/local/mysql/share/mysql目錄中,配製文件有幾個,有my-huge.cnf my-medium.cnf my-large.cnf my-small.cnf,不一樣的流量的網站和不一樣配製的服務器環境,固然須要有不一樣的配製文件了。

通常的狀況下,my-medium.cnf這個配製文件就能知足咱們的大多須要;通常咱們會把配置文件拷貝到/etc/my.cnf 只須要修改這個配置文件就能夠了,使用mysqladmin variables extended-status –u root –p 能夠看到目前的參數,有3個配置參數是最重要的,即key_buffer_size,query_cache_size,table_cache。

key_buffer_size只對MyISAM表起做用,

key_buffer_size指定索引緩衝區的大小,它決定索引處理的速度,尤爲是索引讀的速度。通常咱們設爲16M,實際上稍微大一點的站點 這個數 字是遠遠不夠的,經過檢查狀態值Key_read_requests和Key_reads,能夠知道key_buffer_size設置是否合理。比例 key_reads / key_read_requests應該儘量的低,至少是1:100,1:1000更好(上述狀態值可使用SHOW STATUS LIKE ‘key_read%’得到)。 或者若是你裝了phpmyadmin 能夠經過服務器運行狀態看到,筆者推薦用phpmyadmin管理mysql,如下的狀態值都是本人經過phpmyadmin得到的實例分析:

這個服務器已經運行了20天 php

key_buffer_size – 128M
key_read_requests – 650759289
key_reads - 79112

比例接近1:8000 健康情況很是好mysql



另一個估計key_buffer_size的辦法 把你網站數據庫的每一個表的索引所佔空間大小加起來看看以此服務器爲例:比較大的幾個表索引加起來大概125M 這個數字會隨着表變大而變大。web



從4.0.1開始,MySQL提供了查詢緩衝機制。使用查詢緩衝,MySQL將SELECT語句和查詢結果存放在緩衝區中,從此對於一樣的SELECT語句(區分大小寫),將直接從緩衝區中讀取結果。根據MySQL用戶手冊,使用查詢緩衝最多能夠達到238%的效率。算法



經過調節如下幾個參數能夠知道query_cache_size設置得是否合理sql



Qcache inserts
Qcache hits
Qcache lowmem prunes
Qcache free blocks
Qcache total blocks


Qcache_lowmem_prunes的值很是大,則代表常常出現緩衝不夠的狀況,同時Qcache_hits的值很是大,則代表查詢緩衝使用很是頻 繁,此時須要增長緩衝大小Qcache_hits的值不大,則代表你的查詢重複率很低,這種狀況下使用查詢緩衝反而會影響效率,那麼能夠考慮不用查詢緩 衝。此外,在SELECT語句中加入SQL_NO_CACHE能夠明確表示不使用查詢緩衝。數據庫



Qcache_free_blocks,若是該值很是大,則代表緩衝區中碎片不少query_cache_type指定是否使用查詢緩衝緩存


我設置:服務器


query_cache_size = 32M
query_cache_type= 1


獲得以下狀態值:併發



Qcache queries in cache 12737 代表目前緩存的條數
Qcache inserts 20649006
Qcache hits 79060095  看來重複查詢率還挺高的
Qcache lowmem prunes 617913 有這麼屢次出現緩存太低的狀況
Qcache not cached 189896   
Qcache free memory 18573912  目前剩餘緩存空間
Qcache free blocks 5328 這個數字彷佛有點大 碎片很多
Qcache total blocks 30953


若是內存容許32M應該要往上加點less



table_cache指定表高速緩存的大小。每當MySQL訪問一個表時,若是在表緩衝區中還有空間,該表就被打開並放入其中,這樣能夠更快地訪問表內 容。經過檢查峯值時間的狀態值Open_tables和Opened_tables,能夠決定是否須要增長table_cache的值。若是你發現 open_tables等於table_cache,而且opened_tables在不斷增加,那麼你就須要增長table_cache的值了(上述狀 態值可使用SHOW STATUS LIKE ‘Open%tables’得到)。注意,不能盲目地把table_cache設置成很大的值。若是設置得過高,可能會形成文件描述符不足,從而形成性能 不穩定或者鏈接失敗。



對於有1G內存的機器,推薦值是128-256。



筆者設置table_cache = 256



獲得如下狀態:


Open tables 256
Opened tables 9046


雖然open_tables已經等於table_cache,可是相對於服務器運行時間來講,已經運行了20天,opened_tables的值也很是 低。所以,增長table_cache的值應該用處不大。若是運行了6個小時就出現上述值 那就要考慮增大table_cache。



若是你不須要記錄2進制log 就把這個功能關掉,注意關掉之後就不能恢復出問題前的數據了,須要您手動備份,二進制日誌包含全部更新數據的語句,其目的是在恢復數據庫時用它來把數據盡 可能恢復到最後的狀態。另外,若是作同步複製( Replication )的話,也須要使用二進制日誌傳送修改狀況。



log_bin指定日誌文件,若是不提供文件名,MySQL將本身產生缺省文件名。MySQL會在文件名後面自動添加數字引,每次啓動服務時,都會從新生 成一個新的二進制文件。此外,使用log-bin-index能夠指定索引文件;使用binlog-do-db能夠指定記錄的數據庫;使用binlog- ignore-db能夠指定不記錄的數據庫。注意的是:binlog-do-db和binlog-ignore-db一次只指定一個數據庫,指定多個數據 庫須要多個語句。並且,MySQL會將全部的數據庫名稱改爲小寫,在指定數據庫時必須所有使用小寫名字,不然不會起做用。



關掉這個功能只須要在他前面加上#號


#log-bin


開啓慢查詢日誌( slow query log ) 慢查詢日誌對於跟蹤有問題的查詢很是有用。它記錄全部查過long_query_time的查詢,若是須要,還能夠記錄不使用索引的記錄。下面是一個慢查詢日誌的例子:



開啓慢查詢日誌,須要設置參數log_slow_queries、long_query_times、log-queries-not-using-indexes。



log_slow_queries指定日誌文件,若是不提供文件名,MySQL將本身產生缺省文件名。long_query_times指定慢查詢的閾 值,缺省是10秒。log-queries-not-using-indexes是4.1.0之後引入的參數,它指示記錄不使用索引的查詢。筆者設置 long_query_time=10



筆者設置:


sort_buffer_size = 1M
max_connections=120
wait_timeout =120
back_log=100
read_buffer_size = 1M
thread_cache=32
interactive_timeout=120
thread_concurrency = 4


參數說明:



back_log


要求MySQL能有的鏈接數量。當主要MySQL線程在一個很短期內獲得很是多的鏈接請求,這就起做用,而後主線程花些時間(儘管很短)檢查鏈接而且啓 動一個新線程。back_log值指出在MySQL暫時中止回答新請求以前的短期內多少個請求能夠被存在堆棧中。只有若是指望在一個短期內有不少連 接,你須要增長它,換句話說,這值對到來的TCP/IP鏈接的偵聽隊列的大小。你的操做系統在這個隊列大小上有它本身的限制。 Unix listen(2)系統調用的手冊頁應該有更多的細節。檢查你的OS文檔找出這個變量的最大值。試圖設定back_log高於你的操做系統的限制將是無效 的。



max_connections


併發鏈接數目最大,120 超過這個值就會自動恢復,出了問題能自動解決



thread_cache


沒找到具體說明,不過設置爲32後 20天才建立了400多個線程 而之前一天就建立了上千個線程 因此仍是有用的



thread_concurrency


#設置爲你的cpu數目x2,例如,只有一個cpu,那麼thread_concurrency=2
#有2個cpu,那麼thread_concurrency=4
skip-innodb
#去掉innodb支持


代碼:



# Example MySQL config file for medium systems.
#
# This is for a system with little memory (32M - 64M) where MySQL plays
# an important part, or systems up to 128M where MySQL is used together with
# other programs (such as a web server)
#
# You can copy this file to
# /etc/my.cnf to set global options,
# mysql-data-dir/my.cnf to set server-specific options (in this
# installation this directory is /var/lib/mysql) or
# ~/.my.cnf to set user-specific options.
#
# In this file, you can use all long options that a program supports.
# If you want to know which options a program supports, run the program
# with the "--help" option.
# The following options will be passed to all MySQL clients
[client]
#password = your_password
port = 3306
socket = /tmp/mysql.sock
#socket = /var/lib/mysql/mysql.sock
# Here follows entries for some specific programs
# The MySQL server
[mysqld]
port = 3306
socket = /tmp/mysql.sock
#socket = /var/lib/mysql/mysql.sock
skip-locking
key_buffer = 128M
max_allowed_packet = 1M
table_cache = 256
sort_buffer_size = 1M
net_buffer_length = 16K
myisam_sort_buffer_size = 1M
max_connections=120
#addnew config
wait_timeout =120
back_log=100
read_buffer_size = 1M
thread_cache=32
skip-innodb
skip-bdb
skip-name-resolve
join_buffer_size=512k
query_cache_size = 32M
interactive_timeout=120
long_query_time=10
log_slow_queries= /usr/local/mysql4/logs/slow_query.log
query_cache_type= 1
# Try number of CPU's*2 for thread_concurrency
thread_concurrency = 4
#end new config
# Don't listen on a TCP/IP port at all. This can be a security enhancement,
# if all processes that need to connect to mysqld run on the same host.
# All interaction with mysqld must be made via Unix sockets or named pipes.
# Note that using this option without enabling named pipes on Windows
# (via the "enable-named-pipe" option) will render mysqld useless!
#
#skip-networking
# Replication Master Server (default)
# binary logging is required for replication
#log-bin
# required unique id between 1 and 2^32 - 1
# defaults to 1 if master-host is not set
# but will not function as a master if omitted
server-id = 1
# Replication Slave (comment out master section to use this)
#
# To configure this host as a replication slave, you can choose between
# two methods :
#
# 1) Use the CHANGE MASTER TO command (fully described in our manual) -
# the syntax is:
#
# CHANGE MASTER TO MASTER_HOST=, MASTER_PORT=,
# MASTER_USER=, MASTER_PASSWORD= ;
#
# where you replace , , by quoted strings and
# by the master's port number (3306 by default).
#
# Example:
#
# CHANGE MASTER TO MASTER_HOST='125.564.12.1', MASTER_PORT=3306,
# MASTER_USER='joe', MASTER_PASSWORD='secret';
#
# OR
#
# 2) Set the variables below. However, in case you choose this method, then
# start replication for the first time (even unsuccessfully, for example
# if you mistyped the password in master-password and the slave fails to
# connect), the slave will create a master.info file, and any later
# change in this file to the variables' values below will be ignored and
# overridden by the content of the master.info file, unless you shutdown
# the slave server, delete master.info and restart the slaver server.
# For that reason, you may want to leave the lines below untouched
# (commented) and instead use CHANGE MASTER TO (see above)
#
# required unique id between 2 and 2^32 - 1
# (and different from the master)
# defaults to 2 if master-host is set
# but will not function as a slave if omitted
#server-id = 2
#
# The replication master for this slave - required
#master-host =
#
# The username the slave will use for authentication when connecting
# to the master - required
#master-user =
#
# The password the slave will authenticate with when connecting to
# the master - required
#master-password =
#
# The port the master is listening on.
# optional - defaults to 3306
#master-port =
#
# binary logging - not required for slaves, but recommended
#log-bin
# Point the following paths to different dedicated disks
#tmpdir = /tmp/
#log-update = /path-to-dedicated-directory/hostname
# Uncomment the following if you are using BDB tables
#bdb_cache_size = 4M
#bdb_max_lock = 10000
# Uncomment the following if you are using InnoDB tables
#innodb_data_home_dir = /var/lib/mysql/
#innodb_data_file_path = ibdata1:10M:autoextend
#innodb_log_group_home_dir = /var/lib/mysql/
#innodb_log_arch_dir = /var/lib/mysql/
# You can set .._buffer_pool_size up to 50 - 80 %
# of RAM but beware of setting memory usage too high
#innodb_buffer_pool_size = 16M
#innodb_additional_mem_pool_size = 2M
# Set .._log_file_size to 25 % of buffer pool size
#innodb_log_file_size = 5M
#innodb_log_buffer_size = 8M
#innodb_flush_log_at_trx_commit = 1
#innodb_lock_wait_timeout = 50
[mysqldump]
quick
max_allowed_packet = 16M
[mysql]
no-auto-rehash
# Remove the next comment character if you are not familiar with SQL
#safe-updates
[isamchk]
key_buffer = 20M
sort_buffer_size = 20M
read_buffer = 2M
write_buffer = 2M
[myisamchk]
key_buffer = 20M
sort_buffer_size = 20M
read_buffer = 2M
write_buffer = 2M
[mysqlhotcopy]
interactive-timeout


補充



優化table_cachetable_cache指定表高速緩存的大小。每當MySQL訪問一個表時,若是在表緩衝區中還有空間,該表就被打開並放入其 中,這樣能夠更快地訪問表內容。經過檢查峯值時間的狀態值Open_tables和Opened_tables,能夠決定是否須要增長 table_cache的值。若是你發現open_tables等於table_cache,而且opened_tables在不斷增加,那麼你就須要增 加table_cache的值了(上述狀態值可使用SHOW STATUS LIKE ‘Open%tables’得到)。注意,不能盲目地把table_cache設置成很大的值。若是設置得過高,可能會形成文件描述符不足,從而形成性能 不穩定或者鏈接失敗。對於有1G內存的機器,推薦值是128-256。



案例1

:該案例來自一個不是特別繁忙的服務器table_cache – 512open_tables – 103opened_tables – 1273uptime – 4021421 (measured in seconds)該案例中table_cache彷佛設置得過高了。在峯值時間,打開表的數目比table_cache要少得多。



案例2

:該案例來自一臺開發服務器。table_cache – 64open_tables – 64opened-tables – 431uptime – 1662790 (measured in seconds)雖然open_tables已經等於table_cache,可是相對於服務器運行時間來講,opened_tables的值也很是低。 所以,增長table_cache的值應該用處不大。案例3:該案例來自一個upderperforming的服務器table_cache – 64open_tables – 64opened_tables – 22423uptime – 19538該案例中table_cache設置得過低了。雖然運行時間不到6小時,open_tables達到了最大值,opened_tables的值 也很是高。這樣就須要增長table_cache的值。優化key_buffer_sizekey_buffer_size指定索引緩衝區的大小,它決定 索引處理的速度,尤爲是索引讀的速度。經過檢查狀態值Key_read_requests和Key_reads,能夠知道key_buffer_size 設置是否合理。比例key_reads / key_read_requests應該儘量的低,至少是1:100,1:1000更好(上述狀態值可使用SHOW STATUS LIKE ‘key_read%’得到)。key_buffer_size只對MyISAM表起做用。即便你不使用MyISAM表,可是內部的臨時磁盤表是 MyISAM表,也要使用該值。可使用檢查狀態值created_tmp_disk_tables得知詳情。對於1G內存的機器,若是不使用 MyISAM表,推薦值是16M(8-64M)。



案例1:健康情況key_buffer_size – 402649088 (384M)key_read_requests – 597579931key_reads - 56188


案例2:警報狀態key_buffer_size – 16777216 (16M)key_read_requests – 597579931key_reads - 53832731案例1中比例低於1:10000,是健康的狀況;案例2中比例達到1:11,警報已經拉響。

相關文章
相關標籤/搜索