Cenário Estamos atualizando nosso patrimônio SQL para o SQL Server 2019 e configuramos qual será o ambiente de produção.
De: SQL2008R2 Standard/Windows Server 2008R2 - Servidor Principal/Servidor Secundário (Cluster de Failover do Windows) e Servidor de Relatórios (Replicação Transacional).
Para: SQL2019 Standard/Windows Server 2019 - Servidor principal/servidor secundário (sempre ativo) e servidor de relatórios (replicação transacional)
Os backups de 2008R2 foram restaurados em 2019 e o nível de compatibilidade foi definido como o mais recente. A configuração Always-On foi relativamente suave e os testes iniciais em relação ao aplicativo atual não mostraram problemas de compatibilidade.
O problema é puramente com a configuração da Replicação Transacional. Existem 2 bancos de dados que requerem replicação, uma publicação cada uma com a primária como editora e distribuidora.
O Problema Durante a inicialização da assinatura de cada BD no servidor de relatórios ele roda bem até chegar ao ponto de criar funções e produzir os erros abaixo.
1º banco de dados:
Mensagem: A opção "INLINE=ON" não é válida para esta função. Verifique a documentação para as construções suportadas com a opção INLINE em uma função. Texto do comando: CREATE FUNCTION [dbo].[f_clienttels - Mirror Copy ce2d3663eb494f3589bd5000dad1bf1f](@ClientID [int]) RETURNS varchar WITH INLINE = ON, EXECUTE AS CALLER AS BEGIN ......
2º banco de dados:
Mensagem: Foi especificada uma opção inválida para a instrução "CREATE/ALTER FUNCTION". Sintaxe incorreta perto da palavra-chave 'com'. Se esta instrução for uma expressão de tabela comum, uma cláusula xmlnamespaces ou uma cláusula de contexto de controle de alterações, a instrução anterior deverá ser encerrada com um ponto e vírgula. Sintaxe incorreta perto de ')'. Texto do comando: CREATE FUNCTION [dbo].[GetGroupAndDescendantGroupsSelective - Mirror Copy 46f329d5eed444428f45b052f07c7ea8](@GroupId [int]) RETURNS TABLE WITH INLINE = ON AS RETURN ( WITH GroupsCTE AS ( ........
Ambos são erros diferentes, mas acredito que ambos tenham a ver com a opção "INLINE=ON", esta opção não está presente em nenhuma dessas funções, nenhuma de nossas funções usa a opção inline explicitamente, se você remover esses artigos da assinatura ele apenas dá o mesmo erro na próxima função (erro CTE se a função iniciar com um CTE e o erro INLINE=ON se não iniciar).
Portanto, parece que a replicação está inserindo "WITH INLINE = ON" nas funções antes da replicação e, em seguida, cometendo erros na adição feita.
Corrigi todas as instâncias para a atualização CU4 mais recente 15.0.4033.1, testei essas funções em ambos os servidores (que funcionam), validei todas as funções/procs no banco de dados e todas estão bem. No ambiente 2008R2 atual, tive que recriar a publicação alguns meses atrás e não obtive esses erros. Como solução alternativa, por enquanto, estou criando funções manualmente no assinante e removendo todos os artigos de função da publicação.
Qualquer ajuda com uma resolução para isso seria muito apreciada, a única referência a esse erro (do 1º DB) é mencionar que não está documentado (link abaixo) e não consegui encontrar nenhuma outra postagem no fórum mencionando-o.
16203 – A opção “INLINE=ON” não é válida para esta função. Verifique a documentação para as construções suportadas com a opção INLINE em uma função.
De: Brent Ozar - O que há de novo no sys.messages do SQL Server 2019: Mais recursos não anunciados
Não temos um contrato de suporte ativo com a Microsoft, mas estamos tentando contatá-los por meio do fornecedor que forneceu as licenças, então darei uma atualização aqui se eles nos retornarem.
Posso fornecer mais informações se necessário.
Consulte este artigo A única solução que funcionou para mim foi descartar e recriar a UDF após a atualização para o SQL 2019.
A coluna inline_Type de Sys.sql_modules será 1 após a atualização para o SQL 2019. Depois de descartar e recriar a UDF, Inline_type será 0 e a inicialização da replicação funcionará bem.
Encontrei esse problema ao migrar uma publicação que inclui algumas UDFs escalares do SQL 2016 para o SQL 2019. Alterar as configurações do banco de dados do editor não resolveu o problema. E como os assinantes incluem versões mais antigas do SQL Server, adicionar "WITH INLINE=OFF" não é uma opção na definição da função. Portanto, minha solução é forçar o udf a não ser inlineável adicionando o seguinte código na definição da função:
Se você fizer uma seleção em sys.sql_modules, is_inlineable será exibido como 0 e os scripts de instantâneo serão gerados com êxito.
Como acompanhamento disso, a atualização para o SQL Server 2019 CU9 remove essa solução alternativa.
Qualquer função do formato: Criar função como tabela de retorno selecione 1 x
É criado com inline_type = 1 e, em seguida, a replicação gera o erro acima.
Tivemos que reverter CU9 devido a esse recurso.
Desculpas pelo atraso na postagem dessas descobertas, passei mais de um mês indo e voltando com o suporte da Microsoft sobre isso (em um ponto eles me disseram que a replicação não foi projetada para replicar funções e procedimentos armazenados e apenas não replicá-los como uma correção ?!!), eles finalmente admitiram que é realmente um bug, depois que eu enviei a eles um monte de evidências de experimentos do meu lado. O bug é, na verdade, com o processo de restauração/atualização do banco de dados no SQL Engine e não com a própria replicação transacional como apareceu pela primeira vez.
Causa/Investigação
A causa raiz disso é que quando um banco de dados é restaurado de uma versão anterior do SQL (2008R2 no meu caso) para uma nova instância do SQL 2019, por padrão, parece sinalizar as funções com inline_type = 1 em sys.sqlmodules (isso se manifesta como "Marcado para inlining" nas propriedades da função na GUI). Há um sinalizador nessa tabela chamado inlinable que foi um pouco complicado ao investigar inicialmente, pois parece que a replicação está usando inline_type , inlinable permanece verdadeiro mesmo após a solução alternativa e não impede a replicação.
Cheguei a esta conclusão através dos seguintes passos:
Essa opção é aplicada automaticamente por replicação devido ao sinalizador inline_type.
OU
O motivo do 2º erro é porque está declarando automaticamente INLINE = ON no código replicado, fazendo com que a sintaxe seja inválida quando a função contém um CTE.
Gambiarra
A única solução viável para isso é recriar todas as funções após a restauração/atualização para que seus sinalizadores sejam definidos corretamente. Nota: nem todas as funções são sinalizadas incorretamente, algumas legitimamente devem ser sinalizadas com inline_type = 1, a solução alternativa irá configurá-las corretamente para que não faça mal se elas forem capturadas no script abaixo.
Eu fiz isso por meio de um PowerShell rápido e sujo (abaixo), alguns dos artigos da Microsoft de problemas semelhantes sugerem que sp_refreshsqlmodule isso não funcionou para mim em primeira instância, mas não consigo ver nenhuma razão lógica para não, então vale a pena tente em primeira instância em vez disso.
Resolução Final
A causa raiz terá que ser corrigida no código de restauração do mecanismo/banco de dados SQL para realmente resolver esse cenário exato. A Microsoft confirmou que a correção para isso será implementada na atualização do SQL Server 2019 CU6.
Não tenho certeza se concordo com isso sendo chamado de Hotfix quando você tem que esperar 3 meses por isso!
Espero que isso ajude outra pessoa e também sirva de lição de que, quando você entrar em contato com o suporte da Microsoft, esteja preparado para fazer muito de sua própria investigação sem aviso prévio e enviá-la para eles, isso realmente ajudou a acelerar o processo.