Number of processes exceeded: zeitliche Entwicklung als Kurzübersicht

Auf einer 12c Datenbank zeigte sich ein ORA-0020

ORA-00020: maximum number of processes (300) exceeded

Bevor der Parameter erhöht wird mit

ALTER SESSION SET PROCESSES=350 scope=BOTH;

lohnt es sich zu schauen, wie denn die Entwicklung der letzten Tage (max des Values in der History) war.

Folgender SQL-Befehl leistet das:

1
2
3
4
5
6
7
8
9
10
-- Maximum per day:
SELECT instance_number inst, TO_CHAR( begin_time, 'YYYY-MM-DD') DATUM , MAX(processes) FROM
(SELECT instance_number, ROUND(maxval/100 * gv$parameter.VALUE) processes, begin_time
FROM dba_hist_sysmetric_summary
join gv$parameter
ON dba_hist_sysmetric_summary.instance_number = gv$parameter.inst_id
WHERE gv$<a href="http://parameter.name">parameter.name</a> = 'processes'
AND metric_name = 'Process Limit %')
GROUP BY instance_number,TO_CHAR( begin_time, 'YYYY-MM-DD')
ORDER BY DATUM DESC;

Ausgabe:

INST DATUM MAX(PROCESSES)
 ---------- ---------- --------------
 1 2017-11-27 299
 1 2017-11-26 265
 1 2017-11-25 268
 1 2017-11-24 265
 1 2017-11-23 218
 1 2017-11-22 219
 1 2017-11-21 218
 1 2017-11-20 137
 1 2017-11-19 137
 1 2017-11-18 134

Nun kann man anhand der Entwicklung entscheiden, ob man auf jeden Fall den INIT.ORA Parameter überhöht, oder ob man es als einzelen Außreisser wertet. Selbst dann müsste man entscheiden ob man nicht dennoch erhöht.
Jedoch hier spricht die stetig steigende Resourcenauslastung, wenn keine weitere Ursachenforschung sinnvoll erscheint, für die pragmatische Erhöhung zu sprechen.

ORACLE: Passwort = Username, unsichere Passwörter ermitteln

 unsicheres Passwort, identisch mit Username oder „meistgenutzt“ (auf Liste)
Sicherheitslücke: User mit leicht zu erratenden Passwort

Ein weiterer Aspekt, der es potentiellen Angreifern leichter macht ist der Fall, dass ein User sein Passwort als Usernamen gewählt hat.

Wir stellen also ein einfaches Script vor, das die User ermittelt die in diese  Sicherheitsklasse fallen.

Wir gehen von der Annahme aus, der User hätte Username = Passwort.

Schritte zu unserer Lösung:
  1. Loopen über alle DB-User
  2. hashen unseres angenommen Passworts nach der Standardmethode
  3. ziehen des gespeicherten Hashs
  4. compare. Bei Treffer, Listung des Users

Um einen Testfall zu haben, machen wir folgendes, ausgehend von User SCOTT, oder einem neu anzulegenden User TEST, um einen Testfall für das Script zu haben:

ALTER USER SCOTT IDENTIFIED BY SCOTT;

 

Wir lassen unser Script laufen:

SCOTT is UNSAFE PWD guessed IS SCO******
TEST is UNSAFE PWD guessed IS TES******

PL/SQL-Prozedur erfolgreich abgeschlossen.

 

Oracle Passwörter sind jedoch nicht mehr Case-Insensitiv.
Was ist, wenn des Users Passwort „Scott“ lautet? Es sind immerhin nur wenige Versuche für den potentiellen Angreifer, die KOmbinationen SCOTT, Scott sowie scott durchzuprobieren. Wir testen das aus:

ALTER USER SCOTT IDENTIFIED BY Scott;

Ergebnis:

SCOTT is UNSAFE PWD guessed IS Sco******
TEST is UNSAFE PWD guessed IS TES******

PL/SQL-Prozedur erfolgreich abgeschlossen.

 

Unser Script findet das auch! Natürlich haben wir das schon bedacht, obige Steps 2-4 erfolgen jeweils für die Varianten „angenommenes Passwort Username“ in den beschriebenen drei Varianten.

  1. Loopen über alle DB-User
  2. Erstelle Passwort wie Username in Lowercase ( jump to 5)
  3. Erstelle Passwort wie Username in Uppercase  ( jump to 5)
  4. Erstelle Passwort wie Username in Mixedcase (Capitals) ( jump to 5)
  5. hashen unseres angenommen Passworts nach der Standardmethode
  6. ziehen des gespeicherten Hashs
  7. compare. Bei Treffer, Listung des Users.
  8. jump back – next step

Wie sieht das script aus? Hier haben wir es:

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
SET serveroutput ON size 1000000

DECLARE
unsecure BOOLEAN;
DUMMY VARCHAR2(80);
c_username VARCHAR2(256);
chk_token VARCHAR2(256);
dbname v$database.name%TYPE;

lv_pwd_raw RAW(128);
lv_enc_raw RAW(2048);
LV_HASH_FOUND VARCHAR2(300);

CURSOR c_main(cp_user IN VARCHAR2)
IS
SELECT SUBSTR(spare4,3,40) hash,
SUBSTR(spare4,43,20) salt,
spare4
FROM sys.USER$
WHERE name=cp_user;
lv_user c_main%ROWTYPE;

CURSOR cu_user
IS
SELECT username
FROM dba_users
WHERE ACCOUNT_STATUS LIKE 'OPEN%';

FUNCTION COMPARE_PW_HASH(luser IN VARCHAR2, lpw IN VARCHAR2)
RETURN NUMBER IS

BEGIN
OPEN c_main(UPPER(luser));
FETCH c_main INTO lv_user;
CLOSE C_MAIN;
lv_pwd_raw := UTL_RAW.cast_to_raw(lpw)||HEXTORAW(lv_user.salt);
lv_enc_raw := sys.dbms_crypto.hash(lv_pwd_raw, 3);
lv_hash_found:=UTL_RAW.cast_to_varchar2(lv_enc_raw);

IF LV_ENC_RAW = LV_USER.hash THEN
-- DBMS_OUTPUT.PUT_LINE('PWD found for User ' || luser );
RETURN 1;
ELSE
-- dbms_output.put_line('PWD not found for Safe User ' || luser);
RETURN 0;
END IF;
END;

BEGIN
DBMS_OUTPUT.ENABLE(10000000);

SELECT NAME INTO dbname FROM v$database;
--DBMS_OUTPUT.PUT_LINE('Start Checking DB ' || dbname);
--DBMS_OUTPUT.PUT_LINE('');

OPEN cu_user;
LOOP
FETCH cu_user INTO c_username;
EXIT WHEN cu_user%NOTFOUND;

unsecure := FALSE;

IF COMPARE_PW_HASH ( c_username , c_username ) > 0 THEN
unsecure := TRUE;
chk_token := c_username;
ELSIF COMPARE_PW_HASH ( c_username , UPPER(c_username) ) > 0 THEN
unsecure := TRUE;
chk_token := UPPER ( c_username) ;
ELSIF COMPARE_PW_HASH ( c_username , UPPER(SUBSTR(c_username,1,1))
|| LOWER(SUBSTR(c_username,2,LENGTH(c_username)))
) > 0 THEN
unsecure := TRUE;
chk_token := UPPER(SUBSTR(c_username,1,1))
|| LOWER(SUBSTR(c_username,2,LENGTH(c_username)));
ELSIF COMPARE_PW_HASH ( c_username , '123456' ) > 0 THEN
unsecure := TRUE;
chk_token := '123456';
END IF;

IF unsecure THEN
DBMS_OUTPUT.PUT_LINE( c_username || ' is UNSAFE PWD guessed IS '
|| SUBSTR(chk_token,1,3) || '******' );
ELSE
--DBMS_OUTPUT.PUT_LINE(c_username );
NULL;
END IF;
END LOOP;
CLOSE cu_user;
--
END;
Prüfung auf beliebte, damit unsichere Passwörter

 

Jetzt verfeinern wir das Script noch um einen kleinen Aspekt. Erstaunlicherweise gibt es tatsächlich „beliebte Passwörter“.
Hier Artikel zu dem Thema:

https://www.com-magazin.de/news/sicherheit/25-unsichersten-passwoerter-2015-1072804.html

http://www.maclife.de/news/diese-passwoerter-sollten-keinen-fall-verwenden-10086942.html

Passwort Hitliste weltweit 2015:
  1. 123456
  2. password
  3. 12345678
  4. qwerty
  5. …. (siehe Link)

Das heisst, Passwörter wie „123456“ sollten wir auch nicht verwenden.
Dieses Passwort verwenden laut dieser Untersuchungen signifikant viele Personen, daher wären es für den potentiellen Angreifer auch nur einige wenige Versuche die ersten 20% Wahrscheinlichkeit des benutzten Passwortes abzuchecken. Daher nehmen wir diese in eine erweitere Variante des Scriptes auf. Die eingebaute Liste der Passwörter ist natürlich nachzupflegen. In der Luxusvariante läge sie in einer Tabelle, in der mindestens jährlich die neuesten Passworthits eingepflegt werden, uns reicht hier für das Prinzip jedoch eine fest verdrahtete Liste.

Wir testen das:

ALTER USER SCOTT IDENTIFIED BY 123456;

 

Ausgabe des neuen Scriptes:

SCOTT is UNSAFE PWSTYLE IS 4 **
TEST is UNSAFE PWSTYLE IS 1 **

PL/SQL-Prozedur erfolgreich abgeschlossen.

 

Was hat sich geändert?  Nun, es wird nicht mehr das Passwort , auch nicht dessen Anfang, im Klartext wiederholt, auch der Admin muss das gar nicht wissen. Es reicht die Kategorisierung in eine Fehlerklasse.

SCOTT fällt jetzt in die Fehlerklasse 4. Ein zu implementierender Automatismus könnte ihn also anmailen, oder der Admin ansprechen und darauf hinweisen: „Lieber User SCOTT, du hast ein unsicheres Passwort. Dieses steht auf der Liste der weltweit am meisten genutzten Passwörter. Bitte denke dir aus Sicherheitsgründen, zu unsere aller Beruhigung, ein neues Passwort aus.„.

Kategorien der Fehlerklassen:

 

  1. Passwort wie username (in Lowercase )
  2. Passwort wie USERNAME  (in Uppercase )
  3. Passwort wie Username  (in Mixedcase (Capitals) )
  4. befindet sich in Hitliste der beliebtesten Passwörter

Hier noch zu guter Letzt das erweiterte Script:

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
SET serveroutput ON size 1000000

DECLARE
TYPE string_list IS VARRAY(40) OF VARCHAR(16);

pw_list STRING_LIST := string_list(
'123456','password','12345678','qwerty','12345','123456789','football',
'1234','1234567','baseball','welcome','1234567890','abc123','111111',
'1qaz2wsx','dragon','master','monkey','letmein','login','princess',
'qwertyuiop', 'solo', 'passw0rd', 'starwars', 'hallo', 'passwort',
'hallo123', 'schalke04', 'passwort1', 'qwertz', 'schatz', 'hallo1',
'fussball', NULL, NULL, NULL,NULL,NULL,NULL ); -- hier Erweiterungen eintragen

pwstyle PLS_INTEGER;
DUMMY VARCHAR2(80);
c_username VARCHAR2(256);
dbname v$database.name%TYPE;

lv_pwd_raw RAW(128);
lv_enc_raw RAW(2048);
LV_HASH_FOUND VARCHAR2(300);

CURSOR c_main(cp_user IN VARCHAR2)
IS
SELECT SUBSTR(spare4,3,40) hash,
SUBSTR(spare4,43,20) salt,
spare4
FROM sys.USER$
WHERE name=cp_user;
lv_user c_main%ROWTYPE;

CURSOR cu_user
IS
SELECT username
FROM dba_users
WHERE ACCOUNT_STATUS LIKE 'OPEN%';

FUNCTION COMPARE_PW_HASH(luser IN VARCHAR2, lpw IN VARCHAR2)
RETURN NUMBER IS

BEGIN
OPEN c_main(UPPER(luser));
FETCH c_main INTO lv_user;
CLOSE C_MAIN;
lv_pwd_raw := UTL_RAW.cast_to_raw(lpw)||HEXTORAW(lv_user.salt);
lv_enc_raw := sys.dbms_crypto.hash(lv_pwd_raw, 3);
lv_hash_found:=UTL_RAW.cast_to_varchar2(lv_enc_raw);

IF LV_ENC_RAW = LV_USER.hash THEN
-- DBMS_OUTPUT.PUT_LINE('PWD found for User ' || luser );
RETURN 1;
ELSE
RETURN 0;
END IF;
END;

BEGIN
DBMS_OUTPUT.ENABLE(10000000);

SELECT NAME INTO dbname FROM v$database;

OPEN cu_user;
LOOP
FETCH cu_user INTO c_username;
EXIT WHEN cu_user%NOTFOUND;

pwstyle := 0;

IF COMPARE_PW_HASH ( c_username , c_username ) > 0 THEN
pwstyle := 1; -- PW = username
ELSIF COMPARE_PW_HASH ( c_username , UPPER(c_username) ) > 0 THEN
pwstyle := 2; -- PW = UPPER(USERNAME)
ELSIF COMPARE_PW_HASH ( c_username , UPPER(SUBSTR(c_username,1,1))
|| LOWER(SUBSTR(c_username,2,LENGTH(c_username)))
) > 0 THEN
pwstyle := 3; -- PW = Username
ELSE
FOR i IN 1..36 LOOP
IF COMPARE_PW_HASH ( c_username , pw_list(i) ) > 0 THEN
pwstyle := i+3; -- PW ist PW(i) aus Liste der meistgenutzten
EXIT;
END IF;
END LOOP;
END IF;

IF pwstyle > 0 THEN
DBMS_OUTPUT.PUT_LINE( c_username || ' is UNSAFE PWSTYLE IS ' || PWSTYLE || ' **' );
END IF;
END LOOP;
CLOSE cu_user;
--
END;
/
Wissen zum Thema:

 

https://www.experts-exchange.com/articles/855/How-Oracle-Stores-Passwords.html

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.

Googlemail – rejected (Mailserver kann nichts an Google Adressen schicken)

Problem: Google lehnt Mail von neuem DEBIAN Server ab (sendmail)

Nachdem der neue Mailserver mit sendmail auf debian 9 Stretch abgesetzt war, kam diese seltsame Fehlermeldung zurück, wenn man eine Mail an eine google Adresse geschickt hatte:

Return-Path: <MAILER-DAEMON@mail.mydomain.com>
X-Spam-Checker-Version: SpamAssassin 3.4.1 (2015-04-28) on
mail.mydomain.com
X-Spam-Level:
X-Spam-Status: No, score=-1.9 required=4.5 tests=BAYES_00,NO_RELAYS,
T_TVD_MIME_NO_HEADERS,URIBL_BLOCKED autolearn=ham autolearn_force=no
version=3.4.1
Received: from localhost (localhost)
by mail.mydomain.com (8.15.2/8.15.2/Debian-8) id v9N9l9ff017607;
Mon, 23 Oct 2017 11:47:09 +0200
Date: Mon, 23 Oct 2017 11:47:09 +0200
From: Mail Delivery Subsystem <MAILER-DAEMON@mail.mydomain.com>
Message-Id: <201710230947.v9N9l9ff017607@mail.mydomain.com>
To: <sender@mymail.de>
MIME-Version: 1.0
Content-Type: multipart/report; report-type=delivery-status;
boundary=“v9N9l9ff017607.1508752029/mail.mydomain.com“
Subject: Returned mail: see transcript for details
Auto-Submitted: auto-generated (failure)

This is a MIME-encapsulated message

–v9N9l9ff017607.1508752029/mail.mydomain.com

The original message was received at Mon, 23 Oct 2017 11:47:09 +0200
from ip-xx-xxx-xx-xxx.hsi16.unitymediagroup.de [95.223.21.104]

—– The following addresses had permanent fatal errors —–
<testuser@googlemail.com>
(reason: 550-5.7.1 [2a01:4f8:a0:6386::2] Our system has detected that this message does)

—– Transcript of session follows —–
… while talking to gmail-smtp-in.l.google.com.:
>>> DATA
<<< 550-5.7.1 [2a01:4f8:a0:6386::2] Our system has detected that this message does
<<< 550-5.7.1 not meet IPv6 sending guidelines regarding PTR records and
<<< 550-5.7.1 authentication. Please review
<<< 550-5.7.1 https://support.google.com/mail/?p=IPv6AuthError for more information
<<< 550 5.7.1 . z202si3574495wmd.61 – gsmtp
554 5.0.0 Service unavailable

Einen hilfreichen Hinweis finden wir im Text zum Link am Ende der obigen Meldung  hinter der URL (Originaltext siehe weiter unten).

Der Text ist recht allgemein und tangiert mehrere Bereiche. Obwohl man zunächst den Eindruck gewinnen könnte,  liegt es jedoch definitiv nicht am SPF-Datensatz oder der DMARK-Richtlinie, der alte Server hatte das auch nicht.
Jedoch hat der neue Server auch eine aktive  IPv6 Adresse. Und diese soll laut Text (s.u) im Reverse-Lookup konfiguriert sein. Nun, der Reverselookup der IP ist auf die IPv4 Adresse vorkonfiguriert.
Im Sendmail M4 File kann man versuchen, das Versenden über IPv6 zu disablen:

DAEMON_OPTIONS(`Name=IPv4, Family=inet, Port=smtp‘)dnl
dnl  DAEMON_OPTIONS(`Name=IPv6, Family=inet6, Port=smtp‘)dnl

DAEMON_OPTIONS(`Name=IPv4, Family=inet, Addr=192.168.0.2′)
dnl DAEMON_OPTIONS(`Name=IPv6, Family=inet6, Addr=<…your IPv6 IP...>‘)

Das hilt jedoch nicht.

Lösung war eine zusätzliche Konfigurationszeile im M4:

Wenn die IPv4 Adresse W.X.Y.Z lautet, füge diese Zeile hinzu:

CLIENT_OPTIONS(`Family=inet6,Addr=:::ffff:W.X.Y.Z‘)dnl

Danach wie immer aus dem M4 File (/etc/mail/sendmail.mc) das cf File erzeugen (sendmail.cf), sendmail neu starten ->

Danach akzeptierte auch Google die Mails!


Anhang: Google-link in der Fehlermeldung mit Text

https://support.google.com/mail/?p=IPv6AuthError

Authentifizierung und Identifikation

Warum ist es wichtig, Nachrichten zu authentifizieren?

Die Authentifizierung stellt sicher, dass Ihre Nachrichten richtig klassifiziert werden. E-Mails ohne Authentifizierung werden meist abgelehnt oder im Spamordner abgelegt, da es sich dabei mit hoher Wahrscheinlichkeit um gefälschte Phishing-Nachrichten handelt.

Nicht authentifizierte E-Mails mit Anhang werden aus Sicherheitsgründen in der Regel sofort abgelehnt.

Um zu gewährleisten, dass Gmail Sie identifizieren kann, sollten Sie Folgendes beachten:

  • Verwenden Sie zum Senden von Massen-E-Mails eine gleichbleibende IP-Adresse.
  • Speichern Sie gültige Reverse-DNS-Daten für die IP-Adressen, von denen Sie E-Mails senden und die auf Ihre Domain verweisen.
  • Verwenden Sie in jeder gesendeten Massen-E-Mail dieselbe „Von:“-Adresse in der Kopfzeile.

Außerdem empfehlen wir Ihnen Folgendes:

  • Verschlüsseln Sie Nachrichten mit einer DKIM-Signatur. Wir authentifizieren nur Signaturen, die mit mindestens 1.024 Bit verschlüsselt wurden.
  • Veröffentlichen Sie einen SPF-Datensatz.
  • Veröffentlichen Sie eine DMARC-Richtlinie.

Weitere Informationen über die Authentifizierung von E-Mails

Zusätzliche Richtlinien für IPv6

  • Die sendende IP-Adresse muss einen PTR-Eintrag aufweisen, d. h. eine Reverse-DNS der sendenden IP, der mit der IP-Adresse übereinstimmen sollte, die über die Forward-DNS-Abfrage des im PTR-Eintrag genannten Hostnamens ermittelt wird. Andernfalls werden die E-Mails als Spam eingestuft oder möglicherweise sogar zurückgewiesen.
  • Die Domain des Absenders sollte den Anforderungen einer SPF- oder DKIM-Prüfung genügen. Ansonsten kann es vorkommen, dass E-Mails als Spam eingestuft werden.

 

 

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

Fehlermeldung: sendmail unknown configuration line in sendmail.cf

Nach einer Konfigurationsänderung für sendmail  ( Datei sendmail.mc ) startete der Sendmail nicht mehr an.

Die Meldung lautete:

sendmail[30029]: NOQUEUE: SYSERR(root): /etc/mail/sendmail.cf: line 97: unknown configuration line „\n“

Die sendmail.cf sah eigentlich harmlos aus:

sendmail.cf - Fehlerhafte Zeile
sendmail.cf – Fehlerhafte Zeile

Wenn man jedoch den Cursor positionierte, fand man das Problem:

Es hatte sich ein Leerzeichen eingeschlichen.
Woher kommt das?

Ein Blick in die m4-Datei zeigte:

Dieses Blank wäre nie aufgefallen, hätte ich nicht auf der Fehlersuche etwas Ordnung reingebracht, die teilweise optionalen DNL  (define newline) Commands  noch nachgetragen.
Erst dann visualisiert sich das Problem:

Ein böser Effekt. Man sieht halt keine Leerzeichen am Zeilenende.
Und ich dachte, moderne  Software stolpert nicht mehr über so etwas.

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.