幾種常用(閉源、開源)關系型數據庫的架構和實現原理解讀
一、 Oracle
(一) Oracle 架構
Oracle Server包括數據庫(Database)和實例(Instance)兩大部分,兩者相互獨立。數據庫由數據文件 、控制文件和日志文件組成,實例由內存池和后臺進程組成,示意圖如下:
一臺Oracle Server可創建多個Database,不同的Database之間相互獨立。每個Database有屬于自己的全套相關文件,如:密碼文件,參數文件,數據文件,控制文件和日志文件
Database由一系列物理文件(如二維表文件)組成。用戶不能直接讀取Database中的內容,必須通過Oracle instance才能讀取,一個Instance只能連接一個Database,但是一個Database可以被多個Instance連接。
各功能組件說明如下:
1、用戶連接進程
用戶連接進程是連接用戶和Oracle Instance的橋梁。包括:用戶進程、服務進程和PGA
- 用戶進程User Process
當一個Database User請求連接到Oracle Server時,Oracle Server創建的User Process。
- Server Process服務進程
用于處理Database User和Oracle Server之間的連接。
- 程序全局區PGA
PGA:由Server Process分配,用于當前User Session的內存區,不同的用戶擁有不同的PGA。PGA包含了Server Process數據和控制信息的內存區域。包括棧空間、 Session Info、 私有SQL區。
2、SGA(System Global Area)
SGA與Oracle性能息息相關,在Instance啟動時被分配,關閉時被釋放。主要包含如下幾種數據結構:
- 數據庫緩沖區(Database buffer cache)
oracle 執行SQL語句的區域。當進行數據更新或數據查詢時,用戶執行的SQL語句不會直接對磁盤上的數據文件進行更改操作,而是首先將數據文件復制到數據庫緩沖區緩存,再更改或查詢緩存中的副本。此外,被頻繁訪問的數據塊會存在于數據庫緩沖區緩存中。
- 日志緩沖區(Redo log Buffer)
用于短期存儲redo log。
- 共享池(Shared Pool)
用于緩存所有頻繁執行的代碼和頻繁訪問的對象定義。共享池內有下列三種數據結構:
庫緩沖(library cache):存儲最近執行的代碼
數據字典緩存(data dictionary cache):存儲最近使用的對象定義
PL/SQL緩沖區(PL/SQL buffer):用于存儲過程、函數、打包的過程、打包的函數、對象類型定義和觸發器。
- 大型池(Large Buffer)
用于共享的服務器進程。
- JAVA池(Java Buffer):
只有當應用程序需要在數據庫中運行java存儲程序時,才需要java池。
3、后臺進程
后臺進程主要用于數據庫管理 ,是Oracle Instance和Oracle Database的聯系紐帶,分為核心進程和非核心進程。
1) 核心進程:
- 數據庫寫入進程(DBWn)
Server process連接Oracle后,通過數據庫寫進程(DBWn)將數據緩沖區中的“臟緩沖區” 的數據塊寫入到數據文件;
- 檢查點進程(CKPT)
Checkpoint (CKPT)檢查點進程主要用于更新數據文件頭,更新控制文件和觸發DBWn數據庫寫進程。
- 進程監視進程(PMON)
當后臺進程執行失敗后負責清理數據庫緩存和閑置資源,是Oracle的自動維護機制。
- 系統監視進程(SMON)
用途如下:
當數據庫實例崩潰時,用于數據庫實例的自動恢復。
清除作廢的排序臨時段,回收整理碎片,合并空閑空間,釋放臨時段,維護閃回的時間點。
- 重做日志文件和日志寫入進程
用于記錄數據庫的改變和記錄數據庫被改變之前的原始狀態,當滿足以下條件時,激活LGWR:
提交指令
日志緩沖區超過1/3
每三秒
每次DBWn執行之前
2) 非核心進程
- 歸檔進程(ARCn)
是可選的后臺進程,當數據庫處于ArchiveLog模式時,自動歸檔redo log,并保存數據庫的所有修改記錄。
SGA(System Global Area)和后臺進程組成Instance。
4、存儲結構
存儲結構可從物理結構和邏輯結構兩方面理解。
1) 物理結構
Database物理結構:是Database在操作系統中的文件集合,即:磁盤上的物理文件,主要由數據文件、控制文件、重做日志文件、歸檔日志文件、參數文件、口令文件組成。
數據文件、重做日志文件、控制文件、跟蹤文件、警告文件屬于數據庫文件
- Data Files
數據文件是數據的存儲倉庫,數據被使用時才被調入內存中的。
- Redo Log Files
重做日志文件包含對數據庫所做的更改操作記錄,在Oracle發生故障時能夠恢復數據。
- Control Files
控制文件包含維護和驗證數據庫完整性的必要的信息。例如,控制文件用于識別數據文件和重做日志文件,一個數據庫至少需要一個控制文件。
- 跟蹤文件 (Trace Files)
在instance 中運行的每一個后臺進程都有一個跟蹤文件(trace file)與之相連。Trace file記載后臺進程所遇到的重大事件的信息。
- 警告日志( Alert Log)
是一種特殊的跟蹤文件,每個數據庫都有一個跟蹤文件,同步記載數據庫的消息和錯誤。
參數文件、口令文件、歸檔文件屬于非數據庫文件。
- Parameter File
實例參數文件,當啟動oracle實例時,SGA結構會根據此參數文件的設置內存,后臺進程會據此啟動。
- Password File
用戶通過提交username/password來建立會話,Oracle根據存儲在數據字典的用戶定義對用戶名和口令進行驗證。
- 歸檔文件
是重做日志文件的脫機副本,這些副本可能對于從介質失敗中進行恢復很必要。
2) 邏輯結構
- 表空間
用于存儲數據庫對象的邏輯空間,是信息存儲的最大邏輯單位,是一系列數據文件的集合。一個數據庫可以由多個表空間組成,每個表空間包括多個段。
- 段:
是對象在數據庫中占用的空間。段是區的集合
- 區:
是為數據一次性預留的一個較大的存儲空間,區是塊的集合
- 塊:
ORACLE最基本的存儲單位,在建立數據庫的時候指定,并被映射到磁盤塊。
3) 邏輯空間到物理空間的映射
(二) Oracle RDBMS的運行過程
1. User訪問Oracle Server之前提交一個請求(包含了db_name、password、instance_name、username等信息);
2. Oracle Server接收到請求并通過Password File的驗證后,分配SGA內存池,啟動后臺進程同時創建并啟動實例;
3. 啟動實例之后,User Process與Server Process建立Connect;
4. Server process和Oracle Instance建立Sesscion,隨后接收用戶請求,執行相關操作;
(三) 寫SQL語句的執行過程
1. 用戶執行SQL語句,Server process收到后,將SQL語句送到Instance,再將SQL語句載入數據庫緩沖區。
2. Server Process通知Oracle Database將與SQL語句相關的數據塊副本加載到緩沖區中。
3. 在數據庫緩存區執行SQL語句,修改數據文件副本,形成“臟緩沖區”
4. CKPT檢查到”臟緩沖區”,調用DBWn數據庫寫進程,
5. 在DBWn運行之前,先運行了LGWR,將數據文件的原始狀態和數據庫的改變記錄到Redo Log Files
6. 運行DBWn,將“臟緩沖區的內容寫入到數據文件”
7. 同時CKPT修改控制文件和數據文件頭
8. SMON回收不必要的空閑資源
9. 返回結果給用戶
(四) Oracle的高可用性架構
1. Oracle RAC(Real Application Clusters)
RAC 是 Oracle 數據庫的一個群集解決方案,包括計算層和存儲層。如下圖所示:
1) 存儲層——共享存儲
Oracle RAC的核心是共享磁盤子系統,集群中所有節點必須能夠訪問所有數據文件、重做日志文件、控制文件和參數文件,因此,這些文件必須存放在共享存儲中。常用的共享存儲方式有OCFS、OCFS2、RAW、NFS、ASM 等。說明如下:
OCFS(Oracle Cluster File System) 和 OCFS2 都是文件系統,和 NFS 一樣,提供集群環境共享存儲的文件系統。
RAW 裸設備也是一種存儲方式。把共享存儲映射到 RAW Device,Oracle在存儲數據時,選擇 RAW device存儲即可。但相對于文件系統來說, RAW不直觀,不便于管理,而且有數量的限制,現已被OCFS取代。
ASM 是一種數據庫存儲的方案,并不是 cluster 的方案,使用 ASM 時,還需使用OCFS/OCFS2 或RAW。
2) 計算層
計算層至少需要兩臺以上的服務器,在每臺服務器上安裝集群軟件和Oracle的 RAC 組件,從邏輯結構上看,每個節點都有一個獨立的實例,這些實例訪問同一個數據庫。節點之間通過集群軟件的通信層(Communication Layer)進行通信,利用高速緩存合并技術,實現集群中各節點緩存的高速同步,使得集群中的每個實例,都保留了一份相同的數據庫 cache。從而最大限度地低降低磁盤I/O。因此,RAC有如下特點:
每一個節點的實例都有自己的 SGA;
每一個節點的實例都有自己的后臺進程
每一個節點的實力都有自己的 redo logs
每一個節點的實例都有自己的 undo 表空間
所有節點都共享一份 datafiles 和 controlfiles
2、Data Guard
在Data Gurad 環境中,至少有兩個數據庫,一個主庫(Primary Database)處于Open 狀態,另一個備庫(Standby Database)處于standby狀態。
備庫又分物理庫和邏輯庫。物理庫和主庫完全一樣,通過REDO應用來保持與主庫的數據一致性,支持只讀服務;邏輯庫通過SQL應用,在備庫端執行和主庫同樣的SQL語句,以此來保持與主庫的數據一致,因此文件的物理結構(甚至數據的邏輯結構)都可以與主庫不一致。邏輯庫支持讀寫服務。
Data Guard適合多機房方案,實際部署時,主庫部署在主機房,備庫部署在其他機房。
二、 MySQL
(一) MySQL架構
1、連接器(Connectors)
MySQL向外提供的接口,如java,.net,php等語言可以通過該組件來操作SQL語句,實現與SQL的交互。
2、管理服務組件和工具組件(Management Service & Utilities)
提供對MySQL的集成管理,如備份(Backup),恢復(Recovery),安全管理(Security)等
3、連接池組件(Connection Pool)
負責監聽對客戶端向MySQL Server端的各種請求,接收請求,轉發請求到目標模塊。每個成功連接MySQL Server的客戶請求都會被創建或分配一個線程,該線程負責客戶端與MySQL Server端的通信,接收客戶端發送的命令,傳遞服務端的結果信息等。
4、SQL接口組件(SQL Interface)
接收用戶SQL命令,如DML,DDL和存儲過程等,并將最終結果返回給用戶。
5、查詢分析器組件(Parser)
首先分析SQL命令語法的合法性,并嘗試將SQL命令分解成數據結構,若分解失敗,則提示SQL語句不合理。
6、優化器組件(Optimizer)
對SQL命令按照標準流程進行優化分析。
7、緩存主件(Caches & Buffers)
緩存和緩沖組件
8、MySQL存儲引擎
MySQL屬于關系型數據庫,而關系型數據庫的存儲是以表的形式進行的,對于表的創建,數據的存儲,檢索,更新等都是由MySQL存儲引擎完成的。
因MySQL的開源性,允許第三方基于MySQL骨架,開發適合自己業務需求的存儲引擎。因此,MySQL支持的存儲引擎種類較多,可以分為官方存儲引擎和第三方存儲引擎。
當前,MySQL的存儲引擎有MyISAM、InnoDB、NDB、Archive、Federated、Memory、Merge、Parter、Community、Custom等。其中,比較常用的存儲引擎包括InnoDB、MyISAM和Momery。
9、物理文件(File System)
實際存儲MySQL數據庫文件和一些日志文件等的系統,如Linux,Unix,Windows等。
(二) 一個查詢流程圖
(三) MySQL的高可用架構
因MySQL的開源屬性,其高可用架構非常靈活,目前常用的主要有以下幾種:
1、主從復制模式
這是MySQL自身提供的一種高可用解決方案,數據同步方法采用的是MySQL replication技術。為了達到更高的可用性,在實際的應用環境中,需要配合高可用集群軟件keepalived來實現自動failover,否則,需要手工切換。
2、MHA(Master High Availability)
MHA是相對成熟的高可用解決方案,該軟件由兩部分組成:MHA Manager(管理節點)和MHA Node(數據節點)。搭建MHA時,要求一個集群必須最少有三臺數據庫服務器,一主二從(即一臺master,一臺備用master,另外一臺slave)。
MHA Manager可以單獨部署在一臺獨立的機器上管理多個master-slave集群,或部署在一臺slave節點上,MHA Node運行在每臺MySQL服務器上。
運行時,MHA Manager會定時探測集群中的master節點,當master故障時,會自動將最新數據的slave提升為新的master,然后將其他所有slave重新指向新的master。整個故障轉移過程對應用程序完全透明。整個切換過程如下:
從宕機崩潰的master保存二進制日志事件(binlog events);
識別含有最新更新的slave;
應用差異的中繼日志(relay log)到其他的slave;
應用從master保存的二進制日志事件(binlog events);
提升一個slave為新的master;
使其他的slave連接新的master進行復制;
3、MGR(MySQL Group Replication)
MGR是MySQL官方推薦的另一種高可用架構,復制組間的數據同步基于Paxos協議。
當客戶端發起更新事務時,該事務先在本地執行,執行完成之后就要發起對事務的提交操作。在還沒有真正提交之前,需要將產生的復制寫集廣播出去,復制到其它成員。如果沖突檢測成功,組內決定該事務可以提交,其它成員可以應用,否則就回滾。
組復制可以在兩種模式下運行:
- 單主模式下,組復制具有自動選主功能,每次只有一個 Server成員接受更新,其它成員只提供讀服務。
- 多主模式下,所有的Server 成員都可以同時接受更新,沒有主從之分,成員角色是完全對等的。
三、 PostgreSQL
(一) PostgreSQL 的體系架構
PostgreSQL 使用C/S模式提供服務??蛻舳撕头掌骺梢栽诓煌闹鳈C上,通過TCP/IP進行網絡連接,架構如下:
1、主進程Postgres(常駐進程)
主進程是PostgreSQL啟動時,第一個啟動的進程Postgres。啟動時,他會執行恢復、初始化共享內存,啟動后臺進程。當有客戶端發起鏈接請求時,postgres會生成子進程,同時創建后端進程。
是整個數據庫實例的總控進程,負責啟動和關閉該數據庫實例。
2、Postgres(子進程),子進程
Postgres接受前端請求,對數據庫進行檢索,最后返回結果。如請求是對數據庫進行更新,會先記錄日志(PostgreSQL稱為WAL日志),以便宕機重啟時的數據恢復。另外,日志會定期歸檔保存,以便需要時進行數據恢復。
3、后臺進程(Background Process)
- Syslogger(系統日志)進程
將錯誤信息寫到log日志中。
- BgWriter(后臺)進程
周期性的將臟內存塊寫入文件。
- Checkpointer
當檢查點出現時,將臟內存塊寫到數據文件
- WalWrite(預寫式日志)進程
將WAL(Write Ahead Log預寫式日志)緩存寫入WAL文件。
- PgArch(歸檔)進程
在歸檔模式下時,復制WAL文件到特定的路徑下。
WAL日志會被循環使用,PgArch在歸檔前會把WAL日志備份出來。通過PITY(Point in Time Recovery)技術,可以對數據庫進行一次全量備份后,該技術將備份時間點之后的WAL日志通過歸檔進行備份,使用數據庫的全量備份再加上后面產生的WAL日志,即可把數據庫向前推到全量備份后的任意一個時間點。
- AutoVacuum(自動清理)進程
當自動vacuum被啟用時,用來派生autovacuum工作進程。autovacuum進程的作用是在需要時自動對膨脹表執行vacuum操作。
在PostgreSQL數據庫中,對表進行DELETE操作后,舊的數據并不會立即被刪除,并且,在更新數據時,也并不會在舊的數據上做更新,而是新生成一行數據。舊的數據只是被標識為刪除狀態,只有在沒有并發的其他事務讀到這些就數據時,它們才會被清楚。這個清除工作就有AutoVacuum進程完成。
- PgStat(統計數據收集)進程
用來收集數據庫統計信息。
4、共享內存和本地內存
示意圖如下:
- 共享內存
PostgreSQL啟動后,會生成一塊共享內存,用于做數據塊的緩沖區,以便提高讀寫性能。WAL日志緩沖區和Clog緩沖區也存在共享內存中,除此之外還有全局信息比如進程、鎖、全局統計等信息也保存在共享內存中。
數據緩沖區通過BgWrite進程,定期將數據寫入數據文件。WAL緩沖區通過WALWrite進程寫入WAL文件,并通過PgArch定期進行歸檔,寫入歸檔日志
- 本地內存
非全局存儲的數據都存在本地內存中,主要包括:
臨時緩沖區:用于臨時表。默認值為8MB
work_mem: 用于排序、位圖索引、哈希鏈接和合并鏈接操作。默認值為4MB。。
manintance_work_mem: 用于vacuum和創建索引操作。默認值為64MB。
(二) 數據結構
1. 數據庫相關概念:
PostgreSQL由一系列數據庫組成。一套PostgreSQL程序稱之為一個數據庫群集。
當initdb()命令執行后,template0 , template1 , 和postgres數據庫被創建。
template0和template1數據庫是創建用戶數據庫時使用的模版數據庫,他們包含系統元數據表。
initdb()剛完成后,template0和template1數據庫中的表是一樣的。但是template1數據庫可以根據用戶需要創建對象。
用戶數據庫是通過克隆template1數據庫來創建的;
2. 表空間相關概念:
initdb()后,創建pg_default和pg_global表空間。
建表時如果沒有指定特定的表空間,表默認被存在pg_default表空間中。
用于管理整個數據庫集群的表默認被存儲在pg_global表空間中。
pg_default表空間的物理位置為$PGDATAbase目錄。
pg_global表空間的物理位置為$PGDATAglobal目錄。
一個表空間可以被多個數據庫同時使用。此時,每一個數據庫都會在表空間路徑下創建為一個新的子路徑。
創建一個用戶表空間會在$PGDATApg_tblspc目錄下面創建一個軟連接,連接到表空間制定的目錄位置。
3. 表相關概念:
每個表有三個數據文件:
一個文件用于存儲數據(文件名是表的OID);
一個文件用于管理表的空閑空間(文件名是OID_fsm)。
一個文件用于管理表的塊是否可見(文件名是OID_vm)。
索引沒有_vm文件,只有OID和OID_fsm兩個文件
(三) 后端進程的處理流程
接收前端發送過來的查詢(SQL文)
構文解析。將SQL文(單純的文字)轉換成構文樹parser tree。
構文樹解析完以后,換為查詢樹。這時會訪問數據庫,檢查表是否存在,如果存在的話,則把表名轉換為OID。這個處理稱為分析處理(Analyze)。
因PostgreSQL還通過查詢語句的重寫實現視圖(view)和規則(rule),所以需要時,此階段會對查詢語句進行重寫。
解析查詢樹后,可生成計劃樹。
按照執行計劃里面的步驟可以完成查詢要達到的目的。
執行結果返回給前端。
返回到步驟一重復執行。
四、 國產關系型數據庫
國產關系型數據庫較多,此處僅以GaussDB T為例
(一) GaussDB T架構
1. 內存結構
內存結構分為4部分,如下圖:
Listener:包括TCP LSNR和IPC LSNR,用于偵聽用戶的連接請求
Agent Pool:代理的連接池
SGA:
Log Buffer: 全局日志緩沖區,緩存redo日志
Data Buffer:全局數據頁緩沖區,用于緩存表索引等數據
SQL Cache:全局執行計劃緩沖區
Sort Area: 全局排序/物化緩沖區
Dictionary Cache: 全局數據字典(元數據)緩沖區
Large pool,大池,存放較大的SQL
Session Pool,全局Session池,用于存放Session
- 后臺進程
LOGW:日志寫線程,負責將log buffer中的日志寫到磁盤。
CKPT:負責將臟頁(Dirty Page)刷到磁盤,保證WAL,并更新Control File。
SMON:負責監測系統的狀態,比如檢測死鎖,修復異常的session。
JOBS:應用定制的后臺任務調度。
LOGR:日志復制,用于HA和GR。
ARCH:用于日志文件歸檔。
2、存儲結構
數據以文件方式存儲,主要有三種文件:
DATA FILE,數據文件,用于存放各種數據,單庫最多1024個數據文件,每個數據文件最大8T(undo除外,undo最大32G)
LOG FILE,日志文件,用于存放redo日志,可以重復使用,最少3組,每個redo 日志文件一般建議5-20G
CONTROL FILE,控制文件,用于數據庫名、數據文件位置等信息,在數據庫啟動到mount階段時會檢查。
(二) GaussDB T關鍵技術
當進行事務提交時,必須先將Redo log刷盤。
臟頁數據刷盤后,可用Redo日志可回收。
如果數據未刷盤前掉電,加電后需要重做Redo,保持數據的一致性。
臟頁隊列:臟頁按時序組成鏈表,即臟頁隊列,Checkpoint按該隊列順序分組刷盤;
Checkpoint任務調度:Checkpoint后臺服務線程通過定時、臟頁量、RedoLog滿,三個策略滿足之一會觸發刷盤操作;
Redo 任務調度:Redo后臺服務線程通過定時、Redo buffer量、事務提交滿足之一時會觸發Redo Log Buffer刷盤操作;
鏡像頁機制:刷盤時間相對較長,為避免I/O阻塞,Checkpoint通過一個鏡像頁面緩存來完成刷盤。
采用MVCC機制提高事務并發能力。
(三) GaussDB T的高可用部署模式
1、單機和主備部署模式
2、分布式部署模式
(四) 典型的分布式部署架構
各組件說明如下:
OM(Operation Manager):運維管理模塊。提供集群日常運維、配置管理的管理接口、工具。
CM(Cluster Manager):集群管理模塊。管理和監控分布式系統中各個功能單元和物理資源的運行情況,確保整個系統的穩定運行。
CN(Coordinator Node):協同調度節點。負責接收來自應用的訪問請求,并向客戶端返回執行結果;負責分解任務,并調度任務分片在各DN上并行執行。集群中,CN有多個且CN的角色是平等的。
DN(Datanode):數據節點。負責存儲業務數據,執行數據查詢任務以及向CN返回執行結果。在集群中,DN有多個。每個DN支持設置多個存儲備機。
GTS(Global Time Server):全局時鐘服務器。用于強一致場景下,為各個節點提供邏輯時鐘。
五、 主流關系型數據庫特點分析