DB2 FOR Z/OS PCTFREE FOR UPDATE FOR PERFORMANCE

Nota del editor: Este artículo fue publicado originalmente en inglés. Con la aprobación del autor, el equipo de IDUG ha creado la traducción que a continuación se presenta.

 

El contenido de este artículo es de aplicación Db2 12 for z/OS y Universal Table Spaces (UTS)

Es responsabilidad del lector la interpretación y aplicación de dicho contenido a versiones previas de Db2 for z/OS y otros tipos de espacios para tablas.

 

Existen muchas opciones a la hora de diseñar los tablespaces y tablas para ciertas situaciones. Uno de los aspectos a tener en cuenta es cuánto espacio libre se reservará para los INSERTs y UPDATEs posteriores. Uno debe considerar cuidadosamente aspectos como el uso que la aplicación hará de la tabla (clustering de índices, lectura o actualización, acceso directo secuencial a la información). En este artículo, consideraremos uno de los muchas posibles consideraciones de diseño: le espacio libre reservado para UPDATEs.

 

Existen cuatro definiciones a nivel de tablespace que determinan como el espacio libre es asignado y gestionado por Db2 for z/OS:

 

FREEPAGE

FREEPAGE indica con qué frecuencia Db2 reserva una página vacía durante los procesos de carga o reorganización de un tablespace o una partición de un tablespace. El valor por defecto es 0, y debería ser 0 para casi  todos los tablespaces y particiones. La única vez que un valor mayor de 0 debería ser considerado es cuando el valor especificado para PCTFREE no se muestra efectivo. En estas situaciones, FREEPAGE sería utilizado como un sustituto de PCTFREE cuando se desea mantener un espacio libre para conservar el “clustering” de la tabla. Puesto que los tamaños de página disponibles en Db2 for z/OS son 4K, 8K, 16K y 32K, existe una gran flexibilidad para acomodar tamaños de fila mayores en páginas mayores. Por lo tanto, la utilización de FREEPAGE en un tablespace o partición está sólo reservada para esas raras ocasiones.

 

PCTFREE

PCTFREE indica el porcentaje de espacio libre a reservar en cada página durante los procesos de carga o reorganización de un tablespace o partición. De este modo se reserva espacio libre en cada página para las nuevas filas (INSERTs) o posibles cambios en el tamño de filas ya existentes (UPDATEs). El propósito principal que se persigue es de mantener la secuencia de clustering (mantener las filas de la tabla en un orden específico basado en los valores existentes en la fila y que están soportados por un índice cuya clave son dichos valores) siempre que dicho orden de clustering sea importante en el proceso que la aplicación haga de la información de la tabla. Hay muchas razones para mantener la secuencia de clustering que serán tratadas como tema de blog en el futuro.

 

PCTFREE FOR UPDATE

Este parámetro en la definición del tablespace fue introducido silenciosamente en Db2 11 for z/OS, y aunque ha sido promocionado en presentaciones, artículos y manuales, fue ignorado por el típico Db2 DBA que copiaba rutinariamente viejos DDLs para crear nuevos tablespaces y tablas. Lo que PCTFREE FOR UPDATE hace es reservar un porcentaje de espacio libre en cada página de datos Db2 para futuras sentencias UPDATE. Asi pues, durante los procesos de carga o reorganización de un tablespace o partición, Db2 reservará dicho espacio libre. Además, sentencias INSERT y utilidades que añadan información no utilizarán este espacio libre. Ese ese espacio libre reservado en la página de datos Db2 será sólo utilizado por sentencias UPDATE, y por nada más.

Es efectivo inmediatamente el CREATE o ALTER del tableapace o partición ha sido ejecutado. Si existen valores para PCTFREE y para FOR UPDATE, el total de espacio libre reservado es la combinación de ambos porcentajes. Así, PCTFREE 10 FOR UPDATE 10 indica que un total de 20% de espacio libre se reserva en cada página de datos Db2 durante LOAD y REORG, y que un 10% de dicho espacio libre estará reservado para futuras sentencias UPDATE.

Hay un parámetro de instalación PCTFREE_UPD que dicta la configuración predeterminada de PCTFREE FOR UPDATE para espacios de tablas en todo el sistema. Además, establecer PCTFREE FOR UPDATE en -1 le dice a Db2 que administre esta configuración dinámicamente usando estadísticas en tiempo real.

 

 MAXROWS

MAXROWS especifica el número máximo de filas permitidas por página de datos Db2. Esta configuración ha estado disponible durante mucho tiempo, pero los DBA realmente no la utilizaron para administrar el espacio libre para las actualizaciones.

Se usó principalmente como una configuración de concurrencia para tablas pequeñas pero altamente actualizadas a través de MAXROWS 1, que reservó una página por fila. Esta técnica se ha reemplazado principalmente con el bloqueo de nivel de fila (LOCKSIZE ROW) en estas muy específicas situaciones.

 

 

La necesidad de PCTFREE FOR UPDATE

En un sentido tradicional, Db2 para z/OS realiza una actualización de una fila Db2 en el mismo lugar que la fila está ocupando. Es decir, una fila de datos que se cambia a través de una instrucción UPDATE se devuelve a la misma página de datos Db2 y en la misma ubicación en que se recuperó. Esto es bueno porque el ID de registro (RID) de la fila está incluído en cada índice definido sobre la tabla, y cambiar esas valores del RID en las entradas de cada índice podría aumentar el costo y la concurrencia de la instrucción UPDATE.

El RID presente en un índice es básicamente un apuntador a una fila de datos en una tabla; consta de un número de página y un número de registro. No incluye la ubicación física real de una fila en una página de datos Db2. El valor del RID en un índice  apunta específicamente a un map-ID en la página de datos. Por lo tanto, una fila puede reubicarse dentro de la misma página de datos Db2 sin que el valor del RID cambie;  pero si esa fila se reubicara en otra página de datos Db2, habría que actualizar el valor del RID también y por lo tanto cada uno de las entradas de índices con ese valor de RID.

Todo esto funciona muy bien cuando el tamaño de la fila es una longitud fija, pero cuando se introducen campos de longitud variable o se utiliza la compresión de la fila, las cosas se vuelven un poco más complicadas. Si una actualización hace que una fila aumente de longitud, es posible que no quepa en la misma ubicación de en la página de datos Db2 de la que proviene. Ahora, es importante señalar nuevamente que un RID no apunta específicamente a una fila de datos.

Lo que realmente apunta el RID es una map-ID, que es un campo fijo ubicado al final de la página de datos Db2. Es el map-ID el  que apunta a la dirección física real de la fila en la página de datos. Esto le da a Db2 la oportunidad de mover la fila a otra posición en la página de datos sin afectar el valor de RID. Si Db2 puede encontrar una cantidad contigua de espacio libre en la página para la fila expandida, la moverá allí y actualizará el map-ID correspondiente.

Si no se encuentra espacio libre contiguo en la página de datos, entonces Db2 podría intentar la compactación de la página, donde intenta mezclar filas de datos de tal manera que los "agujeros" más pequeños de espacio libre se puedan combinar en una cantidad contigua más grande en la que la fila puede caber. En última instancia, si todos los intentos de colocar la fila expandida en la página de datos de la que proviene falla, Db2 tiene que ubicar la fila en una página de datos diferente. Realiza una búsqueda de espacio disponible en una página diferente, y cuando se encuentra inserta la fila en esa página y luego regresa a la página original para colocar un puntero a la nueva ubicación de la fila donde existía la imagen de la fila anterior. Esto se llama reubicación de fila, y la reubicación resultante se identifica como una referencia indirecta.

Las referencias indirectas en pequeñas cantidades pueden no ser algo malo, pero si suceden con demasiada frecuencia puede ocasionar problemas graves de rendimiento. Muchas referencias indirectas pueden hacer que las lecturas aleatorias tengan que leer páginas adicionales de datos, ya que cuando siguen un RID a una fila, dicha fila puede ser, en realidad, un puntero a una fila reubicada. También puede causar una degradación del rendimiento de los lectores secuenciales si muchas filas reubicadas obligan a que los datos no estén agrupados (significativamente fuera de secuencia). Si hay muchas referencias indirectas y se ejecuta una utilidad RUNSTATS, eso puede afectar el clusterratio y, posteriormente, afectar los accesspath a los datos. Para las operaciones de actualización que sufren muchas reubicaciones de filas debido a la expansión de filas, el impacto en el rendimiento puede ser especialmente significativo, y esto podría agravarse aún más en un entorno data-sharing. Es un tema complicado, pero si un conjunto de páginas (partición) es dependientegrupo del bufferpool del grupo datasharing, cada compactación de página o reubicación de fila podría implicar una escritura síncrona de la ´pagina de datos a disco, así como una escritura de registro de log síncrona también. En estas situaciones, los procesos de actualización que tardan minutos pueden convertirse rápidamente en horas y en un grave problema de rendimiento.

Si bien el remedio para las reubicaciones de filas es un REORG tablespace o partición, los procesos REORG en estos tiempos de total disponibilidad de aplicación son cada vez más difíciles de programar y ejecutar. La solución definitiva es mitigar la necesidad de un REORG configurando correctamente el espacio libre, incluido PCTFREE FOR UPDATE cuando sea posible. Esto ayudará a reducir la reubicación de las filas en aquellas situaciones en las que tenga una combinación de nuevas inserciones en orden y actualizaciones pesadas que resulten en un aumento de la longitud de las filas.

 

Monitorización y configuración de valores de espacio libre

Existen algunas herramientas que se pueden utilizar para monitorizar adecuadamente las asignaciones de espacio libre así como la necesidad de un proceso REORG que reclame dicha asignación de espacio libre. Las tablas de estadísticas en tiempo real de Db2 son probablemente la más fácil e importante de estas herramientas.

Se puede utilizar una sencilla consulta contra la tabla del catálogo del sistema SYSIBM.SYSTABLESPACESTATS para ver cuántas reubicaciones de fila se han producido desde que se ejecutó la utilidad LOAD REPLACE o REORG en una partición de un tablespace, o cuando la partición se creó originalmente. Las columnas que contabilizan estas reubicaciones de filas son REORGNEARINDREF y REORGFARINDREF, y se pueden usar en combinación con otras columnas en SYSIBM.SYSTABLESPACESTATS para determinar si se necesita un REORG, pero también si se necesita un ajuste para PCTFREE FOR UPDATE.

Yo utilizo una fórmula simple de referencias indirectas totales, divididas por el número total de filas en la partición, según (((TBSP.REORGNEARINDREF + TBSP.REORGFARINDREF) * 100) /TBSP.TOTALROWS).

Si el porcentaje resultante es mayor que 5, eso me dice que la partición está lista para ejecutar un proceso REORG que reclame el espacio libre. Si esto sucede con demasiada frecuencia, incluso cuando se reorganiza con frecuencia, entonces es hora de considerar incrementar el valor del PCTFREE FOR UPDATE antes del siguiente proceso REORG..

Otra forma de monitorizar la necesidad de espacio libre para actualizaciones es comprobar el valor presente en la columna PCTFREE_UPD_CALC en la tabla del catálogo del sistema SYSIBM.SYSTABLEPART. Este es el espacio libre para actualizaciones que el propio Db2 o las utilidades calculan. Aún cuando no permita que Db2 controle mi espacio libre para actualizaciones, Db2 mantiene este valor para todas las particiones de espacio de tabla, independientemente de si PCTFREE FOR UPDATE está, o no, configurado en -1 (dejar que Db2 controle). No encuentro este valor significativamente útil porque he visto porcentajes tan altos como 99%. También lo he visto con valor 0...¡aunque la partición necesita realmente un valor distinto de 0! No obstante, el valor de la columna PCTFREE_UPD_CALC lo utilizo como una indicación de que la partición puede necesitar espacio libre para actualizaciones. Siempre que el valor sea mayor que cero, pongo atención sobre la partición como candidato para una revisión del valor de PCTFREE FOR UPDATE..

Una herramienta extremadamente valiosa al evaluar el desempeño es el informe SMF de accounting. Recomiendo ejecutar un informe SMF de accounting para una aplicación de actualización importante, inmediatamente después de un REORG. De esa manera hay una línea de base del rendimiento de la aplicación de actualización. Cuando se ejecutan informes de contabilidad SMF posteriores para una carga de trabajo similar que muestra un aumento marcado en la actividad de la actividad de bufferpools, escrituras de log  y las I/O síncronas, pueden indicar que se precisa espacio libre para las actualizaciones. No obstante, esa mayor actividad puede indicar otros problemas; pero la supervisión cuidadosa del PCT_UPD_CALC desde SYSIBM.SYSTABLEPART y las referencias indirectas en SYSIBM.SYSTABLESPACESTATS se pueden utilizar para correlacionar un problema de rendimiento en una aplicación con la necesidad de espacio libre para las actualizaciones.

Cuando calculo qué espacio libre para actualizaciones para un espacio de tabla o partición en particular es necesario, hago un análisis observando la longitud promedio de fila, las reubicaciones de fila y la configuración actual de espacio libre; a partir de dichos valores trato de obtener nuevas configuraciones de espacios libres. Intento promediar  las inserciones y modificaciones en la tabla durante un período de tiempo proyectado. Las dos consultas siguientes son un punto de partida. La primera consulta analiza la configuración actual.

 

select TSNAME, PARTITION, PCTFREE, FREEPAGE, PCTFREE_UPD, PCTFREE_UPD_CALC
  from sysibm.systablepart ts
 where ts.dbname = ”
   and TS.TSNAME IN (‘<table space name’)
 order BY TSNAME, PARTITION;

 

Esta otra consulta calcula cuántas filas caben en el espacio libre, pero sacrifica alguna precisión si los valores de espacio libre son diferentes en cada partición.

select TSNAME, avg(AVGROWLEN) AVGROWLEN,
       int(((max(dec(pctfree,5,2)/100)*4096) – 40)/avg(AVGROWLEN + 2)) as rows_in_free,
       max(pctfree) pctfree,
       max(pctfree_upd) pctfree_upd, avg(pctfree_upd_calc) pctfree_upd_calc
  from SYSIBM.SYSTABLEPART
 where DBNAME = ”
 group by TSNAME;

 

Luego miro SYSTABLESPACESTATS para los valores de las columnas REORGINSERTS, REORGDELETES, REORGUPDATES, REORGUNCLUSTINS, REORGNEARINDREF, REORGFARINDREF para emitir un juicio sobre si favorecer las inserciones, las  modificaciones, o ambos. Me concentro en el rendimiento general, también teniendo en cuenta el valor de clustering y el posible desvío de datos, si corresponde. Entonces, en lugar de establecer un valor de PCTFREE grande, trato de equilibrar PCTFREE y PCTFREE FOR UPDATE.

¡Todo esto realmente ha valido la pena con mejores tiempos de ejecución de aplicaciones y procesos REORGs menos frecuentes!

¡Salud!

Recent Stories
DB2 FOR Z/OS PCTFREE FOR UPDATE FOR PERFORMANCE

IBM DB2 EN LA NUBE DE AMAZON AWS

JSON SQL APIs en Db2 para z/OS y servicios nativos REST