資料庫通用基礎實現技術 多程序共享資訊

2021-04-24 12:43:50 字數 2529 閱讀 1938

berkeley db資料庫以程式庫的方式鏈結到應用程式中,而應用程式可以以多執行緒、多程序的方式訪問同乙個資料庫環境中的所有資料庫。注意,這裡的資料庫環境(database environment, db_env)是berkeley db的乙個術語,相當於關聯式資料庫中的乙個「資料庫」,我們知道這個「資料庫」中有很多個「關係表」。而berkeley db當中用「資料庫」("database")來指代大家所熟悉的「關係表」---記住這個術語的改變,否則後面就很難理解了。

在通常的關聯式資料庫伺服器中,通常也是有很多個程序在向客戶連線提供資料,所以本文所描述的技術適用於所有的資料庫系統。

由於資料庫系統當中的資料最終都是儲存在磁碟的檔案中的,而且為了高效地讀寫,這些檔案都有比較複雜的結構,首先它們都被分成很多個頁,每個頁有相同的複雜結構,比如

每個頁上有很多字段記錄本頁有多少條記錄、每個記錄的各個欄位的起始位址、長度,等等,除此之外還有很多使用者資料。向資料庫檔案中讀寫資料時,都需要訪問頁中的很多字段;另外,必須保證多個程序對這些頁的讀寫訪問符合規定的隔離級別,比如不可以讀取未提交資料(可選)、多個程序不可以同時寫同乙個頁等等。

為了實現上述需求,通常使用兩種方法:

1. 對映檔案

現在的作業系統都支援把乙個檔案對映到乙個程序的記憶體空間中,當程序a把檔案f對映到自己的記憶體空間後,在這個程序中,就得到乙個指標(位址)b,你可以把這個位址當作檔案第乙個位元組的記憶體位址,同時你可以認為這個檔案後續的位元組的位址就是在b的基礎上加上檔案內的偏移值,所以檔案中第二個位元組在記憶體中的位址是b + 1, 最後乙個位元組在記憶體中的位址是b + 檔案長度 - 1. 多個程序可以同時把同乙個檔案對映到自己的記憶體空間,並且它們可以同時對這個檔案修改,任何乙個程序的改動可以立刻被其他程序看到(有些作業系統,比如 windows,對對映檔案的共享一致性提供多種選項,除了這種完全一致性外,可以有更鬆弛的級別)。由於對映檔案的這些特性,我們可以使用對映檔案把同乙個資料庫檔案對映到各個需要訪問這個資料庫檔案的程序中,從而併發地處理使用者的讀、寫資料請求。

需要注意的有三點:

第一,各個程序把同乙個檔案對映到自己的位址空間後,所得到的指標值未必相同,而且多次執行同乙個程式,得到的指標值也不同。那麼,我們就不可以在這樣的資料庫檔案中使用絕對位址,只能儲存檔案內偏移值(offset),然後在對映到某個程序的位址空間之後,當我們需要訪問某個位址值時候,都是要做基位址+偏移值的運算,得到目標記憶體位址;比如基位址是b, 本頁第一條記錄起始偏移值是o, 那麼對映後第一條記錄在記憶體中的位址就是b + o. 如果在頁內偏移值為d的地方要儲存某個欄位的起始位址,而我們只知道該欄位目前在本程序中的位址是p,我們應該這樣做: (*(offset_t *)(b + d)) = p - b; 也就是說,要儲存位址到資料庫檔案,也是用目標位址-本頁基位址得到目標的偏移值,寫到頁內的特定位置。

第二,當乙個頁對映到多個程序後,由於多個程序可以不受任何限制同時訪問這個頁,我們需要一種互斥機制確保讀寫一致性,或者叫做資料庫事務的隔離級別。通常的資料庫系統使用鎖定技術,也有其他方法,比如基於時間戳、多版本的機制,以及樂觀的併發控制。berkeley db中主要使用鎖定技術,每個頁是乙個可以被鎖定的物件(lock object),而事務、游標控制代碼等就是鎖定者(locker),鎖系統通過作業系統提供的互斥原語確保被鎖定lock object只被得到了其lock的locker訪問,其他locker只能等到這些lock被釋放後才能得到lock來訪問這個lock object. 關於鎖系統的更多細節,我們以後再做討論。

第三,這種多程序共享資訊的技術,不僅僅限於共享資料庫檔案,在資料庫系統自身執行過程中使用的資訊,也可以使用這樣的對映技術。這時,每個檔案內儲存的是資料庫自身的資訊,比如,鎖系統中需要記錄有哪些locker在等待哪些lock,以便這些lock被現屬的locker釋放後,可以通知到等待的locker;同時需要記錄哪些locker目前持有哪些lock,鎖著的是哪些lock object等等,這些資訊不是使用者資料,而是資料庫自身執行過程中需要的資訊,它們必須被本資料庫系統的所有程序同步地訪問到,所以它們也可以被儲存在檔案中,在資料庫執行期間對映到每個資料庫程序中,在一定的互斥機制下,各個程序可以共享這些資訊。這時,還需要對這個對映檔案的空間進行管理,包括分配、釋放、合併空間等等,類似c/c++的記憶體空間管理函式。在通常的應用程式中,我們呼叫 malloc/realloc/free或者new/delete 來分配、釋放空間,這時c/c++的這些函式來管理我們的堆空間,這個堆空間是作業系統分配給程序的。針對特定資料庫的資料結構及訪問方式的特徵,可以對空間管理演算法做各種優化,使得分配、釋放速度快、內碎塊少等優點。

2. 系統記憶體

除了用對映檔案來多程序共享資訊外,還可以使用系統記憶體---它與檔案、訊號量等一樣,也是一種由作業系統管理的核心物件。在具有虛擬記憶體管理的作業系統中,作業系統自身預留一部分虛擬位址空間以及物理記憶體供自身使用,所有程序都可以申請建立或者開啟乙個系統記憶體,得到乙個本程序內使用的位址(指標值),然後,我們就可以像操縱本程序的空間一樣,訪問這個系統記憶體空間,同時與其他程序共享訪問這個空間。在另外一些沒有虛存管理的作業系統中(比如 vxworks, dos等),所有程序在同乙個位址空間中執行,這時訪問系統記憶體更快更直接,而且每個程序/任務/執行緒(各種這類系統中術語有所不同)得到的指標值都是相同的。 除此之外,所有其他方面,系統記憶體和對映檔案在資料庫技術方面是一樣的。

多程序併發mysqldump資料庫匯入工具

本 詳情及用法已上傳到github上 如果覺得有用的,歡迎star收藏,感謝 本人菜鳥一名,閒來無事寫來玩玩,有問題請多多指教 github個人主頁 主頁上還有別的一些小工具 自定義程序數 根據程序數把要匯入的sql檔案分塊,並且對sql檔案大小進行排序,打亂,藉此盡可能實現每個程序要處理相同任務量...

python web框架多程序部署下資料庫連線問題

python常用的web框架,諸如flask,django,在生產部署時,都會選擇多程序的部署方式,選用的中介軟體多為uwsgi或者gunicorn。如果專案裡使用了資料庫,那麼就要考慮資料庫連線在多程序下的一些問題,本文以mysql資料庫為例。python連線mysql的客戶端驅動庫有很多種,例如...

通用資料庫訪問DLL實現

通用資料庫訪問模組 實現介面 通過范型類來做所有操作的物件,來對應任何表結構的資料。這種通用型別只能對單錶操作吧,不是很方便。包裝通用事務和通用資料庫鏈結物件,便於對不通資料庫相容 內建方法為泛型型別物件的,增刪改及查詢,加返回泛型集合物件 通用表物件對映模型 基類實現 新增更新字典,加入查詢表字段...