Script desenvolvido pela Microsoft verifica se PCs estão vulneráveis aos ataques gerados pelas falhas Meltdown e Spectre


A Microsoft anunciou em seu site de suporte a disponibilidade de um script do PowerShell que pode ser utilizado por profissionais de TI para verificar se PCs são vulneráveis aos ataques Meltdown e Spectre.

O script pode ser utilizado via PowerShell no Windows 10 (1v1507, v1511, v1607, v1703 e v1709), Windows 8.1 e Windows 7 com SP1.

Ações recomendadas
Antes de começar, a Microsoft alerta que seus precisam tomar as seguintes medidas para se protegerem contra as vulnerabilidades:

– Verifique se você está executando um aplicativo antivírus com suporte antes de instalar as atualizações de SO ou firmware. Contate o fornecedor do software antivírus para obter informações de compatibilidade.

– Aplique as atualizações disponíveis do sistema operacional Windows, incluindo as atualizações de segurança do Windows de janeiro de 2018.

– Aplique a atualização de firmware fornecida pelo fabricante do dispositivo.

Nota: Máquinas baseadas no Windows (físicas ou virtuais) devem instalar as atualizações de segurança da Microsoft que foram lançadas em 3 de janeiro de 2018.

Aviso
Os clientes que só instalarem as atualizações de segurança do Windows de janeiro de 2018 não receberão o benefício de todas as proteções conhecidas contra as vulnerabilidades. Além de instalar as atualizações de segurança de janeiro, é necessária uma atualização do microcódigo do processador ou do firmware. Ele deve estar disponível pelo fabricante do seu dispositivo.

Observação: Os dispositivos da linha Surface receberão uma atualização do microcódigo através do Windows Update.

Script da Microsoft verifica se PCs são vulneráveis aos ataques Meltdown e Spectre

Verificando se o computador é vulnerável aos ataques Meltodown e Spectre

Para ajudar os clientes a confirmar se as proteções foram habilitadas e se seus sistemas estão vulneráveis, a Microsoft publicou um script PowerShell que os profissionais de TI podem executar em seus sistemas. Instale e execute o script executando os seguintes comandos:

Instale o módulo via PowerShell:

PS > Install-Module SpeculationControl

Execute o módulo no PowerShell para validar se as proteções estão habilitadas:

PS > Get-SpeculationControlSettings

A saída desse script PowerShell será semelhante à exibida abaixo. As proteções habilitadas serão exibidas na saída como “True”:

PS > Get-SpeculationControlSettings

Speculation control settings for CVE-2017-5715 [branch target injection]
Hardware support for branch target injection mitigation is present: True
Windows OS support for branch target injection mitigation is present: True
Windows OS support for branch target injection mitigation is enabled: True
Speculation control settings for CVE-2017-5754 [rogue data cache load]
Hardware requires kernel VA shadowing: True
Windows OS support for kernel VA shadow is present: True
Windows OS support for kernel VA shadow is enabled: True
Windows OS support for PCID optimization is enabled: True

Perguntas frequentes

P: Como saber se eu tenho a versão certa do microcódigo da CPU?
R: O microcódigo é fornecido através de uma atualização de firmware. Consulte o fabricante do dispositivo sobre aversão do firmware que possui a atualização apropriada para a sua CPU.

P: Meu sistema operacional (SO) não está listado. Quando posso esperar o lançamento de uma correção?
R: Abordar uma vulnerabilidade de hardware através de uma atualização de software apresenta desafios significativos, e as mitigações para sistemas operacionais mais antigos exigem extensas mudanças na arquitetura. A Microsoft está trabalhando com fabricantes de chips afetados para determinar a melhor maneira de proporcionar mitigações, que podem ser disponibilizadas em atualizações futuras.

P: Onde posso encontrar as atualizações de firmware/hardware do Surface?
A: As atualizações para dispositivos Microsoft Surface serão entregues aos clientes através do Windows Update, juntamente com as atualizações para o sistema operacional Windows. Para obter mais informações, consulte o artigo KB4073065.

Nota: Se seu dispositivo não for da Microsoft, aplique o firmware do fabricante do dispositivo. Contate o fabricante para obter mais informações.

P: Tenho um arquitetura x86, mas não vejo atualização. Vou receber uma?
R: Abordar uma vulnerabilidade de hardware através de uma atualização de software apresenta desafios significativos, e as mitigações para sistemas operacionais mais antigos exigem extensas mudanças na arquitetura. Estamos trabalhando com fabricantes de chips afetados para determinar a melhor maneira de fornecer mitigações para clientes x86, que podem ser fornecidos em uma atualização futura.

Fontes e Direitos Autorais: Suporte Microsoft – 05/01/2018 – https://support.microsoft.com/pt-br/help/4073119/protect-against-speculative-execution-side-channel-vulnerabilities-in

Anúncios

Dica do Mês – Conhecendo a nova DMF sys.dm_exec_input_buffer no Microsoft SQL Server 2016


Bom dia, bom dia, bom dia….. Feliz 2017

Salve, salve comunidade, estou retorno hoje, conforme o prometido após alguns dias de “descanso mental”. Espero que todos tenham passado um ótimo fim de ano e estejam preparados para os desafios de 2017.

Estamos completando o primeiro ano da sessão Dica do Mês, sendo este o post de número 12, poxa vida muito legal ver o quanto de conteúdo e conhecimento já foi transmitido nesta sessão.

Hoje dia 16 de Janeiro primeiro post de 2017 dedicado mais uma vez ao Microsoft SQL Server, dentre os quais voltados exclusivamente a versão 2016, vou destacar um assunto bem conhecido de qualquer DBA denominado Input Buffer.

Não vou destacar do que se trata este conceito mais sim apresentar como a partir do SQL Server 2016 podemos recurperar e coletar as informações relacionado a ele de uma maneira diferente se comparado com as versões anteriores.

Então vamos lá, seja bem vindo ao Dica do Mês número 12……

Introdução

Reconhecer e identificar o que esta sendo transacionado dentro do seu servidor ou instância do Microsoft SQL Server para muitos é coisa de outro mundo, para outros coletar estes dados não passa de um simples comando que você pode executar.

Na verdade os lados da moeda tem a sua verdade, identificar e entender o que esta sendo transacionado não é uma tarefa fácil por isso pode ser considerado algo fora da terra, como também, coletar e armazenar é algo muito simples, e realmente é!!!

Desde as versões mais antigas do SQL Server a maneira mais comum e menos consumista de se obter informações sobre o Buffer ou Input Buffer dentro de um servidor ou instância era através do comando DBCC Input Buffer, onde bastava simplesmente executar este comando para se obter a informações sobre o buffer de uma sessão específica.

Agora na versão 2016 desta RC0 a Microsoft de um novo jeitinho para se obter estes dados através do uso da nova DMF – Dynamic Management Function ou Função de Gerenciamento Dinâmico chamada Sys.dm_exec_input_buffer.

Ao executar pela primeira vez esta DMF, pensei que seria um recurso substituto ao bem e velho DBCC Input Buffer, ao começar a brincar um pouco mais com ela  observei que existe uma pequena similaridade entre ambos.

Similaridade que se tornou mais clara na maneira que a sys.dm_exec_input_buffer apresentar os dados coletados que estão sendo transacionados, o que também acabou ficando somente nisso, durante as diversas execuções que realizei, foi possível  reconhecer algumas pequenas diferenças que podemos reconhecer como vantagens no uso da sys.dm_exec_input_buffer em comparação ao DBCC InputBuffer.

Sys.dm_exec_input_buffer x DBCC Input Buffer

Basicamente a forma de uso de ambos os recursos não posso dizer que seja algo muito diferente, o DBCC InputBuffer você executa de forma direta passando o SID da sessão a qual você deseja obter o buffer, já a sys.dm_exec_input_buffer o mínimo a favor é executar um comando Select direcionado para esta DMF.

Falando das vantagens destaco abaixo as mais fáceis de se identificar:

  1. Ao executar a dmf o resultado é apresentado diretamente como um conjunto de linhas, o que permite em uma bloco de código obter os input buffers de diversas sessões, uma grande vantagem se comparada com o DBCC Input Buffer;
  2. Outra diferença clara é a capacidade de realizar joins com outras DMFs dentre elas: sys.dm_exec_sessions, sys.dm_exec_connections e sys.dm_exec_requests através do uso do operador Cross Join;
  3. Através da execução de uma simples query através do comando select podemos recuperar o buffer de diversas entradas de sessões distintas sem a necessidade de criar um script, tabela temporária ou tabela auxiliar; e
  4. Possibilidade armazenar o resultado da relação de buffers coletados em uma nova tabela.

Exemplos

Como já mencionei anteriormente a forma de uso da sys.dm_exec_input_buffer é bem simples e fácil, como também, a apresentação dos dados coletados, os dois exemplos apresentados a seguir demonstram como podemos fazer uso desta nova DMF no Microsoft SQL Server 2016:

— 1 – Executando um simples Select —
SELECT * FROM sys.dm_exec_input_buffer(52, 0);

dica-12-01Figura 1 – Buffer coletado da sessão 52.

— 2 – Utilizando o operador Cross Apply —
SELECT es.session_id, ib.event_info
FROM sys.dm_exec_sessions AS es
CROSS APPLY sys.dm_exec_input_buffer(es.session_id, NULL) AS ib
WHERE es.session_id > 50;

dica-12-02Figura 2 – Buffers coletados após a execução do exemplo 2.

Referências

Conclusão

Como de costume a cada nova versão ou atualização a Microsft esta apresentando diversas inovações e melhorias no Microsoft SQL Server, mantendo o produto no seu mais alto nível de funcionalidades, recursos e inovações.

Neste post você pode perceber que mais uma vez isso esta presente, uma nova maneira de se obter informações sobre os buffers que estão sendo transacionados e processados dentro de um servidor ou instância do SQL Server através da DMF sys.dm_exec_input_buffers.

Agradecimentos

Mais uma vez obrigado por sua visita, agradeço sua atenção, fique a vontade para enviar suas críticas, sugestões, observações e comentários.

Conto com a sua presença em mais este ano aqui no meu blog….

Feliz 2017!!!

Criando Funções e Esquemas de Particionamento de Dados para oferecer possíveis ganhos desempenho e distribuição de dados no Microsoft SQL Server 2008 e Microsoft SQL Server 2008 R2.


Pessoal, bom dia.

Estou de volta, com mais um artigo. Hoje vou falar um pouco de Particionamento de Dados no Microsoft SQL Server 2008 e Microsoft SQL Server 2008 R2, através do Partition Function e Partition Scheme.

Recentemente venho recebendo de alguns contatos, questionamentos sobre como podemos tentar melhorar o desempenho de nossos servidores SQL Server, de uma forma, que não impacte na estrutura interna de aplicações que estão fazendo acesso aos dados.

A princípio veio a minha mente utilizar o particionamento do banco de dados em diversos Filegroups, algo que normalmente eu utilizo e consigo mensurar e observar melhoras de desempenho.

Por outro lado, também pensei em utilizar particionamento horizontal de tabelas, fazendo com o banco de dados, cresça no seu tamanho de tabelas, mas isso vai impactar diretamente na aplicação.

Então, me deparei com a possibilidade de utilizar o Particionamento de Dados através do uso de Funções e Esquemas, o que poderia aliar ainda o uso de outros Filegroups.

Muito bem, um dos cenários mais atraentes para se utilizar este tipo de técnica, consiste na identificação de tabelas que possuem um volume grande de manipulações de dados, como também, sua quantidade de registro cresce constantemente, passando de centenas de dados, milhares ou bilhões de linhas de registros em pouco tempo.

Como de costumo vou destacar um pouco das finalidades e funcionalidades destes recursos, inicialmente pela Função de Particionamento.

Partition Function (Funções de Particionamento): Cria uma função no banco de dados atual que mapeia as linhas de uma tabela ou índice em partições com base nos valores de uma coluna especificada. Usar a instrução CREATE PARTITION FUNCTION é a primeira etapa na criação de uma tabela particionada ou índice.

No momento da criação uma função de particionamento, temos a necessidade de especificar o lado, sendo ele: Left ou Right, que determinada à forma de controle para alocação do dado em uma partição.

Ao especificar qual lado de cada intervalo de valor de limite, esquerdo ou direito, os valores devem pertencer. Estamos definindo a forma com que os intervalos serão classificados pelo Mecanismo de Banco de Dados em ordem crescente da esquerda para a direita. Se não for especificado, LEFT é o padrão.

O escopo de uma função de partição está limitado ao banco de dados no qual ele for criado. No banco de dados, as funções de partição residem em um namespace separado das outras funções.

Quaisquer linhas cuja coluna de particionamento tenha valores nulos serão colocadas na partição mais à esquerda, a menos que NULL seja especificado como um valor de limite e RIGHT sejam indicados. Nesse caso, a partição mais à esquerda será uma partição vazia e os valores NULL serão colocados na partição seguinte.

Qualquer uma das permissões a seguir pode ser usada para executar CREATE PARTITION FUNCTION:

  • Permissão ALTER ANY DATASPACE. Essa permissão tem como padrão os membros da função de servidor fixa sysadmin e das funções de banco de dados fixas db_owner e db_ddladmin.
  • Permissão CONTROL ou ALTER no banco de dados no qual a função de partição está sendo criada.
  • Permissão CONTROL SERVER ou ALTER ANY DATABASE no servidor do banco de dados no qual a função de partição está sendo criada.

Partition Scheme (Schemas de Particionamento): Cria um esquema no banco de dados atual que mapeia as partições de uma tabela particionada ou índice para grupos de arquivos.

Uma função de partição deve primeiramente ser criada em uma instrução CREATE PARTITION FUNCTION antes de criar um esquema de partição.

Ao criarmos um Esquema de Particionamento, temos a obrigatoriedade de vincular as áreas de particionamento e alocação de dados, de acordo com os limites especificados, como faixa de valores na Função de Particionamento. Neste caso, se especificamos três limites de valores em nossa função, deveremos utilizar quatro áreas de alocação de dados em nosso esquema, para podermos armazenados todos os possíveis limites de dados.

Para criar um Esquema de particionamento, através do comando CREATE PARTITION SCHEME, devemos ter uma das seguintes permissões:

  • Permissão ALTER ANY DATASPACE. Esta permissão tem como padrão os membros da função de servidor fixa sysadmin e das funções de banco de dados fixas db_owner e db_ddladmin.
  • Permissão CONTROL ou ALTER no banco de dados no qual o esquema de partição está sendo criado.
  • Permissão CONTROL SERVER ou ALTER ANY DATABASE no servidor do banco de dados no qual o esquema de partição está sendo criado.

Agora que conhecemos um pouco do que uma Função de Particionamento e um Esquema de Particionamento devem realizar, vamos agora, começar a criar o nosso ambiente, para colocarmos em uso estes dois recursos.

Vale ressaltar que somente a Edição Enterprise do Microsoft SQL Server 2005 em diante tem a capacidade de trabalhar com Funções e Esquemas de Particionamento de Tabelas e Índices.

Começamos pela criação do nosso banco de dados, vou definir o nome deste Banco como Particionamento, conforme apresenta o Código 1.

— Código 1 – Criando o Banco de Dados –

Create Database Particionamento

ON PRIMARY

(NAME = Particionamento_Dados,

  FILENAME = N’C:\SQL\Teste_Dados.mdf’,

  SIZE = 2MB,

  MAXSIZE = Unlimited,

  FILEGROWTH = 10%)

LOG ON

(NAME = Particionamento_Log,

 FILENAME = N’C:\SQL\Particionamento_Log.ldf’,

 SIZE = 4MB,

 MAXSIZE = Unlimited,

 FILEGROWTH = 10%)

 

O próximo consiste no adicionamento de novos Filegroups (Agrupamento de Arquivos) e em seguida a criação de novos arquivos de dados, que serão utilizados em conjunto com a nossa função e esquema de particionamento. Na primeira parte do Código 2, vamos criar os dois novos Filegroups, denominados: ParticionamentoFG1 e ParticionamentoFG2.

— Código 2 – Parte I – Criação de novos Filegroups –

Alter Database Particionamento

Add FileGroup ParticionamentoFG1

Go

Alter Database Particionamento

Add FileGroup ParticionamentoFG2

Go

Nossos Filegroups já estão criados, falta agora vincular os nossos arquivos de dados e estes repositórios, conforme apresenta a segunda parte do Código 2.

 

— Código 2 – Parte II – Criação de novos arquivos de dados e vínculo com os Filegroups –

Alter Database Particionamento

Add File

 (Name = Particionamento_Dados_Segundo,

  FileName = ‘C:\SQL\Particionamento_Dados_Segundo.ndf’,

  Size = 2MB,

  MaxSize = Unlimited,

  Filegrowth = 10%)

To Filegroup ParticionamentoFG1

Go

Alter Database Particionamento

Add File

 (Name = Particionamento_Dados_Terceiro,

  FileName = ‘C:\SQL\Particionamento_Dados_Terceiro.ndf’,

  Size = 5MB,

  MaxSize = Unlimited,

  Filegrowth = 10%)

To Filegroup ParticionamentoFG2

Go

Pois bem, nossos novos arquivos de dados estão criados e vinculados com seus respectivos filegrous, vamos utilizar a Visão de Catálogo de Sistema, sys.FileGroups para obter a relação de agrupamento de arquivos definidos para o nosso Banco de Dados Particionamento. Para isso podemos executar o Código 3, conforme apresento abaixo:

 — Código 3 – Consultando a relação de Filegroups –

Select * from sys.FileGroups

Após executarmos este código recebemos o seguinte resultado:

Figura 1 – Relação de Filegroups configurados para o Banco de Dados – Particionamento.

Podemos constatar e comprovar a existência dos três Filegroups alocados para este banco de dados, o próximo passo consiste justamente na parte mais importante deste artigo, onde estaremos fazendo a criação da nossa Função de Particionamento e Esquema de Particionamento de Dados.

Para isso, vou utilizar o Código 4 e Código 5, respectivamente:

— Código 4 – Criando a Função de Particionamento PF_Valores –

CREATE PARTITION FUNCTION PF_Valores (Int)

AS RANGE Left FOR VALUES (1,4,8)

GO

É possível notar que a função de particionamento PF_Valores, possui como faixa de valores os Número 1, 4 e 8, além disso, o controle para delimitação dos valores esta definido ao Esquerda. Outro detalhe importante que estes valores serão tratados e reconhecidos como Inteiros.

Podemos confirmar a criação desta função, através da Visão de Catálogo de Sistema: Sys.Partition_Functions, através do código: Select * from sys.partition_functions

— Código 5 – Criando a Esquema de Particionamento PS_Valores –

CREATE PARTITION SCHEME PS_Valores

AS PARTITION PF_Valores

TO (ParticionamentoFG1, ParticionamentoFG1, ParticionamentoFG2, ParticionamentoFG2);

GO

Fazendo uma rápida análise, podemos observar que o esquema de particionamento PS_Valores, esta vinculado em sua opção Partition a função PF_Valores, para as seguintes áreas de alocação de dados:

  • ParticionamentoFG1 e ParticionamentoFG2

Sendo assim, como a função PF_Valores tem o controle de limite de valores, a partir da Esquerda, respeitando sua faixa de valores: 1, 4 e 8. O SQL Server vai criar a seguinte estrutura para armazenamento de dados, conforme apresenta a Tabela 1:

Partition

1

2

3

4

 Valores

Int <= 1

Int > 1 AND Int <= 4

Int > 4 AND col1 <=8

Int > 8

Tabela 1 – Estrutura para alocação de dados de acordo com a partição.

A partir do momento em que o vínculo entre o Esquema de Particionamento é definido com a Função de Particionamento, o SQL Server define a sua falta de distribuição de dados, conforme a Tabela 1, mas atrelando os Filegroups especificados no esquema. Com isto, teremos a distribuição de dados apresentada na Tabela 2:

Partition

1

2

3

4

 Valores

Int <= 1

Int > 1 AND col1 <= 4

Int   > 4   AND Int <=8

Int > 8

Filegroups

ParticionamentoFG1

ParticionamentoFG1

ParticionamentoFG2

ParticionamentoFG2

Data_Space

2

2

3

3

Tabela 2 – Estrutura para alocação de dados de acordo com a partição e filegroup.

Estamos chegando ao final, agora falta pouco para concluirmos este artigo, nesta parte final vamos criar uma tabela chamada Valores e ao invés de vincular esta tabela com um Filegroups, vamos fazer o vínculo com nosso Esquema de Particionamento PS_Valores, através da coluna Valor que é do tipo inteiro, o mesmo tipo que configuramos na criação da Função PF_Valores. Com isso o SQL Server, terá a capacidade de distribuir os dados entre os Filegroups, conforme apresenta o Código 6.

— Código 6 – Criação da Tabela Valores –

Create Table Valores

 (Codigo Int Identity(1,1),

  Descritivo Varchar(20) Not Null,

  Valor Int Not Null)

On PS_Valores(Valor)

Nossa tabela esta criada e pronta para receber os dados, agora podemos realizar a série de comandos Inserts e observar o crescimento dos nossos arquivos de dados, vinculados de acordo com seus Filegroups.

Vamos então executar em partes do Código 7, neste código estamos realizando a inserção de massas de dados divididas em faixas de valores para forçar e apresentar o particionamento de dados. Vale ressaltar que estamos inserindo em cada porção o número de 100 mil linhas de registros, o que poderá demandar um certo tempo de processamento.

— Código 7 – Parte I – Inserção de Dados —

Insert Into Valores (Descritivo, Valor)

Values (‘Este é um teste’,1)

Go 100000

 

Insert Into Valores (Descritivo, Valor)

Values (‘Este é um teste’,10)

Go 100000

 

Insert Into Valores (Descritivo, Valor)

Values (‘Este é um teste’,2)

Go 100000

 

Insert Into Valores (Descritivo, Valor)

Values (‘Este é um teste’,9)

Go 100000

— Código 7 – Parte II – Inserção de Dados —

Insert Into Valores (Descritivo, Valor)

Values (‘Este é um teste’,3)

Go 100000

 

Insert Into Valores (Descritivo, Valor)

Values (‘Este é um teste’,8)

Go 100000

 

Insert Into Valores (Descritivo, Valor)

Values (‘Este é um teste’,4)

Go 100000

 

Insert Into Valores (Descritivo, Valor)

Values (‘Este é um teste’,7)

Go 100000

— Código 7 – Parte III – Inserção de Dados —

Insert Into Valores (Descritivo, Valor)

Values (‘Este é um teste’,5)

Go 100000

 

Insert Into Valores (Descritivo, Valor)

Values (‘Este é um teste’,6)

Go 100000

Após inserir todas as faixas de valores, foi possível observar que o SQL Server realizou a distribuição dos dados de acordo com as faixas definidas em nossa função, trabalhando em conjunto com o nosso esquema.

Todo este trabalho foi feito de forma transparente, sem que fosse necessário mais algum tipo de customização, na verdade toda a regra de negócio já havia sido definida na função e esquema. Isso nos mostra o quanto podemos evoluir com este tipo de cenário, fazendo uso deste recurso fantástico em nosso ambiente de trabalho, proporcionando uma forma de trabalho rápida, inteligente, simples e prática.

Como também, é importante destacar que momento em que estivermos realizando qualquer tipo de manipulação de dados, o SQL Server estará fazendo acesso a locais distintos, arquivos distintos e conseguindo ler dados distribuídos de forma contínua e simultânea.

Outro detalhe interessante foi à forma de crescimento de nossos arquivos de dados, sendo feito de acordo com a distribuição de dados, por parte do esquema, o que também indica todo processo de análise e inteligência realizado pelo SQL Server, conforme os dados estão sendo manipulados.

Bom, acredito que este artigo com certeza vai ajudar em muito o sua dia-a-dia, principalmente no que diz respeito à particionamento de tabelas, índices, dados e Filegroups. Por outro lado, poderá servir como base para outras soluções, dentre elas a melhoria para acesso a grandes tabelas e bancos de dados.

Mais uma vez agradeço a sua visita, nos encontramos em breve.

Pesquisando o mesmo registro em diversas tabelas no SQL Server 2008, R2 e 2012.


Pessoal, bom dia.

Gostaria de lançar uma pergunta para vocês.

Quem nunca teve a necessidade de pesquisar a mesa informação em mais de uma tabela no Banco de Dados, mais especificamente no Microsoft SQL Server?

Pois bem, é justamente a resposta para este questionamento que é um dos mais comuns nos fóruns, listas de usuários e até mesmo dentro da sua empresa, que esta dica pretende responder.

Como todos sabem, um simples Banco de Dados é organizado logicamente por uma estrutura de armazenamento de dados chamada Tabela. Este estrutura é dividida de forma lógica e física em pequenas áreas de armazenamento chamadas colunas.

Seguindo este conceito, podemos imaginar a dificuldade para qualquer Administrador de Banco de Dados, Analista de Sistemas, Desenvolvedor ou qualquer outro profissional da área de TI, BI ou Tomada de Decisão tem a dificuldade para se encontrar o mesmo dado espalhado por estas estruturas de armazenamento.

Com base nesta necessidade, e também respondendo a diversos questionamentos que venho sempre recebendo em meus e-mails, posts que respondo diariamente nos Fóruns MSDN. Como não sempre, sabemos por onde começar pesquisei um pouco de informações na Internet e acredito ter consegui desenvolver uma possível solução ou ideia de solução para este cenário.

A possível solução:

Conforme destaquei anteriormente, desenvolvi uma possível solução para este cenário, denominada “Mecanismo de Pesquisa de Dados em Objetos”. O código utilizado por esta funcionalidade esta dividido em sete partes para facilitar o entendimento e criação deste mecanismo de pesquisa.

Parte 1 – Considerada o ponto inicial da criação do Mecanismo, bastante simples e de fácil compreensão. Trata-se da Criação das Tabelas que serão utilizadas como repositório para os dados.

— Parte 1: Verificando a existência das Tabelas —

If Exists(Select Object_Id(‘Tabela1’))

 Begin

  Drop Table Tabela1

 

  CREATE TABLE Tabela1

   (Coluna1 INT,

    Coluna2 INT,

    Coluna3 INT)

 End

 Else

  Begin

   CREATE TABLE Tabela1

    (Coluna1 INT,

     Coluna2 INT,

     Coluna3 INT)

  End 

 

If Exists(Select Object_Id(‘Tabela2’))

 Begin

  Drop Table Tabela2

 

  CREATE TABLE Tabela2

   (Coluna1 INT,

    Coluna2 INT,

    Coluna3 INT)

 End

 Else

  Begin

   CREATE TABLE Tabela2

    (Coluna1 INT,

     Coluna2 INT,

     Coluna3 INT)

  End  

 

If Exists(Select Object_Id(‘Tabela3’))

 Begin

  Drop Table Tabela3

 

  CREATE TABLE Tabela3

   (Coluna1 INT,

    Coluna2 INT,

    Coluna3 INT)

 End

  Else

  Begin

   CREATE TABLE Tabela3

    (Coluna1 INT,

     Coluna2 INT,

     Coluna3 INT)

  End

Parte 2 – Responsável pela população de dados, para tabelas criadas anteriormente:

— Parte 2: Inserindo os registros —

INSERT INTO Tabela1 VALUES (1, 2, 3)

INSERT INTO Tabela1 VALUES (0, 7, 9)

INSERT INTO Tabela1 VALUES (3, 4, 2)

 

INSERT INTO Tabela2 VALUES (2, 2, 2)

INSERT INTO Tabela2 VALUES (3, 9, 5)

INSERT INTO Tabela2 VALUES (1, 6, 8)

 

INSERT INTO Tabela3 VALUES (4, 0, 7)

INSERT INTO Tabela3 VALUES (6, 5, 1)

INSERT INTO Tabela3 VALUES (4, 7, 9)

Parte 3 – Relaciona-se a declaração de variáveis, utilizadas como parâmetros de entrada de valores como forma de inteligência para o Mecanismo de Pesquisa de dados. Mas não é somente isso que esta parte do código faz, existe um ponto importante relacionado à variável @ValordePesquisa, esta variável é o elemento definido na estrutura do código responsável em receber o valor que será pesquisado.

— Parte 3: Declarando as variáveis —

DECLARE @Comando VARCHAR(1000),

                @ComandoTransact VARCHAR(100),

                @ValordePesquisa INT,

                @TABLE_NAME VARCHAR(20),

                @Coluna_NAME VARCHAR(20)

 

Set @Comando = ”

Set @TABLE_NAME = ”

Set @Coluna_NAME = ”

 

Set @ComandoTransact = ‘SELECT ”?”, ”^”, COUNT(*) AS TOTAL FROM ? WHERE ^ = @ UNION ALL’ + CHAR(10)

 

Set @ValordePesquisa = 3 — Informe o valor a ser pesquisado dentro do Mecanismo.

Parte 4 –  Começamos a montar a estrutura responsável em pesquisar dos dados, com base, nas tabelas e colunas existentes em nosso ambiente. Fazemos a declaração de uma variável do tipo Cursor. Sendo este cursor, declarado com a opção Fast_forward, habilitando os otimizadores de desempenho existentes no SQL Server, visando otimizar a pesquisa de dados e também o armazenamento dos mesmos nas variáveis vinculadas ao Cursor.

— Parte 4: Declarando o CursordePesquisa para retornar o nome da tabela e nome da Coluna —

DECLARE CursordePesquisa CURSOR FAST_FORWARD

FOR SELECT TABLE_NAME,

COLUMN_NAME

FROM INFORMATION_SCHEMA.COLUMNS

 

— Abrindo o CursordePesquisa —

OPEN CursordePesquisa FETCH NEXT FROM CursordePesquisa

INTO @TABLE_NAME, @Coluna_NAME

Parte 5 – Iniciamos o bloco condicional While, elemento importante no nosso ambiente, responsável em montar a estrutura de execução do Select armazenado na variável @Comando, fazendo um busca do nome das tabelas e suas respectivas colunas através das variáveis @TableName e @ColunaName, vinculadas ao CursordePesquisa, contendo os valores encontrados na execução de cada registro encontrado pelo Cursor.

— Parte 5: Iniciando o bloco condicional While —

WHILE @@FETCH_STATUS = 0

 BEGIN

  SET @Comando = @Comando + REPLACE(REPLACE(REPLACE(@ComandoTransact,’?’,@TABLE_NAME),’^’,@Coluna_NAME),’@’,@ValordePesquisa)

  FETCH NEXT FROM CursordePesquisa

  INTO @TABLE_NAME, @Coluna_NAME

 END

Parte 6 – Pode ser considerada uma das mais importantes para o funcionamento do Mecanismo de pesquisa. Ela tem como finalidade realizar a concatenação e União dos Selects conforme os mesmos vão sendo montados durante a execução do CursordePesquisa e do Bloco Condicional While.

— Parte 6: Realizando a Concatenação e União dos Selects —

SET @Comando = LEFT(@Comando,LEN(@Comando)-LEN(‘UNIONALL’)-2)

Parte 7 – Consiste na parte final do código, responsável em criar a Tabela Temporária #Resultados, utilizada para armazenar o resultado dos dados encontrados pelo CursordePesquisa. Nas parte do código, realizamos a inserção dos dados nesta tabela temporário através do comando Insert tendo como parâmetro para entrada de valores o comando Exec (@comando), fazendo a execução da variável @Comando, contendo em sua estrutura as Partes 4, 5 e 6 do Mecanismo de Pesquisa dos Dados.

— Parte 7: Criando a Tabela Temporária para armazenar os Resultados —

CREATE TABLE #Resultados

 (NomeTabela Varchar(20),

  NomeColuna VARCHAR(20),

  TotaldeRegistros INT)

 

— Inserindo os dados na tabela Resultados com base na execução do @Comando —

INSERT INTO #Resultados

Exec (@Comando)

 

— Encerrando o Cursor —

CLOSE CursordePesquisa

DEALLOCATE CursordePesquisa

 

— Apresentando os dados —

SELECT * FROM #Resultados

 

— Excluíndo a Tabela Temporária Resultados —

DROP TABLE #Resultados

A final da execução do nosso Mecanismo de Pesquisa de Dados em Objetos, temos o resultado apresentado na Figura 1:

Figura 1 – Resultado da pesquisa de dados, com base no valor informado na variável @ValordePesquisa.

Bom galera, é isso, chegamos ao final de mais dica, acredito que através deste código, muitos questionamentos, dúvidas e até mesmo dificuldades foram respondidas.

Espero que todos tenham gostado.

Nos encontramos em breve.

Até mais.

 

Tempo restante para finalizar execução do Backup no Microsoft SQL Server 2008 e R2.


Pessoal, bom dia.

Quais as novidades?

Estou de volta com mais uma dica para vocês. Hoje vou falar um pouco sobre o tempo de execução de um processo de Backup.

Introdução

Uma das principais atividades de qualquer profissional da área de TI é manter seu ambiente em funcionamento, pois bem, para que isso possa acontecer nada como realizar o bom e velho processo de backup.

Acredito que você leitor já deve ter passado pela necessidade de realizar um backup de seu ambiente, máquina, banco de dados, arquivos, etc.

Existem diversos mitos sobre as técnicas de backup, mas na verdade o problema normalmente não esta relacionado ao processo de backup, muito pelo contrário, o problema na verdade é o processo de Restore(Restauração ou Recuperação dos Dados). Sendo o processo de restauração, atividade crucial para funcionamento e disponibilidade de todo e qualquer tipo de ambiente.

Para Microsoft esta preocupação é a mesma de todos, manter sempre o ambiente seguro, o administrador tranqüilo e o usuário feliz. Pensando nisso, a Microsoft introduziu a partir do SQL Server 2008 alguns atributos que possibilitam consultar e obter informações sobre o tempo de execução de um backup, como também, seu indicador de execução e até mesmo o tempo restante para sua conclusão.

Como obter informações sobre o Backup

O processo de backup normalmente apresenta um conjunto específico de informações que nos ajudam a identificar o quanto esta atividade demanda de processamento de hardware, como também, a sua importância.

Para que possamos obter estas informações durante o seu tempo de execução, foi introduzido a partir do Microsoft SQL Server 2008, a DMV(Dynamic Management View / Visão de Gerenciamento Dinâmico) chamada: sys.dm_exec_requests.

É com base nesta nova DMV, que temos a possibilidade de encontrar as informações todas as transações em execução em nosso Servidor ou Instância SQL Server. Esta DMV possui um conjunto específico de dados utilizados em tempo real e de forma dinâmica, o que possibilitam a sua obtenção de informação no tempo de execução da transação.

A seguir apresento algumas das colunas existentes na sys.dm_exec_requests, utilizadas para retorno de dados sobre o Backup:

  • Command: Apresenta o time do comando transacional em execução;
  • Estimated_Completion_Time: Apresenta uma estimativa de tempo para conclusão da transação;
  • Start_Time: Apresenta a data e hora de inicialização da transação; e
  • Percent_Complete: Apresenta a porcentagem de execução concluída para esta transação.

Através da combinação de uso destas quatro colunas, foi possível desenvolver o código de permite identificar e apresentar as informações sobre o tempo de execução e conclusão do Backup.

A seguir apresento o Código 1, utilizado como método de transação para obtenção de dados sobre a execução de um backup:

— Exemplo: Código 1 – Obtendo informações sobre o Backup —

SELECT command,

               ‘EstimatedEndTime’ = Dateadd(ms,estimated_completion_time,Getdate()),

               ‘EstimatedSecondsToEnd’ = estimated_completion_time / 1000,

               ‘EstimatedMinutesToEnd’ = estimated_completion_time / 1000 / 60,

               ‘BackupStartTime’ = start_time,

               ‘TimeExecution’=  DateDiff(minute,Getdate(),Start_time),

               ‘PercentComplete’ = percent_complete

FROM sys.dm_exec_requests

 WHERE session_id = @@SPID

De posse deste código, agora fica mais fácil conseguir encontrar as informações sobre o tempo de execução, estimativas de encerramento e porcentagem já concluída do nosso backup.

 Espero que todos tenham gostado nos encontramos em breve.

 Até mais.

Resposta – Script Challenge 11


Pessoal, bom dia.

Como vocês estão? Alguma novidade?

Pois bem, como promessa é dívida, estou de volta com a resposta para mais um Script Challenger, agora na versão 2012, mais agressivo e desafiador.

Para aqueles que não participaram deste novo desafio, o código utilizado no Script Challenger 11, esta apresentado abaixo:

– Script Challenger 11 – Código 1 –

SELECT  OBJECT_NAME(s.[object_id]) AS [Table Name] ,

        i.name AS [Index Name] ,

        i.index_id ,

        user_updates AS [Total Writes] ,

        user_seeks + user_scans + user_lookups AS [Total Reads] ,

        user_updates – ( user_seeks + user_scans + user_lookups ) AS [Difference]

FROM  sys.dm_db_index_usage_stats AS s WITH ( NOLOCK ) INNER JOIN sys.indexes AS i WITH ( NOLOCK )

                                                                                                     ON s.[object_id] = i.[object_id]

                                                                                                     AND i.index_id = s.index_id

WHERE   OBJECTPROPERTY(s.[object_id], ‘IsUserTable’) = 1

AND s.database_id = DB_ID()

AND user_updates > ( user_seeks + user_scans + user_lookups )

AND i.index_id > 1

ORDER BY [Difference] DESC, [Total Writes] DESC, [Total Reads] ASC ;

Durante o período de tempo em que este desafio estava em aberto, recebi algumas observações e melhorias para o código, o que gostaria de agradecer a todos os participantes por estas sugestões.

Agora vou matar a curiosidade de todos e apresentar a resposta. Ao executar este código, o SQL Server ira realizar uma análise fazendo acesso entre a System View: sys.Indexes e a DMF sys.dm_db_index_usage_stats, a fim de identificar quais são os índices Não-Clusterizados que estão apresentando um Número de Escrita maior que o Número de Leituras, o que indica uma utilização incorreta do mesmo.

O grande segredo deste código encontra-se nestas linhas:

user_updates AS [Total Writes] ,

user_seeks + user_scans + user_lookups AS [Total Reads],

user_updates – ( user_seeks + user_scans + user_lookups ) AS [Difference]

Onde:

A coluna [Total Writes]: tem a finalidade de retornar a quantidade de escritas realizadas para cada índice identificado neste código;

A coluna [Total Reads]: tem a finalidade de retornar a quantidade de leituras realizadas para cada índice identificado neste código, com base, na soma das colunas: User_seeks + User_scans + User_lookups; e

A coluna [Difference]: tem a finalidade de apresenta a diferença entre o Total de Escritas e Totais de Leituras, com base, na subtração entre as colunas: user_updates – ( user_seeks + user_scans + user_lookups )

Esta diferença entre o Total de Escrita – o Total de Leituras, nos indica que este índice esta sendo nos Processos de Manipulação de Dados: Insert, Update e Delete, por outro lado, nos Processos de Pesquisa e Consulta: Select ele não esta envolvido em alguns casos o que pode representar que este índice é desnecessário ou esta sendo mal utilizado.

Qual é a importância deste código?

Basicamente demonstrar para o Desenvolvedor que nem sempre um índice é a melhor solução para aceleração e organizar uma pesquisa de dados, pois se o mesmo não esta sendo utilizado ele não representa um recurso que traga vantagens para o ambiente, muito pelo contrário, o mesmo pode estar somente ocupando espaço, ocasionando fragmentação e também com informações estatísticas desatualizadas por falta de uso.

Então pessoal é isso, vou encerrando aqui mais este desafio. Espero que todos possam ter gostado e que este código posso ser útil.

Agradeço mais uma vez a sua visita e participação.

Até mais.

Resposta – Script Challenge – Número 9


Salve pessoal…

Estou de volta, agora com a resposta para o Script Challenger – Número 9, postado a algumas a semanas. Bom, para aqueles que não se lembram do código postado, segue abaixo novamente o script utilizado neste desafio.

– Script Challenge – Número 9 –

Create Trigger T_Calcular_Horas
On CTProducao_Moinho
For Insert, Update
As
Declare @TotalDias VarChar(4),
@TotalHoras VarChar(3),
@TotalMinutos VarChar(4),
@NUMMO CHAR(7),
@ValorFormatado Char(5)

Set @NUMMO=(Select NUMMO from Inserted)

Set @TotalDias=(Select DateDiff(Day,DataInicio,DataFinal) from CTProducao_Moinho Where NUMMO=@NUMMO)
Set @TotalHoras=(Select DateDiff(Hour,Convert(Char(20),DataInicio,103)+HoraInicio,Convert(Char(20),DataFinal,103)+HoraFinal) from CTProducao_Moinho Where NUMMO=@NUMMO)
Set @TotalMinutos=(Select DateDiff(Minute,Convert(Char(20),DataInicio,103)+HoraInicio,Convert(Char(20),DataFinal,103)+HoraFinal) from CTProducao_Moinho Where NUMMO=@NUMMO)

If @TotalDias >=2
Begin
Update CTProducao_Moinho
Set TotalHoras=@TotalHoras+’:00′
Where NUMMO=@NUMMO
End
Else
Begin
If (@TotalHoras >=1) And (@TotalHoras <=24)
Begin
If (@TotalHoras = 1) And (@TotalMinutos < 60)
Set @ValorFormatado=’00:’+@TotalMinutos

If (Len(@TotalHoras) = 1) And (@TotalMinutos > 60)
Begin
Set @ValorFormatado=Convert(Char(4),Convert(Int,@TotalMinutos)/Convert(Int,@TotalHoras))
Set @ValorFormatado=’0′+@TotalHoras+’:’+@ValorFormatado
End

If (Len(@TotalHoras) = 1)
Set @ValorFormatado=’0′+@TotalHoras+’:00′

If (Len(@TotalHoras) = 1) And (@TotalMinutos = 60)
Set @ValorFormatado=’0′+@TotalHoras+’:00′

Update CTProducao_Moinho
Set TotalHoras=@ValorFormatado
Where NUMMO=@NUMMO
End
Else
Begin
If @TotalMinutos=60
Begin
Update CTProducao_Moinho
Set TotalHoras=’01:00′
Where NUMMO=@NUMMO
End
Else
Begin
If Len(@TotalMinutos) = 1
Set @ValorFormatado=’00:0′+@TotalMinutos
Else
Set @ValorFormatado=’00:’+@TotalMinutos

Update CTProducao_Moinho
Set TotalHoras = @ValorFormatado
Where NUMMO=@NUMMO
End
End
End

Pois bem, você conseguiu encontrar a respostas para este Código? Diversos participantes me enviaram por e-mail suas respostas, alias foram diversas, eu fiquei surpreso, pois este desafio apresentou o maior número de respostas obtidas até agora. Foram aproxidamente 100 respostas, com observações, dicas, críticas e comentários sobre o código.

Para aqueles que não participaram, a resposta deste Script Challenger – Número 9 é muito simples.

Como vocês podem observar, trata-se de um Trigger chamado T_Calcular_Horas vínculado a tabel CTProducao_Moinho, disparado na ocorrências de Inserts e Updates.

A função básica deste trigger e análisar através de algumas condições uma possível diferenção entre horas, minutos e segundos para formatar o valor de preenchimento do campo TotalHoras, utilizado em um ERP para controle de qualidade na área de produção de uma indústria que trabalhei a algum tempo.

De acordo com o valores de diferença, realizo a concatenação dos valores e posteriormente, a trigger executa um Update sobre a Table CTProducao_Moinho diretamente no campo TotalHoras.

Vale ressaltar que este script respeita algumas regras de negócios da empresa e também do ERP por isso, foi necessário realizar estas análises, conversões e concatenações de valores.

Muito bem galera, esta aqui a resposta, espero que todos possam ter entendido e gostado.

Nos encontramos nos próximos Script Challenger.

Até mais.