Schlagwort-Archive: Troubleshooting

Verwirrung um ISDEFAULT in v$parameter

In der Data Dictionary-View „v$parameter“ sind die Einstellungen der Instanz-Parameter hinterlegt. Da diese Parameter nicht nur in den Konfigurationsdateien (init.ora oder SPFile) sondern auch in der laufenden Instanz oder in einzelnen Sessions geändert werden können, ist diese View der erste Anlaufpunkt, wenn man sich einen Überblick über die aktuellen Einstellungen verschaffen will.

Allerdings sind die Spalten dieser View nicht mit Kommentaren versehen, und ihre Namen können irreführend sein, wie im Fall der Spalte „isdefault“:

Weiterlesen

Hallo Steinzeit! 8-Zeichen-Restriktion bei Servernamen

Manchmal trifft man noch auf Relikte aus der IT-Steinzeit. Zum Beispiel, wenn man den folgenden Code ausführen will, um in SQL die IP-Adresse des Hosts zu ermitteln. In diesem Beispiel ist der Servername „xx-myserver“:

SQL> select sys.utl_inaddr.get_host_address() from dual;

select sys.utl_inaddr.get_host_address() from dual

*

ERROR in line 1:

ORA-29257: host xx-myser unknown

ORA-06512: at "SYS.UTL_INADDR", line 19

ORA-06512: at "SYS.UTL_INADDR", line 40

ORA-06512: at line 1

Auch in Tracefiles fällt in diesem Fall auf, daß der Servername auf „xx-myser“ gekürzt ist.

Gut versteckt in der Oracle Knowledge Base findet sich das Dokument 957443.1, das folgendes aussagt:

Oracle 10.1, 10.2 and 11.1 do not support a hostname longer than 8 characters on HP-UX operating system.

Also frei übersetzt: Bis ins Jahr 2009 (Release von 11gR2) war es für Oracle unter HP-UX nicht vorgesehen, Servernamen mit mehr als acht Zeichen zu unterstützen!

Zugegeben, die Zahl der potentiellen Probleme damit wird klein sein, aber auf jeden Fall größer als Null, wie man in diesem Thread sehen kann. Wer bei der Vergabe von Servernamen diese Grenze überschreiten will, sollte also besser Oracle 11.2 einsetzen…

Fallstudie: ORA-01652 und fragmentierte Tablespaces

Seit Oracle 9i gibt es die sogenannten „System Managed Tablespaces“, bei denen das RDBMS die Extentgröße automatisch festlegt („Autoallocate“, im Gegensatz zu „Uniform Extent Size“). Dieses Feature nimmt dem DBA einige Planungsarbeit ab, kann aber auch Tücken mit sich bringen, wie diese Fallstudie zeigt.

Szenario

  • Oracle 10gR2 (10.2.0.4)
  • Ein Tablespace für nahezu alle Tabellen der Anwendung:
    • 1 TB Größe
    • Locally Managed mit ASSM
    • Auto Extent Size
    • ca. 5000 Tabellen, viele davon > 1 GB und partitioniert.

Es wird ein „CREATE TABLE AS SELECT“ („CTAS“) ausgeführt, das nach einiger Laufzeit mit dem Fehler

ORA-01652: unable to extend temp segment by 128 in tablespace USERS

abbricht. Die Entwickler erwarteten, daß eigentlich noch genügend Platz im Tablespace hätte vorhanden sein müssen. Die Vergrößerung des Tablespaces bringt für einige Zeit Abhilfe, dann taucht der Fehler jedoch wieder auf. Weiterlesen

DBMS_SESSION: Anwender und Sessions mehrschichtiger Anwendungen in der DB identifizieren

„Wer war das“!?

In mehrschichtigen Softwarearchitekturen (also einem Großteil der Web-Anwendungen) wird die Verbindung zur Datenbank meist über wiederverwendbare Verbindungen, sog. Connection Pools, aufgebaut (siehe dazu auch meinen Artikel über Proxy-User). Wenn die Benutzerverwaltung nicht in der Datenbank sondern in der Anwendung stattfindet, verbindet sich dabei der Application Server üblicherweise mit einem einzigen, „technischen User“ mit der Datenbank.

Dem Vorteil der dadurch eingesparten Zeit für einen Verbindungsaufbau bei jeder DB-Abfrage steht damit aber der Nachteil gegenüber, daß auf der DB-Seite nicht mehr nachvollzogen werden kann, welcher Anwender und welche (oder welcher Teil der) Anwendung in einer bestimmten Session läuft. Das ist zwar im Normalbetrieb nicht so wichtig, wenn es aber zu Problemen kommt, dann kann diese fehlende Information die Fehlersuche schwer beeinträchtigen. Drei häufige Szenarien seien hier genannt:

  • Der DB-Server ist plötzlich überlastet. Die Ursache kann zwar bis zu einer bestimmten Session in der Datenbank verfolgt werden, aber nun ist noch nicht klar, wer diese Session besitzt und welche Aufgabe er gerade ausführen will.
  • Ein Anwender beklagt sich über zu lange Antwortzeiten in einem bestimmten Anwendungsteil. Von den 500 offenen Sessions auf der DB kann aber nicht identifiziert werden, in welcher dieser Sessions der Anwender aktiv ist, und daher kann keine gezielte Fehlerverfolgung (z.B. mittels Tracing) durchgeführt werden.
  • Zur Erfüllung von Sicherheitsrichtlinien sollen Informationen über die Aktivitäten von Anwendern in der Datenbank gesammelt werden (Auditing). Das Oracle RDBMS kann das zwar von Haus aus, wenn aber die Verbindung nur über einen einzigen Useraccount läuft, fehlen wesentliche Informationen.

Softwareentwickler sollten daher schon im eigenen Interesse Ihre Anwendungen von Anfang an so instrumentieren, daß ein DBA bei Problemen auf der Datenbank gezielt Informationen sammeln kann.

Weiterlesen

Data Pump: Umgang mit Partitionen

Dieser Artikel bezieht sich im Wesentlichen auf Oracle Version 10g.

Problem:

Aus einer Quell-DB mit partitionierten Tabellen sollen Daten auf eine Ziel-DB ohne Partitioning Option transferiert werden. Diese Kombination ist wegen der Zusatzkosten für die Partitioning Option gar nicht so selten; die Quelle könnte ein Produktionssystem und das Ziel ein Testsystem oder ein Data Mart sein.

Wird ein herkömmlicher Import mit der Data Pump versucht, bricht imdp mit der Fehlermeldung „ORA-00439: feature not enabled: Partitioning“ ab.

Dummerweise wird dieser Fehler ausgegeben, auch wenn die Tabelle in der Ziel-DB bereits existiert und nur die Inhalte übertragen werden sollen (d.h., die Option „table_exists_action=append“ hilft hier auch nicht).

Abhilfe:

  1. Manuelles Anlegen der Tabelle in der Ziel-DB ohne Partitionen bzw. bestehende, unpartitionierte Tabelle leeren (truncate)
  2. Bei großen Datenmengen im Vorfeld Indizes und Constraints deaktivieren
  3. Import der Daten mit der Option „CONTENT=DATA_ONLY
  4. Indizes und Constraints wieder aktivieren oder neu aufbauen.

Soll ein ganzes Schema mit vielen unpartitionierten und wenigen partitionierten Tabellen importiert werden, dann kann man zunächst die unpartitionierten Tabellen in einem ersten Durchlauf importieren und in einem zweiten Durchlauf die o.g. Punkte durchführen.

Ab Oracle 11g

…wird das viel einfacher: Mit der Option

PARTITION_OPTIONS=merge

Können alle Partitionen der Quelle in eine Tabelle des Ziels überführt werden. Darüberhinaus gibt es mit „departition“ auch die Möglichkeit, pro Partition eine neue Zieltabelle anzulegen.

Tabellenspalten lassen sich nicht löschen

Derzeit arbeite ich intensiv an einem spannenden Projekt, das in Kürze online sein wird. Daher bleibt mir vorerst nur wenig Zeit zum Bloggen, aber für einen kurzen Artikel reicht es heute!

Szenario:

Bei einer Tabelle wird versucht, eine Spalte zu löschen. Dies endet mit der Fehlermeldung:

ORA-39726: unsupported add/drop column operation on compressed tables

Die Fehlermeldung gibt einen Hinweis darauf, daß die Tabelle mit Datenkompression versehen ist. Der Versuch, die Tabelle zu dekomprimieren und danach die Spalten zu löschen schlägt aber auch fehl! Hier ein Beispiel zum Nachtesten:

CREATE TABLE aerger(c1 NUMBER, u1 NUMBER) COMPRESS
/
ALTER TABLE aerger SET UNUSED( u1 )
/
ALTER TABLE aerger DROP UNUSED COLUMNS
/

Error at line 1
ORA-39726: unsupported add/drop column operation on compressed tables

ALTER TABLE aerger NOCOMPRESS
/
ALTER TABLE aerger DROP UNUSED COLUMNS
/

Error at line 1
ORA-39726: unsupported add/drop column operation on compressed tables

Das Beispiel könnte man auch abkürzen und den Weg über „set unused“ gar nicht verwenden; auch ein direktes „Drop“ geht nach einer Kompression nicht mehr.

Ist das nun ein Bug? Laut dem Artikel 1068820.1 der Oracle Knowledge Base nicht: In 10g ist dies das erwartete Verhalten. Es gab einen Bug in 10.2.0.3, der eine Löschung ermöglichte, was aber nicht dem erwarteten Verhalten entsprach.

Lösungsansätze:

  • Unused Colums belassen, wie sie sind.
  • Tabelle mit „create table as select“ neu anlegen.
  • Upgrade auf Oracle 11g .

Anmerkungen zu INSERT ALL

Seit Oracle 9i gibt es die Option des sogenannten „Multi-Table Insert“, mit dem die bekannte INSERT … SELECT … – Syntax so erweitert wurde, daß die Ergebnisse aus dem SELECT auf mehrere Tabellen verteilt werden können. Ein paar Beispiele stehen in der Oracle-Doku.

INSERT ALL und Sequences

Nicht ganz intuitiv ist die Verwendung von Sequences: Soll z.B. in einer Master-Detail-Beziehung eine ID aus einer Sequence mehrfach verwendet werden, so kommt nicht CURRVAL zum Einsatz, sondern es muß überall NEXTVAL verwendet werden:

INSERT ALL
      INTO master_tab ( id, kunde_nr, ... )
    VALUES ( master_seq.NEXTVAL, ... )
      INTO detail_tab ( master_id, detail_nr, ... )
    VALUES ( master_seq.NEXTVAL, 1, ... )
    SELECT kunde_nr
      FROM tmp_aktive_kunden;

Bugs mit Master-Detail-Tabellen

Wenn man das obige Beispiel einmal ausprobiert, kann es durchaus vorkommen, daß es abbricht, wenn eine Fremdschlüsselbeziehung zwischen den Tabellen vorliegt.

ORA-02291: integrity constraint violated - parent key not found

Es handelt sich dabei um den seit 2003 bis heute noch nicht behobenen Bug 2891576. Dieser Bug lässt sich umgehen, indem das vorhandene Constraint entweder deaktiviert oder mit Deferred Constraints gearbeitet wird.

Allerdings gibt es auch beim Workaround einen Wermutstropfen: In einem Szenario mit zwei Tabellen von je etwa 2 Millionen Datensätzen und einem Insert von je 400000 Datensätzen kam es auf einem meiner Testsysteme (10.2.0.3, HP-UX 11.31 Itanium) zu sehr langen Laufzeiten, wenn Deferred Constraints verwendet wurden. Ohne Constraint war das Statement in Sekunden durch. Eine Klärung durch Oracle steht noch aus, ich werde den Artikel dann ergänzen.

Edit vom 21.1.2010:
Für den o.g. „Wermutstropfen“ ist bei Oracle inzwischen der Bug #9169330 erfasst, der momentan aber nicht öffentlich einsehbar ist. Auf jeden Fall arbeitet Oracles Entwicklungsteam daran.

Weblinks