共用方式為


監視和疑難排解加速型資料庫復原

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

本文可協助您監視、診斷及解決 SQL Server 2019 (15.x) 和更新版本中 SQL Server 2019 (15.x) 和更新版本、Azure SQL 受控實例、Azure SQL Database 和 sql database Microsoft Fabric 中的加速資料庫復原 (ADR) 問題。

檢查 PVS 的大小

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

下列範例診斷查詢會顯示目前 PVS 大小、清除程式,以及所有 PVS 大小大於零之資料庫中的其他詳細數據:

SELECT pvss.database_id,
       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_percent_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,
       pvss.oldest_aborted_transaction_id,
       pvss.oldest_active_transaction_id,
       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.master_files AS mf
            WHERE mf.database_id = pvss.database_id
                  AND
                  mf.state = 0
                  AND
                  mf.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.persistent_version_store_size_kb > 0
ORDER BY persistent_version_store_size_kb DESC;

請檢查 [pvs_percent_of_database_size] 數據行,以查看相對於資料庫大小總計的 PVS 大小。 請注意一般 PVS 大小與通常應用活動期間所見基準之間的任何差異。 如果 PVS 明顯大於基準,或接近資料庫大小的 50%,則 PVS 會被視為很大。

如果 PVS 的大小未減少,請使用下列疑難解答步驟來尋找並解決大型 PVS 大小的原因。

小提示

下列疑難解答步驟中提及的數據行會參考本節中診斷查詢結果集中的數據行。

大型 PVS 大小可能是因為下列任何原因所造成:

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

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

DECLARE @LongTxThreshold int = 900;  /* 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 the generated log threshold for long-running transactions */

SELECT  dbtr.database_id,
        DB_NAME(dbtr.database_id) AS database_name,
        st.session_id,
        st.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 st
ON tr.transaction_id = st.transaction_id
INNER JOIN sys.dm_exec_sessions AS sess
ON st.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 = st.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 sdt.transaction_id,
       sdt.transaction_sequence_num,
       s.database_id,
       s.session_id,
       s.login_time,
       GETDATE() AS query_time,
       s.host_name,
       s.program_name,
       s.login_name,
       s.last_request_start_time
FROM sys.dm_tran_active_snapshot_database_transactions AS sdt
INNER JOIN sys.dm_exec_sessions AS s
ON sdt.session_id = s.session_id;

為防止 PVS 清除延遲:

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

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

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

pvs_off_row_page_skipped_low_water_mark 欄位中的大值可能表明因為次要複本上長時間執行的查詢而導致的清理延遲。 除了延遲 PVS 清除之外,次要副本上長時間執行的查詢也可以延遲 鬼物清理

您可以在主要副本上使用以下範例查詢,以找出次要副本上執行時間較長的查詢是否可能阻止 PVS 清除。 如果寫入工作負載正在主要複本上執行,但 low_water_mark_for_ghosts 欄中的值從一次執行範例查詢到下一次執行中沒有增加,那麼可能是次要複本上的長時間執行查詢阻礙了 PVS 和 ghost 清除。

SELECT database_id,
       DB_NAME(database_id) AS database_name,
       low_water_mark_for_ghosts,
       synchronization_state_desc,
       synchronization_health_desc,
       is_suspended,
       suspend_reason_desc,
       secondary_lag_seconds
FROM sys.dm_hadr_database_replica_states
WHERE is_local = 1
      AND
      is_primary_replica = 1;

如需詳細資訊,請參閱 sys.dm_hadr_database_replica_stateslow_water_mark_for_ghosts 數據行的描述。

連接到每個可讀取的次要副本,找出正在執行長時間查詢的會話,如果有設定允許,考慮終止該會話。 如需詳細資訊,請參閱 尋找慢查詢

檢查大量中止的交易

檢查 aborted_version_cleaner_start_timeaborted_version_cleaner_end_time 數據行,以查看最後一次中止的交易清除是否已完成。 oldest_aborted_transaction_id 應會在中止交易清除完成後向更高的方向移動。 如果 oldest_aborted_transaction_id 遠低於 oldest_active_transaction_id,且 current_abort_transaction_count 值很大,則可能有舊的中止交易正在阻止 PVS 清除。

若要解決由於大量中止交易而導致 PVS 清除延遲的問題,請考慮下列事項:

  • 如果您使用 SQL Server 2022 (16.x),請增加 ADR Cleaner Thread Count 伺服器組態的值。 如需詳細資訊,請參閱 伺服器組態:ADR 清除器線程計數
  • 可能的話,請暫停工作負載,以便版本清理程序能夠順利進行。
  • 檢閱應用程式,以識別並解決高交易中止率問題。 中止可能由於高比率的死結、重複索引鍵、約束條件違反或查詢超時。
  • 將工作負載優化,以減少與 PVS 清除程式所需的物件層級或數據分割層級 IX 鎖定不相容的鎖定。 如需更多資訊,請參閱 鎖相容性
  • 如果使用 SQL Server,為了緊急控制 PVS 大小,請暫時停用 ADR。 請參閱 停用 ADR
  • 如果使用 SQL Server,且中止的交易清除尚未順利完成,請檢查錯誤記錄檔中是否有回報 VersionCleaner 問題的訊息。
  • 如果 PVS 大小沒有如預期般減少,即使清理已完成,請檢查 pvs_off_row_page_skipped_oldest_aborted_xdesid 欄位。 大型數值表示中止的交易中的行版本仍然佔用空間。

控制 PVS 大小

如果您有大量 DML 語句的工作負載(INSERTUPDATEDELETEMERGE),例如高容量 OLTP,並觀察 PVS 大小很大,您可能需要增加 ADR Cleaner Thread Count 伺服器組態的值,以控制 PVS 大小。 如需詳細資訊,請參閱 伺服器組態:ADR 清除器線程計數,從 SQL Server 2022 (16.x) 開始提供。

在 SQL Server 2019 (15.x)中,或當增加 ADR Cleaner Thread Count 組態的值無法有效減少 PVS 大小時,可能需要讓工作負載進行一段時間的休息或復原,以便 PVS 清理過程能夠回收空間。

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

例如:

EXEC sys.sp_persistent_version_cleanup [WideWorldImporters];

擷取清除失敗

從 SQL Server 2022 (16.x) 開始,錯誤記錄檔中會記錄值得注意的 PVS 清除訊息。 清除統計數據也會由 tx_mtvc2_sweep_stats擴充事件報告