ما هي أفضل طريقة لنسخ قاعدة البيانات ؟
-
08-06-2019 - |
سؤال
عندما كنت ترغب في إنشاء نسخة من قاعدة البيانات, أنا دائما إنشاء قاعدة بيانات فارغة ثم استعادة نسخة احتياطية من قاعدة البيانات الموجودة فيه.ولكن أنا أتساءل إذا كان هذا هو حقا أقل عرضة للخطأ ، أقل تعقيدا و أكثر طريقة فعالة للقيام بذلك ؟
المحلول
النسخ الاحتياطي واستعادة هو الأكثر مباشرة إلى الأمام طريقة أعلم.عليك أن تكون حذرا بين ملقمات الأمن التفويض لا تأتي مع قاعدة البيانات المستعادة.
نصائح أخرى
فمن الممكن أن تخطي خطوة إنشاء قاعدة بيانات فارغة.يمكنك إنشاء قاعدة بيانات جديدة كجزء من عملية الاستعادة.
هذا هو في الواقع أسهل و أفضل طريقة أعرف أن استنساخ قاعدة البيانات الخاصة بنا.يمكنك القضاء على أخطاء البرمجة النصية النسخ الاحتياطي واستعادة العملية بدلا من تشغيله من خلال SQL Server إدارة Studio
هناك اثنين من الخيارات الأخرى التي يمكنك استكشاف:
- فصل قاعدة البيانات, نسخ .ملف mdf و إعادة إرفاق.
- استخدام SQL Server تكامل الخدمات (SSIS) لنسخ جميع الكائنات على
أقترح الخلاف مع النسخ الاحتياطي واستعادة وأتمتة إذا لزم الأمر.
وهنا ديناميكية النصي sql لقد استعملت في الماضي.يمكن أيضا تعديل ولكن سوف تعطيك الأساسيات.أنا أفضل البرمجة لتجنب الأخطاء التي يمكن أن تجعل استخدام إدارة Studio:
Declare @OldDB varchar(100)
Declare @NewDB varchar(100)
Declare @vchBackupPath varchar(255)
Declare @query varchar(8000)
/*Test code to implement
Select @OldDB = 'Pubs'
Select @NewDB = 'Pubs2'
Select @vchBackupPath = '\\dbserver\C$\Program Files\Microsoft SQL Server\MSSQL.1\MSSQL\Backup\pubs.bak'
*/
SET NOCOUNT ON;
Select @query = 'Create Database ' + @NewDB
exec(@query)
Select @query = '
Declare @vBAKPath varchar(256)
declare @oldMDFName varchar(100)
declare @oldLDFName varchar(100)
declare @newMDFPath varchar(100)
declare @newLDFPath varchar(100)
declare @restQuery varchar(800)
select @vBAKPath = ''' + @vchBackupPath + '''
select @oldLDFName = name from ' + @OldDB +'.dbo.sysfiles where filename like ''%.ldf%''
select @oldMDFName = name from ' + @OldDB +'.dbo.sysfiles where filename like ''%.mdf%''
select @newMDFPath = physical_name from ' + @NewDB +'.sys.database_files where type_desc = ''ROWS''
select @newLDFPath = physical_name from ' + @NewDB +'.sys.database_files where type_desc = ''LOG''
select @restQuery = ''RESTORE DATABASE ' + @NewDB +
' FROM DISK = N'' + '''''''' + @vBAKpath + '''''''' +
'' WITH MOVE N'' + '''''''' + @oldMDFName + '''''''' +
'' TO N'' + '''''''' + @newMDFPath + '''''''' +
'', MOVE N'' + '''''''' + @oldLDFName + '''''''' +
'' TO N'' + '''''''' + @newLDFPath + '''''''' +
'', NOUNLOAD, REPLACE, STATS = 10''
exec(@restQuery)
--print @restQuery'
exec(@query)
على نشر مقدم وظائف عمل عظيم بالنسبة لي.انظر سكوت قو بلوق دخول.
إذا كنت بحاجة إلى شيء حقا قوية ننظر redgate البرمجيات أدوات هنا...إذا كنت تفعل الكثير من SQL في كل هذه تستحق $$.
::================ BackUpAllMyDatabases.cmd ============= START
::BackUpAllMyDatabases.cmd
:: COMMAND LINE BATCH SCRIPT FOR TAKING BACKUP OF ALL DATABASES
::RUN THE SQL SCRIPT VIA THE COMMAND LINE WITH LOGGING
sqlcmd -S localhost -e -i "BackUpAllMyDatabases.sql" -o Result_Of_BackUpAllMyDatabases.log
::VIEW THE RESULTS
Result_Of_BackUpAllMyDatabases.log
::pause
::================ BackUpAllMyDatabases.cmd ============= END
--=================================================BackUpAllMyDatabases.sql start
DECLARE @DBName varchar(255)
DECLARE @DATABASES_Fetch int
DECLARE DATABASES_CURSOR CURSOR FOR
select
DATABASE_NAME = db_name(s_mf.database_id)
from
sys.master_files s_mf
where
-- ONLINE
s_mf.state = 0
-- Only look at databases to which we have access
and has_dbaccess(db_name(s_mf.database_id)) = 1
-- Not master, tempdb or model
--and db_name(s_mf.database_id) not in ('Master','tempdb','model')
group by s_mf.database_id
order by 1
OPEN DATABASES_CURSOR
FETCH NEXT FROM DATABASES_CURSOR INTO @DBName
WHILE @@FETCH_STATUS = 0
BEGIN
declare @DBFileName varchar(256)
set @DBFileName = @DbName + '_' + replace(convert(varchar, getdate(), 112), '-', '.') + '.bak'
--REMEMBER TO PUT HERE THE TRAILING \ FOR THE DIRECTORY !!!
exec ('BACKUP DATABASE [' + @DBName + '] TO DISK = N''D:\DATA\BACKUPS\' +
@DBFileName + ''' WITH NOFORMAT, INIT, NAME = N''' +
@DBName + '-Full Database Backup'', SKIP, NOREWIND, NOUNLOAD, STATS = 100')
FETCH NEXT FROM DATABASES_CURSOR INTO @DBName
END
CLOSE DATABASES_CURSOR
DEALLOCATE DATABASES_CURSOR
--BackUpAllMyDatabases==========================end
--======================RestoreDbFromFile.sql start
-- Restore database from file
-----------------------------------------------------------------
use master
go
declare @backupFileName varchar(100), @restoreDirectory varchar(100),
@databaseDataFilename varchar(100), @databaseLogFilename varchar(100),
@databaseDataFile varchar(100), @databaseLogFile varchar(100),
@databaseName varchar(100), @execSql nvarchar(1000)
-- Set the name of the database to restore
set @databaseName = 'ReplaceDataBaseNameHere'
-- Set the path to the directory containing the database backup
set @restoreDirectory = 'ReplaceRestoreDirectoryHere' -- such as 'c:\temp\'
-- Create the backup file name based on the restore directory, the database name and today's date
@backupFileName = @restoreDirectory + @databaseName + '-' + replace(convert(varchar, getdate(), 110), '-', '.') + '.bak'
-- set @backupFileName = 'D:\DATA\BACKUPS\server.poc_test_fbu_20081016.bak'
-- Get the data file and its path
select @databaseDataFile = rtrim([Name]),
@databaseDataFilename = rtrim([Filename])
from master.dbo.sysaltfiles as files
inner join
master.dbo.sysfilegroups as groups
on
files.groupID = groups.groupID
where DBID = (
select dbid
from master.dbo.sysdatabases
where [Name] = @databaseName
)
-- Get the log file and its path
select @databaseLogFile = rtrim([Name]),
@databaseLogFilename = rtrim([Filename])
from master.dbo.sysaltfiles as files
where DBID = (
select dbid
from master.dbo.sysdatabases
where [Name] = @databaseName
)
and
groupID = 0
print 'Killing active connections to the "' + @databaseName + '" database'
-- Create the sql to kill the active database connections
set @execSql = ''
select @execSql = @execSql + 'kill ' + convert(char(10), spid) + ' '
from master.dbo.sysprocesses
where db_name(dbid) = @databaseName
and
DBID <> 0
and
spid <> @@spid
exec (@execSql)
print 'Restoring "' + @databaseName + '" database from "' + @backupFileName + '" with '
print ' data file "' + @databaseDataFile + '" located at "' + @databaseDataFilename + '"'
print ' log file "' + @databaseLogFile + '" located at "' + @databaseLogFilename + '"'
set @execSql = '
restore database [' + @databaseName + ']
from disk = ''' + @backupFileName + '''
with
file = 1,
move ''' + @databaseDataFile + ''' to ' + '''' + @databaseDataFilename + ''',
move ''' + @databaseLogFile + ''' to ' + '''' + @databaseLogFilename + ''',
norewind,
nounload,
replace'
exec sp_executesql @execSql
exec('use ' + @databaseName)
go
-- If needed, restore the database user associated with the database
/*
exec sp_revokedbaccess 'myDBUser'
go
exec sp_grantdbaccess 'myDBUser', 'myDBUser'
go
exec sp_addrolemember 'db_owner', 'myDBUser'
go
use master
go
*/
--======================RestoreDbFromFile.sql