Buscar este blog

viernes, 30 de diciembre de 2016

Traza y Diagnostico Oracle RAC

DOC ID : Diagnosability for Oracle Clusterware (CRS or Grid Infrastructure) Component and Resource (Doc ID 357808.1)


Trazas y Diagnosticos de LOG en Oracle RAC.

$CRS_HOME/log , Para el diagnostico del Clusterware contiene los siguientes archivos..

ClusterWare Alert ==>  nodo1rac.log

Client ==> Para aplicaciones OCR

RACG ==> /racg/dump  Logfiles para aplicaciones de los nodos incluidas las VIP ONSCrsd crs/log

CSSD /css/log
Evmd /evm/log

Para revisar configuracion de niveles de LOG

[grid@lpprpaxbd01]$ crsctl get log res ora.cdr.db
Get Resource ora.cdr.db Log Level: 1

Para ver los modulos del cluster:










Para revisar niveles de log por module:
CSS: Cluster Synchronozation Services












CRS: Cluster Ready Services:


























Las definiciones para los niveles de Log:

level 0 = turn off
level 2 = default
level 3 = verbose
level 4 = super verbose


Ahora veremos como aumentar el nivel de log para los componentes mas criticos de oracle rac clusterware, escogeremos un servicio critico como CSS para re configurar el nivel de log, para realizar un trace sobre la informacion registrada en algun evento de nivel critico sobre el recurso de cluster CSS.

 CSS:  Cluster Synchronization Services














Ademas Oracle cuenta con una herramienta de diagnostico para recopilar información del Clusterware para enviar a Oracle posterior a la creación de un Service Request CR.

diagcollecton.sh es un script del CRS que recolecta los logs del CRS del nodo local , es un wrapper sobre el perl diagcollection.pl

Obtiene información sobre:
• Cluster Synchronization Services (CSS)
• Event Manager (EVM)
• Cluster Ready Services (CRS) daemons.

Este log suele ser solicitado por soporte Oracle , El tamaño es bastante grande ( del orden de 1,1 Gb ) 
La forma de uso es muy sencilla,solamente hay que buscarlo bajo el arbol de directorios del GRID.

Linux/UNIX 10gR2/11gR1

1. Execute the following as root user:
# script /tmp/diag.log
# id
# env
# cd <temp-directory-with-plenty-free-space>
# export OCH=<CRS_HOME>
# export ORACLE_HOME=<DB_HOME>
# export HOSTNAME=<host>
# $OCH/bin/diagcollection.pl -crshome=$OCH --collect
# exit

The following .gz files will be generated in the current directory and need to be uploaded along with /tmp/diag.log:   
crsData_<hostname>.tar.gz,
ocrData_<hostname>.tar.gz,
oraData_<hostname>.tar.gz,
coreData_<hostname>.tar.gz (only --core option specified)

miércoles, 28 de diciembre de 2016

Como multiplexar controfile en +ASM

1.- Vemos que el controlfile se encuentra solo en un DIKGROUP del +ASM.









2.- Bajamos la base de datos con srvctl, para el caso de grid infraestructura.

srvctl stop database -a cdr

3.- Nos conectamos con rman, para levantar solo la SGA de la instancia, esto solo si la base de datos es standalone, de lo contrario en Oracle RAC, se debe hacer lo siguiente: srvctl start database -d cdr -o nomount.










4.- Restauramos controlfile desde el origen al destino nuevo (multiplexado).










5.- revisamos en el +ASM, que se halla creado el controfile.











6.- Ahora realizmos alter system set control, abrimos la base de datos con force, y validamos en la vista v$controlfile los control multiplexados.

















lunes, 26 de septiembre de 2016

RE-CREAR TBS UNDOTBS ORACLE RAC

COMO RE-CREAR TABLESPACE UNDOTBS EN ORACLE RAC de 4 nodos:

EL UNDO UNDOTBS4 esta mal construido, se debe re crear con los valores correctos,
este undo pertenece a la instancia 4 del RAC, para esto se debe trabajar en el nodo
4.

AUTOEXTENT de 1024M
MAXSIZE    de 20480M
SIZE       de 1024M

1.- Creamos un UNDO de PASO:
Nos conectamos al nodo 4 del RAC.

CREATE UNDO TABLESPACE UNDOTBS5 DATAFILE '+CROSS_DATA' SIZE 1024M
REUSE AUTOEXTEND ON NEXT 1024M MAXSIZE 20480M;

ALTER system SET undo_tablespace=UNDOTBS5 sid='cross4';


2.- Revisamos si tenemos segmentos de UNDO:

 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 = 'UNDOTBS4'
   );


select owner, segment_name, tablespace_name, status from dba_rollback_segs where tablespace_name='UNDOTBS4' and status='ONLINE';

 alter rollback segment "_SYSSMU31_2521593980$" offline;
 alter rollback segment "_SYSSMU32_1804532818$" offline;       
 alter rollback segment "_SYSSMU33_3611631434$" offline;                      
 alter rollback segment "_SYSSMU34_1975830645$" offline;                      
 alter rollback segment "_SYSSMU35_1514068533$" offline;                      
 alter rollback segment "_SYSSMU36_412588268$ " offline;                      
 alter rollback segment "_SYSSMU37_1727375658$" offline;                      
 alter rollback segment "_SYSSMU38_4056056697$" offline;                      
 alter rollback segment "_SYSSMU39_1922814765$" offline;                      
 alter rollback segment "_SYSSMU40_1873340872$" offline;


REFERENCIA: http://neeraj-dba.blogspot.cl/2011/05/how-to-drop-undo-tablespace.html


3.- Borramos el UNDOTBS4 de paso:

DROP tablespace UNDOTBS4 including contents and datafiles;


4.- Ahora podemos re crear el UNDOTBS4 con la correccion de estructura:


CREATE UNDO TABLESPACE UNDOTBS4 DATAFILE '+CROSS_DATA' SIZE 1024M
REUSE AUTOEXTEND ON NEXT 1024M MAXSIZE 20480M;

ALTER system SET undo_tablespace=UNDOTBS4 sid='cross4';



5.- Ahora borramos el UNDO de PASO. UNDOTBS5


DROP tablespace UNDOTBS5 including contents and datafiles;



jueves, 8 de septiembre de 2016

MIGRACION BLOB


MIGRACION BLOB

Uso de Redefinition:

How to Re-Organize a Table Online (Doc ID 177407.1)

PROPOSITO:

Se deben mover segmentos LOBs desde un DISKGROUP (+MRO_DATA) conformado por discos de 40k,
a un nuevo diskgroup (+MRO_BLOB) con discos SATA VMAX 20k, este diskgroup por 5 discos de 200GB.


La tabla comprometida COR_BLOB_DATA con su campo de tipo BLOB (BLOB_DATA), esta contiene 700GB aprox en segmentos 
de tipo LOB (), esta prueba se realiza en el ambiente MRO rac stress, servidores lstrmrobd01 y lstrmrobd02.



Restrictions
------------
The table to be re-organized:
  * Must have a primary key (restriction should have been lifted in 9.2.0.5. 
    It is possible that there is still a problem with this.)
  * Cannot have User-defined data types
  * Cannot have FILE or LONG columns
  * Cannot be clustered
  * Cannot be in the SYS or SYSTEM schema
  * Cannot have materialized view logs and/or 
                materialized views defined on them
  * Cannot be an horizontal subsetting of data
  * Must be re-organized within the same schema
  * Looses its snapshot logs
  * Can get new columns as part of the re-organization, but the
    new columns must be declared NULL until the re-organization 
    is complete

Proceso
-------

   ------ ------ 5' Table COR_BLOB_DATA_ITERIM se convierte en COR_BLOB_DATA  
   |                       y vice-versa      |
    
   1                                            2
 Source Table           3              Create interim Table 
COR_BLOB_DATA     ---> Start redefinition --->      COR_BLOB_DATA_ITERIM 
               3' data Source to Target   ^      ^          
   ^                                     /       |
   |                                    /        |
   |                                   /         4
   |                                  /    Create constraints 
                                     /     Create indexes
   3''                              /      Create triggers
DML on source table                /
updates/deletes/inserts         5 /Finish redefinition
stored into MLOG$_COR_BLOB_DATA      ------



Step 1: Verificar que la tabla puede ser redefinida online.

Step 2: Crear una tabla de paso vacia con la estructura de la tabla original, aqui
        se puede modificar alguna caracterista en su estructura, por ejemplo advance compress.

Step 3: Comienzo del proceso para redefinir la tabla: 
        dbms_redefinition_start

        Cuando comienza el proceso de redefiniton automaticamente hace esto: 
         
         -> inserts all rows from the source table into the 
            interim table 

         -> crea una tabla snapshot MLOG$_XXX y snapshot log
            almacena los cambios DML temporalmente desde el comienzo al final
            del proceso de redefiniton.


Step 4: Se crean las dependencias de la tabla (constraint, trigger,etc)

Step 5: Fin del proceso de redefinition de la tabla
        dbms_redefinition_finish

        Al terminar el proceso finish_redef_table automaticamente hace esto: 

         -> Aplica todos los cambios DML almacenados en la tabla snapshot dentro de la tabla de paso.

         -> intercambio de nombes entre las 2 tablas, la tabla de paso se
            convierte en la de origen y viceversa.

        NOTA: Hay que tener en cuenta los nombres de constraint e indices no tienen el mismo nombre que antes

Step 6: Borramos la tabla de paso.

Step 7: Para RDBMS version 9.2 hacia delante, las constraints e indices puede ser 
        renombrados con ALTER TABLE ... RENAME CONSTRAINT ... 
   

Para esta actividad:
---------------------------
--> La estructura de la tabla:

    SQL> desc EXMRO.COR_BLOB_DATA
    Name                                  Null?    Type
    ------------------------------------- -------- ---------------
     BLOB_DB_ID                                                    NOT NULL NUMBER(10)
     BLOB_ID                                                           NOT NULL NUMBER(10)
     BLOB_DATA                                                      BLOB
     RSTAT_CD                                                         NUMBER(3)
     CREATION_DT                                                  DATE
     REVISION_DT                                                   DATE
     REVISION_DB_ID                                             NUMBER(10)
     REVISION_USER                                              VARCHAR2(30)
     ORIG_CREATION_DT                                       DATE

--> la tabla contiene 1.031.453 filas antes de la re-organization:

    SQL> select count(*) from EXMRO.COR_BLOB_DATA;

      COUNT(*)
    ----------
        1.031.453
   ----------------------------------------------------------------------------------
1. Vemos si la tabla puede ser redefinida online re-organization 
   -----------------------------------------------------------------------------------
   SQL> connect sys/xxx as sysdba
   Connected.

   SQL> grant execute on dbms_redefinition to test;
   Grant succeeded.

   SQL> connect test/test
   Connected.

   SQL> execute DBMS_REDEFINITION.CAN_REDEF_TABLE('EXMRO','COR_BLOB_DATA_ITERIM');
   PL/SQL procedure successfully completed.


   ------------------------------------------------------------
2. Creamos la tabla de paso con su nueva estructura, apuntando 
   al nuevo tablespace del nuevo diskgroup
   ------------------------------------------------------------
  
   CREATE TABLE EXMRO.COR_BLOB_DATA_ITERIM
   (
     BLOB_DB_ID        NUMBER(10)                  NOT NULL,
     BLOB_ID           NUMBER(10)                  NOT NULL,
     BLOB_DATA         BLOB,
     RSTAT_CD          NUMBER(3),
     CREATION_DT       DATE,
     REVISION_DT       DATE,
     REVISION_DB_ID    NUMBER(10),
     REVISION_USER     VARCHAR2(30 BYTE),
     ORIG_CREATION_DT  DATE                        DEFAULT SYSDATE
   )
   LOB (BLOB_DATA) STORE AS (
     TABLESPACE  EXMRO_BLOB_TEST
     ENABLE      STORAGE IN ROW
     CHUNK       8192
     RETENTION
     NOCACHE
     LOGGING
         STORAGE    (
                     INITIAL          256K
                     NEXT             256K
                     MINEXTENTS       1
                     MAXEXTENTS       UNLIMITED
                     PCTINCREASE      0
                     BUFFER_POOL      DEFAULT
                     FLASH_CACHE      DEFAULT
                     CELL_FLASH_CACHE DEFAULT
                    ))
   TABLESPACE EXMRO
   RESULT_CACHE (MODE DEFAULT)
   PCTUSED    0
   PCTFREE    10
   INITRANS   1
   MAXTRANS   255
   STORAGE    (
               INITIAL          256K
               NEXT             256K
               MAXSIZE          UNLIMITED
               MINEXTENTS       1
               MAXEXTENTS       UNLIMITED
               PCTINCREASE      0
               BUFFER_POOL      DEFAULT
               FLASH_CACHE      DEFAULT
               CELL_FLASH_CACHE DEFAULT
              )
   LOGGING 
   NOCOMPRESS 
   NOCACHE
   NOPARALLEL
   MONITORING;

   ----------------------------------------------------
3. Comienzo proceso de re-organization 
   ----------------------------------------------------

cd /home/oracle/dbacore/bca/lob

nohup ./3.start.sh &

[oracle@lstrmrobd01 lob]$ more 3.start.sh
#!/bin/sh
sqlplus / as sysdba << EOF > ./output.log
set timi on
spool redef.log

BEGIN
DBMS_REDEFINITION.START_REDEF_TABLE
 (uname=>'EXMRO',
 orig_table=>'COR_BLOB_DATA',
 int_table=>'COR_BLOB_DATA_ITERIM',
 options_flag=>DBMS_REDEFINITION.CONS_USE_ROWID);
end;
/
EOF

Si se realiza con un usuario creado para la actividad debe tener los siguientes GRANT:

     * CREATE ANY TABLE 
     * ALTER ANY TABLE 
     * DROP ANY TABLE 
     * LOCK ANY TABLE 
     * SELECT ANY TABLE
     * CREATE ANY INDEX
     * CREATE ANY TRIGGER 


   SQL> select sql_text from v$sqlarea where sql_text like '%ITERIM%';


 Esto hace el redefinition cuando se ejecuta el start_redefinition:


INSERT /*+ BYPASS_RECURSIVE_CHECK APPEND SKIP_UNQ_UNUSABLE_IDX */ INTO "EXMRO"."COR_BLOB_DATA_ITERIM"(M_ROW$$,"BLOB_DB_ID","BLOB_ID","BLOB_DATA","RSTAT_CD","CREATION_DT","REVISION_DT","REVISION_DB_ID","REVISION_USER",
"ORIG_CREATION_DT") SELECT "COR_BLOB_DATA"."ROWID","COR_BLOB_DATA"."BLOB_DB_ID","COR_BLOB_DATA"."BLOB_ID","COR_BLOB_DATA".
"BLOB_DATA","COR_BLOB_DATA"."RSTAT_CD","COR_BLOB_DATA"."CREATION_DT","COR_BLOB_DATA"."REVISION_DT","COR_BLOB_DATA"."
REVISION_DB_ID","COR_BLOB_DATA"."REVISION_USER","COR_BLOB_DATA"."ORIG_CREATION_DT" FROM "EXMRO".
"COR_BLOB_DATA" "COR_BLOB_DATA"


El proceso de redefinition utiliza HINT no documentado (BYPASS_RECURSIVE_CHECK) para forzar el uso del CBO de un EXPLAIN_PLAN correcto, 
que no admita otro camino para el proceso de INSERT y SKIP_UNQ_UNUSABLE_IDX (le dice al optimizador que se salte los indices inutilizables)


   SQL> select master,log_table from dba_mview_logs;

   MASTER                         LOG_TABLE
   ------------------------------ ------------------------------
   COR_BLOB_DATA                  MLOG$_COR_BLOB_DATA


   SQL> select mview_name,container_name, build_mode from dba_mviews;

 MVIEW_NAME                     CONTAINER_NAME                 BUILD_MOD
 ------------------------------ ------------------------------ ---------

 COR_BLOB_DATA_ITERIM           COR_BLOB_DATA_ITERIM           PREBUILT


   -----------------------------------------------------
4. Create constraints on the interim table
   -----------------------------------------------------

   Este punto no aplica.

   ------------------------------------------------------------
5. Simulamos actividad DML en la tabla origen
   -------------------------------------------------------------

   No Aplica

   --------------------------------------------------------------------------------
6. Se puede sincronizar la tabla con las nuevas transacciones
   --------------------------------------------------------------------------------

   BEGIN
   DBMS_REDEFINITION.SYNC_ITERIM_TABLE ('EXMRO, 'COR_BLOB_DATA', 'COR_BLOB_DATA_ITERIM');
   end;
   /

   PL/SQL procedure successfully completed.

   

   --------------------------------------------------------------
7. Previlegios necesarios para la tabla de paso.
   -----------------------------------------------------------------

   SQL> select * from USER_TAB_PRIVS_MADE;


   SQL> grant select, update on COR_BLOB_DATA_ITERIM to test;
   Grant succeeded.

   ---------------------------------------------------
8. Finalizamos porceso de re-organization
   ---------------------------------------------------



    PL/SQL procedure successfully completed.


   ----------------------------------
9. Limpiamos la tabla de paso
   ----------------------------------

    SQL> drop table COR_BLOB_DATA_ITERIM ;
    Table dropped.


    ----------------------------------
10. Renombramos las constraints
    ----------------------------------
Para las versiones RDBMS version 9.2, se puede renombrar las constraints:

Ejemplo:

    SQL> alter table emp rename constraint INT_EMP_PK to EMP_PK ;                        
    Table altered.



Nota
----

En ocasiones es necesario interrumpir el proceso de redefinition, para esto
se usa lo siguiente:


SQL>  execute dbms_redefinition.abort_redef_table('EXMRO','COR_BLOB_DATA','COR_BLOB_DATA_ITERIM');
PL/SQL procedure successfully completed.


11. Para monitorear el proceso de redefinition, consultamos lo siguiente:

[oracle@lstrmrobd01 lob]$ more longops.sql
set linesize 120
col opname format a20
col target format a15
col units format a10
col time_remaining format 99999990 heading Remaining[s]
col bps format 9990.99 heading [Units/s]
col fertig format 90.99 heading "complete[%]"
select sid,
       opname,
       target,
       sofar,
       totalwork,
       units,
       (totalwork-sofar)/time_remaining bps,
       time_remaining,
       sofar/totalwork*100 fertig
from   v$session_longops
where  time_remaining > 0
order by 9
/


SQL> @longops

       SID OPNAME               TARGET               SOFAR  TOTALWORK UNITS      [Units/s] Remaining[s] complete[%]
---------- -------------------- --------------- --------- ---------- ---------- --------- ------------ -----------
      3978 Table Scan           EXMRO.COR_BLOB_DATA  19423      21125 Blocks          0.20         8396       91.94
                                

12. Para optimizar el proceso de redefinition


Unos de los parametros del spfile, PARALLEL_THREADS_PER_CPU = 1
que esta seteado, para poder subir este parametro y ejecutar parallel query, se realizara una prueba
aparte , ademas se investiga este parametro y otros que pudiesen afectar el rendimiento de este proceso.

ALTER SESSION FORCE PARALLEL QUERY;
ALTER SESSION FORCE PARALLEL DML PARALLEL 8;
ALTER SESSION FORCE PARALLEL QUERY PARALLEL 8;


 

jueves, 11 de agosto de 2016

Segmentos LOBs Oracle

INTRODUCCION:

Las pruebas que se realizan en esta entrada son para mover campos LOBs, de una tabla especifica, esto se realiza con 2 metodos y 2 opciones por metodo.

1.- Metodo ALTER TABLE MOVE BLOB

1.1 Mover el campo aplicando securefile

1.2 Mover el campo aplicando basicfile

2.- Metodo DBMS_REDEFINITION

2.1 Mover el campo aplicando securefile

2.2 Mover el campo aplicando basicfile

LOBS se categorizan en CLOB (almacenan texto que contiene grandes cantidades de bytes),

-- NCLOB :(es similar al CLOB solo que almacena texto cuyo juego de caracteres está definido)

-- BLOB :(almacena información multimedia dentro de la base de datos)

-- BFILE :(similar al BLOB solo que la información multimedia está almacenada en el sistema          operativo).


Todo tipo de dato LOB tiene dos partes

a) LOB Value (es el contenido) el cual constituye el valor a almacenar por ejemplo: un texto o contenido multimedia.

b) LOB Locator, es un puntero a la ubicación del valor LOB (LOB Value) que es almacenado en la base de datos.

Si el texto o información multimedia se guarda dentro de la base de datos,
el contenido se almacena en un segmento separado de la tabla. Este segmento es de tipo LOB y almacena solo el LOB Value mientras
la tabla que se definió con él campo LOB solo lleva el LOB Locator como puntero al segmento LOB


Los valores LOB son almacenados out-of-line:

· Cuando se especifica explícitamente con la clausula DISABLE STORAGE IN ROW en la creación de la tabla.

· Cuando el tamaño del LOB es mayor que 3964 bytes (independientemente de las propiedades de la columna)

· Si se actualiza un LOB que está almacenado out-of-line y el LOB resultante es más pequeño de 3964 bytes,
  aún así sigue almacenado como out-of-line.

Los valores LOB son almacenados in-line cuando:

· cuando se crea la tabla no se especifica ningún parámetro en la clausula de almacenamiento del LOB.


· Se especifica explícitamente la clausula ENABLE STORAGE IN ROW cuando se crea la tabla, y el tamaño del LOB almacenado en la fila dada es pequeño,
  4K o menos.

· El valor del LOB es NULL (independientemente de las propiedades de almacenamiento de la columna)


Para este ejemplo moveremos segmentos LOBs de un tablespace a otro, de dos formas (ALTER TABLE MOVE y DBMS_REDEFINITION) y compararemos los beneficios y contra de cada estrategia.

1.- Creamos Una tabla

CREATE TABLE test_blob (
      id           NUMBER(15)
    , username     VARCHAR2(30)
    , file_name    VARCHAR2(1000)
    , image        BLOB
    , timestamp    DATE
)
/

Table created.

2.- Creamos un directoria para dejar un PDF.

CREATE OR REPLACE DIRECTORY DIR_TMP AS '/home/oracle/blob' /

Directory created.

 ktm.pdf

3.- Configuramos el archivo de control de Sqlloader:

oad_test_blob_data.ctl


load data
infile *
replace
into table test_blob

FIELDS TERMINATED BY ','
(
    id                   INTEGER external
  , username       CHAR
  , file_name       CHAR
  , image             LOBFILE(file_name)
                          TERMINATED BY EOF
                          NULLIF file_name='NONE'
  , timestamp            SYSDATE
)
begindata
1,JHUNTER,ktm.pdf

4.-Creamos un Procedimiento almacenado para introducir imagenes guardadas en un directorio y introducidas a un campo de tipo LOB, mediante
Sqlloader

write_blob_to_file.sql



CREATE OR REPLACE PROCEDURE "WRITE_BLOB_TO_FILE" AS

    -- +----------------------------------------------------+
    -- | PROGRAM VARIABLES                                  |
    -- +----------------------------------------------------+
    v_out_outdir          VARCHAR2(2000) := 'EXAMPLE_LOB_DIR';
    v_out_filename        VARCHAR2(500);
    v_out_filename_ext    VARCHAR2(4)    := '.out';
    v_out_filename_full   VARCHAR2(500);
    v_file_count          NUMBER         := 0;
    v_file_handle         UTL_FILE.FILE_TYPE;
 
    -- +----------------------------------------------------+
    -- | DYNAMIC SQL VARIABLES                              |
    -- +----------------------------------------------------+
    TYPE v_lob_cur_typ IS REF CURSOR;
    v_lob_cur             v_lob_cur_typ;
    v_sql_string          VARCHAR2(4000);
 
    -- +----------------------------------------------------+
    -- | BLOB WRITE VARIABLES                               |
    -- +----------------------------------------------------+
    v_blob_loc            BLOB;
    v_buffer              RAW(32767);
    v_buffer_size         CONSTANT BINARY_INTEGER := 32767;
    v_amount              BINARY_INTEGER;
    v_offset              NUMBER(38);
 
    -- +----------------------------------------------------+
    -- | EXCEPTIONS                                         |
    -- +----------------------------------------------------+
    invalid_directory_path EXCEPTION;
    PRAGMA EXCEPTION_INIT(invalid_directory_path, -29280);
 
    table_does_not_exist EXCEPTION;
    PRAGMA EXCEPTION_INIT(table_does_not_exist, -00942);
 
    invalid_identifier EXCEPTION;
    PRAGMA EXCEPTION_INIT(invalid_identifier, -00904);
 
    SQL_cmd_not_prop_ended EXCEPTION;
    PRAGMA EXCEPTION_INIT(SQL_cmd_not_prop_ended, -00933);
 
BEGIN

    -- +----------------------------------------------------+
    -- | ENABLE SERVER-SIDE OUTPUT                          |
    -- +----------------------------------------------------+
    DBMS_OUTPUT.ENABLE(1000000);
 
    v_sql_string := 'SELECT file_name, image FROM test.test_blob';
 
    OPEN v_lob_cur FOR v_sql_string;
 
    LOOP
 
        FETCH v_lob_cur INTO v_out_filename, v_blob_loc;
        EXIT WHEN v_lob_cur%NOTFOUND;
     
        v_file_count := v_file_count + 1;
        v_out_filename_full := v_out_filename || v_out_filename_ext;
     
        v_file_handle := UTL_FILE.FOPEN(v_out_outdir, v_out_filename_full, 'wb', 32767);
     
        v_amount := v_buffer_size;
        v_offset := 1;
     
        DECLARE
            invalid_LOB_locator EXCEPTION;
            PRAGMA EXCEPTION_INIT(invalid_LOB_locator, -06502);
     
        BEGIN
     
            WHILE v_amount >= v_buffer_size
            LOOP
                DBMS_LOB.READ(
                lob_loc    => v_blob_loc,
                amount     => v_amount,
                offset     => v_offset,
                buffer     => v_buffer);
             
                v_offset := v_offset + v_amount;
             
                UTL_FILE.PUT_RAW(
                file      => v_file_handle,
                buffer    => v_buffer,
                autoflush => true);
             
                UTL_FILE.FFLUSH(file => v_file_handle);
            END LOOP;
     
        EXCEPTION
     
            WHEN invalid_LOB_locator THEN
                UTL_FILE.PUT_LINE(file => v_file_handle, buffer => '+----------------------------+');
                UTL_FILE.PUT_LINE(file => v_file_handle, buffer => '|      ***   ERROR   ***     |');
                UTL_FILE.PUT_LINE(file => v_file_handle, buffer => '+----------------------------+');
                UTL_FILE.NEW_LINE(file => v_file_handle);
                UTL_FILE.PUT_LINE(file => v_file_handle, buffer => 'Invalid LOB Locator Exception for :');
                UTL_FILE.PUT_LINE(file => v_file_handle, buffer => '===================================');
                UTL_FILE.PUT_LINE(file => v_file_handle, buffer => '    --> ' || v_out_filename);
                UTL_FILE.NEW_LINE(file => v_file_handle);
                UTL_FILE.PUT_LINE(file => v_file_handle, buffer => 'SQL Text:');
                UTL_FILE.PUT_LINE(file => v_file_handle, buffer => '===================================');
                UTL_FILE.PUT_LINE(file => v_file_handle, buffer => '    --> ' || v_sql_string);
                UTL_FILE.FFLUSH(file => v_file_handle);
         
            WHEN others THEN
                UTL_FILE.PUT_LINE(file => v_file_handle, buffer => '+----------------------------+');
                UTL_FILE.PUT_LINE(file => v_file_handle, buffer => '|      ***   ERROR   ***     |');
                UTL_FILE.PUT_LINE(file => v_file_handle, buffer => '+----------------------------+');
                UTL_FILE.NEW_LINE(file => v_file_handle);
                UTL_FILE.PUT_LINE(file => v_file_handle, buffer => 'WHEN OTHERS ERROR');
                UTL_FILE.PUT_LINE(file => v_file_handle, buffer => '=================');
                UTL_FILE.PUT_LINE(file => v_file_handle, buffer => '    --> SQL CODE          : ' || SQLCODE);
                UTL_FILE.PUT_LINE(file => v_file_handle, buffer => '    --> SQL ERROR MESSAGE : ' || SQLERRM);
                UTL_FILE.FFLUSH(file => v_file_handle);
     
        END;
     
        UTL_FILE.FCLOSE(v_file_handle);

    END LOOP;
 
    CLOSE v_lob_cur;
 
    DBMS_OUTPUT.PUT_LINE('Wrote out ' || v_file_count || ' file(s) to ' || v_out_outdir || '.');

EXCEPTION

    WHEN invalid_directory_path THEN
        DBMS_OUTPUT.PUT_LINE('** ERROR ** : Invalid Directory Path: ' || v_out_outdir);
 
    WHEN table_does_not_exist THEN
        DBMS_OUTPUT.PUT_LINE('** ERROR ** : Table Not Found.');
        DBMS_OUTPUT.PUT_LINE('--> SQL: ' || v_sql_string);
 
    WHEN invalid_identifier THEN
        DBMS_OUTPUT.PUT_LINE('** ERROR ** : Invalid Identifier.');
        DBMS_OUTPUT.PUT_LINE('--> SQL: ' || v_sql_string);
 
    WHEN SQL_cmd_not_prop_ended THEN
        DBMS_OUTPUT.PUT_LINE('** ERROR ** : SQL command not properly ended.');
        DBMS_OUTPUT.PUT_LINE('--> SQL: ' || v_sql_string);

END;
/

SQL> @write_blob_to_file.sql

oracle@lpocrvmax01 [cisco1]$ sqlldr userid=test/test control=load_test_blob_data.ctl log=load_test_blob_data.log

Para sacar el tamaño del segmento LOB:

select segment_name, bytes, bytes/1024/1024 EspacioMB from user_segments where segment_name in ('TEST_BLOB');

Para obtener el scripts de la tabla:

SET LONG 10000
SELECT dbms_metadata.get_ddl('TABLE', 'TEST_BLOB',  'TEST') FROM dual;


Para obtener el tamaño y extensiones asociadas al tablespace:

column segment_name format a30
column tablespace_name format a13
set pagesiz 1000
select segment_name, sum(bytes) BYTES, TABLESPACE_NAME, count(*) EXTENTS
from user_extents
group by segment_name, TABLESPACE_NAME
order by 1;




SEGMENT_NAME                          BYTES     TABLESPACE   EXTENTS
------------------------------ ---------- ------------- ----------
SYS_IL0000091075C00004$$      4194304          TEST_AUTO 19
SYS_LOB0000091075C00004$$      4227858432 TEST_AUTO       246  
TEST_BLOB                                          65536     TEST_AUTO      1



SELECT SUM(bytes)/1024/1024 MB FROM dba_segments
 WHERE (owner = 'TEST' and segment_name = 'SYS_LOB0000091045C00004$$') 
    OR (owner, segment_name) IN (SELECT owner, segment_name FROM dba_lobs WHERE owner = 'TEST' AND table_name = 'TEST_BLOB');

4032 MB


Para obtener contenido del campo LOB:

select DBMS_LOB.SUBSTR(image, 5, 12) from TEST_BLOB;


Para mover el segmento (LOB Segment y Index Segment) debemos ejecutar el siguiente sql:


Aqui movemos los segmentos LOBs, a un nuevo tablespace aplicando la nuevas caracteristicas
de Oracle11g, SECUREFILE (Compression, deduplicacion y encriptacion)

SQL> ALTER TABLE TEST_BLOB MOVE LOB(IMAGE) STORE AS SECUREFILE (TABLESPACE TEST_AUTO_TMP COMPRESS HIGH DEDUPLICATE);

Table altered.


Elapsed: 00:10:17.72


RESULTADO:

SEGMENT_NAME    BYTES TABLESPACE_NA    EXTENTS
------------------------------ ---------- ------------- ----------
SYS_IL0000091075C00004$$    65536 TEST_AUTO_TMP 1
SYS_LOB0000091075C00004$$ 87162880 TEST_AUTO_TMP 14  <<==== (84 EspacioMB)
TEST_BLOB            65536 TEST_AUTO     1


SELECT SUM(bytes) BYTES FROM dba_segments
 WHERE (owner = 'TEST' and segment_name = 'SYS_LOB0000091045C00004$$') 
    OR (owner, segment_name) IN (SELECT owner, segment_name FROM dba_lobs WHERE owner = 'TEST' AND table_name = 'TEST_BLOB');

 83 MB



#######################################################################
Aqui movemos los segmentos LOBs, a un nuevo tablespace , dejando la propiedad basica, BASICFILE.

ALTER TABLE TEST_BLOB MOVE LOB(IMAGE) STORE AS BASICFILE
(TABLESPACE TEST_AUTO);

Nota Metalink: SecureFiles Migration and Accessing securefile metadata information  
[ID 1170351.1]

#######################################################################


ALTER TABLESPACE  TEST_AUTO_TMP ADD DATAFILE '+UCSRAC_DATA/cisco/datafile/test_auto_tmp2' size 4096m;

#######################################################################
AHORA REALIZAMOS LAS PRUEBAS CON DBMS_REDEFINITION
#######################################################################

1.- Sacamos el scrip de la creacion de la tabla:

select dbms_metadata.get_ddl('TABLE', 'TEST_BLOB', 'TEST')


CREATE TABLE "TEST"."TEST_BLOB_ITERIM"
   ( "ID" NUMBER(15,0),
"USERNAME" VARCHAR2(30),
"FILE_NAME" VARCHAR2(1000),
"IMAGE" BLOB,
"TIMESTAMP" DATE
   ) SEGMENT CREATION IMMEDIATE
  PCTFREE 10 PCTUSED 40 INITRANS 1 MAXTRANS 255
 NOCOMPRESS NOLOGGING
  STORAGE(INITIAL 65536 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645
  PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1
  BUFFER_POOL DEFAULT FLASH_CACHE DEFAULT CELL_FLASH_CACHE DEFAULT)
  TABLESPACE "TEST_AUTO"
 LOB ("IMAGE") STORE AS SECUREFILE (COMPRESS HIGH DEDUPLICATE
  TABLESPACE "TEST_AUTO_TMP" ENABLE STORAGE IN ROW CHUNK 8192 RETENTION
  NOCACHE NOLOGGING
  STORAGE(INITIAL 65536 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645
  PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1
  BUFFER_POOL DEFAULT FLASH_CACHE DEFAULT CELL_FLASH_CACHE DEFAULT));

Uso de Redefinition:


How to Re-Organize a Table Online (Doc ID 177407.1)


select bytes/1024/1024 "mb" from dba_segments where segment_name like 'TEST_BLOB' and owner='TEST'


select a.owner, a.table_name, a.column_name, a.segment_name , b.bytes/1024/1024 MB
from dba_lobs a, dba_segments b
where a.segment_name = b.segment_name
and a.owner = b.owner
and a.owner= 'TEST'
and a.table_name='TEST_BLOB'
order by b.bytes/1024/1024;

4032 MB


##############################################################################

GRANT que debe tener el usuario de redefinir:


GRANT CREATE ANY TABLE TO TEST;
GRANT ALTER ANY TABLE TO TEST;
GRANT DROP ANY TABLE TO TEST;
GRANT LOCK ANY TABLE TO TEST;
GRANT SELECT ANY TABLE TO TEST;
GRANT CREATE ANY INDEX TO TEST;
GRANT CREATE ANY TRIGGER TO TEST;

Ver si la tabla puede ser redefinida:

begin
dbms_redefinition.can_redef_table
 (uname=>'TEST',
 tname=>'TEST_BLOB',
 options_flag=>DBMS_REDEFINITION.CONS_USE_ROWID);
end;
/


ALTER SESSION FORCE PARALLEL DML PARALLEL 8;
ALTER SESSION FORCE PARALLEL QUERY PARALLEL 8;


1.- START Redefinition


SQL> set timing on

BEGIN
DBMS_REDEFINITION.START_REDEF_TABLE
 (uname=>'TEST',
 orig_table=>'TEST_BLOB',
 int_table=>'TEST_BLOB_ITERIM',
 options_flag=>DBMS_REDEFINITION.CONS_USE_ROWID);
end;
/SQL> 

PL/SQL procedure successfully completed.

Elapsed: 00:10:24.10



2.- Obtener errores del proceso de redefinition:

set timing off
vari num_errors number

BEGIN
DBMS_REDEFINITION.COPY_TABLE_DEPENDENTS
 (uname=>'TEST',
 orig_table=>'TEST_BLOB',
 int_table=>'TEST_BLOB_ITERIM',
 num_errors=>:num_errors);
END;
/

PL/SQL procedure successfully completed.

SQL> print num_errors
NUM_ERRORS
----------

0


3.- finish_redef_table

begin
dbms_redefinition.finish_redef_table
 (uname=>'TEST',
 orig_table=>'TEST_BLOB',
 int_table=>'TEST_BLOB_ITERIM');
end;
/  

4. Drop table TEST_BLOB_ITERIM


5. Reduccion del tamaño de los segmentos LOBs

SELECT SUM(bytes)/1024/1024 MB FROM dba_segments
WHERE (owner = 'TEST' and segment_name = 'SYS_LOB0000091045C00004$$') 
OR (owner, segment_name) IN (SELECT owner, segment_name FROM dba_lobs
WHERE owner = 'TEST' AND table_name = 'TEST_BLOB');

97 MB


SEGMENT_NAME    BYTES TABLESPACE_NA    EXTENTS
------------------------------ ---------- ------------- ----------
SYS_IL0000091084C00004$$    65536          TEST_AUTO 1
SYS_LOB0000091084C00004$$ 101842944 TEST_AUTO 70
TEST_BLOB                                      65536  TEST_AUTO 1


#################################################################################
Procedimiento sin Advance Compress DBMS_REDEFINITION
#################################################################################


CREATE TABLE "TEST"."TEST_BLOB_ITERIM"
   ( "ID" NUMBER(15,0),
"USERNAME" VARCHAR2(30),
"FILE_NAME" VARCHAR2(1000),
"IMAGE" BLOB,
"TIMESTAMP" DATE
   ) SEGMENT CREATION IMMEDIATE
  PCTFREE 10 PCTUSED 40 INITRANS 1 MAXTRANS 255
 NOCOMPRESS NOLOGGING
  STORAGE(INITIAL 65536 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645
  PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1
  BUFFER_POOL DEFAULT FLASH_CACHE DEFAULT CELL_FLASH_CACHE DEFAULT)
  TABLESPACE "TEST_AUTO"
 LOB ("IMAGE") STORE AS BASICFILE (
  TABLESPACE "TEST_AUTO_TMP" ENABLE STORAGE IN ROW CHUNK 8192 RETENTION
  NOCACHE NOLOGGING
  STORAGE(INITIAL 65536 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645
  PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1
  BUFFER_POOL DEFAULT FLASH_CACHE DEFAULT CELL_FLASH_CACHE DEFAULT));


SQL> set timing on

BEGIN
DBMS_REDEFINITION.START_REDEF_TABLE
 (uname=>'TEST',
 orig_table=>'TEST_BLOB',
 int_table=>'TEST_BLOB_ITERIM',
 options_flag=>DBMS_REDEFINITION.CONS_USE_ROWID);
end;SQL>

PL/SQL procedure successfully completed.

Elapsed: 00:04:34.45


begin
dbms_redefinition.finish_redef_table
 (uname=>'TEST',
 orig_table=>'TEST_BLOB',
 int_table=>'TEST_BLOB_ITERIM');
end;
/

drop table TEST_BLOB_ITERIM


SEGMENT_NAME    BYTES                 TABLESPACE_NA           EXTENTS
------------------------------ ---------- ------------- ----------
SYS_IL0000091232C00004$$      4194304         TEST_AUTO_TMP 19
SYS_LOB0000091232C00004$$      4228907008 TEST_AUTO_TMP    247
TEST_BLOB                                              65536 TEST_AUTO             1

###############################################################################


SELECT SUM(bytes)/1024/1024 MB FROM dba_segments
 WHERE (owner = 'TEST' and segment_name = 'SYS_LOB0000091045C00004$$')
    OR (owner, segment_name) IN (SELECT owner, segment_name FROM dba_lobs WHERE owner = 'TEST' AND table_name = 'TEST_BLOB');

  4033 MB


#############################################################################
ALTER TABLE MOVE BLOB BASICFILE
#############################################################################

set timing on
ALTER TABLE TEST_BLOB MOVE LOB(IMAGE) STORE AS BASICFILE (TABLESPACE TEST_AUTO_TMP);


CONCLUSION

Las pruebas realizadas sobre el campo LOB, de la tabla TEST_BLOB campo LOB (IMAGE) al cual
cargamos un archivo PDF de 80 MB, 50 veces, generando 4022 MB de segmentos LOB (SYS_LOB0000091045C00004$$), 271 EXTENTS.

En ambos procedimientos de migracion del campo LOB, con alter tables move y dbms_redefinition (con y sin Advance Compress), los tiempos son similares tomando en cuenta el origen del LOB, mismos storage, Luns, velocidad de los discos, etc.


Las ventajas:

Con ALTER no genera redolog
Procedimiento mas simple

Con Redefinition la tabla que Online
se puede cambiar la estructura de la tabla y aplicando nuevas caracterisiticas.


Desventajas:

Con ALTER se deja indisponible la tabla por el tiempo que lleve mover los segmentos LOBs.


Con Redefinition genera redolog
Procedimiento mas complejo.
Se necesita espacio para tabla de paso.


Resultados en tiempo y Espacio:

1) Alter table move LOB SECUREFILE

Elapsed: 00:10:17.72 Con indisponibilidad de la tabla durante este lapso de tiempo.

Space: conserva el mismo tamaño de los segmentos.


2) dbms_redefinition Con SECUREFILE HIGH y DEDUPLICATE


Elapsed: 00:10:24.10 Con downtime 0

Space: Reduccion de EXTENTS de 256 a 70 , con Espacio en MB 100


3) dbms_redefinition Con BASICFILE

Elapsed: 00:04:34.45 Con downtime 0

Space: conserva el mismo tamaño de los segmentos.

4) Alter table move LOB BASICFILE

Elapsed: 00:04:28.92 Con indisponibilidad de la tabla durante este lapso de tiempo.

Space: conserva el mismo tamaño de los segmentos.


martes, 26 de julio de 2016

RMAN-05507

RMAN-05507: standby controlfile checkpoint is more recent than duplication point in time


Al realizar rman duplicate en Oracle 9i (9.2.0.8) para construir una Standby, los pasos a seguir son 
en este orden:


1. create standby controlfile (en la base primaria).

2. se mueve el controlfile standby hacia la base standby.

3. consideramos tener nuestro ambiente standby preparado (path, init.ora, +ASM, variables de ambiente, tnsnames, listener, etc).

4. startup nomount pfile.

5. correr script rman: para este ejemplo lo siguiente:









6. $ sh reco2_arcall.sh






ExplicacionAl ejecutar el script rman, nos muestra este error, el problema es 
que el controlfile standby esta en un punto mas reciente que la duplicacion al dataprotector 
(Respaldo en CINTA).

Para solucionar esto, lo que debemos hacer es re hacer nuevamente el control standby, pero esta vez
hacer unos switch de redolog (alter system switch logfile).

miércoles, 13 de julio de 2016

Liberación de memoria

Cuando tenemos una situación en que el servidor tiene mucha "memoria utilizada", sin embargo están prácticamente todas las aplicaciones abajo, y el kernel no ha liberado esta memoria.


  • esto es aplicable a un kernel sobre la versión 2.6.16



  • antes de ejecutar este comando, realice primero un "sync" para asegurar que todos los objetos en caché sean liberados



  • esto es una operación no-destructiva, los objetos "sucios" (dirty) no son liberables (al igual como trabaja ORACLE con sus componentes de memoria)



Por ejemplo:

 Captura_de_pantalla_2012-07-12_a_la_s__10.20.37.png

Simplemente realizamos:

# sync
# echo 3 > /proc/sys/vm/drop_caches
# echo 0 > /proc/sys/vm/drop_caches 

Y el sistema quedará:

 Captura_de_pantalla_2012-07-12_a_la_s__10.20.48.png

Significados

echo 0 > /proc/sys/vm/drop_caches 
Estado normal (no libera nada)
echo 1 > /proc/sys/vm/drop_caches 
Libera los pagecache
echo 2 > /proc/sys/vm/drop_caches 
Libera dentries e inodos
echo 3 > /proc/sys/vm/drop_caches 
Libera pagecache, dentries e inodos (Libera Todo)

Donde:
pagecache: Memoria caché de la paginación.

dentries: (Directory Entries) Representa la relación de forma estructurada que existe entre directorios-archivos.

inodes: Son nodos índice de archivos y directorios que usa el Sistema de Archivos para administrar las actividades posibles de dichos archivos y directorios guardados en disco o memoria. Contiene la metadata de los archivos y directorios: permisos, tamaño, propietario, última fecha de acceso, creación, modificación, etc…






Memoria RAM Linux

En el caso de Linux, el Sistema Operativo utiliza toda la memoria que no está siendo utilizada con el fin de poder acelerar las lecturas en disco, lo cual es conocido como memoria caché, o buffer. Esta memoria caché es liberada apenas se necesite memoria RAM para algún otro programa, por lo que si bien, no es memoria libre, pasa a serlo apenas se le necesite.

Tener la memoria RAM llena no implica que apenas se tenga que ejecutar algún otro programa, se recurra a la memoria Swap (de intercambio), ya que el Sistema Operativo sólo utilizará la Swap cuando efectivamente no exista físicamente más RAM disponible luego de haber eliminado todos los buffers.

No es de extrañarse entonces que cuando realizamos el comando "free", vemos que la RAM está siendo utilizada casi al 100,  para este ejemplo no esta siendo utilizada el total de la memoria:









En esta captura se puede analizar lo siguiente:

La memoria RAM total del servidor es de 8GB, el cual tiene usado 7.5GB y libres 600 MB,

Pero:
  • En buffer 4 MB
  • RAM Libre 26 MB
  • En cache 6980 MB

Lo cual nos indica que hay casi 7119 MB (libre + buffer + cache) de memoria RAM efectivamente disponibles para utilizar.

Existe un procedimiento para hacer una "liberación" de la memoria que está en buffers y caché, la cual te dejo detallada en el siguiente enlace: https://itlinux.zendesk.com/entries/21684691-liberacion-de-memoria.