Rozwiązywanie problemów z blokowaniem zapytań w Fabric Data Warehouse

Dotyczy:✅ Magazyn w systemie Microsoft Fabric

Jeśli Twoje zapytania w Warehouse wykonują się wyjątkowo długo lub wyglądają na zawieszone, jedną z możliwych przyczyn są blokady. Blokowanie występuje, gdy sesja przechowuje blokadę, która uniemożliwia kontynuowanie innych zapytań.

W tym artykule pokazano, jak określić, czy blokowanie wpływa na obciążenie i jakie działania można wykonać.

Wskazówka

Warehouse stosuje blokowanie na poziomie tabeli. Każda operacja DML nakłada blokadę na całą tabelę, niezależnie od liczby wierszy, których dotyczy. To zachowanie różni się od SQL Server, które obsługuje blokady na poziomie wiersza i na poziomie strony.

Wymagania wstępne

  • Hurtownia z aktywnymi obciążeniami roboczymi.
  • Członkostwo w roli obszaru roboczego Viewer to minimalny poziom uprawnień wymagany do odpytywania dynamicznych widoków zarządzania (DMV) opisanych w tym artykule.

Krok 1. Sprawdzanie, czy zapytania oczekują na blokady

Zacznij od sprawdzenia, czy jakieś zapytania obecnie oczekują na blokady.

Uruchom poniższe zapytanie:

SELECT
    request_session_id,
    resource_type,
    resource_description,
    request_mode,
    request_status
FROM sys.dm_tran_locks
WHERE request_status = 'WAIT';

Jeśli zapytanie zwraca wiersze, niektóre sesje oczekują na zasoby przechowywane przez inne sesje. Każdy wiersz wskazuje żądanie blokady, którego obecnie nie można udzielić.

Wskazówka

Widok sys.dm_tran_locks może zwracać dużą liczbę wierszy dotyczących przyznanych blokad. Filtrowanie według request_status = 'WAIT' koncentruje się na sesjach, które są blokowane.

Krok 2. Identyfikowanie zablokowanych zapytań

Następnie sprawdź, które zapytania są blokowane i która sesja je blokuje.

SELECT
    session_id,
    status,
    blocking_session_id,
    wait_type,
    total_elapsed_time,
    open_transaction_count
FROM sys.dm_exec_requests
WHERE blocking_session_id <> 0;

To zapytanie zwraca:

  • Sesja z uruchomionym zablokowanym zapytaniem (session_id)
  • Sesja, która obecnie ją blokuje (blocking_session_id)
  • Jak długo czeka (total_elapsed_timew milisekundach)
  • Czy sesja blokująca ma otwartą transakcję (open_transaction_count)

Jeśli zapytanie pokazuje, że blocking_session_id jest różne od zera, a open_transaction_count > 0, oznacza to, że czeka na inną sesję, która utrzymuje blokadę.

Krok 3. Znajdowanie sesji blokującej

Aby zrozumieć, jaki zasób jest zablokowany, sprawdź blokady aktualnie przechowywane przez sesję blokującą. Zastąp element <blocking_session_id> w następującym przykładowym zapytaniu wcześniej zidentyfikowanym elementem session_id:

SELECT
    request_session_id,
    resource_type,
    resource_associated_entity_id,
    request_mode,
    request_status
FROM sys.dm_tran_locks
WHERE
    request_status = 'GRANT'
    AND request_session_id = <blocking_session_id>;

Użyj tego zapytania, aby określić:

  • Na których zasobach sesja blokująca obecnie ma założone blokady. Na przykład można użyć sys.objects, aby zidentyfikować resource_associated_entity_id, gdzie resource_type = OBJECT.
  • Tryb blokady (na przykład wyłączny (X), modyfikacja schematu (Sch-M))
  • Określa, czy blokada jest powiązana z operacją DDL, czy aktualizacją statystyk (UPDSTATS)

Note

Blokady związane ze statystykami (takie jak te z UPDSTATS) również są wyświetlane w pliku sys.dm_tran_locks. Blokady Schema-Modification (Sch-M) i Exclusive (X) są najczęstszymi elementami blokującymi, ale każdy typ blokady może blokować żądanie będące z nim w konflikcie (na przykład Sch-S blokuje Sch-M).

Krok 4. Znajdowanie blokującego właściciela transakcji

W wielu przypadkach możesz woleć poprosić właściciela blokującej transakcji o COMMIT lub ROLLBACK jego pracy zamiast kończyć sesję. Rozważ użycie struktur TRYCATCH do obsługi błędów przy użyciu COMMIT lub ROLLBACK. Aby uzyskać więcej informacji, zobacz TRY... CATCH.

Możesz zidentyfikować właściciela i zapytanie skojarzone z sesją blokującą. Zastąp znacznik <blocking_session_id> w następującym przykładowym zapytaniu wcześniej zidentyfikowanym elementem session_id.

SELECT
    r.session_id,
    s.login_name,
    s.program_name,
    r.status,
    r.blocking_session_id,
    r.command,
    r.total_elapsed_time,
    s.last_request_start_time,
    s.last_request_end_time
FROM sys.dm_exec_requests r
JOIN sys.dm_exec_sessions s
    ON r.session_id = s.session_id
WHERE r.session_id = <blocking_session_id>;
  • login_name jest właścicielem blokującej sesji.
  • program_name to aplikacja, która zainicjowała sesję. Wartość DMS_user wskazuje edytor zapytań portalu Fabric.
  • command to polecenie aktualnie uruchomione.

Następnie możesz skontaktować się z właścicielem transakcji, aby zatwierdzić lub wycofać ją w razie potrzeby.

Krok 5: Sprawdź, czy sesja blokująca jest bezczynna lub czy nie wykazuje postępu

Sesja blokująca może wyglądać na aktywną, ale w rzeczywistości nie robi postępów.

Wskaźniki bezczynności lub wstrzymanej sesji obejmują:

  • status = 'sleeping' wskazuje brak uruchomionego aktywnego zapytania.
  • Poszukaj wartości last_request_start_time, która jest znacznie wcześniejsza od bieżącego czasu, co wskazuje na długotrwale otwarte żądanie.
  • Poszukaj wartości total_elapsed_time, która nie zwiększa się między kolejnymi sprawdzeniami, co wskazuje na zawieszoną sesję.
SELECT
    session_id,
    status,
    last_request_start_time,
    last_request_end_time,
    open_transaction_count
FROM sys.dm_exec_sessions
WHERE session_id = <blocking_session_id>;
  • Jeśli stan sesji to sleeping i open_transaction_count > 0, sesja ma otwartą transakcję bez aktywnego zapytania — utrzymuje blokadę, nie wykonując żadnej pracy.
  • Jeśli sesja pojawia się w sys.dm_exec_requests, a wartość total_elapsed_time nadal rośnie między kolejnymi sprawdzeniami, sesja aktywnie postępuje. Może być lepiej poczekać na zakończenie transakcji, a nie zakończyć ją i wymusić wycofanie.

Krok 6. Podjęcie akcji w celu rozwiązania problemu z blokowaniem

Note

Sytuacje blokujące często są rozwiązywane samodzielnie po zakończeniu transakcji przez sesję blokującą. Jeśli obciążenie może tolerować opóźnienie, oczekiwanie jest najbezpieczniejszą opcją.

Jeśli musisz odblokować zapytania podrzędne, rozważ, czy sesja blokująca ma następujące cechy:

  • Ma otwartą transakcję
  • Pojawia się w stanie bezczynności lub nie postępuje
  • Utrzymuje blokadę blokującą (na przykład blokadę wyłączną (X) lub Sch-M)

Jeśli tak, członek roli obszaru roboczego Administrator może zakończyć sesję przy użyciu:

KILL <session_id>;

Polecenie KILL spowoduje:

  • Kończ sesję
  • Wycofaj wszystkie zmiany wprowadzone w aktywnej transakcji tej sesji
  • Zwolnij blokadę
  • Zezwalaj na kontynuowanie zapytań podrzędnych

Caution

Zakończenie sesji powoduje wycofanie wszystkich niezatwierdzonych zmian wykonanych w tej sesji. Ta akcja może cofnąć zmiany danych wprowadzone przez użytkownika lub aplikację. Użyj tej opcji tylko wtedy, gdy masz pewność, że zakończenie transakcji nie wpływa negatywnie na obciążenie.

Krok 7. Zapobieganie przyszłym problemom z blokowaniem

Aby zapobiec podobnym problemom:

  • Unikaj pozostawiania otwartych jawnych transakcji (BEGIN TRANSACTION bez odpowiadającego elementu COMMIT lub ROLLBACK).
  • Stosuj krótkotrwałe transakcje. Wykonaj tylko niezbędne operacje w ramach transakcji.
  • Zawsze COMMIT lub ROLLBACK transakcje po ich zakończeniu.
  • Planuj operacje DDL (takie jak ALTER TABLE) na okresy niskiego obciążenia.

Proaktywne monitorowanie otwartych transakcji przy użyciu:

SELECT
    session_id,
    login_name,
    open_transaction_count,
    program_name,
    status,
    blocking_session_id,
    last_request_start_time
FROM sys.dm_exec_sessions
WHERE open_transaction_count > 0;

Regularne monitorowanie otwartych transakcji i interweniowanie, gdy jest to konieczne, pomaga zmniejszyć prawdopodobieństwo tworzenia łańcuchów blokujących.