1 /*
2 Copyright (c) 2013, 2021, Oracle and/or its affiliates.
3
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License, version 2.0,
6 as published by the Free Software Foundation.
7
8 This program is also distributed with certain software (including
9 but not limited to OpenSSL) that is licensed under separate terms,
10 as designated in a particular file or component or in included license
11 documentation. The authors of MySQL hereby grant you an additional
12 permission to link the program and your derivative works with the
13 separately licensed software that they have included with MySQL.
14
15 This program is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU General Public License, version 2.0, for more details.
19
20 You should have received a copy of the GNU General Public License
21 along with this program; if not, write to the Free Software
22 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
23
24 /**
25 @file storage/perfschema/table_replication_group_members.cc
26 Table replication_group_members (implementation).
27 */
28
29 #define HAVE_REPLICATION
30
31 #include "my_global.h"
32 #include "table_replication_group_members.h"
33 #include "pfs_instr_class.h"
34 #include "pfs_instr.h"
35 #include "log.h"
36 #include "rpl_group_replication.h"
37
38 /*
39 Callbacks implementation for GROUP_REPLICATION_GROUP_MEMBERS_CALLBACKS.
40 */
set_channel_name(void * const context,const char & value,size_t length)41 static void set_channel_name(void* const context, const char& value,
42 size_t length)
43 {
44 struct st_row_group_members* row=
45 static_cast<struct st_row_group_members*>(context);
46 const size_t max= CHANNEL_NAME_LENGTH;
47 length= std::min(length, max);
48
49 row->channel_name_length= length;
50 memcpy(row->channel_name, &value, length);
51 }
52
set_member_id(void * const context,const char & value,size_t length)53 static void set_member_id(void* const context, const char& value,
54 size_t length)
55 {
56 struct st_row_group_members* row=
57 static_cast<struct st_row_group_members*>(context);
58 const size_t max= UUID_LENGTH;
59 length= std::min(length, max);
60
61 row->member_id_length= length;
62 memcpy(row->member_id, &value, length);
63 }
64
set_member_host(void * const context,const char & value,size_t length)65 static void set_member_host(void* const context, const char& value,
66 size_t length)
67 {
68 struct st_row_group_members* row=
69 static_cast<struct st_row_group_members*>(context);
70 const size_t max= HOSTNAME_LENGTH;
71 length= std::min(length, max);
72
73 row->member_host_length= length;
74 memcpy(row->member_host, &value, length);
75 }
76
set_member_port(void * const context,unsigned int value)77 static void set_member_port(void* const context, unsigned int value)
78 {
79 struct st_row_group_members* row=
80 static_cast<struct st_row_group_members*>(context);
81 row->member_port= value;
82 }
83
set_member_state(void * const context,const char & value,size_t length)84 static void set_member_state(void* const context, const char& value,
85 size_t length)
86 {
87 struct st_row_group_members* row=
88 static_cast<struct st_row_group_members*>(context);
89 const size_t max= NAME_LEN;
90 length= std::min(length, max);
91
92 row->member_state_length= length;
93 memcpy(row->member_state, &value, length);
94 }
95
96
97 THR_LOCK table_replication_group_members::m_table_lock;
98
99 /* Numbers in varchar count utf8 characters. */
100 static const TABLE_FIELD_TYPE field_types[]=
101 {
102 {
103 {C_STRING_WITH_LEN("CHANNEL_NAME")},
104 {C_STRING_WITH_LEN("char(64)")},
105 {NULL, 0}
106 },
107 {
108 {C_STRING_WITH_LEN("MEMBER_ID")},
109 {C_STRING_WITH_LEN("char(36)")},
110 {NULL, 0}
111 },
112 {
113 {C_STRING_WITH_LEN("MEMBER_HOST")},
114 {C_STRING_WITH_LEN("char(60)")},
115 {NULL, 0}
116 },
117 {
118 {C_STRING_WITH_LEN("MEMBER_PORT")},
119 {C_STRING_WITH_LEN("int(11)")},
120 {NULL, 0}
121 },
122 {
123 {C_STRING_WITH_LEN("MEMBER_STATE")},
124 {C_STRING_WITH_LEN("char(64)")},
125 {NULL, 0}
126 }
127 };
128
129 TABLE_FIELD_DEF
130 table_replication_group_members::m_field_def=
131 { 5, field_types };
132
133 PFS_engine_table_share
134 table_replication_group_members::m_share=
135 {
136 { C_STRING_WITH_LEN("replication_group_members") },
137 &pfs_readonly_acl,
138 &table_replication_group_members::create,
139 NULL, /* write_row */
140 NULL, /* delete_all_rows */
141 table_replication_group_members::get_row_count,
142 sizeof(PFS_simple_index), /* ref length */
143 &m_table_lock,
144 &m_field_def,
145 false, /* checked */
146 false /* perpetual */
147 };
148
create(void)149 PFS_engine_table* table_replication_group_members::create(void)
150 {
151 return new table_replication_group_members();
152 }
153
table_replication_group_members()154 table_replication_group_members::table_replication_group_members()
155 : PFS_engine_table(&m_share, &m_pos),
156 m_row_exists(false), m_pos(0), m_next_pos(0)
157 {}
158
~table_replication_group_members()159 table_replication_group_members::~table_replication_group_members()
160 {}
161
reset_position(void)162 void table_replication_group_members::reset_position(void)
163 {
164 m_pos.m_index= 0;
165 m_next_pos.m_index= 0;
166 }
167
get_row_count()168 ha_rows table_replication_group_members::get_row_count()
169 {
170 return get_group_replication_members_number_info();
171 }
172
rnd_next(void)173 int table_replication_group_members::rnd_next(void)
174 {
175 if (!is_group_replication_plugin_loaded())
176 return HA_ERR_END_OF_FILE;
177
178 for (m_pos.set_at(&m_next_pos);
179 m_pos.m_index < get_row_count();
180 m_pos.next())
181 {
182 make_row(m_pos.m_index);
183 m_next_pos.set_after(&m_pos);
184 return 0;
185 }
186
187 return HA_ERR_END_OF_FILE;
188 }
189
rnd_pos(const void * pos)190 int table_replication_group_members::rnd_pos(const void *pos)
191 {
192 if (!is_group_replication_plugin_loaded())
193 return HA_ERR_END_OF_FILE;
194
195 set_position(pos);
196 assert(m_pos.m_index < get_row_count());
197 make_row(m_pos.m_index);
198
199 return 0;
200 }
201
make_row(uint index)202 void table_replication_group_members::make_row(uint index)
203 {
204 DBUG_ENTER("table_replication_group_members::make_row");
205 // Set default values.
206 m_row_exists= false;
207 m_row.channel_name_length= 0;
208 m_row.member_id_length= 0;
209 m_row.member_host_length= 0;
210 m_row.member_port= 0;
211 m_row.member_state_length= 0;
212
213 // Set callbacks on GROUP_REPLICATION_GROUP_MEMBERS_CALLBACKS.
214 const GROUP_REPLICATION_GROUP_MEMBERS_CALLBACKS callbacks=
215 {
216 &m_row,
217 &set_channel_name,
218 &set_member_id,
219 &set_member_host,
220 &set_member_port,
221 &set_member_state,
222 };
223
224 // Query plugin and let callbacks do their job.
225 if (get_group_replication_group_members_info(index, callbacks))
226 {
227 DBUG_PRINT("info", ("Group Replication stats not available!"));
228 }
229 else
230 {
231 m_row_exists= true;
232 }
233
234 DBUG_VOID_RETURN;
235 }
236
237
read_row_values(TABLE * table,unsigned char * buf,Field ** fields,bool read_all)238 int table_replication_group_members::read_row_values(TABLE *table,
239 unsigned char *buf,
240 Field **fields,
241 bool read_all)
242 {
243 Field *f;
244
245 if (unlikely(! m_row_exists))
246 return HA_ERR_RECORD_DELETED;
247
248 assert(table->s->null_bytes == 1);
249 buf[0]= 0;
250
251 for (; (f= *fields) ; fields++)
252 {
253 if (read_all || bitmap_is_set(table->read_set, f->field_index))
254 {
255 switch(f->field_index)
256 {
257 case 0: /** channel_name */
258 set_field_char_utf8(f, m_row.channel_name, m_row.channel_name_length);
259 break;
260 case 1: /** member_id */
261 set_field_char_utf8(f, m_row.member_id, m_row.member_id_length);
262 break;
263 case 2: /** member_host */
264 set_field_char_utf8(f, m_row.member_host, m_row.member_host_length);
265 break;
266 case 3: /** member_port */
267 if (m_row.member_port > 0)
268 set_field_ulong(f, m_row.member_port);
269 else
270 f->set_null();
271 break;
272 case 4: /** member_state */
273 set_field_char_utf8(f, m_row.member_state, m_row.member_state_length);
274 break;
275 default:
276 assert(false);
277 }
278 }
279 }
280 return 0;
281 }
282