1 /* Copyright (c) 2015, 2021, Oracle and/or its affiliates.
2 
3    This program is free software; you can redistribute it and/or modify
4    it under the terms of the GNU General Public License, version 2.0,
5    as published by the Free Software Foundation.
6 
7    This program is also distributed with certain software (including
8    but not limited to OpenSSL) that is licensed under separate terms,
9    as designated in a particular file or component or in included license
10    documentation.  The authors of MySQL hereby grant you an additional
11    permission to link the program and your derivative works with the
12    separately licensed software that they have included with MySQL.
13 
14    This program is distributed in the hope that it will be useful,
15    but WITHOUT ANY WARRANTY; without even the implied warranty of
16    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17    GNU General Public License, version 2.0, for more details.
18 
19    You should have received a copy of the GNU General Public License
20    along with this program; if not, write to the Free Software Foundation,
21    51 Franklin Street, Suite 500, Boston, MA 02110-1335 USA */
22 
23 #include <string>
24 
25 #include "plugin.h"
26 #include "ps_information.h"
27 
28 using std::string;
29 
get_group_members_info(uint index,const GROUP_REPLICATION_GROUP_MEMBERS_CALLBACKS & callbacks,Group_member_info_manager_interface * group_member_manager,char * group_name_pointer,char * channel_name)30 bool get_group_members_info(uint index,
31                             const GROUP_REPLICATION_GROUP_MEMBERS_CALLBACKS& callbacks,
32                             Group_member_info_manager_interface
33                                 *group_member_manager,
34                             char *group_name_pointer,
35                             char *channel_name)
36 {
37   if (channel_name != NULL)
38   {
39     callbacks.set_channel_name(callbacks.context, *channel_name,
40                                strlen(channel_name));
41   }
42 
43   /*
44    This case means that the plugin has never been initialized...
45    and one would not be able to extract information
46    */
47   if (group_member_manager == NULL)
48   {
49     const char* member_state= Group_member_info::get_member_status_string(
50                                   Group_member_info::MEMBER_OFFLINE);
51     callbacks.set_member_state(callbacks.context, *member_state,
52                                strlen(member_state));
53     return false;
54   }
55 
56   size_t number_of_members= group_member_manager->get_number_of_members();
57   if (index >= number_of_members) {
58     /* purecov: begin inspected */
59     if (index != 0) {
60       // No members on view.
61       return true;
62     }
63     /* purecov: end */
64   }
65 
66   Group_member_info* member_info=
67       group_member_manager->get_group_member_info_by_index(index);
68 
69   if(member_info == NULL) // The requested member is not managed...
70   {
71     return true; /* purecov: inspected */
72   }
73 
74   // Get info from view.
75   callbacks.set_member_id(callbacks.context,
76                           *member_info->get_uuid().c_str(),
77                           member_info->get_uuid().length());
78 
79   callbacks.set_member_host(callbacks.context,
80                             *member_info->get_hostname().c_str(),
81                             member_info->get_hostname().length());
82 
83   callbacks.set_member_port(callbacks.context, member_info->get_port());
84 
85   const char* member_state;
86 
87   // override the state if we think it is unreachable
88   if (!member_info->is_unreachable())
89     member_state= Group_member_info::get_member_status_string(
90                                 member_info->get_recovery_status());
91   else
92     member_state= Group_member_info::get_member_status_string(
93                                 Group_member_info::MEMBER_UNREACHABLE);
94 
95   callbacks.set_member_state(callbacks.context, *member_state,
96                              strlen(member_state));
97 
98   delete member_info;
99 
100   return false;
101 }
102 
get_group_member_stats(const GROUP_REPLICATION_GROUP_MEMBER_STATS_CALLBACKS & callbacks,Group_member_info_manager_interface * group_member_manager,Applier_module * applier_module,Gcs_operations * gcs_module,char * group_name_pointer,char * channel_name)103 bool get_group_member_stats(const GROUP_REPLICATION_GROUP_MEMBER_STATS_CALLBACKS& callbacks,
104                             Group_member_info_manager_interface
105                                 *group_member_manager,
106                             Applier_module *applier_module,
107                             Gcs_operations *gcs_module,
108                             char *group_name_pointer,
109                             char *channel_name)
110 {
111   if (group_member_manager != NULL)
112   {
113     char *hostname, *uuid;
114     uint port;
115     unsigned int server_version;
116     st_server_ssl_variables server_ssl_variables=
117       {false,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL};
118 
119     get_server_parameters(&hostname, &port, &uuid, &server_version,
120                           &server_ssl_variables);
121 
122     callbacks.set_member_id(callbacks.context, *uuid, strlen(uuid));
123   }
124 
125   if(channel_name != NULL)
126   {
127     callbacks.set_channel_name(callbacks.context, *channel_name,
128                                strlen(channel_name));
129   }
130 
131   //Retrieve view information
132   Gcs_view *view= gcs_module->get_current_view();
133   if (view != NULL)
134   {
135     const char* view_id_representation=
136         view->get_view_id().get_representation().c_str();
137     callbacks.set_view_id(callbacks.context, *view_id_representation,
138                           strlen(view_id_representation));
139     delete view;
140   }
141 
142   DBUG_EXECUTE_IF("group_replication_get_group_member_stats",
143   {
144     const char act[] =
145         "now signal signal.reached_get_group_member_stats "
146         "wait_for signal.resume_get_group_member_stats";
147     assert(!debug_sync_set_action(current_thd, STRING_WITH_LEN(act)));
148   });
149 
150   //Check if the group replication has started and a valid certifier exists
151   if(!get_plugin_is_stopping() && applier_module != NULL)
152   {
153     Pipeline_member_stats *pipeline_stats= applier_module->get_local_pipeline_stats();
154     if (pipeline_stats != NULL)
155     {
156       std::string last_conflict_free_transaction;
157       pipeline_stats->get_transaction_last_conflict_free(
158          last_conflict_free_transaction);
159       callbacks.set_last_conflict_free_transaction(
160          callbacks.context, *last_conflict_free_transaction.c_str(),
161          last_conflict_free_transaction.length());
162 
163       std::string transaction_committed_all_members;
164       pipeline_stats->get_transaction_committed_all_members(
165          transaction_committed_all_members);
166       callbacks.set_transactions_committed(
167          callbacks.context, *transaction_committed_all_members.c_str(),
168          transaction_committed_all_members.length());
169 
170       /* certification related data */
171       callbacks.set_transactions_conflicts_detected(
172          callbacks.context,
173          pipeline_stats->get_transactions_negative_certified());
174       callbacks.set_transactions_certified(
175          callbacks.context, pipeline_stats->get_transactions_certified());
176       callbacks.set_transactions_rows_in_validation(
177          callbacks.context, pipeline_stats->get_transactions_rows_validating());
178       callbacks.set_transactions_in_queue(
179          callbacks.context,
180          pipeline_stats->get_transactions_waiting_certification());
181 
182       /* clean-up */
183       delete pipeline_stats;
184     }
185   }
186 
187   return false;
188 }
189 
get_connection_status(const GROUP_REPLICATION_CONNECTION_STATUS_CALLBACKS & callbacks,char * group_name_pointer,char * channel_name,bool is_group_replication_running)190 bool get_connection_status(const GROUP_REPLICATION_CONNECTION_STATUS_CALLBACKS& callbacks,
191                            char *group_name_pointer,
192                            char *channel_name,
193                            bool is_group_replication_running)
194 {
195   if (channel_name != NULL)
196   {
197     callbacks.set_channel_name(callbacks.context, *channel_name,
198                                strlen(channel_name));
199   }
200 
201   if (group_name_pointer != NULL)
202   {
203     callbacks.set_group_name(callbacks.context, *group_name_pointer,
204                              strlen(group_name_pointer));
205     callbacks.set_source_uuid(callbacks.context, *group_name_pointer,
206                               strlen(group_name_pointer));
207   }
208 
209   callbacks.set_service_state(callbacks.context,
210                               is_group_replication_running);
211 
212   return false;
213 }
214 
215