استفاده از SQL Server به منظور مدیریت پشتیبان گیری دیتابیس در پایگاه داده ها
دوشنبه 11 مرداد 1395برای مدیریت کامل پایگاه داده ها و پشتیبان گیری پایگاه داده ها ، کپی کردن در شبکه و حذف آن ها تنها از روش stored procedure استفاده می شود.در این مقاله قصد داریم در مورد این روش ها صحبت نماییم.برای درک بهتر موضوع مقاله را مطالعه نمایید.
در این مقاله می خواهیم در مورد مدیریت پشتیبان گیری پایگاه داده صحبت نماییم و تنها روش انجام آن هم استفاده از روش stored procedure است.
این procedure ها که استفاده می شوند با دو سرور و یک شبکه از سرور و یک pc مدیریت می شوند.
اهداف این سیستم عبارت اند از :
1-انجام پشتیبان گیری پایگاه داده
2-کپی پشتیبان گیری بین هر سرور
3-کپی پشتیبان گیری بر روی کامپیوتر دیگر در همان شبکه
4-حذف پشتیبان گیری قدیمی تر از n روز
برای فعال کردن command shell می توانید از کوئری زیر استفاده کنید:
EXEC sp_configure 'show advanced options', 1 GO EXEC sp_configure'xp_cmdshell', 1 GO
این سیستم بر اساس 3 روش مختلف است:
usp_DatabaseBackup_CheckFolderPath :چک می کند که آیا stored procedure ذخیره شده در مسیر ورودی وجود داشته باشد یا نه؟
usp_DatabaseBackUp_CleanUp:تمام فایل ها از یک مسیر خاص حذف می شوند.
usp_DatabaseBackup_Main:انجام پشتیبان گیری محلی، و استفاده از دو روش دیگر برای کپی کردن و حذف پشتیبان گیری از راه های دیگر
1-usp_DatabaseBackup_CheckFolderPath:
این دستور در نتیجه مجموعه ای با تمام فایل ها و پوشه های موجود در یک مسیر خاص را بر می گرداند، فایل ها با زمینه ی isFile=1 و پوشه ها با زمینه ی isFile=0 مشخص شده اند.
پارامتر ورودی Folder_Path مسیر کامل یک پوشه است.
به صورت زیر:
@Folder_Path ex.: "C:\Folder1\Backup"
زمانی که فایل backup در پوشه ی پشتیبان گیری مقصد است، stored procedure آخرین پوشه را از این مسیر و با استفاده از xp_dirtree در مسیر resault به دنبال آخرین نام پوشه ی مشخص شده با isfile=0 است.
CREATE PROCEDURE [dbo].[usp_DatabaseBackup_CheckFolderPath]
@Folder_Path VARCHAR(1000),
@FolderExist INT OUTPUT
AS
iF @Folder_Path LIKE '%' + '\'
SET @Folder_Path = substring(@Folder_Path, 1, len(@Folder_Path) - len('\'))
--Create a temp table to hold the results.
IF OBJECT_ID('tempdb..#DirectoryTree') IS NOT NULL
DROP TABLE #DirectoryTree;
CREATE TABLE #DirectoryTree (
id INT IDENTITY(1,1)
,fullpath VARCHAR(2000)
,subdirectory NVARCHAR(512)
,depth INT
,isfile BIT);
DECLARE @LastFolder AS NVARCHAR(255),@SemiPath as nvarchar(255)
SET @LastFolder = REVERSE(SUBSTRING(REVERSE(@Folder_Path),0,CHARINDEX('\',REVERSE(@Folder_Path))))
set @SemiPath = REPLACE(@Folder_Path,@LastFolder,'')
INSERT #DirectoryTree (subdirectory,depth,isfile)
EXEC master.sys.xp_dirtree @SemiPath,1,1;
DECLARE @RETVAL AS INT = 0
SELECT @FolderExist = 1
FROM #DirectoryTree
WHERE isfile = 0 AND subdirectory = @LastFolder
RETURN
GO
2-usp_DatabaseBackUp_CleanUp
برای نام گذاری فایل های پشتیبان با استفاده از این روش:
YYYYMMDD_SERVERNAME_DBVersion_DatabaseName
برای نام گذاری این فایل ها باید از تاریخ انقضای فایل های backup و بعد ورژن پایگاه داده و بعد نام دیتابیس خود را اضافه نماییم.
GO
CREATE PROCEDURE [dbo].[usp_DatabaseBackUp_Cleanup]
@Folder_Path VARCHAR(1000),
@Exiration_Days INT
AS
DECLARE @Path VARCHAR(1000)
,@FullPath VARCHAR(2000)
,@Id INT;
--Create a temp table to hold the results.
IF OBJECT_ID('tempdb..#DirectoryTree') IS NOT NULL
DROP TABLE #DirectoryTree;
CREATE TABLE #DirectoryTree (
id int IDENTITY(1,1)
,fullpath varchar(2000)
,subdirectory nvarchar(512)
,depth int
,isfile bit);
IF OBJECT_ID('tempdb..#BackUpTable') IS NOT NULL
DROP TABLE #BackUpTable
CREATE TABLE #BackUpTable (
Id int identity(1,1),
FileDate Datetime,
Name varchar(1000),
FullPath varchar(8000),
)
--Populate the table using the initial base path.
INSERT #DirectoryTree (subdirectory,depth,isfile)
EXEC master.sys.xp_dirtree @Folder_Path,1,1;
UPDATE #DirectoryTree SET fullpath = @Folder_Path;
--Loop through the table as long as there are still folders to process.
WHILE EXISTS (SELECT id FROM #DirectoryTree WHERE isfile = 0)
BEGIN
--Select the first row that is a folder.
SELECT TOP (1)
@Id = id
,@FullPath = fullpath
,@Path = @Folder_Path + '\' + subdirectory
FROM #DirectoryTree WHERE isfile = 0;
IF @FullPath = @Path
BEGIN
--Do this section if the we are still in the same folder.
INSERT #DirectoryTree (subdirectory,depth,isfile)
EXEC master.sys.xp_dirtree @Path,1,1;
UPDATE #DirectoryTree
SET fullpath = @Path
WHERE fullpath IS NULL;
--Delete the processed folder.
DELETE FROM #DirectoryTree WHERE id = @Id;
END
ELSE
BEGIN
--Do this section if we need to jump down into another subfolder.
SET @Folder_Path = @FullPath;
--Select the first row that is a folder.
SELECT TOP (1)
@Id = id
,@FullPath = fullpath
,@Path = @Folder_Path + subdirectory
FROM #DirectoryTree WHERE isfile = 0;
INSERT #DirectoryTree (subdirectory,depth,isfile)
EXEC master.sys.xp_dirtree @Path,1,1;
UPDATE #DirectoryTree
SET fullpath = @Path
WHERE fullpath IS NULL;
--Delete the processed folder.
DELETE FROM #DirectoryTree WHERE id = @Id;
END
END
--Output the results.
insert into #BackUpTable
SELECT CASE
WHEN CHARINDEX('_',subdirectory) > 0 AND ISNUMERIC(SUBSTRING(subdirectory,0,CHARINDEX('_',subdirectory))) = 1 THEN CAST(SUBSTRING(subdirectory,0,CHARINDEX('_',subdirectory)) AS DATETIME)
ELSE DATEADD(DD,DATEDIFF(DD,0,GETDATE()),0)
END AS FileDate
,
subdirectory,
fullpath + '\' + subdirectory AS 'CompleteFileList'
FROM #DirectoryTree
WHERE subdirectory LIKE '%.bak'
ORDER BY fullpath,subdirectory;
DECLARE @CMDTOEXEC AS NVARCHAR(4000)
SET @CMDTOEXEC = ''
SELECT @CMDTOEXEC = @CMDTOEXEC + 'exec xp_cmdshell ''del "' + FullPath + '"'';'
FROM #BackUpTable
WHERE FileDate < DATEADD(DD,DATEDIFF(DD,@Exiration_Days,GETDATE()),0)
EXEC sp_executesql @CMDTOEXEC
--Cleanup.
IF OBJECT_ID('tempdb..#DirectoryTree') IS NOT NULL
DROP TABLE #DirectoryTree;
IF OBJECT_ID('tempdb..#BackUpTable') IS NOT NULL
DROP TABLE #BackUpTable;
3-usp_DatabaseBackup_Main
با استفاده از این procedure شما می توانید از دو روش دیگر برای انجام عمل پشتیبان گیری استفاده نمایید.
3 پارامتر وجود دارد:
1-@Server_Local_Path
یک مسیر محلی برای صرفه جویی در backup استفاده می شود.
2-@Backup_Expiration_Days
پاک کردن فایل های backup مثلا به صورت پیش فرض 10 روز
3-@Other_Network_Path
یک مسیر برای صرفه جویی فایل های پشتیبان گیری که به صورت پیش فرض خالی است.
CREATE PROCEDURE [dbo].[usp_DatabaseBackup_Main]
@Server_Local_Path AS VARCHAR(1000),
@Backup_Expiration_Days INT =10,
@Other_Network_path AS NVARCHAR(4000) = ''
AS
-- ******************************** Declare stored procedure variables **************************************
DECLARE @dbName AS sysname
DECLARE @dbVers AS NVARCHAR(1000)
DECLARE @Date as DATETIME,@MESSAGE AS NVARCHAR(MAX)
DECLARE @now AS DATETIME
DECLARE @nowStr AS VARCHAR(25)
DECLARE @backupFileFullPath AS VARCHAR(MAX)
DECLARE @serverName AS sysname
DECLARE @MirroredServerName AS VARCHAR(50)
DECLARE @mirroring_partner_instance AS VARCHAR(50)
DECLARE @Copy_cmd_From_Mirror_To_Principal AS VARCHAR(4000)
DECLARE @Copy_cmd_From_Principal_To_Mirror AS VARCHAR(4000)
DECLARE @CopyFromPrincipalToOtherCMD AS VARCHAR(4000)
-- ******************************** Fill variable with correct value **************************************
SELECT @mirroring_partner_instance = mirroring_partner_instance
FROM sys.database_mirroring
WHERE mirroring_partner_instance IS NOT NULL
SET @MirroredServerName = SUBSTRING(@mirroring_partner_instance,0,CHARINDEX('\',@mirroring_partner_instance))
SET @DATE = GETDATE()
SELECT @dbName = DB_NAME()
SET @serverName = REPLACE(CONVERT(sysname, SERVERPROPERTY(N'servername')) , '\', '$')
SELECT @Other_Network_path = CASE
WHEN SUBSTRING(@Other_Network_path,LEN(@Other_Network_path),LEN(@Other_Network_path)) = '\' THEN @Other_Network_path
WHEN @Other_Network_path <> '' THEN @Other_Network_path + '\'
ELSE @Other_Network_path
END
SELECT @dbVers = SUBSTRING(SUBSTRING(@@VERSION,CHARINDEX('-',@@VERSION)+2,LEN(@@VERSION)),0,CHARINDEX(' ',SUBSTRING(@@VERSION,CHARINDEX('-',@@VERSION)+2,LEN(@@VERSION))))
set @Server_Local_Path = CASE
WHEN SUBSTRING(@Server_Local_Path,LEN(@Server_Local_Path),LEN(@Server_Local_Path)) = '\' THEN @Server_Local_Path
WHEN @Server_Local_Path <> '' THEN @Server_Local_Path + '\'
ELSE @Server_Local_Path
END
SET @now = GETDATE()
SET @nowStr = CAST(DATEPART(yyyy, @now) AS VARCHAR)
IF DATEPART(mm, @now) < 10 SET @nowStr = @nowStr + '0'
SET @nowStr = @nowStr + CAST(DATEPART(mm, @now) AS VARCHAR)
IF DATEPART(dd, @now) < 10 SET @nowStr = @nowStr + '0'
SET @nowStr = @nowStr + CAST(DATEPART(dd, @now) AS VARCHAR)
SET @nowStr = @nowStr + '_'
IF DATEPART(hh, @now) < 10 SET @nowStr = @nowStr + '0'
SET @nowStr = @nowStr + CAST(DATEPART(hh, @now) AS VARCHAR)
IF DATEPART(mi, @now) < 10 SET @nowStr = @nowStr + '0'
SET @nowStr = @nowStr + CAST(DATEPART(mi, @now) AS VARCHAR)
IF DATEPART(ss, @now) < 10 SET @nowStr = @nowStr + '0'
SET @nowStr = @nowStr + CAST(DATEPART(ss, @now) AS VARCHAR)
-- ******************************** Perform backup **************************************
SET @backupFileFullPath = @Server_Local_Path + @nowStr + '_' + @serverName + '_' +@dbVers+'_' + @dbName + '.bak'
BACKUP DATABASE @dbName
TO DISK = @backupFileFullPath
WITH INIT
PRINT 'DB ''' + @dbName + ''' backed up to ''' + @backupFileFullPath + ''' file.'
-- set bak file full path
SET @backupFileFullPath = @Server_Local_Path + @nowStr + '_' + @serverName + '_' +@dbVers+'_' + @dbName + ' [TRANLOG].bak'
-- backup transaction log
BACKUP LOG @dbName
TO DISK = @backupFileFullPath
WITH NOFORMAT
, NOINIT
, SKIP
, STATS = 10;
PRINT 'BackUp database at following path: ' + @Server_Local_Path
-- ******************************** Check if all path exist **************************************
DECLARE @Mirror_Network_Path AS VARCHAR(4000)
SET @Mirror_Network_Path = '\\' + @MirroredServerName + '\' +REPLACE(@Server_Local_Path,':','$')
DECLARE @Server_Local_Path_Exist AS INT,@Mirror_Network_Path_Exist AS INT,@Other_Network_Path_Exist AS INT
EXECUTE [dbo].[usp_DatabaseBackup_CheckFolderPath] @Server_Local_Path,@FolderExist = @Server_Local_Path_Exist OUTPUT;
EXECUTE [dbo].[usp_DatabaseBackup_CheckFolderPath] @Mirror_Network_Path,@FolderExist = @Mirror_Network_Path_Exist OUTPUT;
EXECUTE [dbo].[usp_DatabaseBackup_CheckFolderPath] @Other_Network_path,@FolderExist = @Other_Network_Path_Exist OUTPUT;
-- ******************************** Delete old dabatase on current path **************************************
IF @Server_Local_Path <> '' AND @Server_Local_Path_Exist = 1
BEGIN
EXEC usp_DatabaseBackUp_Cleanup @Server_Local_Path,@Backup_Expiration_Days
END
-- ******************************** Delete old dabatase on other server path **************************************
IF @Mirror_Network_Path <> '' AND @Mirror_Network_Path_Exist = 1
BEGIN
EXEC usp_DatabaseBackUp_Cleanup @Mirror_Network_Path,@Backup_Expiration_Days
PRINT 'System clear up old bakcup files from following path: ' + ISNULL(@Mirror_Network_Path,'')
END
ELSE
BEGIN
PRINT 'Configuration key MirrorPath it''s not correctly setted or the path not exist. MirroPath calculated @Mirror_Network_Path: ' + ISNULL(@Mirror_Network_Path,'')
END
PRINT 'COPY START'
-- ******************************** Copy dabatase from principal server to mirror server *********************************
BEGIN TRY
SET @Copy_cmd_From_Mirror_To_Principal = 'xcopy "' + @Mirror_Network_Path + '*.bak" "' + @Server_Local_Path + '" /Y'
EXECUTE xp_cmdshell @Copy_cmd_From_Mirror_To_Principal
PRINT 'System copy backup from [' + @Mirror_Network_Path + '] to [' + @Server_Local_Path + ']'
SET @Copy_cmd_From_Principal_To_Mirror = 'xcopy "'+ @Server_Local_Path + '*.bak" "' + @Mirror_Network_Path + '" /Y'
EXECUTE xp_cmdshell @Copy_cmd_From_Principal_To_Mirror
PRINT 'System copy backup from [' + @Server_Local_Path + '] to [' + @Mirror_Network_Path + ']'
END TRY
BEGIN CATCH
PRINT 'Error Number = ' + ERROR_NUMBER() + '; Error Message = ' + ERROR_MESSAGE()
END CATCH;
-- ******************************** Delete old dabatase on other external PC path *********************************
-- if exernal path is not empty delete external old db files
IF @Other_Network_path <> ''
BEGIN
--select @Other_Network_Path_Exist as ExternalPathExist
IF @Other_Network_Path_Exist = 1
BEGIN
EXEC usp_DatabaseBackUp_Cleanup @Other_Network_path,@Backup_Expiration_Days
PRINT 'System clear up old bakcup files from following path: ' + ISNULL(@Other_Network_path,'')
-- ******************************** Copy dabatase from principal server to external PC *********************************
BEGIN TRY
SET @CopyFromPrincipalToOtherCMD = 'xcopy "'+ @Server_Local_Path + '*.bak" "'+ @Other_Network_path + '" /Y'
EXECUTE xp_cmdshell @CopyFromPrincipalToOtherCMD
PRINT 'System copy the backup from [' + @Server_Local_Path + '] to [' + @Other_Network_path + ']'
END TRY
BEGIN CATCH
PRINT 'Error Number = ' + ERROR_NUMBER() + '; Error Message = ' + ERROR_MESSAGE()
END CATCH;
END
END
- SQL Server
- 2k بازدید
- 3 تشکر