15 個有用的 MySQL/MariaDB 性能調整和優化技巧(轉載的一篇好文)

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

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

2009 年 4 月,MySQL 被 Oracle 收購。其結果是MySQL 社區分裂,建立了一個叫 MariaDB 的分支 。建立該分支的主要緣由是爲了保持這個項目能夠在 GPL 下的自由。git

今天,MySQL 和 MariaDB 是用於相似 WordPress、Joomla、Magento 和其餘 web 應用程序的最流行的 RDMS 之一(若是不是最多的)。github

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

在 RHEL/CentOS 7 上安裝 LAMPsql

在 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 0 0

 

如今咱們將 MySQL 移動到新磁盤中

首先中止 MySQL 服務:

# service mysqld stop

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

# service httpd stop# 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 服務:

# service mysqld start# service httpd start# 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

「交換」是一個當系統移動部份內存到一個稱爲 「交換空間」 的特殊磁盤空間時的過程。一般當你的系統用完物理內存後就會出現這種狀況,系統將信息寫入磁盤而不是釋放一些內存。正如你猜想的磁盤比你的內存要慢得多。

該選項默認狀況下是啓用的:

# sysctl vm.swappiness 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服務器:

# mysql -u root -pmysql> set global max_connections = 300;

 

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

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

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

mysql> show status like 'Threads_created';mysql> show status like 'Connections';

你能夠用如下公式來計算線程池的命中率:

100 - ((Threads_created / Connections) * 100)

若是你獲得一個較低的數字,這意味着大多數 mysql 鏈接使用新的線程,而不是從緩存加載。在這種狀況下,你須要增長thread_cache_size。

這裏有一個好處是能夠動態地改變 thread_cache_size 而無需重啓 MySQL 服務。你能夠經過如下方式來實現:

mysql> set global thread_cache_size = 16;

 

7. 禁用 MySQL 的 DNS 反向查詢

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

當 DNS 配置錯誤或服務器出現問題時,這極可能會致使延遲。這就是爲何要關閉 DNS 的反向查詢的緣由,你能夠在你的配置文件中添加如下選項去設定:

[mysqld]# Skip reverse DNS lookup of clientsskip-name-resolve

更改後你須要重啓 MySQL 服務。

 

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

若是你有不少重複的查詢而且數據不常常改變 – 請使用緩存查詢。 人們經常不理解 query_cache_size 的實際含義而將此值設置爲 GB 級,這實際上會下降服務器的性能。

背後的緣由是,在更新過程當中線程須要鎖定緩存。一般設置爲 200-300 MB應該足夠了。若是你的網站比較小的,你能夠嘗試給 64M 並在之後及時去增長。

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

query_cache_type = 1query_cache_limit = 256Kquery_cache_min_res_unit = 2kquery_cache_size = 80M

 

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

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

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

[mysqld]tmp_table_size= 64Mmax_heap_table_size= 64M

 

10. 啓用 MySQL 慢查詢日誌

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

slow-query-log = 1slow-query-log-file = /var/lib/mysql/mysql-slow.loglong_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。它們都是可使用超大文件和大容量存儲卷的企業級日誌型文件系統。

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

文件系統XFSExt4Btrfs文件系統最大容量8EB1EB16EB最大文件大小8EB16TB16EB

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

 

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

MySQL 把數據拆分紅包。一般一個包就是發送到客戶端的一行數據。max_allowed_packet 變量定義了能夠被髮送的最大的包。

此值設置得太低可能會致使查詢速度變得很是慢,而後你會在 MySQL 的錯誤日誌看到一個錯誤。建議將該值設置爲最大包的大小。

 

14. 測試 MySQL 的性能優化

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

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

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

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

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

MySQL 性能優化

 

15. 優化和修復 MySQL 數據庫

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

# mysqlcheck -u root -p --auto-repair --check --optimize --all-databases# mysqlcheck -u root -p --auto-repair --check --optimize databasename

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

相關文章
相關標籤/搜索