语句的digest发生在解析器(parser)中,performance_schema中虽然作为digest其中一个存储的地方,但是并不计算digest(语句的归一化Normalization 过程)。而仅仅是将parser计算出来的digest文本与digest SHA256哈希值进行转储。因此performance schema作为解析器计算digest的其中一个充分条件而不是必要条件。解析器计算语句digest只要下面三个条件中的任一个满足即可:
1,Performance Schema digest instrumentation is enabled
2,MySQL Enterprise Firewall is enabled
3,A Query Rewrite Plugin is enabled
解析器计算语句的digest分为两个步骤:第一步,产生归一化(normalized)的语句,将原始语句保留主体结构,去除注释和将参数条件进行标记化替代,产生语句 digest text;第二步根据归一化语句digest text计算 digest hash值。这个过程,参数max_digest_length(The maximum number of bytes of memory reserved per session for computation of normalized statement digests)控制每个session对这个过程使用的内存大小,默认为1024字节。当内存使用超出这个大小,之后未处理的原始语句部分将被截断,并且不参与计算hash值。意味着在此之前相同,之后不同的语句将共享相同的hash值和digest text。并被视为同一个语句进行统计信息收集与聚合。
解析器生成digest text和digest hash之后:
1, 如果performance schema启用digest统计(setup_consumers.NAME='statements_digest'项启用),则performance_schema会将digest text与digest value转储到相关表中(events_statements_current, events_statements_histogram_by_digest, events_statements_history, events_statements_history_long, events_statements_summary_by_digest );
2, 如果performance schema未启用digest统计,则对应表的对应列为空(events_statements_current,events_statements_history, events_statements_history_long ),并且(events_statements_histogram_by_digest , events_statements_summary_by_digest)表不进行统计,没有记录。
performance schema转储digest text的长度,受到参数performance_schema_max_digest_length控制。这个参数与max_digest_length参数的关系理解如下:
1,max_digest_length > performance_schema_max_digest_length ,当digest text长度超出performance_schema_max_digest_length大小后,会被截断存储在performance_schema的表中,但是因为digest hash值不受影响,并且(events_statements_histogram_by_digest , events_statements_summary_by_digest)表以digest hash为维度进行统计,因此不影响对应表的功能;
2,max_digest_length = performance_schema_max_digest_length ,digest text原样转储到performance_schema的表中。
3,max_digest_length < performance_schema_max_digest_length ,digest text原样转储到performance_schema的表中,但是没有必要这么做。
需要考虑到,max_digest_length是针对每个session进行分配,performance_schema_max_digest_length是针对每种语句进行分配,并且performance_schema引擎表是内存表,过大的performance_schema_max_digest_length设置会导致过多的内存使用。并且performance_schema表的内存一旦分配都不会回收,直到停机。
语句的采样sampling仅仅发生在performance_schema中。
当一个新语句记录插入到performance_schema表中,performance_schema会将产生此digest的原始sql作为采样语句存储(对应的列SQL_TEXT:{events_statements_current,events_statements_history, events_statements_history_long}, QUERY_SAMPLE_TEXT:{events_statements_summary_by_digest}, QUERY_SAMPLE_SEEN,QUERY_SAMPLE_TIMER_WAIT ),此大小受到参数performance_schema_max_sql_text_length控制。
当一个已存在的语句行被更新时,performance_schema使用如下策略来决定是否更新当前采样sql信息:
1, 根据采样sql的执行等待时间。当新记录的QUERY_SAMPLE_TIMER_WAIT 大于 当前QUERY_SAMPLE_TIMER_WAIT 时,使用新记录采样更新当前采样信息。
2, 根据当前采样信息的年龄。采样信息过期年龄由performance_schema_max_digest_sample_age参数控制,单位为s,默认10s。如果当前采样记录的保持时间大于此参数设置值,则使用新采样替换当前采样信息。即使新记录信息的执行等待时间小于当前记录采样信息。