Si los archivos de la base de datos de SQL Server están distribuidos en varios discos, puedes crear copias de seguridad de todos los discos de forma simultánea y mantener la coherencia de los datos y las aplicaciones. Puedes lograr esta copia de seguridad en un momento determinado exacto con los grupos de coherencia de instantáneas inmediatas de Compute Engine, que te permiten crear copias de seguridad de los datos en un grupo de discos.
En este instructivo, se describe cómo crear copias de seguridad de bases de datos de SQL Server con instantáneas de Compute Engine y la función de instantáneas de Transact-SQL (T-SQL) que está disponible en SQL Server 2022 y versiones posteriores. Esta solución admite implementaciones de Windows y Linux, y minimiza el impacto en el rendimiento de tus cargas de trabajo en vivo.
Cómo funciona
El flujo de trabajo consta de estos pasos principales, que se administran con una secuencia de comandos que se ejecuta en una instancia de procesamiento:
- Inmoviliza la base de datos: La secuencia de comandos envía un comando de T-SQL a SQL Server para suspender todas las operaciones de escritura de las bases de datos de destino. Esto garantiza que los archivos de la base de datos se encuentren en un estado coherente para la copia de seguridad.
- Toma instantáneas: Mientras la base de datos está inactiva, crea un grupo de instantáneas de los discos en los que residen los archivos de registro y datos de la base de datos. Este es el equivalente de Google Clouda usar un mecanismo de instantáneas a nivel de hardware o servicio.
- Record and thaw: La secuencia de comandos envía otro comando de T-SQL a SQL Server para registrar los metadatos de la copia de seguridad. Este comando crea un pequeño archivo de copia de seguridad que apunta al grupo de coherencia de instantáneas inmediatas y se registra en el historial de copias de seguridad
msdb. Una vez completado el proceso, SQL Server descongela automáticamente la base de datos y reanuda las operaciones normales.
Por lo general, todo este proceso se completa en menos de un segundo, lo que minimiza la duración de la inmovilización de escritura en tu base de datos. Mientras la inmovilización esté vigente, se podrán leer los datos, pero no escribirlos. Puedes cancelar manualmente el estado de inmovilización configurando SUSPEND_FOR_SNAPSHOT_BACKUP=OFF para la base de datos.
Objetivos
En este instructivo, aprenderás a completar las siguientes tareas:- Crea una instancia de SQL Server con dos discos de datos.
- Crea una base de datos nueva con los archivos de datos y de registro en discos separados.
- Crea un grupo de coherencia de todos los discos de la VM que ejecuta SQL Server.
- Crea instantáneas inmediatas del grupo de discos.
- Crea discos nuevos a partir de las instantáneas.
Costos
En este documento, usarás los siguientes componentes facturables de Google Cloud:
Para generar una estimación de costos en función del uso previsto,
usa la calculadora de precios.
Cuando completes las tareas que se describen en este documento, podrás borrar los recursos que creaste para evitar que se te siga facturando. Para obtener más información, consulta Realiza una limpieza.
Antes de comenzar
Para este instructivo, necesitas un proyecto Google Cloud . Puedes crear uno nuevo o seleccionar un proyecto existente:
-
En la consola de Google Cloud , en la página del selector de proyectos, selecciona o crea un proyecto de Google Cloud .
Roles necesarios para seleccionar o crear un proyecto
- Selecciona un proyecto: Para seleccionar un proyecto, no se requiere un rol de IAM específico. Puedes seleccionar cualquier proyecto en el que se te haya otorgado un rol.
-
Crear un proyecto: Para crear un proyecto, necesitas el rol de Creador de proyectos (
roles/resourcemanager.projectCreator), que contiene el permisoresourcemanager.projects.create. Obtén más información para otorgar roles.
-
Verifica que la facturación esté habilitada para tu proyecto de Google Cloud .
-
En la consola de Google Cloud , activa Cloud Shell.
-
Asegúrate de que Microsoft SQL Server 2022 o una versión posterior esté instalado y en ejecución.
Permisos necesarios
Además del acceso de lectura estándar, asegúrate de que el administrador de SQL Server te otorgue el permiso ALTER DATABASE para la base de datos de destino.
Para obtener los permisos que necesitas para crear instancias y crear instantáneas, pídele a tu administrador que te otorgue los siguientes roles de IAM en el proyecto:
-
Administrar instancia:
compute.instanceAdmin.v1 -
Crea instantáneas:
compute.storageAdmin
Para obtener más información sobre cómo otorgar roles, consulta Administra el acceso a proyectos, carpetas y organizaciones.
También puedes obtener los permisos necesarios a través de roles personalizados o cualquier otro rol predefinido.
Crea una instancia de SQL de Compute Engine
Crea una instancia de SQL Server.
En la Google Cloud consola, haz clic en el botón Activar Cloud Shell
para abrir Cloud Shell.
Crea una instancia de SQL Server. Pega el siguiente comando:
REGION=REGIONZONE=$REGION-a VM_NAME=VM_NAMEgcloud compute instances create $VM_NAME \ --boot-disk-auto-delete \ --boot-disk-size 100 \ --boot-disk-type hyperdisk-balanced \ --image-family sql-std-2022-win-2025 \ --image-project windows-sql-cloud \ --machine-type c4-highmem-4 \ --zone $ZONE \ --network-interface subnet=default \ --tags sql-server-instant-snapshot \ --scopes=cloud-platform,service-control,service-management,monitoring-write,logging-write,storage-rw \ --create-disk=device-name=$VM_NAME-data-disk1,mode=rw,name=$VM_NAME-data-disk1,size=100,type=hyperdisk-balanced \ --create-disk=device-name=$VM_NAME-data-disk2,mode=rw,name=$VM_NAME-data-disk2,size=100,type=hyperdisk-balanced
Reemplaza lo siguiente:
- Región: Es la región en la que se implementará tu instancia nueva.
- VM_NAME: Es el nombre de tu nueva instancia de SQL Server.
Crea un grupo de coherencia de discos
Crea un grupo de coherencia.
gcloud compute resource-policies create disk-consistency-group $VM_NAME-snap-grp \ --region=$REGIONAgrega los discos de la VM al grupo de coherencia.
gcloud compute disks add-resource-policies $VM_NAME \ --zone=$ZONE \ --resource-policies=$VM_NAME-snap-grp gcloud compute disks add-resource-policies $VM_NAME-data-disk1 \ --zone=$ZONE \ --resource-policies=$VM_NAME-snap-grp gcloud compute disks add-resource-policies $VM_NAME-data-disk2 \ --zone=$ZONE \ --resource-policies=$VM_NAME-snap-grp
Crear una base de datos nueva
- Crea un nombre de usuario y una contraseña para la instancia de VM.
- Conéctate a la VM mediante el escritorio remoto y accede con el nombre de usuario y la contraseña que creaste en el paso anterior.
- Haz clic con el botón derecho en el botón Iniciar (o presiona Win+X) y, luego, en Terminal (Admin).
- Para confirmar el símbolo de elevación, haz clic en Sí.
Ejecuta la siguiente secuencia de comandos de PowerShell en la ventana de la terminal que se abrió. Este secuencia de comandos inicializa el disco de datos, lo formatea con un tamaño de bloque de 64 KB y le asigna una letra de unidad.
$availableDisks = Get-PhysicalDisk -CanPool $True $diskLetters = [char[]] (68..72) | Where-Object { !(Get-PSDrive $_ -ErrorAction SilentlyContinue) } $diskCount = 0 foreach ($disk in $availableDisks) { $diskLetter = $diskLetters[$diskCount] $diskLabel = "$diskLetter-DataDisk" Initialize-Disk -Number $disk.DeviceId -PartitionStyle MBR -PassThru New-Partition -DiskNumber $disk.DeviceId -UseMaximumSize ` -DriveLetter $diskLetter | Format-Volume -FileSystem NTFS ` -NewFileSystemLabel $diskLabel -AllocationUnitSize 65536 -Confirm:$false New-Item -ItemType Directory -Path "$($diskLetter):\MSSQL" $diskCount = $diskCount +1 }Abre SQL Server Management Studio (SSMS). Ejecútalo como administrador.
En el cuadro de diálogo Conectar al servidor, verifica que el nombre del servidor esté configurado como
localhosty selecciona Conectar.En el menú de archivo, selecciona Archivo > Nuevo > Consulta con la conexión actual.
Copia el siguiente código en la ventana de consulta que se abrió recientemente.
USE Master; GO CREATE DATABASE SnapBackupDB ON PRIMARY ( NAME = 'SnapBackupDB_Data', FILENAME = 'D:\MSSQL\SnapBackupDB.mdf', SIZE = 500MB, MAXSIZE = UNLIMITED, FILEGROWTH = 64MB ) LOG ON ( NAME = 'SnapBackupDB_Log', FILENAME = 'E:\MSSQL\SnapBackupDB_log.ldf', SIZE = 250MB, MAXSIZE = 2GB, FILEGROWTH = 64MB );
Implementa la secuencia de comandos de instantáneas
Esta secuencia de comandos automatiza el proceso completo necesario para tomar instantáneas coherentes con la aplicación de los discos conectados a la VM que ejecuta SQL Server.
- En la misma sesión de Escritorio remoto, abre el Bloc de notas.
- Copia el contenido de la siguiente secuencia de comandos y pégalo en la ventana del Bloc de notas que se abrió.
Guarda el archivo como
take-snapshot.ps1enc:\scripts.# Import Modules Import-Module -Name SQLPS # Set variables $formattedTimestamp = Get-Date -Format 'yyyyMMdd-HHmmss' $backupLocation = 'D:\MSSQL\Backup' $dbName = 'SnapBackupDB' $bkmFile = Join-Path -Path $backupLocation -ChildPath ("${dbName}_${formattedTimestamp}.bkm") $sqlServer = 'localhost' # SQL Commands $suspendDbCmd = "ALTER DATABASE [$dbName] SET SUSPEND_FOR_SNAPSHOT_BACKUP=ON WITH NO_WAIT;" $backupMetadataCmd = "BACKUP DATABASE [$dbName] TO DISK='$bkmFile' WITH METADATA_ONLY, FORMAT;" $unsuspendDbCmd = "ALTER DATABASE [$dbName] SET SUSPEND_FOR_SNAPSHOT_BACKUP=OFF;" # --- Helper Function for SQL Execution --- function Invoke-MySqlCommand { param( [Parameter(Mandatory=$true)] [string]$CommandText, [Parameter(Mandatory=$true)] [System.Data.SqlClient.SqlConnection]$SqlConnection ) Write-Host "Executing SQL Command: $($CommandText)" try { $Command = New-Object System.Data.SqlClient.SqlCommand($CommandText, $SqlConnection) $Result = $Command.ExecuteNonQuery() return $true } catch { Write-Host "Error executing SQL Command: $($CommandText)`n$($_.Exception.Message)" -ForegroundColor Red return $false } } $sqlConn = New-Object System.Data.SqlClient.SqlConnection $sqlConn.ConnectionString = "server='$sqlServer';database='$dbName';Integrated Security=True;" $databaseSuspended = $false if (-not(Test-Path $backupLocation)) { New-Item -Path $backupLocation -ItemType directory -Force } try { $instanceName = (Invoke-RestMethod -Headers @{"Metadata-Flavor"="Google"} -Uri "http://metadata.google.internal/computeMetadata/v1/instance/name") $vmConfigString = (gcloud compute instances list --filter="name=('$instanceName')" --format=json --quiet) if ($LASTEXITCODE -ne 0) { Write-Host "Error querying gcloud for VM instances (exit code: $LASTEXITCODE). Exiting." -ForegroundColor Red exit 1 } $vmConfig = $vmConfigString | ConvertFrom-Json # Open SQL Server connection $sqlConn.Open() # Suspend Database Write-Host "Suspending database '$dbName' for snapshot..." if (-not (Invoke-MySqlCommand -CommandText $suspendDbCmd -SqlConnection $sqlConn)) { Write-Host "Failed to suspend database. Exiting." -ForegroundColor Red exit 1 } $databaseSuspended = $true # Take a disk snapshot try { $consistencyGroupListStr = (gcloud compute resource-policies list --filter='name:*-snap-grp' --format=json --quiet) if ($LASTEXITCODE -ne 0) { throw "gcloud resource-policies list failed (exit code: $LASTEXITCODE)." } $consistencyGroupList = $consistencyGroupListStr | ConvertFrom-Json if (@($consistencyGroupList).Count -eq 0) { throw "No consistency group found matching '*-snap-grp'." } if (@($consistencyGroupList).Count -gt 1) { Write-Warning "More than one consistency group found, using the first one." } $consistencyGroupSelfLink = $consistencyGroupList[0].selfLink $zoneName = Split-Path $vmConfig[0].zone -Leaf $snapshotName = "$($vmConfig.Name)-${formattedTimestamp}" $snapshotCmd = "gcloud compute instant-snapshot-groups create $snapshotName --source-consistency-group=$consistencyGroupSelfLink --zone=$zoneName --quiet" Invoke-Expression $snapshotCmd if ($LASTEXITCODE -ne 0) { throw "gcloud compute instant-snapshot-groups create failed (exit code: $LASTEXITCODE)." } Write-Host "Instant snapshot group created successfully." } catch { Write-Host "Error during snapshot creation: $($_.Exception.Message)" -ForegroundColor Red exit 1 # Exit after handling in finally } # Backup database metadata if (-not (Invoke-MySqlCommand -CommandText $backupMetadataCmd -SqlConnection $sqlConn)) { Write-Host "Failed to backup database metadata." -ForegroundColor Red exit 1 } # Unsuspend Database Write-Host "Unsuspending database '$dbName'..." if (-not (Invoke-MySqlCommand -CommandText $unsuspendDbCmd -SqlConnection $sqlConn)) { Write-Host "Failed to unsuspend database after successful snapshot and metadata backup. Manual intervention may be required." -ForegroundColor Red exit 1 } $databaseSuspended = $false # Successfully unsuspended } catch { Write-Host "An unhandled error occurred: $($_.Exception.Message)" -ForegroundColor Red exit 1 } finally { if ($databaseSuspended -and ($sqlConn.State -eq [System.Data.ConnectionState]::Open)) { if (-not (Invoke-MySqlCommand -CommandText $unsuspendDbCmd -SqlConnection $sqlConn)) { Write-Host "Failed to unsuspend database in finally block. Manual intervention may be required." -ForegroundColor Red } } # Ensure SQL connection is closed if ($sqlConn.State -eq [System.Data.ConnectionState]::Open) { $sqlConn.Close() } }Haz clic con el botón derecho en el botón Iniciar (o presiona Win+X) y, luego, en Terminal (Admin).
Para confirmar el símbolo de elevación, haz clic en Sí.
Ejecuta la secuencia de comandos con el siguiente comando.
C:\scripts\take-snapshot.ps1
Verifica que se hayan creado las instantáneas
Ejecuta los siguientes comandos en Cloud Shell
Verifica que la secuencia de comandos haya creado las instantáneas.
gcloud compute instant-snapshots list --filter="name:$VM_NAME*"Enumera los grupos de instantáneas inmediatas.
gcloud compute instant-snapshot-groups list --zones $ZONEConsulta los detalles del grupo de instantáneas inmediatas.
gcloud compute instant-snapshot-groups describe \INSTANT_SNAPSHOT_NAME--zone=$ZONECopia el valor de
selfLinkpara usarlo en la siguiente sección.
Restablece las Instant Snapshots en discos nuevos
Ejecuta los siguientes comandos en la ventana de la consola Google Cloud .
Crea discos a partir del grupo de coherencia de instantáneas inmediatas.
gcloud compute disks bulk create --source-instant-snapshot-group \INSTANT_SNAPSHOT_NAME_URL\ --source-instant-snapshot-group-region $REGION --zone=$ZONEPara confirmar que se restablecieron tus instantáneas, enumera los discos de la zona.
gcloud compute disks list --zones=$ZONE --filter="name:$VM_NAME-*"Crea una VM nueva a partir de los discos recién creados.
REGION=
REGIONZONE=$REGION-a VM_NAME=VM_NAMEgcloud compute instances create $VM_NAME \ --machine-type c4-highmem-4 \ --zone $ZONE \ --network-interface subnet=default \ --tags sql-server-instant-snapshot \ --disk=name=BOOT_DISK_NAME,boot=yes,auto-delete=no \ --disk=name=DATA_DISK_1_NAME,mode=rw,auto-delete=no \ --disk=name=DATA_DISK_2_NAME,mode=rw,auto-delete=no
Reemplaza lo siguiente:
- Región: Es la región en la que se implementará tu instancia nueva.
- VM_NAME: Es el nombre de tu nueva instancia de SQL.
- BOOT_DISK_NAME: Es el nombre del disco de arranque que se creó en el paso anterior.
- DATA_DISK_1_NAME: Es el nombre del primer disco de datos creado en el paso anterior.
- DATA_DISK_2_NAME: Es el nombre del segundo disco de datos creado en el paso anterior.
Ahora puedes conectar los discos a una VM nueva o existente.
Realiza una limpieza
Para evitar que se apliquen cargos a tu cuenta de Google Cloud por los recursos que usaste en este instructivo, borra el proyecto.
Borra el proyecto
- En la Google Cloud consola, ve a la página Administrar recursos.
- En la lista de proyectos, elige el proyecto que quieres borrar y haz clic en Borrar.
- En el diálogo, escribe el ID del proyecto y, luego, haz clic en Cerrar para borrar el proyecto.
¿Qué sigue?
- Explora arquitecturas de referencia, diagramas y prácticas recomendadas sobre Google Cloud. Consulta nuestro Cloud Architecture Center.