Uso do recurso de controle de versão de linha

A estrutura de controle de versão de linha dá suporte aos seguintes recursos disponíveis no SQL Server:

  • Gatilhos

  • MARS (vários conjuntos de resultados ativos)

  • Indexação online

A estrutura de controle de versão de linha também dá suporte aos seguintes níveis de isolamento da transação baseada no controle de versão de linha que, por padrão, não estão habilitados:

  • Quando a opção de banco de dados READ_COMMITTED_SNAPSHOT for ON, as transações READ_COMMITTED fornecerão consistência de leitura no nível da instrução usando o controle de versão de linha.

  • Quando a opção de banco de dados ALLOW_SNAPSHOT_ISOLATION for ON, as transações SNAPSHOT fornecerão consistência de leitura no nível da transação usando o controle de versão de linha.

Os níveis de isolamento com base no controle de versão de linha reduzem o número de bloqueios adquiridos pela transação eliminando o uso de bloqueios compartilhados em operações de leitura. Isso aumenta o desempenho do sistema reduzindo os recursos usados para gerenciar bloqueios. O desempenho também é aumentado pela redução do número de vezes em que uma transação fica bloqueada por bloqueios adquiridos por outras transações.

Os níveis de isolamento com base no controle de versão de linha aumentam os recursos necessários pelas modificações de dados. Habilitar essas opções faz com que todas as modificações de dados no banco de dados sejam controladas por versão. Uma cópia dos dados antes da modificação é armazenada em tempdb, mesmo quando não há transações ativas que usam o isolamento com base em controle de versão de linha. Os dados após a modificação incluem um ponteiro para os dados controlados por versão armazenados em tempdb. Para objetos grandes, apenas parte do objeto alterado é copiada em tempdb.

Espaço usado em tempdb

Para cada instância do Mecanismo de Banco de Dados, o tempdb deve ter espaço suficiente para manter as versões de linha geradas para cada banco de dados na instância. O administrador de banco do dados deve garantir que tempdb tem espaço suficiente para oferecer suporte ao armazenamento da versão. Há dois armazenamentos de versão em tempdb:

  • O repositório da versão de compilação de índices online é usado para compilações de índices online em todos os bancos de dados.

  • O repositório da versão comum é usado para todas as outras operações de modificação de dados em todos os bancos de dados.

As versões de linha devem ser armazenadas enquanto uma transação ativa precisar acessá-las. Uma vez a cada minuto, um thread em segundo plano remove as versões de linha que não são mais necessárias e libera o espaço da versão no tempdb. Uma transação de longa execução impedirá que o espaço do repositório da versão seja liberado se forem encontradas as seguintes condições:

  • Ela usa isolamento com base em controle de versão de linha.

  • Ela usa gatilhos, MARS ou operações de compilação de índices online.

  • Ela gera versões de linha.

ObservaçãoObservação

Quando um gatilho é acionado em uma transação, são mantidas as versões de linha criadas pelo gatilho até o término da transação, mesmo quando as versões de linha não forem mais necessárias após o gatilho ser concluído. Isso também se aplica a transações confirmadas por leitura que usam controle de versão de linha. Com esse tipo de transação, uma exibição consistente de maneira transacional do banco de dados é necessária apenas para cada instrução na transação. Isso significa que as versões de linha criadas para uma instrução na transação não são necessárias depois que a instrução é concluída. Porém, as versões de linha criadas por cada instrução na transação são mantidas até que a transação seja concluída.

Quando o espaço no tempdb for insuficiente, o Mecanismo de Banco de Dados reduzirá os armazenamentos da versão. Durante o processo de redução, as transações mais longas que estiverem sendo executadas e que ainda não geraram versões de linha serão marcadas como vítimas. Uma mensagem 3967 é gerada no log de erros para cada transação vítima. Se uma transação for marcada como uma vítima, não poderá ler as versões de linha no armazenamento da versão. Ao tentar ler versões de linhas, a mensagem 3966 é gerada e a transação é revertida. Se o processo de redução for executado com êxito, haverá espaço disponível em tempdb. Caso contrário, o tempdb ficará sem espaço e ocorrerá o seguinte:

  • As operações de gravação continuarão a ser executadas, mas não gerarão versões. Uma mensagem informativa (3959) será exibida no log de erros, mas a transação que grava dados não será afetada.

  • As transações que tentam acessar versões de linha que não foram geradas devido a uma reversão completa de tempdb serão encerradas com um erro 3958.

Espaço usado em linhas de dados

Cada linha de banco de dados pode usar até 14 bytes ao término da linha para obter informações sobre o controle de versão de linha. As informações sobre o controle de versão de linha contêm o número de sequência da transação que confirmou a versão e o ponteiro da linha controlada por versão. Esses 14 bytes são adicionados na primeira vez em que a linha é modificada, ou quando uma nova linha é inserida, em qualquer uma destas condições:

  • A opção READ_COMMITTED_SNAPSHOT ou ALLOW_SNAPSHOT_ISOLATION está ON.

  • A tabela tem um gatilho.

  • Os MARS (conjuntos de resultados ativos múltiplos) estão sendo usados.

  • As operações de compilação de índices online estão sendo executadas atualmente na tabela.

Esses 14 bytes são removidos da linha do banco de dados na primeira vez em que a linha é modificada nestas condições:

  • As opções READ_COMMITTED_SNAPSHOT e ALLOW_SNAPSHOT_ISOLATION estão OFF.

  • O gatilho não existe mais na tabela.

  • Os MARS não estão sendo usados.

  • As operações de compilação de índices online não estão sendo executadas no momento.

Se você usar qualquer um dos recursos de versão de linha, poderá ser necessário alocar espaço em disco adicional para o banco de dados para acomodar a linha de 14 bytes por banco de dados. A adição das informações de controle de versão de linha poderá causar a divisão da página de índice ou a alocação de uma nova página de dados se não houver espaço disponível suficiente na página atual. Por exemplo, se o comprimento médio da linha for 100 bytes, os 14 bytes adicionais farão com que uma tabela existente cresça até 14%.

A redução do fator de preenchimento pode ajudar a impedir ou diminuir a fragmentação de páginas de índice. Para exibir informações de fragmentação para os dados e índices de uma tabela ou exibição, use DBCC SHOWCONTIG.

Espaço usado em objetos grandes

O Mecanismo de banco de dados do SQL Server dá suporte a seis tipos de dados que podem manter grandes cadeias de caracteres com até 2 GB (gigabytes) de comprimento: nvarchar(max), varchar(max), varbinary(max), ntext, text e image. Grandes cadeias de caracteres armazenadas que usam esses tipos de dados são armazenadas em uma série de fragmentos de dados vinculados à linha de dados. As informações de controle de versão de linha estão armazenadas em cada fragmento usado para armazenar grandes cadeias de caracteres. Os fragmentos de dados são uma coleção de páginas dedicadas a objetos grandes em uma tabela.

Conforme novos valores grandes forem adicionados a um banco de dados, eles serão alocados com o máximo de 8040 bytes de dados por fragmento. Versões anteriores do Mecanismo de Banco de Dados armazenavam até 8080 bytes de dados ntext, text ou image por fragmento.

O dados de LOB (Objeto Grande) ntext, text e image existentes não são atualizados para criar espaço para as informações de controle de versão de linha quando um banco de dados é atualizado para SQL Server de uma versão anterior do SQL Server. Porém, a primeira vez em que os dados de LOB são modificados, eles são atualizados dinamicamente para habilitar o armazenamento de informações de controle de versão. Isso acontecerá até mesmo se não forem geradas versões de linha. Depois que os dados de LOB são atualizados, o número máximo de bytes armazenados por fragmento é reduzido de 8080 bytes para 8040 bytes. O processo de atualização é equivalente a excluir o valor LOB e reinserir o mesmo valor. Os dados de LOB são atualizados mesmo quando apenas um byte é modificado. Essa é uma operação única para cada coluna ntext, text ou image, mas cada operação pode gerar uma grande quantidade de alocações de página e atividade de E/S dependendo do tamanho dos dados de LOB. Isso também poderá gerar uma grande quantidade de atividade de registro se a modificação for totalmente registrada. As operações WRITETEXT e UPDATETEXT serão registradas minimamente se o modo de recuperação do banco de dados não for definido como FULL.

Os tipos de dados nvarchar(max), varchar(max) e varbinary(max) não estão disponíveis nas versões anteriores do SQL Server. Portanto, eles não têm nenhum problema de atualização.

Deve ser alocado espaço em disco suficiente para acomodar esse requisito.

Monitorando o controle de versão de linha e o armazenamento da versão

Para monitorar os processos de controle de versão de linha, armazenamento de versão e isolamento de instantâneo quanto ao desempenho e aos problemas, o SQL Server fornece ferramentas na forma de DMVs (Exibições de Gerenciamento Dinâmico) e contadores de desempenho no Windows System Monitor.

DMVs

As DMVs a seguir fornecem informações sobre o estado atual do sistema de tempdb e o armazenamento da versão, bem como sobre as transações que usam controle de versão de linha.

sys.dm_db_file_space_usage. Retorna informações de uso do espaço de cada arquivo no banco de dados. Para obter mais informações, consulte sys.dm_db_file_space_usage (Transact-SQL).

sys.dm_db_session_space_usage. Retorna a alocação de página e a atividade de desalocação por sessão para o banco de dados. Para obter mais informações, consulte sys.dm_db_session_space_usage (Transact-SQL).

sys.dm_db_task_space_usage. Retorna a alocação de página e a atividade de desalocação por tarefa para o banco de dados. Para obter mais informações, consulte sys.dm_db_task_space_usage (Transact-SQL).

sys.dm_tran_top_version_generators. Retorna uma tabela virtual para os objetos que produzem a maioria das versões no armazenamento de versão. Agrupa os 256 maiores registros agregados por database_id e rowset_id. Use essa função para localizar os maiores usuários do armazenamento da versão. Para obter mais informações, consulte sys.dm_tran_top_version_generators (Transact-SQL).

sys.dm_tran_version_store. Retorna uma tabela virtual que exibe todos os registros de versão no armazenamento de versão comum. Para obter mais informações, consulte sys.dm_tran_version_store (Transact-SQL).

ObservaçãoObservação

sys.dm_tran_top_version_generators e sys.dm_tran_version_store são funções cuja execução é potencialmente muito dispendiosa, uma vez que ambas consultam todo o armazenamento de versão, que pode ser muito grande.

sys.dm_tran_active_snapshot_database_transactions. Retorna uma tabela virtual para todas as transações ativas em todos os bancos de dados dentro da instância SQL Server que usam controle de versão de linha. As transações de sistema não são exibidas nessa DMV. Para obter mais informações, consulte sys.dm_tran_active_snapshot_database_transactions (Transact-SQL).

sys.dm_tran_transactions_snapshot. Retorna uma tabela virtual que exibe instantâneos tirados por cada transação. O instantâneo contém o número de sequência das transações ativas que usam controle de versão de linha. Para obter mais informações, consulte sys.dm_tran_transactions_snapshot (Transact-SQL).

sys.dm_tran_current_transaction. Retorna uma única linha que exibe informações de estado relacionadas ao controle de versão de linha da transação na sessão atual. Para obter mais informações, consulte sys.dm_tran_current_transaction (Transact-SQL).

sys.dm_tran_current_snapshot. Retorna uma tabela virtual que exibe todas as transações ativas no momento em que a transação de isolamento do instantâneo atual é iniciada. Se a transação atual estiver usando o isolamento de instantâneo, essa função não retornará nenhuma linha. sys.dm_tran_current_snapshot é semelhante ao sys.dm_tran_transactions_snapshot, a não ser por retornar somente as transações ativas para o instantâneo atual. Para obter mais informações, consulte sys.dm_tran_current_snapshot (Transact-SQL).

Contadores de desempenho

Os contadores de desempenho do SQL Server fornecem informações sobre o desempenho do sistema afetado por processos do SQL Server. Os contadores de desempenho a seguir monitoram tempdb e o armazenamento de versão, bem como transações que usam controle de versão de linha. Os contadores de desempenho estão contidos no objeto de desempenho SQLServer:Transactions.

Espaço Livre em tempdb (KB). Monitora a quantidade, em KB (kilobytes), de espaço livre no banco de dados tempdb. Deve haver espaço livre suficiente em tempdb para processar o repositório de versão que dá suporte ao isolamento de instantâneo.

A fórmula a seguir fornece uma estimativa aproximada do tamanho do armazenamento de versão. Para transações de longa execução, pode ser útil monitorar a taxa de geração e limpeza para calcular o tamanho máximo de armazenamento de versão.

[tamanho do armazenamento de versão comum] = 2 * [dados de repositório de versão gerados por minuto] * [maior tempo de execução (minutos) da transação]

O tempo de execução mais longo das transações não deve incluir as compilações de índices online. Como essas operações podem demorar muito tempo em tabelas muito grandes, as compilações de índices online usam um armazenamento de versão separado. O tamanho aproximado do repositório de versão de compilação de índices online é igual à quantidade de dados modificados na tabela, incluindo todos os índices, enquanto a compilação de índices online estiver ativa.

Tamanho do Repositório de Versão (KB). Monitora o tamanho em KB de todos os armazenamentos de versão. Essas informações ajudam a determinar a quantidade de espaço necessária no banco de dados tempdb para o armazenamento de versão. O monitoramento desse contador durante um determinado tempo fornece uma estimativa útil do espaço adicional necessário para tempdb.

Taxa de Geração de Versão (KB/s). Monitora a taxa de geração de versão em KB por segundo em todos os armazenamentos de versão.

Taxa de Limpeza de Versão (KB/s). Monitora a taxa de limpeza de versão em KB por segundo em todos os armazenamentos de versão.

ObservaçãoObservação

As informações da Taxa de Geração de Versão (KB/s) e da Taxa de Limpeza de Versão (KB/s) podem ser usadas para prever os requisitos de espaço de tempdb.

Contagem de unidade de Repositório de Versão. Monitora a contagem de unidades de repositório de versão.

Criação de unidade de Repositório de Versão. Monitora o número total de unidades de repositório de versão criadas para armazenar versões de linha depois que a instância tiver sido iniciada.

Truncamento de unidade de Repositório de Versão. Monitora o número total de unidades de repositório de versão truncadas depois que a instância tiver sido iniciada. Uma unidade de repositório de versão é truncada quando o SQL Server determina que nenhuma das linhas de versão armazenadas na unidade de armazenamento de versão é necessária para a execução de transações ativas.

Taxa de conflito de atualização. Monitora a taxa de transação de instantâneo de atualização com conflitos de atualização para o número total de transações de instantâneo de atualização.

Tempo de Execução da Transação Mais Longa. Monitora o tempo de execução mais longo em segundos de qualquer transação que usa controle de versão de linha. Pode ser usado para determinar se alguma transação está sendo executada por uma quantidade de tempo excessiva.

Transações Monitora o número total de transações ativas. Não inclui as transações de sistema.

Transações de Instantâneo. Monitora o número total de transações de instantâneo ativas.

Transações de Instantâneo de Atualização. Monitora o número total de transações de instantâneo ativas que executam operações de atualização.

Transações da Versão Não Instantâneo. Monitora o número total de transações não instantâneo ativas que geram registros de versão.

ObservaçãoObservação

A soma de Transações de Instantâneo de Atualização e Transações de Versão Não Instantâneo representa o número total de transações que participam da geração de versão. A diferença de Transações de Instantâneo e Transações de Instantâneo de Atualização informa o número de transações de instantâneo somente leitura.