Если rman restore остановился по причине какой-то ошибки, как продолжить восстановление с места остановки, не начиная всё сначала?

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

Сценарий, запускаем восстановление бд через rman(restore database) и, через какое-то время получаем ошибку:

RMAN-00571: ===========================================================

RMAN-00569: =============== ERROR MESSAGE STACK FOLLOWS ===============

RMAN-00571: ===========================================================

ORA-19870: error while restoring backup piece 856802_vg1qa4qf_1_1

ORA-19504: failed to create file "+DATA"

ORA-17502: ksfdcre:4 Failed to create file +DATA

ORA-15041: diskgroup "DATA" space exhausted

И как бы всё… решив проблему с ORA-15041, нужно либо начинать рестор по новой(овер 40ТБ), либо вычислять вручную или ещё как-то, что было восстановлено(~1800 файлов) и долить только нужное(~120 файлов), сконструировав на вышеизложенное новый rman скрипт.

Но можно воспользоваться скриптами:

Вариант 1:

select q'!set newname for DATAFILE !'||datafiled||q'! to '+ASMDG';!' from (
select 
dcopy.file# fcopy,d.file# datafiled 
from 
(
select file# from v$datafile_copy c where c.name is not null
order by c.file#) dcopy right join v$datafile d on dcopy.file#=d.file#)
where fcopy is null
union all
select q'!restore datafile !'||dfiled||q'!;!' from (select 
dcopy.file# fcopy,d.file# dfiled 
from 
(
select file# from v$datafile_copy c where c.name is not null
order by c.file#) dcopy right join v$datafile d on dcopy.file#=d.file#)
where fcopy is null

Вариант 2(в последней строчке вывода результата, нужно заменить запятую на точку с запятой):

select q'!set newname for DATAFILE !'||datafiled||q'! to '+ASMDG';!' from (
select 
dcopy.file# fcopy,d.file# datafiled 
from 
(
select file# from v$datafile c where c.bytes=0 
order by c.file#) dcopy left join v$datafile d on dcopy.file#=d.file#)
union all
select q'!restore datafile !' from dual
union all
select dfiled||q'!,!' from (select 
dcopy.file# fcopy,d.file# dfiled 
from 
(
select file# from v$datafile c where c.bytes=0
order by c.file#) dcopy left join v$datafile d on dcopy.file#=d.file#)

Оба скрипта формируют “set newname for DATAFILE” и “ restore datafile” для каждого файла данных, который нужно восстановить. Оборачиваем вывод скрипта в run блок и запускаем, после того как все файлы восстановлены(restore), выполняем switch database to copy, и продолжаем recover.

Следует, однако, заметить, что, при определённых обстоятельствах, скрипт(особенно вариант 1) будет работать не верно, например на нормально работающей бд в режиме open, вывод скрипта не будет совпадать с реальностью, т.к. в v$datafile_copy может не быть записей, а может быть и наоборот (много записей в v$datafile_copy) и это нормально.

Поэтому, дабы не завалить бд, будьте аккуратны.