http://blog.pgaddict.com/posts/performance-since-postgresql-7-4-to-9-4-pgbench
硬件和系統配置
操作系統 | Ubuntu13.04 |
系統位數 | 64 |
CPU | Intel(R) Core(TM)2 Duo CPU |
內存 | 4G |
硬盤 | Seagate ST2000DM001-1CH164 |
測試工具 | PostgreSQL-9.1.11 |
測試工具
工具名稱 | pgbench |
數據量 | 200W(整個數據庫大小約爲300M) |
模擬客戶端數 | 4 |
線程數 | 4 |
測試時間 | 60秒 |
準備命令:pgbench -i -s 20 pgbenchdb
測試命令:pgbench -r -j4 -c4 -T60 testdb
配置文件
默認的配置配置文件是保存在/etc/postgresql/VERSION/main目錄下的postgresql.conf文件
如果想查看參數修改是否生效,可以用psql連接到數據庫後,用<show 選項名> 來查看。
如果要修改shared_buffers, 在ubuntu下可能需要執行命令<sysctl -w>Managing Kernel Resources
主要選項
選項 | 默認值 | 說明 | 是否優化 | 原因 |
max_connections | 100 | 允許客戶端連接的最大數目 | 否 | 因爲在測試的過程中,100個連接已經足夠 |
fsync | on | 強制把數據同步更新到磁盤 | 是 | 因爲系統的IO壓力很大,爲了更好的測試其他配置的影響,把改參數改爲off |
shared_buffers | 24MB | 決定有多少內存可以被PostgreSQL用於緩存數據(推薦內存的1/4) | 是 | 在IO壓力很大的情況下,提高該值可以減少IO |
work_mem | 1MB | 使內部排序和一些複雜的查詢都在這個buffer中完成 | 是 | 有助提高排序等操作的速度,並且減低IO |
effective_cache_size | 128MB | 優化器假設一個查詢可以用的最大內存,和shared_buffers無關(推薦內存的1/2) | 是 | 設置稍大,優化器更傾向使用索引掃描而不是順序掃描 |
maintenance_work_mem | 16MB | 這裏定義的內存只是被VACUUM等耗費資源較多的命令調用時使用 | 是 | 把該值調大,能加快命令的執行 |
wal_buffer | 768kB | 日誌緩存區的大小 | 是 | 可以降低IO,如果遇上比較多的併發短事務,應該和commit_delay一起用 |
checkpoint_segments | 3 | 設置wal log的最大數量數(一個log的大小爲16M) | 是 | 默認的48M的緩存是一個嚴重的瓶頸,基本上都要設置爲10以上 |
checkpoint_completion_target | 0.5 | 表示checkpoint的完成時間要在兩個checkpoint間隔時間的N%內完成 | 是 | 能降低平均寫入的開銷 |
commit_delay | 0 | 事務提交後,日誌寫到wal log上到wal_buffer寫入到磁盤的時間間隔。需要配合commit_sibling | 是 | 能夠一次寫入多個事務,減少IO,提高性能 |
commit_siblings | 5 | 設置觸發commit_delay的併發事務數,根據併發事務多少來配置 | 是 | 減少IO,提高性能 |
測試數據
測試的數據是運行3次,取平均值。
關閉fsync是爲了更好的體現出其他參數對PostgreSQL的影響。
參數 | 修改值 | 事務總數 | tps(包括建立連接) | tps(不包括建立連接) |
默認設置 | 8464 | 140.999792 | 141.016182 | |
fsync | off | 92571 | 1479.969755 | 1480.163355 |
shared_buffers | 1GB | 100055 | 1635.759275 | 1635.977823 |
work_mem | 10MB | 101209 | 1665.804812 | 1666.04082 |
effective_cache_size | 2GB | 98209 | 1636.733152 | 1636.970271 |
maintenance_work_mem | 512MB | 92930 | 1548.029233 | 1548.223108 |
checkpoint_segments | 32 | 195982 | 3265.995 | 3266.471064 |
checkpoint_completion_target | 0.9 | 194390 | 3239.406493 | 3239.842596 |
wal_buffer | 8MB | 198639 | 3310.241458 | 3310.724067 |
恢復fsync | off | 11157 | 185.883542 | 185.909849 |
commit_delay && commit_siblings | 10 && 4 | 11229 | 187.103538 | 187.131747 |
總結
事務總數 | tps(包括建立連接) | tps(不包括建立連接) | |
優化前 | 8464 | 140.999792 | 141.016182 |
優化後(fsync=on) | 11229 | 187.103538 | 187.131747 |
優化後(fsync=off) | 198639 | 3310.241458 | 3310.724067 |
在fsync打開的情況下,優化後性能能夠提升30%左右。因爲有部分優化選項在默認的SQL測試語句中沒有體現出它的優勢,如果到實際測試中,提升應該不止30%。 測試的過程中,主要的瓶頸就在系統的IO,如果需要減少IO的負荷,最直接的方法就是把fsync關閉,但是這樣就會在掉電的情況下,可能會丟失部分數據。
-------------------------------------------------------------------------------
pg中性能相關常調參數
參數名稱 | 參數意義 | 優化思路 |
shared_buffers | 數據庫服務器將使用的共享內存緩衝區大小,該緩衝區爲所有連接共用。從磁盤讀入的數據(主要包括表和索引)都緩存在這裏。 | 提高該值可以減少數據庫的磁盤IO。 |
work_mem | 聲明內部排序和哈希操作可使用的工作內存大小。該內存是在開始使用臨時磁盤文件之前使用的內存數目。數值以kB爲單位的,缺省是 1024 (1MB)。請注意對於複雜的查詢,可能會同時併發運行好幾個排序或者哈希操作,每個都會使用這個參數聲明的這麼多內存,然後纔會開始求助於臨時文件。同樣,好幾個正在運行的會話可能會同時進行排序操作。因此使用的總內存可能是 work_mem 的好幾倍。ORDER BY, DISTINCT 和mergejoin都要用到排序操作,而哈希操作在哈希連接、哈希聚集和以哈希爲基礎的 IN 子查詢處理中都會用到。該參數是會話級參數。 | 執行排序操作時,會根據work_mem的大小決定是否將一個大的結果集拆分爲幾個小的和 work_mem差不多大小的臨時文件寫入外存。顯然拆分的結果是導致了IO,降低了排序的速度。因此增加work_mem有助於提高排序的速度。通常設置時可以逐漸調大,知道數據庫在排序的操作時不會有大量的寫文件操作即可。該內存每個連接一份,當併發連接較多時候,該值不宜過大。 |
effective_cache_size | 優化器假設一個查詢可以使用的最大內存(包括pg使用的和操作系統緩存),和shared_buffer等內存無關,只是給優化器生成計劃使用的一個假設值。 | 設置稍大,優化器更傾向使用索引掃描而不是順序掃描,建議的設置爲可用空閒內存的25%,這裏的可用空閒內存指的是主機物理內存在運行pg時得空閒值。 |
maintenance_work_mem | 這裏定義的內存只是在CREATE INDEX, VACUUM等時用到,因此用到的頻率不高,但是往往這些指令消耗比較多的資源,因此應該儘快讓這些指令快速執行完畢。 | 在數據庫導入數據後,執行建索引等操作時,可以調大,比如512M。 |
wal_buffers | 日誌緩衝區,日誌緩衝區的大小。 | 兩種情況下要酌情調大:1.單事務的數據修改量很大,產生的日誌大於wal_buffers,爲了避免多次IO,調大該值。 2.系統中併發小數據量修改的短事務較多,並且設置了commit_delay,此時wal_buffers需要容納多個事務(commit_siblings個)的日誌,調大該值避免多次IO。 |
commit_delay | 事務提交後,日誌寫到wal_buffer上到wal_buffer寫到磁盤的時間間隔。 | 如果併發的非只讀事務數目較多,可以適當增加該值,使日誌緩衝區一次刷盤可以刷出較多的事務,減少IO次數,提高性能。需要和commit_sibling配合使用。 |
commit_siblings | 觸發commit_delay等待的併發事務數,也就是系統的併發活躍事務數達到了該值事務纔會等待commit_delay的時間纔將日誌刷盤,如果系統中併發活躍事務達不到該值,commit_delay將不起作用,防止在系統併發壓力較小的情況下事務提交後空等其他事務。 | 應根據系統併發寫的負載配置。例如統計出系統併發執行增刪改操作的平均連接數,設置該值爲該平均連接數。 |
fsync | 設置爲on時,日誌緩衝區刷盤時,需要確認已經將其寫入了磁盤,設置爲off時,由操作系統調度磁盤寫的操作,能更好利用緩存機制,提高IO性能。 | 該性能的提高是伴隨了數據丟失的風險,當操作系統或主機崩潰時,不保證刷出的日誌是否真正寫入了磁盤。應依據操作系統和主機的穩定性來配置。 |
autovacuum | 是否開啓自動清理進程(如開啓需要同時設置參數stats_start_collector = on,stats_row_level = on,),整理數據文件碎片,更新統計信息。 | 如果系統中有大量的增刪改操作,建議打開自動清理進程,這樣一方面可以增加數據文件的物理連續性,減少磁盤的隨機IO,一方面可以隨時更新數據庫的統計信息,使優化器可以選擇最優的查詢計劃得到最好的查詢性能。如果系統中只有只讀的事務,那麼關閉自動清理進程。 |
autovacuum_naptime | 自動清理進程執行清理分析的時間間隔 | 應該根據數據庫的單位時間更新量來決定該值,一般來說單位時間的更新量越大該時間間隔應該設置越短。由於自動清理對系統的開銷較大,該值應該謹慎配置(不要過小)。 |
bgwriter_delay | 後臺寫進程的自動執行時間 | 後臺寫進程的作用是將shared_buffer裏的髒頁面寫回到磁盤,減少checkpoint的壓力,如果系統數據修改的壓力一直很大,建議將該時間間隔設置小一些,以免積累的大量的髒頁面到checkpoint,使checkpoint時間過長(checkpoint期間系統響應速度較慢)。 |
bgwriter_lru_maxpages | 後臺寫進程一次寫出的髒頁面數 | 依據系統單位時間數據的增刪改量來修改 |
bgwriter_lru_multiplier | 後臺寫進程根據最近服務進程需要的buffer數量乘上這個比率估算出下次服務進程需要的buffer數量,在使用後臺寫進程寫回髒頁面,使緩衝區能使用的乾淨頁面達到這個估計值。 | 依據系統單位時間數據的增刪改量來修改。 |
2。 tpcc/壓力測試時pg常調參數示例:
max_connections = 200
#根據數據量儘量調大shared_buffer值,把所有數據都放到內存中更好,
#曾經在32G內存的服務器上把shared_buffert調到了26G
#wal_buffers根據產生的wal日誌量也適當設大點
shared_buffers=1200MB
wal_buffers = 2000kB
#work_mem要適可而止,每個連接都要用這麼大的
work_mem = 1024kB
#一般做做檢查點的時間長於壓力測試的時間,這樣性能數據會更好,等壓力測試完了再去做檢查點吧。
Checkpoint_timeout=120min
bgwriter_delay = 10ms
bgwriter_lru_maxpages = 75
full_page_writes = off
log_min_messages = fatal
#壓力測試時由於高併發等鎖的時間可以長一些
deadlock_timeout = 3s
#平時實踐有些應用中把位圖掃描和順序掃描關了性能會更好
enable_bitmapscan = off
enable_seqscan = off
#如果是隻讀的壓力測試,還可以關掉沒事的後臺寫進程等