¿Cuál es el número máximo de acciones vinculadas permitidas para un evento extendido?

14

Si agrega "demasiadas" acciones a un evento en una sesión de eventos, recibirá este error:

Msg 25639, Nivel 16, Estado 23, Línea 1 El evento, "[nombre del evento]", excede el número de acciones vinculadas permitidas.

¿Cuántas acciones están permitidas? ¿Varía según el evento?

La respuesta, basada en la experimentación, parece ser 27 para sqlserver.rpc_completed. Pero no he encontrado ese número en ninguna documentación de Microsoft . Y parece variar según el evento, ya que pude obtener 30 para sqlserver.sql_batch_completed.

Código de ejemplo que falla:

CREATE EVENT SESSION [Test] ON SERVER 
ADD EVENT sqlserver.rpc_completed(
    ACTION(
        package0.callstack,
        package0.collect_cpu_cycle_time,
        package0.collect_current_thread_id,
        package0.collect_system_time,
        package0.event_sequence,
        package0.last_error,
        package0.process_id,
        sqlos.cpu_id,
        sqlos.numa_node_id,
        sqlos.scheduler_address,
        sqlos.scheduler_id,
        sqlos.system_thread_id,
        sqlos.task_address,
        sqlos.task_elapsed_quantum,
        sqlos.task_resource_group_id,
        sqlos.task_resource_pool_id,
        sqlos.task_time,
        sqlos.worker_address,
        sqlserver.client_app_name,
        sqlserver.client_connection_id,
        sqlserver.client_hostname,
        sqlserver.client_pid,
        sqlserver.context_info,
        sqlserver.database_id,
        sqlserver.database_name,
        sqlserver.is_system,
        sqlserver.nt_username,
        sqlserver.plan_handle))
GO
DROP EVENT SESSION [Test] ON SERVER
GO

Código de ejemplo que tiene éxito (lo mismo excepto excluyendo el último elemento):

CREATE EVENT SESSION [Test] ON SERVER 
ADD EVENT sqlserver.rpc_completed(
    ACTION(
        package0.callstack,
        package0.collect_cpu_cycle_time,
        package0.collect_current_thread_id,
        package0.collect_system_time,
        package0.event_sequence,
        package0.last_error,
        package0.process_id,
        sqlos.cpu_id,
        sqlos.numa_node_id,
        sqlos.scheduler_address,
        sqlos.scheduler_id,
        sqlos.system_thread_id,
        sqlos.task_address,
        sqlos.task_elapsed_quantum,
        sqlos.task_resource_group_id,
        sqlos.task_resource_pool_id,
        sqlos.task_time,
        sqlos.worker_address,
        sqlserver.client_app_name,
        sqlserver.client_connection_id,
        sqlserver.client_hostname,
        sqlserver.client_pid,
        sqlserver.context_info,
        sqlserver.database_id,
        sqlserver.database_name,
        sqlserver.is_system,
        sqlserver.nt_username))
GO
DROP EVENT SESSION [Test] ON SERVER
GO

(Intenté un par de acciones diferentes y no parece relacionarse con las acciones que se incluyen, pero ¿tal vez se basa en un recuento total de caracteres de los nombres de las acciones?)

Lista completa de acciones con las que estaba trabajando:

package0.callstack,
package0.collect_cpu_cycle_time,
package0.collect_current_thread_id,
package0.collect_system_time,
package0.event_sequence,
package0.last_error,
package0.process_id,
sqlos.cpu_id,
sqlos.numa_node_id,
sqlos.scheduler_address,
sqlos.scheduler_id,
sqlos.system_thread_id,
sqlos.task_address,
sqlos.task_elapsed_quantum,
sqlos.task_resource_group_id,
sqlos.task_resource_pool_id,
sqlos.task_time,
sqlos.worker_address,
sqlserver.client_app_name,
sqlserver.client_connection_id,
sqlserver.client_hostname,
sqlserver.client_pid,
sqlserver.context_info,
sqlserver.database_id,
sqlserver.database_name,
sqlserver.is_system,
sqlserver.nt_username,
sqlserver.plan_handle,
sqlserver.query_hash,
sqlserver.query_hash_signed,
sqlserver.query_plan_hash,
sqlserver.query_plan_hash_signed,
sqlserver.request_id,
sqlserver.server_instance_name,
sqlserver.server_principal_name,
sqlserver.server_principal_sid,
sqlserver.session_id,
sqlserver.session_nt_username,
sqlserver.session_resource_group_id,
sqlserver.session_resource_pool_id,
sqlserver.session_server_principal_name

@@ VERSIÓN Salida:

Microsoft SQL Server 2016 (SP1) (KB3182545) - 13.0.4001.0 (X64) 
    Oct 28 2016 18:17:30 
    Copyright (c) Microsoft Corporation
    Developer Edition (64-bit) on Windows Server 2012 R2 Standard 6.3 <X64> (Build 9600: ) (Hypervisor)
Riley Major
fuente

Respuestas:

9

¿Cuántas acciones están permitidas? ¿Varía según el evento?

Investigué un poco y sí, hay un límite en la cantidad de acciones y eventos que se pueden agregar a una definición de evento extendida. No es un valor "difícil", sino que se basa en muchas entradas diferentes, por lo tanto, una definición que no funciona podría funcionar simplemente con la eliminación de un solo evento o una sola acción en un solo evento.

Y parece variar según el evento, ya que pude obtener 30 por sqlserver.sql_batch_completed.

Ya te has topado con la gran cantidad de configuraciones posibles, por lo que sabes que no se basa completamente en la cantidad de acciones. Tampoco es específico para cada evento, sino una combinación de los valores.

¿Qué puedes hacer?

El primer elemento es que los datos de longitud variable son el problema más grande que enfrentarás. ¿Cómo sabes qué es la longitud variable y qué no? Si nos fijamos en el catálogo XE sys.dm_xe_objectsespecíficamente a algunas acciones, verá que hay type_namey type_sizecolumnas que pueden ser útiles para ver si va a añadir un montón de puntos de datos de tamaño variable (tamaño de 0 en la pantalla de abajo).

ingrese la descripción de la imagen aquí

Ahora, probablemente estés pensando: está bien, pero no conozco el límite mágico, así que realmente no es útil. Bueno, lo es y no lo es. Si lo miras específicamente desde un punto de vista numérico, entonces sí, no es muy útil ... sin embargo, esta es una forma terrible de verlo. Debe considerarse como "¿Estoy recopilando solo los datos que necesito?" y en la mayoría de los casos nunca se encontrará con un problema con este error.

Si tomamos la definición en la pregunta que no funciona, parte de la información recopilada parece que realmente no es necesaria. ¿Realmente necesita pila de llamadas, ID de subproceso actual, tiempo de ciclo de la CPU, dirección del trabajador y dirección del planificador? Callstack es variable, el resto son fijos, por lo que solo eliminando el callstack podría encajar en más columnas si es necesario. No digo que necesites más, pero podrías.

El punto es limitar la definición para que sea tan pequeña como sea necesaria. Recopilar todo dará como resultado errores (como los que ha tenido aquí), lentitud del sistema, demasiados datos para analizar o incluso la detención del sistema. Solo porque puedas no significa que debas. No hay nada que indique que estos límites cambiarán o no entre versiones mayores o menores, por lo que mantener la verdadera necesidad mínima es la mejor prevención. Por favor, no solo marque cada casilla (gui) o agregue todas las acciones posibles.

Sean Gallardy
fuente
Me encontré con problemas similares al agregar demasiados eventos a una sola sesión al probar una herramienta QueryableXEventData que estaba desarrollando. Especificar solo aquellos eventos, acciones y campos realmente necesarios es un buen consejo.
Dan Guzman