Consideraciones a tener en cuenta para las instalaciones de ORACLE

En numerosas ocasiones nos hemos podido encontrar con la situación en que tenemos que instalar por ejemplo clientes Oracle de versiones diferentes para poder acceder a distintas bases de datos de versiones, también diferentes. Este hecho, puede provocar que durante las instalaciones nos encontremos con numerosos inconvenientes y sobretodo dudas de cómo encarar la instalación, si hacerlo en el mismo ORACLE_HOME o distinto, que pasa con el registro en Windows, el PATH, etc…

Seguidamente dejo unas cuantas recomendaciones, que evidentemente se tienen que interpretar como lo que son, recomendaciones que para mis casos en concreto, he seguido porque las necesidades de mis clientes lo exígian. Lo que “recomiendo” seguidamente puede diferir en otros clientes que tengan necesidades distintas.

Recomendación 1

Si hay que instalar diferentes clientes de ORACLE en un mismo PC, hacedlo por orden de versión. Es decir, si tenemos que instalar un cliente 7, y un cliente 10g, instalar primero el cliente 7 y posteriormente el 10g.

Recomendación 2

En el ejemplo anterior, además de instalar los clientes por orden de versión, lo haremos en un ORACLE_HOME diferente para evitar sobreescribir ficheros e inhabilitar el cliente de versión más antigua.

Recomendación 3

En clientes bajo Windows, es recomendable definir una memória virtual adecuada, sobretodo para instaladores de versiones más antiguas. Es importante definirla bien para evitar errores que nos pueden despistar y pensar que están relacionados con otros errores de Oracle.

Recomendación 4

Es importante tener claro, que cada instalación de cliente de Oracle de versiones diferentes que hagamos en una misma máquina, tendrá un SQL*NET diferente y por tanto, los ficheros tnsnames.ora y listener.ora deberán ser configurados de manera adecuada para poder acceder a las bases de datos que necesitamos acceder. Puede suceder que con algunos clientes de versiones superiores podemos, evidentemente acceder a versiones anteriores, pero no poder hacerlo con clientes anteriores a versiones superiores. Es por este motivo, que podemos tener en el cliente de versión más nueva, entradas en el fichero tnsnames.ora para conexiones a versiones anteriores, de ahí el hecho, de que tengamos que configurarlo una vez instalado el cliente Oracle de versión superior, aunque tengamos configurado el fichero tnsnames.ora del cliente de versión anterior correctamente.

Recomendación 5

En el registro de Windows, dentro de HKEY_LOCAL_MACHINE/Software/ se guardan las entradas de los clientes instalados de ORACLE. Es necesario saber, que si hemos realizado por ejemplo una instalación de la versión 7 de Oracle y queremos volverla a realizar desde cero, tenemos que eliminar la rama de ORACLE y la ruta que aparece en la variable de entorno PATH. Luego eliminaremos el directorio donde tengamos el cliente instalado y podremos así, volver a arrancar el instalador de Oracle. En versiones superiores, 10G y 11GR2 los instaladores están más logrados y no tenemos que hacer tantas “artimañas”.

Recomendación 6

Existen unos ficheros digamos de rastro que almacena el instalador de Oracle donde se detalla lo que hay instalado en el sistema.
En vesiones anteriores de ORACLE existe un fichero con extensión .rgs ubicado normalmente en /../orainst donde se almacena lo que hay instalado. Si vamos a instalar por ejemplo OEM en una máquina donde ya hay productos instalados de Oracle, podemos renombrar este fichero y ponerle por ejemplo extensión “.old” y posteriormente lanzar el instalador de Oracle “Oracle Installer” así evitaremos problemas en la instalación.

Tened en cuenta que a partir de la versión 6 de Oracle Developer, el instalador ya es capaz de detectar si hay servicios de Windows arrancados. Pero siempre es recomendable bajarlos antes de cualquier instalación.

Los ficheros .rgs almacenados en /../orainst son el registro de los productos Oracle con sus respectivas versiones instalados en la máquina.

Recomendación 7

En versión 7 de Oracle existe un fichero con extensión .log en \ORANT\ORAINST llamado orainst.log digamos de rastro que almacena el instalador de Oracle cuya extensión es .log y no .rgs como en versiones posteriores.

Recomendación 8

En versión 7 de Oracle existe una “herramienta” que permite crear/borrar los servicios de Windows. Se trata del ejecutable oradim73. Podemos ver sus diferentes opciones ejecutando desde la linea de comandos de Windows:

C:\> oradim73 /?
oradim73 -¿
oradim73 –h
oradim73 –help

Ejemplo:

C:\> oradim73 –new –sid ORCL –intpwd oracle –startmode manual –pfile C:\ORANT\DATABASE\initSID.ora

- manual–> Se suele poner manual durante el proceso de instalación, y una vez finalice esta, lo cambiaremos a auto.

C:\oradim73 –edit –sid ORCL –startmode auto

Esta herramienta nos puede ser útil si alguna instalación se nos complica y tenemos que borrar los servicios de Windows.

Recomendación 9

En versión 7 de Oracle para windows ORACLE_SID se define manualmente… Sí es la primera base de datos ORACLE que se crea debemos hacer:

En el registro de Windows:

Ir a HKEY_LOCAL_MACHINE
. Software
. ORACLE
Pulsar el menú “Edición”
Nuevo -> Valor alfanumérico.

Introducir ORACLE_SID en “nuevo valor #1”, seguidamente con el botón derecho pulsar modificar sobre el campo, y poner el valor que corresponda al SID ( en este caso ORCL). Este parámetro ORACLE_SID es el que identifica a la Base de datos a la cual  nos  conectamos por defecto. Imaginemos, que queremos entrar al sqlplus, nos pide usuario, clave y la cadena de conexión, el usuario iria a conectarse a la Base de datos especificada en “cadena de conexión”, pero en caso de que no se especificase, lo haría donde indicase ORACLE_SID.

Posted in Instalaciones | Tagged , , , , | Leave a comment

ORA-28002: The password expire within 7 days … como solucionarlo

Es posible que en alguna ocasión que como DBA te llame un usuario y te diga que al intentar acceder con su usuario a su cuenta le salga el mensaje de error:

ORA-28002: the password will expire within 7 days

Tú le cambias la contraseña, vuelves a probar, y desgraciadamente sigue saliendo el mismo error. Incluso, el usuario puede tener ya la cuenta bloqueada después de varios intentos fallidos de conexión. Visitar este enlace para ver como desbloquear la cuenta: Bloquear/Desbloquear una cuenta ORACLE

El problema es de fácil solución. Todo es debido al perfil (profile) que tenga asociado dicho usuario. Normalmente, el perfil asociado a un usuario en el proceso de creación es DEFAULT. Y dentro de ese perfil, se definen valores como la caducidad y otros parámetros que determinan la caducidad de la contraseña. Para evitar este error, revisaremos dichos parámetros del perfil.

Los podemos consultar via SQLPLUS o bien con OEM. En el ejemplo veremos las dos maneras.

Debemos tener en consideración que …

- Es recomendable que el password expire aunque sea en un periodo prolongado de tiempo.
- El perfil se define en la sentencia de creación del usuario “CREATE USER …”
- Podemos modificar los perfiles una vez creado dicho usuario e incluso cambiar el perfil del usuario.

Empecemos…..

Desde SQLPLUS

Miramos que perfil tiene el usuario asignado:

SQL>  select username, profile from dba_users
where username = 'USUARIO';

 

USERNAME                       PROFILE
—————————— ——————————
USUARIO                          DEFAULT

vemos que tiene asignado el perfil DEFAULT, será el que editaremos para cambiar los valores de expiración de la contraseña. Estos valores de perfil son PASSWORD_LIFE_TIME y basados en la tabla de atributos de usuario ASTATUS y EXPTIME.

sacamos los valores …

SQL> select username, account_status, expiry_date from dba_users;

USERNAME                       ACCOUNT_STATUS                   EXPIRY_DATE
—————————— ——————————– ————
USUARIO                           EXPIRED & LOCKED                 15-AUG-12

en este caso el usuario le expiró el 15 de Agosto de 2012 y además, tiene la cuenta bloqueada. Por tanto, primero desbloquearemos la cuenta tal y como explicamos en la entrada de blog del enlace anterior. Y procedermos a cambiar el límite de caducidad en el profile.

SQL> ALTER PROFILE "DEFAULT" LIMIT PASSWORD_LIFE_TIME UNLIMITED;

Teniendo en cuenta que no le estamos poniendo fecha de “expiración” y siempre es aconsejable hacerlo.  Esto por si sólo no solventa el error, hasta que las tareas de cambio de password, desbloqueo pendientes estén realizadas. Una vez hechas, el usuario al conectarse cogerá los nuevos valores definidos en el perfil.

Recordad que para cambiar la clave del usuario haremos:

SQL>  ALTER USER usuario IDENTIFIED BY VALUES 'clave';

CONCLUSIÓN:
La caducidad de la contraseña está controlada por el límite PASSWORD_LIFE_TIME definido en el perfil (DEFAULT por defecto) y se activa al iniciar la sesión Oracle, pero depende de la combinación de los parámetros ASTATUS y EXPTIME y se reestablece por un cambio de contraseña (alter user … identified by …). El cambio de perfil NO cambiará ASTATUS. En el cambio de contraseña se restablece ASTATUS y PTIME, pero no EXPTIME. Por tanto, los usuarios que estén bloqueados, se tendrán que desbloquear y los que esten en “EXPIRED” se les tendrá que cambiar la contraseña.

Ahora vamos a ver lo mismo desde OEM …

iremos a la pestaña “Servidor” y en el apartado Seguridad pulsaremos en el enlace “Perfiles”.

Seguidamente en el perfil (normalmente suele ser el perfil DEFAULT) que corresponda al usuario afectado, pulsaremos en el perfil y luego lo editaremos …

Por último, editaremos el perfil y cambiaremos sus valores, pulsaremos en “Aplicar” para aplicar los cambios realizados.

Pues esto es todo …
Sencillito!!! ;-)

 

Posted in Administración Oracle, ORA-????? | Tagged , , , | Leave a comment

¡¡¡¡ Crecimiento UNDOscriminado !!!! – Tablespace UNDO

En esta entrada de Blog voy a intentar explicar a grandes rasgos como funcionan los tablespaces de UNDO y mostraré una solución a un crecimiento indiscriminado del tablespace de UNDO que llenó un filesystem e hizo tambalear el sistema.

Es bastante común encontrarse con que el tablespace de UNDO, debido a que algún proceso se cuelgue, empiece a crecer de manera indiscriminada y si a esto le sumas que se tenga configurado en autoextend=ON con un límite mayor de la capacidad libre existente en ese momento en el disco donde se encuentre el datafile del tablespace,  circunstancia, que puede provocar que el disco se llene y por tanto, un posible crash del sistema.

Para evitar esto, un  correcto dimensionamiento del tablespace UNDO nos puede evitar más de un quebradero de cabeza. Empezaré con un poco de teoría para situarnos ….

El tablespace de UNDO es lo que se conoce como un tablespace de sistema. Como lo son el de SYSTEM, SYSAUX o el TEMP. El objetivo de un tablespace de UNDO es almacenar información que permita deshacer cambios, crear imágenes antiguas de bloques de datos e incluso almacenar información útil que la funcionalidad del Flashback pueda requerir en algún momento. El tablespace UNDO debe crearse como UNDO en el proceso de creación y puede perfectamente hacerse con 2 datafiles y en filesystems distintos entre sí y distintos de donde esté ubicado el tablespace TEMP.

 Ejemplo muy básico de creación de UNDO:

CREATE UNDO TABLESPACE undotbs01
DATAFILE '/undotbs01.dbf' SIZE 200M 
AUTOEXTEND ON MAXSIZE 8192M;

El tablespace de tipo UNDO debe existir para que la base de datos pueda almacenar allí los registros propios “de deshacer”. Si no existe, la instancia usará el tablespace SYSTEM para tal fin. Cosa nada recomendable y que es más que probable que en el archivo ALERT_.log se genere el error:

ORA-01552: cannot use system rollback segment for non-system tablespace ‘%s’.

Por otro lado, existe un parámetro de inicialización “UNDO_TABLESPACE” que permite indicarle a la instancia cual es el tablespace UNDO a utilizar, útil en los casos en los que existen varios tablespaces UNDO.

¿ Como gestiona ORACLE el tablespace UNDO ?

Oracle lo puede gestionar de dos maneras distintas:

1.- SMU (System Managed Undo)- (AUTO*) o lo que es lo mismo, modo automático de gestión, donde no se utilizan los segmentos de rollback externos, la información de UNDO se almacena en un tablespace especial dedicado exclusivamente a este objetivo.

2.- RBU (modo manual de gestión del UNDO) – (MANUAL*) . Se almacena de forma externa en segmentos de rollback. Este era el único método que existía en versiones anteriores de Oracle.

Ambos modos de gestión se establecen mediante el parámetro dinámico UNDO_MANAGEMENT que libera a los DBA´s de la administración y monitoreo si lo configuras en modo AUTO.

SQL> alter system set undo_management = <valor>;

Ejemplo para setear el parámetro en modo AUTO:

SQL> alter system set undo_management = AUTO;

¿ Cómo ver que valores de UNDO tenemos configurados en la BBDD ?

SQL> show parameters undo
NAME                                 TYPE        VALUE
------------------------------------ ----------- --------------------------
undo_management                      string       AUTO
undo_retention                       integer      900
undo_tablespace                      string       UNDOTBS1

¿ Que significan ?

undo_management
explicado en el punto anterior.

undo_retention
Parámetro dinámico que indica en segundos (900 por defecto) cuanto tiempo ha de permanecer, al menos, la información de UNDO disponible.

Ej: alter system set undo_retention=<valor>;

undo_tablespace
Parámetro dinámico que indica el tablespace de almacenamiento de “UNDO” a usar en el arranque.

Hasta aquí un poco de teoría, pondré el problema que me he encontrado alguna vez y su solución y ampliaré información durante la explicación para entender mejor otros parámetros que no he explicado anteriormente.

Problema: El Tablespace de UNDO crece indiscriminadamente y llega a llenar el filesystem donde estaba ubicado el datafile asociado. Este crecimiento indiscriminado puede ser debido a una transacción muy grande, un import de alguna tabla muy grande, etc…

Solución:
Volver a poner en el tamaño adecuado el tablespace de UNDO una vez realizada la transacción. Lamentablemente, no se puede reducir un tablespace de UNDO, tenemos que crear un nuevo tablespace tipo undo con el tamaño deseado, asignar este a la BBDD, y eliminar el antiguo. Luego si queremos volver a ponerlo todo igual, repetiremos la operación creando de nuevo otro tablespace tipo undo con el mismo nombre que tenía originalmente el primer tablespace undo y asignárselo a la BBDD. Finalmente borraremos el auxiliar creado. Por último, comprobaremos que realmente el tablespace de UNDO está correctamente definido.

NOTA: Realmente NO es que no se pueda reducir el tablespace de undo haciendo un RESIZE. Lo cierto es que si se puede, pero sólo hasta donde lo permita la HWM (High water mark).

Pasos para solucionar el problema:

Como el datafile llenó el filesystem, lo primero que tenía que hacer es hacer espacio en el filesystem, pero asegurándome de que cuando haga espacio, el tablespace de UNDO no siga creciendo de manera que lo vuelva a llenar. Para ello, primero quitaré el autoextend del tablespace UNDO.

Conectado como sys o system ….

SQL> ALTER DATABASE DATAFILE '/oracle/oradata/SID/undotbs01.dbf' AUTOEXTEND OFF;

Una vez asegurado de que el datafile no crecerá más, haremos espacio en el filesystem. Como se trata del filesystem donde están ubicados los tablespaces de sistema de Oracle como system, temp, etc... y no tenía otros ficheros que pudiese eliminar para hacer espacio. Lo que hice fue reducir el tamaño del tablespace TEMP que posteriormente, cuando ya haya conseguido volver a redefinir el tablespace UNDO volveré a poner a su tamaño original.

SQL> ALTER DATABASE TEMPFILE '/oracle/oradata/SID/temp01.dbf' RESIZE 2048M;

NOTA: Reducir TEMP a un tamaño que nos permita ganar espacio en el filesystem, pero que permita también trabajar a la base de datos.

Ahora podríamos probar de intentar reducir el TS UNDO con resize a ver si Oracle nos lo permite. Esto nos ahorraría el trabajo de crear el auxiliar, etc…. Pero tenemos que saber que tamaño nos deja reducirlo por encima de la HWM. (En mi caso, no lo conseguí, y tuve que crear el TS UNDO auxiliar).

Imaginemos que quiero reducir el datafile a 1000MB …

SQL> ALTER DATABASE DATAFILE ‘/oracle/oradata/SID/undotbs01.dbf’ RESIZE 1000M;

Al ejecutar la instrucción aparece el siguiente error:

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

Pues me veo obligado a crearme el TS Auxiliar para poder reducir el TS de Undo….

CONSULTAS ÚTILES RELACIONADAS CON TODAS LAS TAREAS A REALIZAR

Primero saber el tamaño actual del tablespace de UNDO desde SQLPLUS:

SQL>
SELECT Sum(v$datafile.bytes / 1024 / 1024) AS "Tamaño Actual TS UNDO [MB]"
FROM   v$datafile
       INNER JOIN v$tablespace
         ON v$datafile.ts# = v$tablespace.ts#
       INNER JOIN dba_tablespaces
         ON v$tablespace.NAME = dba_tablespaces.tablespace_name
WHERE  dba_tablespaces.contents = 'UNDO'
       AND dba_tablespaces.status = 'ONLINE'
/

 Podemos visualizarlo también directamente desde la consola de OEM:

Iremos a la pestaña “servidor” y pulsamos en el enlace “Gestión automática de deshacer”  y sale esta pantalla donde podemos ver la información del tablespace Undo incluído su tamaño actual.

La siguiente consulta nos puede ayudar a determinar un valor adecuado para el TS Undo

SELECT Substr(e.VALUE,1,25) "UNDO RETENTION [Sec]",
       d.undo_size / (1024 * 1024) "Tamaño Actual UNDO [MByte]",
       (To_number(e.VALUE) * To_number(f.VALUE) * g.undo_block_per_sec) / (1024 * 1024) "Tamaño Optimo UNDO [MByte]"
FROM   (SELECT Sum(a.bytes) undo_size
        FROM   v$datafile a,
               v$tablespace b,
               dba_tablespaces c
        WHERE  c.contents = 'UNDO'
               AND c.status = 'ONLINE'
               AND b.NAME = c.tablespace_name
               AND a.ts# = b.ts#) d,
       v$parameter e,
       v$parameter f,
       (SELECT Max(undoblks / ((end_time - begin_time) * 3600 * 24)) undo_block_per_sec
        FROM   v$undostat) g
WHERE  e.NAME = 'undo_retention'
       AND f.NAME = 'db_block_size'
/

Devuelve algo como:

UNDO RETENTION [Sec]      Tama??o Actual UNDO [MByte]
------------------------- ---------------------------
Tama??o Optimo UNDO [MByte]
---------------------------
900                                             12288
                 1779.82031

Aún así, yo recomiendo crearlo con el tamaño original e ir controlando durante el trabajo habitual de la BBDD que necesidades tiene el UNDO.

Seguimos … Creamos el nuevo TS Undo auxiliar con el tamaño mínimo de este óptimo sacado anteriormente, por ejemplo.

SQL>CREATE UNDO TABLESPACE "UNDOTBS_AUX" DATAFILE ‘/oracle/oradata/undotbs_aux.dbf’ SIZE 1800M;

Ahora debemos establecerlo en la BBDD. (Yo prefiero hacerlo desde OEM), pero desde SQL se hace así:

SQL> ALTER SYSTEM SET UNDO_TABLESPACE=’UNDOTBS_TEMP’ scope=both;

Ahora ya podríamos eleminar el primer tablespace de Undo (“el original” que creció desmesuradamente):

SQL> DROP TABLESPACE UNDOTBS1 INCLUDING CONTENTS AND DATAFILES;

Aquí nos puede pasar dos cosas, una que lo borre sin problemas y otra es que nos dé el siguiente error:

ERROR at line 1:
ORA-30013: undo tablespace ‘UNDOTBS1′ is currently in use

Pues tenemos que poner offline los segmentos de rollback que están online en el UNDO. Para saber que segmentos son, usaremos la siguiente consulta:

SELECT owner, segment_name, status FROM dba_rollback_segs
WHERE tablespace_name='UNDOTBS1' ORDER BY 3;

Sale algo como:

OWNER  SEGMENT_NAME                   STATUS
 ------ ------------------------------ ----------------
 PUBLIC _SYSSMU1_3129330276$           OFFLINE
 PUBLIC _SYSSMU2_1303119469$           OFFLINE
 PUBLIC _SYSSMU3_1479839839$           OFFLINE
 PUBLIC _SYSSMU4_3642025306$           OFFLINE
 PUBLIC _SYSSMU10_1545059069$          OFFLINE
 PUBLIC _SYSSMU6_1524158477$           OFFLINE
 PUBLIC _SYSSMU7_1101254083$           OFFLINE
 PUBLIC _SYSSMU8_4223133350$           OFFLINE
 PUBLIC _SYSSMU9_3952001453$           OFFLINE
 PUBLIC _SYSSMU5_2891492079$           ONLINE
10 rows selected.

Pues para cambiar el estado haremos:

SQL> ALTER ROLLBACK SEGMENT "_SYSSMU5_2891492079$" OFFLINE;

Seguidamente volveremos a ejecutar la sentencia:

SQL> DROP TABLESPACE UNDOTBS1 INCLUDING CONTENTS AND DATAFILES;
Tablespace dropped.

y no debería dar problemas.

Ahora tan sólo deberíamos volver a crear el tablespace de UNDO con el nombre original y tamaño original antes del incidente y por último, volver a asignar a la Base de datos este tablespace de UNDO que crearemos. (Y en este ejemplo, también volveremos a poner el tamaño que tenía originalmente al tablespace TEMP usando “resize”).  Se hace así:

SQL> CREATE UNDO TABLESPACE "UNDOTBS1" DATAFILE ‘/oracle/oradata/SID/undotbs01.dbf’ SIZE 1000M;
Tablespace created.

SQL> ALTER SYSTEM SET UNDO_TABLESPACE=’UNDOTBS1' SCOPE=BOTH;
System altered.

SQL> DROP TABLESPACE UNDOTBS_TEMP INCLUDING CONTENTS AND DATAFILES;
Tablespace dropped.

NOTA: si no deja borralo, proceder como en el ejemplo anterior.

SQL> show parameters undo
NAME                                 TYPE        VALUE
------------------------------------ -------     --------
_undo_autotune                       boolean     TRUE
undo_management                      string      AUTO
undo_retention                       integer     3000
undo_tablespace                      string      UNDOTBS1

CONSULTAS ÚTILES RELACIONADAS CON EL UNDO

La siguiente consulta busca una sesión de usuario que está en el undo para poderla matar…

column username format a30

SELECT a.name,b.status , d.username , d.sid , d.serial#
FROM   v$rollname a,v$rollstat b, v$transaction c , v$session d
WHERE  a.usn = b.usn
AND    a.usn = c.xidusn
AND    c.ses_addr = d.saddr
AND    a.name IN (
    SELECT segment_name
    FROM dba_segments
    WHERE tablespace_name = 'UNDOTBS1'
   );
Para matar la sesión ejecutaremos:
 SQL>  alter system kill session '147,4';
 donde 147 es el SID y 4 el SERIAL#
# Con la siguiente query podemos ver el estado de los segmentos de UNDO:
# UNEXPIRED significa que estos segmentos de UNDO no contienen ninguna transacción activa,
# pero estos contienen transacciones que todavía son requeridos para FLASHBACK.
# EXPIRED significa que estos segmentos no son requeridos después del periodo de retención definido en undo_retention.
# ACTIVE significa que estos segmentos de UNDO contienen transacciones activas, o sea, no se ha realizado commit.
# Los valores son en MB.  

SELECT SYSDATE AS fecha,
       unexpired.unexpired,
       expired.expired,
       active.active
FROM   (SELECT Sum(bytes / 1024 / 1024) AS unexpired
        FROM   dba_undo_extents
        WHERE  status = 'UNEXPIRED') unexpired,
       (SELECT Sum(bytes / 1024 / 104) AS expired
        FROM   dba_undo_extents tr
        WHERE  status = 'EXPIRED') expired,
       (SELECT CASE
                 WHEN Count(status) = 0
                 THEN 0
                 ELSE Sum(bytes / 1024 / 1024)
               END AS active
        FROM   dba_undo_extents
        WHERE  status = 'ACTIVE') active
/
# Buscar la sesión que está colgada o pendiente de ponerse a OFFLINE en TS UNDO para luego matarla

set lines 10000
column name format a10

SELECT a.name,b.status
FROM   v$rollname a,v$rollstat b
WHERE  a.usn = b.usn
AND    a.name IN (
    SELECT segment_name
    FROM dba_segments
    WHERE tablespace_name = 'UNDOTBS1'
   );

# Transacciones activas en TS UNDO

SELECT NAME, XACTS "ACTIVE TRANSACTIONS"
FROM V$ROLLNAME, V$ROLLSTAT
WHERE STATUS = 'PENDING OFFLINE'
AND V$ROLLNAME.USN = V$ROLLSTAT.USN;
Posted in Administración Oracle | Tagged , , , , , , , | Leave a comment

Tipos de parámetros en ORACLE

Existen tres tipos de parámetros en oracle:

- Parámetros “fijos”=> Son parámetros que una vez instalada la base de datos no se pueden volver a modificar / configurar. El juego de caracteres es un claro ejemplo.

- Parámetros Estáticos => Son parámetros que se pueden modificar, pero su modificación implica cerrar la base de datos y volverla a abrir para que los lea del fichero y pueda realizar el cambio.

- Parámetros Dinámicos=> Son parámetros cuyo valor se puede cambiar sin necesidad de cerrar la base de datos a diferencia de los estáticos.

Podemos asignar valores a los parámetros de la siguiente manera:

SQL> ALTER SYSTEM SET <parámetro> = <valor> [SCOPE = <ámbito>]

El valor del ámbito puede ser uno de los siguientes.

• spfile  –> Fichero de parámetros
• memory  –> En memória (en caliente)
• both  –> En memória y en el fichero de parámetros spfile.

Ejemplo:

El ejemplo anterior sólo funciona a partir de la versión 9.

Para ver el valor actual de un parámetro.
SQL> show parameter <parámetro>

Existe una manera sencilla de verificar que parámetros son dinámicos y cuales son estáticos.

La vista V$PARAMETER nos proporciona este tipo de información.

La columna ISSYS_MODIFIABLE contiene tres (3) tipos de valores:
• Immediate
• Deferred
• False
Por ejemplo:
SQL> select distinct ISSYS_MODIFIABLE from V$PARAMETER;

ISSYS_MODIFIABLE
—————————
IMMEDIATE
DEFERRED
FALSE

IMMEDIATE: identifica aquellos parámetros dinámicos, es decir, los ajustes se realizan de manera inmediata.
DEFERRED: los ajustes pueden ser realizados en “caliente” pero tomarán efecto solo después de que la base de datos sea re-inicializada.
FALSE: obligatoriamente la base de datos debe bajarse para poder efectuar el cambio.

La siguiente sentencia nos permite conocer lo anterior mencionado:

Col NAME format a50
Col ISSYS_MODIFIABLE format a20

Select NAME, ISSYS_MODIFIABLE
From V$PARAMETER
Order by 1

Posted in Administración Oracle | Tagged , , , | Leave a comment

Saber cuando se reinició por última vez una base de datos Oracle

Para saber cuando rebotó una BBDD por última vez:

- desde Sistema Operativo (Unix/Linux):

# ps -ef | grep pmon
oracle   10541     1  0 Jan29 ?        00:03:27 ora_pmon_ORCL
oracle   13606 23880  0 12:25 pts/2    00:00:00 grep pmon

Sale la hora en el proceso. Esa hora corresponde a la última vez que se reinició la instancia de BD.

- desde SQLPLUS

select status, startup_time, instance_name from v$instance;

O lo que es lo mismo pero adornado:

select status Estado, to_char(startup_time, 'HH24:MI DD-MON-YY') "Hora y Fecha de Arranque", instance_name Instancia
from v$instance
/
Posted in Administración Oracle, Linux | Tagged , , , | Leave a comment

Cómo cambiar de Tablespace los índices de un usuario

A veces es necesario cambiar todos los índices de un usuario a un tablespace espécífico de índices. Esto era muy importante en versiones 7, 8 y 9 de Oracle.  Una manera sencilla de hacerlo es desde sqlplus.

La idea es hacer un script que genere otro script con la sentencia sql que permita hacer el cambio. Sería como sigue …

Creamos un fichero llamado alter_ind_ts.sql y dentro copiamos el siguiente contenido:

$ vi alter_ind_ts.sql

Copiamos lo siguiente dentro …

spool alter_ind_ts_usuario.sql
set heading off
set linesize 180
select 'alter index '||owner||'.'||index_name||' rebuild tablespace <Poner_tablespace_destino>;'
from dba_indexes
where owner = '<nombre_usuario_propietario_indices>'
/
spool off

Posteriormente ejecutamos desde sqlplus conectados como system por ejemplo el script alter_ind_ts.sql :

SQL> start alter_ind_ts.sql;

Esto nos generará el script alter_ind_ts_usuario.sql que después de “recrearlo”, es decir, quitar la línea del final donde nos indica las filas devueltasy ponerle un “spool” al inicio del fichero y al final para que nos guarde el resultado de la ejecución del script. Podremos ejecutarlo posteriormente desde el mismo sqlplus y nos realizará el cambio de tablespace de los índices del usuario especificado.

SQL> start alter_ind_ts_usuario.sql ;

Posted in Administración Oracle | Tagged , | Leave a comment

Convertir campo tipo LONG a VARCHAR2 para compatibilizar con Oracle 7

 

 

 

Os pongo en contexto …

Resulta que necesito saber que vistas de un usuario determinado están usando un DBLINK hacia otra Base de datos y el DBLINK está almacenado en una Base de datos Oracle 7.

Para saber las vistas necesito consultar la vista all_views cuyo campo text me indica el nombre y contenido del DBLINK. Por tanto, necesito realizar una consulta de esa vista y campo y buscar el texto “@nombre_DBLINK”.

¿ Que sucede ?

Basicamente que el campo text de la vista all_views es de tipo LONG y por tanto, el realizar una búsqueda de una cadena determinada dentro de ese campo, usando por ejemplo “like” no funciona, nos dará el error “ORA-00932: tipos de dato inconsistentes. Pues para que funcionase debería ser de tipo CHAR o VARCHAR2.

Ejemplo:

select * from all_views
where text like ‘%@NOMBRE_DBLINK%’;
ORA-00932: tipos de dato inconsistentes

La solución pasa por convertir el campo text de tipo LONG a VARCHAR2 para poder consultar usando like (patrón de búsqueda).

Para este proceso, crearé una tabla llamada tabla_vistas con los campos que necesito consultar y con un campo tipo VARCHAR2 que será el que usaré para almacenar la información del campo text de la vista all_views y que es de tipo LONG.

CREATE TABLE tabla_vistas (
    propietario VARCHAR2(30),
    nombre_vista VARCHAR2(30),
    texto VARCHAR2(2000) -- En este campo almacenaré la información del campo text de all_views
    );

Una vez creada la tabla, cuyos tipos de datos en los campos coinciden con los que necesito de all_views excepto el campo “texto” que contendrá los datos sacados del campo “text” de tipo LONG, crearé un cursor de tipo explícito (que son los que usamos cuando una consulta devuelve más de una fila) que recorra la vista all_views y extraiga la información fila a fila y a su vez almacene cada fila en la nueva tabla creada, pero convirtiendo el campo text de all_views de LONG a VARCHAR2 para posteriormente, yo poder realizar una consulta sobre la tabla resultado usando la opción “like” para buscar una cadena determinada.

Esto se hace de la siguiente manera:

set serveroutput on size 320000
DECLARE
          CURSOR c1 IS
          SELECT owner,view_name, text FROM all_views;
          c_owner VARCHAR2(30);
          c_view_name VARCHAR2(30);
          c_text LONG;
          cadena2000 varchar2(2000);
    BEGIN
       OPEN c1;
      LOOP
          FETCH c1 INTO c_owner,c_view_name,c_text;
          cadena2000 := substr(c_text,1,2000);
          INSERT INTO tabla_vistas (propietario,nombre_vista,texto) VALUES (c_owner,c_view_name,cadena2000);
          EXIT WHEN c1%NOTFOUND;
           DBMS_OUTPUT.PUT_LINE('No se han encontrado datos.');
       ENDLOOP;
       CLOSE c1;
    END;

Ahora ya podemos realizar la consulta sobre la tabla “tabla_vistas” que contendrá todas las filas de all_views con los campos que necesitábamos y con el campo “text” de tipo LONG convertido a tipo VARCHAR2 en el campo “texto” del ejemplo.

select * from tabla_vistas

where texto like '%@NOMBRE_DBLINK%'; -- Texto a buscar en la tabla resultados
Posted in Administración Oracle | Tagged , , , , , | Leave a comment

DBMS_OUTPUT.PUT_LINE no muestra la salida por pantalla

Problemilla sencillo de resolver …
Tan sólo hay que añadir la siguiente linea antes de ejecutar el dbms… para poder verlo por pantalla. (Ya sea desde sqlplus o ejecutando TOAD por ejemplo).

set serveroutput on size 320000

Begin
Dbms_output.Put_Line(‘Esto es un ejemplo’);
End;
/

Posted in Administración Oracle | Tagged , | Leave a comment

Deshabilitar acceso a SQLPLUS usando “/as sysdba”

En la entrada de Blog anterior, expliqué como poder acceder como SYSDBA a sqlplus sin tener el password. Evidentemente, esto es un problema grave de seguridad, ya que si cualquiera se hace con el password del usuario oracle y/o cualquier usuario que pertenezca al grupo “dba” tendrá acceso como SYSDBA si hace lo explicado en la entrada de blog anterior. Esto es así porque en el fichero $ORACLE_HOME/rdbms/lib/config.* (.c o .s) que pertenece al grupo dba se dan privilegios implícitos para usar “/as sysdba” sin pedir contraseña a cualquier usuario de sistema operatativo que pertenezca a este grupo.

Pues la solución, es tan sencilla como sacar del grupo “dba” a todos aquellos usuarios de S.O y dejar el grupo vacio. De esta manera, al entrar a sqlplus, se nos solicitará el password.

Otra opción consiste en:

Editar el archivo “$ORACLE_HOME/rdbms/lib/config.c” y hacer referencia a un falso  grupo vacío. Posteriormente, “volver a vincular todos”, para volver a conectar todos los componentes de software de Oracle con el nuevo “grupo vacío” Oracle DBA.

Posted in Administración Oracle, Linux | Tagged , | Leave a comment

Acceder como SYSDBA a SQLPLUS sin conocer el password

De entrada esta “pretensión” de querer entrar a sqlplus sin conocer el password del usuario “SYS” puede ser una pretensión un tanto ambiciosa, pero que como podréis comprobar es más necesario de lo habitual y no es tan difícil.

En ocasiones, si eres un DBA de esos a los que tu empresa te manda cada dos por tres a clientes diferentes donde han pasado diferentes DBA´s y te encuentras que cuando llegas al cliente, ni el mismo cliente conoce los passwords ni de SYS ni de SYSTEM. Pero almenos se tiene acceso al servidor con cuentas de usuario de sistema operativo, si es la de oracle, ya tenemos mucho ganado, sino con root nos bastaría, o incluso, simplemente con poder acceder a una cuenta de usuario que nos permita crear usuarios y asignarle el grupo que deseamos, ya tendríamos solucionado el problema de no conocer el password de SYS o SYSTEM.

Os pongo en situación:

No conocemos el password de SYS ni de SYSTEM. Pero tenemos que realizar tareas de administración.

Nos tenemos que plantear lo siguiente…

- ¿ Tenemos acceso al servidor con un usuario de sistema operativo ? ¿ cúal ?
- ¿ Tenemos acceso al servidor con el usuario de sistema operativo oracle ?
- ¿ Tenemos acceso al servidor con  el usuario root ?

Pues si tenemos acceso con “root” al sistema operativo es fácil. Si hacemos el “su” al usuario oracle ya podremos acceder al servidor de base de datos de dos maneras diferentes con perfil de DBA.

# su – oracle
$ whoami
oracle

– Ahora entramos a sqlplus: forma 1
$ sqlplus “/as sysdba”
$ show user
SQL> show user
USER is “SYS”
SQL>

– O  entramos a sqlplus: forma 2
$ sqlplus /nolog
$ show user
SQL> show user
USER is “”
SQL> connect /as sysdba
SQL> show user
USER is “SYS”

Si tenemos acceso con el usario “oracle”, pues simplemente ejecutar cualquiera de las formas anteriores del ejemplo.

Y sino tenemos acceso con “root” pero tenemos acceso con un usuario que tenga permisos para crear usuarios y cambiar el grupo. Lo que deberíamos hacer es crearnos un usuario con cualquier nombre y asignarlo al grupo “dba”, configuraríamos el .profile (.bash_profile) del usuario el entorno Oracle (Path, ORACLE_HOME, ORACLE_SID, etc…) y entraríamos posteriormente con ese usuario al S.O y luego a sqlplus como lo hemos hecho en cualquiera de los dos ejemplos anteriores.

Para hacer lo comentado anteriormente, primero crearemos el usuario:

# useradd usuario_dba -m -g dba
# passwd usuario_dba
Introduciremos el password.

Ahora configuraremos el entorno Oracle para este usuario. Para ello es necesario conocer algunas de las variables de entorno imprescindibles que tendremos en un “.profile” del usuario “oracle”. Este profile nos sirve de ejemplo y lo tendremos que adaptar al entorno que queremos administrar, es decir, cambiar el ORACLE_HOME y el ORACLE_SID  y adecuarlo al entorno que vamos a administrar.

Ejemplo de .bash_profile en Linux RedHat válido para el entorno Oracle:

#vi  .bash_profile

# Get the aliases and functions
if [ -f ~/.bashrc ]; then
        . ~/.bashrc
fi

# User specific environment and startup programs

PATH=$PATH:$HOME/bin

export PATH

ORACLE_HOME=/u/oracle/11.2.0/ORCL
export ORACLE_HOME

PATH=$PATH:$ORACLE_HOME/bin:$ORACLE_HOME/OPatch
export PATH

ORACLE_SID=ORCL
export ORACLE_SID

LD_LIBRARY_PATH=/usr/lib64:$ORACLE_HOME/lib
export LD_LIBRARY_PATH

ORACLE_UNQNAME=ORCL
export ORACLE_UNQNAME

Las líneas anteriores adaptadas al servidor en concreto que queramos administrar serán las que deberemos añadir en nuestro “profile” del usuario que hayamos creado.

Una vez hecho esto, ya podemos salir y volver a entrar con el usuario para cargar el profile y ejecutar sqlplus como en los primeros ejemplos. Finalmente, comentar que si quisíeramos cambiar una vez conectados a sqlplus, por ejemplo, el password del usuario SYSTEM, lo podríamos hacer sin ningún problema ejecutando:

SQL> alter user SYSTEM identified by “<nuevo password>”;

¿ No es tan complicado verdad ?

Posted in Administración Oracle, Administración Sistemas, Linux | Tagged , , , | Leave a comment