SET LINESIZE 2000
COL TIME FORMAT A20
COL NAME FORMAT A90
SELECT 'LAST APPLIED : ' LOGS, TO_CHAR(NEXT_TIME,'DD-MON-YYYY HH24:MI:SS') TIME, SEQUENCE#, INCARNATION#, NAME
FROM ( SELECT DISTINCT INC_B.INCARNATION#,
FIRST_VALUE(ARC.NEXT_TIME) OVER (ORDER BY ARC.SEQUENCE# DESC) NEXT_TIME,
FIRST_VALUE(ARC.SEQUENCE#) OVER (ORDER BY ARC.SEQUENCE# DESC) SEQUENCE#,
FIRST_VALUE(ARC.NAME ) OVER (ORDER BY ARC.SEQUENCE# DESC) NAME
FROM V$DATABASE_INCARNATION INC_B, V$ARCHIVED_LOG ARC
WHERE ARC.APPLIED = 'YES' AND
ARC.RESETLOGS_CHANGE# = INC_B.RESETLOGS_CHANGE# AND ARC.RESETLOGS_TIME = INC_B.RESETLOGS_TIME AND
INC_B.INCARNATION# = ( SELECT (CASE DBS.DATABASE_ROLE
WHEN 'SNAPSHOT STANDBY' THEN INC_A.PRIOR_INCARNATION#
ELSE INC_A.INCARNATION# END ) INCARNATION
FROM V$DATABASE DBS, V$DATABASE_INCARNATION INC_A
WHERE INC_A.STATUS ='CURRENT' ) )
UNION
SELECT 'LAST RECEIVED : ' LOGS, TO_CHAR(NEXT_TIME,'DD-MON-YYYY HH24:MI:SS') TIME, SEQUENCE#, INCARNATION#, NAME
FROM ( SELECT DISTINCT INC_B.INCARNATION#,
FIRST_VALUE(ARC.NEXT_TIME) OVER (ORDER BY ARC.SEQUENCE# DESC) NEXT_TIME,
FIRST_VALUE(ARC.SEQUENCE#) OVER (ORDER BY ARC.SEQUENCE# DESC) SEQUENCE#,
FIRST_VALUE(ARC.NAME ) OVER (ORDER BY ARC.SEQUENCE# DESC) NAME
FROM V$DATABASE_INCARNATION INC_B, V$ARCHIVED_LOG ARC
WHERE ARC.RESETLOGS_CHANGE# = INC_B.RESETLOGS_CHANGE# AND ARC.RESETLOGS_TIME = INC_B.RESETLOGS_TIME AND
INC_B.INCARNATION# = ( SELECT (CASE DBS.DATABASE_ROLE
WHEN 'SNAPSHOT STANDBY' THEN INC_A.PRIOR_INCARNATION#
ELSE INC_A.INCARNATION# END ) INCARNATION
FROM V$DATABASE DBS, V$DATABASE_INCARNATION INC_A
WHERE INC_A.STATUS ='CURRENT' ) ) ;
Oracle est un problème pour vous? Vous trouvez qu'Oracle est plus compliqué que prévu ? Venez faire un tour ici, peut être vous allez trouver la solution, et si non on peut la trouver pour vous.
Translate
mardi 13 décembre 2016
vendredi 13 mai 2016
ORA-15036: disk XXX is truncated
Chez un client et lors la mise à niveau du grid 11.2.0.3 vers 12.1.0.2 on a eu ce message d'erreur et on a "perdu" un de nos Diskgroups:
SQL> alter diskgroup ARCHMABD MOUNT FORCE ;
alter diskgroup ARCHMABD MOUNT FORCE
*
ERROR at line 1:
ORA-15032: not all alterations performed
ORA-15036: disk '/dev/rdsk/c0d35s0' is truncated
############################
### INF AVANT UPGRADE : ###
############################
ASMCMD> lsdsk -k
Total_MB Free_MB OS_MB Name Failgroup Failgroup_Type Library Label UDID Product Redund Path
1023952 120983 1023952 ARCHMABD_0000 ARCHMABD_0000 REGULAR System UNKNOWN /dev/rdsk/c0d28s0
1048576 123953 1048576 ARCHMABD_0001 ARCHMABD_0001 REGULAR System UNKNOWN /dev/rdsk/c0d35s0
1023952 121011 1023952 ARCHMABD_0002 ARCHMABD_0002 REGULAR System UNKNOWN /dev/rdsk/c0d61s0
1023952 121117 1023952 ARCHMABD_0003 ARCHMABD_0003 REGULAR System UNKNOWN /dev/rdsk/c0d62s0
Note :
La taille des disques est déjà différente pour "/dev/rdsk/c0d35s0"
Comme le disque n'est pas monté il ne va pas apparaître :
ASMCMD> lsdsk -k -G ARCHMABD
Total_MB Free_MB OS_MB Name Failgroup Failgroup_Type Library Label UDID Product Redund Path
Avec "sqlplus / as sysasm" :
SET LINESIZE 2000
SELECT GROUP_NUMBER, NAME, SECTOR_SIZE, BLOCK_SIZE, STATE FROM V$ASM_DISKGROUP WHERE NAME LIKE 'ARCHMABD' ;
GROUP_NUMBER NAME SECTOR_SIZE BLOCK_SIZE STATE
------------ ------------------------------ ----------- ---------- -----------
0 ARCHMABD 0 0 DISMOUNTED
Correction :
$ kfed read /dev/rdsk/c0d35s0 | egrep "name|size"
kfdhdb.dskname: ARCHMABD_0001 ; 0x028: length=15
kfdhdb.grpname: ARCHMABD ; 0x048: length=10
kfdhdb.fgname: ARCHMABD_0001 ; 0x068: length=15
kfdhdb.capname: ; 0x088: length=0
kfdhdb.secsize: 512 ; 0x0b8: 0x0200
kfdhdb.blksize: 4096 ; 0x0ba: 0x1000
kfdhdb.ausize: 1048576 ; 0x0bc: 0x00100000
kfdhdb.dsksize: 1048576 ; 0x0c4: 0x00100000 ...(A)
Créer un fichier avec la métadonnée du disque :
$ kfed read /dev/rdsk/c0d35s0 > /tmp/header_d35s0.kfed
$ less /tmp/header_d35s0.kfed | grep "dsksize"
kfdhdb.dsksize: 1048576 ; 0x0c4: 0x00100000
Comparer avec la taille de l'OS ( Décimal et hexadécimal ) , servez-vous de la calculatrice en mode programmeur si vous voulez.
$ /usr/sbin/devinfo -p /dev/rdsk/c0d35s0
/dev/rdsk/c0d35s0 76 3b0 2048 2147299328 0 4
2147299328 * 512 / 1024 / 1024 = 1048486...(B)
Dans ce cas 512 c'est le blocksize de l'OS
S'il y une différence entre (A) et (B) ...
Modifier le fichier header_d35s0.kfed et insérer la bonne taille du disque selon l'OS, sauvegardez les modifications :
...
kfdhdb.dsksize: 1048486 ; 0x0c4: 0x000FFFA6
...
Charger la métadonnée dans le disque :
$ kfed merge /dev/rdsk/c0d35s0 text=/tmp/header_d35s0.kfed_ok
Essayez de monter le diskgroup :
SQL> ALTER DISKGROUP ARCHMABD MOUNT ;
Diskgroup altered.
On peut maintenant regarder le contenu :
ASMCMD> cd ARCHMABD/
ASMCMD> ls
2015_08_10/
2015_08_11/
2015_08_12/
2015_08_13/
samedi 7 mai 2016
Kerberos - Oracle (Serveur) 11g
Pour être capable d'utiliser Kerberos avec une base de données Oracle :
La configuration a été faite sur un serveur Linuz mais sur Solaris c'est la même chose.
Identifier le nom du serveur de base de
données :
oracle@donsuxx:/home/oracle>
cat /etc/hosts
127.0.0.1 localhost
10.103.yy.xxx donsuxx.domain.intra
donsuxx
Créer les comptes dans l’AD selon l’exemple
ci-dessous
Compte de type « User », ce compte représente le nom du serveur :
Name : donsuxx
Full name : donsuxx.domain.intra
User logon : donsuxx
Password : Password!1
Compte de type « User », ce compte sert à renouveler
les jetons :
Name : SVRENOUV
Full name : SVRENOUV
User logon : SVRENOUV
Password : Password!2
Option : User cannot change password et
Password never expires
Compte de type « User », ce compte est l’owner
de la bd :
Name : ORACLE
Full name : ORACLE
User logon : ORACLE
Password : Password!3
Option : User cannot change password et
Password never expires
· Créer le compte «SVRENOUV » sur le
serveur de base de données avec le même mot de passe de l’AD.
DROP USER "SVRENOUV@DOMAIN.INTRA" CASCADE;
CREATE USER "SVRENOUV@DOMAIN.INTRA"
IDENTIFIED EXTERNALLY
DEFAULT TABLESPACE USERS
TEMPORARY TABLESPACE TEMP
PROFILE DEFAULT
ACCOUNT UNLOCK;
GRANT CREATE SESSION TO
"SVRENOUV@DOMAIN.INTRA";
· Le compte « ORACLE » qui existe déjà
sur le serveur doit avoir aussi le même mot de passe que dans l’AD
DROP USER "ORACLE@DOMAIN.INTRA" CASCADE;
CREATE USER "ORACLE@DOMAIN.INTRA"
IDENTIFIED EXTERNALLY
DEFAULT TABLESPACE USERS
TEMPORARY TABLESPACE TEMP
PROFILE DEFAULT
ACCOUNT UNLOCK;
GRANT CREATE SESSION TO
"ORACLE@DOMAIN.INTRA";
·
Dans l’AD, vérifier si de doublons existent sur
le compte qu’on vient de créer (celle qui représente la machine). En théorie il ne doit pas en avoir de
doublons reliés à notre compte.
Commande : setspn –X
·
Dans l’AD, créer le keytab
ktpass -princ
oraevta/donsuxx.domain.intra@DOMAIN.INTRA -crypto all -pass Password!1
-mapuser donsuxx@DOMAIN.INTRA -ptype KRB5_NT_PRINCIPAL -out C:\key\keytab
Dans la commande il faut cibler :
o
Le nom du service « oraevta » est
juste un nom à utiliser qui doit coïncider avec le nom spécifié dans le
sqlnet.ora de la bd.
Il
pourrait être par exemple : ora, ora11, etc.
o
Le paramètre « -pass » correspond au
même mot de passe du compte qui représente la machine qu’on vient de créer.
o
Le paramètre « -mapuser » doit faire
référence au même compte.
·
Envoyer le fichier « keytab » qu’on
vient de créer vers le serveur de bd et le placer à l’endroit indiqué dans le
« sqlnet.ora ».
·
Vérifier le nom du fichier tampon pour les
jetons
·
Valider les privilèges sur les fichiers
-rw-rw---- 1 oracle oinstall 437 2016-04-22 09:37
keytab
-rwxrwx--- 1 oracle oinstall 692 2016-04-21 16:33
krb5.conf
·
Valider que les entrés dans le fichier services
soient comme ça :
oracle@donsuxx:> cat /etc/services | grep
kerberos
kerberos
88/tcp kerberos5 krb5 # Kerberos
kerberos
88/udp kerberos5 krb5 # Kerberos
kerberos-adm 749/tcp
# kerberos administration
kerberos-adm 749/udp
# kerberos administration
kerberos-iv 750/udp
kerberos4 kerberos-sec kdc #
kerberos version iv
kerberos-iv 750/tcp
kerberos4 kerberos-sec kdc
kerberos_master
751/udp # Kerberos authentication
kerberos_master
751/tcp # Kerberos authentication
·
Sur le serveur de BD, détruire les jetons
existants, le nom du fichier .RC sera en fonction du nom du service.
okdstry -c /tmp/tmpevta
rm /tmp/oraevta.RC
·
Sur le serveur de BD, Initialiser les jetons,
fournir le mot de passe demandé.
okinit -c /tmp/tmpevta -e 23 SRV_RENOUV
ou selon le chiffrement
okinit -c /tmp/tmpevta -e
1 -e 3 oracle
Exemple :
oracle@donsuxx:/home/oracle>
okinit -c /tmp/tmpevta -e 23 SVRENOUV
Kerberos Utilities
for Linux: Version 11.2.0.4.0 - Production on 22-APR-2016 10:02:30
Copyright (c) 1996,
2013 Oracle. All rights reserved.
·
Sur le serveur de BD, lister les jetons
oklist
oracle@donsuxx:/home/oracle> oklist
Kerberos Utilities for Linux: Version 11.2.0.4.0 - Production on 22-APR-2016 11:28:16
Copyright (c) 1996, 2013 Oracle. All rights reserved.
Ticket cache: /tmp/tmpevta
Default principal: SVRENOUV@DOMAIN.INTRA
Valid Starting Expires Principal
22-Apr-2016 10:04:08 22-Apr-2016 18:02:30 krbtgt/DOMAIN.INTRA@DOMAIN.INTRA
·
Sur le serveur de BD, tester la connexion
kerberos. Il faut noter que la connexion est faite avec le même utilisateur qui
a fait le renouvellement
sqlplus /@MABD
oracle@donsuxx:~>
sqlplus /@MABD
SQL*Plus: Release 11.2.0.4.0 Production on Fri Apr 22
11:29:03 2016
Copyright (c) 1982, 2013, Oracle. All rights reserved.
Connected to:
Oracle Database 11g Enterprise Edition Release
11.2.0.4.0 - 64bit Production
With the Partitioning, OLAP, Data Mining and Real
Application Testing options
SQL> show user
USER is "SVRENOUV@DOMAIN.INTRA"
Note: Si vous voulez tester la connexion sur une base de données StandBy, elle doit être en Snapshot et non pas en Physical pour que la connexion se fasse.
Le Client Windows 2008 R2
Exemple de "sqlnet.ora"
# sqlnet.ora Network Configuration File:
C:\oracle\product\10.2.0\client_1\NETWORK\ADMIN
# Generated by Oracle configuration tools.
NAMES.DEFAULT_DOMAIN = votredomain.ca
################################################################
# Methodes Authentifications utilises sont TCPS and
Kerberos5
################################################################
NAMES.DIRECTORY_PATH=(TNSNAMES)
SQLNET.AUTHENTICATION_SERVICES=(BEQ,KERBEROS5)
################################################################
# Ajoute pour la
configuration Kerberos 5 -
################################################################
SQLNET.KERBEROS5_CONF=C:\Logiciels\oracle\ora1120\kerberos\krb5.conf
SQLNET.KERBEROS5_CONF_MIT=true
SQLNET.KERBEROS5_CC_NAME = OSMSFT://
SQLNET.AUTHENTICATION_KERBEROS5_SERVICE=ora
SQLNET.EXPIRE_TIME=0
Le Client Windows 2012 R2
Exemple de "sqlnet.ora"
# sqlnet.ora Network Configuration File: C:\oracle\product\10.2.0\client_1\NETWORK\ADMIN
# Generated by Oracle configuration tools.
NAMES.DEFAULT_DOMAIN = votredomain.ca
################################################################
# Methodes Authentifications utilises sont TCPS and Kerberos5
################################################################
NAMES.DIRECTORY_PATH=(TNSNAMES)
SQLNET.AUTHENTICATION_SERVICES=(NTS)
################################################################
# Ajoute pour la configuration Kerberos 5 -
################################################################
SQLNET.KERBEROS5_CONF=C:\Logiciels\oracle\ora1120\kerberos\krb5.conf
SQLNET.KERBEROS5_CONF_MIT=true
SQLNET.KERBEROS5_CC_NAME = OSMSFT://
SQLNET.AUTHENTICATION_KERBEROS5_SERVICE=ora
SQLNET.EXPIRE_TIME=0
samedi 2 avril 2016
Tracer une session bd avec truss - Option II -
Des fois un trace de base de données ne suffit pas pour retrouver un problème. Dans ce cas, je vais activer aussi un trace au niveau du système d'exploitation avec la commande truss.
##############################################
### Option II ##############################
##############################################
Système d'exploitation : Solaris 10
Version de base de données : 11.2.0.4
Fichier shell : bd_truss.sh
#!/bin/sh
/usr/bin/nohup /usr/bin/truss -fldD -p $2 > /home/ora11204/$1 2>&1&
Cela va générer un fichier de trace qui sera placé dans le répertoire "/home/ora11204/" , Le nom du fichier est passé comme 1er paramètre , le 2ème paramètre correspond au "ID process".
root@serveur:/root# ls -l /usr/bin/truss
-r-xr-xr-x 66 root bin 10052 Jul 6 2011 /usr/bin/truss
root@serveur:/root# chmod u+s /usr/bin/truss
root@serveur:/root# ls -l /usr/bin/truss
-r-sr-xr-x 66 root bin 10052 Jul 6 2011 /usr/bin/truss
sqlplus / as sysdba
DROP USER EVTA CASCADE ;
CREATE USER EVTA IDENTIFIED BY EVTA ;
GRANT CONNECT, RESOURCE TO EVTA ;
EXEC DBMS_SCHEDULER.CREATE_CREDENTIAL('CRED_EVTA','ora11204','yourpasswordunix') ;
CREATE OR REPLACE TRIGGER SYS.TRIG_TRACE_JOB
AFTER LOGON ON DATABASE
DISABLE
DECLARE
id1 VARCHAR2(30);
id2 NUMBER;
ls_username VARCHAR2(30);
ls_osuser VARCHAR2(30);
ls_program VARCHAR2(64);
ls_sid INTEGER;
ls_serial INTEGER;
ls_schemaname VARCHAR2(100);
ls_machine VARCHAR2(100);
ls_spid VARCHAR2(24);
v2 NUMBER;
result NUMBER;
CURSOR USAGERINFO IS
SELECT upper(A.username), A.osuser, upper(A.program), A.sid, A.serial#, A.schemaname, A.machine, B.SPID
FROM v$session A, v$process b
WHERE audsid = userenv('SESSIONID') and a.paddr=b.addr;
BEGIN
-- Obtenir les informations de l'usager en cours
OPEN USAGERINFO;
FETCH USAGERINFO
INTO ls_username, ls_osuser, ls_program, ls_sid, ls_serial, ls_schemaname, ls_machine, ls_spid;
CLOSE USAGERINFO;
if user in ('EVTA') and program like 'SQLPLUS%' then
select user, sys_context('USERENV','SID') into id1, id2 from dual;
execute immediate 'alter session set statistics_level=ALL';
execute immediate 'alter session set tracefile_identifier='''||replace(id1,'$','')||'_'||id2||'''';
execute immediate 'alter session set max_dump_file_size=40960000';
execute immediate 'alter session set EVENTS ''10046 trace name context forever, level 12''';
execute immediate 'BEGIN DBMS_SCHEDULER.CREATE_JOB(JOB_NAME=>'''||'JOB_EVTA'||id2||''''||',JOB_TYPE=>'||'''EXECUTABLE'''||',JOB_ACTION=>'||''''||'/home/ora11204/bd_truss.sh'||''''||',NUMBER_OF_ARGUMENTS=>2,ENABLED=>FALSE,AUTO_DROP=>TRUE,CREDENTIAL_NAME=>'||''''||'CRED_EVTA'||'''); END;' ;
execute immediate 'BEGIN DBMS_SCHEDULER.SET_JOB_ARGUMENT_VALUE('''||'JOB_EVTA'||id2||''''||',1,'||''''||'trace_'||ls_spid||''''||'); END;';
execute immediate 'BEGIN DBMS_SCHEDULER.SET_JOB_ARGUMENT_VALUE('''||'JOB_EVTA'||id2||''''||',2,'||''''||ls_spid||''''||'); END;';
execute immediate 'BEGIN DBMS_SCHEDULER.ENABLE('''||'JOB_EVTA'||id2||''''||') ; END;';
end if;
END;
/
ALTER TRIGGER SYS.TRIG_TRACE_JOB ENABLE ;
Cela va activer deux types de traces à chaque connexion du compte "EVTA", un trace de bases de données et un trace OS, ces deux fichiers pourront vous aider à détecter certains problèmes.
##############################################
### Option II ##############################
##############################################
Version de base de données : 11.2.0.4
- Créer le fichier shell :
Fichier shell : bd_truss.sh
#!/bin/sh
/usr/bin/nohup /usr/bin/truss -fldD -p $2 > /home/ora11204/$1 2>&1&
Cela va générer un fichier de trace qui sera placé dans le répertoire "/home/ora11204/" , Le nom du fichier est passé comme 1er paramètre , le 2ème paramètre correspond au "ID process".
- Demander à votre admin Unix de donner les privilèges SUID pour le truss, en cas l'owner de votre process à tracer ne soit pas le même.(Exemple : grid et home RDBMS installés avec des comptes séparés).
root@serveur:/root# ls -l /usr/bin/truss
-r-xr-xr-x 66 root bin 10052 Jul 6 2011 /usr/bin/truss
root@serveur:/root# chmod u+s /usr/bin/truss
root@serveur:/root# ls -l /usr/bin/truss
-r-sr-xr-x 66 root bin 10052 Jul 6 2011 /usr/bin/truss
- Créer un compte de test dans la base de données :
sqlplus / as sysdba
DROP USER EVTA CASCADE ;
CREATE USER EVTA IDENTIFIED BY EVTA ;
GRANT CONNECT, RESOURCE TO EVTA ;
- Créer la crédentiale -Puisque c'est 11gR2-
EXEC DBMS_SCHEDULER.CREATE_CREDENTIAL('CRED_EVTA','ora11204','yourpasswordunix') ;
- Utiliser le trigger pour créer une "job"
CREATE OR REPLACE TRIGGER SYS.TRIG_TRACE_JOB
AFTER LOGON ON DATABASE
DISABLE
DECLARE
id1 VARCHAR2(30);
id2 NUMBER;
ls_username VARCHAR2(30);
ls_osuser VARCHAR2(30);
ls_program VARCHAR2(64);
ls_sid INTEGER;
ls_serial INTEGER;
ls_schemaname VARCHAR2(100);
ls_machine VARCHAR2(100);
ls_spid VARCHAR2(24);
v2 NUMBER;
result NUMBER;
CURSOR USAGERINFO IS
SELECT upper(A.username), A.osuser, upper(A.program), A.sid, A.serial#, A.schemaname, A.machine, B.SPID
FROM v$session A, v$process b
WHERE audsid = userenv('SESSIONID') and a.paddr=b.addr;
BEGIN
-- Obtenir les informations de l'usager en cours
OPEN USAGERINFO;
FETCH USAGERINFO
INTO ls_username, ls_osuser, ls_program, ls_sid, ls_serial, ls_schemaname, ls_machine, ls_spid;
CLOSE USAGERINFO;
if user in ('EVTA') and program like 'SQLPLUS%' then
select user, sys_context('USERENV','SID') into id1, id2 from dual;
execute immediate 'alter session set statistics_level=ALL';
execute immediate 'alter session set tracefile_identifier='''||replace(id1,'$','')||'_'||id2||'''';
execute immediate 'alter session set max_dump_file_size=40960000';
execute immediate 'alter session set EVENTS ''10046 trace name context forever, level 12''';
execute immediate 'BEGIN DBMS_SCHEDULER.CREATE_JOB(JOB_NAME=>'''||'JOB_EVTA'||id2||''''||',JOB_TYPE=>'||'''EXECUTABLE'''||',JOB_ACTION=>'||''''||'/home/ora11204/bd_truss.sh'||''''||',NUMBER_OF_ARGUMENTS=>2,ENABLED=>FALSE,AUTO_DROP=>TRUE,CREDENTIAL_NAME=>'||''''||'CRED_EVTA'||'''); END;' ;
execute immediate 'BEGIN DBMS_SCHEDULER.SET_JOB_ARGUMENT_VALUE('''||'JOB_EVTA'||id2||''''||',1,'||''''||'trace_'||ls_spid||''''||'); END;';
execute immediate 'BEGIN DBMS_SCHEDULER.SET_JOB_ARGUMENT_VALUE('''||'JOB_EVTA'||id2||''''||',2,'||''''||ls_spid||''''||'); END;';
execute immediate 'BEGIN DBMS_SCHEDULER.ENABLE('''||'JOB_EVTA'||id2||''''||') ; END;';
end if;
END;
/
- Activer le trigger au moment dont vous aurez besoin
ALTER TRIGGER SYS.TRIG_TRACE_JOB ENABLE ;
Cela va activer deux types de traces à chaque connexion du compte "EVTA", un trace de bases de données et un trace OS, ces deux fichiers pourront vous aider à détecter certains problèmes.
vendredi 1 avril 2016
Tracer une session bd avec truss - Option I -
Des fois un trace de base de données ne suffit pas pour retrouver un problème. Dans ce cas, je vais activer aussi un trace au niveau du système d'exploitation avec la commande truss.
##############################################
### Option I ###############################
##############################################
Système d'exploitation : Solaris 10
Version de base de données : 11.2.0.4
Fichier shell : bd_truss.sh
#!/bin/sh
/usr/bin/nohup /usr/bin/truss -fldD -p $2 > /home/ora11204/$1 2>&1&
Cela va générer un fichier de trace qui sera placé dans le répertoire "/home/ora11204/" , Le nom du fichier est passé comme 1er paramètre , le 2ème paramètre correspond au "ID process".
root@serveur:/root# ls -l /usr/bin/truss
-r-xr-xr-x 66 root bin 10052 Jul 6 2011 /usr/bin/truss
root@serveur:/root# chmod u+s /usr/bin/truss
root@serveur:/root# ls -l /usr/bin/truss
-r-sr-xr-x 66 root bin 10052 Jul 6 2011 /usr/bin/truss
sqlplus / as sysdba
DROP USER EVTA CASCADE ;
CREATE USER EVTA IDENTIFIED BY EVTA ;
GRANT CONNECT, RESOURCE TO EVTA ;
execute dbms_java.grant_permission( 'EVTA', 'SYS:java.io.FilePermission', '/usr/bin/truss', 'execute' );
execute dbms_java.grant_permission( 'EVTA', 'SYS:java.io.FilePermission', '/usr/bin/sh', 'execute' );
execute dbms_java.grant_permission( 'EVTA', 'SYS:java.io.FilePermission', '/home/ora11204/bd_truss.sh', 'execute' );
execute dbms_java.grant_permission( 'EVTA', 'SYS:java.lang.RuntimePermission', 'writeFileDescriptor', '' );
execute dbms_java.grant_permission( 'EVTA', 'SYS:java.lang.RuntimePermission', 'readFileDescriptor', '' );
ALTER SESSION SET CURRENT_SCHEMA=EVTA ;
Note: Ces deux classes ont été obtenues du Site d'Oracle - Doc ID 109095.1
CREATE OR REPLACE AND COMPILE JAVA SOURCE NAMED "CaptureStream" AS
import java.util.*;
import java.io.*;
class CaptureStream implements Runnable {
private final InputStream is;
private final String type;
private final OutputStream redirect;
private boolean redirected = false;
CaptureStream(InputStream is, String type, OutputStream redirect)
{
this.is = is;
this.type = type + ">";
this.redirect = redirect;
}
CaptureStream(InputStream is, String type)
{
this(is, type, null);
}
CaptureStream(InputStream is)
{
this(is, " ", null);
}
public void run()
{
try {
PrintWriter pw = null;
if (redirect != null) {
pw = new PrintWriter(redirect);
redirected = true;
}
InputStreamReader isr = new InputStreamReader(is);
BufferedReader br = new BufferedReader(isr);
String line=null;
while ( (line = br.readLine()) != null) {
System.out.println(type + line);
if (redirected) {
pw.println(line);
}
}
if (redirected) {
pw.flush();
pw.close();
}
br.close();
isr.close();
} catch (IOException ioe) {
ioe.printStackTrace();
}
}
}
/
CREATE OR REPLACE AND COMPILE JAVA SOURCE NAMED "ExecOSCmd" AS
import java.util.*;
import java.io.*;
public class ExecOSCmd {
public static void main (String args[])
{
int rc = 0;
if (args.length < 1) {
System.out.println("USAGE: java ExecOSCmd \'cmd\' ");
System.exit(1);
}
try {
String cmd = args[0];
FileOutputStream fos = null;
if (args.length == 2 ) {
fos = new FileOutputStream(args[1]);
}
Runtime rt = Runtime.getRuntime();
Process p = rt.exec(cmd);
CaptureStream err = new CaptureStream(p.getErrorStream(), "ERR");
Thread e = new Thread(err);
/* NOTE we do not join the error thread. If there was no
Error it may never return. We would wait forever for it to
return thus janging this process */
e.start();
CaptureStream out = new CaptureStream(p.getInputStream(),
"OUT", fos);
Thread o = new Thread(out);
o.start();
try {
rc = p.waitFor();
/* Handle exceptions for waitFor() */
} catch (InterruptedException intexc) {
System.out.println("Interrupted Exception on waitFor: " +
intexc.getMessage());
}
if (fos !=null) {
o.join(); // need to wait for the output to finish.
fos.flush();
fos.close();
}
System.out.println("ExitValue: " + rc);
} catch (Throwable t) {
System.out.println("ExitValue: " + rc);
t.printStackTrace();
}
}
}
/
CREATE OR REPLACE PROCEDURE executecmd (cmd VARCHAR2)
AS LANGUAGE JAVA NAME 'ExecOSCmd.main(java.lang.String[])';
/
En tant que sys :
SET LINESIZE 2000
SELECT OBJECT_TYPE, OBJECT_NAME FROM DBA_OBJECTS WHERE OWNER = 'EVTA';
OBJECT_TYPE OBJECT_NAME
------------------- ---------------------------------------
JAVA CLASS CaptureStream
JAVA SOURCE CaptureStream
JAVA CLASS ExecOSCmd
JAVA SOURCE ExecOSCmd
PROCEDURE EXECUTECMD
SET LINESIZE 600
COL TYPE_NAME FORMAT A30
COL NAME FORMAT A30
COL ACTION FORMAT A30
SELECT * FROM DBA_JAVA_POLICY WHERE GRANTEE = 'EVTA';
KIND GRANTEE TYPE_SCHEMA TYPE_NAME NAME ACTION ENABLED SEQ
------ --------- ----------- ------------------------------ ------------------------------ ---------- -------- ---
GRANT EVTA SYS java.io.FilePermission /home/ora11204/bd_truss.sh execute ENABLED 193
GRANT EVTA SYS java.io.FilePermission /usr/bin/sh execute ENABLED 192
GRANT EVTA SYS java.io.FilePermission /usr/bin/truss execute ENABLED 191
GRANT EVTA SYS java.lang.RuntimePermission readFileDescriptor ENABLED 195
GRANT EVTA SYS java.lang.RuntimePermission writeFileDescriptor ENABLED 194
CREATE OR REPLACE TRIGGER SYS.TRIG_TRACE_JAVA
AFTER LOGON ON DATABASE
DISABLE
DECLARE
id1 VARCHAR2(30);
id2 NUMBER;
ls_username VARCHAR2(30);
ls_osuser VARCHAR2(30);
ls_program VARCHAR2(64);
ls_sid INTEGER;
ls_serial INTEGER;
ls_schemaname VARCHAR2(100);
ls_machine VARCHAR2(100);
ls_spid VARCHAR2(24);
v2 NUMBER;
result NUMBER;
CURSOR USAGERINFO IS
SELECT upper(A.username), A.osuser, upper(A.program), A.sid, A.serial#, A.schemaname, A.machine, B.SPID
FROM v$session A, v$process b
WHERE audsid = userenv('SESSIONID') and a.paddr=b.addr;
BEGIN
-- Obtenir les informations de l'usager en cours
OPEN USAGERINFO;
FETCH USAGERINFO
INTO ls_username, ls_osuser, ls_program, ls_sid, ls_serial, ls_schemaname, ls_machine, ls_spid;
CLOSE USAGERINFO;
if user in ('EVTA') then
select user, sys_context('USERENV','SID') into id1, id2 from dual;
execute immediate 'alter session set statistics_level=ALL';
execute immediate 'alter session set tracefile_identifier='''||replace(id1,'$','')||'_'||id2||'''';
execute immediate 'alter session set max_dump_file_size=40960000';
execute immediate 'alter session set EVENTS ''10046 trace name context forever, level 12''';
execute immediate 'BEGIN EVTA.executecmd('''||'/home/ora11204/bd_truss.sh trace_'||replace(id1,'$','')||'_'||id2||'_'||ls_spid||'.txt '||ls_spid||'''); END;' ;
end if;
END;
/
ALTER TRIGGER SYS.TRIG_TRACE_xxx ENABLE ;
Cela va activer deux types de traces à chaque connexion du compte "EVTA", un trace de bases de données et un trace OS , ces deux fichiers pourront vous aider à détecter certains problèmes.
##############################################
### Option I ###############################
##############################################
Version de base de données : 11.2.0.4
- Créer le fichier shell :
Fichier shell : bd_truss.sh
#!/bin/sh
/usr/bin/nohup /usr/bin/truss -fldD -p $2 > /home/ora11204/$1 2>&1&
Cela va générer un fichier de trace qui sera placé dans le répertoire "/home/ora11204/" , Le nom du fichier est passé comme 1er paramètre , le 2ème paramètre correspond au "ID process".
- Demander à votre admin Unix de donner les privilèges SUID pour le truss, en cas l'owner de votre process à tracer ne soit pas le même.(Exemple : grid et home RDBMS installés avec des comptes séparés).
root@serveur:/root# ls -l /usr/bin/truss
-r-xr-xr-x 66 root bin 10052 Jul 6 2011 /usr/bin/truss
root@serveur:/root# chmod u+s /usr/bin/truss
root@serveur:/root# ls -l /usr/bin/truss
-r-sr-xr-x 66 root bin 10052 Jul 6 2011 /usr/bin/truss
- Créer un compte de test dans la base de données :
sqlplus / as sysdba
DROP USER EVTA CASCADE ;
CREATE USER EVTA IDENTIFIED BY EVTA ;
GRANT CONNECT, RESOURCE TO EVTA ;
- Octroyer les privilèges nécessaires
execute dbms_java.grant_permission( 'EVTA', 'SYS:java.io.FilePermission', '/usr/bin/truss', 'execute' );
execute dbms_java.grant_permission( 'EVTA', 'SYS:java.io.FilePermission', '/usr/bin/sh', 'execute' );
execute dbms_java.grant_permission( 'EVTA', 'SYS:java.io.FilePermission', '/home/ora11204/bd_truss.sh', 'execute' );
execute dbms_java.grant_permission( 'EVTA', 'SYS:java.lang.RuntimePermission', 'writeFileDescriptor', '' );
execute dbms_java.grant_permission( 'EVTA', 'SYS:java.lang.RuntimePermission', 'readFileDescriptor', '' );
ALTER SESSION SET CURRENT_SCHEMA=EVTA ;
Note: Ces deux classes ont été obtenues du Site d'Oracle - Doc ID 109095.1
- Créer les classes Java
CREATE OR REPLACE AND COMPILE JAVA SOURCE NAMED "CaptureStream" AS
import java.util.*;
import java.io.*;
class CaptureStream implements Runnable {
private final InputStream is;
private final String type;
private final OutputStream redirect;
private boolean redirected = false;
CaptureStream(InputStream is, String type, OutputStream redirect)
{
this.is = is;
this.type = type + ">";
this.redirect = redirect;
}
CaptureStream(InputStream is, String type)
{
this(is, type, null);
}
CaptureStream(InputStream is)
{
this(is, " ", null);
}
public void run()
{
try {
PrintWriter pw = null;
if (redirect != null) {
pw = new PrintWriter(redirect);
redirected = true;
}
InputStreamReader isr = new InputStreamReader(is);
BufferedReader br = new BufferedReader(isr);
String line=null;
while ( (line = br.readLine()) != null) {
System.out.println(type + line);
if (redirected) {
pw.println(line);
}
}
if (redirected) {
pw.flush();
pw.close();
}
br.close();
isr.close();
} catch (IOException ioe) {
ioe.printStackTrace();
}
}
}
/
CREATE OR REPLACE AND COMPILE JAVA SOURCE NAMED "ExecOSCmd" AS
import java.util.*;
import java.io.*;
public class ExecOSCmd {
public static void main (String args[])
{
int rc = 0;
if (args.length < 1) {
System.out.println("USAGE: java ExecOSCmd \'cmd\' ");
System.exit(1);
}
try {
String cmd = args[0];
FileOutputStream fos = null;
if (args.length == 2 ) {
fos = new FileOutputStream(args[1]);
}
Runtime rt = Runtime.getRuntime();
Process p = rt.exec(cmd);
CaptureStream err = new CaptureStream(p.getErrorStream(), "ERR");
Thread e = new Thread(err);
/* NOTE we do not join the error thread. If there was no
Error it may never return. We would wait forever for it to
return thus janging this process */
e.start();
CaptureStream out = new CaptureStream(p.getInputStream(),
"OUT", fos);
Thread o = new Thread(out);
o.start();
try {
rc = p.waitFor();
/* Handle exceptions for waitFor() */
} catch (InterruptedException intexc) {
System.out.println("Interrupted Exception on waitFor: " +
intexc.getMessage());
}
if (fos !=null) {
o.join(); // need to wait for the output to finish.
fos.flush();
fos.close();
}
System.out.println("ExitValue: " + rc);
} catch (Throwable t) {
System.out.println("ExitValue: " + rc);
t.printStackTrace();
}
}
}
/
CREATE OR REPLACE PROCEDURE executecmd (cmd VARCHAR2)
AS LANGUAGE JAVA NAME 'ExecOSCmd.main(java.lang.String[])';
/
En tant que sys :
SET LINESIZE 2000
SELECT OBJECT_TYPE, OBJECT_NAME FROM DBA_OBJECTS WHERE OWNER = 'EVTA';
OBJECT_TYPE OBJECT_NAME
------------------- ---------------------------------------
JAVA CLASS CaptureStream
JAVA SOURCE CaptureStream
JAVA CLASS ExecOSCmd
JAVA SOURCE ExecOSCmd
PROCEDURE EXECUTECMD
SET LINESIZE 600
COL TYPE_NAME FORMAT A30
COL NAME FORMAT A30
COL ACTION FORMAT A30
SELECT * FROM DBA_JAVA_POLICY WHERE GRANTEE = 'EVTA';
KIND GRANTEE TYPE_SCHEMA TYPE_NAME NAME ACTION ENABLED SEQ
------ --------- ----------- ------------------------------ ------------------------------ ---------- -------- ---
GRANT EVTA SYS java.io.FilePermission /home/ora11204/bd_truss.sh execute ENABLED 193
GRANT EVTA SYS java.io.FilePermission /usr/bin/sh execute ENABLED 192
GRANT EVTA SYS java.io.FilePermission /usr/bin/truss execute ENABLED 191
GRANT EVTA SYS java.lang.RuntimePermission readFileDescriptor ENABLED 195
GRANT EVTA SYS java.lang.RuntimePermission writeFileDescriptor ENABLED 194
- Créer un trigger after logon
CREATE OR REPLACE TRIGGER SYS.TRIG_TRACE_JAVA
AFTER LOGON ON DATABASE
DISABLE
DECLARE
id1 VARCHAR2(30);
id2 NUMBER;
ls_username VARCHAR2(30);
ls_osuser VARCHAR2(30);
ls_program VARCHAR2(64);
ls_sid INTEGER;
ls_serial INTEGER;
ls_schemaname VARCHAR2(100);
ls_machine VARCHAR2(100);
ls_spid VARCHAR2(24);
v2 NUMBER;
result NUMBER;
CURSOR USAGERINFO IS
SELECT upper(A.username), A.osuser, upper(A.program), A.sid, A.serial#, A.schemaname, A.machine, B.SPID
FROM v$session A, v$process b
WHERE audsid = userenv('SESSIONID') and a.paddr=b.addr;
BEGIN
-- Obtenir les informations de l'usager en cours
OPEN USAGERINFO;
FETCH USAGERINFO
INTO ls_username, ls_osuser, ls_program, ls_sid, ls_serial, ls_schemaname, ls_machine, ls_spid;
CLOSE USAGERINFO;
if user in ('EVTA') then
select user, sys_context('USERENV','SID') into id1, id2 from dual;
execute immediate 'alter session set statistics_level=ALL';
execute immediate 'alter session set tracefile_identifier='''||replace(id1,'$','')||'_'||id2||'''';
execute immediate 'alter session set max_dump_file_size=40960000';
execute immediate 'alter session set EVENTS ''10046 trace name context forever, level 12''';
execute immediate 'BEGIN EVTA.executecmd('''||'/home/ora11204/bd_truss.sh trace_'||replace(id1,'$','')||'_'||id2||'_'||ls_spid||'.txt '||ls_spid||'''); END;' ;
end if;
END;
/
- Activer le trigger au moment dont vous aurez besoin
ALTER TRIGGER SYS.TRIG_TRACE_xxx ENABLE ;
Cela va activer deux types de traces à chaque connexion du compte "EVTA", un trace de bases de données et un trace OS , ces deux fichiers pourront vous aider à détecter certains problèmes.
Inscription à :
Articles (Atom)