本文目錄一覽:
- 1、怎麼在linux中使用mysql
- 2、linux 下怎麼優化mysql佔用內存
- 3、linux apache 性能調優 8G 8核 的伺服器
- 4、linux 下怎麼優化mysql佔用內存?
- 5、優化MYSQL資料庫的方法
怎麼在linux中使用mysql
這個要看你的linux的發行版。常見的Linux的發行版有Ubuntu、CentOS等。那麼不同的發行版,整個的安裝、管理、使用都會有一些不同,但是具體差距不大,不過這個要是用文字去說,那就不是三兩句話能說清楚的了。建議你去 91課 去看一下MySQL的視頻課程,每節課也就10分鐘以內,短時間就能了解在不同的linux發行版當中如何使用MySQL。百度知道是不允許髮網址鏈接,所以你還是自己搜索一下吧
linux 下怎麼優化mysql佔用內存
Linux 進程通過 C 標準庫中的內存分配函數 malloc 向系統申請內存,但是到真正與內核交互之間,其實還隔了一層,即內存分配管理器(memory allocator)。常見的內存分配器包括:ptmalloc(Glibc)、tcmalloc(Google)、jemalloc(FreeBSD)。MySQL 默認使用的是 glibc 的 ptmalloc 作為內存分配器。
內存分配器採用的是內存池的管理方式,處在用戶程序層和內核層之間,它響應用戶的分配請求,向操作系統申請內存,然後將其返回給用戶程序。
為了保持高效的分配,分配器通常會預先向操作系統申請一塊內存,當用戶程序申請和釋放內存的時候,分配器會將這些內存管理起來,並通過一些演算法策略來判斷是否將其返回給操作系統。這樣做的最大好處就是可以避免用戶程序頻繁的調用系統來進行內存分配,使用戶程序在內存使用上更加高效快捷。
關於 ptmalloc 的內存分配原理,個人也不是非常了解,這裡就不班門弄斧了,有興趣的同學可以去看下華庭的《glibc 內存管理 ptmalloc 源代碼分析》【文末鏈接】。
關於如何選擇這三種內存分配器,網上資料大多都是推薦摒棄 glibc 原生的 ptmalloc,而改用 jemalloc 或者 tcmalloc 作為默認分配器。因為 ptmalloc 的主要問題其實是內存浪費、內存碎片、以及加鎖導致的性能問題,而 jemalloc 與 tcmalloc 對於內存碎片、多線程處理優化的更好。
目前 jemalloc 應用於 Firefox、FaceBook 等,並且是 MariaDB、Redis、Tengine 默認推薦的內存分配器,而 tcmalloc 則應用於 WebKit、Chrome 等。
linux apache 性能調優 8G 8核 的伺服器
[檢測工具]
為了得到完整的調試結果,建議你採用 ApacheBench 或者 httperf之類的軟體。如果你對非 LAMP 架構的伺服器測試有興趣的話,建議你採用微軟的免費軟體: Web Application Stress Tool(需要 NT 或者 2000)。 (其它伺服器測試工具)
檢測 Apache ,採用 top d 1 顯示所有進程的 CPU 和內存情況。另外,還採用 apachectl status 命令
[硬體優化]
1、升級硬體的一般規則:對於 PHP 腳本而言,主要的瓶頸是 CPU ,對於靜態頁面而言,瓶頸是內存和網路。一台 400 Mhz 的普通奔騰機器所下載的靜態頁面就能讓 T3 專線(45Mbps)飽和。
2、採用 hdparm 來優化磁碟,一般能提升 IDE 磁碟讀寫性能 200%,但是對 SCSI 硬碟也有效果。(不同類型的硬碟對比)
[策略優化]
3、Apache 處理 PHP 腳本的速度要比靜態頁面慢 2-10 倍,因此盡量採用多的靜態頁面,少的腳本。
4、PHP 腳本如果不做緩衝,每次調用都需要編譯,因此,安裝一個 PHP 緩衝產品能提升 25-100% 的性能。
5、如果你採用了 Linux 系統,建議升級內核到 2.4,因為靜態頁面由內核服務。
6、另外一項緩衝技術是把不常修改的 PHP 頁面採用 HTML 緩衝輸出。
7、不要在 Web 伺服器上運行 X-Windows ,關掉沒有必要運行的進程。
8、如果能夠用文本就不要用圖像,盡量減小圖片的尺寸。
9、分散負載,把資料庫伺服器放到另外的機器上去。採用另外低端的機器服務圖片和 HTML 頁面,如果所有的靜態頁面在另外一台伺服器上處理,可以設置 httpd.conf 中的 KeepAlives 為 off ,來減少斷開連接的時間。
10、以上所有的方法都是針對單機而言的,如果你覺得系統還是不夠快,可以採用集群,負載均衡,緩衝技術。採用 Squid 作為緩衝,配置 Squid 的方法。
[編譯優化]
11、把基於文件的會話切換到基於共享內存的會話。編譯 PHP 時採用 –with-mm 選項,在 php.ini 中設置 set session.save_handler=mm 。這個簡單的修改能讓會話管理時間縮短一半。
12、採用最新版本的 Apache ,並把 PHP 編譯其中,或者採用 DSO 模式,不要採用 CGI 方式。
13、編譯 PHP 時,建議採用如下的參數:
–enable-inline-optimization –disable-debug
[配置優化]
14、修改 httpd.conf :
# 關閉 DNS lookups,PHP 腳本只拿 IP 地址
HostnameLookups off
15、如果網路擁擠,CPU 資源不夠用,採用 PHP 的 HTML 壓縮功能:
output_handler = ob_gzhandler
PHP 4.0.4 的用戶請不要使用,因為存在內存泄漏問題。
16、修改 httpd.conf 中的 SendBufferSize 為你最大的頁面文件的大小。加大內核的 TCP/IP 寫緩衝大小。
17、採用資料庫的持久連接時,不要把 MaxRequestsPerChild 設置得太大。
[第三方軟體優化]
18、如果喜歡從修改 Apache 源碼入手,可以安裝 lingerd。在頁面產生和發送後,每個 Apache 進程都會浪費一段時光在客戶連接上,Lingerd 能接管這項工作,讓 Apache 迅速服務下一個客戶請求。
19、如果你足夠勇敢的話,還可以採用 Silicon Graphics 的 Accelerated Apache 補丁。這個工程能使 Apache 1.3 快 10 倍,使 Apache 2.0 快 4 倍。
安裝一個 PHP 緩衝產品能提升 25-100% 的性能。
[Linux系統優化]
1.清理伺服器磁碟碎片:
不論Linux文件系統採用什麼文件格式(ext3、JFS、XFS、ReiserFS )、何種類型的硬碟(IDE 、SCSI),隨著時間的推移文件系統都會趨向於碎片化。ext3、JFS等高級文件系統可以減少文件系統的碎片化,但是並沒有消除。在繁忙的資料庫伺服器中,隨著時間的過去,文件碎片化將降低硬碟性能,硬碟性能從硬碟讀出或寫入數據時才能注意到。時間長了會發現每個磁碟上確實積累了非常多的垃圾文件,釋放磁碟空間可以幫助系統更好地工作。Linux最好的整理磁碟碎片的方法是做一個完全的備份,重新格式化分區,然後從備份恢復文件。但是對於7×24小時工作關鍵任務伺服器來說是比較困難的。Kleandisk是一個高效的磁碟清理工具,它能把磁碟上的文件分成不同的”組”,比如把所有的”core”文件歸成一組(Group),這樣要刪除所有core文件時只要刪除這個組就行了。core文件是當軟體運行出錯時產生的文件,它對於軟體開發人員比較有用,對於其他用戶(比如電子郵件伺服器)卻沒有任何意義。因此,如果沒有軟體開發的需要,見到core文件就可以將其刪除。
2、開啟硬碟DMA
現在使用的IDE硬碟基本支持DMA66/100/133(直接內存讀取)但是Linux發行版本安裝後一般沒有打開,可以 /etc/rc.d/rc.local 最後面加上一行: /sbin/hdparm -d1 –x66 -c3 -m16 /dev/hda 這樣以後每次開機,硬碟的 DMA 就會開啟,不必每次手動設定。添加前後你可以使用命令:hdparm -Tt /dev/hda 來測試對比一下。
3、調整緩衝區刷新參數
Linux內核中,包含了一些對於系統運行態的可設置參數。緩衝刷新的參數可以通過調整 /proc/sys/vm/bdflush文件來完成,這個文件的格式是這樣的:
每一欄是一個參數,其中最重要的是前面幾個參數。第一個數字是在”dirty”緩衝區達到多少的時候強制喚醒bdflush進程刷新硬碟,第二個數字是每次讓bdflush進程刷新多少個dirty塊。所謂dirty塊是必須寫到磁碟中的緩存塊。接下來的參數是每次允許bd flush將多少個內存塊排入空閑的緩衝塊列表。 以上值為RHEL 4.0中的預設值。可以使用兩種方法修改:
(1)使用命令
# echo “100 128 128 512 5000 3000 60 0 0″/proc/sys/vm/bdflush
並將這條命令加到/etc/rc.d/rc.local文件中去。
(2)在/etc/sysctl.conf 文件中加入如下行:
以上的設置加大了緩衝區大小,降低了bdflush被啟動的頻度,VFS的緩衝刷新機制是Linux文件系統高效的原因之一。
4、優化輸入輸出
I/O程序對Linux系統性能也是相當重要的,網路硬體I/O對伺服器尤其重要。現在大多數Linux伺服器使用10/100 Mb乙太網。如果有較重的網路負載,則可以考慮千兆乙太網卡。如果沒有能力購買千兆網卡的話:可以使用多塊網卡虛擬成為一塊網卡,具有相同的IP地址。這項技術,在Linux中,這種技術稱為Bonding。Bonding在Linux2.4以上內核中已經包含了,只需要在編譯的時候把網路設備選項中的 Bonding driver support選中見圖1。當然利用Bonding技術配置雙網卡綁定的前提條件是兩塊網卡晶元組型號相同,並且都具備獨立的BIOS晶元。
然後,重新編譯核心,重新起動計算機,執行如下命令:
現在兩塊網卡已經象一塊一樣工作了。這樣可以提高集群節點間的數據傳輸.bonding對於伺服器來是個比較好的選擇,在沒有千兆網卡時,用兩塊100兆網卡作bonding,可大大提高伺服器到交換機之間的帶寬.但是需要在交換機上設置連接bonding網卡的兩個子口映射為同一個虛擬介面。編輯 /etc/modules.conf文件,加入如下內容,以使系統在啟動時載入Bonding模塊。
「mode」的值表示工作模式,共有0、1、2和3四種模式,這裡設定為0。Bonding工作在負載均衡(Load Balancing (round-robin))方式下,即兩塊網卡同時工作,這時理論上Bonding能提供兩倍的帶寬。Bonding運行在網卡的混雜(Promisc)模式下,而且它將兩塊網卡的MAC地址修改為一樣的。混雜模式就是網卡不再只接收目的硬體地址是自身MAC地址的數據幀,而是可以接收網路上所有的幀。
5、減少虛擬終端機的數量。
Linux安裝後系統默認是6個虛擬終端機,也就是 CTRL+ALT F1~F6 那六個,作為伺服器使用可以關掉其中四個,只留下 CTRL+ALT F1~F2,大約省下 4 Mbytes 的內存,但是這樣一來,X-Window 會從原來的 CTRL+ALT F7 變成 CTRL+ALT F3 。 修改 /etc/inittab 中,將 mingetty 3 ~6 全部加上 # 字型大小 。
6. 關閉一些不用的服務
Linux伺服器在啟動時需要啟動很多系統服務,它們向本地和網路用戶提供了Linux的系統功能介面,直接面嚮應用程序和用戶。提供這些服務的程序是由運行在後台的守護進程(daemons)來執行的。守護進程是生存期長的一種進程。它們獨立於控制終端並且周期性的執行某種任務或等待處理某些發生的事件。他們常常在系統引導裝入時啟動,在系統關閉時終止。linux系統有很多守護進程,大多數伺服器都是用守護進程實現的。如Web服務http等。同時,守護進程完成許多系統任務,比如,作業規划進程crond、列印進程lqd等。
linux 下怎麼優化mysql佔用內存?
Linux 進程通過 C 標準庫中的內存分配函數 malloc 向系統申請內存,但是到真正與內核交互之間,其實還隔了一層,即內存分配管理器(memory allocator)。常見的內存分配器包括:ptmalloc(Glibc)、tcmalloc(Google)、jemalloc(FreeBSD)。MySQL 默認使用的是 glibc 的 ptmalloc 作為內存分配器。
內存分配器採用的是內存池的管理方式,處在用戶程序層和內核層之間,它響應用戶的分配請求,向操作系統申請內存,然後將其返回給用戶程序。
為了保持高效的分配,分配器通常會預先向操作系統申請一塊內存,當用戶程序申請和釋放內存的時候,分配器會將這些內存管理起來,並通過一些演算法策略來判斷是否將其返回給操作系統。這樣做的最大好處就是可以避免用戶程序頻繁的調用系統來進行內存分配,使用戶程序在內存使用上更加高效快捷。
關於 ptmalloc 的內存分配原理,個人也不是非常了解,這裡就不班門弄斧了,有興趣的同學可以去看下華庭的《glibc 內存管理 ptmalloc 源代碼分析》【文末鏈接】。
關於如何選擇這三種內存分配器,網上資料大多都是推薦摒棄 glibc 原生的 ptmalloc,而改用 jemalloc 或者 tcmalloc 作為默認分配器。因為 ptmalloc 的主要問題其實是內存浪費、內存碎片、以及加鎖導致的性能問題,而 jemalloc 與 tcmalloc 對於內存碎片、多線程處理優化的更好。
目前 jemalloc 應用於 Firefox、FaceBook 等,並且是 MariaDB、Redis、Tengine 默認推薦的內存分配器,而 tcmalloc 則應用於 WebKit、Chrome 等。
優化MYSQL資料庫的方法
在開始演示之前,我們先介紹下兩個概念。
概念一,數據的可選擇性基數,也就是常說的cardinality值。
查詢優化器在生成各種執行計劃之前,得先從統計信息中取得相關數據,這樣才能估算每步操作所涉及到的記錄數,而這個相關數據就是cardinality。簡單來說,就是每個值在每個欄位中的唯一值分布狀態。
比如表t1有100行記錄,其中一列為f1。f1中唯一值的個數可以是100個,也可以是1個,當然也可以是1到100之間的任何一個數字。這裡唯一值越的多少,就是這個列的可選擇基數。
那看到這裡我們就明白了,為什麼要在基數高的欄位上建立索引,而基數低的的欄位建立索引反而沒有全表掃描來的快。當然這個只是一方面,至於更深入的探討就不在我這篇探討的範圍了。
概念二,關於HINT的使用。
這裡我來說下HINT是什麼,在什麼時候用。
HINT簡單來說就是在某些特定的場景下人工協助MySQL優化器的工作,使她生成最優的執行計劃。一般來說,優化器的執行計劃都是最優化的,不過在某些特定場景下,執行計劃可能不是最優化。
比如:表t1經過大量的頻繁更新操作,(UPDATE,DELETE,INSERT),cardinality已經很不準確了,這時候剛好執行了一條SQL,那麼有可能這條SQL的執行計劃就不是最優的。為什麼說有可能呢?
來看下具體演示
譬如,以下兩條SQL,
A:
select * from t1 where f1 = 20;
B:
select * from t1 where f1 = 30;
如果f1的值剛好頻繁更新的值為30,並且沒有達到MySQL自動更新cardinality值的臨界值或者說用戶設置了手動更新又或者用戶減少了sample page等等,那麼對這兩條語句來說,可能不準確的就是B了。
這裡順帶說下,MySQL提供了自動更新和手動更新表cardinality值的方法,因篇幅有限,需要的可以查閱手冊。
那回到正題上,MySQL 8.0 帶來了幾個HINT,我今天就舉個index_merge的例子。
示例表結構:
mysql desc t1;+————+————–+——+—–+———+—————-+| Field | Type | Null | Key | Default | Extra |+————+————–+——+—–+———+—————-+| id | int(11) | NO | PRI | NULL | auto_increment || rank1 | int(11) | YES | MUL | NULL | || rank2 | int(11) | YES | MUL | NULL | || log_time | datetime | YES | MUL | NULL | || prefix_uid | varchar(100) | YES | | NULL | || desc1 | text | YES | | NULL | || rank3 | int(11) | YES | MUL | NULL | |+————+————–+——+—–+———+—————-+7 rows in set (0.00 sec)
表記錄數:
mysql select count(*) from t1;+———-+| count(*) |+———-+| 32768 |+———-+1 row in set (0.01 sec)
這裡我們兩條經典的SQL:
SQL C:
select * from t1 where rank1 = 1 or rank2 = 2 or rank3 = 2;
SQL D:
select * from t1 where rank1 =100 and rank2 =100 and rank3 =100;
表t1實際上在rank1,rank2,rank3三列上分別有一個二級索引。
那我們來看SQL C的查詢計劃。
顯然,沒有用到任何索引,掃描的行數為32034,cost為3243.65。
mysql explain format=json select * from t1 where rank1 =1 or rank2 = 2 or rank3 = 2\G*************************** 1. row ***************************EXPLAIN: { “query_block”: { “select_id”: 1, “cost_info”: { “query_cost”: “3243.65” }, “table”: { “table_name”: “t1”, “access_type”: “ALL”, “possible_keys”: [ “idx_rank1”, “idx_rank2”, “idx_rank3” ], “rows_examined_per_scan”: 32034, “rows_produced_per_join”: 115, “filtered”: “0.36”, “cost_info”: { “read_cost”: “3232.07”, “eval_cost”: “11.58”, “prefix_cost”: “3243.65”, “data_read_per_join”: “49K” }, “used_columns”: [ “id”, “rank1”, “rank2”, “log_time”, “prefix_uid”, “desc1”, “rank3” ], “attached_condition”: “((`ytt`.`t1`.`rank1` = 1) or (`ytt`.`t1`.`rank2` = 2) or (`ytt`.`t1`.`rank3` = 2))” } }}1 row in set, 1 warning (0.00 sec)
我們加上hint給相同的查詢,再次看看查詢計劃。
這個時候用到了index_merge,union了三個列。掃描的行數為1103,cost為441.09,明顯比之前的快了好幾倍。
mysql explain format=json select /*+ index_merge(t1) */ * from t1 where rank1 =1 or rank2 = 2 or rank3 = 2\G*************************** 1. row ***************************EXPLAIN: { “query_block”: { “select_id”: 1, “cost_info”: { “query_cost”: “441.09” }, “table”: { “table_name”: “t1”, “access_type”: “index_merge”, “possible_keys”: [ “idx_rank1”, “idx_rank2”, “idx_rank3” ], “key”: “union(idx_rank1,idx_rank2,idx_rank3)”, “key_length”: “5,5,5”, “rows_examined_per_scan”: 1103, “rows_produced_per_join”: 1103, “filtered”: “100.00”, “cost_info”: { “read_cost”: “330.79”, “eval_cost”: “110.30”, “prefix_cost”: “441.09”, “data_read_per_join”: “473K” }, “used_columns”: [ “id”, “rank1”, “rank2”, “log_time”, “prefix_uid”, “desc1”, “rank3” ], “attached_condition”: “((`ytt`.`t1`.`rank1` = 1) or (`ytt`.`t1`.`rank2` = 2) or (`ytt`.`t1`.`rank3` = 2))” } }}1 row in set, 1 warning (0.00 sec)
我們再看下SQL D的計劃:
不加HINT,
mysql explain format=json select * from t1 where rank1 =100 and rank2 =100 and rank3 =100\G*************************** 1. row ***************************EXPLAIN: { “query_block”: { “select_id”: 1, “cost_info”: { “query_cost”: “534.34” }, “table”: { “table_name”: “t1”, “access_type”: “ref”, “possible_keys”: [ “idx_rank1”, “idx_rank2”, “idx_rank3” ], “key”: “idx_rank1”, “used_key_parts”: [ “rank1” ], “key_length”: “5”, “ref”: [ “const” ], “rows_examined_per_scan”: 555, “rows_produced_per_join”: 0, “filtered”: “0.07”, “cost_info”: { “read_cost”: “478.84”, “eval_cost”: “0.04”, “prefix_cost”: “534.34”, “data_read_per_join”: “176” }, “used_columns”: [ “id”, “rank1”, “rank2”, “log_time”, “prefix_uid”, “desc1”, “rank3” ], “attached_condition”: “((`ytt`.`t1`.`rank3` = 100) and (`ytt`.`t1`.`rank2` = 100))” } }}1 row in set, 1 warning (0.00 sec)
加了HINT,
mysql explain format=json select /*+ index_merge(t1)*/ * from t1 where rank1 =100 and rank2 =100 and rank3 =100\G*************************** 1. row ***************************EXPLAIN: { “query_block”: { “select_id”: 1, “cost_info”: { “query_cost”: “5.23” }, “table”: { “table_name”: “t1”, “access_type”: “index_merge”, “possible_keys”: [ “idx_rank1”, “idx_rank2”, “idx_rank3” ], “key”: “intersect(idx_rank1,idx_rank2,idx_rank3)”, “key_length”: “5,5,5”, “rows_examined_per_scan”: 1, “rows_produced_per_join”: 1, “filtered”: “100.00”, “cost_info”: { “read_cost”: “5.13”, “eval_cost”: “0.10”, “prefix_cost”: “5.23”, “data_read_per_join”: “440” }, “used_columns”: [ “id”, “rank1”, “rank2”, “log_time”, “prefix_uid”, “desc1”, “rank3” ], “attached_condition”: “((`ytt`.`t1`.`rank3` = 100) and (`ytt`.`t1`.`rank2` = 100) and (`ytt`.`t1`.`rank1` = 100))” } }}1 row in set, 1 warning (0.00 sec)
對比下以上兩個,加了HINT的比不加HINT的cost小了100倍。
總結下,就是說表的cardinality值影響這張的查詢計劃,如果這個值沒有正常更新的話,就需要手工加HINT了。相信MySQL未來的版本會帶來更多的HINT。
原創文章,作者:XUZPF,如若轉載,請註明出處:https://www.506064.com/zh-tw/n/130917.html