Есть ли способ избежать ошибок MOVE при восстановлении скрипта? - PullRequest
0 голосов
/ 14 июня 2019

Я некоторое время искал эту проблему и не могу найти решение, если ее нет.

Каждую неделю мы получаем новые базы данных от клиентов. Я разработал инструмент для восстановления наших собственных баз данных, чтобы все базы данных оставались вместе с клиентскими. Инструмент работает для некоторых баз данных, но в других я получаю некоторые ошибки из-за файлов журнала.

Мой скрипт для восстановления базы данных следующий

USE [master] 
ALTER DATABASE[MyDataBase] SET SINGLE_USER WITH ROLLBACK IMMEDIATE 
RESTORE DATABASE[MyDataBase] 
FROM  DISK = N'MyDataBase.bak' 
WITH NOUNLOAD, 
REPLACE, STATS = 5 
ALTER DATABASE[MyDataBase] SET MULTI_USER

Я знаю, что если я использую команду MOVE, я смогу справиться со своей проблемой, дело в том, что у меня нет возможности узнать файлы заранее, то есть я не могу написать какой-либо специальный код для восстановления баз данных.

Углубившись немного глубже, я обнаружил, что могу распечатать все мои файлы журналов из базы данных с помощью следующей команды

SELECT 
  DB_NAME([database_id]) [database_name]
, [file_id]
, [type_desc] [file_type]
, [name] [logical_name]
, [physical_name]
FROM sys.[master_files]
WHERE [database_id] IN (DB_ID('MyDataBase'))
ORDER BY [type], DB_NAME([database_id]);

но файлы, представленные там, имеют совершенно отличные имена от тех, с которыми я получаю сообщение об ошибке.

Еще одна важная вещь, на которую следует обратить внимание: если я восстановлю базу данных, а затем попытаюсь восстановить через tsql, я смогу выполнить восстановление, но у меня есть задание агента сервера, которое переименовывает файлы, чтобы сохранить их в чистоте, и после запуска я невозможно восстановить базу данных снова, выдавая те же ошибки, что и перед восстановлением вручную.

Я понятия не имею, достижимо ли то, чего я пытаюсь достичь, и если да, то как этого достичь. Если бы кто-нибудь мог дать мне немного света, это было бы удивительно

1 Ответ

2 голосов
/ 14 июня 2019

ВОССТАНОВИТЬ FILELISTONLY сообщит вам файлы, и вы можете создать ВОССТАНОВЛЕНИЕ ... С ПЕРЕМЕЩЕНИЕМ из этого:

EG

--backup database a to disk='c:\temp\a.bak'

declare @fn nvarchar(255) = 'c:\temp\a.bak';
declare @sql nvarchar(max) = concat('restore filelistonly from disk=''',@fn,'''');
declare @targetFolder nvarchar(max) = 'c:\temp\customer_123';
declare @dbname sysname = 'a_123';

declare @t table
(
LogicalName nvarchar(128),--,   --Logical name of the file.
PhysicalName    nvarchar(260),--    Physical or operating-system name of the file.
Type    char(1),--  The type of file, one of:
FileGroupName   nvarchar(128) NULL, --  Name of the filegroup that contains the file.
Size    numeric(20,0),--    Current size in bytes.
MaxSize numeric(20,0),--    Maximum allowed size in bytes.
FileID  bigint,--   File identifier, unique within the database.
CreateLSN   numeric(25,0),--    Log sequence number at which the file was created.
DropLSN numeric(25,0) NULL, --  The log sequence number at which the file was dropped. If the file has not been dropped, this value is NULL.
UniqueID    uniqueidentifier,-- Globally unique identifier of the file.
ReadOnlyLSN numeric(25,0) NULL, --  Log sequence number at which the filegroup containing the file changed from read-write to read-only (the most recent change),--.
ReadWriteLSN    numeric(25,0) NULL, --  Log sequence number at which the filegroup containing the file changed from read-only to read-write (the most recent change),--.
BackupSizeInBytes   bigint, --  Size of the backup for this file in bytes.
SourceBlockSize int, -- Block size of the physical device containing the file in bytes (not the backup device),--.
FileGroupID int,-- ID of the filegroup.
LogGroupGUID    uniqueidentifier NULL, --   NULL.
DifferentialBaseLSN numeric(25,0) NULL, --  For differential backups, changes with log sequence numbers greater than or equal to DifferentialBaseLSN are included in the differential 
DifferentialBaseGUID    uniqueidentifier NULL, --   For differential backups, the unique identifier of the differential base.
IsReadOnly  bit,--  1 = The file is read-only.
IsPresent   bit,--  1 = The file is present in the backup.
TDEThumbprint   varbinary(32) NULL, --  Shows the thumbprint of the Database Encryption Key. The encryptor thumbprint is a SHA-1 hash of the certificate with which the key is encrypted. For information about database encryption, see Transparent Data Encryption (TDE),--.
SnapshotURL nvarchar(360)-- NULL    The URL for the Azure snapshot of the database file contained in the FILE_SNAPSHOT backup. Returns NULL if no FILE_SNAPSHOT backup.
);
insert into @t
exec (@sql);


with q as 
(
select concat('restore database ',@dbname,' from disk=''',@fn,''' with ') l
union all
select concat('
move ''',LogicalName,''' to ''', @targetFolder, '\', LogicalName, case [type] when 'D' then '.mdf' when 'L' then '.ldf' else null end, ''' , ')
from @t 
union all
select 'RECOVERY, STATS = 10'
)
select @sql = STRING_AGG(l,'
')
from q;


print (@sql);
exec (@sql );
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...