This document is posted to help you gain knowledge. Please leave a comment to let me know what you think about it! Share it to your friends and learn new things together.
• There’s a bunch of great interfaces in to the MySQL Server now, from the well known storage engines, through pre/post parser plugins, auditing, full text search, INFORMATION_SCHEMA tables, UDFs, replication interfaces, and more.. • We’ve made great strides in instrumenting the core server, but if
you want to use plugins, and don’t also add to the instrumentation in the new standard ways, this will cause new black holes in your available performance data
• The main interface is within ./include/mysql/psi/ • The ABI is maintained via ./include/mysql/psi/psi.h • Great Doxygen based docs here: • https://dev.mysql.com/doc/dev/mysql-server/8.0.0/PAGE_PFS_PSI.html
• The API is broken down by the type of instrumentation • Threads, sync points (mutexes, rwlocks, conditions etc.) in
include/mysql/psi/mysql_thread.h • File IO in include/mysql/psi/mysql_file.h • Memory in include/mysql/psi/mysql_memory.h • Network IO in include/mysql/psi/mysql_socket.h
• These all use the underlying versioned performance schema interfaces via the psi.h ABI
• Now you know where you may be waiting for thread synchronisation or file IO (or network IO, I won’t talk about that here, look at the API if you’re doing some Daemon plugin) • You can track more major sections of code with Stages - the thread
states that exposed via process lists and profiling interfaces • API is within include/mysql/psi/mysql_stage.h
An Example - Stagesstatic int client_error_log_open() { mysql_set_stage(opening_client_error_log_file.m_key); mysql_mutex_lock(&LOCK_client_error_log); /* Open the file, maybe write some header */
return 0; }
static int client_error_notify(…) { … if (error_event->event_subclass == MYSQL_AUDIT_GENERAL_ERROR) { mysql_set_stage(recording_error_statistics.m_key); /* Update stats, write log file etc. */ } return 0; }
• Note that when adding stages, you are hijacking the current stage • Think about where in the flow your stage can be added • Consider adding a “continuation” stage • This can show code executed after your plugin (or face the blame
• You can also track progress of stages within 5.7+ • Call mysql_set_stage(…) • Then mysql_stage_set_work_estimated(<stage>, <estimate count>) • Then while doing the estimated work, at the right interval: • mysql_stage_set_work_completed(<stage>, <completed count>);
( SELECT thread_id, nesting_event_id, event_id, event_name, sys.format_time(timer_wait) AS time FROM performance_schema.events_stages_history_long ORDER BY event_id )
UNION ALL ( SELECT thread_id, nesting_event_id, event_id, concat('-> ', event_name), sys.format_time(timer_wait) AS time FROM performance_schema.events_waits_history_long WHERE event_name != 'idle' ORDER BY event_id )
ORDER BY thread_id, event_id; +-----------+------------------+----------+--------------------------------------------------------+-----------+ | thread_id | nesting_event_id | event_id | event_name | time |
The preceding 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, and timing of any features or functionality described for Oracle’s products remains at the sole discretion of Oracle.