tnsping pour instant client
tnsping manque à Oracle Instant Client.
Un hack de Laurent Schneider pour le remplacer :
whence tnsping >/dev/null 2>&1 || tnsping() { :| sqlplus -L -s x/x@$1 | grep ORA- | (grep -v ORA-01017 || echo OK) }
tnsping manque à Oracle Instant Client.
Un hack de Laurent Schneider pour le remplacer :
whence tnsping >/dev/null 2>&1 || tnsping() { :| sqlplus -L -s x/x@$1 | grep ORA- | (grep -v ORA-01017 || echo OK) }
Dans le précédent article, on a pu voir que la clause MODEL d’Oracle permettait de faire des calculs un peu comme on les ferait avec un tableur en utilisant le résultat de certaines cellules pour en calculer d’autres.
La modélisation permet aussi de créer des lignes comlpètes de toute pièce en s’appuiant sur les précédentes. Ces types de modélisations sont généralement utilisés pour se projeter dans l’avenir et donc intéressant pour les modèles décisionnels
Je vais construire ici un modèle fictif, pour montrer la méthode, qui va donc se baser sur un historique et extrapoler un avenir.
Le modèle à utiliser sera celui d’un ingénieur commercial qui voudrait prédire l’évolution de ses tarifs. Rien que du très classique en fin de compte. Les règles de calcul vont être lesquelles ?
Je vais donc
je prendrai comme hypothèse, qu’au pire des cas, l’indice n’évoluera pas plus qu’il n’a évolué l’une de ces deux dernières années.
Je ne sais pas s’il existe vraiement un niveau 0 de l’exploitation des SGBD oracle, mais le redimensionnement, à la hausse, des fichiers de tablespaces est du niveau le plus trivial qui soit. Cependant, à peine plus compliqué, il est parfois nécessaire de redimensionner les redo logs, ou plus précisément les “archived red log files”. C’est pourtant parfois nécessaire quand par exemple on constate un nombre de switch trop élevé. Il est recommandé d’en avoir 3 à 4 par heures et on les comptes soit en mode texte avec SQL*Plus soit de manière plus graphique avec l’outil qui vous semblera bon.
Ce que l’on souhaite faire c’est afficher simplement le nombre de redo log files générés en mode graphiquesous forme de heat-map. Pour ce faire on utilise highcharts qui a le bon goût d’être gratuit pour un usage récréatif et non commercial. Et parce qu’on aime s’amuser on testera aussi avec plotly qui est gratuit tout court.
Pour ce faire, On choisit de séparer le code HTML, du javascript et des données de manière ce que chaque partie de code puisse être réutilisés au maximum.
SQL est pratique mais il est compliqué de produire un script SQL qui s’adapte à toutes les versions de la base oracle ou qui réagit en fonction de certains résultats de requêtes. Cet article pour donner des astuces de scripting afin de gérer des branchements et boucles en pur SQL et de pouvoir créer des scripts adaptifs.
(suite…)
On est souvent confronté à la problématique suivante, comment arrondir une date en dehors des sentiers tracés par trunc (la minute, l’heure, la semaine …) et donc stackoverflow donne ces exemples de réponses pour arrondir une date à 10 minutes mais qui sont facilement extrapolables à d’autres intervals :
SELECT sysdate, TRUNC(sysdate, 'MI') - MOD(TO_CHAR(sysdate, 'MI'), 10) / (24 * 60) FROM dual;
select trunc(sysdate, 'mi') - numtodsinterval(mod(EXTRACT(minute FROM cast(sysdate as timestamp)), 10), 'minute') from dual;
select trunc(sysdate, 'mi') - mod(EXTRACT(minute FROM cast(sysdate as timestamp)), 10) / (24 * 60) from dual;
Au niveau du coût pour les 3 on a (avec un temps d’execution identique inférieur au centième de seconde) :
----------------------------------------------------------------- | Id | Operation | Name | Rows | Cost (%CPU)| Time | ----------------------------------------------------------------- | 0 | SELECT STATEMENT | | 1 | 2 (0)| 00:00:01 | | 1 | FAST DUAL | | 1 | 2 (0)| 00:00:01 | ----------------------------------------------------------------- Statistics ---------------------------------------------------------- 1 recursive calls 0 db block gets 0 consistent gets 0 physical reads 0 redo size 657 bytes sent via SQL*Net to client 520 bytes received via SQL*Net from client 2 SQL*Net roundtrips to/from client 0 sorts (memory) 0 sorts (disk) 1 rows processed
Un exemple ?
alter session set NLS_DATE_FORMAT='YY-MM-DDHH24:MI:SS' ; col DT for a8 wrap col S10 for a8 wrap col M for a8 wrap col M5 for a8 wrap col M10 for a8 wrap col M15 for a8 wrap col M30 for a8 wrap col H2 for a8 wrap col H3 for a8 wrap col H6 for a8 wrap col H8 for a8 wrap col H12 for a8 wrap col DAY for a8 wrap col WEEK for a8 wrap select sysdate DT , sysdate - mod(EXTRACT(second FROM cast(sysdate as timestamp)), 10) / (24 * 60 * 60) S10 , trunc(sysdate, 'mi') M , trunc(sysdate, 'mi') - mod(EXTRACT(minute FROM cast(sysdate as timestamp)), 5) / (24 * 60) M5 , trunc(sysdate, 'mi') - mod(EXTRACT(minute FROM cast(sysdate as timestamp)), 10) / (24 * 60) M10 , trunc(sysdate, 'mi') - mod(EXTRACT(minute FROM cast(sysdate as timestamp)), 15) / (24 * 60) M15 , trunc(sysdate, 'mi') - mod(EXTRACT(minute FROM cast(sysdate as timestamp)), 30) / (24 * 60) M30 , trunc(sysdate, 'hh24') - mod(EXTRACT(hour FROM cast(sysdate as timestamp)), 2) / 24 H2 , trunc(sysdate, 'hh24') - mod(EXTRACT(hour FROM cast(sysdate as timestamp)), 3) / 24 H3 , trunc(sysdate, 'hh24') - mod(EXTRACT(hour FROM cast(sysdate as timestamp)), 6) / 24 H6 , trunc(sysdate, 'hh24') - mod(EXTRACT(hour FROM cast(sysdate as timestamp)), 8) / 24 H8 , trunc(sysdate, 'hh24') - mod(EXTRACT(hour FROM cast(sysdate as timestamp)), 12) / 24 H12 , trunc(sysdate, 'dd') DAY , trunc(sysdate, 'd') WEEK from dual /
DT | S10 | M | M5 | M10 | M15 | M30 | H2 | H3 | H6 | H8 | H12 | DAY | WEEK |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|
18-05-14 17:28:39 |
18-05-14 17:28:30 |
18-05-14 17:28:00 |
18-05-14 17:25:00 |
18-05-14 17:20:00 |
18-05-14 17:15:00 |
18-05-14 17:00:00 |
18-05-14 16:00:00 |
18-05-14 15:00:00 |
18-05-14 12:00:00 |
18-05-14 16:00:00 |
18-05-14 12:00:00 |
18-05-14 00:00:00 |
18-05-13 00:00:00 |
C’était pourtant pas si compliqué
[oracle@serveur ~/work]$ adrci ADRCI: Release 11.2.0.4.0 - Production on Thu Jan 7 14:14:24 2016 Copyright (c) 1982, 2011, Oracle and/or its affiliates. All rights reserved. ADR base = "/opt/oracle" adrci> show incident ADR Home = /opt/oracle/diag/rdbms/titi/titi: ************************************************************************* 0 rows fetched ADR Home = /opt/oracle/diag/rdbms/serveur/DB: ************************************************************************* INCIDENT_ID PROBLEM_KEY CREATE_TIME -------------------- ----------------------------------------------------------- ---------------------------------------- 208129 ORA 600 [ktcccod-1] 2016-01-05 06:45:45.367000 +01:00 592465 ORA 600 [kdBlkCheckError] 2016-01-07 11:27:32.712000 +01:00 592481 ORA 600 [kdBlkCheckError] 2016-01-07 11:29:22.188000 +01:00 592466 ORA 600 [kdBlkCheckError] 2016-01-07 12:08:52.179000 +01:00 592457 ORA 600 [kdBlkCheckError] 2016-01-07 12:11:18.073000 +01:00 592449 ORA 600 [kdBlkCheckError] 2016-01-07 12:22:53.246000 +01:00 592467 ORA 600 [kdBlkCheckError] 2016-01-07 12:57:21.733000 +01:00 592441 ORA 600 [kdBlkCheckError] 2016-01-07 13:20:34.972000 +01:00 592442 ORA 600 [kdBlkCheckError] 2016-01-07 13:36:02.718000 +01:00 592443 ORA 600 [kdBlkCheckError] 2016-01-07 13:43:26.175000 +01:00 adrci> IPS CREATE PACKAGE PROBLEM 592443 DIA-48448: This command does not support multiple ADR homes adrci> show homes ADR Homes: diag/rdbms/titi/titi diag/rdbms/serveur/DB adrci> SET HOME diag/rdbms/serveur/DB adrci> show incident ADR Home = /opt/oracle/diag/rdbms/serveur/DB: ************************************************************************* INCIDENT_ID PROBLEM_KEY CREATE_TIME -------------------- ----------------------------------------------------------- ---------------------------------------- 208129 ORA 600 [ktcccod-1] 2016-01-05 06:45:45.367000 +01:00 592465 ORA 600 [kdBlkCheckError] 2016-01-07 11:27:32.712000 +01:00 592481 ORA 600 [kdBlkCheckError] 2016-01-07 11:29:22.188000 +01:00 592466 ORA 600 [kdBlkCheckError] 2016-01-07 12:08:52.179000 +01:00 592457 ORA 600 [kdBlkCheckError] 2016-01-07 12:11:18.073000 +01:00 592449 ORA 600 [kdBlkCheckError] 2016-01-07 12:22:53.246000 +01:00 592467 ORA 600 [kdBlkCheckError] 2016-01-07 12:57:21.733000 +01:00 592441 ORA 600 [kdBlkCheckError] 2016-01-07 13:20:34.972000 +01:00 592442 ORA 600 [kdBlkCheckError] 2016-01-07 13:36:02.718000 +01:00 592443 ORA 600 [kdBlkCheckError] 2016-01-07 13:43:26.175000 +01:00 10 rows fetched adrci> IPS CREATE PACKAGE PROBLEMKEY "ORA 600 [kdBlkCheckError]" Created package 1 based on problem key ORA 600 [kdBlkCheckError], correlation level typical adrci> show problem ADR Home = /opt/oracle/diag/rdbms/serveur/DB: ************************************************************************* PROBLEM_ID PROBLEM_KEY LAST_INCIDENT LASTINC_TIME -------------------- ----------------------------------------------------------- -------------------- ---------------------------------------- 1 ORA 600 [ktcccod-1] 208129 2016-01-05 06:45:45.367000 +01:00 2 ORA 600 [kdBlkCheckError] 592443 2016-01-07 13:43:26.175000 +01:00 2 rows fetched adrci> IPS ADD FILE /opt/oracle/diag/rdbms/serveur/DB/trace/DB_s001_217994.trc PACKAGE 2 DIA-49404: No such package [2] adrci> IPS SHOW PACKAGE PACKAGE_ID 1 PACKAGE_NAME ORA600kdB_20160107142052 PACKAGE_DESCRIPTION DRIVING_PROBLEM 2 DRIVING_PROBLEM_KEY ORA 600 [kdBlkCheckError] DRIVING_INCIDENT 592465 DRIVING_INCIDENT_TIME 2016-01-07 11:27:32.712000 +01:00 STATUS New (0) CORRELATION_LEVEL Typical (2) PROBLEMS 1 main problems, 1 correlated problems INCIDENTS 6 main incidents, 2 correlated incidents INCLUDED_FILES 41 adrci> IPS GENERATE PACKAGE 1 IN /opt/oracle/work Generated package 1 in file /opt/oracle/work/ORA600kdB_20160107142052_COM_1.zip, mode complete adrci> exit
Je veux savoir quelle est ma session au niveau de v$session et à quel processus OS elle correspond
La requête à passer est la suivante :
set pages 0 lines 230 newp none emb on col machine for a25 select v.SID, v.USERNAME, v.MACHINE, v.PROGRAM, v.TERMINAL, SPID "OS PID", v.process from v$session v inner join v$process p on v.paddr=p.addr where v.AUDSID=USERENV('SESSIONID') and v.MACHINE=SYS_CONTEXT('USERENV','HOST') and v.TERMINAL=USERENV('TERMINAL') /
Son résultat :
SID USERNAME MACHINE ---------- ------------------------------ ------------------------- 633 SYS srvorcl.ojo.fr PROGRAM TERMINAL ------------------------------------------------ ------------------------------ sqlplus@srvorcl.ojo (TNS V1-V3) pts/2 OS PID PROCESS ------------------------ ------------------------ 147476 147469
On a OS PID qui correspond à l’identifiant du process de connexion de SQLPLUS à la base de données et process qui correspond l’indentifiant du process sqlplus
ps -edf | grep 147476 | grep -v grep oracle 147476 147469 0 15:12 ? 00:00:00 oracleTECH (DESCRIPTION=(LOCAL=YES)(ADDRESS=(PROTOCOL=beq))) ps -edf | grep 147469 | grep -v grep oracle 147469 197784 0 15:12 pts/2 00:00:00 sqlplus oracle 147476 147469 0 15:12 ? 00:00:00 oracleORCL (DESCRIPTION=(LOCAL=YES)(ADDRESS=(PROTOCOL=beq)))
Pour tuer la connexion sans tuer sqlplus (et se retrouver en mode nolog) c’est le process 147476 qu’il faut tuer.
C’était pourtant pas si compliqué
Ma base est bloquée et je ne sais pas pourquoi … J’ouvre une SR, et forcé”ment pour qu’il y ait un peu de répondant il faut que j’envoie un hanganalyze et un systemstate dump. Les instructions :
connect / as sysdba oradebug setmypid oradebug unlimit oradebug hanganalyze 3 -- wait 90 seconds oradebug hanganalyze 3 oradebug dump systemstate 266 -- wait 90 seconds oradebug dump systemstate 266 -- wait 90 seconds oradebug dump systemstate 266
C’était pourtant pas si compliqué
Mais pourquoi est-ce que ce paramètre est positionné à cette valeur ? Qui ne s’est pas posé la question devant un optimizer_index_cost_adj qui n’est pas à 100 ou un NLS_SORT qui n’est pas à Binary. Le vilain qui a fait le coup n’a pas commenté. Alors que pour le faire il suffit de passer les bonnes commandes
Pour commenter une valeur que l’on passe au niveau du SPFILE (Commentaire de 255 caractères maximum):
alter system set PARAMETRE=VALEUR comment='Gagne 42 minutes, le 25 mai 2001, D. N. Adams' scope=spfile sid='*' ;
Pour commenter un SQL_PROFILE existant (Commentaire de 500 caractères maximum):
begin sys.dbms_sqltune.ALTER_SQL_PROFILE( 'nomDuProfile' , 'COMMENT' , 'Souci sur V$OGONS, contourne 0RA-1952, 11 mars 2013, Z. Beeblebrox' ) ; end; /
C’était pourtant pas si compliqué