We usually need to duplicate our databases to test servers which have different disk layouts than production server. So we need to distribute the datafiles according to the disk space and directory structure of the new server. It becomes a time-consuming task if you’re dealing with hundreds of datafiles. Today I saw a PL/SQL script written by Bobby Durrett for renaming datafiles for RMAN restore. It produces required “set newname” commands which can be used by RMAN. That was a great idea and I decided to write my own version to satisfy my needs:
DECLARE CURSOR DF_CURSOR IS SELECT 'data' ft, FILE_ID, FILE_NAME, BYTES / (1024 * 1024 * 1024) fsize FROM dba_data_files union all SELECT 'temp' ft, FILE_ID, FILE_NAME, BYTES / (1024 * 1024 * 1024) fsize FROM dba_temp_files ORDER BY ft, file_id; TYPE array_number IS TABLE OF NUMBER; TYPE array_varchar2 IS TABLE OF VARCHAR2 (200); diskno NUMBER; diskspace array_number := array_number ( 30, 20, 20, 120); -- Sizes in GB diskpath array_varchar2 := array_varchar2 ( '/u01/data', '/u02/data', '/u03/data', '/u04/data'); prefix VARCHAR2 (200) := '/SID'; -- will be added to diskpaths BEGIN FOR df IN DF_CURSOR LOOP FOR diskno IN 1 .. diskspace.COUNT LOOP IF (diskspace (diskno) > df.fsize) THEN DBMS_OUTPUT.put_line ( 'set newname for ' || df.ft || 'file ' || df.FILE_ID || ' to ''' || diskpath (diskno) || prefix || SUBSTR (df.FILE_NAME, INSTR (df.FILE_NAME, '/', -1)) || ''';'); diskspace (diskno) := diskspace (diskno) - df.fsize; EXIT; END IF; END LOOP; END LOOP; END; /
It’s very easy to edit this script. You just need to enter the disk partitions and available/free disk spaces (in gigabytes) on them (line 17 and 13). While entering the disk space in GBs, round the size down. You can set “prefix” (line 29) to empty string if you don’t want to use it. Here’s a sample output:
set newname for datafile 1 to '/u01/data/SID/sys1.dbf'; set newname for datafile 2 to '/u01/data/SID/tx_data11.dbf'; set newname for datafile 3 to '/u01/data/SID/tx_idx11.dbf'; set newname for datafile 4 to '/u01/data/SID/undotbs_01.dbf'; ... set newname for datafile 296 to '/u04/data/SID/archive3.dbf'; set newname for tempfile 1 to '/u04/data/SID/mgmt_temp.dbf'; set newname for tempfile 2 to '/u04/data/SID/ERP_iastemp.dbf';
I haven’t tested the output of the script yet and I also made some small modifications right before publishing it, so there might be some errors. I would be happy to hear your feedback.