Formatear el prompt del SQLplus

Hoy vamos a ver una entrada muuy sencilla de como formatear el prompt de SQLPLUS
Bajo nuestro oracle home tenemos un fichero llamado glogin.sql donde podemos definir las variables del sqlplus, entre ellas el prompt.
Supongaamos que queremos saber cual es el usuario con el que nos conectamos, seria tan sencillo como aniadir la linea

dbserver01:vi /u01/app/oracle/product/19c/dbhome_1/sqlplus/admin/glogin.sql
--
-- Copyright (c) 1988, 2005, Oracle.  All Rights Reserved.
--
-- NAME
--   glogin.sql
--
-- DESCRIPTION
--   SQL*Plus global login "site profile" file
--
--   Add any SQL*Plus commands here that are to be executed when a
--   user starts SQL*Plus, or uses the SQL*Plus CONNECT command.
--
-- USAGE
--   This script is automatically run
--
def _editor=vi
set timing on
set feedback on
set sqlprompt "_user  _connect_identifier > "

Ms informacion, en:

  • https://www.youtube.com/watch?v=Ax4s39KfcZ8
  • https://www.oreilly.com/library/view/oracle-sqlplus-the/0596007469/re95.html

Capturar errores de usuario en la base de datos

Hoy vamos a ver como facilitarnos un poco el control del código de aplicación de la base de datos.

En muchas ocasiones, los desarrolladores no llevan a cabo correctamente la captura de errores , lo que produce una serie quejas «no me va y no me da error».
Para lidiar con estas situaciones podemos crear un pequeño trigger que registre en la base de datos que y quien genera errores en la base de datos, para poder seguirlos y depurar estos errores.

Vamos a suponer que:

  • Tenemos un tablespace específico llamado CONTROL donde guardaremos nuestros datos
  • Tenemos un usuario llamado CONTROL que será el propietario del código

Primero crearemos la tabla que contendrán los errores:

-- Creamos la tabla 
create table CONTROL.oraerror (
identificador   NUMBER,
FECHA           DATE,
ESQUEMA         VARCHAR2(30),
USUARIO         VARCHAR2(50),
SQL_ID          VARCHAR2 (13) DEFAULT NULL,
SQL_HASH_VALUE  NUMBER DEFAULT NULL,
err_nr          NUMBER(10),
err_msg         VARCHAR2(4000),
stmt            CLOB
) TABLESPACE CONTROL;

--
-- Creamos una secuencia para el oraerror
create sequence CONTROL.oraerror_seq
start with 1
increment by 1
minvalue 1
nomaxvalue
nocache
nocycle;

Y después crearemos nuestro trigguer

CREATE OR REPLACE TRIGGER CONTROL.after_error
 AFTER SERVERERROR ON DATABASE
 DECLARE
 id             NUMBER;
 vSerial        NUMBER DEFAULT NULL;
 ESQUEMA        VARCHAR2(30);
USUARIO         VARCHAR2(50);
 SQL_ID         VARCHAR2 (13) DEFAULT NULL;
 SQL_HASH_VALUE NUMBER DEFAULT NULL;
  sql_text      ORA_NAME_LIST_T;
 v_stmt         CLOB;
 n              NUMBER;
 vsid           NUMBER DEFAULT NULL;
BEGIN
 -- BUscamos ID 
SELECT dbms_debug_jdwp.current_session_serial serial# INTO vSerial 
      FROM DUAL;
SELECT oraerror_seq.nextval,SYS_CONTEXT ('USERENV', 'sid') INTO  id, vsid
     FROM dual;
SELECT  SQL_ID, SQL_HASH_VALUE,USERNAME,OSUSER INTO SQL_ID, SQL_HASH_VALUE,ESQUEMA,USUARIO
   FROM sys.v_$session   WHERE sid = vsid AND serial# = vSerial;
n:= ora_sql_txt(sql_text);

IF n >= 1
 THEN
 FOR i IN 1..n LOOP
 v_stmt := v_stmt || sql_text(i);
 END LOOP;
END IF;
--
 FOR n IN 1..ora_server_error_depth LOOP
      INSERT  /*+ APPEND */ 
      INTO CONTROL.oraerror VALUES(id, sysdate, ESQUEMA, USUARIO, SQL_ID,SQL_HASH_VALUE,  ora_server_error(n), ora_server_error_msg(n), v_stmt);
  END LOOP;
 --
END ;

Con esto tendrémos en nuestra tabla todos los errores que dela base de datos.
Hay que tener en cuenta que, muchos de los errores pueden ser correctos, como los errores :

  • ORA-01017: nombre de usuario/contraseña no válidos; conexión denegada
  • ORA-00001: unique constraint (XXXX) violated (error asumible en cargas masivas)
  • ORA-03113: end-of-file on communication channel ORA-03113: end-of-file on communication channel

Con lo que habrá que seguirlos con cuidado y ver en que caso son reprochables o asumibles

Añadir agentes en OEM12c

Una vez tenemos instalado el OEM12c el siguiente paso lógico es el de añadir nuestros sistemas para su gestión.

El primer paso que tenemos que dar, es el de añadir nuestros hosts, bien sea por autodescubrimiento o bien de manera manual. El problema con el que nos encontramos es que, el OEM12c no tiene instalados los agentes para los distintos hosts de las arquitecturas, por lo que tenemos que hacerlo nosotros manualmente
ScreenHunter_114 Jul. 26 09.57

La actualización en modo on-line no funciona, con lo que, debemos de ir a la actualización «off-line»
En la actualización off-line, el sistema nos aconseja el bajarnos el catálogo de agentes que podemos utilizar y «cargarlos» al OEM . El problema es que, tampoco funciona , devolviendonos el siguiente error:

«The uploaded catalog file does not contain the following files: «components.xml, aru_targets.xml, patch_recommendations.xml, certifications.xml, aru_releases.xml, aru_component_releases.xml, aru_languages.xml, aru_product_groups.xml, aru_platforms.xml, aru_product_releases.xml, aru_products.xml»»

¿Que podemos hacer?
La solución será el instalar el catálogo de agentes desde linea de comandos. Los pasos detallados de lo que debemos de hacer es:

1- Vamos a la pestaña «Configurar-> extensibilidad-> Actualizacion automatica , alli tendremos que cambiar el modo «online» por «oflline»

Una vez hecho eso, OEM12c nos indicará en un desplegable donde podemos descargar el último catálogo de agentes,en mi caso fué https://updates.oracle.com/Orion/Download/download_patch/p9348486_112000_Generic.zip

Lo que tendremos que hacer es abrir una consola de sistema operativo para descargar los agentes y añadirlos al catalogo de OEM, para esto haremos
ya en modo consola y desde nuestro usuario de OEM12c hacemos:

cd /u01/app/oracle/libreria_instalacion/
wget https://updates.oracle.com/Orion/Download/download_patch/p9348486_112000_Generic.zip
cd  $OEM_HOME
$OEM_HOME/bin/emcli login -username=SYSMAN
** Introducimaos contraseña de OEM 
./emcli import_update_catalog -file=/u01/app/oracle/libreria_instalacion/p9348486_112000_Generic.zip  -omslocal

COmo podéis ver, hay un directorio «libreria_instalacion» del que no hemos hablado antes, este directorio lo hemos creado previamente en el servidor y lo hemos dado de alta en las opciones
Configurar->Provisionamiento y aplicacion de parches -> Biblioteca de software

ScreenHunter_115 Jul. 29 12.52

Con esto ya tenemos nuestros agentes en el catálogo, ahora ya podemos descargarlos e instalarlos.
Esta parte ya funciona bien desde la actualizacion «online», con lo que volveremos a
ScreenHunter_115 Jul. 26 10.05

Y seleccionaremos «online».
Una vez activado la instalacion online, se conectará a el repositorio de oracle y tendremos disponibles todos los agentes, lo siguiente será seleccionarlos para la descarga y posteriormente para la instalacion
ScreenHunter_113 Jul. 26 09.40
ScreenHunter_116 Jul. 26 10.50

Introduccion a los servicios de Oracle

Uno de los elementos mas potentes que introdujo Oracle en la versión 10g fué el uso de servicios.
Los servicios de Oracle no son otra cosa que una abstracción lógica de una instancia de base de datos. Aunque los servicios tienen mas sentido en entorno RAC, hoy vamos a ver como se configuran y para que pueden servir en un entorno de «single instance».

Supongamos tenemos una base de datos produccion en la que tenemos consolidados 4 entornos distintos ( Webfotos,Cargas,Contabilidad y Desarrollo ) que acceden a nuestra instancia con el mismo esquema,y desde servidores de aplicaciones que comparten máquina entre ellos, en el momento en que la base de datos tiene problemas nos es muy difícil el saber quien es quien.
Si pudiésemos discriminar las conexiones por una agrupación lógica, sería mas fácil el verlo, y , mas aún, si el EMC fuese capaz de separar las gráficas y estadísticas por esa agrupación.

Pues esto es exactamente lo que nos proporcionan los servicios Oracle.
En nuestro caso ficticio, vamos a crear los distintos servicios:

  • Webfotos
  • Cargas
  • Contabilidad
  • Desarrollo

De esta forma, cada conexión de estos 4 entornos usara un service_name distinto en su TNS_NAMES de cliente, y , la base de datos podrá identificar ( y limitar) a cada uno de ellos de manera separada.

Lo primero que tendremos que hacer es crear los servicios. Para esto tenemos dos maneras, o bien desde el srvctl ( en caso de RAC,Grid control u Oracle restart), o mediante el paquete DBMS_SERVICES , como nuestro caso es el de una «single instance», no nos va a quedar mas remedio que usar este paquete.
Mediante la función CREATE_SERVICE crearemos los servicios de la manera:

exec dbms_service.CREATE_SERVICE(SERVICE_NAME=>'webfotos', NETWORK_NAME=>'webfotos')
exec dbms_service.CREATE_SERVICE(SERVICE_NAME=>'cargas', NETWORK_NAME=>'cargas')
exec dbms_service.CREATE_SERVICE(SERVICE_NAME=>'contabilidad', NETWORK_NAME=>'contabilidad')
exec dbms_service.CREATE_SERVICE(SERVICE_NAME=>'desarrollo', NETWORK_NAME=>'desarrollo')

Una vez creados los servicios, los arrancaremos con la función

exec dbms_service.START_SERVICE('webfotos')
exec dbms_service.START_SERVICE('cargas')
exec dbms_service.START_SERVICE('contabilidad')
exec dbms_service.START_SERVICE('desarrollo')

Para comprobar si la creación de nuestros servicios ha funcionado, podemos chequear el parámetro service_names

SQL> select value from v$parameter where NAME='service_names';
VALUE
---------------------------
produccion,webfotos,cargas,contabilidad,desarrollo

O bien el listener con lsnrctl services

[oracle@blog] [$lsnrctl services

LSNRCTL for Linux: Version 11.2.0.2.0 - Production on 17-MAY-2013 13:31:06

Copyright (c) 1991, 2011, Oracle.  All rights reserved.

Connecting to (ADDRESS=(PROTOCOL=tcp)(HOST=)(PORT=1521))
Services Summary...
Service "PLSExtProc" has 1 instance(s).
  Instance "PLSExtProc", status UNKNOWN, has 1 handler(s) for this service...
    Handler(s):
      "DEDICATED" established:0 refused:0
         LOCAL SERVER
Service "produccion" has 1 instance(s).
  Instance "XE", status READY, has 1 handler(s) for this service...
    Handler(s):
      "DEDICATED" established:34 refused:0 state:ready
         LOCAL SERVER
Service "webfotos" has 1 instance(s).
  Instance "XE", status READY, has 1 handler(s) for this service...
    Handler(s):
      "DEDICATED" established:34 refused:0 state:ready
         LOCAL SERVER
Service "contabilidad" has 1 instance(s).
  Instance "XE", status READY, has 1 handler(s) for this service...
    Handler(s):
      "DEDICATED" established:34 refused:0 state:ready
         LOCAL SERVER
Service "desarrollo" has 1 instance(s).
  Instance "XE", status READY, has 1 handler(s) for this service...
    Handler(s):
      "DEDICATED" established:34 refused:0 state:ready
         LOCAL SERVER
Service "cargas" has 1 instance(s).
  Instance "XE", status READY, has 1 handler(s) for this service...
    Handler(s):
      "DEDICATED" established:34 refused:0 state:ready
         LOCAL SERVER
The command completed successfully

Ahora, solamente tendremos que modificar los respectivos TNSNAMES de los distntos entornos para que se conecten mediante SERVICE_NAME y no mediante SID y tendremos identificados cada una de la sesiones de oracle con el servicio.

¿que beneficios nos aporta todo esto?

  • Trazabilidad: Nos va a ser sencillísimo encontrar quien es el que esta haciendo algo ya que en un primer vistazo encontraremos al culpable «logico» del problema, una vez tenemos el origen del problema es mas sencillo abordarlo.
  • Accounting: Vamos a poder ser capaces de ver los consumos de cada aplicacion/grupo lógico en la base de datos, lo que nos puede ser muy bueno a la hora de derivar costes o limitar recursos
  • control de accesos: Si en un momento específico queremos asegurarnos de que un elemento lógico no acceda a la aplicacion, podemos detener el servicio y el resto funcionaría correctamente.Esto puede ser muy útil por ejemplo, para evitar cargas en horario diurno, o para controlar los equipos de desarrollo

Hasta ahora lo hemos visto todo muy fácil, pero .. ¿que ocurre cuando reinicias la base de datos?.
Para que la instancia levante los servicios al arrancar deberán de estar en el init.ora con la sintaxsis:


service_names='produccion','webfotos','cargas','desarrollo'

Si no es así , cuando se levante nuestra base de datos no se levantan los servicios, y esto hace que no funcione nada de lo que apunta a ellos.
La solución como os decía la principio es hacerlo desde el srvctl, pero …
¿como lo hacemos si no tenemos RAC,Grid u Oracle restart?
La respuesta es brutalmente sencilla.

[oracle@blog] [$sqlplus "/as sysdba"
SQL*Plus: Release 11.2.0.2.0 Production on Vie May 17 13:09:11 2013
Copyright (c) 1982, 2011, Oracle.  All rights reserved.

Connected to:
Oracle Database 11g Express Edition Release 11.2.0.2.0 - 64bit Production
SQL> alter system set service_names='produccion,webfotos,cargas,contabilidad,desarrollo';
System altered.

Tan sencillo como acabáis de ver, simplemente hemos de conectarnos desde el sqlplus y hacer un ALTER SYSTEM para el parámetro service_names poniendo nuestros servicios separados por comas.

Como siempre, para mas información, tenemos la documentación de Oracle del paqueteDBMS_SERVICES

Problemas con los requerimientos del cliente 11gr2 en windows

Volvemos tras las vacaciones navideñas con una pequeña entrada de esas tremendamente simples, pero que pueden ser evitarnos una gran pérdida de tiempo.

Una de las cosas mas engorrosas de las instalaciones de Oracle es la instalación del cliente, en primer lugar, porque pocas veces nos especifican que es exactamente los componentes del cliente que necesitan, y en segundo lugar, por que, hasta estas últimas versiones la instalación ( especialmente la desinstalación) del cliente de windows era muy engorrosa.

Pues bien, el otro día en la instalación de un cliente 11gr2 en windows me encontré con un error nuevo:

error_instalacion_XP

Mi windows XP detectaba un error en los requerimientos de la instalacion del cliente (no instantclient), cuando, todos los requerimientos eran correctos.

La solución es tan sencilla como el habilitar el uso compartido de C$. Parece ser que el instalador utiliza «\\< servidor >\C$\temp» , con lo que si no está habilitado el recurso, la instalación falla.

La información completa del caso está (como siempre) en metalink, en la nota «Installation of 11gR2 on Windows Fails Checking Requirements [ID 1133495.1]»