== Introduction == MySQL interfaces with TokuDB through a set of plugins, which, at the time of this writing (October 2011) includes the tokudb storage engine plugin, the user data information schema plugin, and the user data exact information schema plugin. Each plugin provides initialize and de-initialize functions for mysql to call when they are installed or uninstalled by clients. == Problem == It was originally discovered that the two information schema plugins would crash if the tokudb storage engine failed to init properly. The information plugins depend on the storage engine plugin, so a quick fix for this problem was to have the storage engine plugin's init function set a global flag if it failed. The information schema plugins could first check this flag before proceeding. This fixed the original problem, but the following still remain: * a client connects, uninstalls tokudb storage engine, accesses the tokudb user data/exact table. * uninstall the tokudb engine plugin, drop a table, select from it to see that it does not exist, then install the tokudb engine to see that it has reappeared. * any situation where one client is using any plugin while another client modifies one. == Proposed solution == Use a flag, call it tokudb_hton_initialized, that is set if the storage engine's init function suceeds. The information schema plugins will check that this flag is set before proceeding. To protect against client race conditions, use a reader-writer lock to protect the flag. Any clients which depend on the status of the flag grab a read lock. Clients that change the status of the flag grab a write lock. Using this flag and a protecting reader-writer lock, we can ensure that no client is under the assumption that the handlerton is usable while it is not, due to failure or uninstallation, etc. == Implementation == {{{ #!c static int tokudb_hton_initialized; // grab a write lock when changing the // hton_init flag tokudb_init_func() { grab_hton_init_writelock(); ... tokudb_hton_initialized = 1; error: release_hton_init_writelock(); } tokudb_end() { grab_hton_init_writelock(); assert(tokudb_hton_initialized); ... tokudb_hton_initialized = 0; release_hton_init_writelock(); } // grab a read lock while assuming // the handlerton is usable // // same thing for user_data_exact tokudb_user_data_fill() { grab_hton_init_readlock(); if (!tokudb_hton_initialized) { // error } else { // fill the user data table } release_hton_init_readlock(); } }}}