Extending MySQL using the Component Infrastructure – part 12: instrument your code

Mysql

This post is the twelfth one of a series of articles on extending MySQL with the Component Infrastructure:

Extending MySQL using the Component Infrastructure – part 1Extending MySQL using the Component Infrastructure – part 2: building the serverExtending MySQL using the Component Infrastructure – part 3: component servicesExtending MySQL using the Component Infrastructure – part 4: error loggingExtending MySQL using the Component Infrastructure – part 5: privilegesExtending MySQL using the Component Infrastructure – part 6: functionsExtending MySQL using the Component Infrastructure – part 7: messages to usersExtending MySQL using the Component Infrastructure – part 8: linking a third party libraryExtending MySQL using the Component Infrastructure – part 9: adding a new functionExtending MySQL using the Component Infrastructure – part 10: status variablesExtending MySQL using the Component Infrastructure – part 11: performance_schema tableExtending MySQL using the Component Infrastructure – part 12: instrument your code

We already saw multiple services to create our component. Now, our virus scan component is complete and works as expected.

However, when you create extension to the MySQL Server, it’s also a good practice to add instrumentation to your code. This will help you to understand what is your code doing and how it performs in MySQL.

This is exactly what we will add today to our component.

The new code is on the branch par12 of this GitHub repository: https://github.com/lefred/mysql-component-viruscan.

We starts by replacing the mutex we used for our table in Performance_Schema (see part 11) from native_mutex_t to mysql_mutex_t.

And we will use REQUIRES_MYSQL_MUTEX_SERVICE_PLACEHOLDER (line 61 of scan.h) . We also need to add it in the requirements of our component (line 485 of scan.cc)

Then we define the new mutex key and information that will be used in MySQL Performance Schema on line 52 to 56 of scan.cc:

PSI_mutex_key key_mutex_virus_data = 0;
PSI_mutex_info virus_data_mutex[] = {
{&key_mutex_virus_data, “virus_scan_data”,
PSI_FLAG_SINGLETON, PSI_VOLATILITY_PERMANENT,
“Virus scan data, permanent mutex, singleton.”}
};

Something very important is to not forget the registration of the mutex (this was not required with the native_mutex_t type) when initializing the component. Otherwise nothing will work as expected.

This is exactly what we do in viruscan_service_init() on line 372 of scan.cc:

mysql_mutex_register(“virus_scan”, virus_data_mutex, 1);

We will add a “bug” that when triggered we will spend 5 seconds waiting with the lock acquired to create some contention in case of another session tries to also scan data triggering that bug at the same time.

This fake bug is triggered by the string “bug-struck” and it’s coded from line 214 to 221 in scan.cc:

//just a fake bug
if (strcmp(data, “bug-stuck”) == 0) {
mysql_mutex_lock(&LOCK_virus_data);
LogComponentErr(INFORMATION_LEVEL, ER_LOG_PRINTF_MSG,
“Generating a bug to spend time in mutex”);
my_sleep(5000000); // 5.0s
mysql_mutex_unlock(&LOCK_virus_data);
}

We also print a message in MySQL’s error log.

Let’s see all this in action in performance_schema tables setup_instruments and events_waits_history:

session 1

And meanwhile into another session:

session 2

Summary

If you are looking for what can be instrumented this is the current list of available instrumentation: PFS_PSI_LIST.

We have now covered most of the main component services to create that can be used to create our own component.

I hope you enjoyed this journey and I’m curious to see the components you will created. Please share them with me !

And as usual, enjoy MySQL and happy coding !