Guía de seguimiento dinámico de Solaris

Capítulo 11 Memorias intermedias y almacenamiento en memoria intermedia

La administración y el almacenamiento en memoria intermedia de los datos supone un servicio fundamental proporcionado por la estructura de DTrace para sus clientes, como dtrace(1M). En este capítulo, se examina detalladamente el almacenamiento en memoria intermedia de los datos y se describen las opciones que puede utilizar para cambiar las directivas de administración de la memoria intermedia de DTrace.

Memorias intermedias principales

La memoria intermedia principal está presente en cada llamada de Dtrace y es en la que las acciones de seguimiento registran sus datos de forma predeterminada. Entre estas acciones, se incluyen:

exit()

printf()

trace()

ustack()

printa()

stack()

tracemem()

 

Las memorias intermedias principales siempre se asignan por CPU. Esta directiva no se puede ajustar, aunque la asignación de seguimiento y de memoria intermedia puede restringirse a una única CPU mediante la opción cpu.

Directivas de memorias intermedias principales

DTrace permite realizar un seguimiento en contextos altamente limitados en el núcleo. En concreto, DTrace permite realizar un seguimiento en contextos en los que es posible que el software del núcleo no pueda asignar memoria de forma fiable. A consecuencia de esta flexibilidad de contexto, siempre existe la posibilidad de que DTrace intente realizar un seguimiento de los datos cuando no haya espacio disponible. DTrace debe disponer de una directiva para afrontar estas situaciones cuando surjan, aunque es posible que desee ajustar la directiva en función de las necesidades de un determinado experimento. A veces, la directiva adecuada puede consistir en descartar los nuevos datos. Otras veces, es posible que sea recomendable utilizar el espacio que contiene los datos registrados más antiguos para realizar un seguimiento de los nuevos datos. Lo más frecuente es que la directiva deseada consista en reducir al mínimo las probabilidades de que se agote, en primer lugar, el espacio disponible en disco. Para adaptarse a estas exigencias cambiantes, DTrace admite varias directivas de memorias intermedias diferentes. Esta compatibilidad se implementa con la opción bufpolicy y puede establecerse por consumidor. Consulte el Capítulo 16Opciones y optimizables para obtener más información sobre cómo establecer las opciones.

Directiva switch

La memoria intermedia principal presenta de forma predeterminada una directiva de memoria intermedia switch. Con esta directiva, las memorias intermedias se asignan en pares por CPU: una memoria intermedia está activa, mientras que la otra está inactiva. Cuando un consumidor de DTrace intenta leer una memoria intermedia, el núcleo conmuta primero entre las memorias intermedias inactivas y activas. La conmutación de memorias intermedias se realiza de tal forma que no haya ninguna ventana en la que puedan perderse los datos del seguimiento. Una vez conmutadas las memorias intermedias, la memoria intermedia que se ha establecido como inactiva recientemente se copia en el consumidor de DTrace. Esta directiva garantiza que el consumidor siempre verá una memoria intermedia consecuente consigo misma: nunca se copia y se realiza un seguimiento de una memoria intermedia simultáneamente. Esta técnica también evita que se introduzca una ventana en la que se pause el seguimiento o, por el contrario, se impida. El consumidor controla la velocidad con la que la memoria intermedia se conmuta y se lee gracias a la opción switchrate. Al igual que con cualquier opción de velocidad, switchrate puede especificarse con cualquier sufijo de tiempo, aunque se establece de forma predeterminada en velocidad por segundo. Para obtener más información sobre switchrate y otras opciones, consulte el Capítulo 16Opciones y optimizables.


Nota –

Para procesar la memoria intermedia principal en el nivel del usuario con una velocidad superior a la predeterminada de una por segundo, ajuste el valor de switchrate. El sistema procesa las acciones que inducen la actividad del usuario (como printa() y system()) cuando se procesa el registro correspondiente en la memoria intermedia principal. El valor de switchrate indica la velocidad con la que el sistema procesará dichas acciones.


Con la directiva switch, si un determinado sondeo habilitado realiza un seguimiento de una cantidad de datos superior al espacio disponible en la memoria intermedia principal activa, los datos se anulan y se incrementa un recuento de anulación por CPU. En el caso de que se produzcan una o varias anulaciones, dtrace(1M) muestra un mensaje similar al siguiente:


dtrace: 11 drops on CPU 0

Si el tamaño de un determinado registro es superior al tamaño total de memoria intermedia, el registro se anulará independientemente de la directiva de memoria intermedia. Puede reducir o eliminar las anulaciones aumentando el tamaño de la memoria intermedia principal con la opción bufsize o aumentando la velocidad de conmutación con la opción switchrate.

Con la directiva switch, el espacio temporal de copyin(), copyinstr() y alloca() se asigna fuera de la memoria intermedia activa.

Directiva fill

Es posible que desee utilizar una única memoria intermedia del núcleo para solucionar algunos problemas. Aunque este enfoque puede implementarse con la directiva switch y las construcciones del lenguaje D adecuadas mediante el aumento de una variable en D y la utilización de la acción exit() como predicado, esta implementación no impide la posibilidad de que se produzcan anulaciones. Para solicitar una única memoria intermedia de gran tamaño en el núcleo y continuar con el seguimiento hasta que se rellenen una o más memorias intermedias por CPU, utilice la directiva de memoria intermedia fill. Con esta directiva, el seguimiento continúa hasta que un sondeo habilitado intente realizar un seguimiento de una cantidad de datos superior a los datos que caben en el espacio restante de la memoria intermedia principal. Si persiste la ausencia de espacio disponible, la memoria intermedia se marca como llena y se le notifica al consumidor que se ha rellenado, al menos, una de sus memorias intermedias por CPU. Una vez que dtrace(1M) detecta una única memoria intermedia llena, se detiene el seguimiento, se procesan todas las memorias intermedias y se cierra dtrace. No se realizará ningún seguimiento de ningún dato adicional en la memoria intermedia llena, aunque los datos quepan en la memoria intermedia.

Para utilizar la directiva fill, establezca la opción bufpolicy en fill. Por ejemplo, el siguiente comando realiza un seguimiento de cada entrada de llamada del sistema en una memoria intermedia de 2K por CPU con la directiva de memoria intermedia establecida en fill:


# dtrace -n syscall:::entry -b 2k -x bufpolicy=fill

Directiva fill y sondeos END

Los sondeos END no se activan normalmente hasta que el consumidor de DTrace haya detenido explícitamente el seguimiento. Se garantiza que los sondeos END se activen sólo en una CPU, aunque no se haya definido la CPU en la que se activará el sondeo. Con las memorias intermedias fill, el seguimiento se detiene explícitamente cuando, al menos, una de las memorias intermedias principales por CPU se haya marcado como llena. Si se selecciona la directiva fill, es posible que el sondeo END se active en una CPU con una memoria intermedia llena. Para adaptar el seguimiento de END en las memorias intermedias fill, DTrace calcula la cantidad de espacio consumido potencialmente por los sondeos END y resta este espacio del tamaño total de la memoria intermedia principal. Si el tamaño neto es negativo, DTrace no se iniciará y dtrace(1M) generará una salida con el correspondiente mensaje de error:


dtrace: END enablings exceed size of principal buffer

El mecanismo de reserva garantiza que una memoria intermedia llena tenga siempre suficiente espacio para cualquier sondeo END.

Directiva ring

La directiva de memoria intermedia ring ayuda a realizar un seguimiento de los eventos que han conducido a un fallo. Como la reproducción de un fallo puede llevar horas o días, es posible que desee mantener sólo los datos más recientes. Una vez rellenada la memoria intermedia principal, el seguimiento se ajusta a la primera entrada, sobrescribiendo consiguientemente los datos de seguimiento antiguos. Establezca la memoria intermedia circular definiendo la opción bufpolicy en la cadena ring:


# dtrace -s foo.d -x bufpolicy=ring

Al utilizarlo para crear una memoria intermedia circular, dtrace(1M) no mostrará ningún resultado hasta que finalice el proceso. En ese momento, la memoria intermedia circular se consume y procesa. dtrace procesa cada memoria intermedia circular en el orden de la CPU. En una memoria intermedia de la CPU, los registros de seguimiento se muestran de más antiguo a más reciente. Al igual que con la directiva de memoria intermedia switch, no se realiza ninguna ordenación entre los registros de diferentes CPU. Si esta ordenación es necesaria, debe realizar un seguimiento de la variable timestamp como parte de la solicitud de seguimiento.

En el siguiente ejemplo, se muestra el uso de la directiva #pragma option para habilitar el almacenamiento en memoria intermedia circular:

#pragma D option bufpolicy=ring
#pragma D option bufsize=16k

syscall:::entry
/execname == $1/
{
	trace(timestamp);
}

syscall::rexit:entry
{
	exit(0);
}

Otras memorias intermedias

Hay memorias intermedias principales disponibles cada vez que se habilita DTrace. Además de estas memorias intermedias principales, algunos consumidores de DTrace pueden disponer de memorias intermedias de datos del núcleo adicionales: una memoria intermedia de adición, que se describe en el Capítulo 9Adiciones, y una o varias memorias intermedias especulativas, que se describen en el Capítulo 13Seguimiento especulativo.

Tamaños de memorias intermedias

El tamaño de memoria intermedia puede ajustarse por consumidor. Se proporcionan diferentes opciones para ajustar cada tamaño de memoria intermedia, como se muestra en la siguiente tabla:

Memoria intermedia 

Opción de tamaño 

Principal 

bufsize

Especulativo 

specsize

Adición 

aggsize

Cada una de estas opciones se establece con un valor que indica el tamaño. Al igual que con cualquier opción de tamaño, este valor puede tener un sufijo de tamaño opcional. Consulte el Capítulo 16Opciones y optimizables para obtener más información. Por ejemplo, si desea establecer el tamaño de memoria intermedia en un megabyte en la línea de comandos de dtrace, puede utilizar -x para definir la opción:


# dtrace -P syscall -x bufsize=1m

También puede utilizar la opción -b en dtrace :


# dtrace -P syscall -b 1m

Por último, puede establecer bufsize mediante #pragma D option:

#pragma D option bufsize=1m

El tamaño de memoria intermedia seleccionada indica el tamaño de la misma en cada CPU. Además, para la directiva de memoria intermedia switch, bufsize indica el tamaño de cada memoria intermedia en cada CPU. El tamaño de memoria intermedia se establece de forma predeterminada en 4 megabytes.

Directiva de cambio de tamaño de la memoria intermedia

A veces, es posible que el sistema no disponga de la cantidad adecuada de memoria libre del núcleo para asignar una memoria intermedia del tamaño deseado debido a que no hay suficiente memoria disponible o a que el consumidor de DTrace ha superado uno de los límites descritos en el Capítulo 16Opciones y optimizables. Puede configurar la directiva para el fallo de asignación de la memoria intermedia mediante la opción bufresize, que se establece de forma predeterminada en auto. Con la directiva de cambio de tamaño de la memoria intermedia auto, el tamaño de una memoria intermedia se divide en dos hasta que se realice satisfactoriamente una asignación. dtrace(1M) genera un mensaje cuando la memoria intermedia que se asigna tiene un tamaño inferior al solicitado:


# dtrace -P syscall -b 4g
dtrace: description 'syscall' matched 430 probes
dtrace: buffer size lowered to 128m
...

o:


# dtrace -P syscall'{@a[probefunc] = count()}' -x aggsize=1g
dtrace: description 'syscall' matched 430 probes
dtrace: aggregation size lowered to 128m
...

También puede intervenir manualmente cuando se produzca un fallo de asignación de la memoria intermedia, ajustando bufresize en manual. Con esta directiva, un fallo de asignación provocará que DTrace no pueda iniciarse:


# dtrace -P syscall -x bufsize=1g -x bufresize=manual
dtrace: description 'syscall' matched 430 probes
dtrace: could not enable tracing: Not enough space
#

La opción bufresize determina la directiva de cambio de tamaño de todas las memorias intermedias: principales, especulativas y de adición.