Udostępnij za pośrednictwem


Rozwiązywanie problemów z błędami dziennika transakcji w usłudze Azure SQL Database

Dotyczy:Azure SQL Database

Mogą wystąpić błędy 9002 lub 40552, gdy dziennik transakcji jest pełny i nie może zaakceptować nowych transakcji. Te błędy występują, gdy dziennik transakcji bazy danych zarządzany przez usługę Azure SQL Database przekracza progi miejsca i nie może nadal akceptować transakcji. Te błędy są podobne do problemów z pełnym dziennikiem transakcji w programie SQL Server, ale mają różne rozwiązania w programie SQL Server, usłudze Azure SQL Database i usłudze Azure SQL Managed Instance.

Uwaga

Ten artykuł koncentruje się na usłudze Azure SQL Database. Usługa Azure SQL Database jest oparta na najnowszej stabilnej wersji aparatu bazy danych programu Microsoft SQL Server, więc większość zawartości jest podobna, chociaż opcje rozwiązywania problemów i narzędzia mogą różnić się od programu SQL Server.

Aby uzyskać więcej informacji na temat rozwiązywania problemów z dziennikiem transakcji w usłudze Azure SQL Managed Instance, zobacz Rozwiązywanie problemów z błędami dziennika transakcji w usłudze Azure SQL Managed Instance.

Aby uzyskać więcej informacji na temat rozwiązywania problemów z dziennikiem transakcji w programie SQL Server, zobacz Rozwiązywanie problemów z pełnym dziennikiem transakcji (błąd programu SQL Server 9002).

Automatyczne kopie zapasowe i dziennik transakcji

W usłudze Azure SQL Database kopie zapasowe dziennika transakcji są wykonywane automatycznie. Aby uzyskać informacje o częstotliwości, przechowywaniu i innych informacjach, zobacz Automatyczne kopie zapasowe.

Wolne miejsce na dysku, wzrost plików bazy danych i lokalizacja pliku są również zarządzane, więc typowe przyczyny i rozwiązania problemów z dziennikami transakcji różnią się od programu SQL Server.

Podobnie jak w przypadku programu SQL Server dziennik transakcji dla każdej bazy danych jest obcinany po pomyślnym zakończeniu tworzenia kopii zapasowej dziennika. Obcięcie pozostawia puste miejsce w pliku dziennika, którego następnie można użyć do nowych transakcji. Gdy plik dziennika nie może być obcięty przez kopie zapasowe dziennika, plik dziennika rośnie, aby pomieścić nowe transakcje. Jeśli plik dziennika osiągnie maksymalny limit w usłudze Azure SQL Database, nowe transakcje zapisu kończą się niepowodzeniem.

Aby uzyskać informacje na temat rozmiarów dziennika transakcji, zobacz:

Zapobieganie obcinaniu dziennika transakcji

Aby dowiedzieć się, co uniemożliwia obcięcie dziennika w danym przypadku, zapoznaj się z log_reuse_wait_desc artykułem .sys.databases Ponowne użycie dziennika informuje o tym, jakie warunki lub przyczyny uniemożliwiają obcięcie dziennika transakcji przez zwykłą kopię zapasową dziennika. Aby uzyskać więcej informacji, zobacz sys.databases (Transact-SQL).

SELECT [name], log_reuse_wait_desc FROM sys.databases;

W przypadku usługi Azure SQL Database zaleca się nawiązanie połączenia z określoną bazą danych użytkownika, a nie z bazą master danych, aby wykonać to zapytanie.

Następujące wartości parametru log_reuse_wait_desc in sys.databases mogą wskazywać przyczynę, dla którego obcinanie dziennika transakcji bazy danych jest blokowane:

Log_reuse_wait_desc Diagnoza Wymagana odpowiedź
NIC Typowy stan. Dziennik nie blokuje obcięcia. Nie
PUNKT KONTROLNY Do obcinania dziennika jest wymagany punkt kontrolny. Rzadko. Nie jest wymagana żadna odpowiedź, chyba że nie zostanie to utrzymane. Jeśli jest to trwałe, prześlij wniosek o pomoc techniczną platformy Azure.
KOPIA ZAPASOWA DZIENNIKA Wymagana jest kopia zapasowa dziennika. Nie jest wymagana żadna odpowiedź, chyba że nie zostanie to utrzymane. Jeśli jest to trwałe, prześlij wniosek o pomoc techniczną platformy Azure.
AKTYWNA KOPIA ZAPASOWA LUB PRZYWRACANIE Trwa tworzenie kopii zapasowej bazy danych. Nie jest wymagana żadna odpowiedź, chyba że nie zostanie to utrzymane. Jeśli jest to trwałe, prześlij wniosek o pomoc techniczną platformy Azure.
AKTYWNA TRANSAKCJA Bieżąca transakcja uniemożliwia obcięcie dziennika. Nie można obcinać pliku dziennika z powodu aktywnych i/lub niezatwierdzonych transakcji. Zobacz następną sekcję.
REPLIKACJI W usłudze Azure SQL Database może się to zdarzyć, jeśli włączono funkcję przechwytywania zmian danych (CDC). Wykonywanie zapytań sys.dm_cdc_errors i usuwanie błędów. Jeśli nie można rozwiązać, prześlij wniosek o pomoc techniczną przy użyciu pomocy technicznej platformy Azure.
AVAILABILITY_REPLICA Trwa synchronizacja z repliką pomocniczą. Nie jest wymagana żadna odpowiedź, chyba że nie zostanie to utrzymane. Jeśli jest to trwałe, prześlij wniosek o pomoc techniczną platformy Azure.

Obcinanie dziennika uniemożliwione przez aktywną transakcję

Najczęstszym scenariuszem dziennika transakcji, który nie może zaakceptować nowych transakcji, jest długotrwała lub zablokowana transakcja.

Uruchom to przykładowe zapytanie, aby znaleźć niezatwierdzone lub aktywne transakcje oraz ich właściwości.

  • Zwraca informacje o właściwościach transakcji z sys.dm_tran_active_transactions.
  • Zwraca informacje o połączeniu sesji z sys.dm_exec_sessions.
  • Zwraca informacje o żądaniach (dla aktywnych żądań) z sys.dm_exec_requests. To zapytanie może również służyć do identyfikowania zablokowanych sesji, wyszukania elementu request_blocked_by. Aby uzyskać więcej informacji, zobacz Zbieranie informacji blokujących.
  • Zwraca tekst lub tekst buforu wejściowego bieżącego żądania przy użyciu widoków DMV sys.dm_exec_sql_text lub sys.dm_exec_input_buffer . Jeśli dane zwrócone przez text pole sys.dm_exec_sql_text ma wartość NULL, żądanie nie jest aktywne, ale ma zaległą transakcję. W takim przypadku event_info pole zawiera sys.dm_exec_input_buffer ostatnią instrukcję przekazaną do aparatu bazy danych.
SELECT [database_name] = db_name(s.database_id)
, tat.transaction_id, tat.transaction_begin_time, tst.session_id 
, session_open_transaction_count = tst.open_transaction_count
, transaction_duration_s = datediff(s, tat.transaction_begin_time, sysdatetime())
, input_buffer = ib.event_info
, request_text = CASE  WHEN r.statement_start_offset = 0 and r.statement_end_offset= 0 THEN left(est.text, 4000)
                       ELSE    SUBSTRING ( est.[text],    r.statement_start_offset/2 + 1, 
                                           CASE WHEN r.statement_end_offset = -1 THEN LEN (CONVERT(nvarchar(max), est.[text])) 
                                                ELSE r.statement_end_offset/2 - r.statement_start_offset/2 + 1
                                           END  )  END
, request_status = r.status
, request_blocked_by = r.blocking_session_id
, transaction_state = CASE tat.transaction_state    
                     WHEN 0 THEN 'The transaction has not been completely initialized yet.'
                     WHEN 1 THEN 'The transaction has been initialized but has not started.'
                     WHEN 2 THEN 'The transaction is active - has not been committed or rolled back.'
                     WHEN 3 THEN 'The transaction has ended. This is used for read-only transactions.'
                     WHEN 4 THEN 'The commit process has been initiated on the distributed transaction. This is for distributed transactions only. The distributed transaction is still active but further processing cannot take place.'
                     WHEN 5 THEN 'The transaction is in a prepared state and waiting resolution.'
                     WHEN 6 THEN 'The transaction has been committed.'
                     WHEN 7 THEN 'The transaction is being rolled back.'
                     WHEN 8 THEN 'The transaction has been rolled back.' END 
, transaction_name = tat.name
, azure_dtc_state    --Applies to: Azure SQL Database only
             =    CASE tat.dtc_state 
                 WHEN 1 THEN 'ACTIVE'
                 WHEN 2 THEN 'PREPARED'
                 WHEN 3 THEN 'COMMITTED'
                 WHEN 4 THEN 'ABORTED'
                 WHEN 5 THEN 'RECOVERED' END
, transaction_type = CASE tat.transaction_type    WHEN 1 THEN 'Read/write transaction'
                                             WHEN 2 THEN 'Read-only transaction'
                                             WHEN 3 THEN 'System transaction'
                                             WHEN 4 THEN 'Distributed transaction' END
, tst.is_user_transaction
, local_or_distributed = CASE tst.is_local WHEN 1 THEN 'Local transaction, not distributed' WHEN 0 THEN 'Distributed transaction or an enlisted bound session transaction.' END
, transaction_uow    --for distributed transactions. 
, s.login_time, s.host_name, s.program_name, s.client_interface_name, s.login_name, s.is_user_process
, session_cpu_time = s.cpu_time, session_logical_reads = s.logical_reads, session_reads = s.reads, session_writes = s.writes
, observed = sysdatetimeoffset()
FROM sys.dm_tran_active_transactions AS tat 
INNER JOIN sys.dm_tran_session_transactions AS tst  on tat.transaction_id = tst.transaction_id
INNER JOIN Sys.dm_exec_sessions AS s on s.session_id = tst.session_id 
LEFT OUTER JOIN sys.dm_exec_requests AS r on r.session_id = s.session_id
CROSS APPLY sys.dm_exec_input_buffer(s.session_id, null) AS ib 
OUTER APPLY sys.dm_exec_sql_text (r.sql_handle) AS est;

Zarządzanie plikami w celu zwolnienia większej ilości miejsca

Jeśli dziennik transakcji nie może zostać obcięty w elastycznych pulach usługi Azure SQL Database, zwolnienie miejsca dla elastycznej puli może być częścią rozwiązania. Jednak rozpoznawanie katalogu głównego warunku blokującego obcinanie pliku dziennika transakcji jest kluczem. W niektórych przypadkach tymczasowe utworzenie większej ilości miejsca na dysku umożliwia ukończenie długotrwałych transakcji, usunięcie warunku blokującego obcięcie pliku dziennika transakcji z normalną kopią zapasową dziennika transakcji. Jednak zwolnienie miejsca może zapewnić tylko tymczasową ulgę do czasu ponownego wzrostu dziennika transakcji.

Aby uzyskać więcej informacji na temat zarządzania przestrzenią plików baz danych i elastycznymi pulami, zobacz Zarządzanie miejscem na pliki dla baz danych w usłudze Azure SQL Database.

Błąd 40552: Sesja została zakończona z powodu nadmiernego użycia miejsca w dzienniku transakcji

40552: The session has been terminated because of excessive transaction log space usage. Try modifying fewer rows in a single transaction.

Aby rozwiązać ten problem, wypróbuj poniższe metody:

  1. Problem może wystąpić w dowolnej operacji DML, takiej jak wstawianie, aktualizowanie lub usuwanie. Przejrzyj transakcję, aby uniknąć niepotrzebnych zapisów. Spróbuj zmniejszyć liczbę wierszy, które są obsługiwane natychmiast, implementując przetwarzanie wsadowe lub dzielenie na wiele mniejszych transakcji. Aby uzyskać więcej informacji, zobacz How to use batching to improve SQL Database application performance (Jak używać przetwarzania wsadowego w celu zwiększenia wydajności aplikacji usługi SQL Database).
  2. Problem może wystąpić z powodu operacji ponownego kompilowania indeksu. Aby uniknąć tego problemu, upewnij się, że następująca formuła jest prawdziwa: (liczba wierszy, których dotyczy tabela) pomnożona przez (średni rozmiar pola zaktualizowanego w bajtach + 80) < 2 gigabajtów (GB). W przypadku dużych tabel rozważ utworzenie partycji i przeprowadzenie konserwacji indeksu tylko na niektórych partycjach tabeli. Aby uzyskać więcej informacji, zobacz Create Partitioned Tables and Indexes (Tworzenie partycjonowanych tabel i indeksów).
  3. Jeśli wykonujesz operacje zbiorcze wstawiania przy użyciu bcp.exe narzędzia lub System.Data.SqlClient.SqlBulkCopy klasy, spróbuj użyć -b batchsize opcji lub BatchSize , aby ograniczyć liczbę wierszy skopiowanych do serwera w każdej transakcji. Aby uzyskać więcej informacji, zobacz narzędzie bcp.
  4. Jeśli ponownie kompilujesz indeks za pomocą instrukcji ALTER INDEX , użyj SORT_IN_TEMPDB = ONopcji , ONLINE = ONi RESUMABLE=ON . W przypadku indeksów z możliwością wznowienia obcinanie dzienników jest częstsze. Aby uzyskać więcej informacji, zobacz ALTER INDEX (Transact-SQL).

Uwaga

Aby uzyskać więcej informacji na temat innych błędów ładu zasobów, zobacz Błędy ładu zasobów.

Następne kroki