Historial de Backups con PowerShell

Hace un tiempo atrás escribí un post acerca del historial de backups y restores de una base de datos, esos scripts estoy seguro que les fueron de mucha utilidad, sin embargo yo sabia tenían algunas limitaciones las cuales requerían que en algunos casos tengamos que hacer cambios al código para que pudiera hacer lo que necesitábamos, pero si no dominábamos las tablas de sistema que están involucradas en el código, estos cambios se tornaban incluso más difíciles. Pues bueno ahora les traigo otra alternativa a esos scripts, este primer post nos guiara en los aspectos mas importantes del cmdlet de Powershell que vamos a utilizar para poder obtener esta misma información y más. Sigue leyendo “Historial de Backups con PowerShell”

Anuncios

Instalando Modulo DBATools

Hola, tal y como lo comente en mi entrada anterior existe un modulo de powershell creado inicialmente por Chrissy LeMaire (b|t), este modulo fue inicialmente concebido como una serie de comandos para hacer una migración entre instancias SQL Server de forma sencilla a través de Powershell, sin embargo con el paso del tiempo y el entusiasmo de la comunidad por querer hacer de este modulo algo mas que una herramienta para migración entre de instancias, una serie de personajes reconocidos en la comunidad de SQL Server se unieron a Chrissy para añadir más funcionalidad a este modulo y de esta manera pueda ser aprovechada por todos los DBAs que día a día luchamos para poder mantener nuestras bases de datos en linea y corriendo. Sigue leyendo “Instalando Modulo DBATools”

Introducción a Powershell para DBAs

Estimados amigos, hace relativamente poco tiempo he podido descubrir que PowerShell brinda un sinfín de posibilidades para automatizar nuestras tareas rutinarias tanto a nivel de base de datos como a nivel de la administración propia de los servidores; sí imagino lo que algunos estan pensando,  al parecer he vivido bajo de una roca y no he podido darme cuenta antes de todas las ventajas que ofrece PowerShell no sólo para los DBAs sino para los administradores de servidores en general.

Sigue leyendo “Introducción a Powershell para DBAs”

Tempdb: Reducir Tamaño

Bienvenidos nuevamente, este post es sobre un tema que seguramente muchos de ustedes han tenido que enfrentar, y es que hay ocaciones en las cuales  uno se encuentra con que el disco del servidor que aloja nuestra “tempdb” se encuentra casi llego y algunos procesos que demandan gran espacio en ella se caen justamente por falta de espacio. Sigue leyendo “Tempdb: Reducir Tamaño”

¿Qué job actualizo mi tabla?

Estimados,

Les voy a contar una anécdota que me sucedió hace algún tiempo y que me sirvió para poder buscar información y aprender más sobre historial de los jobs de base de datos lo cual me fue de mucha ayuda en esa situación. Pues bueno tenía una base de datos que contenía muchas tablas y estas eran llenadas desde diversos jobs los cuales estaban programados en diversos servidores, no se tenía un mapa completo del origen de los datos de cada una de esas tablas; hasta que un desafortunado día un jefe me dice: “… Hey, ¿puedes verificar por qué la tabla X no se ha llenado?” Sigue leyendo “¿Qué job actualizo mi tabla?”

El Datafile que no podia eliminarse

Empezaré diciendo que el eliminar datafiles de una base de datos no es una tarea que sea del todo recomendada ni mucho menos frecuente dentro de las tareas cotidianas de una DBA, pero hay momentos en los que se va a necesitar realizarla y hay que estar preparados para saber qué hacer si esta falla, como me paso a mí.

Primero hay que entender que los datafiles son los archivos físicos de nuestra base de datos. Cuando creamos una base de datos, se crea por defecto sólo uno (basado en lo que tengamos configurado en nuestra base de datos “model”), el cual tiene como extension *.mdf. Sin embargo, nosotros podemos crear más datafiles, conocidos como secundarios y de extensión *.ndf, los cuales podemos distribuirlos entre los diferentes discos de nuestro servidor.

Ahora en mi caso particular yo estaba buscando refrescar uno de mis ambientes de desarrollo con data más reciente de mi base de datos de producción, pero dado que esta es una base de datos de más de 1TB de información y que se tiene una limitación de espacio en el ambiente de desarrollo, antes de refrescar el ambiente, se hace un trabajo de truncado de tablas de log y otras que no son importantes para el funcionamiento de la aplicación en el ambiente de desarrollo. Luego del proceso de truncado se procede a realizar un shrink de los datafiles (lo cual es algo que JAMAS se debe hacer en producción) y la eliminación de los datafiles que sobran y esto venía funcionando bien desde siempre hasta que un día FALLO.

Esta falla evitaba que el datafile se vaciara completamente, por ende, hacía imposible su eliminación, luego de mucho buscar y ver en los primeros resultados de mi búsqueda que uno nunca va a poder hacer un DBCC SHRINK con EMPTYFILE a un archivo primario (recuerdan el archivo *.mdf, ese es el primario), lo cual ya sabía, solo se puede hacer esto en los secundarios, y el archivo que no podía eliminar era efectivamente un secundario. El mensaje de error que aparecía era el siguiente:

Msg 2555, Level 16, State 2, Line 2
Cannot move all contents of file “xxx” to other places to complete the empty

Entonces lo que se me ocurrio fue buscar que objetos eran los que no se habia podido mover del datafile que queria eliminar, para esto use la siguiente consulta, la cual viene de esta pagina:

CREATE TABLE #Object_Search
(File_id          BIGINT,
Page_id          BIGINT,
pg_alloc         BIGINT,
ext_size         BIGINT,
object_id        BIGINT,
index_id         BIGINT,
partition_number BIGINT,
partition_id     BIGINT,
iam_chain_type   VARCHAR(50),
pfs_bytes        VARCHAR(50)
);
GO

INSERT INTO #Object_Search
EXEC ('DBCC EXTENTINFO(''MyDatabase'')');
GO

DECLARE @id AS INT;
SELECT @id = FILE_ID('xxx');
SELECT DISTINCT
[name]
FROM
(
SELECT OBJECT_NAME(object_id) AS name,
*
FROM #Object_Search
WHERE File_id = @id
) x;

Esto me permitio ubicar la tabla “heap” que no se estaba moviendo, lo que hice para resolver el problema fue crearle un indice cluster, y volver a ejecutar el comando DBCC SHRINKFILE con EMPTYFILE y esta vez si funciono y pude eliminar el archivo que me estaba dado problemas.

Espero que este corto articulo les haya sido de utilidad. Hasta la proxima.

 

Cuanto Durará mi Backup o Restore

Bueno esto es algo que creo que todos se han preguntado en algún momento cuando deciden hacer una operación de backup o restore, especialmente cuando la base de datos de tamaño algo considerable, pues déjenme decirles que si se puede identificar el tiempo que va a tomar una de estas operaciones con un simple script.

Sin embargo hay cosas que deben de considerar cuando ejecuten el script que les dejare líneas más abajo:

  1. Nunca tomen el primer estimado como 100% exacto, hay que dejar que la operación (backup / restore) se asiente, al comienzo comenzara a dar algunos números que cambiaran rápidamente si la base de datos es muy grande. Esperen unos 30 segundos o un minuto luego de iniciada la operación para poder tener un estimado más exacto.
  2. El tráfico de red importa, si están haciendo un backup o restore, desde o hacia una unidad de red, es importante considerar el ratio de transferencia de datos entre estos dos puntos, he visto casos en los que un restore tomaba 20 minutos entre el punto “A” y el punto “B”, sin embargo cuando se hacia el restore desde el punto “A” y el punto “C” demoraba más de 12 horas, y es por el ratio de transferencia.
  3. El estimado es exacto en la mayoría de casos, sin embargo hay veces en las que circunstancias ajenas, tales como sobre carga en alguno de los dos servidores, o cambios en la red pueden hacer que este cambie.

En todos los casos es importante que si el restore tomara mucho tiempo hay que monitorearlo constantemente. A continuación el script, espero les sea de mucha utilidad como a mí.

select
session_id,
convert(nvarchar(22),db_name(database_id)) as [database],
case command
when 'BACKUP DATABASE' then 'DB'
when 'RESTORE DATABASE' then 'DB RESTORE'
when 'RESTORE VERIFYON' then 'VERIFYING'
when 'RESTORE HEADERON' then 'VERIFYING HEADER'
else 'LOG' end as [type],
start_time as [started],
dateadd(mi,estimated_completion_time/60000,getdate()) as [finishing],
datediff(mi, start_time, (dateadd(mi,estimated_completion_time/60000,getdate()))) - wait_time/60000 as [mins left],
datediff(mi, start_time, (dateadd(mi,estimated_completion_time/60000,getdate()))) as [total wait mins (est)],
convert(varchar(5),cast((percent_complete) as decimal (4,1))) as [% complete],
getdate() as [current time]
from sys.dm_exec_requests
where command in ('BACKUP DATABASE','BACKUP LOG','RESTORE DATABASE','RESTORE VERIFYON','RESTORE HEADERON')