No momento, estou atualizando nosso data warehouse do SQL 2012 para o SQL 2016. Tenho meus DWs antigos e novos 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 é Win 2008 com 24 Gb de RAM. SQL 2012 Padrão Memória máxima definida para 16 Gb. O novo servidor é Win 2012 com 64 Gb de RAM. Desenvolvedor SQL 2016. Memória máxima definida para 50 Gb. O novo DW está executando a v13.0.1601.5 RTM Developer Edition (64 bits).
Ao executar meu processo ETL, as etapas de carregamento que usam uma mesclagem SQL em uma dimensão ou tabela de fatos falham com o seguinte erro.
Texto completo:
DESCRIÇÃO: SQL Server Assertion: File: , line=951 Failed Assertion = 'IS_OFF (BUF_MINLOGGED, m_buf->bstat) || pageModifyType != PageModifyType_Contents || GetPagePtr ()->IsTextPage ()'. Esse erro pode estar relacionado ao tempo. Se o erro persistir após executar novamente a 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 sejam 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 por esse erro mostram que era um erro conhecido no SQL 2008, 2012 e 2014 e corrigido em hotfixes e atualizações cumulativas subsequentes. então estou um pouco surpreso ao vê-lo reaparecer em 2016.
Os links que encontrei dizem que afeta o SSIS ao tentar fazer inserções se o banco de dados estiver no modelo de recuperação Simples ou Bulk Logged. (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 é uma solução para um Data Warehouse.
Alguém mais encontrou isso com 2016?
Alguém pode sugerir soluções alternativas?
Atualizações:
26/07/2016: Apliquei a atualização crítica KB3164398 (v13.0.1708.0) e o problema persiste.
27/07/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 chamada de suporte com a Microsoft.
08/12/2016: MS-Support respondeu inicialmente, mas as respostas foram "Não temos uma solução para isso". O cara do suporte iria discutir isso com seus colegas e me retornaria. 8 dias depois, não tive notícias dele.
Embora eu não tenha uma 'correção', encontramos uma solução alternativa que nos convinha. Veja minha resposta postada.
29/9/2016. Eu apliquei CU2 na semana passada. Na quinta-feira, executamos acidentalmente uma versão antiga da mesclagem, que falhou novamente com o mesmo erro. Então... CU2 também não consertou.
23/01/2017 : Apliquei o 2016 SP1 CU1 e acredito que isso resolveu o problema. Especificamente KB3205964
Olhando para o KB, você tem algumas opções/soluções alternativas:
MERGE
comando? O que significa 'multiple BULK INSERTs' aqui? Existe uma maneira de converter sua abordagem em BULK INSERTs únicos, um de cada vez, por exemplo? No SSIS, você pode definir 'MaxConcurrentExecutables' como 1 temporariamente, por exemplo, veja se isso ajuda. Vincule-o a uma variável de configuração para que você possa alterá-lo novamente mais tarde. Obviamente, isso vai desacelerar as coisas, mas você prefere que 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 seu 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 em execução paralela ou 1 hora e 10 minutos em série.MERGE
é bom, mas tem alguns problemas. Você pode considerar a conversão de volta paraINSERT
/UPDATE
. Além disso, você deve usarHOLDLOCK
withMERGE
de acordo com aqui . Você usa essa dica? Faz alguma diferença para este problema se você fizer isso? Tivemos um problema em uma versão inicial do SQL 2014 em que o usoMERGE
com DML (OUTPUT
cláusula) combinável em columnstore causava esse tipo de afirmação - fiz com que retirassem os índices columnstore das dimensões, que eles adicionaram sem me avisar.Boa sorte.
Acredito que isso tenha sido resolvido em 2016 SP1 CU1.
Especificamente por KB3205964
Isso é corrigido aplicando a atualização cumulativa 1 (CU1) para MSSQL2016, consulte o link https://support.microsoft.com/en-us/kb/3164674
Acredito que encontramos outra solução alternativa. Estou postando minha resposta porque acho que pode ser útil e é diferente o suficiente da sugestão de wBob.
Alteramos a parte insert da instrução merge para que ela seja inserida em uma tabela temporária em vez do destino original.
Depois que a instrução merge é executada, inserimos da tabela # no destino.
Não é o ideal, mas pelo menos a mesclagem ainda lida com a complexidade do 'upsert' marcando as linhas que foram retiradas/expiradas.
Descobrimos que essa é uma compensação aceitável em comparação com reescrever completamente a mesclagem como inserções e atualizações separadas.