在部署了的GreenPlum集群中進行數據查詢時,發現數據量一旦大了,查詢一跑就中斷,提示某個segment中斷了連接。
ERROR 58M01 "Error on receive from seg0 slice1 192.168.110.84:6000 pid=xxx: server closed the connection unexpectedly" This probably means the server terminated abnormally before or while processing the request
查看master的pg_log中的日志:
seg-1 could not connect to segment: initalization of segwork group failed (cdbgang.c:237)
經過簡單的分析可以猜測是內存相關參數沒有優化好,因為同樣的SQL查詢小一點時間間隔能很快出結果。那么就從兩個方面着手:
1.服務器的內存不夠,導致segment中斷了交互。
2.數據庫參數設置不合理,導致用不了那么多內存。
針對第一個問題:
1)首先排查虛擬機的內存,發現只有8G,感覺有點少,於是加到了32G,仍然出現之前的問題。
2)那么猜想是不是系統設置的限制了內存的使用?於是使用:
prctl -n project.max-shm-memory -i project default
prctl -n project.max-sem-ids -i project default
查看了相應的設置,都很大,不需要修改。因此可以排除是系統的瓶頸,接下來查看數據庫的:
1)直接打開master節點的postgresql.conf文件查看配置,發現shared_buffers及所有的參數都是默認值,優化后。重啟數據庫仍然有上述問題。
2)查看max_statement_mem、statement_mem、gp_vmem_protect_limit三個參數,發現在master上沒有設置,估計這里有問題。
3)使用gpconfig -s statement_mem報錯,提示節點中斷連接。感覺這個錯誤報的非常蛋疼,混淆了思路,以為數據節點有誤。
4)確定gp_vmem_protect_limit參數,發現是8GB,完全夠了。一度陷入停滯,經過查資料和對白配置文件,發現statement_mem參數在conf文件中沒有,那么很可能就是默認值了,於是進了一步操作。
5)打開數據庫,執行select * from gp_settings; 查看數據庫的所有配置,發現statement_mem參數為默認的128MB,因此可以肯定問題了。
6)由於gpconfig查詢參數失敗,就沒有嘗試使用gpconfig來設置參數,采用手動修改每個節點的值。重啟數據庫后,成功解決問題。
后記,后來通過pgconfig -c statement_mem -v 2GB發現是可以設置參數的,就是-s來查詢的時候報錯。rlg,手動改了那么多文件完全可以很簡單搞定的······
Greenplum參數配置優化:
查詢參數
gpconfig --show max_connections
修改參數配置命令
gpconfig-c <parameter name> -v <parameter value> 比如:gpconfig-c log_statement -v DDL 刪除配置 gpconfig -r <parameter name>
work_mem
work_mem(,global,物理內存的2%-4%),segment用作sort,hash操作的內存大小
當PostgreSQL對大表進行排序時,數據庫會按照此參數指定大小進行分片排序,將中間結果存放在臨時文件中,這些中間結果的臨時文件最終會再次合並排序,所以增加此參數可以減少臨時文件個數進而提升排序效率。當然如果設置過大,會導致swap的發生,所以設置此參數時仍需謹慎。
查看現有配置值
gpconfig -s work_mem
Values on all segments are consistent
GUC : work_mem
Master value: 32MB
Segment value: 32MB
修改配置
gpconfig -c work_mem -v 128MB
另一種寫法:SET work_mem TO '64MB' 配置成功返回: gpadmin-[INFO]:-completed successfully with parameters
mainteance_work_mem(
global,CREATE INDEX, VACUUM等時用到,segment用於VACUUM,CREATE INDEX等操作的內存大小,缺省是16兆字節(16MB)。因為在一個數據庫會話里, 任意時刻只有一個這樣的操作可以執行,並且一個數據庫安裝通常不會有太多這樣的工作並發執行, 把這個數值設置得比work_mem更大是安全的。 更大的設置可以改進清理和恢復數據庫轉儲的速度。
查看現有配置值
gpconfig -s maintenance_work_mem
GUC : maintenance_work_mem
Master value: 64MB Segment value: 64MB 修改配置 gpconfig -c maintenance_work_mem -v 256MB
max_statement_mem
設置每個查詢最大使用的內存量,該參數是防止statement_mem參數設置的內存過大導致的內存溢出.
查看現有配置值
gpconfig -s max_statement_mem
Values on all segments are consistent GUC : max_statement_mem Master value: 2000MB Segment value: 2000MB 修改配置 gpconfig -c max_statement_mem -v 2000MB
statement_mem
設置每個查詢在segment主機中可用的內存,該參數設置的值不能超過max_statement_mem設置的值,如果配置了資源隊列,則不能超過資源隊列設置的值。
查看現有配置值
gpconfig -s statement_mem
Values on all segments are consistent GUC : statement_mem Master value: 125MB Segment value: 125MB 修改配置 gpconfig -c statement_mem -v 256MB
gp_vmem_protect_limit
控制了每個segment數據庫為所有運行的查詢分配的內存總量。如果查詢需要的內存超過此值,則會失敗。
查看現有配置值
gpconfig -s gp_vmem_protect_limit
Values on all segments are consistent GUC : gp_vmem_protect_limit Master value: 8192 Segment value: 8192
gp_workfile_limit_files_per_query
SQL查詢分配的內存不足,Greenplum數據庫會創建溢出文件(也叫工作文件)。在默認情況下,一個SQL查詢最多可以創建 100000 個溢出文件,這足以滿足大多數查詢。
該參數決定了一個查詢最多可以創建多少個溢出文件。0 意味着沒有限制。限制溢出文件數據可以防止失控查詢破壞整個系統。
查看現有配置值
gpconfig -s gp_workfile_limit_files_per_query
Values on all segments are consistent GUC : gp_workfile_limit_files_per_query Master value: 100000 Segment value: 100000
gp_statement_mem
服務器配置參數 gp_statement_mem 控制段數據庫上單個查詢可以使用的內存總量。如果語句需要更多內存,則會溢出數據到磁盤。
effective_cache_size
(master節點,可以設為物理內存的85%)
這個參數告訴PostgreSQL的優化器有多少內存可以被用來緩存數據,以及幫助決定是否應該使用索引。這個數值越大,優化器使用索引的可能性也越大。因此這個數值應該設置成shared_buffers加上可用操作系統緩存兩者的總量。通常這個數值會超過系統內存總量的50%以上。
查看現有配置值:
gpconfig -s effective_cache_size
Values on all segments are consistent GUC : effective_cache_size Master value: 512MB Segment value: 512MB 修改配置 gpconfig -c effective_cache_size -v 40960MB
gp_resqueue_priority_cpucores_per_segment
master和每個segment的可以使用的cpu個數,每個segment的分配線程數;
查看現有配置值
gpconfig -s gp_resqueue_priority_cpucores_per_segment
Values on all segments are consistent GUC : gp_resqueue_priority_cpucores_per_segment Master value: 4 Segment value: 4 gpconfig -s checkpoint_segments 修改配置 gpconfig -c gp_resqueue_priority_cpucores_per_segment -v 8
max_connections
最大連接數,Segment建議設置成Master的5-10倍。
max_connections = 200 #(master、standby)
max_connections = 1200 #(segment)
查看現有配置值:
gpconfig -s max_connections
GUC : max_connections
Master value: 250 Segment value: 750 修改配置 gpconfig -c max_connections -v 1200 -m 300
max_prepared_transactions
這個參數只有在啟動數據庫時,才能被設置。它決定能夠同時處於prepared狀態的事務的最大數目(參考PREPARE TRANSACTION命令)。如果它的值被設為0。則將數據庫將關閉prepared事務的特性。它的值通常應該和max_connections的值一樣大。每個事務消耗600字節(b)共享內存。
查看現有配置值:
gpconfig -s max_prepared_transactions
Values on all segments are consistent GUC : max_prepared_transactions Master value: 250 Segment value: 250 修改配置 gpconfig -c max_prepared_transactions -v 300
max_files_per_process
設置每個服務器進程允許同時打開的最大文件數目。缺省是1000。 如果內核強制一個合理的每進程限制,那么你不用操心這個設置。 但是在一些平台上(特別是大多數BSD系統), 內核允許獨立進程打開比個系統真正可以支持的數目大得多得文件數。 如果你發現有"Too many open files"這樣的失敗現像,那么就嘗試縮小這個設置。 這個值只能在服務器啟動的時候設置。
查看現有配置值:
gpconfig -s max_files_per_process
Values on all segments are consistent GUC : max_files_per_process Master value: 1000 Segment value: 1000 修改配置 gpconfig -c max_files_per_process -v 1000
shared_buffers
只能配置segment節點,用作磁盤讀寫的內存緩沖區,開始可以設置一個較小的值,比如總內存的15%,然后逐漸增加,過程中監控性能提升和swap的情況。
gpconfig -s shared_buffers
Values on all segments are consistent GUC : shared_buffers Master value: 64MB Segment value: 125MB 修改配置 gpconfig -c shared_buffers -v 1024MB gpconfig -r shared_buffers -v 1024MB
temp_buffers: 即臨時緩沖區,擁有數據庫訪問臨時數據,GP中默認值為1M,在訪問比較到大的臨時表時,對性能提升有很大幫助。
查看現有配置值:
gpconfig -s temp_buffers
Values on all segments are consistent GUC : temp_buffers Master value: 1024 Segment value: 1024 修改配置 gpconfig -c temp_buffers -v 4096
gp_fts_probe_threadcount:
設置ftsprobe線程數,此參數建議大於等於每台服務器segments的數目。
查看現有配置值:
gpconfig -s gp_fts_probe_threadcount
Values on all segments are consistent GUC : gp_fts_probe_threadcount Master value: 16 Segment value: 16
重啟數據庫,使參數生效
gpstop -u 重新加載配置文件 postgresql.conf 和 pg_hba.conf
