-
Daogang Qu authored
Problem ======= When 'UNINSTALL PLUGIN' and 'START GROUP_REPLICATION' command runs in parallel, there is a crash caused by trying to destroy a locked mutex. Analysis ======== The problem can be caused by the following scenario: Step1: The 'UNINSTALL PLUGIN' thread holds the plugin_running_mutex to stop GROUP_REPLICATION, then switch the execution to 'START GROUP_REPLICATION' thread. Step2: The 'START GROUP_REPLICATION' thread waits before acquiring the plugin_running_mutex, then switch the execution to 'UNINSTALL PLUGIN' thread. Step3: The 'UNINSTALL PLUGIN' thread releases the plugin_running_mutex after stopping GROUP_REPLICATION, then switch the execution to 'START GROUP_REPLICATION' thread. Step4: The 'START GROUP_REPLICATION' thread holds the plugin_running_mutex to start GROUP_REPLICATION, then switch the execution to 'UNINSTALL PLUGIN' thread. Step5. The 'UNINSTALL PLUGIN' thread destroys the plugin_running_mutex locked by the 'START GROUP_REPLICATION' thread. The 'UNINSTALL PLUGIN' thread calls group_replication_cleanup() to stop GROUP_REPLICATION and set group_replication_handler to NULL. The 'START GROUP_REPLICATION' thread calls group_replication_start() to start GROUP_REPLICATION if group_replication_handler is not NULL. To avoid above problem, the executions of group_replication_cleanup() and group_replication_start() must be mutual exclusive. Fix === To fix the problem, introduce a new global mutual lock to make the executions of group replication plugin handler function accessors be mutual exclusive.
Daogang Qu authoredProblem ======= When 'UNINSTALL PLUGIN' and 'START GROUP_REPLICATION' command runs in parallel, there is a crash caused by trying to destroy a locked mutex. Analysis ======== The problem can be caused by the following scenario: Step1: The 'UNINSTALL PLUGIN' thread holds the plugin_running_mutex to stop GROUP_REPLICATION, then switch the execution to 'START GROUP_REPLICATION' thread. Step2: The 'START GROUP_REPLICATION' thread waits before acquiring the plugin_running_mutex, then switch the execution to 'UNINSTALL PLUGIN' thread. Step3: The 'UNINSTALL PLUGIN' thread releases the plugin_running_mutex after stopping GROUP_REPLICATION, then switch the execution to 'START GROUP_REPLICATION' thread. Step4: The 'START GROUP_REPLICATION' thread holds the plugin_running_mutex to start GROUP_REPLICATION, then switch the execution to 'UNINSTALL PLUGIN' thread. Step5. The 'UNINSTALL PLUGIN' thread destroys the plugin_running_mutex locked by the 'START GROUP_REPLICATION' thread. The 'UNINSTALL PLUGIN' thread calls group_replication_cleanup() to stop GROUP_REPLICATION and set group_replication_handler to NULL. The 'START GROUP_REPLICATION' thread calls group_replication_start() to start GROUP_REPLICATION if group_replication_handler is not NULL. To avoid above problem, the executions of group_replication_cleanup() and group_replication_start() must be mutual exclusive. Fix === To fix the problem, introduce a new global mutual lock to make the executions of group replication plugin handler function accessors be mutual exclusive.
Loading