In this blog, I will be discussing about handlerton, a model in which MySQL has organised it’s storage engines.
MySQL provides a class ‘handler’, by deriving it’s sub-classes and implementing it’s virtual functions one can write custom storage engines. But there is a limitation to this class, as all operation defined here are specific to one table. Imagine an operation like commit, rollback which would affect all the tables in the database. Such code cannot be put inside the handler class or it’s sub-classes.
Well, all those functionality are exposed as callback function pointers inside the handlerton. It’s a C structure. A singleton for all the handlers in the storage engine. Hence, the name handlerton. One instance per storage engine.
It is defined in sql/handler.h
We won’t be going in details of the handlerton structure. It mainly consists of global paramaters and functions pointers. Like- interface name, name of storage engine, legacy db type, functions for commit, rollback, close connection, savepoint set, alter tablespace, etc.
MySQL plugin implementation provides a nice way to initialize and get the hook on the respective handlerton for the storage engine.
Currently MySQL supports 9 types of plugin. Storage engine being one of them. Check the files sql/plugin.h, sql/sql_plugin.h, sql/sql_plugin.cc
Also, check out the array of function pointers which contains the initialize and de-initialize functions for all plugin types. plugin_type_initialize[ ], plugin_type_deinitialize[ ] (sql_plugin.cc:92, 98)
During plugin initialization phase in function plugin_initialize(),
ha_initialize_handlerton() is called,
sql_plugin.cc:1126: if ((*plugin_type_initialize[plugin->plugin->type])(plugin))
which is responsible for allocating memory and storing the handlerton in the static array defined in sql/handler.cc (static handlerton *installed_htons;)
This static array maintains all the handlertons initialized in the MySQL which includes the pre-installed legacy databases engines and also the custom made dynamically loaded engines.
Check the enum legacy_db_type, sql/handler.h:374
After handlerton initialization, the function st_mysql_plugin::(*init)() is called.
sql_plugin.cc:1145 if (plugin->plugin->init(plugin))
Please note that it is a function pointer, provided at the hand of developer to customize the handlerton object. The developers can write own functions for the global operations declared inside the handlerton structure and assign them to the respective function pointers in this code.
This function pointer (init) is assigned during the plugin declaration, in the macro mysql_declare_plugin(name). mysql_declare_plugin(name) and mysql_declare_plugin_end are implemented using C macros, which internally take cares of many variables – plugin version, size st_mysql_plugin structure, etc. It can be found in sql/plugin.h file.
The whole macro design is worth knowing and something you would like to use in your code. And so is the handlerton pattern.