Sqlserver
 sql >> база данни >  >> RDS >> Sqlserver

Как да премествате файлове с данни в SQL Server – част 1

Въведение

Има редица ситуации, които биха гарантирали движението на файлове с база данни или регистрационни файлове на транзакции от един том в друг на същия сървър. Те могат да включват:

  1. Необходимостта от форматиране на тома, ако приемем, че не е форматиран правилно при инсталиране на SQL Server . Припомнете си, че когато инсталирате SQL Server, се препоръчва за форматиране на томовете да се използва размер на единица за разпределение 64K. Ако това не бъде направено в точката на инсталиране и трябва да се направи по-късно, очевидно ще изисква запазване на резервно копие на базата данни или създаване на нов, правилно форматиран том и преместване на базата данни в този нов том.
  2. Необходимостта от използване на нов том, ако се приеме, че са достигнати ограниченията за основното хранилище . Добър пример би било ограничението от 2TB на VMware Data Store. Такъв е случаят с VSphere 5.0. По-високите версии на VSphere имат много по-високи ограничения.
  3. Необходимостта от подобряване на производителността чрез управление на IO . Още една причина, поради която може да искате да преместите файлове с данни, е производителността. Има случаи, когато базата данни се създава с множество файлове с данни, всички седнали на един диск, докато стане очевидно, с нарастването на базата данни, че сте създали „горещ регион“ в слоя за съхранение. Едно решение би било създаване на нови файлове с данни и възстановяване на клъстерирани индекси, друго би било преместване на файлове с данни.

Сценарий първи:Преместване на потребителски бази данни

Стъпките, свързани с преместването на потребителска база данни, включват следното:

  1. Вземете базата данни офлайн
  2. Актуализирайте системния каталог с новото местоположение
  3. Копирайте файла с данни физически на новото местоположение
  4. Пренесете базата данни онлайн

Списък 1 показва командите, изпълнени за постигане на тези стъпки.

Списък 1 Преместване на файлове с данни

-- 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');

Важно е да се отбележи, че когато извеждате база данни офлайн, броят на активните сесии може да забави процеса. Планирането на престой за изпълнение на тази задача би било добра идея. По време на такъв престой собственикът на приложението трябва да спре свързването на приложните услуги към базата данни, преди DBA да се опита да изведе базата данни офлайн. Има случаи, в които не е толкова удобно да извеждате базата данни офлайн, тогава изключването на инстанцията би било най-добрият вариант. В такъв случай подходът би бил малко по-различен:

  1. Актуализирайте системния каталог с новото местоположение
  2. Изключете екземпляра
  3. Копирайте желания файл с данни физически на новото местоположение
  4. Стартирайте екземпляра

И в двата подхода концепцията е една и съща:включва актуализиране на системния каталог в главната база данни и след това физическо преместване на желания файл с данни. И в двата случая файлът с данни трябва да бъде чисто затворен. Нека да разгледаме стъпките, включени в първия подход.

Фиг. 1 Проверете местоположението на файловете с данни

Първата стъпка би била да се провери състоянието на нещата, за да започнете. Продължете да настроите базата данни офлайн и да промените системния каталог.

Фиг. 2 Задаване на база данни офлайн и промяна на каталог

Както се вижда на фиг. 3, след като актуализираме каталога, запитването на sys.master_files ни казва новото местоположение, където главната база данни очаква файлът с данни да бъде, независимо дали сме преместили физически файла или не. На Фиг. 4 също така виждаме, че не е възможно да се пренесе базата данни онлайн, без първо да преместите файла на новото място физически (и преименувайте файла, за да съответства на новото име, посочено в каталога).

Фиг. 3 Местоположение на нови файлове

Фиг. 4 Липсващ файл

Също така бихме искали да отбележим, че след като копираме файла, губим предишните разрешения за файла и SQL Server няма да може да отвори файла, когато се опитаме да пренесем базата данни онлайн. Трябва да редактираме разрешенията на файла и да добавим да предоставим на акаунта NT SERVICE\MSSQLSERVER пълни разрешения за файла.

Фиг. 5 Копирайте файла с данни

Фиг. 6 Разрешения на местоназначение

Фиг. 7a Разрешения в източник

Фиг. 7b Разрешения в източник

Ако се опитаме да върнем базата данни онлайн отново с липсващи тези разрешения, ще получим грешка 0x5 (Достъпът е отказан). Ако трябва да направим нещо като преместване на файла с данни с помощта на задача на агент, откриваме, че акаунтът на агент на SQL Server придобива собствеността върху файла и можем да донесем базата данни само защото акаунтът на агент на SQL Server е същият като акаунта на SQL Server.

Фиг. 8 Достъпът е отказан при нов файл с данни

Ако приемем, че се опитвате да пренесете базата данни онлайн с помощта на SSMS GUI, ще видите тези грешки в Event Viewer, както и в регистъра за грешки на SQL Server, ако погледнете внимателно. Освен това, ако използвате втория подход (рестартиране на целия екземпляр), ще забележите, че базата данни ще бъде блокирана на етапа на възстановяване. Разглеждането на регистрационния файл за грешки ще ви каже какво наистина се случва.

Списък 2 Преместване на файлове с данни с помощта на задача на агент

/* ==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

Фиг. 9 Разрешения за файл с данни при използване на задание на агент

Фиг. 10 База данни онлайн

Автоматизиране на процеса

Само за забавление можем да решим да използваме SQL Server Agent Job за целия процес. Ние конфигурираме стъпка на работа за всяка стъпка от нашия процес. Това може да е полезно, ако искате да бъдете суперзвезда DBA и да планирате такава миграция за една нощ, докато се приберете вкъщи и се отпуснете със семейството си. Определено бихте искали да сте сигурни, че конфигурирате известие да се задейства, когато задачата успее, така че да сте сигурни, че действително ще се свърши, докато ви няма.

Списък 3 Изпълнение на задачата с помощта на задача на агент

/* ==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

Заключение

В тази статия видяхме един начин за преместване на файлове с потребителска база данни в SQL Server. Ние също така видяхме необходимостта да се уверим, че обръщаме внимание на разрешенията за файла с данни на новото място, така че да не срещнем грешки при връщането на базата данни обратно онлайн. Ние също така видяхме, че можем да поставим всичко това в задача на SQL Server Agent, използвайки подсистемите T-SQL и PowerShell. В следваща статия ще видим два други метода за преместване на файлове от база данни в нов том.

Допълнително четене:

Преместване на файлове с данни в SQL Server – част 2


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. План за изпълнение на SQL Server — какво е това и как помага при проблеми с производителността?

  2. Разберете типа данни на колоните, върнати в набор от резултати в SQL Server

  3. Ръководство за CTE в SQL Server

  4. Как ISNUMERIC() работи в SQL Server

  5. Как да възстановите база данни от C#