SQL Server: problem z odtworzeniem bazy z in memory

15-mar-2020

Podczas odtwarzania bazy WideWorldImporters pojawiał się błąd, a właściwie cała seria błędów:

  • An error occurred during recovery, preventing the database 'WideWorldImporters’ (7:0) from restarting. Diagnose the recovery errors and fix them, or restore from a known good backup. If errors are not corrected or expected, contact Technical Support.
  • [WARNING] ALTER or DROP TABLE could not clean up root row within 10 seconds.
  • [ERROR] HkHostRecoverDatabaseHelper::ReportAndRaiseFailure(): Database ID: [7] 'WideWorldImporters’. Failed to load XTP checkpoint. Error code: 0x82000018. (sql\ntdbms\hekaton\sqlhost\sqlmin\hkhostdb.cpp:5740)
  • restoreHkDatabase: DbId 7, Msg 41316, Level 16, State 0, Restore operation failed for database 'WideWorldImporters’ with internal error code '0x82000031′.
  • [ERROR] HkRtRestoreDatabase(): Recovery failed with error 0x82000031 on database 7. This error will be mapped to 'HK_E_RESTORE_ABORTED’ (0x82000018). (sql\ntdbms\hekaton\runtime\src\hkruntime.cpp:5505)
  • The code generation directory cannot be created or set up correctly.
  • Creation of directory \\?\F:\data\xtp failed for reason 3.
  • [INFO] HkCkptLoadInternalEx(): Database ID: [7]. Root file: {3E231B6B-9EF1-4AE3-A1DB-BD01DC866DD9}, watermark: 40, RecoveryLsn: 00000272:00005EC4:0002, RecoveryCheckpointId: 4, RecoveryCheckpointTimestamp: 0xb

Właściwie kluczowym do rozwiązania probelmu jest komunikat:

  • Creation of directory \\?\F:\data\xtp failed for reason 3.

Rzeczywiście, kiedy odtwarzana jest baza in-memory, to jeden z etapów polega na przekompilowaniu procedur. Te procedury powinny znaleźć się w katalogu xtp. Trzeba więc sprawdzić dlaczego SQL Server nie może sobie poradzić z założeniem katalogu.

W moim przypadku podczas instalacji określiłem domyślny katalog na dane na dysku F:. Potem jednak zmieniłem zdanie i dysk F: został usunięty. Polecenie restore, jakie używałem nie wskazywało na dysk F, nie odwoływało się też do wartości domyślnych. Każdy katalog był wymieniony jawnie:

RESTORE DATABASE [WideWorldImporters] 
FROM DISK = N'C:\SQL_backups\WideWorldImporters-Full.bak' 
WITH FILE = 1, 
MOVE N'WWI_Primary' TO N'c:\sql_data\wwi\WideWorldImporters.mdf', 
MOVE N'WWI_UserData' TO N'c:\sql_data\wwi\WideWorldImporters_UserData.ndf', 
MOVE N'WWI_Log' TO N'c:\sql_log\WideWorldImporters.ldf', 
MOVE N'WWI_InMemory_Data_1' TO N'c:\sql_data\wwi\WideWorldImporters_InMemory_Data_1', 
NOUNLOAD, REPLACE, STATS = 1

No więc dlaczego F?

SELECT 
 SERVERPROPERTY('InstanceDefaultDataPath') AS DataPath
 ,SERVERPROPERTY('InstanceDefaultLogPath') AS LogPath
 ,SERVERPROPERTY('InstanceDefaultBackupPath') AS BackupPath

To są wartości domyślne w jakich SQL Server chce utworzyć katalog xtp…. i inaczej sie nie da. By Design!

Do zmiany tej wartości na poprawny katalog można posłużyć się poleceniem

EXEC xp_instance_regwrite N'HKEY_LOCAL_MACHINE', N'Software\Microsoft\MSSQLServer\MSSQLServer', N'DefaultData', REG_SZ, N'd:\sql_data\'
GO

albo zrobić to w Management Studio, we właściwościach serwera. Ponieważ dane są przechowywane w rejestrze, po zmianie zrestartuj usługę SQL!

 

Komentarze są wyłączone

Autor: Rafał Kraik