記憶體最佳化資料表的持久性
記憶體內部 OLTP 針對經記憶體最佳化的資料表提供完整的持久性。 當變更經記憶體最佳化資料表的交易認可後,只要基礎儲存體可用,SQL Server (針對磁碟型資料表也是) 即保證永久變更 (重新啟動資料庫後會繼續存在)。 持久性有兩個重要元件:交易記錄及磁碟儲存的保存資料變更。
交易記錄
磁碟基礎的資料表或持久記憶體最佳化資料表的所有變更,都可以在一個或多個交易記錄檔記錄上擷取。 交易認可時,SQL Server 將交易相關的記錄資料列寫入磁碟後,才會與交易認可的應用程式或使用者工作階段通訊。 這樣可保證交易所做的變更是持久的。 記憶體最佳化資料表的交易記錄檔會與磁碟資料表所使用的相同記錄檔資料流完全整合在一起。 這項整合允許現有的交易記錄檔備份、復原及還原作業繼續運作,而不需要進行其他任何步驟。 不過,由於In-Memory OLTP 可以大幅增加工作負載的交易輸送量,因此您必須確定已適當地設定交易記錄儲存體,以處理增加的 IO 需求。
資料和差異檔案
記憶體最佳化資料表中的資料會在記憶體中儲存為自由格式的資料列,並透過一個或多個記憶體中的索引加以連結。 資料列沒有任何頁面結構,例如用於磁碟基礎的資料表頁面結構。 當應用程式準備好認可交易時,In-Memory OLTP 會產生交易的記錄檔記錄。 記憶體最佳化的資料表持續性會透過一組資料和差異檔案使用背景執行緒完成。 資料和差異檔案位於一個或多個容器 (和 FILESTREAM 資料使用相同的機制)。 這些容器會對應到新的檔案群組類型,稱為記憶體最佳化的檔案群組。
資料會遵循嚴格的順序寫入,使轉動式媒體的磁碟延遲減到最少。 您可以在不同的磁碟上使用多個容器以散發 I/O 活動。 從磁碟上的資料檔案和差異檔案將資料讀入記憶體時,不同磁碟上多個容器內的資料檔案和差異檔案將會提升復原效能。
應用程式不會直接存取資料和差異檔案。 所有資料讀取和寫入皆使用記憶體中資料。
資料檔案
資料檔案包含了由 INSERT 或 UPDATE 作業中的多筆交易所插入的一個或多個記憶體最佳化資料表而來的資料列。 例如,某個資料列可能來自記憶體最佳化資料表 T1,而下一個資料列可能來自記憶體最佳化資料表 T2。 資料列會以交易記錄中的交易順序附加到資料檔案,好讓資料存取循序進行。 相較於隨機 I/O,這樣的重要性順序會產生較佳的 I/O 輸送量。 若為記憶體大於 16GB 的電腦,每個資料檔案的大小約為 128MB;若為記憶體小於或等於 16GB 的電腦,每個資料檔案的大小約為 16MB。 一旦資料檔案已滿,新交易所插入的資料列將會儲存至另一個資料檔案。 經過一段時間後,從持久的記憶體最佳化資料表而來的資料列將由多個資料檔案各自儲存,每個資料檔案所包含的資料列來自互不相交但屬連續範圍的交易。 例如,交易認可時間戳記範圍為 (100, 200) 的資料檔案,包含交易 (具有大於 100 及小於或等於 200 的認可時間戳記) 所插入的所有資料列。 認可時間戳記是交易在準備認可時獲指派的一個單純遞增數字。 每筆交易都有其獨一無二的認可時間戳記。
當資料列遭到刪除或更新時,並不會就地移除或變更資料檔案中的該資料列,而是在另一類型的檔案中追蹤已刪除的資料列:差異檔案。 每個資料列的刪除和插入作業將統整為 Tuple,藉此處理更新作業。 這可使資料檔案排除隨機 IO。
差異檔案
每一個資料檔案皆會與具有相同交易範圍,且將追蹤由該交易範圍內的交易所插入之已刪除資料列的差異檔案進行配對。 這種資料和差異檔案稱為檢查點檔案組 (CFP),並為配置、取消配置與合併作業的單位。 例如,與交易範圍 (100, 200) 對應的差異檔案會儲存由範圍 (100, 200) 內的交易所插入的已刪除資料列。 就像資料檔案,對差異檔案的存取也是循序進行。
當資料列遭到刪除時,並不會從資料檔案移除該資料列,而是該資料列的參考將附加到與該資料列插入當時的交易範圍相關聯的差異檔案。 由於要刪除的資料列已存在於資料檔案中,差異檔案只會儲存參考資訊 {inserting_tx_id, row_id, deleting_tx_id }
,且將遵照原始刪除或更新作業的交易記錄順序。
擴展資料檔案和差異檔案
資料檔案和差異檔案是由稱為離線檢查點的背景執行緒所擴展。 此執行緒會讀取記憶體最佳化資料表已認可之交易所產生的交易記錄,再將已插入及刪除的資料列相關資訊附加到適當的資料檔案和差異檔案。 不同於在檢查點完成時以隨機 I/O 方式排清資料/索引頁的磁碟資料表,記憶體最佳化資料表的保存是連續的背景作業。 如此將會存取多個差異檔案,因為交易可以刪除或更新任何先前交易所插入的任何資料列。 刪除資訊一律會附加到差異檔案的結尾。 例如,認可時間戳記為 600 的交易會插入一個新的資料列,並且刪除認可時間戳記為 150、250 和 450 的交易所插入的資料列,如下圖所示。 所有 4 個檔案 I/O 作業 (三個用於已刪除的資料列,一個用於新插入的資料列) 都是對應的差異檔案和資料檔案的附加專用作業。
存取資料和差異檔案
在發生以下情況時,將會存取資料檔案和差異檔案組。
離線檢查點執行緒 此執行緒會將插入和刪除附加至記憶體優化資料列,並附加至對應的資料和差異檔案組。
合併作業 作業會合並一或多個資料和差異檔案組,並建立新的資料和差異檔案組。
在當機復原期間,當重新開機SQL Server或資料庫恢復上線時,記憶體優化的資料會使用資料和差異檔案組填入。 從對應的資料檔案讀取資料列時,差異檔案會當做已刪除之資料列的篩選條件。 因為每個資料和差異檔案組是獨立的,所以這些檔案會平行載入,以減少將資料擴展到記憶體所花的時間。 資料載入記憶體之後,記憶體中 OLTP 引擎會套用檢查點檔案仍未涵蓋的使用中交易記錄,使記憶體最佳化資料完成。
還原作業期間,會從資料庫備份建立In-Memory OLTP 檢查點檔案,然後套用一或多個交易記錄備份。 就像進行當機復原一樣,記憶體中 OLTP 引擎會將資料平行載入記憶體中,以減少對復原時間的衝擊。
合併資料和差異檔案
記憶體最佳化資料表的資料是儲存於一個或多個資料檔案和差異檔案組 (又稱為檢查點檔案組或 CFP)。 資料檔案會儲存已插入的資料列,而差異檔案將參考已刪除的資料列。 在執行 OLTP 工作負載期間,隨著 DML 作業更新、插入和刪除資料列,會建立新的 CFP 以保存新資料列,並且將已刪除之資料列的參考附加至差異檔案。
所有先前已關閉及目前使用中 CFP 的中繼資料都將儲存至稱為儲存體陣列的內部陣列結構。 它是有大小限制的 (8,192 個項目) CFP 陣列。 儲存體陣列中的項目是依交易範圍排序。 儲存體陣列中的 CFP (連同記錄結尾) 代表使用記憶體最佳化資料表復原資料庫時所需的所有磁碟內存狀態。
經過一段時間後,透過 DML 作業,CFP 數目的成長造成儲存體陣列達到承載容量,導致遇到下列情況:
已刪除的資料列。 已刪除的資料列仍保留在資料檔案中,但在對應的差異檔案中卻標示為已刪除。 這些資料列都是不再需要而即將從儲存體移除的項目。 如果已刪除的資料列未從 CFP 移除,就會不必要地佔用空間並延緩復原時間。
儲存體陣列已滿。 一旦配置於儲存體陣列的項目多達 8,000 個 (陣列中的 192 個項目會保留給現有的合併競爭或讓您手動進行合併),便無法再對持久的記憶體最佳化資料表執行任何新的 DML 交易。 屆時將只允許檢查點及合併作業取用剩餘的項目。 這可確保 DML 交易不致填滿此陣列,且陣列中的某些項目將得以保留供合併現有檔案和回收陣列中的空間。
儲存體陣列操作負擔。 內部處理序會搜尋儲存體陣列據以執行作業,例如尋找差異檔案從而附加已刪除的資料列相關資訊。 這類作業的成本將隨著項目數增多而增加。
為了避免上列效率不佳的情況,較舊已關閉的 CFP 會依以下所述的合併原則進行合併,使儲存體陣列壓縮後的 CFP 數目減少但仍代表相同的資料集。
資料庫中所有持久資料表的記憶體中大小總計不應該超過 250 GB。 使用高達 250GB 記憶體的持久資料表,將需要平均 500 GB 的儲存空間 (假設有插入、刪除和更新等作業)。 記憶體最佳化的檔案群組中需要 4,000 個資料和差異檔案組,才能支援 500 GB 的儲存空間。
資料庫活動的短期突波可能會造成檢查點及合併作業落後,這會增加所需的資料和差異檔案組數。 為了容納資料庫活動的短期突波尖峰,儲存體系統可以配置最多 8,000 個資料和差異檔案組,總儲存體大小高達 1TB。 達到該限制時,資料庫上將不允許新交易,直到檢查點作業趕上為止。 如果持久的資料表大小在記憶體中長時間超過 250GB,就有可能會達到 8,000 個檔案組的限制。
合併作業將根據內部定義的合併原則,接受一個或多個相鄰且已關閉的 CFP (稱為合併來源) 當做輸入,並且產生單一 CFP 結果,稱為合併目標。 來源 CFP 的每個差異檔案中的項目用於篩選對應資料檔案中的資料列,以移除不再需要的資料列。 來源 CFP 中剩餘的資料列則會合併成單一目標 CFP。 在合併完成後,產生的合併目標 CFP 將取代來源 CFP (合併來源)。 合併來源 CFP 會歷經一個過渡階段後才從儲存體移除。
在底下的範例中,記憶體最佳化資料表檔案群組在時間戳記 500 有四個資料檔案和差異檔案組包含了得自先前交易的資料。 例如,第一個資料檔案中的資料列對應到時間戳記大於 100 且小於或等於 200 (或者以 (100, 200] 表示) 的交易。 在考量到資料列標記為已刪除的情況下,第二和第三個資料檔案會顯示為低於 50% 已滿。 合併作業會結合這兩個 CFP 並且建立新的 CFP,其包含了時間戳記大於 200 且小於或等於 400 的交易,也就是這兩個 CFP 合併的範圍。 如您所見,另有一個 CFP 的範圍為 (500, 600] 以及在交易範圍 (200, 400] 的非空白差異檔案,表示合併作業可與交易活動同時完成,包括刪除來源 CFP 中的更多資料列。
背景執行緒會使用合併原則評估所有已關閉的 CFP,然後起始一項或多項對合格 CFP 的合併要求。 這些合併要求將由離線檢查點執行緒來處理。 系統會定期評估合併原則,以及在檢查點關閉時進行評估。
SQL Server 2014 (12.x) 合併原則
SQL Server 2014 (12.x) 會實作下列合併原則:
在考量到已刪除的資料列之後,如果可以合併兩個或多個連續的 CFP,使其產生的資料列數能夠納入 1 個理想大小的 CFP,就會排程進行合併。 CFP 的理想大小會以下列方式決定:
如果電腦的記憶體小於或等於 16GB,則資料檔案是 16MB,而且差異檔案是 1MB。
如果電腦的記憶體大於 16GB,則資料檔案是 128MB,而且差異檔案是 16MB。
如果資料檔案超過 256 MB,而且一半以上的資料列已刪除,則單一 CFP 可以自行合併。 資料檔案可以超出 128MB,例如,單一交易或多個並行交易插入或更新大量資料,強制資料檔案超出其理想大小,因為交易無法跨越多個 CFP。
以下幾個範例顯示根據合併原則將會合併的 CFP:
相鄰的 CFP 來源檔案 (% 已滿) | 合併選取 |
---|---|
CFP0 (30%)、CFP1 (50%)、CFP2 (50%)、CFP3 (90%) | (CFP0、CFP1) 未選擇 CFP2 是因為此項目會使得產生的資料檔案超過理想大小的 100%。 |
CFP0 (30%)、CFP1 (20%)、CFP2 (50%)、CFP3 (10%) | (CFP0、CFP1、CFP2)。 從左邊開始選擇檔案。 未選擇 CTP3 是因為此項目會使得產生的資料檔案超過理想大小的 100%。 |
CFP0 (80%)、CFP1 (30%)、CFP2 (10%)、CFP3 (40%) | (CFP1、CFP2、CFP3)。 從左邊開始選擇檔案。 略過 CFP0 是因為此項目若與 CFP1 合併,產生的資料檔案將會超過理想大小的 100%。 |
並非所有餘留可用空間的 CFP 都有資格進行合併。 例如,若兩個相鄰的 CFP 都是 60% 已滿,就沒有資格進行合併,而且這些 CFP 各自仍將有 40% 未使用的儲存空間。 最糟的情況是所有 CFP 皆為 50% 已滿,儲存空間利用率只達 50%。 已刪除的資料列可能由於 CFP 沒有資格進行合併而仍存在於儲存體中,但是記憶體內部記憶體回收可能已從記憶體移除已刪除的資料列。 儲存體和記憶體的管理與記憶體回收無關。 使用中 CFP 所佔的儲存空間 (未必所有 CFP 一概更新) 最多可達記憶體中持久性資料表大小的 2 倍。
如有需要,可以藉由呼叫 sys.sp_xtp_merge_checkpoint_files (Transact-SQL) 明確執行手動合併。
CFP 的生命週期
CPF 解除配置之前會歷經幾個過渡狀態。 在任何給定的時間,CFP 都會處於以下其中一個階段:已預先建立、建構中、使用中、合併目標、已合併來源、備份/高可用性所需、正在轉換為標記和標記。 如需這些階段的說明,請參閱 sys.dm_db_xtp_checkpoint_files (Transact-SQL)。
在考量到 CFP 在各個不同階段所佔的儲存空間之後,持久的記憶體最佳化資料表所佔的整體儲存空間可能遠大於該資料表在記憶體中大小的 2 倍。 您可以查詢 DMV sys.dm_db_xtp_checkpoint_files (Transact-SQL) ,以列出記憶體優化檔案群組中的所有 CFP,包括其階段。 將 CFP 從「合併來源」狀態轉換為「標記」狀態且最後為記憶體回收的程序,最多可能會使用五個檢查點,每個檢查點後面都接著交易記錄備份 (如果資料庫有設定完整或大量記錄復原模式)。
您可以手動強制檢查點過後即執行記錄備份以加速記憶體回收,但是這樣將會增加 5 個空的 CFP (5 組資料/差異檔案組,每個資料檔案的大小為 128MB)。 在實際狀況下,做為部分備份策略的自動檢查點和記錄備份,將能在這些階段中順利轉換 CFP,而不需要任何手動介入。 記憶體回收處理序造成的影響是,具有記憶體最佳化資料表的資料庫其儲存體大小可能高於在記憶體中的大小。 CFP 是記憶體中持久性記憶體最佳化資料表大小高達四倍的情形是可能發生的狀況。