For replication of database to new file system, we can use below script to split
production datafiles. It will generate set newname datafile output by evenly splitting based on available storage and checking & correcting duplicate file names.
Script input: List of file new file system name and size in GB for parameters
file_system_name (0) and file_system_size (0) in below script. Parameter m_threshold := 100 will keep 100GB free space for each file system.
SET serveroutput on
SET serveroutput on size 1000000
SET LINESIZE 120
DECLARE
TYPE str_array IS TABLE OF VARCHAR2 (100)
INDEX BY BINARY_INTEGER;
TYPE num_array IS TABLE OF NUMBER
INDEX BY BINARY_INTEGER;
file_system_name str_array;
file_system_size num_array;
path_selection NUMBER := 0;
m_threshold NUMBER := 0;
no_space_available EXCEPTION;
PROCEDURE rman_rename (
str_array_in str_array,
num_array_in IN OUT num_array,
threshold IN NUMBER
)
IS
BEGIN
FOR file_name1 IN
(SELECT file#, BYTES / 1024 / 1024 / 1024 AS gb, concat(RTRIM(file_name, '.dbf'),'.dbf') file_name
FROM (SELECT SUBSTR (NAME,
INSTR (NAME, '/', -1, 1) + 1
) file_name
FROM v$datafile
GROUP BY SUBSTR (NAME, INSTR (NAME, '/', -1, 1) + 1)
HAVING COUNT (1) = 1),
v$datafile
WHERE SUBSTR (NAME, INSTR (NAME, '/', -1, 1) + 1) = file_name
UNION ALL
SELECT file#, BYTES / 1024 / 1024 / 1024 AS gb, file_name
FROM (SELECT BYTES, file#,
SUBSTR
(SUBSTR (NAME, INSTR (NAME, '/', -1, 1) + 1),
1,
INSTR (SUBSTR (NAME,
INSTR (NAME, '/', -1,
1)
+ 1
),
'.',
1,
1
)
- 1
)
|| '_'
|| CHR
( 96
+ ROW_NUMBER () OVER (PARTITION BY file_name ORDER BY file_name)
)
|| '.dbf' file_name
FROM (SELECT COUNT (1),
SUBSTR (NAME,
INSTR (NAME, '/', -1, 1) + 1
) file_name
FROM v$datafile
GROUP BY SUBSTR (NAME, INSTR (NAME, '/', -1, 1) + 1)
HAVING COUNT (1) > 1),
v$datafile
WHERE SUBSTR (NAME, INSTR (NAME, '/', -1, 1) + 1) =
file_name)
ORDER BY 2 DESC)
LOOP
<<main_loop>>
LOOP
IF ((num_array_in (path_selection) - threshold) >= file_name1.gb
)
THEN
num_array_in (path_selection) :=
num_array_in (path_selection)
- file_name1.gb;
DBMS_OUTPUT.put_line ( 'set newname for DATAFILE '
|| file_name1.file#
|| ' to '
|| ''''
|| str_array_in (path_selection)
|| file_name1.file_name
|| ''''
|| ';'
--|| num_array_in (path_selection)
-- || '-->'
-- || file_name1.gb
);
IF (path_selection = str_array_in.COUNT - 1)
THEN
path_selection := 0;
ELSE
path_selection := path_selection + 1;
END IF;
EXIT main_loop;
ELSE
IF (path_selection < str_array_in.COUNT - 1)
THEN
path_selection := path_selection + 1;
GOTO main_loop;
ELSE
RAISE no_space_available;
END IF;
END IF;
END LOOP;
END LOOP;
DBMS_OUTPUT.put_line ('Remaining Space');
DBMS_OUTPUT.put_line ('---------------');
FOR i IN 1 .. num_array_in.COUNT
LOOP
DBMS_OUTPUT.put_line ( 'PATH-->'
|| str_array_in (i - 1)
|| ' SPACE(GB)-->'
|| num_array_in (i - 1)
);
END LOOP;
EXCEPTION
WHEN no_space_available
THEN
DBMS_OUTPUT.put_line ('No Space Available !!');
WHEN OTHERS
THEN
DBMS_OUTPUT.put_line ('OTHERS Exception');
END rman_rename;
BEGIN
file_system_name (0) := '/oradata/brmpp/data01/';
file_system_size (0) := 9800.00;
file_system_name (1) := '/oradata/brmpp/data02/';
file_system_size (1) := 9800.00;
file_system_name (2) := '/oradata/brmpp/data03/';
file_system_size (2) := 9800.00;
file_system_name (3) := '/oradata/brmpp/data04/';
file_system_size (3) := 9800.00;
m_threshold := 100;
rman_rename (file_system_name, file_system_size, m_threshold);
END;
/
production datafiles. It will generate set newname datafile output by evenly splitting based on available storage and checking & correcting duplicate file names.
Script input: List of file new file system name and size in GB for parameters
file_system_name (0) and file_system_size (0) in below script. Parameter m_threshold := 100 will keep 100GB free space for each file system.
SET serveroutput on
SET serveroutput on size 1000000
SET LINESIZE 120
DECLARE
TYPE str_array IS TABLE OF VARCHAR2 (100)
INDEX BY BINARY_INTEGER;
TYPE num_array IS TABLE OF NUMBER
INDEX BY BINARY_INTEGER;
file_system_name str_array;
file_system_size num_array;
path_selection NUMBER := 0;
m_threshold NUMBER := 0;
no_space_available EXCEPTION;
PROCEDURE rman_rename (
str_array_in str_array,
num_array_in IN OUT num_array,
threshold IN NUMBER
)
IS
BEGIN
FOR file_name1 IN
(SELECT file#, BYTES / 1024 / 1024 / 1024 AS gb, concat(RTRIM(file_name, '.dbf'),'.dbf') file_name
FROM (SELECT SUBSTR (NAME,
INSTR (NAME, '/', -1, 1) + 1
) file_name
FROM v$datafile
GROUP BY SUBSTR (NAME, INSTR (NAME, '/', -1, 1) + 1)
HAVING COUNT (1) = 1),
v$datafile
WHERE SUBSTR (NAME, INSTR (NAME, '/', -1, 1) + 1) = file_name
UNION ALL
SELECT file#, BYTES / 1024 / 1024 / 1024 AS gb, file_name
FROM (SELECT BYTES, file#,
SUBSTR
(SUBSTR (NAME, INSTR (NAME, '/', -1, 1) + 1),
1,
INSTR (SUBSTR (NAME,
INSTR (NAME, '/', -1,
1)
+ 1
),
'.',
1,
1
)
- 1
)
|| '_'
|| CHR
( 96
+ ROW_NUMBER () OVER (PARTITION BY file_name ORDER BY file_name)
)
|| '.dbf' file_name
FROM (SELECT COUNT (1),
SUBSTR (NAME,
INSTR (NAME, '/', -1, 1) + 1
) file_name
FROM v$datafile
GROUP BY SUBSTR (NAME, INSTR (NAME, '/', -1, 1) + 1)
HAVING COUNT (1) > 1),
v$datafile
WHERE SUBSTR (NAME, INSTR (NAME, '/', -1, 1) + 1) =
file_name)
ORDER BY 2 DESC)
LOOP
<<main_loop>>
LOOP
IF ((num_array_in (path_selection) - threshold) >= file_name1.gb
)
THEN
num_array_in (path_selection) :=
num_array_in (path_selection)
- file_name1.gb;
DBMS_OUTPUT.put_line ( 'set newname for DATAFILE '
|| file_name1.file#
|| ' to '
|| ''''
|| str_array_in (path_selection)
|| file_name1.file_name
|| ''''
|| ';'
--|| num_array_in (path_selection)
-- || '-->'
-- || file_name1.gb
);
IF (path_selection = str_array_in.COUNT - 1)
THEN
path_selection := 0;
ELSE
path_selection := path_selection + 1;
END IF;
EXIT main_loop;
ELSE
IF (path_selection < str_array_in.COUNT - 1)
THEN
path_selection := path_selection + 1;
GOTO main_loop;
ELSE
RAISE no_space_available;
END IF;
END IF;
END LOOP;
END LOOP;
DBMS_OUTPUT.put_line ('Remaining Space');
DBMS_OUTPUT.put_line ('---------------');
FOR i IN 1 .. num_array_in.COUNT
LOOP
DBMS_OUTPUT.put_line ( 'PATH-->'
|| str_array_in (i - 1)
|| ' SPACE(GB)-->'
|| num_array_in (i - 1)
);
END LOOP;
EXCEPTION
WHEN no_space_available
THEN
DBMS_OUTPUT.put_line ('No Space Available !!');
WHEN OTHERS
THEN
DBMS_OUTPUT.put_line ('OTHERS Exception');
END rman_rename;
BEGIN
file_system_name (0) := '/oradata/brmpp/data01/';
file_system_size (0) := 9800.00;
file_system_name (1) := '/oradata/brmpp/data02/';
file_system_size (1) := 9800.00;
file_system_name (2) := '/oradata/brmpp/data03/';
file_system_size (2) := 9800.00;
file_system_name (3) := '/oradata/brmpp/data04/';
file_system_size (3) := 9800.00;
m_threshold := 100;
rman_rename (file_system_name, file_system_size, m_threshold);
END;
/