// execute the increment_transactions_waiting_apply logic of the start operation execution from the node // Execute start operation from node -- 20 Aug 2022 20:07:32 -- thread A group_replication.so!Pipeline_stats_member_collector::increment_transactions_waiting_apply(Pipeline_stats_member_collector * const this) (/source_code/mysql-8.0.27/plugin/group_replication/src/pipeline_stats.cc:352) group_replication.so!Applier_handler::handle_event(Applier_handler * const this, Pipeline_event * event, Continuation * cont) (/source_code/mysql-8.0.27/plugin/group_replication/src/handlers/applier_handler.cc:132) group_replication.so!Event_handler::next(Event_handler * const this, Pipeline_event * event, Continuation * continuation) (/source_code/mysql-8.0.27/plugin/group_replication/include/pipeline_interfaces.h:769) group_replication.so!Certification_handler::inject_transactional_events(Certification_handler * const this, Pipeline_event * pevent, Gtid * gtid, Continuation * cont) (/source_code/mysql-8.0.27/plugin/group_replication/src/handlers/certification_handler.cc:697) group_replication.so!Certification_handler::log_view_change_event_in_order(Certification_handler * const this, Pipeline_event * view_pevent, std::string & local_gtid_string, Gtid * gtid, Continuation * cont) (/source_code/mysql-8.0.27/plugin/group_replication/src/handlers/certification_handler.cc:818) group_replication.so!Certification_handler::extract_certification_info(Certification_handler * const this, Pipeline_event * pevent, Continuation * cont) (/source_code/mysql-8.0.27/plugin/group_replication/src/handlers/certification_handler.cc:529) group_replication.so!Certification_handler::handle_event(Certification_handler * const this, Pipeline_event * pevent, Continuation * cont) (/source_code/mysql-8.0.27/plugin/group_replication/src/handlers/certification_handler.cc:129) group_replication.so!Event_handler::next(Event_handler * const this, Pipeline_event * event, Continuation * continuation) (/source_code/mysql-8.0.27/plugin/group_replication/include/pipeline_interfaces.h:769) group_replication.so!Event_cataloger::handle_event(Event_cataloger * const this, Pipeline_event * pevent, Continuation * cont) (/source_code/mysql-8.0.27/plugin/group_replication/src/handlers/event_cataloger.cc:53) group_replication.so!Applier_module::inject_event_into_pipeline(Applier_module * const this, Pipeline_event * pevent, Continuation * cont) (/source_code/mysql-8.0.27/plugin/group_replication/src/applier.cc:235) group_replication.so!Applier_module::apply_view_change_packet(Applier_module * const this, View_change_packet * view_change_packet, Format_description_log_event * fde_evt, Continuation * cont) (/source_code/mysql-8.0.27/plugin/group_replication/src/applier.cc:317) // applier main loop group_replication.so!Applier_module::applier_thread_handle(Applier_module * const this) (/source_code/mysql-8.0.27/plugin/group_replication/src/applier.cc:486) group_replication.so!launch_handler_thread(void * arg) (/source_code/mysql-8.0.27/plugin/group_replication/src/applier.cc:50) pfs_spawn_thread(void * arg) (/source_code/mysql-8.0.27/storage/perfschema/pfs.cc:2946) libpthread.so.0!start_thread (未知源:0) libc.so.6!clone (未知源:0) // decrement_transactions_waiting_apply logic that executes the start operation from the node // execute decrement_transactions_waiting_apply -- thread B group_replication.so!Pipeline_stats_member_collector::decrement_transactions_waiting_apply(Pipeline_stats_member_collector * const this) (/source_code/mysql-8.0.27/plugin/group_replication/src/pipeline_stats.cc:358) group_replication.so!Recovery_module::wait_for_applier_module_recovery(Recovery_module * const this) (/source_code/mysql-8.0.27/plugin/group_replication/src/recovery.cc:549) group_replication.so!Recovery_module::recovery_thread_handle(Recovery_module * const this) (/source_code/mysql-8.0.27/plugin/group_replication/src/recovery.cc:326) group_replication.so!launch_handler_thread(void * arg) (/source_code/mysql-8.0.27/plugin/group_replication/src/recovery.cc:48) pfs_spawn_thread(void * arg) (/source_code/mysql-8.0.27/storage/perfschema/pfs.cc:2946) libpthread.so.0!start_thread (未知源:0) libc.so.6!clone (未知源:0) // Parent thread of the above operation -- thread C libpthread.so.0!pthread_create@@GLIBC_2.2.5 (未知源:0) my_thread_create(my_thread_handle * thread, const my_thread_attr_t * attr, my_start_routine func, void * arg) (/source_code/mysql-8.0.27/mysys/my_thread.cc:80) pfs_spawn_thread_vc(PSI_thread_key key, PSI_thread_seqnum seqnum, my_thread_handle * thread, const my_thread_attr_t * attr, void *(*)(void *) start_routine, void * arg) (/source_code/mysql-8.0.27/storage/perfschema/pfs.cc:2997) group_replication.so!inline_mysql_thread_create(PSI_thread_key key, unsigned int sequence_number, my_thread_handle * thread, const my_thread_attr_t * attr, my_start_routine start_routine, void * arg) (/source_code/mysql-8.0.27/include/mysql/psi/mysql_thread.h:139) group_replication.so!Recovery_module::start_recovery(Recovery_module * const this, const std::string & group_name, const std::string & rec_view_id) (/source_code/mysql-8.0.27/plugin/group_replication/src/recovery.cc:85) group_replication.so!Plugin_gcs_events_handler::handle_joining_members(const Plugin_gcs_events_handler * const this, const Gcs_view & new_view, bool is_joining, bool is_leaving) (/source_code/mysql-8.0.27/plugin/group_replication/src/gcs_event_handlers.cc:986) group_replication.so!Plugin_gcs_events_handler::on_view_changed(const Plugin_gcs_events_handler * const this, const Gcs_view & new_view, const Exchanged_data & exchanged_data) (/source_code/mysql-8.0.27/plugin/group_replication/src/gcs_event_handlers.cc:699) group_replication.so!Gcs_xcom_control::install_view(Gcs_xcom_control * const this, Gcs_xcom_view_identifier * new_view_id, const Gcs_group_identifier & group, std::map, std::allocator > > * states, std::set, std::allocator > * total, std::set, std::allocator > * left, std::set, std::allocator > * join, Gcs_view::Gcs_view_error_code error_code) (/source_code/mysql-8.0.27/plugin/group_replication/libmysqlgcs/src/bindings/xcom/gcs_xcom_control_interface.cc:1786) group_replication.so!Gcs_xcom_control::process_control_message(Gcs_xcom_control * const this, Gcs_message * msg, Gcs_protocol_version maximum_supported_protocol_version, Gcs_protocol_version used_protocol_version) (/source_code/mysql-8.0.27/plugin/group_replication/libmysqlgcs/src/bindings/xcom/gcs_xcom_control_interface.cc:1684) group_replication.so!do_cb_xcom_receive_data_state_exchange(, , Gcs_xcom_communication &, Gcs_xcom_control &)( packet, xcom_nodes, Gcs_xcom_communication & xcom_communication, Gcs_xcom_control & xcom_control) (/source_code/mysql-8.0.27/plugin/group_replication/libmysqlgcs/src/bindings/xcom/gcs_xcom_interface.cc:1380) group_replication.so!do_cb_xcom_receive_data(synode_no message_id, synode_no origin, Gcs_xcom_nodes * xcom_nodes_raw_ptr, synode_no cache_last_removed, u_int size, char * data_raw_ptr) (/source_code/mysql-8.0.27/plugin/group_replication/libmysqlgcs/src/bindings/xcom/gcs_xcom_interface.cc:1480) group_replication.so!Data_notification::do_execute(Data_notification * const this) (/source_code/mysql-8.0.27/plugin/group_replication/libmysqlgcs/src/bindings/xcom/gcs_xcom_notification.cc:81) group_replication.so!Parameterized_notification::operator()(Parameterized_notification * const this) (/source_code/mysql-8.0.27/plugin/group_replication/libmysqlgcs/src/bindings/xcom/gcs_xcom_notification.h:225) // main loop group_replication.so!Gcs_xcom_engine::process(Gcs_xcom_engine * const this) (/source_code/mysql-8.0.27/plugin/group_replication/libmysqlgcs/src/bindings/xcom/gcs_xcom_notification.cc:221) group_replication.so!process_notification_thread(void * ptr_object) (/source_code/mysql-8.0.27/plugin/group_replication/libmysqlgcs/src/bindings/xcom/gcs_xcom_notification.cc:158) pfs_spawn_thread(void * arg) (/source_code/mysql-8.0.27/storage/perfschema/pfs.cc:2946) libpthread.so.0!start_thread (未知源:0) libc.so.6!clone (未知源:0) From the thread debug results: After the start group_replication operation on the slave node, thread A enters the main loop of applier_thread_handle, and then executes function logic such as apply_view_change_packet to apply the view change, Finally, execute increment_transactions_waiting_apply to increment. Causes the m_transactions_remote_applier_queue corresponding to COUNT_TRANSACTIONS_REMOTE_IN_APPLIER_QUEUE to increase from 0 to 1. In the process of thread A performing the appeal operation, thread C of MGR starts, and starts a new thread B, performs recovery operation, and executes decrement_transactions_waiting_apply after completion to perform self-decrement. After decrementing, the m_transactions_remote_applier_queue corresponding to COUNT_TRANSACTIONS_REMOTE_IN_APPLIER_QUEUE will decrease by 1. For the above operations, the normal logic should first perform the auto-increment operation of thread A, and then thread C calls thread B to perform the auto-decrement operation through start_recovery(). Finally, the m_transactions_remote_applier_queue corresponding to COUNT_TRANSACTIONS_REMOTE_IN_APPLIER_QUEUE is 0. But from the above logic, it should be that there is a problem with thread A (or its parent thread) and thread C thread concurrently, which causes thread B to start early, resulting in self-decrease first, and then self-increase. This in turn causes m_transactions_remote_applier_queue to be 1.