Esercizio - Eseguire un ripristino temporizzato
In questo esercizio si apprenderà come eseguire il ripristino in seguito a un errore comune usando il ripristino temporizzato (PITR). Questo processo può essere eseguito in modo semplice nel portale o a livello di codice. In questo esercizio si apprenderà come eseguire il processo usando l'interfaccia della riga di comando di Azure.
Eseguire la configurazione: usare gli script per distribuire il database SQL di Azure
Nel terminale a destra verrà visualizzato Azure Cloud Shell, che consente di interagire con Azure tramite un browser. Prima di iniziare gli esercizi, è necessario eseguire uno script per creare l'ambiente: un database SQL di Azure contenente il database AdventureWorks. Nello script verranno richiesti la password e l'indirizzo IP locale.
Per il completamento degli script sono necessari 3-5 minuti. Assicurarsi di annotare la password, l'ID univoco e l'area, perché non verranno visualizzati di nuovo.
Per ottenere l'indirizzo IP richiesto, è necessario disconnettersi da tutti i servizi VPN ed eseguire
(Invoke-WebRequest -Uri "https://ipinfo.io/ip").Content
in una finestra di PowerShell locale, non nel browser. Annotare l'indirizzo IP risultante.In Azure Cloud Shell, a destra di questa pagina, eseguire lo script seguente. Quando richiesto, immettere una password complessa e un indirizzo IP pubblico.
$adminSqlLogin = "cloudadmin" $password = Read-Host "Your username is 'cloudadmin'. Please enter a password for your Azure SQL Database server that meets the password requirements" # Prompt for local IP address $ipAddress = Read-Host "Disconnect your VPN, open PowerShell on your machine and run '(Invoke-WebRequest -Uri "https://ipinfo.io/ip").Content'. Please enter the value (include periods) next to 'Address': " # Get resource group and location and random string $resourceGroup = Get-AzResourceGroup | Where ResourceGroupName -like "<rgn>[sandbox resource group name]</rgn>" $resourceGroupName = "<rgn>[sandbox resource group name]</rgn>" $uniqueID = Get-Random -Minimum 100000 -Maximum 1000000 $storageAccountName = "mslearnsa"+$uniqueID $location = $resourceGroup.Location # The logical server name has to be unique in the system $serverName = "aw-server$($uniqueID)"
Visualizzare e archiviare (in un file di testo o in una posizione simile) le informazioni che saranno necessarie in tutto il modulo eseguendo lo script seguente in Azure Cloud Shell. Sarà necessario premere INVIO dopo aver incollato il codice, perché l'ultima riga non viene eseguita per impostazione predefinita.
Write-Host "Please note your unique ID for future exercises in this module:" Write-Host $uniqueID Write-Host "Your resource group name is:" Write-Host $resourceGroupName Write-Host "Your resources were deployed in the following region:" Write-Host $location Write-Host "Your server name is:" Write-Host $serverName
Importante
Non dimenticare di prendere nota della password, dell'ID univoco e dell'area. Queste informazioni saranno necessarie nel corso del modulo.
Eseguire lo script seguente per distribuire un database SQL di Azure e un server logico con l'esempio AdventureWorks. Lo script aggiunge anche l'indirizzo IP come regola del firewall, abiliterà Microsoft Defender for Cloud e creerà un account di archiviazione da usare nelle unità successive.
# The logical server name has to be unique in the system $serverName = "aw-server$($uniqueID)" # The sample database name $databaseName = "AdventureWorks" # The storage account name has to be unique in the system $storageAccountName = $("sql$($uniqueID)") # Create a new server with a system-wide unique server name $server = New-AzSqlServer -ResourceGroupName $resourceGroupName ` -ServerName $serverName ` -Location $location ` -SqlAdministratorCredentials $(New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList $adminSqlLogin, $(ConvertTo-SecureString -String $password -AsPlainText -Force)) # Create a server firewall rule that allows access from the specified IP range and all Azure services $serverFirewallRule = New-AzSqlServerFirewallRule ` -ResourceGroupName $resourceGroupName ` -ServerName $serverName ` -FirewallRuleName "AllowedIPs" ` -StartIpAddress $ipAddress -EndIpAddress $ipAddress $allowAzureIpsRule = New-AzSqlServerFirewallRule ` -ResourceGroupName $resourceGroupName ` -ServerName $serverName ` -AllowAllAzureIPs # Create a database $database = New-AzSqlDatabase -ResourceGroupName $resourceGroupName ` -ServerName $serverName ` -DatabaseName $databaseName ` -SampleName "AdventureWorksLT" ` -Edition "GeneralPurpose" -Vcore 2 -ComputeGeneration "Gen5" # Enable Azure Defender $azureDefender = Enable-AzSqlServerAdvancedDataSecurity ` -ResourceGroupName $resourceGroupName ` -ServerName $serverName # Create a storage account $storageAccount = New-AzStorageAccount -ResourceGroupName $resourceGroupName ` -AccountName $storageAccountName ` -Location $location ` -Type "Standard_LRS"
Nel computer locale aprire SSMS e creare una nuova connessione al server logico. Come nome del server immettere il nome del server logico del database SQL di Azure. Se il nome non è stato salvato in precedenza, può essere necessario fare riferimento al portale di Azure per ottenerlo. Ad esempio:
aw-server\<unique ID>.database.windows.net
.Nel portale di Azure immettere AdventureWorks nella casella di ricerca per trovare il database e il server logico associato.
Nella casella Autenticazione immettere Autenticazione di SQL Server. Immettere le informazioni relative ad Accesso e Password per l'amministratore del server corrispondente, ovvero quello specificato durante la distribuzione nell'esercizio precedente.
Selezionare la casella Memorizza password, quindi selezionare Connetti.
Nota
A seconda della configurazione locale, ad esempio della VPN, l'indirizzo IP client può essere diverso dall'indirizzo IP usato dal portale di Azure durante la distribuzione. In tal caso, verrà visualizzato il messaggio "L'indirizzo IP client non ha accesso al server. Accedere a un account Azure e creare una nuova regola del firewall per abilitare l'accesso. Se viene visualizzato questo messaggio, accedere con l'account usato per l'ambiente sandbox e aggiungere una regola del firewall per l'indirizzo IP del client. È possibile completare questi passaggi usando la procedura guidata popup in SSMS.
Completare il ripristino temporizzato
Prima di continuare, è importante comprendere il processo consigliato per eseguire il ripristino temporizzato:
- Una tabella o un database viene eliminato per sbaglio.
- Determinare il momento in cui è necessario tornare; deve essere antecedente all'errore.
- Eseguire il ripristino temporizzato tramite PowerShell o il portale di Azure per tornare a questo momento. Il processo distribuisce un nuovo database e ripristina una copia del database. Ad esempio: AdventureWorks-copy.
- Verificare che il nuovo database, ad esempio AdventureWorks-copy, sia nello stato corretto, ovvero come prima che si verificasse il problema.
- Rinominare il database originale. Rinominare, ad esempio, AdventureWorks in AdventureWorks-old.
- Rinominare il nuovo database con il nome del database originale. Rinominare, ad esempio, AdventureWorks-copy in AdventureWorks.
- Eliminare il database originale. Ad esempio: AdventureWorks-old.
In questo esercizio verranno completati questi passaggi.
Simulare l'eliminazione dei dati
Prima di tutto, verificare che la tabella che verrà eliminata accidentalmente esista e contenga dati. Esaminare alcuni dei valori in SalesLT.OrderDetail.
Passare a SSMS e controllare/aggiornare la connessione. Selezionare File>Connect Object Explorer, quindi selezionare il pulsante Opzioni.
Assicurarsi che la connessione in uso si connetta al server logico, ma non a un database specifico. Usare, ad esempio, <predefinito> come illustrato nello screenshot seguente. Verificare anche che nella scheda Parametri aggiuntivi per la connessione non sia presente testo.
Espandere la cartella Database, quindi fare clic con il pulsante destro del mouse sul database AdventureWorks e selezionare Nuova query. Immettere la query seguente ed eseguirla selezionando Esegui, quindi esaminare i risultati:
SELECT TOP 10 * from SalesLT.SalesOrderDetail
Simulare la perdita di dati eliminando una tabella nel database.
Nella stessa finestra di query eseguire questa query, quindi selezionare la scheda Messaggi nella finestra Risultati e prendere nota dell'ora di completamento:
DROP TABLE SalesLT.SalesOrderDetail
Importante
Salvare l'ora di completamento. in quanto sarà necessario più avanti. Ecco un esempio:
Completion time: 2020-06-22T09:20:27.1859237-07:00
.Infine, prima di iniziare la procedura per il ripristino del database, eseguire il codice seguente in Azure Cloud Shell a destra di questa pagina per configurare l'ambiente:
$resourceGroup = Get-AzResourceGroup | Where ResourceGroupName -like <rgn>[sandbox resource group name]</rgn> $server = Get-AzureRmSqlServer -ResourceGroupName $resourceGroup.ResourceGroupName $logical_server = $server.ServerName $resource_group = $resourceGroup.ResourceGroupName # Specify your default resource group and Azure SQL Database logical server az configure --defaults group=$resource_group sql-server=$logical_server # Confirm the defaults are set az configure --list-defaults
I parametri
group
esql-server
restituiti devono corrispondere ai nomi del gruppo di risorse di Microsoft Learn e del server logico del database SQL di Azure.
Identificare l'ora in cui ripristinare il database
Il primo passaggio consiste nel determinare il tempo in cui ripristinare il database. È necessario sapere quando si è verificata l'ultima transazione "valida" prima di quella "non valida". Si eseguirà il ripristino prima della transazione non valida, ma dopo l'ultima valida.
Un modo per determinare l'ora dell'eliminazione consiste nell'esaminare l'ora di completamento dell'istruzione DROP, annotata nel passaggio precedente.
Un modo alternativo consiste nell'usare i log di controllo nel portale di Azure. In questo esercizio non è stato configurato il controllo in Log Analytics, ma si vedrà che cosa è possibile fare nel caso in cui sia configurato. È possibile passare al database SQL di Azure nel portale di Azure. Nel riquadro a sinistra, in Sicurezza, è possibile selezionare Controllo, quindi Visualizza log di controllo. Se si seleziona Log Analytics, viene visualizzato un editor di query che consente di eseguire query nei log tramite Kusto Query Language (KQL). Questo linguaggio di query consente ai professionisti SQL di eseguire facilmente query sui log.
È quindi possibile eseguire la query KQL seguente:
search database_name_s == "AdventureWorks" | where Category == 'SQLSecurityAuditEvents' and statement_s like 'DROP' | project format_datetime(event_time_t, 'yyyy-MM-dd hh:mm:ss.fff'), ResourceGroup, server_instance_name_s, database_name_s, statement_s, succeeded_s,client_ip_s, server_principal_name_s, application_name_s | sort by event_time_t desc
I risultati saranno simili ai seguenti, ma con data e ora diverse.
Nota
Possono essere necessari da 5 a 10 minuti perché i log vengano visualizzati qui, quindi ai fini di questo esercizio non sono stati inseriti. Si userà invece l'ora di completamento annotata nel passaggio precedente. Sarà necessario eseguire la conversione nel fuso orario GMT. In una situazione reale, è improbabile che si riesca a visualizzare la finestra con l'ora di completamento, quindi l'uso del controllo può aiutare notevolmente.
In questo esempio la data/ora è
2020-07-24 08:06:24.386
da Log Analytics e2020-07-24T13:06:24.386-07:00
da SSMS. Il formato richiesto è leggermente diverso. Usare l'esempio seguente per determinare il formato corretto. È anche possibile sottrarre 0,001 secondi per assicurarsi di eseguire il ripristino a un punto nel tempo precedente a quello in cui si è verificato l'errore:- Formato di Log Analytics:
2020-07-24 08:06:24.386
- Formato SSMS:
2020-07-24T13:06:24.386-07:00
- Formato richiesto:
2020-07-24T20:06:24.385
- Formato di Log Analytics:
Impostare
$before_error_time
sul valore risultante, sostituendo il proprio tempo nel tempo in questo esempio:$before_error_time ="2020-07-24T20:06:24.385"
Ripristinare il database e confermare i dati mancanti
In questa sezione si userà az cli db restore
per eseguire il ripristino a un punto nel tempo precedente all'eliminazione della tabella.
Eseguire lo script seguente nel terminale a destra di questa finestra:
# Restore the database to a time before the database was deleted az sql db restore --dest-name "AdventureWorks-copy" --name "AdventureWorks" --time $before_error_time --verbose
Il ripristino richiede circa da 5 a 10 minuti. Quando si esegue un ripristino, Azure distribuisce un nuovo database SQL di Azure nel server logico del database SQL di Azure. Il nuovo database ha le stesse opzioni di configurazione del database originale. Dopo la distribuzione del database SQL di Azure, Azure ripristina il database nel nuovo database SQL di Azure.
È possibile controllare lo stato aggiornando la vista dei database in SSMS. Fare clic con il pulsante destro del mouse sulla cartella Database e selezionare Aggiorna. Dopo la distribuzione del database, si noterà che il ripristino è in corso:
Per il completamento del ripristino, una volta in corso, saranno necessari altri 2 o 3 minuti. Il completamento del comando indica che l'operazione è terminata. Quando si avvia un aggiornamento, non sarà inoltre più visualizzata l'indicazione (ripristino...) accanto al database di copia.
Se si nota che il ripristino richiede più tempo di quanto indicato in precedenza, la causa potrebbe essere l'ambiente Microsoft Learn. Per una sottoscrizione singola, è previsto un limite per il numero di richieste di ripristino che è possibile elaborare o inviare contemporaneamente. Per altre informazioni sui limiti e per i relativi dettagli per il ripristino temporizzato, vedere Ripristino di un database da un backup nel database SQL di Azure.
Verificare ora che il nuovo database sia nello stato corretto, ovvero come prima che si verificasse il problema. Fare clic con il pulsante destro del mouse sul server logico in SSMS e scegliere Aggiorna per aggiornare la connessione al server logico del database SQL di Azure.
Fare clic con il pulsante destro del mouse sul nuovo database, ad esempio AdventureWorks-copy e scegliere Nuova query.
Usare questa query per verificare che la tabella esista:
SELECT TOP 10 * from SalesLT.SalesOrderDetail
I risultati visualizzati saranno simili a quelli dello screenshot seguente. Questo risultato conferma che il database è stato ripristinato nel percorso desiderato.
Eseguire lo scambio dei database e la pulizia
Successivamente, rinominare il database originale in AdventureWorks-old così da poter rinominare, in seguito, il nuovo database con il nome del database originale. Se le applicazioni usano la logica di ripetizione dei tentativi, non sarà necessario modificare le stringhe di connessione.
Se a un certo punto il database risulta non disponibile, ad esempio se non è possibile connettersi ai database in SSMS se si aggiorna la connessione, la causa potrebbe essere l'esecuzione di aggiornamenti nella tabella DNS. Il database non è quindi fisicamente non disponibile, ma non è risolvibile. Le normali attività dovrebbero riprendere dopo alcuni minuti.
Usare questo comando per modificare il nome del database:
az sql db rename --name "AdventureWorks" --new-name "AdventureWorks-old"
Ora che il nome del database originale non è più in uso, è possibile rinominare il database di copia con il nome di quello originale, usando di nuovo Azure Cloud Shell:
az sql db rename --name "AdventureWorks-copy" --new-name "AdventureWorks"
Il database precedente non è più necessario, quindi è possibile eliminarlo usando
az sql db delete
:az sql db delete --name "AdventureWorks-old" --yes Write-Host "Database deleted"
È possibile verificare che il database precedente non esista più usando questo comando:
az sql db list -o table
Si è visto come usare il ripristino temporizzato nel database SQL di Azure. Il ripristino temporizzato è disponibile anche in Istanza gestita di SQL di Azure per i database, ma non per un'intera istanza. È possibile usare quasi gli stessi comandi, ad eccezione di az sql midb
che deve essere usato al posto di az sql db
.