Está en la página 1de 6

thesolidqjournal

database administration

Por Herbert Albert y Gianluca Hotz


Traducido por Enrique Catal

Disfrutando con PowerShell

Restauracin con PowerShell


(Parte 1)
Vea cmo utilizar PowerShell para restaurar copias de seguridad fcilmente mediante una configuracin de planes de mantenimiento SQL Server bastante habitual.
ay varias maneras de implementar y automatizar
backups en SQL Server. Lo ms comn es crear
un script o conjunto de scripts y trabajos de SQL Server para lanzar y testear la estrategia de backups en
nuestras empresas. No nos engaemos, los planes
de mantenimiento de SQL Server todava carecen de
mucha funcionalidad, y nos damos cuenta cuando intentamos realizar algo fuera de las posibilidades de
serie. En la columna de este mes, daremos un vistazo a como utilizar PowerShell para restaurar fcilmente backups creados con cualquiera de las tareas
mas comunes que podemos hacer con los planes de
mantenimiento de SQL Server. Este artculo adems,
servir de base para futuros artculos donde proveeremos soluciones ms genricas para cubrir otras implementaciones.

Planes de mantenimiento de SQL


Server para backups
Con los planes de mantenimiento podemos agendar
fcilmente copias de seguridad completas, diferenciales y del log de transacciones, dndonos la posibilidad de implementar una estrategia robusta con la
que manejar nuestras copias de seguridad.
Como sabemos, podemos crear dispositivos de
copia de seguridad donde escribir los backups, donde
se vayan aadiendo o sobreescribiendo o que sirvan
como base a conjuntos de copia de seguridad. Tambien podemos por el contrario, utilizar ficheros nuevos para crear las copias de seguridad (ver imagen
1). En ese caso, el fichero de backup utiliza la siguiente convencin de nomenclatura DatabaseName_YYYY_MM_DD_HHMMSS_XXXXXXX
(donde XXXXXXX es un nmero creado interna-

Imagen 1: Opciones de backup


mente). Por defecto, las extensiones de backup son
.bak para copias de seguridad completas o diferenciales, y .trn para los logs de transacciones, aunque
estos valores son personalizables.
En muchas ocasiones, los planes de mantenimiento se configuran con la opcin de crear nuevos
dispositivos para el conjunto de copias, pero en este
caso nos centraremos en el apartado de restauracin
de copias de seguridad.
Cuando tenemos que restaurar una base de
datos en la misma instancia donde se ha realizado el
backup, y la base de datos msdb no se ha corrompido, la restauracin es realmente fcil. SQL Server
almacena un histrico de copias de seguridad realizados en msdb y dicha informacin es utilizada por SQL
Server Management Studio para enumerar todos los
conjuntos de copia de seguridad necesarios para restaurar la base de datos al punto que queramos (o al
ltimo backup que hiciramos). Este tipo de restauraciones se puede realizar con tan solo unos clicks
de ratn desde el formulario de restauracin de
bases de datos.

The SolidQ Journal, Agosto 2010 www.solidq.com/sqj

En algunas ocasiones, el histrico de copias de


seguridad no est disponible, parcial o totalmente.
Esto puede ocurrir por ejemplo, cuando necesitamos
restaurar una base de datos en una instancia diferente a la que realiz el backup, o cuando ocurre
algun error en la base de datos msdb.
Por cualquier razn, hay casos en los que tenemos
que identificar a mano tanto el conjunto de copias de
seguridad, como la secuencia que deseamos restaurar. Esto puede ser realmente tedioso, especialmente
cuando no tratamos con una nica BBDD, sino con varias, y ms todava cuando no hablamos de un backup
completo, sino una estrategia que involucre copias
completas, diferenciales y/o del log. Hablamos pues,
de escenarios con docenas o cientos de conjuntos de
copia de seguridad que deben restaurarse en una secuencia determinada. Este tipo de ejemplos es el que
sirven para ilustrar entonces lo que podemos llegar a
conseguir con la automatizacin de la restauracin de
copias de seguridad mediante PowerShell.

Identificando las copias de seguridad


a restaurar
Incluso si solo tenemos un directorio con copias de
seguridad, existe informacin que podemos obtener
del propio sistema de ficheros
Los planes de mantenimiento utilizan una convencin de nombres para los nombres de ficheros
que nos permite identificar tanto el nombre de la
base de datos, como la fecha en la que fue creada o
el tipo. Incluso podemos inferir cuando fue escrito
por ltima vez algo en dicho fichero. Adems, las propias extensiones de los ficheros nos dan una pista
tambin sobre el tipo de copia de seguridad.
Por supuesto, para estar seguro de que lo que
hay dentro es lo que dice ser, hemos de leer los metadatos de cada conjunto de copias de seguridad,
pero llegados a este punto, nos interesa crear una
solucin muy simple basada en las propias convenciones de nombres de los planes de mantenimiento.
En futuros artculos, nos centraremos en soluciones
ms robustas.
Imaginemos que estamos simplemente haciendo
una mezcla de copias de seguridad completas y del
log de transacciones, utilizando para ello sus extensiones por defecto (.bak y .trn respectivamente) y

The SolidQ Journal, Agosto 2010 www.solidq.com/sqj

que estamos creando todas las copias de seguridad


bajo la ruta D:\Temp.
Imaginemos ahora que queremos restaurar la base
de datos AdventureWorks al punto mas reciente del
tiempo disponible. Lo primero de todo es encontrar la
copia de seguridad completa ms reciente. Esto puede
llevarse a cabo realizando una bsqueda en el directorio
de copias de seguridad buscando por nombre de base
de datos y extensin, ordenando el resultado de forma
que obtengamos el ms reciente (el ltimo elemento
de la lista ordenada). La sentencia siguiente realiza lo
que necesitamos en tan solo una nica lnea de cdigo:
Get-ChildItem D:\Temp -Filter AdventureWorks*.bak | `
sort Name | Select-Object -Last 1

Ahora podemos usar una tcnica similar para obtener el conjunto de ficheros de copia de seguridad
del registro de transacciones a partir del fichero de
Script 1: Retrieving All Backup Set Files Needed
to Restore a Database

# Parameters
$DB = AdventureWorks;
$Path = D:\Temp;
$FullPattern = *.bak;
$LogPattern = *.trn;
# Enumerate Last Full Back
$FullBackup = Get-ChildItem $Path -Filter ($DB + $FullPattern) `
| sort Name `
| Select-Object -Last 1;
# Enumerate Log Backups
$LogBackups = Get-ChildItem $Path -Filter ($DB + $LogPattern) `
| Where-Object { $_.LastWriteTime -gt `
$Fullbackup.LastWriteTime} `
| sort Name;
Write-Output Full Backup to Restore:;
Write-Output $Fullbackup | Format-Table -AutoSize;
Write-Output Log Backups to Restore:;
Write-Output $LogBackups | Format-Table -AutoSize;

thesolidqjournal
database administration

10

Full Backup to Restore:


Directory: D:\Temp
Mode
LastWriteTime
Length Name
--------------------- -----a- 8/9/2010 2:50 PM 181490176
AdventureWorks_backp_2010_08_09_145042_9791764.bak
Log Backups to Restore:
Directory: D:\Temp
Mode
----a-a-a-

LastWriteTime
------------8/9/2010 2:51 PM
8/9/2010 2:51 PM
8/9/2010 2:52 PM

Length
-----84480
17920
17920

Name
----AdventureWorks_backup_2010_08_09_145152_7061646.trn
AdventureWorks_backup_2010_08_09_145156_1693626.trn
AdventureWorks_backup_2010_08_09_145209_2361100.trn

Figure 2: Results of Running Script 1 to Retrieve Backup Set Files


copia de seguridad completo anterior. La diferencia
es que ahora necesitamos aadir una clusula
Where-Object en la tubera para que se devuelvan
nicamente los ficheros a partir del backup completo
encontrado anteriormente. Esto puede ser realizado
filtrando por la propiedad que indica cuando fue la ltima vez que fue escrito el fichero.
En el script 1, puedes ver un ejemplo que recupera todos los conjuntos de backup que se necesitan
para restaurar una BBDD dada.
Cuyo resultado podemos ver en la Figura 2.

Restaurando copias de seguridad


Ahora que sabemos que conjuntos de copias de seguridad restaurar, necesitamos escribir algo de cdigo que lo haga. En este punto podemos elegir dos
opciones: usar concatenacin de scripts para crear
un bloque T-SQL y utilizarlo mediante ADO.NET o utilizar objetos SMO.
Normalmente los DBA tendemos a sentirnos mas
cmodos con T-SQL porque es mas fcil revisarlo. A
pesar de ello, escribir dicho cdigo con concatenacin
de scripts puede ser tanto un error como muy tedioso.
Los objetos SMO proveen de una amplia biblioteca de
clases para operaciones de backup y restauracin y,
como veremos ms tarde, siempre podemos obtener
el cdigo T-SQL que producen por debajo.
Estas clases son parte de versiones SMO anteriores, pero en SQL Server 2008, todas las clases que per-

DBAs tend to be more


comfortable with T-SQL
batches because its easier
to review them. However,
building such batches with
string concatenation can
be tedious and error-prone.

tenecen a la seccin de backup y restauracin han sido


movidas a una librera denominada SMOExtended.dll.
Por lo tanto, debemos cargar la librera de clases SMOExtended junto a SMO antes de poder obtener permiso para utilizar sus objetos desde PowerShell.
El script 2 muestra un ejemplo de restauracin
de una copia de seguridad completa utilizando PowerShell y SMO.
Como podemos ver en el script, necesitamos un
objeto Server, Restore y BackupDeviceItem como
mnimo para realizar la restauracin.
El objeto Server define una conexin contra la instancia de SQL Server en la que queremos restaurar
la base de datos finalmente. BackupDeviceItem define donde encontrar el conjunto de copia de seguridad a restaurar. Finalmente, el objeto Restore define
las propiedades relacionadas con la propia operacin
de restauracin.

The SolidQ Journal, Agosto 2010 www.solidq.com/sqj

11

Script 2: Performing a Full Database Restore Using PowerShell and SMO


[System.Reflection.Assembly]::LoadWithPartialName(`
Microsoft.SqlServer.SMO) | Out-Null;
[System.Reflection.Assembly]::LoadWithPartialName(`
Microsoft.SqlServer.SMOExtended) | Out-Null;
# Parameters
$InstanceName = .;
$BackupsetFile = D:\Temp\AdventureWorks_backup_2010_08_09_145042_9791764.bak;
$DatabaseName = AdventureWorks;
$Server = New-Object Microsoft.SqlServer.Management.Smo.Server $InstanceName;
$Restore = New-Object Microsoft.SqlServer.Management.Smo.Restore;
$Device = New-Object Microsoft.SqlServer.Management.Smo.BackupDeviceItem;
$Restore.Action = Database;
$Restore.Database = $DatabaseName;
$Restore.ReplaceDatabase = $true;
$Device.DeviceType = File;
$Device.Name = $BackupsetFile;
$Restore.Devices.Add($Device);
#$Restore.Script($Server);
$Restore.SqlRestore($Server);

#uncomment to script out action

En este ejemplo, para la operacin de restauracin, estamos proveiendo nicamente el nombre de


base de datos, el tipo de restauracin (base de datos
en este caso) y la propia base de datos que ser reemplazada. Esta ltima propiedad, que simplemente
vale True ser convertida ms tarde en la opcin REPLACE del comando T-SQL RESTORE DATABASE.
El resto de opciones para RESTORE DATABASE se
pueden aadir de la misma manera.
Una vez inicializados los objetos, simplemente
debemos invocar el mtodo SqlRestore del objeto
Restore para iniciar la restauracin.
Puedes adems chequear el comando RESTORE
DATABASE utilizando SQL Server Profiler, para de
esta forma ver lo que est lanzando realmente.
Adicionalmente, si lo que quieres es chequear el
cdigo T-SQL que se lanzar, sin lanzarlo finalmente,
puedes invocar al mtodo Script del objeto Restore
antes de invocar a SqlRestore. Esta funcionalidad es
bastante interesante y est disponible para muchsi-

The SolidQ Journal, Agosto 2010 www.solidq.com/sqj

mos objetos. Si eres entusiasta de SQL Server Management Studio, es muy similar a las opciones de
scripting que dicha herramienta posee.
Si no te sientes cmodo lanzando comandos de restauracin mediante SMO, recuerda que sigues siendo
libre de generar cdigo T-SQL mediante concatenacin,
o que incluso puedes generar el cdigo a un fichero para
revisarlo independientemente de su ejecucin.
Ahora que sabemos como lanzar un comando de
restauracin mediante SMO, simplemente aplicaremos nuestros conocimientos al ejemplo que hemos
empezado anteriormente. Primero lo que haremos
ser restaurar el backup completo y luego mediante
un bucle foreach , iremos restaurando los logs de
transacciones.
Es importante recordar que la base de datos debe
permanecer en modo in recovery hasta llegar al ltimo backup. Por comodidad lo restauraremos todo
en modo NORECOVERY y aplicaremos un ltimo comando para pasar la BBDD a modo RECOVERY.

thesolidqjournal
database administration

12

Script 3: Complete Script to Restore All Backups and Recover the Database

[System.Reflection.Assembly]::LoadWithPartialName(`
Microsoft.SqlServer.SMO) | Out-Null;
[System.Reflection.Assembly]::LoadWithPartialName(`
Microsoft.SqlServer.SMOExtended) | Out-Null;
# Parameters
$InstanceName = .
$DatabaseName = AdventureWorks;
$BackupPath = D:\Temp;
$FullBackupPattern = *.bak;
$LogBackupPattern = *.trn;
# Enumerate Last Full Back
$FullBackup = Get-ChildItem $BackupPath `
-Filter ($DatabaseName + $FullBackupPattern) `
| sort Name `
| Select-Object -Last 1;
# Enumerate Log Backups
$LogBackups = Get-ChildItem $BackupPath `
-Filter ($DatabaseName + $LogBackupPattern) `
| Where-Object { $_.LastWriteTime -gt $FullBackup.LastWriteTime} `
| sort Name ;
# Define Connection
$Server = New-Object Microsoft.SqlServer.Management.Smo.Server $InstanceName;
#Restore the Full Backup Set
$Restore = New-Object Microsoft.SqlServer.Management.Smo.Restore;
$Device = New-Object Microsoft.SqlServer.Management.Smo.BackupDeviceItem;
$Restore.Action = Database;
$Restore.Database = $DatabaseName;
$Restore.ReplaceDatabase = $true;
$Restore.NoRecovery = $true;
$Device.DeviceType = File;
$Device.Name = $BackupPath + \ + $FullBackup.Name;
$Restore.Devices.Add($Device);
$Restore.SqlRestore($Server);
Write-Output (Full backup restored: + $FullBackup.Name)
#Restore Log Backups
foreach ($BackupsetFile IN $LogBackups)
{
$Restore = New-Object Microsoft.SqlServer.Management.Smo.Restore;
$Device = New-Object Microsoft.SqlServer.Management.Smo.BackupDeviceItem;
$Restore.Action = Log;
$Restore.Database = $DatabaseName;
$Restore.NoRecovery = $true;

The SolidQ Journal, Agosto 2010 www.solidq.com/sqj

13

$Device.DeviceType = File;
$Device.Name = $BackupPath + \ + $BackupsetFile.Name;
$Restore.Devices.Add($Device);
$Restore.SqlRestore($Server);
Write-Output (Transaction log backup restored: + $BackupsetFile.Name);
};
# Recover the database
$Restore=New-Object Microsoft.SqlServer.Management.Smo.Restore;
$Restore.Action = Log;
$Restore.Database = $DatabaseName;
$Restore.NoRecovery = $false;
$Restore.SqlRestore($Server);
Write-Output Recovery Complete;

Para ello hay que saber que la propiedad NoRecovery del objeto Restore se da en negativo, por lo que
debe de ponerse inversamente a lo que deseamos
conseguir.
El script 3, muestra el script completo que restaurar tanto los backups completos como diferenciales y que finalmente restaurar la base de
datos. Con este script, todo lo que necesitamos
hacer es definir nicamente las variables y lanzarlo
sin ms.

Conclusin
En este nmero hemos visto lo simple que es escribir cdigo PowerShell para realizar tareas administrativas comunes. Por supuesto el cdigo est muy
lejos de ser robusto y flexible, puesto que asume un
montn de cosas como que el patrn de nombres y
las propiedades de los ficheros son suficiente indicativo de su contenido, y que no existe un sistema de
manejo de errores ni la posibilidad de encontrarnos
con copias de seguridad diferenciales.
A pesar de ello, el punto clave de este artculo ha
sido por un lado introducir algunos objetos SMO y por
otro ensear que se puede explotar informacin
desde el propio sistema de ficheros, sin necesidad de
recurrir a ver los metadatos de las copias de seguridad. En los prximos nmeros iremos entrando gradualmente en mayor robustez y aadiendo ms

The SolidQ Journal, Agosto 2010 www.solidq.com/sqj

funcionalidad a la solucin, como la capacidad de renombrar bases de datos o ficheros de las mismas.

Sobre los Autores


Herbert Albert Es Mentor y Administrador
General de Solid Quality Mentors Europa
Central. Es MCSE, MCDBA, y MCT en SQL
Server, Herbert es un entrenador formador
y consultor de SQL Server cuyo conocimiento cubre un amplio espectro de tecnologas
de Microsoft. Trabaja de forma muy cercana con Microsoft
Austria en varios eventos de entrenamientoformacin. Sigue
a Herbert en twitter: @AlbertHerbert
Gianluca Hotz, Es Mentor con Solid
Quality Mentors, especializado en arquitectura, Alta disponibilidad, mejora de
rendimiento, y diseo de bases de datos
SQL Server. Como entrenador formador y
autor, Gianluca ha administrado impartido cursos de SQL server Server para
elun enorme CTEC italiano. Tambin apoya a Microsoft Italia
en el campo como speaker en conferencias locales. Gianluca fund el Grupo de Usuarios de SQL Server, actualmente
funge como Vicepresidente, y asiste a otros usuarios en grupos de noticias. Ha sido MVP de Microsoft SQL Server desde 1998. Sigue a Gianluca en twitter: @glhotz