Casos do Dia a Dia – In-Memory OLTP – Mensagens de Erro

E aí Jhow,

Vamos para o último post da série do In-Memory. Hoje vou mostrar alguns erros que podemos encontrar ao utilizar o In-Memory.

Recomendo que veja também os outros posts da série que está bem legal! xD

Casos do Dia a Dia – In-Memory OLTP – Conceitos Básicos

Casos do Dia a Dia – In-Memory OLTP – Use com Moderação – Problema Utilização Memória

Casos do Dia a Dia – In-Memory OLTP – Mensagens de Erro

Vamos nessa!!! #gogogo


In-Memory – Mensagens de Erro:

Vou recapitular alguns erros que já citei nos posts anteriores dessa série do In-Memory. Lembra das limitações que citei no post dos Conceitos Básicos do In-Memory? Vamos ver aqui também alguns erros sobre isso.

  • Versão SQL Server:

Vou utilizar a seguinte versão para realizar os testes:

Microsoft SQL Server 2017 (RTM-CU13) (KB4466404) – 14.0.3048.4 (X64)   Nov 30 2018 12:57:58   Copyright (C) 2017 Microsoft Corporation Developer Edition (64-bit) on Windows 10 Home 10.0 <X64> (Build 18362: )


In-Memory – CREATE TABLE:

Se você tentar criar uma tabela In-Memory com o DURABILITY = SCHEMA_ONLY e sem um índice ou uma primary key, você vai receber um ERRO. Segue um exemplo:

Msg 41327, Level 16, State 7, Line 6

The memory optimized table ‘InMemorySchemaWithoutIndex’ must have at least one index or a primary key.

Msg 1750, Level 16, State 0, Line 6

Could not create constraint or index. See previous errors.

Da mesma forma, se você tentar criar uma tabela In-Memory com o DURABILITY = SCHEMA_AND_DATA e sem uma primary key, você também vai receber um ERRO, mas repare que ele é diferente do anterior. Segue um exemplo:

Msg 41321, Level 16, State 7, Line 23

The memory optimized table ‘InMemoryDataWithoutIndex’ with DURABILITY=SCHEMA_AND_DATA must have a primary key.

Msg 1750, Level 16, State 0, Line 23

Could not create constraint or index. See previous errors.

Se você tentar criar uma tabela In-Memory em uma database onde o In-Memory não está habilitado, você vai receber outro ERRO. Segue um exemplo:

Msg 41337, Level 16, State 100, Line 6

Cannot create memory optimized tables. To create memory optimized tables, the database must have a MEMORY_OPTIMIZED_FILEGROUP that is online and has at least one container.


In-Memory – TRUNCATE TABLE:

Se você precisar limpar uma tabela In-Memory e tentar fazer um TRUNCATE TABLE, você vai receber um ERRO, pois essa operação não é suportada no In-Memory. Segue um exemplo:

Msg 10794, Level 16, State 96, Line 98

The statement ‘TRUNCATE TABLE’ is not supported with memory optimized tables.


In-Memory – ALTER INDEX – REBUILD / COMPRESSION:

Nesse exemplo, vou criar uma tabela In-Memory chamada “InMemoryExampleCompression” com um índice também.

Depois, vou tentar fazer a Compressão de Dados do meu índice, mas vou receber uma mensagem de erro informando que a operação ALTER INDEX não é suportada no In-Memory.

Msg 10794, Level 16, State 12, Line 390

The operation ‘ALTER INDEX’ is not supported with memory optimized tables.

Fazendo uma rápida pesquisa no google, verifiquei que o In-Memory até consegue fazer algumas operações nos índices, mas de uma forma diferente. Segue uma breve explicação:

Referência: https://docs.microsoft.com/pt-br/sql/relational-databases/in-memory-oltp/altering-memory-optimized-tables?view=sql-server-ver15

Agora vamos fazer mais um teste. Repare que agora recebemos uma mensagem diferente e ela informa que a opção “data_compression” não é suportada no In-Memory.

Msg 10794, Level 16, State 89, Line 17

The index option ‘data_compression’ is not supported with indexes on memory optimized tables.


In-Memory – CHECKDB / CHECKTABLE

No In-Memory você também não consegue validar a Corrupção de Dados com o CHECKDB. Ao executar o comando abaixo, ele não retorna nenhum erro, contudo, se você procurar o retorno dos objetos que utilizam o In-Memory, você vai encontrar uma mensagem informando que essa operação não é suportada e que o objeto foi ignorado no processamento:

Object ID 50099219 (object ‘InMemoryExample’): The operation is not supported with memory optimized tables. This object has been skipped and will not be processed.

CHECKDB found 0 allocation errors and 0 consistency errors in database ‘Teste’.

DBCC execution completed. If DBCC printed error messages, contact your system administrator.

Agora, se você executar um CHECKTABLE o comando vai falhar e você vai receber uma mensagem parecida com a anterior:

Msg 5296, Level 16, State 1, Line 399

Object ID 50099219 (object ‘InMemoryExample’): The operation is not supported with memory optimized tables. This object has been skipped and will not be processed.


In-Memory – FOREIGN KEY

Se você não sabe o que é uma FOREIGN KEY, segue abaixo uma referência da documentação da Microsoft:

https://docs.microsoft.com/pt-br/sql/relational-databases/tables/create-foreign-key-relationships?view=sql-server-ver15

De forma resumida, FOREIGN KEY são chaves estrangeiras que utilizamos para garantir a integridade dos dados entre duas tabelas.

“Como assim Luiz??? Entendi nada!!! Traduz por favor kkk”

Calma que você vai entender com o próximo exemplo. Já já chegaremos lá.

No SQL Server 2016, algumas limitações do In-Memory foram removidas. Uma delas foi a possibilidade de criar uma Foreign Key entre tabelas In-Memory.

Referências:

https://www.mssqltips.com/sqlservertip/4751/foreign-key-support-in-sql-server-2016-memory-optimized-tables/

https://docs.microsoft.com/pt-br/sql/relational-databases/in-memory-oltp/transact-sql-constructs-not-supported-by-in-memory-oltp?view=sql-server-ver15

Ou seja, no SQL Server 2014 isso ainda não era possível e você teria o erro abaixo:

The feature ‘FOREIGN KEY’ is not supported with memory optimized tables.

FOREIGN KEY -> TESTE

Certo, chega de teoria e vamos testar isso na prática!

Nesse exemplo, vou criar duas tabelas In-Memory, depois uma Foreign Key entre elas e por fim vou inserir alguns dados e testar se vai manter a integridade entre as tabelas.

Show! Até aqui tudo certo! Nós conseguimos criar a Foreign Key e inserir os dados normalmente.

Agora vamos fazer um teste para validar a integridade entre as tabelas. Vou tentar inserir um valor “2” para a coluna “ID_1” na tabela “dbo.InMemoryTable2”. Essa coluna referencia a outra tabela “dbo.InMemoryTable1”, contudo, esse valor não existe lá. Então vamos validar se o SQL Server vai permitir ou não essa operação.

Msg 547, Level 16, State 0, Line 441

The INSERT statement conflicted with the FOREIGN KEY constraint “FK_DiskBased1”. The conflict occurred in database “Teste”, table “dbo.DiskBased1”, column ‘ID_1’.

Show! Ele deu um erro porque o valor não existe na outra tabela e com isso conseguimos manter a integridade entre as tabelas In-Memory! =)

FOREIGN KEY -> IN-MEMORY x DISK BASED

Agora vamos testar se é possível criar uma FOREIGN KEY entre uma tabela normal e outra com o In-Memory.

Msg 10778, Level 16, State 0, Line 468

Foreign key relationships between memory optimized tables and non-memory optimized tables are not supported.

Msg 1750, Level 16, State 1, Line 468

Could not create constraint or index. See previous errors.

EITA! Não tem como! =(

Pois é! Infelizmente não vamos conseguir manter a integridade dos dados entre uma tabela normal e outra com o In-Memory! Então vamos provar isso!

Como podemos ver, conseguimos inserir um dado inconsistente, pois ele não existe na outra tabela! Portanto, tome cuidado com isso! =(

Vamos ver se isso também será corrigido no futuro.


In-Memory – Insufficient Memory:

Agora vamos ver um dos erros mais perigosos que podemos encontrar no In-Memory!

No post anterior “Casos do Dia a Dia – In-Memory OLTP – Use com Moderação – Problema Utilização Memória”, mostrei um caso real do dia a dia onde o In-Memory gerou uma série de problemas na utilização de memória.

“There is insufficient system memory in resource pool “internal” to run this query.”

Traduzindo, o SQL Server está informando que não existe memória suficiente para executar a query. Ferrou!!!

Agora imagine se isso acontecer no seu ambiente de produção no horário de maior movimento, seria um CAOS!!! Por isso eu disse que esse é um dos erros mais perigosos do In-Memory, pois aqui o cliente pode ter prejuízos se não conseguir finalizar as vendas por exemplo.

No primeiro post da série “Casos do Dia a Dia – In-Memory OLTP – Conceitos Básicos” eu falei um pouco sobre o Resource Governor e ele pode ajudar a reduzir um pouco o impacto nesse caso também.

Segue mais algumas informações sobre esse erro de memória:

Referência: http://sqlmagu.blogspot.com/2015/02/erro-there-is-insufficient-system.html

Bora simular isso então!

Inicialmente, vou ajustar o “Max server memory” para 5 GB.

Agora vou criar uma tabela In-Memory e depois validar a utilização de memória.

Como podemos ver, estamos utilizando um pouco mais de 3 GB de memória com o In-Memory (MEMORYCLERK_XTP).

Agora vou criar uma segunda tabela e verificar o que vai acontecer.

Msg 701, Level 17, State 137, Line 329

There is insufficient system memory in resource pool ‘default’ to run this query.

Como podemos ver, o SQL Server não conseguiu executar a query porque não tinha memória suficiente!

Se você consultar o Error Log também irá encontrar esse erro lá.

Por fim, vou excluir as tabelas In-Memory.


In-Memory – Remove Filegroup

Por último, vou mostrar um erro que recebemos ao tentar remover o In-Memory. Como eu mencionei nos posts anteriores, uma vez que o In-Memory é configurado, você não consegue removê-lo!

“Putz Luiz, é sério isso mesmo?”

Até a versão que estou utilizando (citei no início do post) isso realmente não é possível. Vamos testar!

Msg 41802, Level 16, State 1, Line 151

Cannot drop the last memory-optimized container ‘Teste_In_Memory’.

Msg 5042, Level 16, State 8, Line 153

The filegroup ‘Teste_In_Memory’ cannot be removed because it is not empty.

O mais estranho é que mesmo excluindo todos os objetos que utilizam o In-Memory, ainda assim você não vai conseguir removê-lo! Que loucura! Pois é, mas a própria Microsoft nos informa que você só consegue remover o In-Memory dropando a database. #medo #chatiado

https://docs.microsoft.com/en-us/sql/relational-databases/in-memory-oltp/the-memory-optimized-filegroup?view=sql-server-2017

Se você conferir os Filegroups da database, você irá encontrar um para o In-Memory.

Object Explorer -> Botão direito na Database -> Properties -> Filegroups -> Memory Optimized Data

Então, se você dropar a database você vai conseguir remover os arquivos do In-Memory, mas vai perder também TODOS os seus outros dados. =(

Commands completed successfully.

Uma outra solução para você se livrar de vez do In-Memory seria:

  • Criar uma nova database;
  • Migrar todos os seus dados para essa database (sem utilizar o in-memory);
  • Dropar a database antiga;
  • Renomear a nova database com o nome antigo;
  • Ou seja, você vai ter um trabalho do cão!!!

Portanto, tenha muito cuidado ao implantar isso em produção! Faça testes primeiro e crie quando for realmente útil e necessário, pois é um caminho sem volta. =(

Referências:

https://www.sqlpassion.at/archive/2019/03/19/removing-an-in-memory-oltp-file-group/

https://feedback.azure.com/forums/908035-sql-server/suggestions/32896801-in-memory-oltp-allow-removal-of-filegroup-for-me


Download – Scripts:

Segue abaixo os scripts utilizados nesse post:

https://github.com/luizvitorf/SQLServer/blob/master/Scripts/In-Memory/Casos%20do%20Dia%20a%20Dia%20-%20In-Memory%20OLTP%20-%20Mensagens%20de%20Erro.sql


Espero que tenha gostado e que isso também possa ser útil no seu dia a dia. Até o próximo post!

Me siga no LinkedIn e YouTube para ficar por dentro das novidades.

Abraço,

Luiz Vitor França Lima

Consultor SQL Server

2 comentários em “Casos do Dia a Dia – In-Memory OLTP – Mensagens de Erro

  1. Pingback: Casos do Dia a Dia – In-Memory OLTP – Use com Moderação – Problema Utilização Memória – Luiz Lima

  2. Pingback: Casos do Dia a Dia – In-Memory OLTP – Conceitos Básicos – Luiz Lima

Deixe uma resposta