MySQL 5.6.14 Source Code Document
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
Performance schema: instrumentation interface page.

MySQL performance schema instrumentation interface.

Introduction

The instrumentation interface consist of two layers:

  • a raw ABI (Application Binary Interface) layer, that exposes the primitive instrumentation functions exported by the performance schema instrumentation
  • an API (Application Programing Interface) layer, that provides many helpers for a developer instrumenting some code, to make the instrumentation as easy as possible.

The ABI layer consists of:

#include "mysql/psi/psi.h"

The API layer consists of:

#include "mysql/psi/mutex_mutex.h"
#include "mysql/psi/mutex_file.h"

The first helper is for mutexes, rwlocks and conditions, the second for file io.

The API layer exposes C macros and typedefs which will expand:

  • either to non-instrumented code, when compiled without the performance schema instrumentation
  • or to instrumented code, that will issue the raw calls to the ABI layer so that the implementation can collect data.

Note that all the names introduced (for example, mysql_mutex_lock) do not collide with any other namespace. In particular, the macro mysql_mutex_lock is on purpose not named pthread_mutex_lock. This is to:

  • avoid overloading pthread_mutex_lock with yet another macro, which is dangerous as it can affect user code and pollute the end-user namespace.
  • allow the developer instrumenting code to selectively instrument some code but not all.

Design principles

The ABI part is designed as a facade, that exposes basic primitives. The expectation is that each primitive will be very stable over time, but the list will constantly grow when more instruments are supported. To support binary compatibility with plugins compiled with a different version of the instrumentation, the ABI itself is versioned (see PSI_v1, PSI_v2).

For a given instrumentation point in the API, the basic coding pattern used is:

  • (a) notify the performance schema of the operation about to be performed.
  • (b) execute the instrumented code.
  • (c) notify the performance schema that the operation is completed.

An opaque "locker" pointer is returned by (a), that is given to (c). This pointer helps the implementation to keep context, for performances.

The following code fragment is annotated to show how in detail this pattern in implemented, when the instrumentation is compiled in:

static inline int mysql_mutex_lock(
  mysql_mutex_t *that, myf flags, const char *src_file, uint src_line)
{
  int result;
  struct PSI_mutex_locker_state state;
  struct PSI_mutex_locker *locker= NULL;

  ............... (a)
  locker= PSI_server->start_mutex_wait(&state, that->p_psi,
                                       PSI_MUTEX_LOCK, locker, src_file, src_line);

  ............... (b)
  result= pthread_mutex_lock(&that->m_mutex);

  ............... (c)
  PSI_server->end_mutex_wait(locker, result);

  return result;
}

When the performance schema instrumentation is not compiled in, the code becomes simply a wrapper, expanded in line by the compiler:

static inline int mysql_mutex_lock(...)
{
  int result;

  ............... (b)
  result= pthread_mutex_lock(&that->m_mutex);

  return result;
}