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.