Compactação de backup causando corrupção no banco de dados TDE do SQL 2017

13

No SQL Server 2017 (CU3), sempre que eu ativo a compactação de backup em um dos meus bancos de dados TDE, o processo de backup sempre corrompe uma página específica no banco de dados. Se eu executar o backup sem compactação, ele não será corrompido. Aqui estão as etapas que eu segui para verificar e reproduzir esse problema:

  1. Execute o DBCC CheckDB no banco de dados "TDE_DB1"; tudo é bom, sem erros;
  2. Faça backup do banco de dados com êxito sem compactação; RESTORE VERIFYONLY diz que tudo é bom;
  3. Restaurar com sucesso o banco de dados como "TDE_DB2"; tudo está bom, o DBCC CheckDB não mostra erros;
  4. Faça backup com êxito do banco de dados "TDE_DB1" COM compactação; RESTORE VERIFYONLY erros, dizendo "Dano ao conjunto de backup foi detectado";
  5. Tente restaurar o banco de dados como "TDE_DB2"; erros, dizendo "RESTORE detectou um erro na página (1: 92454) no banco de dados"
  6. Repita as etapas 1 a 3; tudo está bem;
  7. DROP "TDE_DB1" e "TDE_DB2"; Restaurar "TDE_DB1" do backup; tudo está bem;
  8. Repita as etapas de 1 a 5; obtenha os mesmos resultados;

Para resumir: O banco de dados e os backups regulares parecem bons, executando CHECKDB no banco de dados e VERIFYONLY nos backups não relatam erros. O backup do banco de dados com compactação parece causar corrupção.

Abaixo estão os exemplos de código com erros. (Nota: MAXTRANSFERSIZE é necessário para usar a compactação com um banco de dados TDE )

-- Good, completes with no corruption;
BACKUP DATABASE [TDE_DB1] TO DISK = N'E:\MSSQL\Backup\TDE_DB1a.bak' WITH CHECKSUM;
RESTORE VERIFYONLY FROM DISK = N'E:\MSSQL\Backup\TDE_DB1a.bak' WITH CHECKSUM;

RESTORE DATABASE [TDE_DB2]
FROM DISK = 'E:\MSSQL\Backup\TDE_DB1a.bak'
WITH MOVE 'DataFileName' to 'E:\MSSQL\Data\TDE_DB2.mdf'
,MOVE 'LogFileName' to 'F:\MSSQL\Log\TDE_DB2_log.ldf';


-- Bad, I haz corruption;
BACKUP DATABASE [TDE_DB1] TO DISK = N'E:\MSSQL\Backup\TDE_DB1b.bak' WITH CHECKSUM, COMPRESSION, MAXTRANSFERSIZE = 131072;
RESTORE VERIFYONLY FROM DISK = N'E:\MSSQL\Backup\TDE_DB1b.bak' WITH CHECKSUM;
-- ERROR
--Msg 3189, Level 16, State 1, Line 1
--Damage to the backup set was detected.
--Msg 3013, Level 16, State 1, Line 1
--VERIFY DATABASE is terminating abnormally.

RESTORE DATABASE [TDE_DB2]
FROM DISK = 'E:\MSSQL\Backup\TDE_DB1b.bak'
WITH MOVE 'DataFileName' to 'E:\MSSQL\Data\TDE_DB2.mdf'
,MOVE 'LogFileName' to 'F:\MSSQL\Log\TDE_DB2_log.ldf';
-- ERROR
--Msg 3183, Level 16, State 1, Line 7
--RESTORE detected an error on page (1:92454) in database "TDE_DB2" as read from the backup set.
--Msg 3013, Level 16, State 1, Line 7
--RESTORE DATABASE is terminating abnormally.

Tentei verificar a página relatada como tendo o erro (é sempre a mesma página.), Mas a DBCC PAGE relata que o ObjectId é 0. De acordo com este artigo de Paul Randal, isso significa que não foram encontrados metadados e um dos motivos pode ser que a própria página esteja corrompida e valores incorretos foram usados ​​para tentar procurar os metadados. Seu conselho é executar o CHECKDB, o que não posso fazer porque o backup corrompido não será restaurado.

Tentei as sugestões deste SO Post (Adicionando INIT e FORMAT ao comando BACKUP) para redefinir os metadados, mas isso não pareceu mudar nada, ainda assim eu danifico o backup compactado.

Isso acontece apenas com um dos meus bancos de dados TDE. Eu tenho outros 4 bancos de dados TDE nesse mesmo servidor e eles não têm esse problema. Isso me diz que pode haver um problema subjacente nesse banco de dados específico. Percebo que a solução mais fácil é não usar a compactação, mas sinto que isso pode realmente ser um alerta precoce para um problema maior vindo pela estrada.

Alguém já viu isso antes, ou tem alguma idéia de por que a compactação corromperia essa página? Neste ponto, estou meio que sem saber o que fazer a seguir. Eu considerei restaurar a página de um backup anterior, mas não acho que isso importe, pois a página no banco de dados regular parece boa.

ATUALIZAÇÃO 1: Abaixo estão os resultados da DBCC PAGE, com a opção 0:

Execução do DBCC concluída. Se o DBCC imprimiu mensagens de erro, entre em contato com o administrador do sistema.

PÁGINA: (1: 92454)

AMORTECEDOR:

BUF @ 0x000002187AE55640

bpage = 0x000002184865E000 bhash = 0x0000000000000000
bpageno = (1: 92454) bdbid = 8 breferences = 0 bcputicks = 563 bsampleCount = 1
bUse1 = 51429 bstat = 0x809 blog = 0x15a
bnext = 0x000000000000

CABEÇALHO DA PÁGINA:

Page @ 0x000002184865E000

m_pageId = (1: 92454) m_headerVersion = 111
m_type = 189 m_typeFlagBits = 0x2d m_level = 197
m_flagBits = 0x525e m_objId (AllocUnitId.idObj) = 788815194
m_indexId: AllocUnad IndexId = -1 Metadados: ObjectId = 0 m_prevPage = (32842: 1881351155) m_nextPage = (13086: -560562340)
pminlen = 36067 m_slotCnt = 8149 m_freeCnt = 51871 m_freeData = 7295 m_reservedCnt = 4810 m_s 14755
m_xdesId = (12811: 1559482793) m_ghostRecCnt = 12339
m_tornBits = -1381699202 DB Frag ID = 1

Status de alocação

GAM (1: 2) = SGAM ATRIBUÍDO (1: 3) =
PFS NÃO ATRIBUÍDO (1: 88968) = 0x0 0_PCT_FULL DIFF (1: 6) = NÃO MUDADO
ML (1: 7) = NÃO MIN_LOGGED

Se eu tentar executar o DBCC PAGE com outras opções, obtenho os erros abaixo:

PÁGINA DBCC com opção 1: Msg 0, Nível 11, Estado 0, Linha 0 Ocorreu um erro grave no comando atual. Os resultados, se existirem, deveriam ser descartados.

DBCC PAGE com opção 3: Msg 2514, Nível 16, Estado 5, Linha 3 Ocorreu um erro de DBCC PAGE: Tipo de página inválido - o estilo de despejo 3 não é possível.

ATUALIZAÇÃO 2: Aqui estão alguns dos resultados do DMO sys.dm_db_database_page_allocations:

object_id = 75 = 1 index_id rowset_id = 281474981625856 allocation_unit_id = 281474981625856
allocation_unit_type = 1 allocation_unit_type_desc = IN_ROW_DATA extent_file_id = 1 extent_page_id = 92448
allocated_page_iam_file_id = 1 = 104 allocated_page_iam_page_id
allocated_page_file_id = 1 allocated_page_page_id = 92454
is_allocated = 0 is_iam_page = 0 = 0 is_mixed_page_allocation

Eric Cobb
fonte

Respostas:

8

Parece que esse problema ocorre com bancos de dados que tiveram operações SHRINK executadas neles. No meu caso, eu estava tirando uma cópia de um de nossos bancos de dados de produção no SQL Server 2014 (que já está criptografado com TDE), executando o DBCC SHRINKFILE nos arquivos de dados e de log, depois fazendo um backup e restaurando-o no meu novo SQL 2017 Server. (O motivo da redução foi a redução do tamanho para agilizar a transferência do backup.)

Como teste, restaurei uma cópia do banco de dados em que não executei o DBCC SHRINKFILE e não tive problemas de corrupção ao compactar backups.

Então, para resumir, os resultados dos meus testes são os seguintes:

  • As operações normais de backup / restauração nesse banco de dados TDE "reduzido" funcionam corretamente no SQL 2017
  • A compactação de backups do banco de dados TDE "encolhido" parece causar corrupção na tabela sys.sysmultiobjrefs
  • A compactação de backups do banco de dados TDE regular (sem o DBCC SHRINKFILE executado) funciona corretamente e não relata corrupção

Não sei se esse é um bug confirmado no SQL Server 2017, mas enviei minhas descobertas à Microsoft para que elas examinassem.

Portanto, a moral dessa história é: NÃO ENCOLHE AS BASES DE DADOS! SEMPRE! :)

Eric Cobb
fonte