Inhaltsverzeichnis
Oracle Datenbank 23ai Free Edition über ein Container Image unter Linux 9 als Testumgebung für AI Vector Search verwenden
Aufgabe: Unter Oracle Linux 9 soll in einem Container Image die Oracle 23ai Free als Entwicklungsumgebung für das AI Hybrid Vector Search Feature betrieben werden.
Zur Installation über das RPM siehe ⇒ Oracle Datenbank 23ai Free Edition unter Linux 9.4
Das Container Image ist aktueller als die RPM Installation, gerade bei den AI Featuren wird aber gerade die aktuellste Version benötigt.
Aktuell (13.03.2025) kommt die Version „23.7.0.25.01“ zum Vorschein nachdem der Container gestartet wurde.
Ablauf:
- Installations-DVD von https://yum.oracle.com/oracle-linux-isos.html herunterladen
- Basis System Oracle Linux 9 bereitstellen, ähnlich wie Ein Oracle Linux 8 Basis System als Grundlagen für eine Oracle Datenbank Installation vorbereiten
- Netzwerk Konfigurieren siehe ⇒ https://docs.oracle.com/en/operating-systems/oracle-linux/9/network/OL9-NETWORK.pdf
- podman Installation
- 23ai podman Container laden und aktiveren (unser Container heißt freeDB)
- Start Konfiguration ( unser Container heißt im Anschuss freeDB)
- Laden des Models über eine Ordner im Host System
- Testen des Anlegens eine Vector Indexes
Siehe zu den Unterschied PodMan zu Docker ⇒ https://www.imaginarycloud.com/blog/podman-vs-docker
Linux 9 Betriebssystem vorbereiten
Updates und Tools:
dnf update dnf install -y dnf-utils zip unzip tar gzip git
Nach einer Default Installation wird Podman installiert.
Podman Installation
Podman installieren:
dnf install -y podman # Script Lib um podman wie docker zu bedienen dnf install -y podman-docker # dnf install -y podman-plugins # weitere podman tools dnf install -y buildah skopeo
Die Container Images werden später unter „/var/lib/containers“ abgelegt.
Container User "oracle" und auf dem Host Verzeichnisse anlegen
Vor dem Anlegen des Images muss schon alles vorbereitet sein, das Datenbank Verzeichnis und das Verzeichnis für DataPump und ähnliches wird auf dem Host angelegt.
Oracle zum Container User berechtigen
Als root User den vorhanden Oracle User in meiner Installation zum Container User aktiveren:
# useradd oracle -- nur fall noch nicht angelegt echo "oracle ALL=(ALL) NOPASSWD: /usr/bin/podman" >> /etc/sudoers echo "alias podman=\"sudo /usr/bin/podman\"" >> /home/oracle/.bash_profile #testen su - oracle podman ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
Bei Warnungen wie diesen:
WARN[0000] The cgroupv2 manager is set to systemd but there is no systemd user session available WARN[0000] For using systemd, you may need to log in using a user session WARN[0000] Alternatively, you can enable lingering with: `loginctl enable-linger 54321` (possibly as root) WARN[0000] Falling back to --cgroup-manager=cgroupfs
Conf Datei unter dem User anlegen:
mkdir -p ${HOME}/.config/containers vi ${HOME}/.config/containers/containers.conf [engine] events_logger = "file" cgroup_manager = "cgroupfs"
Verzeichnisse für die Datenbank Dateien
Verzeichnisse für die Datenbank Dateien anlegen:
Als root
mkdir -p /opt/oracle/oradata/ chown -R oracle:oinstall /opt/oracle/
Oracle DB Directory im Container für die Datenbank auf ein Host Laufwerk anlegen
Um ein Model in die Datenbank laden zu können, muss die Datenbank auf das Model zugreifen können.
Dazu verwendet die Datenbank ein DB Directory Objekt, das auf ein Verzeichnis zeigt.
Das Verzeichnis soll aber nicht im Container liegen, sondern im Host System.
Host Directory anlegen:
su - oracle mkdir /opt/oracle/datadump
Host Directory auf den Container mappen:
#weitere -v option am anlegen -v /opt/oracle/datadump:/opt/oracle/datadump #wie aber bei einem bestehenden Container mappen?? # gar nicht muss gleich zu Begin mit dem run Kommando angegeben werden! # wir führen da also gleich später mit dem Run Befehl durch!
Oracle 23ai Container DB aktivieren
Aus der Doku:
podman run --name <container name> \ -P | -p <host port>:1521 \ -e ORACLE_PWD=<your database passwords> \ -e ORACLE_CHARACTERSET=<your character set> \ -e ENABLE_ARCHIVELOG=true \ -e ENABLE_FORCE_LOGGING=true \ -v [<host mount point>:]/opt/oracle/oradata \ container-registry.oracle.com/database/free:latest Parameters: --name: The name of the container (default: auto generated) -P | -p: The port mapping of the host port to the container port. Only one port is exposed: 1521 (Oracle Listener) -e ORACLE_PWD: The Oracle Database SYS, SYSTEM and PDB_ADMIN password (default: auto generated) -e ORACLE_CHARACTERSET: The character set to use when creating the database (default: AL32UTF8) -e ENABLE_ARCHIVELOG: To enable archive log mode when creating the database (default: true) -e ENABLE_FORCE_LOGGING: To enable force logging mode when creating the database (default: true) -v /opt/oracle/oradata The data volume to use for the database. Has to be writable by the Unix "oracle" (uid: 54321) user inside the container. If omitted the database will not be persisted over container recreation. -v /opt/oracle/scripts/startup Optional: A volume with custom scripts to be run after database startup. For further details see the "Running scripts after setup and on startup" section below. -v /opt/oracle/scripts/setup Optional: A volume with custom scripts to be run after database setup. For further details see the "Running scripts after setup and on startup" section below.
Erster Versuch:
podman run -d --name freeDB \ --network=host \ -e ORACLE_PWD:oracle \ -v /opt/oracle/oradataFree:/opt/oracle/oradata \ -v /opt/oracle/datadump:/opt/oracle/datadump \ container-registry.oracle.com/database/free:latest
Hat das mit dem Mount geklappt?
podman inspect freeDB --format '{{.Mounts}}' [{bind /opt/oracle/datadump /opt/oracle/datadump [rbind] true rprivate} {bind /opt/oracle/oradataFree /opt/oracle/oradata [rbind] true rprivate} ] #Im Container Image prüfen podman exec -it freeDB bash bash-4.4$ cd /opt/oracle/datadump/ bash-4.4$ ls readme.txt
was wurde erzeugt:
# Welche Images stehen zur Verfügung podman images REPOSITORY TAG IMAGE ID CREATED SIZE container-registry.oracle.com/database/free latest ac5f0e5fb443 5 weeks ago 9.55 GB # Was läuft gerade podman ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 50ff33e947bf container-registry.oracle.com/database/free:latest /bin/bash -c $ORA... About an hour ago Up 53 seconds (starting) 1521/tcp freeDB # Configuration des zuletzt gestarteten Images podman inspect -l # Letzte Logs anzeigen podman logs -l # Was läuft im Container podman top -l
Passwort setzen und erstmalig anmelden:
podman exec freeDB ./setPassword.sh oracle podman exec -it freeDB sqlplus sys/oracle@free as sysdba
Es kommt eine 23.7.0.25.01 zum Vorschein!
Wieder löschen:
podman stop freeDB
podman rm freeDB
Alles löschen und neu anfragen:
podman system prune --all --force && podman rmi --all
Am Container anmelden:
podman exec -it freeDB bash
Netzwerk Zugriff von außen auf die Datenbank ermöglichen
Nach dem Start des Containers läuft der Listener der DB auf dem Port 1521 der lokalen IP Adresse des Containers!
ip address show
ss -tulpn
Das heißt der Container ist nur lokal erreichbar und das Netzwerk muss gemappt werden.
Siehe dazu:
Alternativ mit --network=host anlegen
Die einfachste Option ist es den Netzwerk Stack zu sharen, Port muss im Host System frei sein und localhost ist dann der Container und der Host!
Anlegen mit der Option –network=host (siehe oben den run Befehl des podman).
Automatischen Start der Container einrichten
Das Image existiert zwar noch nicht, aber wir legen schon mal die Dateien dazu an, unsere Image heißt freeDB
als Oracle:
cd /opt/oracle/ mkdir podmanScripts
StartScript:
cd /opt/oracle/podmanScripts vi startContainer.sh #!/bin/bash # Clean up old temp files. rm -Rf /tmp/podman-run-* rm -Rf /tmp/containers-user-* sudo /usr/bin/podman system migrate sudo /usr/bin/podman start freeDB
StopScript
vi stopContainer.sh #!/bin/bash sudo /usr/bin/podman stop freeDB
rechte:
chmod 764 /opt/oracle/podmanScripts/startContainer.sh chmod 764 /opt/oracle/podmanScripts/stopContainer.sh
Service anlegen
als root
vi /lib/systemd/system/podmanContainer.service [Unit] Description=podman Container Service After=syslog.target network.target [Service] LimitMEMLOCK=infinity LimitNOFILE=65535 RemainAfterExit=yes User=oracle Group=dba Restart=no ExecStart=/bin/bash -c '/opt/oracle/podmanScripts/startContainer.sh' ExecStop=/bin/bash -c '/opt/oracle/podmanScripts/stopContainer.sh' [Install] WantedBy=multi-user.target
Dienst aktiveren:
systemctl daemon-reload
systemctl start podmanContainer.service
systemctl enable podmanContainer.service
An der Datenbank anmelden über den PC - DB Directory anlegen
Nachdem nun der Port der DB auf dem Server zur Verfügung steht kann sich der SYS User an der Datenbank anmelden und das DB Directory anlegen.
Der Service Name der PDB lautet freepdb1 ( Konnect String ist dann sys@//10.10.10.118:1521/freepdb1 as sysdba )
prüfen ob auch in der richtigen Datenbank:
SELECT sys_context('USERENV','CON_NAME') CON_NAME, sys_context('USERENV','CON_ID') CON_ID, sys_context('USERENV','DB_NAME') DB_NAME FROM DUAL;
User und DB Directory für Imports/Exports anlegen
Über das Directory kann dann das Schema gesichert werden (mit DataPump) und wir verwenden das Directory um das Modell später zu laden.
User anlegen
-- USER SQL CREATE USER GPI IDENTIFIED BY gpi DEFAULT TABLESPACE USERS TEMPORARY TABLESPACE TEMP; -- QUOTAS ALTER USER GPI QUOTA UNLIMITED ON USERS; -- ROLES GRANT CONNECT TO GPI ; GRANT CTXAPP TO GPI ; GRANT SELECT_CATALOG_ROLE TO GPI ; GRANT DB_DEVELOPER_ROLE TO GPI ; -- SYSTEM PRIVILEGES GRANT CREATE MINING MODEL TO GPI ;
Directory anlegen
CREATE OR REPLACE directory DATA_EXCHANGE AS '/opt/oracle/datadump'; GRANT READ,WRITE ON directory DATA_EXCHANGE TO gpi;
Datapump Test um das Mapping des Verzeichnis zu prüfen
Dummy Export:
podman exec -it freeDB bash #Im Container bash-4.4$ cd /opt/oracle/product/23ai/dbhomeFree/ bash-4.4$ export ORACLE_HOME=$PWD bash-4.4$ cd bin bash-4.4$ ./expdp "'sys/oracle@//10.10.10.118:1521/freepdb1 as sysdba'" ESTIMATE_ONLY=YES FULL=Y DIRECTORY=DATA_EXCHANGE JOB_NAME=EXP_SPACE_V01 LOGFILE=estimate_export.log bash-4.4$ cd /opt/oracle/datadump/ bash-4.4$ ls estimate_export.log readme.txt exit #Im Host System [root@podman23ai datadump]# ls -ls total 8 8 -rw-r--r-- 1 oracle oinstall 7387 Mar 14 18:25 estimate_export.log 0 -rw-r--r-- 1 root root 0 Mar 14 17:46 readme.txt
Datei wurde angelegt, das Zusammen Spiel klappt!
Ein Model in die Datenbank laden
Für das Datenbank „AI Vector Search“ Feature benötigen wir das „Open Neural Network Exchange (ONNX) format“ für die Modelle
Im ersten Test wird das empfohlene ll-MiniLM-L12_v2 sentence transformer model in die Datenbank geladen,
Das Model wird so beschrieben: „It maps sentences & paragraphs to a 384-dimensional dense vector space and can be used for tasks like clustering or semantic search“.
Das Modell wird mit Git aus dem Repository geladen.
Falls git noch nicht installiert:
dnf install git git-lfs
Repo Anlegen unter dem Oracle Host User!
su - oracle mkdir /opt/oracle/ai git clone https://huggingface.co/sentence-transformers/all-MiniLM-L12-v2 cd /opt/oracle/ai/all-MiniLM-L12-v2/onnx
Modell Daten in das Import Verzeichnis kopieren:
cp /opt/oracle/ai/all-MiniLM-L12-v2/onnx/model.onnx /opt/oracle/datadump/all-MiniLM-L12-v2_model.onnx
In der PDB als GPI User anmelden und Modell einlesen:
-- löschen falls schon exisitert! BEGIN DBMS_VECTOR.DROP_ONNX_MODEL (model_name => 'ALL_MINILM_L12_V2', force => TRUE); END; / #einlesen BEGIN DBMS_VECTOR.LOAD_ONNX_MODEL( directory => 'DATA_EXCHANGE' ,file_name => 'all-MiniLM-L12-v2_model.onnx' ,model_name => 'ALL_MINILM_L12_V2' ,metadata => JSON ('{ "function" : "embedding", "embeddingOutput" : "embedding", "input": { "input": ["DATA"] } }') ); END; /
Problem :„ORA-54426: Tensor „input_ids“ contains multiple dimensions (2) of variable size.“ ??
Mit der aktuellen Version kein Erfolg mit einer älteren Version hat es geklappt:
SELECT * FROM user_mining_models ALL_MINILM_L12_V2 EMBEDDING ONNX NATIVE 14.03.2025 19:06
Nächster Versuch mit einem anderen Model:
git clone https://huggingface.co/Atgenomix/icd_o_sentence_transformer_128_dim_model
Hier noch keine Lösung da nicht im richtigen Format …
Problem : ORA-54401: ONNX runtime error: „Failed to load model because protobuf parsing failed.“
Einen Hybrid Vektor anlegen
Nun kann versucht werden einen Hybrid Vektor anzulegen unter dem User GPI in der PDB:
DROP INDEX IDX_HV_TEXTE; INDEX IDX_HV_TEXTE dropped. CREATE HYBRID VECTOR INDEX IDX_HV_TEXTE ON TEXTE (TEXT) PARAMETERS ('MODEL ALL_MINILM_L12_V2'); Hybrid VECTOR created.
Abfragen:
SELECT DBMS_HYBRID_VECTOR.SEARCH( JSON( '{ "hybrid_index_name" : "IDX_HV_TEXTE" , "search_text" : "Katze" } ' ) ) FROM DUAL; [{"rowid":"AAARdvAAAAAAAMLAAC","score":67.05,"vector_score":73.35,"text_score":4,"vector_rank":1,"text_rank":1,"chunk_text":"Die Katze auf dem Dach","chunk_id":"1"} ,{"rowid":"AAARdvAAAAAAAMLAAB","score":65.25,"vector_score":71.38,"text_score":4,"vector_rank":2,"text_rank":1,"chunk_text":"Die liebsten Haustiere sind Katze und Hund","chunk_id":"1"} ,{"rowid":"AAARdvAAAAAAAMLAAA","score":51.86,"vector_score":57.05,"text_score":0,"vector_rank":3,"text_rank":80,"chunk_text":"Ein Hund steht neben der Hütte","chunk_id":"1"}]
Soweit scheint die Umgebung nun für den Test der Hybrid Vektor Search vorbereitet zu sein.
Ein Modell aus der Cloud importieren
Zuvor muss DBMS_CLOUD allerdings in unsern Container installiert werden, siehe auch ⇒ https://oracle-base.com/articles/21c/dbms_cloud-installation
dann kann direkt ein Modell geladen werden, siehe ⇒ https://blogs.oracle.com/machinelearning/post/use-our-prebuilt-onnx-model-now-available-for-embedding-generation-in-oracle-database-23ai
Quellen
Oracle:
Podman:
Modelle für den Oracle Vector Index: