Данная заметка направлена на то, чтобы сэкономит время на ручное вычисление недостающих файлов, которые нужно восстановить и исключить повторный запуск восстановления с нуля.
Сценарий, запускаем восстановление бд через 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) и это нормально.
Поэтому, дабы не завалить бд, будьте аккуратны.