terça-feira, 8 de fevereiro de 2011

Erros Com Tabelas: spidxx Attempt to fetch logical page (1:2032) in database 5 failed. It belongs to allocation unit xxxxx.... not to xxxxx....

Primeiro conselho que dou é checar o banco de dados na qual as tabelas estão com um DBCC CHECKDB.
Os erros apresentados no output do DBCC são semelhantes aos demonstrados abaixo;


Msg 2533, Level 16, State 1, Line 1
Table error: page (1:540) allocated to object ID 325576198, index ID 1, partition ID 72057625823870976, alloc unit ID 72057625827803136 (type In-row data) was not seen. The page may be invalid or may have an incorrect alloc unit ID in its header.

Msg 8976, Level 16, State 1, Line 1
Table error: Object ID 325576198, index ID 1, partition ID 72057625823870976, alloc unit ID 72057625827803136 (type In-row data). Page (1:540) was not seen in the scan although its parent (1:546) and previous (1:399) refer to it. Check any previous errors.

Tendo os Object ID em mão fica fácil determinar onde os problemas estão, basta rodar a query abaixo;


SELECT * FROM sys.objects
WHERE object_ID in ('325576198')  -- Utilizo o IN aqui, pois podemos ter vários objetos com problemas

Agora que temos os objetos / tabelas com problemas, vamos dar o  Fix neste problema.

- Deixe o DB em Single_User
- Rode o Comando DBCC CHECKDB(nome_db, repair_allow_data_loss)
- Volte o DB para Multi_User

Isso irá resolver o seu problema de Fetch Logical Pages e também erros de consistência do DB.


Abraços.

sábado, 6 de novembro de 2010

Obtendo informações dos SPIDs no pool

Resolvi postar aqui uma série de scripts para trabalhar com SPIDs logados no SQL Server:

-----------------------------------------------
-- Ver situação do seu SPID atual
SELECT * FROM master.dbo.sysprocesses
WHERE spid = (SELECT CAST(@@spid AS CHAR(10)))
-----------------------------------------------

-----------------------------------------------
-- Ver situação de certo SPID
DECLARE @spid AS INT
SET @spid = 1 -- Mudar este valor

SELECT * FROM master.dbo.sysprocesses
WHERE spid = @spid
-----------------------------------------------

-----------------------------------------------
-- Ver qual o Login Name do seu SPID
SELECT spid, loginame FROM master.dbo.sysprocesses
WHERE spid = (SELECT CAST(@@spid AS CHAR(10)))
-----------------------------------------------

-----------------------------------------------
-- Ver qual o Login Name de certo SPID
DECLARE @spid AS INT
SET @spid = 1

SELECT spid, loginame FROM master.dbo.sysprocesses
WHERE spid = @spid
-----------------------------------------------

Abraço.

Error Handling no SQL Server

Trabalhar com programação em T-SQL ficou ainda melhor com Error Handling, podemos dar direções diferentes dependendo do que está acontencendo em nosso código; podemos trabalhar com testes de ambiente etc com essa "nova maravilha" do SQL Server;

Abaixo está um script completo com minhas anotações sobre Error Handling:



-- Cria uma tabela para teste
CREATE TABLE mytable
( ID INT NOT NULL PRIMARY KEY)

-- Inicia uma transação e não trata o erro
-- repare que somente um registro não será inserido
-- na tabela, pois estamos dando commmit na transação
-- e não tratando erros
BEGIN TRAN
INSERT mytable VALUES (1)
INSERT mytable VALUES (1)
INSERT mytable VALUES (2)
COMMIT TRAN

SELECT * FROM mytable -- Seleciona os registros da tabela
TRUNCATE TABLE mytable -- Deleta todos os dados da tabela

--// -------------------------------

-- Após configurar a função XACT_ABORT para ON
-- o sql passará a fazer rollback de toda a transação dentro
-- do bloco de transação
SET XACT_ABORT ON
GO
BEGIN TRAN
INSERT mytable VALUES (3)
INSERT mytable VALUES (3)
INSERT mytable VALUES (4)
COMMIT TRAN
GO
SET XACT_ABORT OFF
GO

SELECT * FROM mytable -- Seleciona os registros da tabela
TRUNCATE TABLE mytable -- Deleta todos os dados da tabela
--// -------------------------------

-- Com o bloco de tratamento de erros é possível
-- direcionar o fluxo para o rollback da transação em
-- vez de tentar comitar as transações corretas.
-- Isto faz com que todo o conteúdo da transação seja desfeito
BEGIN TRY
BEGIN TRAN
INSERT mytable VALUES(1)
INSERT mytable VALUES(1)
INSERT mytable VALUES(2)
COMMIT TRAN
END TRY
BEGIN CATCH
ROLLBACK TRAN
PRINT 'A Transação Não Foi Comitada no Banco'
END CATCH

SELECT * FROM mytable -- Seleciona os registros da tabela
TRUNCATE TABLE mytable -- Deleta todos os dados da tabela


(basta copiar e colar no SQL Server para ter um código mais legível)

Abraço.

Lista de JOBs que falharam no seu ambiente

O que fazer pra saber quais foram os últimos jobs que tiveram falhas no seu ambiente?
Abaixo postei uma query para simplificar o trabalho de caça aos jobs falhando :)

Como já postei o arquivo em outros sites da internet, vou deixar padrão aqui no meu blog:

--------------------------------------------------------------
/*

Created by - Marcos Rosa

The following select uses the three below tables
from msdb

syscategories: Shows all possible categories
sysjobs: Shows all jobs within the instance
sysjobservers: Shows information for runtime of all jobs

The outcomes information for success or failure of a job is:
0 = Failed
1 = Succeeded
3 = Canceled
5 = Unknown

I used my own aliases to create and label fields feel free to change it at
any time you feel it is reqired.

*/
--------------------------------------------------------------

USE MSDB

SELECT tb.Name, tb.Enabled, tb.Description, tb3.name as Category
, Job_Status =
CASE last_run_outcome
WHEN 0 THEN 'Failed'
WHEN 1 THEN 'Succeeded'
WHEN 3 THEN 'Canceled'
WHEN 5 THEN 'Unknown'
ELSE 'Not for sale'
END , tb2.last_outcome_message as Output_Message
FROM sysjobs as tb, sysjobservers as tb2, syscategories as tb3
WHERE tb.job_id = tb2.job_id and tb.category_id = tb3.category_id
ORDER BY last_run_outcome


Espero que gostem, se tiverem mais informações úteis para a query e estiverem afim de compartilhar, enviem uma nota.

Obrigado e Abraço.

Criando e Trabalhando com CURSOR

Poucos dias atrás trabalhei com cursor; resolvi então postar aqui um script rápido para você basear seus cursores caso necessário:

Se por exemplo eu quero mostrar todos os nomes contendo Marcos e seus endereços
da minha tabela chamada tabela_funcionarios; Lógicamente se eu tiver que fazer isso na vida real eu escreverei a seguinte Query:

SELECT Nome, Endereco
FROM tabela_funcionarios
WHERE Nome = 'Marcos'

Mas para mostrar como podemos criar um cursor, segue o script abaixo:

DECLARE @Nome char(10)
,@Endereco char(20)

DECLARE cursor_regs CURSOR FOR
SELECT * FROM tabela_funcionarios
FOR READ ONLY

OPEN cursor_regs

FETCH cursor_regs INTO @Nome, @Endereco

WHILE @@FETCH_STATUS = 0
BEGIN

IF @Nome = 'Marcos'
PRINT @Nome + ' ' + @Endereco
ELSE
PRINT 'Nome Comum'
FETCH cursor_regs INTO @Nome, @Endereco
END

CLOSE cursor_regs
DEALLOCATE cursor_regs


Pessoal, tomem muito cuidado quando trabalhar com cursor, atens validem se não existem formas diferentes que sejam menos custosas para o servidor. No caso do nosso exemplo a utilização do cursor foi somente para fins de demonstração, pois está totalmente fora de conceito fazer essa simples query com cursor!

Abraços.

segunda-feira, 11 de outubro de 2010

T-SQL Scripts para o Dia Dia

Olá pessoal,

Devo desculpas pelo tempo que fiquei sem dar as caras no blog e dever vários posts, mas é que estou um tanto atarefado e isto impactou diretamento n omeu rendimento quanto ao blog.

Bom hoje passo rápidamente dois scrips para o dia dia do DBA; Uma das nossas funções como DBA é garantir que nosso ambiente esteja 100% seguro quando falamos de backups. Para isto temos um script básico e facilitador que se pensarmos em conjunto com as funcionalidades de tasks do windows ou até mesmo criar um job com o script,



SELECT @@SERVERNAME
PRINT '------------------
'
SELECT substring(d.name,1,50) as dbname,
CASE b.type
WHEN 'D' THEN 'BACKUP FULL'
WHEN 'I' THEN 'BACKUP DIFFERENCIAL'
WHEN 'L' THEN 'LOG'
WHEN 'F' THEN 'FILE OR FILEGROUP'
ELSE 'NO BACKUP'
END as TYPE
,max(b.backup_start_date) as backup_date
FROM master..sysdatabases d LEFT JOIN msdb..backupset b
ON d.name = b.database_name
WHERE d.name not in ('model','tempdb')
-- AND b.backup_start_date is null
GROUP BY d.name, type order by d.name

Na clausula WHERE, na linha comentada, podemos utilizá-la para buscar somente databases sem quaisquer backups ou sem informações de backups.

Quaisquer dúvidas, post sua mensagem que eu responderei assim que puder.

Abraços.

segunda-feira, 21 de dezembro de 2009

LIsta de Imagens para o Post Tuning Índex com DTA

Este post é complemento do último post sobre Tuning Índex com o DTA;
Aqui você encontra a lista das imagens referenciadas no post.


Figura 1. Acessando o Profiler de dentro do SSMS




Figura 2. Configurando a tela do trace




Figura 3. Tela Configurada Para Realização do Trace



Figura 4. Outras Opções de Trace e detalhamento de notificações para cada evento.



Figura 5. T-SQL consultando um valor pelo índex e uma consulta DML incrementando o índex.


Figura 6. Representação do DTA realizando uma otimização de uma TSQL.


Figura 7. Abrindo o DTA (O DTA também pode ser aberto através do SSMS).

Figura 8. Configurando a tela “General” do DTA.

Figura 9. Configurando as opções do tuning.


Figura 10. Utilizando os scripts para melhoria de desempenho das queries.

Pesquisar este blog

Carregando...