1. 程式人生 > >【MySQL】15個有用的MySQL/MariaDB性能調整和優化技巧

【MySQL】15個有用的MySQL/MariaDB性能調整和優化技巧

cache 實踐 isam 今天 都是 第一個 斷開 企業 最新

MySQL 是一個強大的開源關系數據庫管理系統(簡稱 RDBMS)。它發布於 1995 年(20年前)。它采用結構化查詢語言(SQL),這可能是數據庫內容管理中最流行的選擇。最新的 MySQL 版本是 5.6.25,於 2015 年 5 月 29 日發布。

關於 MySQL 一個有趣的事實是它的名字來自於 Michael Widenius(MySQL 的創始人)的女兒“ My”。盡管有許多關於 MySQL 有趣的傳聞,不過本文主要是向你展示一些有用的實踐,以幫助你管理你的 MySQL 服務器。

2009 年 4 月,MySQL 被 Oracle 收購。其結果是MySQL 社區分裂,創建了一個叫 MariaDB 的分支 。創建該分支的主要原因是為了保持這個項目可以在 GPL 下的自由。

今天,MySQL 和 MariaDB 是用於類似 WordPress、Joomla、Magento 和其他web 應用程序的最流行的 RDMS 之一(如果不是最多的)。

這篇文章將告訴你一些基本的,但非常有用的關於如何優化 MySQL/MariaDB 性能的技巧。註意,本文假定您已經安裝了 MySQL 或 MariaDB。如果你仍然不知道如何在系統上安裝它們,你可以按照以下說明去安裝:

在 RHEL/CentOS 7 上安裝 LAMP

在 Fedora 22 上安裝 LAMP

在 Ubuntu 15.04 安裝 LAMP

在 Debian 8 上安裝 MariaDB

在 Gentoo Linux

上安裝 MariaDB

在 Arch Linux 上安裝 MariaDB

重要提示: 在開始之前,不要盲目的接受這些建議。每個MySQL 設置都是不同的,在進行任何更改之前需要慎重考慮。

你需要明白這些:

MySQL/MariaDB 配置文件位於 /etc/my.cnf。 每次更改此文件後你需要重啟 MySQL 服務,以使更改生效。

這篇文章使用 MySQL 5.6 版本。

1. 啟用 InnoDB 的每張表一個數據文件設置

首先,有一個重要的解釋, InnoDB 是一個存儲引擎。MySQL 和 MariaDB 使用InnoDB 作為默認存儲引擎。以前,MySQL 使用系統表空間來保存數據庫中的表和索引。這意味著服務器唯一的目的就是數據庫處理,它們的存儲盤不用於其它目的。

InnoDB 提供了更靈活的方式,它把每個數據庫的信息保存在一個 .ibd 數據文件中。每個 .idb 文件代表它自己的表空間。通過這樣的方式可以更快地完成類似 “TRUNCATE” 的數據庫操作,當刪除或截斷一個數據庫表時,你也可以回收未使用的空間。

這樣配置的另一個好處是你可以將某些數據庫表放在一個單獨的存儲設備。這可以大大提升你磁盤的 I/O 負載。

MySQL 5.6及以上的版本默認啟用 innodb_file_per_table。你可以在 /etc/my.cnf 文件中看到。該指令看起來是這樣的:

innodb_file_per_table=1

2. 將 MySQL 數據庫數據存儲到獨立分區上

註意:此設置只在 MySQL 上有效, 在 MariaDB 上無效。

有時候操作系統的讀/寫會降低你 MySQL 服務器的性能,尤其是如果操作系統和數據庫的數據位於同一塊磁盤上。因此,我建議你使用單獨的磁盤(最好是 SSD)用於 MySQL 服務。

要完成這步,你需要將新的磁盤連接到你的計算機/服務器上。對於這篇文章,我假定磁盤掛在到 /dev/sdb。

下一步是準備新的分區:

#fdisk /dev/sdb

現在按 “N” 來創建新的分區。接著按 “P”,使其創建為主分區。在此之後,從 1-4 設置分區號。之後,你可以選擇分區大小。這裏按 enter。在下一步,你需要配置分區的大小。

如果你希望使用全部的磁盤,再按一次 enter。否則,你可以手動設置新分區的大小。準備就緒後按“w” 保存更改。現在,我們需要為我們的新分區創建一個文件系統。這可以用下面命令輕松地完成:

#mkfs.ext4 /dev/sdb1

現在我們會掛載新分區到一個目錄。我在根目錄下創建了一個名為 “ssd” 的目錄:

#mkdir /ssd/

掛載新分區到剛才創建的目錄下:

#mount /dev/sdb1  /ssd/

你可以在 /etc/fstab 文件中添加如下行設置為開機自動掛載:

/dev/sdb1 /ssd ext3 defaults 00

現在我們將MySQL 移動到新磁盤中

首先停止 MySQL 服務:

# service mysqld stop

我建議你??同時停止 Apache/nginx,以防止任何試圖寫入數據庫的操作:

  1. # service httpd stop
  2. # service nginx stop

現在復制整個 MySQL 目錄到新分區中:

#cp /var/lib/mysql /ssd/ -Rp

這可能需要一段時間,具體取決於你的 MySQL 數據庫的大小。一旦這個過程完成後重命名 MySQL 目錄:

#mv /var/lib/mysql /var/lib/mysql-backup

然後創建一個符號鏈接:

#ln -s /ssd/mysql /var/lib/mysql

現在啟動你的 MySQL 和 web 服務:

  1. # service mysqld start
  2. # service httpd start
  3. # service nginx start

以後你的數據庫將使用新的磁盤訪問。

3. 優化使用 InnoDB 的緩沖池

InnoDB 引擎在內存中有一個緩沖池用於緩存數據和索引。這當然有助於你更快地執行MySQL/MariaDB 查詢語句。選擇合適的內存大小需要一些重要的決策並對系統的內存消耗有較多的認識。

下面是你需要考慮的:

其它的進程需要消耗多少內存。這包括你的系統進程,頁表,套接字緩沖。

你的服務器是否專門用於 MySQL 還是你運行著其它非常消耗內存的服務。

在一個專用的機器上,你可能會把 60-70%的內存分配給 innodb_buffer_pool_size。如果你打算在一個機器上運行更多的服務,你應該重新考慮專門用於 innodb_buffer_pool_size 的內存大小。

你需要設置 my.cnf 中的此項:

innodb_buffer_pool_size

4. 在 MySQL 中避免使用 Swappiness

“交換”是一個當系統移動部分內存到一個稱為“交換空間” 的特殊磁盤空間時的過程。通常當你的系統用完物理內存後就會出現這種情況,系統將信息寫入磁盤而不是釋放一些內存。正如你猜測的磁盤比你的內存要慢得多。

該選項默認情況下是啟用的:

  1. #sysctl vm.swappiness
  2. vm.swappiness= 60

運行以下命令關閉 swappiness:

#sysctl -w vm.swappiness=0

5. 設置 MySQL 的最大連接數

max_connections 指令告訴你當前你的服務器允許多少並發連接。MySQL/MariaDB 服務器允許有 SUPER 權限的用戶在最大連接之外再建立一個連接。只有當執行 MySQL 請求的時候才會建立連接,執行完成後會關閉連接並被新的連接取代。

請記住,太多的連接會導致內存的使用量過高並且會鎖住你的 MySQL 服務器。一般小網站需要 100-200 的連接數,而較大可能需要 500-800 甚至更多。這裏的值很大程度上取決於你 MySQL/MariaDB 的使用情況。

你可以動態地改變 max_connections 的值而無需重啟MySQL服務器:

  1. # mysql -u root -p
  2. mysql>setglobal max_connections = 300;

6. 配置 MySQL 的線程緩存數量

thread_cache_size 指令用來設置你服務器緩存的線程數量。當客戶端斷開連接時,如果當前線程數小於thread_cache_size,它的線程將被放入緩存中。下一個請求通過使用緩存池中的線程來完成。

要提高服務器的性能,你可以設置 thread_cache_size 的值相對高一些。你可以通過以下方法來查看線程緩存命中率:

  1. mysql>show status like ‘Threads_created‘;
  2. mysql>show status like ‘Connections‘;

你可以用以下公式來計算線程池的命中率:

100 - ((Threads_created / Connections) * 100)

如果你得到一個較低的數字,這意味著大多數mysql 連接使用新的線程,而不是從緩存加載。在這種情況下,你需要增加thread_cache_size

這裏有一個好處是可以動態地改變 thread_cache_size 而無需重啟 MySQL 服務。你可以通過以下方式來實現:

mysql>setglobal thread_cache_size = 16;

7. 禁用 MySQL 的 DNS 反向查詢

默認情況下當新的連接出現時,MySQL/MariaDB會進行 DNS 查詢解析用戶的 IP 地址/主機名。對於每個客戶端連接,它的 IP 都會被解析為主機名。然後,主機名又被反解析為 IP 來驗證兩者是否一致。

當 DNS 配置錯誤或服務器出現問題時,這很可能會導致延遲。這就是為什麽要關閉 DNS 的反向查詢的原因,你可以在你的配置文件中添加以下選項去設定:

  1. [mysqld]
  2. #Skip reverse DNS lookup of clients
  3. skip-name-resolve

更改後你需要重啟 MySQL 服務。

8. 配置 MySQL 的查詢緩存容量

如果你有很多重復的查詢並且數據不經常改變 – 請使用緩存查詢。人們常常不理解 query_cache_size 的實際含義而將此值設置為 GB 級,這實際上會降低服務器的性能。

背後的原因是,在更新過程中線程需要鎖定緩存。通常設置為 200-300 MB應該足夠了。如果你的網站比較小的,你可以嘗試給 64M 並在以後及時去增加。

在你的 MySQL 配置文件中添加以下設置:

  1. query_cache_type= 1
  2. query_cache_limit= 256K
  3. query_cache_min_res_unit= 2k
  4. query_cache_size= 80M

9. 配置臨時表容量和內存表最大容量

tmp_table_sizemax_heap_table_size 這兩個變量的大小應該相同,它們可以讓你避免磁盤寫入。tmp_table_size 是內置內存表的最大空間。如果表的大小超出限值將會被轉換為磁盤上的 MyISAM 表。

這會影響數據庫的性能。管理員通常建議在服務器上設置這兩個值為每 GB 內存給 64M。

  1. [mysqld]
  2. tmp_table_size=64M
  3. max_heap_table_size=64M

10. 啟用 MySQL 慢查詢日誌

記錄慢查詢可以幫助你定位數據庫中的問題並幫助你調試。這可以通過在你的 MySQL 配置文件中添加以下值來啟用:

  1. slow-query-log= 1
  2. slow-query-log-file = /var/lib/mysql/mysql-slow.log
  3. long_query_time= 1

第一個變量啟用慢查詢日誌,第二個告訴 MySQL 實際的日誌文件存儲位置。使用 long_query_time 來定義完成 MySQL 查詢多少用時算長。

11. 檢查 MySQL 的空閑連接

空閑連接會消耗資源,可以的話應該被終止或者刷新。空閑連接是指處於 “sleep” 狀態並且保持了很長一段時間的連接。你可以通過運行以下命令查看空閑連接:

# mysqladmin processlist -u root -p | grep “Sleep”

這會顯示處於睡眠狀態的進程列表。當代碼使用持久連接到數據庫時會出現這種情況。使用 PHP 調用 mysql_pconnect 可以打開這個連接,執行完查詢之後,刪除認證信息並保持連接為打開狀態。這會導致每個線程的緩沖都被保存在內存中,直到該線程結束。

首先你要做的就是檢查代碼問題並修復它。如果你不能訪問正在運行的代碼,你可以修改 wait_timeout 變量。默認值是 28800 秒,而你可以安全地將其降低到 60 :

wait_timeout=60

12. 為 MySQL 選擇正確的文件系統

選擇正確的文件系統對數據庫至關重要。在這裏你需要考慮的最重要的事情是 - 數據的完整性,性能和易管理性。

按照 MariaDB 的建議,最好的文件系統是XFS、ext4 和 Btrfs。它們都是可以使用超大文件和大容量存儲卷的企業級日誌型文件系統。

下面你可以找到一些關於這三個文件系統的有用信息:

文件系統

XFS

Ext4

Btrfs

文件系統最大容量

8EB

1EB

16EB

最大文件大小

8EB

16TB

16EB

我們的這篇文章詳細介紹了 Linux 文件系統的利與弊: Linux 文件系統解析

13. 設置 MySQL 允許的最大數據包

MySQL 把數據拆分成包。通常一個包就是發送到客戶端的一行數據。max_allowed_pa??cket 變量定義了可以被發送的最大的包。

此值設置得過低可能會導致查詢速度變得非常慢,然後你會在 MySQL 的錯誤日誌看到一個錯誤。建議將該值設置為最大包的大小。

14. 測試 MySQL 的性能優化

你應該定期檢查 MySQL/MariaDB 的性能。這將幫助你了解資源的使用情況是否發生了改變或需要進行改進。

有大量的測試工具可用,但我推薦你一個簡單易用的。該工具被稱為 mysqltuner。

使用下面的命令下載並運行它:

  1. #wget https://github.com/major/MySQLTuner-perl/tarball/master
  2. #tar xf master
  3. #cd major-MySQLTuner-perl-993bc18/
  4. # ./mysqltuner.pl

你將收到有關 MySQL 使用的詳細報告和推薦提示。下面是默認 MariaDB 安裝的輸出樣例:

15. 優化和修復 MySQL 數據庫

有時候 MySQL/MariaDB 數據庫中的表很容易崩潰,尤其是服務器意外關機、文件系統突然崩潰或復制過程中仍然訪問數據庫。幸運的是,有一個稱為 ‘mysqlcheck‘ 的免費開源工具,它會自動檢查、修復和優化 Linux 中數據庫的所有表。

  1. # mysqlcheck -u root -p --auto-repair --check --optimize--all-databases
  2. # mysqlcheck -u root -p --auto-repair --check --optimizedatabasename

就是這些!我希望上述文章對你有用,並幫助你優化你的MySQL 服務器。一如往常,如果你有任何疑問或評論,請在下面的評論部分提交。

【MySQL】15個有用的MySQL/MariaDB性能調整和優化技巧