deadlock por exchangeEvent e threadPool

Hoje me deparei com uma situação muito incomum, monitorando a ocorrência de deadlocks no database, verifiquei no gráfico do deadlock uma enorme relação de consultas e aparentemente sendo bloqueadas por outras sessões requisitando a mesma consulta. E relação dos bloqueios eram descritas como bloqueios por ExchangeEvents e ThreadPool.

Lendo alguns blogs, concluí que problema é basicamente índices inapropriados, geralmente associado a um plano de execução com muitos operadores de index scan em nonclustered index. Ou seja meu amigo, a consulta precisa sofrer uma reescrita ou os índices precisam ser completamente revistos.

Nestas horas como DBA o difícil é a missão de explicar porque uma única nova coluna na consulta é capaz de impactar tão drasticamente na elaboração do plano de execução e consequente regressão de performance.

 

 

https://blogs.msdn.microsoft.com/bartd/2008/09/24/todays-annoyingly-unwieldy-term-intra-query-parallel-thread-deadlocks/

Intra-Query Parallel Deadlock

Erro Sql Server cluster instance name ” alread exists as clustered resource.

Ao tentar realizar a instalação de uma instancia do Sql Server Clusterizada, me deparei com o erro abaixo.

isso ocorre quando as referências do nome do cluster já existem, no meu caso era uma lab de um cluster sql server que foi removido e agora voltava a ser adicionado com o mesmo nome.

A solução consistem em além de remover as referências deste nome que ficam registradas no AD, é necessário rodar a instrução PowerShell como administrador:

Remove-ClusterResource “NomeDoCluster”

Na maioria dos casos apenas rodando a instrução via powershell irá resolver, quando vc roda via powershell dependendo da versão do seu powershell, irá aparecer uma caixa de dialogo perguntando se realmente deseja remover o recurso clusterizado, aí é só confirmar.

Depois é só partir para o abraço garoto.

referências no forum

https://www.sqlservercentral.com/Forums/1718935/Cluster-Install-Problem–Name-already-exists-as-a-clustered-resource

 

Persistir ou não colunas calculadas no sql server

realizando testes de insert para a tabela com colunas calculadas e não persistidas tivemos os resultados, criando a tabela com 3 colunas calculadas porém não persistidas

CREATE TABLE [dbo].[Viagem_Fuso](

[Viagem] [int] NULL,

[Entrega] [varchar](30) NULL,

[Data] [datetime] NULL,

[Fuso] [smallint] NULL,

[Data_UTC]  AS (dateadd(minute, -((1)*[Fuso]),[Data])),

[Data_UTC-3]  AS (dateadd(minute, -((1)*[Fuso]+(180)),[Data])),

[Data_UTC-4]  AS (dateadd(minute, -((1)*[Fuso]+(240)),[Data]))

) ON [PRIMARY]



GO

 

utilizando o script abaixo para inserir 10 mil registros na tabela

declare @data datetime2 = getdate();

print @data;

insert into viagem_fuso values

(1,'teste', @data, -120)

go 10000

declare @data datetime2 = getdate();

print @data;

Tempo de insert  foi de 30 segundos para inserir 10 mil registros
E o tempo de leitura total foi de 196 milesegundos.

SQL Server Execution Times:

CPU time = 0 ms,  elapsed time = 0 ms.

Table ‘Viagem_Fuso’. Scan count 1, logical reads 60, physical reads 0, read-ahead reads 76, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.

SQL Server Execution Times:

CPU time = 16 ms,  elapsed time = 196 ms.

 

Os Resultados para a mesma tabela com as colunas calculadas e campos persistidos fisicamente;

 

CREATE TABLE [dbo].[Viagem_Fuso2](

[Viagem] [int] NULL,

[Entrega] [varchar](30) NULL,

[Data] [datetime] NULL,

[Fuso] [smallint] NULL,

[Data_UTC]  AS (dateadd(minute, -((1)*[Fuso]),[Data])) persisted ,

[Data_UTC-3]  AS (dateadd(minute, -((1)*[Fuso]+(180)),[Data])) persisted ,

[Data_UTC-4]  AS (dateadd(minute, -((1)*[Fuso]+(240)),[Data])) persisted

) ON [PRIMARY]

Neste novo cenário o tempo de insert foi 29seg

E o tempo de leitura foi de apenas 6milesegundos:

 

set statistics io on;
set statistics time on;

select * from viagem_fuso2

Table ‘Viagem_Fuso2’. Scan count 1, logical reads 91, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.

 

SQL Server Execution Times:

CPU time = 16 ms,  elapsed time = 6 ms.

 

Conclusão, colunas persistidas consomem um pouco mais de storage, memória(buffer cache), mas apresenta um ganho significativo na redução da utilização de processador no momento da leitura, e no momento do insert o impacto não é significativo.

Lidando com o erro “Query processor could not produce a query plan”

Atendendo a uma demanda de cliente, onde no cenário precisamos realizar uma sumarização de dados das últimas operações de clientes consolidando tudo dentro de um determinado período.

Ocorria que a consulta iria percorrer a maior tabela do cliente, a tabela chega a representar mais de 80% do tamanho do banco de dados do cliente, portanto era muito importante que nossa consulta, trabalhasse de maneira obrigatória com um índice filtrado, pois nossa consulta desejava apenas um range de informação da tabela, e foi criado um índice apenas para aquele período, para justamente não corrermos o risco de um plano de execução mau elaborado realizando um fullscan no database e fazendo com que não apenas a consulta demorasse muito como também iria comprometer todo o hardware da produção do cliente.

Neste exemplo, a big table é a tabela  Vendas (exemplo hipotético)

Após montar um script (exemplo hipotético simples), abaixo, o sql server resultou em erro:

declare @data_venda datetime = '2017-05-01';

with clientes as (
       select cod_cliente from clientes
       where 
       ultima_acao > @data_venda
       )
,ultima_venda_cliente  as (select  distinct v.cod_cliente, max(v.data_venda) over( partition by v.cod_cliente order by v.data_venda desc)
              from vendas v with(nolock, index(idx_filtrado_vendas_cliente_data))
              join clientes vp  on vp.cod_cliente = c.cod_cliente
              where
              v.data_venda >= @data_venda
              )
select * from ultima_venda_cliente
Msg 8622, Level 16, State 1, Line 6
Query processor could not produce a query plan because of the hints defined in this query. Resubmit the query without specifying any hints and without using SET FORCEPLAN.

Para quem não é persistente, acreditaria pela mensagem de erro que não é possível forçar nesta consulta a utilização de um índice filtrado, pois a mensagem de erro manda submeter a consulta novamente sem hint e afirmando que a utilização do hint é a causa do problema.

A solução é tão simples que quando realizei, quase não acreditei, e foi puramente por acaso que descobri, porque em uma rápida pesquisa na net nada encontrei documentado a respeito.

Basta não trabalhar com parâmetros dentro da CTE onde forço a utilização do índices e está tudo resolvido.

declare @data_venda datetime = '2017-05-01';

with clientes as (
       select cod_cliente from clientes
       where 
       ultima_acao > @data_venda
       )
,ultima_venda_cliente  as (select  distinct v.cod_cliente, max(v.data_venda) over( partition by v.cod_cliente order by v.data_venda desc)
              from vendas v with(nolock, index(idx_filtrado_vendas_cliente_data))
              join clientes vp  on vp.cod_cliente = c.cod_cliente
              where
              v.data_venda >=  '2017-05-01'-- aqui não pode ter parametros @data_venda
              )
select * from ultima_venda_cliente

troubleshoting instalação sql server clusterizado permissões ad

Para erros durante a instalação de um cluster referentes a permissões no add

existem 2 erros comuns,

1 seria igual abaixo:

Cluster network name resource ‘SQL Network Name (nome network sql cluster)’ failed to create its associated computer object in domain ‘dominio’ during: Resource online.

The text for the associated error code is: A constraint violation occurred.

 

e o outro seria

Cluster network name resource ‘SQL Network Name (nome network sql cluster)’ failed to create its associated computer object in domain ‘dominio’ for the following reason: Resource online.

The associated error code is: -1073741790

 

A solução é abrir no AD, o nome do seu cluster, no caso windows cluster, e conceder permissão de criação de objetos filhos.

Além disso crie manualmente o seu computador no ad com o nome do seu sql network name informado na instalação, e adicione permissões totais a este computador do ad, para o computador do cluster.

 

 

Error during installation of an SQL server Failover Cluster Instance

 

 

When Creating a New Resource or Role in Windows Server 2012 R2 Failover Cluster, the Network Name Fails to Come Online or Failed to Create Associated Computer Object in Domain

Tentar excluir um excel em uso no SSIS

Recentemente tive uma briga chata com um processo que deveria ser relativamente simples no SSIS ( Integration Service), o processo consistia em tentar mover ou excluir um arquivo do excel, para um outra pasta após realizar um carga dos dados contidos neste mesmo excel.

Ocorre que dentro da package onde eu estava realizando a carga deste arquivo excel, sempre que se tentava realizar a excluisão ou move-lo de lugar, resultava-se a mensagem:

“[SSIS Errors] The process cannot access the file because it is being used by another process”

Eu tive que brigar alguns dias com isso, várias opiniões de diversos foruns, alguns falando que utilizando outros modelos de conexão com excel funcionava normalmente, e o modelo de conexão que estou utilizando é o .Net Providers for OleDB, mas especificamente Microsoft Office 12.0 Access Database Engine OLE DB Provider.

Outros diziam que se deveria trabalhar primeiro com a cópia do arquivo e o processo de exclusão ser realizado em outra package, pois bem. Tentei tudo isso e sempre retornava a mesma mensagem.

A única solução que no meu caso resolveu, e também requereu dividir o processo em 2 packages.

A primeira package eu passo um parametro com um id de um processo para a próxima package que irá realizar a carga de diversos arquivos de excel em um determinado diretório. Nesta pacakage de carga, eu gravo todos os arquivos carregados em uma tabela, e os copio para o diretório que desejo (pois copiar não dá erro). E aí vem o truque de mestre, sempre que eu termino de carregar cada arquivo, eu coloco uma Script Task onde eu implemento um script C# para dar um release na conexão com o arquivo, e Gotcha. Ao voltar para a package principal, e sim é necessário que seja realizado a exclusão fora da package de carga, agora basta percorrer a minha tabela com todos os arquivos que foram carregados naquele processo e excluir um a um.

A Chave para isso é:

A exclusão não pode ser realizada na mesma package.

E segundo, após a carga de cada arquivo excel, deve-se fazer o release da conexão, com uma script Task semelhante a abaixo :

object rawConnection = Dts.Connections[“arquivo”].AcquireConnection(Dts.Transaction);
Dts.Connections[“arquivo”].ReleaseConnection(rawConnection);

login sql server 2016

Recentemente instalei uma instância do sql server 2016 que permitia apenas autenticação to tipo windows authentication, posteriormente apliquei a atualização do SP1 eu modifiquei a instancia para também aceitar sql authentication, criei um novo usuário sql com permissão sysadmin, e ainda assim eu recebia uma negativa de conexão com a resposta:

Login failed for user ‘agnaldo’. ( Mcrosoft Sql Server, Error: 18456)

Aí reiniciei a instancia, e tudo funcionou normalmente. Conferindo a documentação msdn, verá que sempre que realizar a mudança de uma instancia que permite apenas windows authentication para mixed authentication, será necessário reiniciar a instancia, conforme a documentação oficial em 4 passos.

https://msdn.microsoft.com/en-us/library/ms188670.aspx

To change security authentication mode

  1. In SQL Server Management Studio Object Explorer, right-click the server, and then click Properties.
  2. On the Security page, under Server authentication, select the new server authentication mode, and then click OK.
  3. In the SQL Server Management Studio dialog box, click OK to acknowledge the requirement to restart SQL Server.
  4. In Object Explorer, right-click your server, and then click Restart. If SQL Server Agent is running, it must also be restarted.

Mas além disso, para muitas outras situações sabemos que vira e mexe a velha história de reboot/restart por mais simplória que pareça ser, zera alguns marcadores e variáveis que no final das contas resolve nossos problemas.

 

 

Erro informando path string no SSIS

Um problema muito comum em aplicações, e digo isso porque não se trata apenas de um problema restrito a ferramenta Sql Server Integration Service (SSIS), mas também lembro-me de me deparar com o mesmo problema quando programava em Delphi e PHP  para ambientes Windows Servers, diferentemente dos outros windows, sempre que se desejava informar um caminho físico de uma pasta no Servidor, não bastava informar algo do tipo

c:\pasta\arquivo.txt

Para ambientes windows server o correto seria:

c:\\pasta\\arquivo.txt

Hoje tentando atribuir um caminho a uma variável no SSIS, tive um erro conforme  conforme a imagem:

Por intuição descrobri que a composição de strings é semelhante no SSIS dentro de expressions, a diversas linguagens de programação. E é simplesmente resolvido passando a colocar 2 barras invertidas ao invés de uma única barra invertida. No SSIS sempre que se deseja passar um caracter que funcionaria como um caracter de fechamento, utiliza-se barra invertida (\) exemplo se eu quiser atribuir a string:  ela disse:- Ele é “forte”:

@str = “ela disse: – Ele é \”forte\”

Observe que sem a barra invertida, as aspas duplas funcionariam como final de string. Eis o porque da diferenciação da barra invertida dentro de strings, ela tem um tratamento deferenciado dos demais caracteres, ela funciona como um caracter de controle dentro de strings, para validar qualquer caracter seguinte como texto e não um modificador seja ele aspas duplas(“) ou a própria barra invertida (\), assim sendo se vc quiser passar uma barra invertida dentro de um string, deverá colocar 2 barras inverdidas ao invés de uma única, pois a primeira barra invertida irá funcionar como caracter de controle para dizer que a próxima barra invertida deve ser considerada como texto.

 

Disco adicionado ao cluster Sql após a instalação

Por padrão o Sql Server não reconhece um disco adicionado ao cluster após a instalação do cluster, por default ele irá reconhecer apenas aqueles discos que foram informados como discos pertencentes ao cluster no ato da instalação do Sql Server.

Aí você adiciona um novo disco ao cluster:untitled

e até atribuí este disco como pertencente a Role do Sql Serveruntitled1

Mas ainda assim, o disco não fica disponível para ser utilizado no Sql Server. Abrindo as propriedades da instancia para alterar o disco de dados padrão, percebe-se que a unidade D: ainda não está visível no SQL SERVER, embora esteja visível para o S.O.

untitled2

Para torna-lo visível e disponível ao Sql Server, é necessário localizar o serviço do Sql Server, e incluir o novo disco como dependência. Agora observe que se eu adicionar o novo disco como dependência da minha role, o diagrama de dependência irá me mostrar que tem algo errado e o meu disco ainda não irá para o sql server.

untitleduntitled4

untitled3 untitled5

Observe no gráfico de dependências, que o novo disco de dados ainda está fora da hierarquia de dependências do Sql Server

para resolver este problema basta adicionar os discos dependentes do sql server não a Role mas ao serviço do Sql Server untitled6

Incluindo todos os discos como dependências do serviço do Sql Server, pronto, sem paradas e sem indisponibilidade o novo disco já estará disponível para o Sql Server.

 

No disks suitable for cluster disks were found.

Depois de tanto tempo sem escrever, mas já que tenho me deparado com tantos troubleshooting ultimamente, que acredito que o de hoje  merece a escrita de um artigos. Pois certamente muitos de vocês cedo ou tarde passaram ou passarão pele mesmo problema.

Brincando em um lab de clusterização sql server, me deparei com este problema: um disco que embora estivesse disponível e apresentado para o SO, uma vez removido do cluster por alguma razão qualquer, já não era mais possível adiciona-lo novamente ao cluster. Todas as vezes em que se tentava adicionar um novo disco recebia-se a mensagem que nenhum disco foi encontrado e apto para ser adicionado ao cluster.

No disks suitable for cluster disks were found.

Aí pesquisando um pouco encontrei este artigo:

Windows Server 2012 (R2) – Failover Cluster can’t access disks after outage

Powershell clean disk on cluster

Clear-ClusterDiskReservation -disk 1

Onde rodando o comando em powershell como administrador para limpar as referências do disco no cluster, e via Disks  Management do windows, colocando o disco offline e online (em alguns casos é necessário recriar) o disco volta a ficar disponível para ser adicionado ao cluster. A atenção no comando powershell é quanto a número do disco, que você consegue pegar através do Disk Management do windows, que aparece através do atalho Win + X.

untitled1

untitled2

#troubleshotted

 

Translate »