Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Microsoft SQL Server Новый топик    Ответить
 Как определить ID базы, к которой применяется команда восстановления?  [new]
Alexander Us
Member

Откуда:
Сообщений: 1130
Как определить ID базы, к которой применяется команда восстановления полного/дифф/лога?

Следующая команда даёт "почти" желаемое, но приходится имя базы вычитывать из столбца "query" вручную,
а столбец database_id выдает = 1 (master)

Пожалуйста, не предлагайте парзить столбец "query" на имя базы.

SELECT 
  session_id 
, command
, a.text AS query
, database_id --> master
FROM sys.dm_exec_requests r CROSS APPLY sys.dm_exec_sql_text(r.sql_handle) a
WHERE r.command in ('BACKUP DATABASE','RESTORE DATABASE') 
30 сен 19, 15:39    [21982863]     Ответить | Цитировать Сообщить модератору
 Re: Как определить ID базы, к которой применяется команда восстановления?  [new]
Гавриленко Сергей Алексеевич
Member

Откуда: Moscow
Сообщений: 36965
Никак, кроме того, как вам не предлагать. Ну еще в extended events может что есть.

Сообщение было отредактировано: 30 сен 19, 15:43
30 сен 19, 15:43    [21982871]     Ответить | Цитировать Сообщить модератору
 Re: Как определить ID базы, к которой применяется команда восстановления?  [new]
Alexander Us
Member

Откуда:
Сообщений: 1130
Гавриленко Сергей Алексеевич,


спасибо за идею.

Сажется, с (примерно) таким запросом можно что то получить:
SELECT	top 100
	te.name, 
	ft.SPID,
	ft.LoginName,
	ft.Hostname,
	ft.ClientProcessID,
	ft.DatabaseName, 
	ft.FileName, 
	ft.StartTime, 
	dateadd(ms,ft.Duration/1000,ft.StartTime) [FinishTime],
	ft.ApplicationName ,
	ft.ObjectID,
	ft.Duration/1000/1000 [Duration (s)],
	ft.TextData,
	ft.RoleName,
	ft.TargetUserName,
	ft.TargetLoginName
FROM sys.traces st 
CROSS Apply ::fn_trace_gettable(reverse(stuff(reverse(st.path),1,charindex('_',reverse(st.path)),'crt.')), st.max_files) AS ft 
INNER JOIN sys.trace_events AS te ON ft.EventClass = te.trace_event_id 
WHERE 1=1
	and  te.name LIKE 'Audit Backup/Restore Event'  
	and st.is_default=1 
	and st.status=1
ORDER BY ft.StartTime desc;
30 сен 19, 16:45    [21982978]     Ответить | Цитировать Сообщить модератору
 Re: Как определить ID базы, к которой применяется команда восстановления?  [new]
Владислав Колосов
Member

Откуда:
Сообщений: 7754
Alexander Us,

в sys.databases разве не указан статус базы?
30 сен 19, 17:25    [21983023]     Ответить | Цитировать Сообщить модератору
 Re: Как определить ID базы, к которой применяется команда восстановления?  [new]
Гавриленко Сергей Алексеевич
Member

Откуда: Moscow
Сообщений: 36965
Владислав Колосов,

Будет проблематично выяснить, какой процесс какую ресторит базу, если одновременно запущено более одного процесса рестора.

Сообщение было отредактировано: 30 сен 19, 17:33
30 сен 19, 17:32    [21983037]     Ответить | Цитировать Сообщить модератору
 Re: Как определить ID базы, к которой применяется команда восстановления?  [new]
Владислав Колосов
Member

Откуда:
Сообщений: 7754
Гавриленко Сергей Алексеевич,

я думаю, что lock на базу будет держать единственный SPID, хотя и не проверял.
30 сен 19, 18:03    [21983061]     Ответить | Цитировать Сообщить модератору
 Re: Как определить ID базы, к которой применяется команда восстановления?  [new]
teCa
Member

Откуда:
Сообщений: 628
А разве select database_id from sys.dm_exec_requests where command='BACKUP DATABASE' это не покажет?
30 сен 19, 18:36    [21983110]     Ответить | Цитировать Сообщить модератору
 Re: Как определить ID базы, к которой применяется команда восстановления?  [new]
teCa
Member

Откуда:
Сообщений: 628
teCa,

select database_id,DB_NAME (database_id) as [NAME] from sys.dm_exec_requests

Разве не этот результат необходим?
30 сен 19, 18:40    [21983117]     Ответить | Цитировать Сообщить модератору
 Re: Как определить ID базы, к которой применяется команда восстановления?  [new]
Гавриленко Сергей Алексеевич
Member

Откуда: Moscow
Сообщений: 36965
teCa,

Вы пробовали читать хотя бы первый пост темы до конца?
30 сен 19, 18:51    [21983132]     Ответить | Цитировать Сообщить модератору
 Re: Как определить ID базы, к которой применяется команда восстановления?  [new]
Alexander Us
Member

Откуда:
Сообщений: 1130
Владислав Колосов,

Если восстанавливается база с опцией "NORECOVERY", то её статус будет RESTORING, как во премя восстановления, так и после его окончания.

С идеей Сергейя Алексеевича, думаю, можно допилить приведённый мной запрос.
Если что то получится, выложу.
30 сен 19, 19:36    [21983175]     Ответить | Цитировать Сообщить модератору
 Re: Как определить ID базы, к которой применяется команда восстановления?  [new]
Alexander Us
Member

Откуда:
Сообщений: 1130
Всем спасибо.

Получается как то так:
;WITH RST as
(
	SELECT TOP 1000
		 ft.SPID	
		,ft.DatabaseName 
		,ft.DatabaseID      --by (full) restore database is null 
		,ft.StartTime	
		,cast(ft.TextData	 as nvarchar(max)) TextData
		,ft.ClientProcessID 
		,ft.HostName 			 
	FROM 
	            sys.traces st 
	CROSS APPLY ::fn_trace_gettable(reverse(stuff(reverse(st.path),1,charindex('_',reverse(st.path)),'crt.')), st.max_files) AS ft 
	INNER JOIN  sys.trace_events AS te ON ft.EventClass = te.trace_event_id 
	WHERE te.name LIKE 'Audit Backup/Restore Event'   
	ORDER BY ft.StartTime desc
)
, QVR as
(
	SELECT 	
	  req.command type				
	, SUBSTRING(sqltext.text, (req.statement_start_offset/2)+1, 
	((CASE req.statement_end_offset
		WHEN -1 THEN DATALENGTH(sqltext.text)
		ELSE req.statement_end_offset
		END - req.statement_start_offset)/2) + 1) AS statement_text    
	,db_name(req.database_id) db_name
	,req.percent_complete 
	,req.estimated_completion_time 
	,req.session_id as s_id
	,req.status as req_status		
	,ses.host_name	
	,ses.host_process_id	
	,req.start_time 
	FROM 
				sys.dm_exec_requests req with(nolock)	
	INNER JOIN  sys.dm_exec_sessions ses with(nolock) on req.session_id=ses.session_id			 
	CROSS APPLY sys.dm_exec_sql_text(req.sql_handle)  AS sqltext 	
	where 1=1    
	and req.session_id <> @@SPID
)
select 
 a.SPID 
,b.type 
,(select d.dbid  from sysdatabases d where a.DatabaseName = d.name ) database_id
,a.DatabaseName 
,a.TextData 
,b.percent_complete
, RTRIM(estimated_completion_time/1000/3600)+':'+RIGHT('0'+RTRIM((estimated_completion_time/1000)%3600/60), 2)+':'+RIGHT('0'+RTRIM((estimated_completion_time/1000)%60), 2) AS TimeRemaining
 from 	
RST a join QVR b on a.TextData = b.statement_text 
and a.StartTime = b.start_time 
and a.SPID = b.s_id 
and a.ClientProcessID = b.host_process_id 


SPIDtypedatabase_idDatabaseNameTextDatapercent_completeTimeRemaining
63RESTORE DATABASE16myDBrestore database [myDB] from disk = 'X:\myDB_backup.full' with norecovery запятая stats=139.720:51:52
1 окт 19, 10:11    [21983485]     Ответить | Цитировать Сообщить модератору
 Re: Как определить ID базы, к которой применяется команда восстановления?  [new]
teCa
Member

Откуда:
Сообщений: 628
Гавриленко Сергей Алексеевич
teCa,

Вы пробовали читать хотя бы первый пост темы до конца?


Если вы про то, что если в случае command in ('BACKUP DATABASE','RESTORE DATABASE'), database_id всегда равно 1, то об этом можно догадаться только из вашего замечания. И то, я до сиз пор не уверен, правильно ли я его понял.
1 окт 19, 10:47    [21983544]     Ответить | Цитировать Сообщить модератору
 Re: Как определить ID базы, к которой применяется команда восстановления?  [new]
invm
Member

Откуда: Москва
Сообщений: 9345
Alexander Us
Получается как то так
Ненадежно и муторно.

Надежней и проще - sys.dm_tran_locks.
На восстанавливаемую БД накладывается X. Соответственно это и искать в sys.dm_tran_locks для сессии, выполняющей restore.
1 окт 19, 10:47    [21983545]     Ответить | Цитировать Сообщить модератору
 Re: Как определить ID базы, к которой применяется команда восстановления?  [new]
Владислав Колосов
Member

Откуда:
Сообщений: 7754
Мне интересно - для чего это вообще нужно? Для промышленных систем устанавливают специализированное ПО управления резервным копированием, для домашних и мелкоофисных - избыточно.
1 окт 19, 11:41    [21983628]     Ответить | Цитировать Сообщить модератору
 Re: Как определить ID базы, к которой применяется команда восстановления?  [new]
Alexander Us
Member

Откуда:
Сообщений: 1130
Владислав Колосов
Мне интересно - для чего это вообще нужно? ....


Владислав, остерегайтесь спрашивать некотрых людей о здоровье.
Можете получить слишком подробный ответ :))

Для для упрощения миграации кучи баз на другой сервер был сделан свой "пакетный" лог шиппинг.
Восстанавливаются логи всех баз, которые не учавствуют в зеркалировании и нативном лог шипинге.
При удалении зеркалирования база(ы) автоматически "подхватывается" на "пакетный" лог шиппинг.
Для восстановления логов достаточно указать корневой каталог, тул сам находит папку базы и файл лога, с которого можно продолжить восстановление.

Но захотелось ещё корректно исключать базы, для которых идёт полное или дифференциальное восстановление, а не отлавливать ошибку.

.........................
Специализированное ПО управления резервным копированием (Idera) не прижилось.
В принципе, Idera была не виновата, виноват был сетевой накопитель, который инвертировал 1 бит на ~700GB.
Но после этого использую нативное резервное копироване на локальный (шифрованный) USB диск с нативной проверкой, затем подсчёт хеш сумм, перенос в хранилище (robocopy), подсчёт хеш сумм там (локальный скрипт), сравнение хеш сумм.

С Уважением,
Александр
1 окт 19, 12:11    [21983694]     Ответить | Цитировать Сообщить модератору
 Re: Как определить ID базы, к которой применяется команда восстановления?  [new]
Alexander Us
Member

Откуда:
Сообщений: 1130
invm
Alexander Us
Получается как то так
Ненадежно и муторно.

Надежней и проще - sys.dm_tran_locks.
На восстанавливаемую БД накладывается X. Соответственно это и искать в sys.dm_tran_locks для сессии, выполняющей restore.


Спасибо.
Теперь так:

SELECT 	
 req.command type				
, SUBSTRING
	(sqltext.text
	,req.statement_start_offset/2+1
	,(
	    CASE req.statement_end_offset
		WHEN -1 THEN DATALENGTH(sqltext.text)
		ELSE req.statement_end_offset
		END - req.statement_start_offset
		)/2 + 1
	) AS statement_text    
,req.percent_complete 
,RTRIM(estimated_completion_time/1000/3600)+':'+RIGHT('0'+RTRIM((estimated_completion_time/1000)%3600/60), 2)+':'+RIGHT('0'+RTRIM((estimated_completion_time/1000)%60), 2) AS TimeRemaining
,req.session_id as s_id
,req.status as req_status		
,ses.host_name
,ses.host_process_id	
,req.start_time 
,lck.resource_database_id  database_id
,db_name(lck.resource_database_id) database_name
FROM 
     sys.dm_exec_requests req with(nolock)	
JOIN sys.dm_exec_sessions ses with(nolock) on req.session_id=ses.session_id			 	
JOIN sys.dm_tran_locks	 lck with(nolock) on req.session_id=lck.request_session_id 
CROSS APPLY sys.dm_exec_sql_text(req.sql_handle)  as sqltext 
where 1=1    
and req.session_id <> @@SPID
and lck.request_mode = 'X'
and lck.request_owner_type = 'EXCLUSIVE_TRANSACTION_WORKSPACE'
and sqltext.text like '%RESTORE DATABASE%'
1 окт 19, 15:56    [21984048]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить