Description:
Currently, events_*_summary_by_thread_* tables collect data always when corresponding instrumentation is enabled. But not all users need this summary data. Many are interested only in *_current and *_history* tables. But no matter of that memory for events_*_summary_by_thread_* still allocated and never freed.
How to repeat:
1. Start MTR:
./mtr --start innodb &
2. Connect to it and run:
mysql> set global max_connections=1024;
Query OK, 0 rows affected (0,00 sec)
mysql> create database sbtest;
Query OK, 1 row affected (0,02 sec)
3. Prepare sysbench test:
sysbench --threads=100 --events=0 --time=100 --mysql-host=127.0.0.1 --mysql-port=13000 --mysql-user=root ~/build/sysbench/share/sysbench/oltp_write_only.lua --tables=10 prepare
4. Run sysbench test with 100, 300, 400, 500, 600 threads:
sysbench --threads=100 --events=0 --time=60 --mysql-host=127.0.0.1 --mysql-port=13000 --mysql-user=root ~/build/sysbench/share/sysbench/oltp_write_only.lua --tables=10 run
5. Measure memory usage:
mysql> \R before tests>
PROMPT set to 'before tests> '
before tests> select sum(CURRENT_NUMBER_OF_BYTES_USED) from memory_summary_global_by_event_name where event_name like '%by_thread%';
+-----------------------------------+
| sum(CURRENT_NUMBER_OF_BYTES_USED) |
+-----------------------------------+
| 62193664 |
+-----------------------------------+
1 row in set (0,00 sec)
before tests> select sum(CURRENT_NUMBER_OF_BYTES_USED) from memory_summary_global_by_event_name where event_name like '%by_thread%';
+-----------------------------------+
| sum(CURRENT_NUMBER_OF_BYTES_USED) |
+-----------------------------------+
| 62193664 |
+-----------------------------------+
1 row in set (0,00 sec)
before tests> \R after prepare>
PROMPT set to 'after prepare>'
after prepare>select sum(CURRENT_NUMBER_OF_BYTES_USED) from memory_summary_global_by_event_name where event_name like '%by_thread%';
+-----------------------------------+
| sum(CURRENT_NUMBER_OF_BYTES_USED) |
+-----------------------------------+
| 62193664 |
+-----------------------------------+
1 row in set (0,00 sec)
after prepare>\R after 100 threads>
PROMPT set to 'after 100 threads> '
after 100 threads> select sum(CURRENT_NUMBER_OF_BYTES_USED) from memory_summary_global_by_event_name where event_name like '%by_thread%';
+-----------------------------------+
| sum(CURRENT_NUMBER_OF_BYTES_USED) |
+-----------------------------------+
| 62193664 |
+-----------------------------------+
1 row in set (0,00 sec)
after 100 threads> \R after 300 threads>
PROMPT set to 'after 300 threads> '
after 300 threads> select sum(CURRENT_NUMBER_OF_BYTES_USED) from memory_summary_global_by_event_name where event_name like '%by_thread%';
+-----------------------------------+
| sum(CURRENT_NUMBER_OF_BYTES_USED) |
+-----------------------------------+
| 124387328 |
+-----------------------------------+
1 row in set (0,01 sec)
after 300 threads> \R after 400 threads>
PROMPT set to 'after 400 threads> '
after 400 threads> select sum(CURRENT_NUMBER_OF_BYTES_USED) from memory_summary_global_by_event_name where event_name like '%by_thread%';
+-----------------------------------+
| sum(CURRENT_NUMBER_OF_BYTES_USED) |
+-----------------------------------+
| 124387328 |
+-----------------------------------+
1 row in set (0,00 sec)
after 400 threads> \R after 500 threads>
PROMPT set to 'after 500 threads> '
after 500 threads> select sum(CURRENT_NUMBER_OF_BYTES_USED) from memory_summary_global_by_event_name where event_name like '%by_thread%';
+-----------------------------------+
| sum(CURRENT_NUMBER_OF_BYTES_USED) |
+-----------------------------------+
| 186580992 |
+-----------------------------------+
1 row in set (0,00 sec)
after 500 threads> \R after 600 threads>
PROMPT set to 'after 600 threads> '
after 600 threads> select sum(CURRENT_NUMBER_OF_BYTES_USED) from memory_summary_global_by_event_name where event_name like '%by_thread%';
+-----------------------------------+
| sum(CURRENT_NUMBER_OF_BYTES_USED) |
+-----------------------------------+
| 248774656 |
+-----------------------------------+
1 row in set (0,00 sec)
after 600 threads> select sleep(300);
+------------+
| sleep(300) |
+------------+
| 0 |
+------------+
1 row in set (5 min 0,00 sec)
after 600 threads> select sum(CURRENT_NUMBER_OF_BYTES_USED) from memory_summary_global_by_event_name where event_name like '%by_thread%';
+-----------------------------------+
| sum(CURRENT_NUMBER_OF_BYTES_USED) |
+-----------------------------------+
| 248774656 |
+-----------------------------------+
1 row in set (0,00 sec)
after 600 threads> ^C
after 600 threads> select event_name, sum(CURRENT_NUMBER_OF_BYTES_USED) from memory_summary_global_by_event_name where event_name like '%by_thread%' group by event_name;
+-------------------------------------------------------------------------------+-----------------------------------+
| event_name | sum(CURRENT_NUMBER_OF_BYTES_USED) |
+-------------------------------------------------------------------------------+-----------------------------------+
| memory/performance_schema/events_waits_summary_by_thread_by_event_name | 18153472 |
| memory/performance_schema/events_stages_summary_by_thread_by_event_name | 5734400 |
| memory/performance_schema/events_statements_summary_by_thread_by_event_name | 41074688 |
| memory/performance_schema/events_transactions_summary_by_thread_by_event_name | 90112 |
| memory/performance_schema/events_errors_summary_by_thread_by_error | 150544384 |
| memory/performance_schema/memory_summary_by_thread_by_event_name | 33177600 |
+-------------------------------------------------------------------------------+-----------------------------------+
6 rows in set (0,00 sec)
As you see memory usage gets increasing and never freed.
Suggested fix:
Provide options (each for each table) to disable data collection for events_*_summary_by_thread_* tables.