Sdílet prostřednictvím


Řešení potíží s akcelerovaným obnovením databáze

platí pro: SQL Server 2019 (15.x) a novější verze Azure SQL DatabaseAzure SQL Managed InstanceSQL Database v Microsoft Fabric

Tento článek pomáhá diagnostikovat problémy s zrychleným obnovením databáze (ADR) v SQL Serveru 2019 (15.x) a novějším, službě Azure SQL Managed Instance, Azure SQL Database a databází SQL v Microsoft Fabric.

Prozkoumejte velikost PVS

Pomocí sys.dm_tran_persistent_version_store_stats DMV zjistěte, jestli je velikost trvalého úložiště verzí větší než se čekalo.

Následující ukázkový dotaz ukazuje informace o aktuální velikosti PVS, procesech vyčištění a dalších podrobnostech:

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();

Zkontrolujte sloupec pvs_pct_of_database_size a podívejte se na velikost PVS vzhledem k celkové velikosti databáze. Všimněte si jakýchkoli rozdílů od typické velikosti PVS ve srovnání s referenčními hodnotami zjištěnými během jiných období aktivity aplikace. PVS se považuje za velký, pokud je výrazně větší než referenční hodnota nebo je blízko 50% velikosti databáze. Pomocí následujícího postupu při řešení potíží vyhledejte důvod velké velikosti PVS.

Pokud je velikost PVS větší, než se čekalo, zkontrolujte následující:

Kontrola dlouhotrvajících aktivních transakcí

Dlouhotrvající aktivní transakce můžou zabránit vyčištění PVS v databázích, které mají povolenou službu ADR. Pomocí sloupce oldest_transaction_begin_time zkontrolujte počáteční čas nejstarší aktivní transakce. Další informace o dlouhotrvajících transakcích najdete v následujícím ukázkovém dotazu. Můžete nastavit prahové hodnoty pro dobu trvání transakce a množství vygenerovaného transakčního protokolu:

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;

S identifikovanými relacemi zvažte ukončení těchto relací, pokud je to povoleno. Zkontrolujte aplikaci a zjistěte povahu problematických aktivních transakcí, abyste se vyhnuli problému v budoucnu.

Další informace o řešení potíží s dlouhotrvajícími dotazy najdete v tématu:

Kontrola dlouhotrvajících aktivních skenů snímků

Dlouhotrvající aktivní prohledávání snímků mohou zabránit procesu čištění PVS v databázích, které mají aktivovanou funkci ADR. Příkazy používající READ COMMITTED izolaci snímků (RCSI) nebo SNAPSHOTúrovně izolace přijímají časové razítka na úrovni instance. Snímek skenování používá časové razítko k rozhodování o viditelnosti řádků verze pro transakce RCSI nebo SNAPSHOT. Každý příkaz používající RCSI má vlastní časové razítko, zatímco SNAPSHOT izolace má časové razítko na úrovni transakce.

Tato časová razítka transakcí na úrovni instance se používají i v transakcích s jednou databází, protože každá transakce může vyzvat k transakci mezi databázemi. Prohledávání snímků může proto bránit vyčištění PVS v libovolné databázi ve stejné instanci databázového stroje. Podobně platí, že pokud není povolené ADR, můžou kontroly snímků zabránit vyčištění úložiště verzí v tempdb. V důsledku toho může PVS zvětšit velikost, pokud jsou přítomny dlouhotrvající transakce, které používají SNAPSHOT nebo RCSI.

Ve sloupci dotazu na řešení potíží na začátku tohoto článku se ve sloupci pvs_off_row_page_skipped_min_useful_xts zobrazuje počet stránek vynechaných pro obnovu kvůli dlouhému skenování snímků. Pokud tento sloupec zobrazuje větší hodnotu než obvykle, znamená to, že dlouhé skenování snímků brání vyčištění PVS.

Pomocí následujícího ukázkového dotazu vyhledejte relaci s dlouhotrvající transakcí SNAPSHOT nebo 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;

Jak zabránit zpoždění čištění PVS:

  • Pokud je to možné, zvažte ukončení dlouhé relace aktivní transakce, která zpožďuje vyčištění PVS.
  • Vylaďte dlouhotrvající dotazy, aby se zkrátila doba trvání dotazu.
  • Zkontrolujte aplikaci a zjistěte povahu problematické aktivní kontroly snímků. Zvažte jinou úroveň izolace, například READ COMMITTEDmísto SNAPSHOT nebo RCSI, pro dlouhotrvající dotazy, které způsobují zpoždění při vyčišťování PVS. K tomuto problému dochází častěji s úrovní izolace SNAPSHOT.
  • V elastických fondech Azure SQL Database zvažte přesun databází s dlouhotrvajícími transakcemi pomocí izolace SNAPSHOT nebo RCSI z elastického fondu.

Kontrola dlouhotrvajících dotazů na sekundárních replikách

Pokud databáze obsahuje sekundární repliky, zkontrolujte, jestli se sekundární dolní mez posouvá.

Identifikujte dlouhotrvající dotazy na sekundární replice spuštěním následujících DMV (zobrazení dynamické správy) na primární replice, které mohou bránit vyčištění PVS.

Ve zobrazení dynamické správy sys.dm_tran_persistent_version_store_stats mohou sloupce pvs_off_row_page_skipped_low_water_mark také indikovat zpoždění údržby způsobené dlouhotrvajícím dotazem na sekundární replice.

Připojte se k sekundární replice, vyhledejte relaci, na které běží dlouhý dotaz, a pokud je tato relace povolená, zvažte ukončení relace. Dlouhotrvající dotaz na sekundární replice může zdržovat čištění PVS a zároveň zabránit čištění duchů.

Kontrola velkého počtu přerušených transakcí

Pokud se žádný z předchozích scénářů nevztahuje na vaše úlohy, je pravděpodobné, že se čištění se zpožďuje kvůli velkému počtu zrušených transakcí. Zkontrolujte aborted_version_cleaner_last_start_time a aborted_version_cleaner_last_end_time sloupce a zjistěte, jestli se dokončilo poslední přerušené vyčištění transakce. oldest_aborted_transaction_id by se mělo po dokončení vyčištění neúspěšné transakce přesunout na vyšší úroveň. Pokud je oldest_aborted_transaction_id mnohem nižší než oldest_active_transaction_ida current_abort_transaction_count má větší hodnotu, pravděpodobně dojde k přerušení staré transakce, která brání vyčištění PVS.

Pokud chcete vyřešit velký počet přerušených transakcí, zvažte následující:

  • Pokud je to možné, zastavte pracovní zátěž a umožněte čističi verze pokročit.
  • Optimalizujte úlohu, abyste snížili zámky na úrovni objektů.
  • Zkontrolujte aplikaci a zjistěte problém s vysokou rychlostí přerušení transakce. Přerušení může pocházet z vysoké míry zablokování, duplicitních klíčů, porušení omezení nebo vypršení časového limitu dotazu.
  • Pokud používáte SQL Server, zakažte ADR jako krok jen pro nouzové situace, abyste mohli řídit velikost PVS. Viz Zakázat ADR.
  • Pokud nedávno nebylo úspěšně dokončeno vyčištění přerušené transakce, zkontrolujte v chybovém protokolu zprávy, které hlásí problémy VersionCleaner.
  • Pokud se velikost PVS nezmenší podle očekávání i po dokončení čištění, zkontrolujte sloupec pvs_off_row_page_skipped_oldest_aborted_xdesid. Velké hodnoty označují, že se prostor stále používá pro verze řádků ze zrušených transakcí.

Ruční spuštění procesu čištění PVS

Pokud máte úlohu s velkým objemem příkazů DML (INSERT, UPDATE, DELETE, MERGE), jako je OLTP s velkým objemem, může proces čištění PVS vyžadovat dobu odpočinku a obnovení, aby se uvolnilo místo.

Chcete-li aktivovat proces čištění PVS ručně mezi úlohami, nebo během údržby, použijte systémovou uloženou proceduru sys.sp_persistent_version_cleanup.

Například:

EXEC sys.sp_persistent_version_cleanup [WideWorldImporters];

Zachytit selhání při čištění

Od SQL Serveru 2022 (16.x) se chování čištění PVS zaznamená do protokolu chyb. Obvykle to vede k nové události protokolu zaznamenané každých 10 minut. Statistiky čištění jsou hlášeny také prostřednictvím rozšířené události tx_mtvc2_sweep_stats.