DBA-Referenz
Nutzungsregeln: Die unten aufgeführten Befehle sind die stabilen, gut bekannten Formen. Das Verhalten unterscheidet sich zwischen Versionen und Editionen (Lizenzierung!) – wenn eine Zeile "gegen Ihre Version prüfen" sagt, schlagen Sie vor der Verwendung in der Herstellerdokumentation für die genaue Version nach. Führen Sie niemals Diagnoseanweisungen aus, die Daten in der Produktion ändern, ohne einen Änderungsnachweis.
1. Engine-Schnellvergleich
| Thema | Oracle | PostgreSQL | SQL Server | Db2 LUW | MySQL / MariaDB (InnoDB) |
|---|---|---|---|---|---|
| Nebenläufigkeitsmodell | MVCC (Undo); Leser blockieren niemals Schreiber | MVCC (Zeilenversionen in der Tabelle; VACUUM) | Sperren standardmäßig; MVCC, wenn RCSI/Snapshot aktiviert | Sperren; "aktuell festgeschriebene" Lesevorgänge (CUR_COMMIT) | MVCC (Undo) + Next-Key/Gap-Locks in REPEATABLE READ (Standard) |
| Transaktionales DDL | Nein (impliziter Commit vor/nach) | Ja (außer z. B. CREATE INDEX CONCURRENTLY, CREATE DATABASE, VACUUM) | Ja für die meisten DDL-Anweisungen | Ja für die meisten DDL-Anweisungen (pro Anweisung prüfen) | Nein (impliziter Commit; MySQL 8 DDL ist nur pro Anweisung atomar) |
| Sperreneskalation | Niemals | Niemals | Ja (Zeile/Seite -> Tabelle, ~5000 Sperren pro Objekt pro Anweisung) | Ja (LOCKLIST/MAXLOCKS) | Nein (aber Gap-Locks) |
| Abfragestatistiken | AWR/ASH (Diagnostics Pack), Statspack | pg_stat_statements | Query Store, DMVs | MON_GET_*-Tabellenfunktionen | performance_schema, sys-Schema, langsames Log |
| Sitzungs-Sperr-Timeout | ALTER SESSION SET DDL_LOCK_TIMEOUT = 30; (DDL, Sekunden) | SET lock_timeout = '5s'; | SET LOCK_TIMEOUT 5000; (ms) | SET CURRENT LOCK TIMEOUT 30; (s) | SET SESSION lock_wait_timeout = 30; (Metadatensperren) + innodb_lock_wait_timeout (Zeilensperren) |
2. Performanzdiagnose
Methode: (1) Definieren Sie das Symptom (eine Abfrage, ein Zeitfenster, die gesamte Instanz); (2) Betrachten Sie Wartezeiten/Zeitmodell, bevor Sie SQL optimieren; (3) Holen Sie den tatsächlichen Ausführungsplan (nicht nur den geschätzten); (4) Vergleichen Sie geschätzte vs. tatsächliche Zeilen – Kardinalitätsfehleinschätzungen sind die übliche Ursache (veraltete Statistiken, Schiefe, korrelierte Prädikate, Parameter-Sniffing/Bind Peeking); (5) Ändern Sie eine Sache, messen Sie.
Oracle
- Geschätzter Plan:
EXPLAIN PLAN FOR <stmt>;dannSELECT * FROM TABLE(DBMS_XPLAN.DISPLAY); - Tatsächlicher Plan: Ausführen mit
/*+ GATHER_PLAN_STATISTICS */dannSELECT * FROM TABLE(DBMS_XPLAN.DISPLAY_CURSOR('<SQL_ID>', NULL, 'ALLSTATS LAST')); - AWR/ASH/ADDM (
@?/rdbms/admin/awrrpt.sql,ashrpt.sql,addmrpt.sql,V$ACTIVE_SESSION_HISTORY,DBA_HIST_*) erfordern das Diagnostics Pack (Enterprise Edition); SQL Monitor und SQL Tuning Advisor erfordern das Tuning Pack. Überprüfen SieCONTROL_MANAGEMENT_PACK_ACCESS. Ohne Lizenz: Statspack. - Live-Wartezeiten:
V$SESSION(event,wait_class,sql_id,blocking_session),V$SYSTEM_EVENT,V$SQL/V$SQLSTATS. - Häufige Wartezeiten:
db file sequential read(Einzelblock, Indexzugriff),db file scattered read/direct path read(vollständige Scans),log file sync(Commit-Häufigkeit / Redo-I/O),enq: TX - row lock contention(Anwendungssperren),enq: TM - contention(oft nicht indizierte Fremdschlüssel),latch: cache buffers chains(heiße Blöcke),gc *(RAC-Interconnect). - Planstabilität: SQL Plan Management (Baselines); SQL-Profile benötigen das Tuning Pack.
PostgreSQL
EXPLAIN (ANALYZE, BUFFERS) <stmt>;- ANALYZE führt die Anweisung aus: DML inBEGIN; ... ROLLBACK;einschließen.pg_stat_statements(benötigtshared_preload_libraries): Top-SQL nachtotal_exec_time(Spaltennamen in PG13 geändert:total_exec_time,mean_exec_time).SELECT queryid, calls, round(total_exec_time) total_ms, round(mean_exec_time::numeric,1) mean_ms, rows, left(query,80) FROM pg_stat_statements ORDER BY total_exec_time DESC LIMIT 20;- Live:
pg_stat_activity(state,wait_event_type,wait_event,xact_start,query); Sitzungen im Zustandidle in transactionhalten Sperren und blockieren VACUUM. auto_explain-Modul für langsame Pläne in Logs;track_io_timing = onfür I/O-Zeitmessungen.- Zustand:
pg_stat_user_tables(seq_scan,n_dead_tup,last_autovacuum,last_autoanalyze); Bloat; Transaktions-ID-Überlauf:SELECT datname, age(datfrozenxid) FROM pg_database;. - Beenden:
pg_cancel_backend(pid)(Abfrage) dannpg_terminate_backend(pid)(Sitzung).
SQL Server
- Tatsächlicher Plan: SSMS "Tatsächlichen Ausführungsplan einschließen" oder
SET STATISTICS XML ON;;SET STATISTICS IO, TIME ON;für Lesevorgänge/CPU. - Query Store (2016+; standardmäßig aktiviert für neue Datenbanken in 2022):
sys.query_store_query,sys.query_store_query_text,sys.query_store_plan,sys.query_store_runtime_stats,sys.query_store_wait_stats(2017+); Regressionen -> PlanerzwingungEXEC sp_query_store_force_plan @query_id = <q>, @plan_id = <p>;. - DMVs:
sys.dm_exec_requests(wait_type,blocking_session_id),sys.dm_os_wait_stats,sys.dm_exec_query_stats+CROSS APPLY sys.dm_exec_sql_text(sql_handle)+sys.dm_exec_query_plan(plan_handle). - Häufige Wartezeiten:
PAGEIOLATCH_*(Datenlesevorgänge),LCK_M_*(Blockierung),WRITELOG(Log-I/O / Commit-Rate),CXPACKET/CXCONSUMER(Parallelität - MAXDOP/Kosten-Schwellenwert prüfen),SOS_SCHEDULER_YIELD(CPU),ASYNC_NETWORK_IO(Client konsumiert Ergebnisse nicht),RESOURCE_SEMAPHORE(Speicherzuweisungen). - Parameter-Sniffing: Pläne pro Parameter vergleichen; Optionen
OPTION (RECOMPILE),OPTIMIZE FOR, Query Store-Hinweise (2022) - je nach Fall wählen. - Erweiterte Ereignisse; die Sitzung
system_healthbehält aktuelle Deadlock-Graphen.
Db2 LUW
- Explain: Explain-Tabellen erstellen (
SYSPROC.SYSINSTALLOBJECTSoderEXPLAIN.DDL),EXPLAIN PLAN FOR <stmt>, formatieren mitdb2exfmt -d <DB> -1 -o plan.txt; Schnellansichtdb2expln. - Überwachungstabellenfunktionen:
MON_GET_PKG_CACHE_STMT(Top-SQL:STMT_EXEC_TIME,NUM_EXECUTIONS,ROWS_READ),MON_GET_CONNECTION,MON_GET_ACTIVITY,MON_GET_TABLE,MON_GET_BUFFERPOOL. - Sperren:
SYSIBMADM.MON_LOCKWAITS,db2pd -db <DB> -wlocks,db2pd -db <DB> -locks. - Statistiken:
RUNSTATS ON TABLE <SCHEMA>.<TABLE> WITH DISTRIBUTION AND DETAILED INDEXES ALL;-REORGCHKzur Beurteilung des Reorganisationsbedarfs;db2advisfür Indexempfehlungen.
MySQL / MariaDB
EXPLAIN <stmt>; tatsächlich: MySQL 8.0.18+EXPLAIN ANALYZE <stmt>; MariaDBANALYZE <stmt>(beide führen die Anweisung aus).- Top-SQL:
sys.statement_analysis,performance_schema.events_statements_summary_by_digest; langsames Abfrage-Log (slow_query_log,long_query_time) +pt-query-digest. - InnoDB:
SHOW ENGINE INNODB STATUS\G(letzter Deadlock, Verlauf der List Länge),information_schema.INNODB_TRX,sys.innodb_lock_waits; MySQL 8:performance_schema.data_locks/data_lock_waits; MariaDB:information_schema.INNODB_LOCKS/INNODB_LOCK_WAITSund das PluginMETADATA_LOCK_INFO; MySQL-Metadatensperren:performance_schema.metadata_locks.
3. Sperren und Nebenläufigkeit – Fallstricke
| Engine | Falle | Abhilfe |
|---|---|---|
| Alle | Lange Transaktion + DDL: Das DDL wartet, und jede spätere Abfrage stellt sich dahinter an | Kurzes Sperr-Timeout für DDL, Wiederholungsschleife, Ausführung, wenn keine langen Transaktionen aktiv sind; vorher prüfen (aktive Sitzungen) |
| Oracle | Nicht indizierte Fremdschlüssel -> TM-Sperren auf dem Kind, wenn übergeordnete Zeilen gelöscht/Primärschlüssel aktualisiert werden | Fremdschlüsselspalten indizieren |
| Oracle | DDL schlägt fehl mit ORA-00054 bei belegtem Objekt | DDL_LOCK_TIMEOUT; Online-Varianten (CREATE INDEX ... ONLINE, ALTER TABLE ... MOVE ONLINE 12.2+, DBMS_REDEFINITION) - alle nur in der Enterprise Edition (nicht in SE2) |
| Oracle | Commit innerhalb einer Schleife über einen offenen Cursor -> ORA-01555 snapshot too old | Nach Schlüssel-/Rowid-Bereichen chunken (DBMS_PARALLEL_EXECUTE), Undo-Aufbewahrungsdauer dimensionieren |
| PostgreSQL | Die meisten ALTER TABLE nehmen ACCESS EXCLUSIVE; das Warten darauf blockiert alle Leser | SET lock_timeout; CREATE INDEX CONCURRENTLY; FK/CHECK NOT VALID dann VALIDATE CONSTRAINT |
| PostgreSQL | Spaltentypänderung schreibt die Tabelle neu (außer bei sicheren Fällen wie der Erhöhung der varchar-Länge) | Expandieren/Kontrahieren mit neuer Spalte + Backfill |
| PostgreSQL | Sitzungen im Zustand idle in transaction | idle_in_transaction_session_timeout, Anwendung korrigieren |
| SQL Server | Leser blockieren Schreiber unter dem standardmäßigen READ COMMITTED | READ_COMMITTED_SNAPSHOT ON evaluieren (Auswirkungen auf den Versionierungsspeicher in tempdb; testen) |
| SQL Server | Sperreneskalation auf Tabellenebene bei großen DML-Operationen | Batches unter ~5000 Zeilen; ALTER TABLE ... SET (LOCK_ESCALATION = ...) mit Vorsicht |
| SQL Server | NOLOCK als "Fix" verwendet | Dirty Reads, fehlende/doppelte Zeilen – in Reviews ablehnen |
| Db2 | LOCKTIMEOUT = -1 (ewiges Warten) standardmäßig | CURRENT LOCK TIMEOUT in Release-Sitzungen setzen |
| Db2 | ALTER TABLE ... DROP COLUMN, die meisten ALTER COLUMN SET DATA TYPE, SET NOT NULL/DROP NOT NULL versetzen eine zeilenorganisierte Tabelle in den Status "Reorganisationsanstehend" (SQLSTATE 57007): bis REORG TABLE sind nur Scans, DROP/RENAME/TRUNCATE und die meisten anderen ALTER-Operationen erlaubt; maximal 33 Arbeitseinheiten solcher Operationen, bevor REORG obligatorisch wird | REORG TABLE im Fenster planen; REORG_PENDING / NUM_REORG_REC_ALTERS in SYSIBMADM.ADMINTABINFO prüfen |
| MySQL | Metadaten-Sperren-Wartezeiten (MDL): DDL blockiert durch eine offene Transaktion und blockiert dann alle | lock_wait_timeout niedrig in der Release-Sitzung; lange, im Leerlauf befindliche Transaktionen killen |
| MySQL | Online DDL fällt stillschweigend auf Tabellenkopie zurück | Immer ALGORITHM=INSTANT (oder INPLACE) mit LOCK=NONE angeben, damit es einen Fehler ausgibt; stattdessen gh-ost / pt-online-schema-change |
| MySQL | Gap/Next-Key-Sperren bei Bereichsaktualisierungen unter REPEATABLE READ | Das Prädikat indizieren; READ COMMITTED in Betracht ziehen, wo akzeptabel |
Deadlocks: immer ein Designproblem (inkonsistente Zugriffsreihenfolge, fehlende Indizes). Erfassen: Oracle-Trace-Datei / Alert-Log (ORA-00060), PostgreSQL-Log (log_lock_waits = on für Wartezeiten > deadlock_timeout), SQL Server system_health XE, Db2-Ereignismonitor für Sperren, MySQL innodb_print_all_deadlocks.
4. HA / DR
| Engine | Lokales HA | DR / Replicas | Wichtige Operationen & Prüfungen |
|---|---|---|---|
| Oracle | RAC (Shared Storage, Active-Active, zusätzliche Lizenz) | Data Guard physischer Standby (Redo Apply); Active Data Guard = schreibgeschützt geöffnet mit Apply (zusätzliche Lizenz) | Schutzmodi: Maximum Performance (ASYNC, Standard), Maximum Availability (SYNC, fällt zurück), Maximum Protection (SYNC, Primärstopps, wenn kein Standby vorhanden). Broker dgmgrl: SHOW CONFIGURATION;, VALIDATE DATABASE <stby>;, SWITCHOVER TO <stby>;, FAILOVER TO <stby>;. Verzögerung: V$DATAGUARD_STATS. Primär in FORCE LOGGING. Fast-Start Failover benötigt einen Observer (idealerweise an einem dritten Standort). |
| PostgreSQL | Patroni (DCS: etcd/Consul/ZooKeeper) + HAProxy/VIP | Streaming-Replikation (physisch, WAL); logische Replikation (Publikationen/Abonnements, PG10+) | pg_stat_replication (sent_lsn, write_lsn, flush_lsn, replay_lsn), pg_is_in_recovery(), pg_promote() (PG12+). Sync: synchronous_standby_names + synchronous_commit. Replikations-Slots behalten WAL, wenn ein Replikat ausfällt -> Festplatte voll: überwachen, begrenzen mit max_slot_wal_keep_size (PG13+). Patroni: patronictl -c <cfg> list / switchover / failover; REST-Health-Endpunkte (/primary, /replica) für den Load Balancer. Logische Replikation repliziert weder DDL noch Sequenzwerte (Stand PG 18): additive Schemaänderungen zuerst auf dem Abonnenten anwenden und Sequenzen zurücksetzen, bevor ein Failover auf einen Abonnenten durchgeführt wird. |
| SQL Server | Failover Cluster Instance (Shared Storage, WSFC) | Always On Availability Groups (WSFC, oder Pacemaker unter Linux); Log Shipping | Automatisches Failover nur zwischen synchronen Commit-Replikaten. Listener für Clients (MultiSubnetFailover=True). Logins, Agent-Jobs, Linked Server, Credentials werden NICHT repliziert (Contained AG, SQL Server 2022 Enterprise, hilft). Volle AGs benötigen Enterprise; Basic AG in der Standard Edition (1 DB, 2 Replikate). sys.dm_hadr_database_replica_states prüfen. Geplantes Failover: ALTER AVAILABILITY GROUP [<AG>] FAILOVER; auf dem synchronen sekundären Ziel. Lesbare Sekundäre haben Auswirkungen auf die Lizenzierung. |
| Db2 LUW | pureScale (Active-Active) oder HADR + Pacemaker/TSA-Automatisierung | HADR (bis zu 3 Standbys, HADR_TARGET_LIST) | HADR_SYNCMODE: SYNC, NEARSYNC, ASYNC, SUPERASYNC. Überwachen mit db2pd -db <DB> -hadr oder MON_GET_HADR. Rollenwechsel auf Standby: TAKEOVER HADR ON DATABASE <DB> (BY FORCE für Failover). Lesezugriffe auf Standby über DB2_HADR_ROS (Einschränkungen). |
| MySQL / MariaDB | InnoDB Cluster (Group Replication + MySQL Router); Galera (MariaDB) | Async / Semi-Sync-Replikation, GTID-basiert | SHOW REPLICA STATUS (MySQL 8.0.22+; MariaDB 10.5.1+ akzeptiert REPLICA als Synonym für SLAVE; ältere Versionen: SHOW SLAVE STATUS). Replikationsverzögerung und fehlerhafte GTIDs überwachen; Galera benötigt ein Quorum der primären Komponente (3 Knoten oder Arbitrator). |
Designregeln: RPO/RTO pro Anwendung definieren, bevor sync/async gewählt wird; DR-Test mindestens jährlich mit dokumentierten Ergebnissen (DORA erfordert IKT-Kontinuitätstests für Finanzinstitute); Clients müssen sich transparent wieder verbinden können (Verbindungszeichenfolgen mit mehreren Hosts/Listener/SCAN, Wiederholungslogik); Verzögerung überwachen und alarmieren; Split-Brain-Schutz (Quorum, Fencing, Observer/Witness an einem dritten Standort).
5. Backup, Wiederherstellung, PITR
| Engine | Vollständig / Inkrementell | PITR | Validieren |
|---|---|---|---|
| Oracle (RMAN) | BACKUP DATABASE PLUS ARCHIVELOG; inkrementell Stufe 0/1; CONFIGURE CONTROLFILE AUTOBACKUP ON; CONFIGURE RETENTION POLICY TO RECOVERY WINDOW OF 14 DAYS; | ARCHIVELOG-Modus erforderlich. RUN { SET UNTIL TIME "TO_DATE('2026-10-01 12:00','YYYY-MM-DD HH24:MI')"; RESTORE DATABASE; RECOVER DATABASE; } dann ALTER DATABASE OPEN RESETLOGS; | RESTORE DATABASE VALIDATE;, CROSSCHECK BACKUP;, LIST BACKUP SUMMARY;, REPORT NEED BACKUP;, DELETE OBSOLETE; |
| PostgreSQL | pg_basebackup -D <dir> -Ft -z -X stream -P; pgBackRest --type=full / diff / incr backup; Barman. pg_dump ist nur logisch (kein PITR) | WAL-Archivierung (archive_mode, archive_command); Basis wiederherstellen + restore_command + recovery_target_time + recovery.signal (PG12+). pgBackRest: pgbackrest --stanza=<s> --type=time "--target=2026-10-01 12:00:00+02" restore | pgbackrest --stanza=<s> check, pgbackrest --stanza=<s> info; regelmäßiger echter Wiederherstellungstest |
| SQL Server | Wiederherstellungsmodell FULL; BACKUP DATABASE [<db>] TO DISK = N'<path>' WITH CHECKSUM, COMPRESSION; differentiell; BACKUP LOG | Vollständige Wiederherstellung WITH NORECOVERY, dann differenziell und Log(s) WITH NORECOVERY, dann RESTORE DATABASE [<db>] WITH RECOVERY; STOPAT für PITR | RESTORE VERIFYONLY FROM DISK = N'<backup_file>';; regelmäßige Wiederherstellungstests |
| Db2 LUW | BACKUP DATABASE <db> TO <dir> WITH 2 BUFFERS BUFFER 1024 PARALLELISM 4 COMPRESS INCLUDE LOGS WITHOUT PROMPTING;; inkrementell INCREMENTAL DELTA / INCREMENTAL (Tabelle muss verfolgt werden ENABLED FOR ROLLFORWARD USING AUTO TABLE RECOVERY) | Rollforward: RESTORE DATABASE <db> ... LOGTARGET <dir>; ROLLFORWARD DATABASE <db> TO 2026-10-01-12.00.00.000000 USING LOCAL TIME AND STOP; | db2ckbkp (schnell); regelmäßiger echter Test; MON_GET_BACKUP / MON_GET_ROLLFORWARD zur Überwachung |
| MySQL / MariaDB | Physikalisch: xtrabackup --backup (Percona XtraBackup) oder mariabackup --backup; logisch: mysqldump --single-transaction --routines --triggers --events (InnoDB, konsistent, kein PITR) | Binlogs (log_bin, expire_logs_days / binlog_expire_logs_seconds); Wiederherstellung: Basis wiederherstellen (physikalisch: --prepare dann kopieren; logisch: mysql < dump) + mysqlbinlog bis zum gewünschten Zeitpunkt | xtrabackup --validate (Percona XtraBackup 8.0.34+); sekundäre Replikat bereitstellen und Verzögerung prüfen; mysqlbinlog |
Praktische Hinweise:
- Backup-Strategie an RPO/RTO ausrichten: Archivlog-Backups ermöglichen PITR, erhöhen aber die Wiederherstellungszeit.
- Backups auf ein separates Ziel verschieben (Cloud-Objektspeicher, NAS, anderes Rechenzentrum).
- Backup-Tests automatisieren (Wiederherstellung in einer Staging-Umgebung).
- Backup-Verschlüsselung und -Überwachung (Benachrichtigung bei Fehlern).
- Aufbewahrungsrichtlinie für Backups gemäß den gesetzlichen Anforderungen (DSGVO, DORA, etc.).
6. Sicherheit und GDPR / DSGVO
Die DSGVO ist eine Verordnung (EU) 2016/679. Sie gilt für alle personenbezogenen Daten (PII), die in der EU von Unternehmen verarbeitet werden, unabhängig vom Standort des Unternehmens. DORA (Verordnung (EU) 2022/2554) schreibt IKT-Kontinuitätstests und Cybersicherheitsresilienz für Finanzunternehmen vor.
Grundlegende Maßnahmen
| Bereich | Aktion | Datenbankprüfung |
|---|---|---|
| Zugriffskontrolle | Rollen & minimale Rechte (Least Privilege). Keine generischen freigegebenen Anmeldeinformationen | Engine-spezifische Rollen: DBA (Oracle), pg_read_all_data/pg_write_all_data (PG 17+), db_datareader/db_datawriter (SQL Server), DBADM / DATAACCESS (Db2), SELECT/INSERT/UPDATE/DELETE-Berechtigungen (MySQL) |
| Verschlüsselung ruhender Daten (TDE) | Oracle TDE, SQL Server TDE (DEK, Zertifikat), PostgreSQL TDE nur über pg_tde (Percona) oder CyberTec, MySQL Enterprise TDE (InnoDB Tablespace Encryption), MariaDB Data-at-Rest Encryption (Aria/InnoDB) | Prüfen, ob TDE aktiviert ist, Schlüsselverwaltung prüfen (HSM, Azure Key Vault, HashiCorp Vault) |
| Verschlüsselung in der Übertragung (TLS) | Erzwingen von TLS 1.2+; Client-Server-Verbindungen verschlüsselt | SELECT name, value FROM v$parameter WHERE name LIKE '%ssl%' (Oracle), SHOW ssl; (PostgreSQL, MySQL), sys.configurations WHERE name LIKE '%ssl%' (SQL Server), `db2 get db cfg |
| Audit-Logging | Erfassen, wer wann auf welche Daten zugegriffen hat | Oracle Audit Vault / Unified Audit, PostgreSQL pgaudit, SQL Server Audit, Db2 Audit Facility, MySQL Enterprise Audit / MariaDB Audit Plugin |
| Datenmaskierung | Dynamische Datenmaskierung (SQL Server 2016+, Oracle 12c+), PII-Spalten maskieren | Testen, dass maskierte Werte nicht umgangen werden können (z. B. über UNMASK-Berechtigung) |
| Pseudonymisierung | PII in Tabellen durch Token oder Hash ersetzen; Salt für Hash-Werte verwenden | Überprüfen, ob Hash eindeutig und umkehrbar ist (sichere Hash-Funktion, z. B. SHA-256) |
DSGVO-spezifische Datenbankprüfungen
- Recht auf Löschung ("Recht auf Vergessenwerden"): Stellen Sie sicher, dass ein Prozess zur Löschung personenbezogener Daten aus allen Tabellen vorhanden ist; prüfen Sie, ob die Löschung kaskadiert (Fremdschlüssel).
- Datenportabilität: Verfahren zum Export von PII in einem maschinenlesbaren Format (CSV, JSON) vorhanden.
- Datenminimierung: Speichern Sie nicht mehr personenbezogene Daten als für den Verarbeitungszweck erforderlich ist; prüfen Sie, ob historische Daten archiviert/gelöscht werden können.
- Verzeichnis der Verarbeitungstätigkeiten (VVT): Dokumentieren Sie, welche Datenbanken, welche Tabellen personenbezogene Daten enthalten, zu welchem Zweck und mit welcher Rechtsgrundlage.
- Datenbestandsaufnahme: Führen Sie eine Bestandsaufnahme aller Datenbanken durch, die personenbezogene Daten enthalten.
- Verletzung der Daten: Verfahren zur Erkennung und Meldung von Datenschutzverletzungen.
7. Oracle-zu-PostgreSQL-Migration
Allgemeine Strategie
- Bewertung: ORACLE_DATABASE_LINK, Speicherprozeduren, Datenmodelle prüfen.
- Schema-Migration: Verwenden Sie ora2pg, AWS DMS (Schema Conversion Tool), pgloader oder manuelle / angepasste Skripte.
- Datenmigration: Verwenden Sie ora2pg, AWS DMS, oder exportieren Sie Daten als CSV und importieren Sie sie mit
\copy. - Anwendungsvalidierung: Testen Sie die Anwendung gründlich gegen die PostgreSQL-Datenbank.
- Umschaltung: Planen Sie die Umschaltung (Cutover) mit minimaler Ausfallzeit.
Typische Fallstricke
| Oracle | PostgreSQL | Problem | Abhilfe |
|---|---|---|---|
SYSDATE / CURRENT_DATE | CURRENT_TIMESTAMP, NOW(), LOCALTIMESTAMP | Unterschiedliche Datums-/Zeitfunktionen | Suchen/Ersetzen im Code; transaction_timestamp() für Anweisungsbeginn |
ROWNUM | LIMIT / OFFSET | Unterschiedliche Syntax; ROWNUM wird vor der Sortierung ausgewertet | Umschreiben auf LIMIT und OFFSET in Unterabfragen, falls nötig, um zuerst zu sortieren |
SEQUENCE.NEXTVAL / CURRVAL | NEXTVAL('seq') / CURRVAL('seq') | Unterschiedliche Syntax | Suchen/Ersetzen im Code; pg_get_serial_sequence() für automatisch inkrementierte Sequenzen |
CONNECT BY (hierarchische Abfragen) | WITH RECURSIVE | Völlig andere Syntax | Manuelles Umschreiben auf rekursive CTEs |
MERGE (seit 9i) | INSERT ... ON CONFLICT DO UPDATE / MERGE (PG 15+) | Unterschiedliche Syntax, Nebeneffekte bei ON CONFLICT DO UPDATE | Auf PG MERGE (PG 15+) oder äquivalente Logik migrieren; ON CONFLICT DO UPDATE kann Sperren ausweiten |
MATERIALIZED VIEW (einfaches Auffrischen) | REFRESH MATERIALIZED VIEW CONCURRENTLY (benötigt eindeutigen Index) | CONCURRENTLY vermeidet Sperren, erfordert aber einen eindeutigen Index | Eindeutigen Index auf der materialisierten Sicht erstellen, bevor CONCURRENTLY verwendet wird |
V$-Sichten | pg_catalog, information_schema, Monitoring-Ansichten | Völlig andere Katalogsichten | Code umschreiben, um die entsprechenden PG-Kataloge zu verwenden |
UTL_FILE | COPY / pg_file_server | Unterschiedliche Dateizugriffsmechanismen; COPY ist nur für Dateien auf dem Server | Verwenden Sie COPY ... TO PROGRAM (sicher einrichten) oder einen Client-seitigen Export |
DBMS_SCHEDULER | pg_cron (Erweiterung) oder Betriebssystem-Cron | Kein integrierter, funktionsreicher Scheduler in PG | pg_cron oder Betriebssystem-Cron für die Planung verwenden |
AUTHID CURRENT_USER (Definer's Rights) | SECURITY DEFINER / SECURITY INVOKER | Unterschiedliches Rechteverhalten | Funktionen als SECURITY INVOKER für das Standardverhalten oder SECURITY DEFINER für erhöhte Rechte definieren |
PIPELINED TABLE FUNCTIONS | RETURNS TABLE ... oder SETOF (die gesamte Ergebnismenge wird vor der Rückgabe materialisiert) | Keine Pipeline-Funktionen (kein Streaming in einer einzigen Transaktion) | Verwenden Sie RETURNS SETOF mit RETURN QUERY oder RETURN NEXT; die gesamte Ausgabe materialisiert |
ORACLE_TEXT / ORDSYS | pg_trgm, FTS (tsvector), pgroonga, pg_bigm | Andere Volltextsuche-Konfiguration | Migrieren Sie die Logik auf PG-Textsuch-Konfigurationen |
| Große Objekte | BYTEA / LO | Andere große Objektspeicherung | BYTEA für kleinere Objekte verwenden; große Objekte für sehr große (reines PG) |
DEFAULT ON NULL | COALESCE in DEFAULT | Unterschiedliche Default-Syntax | In PG ist DEFAULT ON NULL nicht verfügbar; stattdessen COALESCE im DEFAULT-Ausdruck verwenden |
Weitere Überlegungen zur Migration
- Berücksichtigung von Schemas: Ordnen Sie Oracle-Schemas (Benutzer) PG-Schemas zu, vorzugsweise innerhalb einer einzigen Datenbank.
- Sequenzen: In PostgreSQL sind Sequenzen separate Objekte. Migrieren Sie Sequenzwerte mit
setval(). - Trigger: Oracle-Trigger (BEFORE/AFTER, für jede Zeile) sind vorhanden, aber PG-Trigger unterstützen keine
FOLLOWS/PRECEDES-Reihenfolge (vor PG 17). - Pakete: In PG durch Schemas mit Funktionen/Prozeduren ersetzt; es gibt keine Paketvariablen.
- Dynamisches SQL:
EXECUTE IMMEDIATEin Oracle wird zuEXECUTEin PL/pgSQL. - Cursor:
SYS_REFCURSORwird zuREFCURSOR;FOR ... LOOPist ähnlich. - Ausnahmen:
EXCEPTION WHEN OTHERS THENwird zuEXCEPTION WHEN OTHERS THEN. COMMIT/ROLLBACK: In gespeicherten Prozeduren/Funktionen sind Transaktionen anders; das impliziteCOMMITvon Oracle ist in PG nicht vorhanden; behandeln Sie Transaktionen innerhalb von Prozeduren explizit.SELECT FOR UPDATE: Wird unterstützt; achten Sie auf Sperrkonflikte.
8. Bewährte Methoden für Release-Skripte
Allgemeine Grundsätze
- Idempotenz: Jedes Skript sollte mehrmals ausgeführt werden können, ohne Schaden zu verursachen (z. B.
IF NOT EXISTSfürCREATE,CREATE OR REPLACEfür Funktionen). - Rückgängig machen (Rollback): Bereitstellung eines Rollback-Skripts für jede Änderung, sofern möglich. Dies ist für kritische Releases unerlässlich.
- Transaktionale Einhüllung: Wickeln Sie das gesamte Release in eine Transaktion (wenn die Engine dies unterstützt, z. B. PostgreSQL).
- Versionskontrolle: Committen Sie Release-Skripte in dieselbe Versionskontrolle wie den Anwendungscode.
- Testen: Führen Sie das Release-Skript zuerst in einer Staging-Umgebung aus, die der Produktion möglichst ähnlich ist.
- Peer-Review: Lassen Sie das Skript von einem anderen Teammitglied überprüfen, bevor Sie es in der Produktion ausführen.
- Änderungsmanagement: Dokumentieren Sie die Änderung, den Grund, das Datum, die ausführende Person und etwaige Probleme.
- Ausführungsreihenfolge: Führen Sie Skripte in einer definierten Reihenfolge aus. Erwägen Sie die Verwendung eines Tools wie Flyway oder Liquibase zur Versionskontrolle und sequentiellen Ausführung.
Checkliste für die Skriptüberprüfung
- Sperren: Wird das Skript Sperren verursachen? Wird es lange laufen? Wird es andere Prozesse blockieren? (Prüfen Sie auf
ACCESS EXCLUSIVEin PG,SCH_Min SQL Server,TM-Sperren in Oracle,LOCK TABLE). - Ausführungsplan: Wie wird das Skript ausgeführt? (Verwenden Sie
EXPLAIN). Wird ein Full Table Scan oder ein effizienter Index verwendet? - Datenvolumen: Wie viele Zeilen werden betroffen sein? (Schätzen Sie, ob DMLs viele Zeilen ändern werden).
- Rückgängig machen (Rollback): Gibt es ein Rollback-Skript? Wie werden Daten wiederhergestellt, wenn etwas schief geht?
- Abhängigkeiten: Hängt das Skript von anderen, nicht bereitgestellten Änderungen ab (z. B. Tabellen, Ansichten, Funktionen)?
- Berechtigungen: Ist der/die Ausführende berechtigt? Verfügt der Dienstkonto über die erforderlichen Berechtigungen?
- Metadaten: Sind die Metadaten korrekt (z. B. Datentypen, Einschränkungen, Standardwerte, Kommentare)?
- Sicherheit: Werden sensible Daten offengelegt? Werden Sicherheitspraktiken verletzt?
- Dokumentation: Ist das Skript klar kommentiert?
9. Überprüfungs-Checkliste (Zusammenfassung)
Dies ist eine Kurzcheckliste für die Überprüfung von Datenbankänderungen und -architekturen.
Allgemein
- RPO/RTO definiert
- Hochverfügbarkeit (HA) korrekt konfiguriert (Patroni, Data Guard, AG, HADR, InnoDB Cluster)
- Backup-Strategie dokumentiert und getestet
- Disaster Recovery (DR) getestet (mindestens jährlich)
- Sicherheitsaudit durchgeführt (DSGVO, Least Privilege)
- Überwachung eingerichtet (Performance, Sperren, Fehler)
Performance
- Ausführungspläne für alle neuen/geänderten Abfragen überprüft
- Indizes überprüft und ausreichend
- Statistiken aktuell (oder Autovacuum/Autoanalyze richtig konfiguriert)
- Keine langen Transaktionen identifiziert
- Keine Parameter-Sniffing-Probleme identifiziert (SQL Server)
- Kardinalitätsschätzungen korrekt
Sperren / Nebenläufigkeit
- Alle Tabellen haben geeignete Indizes (einschließlich Fremdschlüssel)
- Keine lang andauernden Transaktionen, die zu Blocker
- Deadlocks durch Überprüfung des Anwendungszugriffsmusters verhindert
- DDL-Sperr-Timeout angemessen niedrig eingestellt
- Online-Operationen für Neuerstellungen von Indizes bevorzugt
SQL-Release
- Idempotenz sichergestellt
- Rollback-Skript bereitgestellt (oder Strategie dokumentiert)
- In transaktionalen Block gehüllt (falls von der Engine unterstützt)
- Auswirkungen auf das Datenvolumen bewertet
- Auf Sperrkonflikte überprüft
- Code-Review durchgeführt
- In Staging-Umgebung getestet
Migration (Oracle -> PostgreSQL)
- Schema-Migration geschehen (mit ora2pg oder Tool)
- Datenmigration geschehen und validiert
- Anwendung getestet (alle kritischen Pfade)
- Umschaltungsplan erstellt (mit Rollback-Option)
- Leistungsregression überwacht
- Fallstricke (CONNECT BY, ROWNUM, MERGE, etc.) behoben