Resolução de problemas no bloqueio de consultas em Fabric Data Warehouse

Aplica-se a:✅ Armazém no Microsoft Fabric

Se as tuas consultas no Warehouse demorarem invulgarmente a executar ou parecerem bloqueadas, uma possível causa é um bloqueio. O bloqueio ocorre quando uma sessão mantém um bloqueio que impede que outras consultas prossigam.

Este artigo mostra-lhe como determinar se o bloqueio está a afetar a sua carga de trabalho e que ações pode tomar.

Tip

O armazém utiliza bloqueio ao nível da mesa. Qualquer operação DML adquire um bloqueio em toda a tabela, independentemente do número de linhas afetadas. Este comportamento é diferente do SQL Server, que suporta bloqueios ao nível da linha e da página.

Pré-requisitos

  • Um armazém com cargas de trabalho ativas.
  • Ser membro da função de Visualizador do espaço de trabalho é a permissão mínima para consultar as vistas de gestão dinâmicas (DMVs) mencionadas neste artigo.

Passo 1: Verifique se as consultas estão à espera de fechaduras

Comece por verificar se existem consultas atualmente à espera de bloqueios.

Execute a seguinte consulta:

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

Se a consulta devolver linhas, algumas sessões estão à espera de recursos mantidos por outras sessões. Cada linha indica um pedido de bloqueio que atualmente não pode ser concedido.

Tip

A vista sys.dm_tran_locks pode retornar um grande número de linhas para bloqueios concedidos. Filtrar por request_status = 'WAIT' centra-se nas sessões que estão bloqueadas.

Passo 2: Identificar consultas bloqueadas

De seguida, verifica quais as consultas que estão bloqueadas e que sessão as está a bloquear.

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;

Esta consulta retorna:

  • A sessão que executa a consulta bloqueada (session_id)
  • A sessão que está atualmente a bloqueá-la (blocking_session_id)
  • Há quanto tempo está à espera (total_elapsed_time, em milissegundos)
  • Se a sessão bloqueante tem uma transação aberta (open_transaction_count)

Se uma consulta mostrar blocking_session_id que é diferente de zero e open_transaction_count > 0, está à espera de outra sessão que está a manter um bloqueio.

Passo 3: Encontrar a sessão de bloqueio

Para compreender qual o recurso que está bloqueado, verifique os bloqueios atualmente detidos pela sessão bloqueadora. Substitua um session_id que identificou anteriormente pelo <blocking_session_id> na seguinte consulta de exemplo:

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

Use esta consulta para determinar:

  • Em que recursos a sessão bloqueadora tem atualmente bloqueios. Por exemplo, pode utilizar sys.objects para identificar o/a resource_associated_entity_id onde o/a resource_type = OBJECT.
  • O modo de bloqueio (por exemplo, Exclusivo (X), Schema-Modification (Sch-M))
  • Se o bloqueio está relacionado com uma operação DDL ou atualização estatística (UPDSTATS)

Note

Fechaduras relacionadas com estatísticas (como as de UPDSTATS) também aparecem em sys.dm_tran_locks. Os bloqueios Schema-Modification (Sch-M) e Exclusivo (X) são os bloqueios mais comuns, mas qualquer tipo de bloqueio pode bloquear um pedido incompatível (por exemplo, Sch-S bloqueia Sch-M).

Passo 4: Encontrar o proprietário da transação bloqueadora

Em muitos casos, poderá preferir pedir ao responsável pela transação que está a bloquear para COMMIT ou ROLLBACK o seu trabalho, em vez de encerrar a sessão. Considere usar estruturas TRYCATCH para o tratamento de erros com COMMIT ou ROLLBACK. Para obter mais informações, consulte TRY...CATCH.

Pode identificar o proprietário e fazer a consulta associada à sessão de bloqueio. Substitua um session_id que identificou anteriormente pelo <blocking_session_id> no seguinte exemplo de consulta:

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 é o proprietário da sessão de bloqueio.
  • program_name é a aplicação que iniciou a sessão. O DMS_user valor indica o editor de consultas do portal Fabric.
  • command é o comando atualmente em execução.

Pode então contactar o proprietário da transação para a confirmar ou anulá-la, se adequado.

Passo 5: Verifique se a sessão de bloqueio está ociosa ou não está a progredir

Uma sessão de bloqueio pode parecer ativa, mas não está realmente a progredir.

Os indicadores de uma sessão inativa ou parada incluem:

  • status = 'sleeping' indica que não há consulta ativa em execução.
  • Procure um last_request_start_time significativamente anterior à hora atual, o que indica uma solicitação aberta há muito tempo.
  • Procure um total_elapsed_time que não esteja a aumentar entre verificações, indicando uma sessão estagnada.
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>;
  • Se o estado da sessão for sleeping e open_transaction_count > 0, a sessão tem uma transação aberta sem qualquer consulta ativa — mantém um bloqueio sem executar qualquer operação.
  • Se a sessão aparecer em sys.dm_exec_requests e total_elapsed_time continuar a aumentar entre verificações, a sessão está efetivamente em curso. Pode ser preferível esperar que a transação seja concluída em vez de a terminar e forçar um rollback.

Passo 6: Agir para resolver o bloqueio

Note

As situações de bloqueio muitas vezes resolvem-se sozinhas assim que a sessão de bloqueio conclui a sua transação. Se a sua carga de trabalho tolerar o atraso, esperar é a opção mais segura.

Se precisar de desbloquear consultas a jusante, considere se uma sessão de bloqueio tem as seguintes características:

  • Tem uma transação em aberto
  • Parece parar ou não progredir
  • Está a segurar um bloqueio (por exemplo, Exclusivo (X) ou Sch-M)

Se sim, um membro do papel de espaço de trabalho de Administrador pode terminar uma sessão utilizando:

KILL <session_id>;

O KILL comando irá:

  • Fim da sessão
  • Anular todo o trabalho realizado na transação ativa da sessão
  • Liberta a fechadura
  • Permitir que as consultas a jusante avancem

Atenção

Matar uma sessão reverte todo o trabalho não comprometido realizado por essa sessão. Esta ação pode desfazer alterações de dados feitas pelo utilizador ou aplicação. Use esta opção apenas quando tiver a certeza de que terminar a transação não afeta negativamente a sua carga de trabalho.

Passo 7: Prevenir futuros problemas de bloqueio

Para ajudar a prevenir problemas semelhantes:

  • Evite deixar transações explícitas abertas (BEGIN TRANSACTION sem um correspondente COMMIT ou ROLLBACK).
  • Mantenha as transações de curta duração. Realize apenas as operações necessárias dentro da transação.
  • Sempre COMMIT ou ROLLBACK transações quando concluídas.
  • Agendar operações DDL (como ALTER TABLE) durante janelas de baixo tráfego.

Monitorizar proativamente as transações abertas utilizando:

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;

Monitorizar regularmente as transações abertas e intervir quando apropriado ajuda a reduzir a probabilidade de formação de blockchains.