Monitoramento de Espaço e Performance do Tempdb no SQL Server

O monitoramento do banco de dados tempdb é uma tarefa crítica para administradores de SQL Server, pois o esgotamento de espaço nesse recurso pode interromper transações e impactar a disponibilidade do ambiente. Diferente de bancos de dados comuns, o tempdb gerencia objetos internos e versões de linha que não aparecem em visualizações tradicionais como sys.partitions ou através do comando sp_spaceused.

Estrutura de Uso de Espaço

Para uma análise precisa, é necessário classificar o uso do espaço em três categorias principais:

  • Objetos do Usuário: Tabelas temporárias (#temp), variáveis de tabela e índices.
  • Objetos Internos: Tabelas de trabalho usadas para operações de sort, hash joins e cursores.
  • Versões de Linha (Version Store): Dados mantidos para dar suporte a níveis de isolamento de snpashot, gatilhos (triggers) e operações de índice online.

Visualizações de Gerenciamento Dinâmico (DMVs) essenciais

As DMVs abaixo premitem mapear como o espaço está sendo distribuído entre os arquivos e as sessões ativas:

1. sys.dm_db_file_space_usage

Esta visão detalha a alocação por arquivo físico dentro do tempdb.

Coluna Descrição
unallocated_extent_page_count Páginas em extensões não alocadas (espaço livre).
version_store_reserved_page_count Páginas reservadas para o Version Store.
user_object_reserved_page_count Páginas alocadas para objetos criados pelo usuário.
internal_object_reserved_page_count Páginas alocadas para processos internos do motor SQL.

2. sys.dm_db_session_space_usage

Utilizada para identificar quais sessões estão consumindo recursos excessivos de páginas temporárias. Importante notar que os contadores são atualizados conforme as tarefas são concluídas.

Scripts de Diagnóstico de Espaço

O script a seguir consolida informações de uso global e por sessão, permitindo identificar consultas "ofensoras" que estão saturando o disco:

-- Consulta de resumo de utilização global do TempDB
SELECT 
    DB_NAME(database_id) AS NomeBanco,
    CAST(SUM(user_object_reserved_page_count) * 8.0 / 1024 AS DECIMAL(10,2)) AS EspacoUsuario_MB,
    CAST(SUM(internal_object_reserved_page_count) * 8.0 / 1024 AS DECIMAL(10,2)) AS EspacoInterno_MB,
    CAST(SUM(version_store_reserved_page_count) * 8.0 / 1024 AS DECIMAL(10,2)) AS VersionStore_MB,
    CAST(SUM(unallocated_extent_page_count) * 8.0 / 1024 AS DECIMAL(10,2)) AS EspacoLivre_MB
FROM sys.dm_db_file_space_usage
WHERE database_id = 2 -- ID do TempDB
GROUP BY database_id;

-- Identificação de sessões com alto consumo de objetos internos e temporários
SELECT 
    s.session_id,
    s.login_name,
    s.host_name,
    (usage.user_objects_alloc_page_count * 8 / 1024) AS AlocUsuario_MB,
    (usage.user_objects_dealloc_page_count * 8 / 1024) AS DesalocUsuario_MB,
    (usage.internal_objects_alloc_page_count * 8 / 1024) AS AlocInterno_MB,
    (usage.internal_objects_dealloc_page_count * 8 / 1024) AS DesalocInterno_MB,
    st.text AS TextoSQL
FROM sys.dm_db_session_space_usage AS usage
INNER JOIN sys.dm_exec_sessions AS s ON usage.session_id = s.session_id
LEFT JOIN sys.dm_exec_requests AS r ON s.session_id = r.session_id
OUTER APPLY sys.dm_exec_sql_text(r.sql_handle) AS st
WHERE usage.session_id > 50 
  AND (usage.user_objects_alloc_page_count > 0 OR usage.internal_objects_alloc_page_count > 0);

Monitoramento do Version Store

O Version Store pode crescer indefinidamente se houver transações de longa duração abertas sob o isolamento de snapshot. Para localizar a transação mais antiga que está impedindo a limpeza do tempdb, utilize:

SELECT 
    at.transaction_id,
    at.elapsed_time_seconds,
    st.session_id,
    st.is_snapshot
FROM sys.dm_tran_active_snapshot_database_transactions at
INNER JOIN sys.dm_tran_session_transactions st ON at.transaction_id = st.transaction_id
ORDER BY at.elapsed_time_seconds DESC;

Análise de Gargalos de I/O

Como o tempdb é intensamente acessado, o disco pode se tornar um limitador de performance. Podemos medir a latência de leitura e escrita através da DMV sys.dm_io_virtual_file_stats:

SELECT 
    file_id,
    num_of_reads,
    io_stall_read_ms / NULLIF(num_of_reads, 0) AS LatenciaLeitura_ms,
    num_of_writes,
    io_stall_write_ms / NULLIF(num_of_writes, 0) AS LatenciaEscrita_ms
FROM sys.dm_io_virtual_file_stats(2, NULL);

Valores ideais para o tempdb devem estar abaixo de 10ms para leitura e 5ms para escrita. Latências superiores a 20ms indicam a necessidade de mover os arquivos para discos mais rápidos (como SSDs/NVMe) ou revisar a configuração de arquivos de dados.

Identificação de Contenção de Metadados (DDL)

A criação e destruição excessiva de tabelas temporárias pode causar contenção em páginas de metadados do sistema (PFS, GAM, SGAM). Para observar se há sessões aguardando recursos do tempdb, monitore os latches:

SELECT 
    session_id, 
    wait_duration_ms, 
    resource_description, 
    wait_type
FROM sys.dm_os_waiting_tasks
WHERE resource_description LIKE '2:%' 
  AND wait_type LIKE 'PAGE%LATCH_%';

Se houver muitos registros onde o resource_description aponta para as primeiras páginas dos arquivos (ex: 2:1:1, 2:1:2, 2:1:3), considere habilitar a flag 1118 (em versões antigas) ou garantir que múltiplos arquivos de dados de tamanho igual foram criados para o tempdb.

Tags: SQL-Server tempdb database-monitoring sql-performance dmv

Publicado em 7-28 14:05