Archive

Archive for July, 2011

Trouble shooting da TempDB SQL Server

Esse procedimento é dedicado ao meu amigo Jeferson Kiocia  que me  ensinou muitas coisas, sobre windows, Contadores de Performance, Infra,Storage e etc.. Na verdade ele me disse: “Faz um procedimento sobre algo quando “Ferrar” o disco da TempDB! Quando der uma M…. Você tem que ter a solução rápido”. E aqui estamos. Fica a dica: Sempre documente os procedimentos, mesmo, que ainda não tenha acontecido. Porque quando acontecer, você será cobrado e a dor de cabeça será tremenda e ainda você pode ouvir “Se você sabia que isso poderia acontecer, porque não fez um procedimento?”.

Quando usar este procedimento?

O procedimento deve ser usando quando o array que hospeda a tempdb falhar(Nunca deveria acontecer, leia no final do post). Quando isso acontece o SQL Server retorna um erro,pois, o caminho onde a tempdb estava não foi encontrado.

Cenário: Imagine um cenário que temos a tempdb em um disco de nome S, conforme print:

E esse disco falhou ou a letra não é mais a mesma(se você trocou a letra depois da falha). Quando o SQL Server iniciar na próxima vez ele retornará as seguintes mensagens no Event Viewer:

Erro:1

Erro:2


Erro:3

Quando aparecer qualquer dessas mensagens, que dizer que a tempdb não foi encontrada. A solução para esse tipo de problema é: Se conectar ao SQL Server via prompt de comando e alterar o arquivo da tempdb de unidade. Vá até a a pasta aonde encontra-se os binários do SQL Server.

Você deve acessar esse caminho via promt de comand, conforme print:

Digite a linha de comando abaixo para inicar o SQL Server pelo prompt.

Sqlservr.exe -f -m -sNomeDaInstancia

O print mostra a linha digitada:

Obs: O SQL Server Agent deve estar desabilitado para a execução desta linha de comando. Se o SQL Server estiver ativo, você não conseguirá usar o SQL em single user mode. Os parâmetros são explicados abaixo:
f ? Executa o sql server com as configurações minimas.
m ? Entra no sql server em single user mode.
s ? Nome da instancia do sql server. Esse nome pode ser obtido no SQL Server Configuration Manager.

Nome da Instancia.

Com o SQL Server iniciado no prompt que foi aberto:

Quando o SQL Server é inicado desta maneira, a tempdb por default vai para o diretorio de bases de dados padrão do SQL Server de instalação(aonde encontra-se a master, model e msdb). Abra um novo prompt do MS-DOS e use um utilitário de linha de comando para mudar a tempdb de diretório. Use a linha de comando abaixo:

osql.exe -E -sNomeDaInstancia

Conforme o print abaixo:

Obs: O parâmetro -E é a conexão trusted (integrada com o windows), o usuário que está executando este procedimento deve ter permissões de SA no SQL Server. Neste exemplo usamos o login TMKTSQLSVC que é uma conta do windows com permissões de SA.

Após conectado ao SQL Server, execute os comandos abaixo para modificar a tempdb para a nova unidade.

USE MASTER
GO
ALTER DATABASE tempdb MODIFY FILE
(NAME= tempdev, FILENAME= ‘F:/MSSQL2005/MSSQL/SYS_DBS/DATA/tempdb.mdf’)
GO
ALTER DATABASE tempdb MODIFY FILE
(NAME= templog, FILENAME= ‘F:/MSSQL2005/MSSQL/SYS_DBS/LOG/templog.ldf’)

O SQL Server retorna a mensagem que os arquivos da tempdb serão movidos após a próxima reinicialização do serviço do SQL Server.

Digite exit na janela aonde você digitou os comandos e aperte a tecla enter.
Na outra janela de prompt que está em aberta pressione CTRL C aparecerá uma mensagem solicitando confirmação se você deseja fazer o shutdown do SQL Server.

Pressione a tecla Y.

Inicie o SQL Server normalmente.

Após o procedimento o SQL Server deve subir normalmente.

Obs: Leitura no final do post: A tempdb sempre deve estar em um disco que oferece redundância, de preferência um disco com alta velocidade para escrita e leitura(RAID 10). Esse procedimento foi criado em um ambiente onde a tempdb estava em um RAIDO.

Espero ter ajudado.
Abssssss

Advertisements

Integrando os contadores do System Monitor ao SQL Server Profiler

Esse artigo é dedicado ao meu amigo Marcelo Fernandes da Silva (Misifio/D2). Graças a ele, estou no “mundo SQL Server”. Sempre está me incentivando e me dando uns helps.Quem o conhece sabe o quanto ele conhece(É muitooo viuuuu!) de SQL Server. Vamos ao trabalho.

Esse procedimento pode ser implementado em um ambiente que existe diversos sites, e você deseja realizar um procedimento pró-ativo de melhoria no ambiente começando pelo código T-SQL que é executado no mesmo.

Capturando Log Counters.

O primeiro passo é capturar as informações numericas relacionadas a gargalo de disco, processamento, memória e etc. Abra o System Monitor conforme figura abaixo:

Clique com o botão direito em Counters Log e escolha a opção New Log Settings..

Aparecerá uma caixa solicitando o nome do Counter Log a ser criado. Preencha e clique em OK.

Aparecerá a já nela de configurações dos contadores a ser escolhido.

Current log file name:  Caminho e Nome do arquivo do contador
Add Objects:  Lista de objetos do System Monitor
Add Counters:  Lista de Contadores do System Monitor
Interval: Intervalo de tempo em que os dados serão coletados
Run As: Credencial que irá executar o counter log e gravar os arquivos na pasta que será selecionada.

Clique em add counters para adicionarmos os contadores. No nosso exemplo será usado apenas alguns contadores do objeto processador. Clique em Add.

Na guia Log Files, você configura o tamanho que terá o arquivo do contadores e qual o caminho aonde o mesmo será gravado.

Clique em configure.

Será aberta a janela aonde o arquivo deverá ser salvo. Por default o arquivo é sempre salvo no diretório C:. Aqui nós criaremos uma pasta no diretório F: e apontaremos o caminho do arquivo para esta pasta(CountersSQL).

Clique em OK.

Na guia Schedule, podemos agendar o horário que o contador inicie, intervalo e etc. Não usaremos isso, pois, iniciaremos o mesmo manualmente.

Clique em OK

Voltando para a guia General. Preencha o textbox com a credencial que irá executar o contador e clique em Set Password. Abrirá uma janela parecida com a do print abaixo:

Obs: Neste exemplo estou usando a conta do serviço do SQL Server, pois, a mesma possui direitos de Admins do dominio. Sempre use uma conta que tem permissão de gravação na pasta no qual será gravado o log. Clique em OK. Depois clique em OK na guia General.

Na opção de counters Log irá aparecer o seu contador e qual caminho você salvou.


Clique com o botão direito e inicie o contador, o mesmo mudará de cor, conforme print:

Iremos para a segunda parte do procedimento

Unificando as ferramentas

Para que esta tarefa seja concluída você deve ter um arquivo do profiler que estava executando na mesma hora em que o Counter Log foi iniciado. Um dos pré-requisitos para que os dados sejam “mesclados” é que o profiler deve ter sido criado com a coluna Start Time selecionada.

Vamos partir do pressuposto que o arquivo do profiler já havia sido coletado e o counter log também. E que os mesmos foram executados durante o mesmo periodo.

Abra o profiler e vá em Open/File/Trace File

Navegue até a pasta aonde está salvo o arquivo .trc do profiler do SQL Server.

Clique em Abrir.
Novamente no Menu File escolha a seguinte opção:

Ao clicar nesta opção, você deverá passar o caminho aonde esta salvo o counter log que foi criado.

Clique em abrir.

A janela com os contadores que você escolheu anteriormente irá aparecer todos desmarcados. Marque os check box apenas do tempo total de processamento.

Obs: Você pode escolher mais que um contador, neste exemplo apenas usaremos o tempo de processamento. Apenas um contador facilita a visualização e se for um problema de processamento em um devido horário, não tem porque adicionar contadores de disco.

Após você escolher o contador o resultado será apresentado, conforme abaixo:

Você pode analisar em qual horário foi o pico de processamento e o que estava rodando no exato momento no profiler.

Espero que seja uma dica útil para alguém que esta começando….

Calculo SQL Server com Windows Function

Ola galera, bom dia(Agora já é tarde, tive que parar pra resolver umas “buchinhas”, voltando após almoço e globo esporte). Blz ?
Hoje iremos fazer uma query usando as windows Function do SQL Server.Esse post  foi originado de uma query que tivemos que criar aqui na empresa. E a maneira mais “elegante” de escrever a  query foi usando as Windows Function.
Tendo as seguintes informações em um arquivo .xls, que me foi passado por um amigo desenvolvedor:
TabelaA

 

TabelaB

E o mesmo deseja o seguinte resultado as informações:

 

Vou explicar os calculos:

primeira Coluna “SomaProdutos” é a soma dos produtos das duas tabelas por IdPeriodo
Ex: A tabela A e a Tabela B armazena a informação de Valor para o periodo  1.
A soma dos valores 77 + 55 é  igual a 132 e assim sucessivamente.
A coluna “DiasUteis” é uma informação que esta atrelada a cada IdPeriodo. Em um periodo existe uma
certa quantidade de dias uteis para aquele periodos. No meu caso trasnformei essas    informações em
uma tabela de dias uteis e o IdPeriodo.
A coluna “Multiplicação” é a multiplicação dos DiasUteis por SomaProdutos.
A coluna “SomaMultiplicacao” é a soma total da coluna “Multiplicacao”.
A coluna “SomaDias” é a soma da coluna DiasUteis.
E a ultima coluna “Resultado” é a Divisão da coluna  “SomaMultiplicacao” por “SomaDias”.

Uma das vantagens da Windows Function é que podemos ter acesso aos detalhes de uma informação agrupada.
Mais informações Fabiano Amorim: http://blogs.solidq.com/fabianosqlserver/Post.aspx?ID=58

Vamos aos código (A parte boa….rs).
Primeiro crio as tabelas temporarias conforme arquivo .xls (É possivel fazer apenas com uma tabela de periodo,mas, depois da fejuca. Vamos que vamos). Crio a tabela de dias uteis e insiro as informações do meu arquivo .xls.
use tempdb
go
create table #tmp_produto_um(id_periodo int, id_produto int, valor decimal(19,2))
create table #tmp_produto_dois(id_periodo int, id_produto int, valor decimal(19,2))
create table #tmp_dias_uteis(id_periodo int, qtdeDias int)

insert into #tmp_produto_um(id_periodo,id_produto,valor) values(1,18,55.00),(2,18,44.00),(3,18,33.00),(4,18,22.00)
insert into #tmp_produto_dois(id_periodo,id_produto,valor) values(1,19,77.00),(2,19,66.00),(3,19,44.00),(4,19,33.00)
insert into #tmp_dias_uteis(id_periodo,qtdeDias)values(1,22),(2,21),(3,22),(4,23)

SELECT * FROM #tmp_produto_um
SELECT * FROM #tmp_produto_dois
SELECT * FROM #tmp_dias_uteis

 

 

 

Crio uma CTE com a soma dos Valores que no .xls é: SomaProdutos.A multiplicação que no .xls é:DiasUteis * SomaProdutos.

;WITH cte AS
(
SELECT    p.id_periodo                                AS IdPeriodo
        ,SUM(d.valor) + SUM(p.valor)                 AS ValorTotal
        ,u.qtdeDias                                    AS QtdeDias
        ,(SUM(d.valor) + SUM(p.valor)) * u.qtdeDias    AS ProdutVsDiasUteis
        FROM #tmp_produto_um p
        JOIN #tmp_produto_dois d
        ON p.id_periodo = d.id_periodo
        JOIN #tmp_dias_uteis u
        ON u.id_periodo = p.id_periodo
        GROUP BY p.id_periodo,u.qtdeDias
)
Abaixo realizo a query chamando a CTE e usando o SUM com o OVER() para que possa ser realizado a soma das colunas, sem a necessidade de agregação. E dentro da SubQuery crio a soma para ser usada como a coluna resultado. Código total abaixo:

;WITH cte AS
(
SELECT    p.id_periodo                                AS IdPeriodo
        ,SUM(d.valor) + SUM(p.valor)                 AS ValorTotal
        ,u.qtdeDias                                    AS QtdeDias
        ,(SUM(d.valor) + SUM(p.valor)) * u.qtdeDias    AS ProdutVsDiasUteis
        FROM #tmp_produto_um p
        JOIN #tmp_produto_dois d
        ON p.id_periodo = d.id_periodo
        JOIN #tmp_dias_uteis u
        ON u.id_periodo = p.id_periodo
        GROUP BY p.id_periodo,u.qtdeDias
)
SELECT  
        c.IdPeriodo,
        c.ValorTotal,
        c.QtdeDias,
        c.ProdutVsDiasUteis
        ,SUM(c.ProdutVsDiasUteis)        OVER()    AS SomaProdutVsDiasUteis
        ,SUM(c.QtdeDias)                OVER()    AS SomaTotalDias
        ,ROUND(D.SomaDiasUteis / D.SomaDias,2)  AS GeralCalculado
        FROM cte c
        JOIN (    SELECT    a.IdPeriodo
                        ,SUM(a.ProdutVsDiasUteis)        OVER()    AS SomaDiasUteis
                        ,SUM(a.QtdeDias)                OVER()    AS SomaDias
                FROM  cte a
                ) as D
        ON c.IdPeriodo = D.IdPeriodo

Como pode ser visto o resultado do SQLServer é o mesmo que o arquivo .xls que foi colocada no print anteriormente.
Resultado SQL Server:


Espero ter ajudado.
Abs a todos…e tenham uma ótima semana.