miércoles, 11 de noviembre de 2015

Mover una partición de tabla online :: Oracle 12c :: New Feature

Mover una partición de tabla online :: Oracle 12c :: New Feature

Hola gente,

Para los que trabajamos con muchísimos datos, acá les paso otro new feature:
Como mover una partición de tabla online con Oracle 12c.

Primero recuerden para tener particionamiento deben usar la versión Enterprise de Oracle y tener habilitado el particionamiento.... si por ambos tienen que pagar un montón de dinero en sus ambientes productivos, pero vale la pena si manejan millones de millones de registros.

Vamos de una vez al ejemplo:

Imaginemos que tenemos una partición de tabla muy importante para nuestro negocio, muy "hot" y queremos moverla a un dispositivo en el storage mas rápido.

Primero lógicamente creamos el nuevo tablespace en el dispositivo rápido. Pero viene el inconveniente que tenemos la necesidad de mover la partición online dado que NO podemos sacar a los usuarios, ni mucho menos detener la operativa de la empresa. Acá aparece el nuevo feature a salvarnos.

Creamos el tablespace target al cual queremos mover nuestra partición de forma online.

##En mi ambiente de test no tengo FLASH Device ni ASM = (, pero se lo imaginan ni modo.

CREATE TABLESPACE tbs_target DATAFILE
  '/u01/app/oracle/oradata/bdOrcl/pdbdemo/tbs_target01.dbf' 
  SIZE 1M AUTOEXTEND ON NEXT 1M MAXSIZE UNLIMITED
LOGGING
EXTENT MANAGEMENT LOCAL AUTOALLOCATE
BLOCKSIZE 8K
SEGMENT SPACE MANAGEMENT AUTO

FLASHBACK ON;

Creamos una tabla con una partición donde ejecutar nuestra prueba:

CREATE TABLE hr.facturas
(
   fac_numero     NUMBER (10) NOT NULL,
   id_cliente     VARCHAR2 (10) NOT NULL,
   fecha          DATE NOT NULL
)
PARTITION BY RANGE
   (fecha)
   INTERVAL ( NUMTODSINTERVAL (7, 'day') )
   (
      PARTITION
         p_antes_01_JAN_1982
         VALUES LESS THAN (TO_DATE ('01-01-1982', 'dd-mm-yyyy')))

ENABLE ROW MOVEMENT;

Insertamos un poco de registros, en mi caso inserte 2500 registros de la siguiente manera... ojo es data loca.

DECLARE
   V_CONSECUTIVO   NUMBER (5);
   V_FECHA         DATE;
   XY              NUMBER (10);
BEGIN
   V_CONSECUTIVO := 1000;
   V_FECHA := SYSDATE - 12500; -- Antes de 1982, jueguen con las fechas en su carga de datos.

   FOR X IN 1 .. 500
   LOOP
      INSERT INTO HR.FACTURAS (FAC_NUMERO, ID_CLIENTE, FECHA)
           VALUES (V_CONSECUTIVO, V_CONSECUTIVO, V_FECHA);

      V_CONSECUTIVO := V_CONSECUTIVO + 1;
      V_FECHA := V_FECHA + 1;
   END LOOP;

   COMMIT;

END;

Ejecutamos las estadísticas en la tabla:

execute dbms_stats.gather_table_stats('HR','FACTURAS')

Revisamos las particiónes, tablespaces y el numero registros que tengo de la tabla FACTURAS:

SELECT partition_name, num_rows, tablespace_name
  FROM DBA_tab_partitions
 WHERE table_name = 'FACTURAS'

 ORDER BY 2 DESC;


Ojo
Para los que se preguntan en que momento cree las 340 restantes particiones, la respuesta es muy simple... use el feature INTERVAL durante la creación de la tabla, el cual va creando particiones en el momento en que lo necesita, caso contrario tendría que haber creado esa cantidad de particiones de tabla de forma manual o el insert de los nuevos registros que se encuentran fuera del rango daría error.

Ahora si el momento de la verdad, muevo la partición de la tabla de forma ONLINE:

 ALTER TABLE hr.facturas
 MOVE PARTITION p_antes_01_jan_1982 COMPRESS BASIC
 TABLESPACE tbs_target
 UPDATE INDEXES ONLINE;

Revisamos de nuevo las particiones de la tabla:
SELECT partition_name, num_rows, tablespace_name
  FROM DBA_tab_partitions
 WHERE table_name = 'FACTURAS'

 ORDER BY 2 DESC;




Y como pueden notar el tablespace de la partición "P_ANTES_01_JAN_1982" es ahora TBS_TARGET.

Y colorin colorado este cuento se ha acabado.

Suerte a todos,

Miguel Vega