Archive

Archive for June, 2012

Restore Parcial no SQL Server

Galera, boa tarde.

Como de costume, sempre dedico meu post as pessoas próximas a mim, pois, são elas que nos moldam e nos incentivam a sempre dar um passo a frente. Este post é dedicado ao líder que tive, um verdadeiro líder, Eduardo G. Pinho.

Muito tempo que não posto nada, mesmo tendo os posts no meu note não estou arrumando tendo de publicar, espero que todo mundo entenda. Hoje gostaria de dar uma pequena pausa na seção de índices e falar sobre um assunto que não vejo muito na net. Restore de banco de dados por file groups. Vamos lá!?

O leitor deve esta se perguntando quando devo realmente usar esse cenário? Uma coisa interessante que percebi nas empresas onde passei é que os DBAs anteriores não seguiam realmente as boas práticas à risca. Esse cenário, seria mais adequado para ambientes que existam tabelas realmente gigantescas e que não podem sofrer expurgo. Quando o banco de dados é criado do zero a tarefa torna-se mais simples. É possível dimensionar todos os filegroups com a sua real necessidade. Uma vez que o desenho do banco não seguiu as boas práticas, fica realmente difícil ajustá-lo depois que o mesmo está sendo utilizado em produção.

Imagine o cenário que o sistema foi feito por módulos e as tabelas do módulo de clientes estão em um Filegroup e as tabelas de Produtos em outro filegroup, você pode voltar o módulo de clientes ONLINE enquanto vai fazendo restore parcial dos outros módulos (se os mesmos foram criados em filegroups distintos).

Para este post iremos criar um banco de dados com a seguinte estrutura:

Um arquivo de dados com a extensão .mdf em um filegroup primário , um segundo arquivos de dados com a extensão .ndf no filegroup FG_USER_SECUNDARIO e um arquivo de log.

CREATE DATABASE [VariosGruposDeArquivos]

ON  PRIMARY

(

      NAME = N’VariosGruposDeArquivos_Primary’,

      FILENAME = N’C:\T\VariosGruposDeArquivos_Primary.mdf’ , SIZE = 4096KB , FILEGROWTH = 10%

),  FILEGROUP [FG_USER_SECUNDARIO]

(

      NAME = N’VariosGruposDeArquivos_Secondary’,

      FILENAME = N’C:\T\VariosGruposDeArquivos_Secondary.ndf’ , SIZE = 4096KB , FILEGROWTH = 10%

)

LOG ON

(

      NAME = N’VariosGruposDeArquivos_log’,

      FILENAME = N’C:\T\VariosGruposDeArquivos_log.ldf’ , SIZE = 1024KB , FILEGROWTH = 10%

)

GO

EXEC dbo.sp_dbcmptlevel @dbname=N’VariosGruposDeArquivos’, @new_cmptlevel=90

GO

Obs: Os arquivos estão sendo criados no C: apenas pra propósitos de testes, em um ambiente real esse cenário NUNCA deve ser real.

Após o banco ser criado, colocaremos o seu recovery model como full.

ALTER DATABASE [VariosGruposDeArquivos] SET RECOVERY FULL

Agora criaremos duas tabelas no nosso banco de dados, sendo que a tabela de Cliente será criado no filegroup PRIMARY e a tabela Produto será criada no filegroup FG_USER_SECUNDARIO.

SET ANSI_NULLS ON

GO

SET QUOTED_IDENTIFIER ON

GO

CREATE TABLE [dbo].[Cliente](

      [ClienteID] [int] IDENTITY(1,1) NOT NULL,

      [ClienteCadastro] [datetime] NULL,

 CONSTRAINT [PK_Cliente] PRIMARY KEY CLUSTERED

(

      [ClienteID] ASC

) ON [PRIMARY]

) ON [PRIMARY]

GO

CREATE TABLE [dbo].[Produto](

      [ProdutoID] [int] IDENTITY(1,1) NOT NULL,

      [ProdutoCadastro] [datetime] NULL,

 CONSTRAINT [PK_Produto] PRIMARY KEY CLUSTERED

(

      [ProdutoID] ASC

) ON [FG_USER_SECUNDARIO]

) ON [FG_USER_SECUNDARIO]

GO

Obs: Como boa prática, sempre crie um arquivo secundário e atribua-o a um filegroup de usuário. Coloque o filegroup de usuário como padrão. O filegroup PRIMARY deve apenas ter os metadados do banco de dados em si, e nunca nenhuma informação de usuário. O estado do filegroup PRIMARY define o estado do database.

Agora iremos inserir informação nas duas tabelas.

INSERT INTO dbo.Cliente(ClienteCadastro) VALUES (GETDATE())

INSERT INTO dbo.Produto(ProdutoCadastro) VALUES (GETDATE())

INSERT INTO dbo.Cliente(ClienteCadastro) VALUES (GETDATE())

INSERT INTO dbo.Produto(ProdutoCadastro) VALUES (GETDATE())

Agora realizaremos um backup full do nosso banco de dados.

BACKUP DATABASE [VariosGruposDeArquivos] TO  DISK = N’C:\T\VariosGruposDeArquivos.bak’ WITH NOFORMAT, INIT, 

      NAME = N’VariosGruposDeArquivos-Full Database Backup’, SKIP, NOREWIND, NOUNLOAD,  STATS = 10

GO

Se fizermos um select nas tabelas, veremos que cada uma delas possuem duas linhas.

Agora o que iremos fazer é o seguinte: Vamos “dropar” esse database e aplicar os restores com os arquivos de backups que já criamos anteriormente. Abaixo segue o script:

use master

go

drop database VariosGruposDeArquivos

Imagine o cenário que o banco de dados está corrompido e será necessário realizar o restore do seu banco parcial e liberando os módulos para os usuários conforme o restore vai acontecendo. O script abaixo traz o script de restore do banco de dados. Nesse script o “pulo do gato” está em duas clausulas: FILE e PARTIAL. Na clausula file você pode passa qual o datafile que você que realizar o restore e a clausula partial informa que o restore será feito em “pedaços”.

RESTORE DATABASE [VariosGruposDeArquivos]

FILE = N’VariosGruposDeArquivos_Primary’

FROM  DISK = N’C:\T\VariosGruposDeArquivos.bak’

WITH  FILE = 1,  NOUNLOAD,  REPLACE,  STATS = 10, PARTIAL

GO

Se fizermos um select na tabela de clientes os dados serão retornados, conforme o print:

Ao fazer um select na tabela de produtos que está em um outro datafile, um erro será retornado:

Msg 8653, Level 16, State 1, Line 1

The query processor is unable to produce a plan for the table or view ‘Produto’ because the table resides in a filegroup which is not online.

Vamos deixar o outro filegrouo online, aplicaremos novamente o comando de restore. O arquivo do backup será o mesmo, o que mudará dessa vez é o valor do parâmetro “FILE”. Agora nos iremos informar o nome do segundo datafile.

RESTORE DATABASE [VariosGruposDeArquivos]

FILE = N’VariosGruposDeArquivos_Secondary’

FROM  DISK = N’C:\T\VariosGruposDeArquivos.bak’

WITH  FILE = 1,  NOUNLOAD,  REPLACE,  STATS = 10

GO

Como podemos ver a tabela foi restaurada:

Ate a próxima KIDS

Advertisements