共用方式為


加速資料庫復原疑難排解

適用於:Microsoft Fabric 中的 SQL Server 2019 (15.x) 和更新版本 Azure SQL 資料庫 Azure SQL 受控執行個體SQL Database

本文可協助診斷 SQL Server 2019 (15.x)及更高版本、Azure SQL 受控實例、Azure SQL Database,以及 Microsoft Fabric 中的 SQL 資料庫內,與 加速資料庫復原 (ADR) 有關的問題。

檢查 PVS 的大小

使用 sys.dm_tran_persistent_version_store_stats DMV 來識別永續性版本存放區 (PVS) 大小是否大於預期。

下列範例查詢顯示當前 PVS 大小、清理程序和其他詳細信息:

SELECT  DB_NAME(pvss.database_id) AS database_name,
        pvss.persistent_version_store_size_kb / 1024. / 1024 AS persistent_version_store_size_gb,
        100 * pvss.persistent_version_store_size_kb / df.total_db_size_kb AS pvs_pct_of_database_size,
        df.total_db_size_kb/ 1024. / 1024 AS total_db_size_gb,
        pvss.online_index_version_store_size_kb / 1024. / 1024 AS online_index_version_store_size_gb,
        pvss.current_aborted_transaction_count,
        pvss.aborted_version_cleaner_start_time,
        pvss.aborted_version_cleaner_end_time,
        dt.database_transaction_begin_time AS oldest_transaction_begin_time,
        asdt.session_id AS active_transaction_session_id,
        asdt.elapsed_time_seconds AS active_transaction_elapsed_time_seconds,
        pvss.pvs_off_row_page_skipped_low_water_mark,
        pvss.pvs_off_row_page_skipped_min_useful_xts,
        pvss.pvs_off_row_page_skipped_oldest_aborted_xdesid
FROM sys.dm_tran_persistent_version_store_stats AS pvss
CROSS APPLY (
            SELECT SUM(size * 8.) AS total_db_size_kb
            FROM sys.database_files
            WHERE state = 0
                  AND
                  type = 0
            ) AS df
LEFT JOIN sys.dm_tran_database_transactions AS dt
ON pvss.oldest_active_transaction_id = dt.transaction_id
   AND
   pvss.database_id = dt.database_id
LEFT JOIN sys.dm_tran_active_snapshot_database_transactions AS asdt
ON pvss.min_transaction_timestamp = asdt.transaction_sequence_num
   OR
   pvss.online_index_min_transaction_timestamp = asdt.transaction_sequence_num
WHERE pvss.database_id = DB_ID();

請檢查 [pvs_pct_of_database_size] 數據行,以查看相對於資料庫大小總計的 PVS 大小。 請注意,典型 PVS 大小與應用程式活動其他期間所得出的基準相較是否有任何差異。 如果 PVS 明顯大於基準,或接近資料庫大小的 50%,則 PVS 會被視為很大。 使用下列疑難解答步驟來尋找 PVS 大小過大的原因。

如果 PVS 大小比預期大,請檢查:

檢查長時間執行的作用中交易

長時間運行的活動交易會阻止已啟用 ADR 的資料庫執行 PVS 清理。 使用 oldest_transaction_begin_time 欄位檢查最舊的活躍交易開始時間。 如需長時間執行交易的詳細資訊,請使用下列範例來查詢。 您可以設定交易持續時間的臨界值和產生的事務歷史記錄量:

DECLARE @LongTxThreshold int = 1800;  /* The number of seconds to use as a duration threshold for long-running transactions */
DECLARE @LongTransactionLogBytes bigint = 1073741824; /* The number of bytes to use as a log amount threshold for long-running transactions */

SELECT  dbtr.database_id,
        transess.session_id,
        transess.transaction_id,
        atr.name,
        sess.login_time,
        dbtr.database_transaction_log_bytes_used,
        CASE WHEN GETDATE() >= DATEADD(second, @longTxThreshold, tr.transaction_begin_time) THEN 'DurationThresholdExceeded' 
                WHEN dbtr.database_transaction_log_bytes_used >= @LongTransactionLogBytes THEN 'LogThresholdExceeded' 
                ELSE 'Unknown'
        END AS Reason
FROM sys.dm_tran_active_transactions AS tr
INNER JOIN sys.dm_tran_session_transactions AS transess
ON tr.transaction_id = transess.transaction_id
INNER JOIN sys.dm_exec_sessions AS sess
ON transess.session_id = sess.session_id
INNER JOIN sys.dm_tran_database_transactions AS dbtr
ON tr.transaction_id = dbtr.transaction_id
INNER JOIN sys.dm_tran_active_transactions AS atr
ON atr.transaction_id = transess.transaction_id
WHERE GETDATE() >= DATEADD(second, @LongTxThreshold, tr.transaction_begin_time)
        OR
        dbtr.database_transaction_log_bytes_used >= @LongTransactionLogBytes;

若已識別會話,請考慮在情況允許時終止會話。 檢閱應用程式,以判斷有問題的使用中交易本質,以避免未來發生問題。

如需針對長時間執行的查詢進行疑難排解的詳細資訊,請參閱:

檢查長時間執行的作用中快照集掃描

長時間執行的活動快照集掃描可能會阻止在啟用了 ADR 的資料庫中進行 PVS 清理。 使用 READ COMMITTED 快照集隔離 (RCSI) 或 SNAPSHOT隔離等級的語句, 接收實例層級時間戳。 快照掃描會使用時間戳來決定 RCSI 或 SNAPSHOT 交易的版本列可見性。 使用 RCSI 的每個語句都有自己的時間戳,而 SNAPSHOT 隔離具有事務層級的時間戳。

這些實例層級的交易時間戳即使在單一資料庫交易中使用,因為任何交易都可能會提示跨資料庫交易。 因此,快照掃描可以防止在同一資料庫引擎實例上的任何資料庫中進行 PVS 清除。 同樣地,當 ADR 未啟用時,快照集掃描可能會阻止清除 tempdb中的版本存放區。 因此,當有使用 SNAPSHOT 或 RCSI 的長期執行交易時,PVS 的規模可能會增大。

在本文開頭的 疑難解答查詢 中,pvs_off_row_page_skipped_min_useful_xts 欄會顯示因為長時間的快照掃描而略過回收的頁面數目。 如果此欄位顯示的值比一般值大,表示長時間的快照掃描正在防止 PVS 清除。

使用下列範例查詢來尋找具有長時間執行 SNAPSHOT 或 RCSI 交易的工作階段:

SELECT snap.transaction_id,
        snap.transaction_sequence_num,
        session.session_id,
        session.login_time,
        GETUTCDATE() AS [now],
        session.host_name,
        session.program_name,
        session.login_name,
        session.last_request_start_time
FROM sys.dm_tran_active_snapshot_database_transactions AS snap
INNER JOIN sys.dm_exec_sessions AS session
ON snap.session_id = session.session_id
ORDER BY snap.transaction_sequence_num ASC;

為防止 PVS 清除延遲:

  • 如果可能的話,請考慮終止造成延遲 PVS 清除的長時間作用中交易工作階段。
  • 優化長時間執行的查詢,以縮短查詢時間。
  • 請檢閱應用程式,以判斷有問題之作用中快照集掃描的性質。 針對延遲 PVS 清理的長時間執行查詢,請考慮使用不同的隔離級別,例如 READ COMMITTED,而不是 SNAPSHOT 或 RCSI。 此問題會在隔離等級 SNAPSHOT 更頻繁地發生。
  • 在 Azure SQL Database 彈性集區中,請考慮使用 SNAPSHOT 隔離或 RCSI 從彈性集區移動具有長時間執行交易的資料庫。

檢查次要復本上長時間執行的查詢

如果資料庫有次要複本,請檢查次要低水位標記是否正在前進。

在主要複本上執行下列 DMV,以識別可能防止 PVS 清除的次要複本上長時間執行的查詢:

sys.dm_tran_persistent_version_store_stats DMV 中,pvs_off_row_page_skipped_low_water_mark 欄位也可以指示清除延遲,這是由於在次要複本上長時間運行的查詢。

連線到備用複本,找出執行長時間查詢的會話,然後在允許的情況下考慮終止該會話。 次要副本上長時間執行的查詢可能會延遲 PVS 清理並防止 虛刪除清理

檢查大量中止的交易

如果先前的案例都不適用於您的工作負載,則清理程序可能會因大量中止的交易而延遲。 檢查 aborted_version_cleaner_last_start_timeaborted_version_cleaner_last_end_time 數據行,以查看最後一次中止的交易清除是否已完成。 oldest_aborted_transaction_id 應會在中止交易清除完成後向更高的方向移動。 如果 oldest_aborted_transaction_id 遠低於 oldest_active_transaction_id,且 current_abort_transaction_count 具有較大的值,則可能是有一個舊的中止交易正在阻礙 PVS 清除。

若要處理大量中止的交易,請考慮下列事項:

  • 可能的話,請暫停工作負載,以便版本清理程序能夠順利進行。
  • 將工作負載優化,以減少物件層級鎖定。
  • 檢閱應用程式以識別高交易中止率問題。 中止可能由於高比率的死結、重複索引鍵、約束條件違反或查詢超時。
  • 如果使用 SQL Server,為了緊急控制 PVS 大小,請暫時停用 ADR。 請參閱 停用 ADR
  • 如果中止的交易清除尚未順利完成,請檢查錯誤記錄檔中是否有回報 VersionCleaner 問題的訊息。
  • 如果 PVS 大小沒有如預期般減少,即使清理已完成,請檢查 pvs_off_row_page_skipped_oldest_aborted_xdesid 欄位。 大型數值表示中止的交易中的行版本仍然佔用空間。

手動啟動 PVS 清除程序

如果您有大量 DML 語句的工作負載(INSERTUPDATEDELETEMERGE),例如大量 OLTP,則 PVS 清除程式可能需要一段時間的休息/復原才能回收空間。

若要在工作負載之間或維護期間手動啟動 PVS 清除程序,請使用系統預存程序 sys.sp_persistent_version_cleanup

例如:

EXEC sys.sp_persistent_version_cleanup [WideWorldImporters];

擷取清除失敗

從 SQL Server 2022 (16.x) 開始,PVS 清除行為會記錄在錯誤記錄檔中。 這通常會導致每 10 分鐘記錄一次新的記錄事件。 清除統計數據也會由 tx_mtvc2_sweep_stats擴充事件報告