openGauss資料庫作為開源資料庫的後起之秀,這兩年開源社群蓬勃發展,越來越多的公司和企業加入到openGauss開源社群。作為純國産開源的關系型資料庫,目前部分銀行已經嘗試在生産應用openGauss資料庫,同時也有很多合作夥伴在openGauss核心的基礎上推出各自的商業版本。
openGauss資料庫至今為止基本保持三月一次發版的節奏。每次發版都會發現内容非常多,不僅包含大功能的新增和改進,同時也有非常多的問題被修複。可以說openGauss開源社群的投入,并不遜色于傳統的大型商業資料庫公司。國内幾家合作夥伴的加入和貢獻,也讓openGauss資料庫生态越來越好,這也給企業在生産使用openGauss資料庫帶來更大的信心。
作為新的資料庫,如何做好企業及部署,這是值得探讨的地方。這篇文章并不是一個細緻的安裝教程,網上也不缺乏該類教程,而是結合商業資料庫應用和部署的經驗,讨論下openGauss資料庫企業級應用需求下需要考慮的方方面面。
資料庫架構設計
openGauss作為集中式的單機資料庫,這裡的架構設計主要是讨論高可用怎麼做,同城和異地容災怎麼做。
本地高可用
傳統的資料庫本地高可用有兩種比較流行的方式:集中式存儲方式和資料庫複制方式。Db2和Oracle等商業資料庫的部署大部分都是采用集中式存儲的模式。而MySQL資料庫就基本都是通過資料庫複制的模式來實作高可用。
集中式存儲
集中式存儲方案是目前企業級部署中應用最廣泛也是最成熟的方案。資料庫的資料部署在存儲上,上層通過系統的HA工具監控和切換。然而這種方式也有缺點。首先是外置存儲的性能和内置SSD盤的性能差異在資料庫應用場景對比還是比較明顯的。其次是磁盤資料的損壞需要通過資料庫恢複來修複,相對恢複時間較長。最後從部署成本來說,集中式存儲方案部署較重,需要存儲布線等。
資料庫複制
資料庫複制方案是通過資料庫日志的實體或者邏輯同步,在備機實時重做主機的修改,進而保證主備資料庫的資料一緻性。這也是一個非常成熟的方案。Db2和Oracle等商業資料庫都有基于資料庫日志實體同步的功能。MySQL的日志邏輯複制也應用非常廣泛。這種方案下資料庫主機上的存儲采用内置盤,主備的資料是完全隔離的,更好的利用了内置盤的性能和做到了存儲上的隔離。
openGauss資料庫也支援資料庫日志的實體複制和邏輯複制。邏輯複制存在一個比較重大的缺點,就是對于大事務的資料回放性能不好。是以在openGauss資料庫的高可用設計中,資料庫日志實體同步是目前最好的方案。
官方的架構圖也是推薦使用這種方式。openGauss資料庫提供了om工具來幫助部署和管理openGauss資料庫的主備叢集節點。openGauss資料庫的實體複制支援一主多備和級聯備等功能,未來也會加入延時複制功能。openGauss的備機是支援隻讀操作的,可以實作讀寫分離,減少主庫的讀負載。
建議本地高可用就通過資料庫實體同步來實作。建議打開備機可讀,設定wal_level為hot_standby。為了保障資料一緻性,synchronous_commit建議修改為remote_write或者remote_receive。如果隻有一主一從的情況下,建議設定most_available_sync為on。最後通過第三方的高可用叢集軟體來監視openGauss的主從狀态,實作故障自動切換等高可用場景。
用戶端通路方式
openGauss資料庫主從架構下,用戶端如何連接配接到主資料庫呢?又怎麼做讀寫分離?這個時候就需要讨論下用戶端連接配接資料庫的幾種方式:VIP,DNS和主機清單。因為openGauss資料庫的jdbc驅動裡支援設定多個主機,并提供參數設定隻連主節點還是隻連備節點,這也應對了讀寫分離的需求。
VIP
傳統的VIP模式隻能支援應用連接配接到主節點上,從節點的讀請求是不太好設定的。增加讀VIP的管理對于高可用軟體來說就太複雜了。VIP管理還有一個限制是必須屬于同一網段。對于同城雙中心不能采用相同網段的情況下,VIP漂移就不能實作。
DNS
DNS也具備高可用性,但是隻能檢測到機器IP是否存在,不能檢測openGauss的服務,是以采用DNS的高可用相對來說不太适合資料庫來使用。
主機清單
例如下面這個例子就是隻連主庫的用戶端設定:
url=jdbc:postgresql://:26000,:26000/?connectTimeout=5&targetServerType=master&tcpKeepAlive=true
我比較偏向于采用主機清單的方式,通過配置用戶端參數,實作自動主庫發現,負載均衡,隻讀從庫等各類應用場景需求。這種方式也避免了VIP,DNS在不同架構下的管理複雜性,相對更通用一些。缺點是增加了一點用戶端資料源配置的複雜性。
同城容災
資料庫級的同城容災可能會分成不同的級别來實作。金融行業的同城資料中心一般都要求具備全量承載資料和業務的能力。資料庫實作同城容災最主要目标是最小化RPO和RTO名額,在此基礎上可能還會有同城災備資料庫的隻讀通路等需求。同城容災的實作方式也有兩種主流模式:存儲複制和資料庫複制。優缺點和本地高可用差不多。但是如果本地openGauss采用了内置盤部署,那麼也就不支援做存儲複制的容災模式了。是以建議openGauss資料庫還是采用資料庫複制的方式。注意在設定synchronous_standby_names的時候要保證同城至少有一個節點處于資料同步狀态。
這裡稍微讨論下同城容災的幾個定位:
1.同城是否需要保障RPO=0?
金融行業的大部分需要做同城容災的應用都要求RPO=0,不能容忍同城切換丢失資料。是以在設計synchronous_standby_names的時候需要加上同城備機并設定成同步模式。然而雙中心間的網絡穩定性顯然要比同中心要差很多,為了避免設定了強同步後,雙中心網絡抖動可能會影響主機性能,可以考慮設定most_available_sync參數為ON,丢失備機的情況下主機可以斷開備機并恢複工作。
2.同城資料庫是否需要隻讀通路?
資料庫的備機提供隻讀通路的能力,包括同城的資料庫備機。那麼是否真的需要去啟用這個功能呢?從前端業務的性能考慮,顯然同機房通路要比跨機房通路要更快一些。而從後端資料庫的處理能力來說,需要隻讀能力擴充的需求,都是為了滿足減輕主庫的運作壓力,并且還要求應用能夠配置單獨的隻讀資料源,從應用層就解決好讀寫分離。在這些場景需求裡,顯然本地的備機隻讀通路就可以解決這些問題,是以大機率是不需要更新到同城隻讀通路的性能擴充需求的。隻有一種情況下需要同城隻讀通路,那就是為了架構的便利性,同城切換的便利性等需求。這種情況下并不是以擴充性能為目的,而是以技術架構方案的整體性設計需要。
3.同城是否需要自動切換?
這個問題一直是讨論的比較多的地方。保守一點的想法是同城切換都是交給人工來決策的。激進一點的想法是同城都保障不丢資料庫,當然也可以自動切換,交給HA監控并自動化切換修複多好。是以面對不同的選擇,這裡對于同城的定位就不一樣,所涉及的HA架構設計也很不相同。個人認為除非同城雙中心定位完全無主次之分,否則大部分應用還是偏向于運作在主機房,這種情況下,同城切換适合交給人為決策,自動化平台快速實作。
異地容災
異地容災也需要分不同的資料保護類型。可能最關鍵的應用也就是盡可能減少RPO和RTO。這種類型的關鍵應用也是建議通過資料庫主從複制的方式來實作,隻是異地的資料庫節點通常都是設定為異步模式。
openGauss資料庫支援級聯備,也就是從一主多從的某個從庫上,配置一個級聯備機,指向異地容災的資料庫從庫。這也是比較推薦的方式,減少主庫的壓力。
使用者規劃設計
這裡主要讨論下安裝部署裡的作業系統使用者,資料庫使用者等規劃設計。
系統使用者
作業系統使用者主要是安裝openGauss的使用者群組,以及需要使用gsql用戶端通路openGauss資料庫的作業系統使用者。例如華為的openGauss資料庫預設采用omm使用者和dbgrp使用者組,這在華為的高斯分布式産品裡都是這個設計的。我們使用openGauss的時候也延續了這個習慣。
超級使用者
omm作業系統使用者具有openGauss資料庫程式的通路權限,能執行gsql、gs_ctl等工具。而這些工具的權限一般是700,也就是說隻有omm使用者能使用。而通常omm使用者通路本地的openGauss是通過socket,可以使用超級使用者,還可以免密,是以這個使用者完全是交給系統管理者的,不适合交給使用者使用。
應用使用者
那麼如果應用使用者需要使用gsql等工具怎麼辦?這種情況下建議設計一個系統使用者appuser,并為它安裝一個單獨的gsql等工具用戶端,通過IO連接配接資料庫。
資料庫使用者
資料庫使用者也應該分為幾種類型:超級管理者、監控管理者、資料庫管理者和普通資料庫使用者。
超級管理者
一開始initdb的初始使用者就是超級管理者使用者,具有sysadmin的權限。這個使用者通常不會交給應用來使用,甚至不應該當做超級管理者來使用。這個使用者隻能是作為能夠登入到這個作業系統上應急的免密超級使用者。
是以為了管理openGauss資料庫,我們還需要建立一個單獨的管理者使用者具備sysadmin角色權限。例如設計一個gsadmin使用者,在運維工具平台通過這個使用者遠端管理所有的openGauss資料庫。
create user gsadmin with sysadmin password 'xxxxxxxx'
還有一種使用者是遠端備份使用者,建議建立單獨的使用者并sysadmin角色權限。
監控管理者
openGauss資料庫從2.0.0版本開始提供了monadmin角色。這個角色權限能夠通路所有的系統視圖。是以對于監控使用者,建議配置這個角色即可。
create user monadmin with monadmin password 'xxxxxxxx'
資料庫管理者
openGauss的資料庫是互相隔離的。對于每一個獨立的資料庫,可以設定一個資料庫管理者角色的使用者,給予全庫的管理權限。
grant all privileges on database <dbname> to <username>
這種使用者通常也是作為應用來連接配接的使用者,具備全庫的對象管理能力,也具備資料修改查詢能力。這是一種很常見的用法, 很少有在應用資料源配置連接配接使用者的時候還繼續做細緻的權限分離。當然資料庫權限管理是具備相關能力的。
普通資料庫使用者
除了本應用系統使用的資料庫管理者使用者,可能還存在類似跨系統通路的特殊需求情況。例如抽取資料的使用者,隻讀通路的使用者等。這些使用者建議建立單獨的最小授權使用者。
白名單
在openGauss資料庫的目錄下,設計了pg_hba.conf配置檔案,用來定義使用者通路資料庫的方式,也可以稱作是白名單管理。定義了在什麼通路類型下,通路哪個資料庫,是哪個使用者,從哪裡來通路,采用何種驗證方式。這些組合可以實作很複雜的白名單過濾規則。這種可以過濾IP的使用者通路控制有點像mysql,但是又完全不一樣。openGauss裡的資料庫使用者名對應的就是一個使用者角色,不像mysql,如果使用者名裡的IP不一樣,其實算是不同的使用者。
不過從金融行業的實踐來看,資料庫伺服器和應用伺服器等在隔離的網絡區内,主機間的通路控制通過網絡來管理,基本不需要底層資料庫來實作複雜的管控。為了管理友善,不如全部放開資料庫級别的ip管控。下面這個例子使用gs_guc工具配置整個叢集所有的白名單:
gs_guc reload -N all -I all -h "host all all 0.0.0.0/0 sha256"
翻譯過來就是任何IP基于host請求過來的所有使用者通路所有資料庫都采用sha256加密算法驗證使用者。
檔案系統設計
openGauss資料庫建議配置至少兩個獨立的檔案系統。一個用來放資料庫,一個用來放資料庫運作中産生的歸檔日志,診斷日志等。
資料庫
資料庫存放的路徑建議放在單獨的檔案系統上。部分重要的業務系統也建議将線上日志pg_xlog放在單獨的檔案系統上,與資料data分開。然而從實際情況來看,data和xlog采用不同的檔案系統,除非底層的盤也是獨立的,性能是沒有什麼差別的。是以暫時建議采用一個就可以了。
診斷日志
資料庫運作中産生的診斷日志,審計日志,歸檔日志,core檔案等,都是不影響資料庫運作的,但是又持續不斷的産生的。是以需要單獨規劃一個檔案系統來存放,同時做好這些日志的清理政策。這個檔案系統也可以用來規劃存放腳本檔案,備份檔案,跑批檔案等臨時檔案。
例如将歸檔日志路徑、審計日志路徑、core檔案路徑和診斷日志路徑都設定到這個檔案系統下面。
gs_guc set -c "archive_command = 'cp %p /gausslog/archive/%f'"
gs_guc set -c "audit_directory='/gausslog/log/omm/pg_audit'"
gs_guc set -c "bbox_dump_path='/gausslog/corefile'"
gs_guc set -c "log_directory='/gausslog/log/omm/pg_log'"
其他運維設計
規劃好了資料庫安裝,下一步是設計相關運維需求方案。
性能參數設定
安裝完成之後最先需要的是根據業務負載需求設定相關參數。這些參數細節比較多,需要好好閱讀相關資料再做選擇。其中max_process_memory和shared_buffers是比較關鍵的記憶體參數,建議按照作業系統記憶體總量(資料庫獨占資源)的70%和50%來設定。
增量檢查點和雙寫開關應該打開。這個是openGauss相對于postgresql比較大的改進機制,解決了全量檢查點的性能瓶頸問題。enable_opfusion開關也建議打開,對于高并發小事務的競争會有改善。
gs_guc set -c "cstore_buffers = 128MB"
gs_guc set -c "enable_alarm = off"
gs_guc set -c "enable_delta_store = on"
gs_guc set -c "enable_double_write = on"
gs_guc set -c "enable_incremental_checkpoint = on"
gs_guc set -c "enable_wdr_snapshot = off"
gs_guc set -c "enable_xlog_prune = on"
gs_guc set -c "log_min_duration_statement = 1s"
gs_guc set -c "maintenance_work_mem=1GB"
gs_guc set -c "max_connections = 2000"
gs_guc set -c "max_files_per_process = 10000"
gs_guc set -c "max_prepared_transactions = 2000"
gs_guc set -c "session_timeout = 0"
gs_guc set -c "shared_buffers = 2GB"
gs_guc set -c "temp_buffers = 128MB"
gs_guc set -c "update_lockwait_timeout = 1min"
gs_guc set -c "wal_buffers = 64MB"
gs_guc set -c "wdr_snapshot_interval = 10min"
gs_guc set -c "work_mem = 512MB"
gs_guc set -c "log_temp_files = 100MB"
gs_guc set -c "enable_mergejoin = ON"
gs_guc set -c "enable_nestloop = ON"
gs_guc set -c "advance_xlog_file_num = 10"
gs_guc set -c "pagewriter_sleep = 1000ms"
gs_guc set -c "xloginsert_locks = 50"
gs_guc set -c "lockwait_timeout = 1min"
gs_guc set -c "enable_opfusion = off"
gs_guc set -c "max_process_memory=3GB"
自動管理
為了降低DBA的運維工作量,使用openGauss的過程裡要充分利用好資料庫的自動管理機制。尤其是跟性能動态調整相關的機制。
自動統計資訊收集分析
openGauss資料庫内部的執行計劃有兩種選擇方式,基于規則和基于代價。基于代價的這種方式依賴于資料庫的統計資訊。資料庫的統計資訊是由analyze指令采集的。除了人為發出analyze指令,openGauss内部也提供了自動analyze的功能。建議打開autoanalyze和autovacuum的開關。
自動清理
openGauss的存儲引擎還有一個比較特殊的地方,就是update和delete都會保留原元組,作為MVCC的基石。這種機制會不停産生死元組,并且一直占據表内的空間。這種情況下需要vacuum指令來回收這些空間,後續的資料才能使用。openGauss提供了autovacuum機制,能夠根據表的資料變化量自動觸發vacuum機制,回收死元組。但是在vacuum受到MVCC機制影響,清理資料會檢查資料庫裡最老的事務。是以除了打開autovacuum,還需要控制好資料庫内的最長事務。是以需要監控pg_stat_activity中xact_start不為空的事務,判斷長事務。如果遇到一直處于idle in transaction狀态的連接配接,一定要檢查處理。
安全審計
openGauss資料庫提供了安全審計功能,可以設定相關審計參數,将審計日志記錄下來,通過sql函數pg_query_audit檢視審計記錄。
下表展示了審計相關的配置項。其中DML操作和SELECT操作審計功能建議關閉,因為審計量太大了。
配置項 | 描述 |
使用者登入、登出審計 | 參數:audit_login_logout 預設值為7,表示開啟使用者登入、退出的審計功能。設定為0表示關閉使用者登入、退出的審計功能。不推薦設定除0和7之外的值。 |
資料庫啟動、停止、恢複和切換審計 | 參數:audit_database_process 預設值為1,表示開啟資料庫啟動、停止、恢複和切換的審計功能。 |
使用者鎖定和解鎖審計 | 參數:audit_user_locked 預設值為1,表示開啟審計使用者鎖定和解鎖功能。 |
使用者通路越權審計 | 參數:audit_user_violation 預設值為0,表示關閉使用者越權操作審計功能。 |
授權和回收權限審計 | 參數:audit_grant_revoke 預設值為1,表示開啟審計使用者權限授予和回收功能。 |
資料庫對象的CREATE,ALTER,DROP操作審計 | 參數:audit_system_object 預設值為12295,表示隻對DATABASE、SCHEMA、USER、DATA SOURCE這四類資料庫對象的CREATE、ALTER、DROP操作進行審計。 |
具體表的INSERT、UPDATE和DELETE操作審計 | 參數:audit_dml_state 預設值為0,表示關閉具體表的DML操作(SELECT除外)審計功能。 |
SELECT操作審計 | 參數:audit_dml_state_select 預設值為0,表示關閉SELECT操作審計功能。 |
COPY審計 | 參數:audit_copy_exec 預設值為0,表示關閉copy操作審計功能。 |
存儲過程和自定義函數的執行審計 | 參數:audit_function_exec 預設值為0,表示不記錄存儲過程和自定義函數的執行審計日志。 |
SET審計 | 參數:audit_set_parameter 預設值為1,表示記錄set操作審計日志 |
如果需要針對特殊使用者進行SQL級别的審計,可以使用AUDIT POLICY統一審計方式。打開enable_security_policy開關統一審計政策才可以生效。
統一審計預設輸出節點的rsyslog日志中,在作業系統背景服務配置檔案/etc/rsyslog.conf中添加代碼:
local0.* /var/log/localmessages
執行如下指令:
sudo touch /var/log/localmessages
sudo chmod 600 localmessages
sudo systemctl restart rsyslog
然後通過建立 AUDIT POLICY實作。
CREATE AUDIT POLICY [ IF NOT EXISTS ] policy_name { { privilege_audit_clause | access_audit_clause } [ filter_group_clause ] [ ENABLE | DISABLE ] };
例如僅審計user1使用者的iud操作:
CREATE AUDIT POLICY adt1 ACCESS INSERT,UPDATE,DELETE FILTER ON ROLES(user1);
監控告警
對于企業級的資料庫部署運維,監控告警和應急處理是最重要的。對于openGauss的監控告警需要達到的目标是能夠準确發現問題并告警,能夠快速基于監控資料分析根因并處理。為了實作這個目标,建議openGauss資料庫的監控一方面要全面采集性能和狀态名額,另一方面對于關鍵名額實作準确告警。
監控
openGauss提供了很多監控視圖。特别是dbe_perf模式下的監控視圖,内容包括OS、Instance、Memory、File、Object、Workload、Session/Thread、Transaction、Query、Cache/IO、Utility、Lock、Wait Events、Configuration、Operator和Workload Manager等對象的監控。這些監控視圖也是WDR報告的快照來源。建議統一采集這些性能快照視圖資料,通過智能運維管理和分析。
告警
相對于監控資料采集的全面性,告警名額需要挑選全局有意義的對象。重要的告警有監控資料庫狀态、主從複制狀态、線上會話數量、等待會話數量、長事務、長SQL、死鎖、復原語句數量等。
備份恢複
openGauss資料庫支援的備份方式還是比較全面的。而企業級的資料庫在這方面要求也很高。一方面為了出問題盡快恢複,資料庫定期備份政策都比較激進,另一方面備份過程還要盡量減少性能影響和資源占用。例如銀行一般每天都會備份全量資料庫,時刻備份歸檔日志,為了減少性能影響,備份會選擇從庫執行。如果是遠端備份,那麼還會采用單獨的備份網段,與生産業務網隔離。
很多國内備份廠家目前也一直在測試備份openGauss資料庫,相信很快就會有類似于NBU這樣的備份産品出現,并在企業級應用。openGauss資料庫支援遠端備份,目前也可以建立基于網絡的備份伺服器,通過備份專用網,統一排程管理所有資料庫的備份。
結束語
其實做好openGauss企業級部署,就是拿之前對于Db2和Oracle的運維标準來建設openGauss資料庫的運維體系。openGauss資料庫技術特點與這些商業資料庫相比差别不大,目前欠缺的也隻是生态和産品成熟性。相信這兩方面會越來越好,是以我對于openGauss資料庫在企業中的應用前景非常看好,也希望其盡快成為一個合格的國産替代品。