Tengo un trabajo en SQL 2008 que ejecuta un proceso almacenado para hacer una copia de seguridad de todas las bases de datos. Esto se ejecuta diariamente a través del trabajo del agente del servidor sql.
Se cierra con éxito todos los días, pero algunos días se cierra con éxito solo después de hacer una copia de seguridad de algunas bases de datos. Puede ser un número diferente de bases de datos cada vez. La mayoría de los días realiza una copia de seguridad de todas las bases de datos, pero a veces 2 copias de seguridad con éxito, a veces 5, etc.
No veo ningún error en el historial de trabajos, el visor de eventos o el registro del servidor sql.
Las copias de seguridad se realizan en un disco local, aunque la carpeta es una "unión" a una carpeta en un volumen de almacenamiento expandible.
El sistema operativo es Windows 2003 de 64 bits que ejecuta Sql Server 2008 web edition de 64 bits como una máquina virtual que se ejecuta en el host Vmware ESXi 5.
Procedimiento almacenado:
ALTER PROCEDURE [dbo].[backup_all_databases]
@path VARCHAR(255)='c:\backups\'
AS
DECLARE @name VARCHAR(50) -- database name
DECLARE @fileName VARCHAR(256) -- filename for backup
DECLARE @fileDate VARCHAR(20) -- used for file name
DECLARE @dbIsReadOnly sql_variant -- is database read_only?
DECLARE @dbIsOffline sql_variant -- is database offline?
DECLARE db_cursor CURSOR FOR
SELECT name
FROM master.dbo.sysdatabases
WHERE name NOT IN ('tempdb')
AND version > 0 AND version IS NOT NULL
OPEN db_cursor
FETCH NEXT FROM db_cursor INTO @name
WHILE @@FETCH_STATUS = 0
BEGIN
SET @fileName = @path + @name + '.bak'
SET @dbIsReadOnly = (SELECT DATABASEPROPERTY(@name, 'IsReadOnly')) -- 1 = Read Only
SET @dbIsOffline = (SELECT DATABASEPROPERTY(@name, 'IsOffline')) -- 1 = Offline
IF (@dbIsReadOnly = 0 OR @dbIsReadOnly IS NULL) AND @dbIsOffline =0
BEGIN
BACKUP DATABASE @name TO DISK = @fileName WITH INIT
WAITFOR DELAY '00:00:20'
END
FETCH NEXT FROM db_cursor INTO @name
END
CLOSE db_cursor
DEALLOCATE db_cursor
¿Alguna sugerencia por favor?
fuente
Compruebe si hay errores después del comando "copia de seguridad", envíe su propio correo electrónico para detectar cualquier error detectado.
Esto le dará un punto de partida para ver lo que está sucediendo y garantizará alertarlo de cualquier problema hasta que resuelva el problema del trabajo.
fuente
Poner una orden en el cursor. He visto que los cursores de sys.databases tienen "problemas" cuando permite que SQL seleccione el orden en que se devuelven los datos. Ordenar por nombre debería ser suficiente.
fuente
¿La copia de seguridad se ejecuta al mismo tiempo que la copia de seguridad en cinta o algún otro proceso de copia o acceso a los archivos de copia de seguridad? Si es así, apuesto a que no se puede sobrescribir el archivo porque está en uso. Si tiene espacio para varias copias de seguridad, puede cambiar su proceso para agregar una marca de fecha al archivo de salida, pero luego necesitará una rutina de limpieza.
fuente
Con la introducción de SQL Server 2005, el cursor en bucle a través de sysdatabases e incluso sys.databases pareció cambiar, por lo que no fue confiable, y este cambio en el comportamiento también se pudo ver con sp_foreachdb.
Descubrí que cambiar el tipo de cursor ayudó (creo que fue un avance rápido), pero finalmente cambié a soluciones como la solución de respaldo y mantenimiento de Ola Hallengren. Como la mayoría de las cosas que son críticas, como las copias de seguridad, aún necesita verificar todas las bases de datos para asegurarse de que estén respaldadas incluso con estas posibles soluciones, ¡y obviamente lo hizo, muy bien!
Tipos de cursor: http://msdn.microsoft.com/en-us/library/ms378405(v=SQL.90).aspx
Solución de mantenimiento de Ola: http://ola.hallengren.com/
fuente
Tuve el mismo problema, especialmente al hacer una copia de seguridad de grandes bases de datos.
@@fetch_status
es una variable GLOBAL, por lo que podría modificarse (establecerse en 0) por otro cursor que no sea el suyo. Lo resolví haciendo lo siguiente (en pseudocódigo):fuente
He intentado resolver este problema y parece que muchas veces los usuarios publicaron la solución de que si hace que la declaración del cursor sea insensible, entonces comienza a funcionar. Así que lo probé y sí, solo se asegura de que la declaración del cursor sea estática y comience a funcionar.
El hecho por el que falla es: compruebe la configuración del umbral del cursor a nivel del servidor; si está configurado como -1, significa que todos los cursores se llenan sincrónicamente en otras palabras mientras intenta leer los datos del conjunto de teclas del cursor que están sincronizados y todo se intenta leer al mismo tiempo Si cambiamos este valor a 0 que le dice al servidor SQL que haga una población asincrónica en palabras simples, el cursor puede recuperar los registros mientras el conjunto de claves aún estará poblado y verá que después de hacer este cambio a nivel del servidor, nunca perderá ninguna base de datos usando cursores
Soluciones: declare el cursor estático o cambie la configuración de nivel del servidor "Umbral del cursor" a 0 desde -1.
Gracias Gaurav Mishra | Senior DBA
fuente