ODA Reimage Survival Guide:
Automatically Recreating Dozens of Databases Before RMAN Restore
One of the biggest challenges during an Oracle Database
Appliance (ODA) OS reimage is that the process wipes out all appliance
metadata, database homes, and database registrations. While RMAN backups
protect the database contents, they do not recreate the ODA infrastructure
required to host those databases.
Recently, I had to plan a reimage of an ODA cluster running
Oracle 19c with more than 20 databases spread across multiple database homes.
The main challenge was:
After reimaging the appliance, how do we quickly recreate
all databases using odacli create-database without manually collecting and
typing parameters for every database?
This article describes a simple and repeatable approach.
The Challenge
When an ODA is reimaged:
- Linux
OS is rebuilt
- Grid
Infrastructure is reinstalled
- ODA
repository metadata is wiped out
- Database
homes disappear
- Databases
are no longer registered with ODA
After the reimage, the typical workflow is:
- Recreate
DB homes
- Create
empty databases using odacli create-database
- Restore
RMAN backups
- Recover
databases
For a handful of databases this is manageable.
For 20, 30, or more databases, manually recreating commands
becomes both time-consuming and error-prone.
Required Information
To recreate a database using ODA, we need information
similar to:
odacli create-database \
--dbname cisprep6 \
-u cisprep6 \
-cs UTF8 \
-cl OLTP \
--dbtype SI \
--no-cdb \
--target-node oda-node1 \
--dbshape Odb4 \
--dbstorage ASM \
-dh <DBHOMEID>
The challenge is collecting these attributes for every
database before the reimage.
Exploring the ODA Repository
Oracle stores database metadata inside the internal MySQL
repository.
Connect to the repository:
/opt/oracle/dcs/mysql/bin/mysql --defaults-file=/opt/oracle/dcs/mysql/etc/mysqldb.cnf
List tables:
use dcsagentdb;
show tables;
The most useful tables were:
Db,DBNode
Understanding Database Metadata
The db table contains most of the information required for
recreation.
Example query:
select
name,
databaseUniqueName,
characterSet,
dbClass,
dbType,
dbShape,
isCdb,
dbTargetNodeNumber,
dbVersion,
dbStorage
from db;
Sample output
+----------+--------------------+--------------+
| name | databaseUniqueName |
characterSet |
+----------+--------------------+--------------+
| edadev | edadev | UTF8 |
| edatest | edatest | UTF8 |
| soaiq56 | soaiq56 | AL32UTF8 |
+----------+--------------------+--------------+
Resolving Target Node Names
The db table stores only the node number:0,1
To map that value to the actual node name:
select nodeNumber,nodeName from
DBNode;
Example
+------------+----------------+
| nodeNumber | nodeName |
+------------+----------------+
| 0 | oda-node1 |
| 1 | oda-node2 |
+------------+----------------+
Generating ODA Commands Automatically
Instead of manually creating commands, we can make MySQL
generate them.
Example query:
SELECT CONCAT(
'odacli create-database ',
'--dbname ',d.name,' ',
'-u ',d.databaseUniqueName,' ',
'-cs ',d.characterSet,' ',
'-cl ',UPPER(d.dbClass),' ',
'--dbtype ',UPPER(d.dbType),' ',
IF(TRIM(IFNULL(d.isCdb,''))='YES',
'--cdb ',
'--no-cdb '
),
'--target-node ',n.nodeName,' ',
'--dbshape ',d.dbShape,' ',
'--dbstorage ',UPPER(d.dbStorage),' '
)
FROM db d
JOIN DBNode n
ON n.nodeNumber=d.dbTargetNodeNumber;
This generates ready-to-run odacli create-database commands.
Complete Automation Script
The
following script generates a database recreation script automatically.
#!/bin/bash
DBHOMEID="<DBHOMEID>"
SCRIPT_NAME="create_database_$(hostname -s).sh"
/opt/oracle/dcs/mysql/bin/mysql \
--defaults-file=/opt/oracle/dcs/mysql/etc/mysqldb.cnf
<<EOF > ${SCRIPT_NAME}
USE dcsagentdb;
SELECT CONCAT(
'odacli create-database ',
'--dbname ',d.name,' ',
'-u ',d.databaseUniqueName,' ',
'-cs ',d.characterSet,' ',
'-cl ',UPPER(d.dbClass),' ',
'--dbtype ',UPPER(d.dbType),' ',
IF(TRIM(IFNULL(d.isCdb,''))='YES',
'--cdb ',
'--no-cdb '
),
'--target-node ',n.nodeName,' ',
'--dbshape ',d.dbShape,' ',
'--dbstorage ',UPPER(d.dbStorage),' ',
'-dh ${DBHOMEID}'
)
FROM db d
JOIN DBNode n
ON n.nodeNumber=d.dbTargetNodeNumber;
EOF
sed -i '/^odacli/!d' ${SCRIPT_NAME}
chmod u+x ${SCRIPT_NAME}
echo "Generated: ${SCRIPT_NAME}"
Why
This Helps
Instead
of manually documenting:
- Database name
- Unique name
- Character set
- Database shape
- Storage type
- Target node
- CDB/Non-CDB status
for
every database, the script extracts everything directly from the ODA
repository.
For
environments with 20+ databases, this can save several hours of manual effort
and significantly reduce human errors.
Recommended
Pre-Reimage Checklist
Before
starting the ODA reimage:
✅
RMAN backups validated
✅
Database home inventory captured
✅
odacli list-dbhomes output saved
✅
Database recreation script generated
✅
TDE wallets backed up (if applicable)
✅
Listener and application connection information documented
✅
Database services documented
✅
Post-reimage DB home creation plan prepared
Final
Thoughts
RMAN
backups are only part of an ODA recovery strategy. During a full appliance
reimage, the biggest challenge is often recreating the appliance metadata
accurately and consistently. Leveraging the ODA repository itself to generate
odacli create-database commands provides a simple, reliable, and highly
scalable approach for environments hosting dozens of databases.
Same
dbhome we can group together and run like below
cat
create_databases_test.sh
/opt/oracle/dcs/bin/odacli
list-dbhomes
echo -n
"Enter DBHOME-ID from the above list: "
read
DBHOMEID
odacli
create-database --dbname db1 -u db1 -cs UTF8 -cl OLTP --dbtype SI --no-cdb
--target-node tuslsoda01b --dbshape Odb4 --dbstorage ASM -dh $DBHOMEID
odacli
create-database --dbname db2 -u db2 -cs UTF8 -cl OLTP --dbtype SI --no-cdb
--target-node tuslsoda01a --dbshape Odb2 --dbstorage ASM -dh $DBHOMEID
Only
catch is we have to type password 2 times for every database as odacli does not
gives any option to provide password as an argument…
I hope
you have learned something useful
No comments:
Post a Comment