Georgi Kodinov
Team Lead, MySQL server general team
How to Instrument Your Code in
MySQL Performance Schema
© 2019 Oracle1
Safe harbor statement
The following is intended to outline our general product direction. It is intended for information purposes
only, and may not be incorporated into any contract. It is not a commitment to deliver any material,
code, or functionality, and should not be relied upon in making purchasing decisions.
The development, release, timing, and pricing of any features or functionality described for Oracle’s
products may change and remains at the sole discretion of Oracle Corporation.
2 © 2019 Oracle
Topics Covered
Why should I instrument my code ?
How do I go about instrumenting it ?
Mechanics of instrumentation
PERFORMANCE_SCHEMA: not just about performance
© 2019 Oracle3
Why should I instrument my code ?
• Understand what resources it uses:
• memory, locks, time, files, etc.
• More debuggable
• Provides extra insight into code operation and issues
• Expose extra volatile information to users and administrators
• Make your code more portable
© 2019 Oracle4
How do I instrument my code ?
Contribute data to the instruments provided
Future: add your own instruments
© 2019 Oracle5
Most of the times it’sTHAT easy !
#include <pthread.h>
pthread_mutex_t foo;
void do_something()
{
pthread_mutex_lock(&foo);
...
pthread_mutex_unlock(&foo);
}
#include "mysql/psi/mysql_mutex.h“
mysql_mutex_t foo;
void do_something()
{
mysql_mutex_lock(&foo);
...
mysql_mutex_unlock(&foo);
}
© 2019 Oracle6
Extra step: register your objects
#ifdef HAVE_PSI_MUTEX_INTERFACE
PSI_mutex_key mutex_key_foo = PSI_NOT_INSTRUMENTED;
static PSI_mutex_info all_mutexes[]=
{
{ &mutex_key_foo, "LOCK_foo", PSI_FLAG_SINGLETON, 0, "example doc"},
..
}
..
count = static_cast<int>(array_elements(all_mutexes));
mysql_mutex_register(“category_foo”, all_mutexes, count);
..
mysql_mutex_init(mutex_key_foo, &foo, MY_MUTEX_INIT_FAST);
#endif /* HAVE_PSI_MUTEX_INTERFACE */
© 2019 Oracle7
Instrumentation inventory: inline functions
• POSIX threads
• POSIX conditions
• POSIX mutexes
• POSIX read/write locks
• POSIX sockets
• Buffered and unbuffered file I/O
• MySQL stages
• MySQL metadata locks
mysql_thread.h
mysql_cond.h
mysql_mutex.h
mysql_rwlock.h
mysql_socket.h
mysql_file.h
mysql_stage.h
mysql_mdl.h
© 2019 Oracle8
How do I instrument my memory use ?
#include <stdlib.h>
void *foo;
void do_something()
{
foo = malloc(12);
...
free(foo);
}
#include "mysys.h“
void *foo;
void do_something()
{
foo = my_malloc(mem_key_foo, 12, MYF(0));
...
my_free(foo);
}
© 2019 Oracle9
Extra step: register your objects
#ifdef HAVE_PSI_MEMORY_INTERFACE
PSI_memory_key mem_key_foo = PSI_NOT_INSTRUMENTED;
static PSI_memory_info all_memory[] = {
{&mem_key_foo, “FOO", PSI_FLAG_ONLY_GLOBAL_STAT, 0, "example doc"}};
…
count = static_cast<int>(array_elements(all_memory));
mysql_memory_register(category, all_memory, count);
#endif /* HAVE_PSI_MEMORY_INTERFACE */
© 2019 Oracle10
Instrumentation inventory: memory
• Plugin service implemented in mysys:
my_malloc(), my_free(), my_memdup()
etc.
• Static mysys inspired library to link with
components: just my_malloc() and my_free()
include/mysql/service_mysql_alloc.h
components/library_mysys/my_memory.h
© 2019 Oracle11
Instrumenting other stuff: utility macros
#include <mysql/psi/mysql_idle.h>
…
PSI_idle_locker *m_idle_psi = NULL;
PSI_idle_locker_state m_idle_state;
…
MYSQL_START_IDLE_WAIT(m_idle_psi, &m_idle_state);
…
MYSQL_END_IDLE_WAIT(m_idle_psi);
…
© 2019 Oracle12
Instrumentation inventory: utility macros
• Transactions
• Table locks
• “System” (currently shared objects)
• Statements
• Stored programs
• Prepared statements
• MySQL stages
• Errors
• Data locks
 Idle
mysql_transaction.h
mysql_table.h
mysql_system.h
mysql_statement.h
mysql_sp.h
mysql_ps.h
mysql_stage.h
mysql_error.h
mysql_data_lock.h
mysql_idle.h
© 2019 Oracle13
Mechanics of code instrumentation
Under the hood
© 2019 Oracle14
Calling instrumentation: PSI_*_CALL macros
• Server code: direct call
• #define PSI_FILE_CALL(M) pfs_##M##_v1
• Plugins: function pointer
• #define PSI_FILE_CALL(M) psi_file_service->M
• Components: component service handle
• #define PSI_FILE_CALL(M) mysql_service_psi_file_v1->M
© 2019 Oracle15
Random thoughts on good code instrumentation
• Always release the artifacts that instruments returned via the
intended methods !
• Instrumentation can be costly !
• Consider using component infrastructure
© 2019 Oracle16
Performance Schema
Not just about performance !
© 2019 Oracle17
PERFORMANCE_SCHEMA: Not just performance !
• Started as performance instrumentation. Still does it !
• Grown into general storage for fast-changing volatile data
• System variables
• Connection attributes
• Replication, innodb state
• Now supports adding new tables from components
© 2019 Oracle18
Add a PERFORMANCE_SCHEMA table
From a component
© 2019 Oracle19
Step 1:The data
© 2019 Oracle20
Step 2: Basic table APIs
© 2019 Oracle21
Step 3: Data retrieval
© 2019 Oracle22
Step 4: Component code
© 2019 Oracle23
How it drives
© 2019 Oracle24
Let’s look at the table
© 2019 Oracle25
Where to go from here ?
• MySQL Internals Doxygen:
https://dev.mysql.com/doc/dev/mysql-
server/latest/PAGE_PFS.html
• Reference Manual:
https://dev.mysql.com/doc/refman/8.0/en/performance-
schema.html
© 2019 Oracle26
Questions And Answers
© 2019 Oracle27
Copyright © 2019 Oracle and/or its affiliates.28
Meet the MySQL Team at the Conference
Sunny Bains
Luis Soares
Kenny Gryp
Frédéric Descamps
Dimitri Kravtchuk
Ståle Deraas
Pedro Gomes
Geir HøydalsvikNorvald Ryeng
Georgi Kodinov
Join us on MySQL Community Slack
Copyright © 2019 Oracle and/or its affiliates.29
https://lefred.be/mysql-community-on-slack/
Follow us on Social Media
Copyright © 2019 Oracle and/or its affiliates.30
https://www.facebook.com/mysql
https://twitter.com/mysql
https://www.linkedin.com/company/mysql
Thank you !
Georgi “Joro” Kodinov
Team Lead,
MySQL Server GeneralTeam
Georgi.Kodinov@oracle.com
31 © 2019 Oracle

PLe19 How To Instrument Your Code in performance_schema

  • 1.
    Georgi Kodinov Team Lead,MySQL server general team How to Instrument Your Code in MySQL Performance Schema © 2019 Oracle1
  • 2.
    Safe harbor statement Thefollowing is intended to outline our general product direction. It is intended for information purposes only, and may not be incorporated into any contract. It is not a commitment to deliver any material, code, or functionality, and should not be relied upon in making purchasing decisions. The development, release, timing, and pricing of any features or functionality described for Oracle’s products may change and remains at the sole discretion of Oracle Corporation. 2 © 2019 Oracle
  • 3.
    Topics Covered Why shouldI instrument my code ? How do I go about instrumenting it ? Mechanics of instrumentation PERFORMANCE_SCHEMA: not just about performance © 2019 Oracle3
  • 4.
    Why should Iinstrument my code ? • Understand what resources it uses: • memory, locks, time, files, etc. • More debuggable • Provides extra insight into code operation and issues • Expose extra volatile information to users and administrators • Make your code more portable © 2019 Oracle4
  • 5.
    How do Iinstrument my code ? Contribute data to the instruments provided Future: add your own instruments © 2019 Oracle5
  • 6.
    Most of thetimes it’sTHAT easy ! #include <pthread.h> pthread_mutex_t foo; void do_something() { pthread_mutex_lock(&foo); ... pthread_mutex_unlock(&foo); } #include "mysql/psi/mysql_mutex.h“ mysql_mutex_t foo; void do_something() { mysql_mutex_lock(&foo); ... mysql_mutex_unlock(&foo); } © 2019 Oracle6
  • 7.
    Extra step: registeryour objects #ifdef HAVE_PSI_MUTEX_INTERFACE PSI_mutex_key mutex_key_foo = PSI_NOT_INSTRUMENTED; static PSI_mutex_info all_mutexes[]= { { &mutex_key_foo, "LOCK_foo", PSI_FLAG_SINGLETON, 0, "example doc"}, .. } .. count = static_cast<int>(array_elements(all_mutexes)); mysql_mutex_register(“category_foo”, all_mutexes, count); .. mysql_mutex_init(mutex_key_foo, &foo, MY_MUTEX_INIT_FAST); #endif /* HAVE_PSI_MUTEX_INTERFACE */ © 2019 Oracle7
  • 8.
    Instrumentation inventory: inlinefunctions • POSIX threads • POSIX conditions • POSIX mutexes • POSIX read/write locks • POSIX sockets • Buffered and unbuffered file I/O • MySQL stages • MySQL metadata locks mysql_thread.h mysql_cond.h mysql_mutex.h mysql_rwlock.h mysql_socket.h mysql_file.h mysql_stage.h mysql_mdl.h © 2019 Oracle8
  • 9.
    How do Iinstrument my memory use ? #include <stdlib.h> void *foo; void do_something() { foo = malloc(12); ... free(foo); } #include "mysys.h“ void *foo; void do_something() { foo = my_malloc(mem_key_foo, 12, MYF(0)); ... my_free(foo); } © 2019 Oracle9
  • 10.
    Extra step: registeryour objects #ifdef HAVE_PSI_MEMORY_INTERFACE PSI_memory_key mem_key_foo = PSI_NOT_INSTRUMENTED; static PSI_memory_info all_memory[] = { {&mem_key_foo, “FOO", PSI_FLAG_ONLY_GLOBAL_STAT, 0, "example doc"}}; … count = static_cast<int>(array_elements(all_memory)); mysql_memory_register(category, all_memory, count); #endif /* HAVE_PSI_MEMORY_INTERFACE */ © 2019 Oracle10
  • 11.
    Instrumentation inventory: memory •Plugin service implemented in mysys: my_malloc(), my_free(), my_memdup() etc. • Static mysys inspired library to link with components: just my_malloc() and my_free() include/mysql/service_mysql_alloc.h components/library_mysys/my_memory.h © 2019 Oracle11
  • 12.
    Instrumenting other stuff:utility macros #include <mysql/psi/mysql_idle.h> … PSI_idle_locker *m_idle_psi = NULL; PSI_idle_locker_state m_idle_state; … MYSQL_START_IDLE_WAIT(m_idle_psi, &m_idle_state); … MYSQL_END_IDLE_WAIT(m_idle_psi); … © 2019 Oracle12
  • 13.
    Instrumentation inventory: utilitymacros • Transactions • Table locks • “System” (currently shared objects) • Statements • Stored programs • Prepared statements • MySQL stages • Errors • Data locks  Idle mysql_transaction.h mysql_table.h mysql_system.h mysql_statement.h mysql_sp.h mysql_ps.h mysql_stage.h mysql_error.h mysql_data_lock.h mysql_idle.h © 2019 Oracle13
  • 14.
    Mechanics of codeinstrumentation Under the hood © 2019 Oracle14
  • 15.
    Calling instrumentation: PSI_*_CALLmacros • Server code: direct call • #define PSI_FILE_CALL(M) pfs_##M##_v1 • Plugins: function pointer • #define PSI_FILE_CALL(M) psi_file_service->M • Components: component service handle • #define PSI_FILE_CALL(M) mysql_service_psi_file_v1->M © 2019 Oracle15
  • 16.
    Random thoughts ongood code instrumentation • Always release the artifacts that instruments returned via the intended methods ! • Instrumentation can be costly ! • Consider using component infrastructure © 2019 Oracle16
  • 17.
    Performance Schema Not justabout performance ! © 2019 Oracle17
  • 18.
    PERFORMANCE_SCHEMA: Not justperformance ! • Started as performance instrumentation. Still does it ! • Grown into general storage for fast-changing volatile data • System variables • Connection attributes • Replication, innodb state • Now supports adding new tables from components © 2019 Oracle18
  • 19.
    Add a PERFORMANCE_SCHEMAtable From a component © 2019 Oracle19
  • 20.
    Step 1:The data ©2019 Oracle20
  • 21.
    Step 2: Basictable APIs © 2019 Oracle21
  • 22.
    Step 3: Dataretrieval © 2019 Oracle22
  • 23.
    Step 4: Componentcode © 2019 Oracle23
  • 24.
    How it drives ©2019 Oracle24
  • 25.
    Let’s look atthe table © 2019 Oracle25
  • 26.
    Where to gofrom here ? • MySQL Internals Doxygen: https://dev.mysql.com/doc/dev/mysql- server/latest/PAGE_PFS.html • Reference Manual: https://dev.mysql.com/doc/refman/8.0/en/performance- schema.html © 2019 Oracle26
  • 27.
  • 28.
    Copyright © 2019Oracle and/or its affiliates.28 Meet the MySQL Team at the Conference Sunny Bains Luis Soares Kenny Gryp Frédéric Descamps Dimitri Kravtchuk Ståle Deraas Pedro Gomes Geir HøydalsvikNorvald Ryeng Georgi Kodinov
  • 29.
    Join us onMySQL Community Slack Copyright © 2019 Oracle and/or its affiliates.29 https://lefred.be/mysql-community-on-slack/
  • 30.
    Follow us onSocial Media Copyright © 2019 Oracle and/or its affiliates.30 https://www.facebook.com/mysql https://twitter.com/mysql https://www.linkedin.com/company/mysql
  • 31.
    Thank you ! Georgi“Joro” Kodinov Team Lead, MySQL Server GeneralTeam Georgi.Kodinov@oracle.com 31 © 2019 Oracle