MySQL性能優化——參數配置

目的 

  • 通過根據服務器目前狀況,修改Mysql的系統參數,達到合理利用服務器現有資源,最大合理的提高MySQL性能。

修改MySQL配置

  • 打開MySQL配置文件my.cnf

    vi  /etc/my.cnf

MySQL非緩存參數變量介紹及修改

  • 修改back_log參數值:由默認的50修改爲500.(每個連接256kb,佔用:125M)

    • back_log=500

  • 修改wait_timeout參數值,由默認的8小時,修改爲30分鐘。(本次不用)

    • wait_timeout=1800(單位爲妙)

  • 修改max_connections參數值,由默認的151,修改爲3000(750M)。

    • max_connections=3000

  • 修改max_user_connections值,由默認的0,修改爲800

    • max_user_connections=800

  • 修改thread_concurrency值,由目前默認的8,修改爲64

    • thread_concurrency=64

  • ​​​​​​​添加skip-name-resolve,默認被註釋掉,沒有該參數。

    • skip-name-resolve

  • ​​​​​​​skip-networking,默認被註釋掉。沒有該參數。(本次無用)

    • skip-networking建議被註釋掉,不要開啓

  • ​​​​​​​default-storage-engine(設置MySQL的默認存儲引擎)

    • default-storage-engine= InnoDB(設置InnoDB類型,另外還可以設置MyISAM類型)

    • 設置創建數據庫及表默認存儲類型

      show table status like ‘tablename’顯示錶的當前存儲狀態值

      查看MySQL有哪些存儲狀態及默認存儲狀態

       show engines;

      創建表並指定存儲類型

      CREATE TABLE mytable (id int, title char(20)) ENGINE = INNODB;

      修改表存儲類型:

        Alter table tableName engine =engineName

       

      備註:設置完後把以下幾個開啓:

      # Uncomment the following if you are using InnoDB tables

      innodb_data_home_dir = /var/lib/mysql

      #innodb_data_file_path = ibdata1:1024M;ibdata2:10M:autoextend(要註釋掉,否則會創建一個新的把原來的替換的。)

      innodb_log_group_home_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 = 1000M

      innodb_additional_mem_pool_size = 20M

      # Set .._log_file_size to 25 % of buffer pool size

      innodb_log_file_size = 500M

      innodb_log_buffer_size = 20M

      innodb_flush_log_at_trx_commit = 0

      innodb_lock_wait_timeout = 50

      設置完後一定記得把MySQL安裝目錄地址(我們目前是默認安裝所以地址/var/lib/mysql/)下的ib_logfile0和ib_logfile1刪除掉。否則重啓MySQL起動失敗。

MySQL緩存變量介紹及修改

  • 全局緩存
  • key_buffer_size,本系統目前爲384M,可修改爲400M
    • ​​​​​​​key_buffer_size=400M
    • key_buffer_size是用於索引塊的緩衝區大小,增加它可得到更好處理的索引(對所有讀和多重寫),對MyISAM(MySQL表存儲的一種類型,可以百度等查看詳情)表性能影響最大的一個參數。如果你使它太大,系統將開始換頁並且真的變慢了。嚴格說是它決定了數據庫索引處理的速度,尤其是索引讀的速度。對於內存在4GB左右的服務器該參數可設置爲256M或384M.

      怎麼才能知道key_buffer_size的設置是否合理呢,一般可以檢查狀態值Key_read_requests和Key_reads   ,比例key_reads / key_read_requests應該儘可能的低,比如1:100,1:1000 ,1:10000。其值可以用以下命令查得:show status like 'key_read%';

      比如查看系統當前key_read和key_read_request值爲:

      +---------------------------+---------+

      | Variable_name          | Value |

      +---------------------------+---------+

      | Key_read_requests  | 28535 |

      | Key_reads                | 269     |

      +---------------------------+----------+

      可知道有28535個請求,有269個請求在內存中沒有找到直接從硬盤讀取索引.

      未命中緩存的概率爲:0.94%=269/28535*100%.  一般未命中概率在0.1之下比較好。目前已遠遠大於0.1,證明效果不好。若命中率在0.01以下,則建議適當的修改key_buffer_size值。

       

      MyISAM、InnoDB、MyISAM Merge引擎、InnoDB、memory(heap)、archive

  • innodb_buffer_pool_size(默認128M)
    • ​​​​​​​innodb_buffer_pool_size=1024M(1G)
    • innodb_buffer_pool_size:主要針對InnoDB表性能影響最大的一個參數。功能與Key_buffer_size一樣。InnoDB佔用的內存,除innodb_buffer_pool_size用於存儲頁面緩存數據外,另外正常情況下還有大約8%的開銷,主要用在每個緩存頁幀的描述、adaptive hash等數據結構,如果不是安全關閉,啓動時還要恢復的話,還要另開大約12%的內存用於恢復,兩者相加就有差不多21%的開銷。假設:12G的innodb_buffer_pool_size,最多的時候InnoDB就可能佔用到14.5G的內存。若系統只有16G,而且只運行MySQL,且MySQL只用InnoDB,

      那麼爲MySQL開12G,是最大限度地利用內存了。

      另外InnoDB和 MyISAM 存儲引擎不同, MyISAM 的 key_buffer_size 只能緩存索引鍵,而 innodb_buffer_pool_size 卻可以緩存數據塊和索引鍵。適當的增加這個參數的大小,可以有效的減少 InnoDB 類型的表的磁盤 I/O 。

      當我們操作一個 InnoDB 表的時候,返回的所有數據或者去數據過程中用到的任何一個索引塊,都會在這個內存區域中走一遭。

      可以通過 (Innodb_buffer_pool_read_requests – Innodb_buffer_pool_reads) / Innodb_buffer_pool_read_requests * 100% 計算緩存命中率,並根據命中率來調整 innodb_buffer_pool_size 參數大小進行優化。值可以用以下命令查得:show status like 'Innodb_buffer_pool_read%';

      比如查看當前系統中系統中

      | Innodb_buffer_pool_read_requests      | 1283826 |

      | Innodb_buffer_pool_reads                    | 519         |

      +---------------------------------------------------+-------------+

      其命中率99.959%=(1283826-519)/1283826*100%  命中率越高越好。

  • innodb_additional_mem_pool_size(默認8M)
    • ​​​​​​​innodb_additional_mem_pool_size=20M
  • innodb_log_buffer_size(默認8M)
    • ​​​​​​​innodb_log_buffer_size=20M
    • innodb_log_buffer_size  這是InnoDB存儲引擎的事務日誌所使用的緩衝區。類似於Binlog Buffer,InnoDB在寫事務日誌的時候,爲了提高性能,也是先將信息寫入Innofb Log Buffer中,當滿足innodb_flush_log_trx_commit參數所設置的相應條件(或者日誌緩衝區寫滿)之後,纔會將日誌寫到文件 (或者同步到磁盤)中。可以通過innodb_log_buffer_size 參數設置其可以使用的最大內存空間。

       

      InnoDB 將日誌寫入日誌磁盤文件前的緩衝大小。理想值爲 1M 至 8M。大的日誌緩衝允許事務運行時不需要將日誌保存入磁盤而只到事務被提交(commit)。 因此,如果有大的事務處理,設置大的日誌緩衝可以減少磁盤I/O。 在 my.cnf中以數字格式設置。

      默認是8MB,系的如頻繁的系統可適當增大至4MB~8MB。當然如上面介紹所說,這個參數實際上還和另外的flush參數相關。一般來說不建議超過32MB

       

      注:innodb_flush_log_trx_commit參數對InnoDB Log的寫入性能有非常關鍵的影響,默認值爲1。該參數可以設置爲0,1,2,解釋如下:

      0:log buffer中的數據將以每秒一次的頻率寫入到log file中,且同時會進行文件系統到磁盤的同步操作,但是每個事務的commit並不會觸發任何log buffer 到log file的刷新或者文件系統到磁盤的刷新操作;

      1:在每次事務提交的時候將log buffer 中的數據都會寫入到log file,同時也會觸發文件系統到磁盤的同步;

      2:事務提交會觸發log buffer到log file的刷新,但並不會觸發磁盤文件系統到磁盤的同步。此外,每秒會有一次文件系統到磁盤同步操作。

       

      實際測試發現,該值對插入數據的速度影響非常大,設置爲2時插入10000條記錄只需要2秒,設置爲0時只需要1秒,而設置爲1時則需要229秒。因此,MySQL手冊也建議儘量將插入操作合併成一個事務,這樣可以大幅提高速度。根據MySQL手冊,在存在丟失最近部分事務的危險的前提下,可以把該值設爲0。

       
  • query_cache_size(默認32M)
    • ​​​​​​​query_cache_size=40M
    • query_cache_size: 主要用來緩存MySQL中的ResultSet,也就是一條SQL語句執行的結果集,所以僅僅只能針對select語句。當我們打開了 Query Cache功能,MySQL在接受到一條select語句的請求後,如果該語句滿足Query Cache的要求(未顯式說明不允許使用Query Cache,或者已經顯式申明需要使用Query Cache),MySQL會直接根據預先設定好的HASH算法將接受到的select語句以字符串方式進行hash,然後到Query Cache中直接查找是否已經緩存。也就是說,如果已經在緩存中,該select請求就會直接將數據返回,從而省略了後面所有的步驟(如SQL語句的解析,優化器優化以及向存儲引擎請求數據等),極大的提高性能。根據MySQL用戶手冊,使用查詢緩衝最多可以達到238%的效率。

       

      當然,Query Cache也有一個致命的缺陷,那就是當某個表的數據有任何任何變化,都會導致所有引用了該表的select語句在Query Cache中的緩存數據失效。所以,當我們的數據變化非常頻繁的情況下,使用Query Cache可能會得不償失

       

       Query Cache的使用需要多個參數配合,其中最爲關鍵的是query_cache_size和query_cache_type,前者設置用於緩存 ResultSet的內存大小,後者設置在何場景下使用Query Cache。在以往的經驗來看,如果不是用來緩存基本不變的數據的MySQL數據庫,query_cache_size一般256MB是一個比較合適的大小。當然,這可以通過計算Query Cache的命中率(Qcache_hits/(Qcache_hits+Qcache_inserts)*100))來進行調整。 query_cache_type可以設置爲0(OFF),1(ON)或者2(DEMOND),分別表示完全不使用query cache,除顯式要求不使用query cache(使用sql_no_cache)之外的所有的select都使用query cache,只有顯示要求才使用query cache(使用sql_cache)。如果Qcache_lowmem_prunes的值非常大,則表明經常出現緩衝. 如果Qcache_hits的值也非常大,則表明查詢緩衝使用非常頻繁,此時需要增加緩衝大小;

       

      根據命中率(Qcache_hits/(Qcache_hits+Qcache_inserts)*100))進行調整,一般不建議太大,256MB可能已經差不多了,大型的配置型靜態數據可適當調大

       

      可以通過命令:show status like 'Qcache_%';查看目前系統Query catch使用大小

      | Qcache_hits             | 1892463  |

      | Qcache_inserts        | 35627      |

      命中率98.17%=1892463/(1892463 +35627 )*100

  • 局部緩存
  • read_buffer_size(默認值:2097144即2M)
    • ​​​​​​​read_buffer_size=4M
  • read_rnd_buffer_size(默認值:8388608即8M)
    • ​​​​​​​read_rnd_buffer_size=8M
  • tmp_table_size(默認值:8388608 即:16M)
    • ​​​​​​​tmp_table_size=16M
  • record_buffer:(默認值:)
    • ​​​​​​​
  • ​​​​​​​其它緩存
  • table_cache(默認值:512)
    • TABLE_CACHE(5.1.3及以後版本又名TABLE_OPEN_CACHE)

       

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

      SHOW STATUS LIKE 'Open%tables';

      +---------------------+--------+

      | Variable_name  | Value |

      +---------------------+--------+

      | Open_tables      | 356   |

      | Opened_tables  | 0       |

      +----------------------+-------+

      2 rows in set (0.00 sec)

      open_tables表示當前打開的表緩存數,如果執行flush tables操作,則此係統會關閉一些當前沒有使用的表緩存而使得此狀態值減小;

       

      opend_tables表示曾經打開的表緩存數,會一直進行累加,如果執行flush tables操作,值不會減小。

       

      在mysql默認安裝情況下,table_cache的值在2G內存以下的機器中的值默認時256到512,如果機器有4G內存,則默認這個值 是2048,但這決意味着機器內存越大,這個值應該越大,因爲table_cache加大後,使得mysql對SQL響應的速度更快了,不可避免的會產生 更多的死鎖(dead lock),這樣反而使得數據庫整個一套操作慢了下來,嚴重影響性能。所以平時維護中還是要根據庫的實際情況去作出判斷,找到最適合你維護的庫的 table_cache值。

       

      由於MySQL是多線程的機制,爲了提高性能,每個線程都是獨自打開自己需要的表的文件描 述符,而不是通過共享已經打開的.針對不同存儲引擎處理的方法當然也不一樣

       

      在myisam表引擎中,數據文件的描述符 (descriptor)是不共享的,但是索引文件的描述符卻是所有線程共享的.Innodb中和使用表空間類型有關,假如是共享表空間那麼實際就一個數 據文件,當然佔用的數據文件描述符就會比獨立表空間少.


      mysql手冊上給的建議大小 是:table_cache=max_connections*n

         n表示查詢語句中最大表數, 還需要爲臨時表和文件保留一些額外的文件描述符。

      這個數據遭到很多質疑,table_cache夠用就好,檢查 Opened_tables值,如果這個值很大,或增長很快那麼你就得考慮加大table_cache了.

       

      table_cache:所有線程打開的表的數目。增大該值可以增加mysqld需要的文件描述符的數量。默認值是64.

  • thread_cache_size (服務器線程緩存)
    • ​​​​​​​thread_cache_size=64
    • 默認的thread_cache_size=8,但是看到好多配置的樣例裏的值一般是32,64,甚至是128,感覺這個參數對優化應該有幫助,於是查了下:
      根據調查發現以上服務器線程緩存thread_cache_size沒有進行設置,或者設置過小,這個值表示可以重新利用保存在緩存中線程的數量,當斷開連接時如果緩存中還有空間,那麼客戶端的線程將被放到緩存中,如果線程重新被請求,那麼請求將從緩存中讀取,如果緩存中是空的或者是新的請求,那麼這個線程將被重新創建,如果有很多新的線程,增加這個值可以改善系統性能.通過比較 Connections 和 Threads_created 狀態的變量,可以看到這個變量的作用。(–>表示要調整的值)   根據物理內存設置規則如下:
      1G —> 8
      2G —> 16
      3G —> 32     >3G —> 64

        mysql> show status like 'thread%';
      +—————————-+———-+
      | Variable_name           | Value   |
      +—————————-+———-+
      | Threads_cached       | 0          |  <—當前被緩存的空閒線程的數量
      | Threads_connected  | 1          |  <—正在使用(處於連接狀態)的線程
      | Threads_created       | 1498    |  <—服務啓動以來,創建了多少個線程
      | Threads_running       | 1          |  <—正在忙的線程(正在查詢數據,傳輸數據等等操作)
      +—————————-+———-+

      查看開機起來數據庫被連接了多少次?

      mysql> show status like '%connection%';
      +——————————-+——-+
      | Variable_name              | Value|
      +——————————-+——-+
      | Connections                  | 1504|          –>服務啓動以來,歷史連接數
      | Max_used_connections| 2       |
      +——————————-+——-+

      通過連接線程池的命中率來判斷設置值是否合適?命中率超過90%以上,設定合理。

       (Connections -  Threads_created) / Connections * 100 %

 轉載自:憤怒的碼農

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章