什麼是資料庫總帳?

適用於: SQL Server 2022 (16.x) Azure SQL DatabaseAzure SQL 受控執行個體

資料庫總帳是總帳功能的一部分。 資料庫隨著時間演進時,資料庫總帳會以累加方式擷取資料庫的狀態,同時對總帳資料表進行更新。 它會以邏輯方式使用區塊鏈和 Merkle 樹狀資料結構

任何更新總帳資料表的作業都需要執行一些額外的工作,才能維護歷程記錄資料,並計算資料庫總帳中擷取的摘要。 具體而言,針對每個更新的資料列,我們必須:

  • 將舊版的資料列保存在歷程記錄資料表中。
  • 指派交易識別碼並產生新的序號,將其保存在適當的系統資料行中。
  • 序列化資料列內容,並在計算此交易更新的所有資料列雜湊時,將其納入。

為達到目的,總帳會針對以總帳資料表為目標的所有插入、更新和刪除作業擴充資料操作語言 (DML) 查詢計劃。 交易識別碼和新產生的序號會針對新版的資料列設定。 然後,查詢計劃運算子會執行特殊運算式來序列化資料列內容並計算其雜湊,將其附加至儲存在交易層級的 Merkle 樹狀結構,並包含此交易為此總帳資料表更新的所有資料列版本雜湊。 樹狀結構的根代表此總帳資料表中此交易執行的所有更新和刪除作業。 如果交易更新多個資料表,則須為每個資料表維護個別的 Merkle 樹狀結構。 下圖是 Merkle 樹狀結構範例,其中儲存總帳資料表的已更新資料列版本,以及用來序列化資料列的格式。 除了每個資料行的序列化值之外,我們也包含了以下相關中繼資料:資料列中的資料行數目、個別資料行的序數、資料類型、長度和其他影響值解譯方式的資訊。

Diagram that shows a Merkle Tree storing the updated row versions of a ledger table and the format used to serialize the rows

為了擷取資料庫的狀態,資料庫總帳會為每筆交易儲存一個項目。 它會擷取交易的中繼資料,例如其認可時間戳記,以及執行該交易之使用者的身分識別。 其也會針對每個總帳資料表中更新的資料列,擷取 Merkle 樹狀結構根 (如上所述)。 這些項目接著會附加至不容易篡改的資料結構,以允許未來的完整性驗證。 區塊會在下列情況下關閉:

區塊關閉時,會在新的區塊中插入新的交易。 接著,區塊產生程序會:

  1. 從記憶體內佇列和 sys.database_ledger_transactions 系統目錄檢視中,擷取屬於「封閉」區塊的所有交易。
  2. 透過這些交易和上一個區塊的雜湊,來計算 Merkle 樹狀根。
  3. sys.database_ledger_blocks 系統目錄檢視中持續保存封閉區塊。

因為這是定期資料表更新,所以系統會自動保證其持久性。 為了維護單一區塊鏈,這是單一執行緒作業。 但它也很有效率,因為只會計算交易資訊的雜湊,並以非同步方式進行。 它不會影響交易效能。

Diagram that shows a Merkle Tree storing the transactions of a ledger table.

如需總帳如何提供資料完整性的詳細資訊,請參閱摘要管理資料庫驗證文章。

資料庫交易和區塊資料的儲存位置為何?

交易和區塊的資料實際儲存為兩個系統目錄檢視中的資料列:

  • sys.database_ledger_transactions:維護一個資料列,其中包含資料庫總帳中每筆交易的資訊。 此資訊包括此交易所屬區塊的識別碼,以及區塊內的交易序數。
  • sys.database_ledger_blocks:針對總帳中的每個區塊都維護一個資料列 (包括區塊內交易的 Merkle 樹狀根以及上一個區塊的雜湊) 以形成區塊鏈。

若要檢視資料庫總賬,請在 SQL Server Management StudioAzure Data StudioSQL Server Developer 工具中執行下列 T-SQL 陳述式。

SELECT * FROM sys.database_ledger_transactions;
GO

SELECT * FROM sys.database_ledger_blocks;
GO

下列總帳資料表範例是由四個交易組成,而這些交易構成資料庫總帳區塊鏈中的一個區塊:

Screenshot of an example ledger table.

權限

檢視資料庫總帳時需要 VIEW LEDGER CONTENT 權限。 如需總帳資料表相關權限的詳細資訊,請參閱權限