Installer une base Oracle 19.25 sur un ODA GI 19.14 (version DB non supportée par le GI installé)
⚠️ Avertissements avant de reproduire sur un ODA réel
- Procédure non supportée par Oracle. Elle contourne 4 contrôles de compatibilité internes de
odacli/DCS qui existent probablement pour de bonnes raisons (compatibilité binaire GI/DB, patchs requis, etc.). Aucune garantie qu'une base ainsi créée soit stable à long terme, patchable normalement, ou supportée par Oracle en cas d'incident (SR MOS). - Testée uniquement sur une simulation VM Proxmox (ODA X8-2M, GI 19.14.0.0.220118, agent DCS 19.14.0.0.0, nœud unique, RHP non configuré). Un ODA réel diffère sur au moins 3 points qui peuvent changer la procédure :
- HA 2 nœuds :
clonemetadata.xml,imagenames.xmletimg_metadatadoivent probablement être identiques et cohérents sur les deux nœuds (pas testé — sur notre simulation, un seul nœud). - RHP potentiellement configuré : sur notre simulation,
rhpctl query imageconfirmait l'absence totale de RHP (ora.rhpclientinexistant), donc le lookupimagenames.xml/img_metadataétait purement local-fichier. Si RHP est réellement configuré sur l'ODA cible, une étape supplémentaire d'enregistrement viarhpctl add imagepourrait être nécessaire en plus (ou à la place) des éditions de fichiers ci-dessous. - Version d'agent DCS différente : si l'ODA cible n'est pas en 19.14.0.0.0, les classes Java exactes (
DbHomeServiceValidator,RhpUtils) sont dans un jardcs-agent-<version>.jardifférent — la logique est probablement similaire mais à revérifier par décompilation (voir étape 0) plutôt que supposer identique.
- HA 2 nœuds :
- Faire un backup complet avant toute tentative (vzdump/backup ODA officiel + snapshot des disques ASM si possible). Cette procédure modifie une base MySQL interne à DCS (
dcsagentdb) et des fichiers système critiques (/opt/oracle/rhp/*) — une erreur peut casser le fonctionnement normal d'odaclipour tous les dbhomes existants, pas seulement le nouveau. - Tester d'abord sur un ODA non-production si possible.
Contexte / objectif
Forcer odacli create-dbhome puis odacli create-database à accepter une version de base de données (ex: 19.25) plus récente que le Grid Infrastructure installé (ex: 19.14) — cas normalement bloqué par ODA, qui impose GI ≥ DB.
Prérequis
- Le patch Oracle officiel de la version DB cible (ex:
p<numéro>_19250000_Linux-x86-64.zipou équivalent, contenantdb<version>.tar.gz) téléchargé depuis MOS/Oracle Software Delivery Cloud. - Extrait quelque part (le zip contient
pkgrepos/orapkgs/clones/dbXX.tar.gz,clonemetadata.xml,dbXX.tar.gz.info). - Accès root sur l'ODA, accès à
mysql(client embarqué DCS) etjavap(JDK) si l'étape 0 de vérification est nécessaire.
Étape 0 — Vérifier la version de l'agent DCS et adapter si besoin
odacli describe-component 2>&1 | grep -i "DCS-AGENT\|version"
Si la version diffère de 19.14.0.0.0, décompiler le jar correspondant pour confirmer que la logique de validation est similaire avant de continuer :
mkdir -p /tmp/jarcheck && cd /tmp/jarcheck
unzip -o -q /opt/oracle/dcs/bin/dcs-agent-<version>.jar -d dcsagent
javap -p -c com.oracle.dcs.agent.service.db.DbHomeServiceValidator | grep -B30 "not supported for GRID"
javap -p -c com.oracle.dcs.agent.utils.rhp.RhpUtils | grep -B10 "Can't get RHP"
Confirmer que la logique correspond à la description ci-dessous (comparaison de "base version" GI vs DB, lecture de GiUtils.getGiCurrentVersion() depuis une table MySQL, puis lookup imagenames.xml/img_metadata).
Étape 1 — Déposer le clone dans le repository ACFS
Copier db<version>.tar.gz (et son .info) dans le répertoire ACFS réel des clones — pas un éventuel répertoire .local orphelin, vérifier avec crsctl stat res -t | grep -A2 acfsclone pour confirmer le point de montage actif :
cp db19.XXXXXX.tar.gz db19.XXXXXX.tar.gz.info /opt/oracle/oak/pkgrepos/orapkgs/clones/
Étape 2 — clonemetadata.xml
Fichier : /opt/oracle/oak/pkgrepos/orapkgs/clones/clonemetadata.xml (backup avant modif : cp -p clonemetadata.xml clonemetadata.xml.bak-pre-<version>).
Ajouter une ligne <supported .../> dans la section <dbhomes> (ne pas utiliser <defaulthome>, qui doit rester unique et pointer sur la version GI native) :
<supported version="<version_complete>" clone="db<version>.tar.gz"
min_gi_version="19.0" max_gi_version="19.99" size="1.5"
agent_version="<version_agent_dcs_reelle>"
ignore_patches="<repris tel quel du clonemetadata.xml fourni dans le zip officiel>"/>
Point clé : agent_version doit être la version de l'agent DCS réellement installée sur l'ODA, pas celle indiquée dans le zip source du patch (qui suppose un agent mis à jour en même temps que le GI — ce qu'on ne fait pas ici). Le fichier officiel Oracle contient déjà des exemples de ce pairing cross-version (ex: DB 21.5 associée à un agent 19.14.0.0.0) — s'en inspirer directement si le zip du patch cible contient un clonemetadata.xml complet.
Étape 3 — Table MySQL gihome
/opt/oracle/dcs/mysql/bin/mysql --socket=/opt/oracle/dcs/mysql/log/mysqldb.sock -u root dcsagentdb -e "select id,giversion,homelocation from gihome;"
Noter l'id et la giversion d'origine (pour rollback), puis :
UPDATE gihome SET giversion='<version_complete>' WHERE id=<id_noté>;
Rollback : UPDATE gihome SET giversion='<valeur_origine>' WHERE id=<id>;
Étape 4 — imagenames.xml
Fichier : /opt/oracle/rhp/imagenames.xml (backup avant modif).
Choisir un nom d'image suivant la convention observée dans le fichier (IMGDB<major><minor>00, ex IMGDB192500 pour 19.25), puis ajouter dans <dbhomes> :
<supported version="<major.minor>" name="IMGDB<code>"/>
<supported version="<major.minor>.0.0" name="IMGDB<code>"/>
<supported version="<version_complete>" name="IMGDB<code>"/>
Vérifier au préalable si RHP est configuré sur cet ODA (rhpctl query image) — si oui, une étape d'enregistrement rhpctl add image pourrait être requise en complément (non testé sur notre simulation, RHP absent).
Étape 5 — img_metadata
Fichier JSON : /opt/oracle/rhp/img_metadata (backup avant modif). Éditer via un script Python (json.load/json.dump), jamais sed, pour garantir un JSON valide :
import json, collections
with open('/opt/oracle/rhp/img_metadata') as f:
data = json.load(f, object_pairs_hook=collections.OrderedDict)
data['<code_sans_prefixe>'] = [
{
'image_type': 'db',
'version': '19.0.0.0.0',
'ru_version': '<major.minor>.0.0.0',
'groups': '',
'aru_id': '226',
'patches': '',
'nonrolling_patches': '',
'lspatches_bugs': '',
'image_name': 'IMGDB<code>',
'image': '/opt/oracle/oak/pkgrepos/orapkgs/clones/db<version>.tar.gz'
}
]
with open('/opt/oracle/rhp/img_metadata', 'w') as f:
json.dump(data, f, indent=4)
Pas besoin d'entrée gi jumelle dans le même groupe (confirmé par des groupes DB-only existants dans le fichier, ex 11204/11.2.0.4).
Vérifier la validité JSON avant de continuer :
python2 -c "import json; json.load(open('/opt/oracle/rhp/img_metadata')); print('JSON valide')"
(ou python3 selon ce qui est disponible sur l'ODA cible)
Étape 6 — Créer le dbhome
odacli create-dbhome -v <version_complete>
Surveiller via odacli describe-job -i <id>. Si Extract DB clone échoue ou que la VM/le nœud plante pendant cette étape (opération lourde en I/O, plusieurs Go à extraire) : voir section "Robustesse I/O" plus bas.
Étape 7 — Créer la base
odacli create-database --dbname <NOM> --dbshape <shape> --dbstorage ASM --dbhomeid <id_dbhome>
Important : cette commande (comme create-appliance) demande un mot de passe SYS/SYSTEM/PDB Admin de façon interactive via System.console() — elle échoue silencieusement en SSH non-interactif (Enter ... password: null). Doit être lancée depuis une vraie console (console IPMI/ILOM sur ODA réel, ou console série).
Vérification finale
odacli list-databases
su - oracle -c "export ORACLE_HOME=<home_location>; export ORACLE_SID=<NOM>; \$ORACLE_HOME/bin/sqlplus -s / as sysdba <<< 'select name,open_mode,database_role from v\$database;'"
Nettoyage en cas d'échec partiel
Si create-dbhome échoue en cours de route (ex: extraction interrompue), la suppression standard peut elle-même échouer :
odacli delete-dbhome -i <id>
→ PRGH-1010 / deinstall: No such file or directory
(le script deinstall n'existe pas si l'extraction n'a jamais fini). Nettoyage manuel dans ce cas :
rm -rf <home_location_incomplet>
mysql --socket=/opt/oracle/dcs/mysql/log/mysqldb.sock -u root dcsagentdb \
-e "DELETE FROM DatabaseHome WHERE id='<id>';"
Robustesse I/O (retour d'expérience simulation)
Les étapes d'extraction (update-repository, Extract DB clone) sont lourdes en I/O et CPU. Sur notre simulation, plusieurs kernel panics se sont produits pendant ces opérations, avec des causes variées (pression mémoire ARC ZFS côté hôte, contention disque avec d'autres opérations concurrentes). Sur un vrai ODA (matériel dédié, pas de virtualisation partagée), ce risque est probablement bien moindre, mais reste une bonne pratique de :
- Éviter de lancer d'autres opérations I/O lourdes (backup, patch, autre déploiement) en parallèle
- Surveiller l'espace disque disponible sur
/optavant l'extraction (df -h /opt)
Résumé des fichiers modifiés (pense-bête)
| Fichier/Table | Modification | Backup recommandé |
|---|---|---|
clones/db<version>.tar.gz |
Ajouté | — (fichier source) |
clones/clonemetadata.xml |
1 ligne <supported> ajoutée |
.bak-pre-<version> |
MySQL dcsagentdb.gihome.giversion |
Valeur modifiée | Noter la valeur d'origine |
/opt/oracle/rhp/imagenames.xml |
3 lignes ajoutées | .bak-pre-<version> |
/opt/oracle/rhp/img_metadata |
1 clé JSON ajoutée | .bak-pre-<version> |
Validation finale
Cette procédure a été testée avec succès de 3 façons indépendantes sur la simulation, confirmant qu'un dbhome créé via ce hack se comporte ensuite comme un dbhome légitime :
| Base | Chemin de création | Stockage | Résultat |
|---|---|---|---|
DB25 |
Création directe sur le home 19.25 hacké | ASM | ✅ READ WRITE/PRIMARY |
DBTEST |
Upgrade cross-major depuis 12.2.0.1.220118 | ASM | ✅ READ WRITE/PRIMARY |
DBACFS12 |
Upgrade cross-major depuis 12.2.0.1.220118 | ACFS | ✅ READ WRITE/PRIMARY |
Aucune instabilité observée après création, sur plusieurs jours de tests cumulés.
Point technique confirmé : le chemin cross-major (ex: 12.2.0.1→19.25) fonctionne nativement, sans ce hack, dès lors que le dbhome 19.25 existe déjà sur le GI 19.14 (Oracle rapporte des versions génériques réellement différentes entre lignes majeures). Seul un upgrade same-major 19.x→19.x (ex: 19.14→19.25) reste bloqué par un bug distinct (DCS-10045, troncature de version à 4 segments comparée à v$instance.version, qui rapporte génériquement "19.0.0.0.0" pour toute la ligne 19.x).