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!