Tabelas temporais versionadas pelo sistema com tabelas otimizadas para memória

Aplica-se a: SQL Server 2016 (13.x) e versões posteriores da Instância Gerenciada de SQL do Azure

As tabelas temporais com versão controlada pelo sistema para tabelas otimizadas para memória oferecem uma solução econômica para cenários em que auditoria de dados e análise em um ponto no tempo são necessárias sobre os dados coletados com cargas de trabalho OLTP In-Memory.

Nota

As tabelas temporais com otimização de memória só estão disponíveis no SQL Server e na Instância Gerenciada de SQL do Azure. Tabelas com otimização de memória e tabelas temporais estão disponíveis independentemente no Banco de Dados SQL do Azure.

Visão geral

As tabelas temporais versionadas pelo sistema mantêm automaticamente um histórico completo das alterações de dados e oferecem extensões convenientes de Transact-SQL para análise de ponto no tempo. Em um cenário típico, o histórico de dados é retido por um período longo (vários meses, até mesmo anos), embora não seja consultado regularmente.

A auditoria de dados e a análise baseada em tempo podem ser solicitadas em ambientes diferentes, especialmente em sistemas OLTP que processam quantidades extremamente grandes de solicitações e nos quais a tecnologia de OLTP in-memory é usada. No entanto, o uso de tabelas com otimização de memória em cenários temporais é um desafio, pois uma grande quantidade de dados históricos gerados normalmente excede o limite de RAM disponível. Ao mesmo tempo, usar RAM para armazenar dados históricos de somente leitura, que são acessados com menos frequência à medida que ficam mais antigos, não é uma solução ideal.

As tabelas temporais controladas por versão do sistema para tabelas otimizadas para memória fornecem alta taxa de transferência transacional e concorrência sem bloqueios. Eles oferecem a capacidade de armazenar uma grande quantidade de dados históricos usando tabelas na memória para armazenar dados atuais (a tabela temporal) e tabelas baseadas em disco para dados históricos. O efeito sobre as operações DML é reduzido com o uso de uma tabela de preparo com otimização de memória interna gerada automaticamente que armazena o histórico recente e permite a execução de DMLs a partir do código compilado nativamente.

O diagrama a seguir ilustra essa arquitetura.

Diagrama da arquitetura temporal na memória.

Detalhes de implementação

Ao criar uma tabela com otimização de memória versionada pelo sistema, esteja ciente das seguintes considerações. Para opções de sintaxe e para um exemplo, consulte CREATE TABLE.

  • Apenas as tabelas com otimização de memória duráveis podem ser versionadas pelo sistema (DURABILITY = SCHEMA_AND_DATA).

  • A tabela de histórico de uma tabela versionada pelo sistema otimizada para memória deve ser baseada em disco, independentemente de ter sido criada pelo usuário final ou pelo sistema.

  • Consultas que afetam apenas a tabela atual na memória podem ser usadas em módulos T-SQL compilados nativamente. Não há suporte a consultas temporais usando a cláusula FOR SYSTEM TIME em módulos compilados nativamente. A cláusula FOR SYSTEM TIME tem suporte com tabelas otimizadas para memória em consultas ad hoc e módulos não nativos.

  • Quando SYSTEM_VERSIONING = ON, uma tabela interna de preparo com otimização de memória é criada automaticamente para aceitar as alterações de versão do sistema mais recentes, as quais resultam de operações de atualização e exclusão na tabela atual com otimização de memória.

  • Dados da tabela interna de preparo com otimização de memória são movidos regularmente para a tabela de histórico com base em disco por uma tarefa de limpeza de dados assíncrona. Esse mecanismo de liberação de dados tem o objetivo de manter os buffers internos da memória em menos de 10% do consumo de memória de seus objetos pai. Você pode acompanhar o consumo total de memória da tabela temporal com versionamento do sistema otimizada para memória consultando sys.dm_db_xtp_memory_consumers e consolidando os dados da tabela de preparação interna otimizada para memória e da tabela temporal atual.

  • É possível executar manualmente um descarregamento de dados, executando sp_xtp_flush_temporal_history.

  • Com SYSTEM_VERSIONING = OFF, ou quando o esquema de uma tabela versionada pelo sistema é modificado com a adição, remoção ou alteração de colunas, todo o conteúdo do buffer de preparo interno é movido para a tabela de histórico armazenada em disco.

  • A consulta a dados históricos está efetivamente sob o nível de isolamento de instantâneo e sempre retorna uma união entre o buffer de staging em memória e a tabela baseada em disco, sem duplicatas.

  • As operações ALTER TABLE que alteram o esquema da tabela internamente devem executar uma limpeza de dados, o que pode prolongar a duração da operação.

A tabela de preparo com otimização de memória interna

O sistema cria uma tabela de preparo com otimização de memória interna para otimizar operações DML.

  • O nome da tabela é gerado no seguinte formato: Memory_Optimized_History_Table_<object_id> onde <object_id> é o identificador da tabela temporal atual.

  • A tabela replica o esquema da tabela temporal atual mais uma coluna bigint. Essa coluna extra garante a unicidade das linhas movidas para o buffer interno de histórico.

  • A coluna extra tem o seguinte formato de nome: Change_ID[<suffix>], em que <suffix> é adicionado, opcionalmente, caso a tabela já tenha uma coluna Change_ID.

  • O tamanho máximo da linha de uma tabela otimizada para memória versionada pelo sistema é reduzido em 8 bytes devido à coluna bigint extra na tabela de staging. O novo valor máximo agora é 8.052 bytes.

  • A tabela de preparo interna com otimização de memória não é representada no Pesquisador de Objetos do SQL Server Management Studio.

  • Os metadados sobre essa tabela, bem como sua conexão com a tabela temporal atual, podem ser encontrados em sys.internal_tables.

A tarefa de limpeza de dados

O descarregamento de dados é uma tarefa ativada regularmente que verifica se alguma tabela otimizada para memória atende a uma condição baseada no tamanho da memória para a movimentação de dados. A movimentação de dados começa quando o consumo de memória da tabela de preparação interna atinge 8% do consumo de memória da tabela temporal atual.

A tarefa de limpeza de dados será ativada regularmente com uma agenda que varia com base na carga de trabalho existente. Com uma carga de trabalho pesada, a tarefa é executada a cada 5 segundos. Com uma carga de trabalho leve, a frequência aumenta a cada minuto. Uma thread é criada para cada tabela interna de preparo com otimização de memória que precisa ser limpa.

A limpeza de dados exclui todos os registros de buffer interno de memória mais antigos do que a transação mais antiga em execução no momento para mover esses registros para a tabela de histórico com base em disco.

Você pode executar uma liberação de dados executando sp_xtp_flush_temporal_history e especificando o esquema e o nome da tabela:

EXEC sys.sp_xtp_flush_temporal_history <schema_name>, <object_name>;

O mesmo processo de movimentação de dados é executado da mesma forma que quando o sistema executa a tarefa de descarregamento de dados de acordo com sua programação interna.