1/* Copyright (C) 2014 MariaDB Corporation.
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 as published by
5 the Free Software Foundation; version 2 of the License.
6
7 This program is distributed in the hope that it will be useful,
8 but WITHOUT ANY WARRANTY; without even the implied warranty of
9 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 GNU General Public License for more details.
11
12 You should have received a copy of the GNU General Public License
13 along with this program; if not, write to the Free Software
14 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA */
15
16#ifndef MYSQL_SERVER
17#define MYSQL_SERVER
18#endif
19
20#include <my_global.h>
21#include <mysql/plugin.h>
22#include <table.h> /* ST_SCHEMA_TABLE */
23#include <sql_show.h>
24#include <sql_acl.h> /* check_global_access() */
25#include <wsrep_mysqld.h>
26#include <wsrep_utils.h>
27
28/* WSREP_MEMBERSHIP table fields */
29
30/* Node index */
31#define COLUMN_WSREP_MEMB_INDEX 0
32/* Unique member ID */
33#define COLUMN_WSREP_MEMB_UUID 1
34/* Human-readable name */
35#define COLUMN_WSREP_MEMB_NAME 2
36/* Incoming address */
37#define COLUMN_WSREP_MEMB_ADDRESS 3
38
39/* WSREP_STATUS table fields */
40
41/* Node index */
42#define COLUMN_WSREP_STATUS_NODE_INDEX 0
43/* Node status */
44#define COLUMN_WSREP_STATUS_NODE_STATUS 1
45/* Cluster status */
46#define COLUMN_WSREP_STATUS_CLUSTER_STATUS 2
47/* Cluster size */
48#define COLUMN_WSREP_STATUS_CLUSTER_SIZE 3
49/* Global cluster state UUID */
50#define COLUMN_WSREP_STATUS_CLUSTER_STATE_UUID 4
51/* Global cluster state Sequence number */
52#define COLUMN_WSREP_STATUS_CLUSTER_STATE_SEQNO 5
53/* Cluster membership changes */
54#define COLUMN_WSREP_STATUS_CLUSTER_CONF_ID 6
55/* Gap between global and local states ? */
56#define COLUMN_WSREP_STATUS_GAP 7
57/* Application protocol version */
58#define COLUMN_WSREP_STATUS_PROTO_VERSION 8
59
60static const char* get_member_status(wsrep_member_status_t status)
61{
62 switch (status)
63 {
64 case WSREP_MEMBER_UNDEFINED: return "Undefined";
65 case WSREP_MEMBER_JOINER: return "Joiner";
66 case WSREP_MEMBER_DONOR: return "Donor";
67 case WSREP_MEMBER_JOINED: return "Joined";
68 case WSREP_MEMBER_SYNCED: return "Synced";
69 case WSREP_MEMBER_ERROR: return "Error";
70 default: break;
71 }
72 return "UNKNOWN";
73}
74
75static const char* get_cluster_status(wsrep_view_status_t status)
76{
77 switch (status)
78 {
79 case WSREP_VIEW_PRIMARY: return "Primary";
80 case WSREP_VIEW_NON_PRIMARY: return "Non-primary";
81 case WSREP_VIEW_DISCONNECTED: return "Disconnected";
82 default: break;
83 }
84 return "UNKNOWN";
85}
86
87static ST_FIELD_INFO wsrep_memb_fields[]=
88{
89 {"INDEX", MY_INT32_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, 0, "Index", 0},
90 {"UUID", WSREP_UUID_STR_LEN, MYSQL_TYPE_STRING, 0, 0, "Uuid", 0},
91 {"NAME", WSREP_MEMBER_NAME_LEN, MYSQL_TYPE_STRING, 0, 0, "Name", 0},
92 {"ADDRESS", WSREP_INCOMING_LEN, MYSQL_TYPE_STRING, 0, 0, "Address", 0},
93 {0, 0, MYSQL_TYPE_STRING, 0, 0, 0, 0}
94};
95
96static ST_FIELD_INFO wsrep_status_fields[]=
97{
98 {"NODE_INDEX", MY_INT32_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG,
99 0, 0, "Node_Index", 0},
100 {"NODE_STATUS", 16, MYSQL_TYPE_STRING, 0, 0, "Node_Status", 0},
101 {"CLUSTER_STATUS", 16, MYSQL_TYPE_STRING, 0, 0, "Cluster_Status", 0},
102 {"CLUSTER_SIZE", MY_INT32_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG,
103 0, 0, "Cluster_Size", 0},
104 {"CLUSTER_STATE_UUID", WSREP_UUID_STR_LEN, MYSQL_TYPE_STRING,
105 0, 0, 0, 0},
106 {"CLUSTER_STATE_SEQNO", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONGLONG,
107 0, 0, 0, 0},
108 {"CLUSTER_CONF_ID", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONGLONG,
109 0, 0, 0, 0},
110 {"GAP", 10, MYSQL_TYPE_STRING, 0, 0, 0, 0},
111 {"PROTOCOL_VERSION", MY_INT32_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG,
112 0, 0, 0, 0},
113 {0, 0, MYSQL_TYPE_STRING, 0, 0, 0, 0}
114};
115
116static int wsrep_memb_fill_table(THD *thd, TABLE_LIST *tables, COND *cond)
117{
118 int rc= 0;
119
120 if (check_global_access(thd, SUPER_ACL, true))
121 return rc;
122
123 wsrep_config_state->lock();
124
125 Dynamic_array<wsrep_member_info_t> *memb_arr=
126 wsrep_config_state->get_member_info();
127
128 TABLE *table= tables->table;
129
130 for (unsigned int i= 0; i < memb_arr->elements(); i ++)
131 {
132 wsrep_member_info_t memb= memb_arr->at(i);
133
134 table->field[COLUMN_WSREP_MEMB_INDEX]->store(i, 0);
135
136 char uuid[40];
137 wsrep_uuid_print(&memb.id, uuid, sizeof(uuid));
138 table->field[COLUMN_WSREP_MEMB_UUID]->store(uuid, sizeof(uuid),
139 system_charset_info);
140 table->field[COLUMN_WSREP_MEMB_NAME]->store(memb.name, strlen(memb.name),
141 system_charset_info);
142 table->field[COLUMN_WSREP_MEMB_ADDRESS]->store(memb.incoming,
143 strlen(memb.incoming),
144 system_charset_info);
145
146 if (schema_table_store_record(thd, table))
147 {
148 rc= 1;
149 goto end;
150 }
151 }
152
153end:
154 wsrep_config_state->unlock();
155 return rc;
156}
157
158static int wsrep_memb_plugin_init(void *p)
159{
160 ST_SCHEMA_TABLE *schema= (ST_SCHEMA_TABLE *)p;
161
162 schema->fields_info= wsrep_memb_fields;
163 schema->fill_table= wsrep_memb_fill_table;
164
165 return 0;
166}
167
168static struct st_mysql_information_schema wsrep_memb_plugin=
169{ MYSQL_INFORMATION_SCHEMA_INTERFACE_VERSION };
170
171static int wsrep_status_fill_table(THD *thd, TABLE_LIST *tables, COND *cond)
172{
173 int rc= 0;
174
175 if (check_global_access(thd, SUPER_ACL, true))
176 return rc;
177
178 wsrep_config_state->lock();
179
180 wsrep_view_info_t view= wsrep_config_state->get_view_info();
181 wsrep_member_status_t status= wsrep_config_state->get_status();
182
183 TABLE *table= tables->table;
184
185 table->field[COLUMN_WSREP_STATUS_NODE_INDEX]
186 ->store(view.my_idx, 0);
187 table->field[COLUMN_WSREP_STATUS_NODE_STATUS]
188 ->store(get_member_status(status), strlen(get_member_status(status)),
189 system_charset_info);
190 table->field[COLUMN_WSREP_STATUS_CLUSTER_STATUS]
191 ->store(get_cluster_status(view.status),
192 strlen(get_cluster_status(view.status)),
193 system_charset_info);
194 table->field[COLUMN_WSREP_STATUS_CLUSTER_SIZE]->store(view.memb_num, 0);
195
196 char uuid[40];
197 wsrep_uuid_print(&view.state_id.uuid, uuid, sizeof(uuid));
198 table->field[COLUMN_WSREP_STATUS_CLUSTER_STATE_UUID]
199 ->store(uuid, sizeof(uuid), system_charset_info);
200
201 table->field[COLUMN_WSREP_STATUS_CLUSTER_STATE_SEQNO]
202 ->store(view.state_id.seqno, 0);
203 table->field[COLUMN_WSREP_STATUS_CLUSTER_CONF_ID]->store(view.view, 0);
204
205 const char *gap= (view.state_gap == true) ? "YES" : "NO";
206 table->field[COLUMN_WSREP_STATUS_GAP]->store(gap, strlen(gap),
207 system_charset_info);
208 table->field[COLUMN_WSREP_STATUS_PROTO_VERSION]->store(view.proto_ver, 0);
209
210 if (schema_table_store_record(thd, table))
211 rc= 1;
212
213 wsrep_config_state->unlock();
214 return rc;
215}
216
217static int wsrep_status_plugin_init(void *p)
218{
219 ST_SCHEMA_TABLE *schema= (ST_SCHEMA_TABLE *)p;
220
221 schema->fields_info= wsrep_status_fields;
222 schema->fill_table= wsrep_status_fill_table;
223
224 return 0;
225}
226
227static struct st_mysql_information_schema wsrep_status_plugin=
228{ MYSQL_INFORMATION_SCHEMA_INTERFACE_VERSION };
229
230/*
231 Plugin library descriptor
232*/
233
234maria_declare_plugin(wsrep_info)
235{
236 MYSQL_INFORMATION_SCHEMA_PLUGIN,
237 &wsrep_memb_plugin,
238 "WSREP_MEMBERSHIP", /* Plugin name */
239 "Nirbhay Choubey", /* Plugin author */
240 "Information about group members", /* Plugin description */
241 PLUGIN_LICENSE_GPL, /* License */
242 wsrep_memb_plugin_init, /* Plugin Init */
243 0, /* Plugin Deinit */
244 0x0100, /* Version (hex) */
245 NULL, /* Status variables */
246 NULL, /* System variables */
247 "1.0", /* Version (string) */
248 MariaDB_PLUGIN_MATURITY_STABLE /* Maturity */
249},
250{
251 MYSQL_INFORMATION_SCHEMA_PLUGIN,
252 &wsrep_status_plugin,
253 "WSREP_STATUS", /* Plugin name */
254 "Nirbhay Choubey", /* Plugin author */
255 "Group view information", /* Plugin description */
256 PLUGIN_LICENSE_GPL, /* License */
257 wsrep_status_plugin_init, /* Plugin Init */
258 0, /* Plugin Deinit */
259 0x0100, /* Version (hex) */
260 NULL, /* Status variables */
261 NULL, /* System variables */
262 "1.0", /* Version (string) */
263 MariaDB_PLUGIN_MATURITY_STABLE /* Maturity */
264}
265maria_declare_plugin_end;
266
267