WL#2515: PERFORMANCE_SCHEMA statements

Affects: Server-5.6   —   Status: Complete

Add statements instrumentation to the performance schema.

Target audience

* Server core developers

Implementers of the server itself, or implementers of storage engines,
do not have direct control on which MySQL user application generates which
statement, the server just executes what it is given, so the data provided by
this instrumentation can not be used to tune directly the server.

When implementing changes to the code to the server runtime however,
server developers will then be able to use the results on this instrumentation
to evaluate the overall impact of a server change on an end user application,
when doing benchmarks.

* Application developers

Application developers writing queries against the database server to implement
an application are the primary target audience for this instrumentation.

Application developers are expected to use the results of this instrumentation
to change how the application issues queries against the database,
to minimize the application footprint on the server,
and improve the application performances / scalability.

In particular, this instrumentation can be used to see in detail the statements
generated by the application, and see how these statements are executed by the
server.

* Production engineers

Production engineers monitoring the impact of applications against a database
server are the secondary audience for this instrumentation.

Production engineers are expected to use the results of this instrumentation
to monitor and assess the impact of an application on the whole system during
deployment.
Aggregation of statements statistics per connection allows to monitor the
general behavior of an application using this connection.
Aggregation of statements per event name allows to monitor the load on the
server created by each type of statement.

Table of content:
- Terminology
- SETUP_TIMERS Table
- SETUP_INSTRUMENTS Table
- EVENTS_STATEMENTS Tables
- STATEMENTS SUMMARIES Tables
- SETUP_CONSUMERS Table
- Server Variables
- Restrictions
- Requirements
- References

Terminology
-----------

A statement is an event at a high level of the hierarchy
Session -> Transaction -> Statement -> Stage -> Wait
so statements are nesting events for stages.

We monitor from the earliest possible moment when the
server sees that activity is requested on the thread,
to the latest possible moment when all activity is over
as far as the server is concerned. Typically this means
"from the time that server gets packet from client,
to the time when server sends back".

Monitoring is only of the outermost statement --
statements within stored procedures, triggered statements,
cascading actions, and subqueries are not seen separately.

The request might be for something other than COM_QUERY
(for example we can monitor COM_PING), and the request
might contain more than one instruction. Therefore the
monitored event might not be what we usually think of as
a "statement". Sometimes we call COM_PING a "command".

Initially we will not know details, for example we will
not know that a request contains an INSERT statement.

SETUP_TIMERS Table
------------------

There will be an additional "statement" row in performance_schema.SETUP_TIMERS:
mysql> select * from SETUP_TIMERS;
+--------------------+--------------+
| NAME               | TIMER_NAME   |
+--------------------+--------------+
| wait               | CYCLE        |
| statement          | NANOSECOND   |
+--------------------+--------------+

Statements are timed using the "statement" timer,
independently of waits which continue to be timed with the "wait" timer.

SETUP_INSTRUMENTS Table
-----------------------

There will be new rows in PERFORMANCE_SCHEMA.SETUP_INSTRUMENTS
for all possible statements.

Commands sent using a dedicated packet type (enum enum_server_command in the
client/server protocol are considered "statements" in a more general sense,
because sending such a message causes the server to execute some code.
This traffic should be instrumented, to monitor performance and load in general.
See feature requests regarding SHOW STATUS, such as BUG#53498.

Statements expressed in text in SQL are "statements" in a more traditional
sense, such as for example:
 "SELECT * from performance_schema.events_waits_current".
Such statements are later classified by the parser by the enum enum_sql_command.

Both kind of statements are instrumented and represented in setup_instruments,
and the resulting naming theme for statement instruments is as follows:

1) Instrumentation of server commands

Statements defined by the enum enum_server_command
are instrumented using the "statement/com/" prefix.

Given that names for items in this enum, such as COM_INIT_DB,
are already exposed to end users when printed in the query log,
the performance schema instruments names should reuse the names already defined.
COM_INIT_DB is then instrumented as "statement/com/Init DB".
See command_name[] in sql/sql_parse.cc.

Example:

mysql> select * from setup_instruments where name like "statement/com/%" order
by name;
+------------------------------+---------+-------+
| NAME                         | ENABLED | TIMED |
+------------------------------+---------+-------+
| statement/com/Binlog Dump    | YES     | YES   |
| statement/com/Change user    | YES     | YES   |
| statement/com/Close stmt     | YES     | YES   |
| statement/com/Connect        | YES     | YES   |
| statement/com/Connect Out    | YES     | YES   |
| statement/com/Create DB      | YES     | YES   |
| statement/com/Daemon         | YES     | YES   |
| statement/com/Debug          | YES     | YES   |
| statement/com/Delayed insert | YES     | YES   |
| statement/com/Drop DB        | YES     | YES   |
...
| statement/com/Execute        | YES     | YES   |
| statement/com/Fetch          | YES     | YES   |
| statement/com/Field List     | YES     | YES   |
| statement/com/Init DB        | YES     | YES   |
| statement/com/Kill           | YES     | YES   |
| statement/com/Long Data      | YES     | YES   |
| statement/com/Ping           | YES     | YES   |
| statement/com/Prepare        | YES     | YES   |
| statement/com/Processlist    | YES     | YES   |
| statement/com/Query          | YES     | YES   |
| statement/com/Quit           | YES     | YES   |
| statement/com/Refresh        | YES     | YES   |
| statement/com/Register Slave | YES     | YES   |
| statement/com/Reset stmt     | YES     | YES   |
| statement/com/Set option     | YES     | YES   |
| statement/com/Shutdown       | YES     | YES   |
| statement/com/Sleep          | YES     | YES   |
| statement/com/Statistics     | YES     | YES   |
| statement/com/Table Dump     | YES     | YES   |
| statement/com/Time           | YES     | YES   |
+------------------------------+---------+-------+

2) Instrumentation of sql statements

Statements defined by the enum enum_sql_command
are instrumented using the "statement/sql/" prefix.

Given that names for items in this enum, such as SQLCOM_SELECT,
are already exposed to end users by the server status variables,
the performance schema instruments names should reuse the names already defined.
SQLCOM_SELECT is then instrumented as "statement/com/select".
See com_status_vars[] in sql/mysqld.cc.

Example:

mysql> select * from setup_instruments where name like "statement/sql/%" order
by name;
+-------------------------------------+---------+-------+
| NAME                                | ENABLED | TIMED |
+-------------------------------------+---------+-------+
| statement/sql/alter_db              | YES     | YES   |
| statement/sql/alter_db_upgrade      | YES     | YES   |
| statement/sql/alter_event           | YES     | YES   |
| statement/sql/alter_function        | YES     | YES   |
| statement/sql/alter_procedure       | YES     | YES   |
| statement/sql/alter_server          | YES     | YES   |
| statement/sql/alter_table           | YES     | YES   |
| statement/sql/alter_tablespace      | YES     | YES   |
| statement/sql/analyze               | YES     | YES   |
| statement/sql/assign_to_keycache    | YES     | YES   |
| statement/sql/begin                 | YES     | YES   |
| statement/sql/binlog                | YES     | YES   |
| statement/sql/call_procedure        | YES     | YES   |
| statement/sql/change_db             | YES     | YES   |
| statement/sql/change_master         | YES     | YES   |
| statement/sql/check                 | YES     | YES   |
| statement/sql/checksum              | YES     | YES   |
| statement/sql/commit                | YES     | YES   |
...
| statement/sql/update                | YES     | YES   |
| statement/sql/update_multi          | YES     | YES   |
| statement/sql/xa_commit             | YES     | YES   |
| statement/sql/xa_end                | YES     | YES   |
| statement/sql/xa_prepare            | YES     | YES   |
| statement/sql/xa_recover            | YES     | YES   |
| statement/sql/xa_rollback           | YES     | YES   |
| statement/sql/xa_start              | YES     | YES   |
+-------------------------------------+---------+-------+
135 rows in set (0.01 sec)

3) Special "statement/com/Error" instrument

In addition to instruments for regular commands,
a special instrument "statement/com/Error"
is used to account for messages received by the server
that are out of bound.

Note: this behavior is already existing in the query log,
see command_name[COM_END].

Reporting out of bounds messages in the performance schema instrumentation
is very valuable to detect load sent to the server that the server
does not understand.
Such a load can originate from:
- mis configured clients, using a version of mysql more recent that the server,
- attacker.

4) Special "statement/sql/error" instrument

In addition to instruments for valid sql statements, a special instrument
"statement/sql/error" is used to account for text statements that failed to
properly parse.

Detecting broken queries sent by client applications is also
very valuable in production, which is why this special instrument
is used to have a separate accounting for errors.

Possible alternate names:
- "statement/sql/syntax_error"
- "statement/sql/parse_error"

5) Special "statement/com/Query" instrument

Because a query is initially sent as SQL text embedded inside
a COM_QUERY packet, the instrument name for the statement
("statement/sql/insert", ...) will be known only at a later phase in the process.

Statements received are instrumented as "statement/com/Query",
and the event_name instrumented will then change after parsing to:
- either a valid "statement/sql/..." instrument name,
  for queries that can be parsed successfully,
- or the the special "statement/sql/error" instrument name,
  for queries that failed parsing.

6) Alternative considered and rejected

Alternative naming proposal:
'command/query/data manipulation/select/simple'
or 'statement/query/data manipulation/select/simple'

This statement classification does not fit with the current classification
used otherwise with status variables, and would confuse users.

Alternative instrumentation proposal:
Do not instrument some commands such as COM_SLEEP,
COM_CONNECT, COM_TIME, COM_DELAYED_INSERT.

This is not a decision developers should make.
Instrumentation is provided in the code, and it is up to the DBA
to turn setup_instrument.enabled on or off.

In cases when an old command is supposed to be deprecated,
it is actually very valuable to detect when old clients are still sending
these commands to a server, so the instrumentation should be present.

Alternative instrumentation proposal:
instead of starting the instrumentation before parsing with "statement/com/Query"
and changing the event_name after parsing to "statement/sql/...",
start the instrumentation just after parsing, once the statement type is known.

This will cause accounting for the parser stage to be outside a statement
execution, and cause the timer_start / wait_time to be incorrect.

EVENTS_STATEMENTS Tables
------------------------
   
The EVENTS_STATEMENTS tables in PERFORMANCE_SCHEMA are:
- EVENTS_STATEMENTS_CURRENT
- EVENTS_STATEMENTS_HISTORY
- EVENTS_STATEMENTS_HISTORY_LONG
They're analogous to EVENTS_WAITS tables (EVENTS_WAITS_CURRENT etc.)
and most of the column descriptions are the same as in EVENTS_WAITS tables.

The columns for these 3 tables are as described below.

Column THREAD_ID integer not null
Identifies the thread, same as WL#2360.

Column EVENT_ID bigint unsigned not null
Identifies the event, same as WL#2360.

Column EVENT_NAME varchar(128) not null
See section SETUP_INSTRUMENTS Table.
Note that for EVENTS_STATEMENTS_CURRENT, the event name for a running statement
may change during the statement execution.

Column SOURCE varchar(64)
Identifies the line of code raising the event, same as WL#2360.

Column TIMER_START bigint unsigned
Column TIMER_END bigint unsigned
Column TIMER_WAIT bigint unsigned
The time spent in this event, same as WL#2360.

Column LOCK_TIME bigint unsigned
Time spent waiting for a lock on tables.
This metric already exist in the server, and is currently:
- computed in microseconds only (the timer can not be chosen),
- exposed in mysql.slow_log, column lock_time, with a type of "time"
The statement instrumentation will expose this existing metric since it is
available, but normalize the result to picoseconds, for easier comparison with
other performance schema timers (which are all normalized in picoseconds).

Column SQL_TEXT longtext
This statement sql text.

Column CURRENT_SCHEMA varchar(64)
See related column THREADS.PROCESSLIST_DB
The active database at the time the statement is executed.

Column OBJECT_TYPE varchar(64),
column OBJECT_SCHEMA varchar(64),
column OBJECT_NAME varchar(64),
For a top level statement, these columns are all NULL.
For a sub statement (stored procedure, stored function, table trigger, event
scheduler), these columns are reserved for future use.

Column OBJECT_INSTANCE_BEGIN bigint
Identifies the statement, same as WL#2360.

Column MYSQL_ERRNO integer
Statement diagnostics area, error number.

Column RETURNED_SQLSTATE varchar(5)
Statement diagnostics area, returned sqlstate.

Column MESSAGE_TEXT varchar(128)
Statement diagnostics area, message text.

Column ERRORS bigint not null
Statement diagnostics area, number of errors.
This is a convenience column, redundant with RETURNED_SQLSTATE.

Column WARNINGS bigint not null
Statement diagnostics area, number of warnings.

Column ROWS_SENT bigint not null
The number of rows returned to a client.
Note: this existing metric is printed in mysql.slow_log,
but not collected as a session status variable in information_schema.session_status.
With the statement instrumentation, this metric will be collected by statement,
and aggregated.

Column ROWS_EXAMINED bigint not null
The number of rows examined by the server.
Note: this existing metric is printed in mysql.slow_log,
but not collected as a session status variable in information_schema.session_status.
With the statement instrumentation, this metric will be collected by statement,
and aggregated.

Column CREATED_TMP_DISK_TABLES bigint not null
Optimizer metric, collected by statement.
See session status variable CREATED_TMP_DISK_TABLES.

Column CREATED_TMP_TABLES bigint not null
Optimizer metric, collected by statement.
See session status variable CREATED_TMP_TABLES.

Column SELECT_FULL_JOIN bigint not null
Optimizer metric, collected by statement.
See session status variable SELECT_FULL_JOIN.

Column SELECT_FULL_RANGE_JOIN bigint not null
Optimizer metric, collected by statement.
See session status variable SELECT_FULL_RANGE_JOIN.

Column SELECT_RANGE bigint not null
Optimizer metric, collected by statement.
See session status variable SELECT_RANGE.

Column SELECT_RANGE_CHECK bigint not null
Optimizer metric, collected by statement.
See session status variable SELECT_RANGE_CHECK.

Column SELECT_SCAN bigint not null
Optimizer metric, collected by statement.
See session status variable SELECT_SCAN.

Column SORT_MERGE_PASSES bigint not null
Optimizer metric, collected by statement.
See session status variable SORT_MERGE_PASSES.

Column SORT_RANGE bigint not null
Optimizer metric, collected by statement.
See session status variable SORT_RANGE.

Column SORT_ROWS bigint not null
Optimizer metric, collected by statement.
See session status variable SORT_ROWS.

Column SORT_SCAN bigint not null
Optimizer metric, collected by statement.
See session status variable SORT_SCAN.

Column NO_INDEX_USED bigint not null
Optimizer metric, collected by statement.
Note: this existing metric is returned to the client in the client/server
protocol, but not collected as a session status variable in
information_schema.session_status.
With the statement instrumentation, this metric will be collected by statement,
and aggregated.

Column NO_GOOD_INDEX_USED bigint not null
Optimizer metric, collected by statement.
Note: this existing metric is returned to the client in the client/server
protocol, but not collected as a session status variable in
information_schema.session_status.
With the statement instrumentation, this metric will be collected by statement,
and aggregated.

Column NESTING_EVENT_ID bigint unsigned,
column NESTING_EVENT_TYPE enum('STATEMENT', 'STAGE', 'WAIT')
Reserved for future use, always NULL.

Columns considered but rejected:
- SPINS (no semantic for a statement)
- OPERATIONS (likewise)
- NUMBER_OF_BYTES (likewise)
- STAGE_[category]_COUNT_STAR etc.
  This table structure does not work.
  Aggregation of stages statistics grouped by statements should be done
  in a dedicated table, not as columns inlined within EVENTS_STATEMENTS_CURRENT
- WAIT_IO_FILE_COUNT_STAR etc. 
  Likewise.
- ID (See SHOW PROCESSLIST, See THREADS.PROCESSLIST_ID)
  This is a session property, not a statement property.
  Joining session or transaction attributes with statements will cause
  duplications once session / transactions are instrumented and have also
historical data.
- USER (See SHOW PROCESSLIST, See THREADS.PROCESSLIST_USER)
  Likewise.
- HOST (See SHOW PROCESSLIST, See THREADS.PROCESSLIST_HOST)
  Likewise.
- COMMAND (See SHOW PROCESSLIST, See THREADS.PROCESSLIST_COMMAND)
  Redundant with EVENT_NAME
- STATE (See SHOW PROCESSLIST, See THREADS.PROCESSLIST_STATE)
  This is a stage property, no semantic for a statement.
- SERVER_ID (See mysql.general_log)
  No semantic for a statement.
- INFO (See SHOW PROCESSLIST, See THREADS.PROCESSLIST_INFO)
  This is a stage property, not a statement property.
- LAST_INSERT_ID (See mysql.slow_log)
  Use case for this column is unclear, instrumenting this has little value.
- INSERT_ID (See mysql.slow_log)
  Likewise.
- BYTES_SENT, BYTES_RECEIVED
  Tracking this per statement is probably overkill (BYTES_SENT is redundant with
ROWS_SENT),
  an instrumentation per session/connection seems more appropriate, as these are
connection metrics.
- TIME (see SHOW PROCESSLIST)
  Redundant with TIMER_START, but expressed in wall clock instead.
- TRANSACTION_ID (see information_schema.innodb_trx)
  Property of the nesting transaction, not the statement.

Note that other columns might be added later to support other features:
- WL#5395 "Audit log plugin"
- WL#3824 "Resource Limits"
- WL#4689 "Deadlock Monitor"
- WL#5767 "PERFORMANCE SCHEMA, statement digest"

STATEMENTS SUMMARIES Tables
---------------------------

The statements summaries provided are:
- table EVENTS_STATEMENTS_SUMMARY_BY_THREAD_BY_EVENT_NAME
- table EVENTS_STATEMENTS_SUMMARY_GLOBAL_BY_EVENT_NAME

Each table consist of:
- grouping columns
- summary columns

For table EVENTS_STATEMENTS_SUMMARY_BY_THREAD_BY_EVENT_NAME,
the grouping columns are:
- THREAD_ID
- EVENT_NAME
Same as EVENTS_WAITS_SUMMARY_BY_THREAD_BY_EVENT_NAME.

For table EVENTS_STATEMENTS_SUMMARY_GLOBAL_BY_EVENT_NAME,
the grouping columns are:
- EVENT_NAME
Same as EVENTS_WAITS_SUMMARY_GLOBAL_BY_EVENT_NAME.

The summary columns for every statements summary tables are the same,
and are as described below.

Column COUNT_STAR, bigint unsigned
Column SUM_TIMER_WAIT, bigint unsigned
Column MIN_TIMER_WAIT, bigint unsigned
Column AVG_TIMER_WAIT, bigint unsigned
Column MAX_TIMER_WAIT, bigint unsigned
Aggregates of EVENTS_STATEMENT_CURRENT.TIMER_WAIT,
same as waits summaries.

Column LOCK_TIME bigint unsigned not null
Aggregate of EVENTS_STATEMENT_CURRENT.LOCK_TIME.

Column SUM_ROWS_SENT bigint not null
Aggregate of EVENTS_STATEMENT_CURRENT.ROWS_SENT.

Column SUM_ROWS_EXAMINED bigint not null
Aggregate of EVENTS_STATEMENT_CURRENT.ROWS_EXAMINED.

Column SUM_CREATED_TMP_DISK_TABLES bigint not null
Aggregate of EVENTS_STATEMENT_CURRENT.CREATED_TMP_DISK_TABLES.

Column SUM_CREATED_TMP_TABLES bigint not null
Aggregate of EVENTS_STATEMENT_CURRENT.CREATED_TMP_TABLES.

Column SUM_SELECT_FULL_JOIN bigint not null
Aggregate of EVENTS_STATEMENT_CURRENT.SELECT_FULL_JOIN.

Column SUM_SELECT_FULL_RANGE_JOIN bigint not null
Aggregate of EVENTS_STATEMENT_CURRENT.SELECT_FULL_RANGE_JOIN.

Column SUM_SELECT_RANGE bigint not null
Aggregate of EVENTS_STATEMENT_CURRENT.SELECT_RANGE.

Column SUM_SELECT_RANGE_CHECK bigint not null
Aggregate of EVENTS_STATEMENT_CURRENT.SELECT_RANGE_CHECK.

Column SUM_SELECT_SCAN bigint not null
Aggregate of EVENTS_STATEMENT_CURRENT.SELECT_SCAN.

Column SUM_SORT_MERGE_PASSES bigint not null
Aggregate of EVENTS_STATEMENT_CURRENT.SORT_MERGE_PASSES.

Column SUM_SORT_RANGE bigint not null
Aggregate of EVENTS_STATEMENT_CURRENT.SORT_RANGE.

Column SUM_SORT_ROWS bigint not null
Aggregate of EVENTS_STATEMENT_CURRENT.SORT_ROWS.

Column SUM_SORT_SCAN bigint not null
Aggregate of EVENTS_STATEMENT_CURRENT.SORT_SCAN.

Column SUM_NO_INDEX_USED bigint not null
Aggregate of EVENTS_STATEMENT_CURRENT.NO_INDEX_USED.

Column SUM_NO_GOOD_INDEX_USED bigint not null
Aggregate of EVENTS_STATEMENT_CURRENT.NO_GOOD_INDEX_USED.

Column SUM_ERRORS bigint unsigned not null
Aggregate of EVENTS_STATEMENT_CURRENT.ERRORS.

Column SUM_WARNINGS bigint unsigned not null
Aggregate of EVENTS_STATEMENT_CURRENT.WARNINGS.

SETUP_CONSUMERS Table
---------------------

For every 'events_waits_...' row in the PERFORMANCE_SCHEMA.SETUP_CONSUMERS
table, there will be a corresponding 'events_statements_...' row, thus:
mysql> select * from SETUP_CONSUMERS;
+--------------------------------+---------+
| NAME                           | ENABLED |
+--------------------------------+---------+
| events_statements_current      | YES     |
| events_statements_history      | YES     |
| events_statements_history_long | YES     |
+--------------------------------+---------+

The enabling for statements does not depend on enabling for
the lower level, such as events_stages_current.

Server Variables
----------------

The default number of history rows is 10; the default number of
history_long rows is 10000; this is settable with mysqld and
visible thus:

mysql> show variables like 'performance%statements%';
+--------------------------------------------------------+---------+
| Variable_name                                          | Value   |
+--------------------------------------------------------+---------+
| performance_schema_events_statements_history_long_size | 10000   |
| performance_schema_events_statements_history_size      | 10      |
+--------------------------------------------------------+---------+

Restrictions
------------

This task only instruments top level statements.
Instrumentation for:
- nested statements (in stored procedures, stored functions, the event
scheduler, triggers)
- prepared statements
are out of scope.

Requirements
------------

(1) Table performance_schema.events_statements_current.
-------------------------------------------------------

Func-Req (1.1): A fresh MySQL installation of CURRENT-VERSION must create the
table performance_schema.events_statements_current.

Func-Req (1.2): An upgrade from PREVIOUS-VERSION to CURRENT-VERSION must create
the table performance_schema.events_statements_current.

Func-Req (1.3): Security privileges for events_statements_current
are enforced. Legal operations are SELECT, TRUNCATE.
CREATE TABLE and DROP TABLE are currently also legal, as they are used during
install/upgrade.

Func-Req (1.4): Table performance_schema.events_statements_current
is visible in the information_schema.

Func-Req (1.5): Table performance_schema.events_statements_current
is visible in SHOW TABLES.

(2) Table performance_schema.events_statements_history.
-------------------------------------------------------

Func-Req (2.1): A fresh MySQL installation of CURRENT-VERSION must create the
table performance_schema.events_statements_history.

Func-Req (2.2): An upgrade from PREVIOUS-VERSION to CURRENT-VERSION must create
the table performance_schema.events_statements_history.

Func-Req (2.3): Security privileges for events_statements_history
are enforced. Legal operations are SELECT, TRUNCATE.
CREATE TABLE and DROP TABLE are currently also legal, as they are used during
install/upgrade.

Func-Req (2.4): Table performance_schema.events_statements_history
is visible in the information_schema.

Func-Req (2.5): Table performance_schema.events_statements_history
is visible in SHOW TABLES.

(3) Table performance_schema.events_statements_history_long.
------------------------------------------------------------

Func-Req (3.1): A fresh MySQL installation of CURRENT-VERSION must create the
table performance_schema.events_statements_history_long.

Func-Req (3.2): An upgrade from PREVIOUS-VERSION to CURRENT-VERSION must create
the table performance_schema.events_statements_history_long.

Func-Req (3.3): Security privileges for events_statements_history_long
are enforced. Legal operations are SELECT, TRUNCATE.
CREATE TABLE and DROP TABLE are currently also legal, as they are used during
install/upgrade.

Func-Req (3.4): Table performance_schema.events_statements_history_long
is visible in the information_schema.

Func-Req (3.5): Table performance_schema.events_statements_history_long
is visible in SHOW TABLES.

(4) Table performance_schema.events_statements_summary_by_thread_by_event_name.
-------------------------------------------------------------------------------

Func-Req (4.1): A fresh MySQL installation of CURRENT-VERSION must create the
table performance_schema.events_statements_summary_by_thread_by_event_name.

Func-Req (4.2): An upgrade from PREVIOUS-VERSION to CURRENT-VERSION must create
the table performance_schema.events_statements_summary_by_thread_by_event_name.

Func-Req (4.3): Security privileges for
events_statements_summary_by_thread_by_event_name
are enforced. Legal operations are SELECT, TRUNCATE.
CREATE TABLE and DROP TABLE are currently also legal, as they are used during
install/upgrade.

Func-Req (4.4): Table
performance_schema.events_statements_summary_by_thread_by_event_name
is visible in the information_schema.

Func-Req (4.5): Table
performance_schema.events_statements_summary_by_thread_by_event_name
is visible in SHOW TABLES.

(5) Table performance_schema.events_statements_summary_global_by_event_name.
----------------------------------------------------------------------------

Func-Req (5.1): A fresh MySQL installation of CURRENT-VERSION must create the
table performance_schema.events_statements_summary_global_by_event_name.

Func-Req (5.2): An upgrade from PREVIOUS-VERSION to CURRENT-VERSION must create
the table performance_schema.events_statements_summary_global_by_event_name.

Func-Req (5.3): Security privileges for
events_statements_summary_global_by_event_name
are enforced. Legal operations are SELECT, TRUNCATE.
CREATE TABLE and DROP TABLE are currently also legal, as they are used during
install/upgrade.

Func-Req (5.4): Table
performance_schema.events_statements_summary_global_by_event_name
is visible in the information_schema.

Func-Req (5.5): Table
performance_schema.events_statements_summary_global_by_event_name
is visible in SHOW TABLES.

(6) Table performance_schema.setup_timers.
------------------------------------------

Func-Req (6.1): Table setup_timers has a new timer named "statement".

(7) Table performance_schema.setup_instruments.
-----------------------------------------------

Func-Req (7.1): Table setup_instruments displays new rows for the statements
instrumentation, with a prefix "statement/".

(8) Table performance_schema.setup_consumers.
---------------------------------------------

Func-Req (8.1): Table setup_consumers has a new consumer named
"events_statement_current", which control the table of the same name.

Func-Req (8.2): Table setup_consumers has a new consumer named
"events_statement_history", which control the table of the same name.

Func-Req (8.3): Table setup_consumers has a new consumer named
"events_statement_history_long", which control the table of the same name.

(9) Server start options and variables.
---------------------------------------

Func-Req (9.1): A new server start option is available,
"performance-schema-events-statement-history-size", to control the size of the
table events_statements_history.

Func-Req (9.2): A new server start option is available,
"performance-schema-events-statement-history-long-size", to control the size of
the table events_statements_history_long.

Func-Req (9.3): A new server start option is available,
"performance-schema-max-statement-classes", to control the maximum number of
statement instrument classes.

(10) Server status.
-------------------

Func-Req (10.1): A new server status variable is available,
"Performance_schema_statement_classes_lost".

References
----------
   
WL#2360 Performance Schema
WL#1282 Add log file which would log error codes together with queries.
WL#4689	Deadlock Monitor
WL#4813 PERFORMANCE_SCHEMA Instrumenting Stages
WL#5740 PERFORMANCE SCHEMA, chip and OS counters.

BUG#59639 provide option to log stored procedure SQL in general log

PERFORMANCE_SCHEMA.EVENTS_STATEMENTS is a bit like Oracle 11g's V$SQL
http://download.oracle.com/docs/cd/B28359_01/server.111/b28320/dynviews_3042.htm#REFRN30246

The detailed design is documented in doxygen format.
See instructions in the file Doxyfile-perfschema, in the project branch.