The *row-{start,done}
probes are triggered
each time a row operation is pushed down to a storage engine.
For example, if you execute an
INSERT
statement with 100 rows of
data, then the insert-row-start
and
insert-row-done
probes will be triggered 100
times each, for each row insert.
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
: Triggered before a row is inserted into a table.insert-row-done
: Triggered after a row is inserted into a table.update-row-start
: Triggered before a row is updated in a table.update-row-done
: Triggered before a row is updated in a table.delete-row-start
: Triggered before a row is deleted from a table.delete-row-done
: Triggered before a row is deleted from a table.
The arguments supported by the probes are consistent for the
corresponding start
and
done
probes in each case:
database
: The database name.table
: The table name.status
: The status; 0 for success or 1 for failure.
Because the row-level probes are triggered for each individual
row access, these probes can be triggered many thousands of
times each second, which may have a detrimental effect on both
the monitoring script and MySQL. The DTrace environment should
limit the triggering on these probes to prevent the performance
being adversely affected. Either use the probes sparingly, or
use counter or aggregation functions to report on these probes
and then provide a summary when the script terminates or as part
of a query-done
or
query-exec-done
probes.
The following example script summarizes the duration of each row operation within a larger query:
#!/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); }
Running the above script with a query that inserts data into a table, you can monitor the exact time spent performing the raw row insertion:
St Who DB ConnID Dur ms Query 0 @localhost test 13 20767 insert into t1(select * from t2) 4827 -> Row ops