5.8.1.7 行级探针

每次将行操作下推到存储引擎时,都会触发*row-{start,done}探针。例如,如果您执行的一条INSERT语句包含 100 行数据,那么对于每行插入,insert-row-startinsert-row-done探针将分别触发 100 次。

insert-row-start(database, table)
insert-row-done(status)

update-row-start(database, table)
update-row-done(status)

delete-row-start(database, table)
delete-row-done(status)
  • insert-row-start:在将行插入 table 中之前触发。

  • insert-row-done:将行插入 table 中后触发。

  • update-row-start:在更新 table 中的行之前触发。

  • update-row-done:在更新 table 中的行之前触发。

  • delete-row-start:在从 table 中删除行之前触发。

  • delete-row-done:在从 table 中删除行之前触发。

每种情况下,探针支持的参数都与相应的startdone探针一致:

  • database:数据库名称。

  • table:table 名。

  • status:状态; 0table 示成功,1table 示失败。

由于行级别探针是针对每个单独的行访问触发的,因此这些探针每秒可能触发数千次,这可能对监视脚本和 MySQL 都产生不利影响。 DTrace 环境应限制这些探针的触发,以防止对性能造成不利影响。要么少用探针,要么使用计数器或聚合函数报告这些探针,然后在脚本终止时或作为query-donequery-exec-done探针的一部分提供摘要。

以下示例脚本总结了较大查询中每个行操作的持续时间:

#!/usr/sbin/dtrace -s

#pragma D option quiet

dtrace:::BEGIN
{
   printf("%-2s %-10s %-10s %9s %9s %-s \n",
          "St", "Who", "DB", "ConnID", "Dur ms", "Query");
}

mysql*:::query-start
{
   self->query = copyinstr(arg0);
   self->who   = strjoin(copyinstr(arg3),strjoin("@",copyinstr(arg4)));
   self->db    = copyinstr(arg2);
   self->connid = arg1;
   self->querystart = timestamp;
   self->rowdur = 0;
}

mysql*:::query-done
{
   this->elapsed = (timestamp - self->querystart) /1000000;
   printf("%2d %-10s %-10s %9d %9d %s\n",
          arg0, self->who, self->db,
          self->connid, this->elapsed, self->query);
}

mysql*:::query-done
/ self->rowdur /
{
   printf("%34s %9d %s\n", "", (self->rowdur/1000000), "-> Row ops");
}

mysql*:::insert-row-start
{
   self->rowstart = timestamp;
}

mysql*:::delete-row-start
{
   self->rowstart = timestamp;
}

mysql*:::update-row-start
{
   self->rowstart = timestamp;
}

mysql*:::insert-row-done
{
   self->rowdur += (timestamp-self->rowstart);
}

mysql*:::delete-row-done
{
   self->rowdur += (timestamp-self->rowstart);
}

mysql*:::update-row-done
{
   self->rowdur += (timestamp-self->rowstart);
}

通过将查询插入到 table 中的查询运行上述脚本,您可以监视执行原始行插入所花费的确切时间:

St Who        DB            ConnID    Dur ms Query
 0 @localhost test              13     20767 insert into t1(select * from t2)
                                        4827 -> Row ops