~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to plugin/memcached_stats/stats_table.cc

This patch completes the first step in the splitting of
the XA resource manager API from the storage engine API,
as outlined in the specification here:

http://drizzle.org/wiki/XaStorageEngine

* Splits plugin::StorageEngine into a base StorageEngine
  class and two derived classes, TransactionalStorageEngine
  and XaStorageEngine.  XaStorageEngine derives from
  TransactionalStorageEngine and creates the XA Resource
  Manager API for storage engines.

  - The methods moved from StorageEngine to TransactionalStorageEngine
    include releaseTemporaryLatches(), startConsistentSnapshot(), 
    commit(), rollback(), setSavepoint(), releaseSavepoint(),
    rollbackToSavepoint() and hasTwoPhaseCommit()
  - The methods moved from StorageEngine to XaStorageEngine
    include recover(), commitXid(), rollbackXid(), and prepare()

* Places all static "EngineVector"s into their proper
  namespaces (typedefs belong in header files, not implementation files)
  and places all static methods corresponding
  to either only transactional engines or only XA engines
  into their respective files in /drizzled/plugin/

* Modifies the InnoDB "handler" files to extend plugin::XaStorageEngine
  and not plugin::StorageEngine

The next step, as outlined in the wiki spec page above, is to isolate
the XA Resource Manager API into its own plugin class and modify
plugin::XaStorageEngine to implement plugin::XaResourceManager via
composition.  This is necessary to enable building plugins which can
participate in an XA transaction *without having to have that plugin
implement the entire storage engine API*

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/*
2
 
 * Copyright (C) 2009, Padraig O'Sullivan
 
1
/* 
 
2
 * Copyright (c) 2009, Padraig O'Sullivan
3
3
 * All rights reserved.
4
4
 *
5
5
 * Redistribution and use in source and binary forms, with or without
27
27
 * THE POSSIBILITY OF SUCH DAMAGE.
28
28
 */
29
29
 
30
 
#include <config.h>
 
30
#include "config.h"
 
31
#include "drizzled/session.h"
 
32
#include "drizzled/show.h"
 
33
#include "drizzled/my_error.h"
31
34
 
32
35
#include "stats_table.h"
33
 
 
34
 
#include <drizzled/error.h>
35
 
#include <libmemcached/server.h>
 
36
#include "sysvar_holder.h"
 
37
 
 
38
#include <libmemcached/memcached.h>
 
39
 
 
40
#include <string>
 
41
#include <vector>
 
42
 
 
43
using namespace std;
 
44
using namespace drizzled;
36
45
 
37
46
#if !defined(HAVE_MEMCACHED_SERVER_FN)
38
47
typedef memcached_server_function memcached_server_fn;
39
48
#endif
40
49
 
41
 
namespace drizzle_plugin
42
 
{
43
 
 
44
50
extern "C"
45
 
memcached_return  server_function(const memcached_st *ptr,
 
51
memcached_return  server_function(memcached_st *ptr,
46
52
                                  memcached_server_st *server,
47
53
                                  void *context);
48
54
 
49
55
struct server_function_context
50
56
{
51
 
  StatsTableTool::Generator* generator; 
52
 
  server_function_context(StatsTableTool::Generator *generator_arg)
53
 
    : generator(generator_arg)
 
57
  Table* table;
 
58
  plugin::InfoSchemaTable *schema_table;
 
59
  server_function_context(Table *table_arg,
 
60
                          plugin::InfoSchemaTable *schema_table_arg)
 
61
    : table(table_arg), schema_table(schema_table_arg)
54
62
  {}
55
63
};
56
64
 
57
 
 
58
65
extern "C"
59
 
memcached_return  server_function(const memcached_st *memc,
 
66
memcached_return  server_function(memcached_st *memc,
60
67
                                  memcached_server_st *server,
61
68
                                  void *context)
62
69
{
63
70
  server_function_context *ctx= static_cast<server_function_context *>(context);
64
 
 
65
 
  const char *server_name= memcached_server_name(*memc, *server);
66
 
  in_port_t server_port= memcached_server_port(*memc, *server);
 
71
  const CHARSET_INFO * const scs= system_charset_info;
 
72
    
 
73
  char *server_name= memcached_server_name(memc, *server);
 
74
  in_port_t server_port= memcached_server_port(memc, *server);
67
75
 
68
76
  memcached_stat_st stats;
69
77
  memcached_return ret= memcached_stat_servername(&stats, NULL,
70
78
                                                  server_name, server_port);
71
 
 
72
79
  if (ret != MEMCACHED_SUCCESS)
73
80
  {
74
81
    my_printf_error(ER_UNKNOWN_ERROR, _("Unable get stats from memcached server %s.  Got error from memcached_stat_servername()."), MYF(0), server_name);
75
82
    return ret;
76
83
  }
77
84
 
78
 
  char **list= memcached_stat_get_keys((memcached_st *)memc, &stats, &ret);
 
85
  char **list= memcached_stat_get_keys(memc, &stats, &ret);
79
86
  char **ptr= NULL;
80
 
 
81
 
  ctx->generator->push(server_name);
82
 
  ctx->generator->push(static_cast<uint64_t>(server_port));
83
 
 
 
87
 
 
88
  ctx->table->setWriteSet(0);
 
89
  ctx->table->setWriteSet(1);
 
90
 
 
91
  ctx->table->field[0]->store(server_name, strlen(server_name), scs);
 
92
  ctx->table->field[1]->store(server_port);
 
93
 
 
94
  uint32_t col= 2;
84
95
  for (ptr= list; *ptr; ptr++)
85
96
  {
86
 
    char *value= memcached_stat_get_value((memcached_st *)memc, &stats, *ptr, &ret);
87
 
    ctx->generator->push(value);
 
97
    char *value= memcached_stat_get_value(memc, &stats, *ptr, &ret);
 
98
 
 
99
    ctx->table->setWriteSet(col);
 
100
    ctx->table->field[col]->store(value,
 
101
                                  strlen(value),
 
102
                                  scs);
 
103
    col++;
88
104
    free(value);
89
105
  }
90
106
  free(list);
91
 
 
 
107
  /* store the actual record now */
 
108
  ctx->schema_table->addRow(ctx->table->record[0], ctx->table->s->reclength);
92
109
  return MEMCACHED_SUCCESS;
93
110
}
94
111
 
95
 
 
96
 
StatsTableTool::StatsTableTool() :
97
 
  plugin::TableFunction("DATA_DICTIONARY", "MEMCACHED_STATS")
98
 
{
99
 
  add_field("NAME");
100
 
  add_field("PORT_NUMBER", plugin::TableFunction::NUMBER);
101
 
  add_field("PROCESS_ID", plugin::TableFunction::NUMBER);
102
 
  add_field("UPTIME", plugin::TableFunction::NUMBER);
103
 
  add_field("TIME", plugin::TableFunction::NUMBER);
104
 
  add_field("VERSION");
105
 
  add_field("POINTER_SIZE", plugin::TableFunction::NUMBER);
106
 
  add_field("RUSAGE_USER", plugin::TableFunction::NUMBER);
107
 
  add_field("RUSAGE_SYSTEM", plugin::TableFunction::NUMBER);
108
 
  add_field("CURRENT_ITEMS", plugin::TableFunction::NUMBER);
109
 
  add_field("TOTAL_ITEMS", plugin::TableFunction::NUMBER);
110
 
  add_field("BYTES",  plugin::TableFunction::NUMBER);
111
 
  add_field("CURRENT_CONNECTIONS", plugin::TableFunction::NUMBER);
112
 
  add_field("TOTAL_CONNECTIONS", plugin::TableFunction::NUMBER);
113
 
  add_field("CONNECTION_STRUCTURES", plugin::TableFunction::NUMBER);
114
 
  add_field("GETS", plugin::TableFunction::NUMBER);
115
 
  add_field("SETS", plugin::TableFunction::NUMBER);
116
 
  add_field("HITS", plugin::TableFunction::NUMBER);
117
 
  add_field("MISSES", plugin::TableFunction::NUMBER); 
118
 
  add_field("EVICTIONS", plugin::TableFunction::NUMBER);
119
 
  add_field("BYTES_READ", plugin::TableFunction::NUMBER);
120
 
  add_field("BYTES_WRITTEN", plugin::TableFunction::NUMBER);
121
 
  add_field("LIMIT_MAXBYTES", plugin::TableFunction::NUMBER);
122
 
  add_field("THREADS", plugin::TableFunction::NUMBER);
123
 
}
124
 
 
125
 
 
126
 
StatsTableTool::Generator::Generator(drizzled::Field **arg) :
127
 
  plugin::TableFunction::Generator(arg)
128
 
{
129
 
  /* This will be set to the real number if we initialize properly below */
130
 
  number_of_hosts= 0;
131
 
  
132
 
  host_number= 0;
133
 
 
134
 
  /* set to NULL if we are not able to init we dont want to call delete on this */
135
 
  memc= NULL;
136
 
 
137
 
  drizzled::sys_var *servers_var= drizzled::find_sys_var("memcached_stats_servers");
138
 
  assert(servers_var != NULL);
139
 
 
140
 
  const string servers_string(static_cast<char *>(servers_var.value_ptr(NULL, 0, NULL)));
141
 
 
 
112
int MemcachedStatsISMethods::fillTable(Session *,
 
113
                                       Table *table,
 
114
                                       plugin::InfoSchemaTable *schema_table)
 
115
{
 
116
  SysvarHolder &sysvar_holder= SysvarHolder::singleton();
 
117
  const string servers_string= sysvar_holder.getServersString();
 
118
 
 
119
  table->restoreRecordAsDefault();
142
120
  if (servers_string.empty())
143
121
  {
144
122
    my_printf_error(ER_UNKNOWN_ERROR, _("No value in MEMCACHED_STATS_SERVERS variable."), MYF(0));
145
 
    return; 
146
 
  }
 
123
    return 1;
 
124
  } 
 
125
 
147
126
 
148
 
  memc= memcached_create(NULL);
 
127
  memcached_st *memc= memcached_create(NULL);
149
128
  if (memc == NULL)
150
129
  {
151
130
    my_printf_error(ER_UNKNOWN_ERROR, _("Unable to create memcached struct.  Got error from memcached_create()."), MYF(0));
152
 
    return;
 
131
    return 1;
153
132
  }
154
133
 
155
134
  memcached_server_st *tmp_serv=
157
136
  if (tmp_serv == NULL)
158
137
  {
159
138
    my_printf_error(ER_UNKNOWN_ERROR, _("Unable to create memcached server list.  Got error from memcached_servers_parse(%s)."), MYF(0), servers_string.c_str());
160
 
    return;
 
139
    memcached_free(memc);
 
140
    return 1; 
161
141
  }
162
142
 
163
143
  memcached_server_push(memc, tmp_serv);
164
144
  memcached_server_list_free(tmp_serv);
165
145
 
166
 
  number_of_hosts= memc->number_of_hosts;  
167
 
}
168
 
 
169
 
 
170
 
StatsTableTool::Generator::~Generator()
171
 
{
172
 
  if (memc != NULL)
173
 
  {
174
 
    memcached_free(memc);
175
 
  }
176
 
}
177
 
 
178
 
 
179
 
bool StatsTableTool::Generator::populate()
180
 
{
181
 
  if (host_number == number_of_hosts)
182
 
  {
183
 
    return false;
184
 
  }
185
 
 
186
 
  server_function_context context(this);
187
 
 
188
 
  memcached_server_function callbacks[1];
 
146
  memcached_server_fn callbacks[1];
 
147
 
189
148
  callbacks[0]= server_function;
190
 
 
191
 
  unsigned int iferror; 
192
 
  iferror= (*callbacks[0])(memc, &memc->servers[host_number], (void *)&context); 
193
 
 
194
 
  if (iferror)
195
 
  {
196
 
    return false;
197
 
  }
198
 
 
199
 
  host_number++;
200
 
 
201
 
  return true;
202
 
}
203
 
 
204
 
} /* namespace drizzle_plugin */
 
149
  server_function_context context(table, schema_table);
 
150
 
 
151
  memcached_server_cursor(memc, callbacks, &context, 1);
 
152
 
 
153
  memcached_free(memc);
 
154
 
 
155
  return 0;
 
156
}
 
157
 
 
158
bool createMemcachedStatsColumns(vector<const plugin::ColumnInfo *> &cols)
 
159
{
 
160
  /*
 
161
   * Create each column for the memcached stats table.
 
162
   */
 
163
  const plugin::ColumnInfo *name_col= new(std::nothrow) plugin::ColumnInfo("NAME",
 
164
                                                           32,
 
165
                                                           DRIZZLE_TYPE_VARCHAR,
 
166
                                                           0,
 
167
                                                           0,
 
168
                                                           "Name");
 
169
  if (! name_col)
 
170
  {
 
171
    return true;
 
172
  }
 
173
 
 
174
  const plugin::ColumnInfo *port= new(std::nothrow) plugin::ColumnInfo("PORT_NUMBER",
 
175
                                                       4,
 
176
                                                       DRIZZLE_TYPE_LONGLONG,
 
177
                                                       0,
 
178
                                                       0, 
 
179
                                                       "Port Number");
 
180
  if (! port)
 
181
  {
 
182
    return true;
 
183
  }
 
184
 
 
185
  const plugin::ColumnInfo *pid= new(std::nothrow) plugin::ColumnInfo("PROCESS_ID",
 
186
                                                      4,
 
187
                                                      DRIZZLE_TYPE_LONGLONG,
 
188
                                                      0,
 
189
                                                      0, 
 
190
                                                      "Process ID");
 
191
  if (! pid)
 
192
  {
 
193
    return true;
 
194
  }
 
195
 
 
196
  const plugin::ColumnInfo *uptime= new(std::nothrow) plugin::ColumnInfo("UPTIME",
 
197
                                                         4,
 
198
                                                         DRIZZLE_TYPE_LONGLONG,
 
199
                                                         0,
 
200
                                                         0, 
 
201
                                                         "Uptime");
 
202
  if (! uptime)
 
203
  {
 
204
    return true;
 
205
  }
 
206
 
 
207
  const plugin::ColumnInfo *time= new(std::nothrow) plugin::ColumnInfo("TIME",
 
208
                                                       4,
 
209
                                                       DRIZZLE_TYPE_LONGLONG,
 
210
                                                       0,
 
211
                                                       0, 
 
212
                                                       "Time");
 
213
  if (! time)
 
214
  {
 
215
    return true;
 
216
  }
 
217
 
 
218
  const plugin::ColumnInfo *version= new(std::nothrow) plugin::ColumnInfo("VERSION",
 
219
                                                          8,
 
220
                                                          DRIZZLE_TYPE_VARCHAR,
 
221
                                                          0,
 
222
                                                          0,
 
223
                                                          "Version");
 
224
  if (! version)
 
225
  {
 
226
    return true;
 
227
  }
 
228
 
 
229
  const plugin::ColumnInfo *ptr_size= new(std::nothrow) plugin::ColumnInfo("POINTER_SIZE",
 
230
                                                           4,
 
231
                                                           DRIZZLE_TYPE_LONGLONG,
 
232
                                                           0,
 
233
                                                           0, 
 
234
                                                           "Pointer Size");
 
235
  if (! ptr_size)
 
236
  {
 
237
    return true;
 
238
  }
 
239
 
 
240
  const plugin::ColumnInfo *r_user= new(std::nothrow) plugin::ColumnInfo("RUSAGE_USER",
 
241
                                                         4,
 
242
                                                         DRIZZLE_TYPE_LONGLONG,
 
243
                                                         0,
 
244
                                                         0, 
 
245
                                                         "rusage user");
 
246
  if (! r_user)
 
247
  {
 
248
    return true;
 
249
  }
 
250
 
 
251
  const plugin::ColumnInfo *r_sys= new(std::nothrow) plugin::ColumnInfo("RUSAGE_SYSTEM",
 
252
                                                        4,
 
253
                                                        DRIZZLE_TYPE_LONGLONG,
 
254
                                                        0,
 
255
                                                        0, 
 
256
                                                        "rusage system");
 
257
  if (! r_sys)
 
258
  {
 
259
    return true;
 
260
  }
 
261
  const plugin::ColumnInfo *curr_items= new(std::nothrow) plugin::ColumnInfo("CURRENT_ITEMS",
 
262
                                                             4,
 
263
                                                             DRIZZLE_TYPE_LONGLONG,
 
264
                                                             0,
 
265
                                                             0, 
 
266
                                                             "Current Items");
 
267
  if (! curr_items)
 
268
  {
 
269
    return true;
 
270
  }
 
271
 
 
272
  const plugin::ColumnInfo *total_items= new(std::nothrow) plugin::ColumnInfo("TOTAL_ITEMS",
 
273
                                                              4,
 
274
                                                              DRIZZLE_TYPE_LONGLONG,
 
275
                                                              0,
 
276
                                                              0,
 
277
                                                              "Total Items");
 
278
  if (! total_items)
 
279
  {
 
280
    return true;
 
281
  }
 
282
 
 
283
  const plugin::ColumnInfo *bytes= new(std::nothrow) plugin::ColumnInfo("BYTES",
 
284
                                                        4,
 
285
                                                        DRIZZLE_TYPE_LONGLONG,
 
286
                                                        0,
 
287
                                                        0,
 
288
                                                        "Bytes");
 
289
  if (! bytes)
 
290
  {
 
291
    return true;
 
292
  }
 
293
 
 
294
  const plugin::ColumnInfo *curr_cons= new(std::nothrow) plugin::ColumnInfo("CURRENT_CONNECTIONS",
 
295
                                                            4,
 
296
                                                            DRIZZLE_TYPE_LONGLONG,
 
297
                                                            0,
 
298
                                                            0,
 
299
                                                            "Current Connections");
 
300
  if (! curr_cons)
 
301
  {
 
302
    return true;
 
303
  }
 
304
 
 
305
  const plugin::ColumnInfo *total_cons= new(std::nothrow) plugin::ColumnInfo("TOTAL_CONNECTIONS",
 
306
                                                             4,
 
307
                                                             DRIZZLE_TYPE_LONGLONG,
 
308
                                                             0,
 
309
                                                             0,
 
310
                                                             "Total Connections");
 
311
  if (! total_cons)
 
312
  {
 
313
    return true;
 
314
  }
 
315
 
 
316
  const plugin::ColumnInfo *con_structs= new(std::nothrow) plugin::ColumnInfo("CONNECTION_STRUCTURES",
 
317
                                                              4,
 
318
                                                              DRIZZLE_TYPE_LONGLONG,
 
319
                                                              0,
 
320
                                                              0,
 
321
                                                              "Connection Structures");
 
322
  if (! con_structs)
 
323
  {
 
324
    return true;
 
325
  }
 
326
 
 
327
  const plugin::ColumnInfo *cmd_gets= new(std::nothrow) plugin::ColumnInfo("GETS",
 
328
                                                           4,
 
329
                                                           DRIZZLE_TYPE_LONGLONG,
 
330
                                                           0,
 
331
                                                           0,
 
332
                                                           "Gets");
 
333
  if (! cmd_gets)
 
334
  {
 
335
    return true;
 
336
  }
 
337
 
 
338
  const plugin::ColumnInfo *cmd_sets= new(std::nothrow) plugin::ColumnInfo("SETS",
 
339
                                                           4,
 
340
                                                           DRIZZLE_TYPE_LONGLONG,
 
341
                                                           0,
 
342
                                                           0,
 
343
                                                           "Sets");
 
344
  if (! cmd_sets)
 
345
  {
 
346
    return true;
 
347
  }
 
348
 
 
349
  const plugin::ColumnInfo *hits= new(std::nothrow) plugin::ColumnInfo("HITS",
 
350
                                                       4,
 
351
                                                       DRIZZLE_TYPE_LONGLONG,
 
352
                                                       0,
 
353
                                                       0,
 
354
                                                       "Hits");
 
355
  if (! hits)
 
356
  {
 
357
    return true;
 
358
  }
 
359
 
 
360
  const plugin::ColumnInfo *misses= new(std::nothrow) plugin::ColumnInfo("MISSES",
 
361
                                                         4,
 
362
                                                         DRIZZLE_TYPE_LONGLONG,
 
363
                                                         0,
 
364
                                                         0,
 
365
                                                         "Misses");
 
366
  if (! misses)
 
367
  {
 
368
    return true;
 
369
  }
 
370
 
 
371
  const plugin::ColumnInfo *evicts= new(std::nothrow) plugin::ColumnInfo("EVICTIONS",
 
372
                                                         4,
 
373
                                                         DRIZZLE_TYPE_LONGLONG,
 
374
                                                         0,
 
375
                                                         0,
 
376
                                                         "Evictions");
 
377
  if (! evicts)
 
378
  {
 
379
    return true;
 
380
  }
 
381
 
 
382
  const plugin::ColumnInfo *bytes_read= new(std::nothrow) plugin::ColumnInfo("BYTES_READ",
 
383
                                                             4,
 
384
                                                             DRIZZLE_TYPE_LONGLONG,
 
385
                                                             0,
 
386
                                                             0,
 
387
                                                             "bytes read");
 
388
  if (! bytes_read)
 
389
  {
 
390
    return true;
 
391
  }
 
392
 
 
393
  const plugin::ColumnInfo *bytes_written= new(std::nothrow) plugin::ColumnInfo("BYTES_WRITTEN",
 
394
                                                                4,
 
395
                                                                DRIZZLE_TYPE_LONGLONG,
 
396
                                                                0,
 
397
                                                                0,
 
398
                                                                "bytes written");
 
399
  if (! bytes_written)
 
400
  {
 
401
    return true;
 
402
  }
 
403
 
 
404
  const plugin::ColumnInfo *lim_max_bytes= new(std::nothrow) plugin::ColumnInfo("LIMIT_MAXBYTES",
 
405
                                                                4,
 
406
                                                                DRIZZLE_TYPE_LONGLONG,
 
407
                                                                0,
 
408
                                                                0,
 
409
                                                                "limit maxbytes");
 
410
  if (! lim_max_bytes)
 
411
  {
 
412
    return true;
 
413
  }
 
414
 
 
415
  const plugin::ColumnInfo *threads= new(std::nothrow) plugin::ColumnInfo("THREADS",
 
416
                                                          4,
 
417
                                                          DRIZZLE_TYPE_LONGLONG,
 
418
                                                          0,
 
419
                                                          0,
 
420
                                                          "Threads");
 
421
  if (! threads)
 
422
  {
 
423
    return true;
 
424
  }
 
425
 
 
426
  cols.push_back(name_col);
 
427
  cols.push_back(port);
 
428
  cols.push_back(pid);
 
429
  cols.push_back(uptime);
 
430
  cols.push_back(time);
 
431
  cols.push_back(version);
 
432
  cols.push_back(ptr_size);
 
433
  cols.push_back(r_user);
 
434
  cols.push_back(r_sys);
 
435
  cols.push_back(curr_items);
 
436
  cols.push_back(total_items);
 
437
  cols.push_back(bytes);
 
438
  cols.push_back(curr_cons);
 
439
  cols.push_back(total_cons);
 
440
  cols.push_back(con_structs);
 
441
  cols.push_back(cmd_gets);
 
442
  cols.push_back(cmd_sets);
 
443
  cols.push_back(hits);
 
444
  cols.push_back(misses);
 
445
  cols.push_back(evicts);
 
446
  cols.push_back(bytes_read);
 
447
  cols.push_back(bytes_written);
 
448
  cols.push_back(lim_max_bytes);
 
449
  cols.push_back(threads);
 
450
 
 
451
  return false;
 
452
}
 
453
 
 
454
class DeleteMemcachedCols
 
455
{
 
456
public:
 
457
  template<typename T>
 
458
  inline void operator()(const T *ptr) const
 
459
  {
 
460
    delete ptr;
 
461
  }
 
462
};
 
463
 
 
464
void clearMemcachedColumns(vector<const plugin::ColumnInfo *> &cols)
 
465
{
 
466
  for_each(cols.begin(), cols.end(), DeleteMemcachedCols());
 
467
  cols.clear();
 
468
}