SQL 2016 SQL Server Assertion: Arquivo: <pageref.cpp>, line = 951 Falha na asserção

8

Atualmente, estou atualizando nosso data warehouse do SQL 2012 para o SQL 2016. Tenho o DW antigo e o novo funcionando lado a lado em paralelo.

Meu processo ETL (uma estrutura desenvolvida no SSIS por terceiros) foi executado com êxito por mais de 2 anos em 2012, mas está falhando em 2016. Até agora, os bancos de dados e o processo ETL são idênticos.

Ambos os servidores são máquinas virtuais em execução no VMWare. O servidor antigo é o Win 2008 com 24 GB de RAM. SQL 2012 Std. Mem máx. Definido como 16 GB. O novo servidor é o Win 2012 com 64 GB de RAM. Desenvolvedor do SQL 2016 Mem máx. Definido como 50 GB. O novo DW está executando a v13.0.1601.5 RTM Developer Edition (64 bits).

Durante a execução do meu processo ETL, as etapas de carregamento que usam uma SQL Merge em uma dimensão ou tabela de fatos falham com o seguinte erro.

Texto completo:

DESCRIÇÃO: Asserção do SQL Server: Arquivo:, line = 951 Asserção com falha = 'IS_OFF (BUF_MINLOGGED, m_buf-> bstat) || pageModifyType! = PageModifyType_Contents || GetPagePtr () -> IsTextPage () '. Este erro pode estar relacionado ao tempo. Se o erro persistir após a execução da instrução, use DBCC CHECKDB para verificar a integridade estrutural do banco de dados ou reinicie o servidor para garantir que as estruturas de dados na memória não estejam corrompidas.

Conforme recomendado, executei o DBCC e nenhum erro foi encontrado. Eu também reiniciei o SQL. Em seguida, reiniciei o processo ETL e recebi o mesmo erro.

Minhas pesquisas para esse erro mostram que era um erro conhecido no SQL 2008, 2012 e 2014 e corrigido nos hotfixes subsequentes e atualizações cumulativas. então estou um pouco surpreso ao vê-lo reaparecer em 2016.

Os links que encontrei dizem que isso afeta o SSIS ao tentar fazer inserções se o banco de dados estiver no modelo de recuperação Simples ou Registrado em Massa. (Estou executando no modelo de recuperação simples)

Uma solução alternativa sugerida é alterar o modelo de recuperação de banco de dados para COMPLETO. Eu tentei isso e funciona, mas não é muita solução para um Data Warehouse.

Alguém mais encontrou isso em 2016?

Alguém pode sugerir soluções alternativas?

Atualizações:

26/7/2016: apliquei a Atualização crítica KB3164398 (v13.0.1708.0) e o problema ainda existe.

27/7/2016: Apliquei a Atualização Cumulativa CU1 KB3164674 (v13.0.2149.0).

08/03/2016: Ocorreu um erro durante a noite em nosso menor cubo. CU1 não corrigiu o problema. Hoje relatei o bug no MS Connect e também registrei uma ligação de suporte com a Microsoft.

08/12/2016: O suporte da MS respondeu inicialmente, mas a resposta foi "Não temos uma solução para isso". O cara do suporte discutia isso com seus colegas e voltava para mim. 8 dias depois, não tive notícias dele.

Embora eu não tenha uma 'correção', encontramos uma solução alternativa adequada para nós. Veja minha resposta postada.

29/9/2016. Eu apliquei o CU2 na semana passada. Na quinta-feira, acidentalmente executamos uma versão antiga da mesclagem que falhou novamente com o mesmo erro. Então .. CU2 também não o corrigiu.

23/1/2017 : apliquei a CU1 2016 do SP1 2016 e acredito que isso tenha resolvido o problema. Especificamente KB3205964

O senhor jura muito
fonte

Respostas:

2

Olhando para o KB, você tem algumas opções / soluções alternativas:

  1. Alterne para o modelo de recuperação COMPLETO. Você diz "isso não é muito uma opção para um armazém", mas é realmente apenas uma questão de configurar os backups do log de transações regularmente, por exemplo, 15 minutos e depois descartá-los. Os planos SSIS / Manutenção têm tarefas de estoque para fazer isso . Você perderá transações registradas em massa, mas nunca as achei fazer uma grande diferença nos tempos de execução, apenas no tamanho do log. Você pode até fazer backup de log para nul que não descreverei aqui. Se você não tiver certeza do que fazer, pergunte ao DBA local. O espaço em disco e a retenção de backup do log de transações são problemas mais fáceis de resolver do que erros fatais. Quando esse problema for resolvido, você poderá voltar.
  2. O KB menciona "várias instruções BULK INSERT em uma transação de distribuição única". Não está claro em sua pergunta como as inserções em massa estão configuradas. Você está usando o SSIS para executar tarefas 'Execute SQL' que usam oMERGEcomando? O que significa 'INSERT BULK múltiplo' significa aqui? Existe uma maneira de converter sua abordagem em INSERT BULK únicos, um de cada vez, por exemplo? No SSIS, você pode definir 'MaxConcurrentExecutables' como 1 temporariamente, por exemplo, veja se isso ajuda. Amarre-o a uma variável de configuração para que você possa alterá-lo mais tarde. Obviamente, isso atrasará as coisas, mas você prefere que o seu ETL termine em vez de falhar rapidamente. Fazer as coisas em paralelo é um bom padrão e uma força real do SSIS, mas você só pode ir tão rápido quanto o componente mais lento; digamos que você tenha 10 dimensões que levam um minuto e um fato que leva uma hora, seu ETL termina em uma hora paralela ou 1 hora e 10 minutos em série.
  3. MERGEé bom, mas tem alguns problemas. Você pode considerar converter novamente para INSERT/ UPDATE. Além disso, você deve usar HOLDLOCKcom de MERGEacordo com aqui . Você usa essa dica? Faz alguma diferença para esse problema se você o fizer? Tivemos um problema em uma compilação do SQL 2014 no início, em que o uso MERGEcom DML OUTPUTcompostável ( cláusula) no columnstore causou esse tipo de afirmação - eu os fiz retirar os índices columnstore das dimensões que eles adicionaram sem me avisar.
  4. Que tipo de manipulação de transações você está fazendo? Às vezes, com o ETL, a posição é repetível apenas executando novamente. Às vezes, você precisa falhar e reverter. Como você implementou isso? Pode ser alterado para que não seja "transação distribuída única"?

Boa sorte.

wBob
fonte
Olá, @wBob, obrigado pela sua resposta. Para responder suas perguntas. 1. Estamos falando sobre a extração de tabelas de 20 a 30 Gb em uma única etapa. movendo mais de 100 GB de dados. Estou preocupado em explodir os logs TX e também o armazenamento. Talvez eu possa fazer o backup do log uma etapa no ETL após cada extração? 2. Sim O SSIS chama uma tarefa SQL para executar uma mesclagem. Cada etapa é executada sequencialmente. No momento em que a mesclagem está sendo executada, é a única tarefa em execução. 3. Nossa ferramenta ETL é uma estrutura fornecida por um fornecedor. É assim que funciona. Não tenho certeza sobre dicas. irá verificar. 4. Sem manuseio de TX. SQL direto.
Sir jura-a-lot
Portanto, se as execuções bem-sucedidas não continuarem, tente um t-log de 100 GB com backups de log após cada tabela ser movida, isso deve ser resolvido. Obviamente você tem que testar. Quaisquer outros recursos que devemos conhecer sobre o alvo? Columnstore, particionamento, indexação excessiva?
wBob 27/07
Atualmente, não há recursos que ainda não estejam no nosso DW existente em 2012 std. O novo DW / Datamarts é uma cópia exata dos originais, sem armazenamento de colunas ou particionamento. Índices mínimos (mas eficazes). No momento, estamos focando em uma mudança de plataforma, como por exemplo. Finalmente, nosso novo produto DW será o 2016 Enterprise. Mas não estamos adicionando recursos de nível corporativo até que tenhamos o básico funcionando.
11156 Sir Sir Jura Muito
Oi @ wBob. Implementamos sua sugestão dividindo a inserção da mesclagem. Mas, dada a maneira como fiz a pergunta, não sei ao certo qual é a resposta correta. mas acho que você me levou a uma solução válida e viável.
9269 Sir Sir Jura Muito
2

Acredito que isso foi resolvido no 2016 SP1 CU1.

Especificamente por KB3205964

O senhor jura muito
fonte
1

Isso é corrigido aplicando a atualização cumulativa 1 (CU1) para o MSSQL2016, consulte o link https://support.microsoft.com/en-us/kb/3164674

Steve Neshausen
fonte
Steve estava trabalhando comigo nisso. nós pensamos que tínhamos resolvido, mas sem charuto. então removi o crédito e reduzi o voto.
9606 Sir James xinga muito
1

Acredito que encontramos outra solução alternativa. Estou postando minha resposta, pois acho que pode ser útil, e é diferente o suficiente da sugestão do wBob.

Alteramos a parte de inserção da instrução de mesclagem para que ela seja inserida em uma tabela temporária em vez do destino original.

Depois que a instrução de mesclagem é executada, inserimos a partir da #table no destino.

Não é o ideal, mas pelo menos a mesclagem ainda lida com a complexidade do 'upsert', marcando linhas que foram aposentadas / expiradas.

Concluímos que esse é um compromisso aceitável, em comparação com a reescrita completa da mesclagem como inserções e atualizações separadas.

CREATE TABLE #Activity(
[ETL_ActivitySurrogateKey] [int] IDENTITY(1,1) NOT NULL,
[Field1] [varchar](255) NULL,
)

-- Insert statements for procedure here
INSERT INTO #Activity ( [Field1],2,3,etc )

SELECT [Field1],2,3,etc
FROM 
(
    MERGE [DDS_OZ_CC].[dimActivity] AS target 
    USING (
      SELECT [Field1],2,3,etc
      FROM [STAGE_OZ_CC].[Transform_Activity]
      ) as source
    ON
    (
      target.RowIsCurrent = source.RowIsCurrent
         AND target.[Field1] = source.[Field1]
    )
    WHEN MATCHED 
        AND (        
        EXISTS (SELECT target.Level5Id EXCEPT SELECT source.Level5Id)
    )
    THEN
      UPDATE SET 
        ETL_ValidToDateTime = source.ETL_ValidFromDateTime 
       ,ETL_RowIsCurrent = 0 
       ,ETL_LastTouchedBy = source.ETL_LastTouchedBy 
       ,ETL_RowChangeReason = 'SCD2 Retired' 

    WHEN NOT MATCHED THEN 
    INSERT 
    (    
     [Field1],2,3,etc
    )
    VALUES (      
      source.[Field1],2,3,etc
    )
       WHEN NOT MATCHED BY SOURCE AND target.ETL_RowIsCurrent = 1
       THEN UPDATE SET
       ETL_RowIsCurrent = 0 
       ,ETL_RowChangeReason = 'Fact Removed' 
       ,ETL_LastTouchedBy = 'Unknown'

  OUTPUT
    $action      
      ,source.[Field1],2,3,etc    

  ) AS MergeOutput
  (
    action  
    ,[Field1],2,3,etc   
  ) 

  WHERE ACTION = 'UPDATE' AND ETL_RowIsCurrent = 1

    INSERT INTO [DDS_OZ_CC].[dimActivity]
    ( [Field1],2,3,etc  )
    SELECT [Field1],2,3,etc
    FROM #Activity

    END
O senhor jura muito
fonte
Ok, obrigado Peter. Apenas por interesse, você tentou a dica HOLDLOCK?
WBob
Não, eu não. Depois de ler o artigo de Aaron Bertrands sobre o assunto, entendi que era realmente sobre problemas de simultaneidade com vários usuários. No nosso caso, o processo ETL é a única coisa em execução.
Sir Swears-lot-
Acho que valeu a pena tentar apenas ver se você tem um comportamento diferente, além de provavelmente ser uma boa prática, apenas dizer que você não é concorrente agora, não significa que talvez não seja no futuro. De qualquer forma, bem feito em encontrar uma solução e para o próximo problema:)
wBob
Eu gostaria, mas infelizmente estamos com restrições de tempo. Quando encontramos uma solução viável, o chefe fez uma ligação para seguir em frente.
9608 Sir James xinga muito