sql >> Base de Datos >  >> RDS >> Database

Estadísticas de espera instintivas:SOS_SCHEDULER_YIELD

En mi publicación anterior, hablé de las esperas LCK_M_XX, ASYNC_NETWORK_IO y OLEDB y las reacciones instintivas a ellas. En esta publicación, continuaré con el tema de las estadísticas de espera y discutiré la espera SOS_SCHEDULER_YIELD.

Cuando SOS_SCHEDULER_YIELD es el más frecuente en un servidor, es común ver un uso elevado y sostenido de la CPU. La reacción instintiva aquí es que el servidor debe estar bajo presión de la CPU, o que el problema es un spinlock.

Necesitamos un poco de contexto aquí para entender estas dos reacciones.

Programación de subprocesos

La programación de subprocesos en SQL Server es administrada por el propio SQL Server, no por Windows (es decir, no es preventiva). La parte del sistema operativo SQL del motor de almacenamiento proporciona la funcionalidad de programación y la transición de subprocesos de ejecutarse en un procesador (donde el estado del subproceso es EN EJECUCIÓN) a estar en la lista de espera esperando que un recurso esté disponible (el estado es SUSPENDIDO) a estar en Runnable Haga cola una vez que el recurso esté disponible (el estado es EJECUTABLE) esperando llegar al principio de la cola y volver al procesador nuevamente (de nuevo al estado EN EJECUCIÓN). He escrito con mayúscula Procesador, Lista de espera y Cola ejecutable para identificarlos como partes de un programador.

Cada vez que un subproceso necesita un recurso que no puede adquirir de inmediato, se suspende y espera en la Lista de espera para que se le informe (señale) que su recurso está disponible. El tiempo pasado en la lista de espera es el tiempo de espera del recurso y el tiempo pasado en la cola ejecutable es el tiempo de espera de la señal. Juntos se combinan para ser el tiempo de espera total. SQL OS realiza un seguimiento del tiempo de espera y el tiempo de espera de la señal, por lo que tenemos que hacer algunos cálculos en la salida de sys.dm_os_wait_stats para derivar el tiempo de espera del recurso (consulte mi secuencia de comandos aquí).

La Lista de espera no está ordenada (cualquier subproceso en ella se puede señalar en cualquier momento y pasar a la Cola ejecutable) y la Cola ejecutable es Primero en entrar, primero en salir (FIFO) casi el 100% del tiempo. La única excepción a que la cola ejecutable sea FIFO es cuando se han configurado varios grupos de cargas de trabajo del regulador de recursos en el mismo grupo de recursos y tienen diferentes prioridades entre sí. Nunca he visto que esto se use con éxito en producción, así que no lo discutiré más.

Hay otra razón por la que un subproceso puede necesitar salir del procesador:agota su cantidad. La cantidad de subprocesos en SQL OS se fija en 4 milisegundos. El subproceso en sí es responsable de determinar que su cantidad se ha agotado (llamando a las rutinas auxiliares en el sistema operativo SQL) y renunciando voluntariamente al procesador (lo que se conoce como rendimiento). Cuando esto ocurre, el subproceso se mueve directamente al final de la cola ejecutable, ya que no hay nada que esperar. Sin embargo, SQL OS debe registrar un tipo de espera para esta transición fuera del procesador y registra SOS_SCHEDULER_YIELD.

Este comportamiento a menudo se confunde con la presión de la CPU, pero no lo es, es solo un uso sostenido de la CPU. La presión de la CPU, y reconocerla, es un tema completamente diferente para una publicación futura. En lo que respecta a esta publicación, siempre que el tiempo de espera promedio de la señal sea bajo (0-0.1-0.2ms), es bastante seguro que la presión de la CPU no sea un problema.

Spinlocks

Un spinlock es una primitiva de sincronización de muy bajo nivel que se usa para proporcionar acceso seguro para subprocesos a estructuras de datos en SQL Server que son extremadamente calientes (muy volátiles y accedidas y modificadas con una frecuencia increíble por múltiples subprocesos). Ejemplos de tales estructuras son la lista libre de búfer en cada parte del grupo de búfer y la matriz de ponderaciones de relleno proporcional para los archivos de datos en un grupo de archivos.

Cuando un subproceso necesita adquirir un spinlock, busca ver si el spinlock está libre y, de ser así, lo adquiere de inmediato (usando una primitiva de lenguaje ensamblador entrelazada como 'test bit clear and set'). Si no se puede adquirir el spinlock, el subproceso inmediatamente intenta adquirirlo una y otra y otra vez, hasta mil iteraciones, hasta que retrocede (duerme un poco). Esto no se registra como ningún tipo de espera, ya que el subproceso simplemente llama a la función sleep() de Windows, pero puede hacer que otros subprocesos que están esperando tengan tiempos de espera de señal grandes (10-20ms+) ya que el subproceso inactivo permanece en el procesador hasta que obtiene el spinlock.

¿Por qué estoy hablando de spinlocks? Porque también pueden ser la causa de un alto uso de la CPU, y existe la idea errónea de que los spinlocks son la causa de las esperas SOS_SCHEDULER_YIELD. No lo son.

SOS_SCHEDULER_YIELD Causas

Entonces, hay una causa para SOS_SCHEDULER_YIELD:un subproceso que agota su cantidad de programación y las instancias muy recurrentes pueden hacer que SOS_SCHEDULER_YIELD sea la espera más frecuente junto con un alto uso de la CPU.

No verá las esperas SOS_SCHEDULER_YIELD en el resultado de sys.dm_os_waiting_tasks, ya que el subproceso no está esperando. Puede ver qué consulta está generando las esperas SOS_SCHEDULER_YIELD consultando sys.dm_exec_requests y filtrando en la columna last_wait_type.

Esto también significa que cuando vea SOS_SCHEDULER_YIELD en la salida de sys.dm_os_wait_stats, la espera del recurso será cero, porque en realidad no esperó. Pero recuerde que cada una de estas 'esperas' equivale a 4 ms de tiempo de CPU acumulado para la consulta.

La única forma de probar qué está causando las esperas SOS_SCHEDULER_YIELD es capturar las pilas de llamadas de SQL Server cuando se produce ese tipo de espera, utilizando eventos extendidos y símbolos de depuración de Microsoft. Tengo una publicación de blog que describe y muestra cómo realizar esa investigación, y hay un excelente documento técnico sobre spinlocks e investigaciones de spinlock que vale la pena leer si está interesado en esa profundidad de los aspectos internos.

Para el caso del agotamiento cuántico, esa no es la causa principal. Es un síntoma más. Ahora debemos considerar por qué un subproceso puede estar agotando su cantidad repetidamente.

Un subproceso solo puede agotar su cantidad cuando puede continuar procesando el código de SQL Server durante 4 ms sin necesidad de un recurso que sea propiedad de otro subproceso:sin esperar bloqueos, pestillos de página, páginas de archivos de datos para leer desde el disco, asignaciones de memoria, crecimiento de archivos, registro , o la miríada de otros recursos que un subproceso podría necesitar.

La pieza de código más común donde puede ocurrir el agotamiento cuántico y acumular grandes cantidades de esperas SOS_SCHEDULER_YIELD es escanear un índice/tabla donde todas las páginas de archivos de datos necesarios están en la memoria y no hay competencia para acceder a esas páginas, y eso es lo que Lo animo a que busque en los planes de consulta cuando vea SOS_SCHEDULER_YIELD como el tipo de espera principal:escaneos de tabla/índice grandes y/o repetidos.

Esto no significa que esté diciendo que los escaneos grandes son malos, ya que podría ser que la forma más eficiente de procesar su carga de trabajo sea a través de un escaneo. Sin embargo, si las esperas de SOS_SCHEDULER_YIELD son nuevas e inusuales, y son causadas por escaneos grandes, debe investigar por qué los planes de consulta usan escaneos. Tal vez alguien eliminó un índice crítico no agrupado, o las estadísticas están desactualizadas y, por lo tanto, se eligió un plan de consulta incorrecto, o tal vez se pasó un valor de parámetro inusual a un procedimiento almacenado y el plan de consulta solicitó un escaneo o un cambio de código. ocurrió sin adiciones de índice compatibles.

Resumen

Al igual que con otros tipos de espera, comprender exactamente lo que significa SOS_SCHEDULER_YIELD es clave para comprender cómo solucionarlo y si el comportamiento es el esperado debido a la carga de trabajo que se está procesando.

En lo que respecta a las estadísticas generales de espera, puede encontrar más información sobre cómo usarlas para solucionar problemas de rendimiento en:

  • La serie de publicaciones de mi blog SQLskills, que comienza con las estadísticas de espera o, por favor, dígame dónde le duele
  • Mi biblioteca de tipos de espera y clases de bloqueo aquí
  • Curso de capacitación en línea My Pluralsight SQL Server:solución de problemas de rendimiento mediante estadísticas de espera
  • Asesor de rendimiento de SQL Sentry

En el siguiente artículo de la serie, hablaré sobre otro tipo de espera que es una causa común de reacciones instintivas. Hasta entonces, ¡feliz resolución de problemas!