Inhaltsverzeichnis
Oracle 21c Oracle Connection Manager - High Availability Clustering mit Pacemaker
Aufgabe
Der Oracle Connection Manager soll hochverfügbar auf min. zwei System über eine zentrale IP Adresse als ein „active-passive 2-node (1:1) Cluster“ betrieben werden.
D.h. im Netz ist eine aktive IP Adresse konfiguriert über die der alle Clients und alle DB Registrierungen auf den CMAN zugreifen.
Je nach Status des Clusters ist diese Adresse auf eine der beteiligten Maschinen gebunden.
Muss nur diese Maschine zum Beispiel für ein OS Update neu gestartet werden, wird die IP Adresse im Cluster auf den zweiten Knoten umgezogen und dort wird der CMAN neu gestartet.
Da wir im ersten Schritt nur ein zwei Knoten Cluster haben wird das Fencing und das Quorum Feature deaktiviert.
Was mit diesem Konzept leider noch nicht funktioniert ist das Umziehen der aktive Session State des CMAN auf den zweiten Knoten. D.h. im Fehlerfall brechen die Verbindungen ab und müssen neu aufgebaut werden.
Durch das TAF Feature von SQL*Net lässt sich das etwas optimieren, das muss aber im Einzelfall gut getestet werden ob das am Ende gut klappt.
Ablauf:
- Oracle Connection Manager System unter Oracle Linux 8 installiert und konfiguriert ⇒ Oracle 21c - SQL*Net Proxy und Firewall mit dem Oracle Connection Manager CMAN implementieren - Einsatz als Standby DB Proxy für ältere Java Apps
- Cluster Software installieren (nur Software!)
- Maschine herunterfahren und clonen
- Clon als eigenständige Umgebung für den CMAN einrichten (IP Adresse, Name etc.)
- Pacemaker Cluster einrichten
- Cluster IP vergeben
- CMAN konfigurieren
- Cluster Ressource Gruppe aus IP Adresse und CMAN anlegen
- Trigger Skript erzeugen, das die Datenbanken neu am CMAN anmeldet falls als Remote Listener der CMAN eingetragen ist
- Testen
Voraussetzung:
- Netzwerkinterface für die Cluster IP Adresse hat auf allen Servern den gleichen Name wie ens160 oder eth0 etc.
- Maschinen Name / IP Adressen und neue Cluster IP im DNS eingerichtet
- Zeiten auf allen Maschinen im Verbund auf die Sekunde genau synchron!
Pacemaker Cluster Software und Umgebung vorbereiten
Wie immer müssen die grundlegenden Vorausetzung für den Betrieb eines Clusters zu mehr als 100% geben sein!
Software bestehender CMAN Umgebung installieren
Was für eine Maschine haben wir:
hostnamectl Static hostname: cman21c.pipperr.local Icon name: computer-vm Chassis: vm Machine ID: xxxx Boot ID: xxxx Virtualization: vmware Operating System: Oracle Linux Server 8.9 CPE OS Name: cpe:/o:oracle:linux:8:9:server Kernel: Linux 5.4.17-2136.324.5.3.el8uek.x86_64 Architecture: x86-64
Passendes Repository hinzufügen:
dnf config-manager --enable ol8_appstream ol8_baseos_latest ol8_addons
System aktualisieren:
dnf update reboot
Basis Software installieren:
dnf install pcs pacemaker resource-agents fence-agents-all
Name der Maschine auf eine eindeutigen Namen für den Knoten 1 anpassen
vi /etc/hostname cman21c-a.pipperr.local hostname cman21c-a.pipperr.local
Maschine herunterfahren und Clonen
init 0
Nur den Clone starten, IP Adresse und Server Name ändern, bestehende CMAN Maschine wieder starten, nun stehen uns zwei Maschinen zur Verfügung für die nächsten Schritte.
DNS Konfiguration
DNS Auflösung für beide Maschinen einrichten und prüfen!
Die Namen und IP Adressen müssen sich problemlos in alle Richtungen auflösen lassen!
In unsere Umgebung ist das dann:
- cman21c-a 10.10.10.96
- cman21c-b 10.10.10.97
- OraCmanCluster 10.10.10.98
Mein DNS auf Oracle DB Basis siehe ⇒ PowerDNS 4.x - Die Alternative für BIND - Mit einer Oracle Datenbank im Backend einsetzen
Zeit Konfiguration
Sicherstellen das auf beiden Server die gleiche Uhrzeit auf die Sekunde genau eingerichtet ist!
Dazu Crony aktiveren ⇒ https://docs.oracle.com/en/learn/ol-chrony/#introduction und https://docs.oracle.com/en/operating-systems/oracle-linux/8/network/network-ConfiguringNetworkTime.html#ol-nettime-chrony-config
#prüfen timedatectl #Hardware Zeit übernehmen hwclock -w # Crony instalieren dnf list chrony dnf install chrony -y systemctl enable chronyd systemctl start chronyd systemctl status chronyd #prüfen chronyc -n tracking chronyc -n sources -v
in der „/etc/chrony.conf“ eine pool wie https://www.ntppool.org/en/zone/de „pool 0.de.pool.ntp.org“ für die entsprechende Gegend eintragen und chrony Service neu starten.
FW einrichten / ausschalten
Pürfen ob die FW aktiv ist:
firewall-cmd --state
not running
Falls Aktiv diese entsprechend konfigurieren oder deaktivieren falls das möglich ist.
Pacemaker Cluster einrichten
Beide Maschinen sind nun gestartet.
Cluster Stack starten auf beiden Maschinen
Beide Knoten:
systemctl start pcsd.service
systemctl enable pcsd.service
Passwort des Cluster Owners auf beiden Maschinen setzen
Beide Knoten:
echo Clust0wnerPWD | passwd --stdin hacluster
Eigentliches Cluster erzeugen
Nur auf dem Knoten 1!
Schlüsselaustaush
[root@cman21c-a ~]# pcs host auth cman21c-a cman21c-b -u hacluster -p Clust0wnerPWD cman21c-b: Authorized cman21c-a: Authorized
Cluster „OraCmanCluster“ anlegen:
[root@cman21c-a ~]# pcs cluster setup OraCmanCluster cman21c-a cman21c-b No addresses specified for host 'cman21c-a', using 'cman21c-a' No addresses specified for host 'cman21c-b', using 'cman21c-b' Destroying cluster on hosts: 'cman21c-a', 'cman21c-b'... cman21c-b: Successfully destroyed cluster cman21c-a: Successfully destroyed cluster Requesting remove 'pcsd settings' from 'cman21c-a', 'cman21c-b' cman21c-a: successful removal of the file 'pcsd settings' cman21c-b: successful removal of the file 'pcsd settings' Sending 'corosync authkey', 'pacemaker authkey' to 'cman21c-a', 'cman21c-b' cman21c-a: successful distribution of the file 'corosync authkey' cman21c-a: successful distribution of the file 'pacemaker authkey' cman21c-b: successful distribution of the file 'corosync authkey' cman21c-b: successful distribution of the file 'pacemaker authkey' Sending 'corosync.conf' to 'cman21c-a', 'cman21c-b' cman21c-a: successful distribution of the file 'corosync.conf' cman21c-b: successful distribution of the file 'corosync.conf' Cluster has been successfully set up.
Cluster starten:
[root@cman21c-a ~]# pcs cluster start --all cman21c-a: Starting Cluster... cman21c-b: Starting Cluster...
Status überprüfen:
[root@cman21c-a ~]# pcs status Cluster name: OraCmanCluster WARNINGS: No stonith devices and stonith-enabled is not false Cluster Summary: * Stack: unknown (Pacemaker is running) * Current DC: NONE * Last updated: Wed Jan 10 19:58:17 2024 on cman21c-a * Last change: Wed Jan 10 19:57:57 2024 by hacluster via crmd on cman21c-a * 2 nodes configured * 0 resource instances configured Node List: * Node cman21c-a: UNCLEAN (offline) * Node cman21c-b: UNCLEAN (offline) Full List of Resources: * No resources Daemon Status: corosync: active/disabled pacemaker: active/disabled pcsd: active/enabled [root@cman21c-a ~]# corosync-cfgtool -s Local node ID 1, transport knet LINK ID 0 udp addr = 10.10.10.96 status: nodeid: 1: localhost nodeid: 2: connected [root@cman21c-a ~]# corosync-cmapctl | grep members runtime.members.1.config_version (u64) = 0 runtime.members.1.ip (str) = r(0) ip(10.10.10.96) runtime.members.1.join_count (u32) = 1 runtime.members.1.status (str) = joined runtime.members.2.config_version (u64) = 0 runtime.members.2.ip (str) = r(0) ip(10.10.10.97) runtime.members.2.join_count (u32) = 1 runtime.members.2.status (str) = joined
Service auf beiden Maschinen aktiveren beim Reboot
systemctl enable corosync.service systemctl enable pacemaker.service
Stonith deaktiveren
Da wir nur zwei Knoten haben kann diese Feature deaktiviert werden
Nur auf Knoten 1
pcs property set stonith-enabled=false pcs status
reboot Test
Beide Knoten neu starten und testen ob das Cluster funktional ist:
reboot
pcs status
Cluster IP Adresse vergeben
Pürfen ob diese ( oracmancluster.pipperr.local ⇒ 10.10.10.98 ) im DNS das auch richtig aufgelöst wird:
nslookup > oracmancluster.pipperr.local Server: 10.10.10.100 Address: 10.10.10.100#53 Name: oracmancluster.pipperr.local Address: 10.10.10.98
Wie heißt unsere Interface(genauestens prüfen ob auf beiden Knoten das selbe Interface auch am gleichen Switch hängt und gleich heißt!):
ip a .. 2: ens160: .. ..
Virtuelle IP Adresse als Cluster Ressource zuordnen, der Name „cluster_ip“ kann frei gewählt werden:
pcs resource create cluster_ip ocf:heartbeat:IPaddr2 ip=10.10.10.98 cidr_netmask=24 op monitor interval=5s pcs status .. Full List of Resources: * cluster_ip (ocf::heartbeat:IPaddr2): Started cman21c-a ..
Testen auf Knoten 1
ip a .. inet 10.10.10.98/24 brd 10.10.10.255 scope global secondary ens160 valid_lft forever preferred_lft forever ..
Umziehen auf den anderen Knoten:
[root@cman21c-a etc]# pcs resource move cluster_ip cman21c-b Warning: A move constraint has been created and the resource 'cluster_ip' may or may not move depending on other configuration [ pcs status .. Full List of Resources: * cluster_ip (ocf::heartbeat:IPaddr2): Started cman21c-b ..
CMAN
Da auf beiden Seite der CMAN läuft, muss nun auf beiden Seite dafür gesorgt werden, das der CMAN über die Cluster IP Adresse erreicht werden kann.
Konzept:
- Auf beiden Seiten läuft der CMAN (normal über Service gestartet)
- CMAN hört auf alle Anfrage aus dem Netz mit der Cluster IP Adresse
- CMan wird wie die „ocf:heartbeat:oralsnr - Manages an Oracle TNS listener“ Resource gestartet
- Mail wird versandt das umgeschaltete wurde (Resource ocf:heartbeat:MailTo - Notifies recipients by email in the event of resource takeover )
Was noch nicht funktioniert ⇒ Per Skript beim Switch Event der IP Adresse auch die Sessions des aktuellen CMAN auf den anderen umziehen; Skript wird über den Cluster Manager getriggert, in Arbeit …
Als Vorlage für einen eigene CMAN Resource kann diese Definition dienen „./usr/lib/ocf/resource.d/heartbeat/oralsnr“ oder das Dummy Skript Beispiel unter „./usr/lib/ocf/resource.d/heartbeat/Dummy“
Anleitung: siehe ⇒ https://github.com/ClusterLabs/resource-agents/blob/main/doc/dev-guides/ra-dev-guide.asc
Danach das Skript testen mit:
ocf-tester -v -n oracman /usr/lib/ocf/resource.d/heartbeat/oracman
Ein CMAN Konfiguration anlegen
Listener als Vorlage kopieren:
cp ./usr/lib/ocf/resource.d/heartbeat/oralsnr ./usr/lib/ocf/resource.d/heartbeat/oracman
Aus dieser „Ressource“ müssen wir dann unser Startskript aufrufen siehe https://www.pipperr.de/dokuwiki/doku.php?id=dba:sqlnet_cman_connection_manager_21c#auto_start_als_linux_service_einrichten, eine generische Lösung ist mit wohl auch umsetzbar, mit den bestehenden Skripten wird es im ersten Schritt aber deutlich einfacher.
Die wichtigsten Punkte beim Start mit Peacemaker Ressource Skripten:
- Name der Ressource = Dateiname = Präfix für die Methoden der Ressource
- Da hier die Listener Vorlage kopiert wurde, können die existierenden Hilfsskripte für die Oracle/Listener Ressource mit verwendet werden
Anpassen auf;
#!/bin/sh # # # oracman # # Description: Manages an Oracle Listener CMAN Konfiguration as a High-Availability # resource # # # Author: Gunther Pippèrr # Support: gunther@pipperr.de # License: GNU General Public License (GPL) # Copyright: (C) 2024 International Business Machines, Inc. # # This code inspired by the oralsnr resource script # written by Dejan Muhamedagic # # An example usage in /etc/ha.d/haresources: # node1 10.0.0.170 oracman::home::user::cman_listener_name # # See oracman_usage() function below for more details... # # OCF instance parameters: # OCF_RESKEY_home (optional; else read it from /etc/oratab) # OCF_RESKEY_user (optional; user to run the listener) # OCF_RESKEY_cmanname (optional; defaults to LISTENER) # OCF_RESKEY_cmanport (mandatory; for the monitor op) # OCF_RESKEY_cmanclustername (mandatory; for the monitor op) # # Initialization: : ${OCF_FUNCTIONS_DIR=${OCF_ROOT}/lib/heartbeat} . ${OCF_FUNCTIONS_DIR}/ocf-shellfuncs . ${OCF_FUNCTIONS_DIR}/ora-common.sh # Parameter defaults OCF_RESKEY_home_default="/opt/oracle/product/21c/client_2" OCF_RESKEY_user_default="oracle" OCF_RESKEY_cmanname_default="CMAN_GPI" OCF_RESKEY_cmanport_default="1999" OCF_RESKEY_cmanclustername_default="oracmancluster.pipperr.local" : ${OCF_RESKEY_home=${OCF_RESKEY_home_default}} : ${OCF_RESKEY_user=${OCF_RESKEY_user_default}} : ${OCF_RESKEY_cmanname=${OCF_RESKEY_cmanname_default}} : ${OCF_RESKEY_cmanport=${OCF_RESKEY_cmanport_default}} : ${OCF_RESKEY_cmanclustername=${OCF_RESKEY_cmanclustername_default}} ####################################################################### SH=/bin/sh oracman_usage() { methods=`oracman_methods` methods=`echo $methods | tr ' ' '|'` cat <<-! usage: $0 ($methods) $0 manages an Oracle CMAN instance as an HA resource. The 'start' operation starts the oracle cman. The 'stop' operation stops the oracle cman. The 'status' operation reports whether the cman is running The 'monitor' operation reports whether the cman seems to be working The 'validate-all' operation reports whether the parameters are valid The 'methods' operation reports on the methods $0 supports ! } oracman_meta_data() { cat <<END <?xml version="1.0"?> <!DOCTYPE resource-agent SYSTEM "ra-api-1.dtd"> <resource-agent name="oracman" version="1.0"> <version>1.0</version> <longdesc lang="en"> Resource script for Oracle CMAN. It manages an Oracle CMAN instance as an HA resource. </longdesc> <shortdesc lang="en">Manages the Oracle CMAN</shortdesc> <parameters> <parameter name="home" unique="0"> <longdesc lang="en"> The Oracle home directory (aka ORACLE_HOME). </longdesc> <shortdesc lang="en">home</shortdesc> <content type="string" default="${OCF_RESKEY_home_default}" /> </parameter> <parameter name="user" unique="0"> <longdesc lang="en"> Run the CMAN as this user. </longdesc> <shortdesc lang="en">user</shortdesc> <content type="string" default="${OCF_RESKEY_user_default}" /> </parameter> <parameter name="cmanname" unique="1"> <longdesc lang="en"> Listener instance to be started (as defined in cman.ora). Defaults to CMAN_GPI. </longdesc> <shortdesc lang="en">cmanname</shortdesc> <content type="string" default="${OCF_RESKEY_cmanname_default}" /> </parameter> <parameter name="cmanport" unique="1"> <longdesc lang="en"> Listener instance Port to be started (as defined in cman.ora). Defaults to 1999. </longdesc> <shortdesc lang="en">cmanport</shortdesc> <content type="string" default="${OCF_RESKEY_cmanport_default}" /> </parameter> <parameter name="cmanclustername" unique="1"> <longdesc lang="en"> Listener instance start on this Cluster IP Adress </longdesc> <shortdesc lang="en">cmanclustername</shortdesc> <content type="string" default="${OCF_RESKEY_cmanclustername_default}" /> </parameter> </parameters> <actions> <action name="start" timeout="120s" /> <action name="stop" timeout="120s" /> <action name="status" timeout="60s" /> <action name="monitor" depth="0" timeout="30s" interval="10s" /> <action name="validate-all" timeout="5s" /> <action name="meta-data" timeout="5s" /> <action name="methods" timeout="5s" /> </actions> </resource-agent> END } # # methods: What methods/operations do we support? # oracman_methods() { cat <<-! start stop status monitor validate-all methods meta-data usage ! } # # Run commands as the Oracle owner... # runasdba() { if [ "$US" = "$ORACLE_OWNER" ]; then $SH else ( echo ". $ORA_ENVF" cat ) | su -s $SH - $ORACLE_OWNER fi } # # oracman_start: Start the Oracle Connection Manager instance # oracman_start() { if is_proc_running && test_tnsping; then : nothing to be done, we can leave right now ocf_log info "Connection manager $cmanname already running" return $OCF_SUCCESS fi output=`echo /opt/oracle/scripts/startcman.sh | runasdba` if test_tnsping; then : cool, we are up and running ocf_log info "Oracle Connection Manager $cmanname running: $output" return $OCF_SUCCESS else ocf_exit_reason "Oracle Connection Manager $cmanname appears to have started, but is not running properly: $output" ocf_log err "Probable Oracle configuration error" return $OCF_ERR_GENERIC fi } # # oracman_stop: Stop the Oracle instance # oracman_stop() { if is_proc_running; then output=`echo /opt/oracle/scripts/stopcman.sh | runasdba` else ocf_log info "Oracle Connection Manager $cmanname already stopped" return $OCF_SUCCESS fi ocf_stop_processes TERM $PROCS_CLEANUP_TIME `proc_pids` # kill the procs if they hanged if is_proc_running; then ocf_exit_reason "Oracle Connection Manager $cmanname not stopped: $output" return $OCF_ERR_GENERIC else ocf_log info "Oracle Connection Manager $cmanname stopped: $output" return $OCF_SUCCESS fi } # # is_proc_running: is the Oracle Connection Manager running? # is_proc_running() { show_procs | grep "." > /dev/null } # the following two should be run only if the process is running test_listener() { local output output=`/opt/oracle/scripts/statuscman.sh` if echo "$output" | grep -qs 'Uptime' then return $OCF_SUCCESS else ocf_exit_reason "$cmanname status failed: $output" return $OCF_ERR_GENERIC fi } # and does it work? test_tnsping() { local output output=`tnsping $cmanclustername:$cmanport/$cmanname` if echo "$output" | grep -qs '^OK'; then return $OCF_SUCCESS else ocf_exit_reason "tnsping $cmanclustername:$cmanport/$cmanname failed: $output" return $OCF_ERR_GENERIC fi } # # oracman_monitor: Can we connect to the listener? # oracman_monitor() { if is_proc_running; then test_listener && test_tnsping else return $OCF_NOT_RUNNING fi } oracman_status() { if is_proc_running then echo cman $cmanname is running exit $OCF_SUCCESS else echo cman $cmanname is stopped exit $OCF_NOT_RUNNING fi } # OCF_RESKEY_home="/opt/oracle/product/21c/client_2" # OCF_RESKEY_user="oracle" # OCF_RESKEY_cmanname="CMAN_GPI" # OCF_RESKEY_cmanport="1999" oracman_getconfig() { ora_common_getconfig "null" "$OCF_RESKEY_home" "$OCF_RESKEY_user" "$OCF_RESKEY_cmanname" "$OCF_RESKEY_cmanport" ${OCF_RESKEY_cmanclustername} cmanname=${OCF_RESKEY_cmanname} cmanport=${OCF_RESKEY_cmanport} cmanclustername=${OCF_RESKEY_cmanclustername} } oracman_validate_all() { ora_common_validate_all } # used in ora-common.sh show_procs() { ps -U "$ORACLE_OWNER" -o pid,user,args | grep '[t]nslsnr' | grep -i -w "$cmanname" } proc_pids() { show_procs | awk '{print $1}'; } PROCS_CLEANUP_TIME="10" OCF_REQUIRED_PARAMS="cmanname" OCF_REQUIRED_BINARIES="tnsping" ocf_rarun $* # # vim:tabstop=4:shiftwidth=4:textwidth=0:wrapmargin=0
Verteilen
Diese Datei auf den zweiten Knoten kopieren nach „/usr/lib/ocf/resource.d/heartbeat/oracman“
scp /usr/lib/ocf/resource.d/heartbeat/oracman cman21c-b:/usr/lib/ocf/resource.d/heartbeat/oracman
CMAN Konfiguration
Auf beiden Knoten den Cman auf die Clusteradresse konfigurieren
User Oracle:
su - oracle cd $TNS_ADMIN #Kontrollieren das der CMAN auf den Namen der Maschine konfiguriert ist: #auf beiden Maschinen entsprechend anpassen #Nachteil bei Regeländerungen müssen zwei Dateien angepasst werden! # .. (address= (protocol=tcp)(host=oracmancluster.pipperr.local)(port=1999)) ..
Testen das alles auch so funktioniert auf dem Knoten mit der aktiven Cluster IP.
CMAN als Cluster Ressource aktiveren
Gruppe anlegen
Da die virtuelle IP und der CMAN zusammen gehören, werden beide in eine Gruppe gepackt:
#was gibt es schon pcs resource group list # Gruppe anlegen pcs resource group add cmangrp cluster_ip gpicman pcs resource group list cmangrp: cluster_ip gpicman # da wir IP zur angelegt haben Constraint wieder freigeben pcs resource clear cluster_ip Removing constraint: cli-prefer-cluster_ip
Auf beiden Seite die Ressource Hilfe Texte anzeigen lassen um zu prüfen ob die Ressource auch existiert:
pcs resource describe oracman
Anlegen im Cluster auf Knoten A mit:
#als root pcs resource create gpicman oracman home="/opt/oracle/product/21c/client_2" user="oracle" cmanname="CMAN_GPI" cmanport="1999" cmanclustername="oracmancluster.pipperr.local" Assumed agent name 'ocf:heartbeat:oracman' (deduced from 'oracman')
Testen
Wartungsfall
Knoten herausnehmen:
[root@cman21c-a ~]# pcs node standby cman21c-a # Zieht nach B um ... Node List: * Node cman21c-a: standby * Online: [ cman21c-b ] Full List of Resources: * Resource Group: cmangrp: * cluster_ip (ocf::heartbeat:IPaddr2): Started cman21c-b * gpicman (ocf::heartbeat:oracman): Starting cman21c-b .... #wieder aktivieren [root@cman21c-a ~]# pcs node unstandby cman21c-b
Störfall
Knoten B nun „abschießen“
# auf Knoten B anmelden shutdown -h 0
Dienst wechseln sofort auf den aktiven Knoten !
Cluster in Betrieb nehmen
Nachdem das Cluster nun im Prinzip läuft, bleiben noch die Aufgaben das für den „echten“ Betrieb zu optimieren.
CMAN.ora syncroniseren
Die cman.ora zwischen beiden Knoten sollte auf den selben Stand gehalten werden.
In der CMAN.ora sind alle Regeln für A und für B hinterlegt, Datei funktioniert ohne Anpassung in beiden Umgebungen.
Dazu bietet sich rsync als Job auf beiden Knoten an, rsync wird auf A immer um x:15 aufgerufen, auf B immer um x:45.
Alerting / Monitoring
Einbinden in die Überwachung, je nach dem was vorhanden ist.
Datenbank Registierung
Wird der CMAN umgeschaltet, muss sich die DB ja neu an dem CMAN anmelden falls als Remote Listener dieser registriert ist.
Dazu muss der Event des Umschaltens „abgegriffen“ werden und per Skript Kette dann in der DB die Registrierung mit „alter system register“ neu aktviert werden.
Web Oberfläche
Unter https://NodeName/2224 steht nach der Installation eine Oberfläche für das Cluster zur Verfügung.
Der Default User ist „hacluster“ und das Password das bei der Anlage des Clusters definiert wurde.
Cluster beim ersten Aufruf mit „add“ hinzufügen:
Beispiel für eine Übersichtsmaske:
Quellen
Oracle Doku:
Pacemaker
Web