Úvod
Existuje řada situací, které by zaručovaly přesun databázových souborů nebo souborů protokolu transakcí z jednoho svazku do druhého na stejném serveru. Mohou zahrnovat:
- Potřeba naformátovat svazek za předpokladu, že nebyl správně naformátován při instalaci SQL Server . Připomeňme, že při instalaci SQL Serveru se doporučuje použít k formátování svazků velikost alokační jednotky 64 kB. Pokud to není provedeno v okamžiku instalace a je třeba to provést později, bude to samozřejmě vyžadovat zachování zálohy databáze nebo vytvoření nového, správně naformátovaného svazku a přesun databáze na tento nový svazek.
- Potřeba použít nový svazek za předpokladu, že bylo dosaženo limitů pro základní úložiště . Dobrým příkladem by byl limit 2 TB úložiště dat VMware. To je případ od VSphere 5.0. Vyšší verze VSphere mají mnohem vyšší limity.
- Potřeba zlepšit výkon pomocí správy IO . Dalším důvodem, proč můžete chtít přesunout datové soubory, je výkon. Existují případy, kdy je databáze vytvořena s více datovými soubory, které jsou všechny umístěny na jednom disku, dokud není zřejmé, jak databáze roste, že jste vytvořili „horkou oblast“ ve vrstvě úložiště. Jedním řešením by bylo vytváření nových datových souborů a přestavba seskupených indexů, druhým by bylo přesunutí datových souborů.
Scénář 1:Přesouvání uživatelských databází
Kroky spojené s přesunem uživatelské databáze zahrnují následující:
- Přepnout databázi do režimu offline
- Aktualizujte katalog systému o nové umístění
- Datový soubor fyzicky zkopírujte do nového umístění
- Převeďte databázi online
Výpis 1 ukazuje příkazy provedené k dosažení těchto kroků.
Výpis 1 přesouvaných datových souborů
-- 1. Run the following statement to check the current location of files. SELECT name, physical_name AS CurrentLocation, state_desc FROM sys.master_files WHERE database_id = DB_ID(N'BranchDB'); -- 2. Take the database offline. ALTER DATABASE BranchDB SET OFFLINE; -- 3. Move the file or files to the new location (at OS level). -- 4. For each file moved, run the following statement. ALTER DATABASE BranchDB MODIFY FILE ( NAME = WWI_UserData, FILENAME = 'N:\MSSQL\Data\WWI_UserDataNew.ndf' ); -- 5. Run the following statement. ALTER DATABASE BranchDB SET ONLINE; -- 6. Verify the file change by running the following query. SELECT name, physical_name AS CurrentLocation, state_desc FROM sys.master_files WHERE database_id = DB_ID(N'BranchDB');
Je důležité si uvědomit, že při přechodu databáze do režimu offline může počet aktivních relací proces zpozdit. Naplánování odstávky k provedení tohoto úkolu by bylo dobrý nápad. Během takového výpadku by měl vlastník aplikace zastavit připojování aplikačních služeb k databázi dříve, než se správce databáze pokusí převést databázi do režimu offline. Existují případy, kdy není tak pohodlné převést databázi do režimu offline, pak by bylo nejlepší volbou vypnutí instance. V takovém případě by byl přístup mírně odlišný:
- Aktualizujte katalog systému o nové umístění
- Vypněte instanci
- Zkopírujte požadovaný datový soubor fyzicky do nového umístění
- Spusťte instanci
V obou přístupech je koncept stejný:zahrnuje aktualizaci systémového katalogu v hlavní databázi a následné fyzické přemístění požadovaného datového souboru. V obou případech musí být datový soubor čistě uzavřen. Pojďme se podívat na kroky zahrnuté v prvním přístupu.
Obr. 1 Ověřte umístění datových souborů
Prvním krokem by bylo zkontrolovat stav věci. Pokračujte nastavením databáze offline a úpravou systémového katalogu.
Obr. 2 Nastavit databázi offline a upravit katalog
Jak je vidět na obr. 3, jakmile aktualizujeme katalog, dotazování sys.master_files nám sdělí nové umístění, kde hlavní databáze očekává, že se datový soubor nachází, bez ohledu na to, zda jsme soubor fyzicky přesunuli či nikoli. Na obr. 4 také vidíme, že není možné uvést databázi online bez předchozího fyzického přesunutí souboru do nového umístění (a přejmenování souboru tak, aby odpovídal novému názvu uvedenému v katalogu).
Obr. 3 Umístění nového souboru
Obr. 4 Chybějící soubor
Také bychom rádi zdůraznili, že jakmile soubor zkopírujeme, ztratíme předchozí oprávnění k souboru a SQL Server nebude moci soubor otevřít, když se pokusíme uvést databázi online. Musíme upravit oprávnění k souboru a přidat účtu NT SERVICE\MSSQLSERVER úplná oprávnění k souboru.
Obr. 5 Zkopírujte datový soubor
Obr. 6 Oprávnění v cíli
Obr. 7a Oprávnění u zdroje
Obr. 7b Oprávnění u zdroje
Pokud bychom se pokusili znovu uvést databázi do režimu online s těmito chybějícími oprávněními, zobrazí se chyba 0x5 (Přístup odepřen). Pokud bychom provedli něco jako přesun datového souboru pomocí úlohy agenta, zjistíme, že účet SQL Server Agent získává vlastnictví souboru a můžeme přinést databázi pouze proto, že účet SQL Server Agent je stejný jako účet SQL Server.
Obr. 8 Přístup odepřen u nového datového souboru
Za předpokladu, že jste se pokoušeli uvést databázi online pomocí GUI SSMS, uvidíte tyto chyby v Prohlížeči událostí i v protokolu chyb serveru SQL Server, pokud se podíváte pozorně. Kromě toho, pokud byste používali druhý přístup (restartování celé instance), zjistili byste, že databáze by se zasekla ve fázi obnovy. Prozkoumáním protokolu chyb zjistíte, co se skutečně děje.
Výpis 2 přesouvání datových souborů pomocí úlohy agenta
/* ==Scripting Parameters== Source Server Version : SQL Server 2017 (14.0.3023) Source Database Engine Edition : Microsoft SQL Server Standard Edition Source Database Engine Type : Standalone SQL Server Target Server Version : SQL Server 2017 Target Database Engine Edition : Microsoft SQL Server Standard Edition Target Database Engine Type : Standalone SQL Server */ USE [msdb] GO /****** Object: Job [MoveDataFile] Script Date: 7/12/2018 12:33:55 AM ******/ BEGIN TRANSACTION DECLARE @ReturnCode INT SELECT @ReturnCode = 0 /****** Object: JobCategory [[Uncategorized (Local)]] Script Date: 7/12/2018 12:33:56 AM ******/ IF NOT EXISTS (SELECT name FROM msdb.dbo.syscategories WHERE name = N'[Uncategorized (Local)]' AND category_class = 1) BEGIN EXEC @ReturnCode = msdb.dbo.sp_add_category @class = N'JOB' ,@type = N'LOCAL' ,@name = N'[Uncategorized (Local)]' IF (@@error <> 0 OR @ReturnCode <> 0) GOTO QuitWithRollback END DECLARE @jobId BINARY(16) EXEC @ReturnCode = msdb.dbo.sp_add_job @job_name = N'MoveDataFile' ,@enabled = 1 ,@notify_level_eventlog = 0 ,@notify_level_email = 0 ,@notify_level_netsend = 0 ,@notify_level_page = 0 ,@delete_level = 0 ,@description = N'No description available.' ,@category_name = N'[Uncategorized (Local)]' ,@owner_login_name = N'sa' ,@job_id = @jobId OUTPUT IF (@@error <> 0 OR @ReturnCode <> 0) GOTO QuitWithRollback /****** Object: Step [MoveDataFile] Script Date: 7/12/2018 12:33:56 AM ******/ EXEC @ReturnCode = msdb.dbo.sp_add_jobstep @job_id = @jobId ,@step_name = N'MoveDataFile' ,@step_id = 1 ,@cmdexec_success_code = 0 ,@on_success_action = 1 ,@on_success_step_id = 0 ,@on_fail_action = 2 ,@on_fail_step_id = 0 ,@retry_attempts = 0 ,@retry_interval = 0 ,@os_run_priority = 0 ,@subsystem = N'PowerShell' ,@command = N'Copy-Item -Path M:\MSSQL\Data\WWI_UserData1.ndf N:\MSSQL\Data\WWI_UserData1.ndf' ,@database_name = N'master' ,@flags = 0 IF (@@error <> 0 OR @ReturnCode <> 0) GOTO QuitWithRollback EXEC @ReturnCode = msdb.dbo.sp_update_job @job_id = @jobId ,@start_step_id = 1 IF (@@error <> 0 OR @ReturnCode <> 0) GOTO QuitWithRollback EXEC @ReturnCode = msdb.dbo.sp_add_jobserver @job_id = @jobId ,@server_name = N'(local)' IF (@@error <> 0 OR @ReturnCode <> 0) GOTO QuitWithRollback COMMIT TRANSACTION GOTO EndSave QuitWithRollback: IF (@@trancount > 0) ROLLBACK TRANSACTION EndSave: GO
Obr. 9 Oprávnění k datovému souboru při použití úlohy agenta
Obr. 10 Databáze online
Automatizace procesu
Jen pro zábavu se můžeme rozhodnout pro celý proces použít SQL Server Agent Job. Pro každý krok našeho procesu nakonfigurujeme pracovní krok. To může být užitečné, pokud chcete být superstar DBA a naplánovat takovou migraci přes noc, zatímco půjdete domů a odpočinete si s rodinou. Určitě byste měli mít jistotu, že nakonfigurujete oznámení tak, aby se spouštělo, když je úloha úspěšná, abyste si byli jisti, že se to skutečně udělá, když jste pryč.
Výpis 3 Provádění úkolu pomocí úlohy agenta
/* ==Scripting Parameters== Source Server Version : SQL Server 2017 (14.0.3023) Source Database Engine Edition : Microsoft SQL Server Standard Edition Source Database Engine Type : Standalone SQL Server Target Server Version : SQL Server 2017 Target Database Engine Edition : Microsoft SQL Server Standard Edition Target Database Engine Type : Standalone SQL Server */ USE [msdb] GO /****** Object: Job [MoveDataFile] Script Date: 7/12/2018 12:46:47 AM ******/ BEGIN TRANSACTION DECLARE @ReturnCode INT SELECT @ReturnCode = 0 /****** Object: JobCategory [[Uncategorized (Local)]] Script Date: 7/12/2018 12:46:47 AM ******/ IF NOT EXISTS (SELECT name FROM msdb.dbo.syscategories WHERE name = N'[Uncategorized (Local)]' AND category_class = 1) BEGIN EXEC @ReturnCode = msdb.dbo.sp_add_category @class = N'JOB' ,@type = N'LOCAL' ,@name = N'[Uncategorized (Local)]' IF (@@error <> 0 OR @ReturnCode <> 0) GOTO QuitWithRollback END DECLARE @jobId BINARY(16) EXEC @ReturnCode = msdb.dbo.sp_add_job @job_name = N'MoveDataFile' ,@enabled = 1 ,@notify_level_eventlog = 0 ,@notify_level_email = 3 ,@notify_level_netsend = 0 ,@notify_level_page = 0 ,@delete_level = 0 ,@description = N'No description available.' ,@category_name = N'[Uncategorized (Local)]' ,@owner_login_name = N'sa' ,@notify_email_operator_name = N'DBA' ,@job_id = @jobId OUTPUT IF (@@error <> 0 OR @ReturnCode <> 0) GOTO QuitWithRollback /****** Object: Step [Set Database Offline] Script Date: 7/12/2018 12:46:47 AM ******/ EXEC @ReturnCode = msdb.dbo.sp_add_jobstep @job_id = @jobId ,@step_name = N'Set Database Offline' ,@step_id = 1 ,@cmdexec_success_code = 0 ,@on_success_action = 3 ,@on_success_step_id = 0 ,@on_fail_action = 2 ,@on_fail_step_id = 0 ,@retry_attempts = 0 ,@retry_interval = 0 ,@os_run_priority = 0 ,@subsystem = N'TSQL' ,@command = N'ALTER DATABASE BranchDB SET OFFLINE;' ,@database_name = N'master' ,@flags = 0 IF (@@error <> 0 OR @ReturnCode <> 0) GOTO QuitWithRollback /****** Object: Step [MoveDataFile] Script Date: 7/12/2018 12:46:47 AM ******/ EXEC @ReturnCode = msdb.dbo.sp_add_jobstep @job_id = @jobId ,@step_name = N'MoveDataFile' ,@step_id = 2 ,@cmdexec_success_code = 0 ,@on_success_action = 3 ,@on_success_step_id = 0 ,@on_fail_action = 2 ,@on_fail_step_id = 0 ,@retry_attempts = 0 ,@retry_interval = 0 ,@os_run_priority = 0 ,@subsystem = N'PowerShell' ,@command = N'Copy-Item -Path M:\MSSQL\Data\WWI_UserData1.ndf N:\MSSQL\Data\WWI_UserData1.ndf' ,@database_name = N'master' ,@flags = 0 IF (@@error <> 0 OR @ReturnCode <> 0) GOTO QuitWithRollback /****** Object: Step [ModifyFile and Bring Online] Script Date: 7/12/2018 12:46:47 AM ******/ EXEC @ReturnCode = msdb.dbo.sp_add_jobstep @job_id = @jobId ,@step_name = N'ModifyFile and Bring Online' ,@step_id = 3 ,@cmdexec_success_code = 0 ,@on_success_action = 1 ,@on_success_step_id = 0 ,@on_fail_action = 2 ,@on_fail_step_id = 0 ,@retry_attempts = 0 ,@retry_interval = 0 ,@os_run_priority = 0 ,@subsystem = N'TSQL' ,@command = N' ALTER DATABASE BranchDB MODIFY FILE ( NAME = WWI_UserData, FILENAME = ''N:\MSSQL\Data\WWI_UserDataNew.ndf'' ); ALTER DATABASE BranchDB SET ONLINE;' ,@database_name = N'master' ,@flags = 0 IF (@@error <> 0 OR @ReturnCode <> 0) GOTO QuitWithRollback EXEC @ReturnCode = msdb.dbo.sp_update_job @job_id = @jobId ,@start_step_id = 1 IF (@@error <> 0 OR @ReturnCode <> 0) GOTO QuitWithRollback EXEC @ReturnCode = msdb.dbo.sp_add_jobserver @job_id = @jobId ,@server_name = N'(local)' IF (@@error <> 0 OR @ReturnCode <> 0) GOTO QuitWithRollback COMMIT TRANSACTION GOTO EndSave QuitWithRollback: IF (@@trancount > 0) ROLLBACK TRANSACTION EndSave: GO
Závěr
V tomto článku jsme viděli jeden způsob, jak přesunout soubory databáze uživatelů na SQL Server. Také jsme viděli potřebu ujistit se, že věnujeme pozornost oprávněním k datovému souboru v novém umístění, abychom nenarazili na chyby při uvádění databáze zpět do režimu online. Také jsme viděli, že to vše můžeme vložit do úlohy SQL Server Agent pomocí subsystémů T-SQL a PowerShell. V následujícím článku uvidíme dvě další metody přesunu databázových souborů na nový svazek.
Další čtení:
Přesunout datové soubory na SQL Server – část 2