Creación de una copia de seguridad de instantáneas de Transact-SQL

Se aplica a: SQL Server 2022 (16.x)

En este artículo se explica qué, por qué y cómo usar copias de seguridad de instantánea de Transact-SQL. Las copias de seguridad de instantánea de Transact-SQL son nuevas en SQL Server 2022 (16.x).


Las bases de datos cada vez son más grandes. Tradicionalmente, las copias de seguridad de SQL Server son copias de seguridad de streaming. Una copia de seguridad de streaming depende del tamaño de la base de datos. Las operaciones de copia de seguridad consumen recursos (CPU, memoria, E/S, red) que afectan al rendimiento de la carga de trabajo OLTP simultánea durante la copia de seguridad. Una manera de hacer que el rendimiento de la copia de seguridad sea constante, en lugar de depender del tamaño de los datos, consiste en realizar una copia de seguridad de instantáneas mediante mecanismos proporcionados por el hardware o el servicio de almacenamiento subyacentes.

Dado que la propia copia de seguridad se produce en el nivel de hardware, no es una solución SQL Server pura. SQL Server primero debe preparar los archivos de datos y de registro para la instantánea para que se garantice que los archivos estén en un estado que se pueda restaurar más adelante. Una vez hecho esto, la E/S se inmoviliza en SQL Server y el control se entrega a la aplicación de copia de seguridad para completar la instantánea. Una vez completada correctamente la instantánea, la aplicación debe devolver el control a SQL Server donde se reanuda la E/S. Dado que debemos inmovilizar la E/S durante la operación de instantánea, es esencial que la instantánea se produzca rápidamente, de modo que la carga de trabajo del servidor no se interrumpa durante un período prolongado. En el pasado, los usuarios dependían de soluciones de terceros que se crearon sobre el servicio del objeto de escritura de SQL para completar copias de seguridad de instantáneas. El servicio del objeto de escritura de SQL depende de VSS (Servicio de instantáneas de volumen) de Windows junto con VDI (Interfaz de dispositivo virtual) de SQL Server para realizar la orquestación entre SQL Server y la instantánea de nivel de disco. Los clientes de copia de seguridad basados en el servicio del objeto de escritura de SQL tienden a ser complejos y solo funcionan en Windows. Con las copias de seguridad de instantáneas de T-SQL, el lado SQL Server de la orquestación se puede controlar con una serie de comandos de T-SQL. Esto permite a los usuarios crear sus propias aplicaciones de copia de seguridad pequeñas que se pueden ejecutar en Windows o Linux, o incluso soluciones con scripts si el almacenamiento subyacente admite una interfaz de scripting para iniciar una instantánea.

Este es un script de PowerShell de ejemplo que muestra una solución integral de copia de seguridad y restauración de una base de datos en una máquina virtual IaaS de Azure SQL mediante las funcionalidades de copia de seguridad de instantáneas de T-SQL introducidas en SQL Server 2022 (16.x) (y versiones posteriores).

Flujo de trabajo

La sintaxis de copia de seguridad de instantáneas de T-SQL desacopla el mecanismo de instantánea dependiente del proveedor de las operaciones de suspensión y copia de seguridad. Con esta sintaxis, puede:

  1. Inmovilizar una base de datos con el comando ALTER, lo que proporciona la oportunidad de realizar la instantánea del almacenamiento subyacente. Después, puede reanudar la base de datos y registrar la instantánea con el comando BACKUP.
  2. Realizar instantáneas de varias bases de datos simultáneamente con los nuevos comandos BACKUP GROUP y BACKUP SERVER. Con esta opción, se pueden realizar instantáneas en la granularidad de instantáneas del almacenamiento subyacente y eliminar la necesidad de realizar una instantánea del mismo disco varias veces.
  3. Realizar copias de seguridad COMPLETAS y copias de seguridad COMPLETAS COPY_ONLY. Estas copias de seguridad también se registran en msdb.
  4. Realice una recuperación a un momento dado mediante copias de seguridad de registros realizadas con el enfoque de streaming normal después de la copia de seguridad COMPLETA de la instantánea. También se admiten copias de seguridad diferenciales de streaming si lo desea.

Nota:

Los mapas de bits diferenciales se borran durante la primera fase al suspender la base de datos con el comando ALTER. Si el usuario decide reanudar la base de datos sin realizar una copia de seguridad porque se produjo un error en la instantánea o por cualquier otro motivo, el mapa de bits diferencial no será válido. Por lo tanto, las copias de seguridad diferenciales posteriores tendrán un uso más intensivo de E/S, ya que deben examinar toda la base de datos para realizar la copia de seguridad diferencial. El mapa de bits diferencial volverá a ser válido después de una copia de seguridad de instantánea correcta.

En el diagrama siguiente se muestra el flujo de trabajo de alto nivel de las copias de seguridad de instantáneas de T-SQL:

Diagram that shows process from suspend, to snapshot, to backup.

El paso intermedio de instantánea requiere que inicie la instantánea en el almacenamiento subyacente. En el diagrama siguiente se muestra un ejemplo de cómo un script de copia de seguridad puede funcionar con SQL Server para completar el proceso de copia de seguridad de instantáneas:

Diagram shows example of how the backup script can work with SQL Server to complete the backup process.

Del mismo modo, un script de restauración podría funcionar de la siguiente manera:

Diagram shows how the restore script can work with SQL Server to complete the restore task from a snapshot backup.

Limitaciones

El número máximo de bases de datos de las que puede realizar una copia de seguridad con esta característica es 64. Si hay más de 64 bases de datos en el servidor, verá el siguiente error:

Error message:
Msg 925, Level 19, State 1, Line 4
Maximum number of databases used for each query has been exceeded. The maximum allowed is 64.

Ejemplos

En las secciones siguientes se muestran distintos comandos de T-SQL usados para realizar la copia de seguridad de instantáneas en el disco. Cuando una copia de seguridad de instantáneas se escribe en el disco, solo se escriben en el archivo los metadatos conectados a la copia de seguridad de instantáneas. La salida no contiene ninguno de los contenidos de la base de datos, excepto el encabezado y el contenido del archivo. El archivo de shell creado como parte de la realización de la copia de seguridad de instantáneas debe usarse con el URI de instantánea real para realizar una copia de seguridad completa. La RESTAURACIÓN de una base de datos a partir de este archivo requiere que el usuario copie los archivos de base de datos desde el URI de la instantánea en el punto de montaje antes de emitir el comando RESTORE. Los usuarios pueden ejecutar todos los comandos tradicionales de T-SQL como RESTORE HEADERONLY, RESTORE FILELISTONLY en este archivo de metadatos de copia de seguridad de instantáneas junto con RESTORE DATABASE. La sintaxis admite la escritura de metadatos de copia de seguridad de instantáneas en DISK o URL. Los conjuntos de copia de seguridad de instantáneas también se pueden anexar igual que los conjuntos de copia de seguridad de streaming en un único archivo.

Nota:

Para la copia de seguridad en URL, se prefieren los blobs en bloques, aunque los blobs en páginas se admiten para SQL Server en Windows. Para SQL Server en Linux y contenedores, solo se admiten blobs en bloques.

Suspensión de una base de datos de usuario única para la copia de seguridad de instantáneas y registro de una copia de seguridad de base de datos

ALTER DATABASE testdb1
SET SUSPEND_FOR_SNAPSHOT_BACKUP = ON;

BACKUP DATABASE testdb1
TO DISK = 'd:\temp\db.bkm'
WITH METADATA_ONLY, FORMAT;

Suspensión de varias bases de datos de usuario para la copia de seguridad de instantáneas

Si hay varias bases de datos en el mismo disco subyacente, puede suspender varias bases de datos con el siguiente comando.

ALTER SERVER CONFIGURATION
SET SUSPEND_FOR_SNAPSHOT_BACKUP = ON
(GROUP = (testdb1, testdb2));

BACKUP GROUP testdb1, testdb2
TO DISK = 'd:\temp\db.bkm'
WITH METADATA_ONLY, FORMAT;

Suspender todas las bases de datos de usuario en el servidor para realizar una copia de seguridad de instantáneas

Si es necesario suspender todas las bases de datos de usuario del servidor, use el siguiente comando.

ALTER SERVER CONFIGURATION
SET SUSPEND_FOR_SNAPSHOT_BACKUP = ON;

BACKUP SERVER
TO DISK = 'd:\temp\db.bkm'
WITH METADATA_ONLY, FORMAT;

Nota:

Ninguno de estos comandos admite la suspensión de bases de datos del sistema: master, model ni msdb para la copia de seguridad de instantáneas.

Suspensión de varias bases de datos de usuario con un único comando

Registre la instantánea de todas las bases de datos de usuario en el servidor en un único conjunto de copia de seguridad:

ALTER SERVER CONFIGURATION
SET SUSPEND_FOR_SNAPSHOT_BACKUP = ON
(GROUP = (testdb1, testdb2));

BACKUP GROUP testdb1, testdb2
TO DISK = 'd:\temp\db.bkm'
WITH METADATA_ONLY, FORMAT;

Nota:

De forma predeterminada, la suspensión de los comandos de copia de seguridad de instantáneas borrará el mapa de bits diferencial. Si prefiere realizar una copia de seguridad de solo copia, use la palabra clave COPY_ONLY como se muestra en los siguientes ejemplos.

Realizar copias de seguridad de instantáneas de tipo Copy-Only

Dado que el mapa de bits diferencial se borra antes de inmovilizarse, SUSPEND_FOR_SNAPSHOT_BACKUP proporciona una opción (COPY_ONLY) para no borrar dicho mapa antes de inmovilizarse.

ALTER DATABASE testdb1
SET SUSPEND_FOR_SNAPSHOT_BACKUP = ON
(MODE = COPY_ONLY);

BACKUP DATABASE testdb1
TO DISK = 'd:\temp\db.bkm'
WITH METADATA_ONLY, FORMAT;

ALTER SERVER CONFIGURATION
SET SUSPEND_FOR_SNAPSHOT_BACKUP = ON
(GROUP = (testdb1, testdb2), MODE = COPY_ONLY);

BACKUP GROUP testdb1, testdb2
TO DISK = 'd:\temp\db.bkm'
WITH METADATA_ONLY, FORMAT;

ALTER SERVER CONFIGURATION
SET SUSPEND_FOR_SNAPSHOT_BACKUP = ON
(MODE = COPY_ONLY);

BACKUP SERVER
TO DISK = 'd:\temp\db.bkm'
WITH METADATA_ONLY, FORMAT;

Nota:

No es necesario usar COPY_ONLY en el comando BACKUP, ya que ya se especifica al suspender la base de datos para la copia de seguridad de instantáneas.

Etiquetar el conjunto de copias de seguridad

Puede usar las opciones MEDIANAME y MEDIADESCRIPTION en el comando de copia de seguridad para etiquetar el URI asociado a la instantánea. Este uso permite que el archivo de copia de seguridad lleve la información de instantánea subyacente con los metadatos de la base de datos. También puede usar las opciones NAME y DESCRIPTION para etiquetar el URI con la instantánea individual del conjunto de copias de seguridad.

SQL Server no interpreta la información LABEL de ninguna manera. Pero ayuda al usuario a ver el URI asociado a la copia de seguridad de instantáneas con el comando RESTORE LABELONLY.

Después, podría conectar los discos de instantánea ubicados en el URI a la máquina virtual para restaurar la instantánea. El URI de instantánea almacenado en MEDIANAME y MEDIADESCRIPTION también estará disponible para su visualización posteriormente en la msdb tabla de base de datosmsdb.dbo.backupmediaset.

Salida de la copia de seguridad de instantáneas con RESTORE HEADERONLY

La salida con RESTORE HEADERONLY es similar a lo siguiente si la base de datos, el grupo y el servidor se ejecutan en secuencia y se escriben en el mismo archivo de salida:

RESTORE HEADERONLY
FROM DISK = 'd:\temp\db.bkm'
WITH METADATA_ONLY;

Salida de la copia de seguridad de instantáneas con RESTORE FILELISTONLY

La salida con RESTORE FILELISTONLY muestra el primer conjunto de copia de seguridad de forma predeterminada:

RESTORE FILELISTONLY
FROM DISK = 'd:\temp\db.bkm'
WITH METADATA_ONLY;

Filtrar la salida de RESTORE FILELISTONLY a un conjunto de copia de seguridad

Para seleccionar específicamente un conjunto de copia de seguridad determinado de varios conjuntos de copia de seguridad con RESTORE FILELISTONLY, use la cláusula FILE que ya se admite en RESTORE FILELISTONLY.

RESTORE FILELISTONLY
FROM DISK = 'd:\temp\db.bkm'
WITH METADATA_ONLY, FILE = 3;

Screenshot of SSMS output to backups set from query.

Filtrar la salida de RESTORE FILELISTONLY a una base de datos

Filtre para seleccionar una base de datos única de varias bases de datos dentro del conjunto de copia de seguridad seleccionado con RESTORE FILELISTONLY, use la cláusula FILE con la cláusula DBNAME recién introducida. La cláusula DBNAME solo se puede usar en conjuntos de copia de seguridad de instantáneas.

RESTORE FILELISTONLY
FROM DISK = 'd:\temp\db.bkm'
WITH METADATA_ONLY, FILE = 3, DBNAME = 'testdb3';

Screenshot of results of filtering RESTORE FILELISTONLY output to a database.

Restauración de una base de datos de instantáneas

Restaurar una base de datos a partir de una copia de seguridad de instantáneas es como adjuntar una base de datos. Ejecute el comando restore sin la opción RECOVERY si la base de datos debe adjuntarse sin recuperación. De forma predeterminada, RESTORE selecciona la primera base de datos del conjunto de copia de seguridad de instantáneas. En el ejemplo siguiente se restaura testdb1. Si testdb1 ya existe en el servidor, incluya la cláusula REPLACE. Debe montar los archivos de base de datos antes de ejecutar RESTORE.

RESTORE DATABASE testdb1
FROM DISK = 'd:\temp\db.bkm'
WITH METADATA_ONLY, FILE = 3, REPLACE, --> no DBNAME clause - restore first database in backup set
MOVE 'testdb1' TO 'd:\temp\snap\testdb1.mdf',
MOVE 'testdb1_log' TO 'd:\temp\snap\testdb1_log.ldf';

Restauración de una base de datos de instantáneas que aparece en el medio

Si la base de datos que necesita RESTAURARSE está en el medio, especifique la base de datos que se va a restaurar con la cláusula DBNAME. La sintaxis siguiente restaura la base de datos especificada en la cláusula DBNAME.

RESTORE DATABASE testdb3
FROM DISK = 'd:\temp\db.bkm'
WITH METADATA_ONLY, FILE = 3, DBNAME = 'testdb3', --> restores testdb3 database
MOVE 'testdb3' TO 'd:\temp\snap\testdb3.mdf',
MOVE 'testdb3_log' TO 'd:\temp\snap\testdb3_log.ldf',
NORECOVERY;

Restauración de la base de datos con un nombre distinto

Puede restaurar la base de datos con un nombre diferente. Si la base de datos que necesita RESTAURARSE está en el medio, especifique la base de datos que se va a restaurar con la cláusula DBNAME. La siguiente sintaxis restaura la base de datos especificada con la cláusula DBNAME y cambia su nombre a testdb33.

RESTORE DATABASE testdb33 --> renames the specified database testdb3 to testdb33.
FROM DISK = 'd:\temp\db.bkm'
WITH METADATA_ONLY, FILE = 3, DBNAME = 'testdb3', --> original name specified here
MOVE 'testdb3' TO 'd:\temp\snap\testdb3.mdf',
MOVE 'testdb3_log' TO 'd:\temp\snap\testdb3_log.ldf',
NORECOVERY;

Usar RESTORE BACKUPSETONLY para extraer bases de datos de un conjunto de copia de seguridad que contiene varias bases de datos

Un conjunto de copia de seguridad de instantáneas que contiene varias bases de datos de un grupo o instantánea del servidor se puede dividir con el comando RESTORE BACKUPSETONLY. Esto genera un conjunto de copia de seguridad por base de datos.

Si una instantánea del servidor contiene tres bases de datos en un archivo de copia de seguridad que contiene un único conjunto de copia de seguridad, el siguiente comando genera tres conjuntos de copia de seguridad, uno para cada base de datos. Crea un directorio con <file_name_prefix>_<unique_time_stamp> para los archivos de salida.

RESTORE BACKUPSETONLY
FROM DISK = 'd:\temp\db1.bkm'
WITH METADATA_ONLY;

Usar RESTORE BACKUPSETONLY para extraer una base de datos específica de un conjunto de copia de seguridad que contiene varias bases de datos

RESTORE BACKUPSETONLY admite el parámetro DBNAME si el usuario quiere generar una base de datos de las tres bases de datos del conjunto de copia de seguridad. También admite el parámetro FILE para filtrar varios conjuntos de copia de seguridad en el archivo de copia de seguridad.

RESTORE BACKUPSETONLY
FROM DISK = 'd:\temp\db.bkm'
WITH METADATA_ONLY, FILE = 3, DBNAME = 'testdb2';

Vistas de administración dinámica (DMV) para ver el estado de suspensión y los bloqueos adquiridos

sys.dm_server_suspend_status (db_id, db_name, suspend_session_id, suspend_time_ms, is_diffmap_cleared, is_writeio_frozen)
sys.dm_tran_locks (resource_type, resource_database_id, resource_lock_partition, request_mode, request_type, request_status, request_owner_type, request_session_id)

Enumerar los detalles del conjunto de copias de seguridad para las copias de seguridad de instantáneas de T-SQL

SELECT database_name,
    type,
    backup_size,
    backup_start_date,
    backup_finish_date,
    is_snapshot
FROM msdb.dbo.backupset
WHERE is_snapshot = 1;

Propiedades de nivel de servidor y base de datos para comprobar si una base de datos se suspendió para la copia de seguridad de instantáneas

SELECT SERVERPROPERTY('SuspendedDatabaseCount');
SELECT SERVERPROPERTY('IsServerSuspendedForSnapshotBackup');
SELECT DATABASEPROPERTYEX('db1', 'IsDatabaseSuspendedForSnapshotBackup');

Script de solución de problemas de T-SQL de muestra

El siguiente script de T-SQL de muestra se puede usar para detectar bases de datos suspendidas en el servidor y no anular la suspensión si es necesario.

IF (SERVERPROPERTY('IsServerSuspendedForSnapshotBackup') = 1)
BEGIN
    --full server suspended, requires server level thaw
    PRINT 'Full server is suspended, requires server level thaw'

    ALTER SERVER CONFIGURATION
    SET SUSPEND_FOR_SNAPSHOT_BACKUP = OFF
END
ELSE
BEGIN
    IF (SERVERPROPERTY('SuspendedDatabaseCount') > 0)
    BEGIN
        DECLARE @curdb SYSNAME
        DECLARE @sql NVARCHAR(500)

        DECLARE mycursor CURSOR FAST_FORWARD
        FOR
        SELECT db_name
        FROM sys.dm_server_suspend_status;

        OPEN mycursor

        FETCH NEXT
        FROM mycursor
        INTO @curdb

        WHILE @@FETCH_STATUS = 0
        BEGIN
            PRINT 'unfreezing DB ' + @curdb

            SET @sql = 'ALTER DATABASE ' + @curdb + ' SET SUSPEND_FOR_SNAPSHOT_BACKUP = OFF'

            EXEC sp_executesql @SQL

            FETCH NEXT
            FROM mycursor
            INTO @curdb
        END

        PRINT 'All DB unfrozen'

        CLOSE mycursor;

        DEALLOCATE mycursor;
    END
    ELSE
        -- no suspended database, thus no user action needed.
        PRINT 'No database/server is suspended for snapshot backup'
END

Consulte también