Index Rebuild (Wartungsjob oder interaktiv)

Auf dem  Monitoringserver trat ein Problem auf,  durch die hohe Changerate der Daten (ständig kommen neue hinzu, und im Idealfall werden alte gelöscht) ist nach einer gewissen Zeit die Indexfragmentierungsrate recht hoch ist. Die ist zwar nur ein theoretischer Wert, jedoch führt das in der Praxis tatsächlich zu höheren Laufzeiten bei einfachen Abfragen.

Im Extremfall dauerte die Abfrage (count(*)) gegen eine leere Tabelle Minuten. Da kann zwar auch ein korrupter Block im Spiel gewesen sein, jedoch ist das dann nur ein weiterer Grund für Heilung durch einen Index Rebuild, welcher dann letztlich das Problem löst.

Aus dieser Notwendigkeit sind mehrere Jobs entstanden.

Zunächst ein Job, der den akuten Befund „Abfrage auf Tabelle dauert viel zu lange“ ermittelt und einen Index Rebuild durchführt.

Dann entstand ein Job, der als Kriterium für den Reorg nicht eine vielleicht durch Seiteneffekte beeinflusste Laufzeit, sondern direkt die in die INDEX_STATS ermittelte Fragmentierung als Kriterium heranzieht.

Die übliche empfohlene Schwelle für einen Rebuild  ist ein Fragmentierungsgrad > 20%. Wir fanden teilweise 85% Fragmentierung vor.

( siehe MyOracleSupport How Btree Indexes Are Maintained (Doc ID 30405.1) )

File 2 -> INDEXWARTUNG_MITANALYZE.SQL
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
SET SERVEROUTPUT ON SIZE 1000000

/*
Analysiert für einzugebendes SCHEMA die Fragmentierunge der Indizes und wirft einen INDEX REBUILD ONLINE an. Dies hat sich als relativ sinnfrei erwiesen, da der ANALYZE schon die Tabelle lockt - und länger braucht als der Rebuild.  So machen wir lieber einen Wartungsjob ohne Analyze mit nur Rebuild online! (s.u)

Hier eine kleine Feinheit:
Der Index wird in zwei Schritten analysiert, erst ONLINE, soll den Cache füllen,
dann ohne ONLINE, erst dann wird INDEX_STATS gefüllt, was dann schneller erfolgt
Leider sind die Objektgrößen hier im Monitor Schema jenseits gut & böse...,
führt leider auch zu Locks, trotz gefülltem Cache
*/


DECLARE

USERNAM VARCHAR2(30);
INPUTSCHEMA VARCHAR2(30);

NIND_NAME DBA_INDEXES.INDEX_NAME%TYPE; -- VARCHAR(30);
NTAB_NAME DBA_INDEXES.TABLE_NAME%TYPE; --VARCHAR(30);
FRAG VARCHAR(10);
CMD VARCHAR2(500);
CMD_ONLINE VARCHAR2(512);

EXAMINE_ONLY NUMBER;
REPORT_STAT NUMBER;
NLOOP NUMBER;
LINES NUMBER;
FragRate NUMBER;
Iname VARCHAR(30);
DelRows INDEX_STATS.lf_rows%TYPE; --NUMBER
TabRows INDEX_STATS.lf_rows%TYPE; --NUMBER

BEGIN
DBMS_OUTPUT.PUT_LINE('-- INPUTSCHEMA MUSS!! GEQUOTED EINGEGEBEN WERDEN ');
USERNAM := &&INPUTSCHEMA;

EXAMINE_ONLY := &&NODELETE;

/* 0 ==> FALSE; 1 ==> TRUE */
REPORT_STAT := 1;
DBMS_OUTPUT.PUT_LINE('-- Reportmode ist '|| REPORT_STAT);
NLOOP := 0;

-- Hauptschleife über die INDIZES
FOR NIM_IND IN ( SELECT index_name, table_name FROM dba_indexes
WHERE OWNER = USERNAM AND Index_type = 'NORMAL')
LOOP

NIND_NAME := NIM_IND.index_name;
NTAB_NAME := NIM_IND.table_name;

NLOOP := NLOOP + 1;
DBMS_OUTPUT.PUT_LINE( NLOOP || ': INDEX ' || NIND_NAME);

-- nicht zählen nur "ist mindestens eine Zeile da"
CMD := 'SELECT COUNT(*) FROM (SELECT 1 FROM ' || USERNAM || '.' || NTAB_NAME || ' WHERE ROWNUM <= 1)';

EXECUTE IMMEDIATE CMD INTO LINES;

DBMS_OUTPUT.PUT_LINE(NTAB_NAME || ' ZEILEN : '||LINES);

IF LINES > 0 THEN

--- Something to do?

CMD := 'ANALYZE INDEX ' || USERNAM || '.' || NIND_NAME || ' VALIDATE STRUCTURE';
CMD_ONLINE := CMD || ' ONLINE';

DBMS_OUTPUT.PUT_LINE(CMD);

-- Beschleunigung des Locking Statements durch Füllen des Caches
EXECUTE IMMEDIATE CMD_ONLINE;
EXECUTE IMMEDIATE CMD;

SELECT name, lf_rows , del_lf_rows
INTO Iname, TabRows , DelRows
FROM index_stats
WHERE name = NIND_NAME;

IF DELRows > 0 THEN
FragRate := 100*DelRows/Tabrows;
Frag := TO_CHAR((100*DelRows)/TabRows,'999.9');

IF REPORT_STAT <> 0 THEN
DBMS_OUTPUT.PUT_LINE(Iname || ' Rows: ' || TabRows || ' DelRows: '|| DelRows
|| ' Fragmented: ' || Frag);
END IF;

IF FragRate > 20 THEN

CMD := 'ALTER INDEX "' || USERNAM || '"."' || NIND_NAME || '" rebuild ONLINE';

IF REPORT_STAT <> 0 THEN
DBMS_OUTPUT.PUT_LINE(' ****** Fragmentierungsgrad ' || Frag || ' zu hoch, Index Reorg ist erforderlich ');
END IF;

IF EXAMINE_ONLY = 0 THEN
DBMS_OUTPUT.PUT_LINE(' REORG CMD: ' || CMD);
EXECUTE IMMEDIATE CMD;
COMMIT;
END IF;

END IF; -- FragRate

ELSE --DELROWS
DBMS_OUTPUT.PUT_LINE(Iname || ' 0 gelöschte Zeilen -> keine Fragmentierung ');
FragRate := 0;
END IF; -- DELROWS

END IF; -- LINES

END LOOP; -- NUM_TABLES;

END;
/
EXIT

Leider ist das Ermitteln der validen Indexstruktur maßgeblich teurer als meist der einfach Reorg.

(einleuchtende Erklärung https://blog.pythian.com/analyze-index-validate-structure-dark-side/)

Als Zwischenlösung gibt es einen einfachen Trick der im obigen Script angewandt wurde.

Zunächst ein

analyze index ix validate structure online;

der die Tabelle nicht lockt, jedoch auch INDEX_STATS nicht füllt, gefolgt von einem

analyze index ix validate structure;

DIe Hoffnung ist, jetzt sind die Daten im Cache und der die Tabelle lockende ANALYZE dauert nicht so lange.

Da dies jedoch mit den überaus großen Objekten des Monitoringsschemas unter Produktionsbedingungen nicht funktioniert hat,  letztlich ein Job der einfach alle Indizes eines Schemas neu aufbaut.

Dies kann interaktiv erfolgen, oder je nach Bedarf in einem Zyklus. Ein Wartungsfenster ist nicht erforderlich, da der Job die Objekte nicht lockt. Davon würde Job2 profitieren, in einem Wartungsfenster ohne produktiven Betrieb wäre ein VALIDATE STRUCTUR als Kriterium des Rebuilds hilfreich, und dieser könnte ohne Lock durchgeführt werden.

Doch jetzt der Bulk-Job:

Script 3 -> INDEXWARTUNG_BULK.SQL
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
SET SERVEROUTPUT ON SIZE 1000000

/*
Wartungsjob: für einzugebendes SCHEMA wird ein INDEX REBUILD ONLINE angeworfen.
Dies ist bei Objekten deren Analyse teuer ist, die effektiveste Variante.

*/


DECLARE

USERNAM VARCHAR2(30);
INPUTSCHEMA VARCHAR2(30);

NIND_NAME DBA_INDEXES.INDEX_NAME%TYPE; -- VARCHAR(30);
NTAB_NAME DBA_INDEXES.TABLE_NAME%TYPE; --VARCHAR(30);
FRAG VARCHAR(10);
CMD VARCHAR2(500);
CMD_ONLINE VARCHAR2(512);

EXAMINE_ONLY NUMBER;
NLOOP NUMBER;
LINES NUMBER;
FragRate NUMBER;
Iname VARCHAR(30);
DelRows INDEX_STATS.lf_rows%TYPE; --NUMBER
TabRows INDEX_STATS.lf_rows%TYPE; --NUMBER

BEGIN
DBMS_OUTPUT.PUT_LINE('-- INPUTSCHEMA MUSS!! GEQUOTED EINGEGEBEN WERDEN ');
USERNAM := &&INPUTSCHEMA;

EXAMINE_ONLY := 1;
EXAMINE_ONLY := &&NOWRITE;

/* 0 ==> FALSE; 1 ==> TRUE */

NLOOP := 0;

-- Hauptschleife über die INDIZES
FOR NIM_IND IN ( SELECT index_name, table_name FROM dba_indexes
WHERE OWNER = USERNAM AND Index_type = 'NORMAL'
AND TABLE_NAME IS NOT NULL
ORDER BY INDEX_NAME
)
LOOP
BEGIN -- cause excepzion

NIND_NAME := NIM_IND.index_name;
NTAB_NAME := NIM_IND.table_name;

NLOOP := NLOOP + 1;
DBMS_OUTPUT.PUT_LINE( NLOOP || ': INDEX ' || NIND_NAME);

IF 0=1 THEN -- DOCH NICHT COUNT ausführen
-- nicht zählen nur "ist mindestens eine Zeile da"
CMD := 'SELECT COUNT(*) FROM (SELECT 1 FROM ' || USERNAM || '.' || NTAB_NAME || ' WHERE ROWNUM <= 1)';

EXECUTE IMMEDIATE CMD INTO LINES;

DBMS_OUTPUT.PUT_LINE(NTAB_NAME || ' ZEILEN : '||LINES);
ELSE
LINES := -1;
END IF;

IF LINES <> 0 THEN -- In Sonderfällen kann es nötig sein, trotzdem zu reorganiseren. Dann manuell!

--- Something to do?

CMD := 'ALTER INDEX "' || USERNAM || '"."' || NIND_NAME || '" rebuild ONLINE Nologging PARALLEL 4 ';

DBMS_OUTPUT.PUT_LINE(' REORG CMD: ' || CMD);
IF EXAMINE_ONLY = 0 THEN
DBMS_OUTPUT.PUT_LINE(' EXECUTING CMD ');
EXECUTE IMMEDIATE CMD;
COMMIT;
END IF;

END IF; -- LINES

EXCEPTION WHEN OTHERS THEN
BEGIN
IF SQLCODE = -942 THEN
-- http://www.dba-oracle.com/sf_ora_00942_table_or_view_does_not_exist.htm
DBMS_OUTPUT.PUT_LINE (' Misc.Problem Tabellenobjekt ' || NTAB_NAME );
END IF;
DBMS_OUTPUT.PUT_LINE ('Abgefangener Fehler : Errcode ' || SQLCODE);
GOTO END_LOOP;
END; -- EXCP

END;
<<END_LOOP>>
NULL;
END LOOP; -- NUM_TABLES;

END;
/
EXIT

ORACLE DB, finde User mit Default Passwort

Ein kurzer Augenmerk auf eine kleine Feinheit zum Thema Sicherheit:

Selbst aktuell inaktive Standarduser mit Default Passwort sind unschön, aktiviert man diese und vergisst gleichzeitig das Passwort zu ändern, präsentiert man einen Account den ein Angreifer mit Grundwissen nutzen kann. Daher ist es besser bei Routinechecks diesen Punkt prüfen zu können.

Oracle bietet dafür die VIEW mit sprechendem Namen:  DBA_USERS_WITH_DEFPWD

Nutzen wir sie mit:

select * from dba_users_with_defpwd;

 

Die Ausgabe kann lauten:

USERNAME
——————————
APPQOSSYS
XDB
MDSYS
EXFSYS
SI_INFORMTN_SCHEMA
DIP
ORACLE_OCM
ORDSYS
WMSYS
ORDDATA
CTXSYS
ORDPLUGINS
OUTLN
SCOTT

14 Zeilen gewählt.

User SCOTT taucht in der Liste auf, da er das Standardpasswort TIGER hat.

Natürlich können wir das schnell korrigieren:

ALTER USER SCOTT IDENTIFIED BY SCOTT;

Jetzt haben wir das Problem gelöst, der User hat kein Defaultpasswort mehr und taucht auch nicht mehr auf, wenn wir den Report neu ziehen.

Ganz genau betrachtet haben wir aber ein neues Problem generiert.
Es ist ebenfalls unsicher einem User das gleiche Passwort wie der Username zu geben. Zu den Detailaspekten dieses Problems gibt es folgend einen weiteren Beitrag.

Berechtigungsproblem nach Patch DBSW-12.1.0.2.170418 -> sh SQLPLUS -> libsqlplus.so: -> Permission denied

Berechtigungsproblem nach Patch

Nach Patch einer DB von 12.1.0.2.160419 auf 12.1.0.2.170418 lief ein Shellscript nicht mehr (SOLARIS 11).

Die Fehlermeldung lautete:

Oracle Corporation   SunOS 5.11   11.2 August 2015

ld.so.1: sqlplus: fatal: /u01/app/oracle/product/DB4711/12.1.0.2/lib/libsqlplus.so: Permission denied

 

Es wurden folgende Patches angewandt:

DBSW-12.1.0.2.170418
OJVM-12.1.0.2.170418
12.1.0.2.Datapump
DataPump-24592910

Im Log findet sich unter anderem folgende Sektion:

Patching component oracle.javavm.containers, 12.1.0.2.0…

OPatch found the word „warning“ in the stderr of the make command.
Please look at this stderr. You can re-run this make command.
Stderr output:
+ PATH=/bin:/usr/bin:/usr/ccs/bin
+ export PATH
+ lib=/u01/app/oracle/product/DB4711/12.1.0.2/sqlplus/lib/libsqlplus.so
+ makefile=/u01/app/oracle/product/DB4711/12.1.0.2/sqlplus/lib/ins_sqlplus.mk
+ so_ext=so
+ target=dlopenlib
+ basename /u01/app/oracle/product/DB4711/12.1.0.2/sqlplus/lib/libsqlplus.so .so
+ libname=libsqlplus
+ dirname /u01/app/oracle/product/DB4711/12.1.0.2/sqlplus/lib/libsqlplus.so
+ sodir=/u01/app/oracle/product/DB4711/12.1.0.2/sqlplus/lib
+ ardir=/u01/app/oracle/product/DB4711/12.1.0.2/lib/
+ [ var ‚=‘ dlopenlib ]
+ suffix=LIBS
+ var=“
+ [ ! -f /u01/app/oracle/product/DB4711/12.1.0.2/lib/libsqlplus.a ]
+ [ “ ‚!=‘ “ ]
+ make -f /u01/app/oracle/product/DB4711/12.1.0.2/sqlplus/lib/ins_sqlplus.mk dlopenlib _FULL_LIBNAME=/u01/app/oracle/product/DB4711/12.1.0.2/sqlplus/lib/libsqlplus.so _LIBNAME=libsqlplus _LIBDIR=/u01/app/oracle/product/DB4711/12.1.0.2/lib/ _LIBNAME_LIBS=’$(libsqlplusLIBS)‘ _LIBNAME_EXTRALIBS=’$(libsqlplusEXTRALIBS)‘
ld: warning: symbol ‚_init‘ not found, but .init section exists – possible link-edit without using the compiler driver
ld: warning: symbol ‚_fini‘ not found, but .fini section exists – possible link-edit without using the compiler driver

Composite patch 25171037 successfully applied.

Die Warnung ist eigentlich als zu ignorieren bekannt. Durch sie erfährt man aber von dem Abschnitt mit Makefile: das File wird neu gebaut, also entsteht es neu mit den vorgesehenen Defaultrechten. Damit liegt die Ursache auf der Hand:
Vorherige Dateirechte werden überschrieben unabhängig davon, ob jemand eingegriffen hatte, um die Rechte auf world read zu setzen, oder ob sie vorher auf Default standen.
Der Befehl
chmod 644 „Dateipfad/libsqlplus.so“
löst das Zugriffsproblem des Reports, jetzt kann „world“ wieder zugreifen.
Man kann das Ganze auch auf Oracle Metalink nachlesen unter diesen Stichworten:

SYSAUX Growth Oracle 11.2.0.4

Dies ist der detaillierte Beitrag zum Thema SYSAUX Growth Oracle.  Es gibt auch eine kürzere Zusammenfassung:  (Link)

Auf unseren gepatchten SOLARIS Systemen mit Oracle 11.2.0.4, aktuelles Patchlevel, erlebten wir die Auswirkungen eines von Oracle dokumentierten Bugs.

Bug 14373728 „Old Statistics not Purged from SYSAUX Tablespace“

Es fällt auf, dass SYSAUX immer größer wird, auch wenn keine Daten mehr hinzukommen. Im EM sieht das dann so aus:

Piechart SYSAUX Objektgrößen zu Bereichen
Piechart SYSAUX Objektgrößen zu Bereichen

Der dem Piechart zugrunde liegende Befehl:

1
2
SELECT RPAD(occupant_name,24) occupant_name, RPAD(schema_name,20) schema_name, space_usage_kbytes/1024 space_usage_mb
FROM v$sysaux_occupants ORDER BY space_usage_kbytes DESC, occupant_name;

 

Objektgrößen (Textmode)
Objektgrößen (Textmode)
Speicherbedarf AWR
Speicherbedarf AWR

Hier fällt sofort der exzessive Speicherbedarf der AWR Daten auf. Bei einer DB ohne Größenwachstum durch die Nutzerdaten ist es sehr unangenehm, wenn SYSAUX in die Größenordnung der Daten kommt.

„SYSAUX Growth Oracle 11.2.0.4“ weiterlesen

Oracle Opatch failed with error code 73

Beim Patchen einer Datenbank kam unerwartet die Fehlermeldung:

opatch failed with error code 73

Vorarbeiten waren:

Oracle Database 12c Enterprise Edition Release 12.1.0.2.0 – 64bit Production
With the Partitioning, OLAP, Advanced Analytics and Real Application Testing options

Loading login.sql file…
SYS@DBASQL>shutdown immediate
Database closed.
Database dismounted.
ORACLE instance shut down.
SYS@DBASQL>exit
Disconnected from Oracle Database 12c Enterprise Edition Release 12.1.0.2.0 – 64bit Production
With the Partitioning, OLAP, Advanced Analytics and Real Application Testing options
oracle_DBA@dbe16:~$> srvctl stop listener -l LISTENER_DBA

Der folgende Check auf die Prerequisites war erfolgreich:

oracle_DBA@dbe16:/stage/Oracle/SOLARIS/SPARC/12.1.0.2/patches/DBSW-12.1.0.2.170418/25171037$> $ORACLE_HOME/OPatch/opatch prereq CheckConflictAgainstOHWithDetail -ph ./
Oracle Interim Patch Installer version 12.2.0.1.8
Copyright (c) 2017, Oracle Corporation. All rights reserved.

PREREQ session

Oracle Home : /u01/app/oracle/product/DBA/12.1.0.2
Central Inventory : /u01/app/oraInventory
from : /u01/app/oracle/product/DBA/12.1.0.2/oraInst.loc
OPatch version : 12.2.0.1.8
OUI version : 12.1.0.2.0
Log file location : /u01/app/oracle/product/DBA/12.1.0.2/cfgtoollogs/opatch/opatch2017-11-03_08-17-18AM_1.log

Invoking prereq „checkconflictagainstohwithdetail“

Prereq „checkConflictAgainstOHWithDetail“ passed.

OPatch succeeded.

Trotzdem gab es einen Fehler beim Anwenden des Patches:

oracle_DBA@dbe16:/stage/Oracle/SOLARIS/SPARC/12.1.0.2/patches/DBSW-12.1.0.2.170418/25171037$> $ORACLE_HOME/OPatch/opatch apply
Oracle Interim Patch Installer version 12.2.0.1.8
Copyright (c) 2017, Oracle Corporation. All rights reserved.

Oracle Home : /u01/app/oracle/product/DBA/12.1.0.2
Central Inventory : /u01/app/oraInventory
from : /u01/app/oracle/product/DBA/12.1.0.2/oraInst.loc
OPatch version : 12.2.0.1.8
OUI version : 12.1.0.2.0
Log file location : /u01/app/oracle/product/DBA/12.1.0.2/cfgtoollogs/opatch/opatch2017-11-03_08-20-27AM_1.log

Verifying environment and performing prerequisite checks…
Prerequisite check „CheckActiveFilesAndExecutables“ failed.
The details are:

Following executables are active :
/u01/app/oracle/product/DBA/12.1.0.2/lib/libclntsh.so.12.1
UtilSession failed: Prerequisite check „CheckActiveFilesAndExecutables“ failed.
Log file location: /u01/app/oracle/product/DBA/12.1.0.2/cfgtoollogs/opatch/opatch2017-11-03_08-20-27AM_1.log

OPatch failed with error code 73

Ermitteln des Prozesses:

$> fuser    /u01/app/oracle/product/DBA/12.1.0.2/lib/libclntsh.so.12.1
/u01/app/oracle/product/DBA/12.1.0.2/lib/libclntsh.so.12.1:   26298m

$> ps 26298
PID TT S TIME COMMAND
26298 ? S 0:00 /u01/app/oracle/product/DBA/12.1.0.2/bin/tnslsnr LISTEN

Es war der Listener. Obwohl dieser gestoppt war.

Nochmaliges Stoppen des Listeners und der „Opatch apply“ läuft ohne Probleme! Notfalls killen des Prozesses.

Im Alert fand sich übrigens auch eine Fehlermeldung:

ORA-12514: TNS:listener does not currently know of service requested in connect descriptor

Tablespace Map (wie in DBA Studio), auch in Oracle Enterprise Manager 12c

Die aus dem älteren DBA Studio bekannte, recht nützliche Tablespace Map ist im Enterprise Manager recht schwer zu finden.

So sah sie aus:

Tablespace Map DBA Studio
Tablespace Map DBA Studio

Hier kurz der Wegweiser zum Ziel, um sie auch im Enterprise Manager zu nutzen:

Wir navigieren unter Administration – Storage zu Tablespaces:

Was man selektieren muss (Click to View, then ESC to go back)

In der Auswahlbox über die Funktionen, die defaultmäßig auf „Add Datafile“ steht, selektieren wir „Show Tablespace Contents„. Ich muss zugeben, darunter hatte ich etwas Anderes erwartet.

Es geht dann eine Ansicht auf, auf der wir ganz unten unter dem „Contents“ einen unscheinbaren Link finden, „Extent Map„.

die Tablespacemap
Die Tablespacemap

Nutzen wir diesen Link, klappt tatsächlich die aus dem DBA Studio bekannte Ansicht auf! Welch Überraschung.

Für diejenigen, die noch nicht wissen, was man damit Nützliches anfangen kann, folgt eine kurze Erklärung.  Es werden genutze und freie Blöcke farblich gekennzeichnet. Man erkennt damit die Nutzung (und Fragmentierung) des Tablespaces.

Tablespacemap mit Legende
Tablespacemap mit Legende

 

Wofür ist das gut?

Manchmal ist ein Tablespace zu groß, und man bekommt ihn mit ALTER .. RESIZE nicht kleiner, da am Ende des Tablespace noch ein Objekt ist.

ORA-03297: file contains used data beyond requested RESIZE value

Welches Objekt da stört, erfährt man hier dynamisch mit einem einfachen Mouseover (Tooltip). Dann kann man dieses Objekt reorganisieren und hat die Chance, dass der Tablespace verkleinert werden kann. Dies ist nützlich bei Objekten, die üblicherweise nicht automatisiert reorganisert werden können wie SYSAUX.

Hier ist rechts unten die hellblaue Fläche das Objekt welches eine Reorganisation verhindert. Als Tabelle ein Move, als Index ein REBUILD löst das Problem.

Natürlich kann man die den Shrink störenden „höchsten“ Objekte auch mittels der Console ermitteln:

1
2
3
4
5
6
7
8
9
10
11
SELECT * FROM
( SELECT file_id, block_id, block_id + blocks - 1 end_block, owner,
segment_name, partition_name, segment_type
FROM dba_extents
WHERE tablespace_name = 'SYSAUX'
UNION ALL
SELECT file_id, block_id, block_id + blocks - 1 end_block,'free' owner, 'free' segment_name,
NULL partition_name, NULL SEGMENT_TYPE FROM DBA_FREE_SPACE
WHERE TABLESPACE_NAME = 'SYSAUX'
ORDER BY 1 DESC, 2 DESC)
WHERE ROWNUM &lt; 10;

Ein beispielhafter Output sieht dann z.B. so aus:

FILE_ID BLOCK_ID END_BLOCK OWNER SEGMENT_NAME PARTITION_NAME SEGMENT_TYPE
———- ———- ———- —— ——————————- —————————— ——————
10 25792 25855 SYS I_WRI$_OPTSTAT_H_ST INDEX
10 25280 25791 SYS AUD$ TABLE
10 24192 24255 SYS I_WRI$_OPTSTAT_H_OBJ#_ICOL#_ST INDEX
10 24128 24191 SYS WRH$_LATCH WRH$_LATCH_489711439_34766 TABLE PARTITION

 

Dies wären dann die Kandidaten für einen MOVE/REBUILD, um den Platz am Ende der Datei freizuschaufeln.

SYSAUX Wachstum in Oracle 11g – AWR Snapshots zu groß

AWR snapshots

Dies ist der allgemeine Beitrag zu diesem Thema. Am Ende des Beitrags finden Sie einen Link zu dem detaillierten Beitrag (mit Source der Scripte)

Oracle 11g SYSAUX Growth, Bug 14373728 „Old Statistics not Purged from SYSAUX Tablespace“

Beim Betrieb von etlichen Datenbanken, gemischt Oracle 11.2.0.4.3 sowie 12.1.0.2.1, fielen im Vergleich die 11g Datenbanken durch exzessives Größenwachstum in SYSAUX auf – bei gleicher Datenlage wie eine entsprechend auf 12c aufgesetzte DB waren gigabyteweise mehr Daten im Tablespace SYSAUX vorzufinden.
Detailanalyse zeigte dann auf, dass die anwachsenden Daten unter „Automatic Workload Repository“ – AWR geführt sind.

Piechart SYSAUX
Piechart SYSAUX

Der folgende Link weist auf einen Artikel von Frau Held hin, eine hervorragende Fundstelle, die die dem Problem zugrunde liegenden Ursachen beschreibt.

der-oracle-sysaux-tablespace-reorganisation-und-verkleinerung

Dieser Beitrag hier geht noch etwas weiter und beschreibt die Möglichkeiten, eine Maschine zu bereinigen, die schon soviel Daten angehäuft hat, dass die Standardprozeduren in Resourcenprobleme laufen.

Ursache ist ein Bug, der scheinbar in der SOLARIS Release nicht gepatcht war:

Oracle Bug 14373728 Description
Oracle Bug 14373728 Description

Auswirkung:

List size of objects
Liste nach Objektgrösse

Diese Übersicht kommt aus dem EM. Man kann sie sich auch manuell holen:

Select * from v$sysaux_occupants order by SPACE_USAGE_KBYTES DESC

Liste der Objektgrößen - script
Liste der Objektgrößen – script

Wir sehen hier eine Vielzahl von Tabellen und Indizes (partitioned), die definitiv zu groß sind.
Über awrinfo kann man sich die zu erwartenden Größen anzeigen lassen.
Das awrinfo.sql script findet man im $ORACLE_HOME/rdbms/admin directory

Beispieloutput (LINK)

Dort findet man auch eine Schätzung der zu erwartenden Größen des AWR-Bereichs aufgrund der eingestellten Retentionparameter. Üblich ist z.B. ein stündlicher Snapshot für 7 Tage oder 30 Tage.

Die Informationen kann man sich natürlich auch dediziert holen:

SELECT DBID, MIN(SNAP_ID), MIN(BEGIN_INTERVAL_TIME), MAX(SNAP_ID), MAX(BEGIN_INTERVAL_TIME)
from dba_hist_snapshot group by dbid;

ergibt dann beispielsweise:

DBID MIN(SNAP_ID) MIN(BEGIN_INTERVAL_TIME) MAX(SNAP_ID) MAX(BEGIN_INTERVAL_TIME)
———- ———— ————————— ———— —————————
2996453776 15599 26.10.17 00:00:17,112000000 15806 03.11.17 14:00:23,434000000

 

Verändert werden können die Parameter, die die Frequenz der Berechnung und Aufbewahrungszeit steuern, zum Beispiel so:

— change retention time
— this is in minutes chg to 4d
exec DBMS_WORKLOAD_REPOSITORY.MODIFY_SNAPSHOT_SETTINGS(retention=>5760);

 

Aufgrund eines Bugs in der Release 11g kommt es jedoch vor, dass der physische Speicherbedarf unlimitiert anwächst, da alte Snapshots nicht entfernt werden.
Diese müssen dann manuell entfernt werden. Dafür gibt es eine Standardprozedur:

DBMS_WORKLOAD_REPOSITORY. DROP_SNAPSHOT_RANGE
(LOW_SNAP_ID => MIN_ID, HIGH_SNAP_ID => MAX_ID, DBID => DBID);

 

Zu füttern ist der Aufruf mit der DBID sowie dem Range der verwaisten Snapids. Später liefern wir ein Script, mit dem man diese ermitteln kann.

Ausgabe Simplescript:

Partition_name WRH$_ACTIVE_413047826_8381
i 1 dbid 413047826 : WRH$_ACTIVE_413047826_8381 MinInPartition 8381 MaxInPartition 8404

Anzahl verwaister Records ist 6253 MinOrphaned is 8381 MaxOrphaned is 8403

Executing: DBMS_WORKLOAD_REPOSITORY.DROP_SNAPSHOT_RANGE ( low_snap_id ->8381; high_snap_id ->8403; dbid ->413047826);
simple script kann DROP_SNAPSHOT_RANGE direkt aufrufen, das ist die Komfortlösung.

Ausgabe Detailscript:

DBID in DBA_HIST_WR_CONTROL 413047826

===0> Hier stehen die inkonsistenten Daten für das manuelle Delete ==>
DBID in WRH$_EVENT_HISTOGRAM 413047826 MIN SNAPID 8381 MAX SNAPID 8403

===0> Und hier stehen die aktuellen Daten für den zeitnahen Bereich ==>
DBID in DBA_HIST_SNAPSHOT 413047826 MIN SNAPID 8404 MAX SNAPID 8611 MINT 26.10.17 00:00:43,119

Die Werte für den Aufruf von DROP_SNAPSHOT_RANGE kann man hier direkt ablesen und einsetzen.
Im Normalfall wäre man dann schon fertig.

Leider passiert es, wenn die Datenbanken längere Zeit, viele Monate ohne diese Pflege laufen, dass sich soviele Daten in SYSAUX AWR ansammeln, dass die DROP_SNAPSHOT_RANGE-Procedur in solch große Resourcenprobleme kommt, dass das Ganze nicht mehr handelbar ist.

Dafür haben wir dann ein Script gebaut, das resourcenschonend Objekt für Objekt in handlichen Chunks löscht (jeweils commited), und dies in von außen begrenzbaren Iterationen. So konnten wir letztlich das Größenwachstum in den Griff bekommen.

„SYSAUX Wachstum in Oracle 11g – AWR Snapshots zu groß“ weiterlesen

Install SQL Developer 32 Bit (Javaprobleme)

missing JDK path OSD

Ausgangssituation:

Auf einer 32-Bit virtuellen Workstation hätte ich gerne den aktuellsten ORACLE  SQL Developer. Auf der Maschine habe ich keine ADMIN-Rechte, keinen Schreibzugriff auf c:\Programme

Bei OTN habe ich mir die Installationspakete für OSD (Oracle SQL Developer) 4.0x sowie 17.x besorgt, jeweils 32 Bit ohne JDK sowie 64 Bit mit included SDK.

Leider ließ sich kein Paket zum Laufen bringen.
Beim Anstarten fragte OSD immer nach dem Pfad der JRE.

Gab man den richtigen Pfad an, war er leider nicht damit zufrieden.
Ich meinte mich zu erinneren, dass ich auf einer Maschine, auf der ich Schreibrechte hatte, einfach den Pfadnamen anpasste von

….\jdk\jre1.8.0_92

zu

…\jdk\jre

und dass es dann lief.
Hier half das nicht.

Hilfreich war dann dieser Link:

SQL Developer – Cannot find a Java SE SDK installed at path

Die Kollegen wiesen nach, dass der Unterschiede der Releases nur die JDK im OSD Verzeichnis ist.

Unglücklicherweise ist ein harter Verweis eingebaut, so dass man Probleme bei der Benutzung der installierten JRE hat:

Wir sehen  das  SetJavaHome ist  ../../jdk

Und wo soll das sein?

Mit diesen Informationen kann man einfach das JRE ins Verzeichnis mergen und der OSD ist lauffähig.
Es wundert mich schon, dass man zu solch einer „kreativen“ Lösung gezwungen wird.