Oracle Database 12c - Nuevas características: Como habilitar el almacenamiento a 32K en los tipos de datos VARCHAR2 , RAW y NVARCHAR2 en DB12c con Windows 7 64bits.

Por Ronald Vargas Quesada
Publicado en Marzo 2014

A partir de Oracle 12c, existen tres tipos de datos que ha sido incrementados en su valor de almacenamiento:

  • VARCHAR2
  • NVARCHAR2
  • RAW

Estos tipos de datos pueden almacenar ahora 32.767 bytes contra 4.000 bytes en la versión 11g.

De facto esta característica no está habilitada. Para poder tener acceso a ella, es necesario configurar el parámetro MAX_STRING_SIZE al valor EXTENDED.

Sin embargo, el procedimiento no es tan sencillo como hacer un simple cambio de parámetro.

El presente artículo, tiene como objetivo guiarte en el proceso.

Cómo habilitamos el almacenamiento a 32K para los tipos de dato VARCHAR2, NVARCHAR2 y RAW.?

  • Paso 1
    • Cambiar el valor del parámetro en el spfile.
SQL>alter system set max_string_size=extended  scope=spfile;
System altered.

Este parámetro no puede ser cambiado dinámicamente. Antes de surtir efecto, debemos reiniciar la base de datos, haciendo también unos cuántos pasos intermedios.

El valor de facto de MAX_STRING_SIZE, como lo mencionamos anteriormente es “STANDARD”

SQL>show  parameter max_string_size
NAME              TYPE        VALUE --------------- ----------- ---------- max_string_size   string      STANDARD

  • Paso 2
    • Bajar la base de datos: Shutdownimmediate
  • Paso 3
    • Levantar la base de datos en modo UPGRADE
  • Paso 4
    • Ejecutar el script rdbms/admin/utl32k.sql connectado como SYS AS DBA a la base de datos
  • Paso 5
    • Levantar la base de datos en modo normal
  • Paso 6
    • Verificar la activación del valor del parámetro

Tomen en cuenta que el nuevo tamaño para estos tipos de datos, no está soportado para tablas organizadas al índice o en cluster.

Vamos a ver el proceso de habilitación completo.

SQL>shutdown  immediate
Database closed. 
Database  dismounted.
ORACLE instance  shut down.
SQL>startup  upgrade 
ORACLE instance  started. 
Total System  Global Area  471830528 bytes 
Fixed Size                 2403976 bytes 
Variable Size              377487736 bytes 
Database Buffers           83886080 bytes 
Redo Buffers               8052736 bytes 
Database mounted. 
Database opened. 


El siguiente paso puede durar algunos minutos.  Antes de ejecutar este proceso, debe verificar que el parámetro COMPATIBLE tenga asignado el valor 12.0.0.0. o superior, de lo contrario podría obtener un error ORA-01722.

Concluido el primer paso del proceso, continuará con la compilación de todos los objetos que hayan quedado inválidos.

Por control de cambios, verifica antes de proceder con la ejecución del script, la existencia de paquetes inválidos, para tener claro, que los mismos estaban previamente en ese estado.

SQL>@?/rdbms/admin/utl32k
Session altered. 
DOC>;################################################################# DOC>;################################################################# DOC>;The following statement will cause an "ORA-01722: invalid number" DOC>;error if the database has not been opened for UPGRADE. DOC>; DOC>;Perform a "SHUTDOWN ABORT"  and DOC>;restart using UPGRADE. DOC>;################################################################# DOC>;################################################################# DOC>no rows selected
DOC>;################################################################# DOC>;################################################################# DOC>The following statement will cause an "ORA-01722: invalid number" DOC>;error if the database does not have compatible >= 12.0.0 DOC>; DOC>;Set compatible >= 12.0.0 and retry. DOC>;################################################################# DOC>;################################################################# DOC>;#
PL/SQL procedure successfully completed.
Session altered. 26 rows updated. Commit complete. System altered. PL/SQL procedure successfully completed. Commit complete. System altered. Session altered. PL/SQL procedure successfully completed. No errors. Session altered.
PL/SQL procedure successfully completed. Commit complete.
Package altered.
TIMESTAMP -------------------------------------------------- COMP_TIMESTAMP UTLRP_BGN  2013-11-19 18:37:02
DOC>;The following PL/SQL block invokes UTL_RECOMP to recompile invalid DOC>;objects in the database. Recompilation time is proportional to the DOC>;number of invalid objects in the database, so this command may take DOC>;a long time to execute on a database with a large number of invalid DOC>;objects. DOC>; DOC>;Use the following queries to track recompilation progress: DOC>; DOC>;1. Query returning the number of invalid objects remaining. This DOC>;number should decrease with time. DOC>;SELECT COUNT(*) FROM obj$ WHERE status IN (4, 5, 6); DOC>; DOC>;2. Query returning the number of objects compiled so far. This number DOC>;should increase with time. DOC>;SELECT COUNT(*) FROM UTL_RECOMP_COMPILED; DOC>; DOC>;This script automatically chooses serial or parallel recompilation DOC>;based on the number of CPUs available (parameter cpu_count) multiplied DOC>;by the number of threads per CPU (parameter parallel_threads_per_cpu). DOC>;On RAC, this number is added across all RAC nodes. DOC>; DOC>;UTL_RECOMP uses DBMS_SCHEDULER to create jobs for parallel DOC>;recompilation. Jobs are created without instance affinity so that they DOC>;can migrate across RAC nodes. Use the following queries to verify DOC>;whether UTL_RECOMP jobs are being created and run correctly: DOC>; DOC>;1. Query showing jobs created by UTL_RECOMP DOC>;SELECT job_name FROM dba_scheduler_jobs DOC>;WHERE job_name like 'UTL_RECOMP_SLAVE_%'; DOC>; DOC>;2. Query showing UTL_RECOMP jobs that are running DOC>;SELECT job_name FROM dba_scheduler_running_jobs DOC>;WHERE job_name like 'UTL_RECOMP_SLAVE_%'; DOC>;#
ERRORS DURING RECOMPILATION --------------------------- 0
Function created. PL/SQL procedure successfully completed.
Function dropped.

A diferencia de las versiones previas de UTLRP, al final este brinda un resumen de lo realizado. Verifica que no existieron errores durante el proceso de compilación.

...Database user  "SYS", database schema "APEX_040200", user# "98"  18:38:58
...Compiled 0 out  of 2998 objects considered, 0 failed compilation 18:38:58
...263 packages
...255 package  bodies
...453 tables
...11 functions
...16 procedures
...3 sequences
...458 triggers
...1322 indexes
...207 views
...0 libraries
...6 types
...0 type bodies
...0 operators
...0 index types
...Begin key  object existence check 18:38:58
...Completed key  object existence check 18:38:58
...Setting DBMS  Registry 18:38:58
...Setting DBMS  Registry Complete 18:38:59
...Exiting  validate 18:38:59 
PL/SQL procedure successfully completed.

Ahora sí, debemos proceder a bajar la base de datos y levantar la misma normalmente.

SQL>;
SQL>shutdown immediate
Database closed.
Database dismounted.
ORACLE instance shut down. 
SQL>startup ORACLE instance started.
Total System Global Area     471830528 bytes Fixed Size              2403976 bytes Variable Size           377487736 bytes Database Buffers             83886080 bytes Redo Buffers            8052736 bytes Database mounted. Database opened.

Verifica el valor del parámetro modificado al inicio de este proceso.

SQL>show parameter max_string_size 
NAME        TYPE        VALUE ----------------- ------------- --------- max_string_size   string EXTENDED

Comprobación de los cambios realizados

Probando la efectividad de los cambios, logré comprobar que el valor aceptado en Windows 7 64bits, con mi versión de base de datos 12c, no es de 32K para todos los tipos.

Para el tipo VARCHAR2, el resultado es correcto.

SQL>create table t2(campo1_grande varchar2(32767));
Table created.

Para el tipo NVARCHAR2 el tamaño máximo permitido fue de 16K.

SQL>create table t1(campo1_grande  nvarchar2(16400));
create table t1(campo1_grande nvarchar2(16400))
*
ERROR at line 1:
ORA-00910:  longitud especificada demasiado larga para este tipo de dato
SQL>createtablet3(campo1_grande nvarchar2(16383)); Tablecreated.

Con el tipo RAW, llegamos sin problemas al límite de los 32K

SQL>create table t4(campo1_grande raw(16383));
Table created.
SQL>create table t6(campo1_grande raw(32787)); create table t6(campo1_grande raw(32787)) * ERROR at line 1: ORA-00910: longitud especificada demasiado larga para este tipo de dato
SQL>create table t6(campo1_grande raw(32767)); Tablecreated.

La combinación de campos, tampoco presentó un problema, siempre y cuando no se exceda el valor límite que hemos mencionado anteriormente.

SQL>createtablet5(campo1_grande  varchar2(32000), campo2_grande nvarchar2(16000));
Tablecreated.

El procedimiento descrito anteriormente, es válido para una instancia NON-CDB y para una instancia PDB que no forme parte de una solución de alta disponibilidad como lo es el RAC. Para realizar estos cambios en una instancia en HA (Alta Disponibilidad - RAC), debes bajar todos los nodos, excepto uno y realizar en este nodo los pasos aquí indicados. Cuando termines, procede a levantar el resto de instancias de manera normal y listo habrás completado el procedimiento.

Bibliografía de referencia:
La documentación completa sobre este parámetro la puede encontrar en el siguiente link:
http://docs.oracle.com/cd/E16655_01/server.121/e17615/refrn10321.htm#REFRN10321



Ronald Vargas (Oracle ACE Director) es Consultor Técnico en Netsoft de Centroamerica, Oracle VAD para Costa Rica, Nicaragua y Guatemala. Ronald tiene más de 20 años involucrado con tecnologías Oracle. Durante su carrera profesional ha laborado para Partners de Oracle como consultor en más de un centenar de proyectos para el sector público y privado en la región LAD. Es instructor de Oracle University y Academy desde el 2000, así como Profesor Universitario en la ULACIT en San José, Costa Rica. Fundador de los OUG de Costa Rica 2010, Guatemala 2011, Panamá 2013, El Salvador 2014. Ronald es el responsable de introducir el OTN TOUR en la región Centroamerica. Editor y Autor del blog Oracledbacr.blogspot.com desde el 2009.