
We wtorek w T-SQL w zeszłym miesiącu pisałem o kilku nieudokumentowanych flagach śledzenia, które pomagają nadzorować długotrwałe operacje tworzenia kopii zapasowych i przywracania. W tym miesiącu tematem Jesa Borlanda są zdarzenia rozszerzone i pomyślałem, że pokażę nowe możliwości w SQL Server 2016, które w dużej mierze sprawią, że te flagi śledzenia staną się przestarzałe.
Jeśli grasz z CTP2 (możesz go pobrać tutaj), możesz zauważyć nową kategorię backup_restore i nowe wydarzenie backup_restore_progress_trace :
Odkrywanie nowego zdarzenia w oknie dialogowym Nowa sesja CTP2
Oto szybka i brudna sesja XE do przechwytywania danych dla tego zdarzenia (dodałem komentarze dotyczące filtrowania tylko do operacji tworzenia kopii zapasowych lub tylko przywracania; domyślnie obie są uwzględnione):
CREATE EVENT SESSION [Backup progress] ON SERVER
ADD EVENT sqlserver.backup_restore_progress_trace
(
ACTION(package0.event_sequence)
-- to only capture backup operations:
--WHERE [operation_type] = 0
-- to only capture restore operations:
--WHERE [operation_type] = 1
)
ADD TARGET package0.event_file
(
SET filename = N'C:\temp\BackupProgress.xel'
); -- default options are probably ok
GO
ALTER EVENT SESSION [Backup progress] ON SERVER STATE = START;
GO Teraz powiedzmy, że uruchamiam następujące operacje – tworzenie bazy danych, tworzenie kopii zapasowej danych, upuszczanie i przywracanie:
USE [master]; GO CREATE DATABASE floob; GO SELECT s1.* INTO floob.dbo.what FROM sys.all_objects AS s1 CROSS JOIN sys.all_objects; GO BACKUP DATABASE floob TO DISK = 'c:\temp\floob.bak' WITH INIT, COMPRESSION, STATS = 30; GO DROP DATABASE floob; GO RESTORE DATABASE floob FROM DISK = 'c:\temp\floob.bak' WITH REPLACE, RECOVERY;
Teraz możemy zapytać o dane z pliku docelowego zdarzenia:
;WITH x AS
(
SELECT ts,op,db,msg,es
FROM
(
SELECT
ts = x.value(N'(event/@timestamp)[1]', N'datetime2'),
op = x.value(N'(event/data[@name="operation_type"]/text)[1]', N'nvarchar(32)'),
db = x.value(N'(event/data[@name="database_name"])[1]', N'nvarchar(128)'),
msg = x.value(N'(event/data[@name="trace_message"])[1]', N'nvarchar(max)'),
es = x.value(N'(event/action[@name="event_sequence"])[1]', N'int')
FROM
(
SELECT x = CONVERT(XML, event_data)
FROM sys.fn_xe_file_target_read_file
(N'c:\temp\Backup--Progress*.xel', NULL, NULL, NULL)
) AS y
) AS x
WHERE op = N'Backup' -- N'Restore'
AND db = N'floob'
AND ts > CONVERT(DATE, SYSUTCDATETIME())
)
SELECT /* x.db, x.op, x.ts, */
[Message] = x.msg,
Duration = COALESCE(DATEDIFF(MILLISECOND, x.ts,
LEAD(x.ts, 1) OVER(ORDER BY es)),0)
FROM x
ORDER BY es; W przypadku kopii zapasowej flaga śledzenia 3226 nie pomija żadnych danych wyjściowych przechwyconych przez zdarzenia rozszerzone. Pominąłem kolumny wyjściowe, ze względu na filtry, dla zwięzłości:
| Wiadomość | Czas trwania (milisekundy) |
|---|---|
| KOPIOWANIE BAZY DANYCH rozpoczęte | 0 |
| Otwieranie bazy danych za pomocą S lock | 0 |
| Uzyskiwanie blokady operacji zbiorczych w bazie danych | 0 |
| Synchronizacja z innymi operacjami na bazie danych zakończona | 19 |
| Otwieranie zestawu nośników kopii zapasowych | 7 |
| Zestaw nośników kopii zapasowej jest otwarty | 0 |
| Przygotowanie zestawu mediów do pisania | 0 |
| Zestaw nośników jest gotowy do utworzenia kopii zapasowej | 0 |
| Skuteczne opcje:Checksum=0, Compression=1, Encryption=0, BufferCount=7, MaxTransferSize=1024 KB | 0 |
| Usuwanie różnicowych map bitowych | 4 |
| Różnicowe mapy bitowe są usuwane | 0 |
| Pisanie punktu kontrolnego | 6 |
| Punkt kontrolny zakończony (upłynął =6 ms) | 0 |
| Start LSN:101:111920:43, SERepl LSN:0:0:0 | 0 |
| Skanowanie bitmap alokacji | 4 |
| Skanowanie bitmap alokacji zakończone | 0 |
| Obliczanie oczekiwanego rozmiaru całkowitych danych | 0 |
| FID=1, ExpectedExtents=10047, IsDifferentialMapAccurate=0 | 0 |
| TotalSize=658440192 bajty | 0 |
| Szacowany całkowity rozmiar =658460672 bajtów (rozmiar danych =658440192 bajtów, rozmiar dziennika =20480 bajtów) | 0 |
| Oszacowanie pracy zakończone | 0 |
| Ostatni numer LSN:101:111960:1 | 0 |
| Zapisywanie wiodących metadanych | 0 |
| BackupStream(0):Zapisywanie wiodących metadanych do urządzenia c:\temp\floob.bak | 1 |
| Obliczanie oczekiwanego rozmiaru całkowitych danych | 0 |
| FID=1, ExpectedExtents=10047, IsDifferentialMapAccurate=0 | 0 |
| TotalSize=658440192 bajty | 1 |
| Kopiowanie plików danych | 2 |
| Liczba czytników plików danych =1 | 0 |
| Odczyt pliku danych D:\SQL Server\MSSQL13.SQL16\DATA\floob.mdf | 0 |
| BackupStream(0):Zapisywanie MSDA o rozmiarze 10048 przydziałów | 391 |
| 30 procent (198180864/658460672 bajtów) przetworzonych | 554 |
| 60 procent (395313152/658460672 bajtów) przetworzonych | 576 |
| 90 procent (593494016/658460672 bajtów) przetworzonych | 184 |
| Zakończono odczytywanie pliku danych D:\SQL Server\MSSQL13.SQL16\DATA\floob.mdf | 2 |
| BackupStream(0):wypełnienie MSDA 65536 bajtami | 0 |
| BackupStream(0):całkowity rozmiar MSDA =10048 zakresów | 0 |
| InitialExpectedSize=658440192 bajty, FinalSize=658440192 bajty, ExcessMode=0 | 0 |
| Ostatni numer LSN:101:111960:1 | 0 |
| Kopiowanie plików danych zakończone | 0 |
| Kopiowanie dziennika transakcji | 0 |
| MediaFamily(0):FID=2, VLFID=101, DataStreamSize=65536 bajtów | 4 |
| Kopiowanie dziennika transakcji zakończone | 0 |
| Zapisywanie końcowych metadanych | 0 |
| BackupStream(0):Zapisywanie końcowych metadanych na urządzeniu c:\temp\floob.bak | 0 |
| Zapisywanie końca zestawu kopii zapasowych | 30 |
| Zapisywanie rekordów historii | 12 |
| Zapisywanie rekordów historii zakończone (upływało =11 ms) | 0 |
| KOPIOWANIE BAZY DANYCH zakończone | 0 |
Dane zdarzeń dla operacji tworzenia kopii zapasowej
W przypadku przywrócenia zobaczysz te wiersze:
| Wiadomość | Czas trwania (milisekundy) |
|---|---|
| Rozpoczęto PRZYWRACANIE BAZY DANYCH | 0 |
| Otwieranie zestawu kopii zapasowych | 3 |
| Przetwarzanie wiodących metadanych | 0 |
| Rozpoczyna się planowanie | 23 |
| Skuteczne opcje:Checksum=0, Compression=1, Encryption=0, BufferCount=6, MaxTransferSize=1024 KB | 0 |
| Planowanie zakończone | 0 |
| Rozpoczęcie przywracania OFFLINE | 0 |
| Dołączona baza danych jako DB_ID=5 | 1 |
| Przygotowywanie kontenerów | 534 |
| Kontenery są gotowe | 1097 |
| Przywracanie zestawu kopii zapasowych | 0 |
| Szacowany całkowity rozmiar do przesłania =658460672 bajtów | 0 |
| Przesyłanie danych | 1 |
| BackupStream(0):Przetwarzanie MSDA o rozmiarze 10048 przydziałów | 3282 |
| BackupStream(0):Ukończono MSDA | 0 |
| Oczekiwanie na zakończenie zerowania dziennika | 3 |
| Zerowanie dziennika zakończone | 0 |
| BackupStream(0):przetwarzanie MSTL (FID=2, VLFID=101, size=65536 bajtów) | 1024 |
| Transfer danych zakończony | 14 |
| Zestaw kopii zapasowej został przywrócony | 45 |
| Rozpoczyna się przewijanie offline | 1 |
| Przetwarzanie 68 nagłówków VLF | 69 |
| Przetwarzanie nagłówków VLF zakończone | 11 |
| Pierwszy numer LSN:101:111920:43, ostatni numer LSN:101:111960:1 | 0 |
| Zatrzymaj LSN:101:111960:1 | 4 |
| Przewijanie offline jest zakończone | 17 |
| Naprawianie bazy danych zakończone | 2 |
| Przenoszenie bazy danych do ONLINE | 2 |
| Ponowne uruchamianie bazy danych w trybie ONLINE | 87 |
| PostRestoreContainerFixups rozpoczyna się | 5 |
| PostRestoreContainerFixups zakończone | 2 |
| Rozpoczyna się PostRestoreReplicationFixup | 107 |
| PostRestoreReplicationFixup jest ukończony | 2 |
| Baza danych została zrestartowana | 9 |
| Wznawianie wszelkich zatrzymanych indeksowań pełnotekstowych | 6 |
| Zapisywanie rekordów historii | 13 |
| Zapisywanie rekordów historii zakończone (upłynął =13 ms) | 2 |
| Konserwacja MSDB zakończona | 2 |
| Zakończono PRZYWRACANIE BAZY DANYCH | 0 |
Dane zdarzeń dla operacji przywracania
Jeśli rozwiązujesz problemy z powolną operacją tworzenia kopii zapasowej lub przywracania, możesz łatwo filtrować według czasu trwania, aby na przykład widzieć tylko zdarzenia trwające dłużej niż n milisekund. Jedyną rzeczą, której nie widzę w tych danych wyjściowych, jest jakikolwiek sposób na stwierdzenie, czy podczas przywracania działało natychmiastowe inicjowanie pliku — nadal możesz potrzebować flagi śledzenia 3004, jak opisano w moim poście na wtorek z T-SQL z zeszłego miesiąca.
Nie zapomnij zatrzymać sesji (ale możesz zachować definicję sesji na serwerze, aby móc jej ponownie użyć):
ALTER EVENT SESSION [Backup progress] ON SERVER STATE = STOP;
Nie przeprowadziłem żadnych testów wydajności ani analizy wpływu, ale ogólnie powiedziałbym, że – podobnie jak flagi śledzenia – nie jest to coś, co chciałbyś uruchamiać przez cały czas, ale tylko podczas rozwiązywania problemów z określoną operacją. Nieco łatwiej jest skonfigurować tę sesję i zapytać o dane, IMHO, niż włączać flagi śledzenia i analizować wszystkie dane wyjściowe z dziennika błędów SQL Server.