Notatka
Dostęp do tej strony wymaga autoryzacji. Może spróbować zalogować się lub zmienić katalogi.
Dostęp do tej strony wymaga autoryzacji. Możesz spróbować zmienić katalogi.
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.
- Aby uzyskać więcej informacji na temat rozwiązywania problemów z widokami DMV, zobacz Monitorowanie połączeń, sesji i żądań przy użyciu widoków DMV.
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, gdzieresource_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_namejest właścicielem blokującej sesji. -
program_nameto aplikacja, która zainicjowała sesję. WartośćDMS_userwskazuje edytor zapytań portalu Fabric. -
commandto 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
sleepingiopen_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_timenadal 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) lubSch-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 TRANSACTIONbez odpowiadającego elementuCOMMITlubROLLBACK). - Stosuj krótkotrwałe transakcje. Wykonaj tylko niezbędne operacje w ramach transakcji.
- Zawsze
COMMITlubROLLBACKtransakcje 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.