1
/* - mode: c; c-basic-offset: 2; indent-tabs-mode: nil; -*-
2
* vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
4
* Copyright (C) 2009 Sun Microsystems
8
* Jay Pipes <joinfu@sun.com>
10
* This program is free software; you can redistribute it and/or modify
11
* it under the terms of the GNU General Public License as published by
12
* the Free Software Foundation; either version 2 of the License, or
13
* (at your option) any later version.
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 for more details.
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
28
* Implements the INFORMATION_SCHEMA views which allows querying the
29
* state of the transaction log and its entries.
31
* There are three views defined for the transaction log:
33
* CREATE TABLE INFORMATION_SCHEMA.TRANSACTION_LOG (
34
* FILE_NAME VARCHAR NOT NULL
35
* , FILE_LENGTH BIGINT NOT NULL
36
* , NUM_LOG_ENTRIES BIGINT NOT NULL
37
* , NUM_TRANSACTIONS BIGINT NOT NULL
38
* , MIN_TRANSACTION_ID BIGINT NOT NULL
39
* , MAX_TRANSACTION_ID BIGINT NOT NULL
40
* , MIN_END_TIMESTAMP BIGINT NOT NULL
41
* , MAX_END_TIMESTAMP BIGINT NOT NULL
44
* CREATE TABLE INFORMATION_SCHEMA.TRANSACTION_LOG_ENTRIES (
45
* ENTRY_OFFSET BIGINT NOT NULL
46
* , ENTRY_TYPE VARCHAR NOT NULL
47
* , ENTRY_LENGTH BIGINT NOT NULL
50
* CREATE TABLE INFORMATION_SCHEMA.TRANSACTION_LOG_TRANSACTIONS (
51
* ENTRY_OFFSET BIGINT NOT NULL
52
* , TRANSACTION_ID BIGINT NOT NULL
53
* , SERVER_ID INT NOT NULL
54
* , START_TIMESTAMP BIGINT NOT NULL
55
* , END_TIMESTAMP BIGINT NOT NULL
56
* , NUM_STATEMENTS INT NOT NULL
57
* , CHECKSUM BIGINT NOT NULL // had to be BIGINT b/c we have no unsigned int.
62
#include <drizzled/session.h>
63
#include <drizzled/show.h>
65
#include "transaction_log.h"
66
#include "transaction_log_entry.h"
67
#include "transaction_log_index.h"
68
#include "info_schema.h"
78
using namespace drizzled;
80
extern TransactionLog *transaction_log; /* the singleton transaction log */
81
extern TransactionLogIndex *transaction_log_index; /* the singleton transaction log index */
87
inline void operator()(const T *ptr) const
94
* Vectors of columns for I_S tables.
96
static vector<const plugin::ColumnInfo *> *transaction_log_view_columns= NULL;
97
static vector<const plugin::ColumnInfo *> *transaction_log_entries_view_columns= NULL;
98
static vector<const plugin::ColumnInfo *> *transaction_log_transactions_view_columns= NULL;
101
* Methods for I_S tables.
103
static plugin::InfoSchemaMethods *transaction_log_view_methods= NULL;
104
static plugin::InfoSchemaMethods *transaction_log_entries_view_methods= NULL;
105
static plugin::InfoSchemaMethods *transaction_log_transactions_view_methods= NULL;
110
plugin::InfoSchemaTable *transaction_log_view= NULL;
111
plugin::InfoSchemaTable *transaction_log_entries_view= NULL;
112
plugin::InfoSchemaTable *transaction_log_transactions_view= NULL;
114
static bool createTransactionLogViewColumns(vector<const drizzled::plugin::ColumnInfo *> &cols);
115
static bool createTransactionLogEntriesViewColumns(vector<const drizzled::plugin::ColumnInfo *> &cols);
116
static bool createTransactionLogTransactionsViewColumns(vector<const drizzled::plugin::ColumnInfo *> &cols);
118
int TransactionLogViewISMethods::fillTable(Session *,
120
plugin::InfoSchemaTable *schema_table)
122
if (transaction_log != NULL)
124
table->restoreRecordAsDefault();
126
table->setWriteSet(0);
127
table->setWriteSet(1);
128
table->setWriteSet(2);
129
table->setWriteSet(3);
130
table->setWriteSet(4);
131
table->setWriteSet(5);
132
table->setWriteSet(6);
133
table->setWriteSet(7);
135
const string &filename= transaction_log->getLogFilename();
136
table->field[0]->store(filename.c_str(), filename.length(), system_charset_info);
138
/* Grab the file size of the log */
139
struct stat file_stat;
140
(void) stat(filename.c_str(), &file_stat);
142
table->field[1]->store(static_cast<int64_t>(file_stat.st_size));
144
table->field[2]->store(static_cast<int64_t>(transaction_log_index->getNumLogEntries()));
145
table->field[3]->store(static_cast<int64_t>(transaction_log_index->getNumTransactionEntries()));
146
table->field[4]->store(static_cast<int64_t>(transaction_log_index->getMinTransactionId()));
147
table->field[5]->store(static_cast<int64_t>(transaction_log_index->getMaxTransactionId()));
148
table->field[6]->store(static_cast<int64_t>(transaction_log_index->getMinEndTimestamp()));
149
table->field[7]->store(static_cast<int64_t>(transaction_log_index->getMaxEndTimestamp()));
151
/* store the actual record now */
152
schema_table->addRow(table->record[0], table->s->reclength);
157
int TransactionLogEntriesViewISMethods::fillTable(Session *,
159
plugin::InfoSchemaTable *schema_table)
161
if (transaction_log != NULL)
163
/** @todo trigger indexing update here. */
164
for (TransactionLog::Entries::iterator entry_iter= transaction_log_index->getEntries().begin();
165
entry_iter != transaction_log_index->getEntries().end();
168
TransactionLogEntry &entry= *entry_iter;
170
table->restoreRecordAsDefault();
172
table->setWriteSet(0);
173
table->setWriteSet(1);
174
table->setWriteSet(2);
176
table->field[0]->store(static_cast<int64_t>(entry.getOffset()));
177
const char *type_string= entry.getTypeAsString();
178
table->field[1]->store(type_string, strlen(type_string), system_charset_info);
179
table->field[2]->store(static_cast<int64_t>(entry.getLengthInBytes()));
181
/* store the actual record now */
182
schema_table->addRow(table->record[0], table->s->reclength);
188
int TransactionLogTransactionsViewISMethods::fillTable(Session *,
190
plugin::InfoSchemaTable *schema_table)
192
if (transaction_log != NULL)
194
/** @todo trigger indexing update here. */
195
for (TransactionLog::TransactionEntries::iterator entry_iter= transaction_log_index->getTransactionEntries().begin();
196
entry_iter != transaction_log_index->getTransactionEntries().end();
199
TransactionLogTransactionEntry &entry= *entry_iter;
201
table->restoreRecordAsDefault();
203
table->setWriteSet(0);
204
table->setWriteSet(1);
205
table->setWriteSet(2);
206
table->setWriteSet(3);
207
table->setWriteSet(4);
208
table->setWriteSet(5);
209
table->setWriteSet(6);
211
table->field[0]->store(static_cast<int64_t>(entry.getOffset()));
212
table->field[1]->store(static_cast<int64_t>(entry.getTransactionId()));
213
table->field[2]->store(static_cast<int64_t>(entry.getServerId()));
214
table->field[3]->store(static_cast<int64_t>(entry.getStartTimestamp()));
215
table->field[4]->store(static_cast<int64_t>(entry.getEndTimestamp()));
216
table->field[5]->store(static_cast<int64_t>(entry.getNumStatements()));
217
table->field[6]->store(static_cast<int64_t>(entry.getChecksum()));
219
/* store the actual record now */
220
schema_table->addRow(table->record[0], table->s->reclength);
226
static bool createTransactionLogViewColumns(vector<const plugin::ColumnInfo *> &cols)
229
* Create each column for the INFORMATION_SCHEMA.TRANSACTION_LOG view
231
const plugin::ColumnInfo *file_name_col=
232
new (nothrow) plugin::ColumnInfo("FILE_NAME",
234
DRIZZLE_TYPE_VARCHAR,
237
"Filename of the transaction log");
238
if (file_name_col == NULL)
240
errmsg_printf(ERRMSG_LVL_ERROR, _("Failed to allocate ColumnInfo %s. Got error: %s\n"),
246
const plugin::ColumnInfo *file_length_col=
247
new (nothrow) plugin::ColumnInfo("FILE_LENGTH",
249
DRIZZLE_TYPE_LONGLONG,
252
"Length in bytes of the transaction log");
253
if (file_length_col == NULL)
255
errmsg_printf(ERRMSG_LVL_ERROR, _("Failed to allocate ColumnInfo %s. Got error: %s\n"),
261
const plugin::ColumnInfo *num_log_entries_col=
262
new (nothrow) plugin::ColumnInfo("NUM_LOG_ENTRIES",
264
DRIZZLE_TYPE_LONGLONG,
267
"Total number of entries in the transaction log");
268
if (num_log_entries_col == NULL)
270
errmsg_printf(ERRMSG_LVL_ERROR, _("Failed to allocate ColumnInfo %s. Got error: %s\n"),
276
const plugin::ColumnInfo *num_transactions_col=
277
new (nothrow) plugin::ColumnInfo("NUM_TRANSACTIONS",
279
DRIZZLE_TYPE_LONGLONG,
282
"Total number of transaction message entries in the transaction log");
283
if (num_transactions_col == NULL)
285
errmsg_printf(ERRMSG_LVL_ERROR, _("Failed to allocate ColumnInfo %s. Got error: %s\n"),
291
const plugin::ColumnInfo *min_transaction_id_col=
292
new (nothrow) plugin::ColumnInfo("MIN_TRANSACTION_ID",
294
DRIZZLE_TYPE_LONGLONG,
297
"Minimum transaction ID in the transaction log");
298
if (min_transaction_id_col == NULL)
300
errmsg_printf(ERRMSG_LVL_ERROR, _("Failed to allocate ColumnInfo %s. Got error: %s\n"),
301
"MIN_TRANSACTION_ID",
306
const plugin::ColumnInfo *max_transaction_id_col=
307
new (nothrow) plugin::ColumnInfo("MAX_TRANSACTION_ID",
309
DRIZZLE_TYPE_LONGLONG,
312
"Maximum transaction ID in the transaction log");
313
if (max_transaction_id_col == NULL)
315
errmsg_printf(ERRMSG_LVL_ERROR, _("Failed to allocate ColumnInfo %s. Got error: %s\n"),
316
"MAX_TRANSACTION_ID",
321
const plugin::ColumnInfo *min_timestamp_col=
322
new (nothrow) plugin::ColumnInfo("MIN_END_TIMESTAMP",
324
DRIZZLE_TYPE_LONGLONG,
327
"Minimum end timestamp for a transaction in the transaction log");
328
if (min_timestamp_col == NULL)
330
errmsg_printf(ERRMSG_LVL_ERROR, _("Failed to allocate ColumnInfo %s. Got error: %s\n"),
336
const plugin::ColumnInfo *max_timestamp_col=
337
new (nothrow) plugin::ColumnInfo("MAX_END_TIMESTAMP",
339
DRIZZLE_TYPE_LONGLONG,
342
"Maximum end timestamp for a transaction in the transaction log");
343
if (max_timestamp_col == NULL)
345
errmsg_printf(ERRMSG_LVL_ERROR, _("Failed to allocate ColumnInfo %s. Got error: %s\n"),
351
cols.push_back(file_name_col);
352
cols.push_back(file_length_col);
353
cols.push_back(num_log_entries_col);
354
cols.push_back(num_transactions_col);
355
cols.push_back(min_transaction_id_col);
356
cols.push_back(max_transaction_id_col);
357
cols.push_back(min_timestamp_col);
358
cols.push_back(max_timestamp_col);
363
static bool createTransactionLogEntriesViewColumns(vector<const plugin::ColumnInfo *> &cols)
366
* Create each column for the INFORMATION_SCHEMA.TRANSACTION_LOG_ENTRIES view
368
const plugin::ColumnInfo *entry_offset_col=
369
new (nothrow) plugin::ColumnInfo("ENTRY_OFFSET",
371
DRIZZLE_TYPE_LONGLONG,
374
"Offset of this entry into the transaction log");
375
if (entry_offset_col == NULL)
377
errmsg_printf(ERRMSG_LVL_ERROR, _("Failed to allocate ColumnInfo %s. Got error: %s\n"),
383
const plugin::ColumnInfo *entry_type_col=
384
new (nothrow) plugin::ColumnInfo("ENTRY_TYPE",
386
DRIZZLE_TYPE_VARCHAR,
389
"Type of this entry");
390
if (entry_type_col == NULL)
392
errmsg_printf(ERRMSG_LVL_ERROR, _("Failed to allocate ColumnInfo %s. Got error: %s\n"),
398
const plugin::ColumnInfo *entry_length_col=
399
new (nothrow) plugin::ColumnInfo("ENTRY_LENGTH",
401
DRIZZLE_TYPE_LONGLONG,
404
"Length in bytes of this entry");
405
if (entry_length_col == NULL)
407
errmsg_printf(ERRMSG_LVL_ERROR, _("Failed to allocate ColumnInfo %s. Got error: %s\n"),
413
cols.push_back(entry_offset_col);
414
cols.push_back(entry_type_col);
415
cols.push_back(entry_length_col);
420
static bool createTransactionLogTransactionsViewColumns(vector<const plugin::ColumnInfo *> &cols)
423
* Create each column for the INFORMATION_SCHEMA.TRANSACTION_LOG_TRANSACTIONS view
425
const plugin::ColumnInfo *entry_offset_col=
426
new (nothrow) plugin::ColumnInfo("ENTRY_OFFSET",
428
DRIZZLE_TYPE_LONGLONG,
431
"Offset of this entry into the transaction log");
432
if (entry_offset_col == NULL)
434
errmsg_printf(ERRMSG_LVL_ERROR, _("Failed to allocate ColumnInfo %s. Got error: %s\n"),
440
const plugin::ColumnInfo *transaction_id_col=
441
new (nothrow) plugin::ColumnInfo("TRANSACTION_ID",
443
DRIZZLE_TYPE_LONGLONG,
446
"Transaction ID for this entry");
447
if (transaction_id_col == NULL)
449
errmsg_printf(ERRMSG_LVL_ERROR, _("Failed to allocate ColumnInfo %s. Got error: %s\n"),
455
const plugin::ColumnInfo *server_id_col=
456
new (nothrow) plugin::ColumnInfo("SERVER_ID",
458
DRIZZLE_TYPE_LONGLONG,
461
"Server ID for this entry");
462
if (server_id_col == NULL)
464
errmsg_printf(ERRMSG_LVL_ERROR, _("Failed to allocate ColumnInfo %s. Got error: %s\n"),
470
const plugin::ColumnInfo *start_timestamp_col=
471
new (nothrow) plugin::ColumnInfo("START_TIMESTAMP",
473
DRIZZLE_TYPE_LONGLONG,
476
"Start timestamp for this transaction");
477
if (start_timestamp_col == NULL)
479
errmsg_printf(ERRMSG_LVL_ERROR, _("Failed to allocate ColumnInfo %s. Got error: %s\n"),
485
const plugin::ColumnInfo *end_timestamp_col=
486
new (nothrow) plugin::ColumnInfo("END_TIMESTAMP",
488
DRIZZLE_TYPE_LONGLONG,
491
"End timestamp for this transaction");
492
if (end_timestamp_col == NULL)
494
errmsg_printf(ERRMSG_LVL_ERROR, _("Failed to allocate ColumnInfo %s. Got error: %s\n"),
500
const plugin::ColumnInfo *num_statements_col=
501
new (nothrow) plugin::ColumnInfo("NUM_STATEMENTS",
503
DRIZZLE_TYPE_LONGLONG,
506
"Number of statements in this transaction");
507
if (num_statements_col == NULL)
509
errmsg_printf(ERRMSG_LVL_ERROR, _("Failed to allocate ColumnInfo %s. Got error: %s\n"),
515
const plugin::ColumnInfo *checksum_col=
516
new (nothrow) plugin::ColumnInfo("CHECKSUM",
518
DRIZZLE_TYPE_LONGLONG,
521
"Checksum of this transaction");
522
if (checksum_col == NULL)
524
errmsg_printf(ERRMSG_LVL_ERROR, _("Failed to allocate ColumnInfo %s. Got error: %s\n"),
530
cols.push_back(entry_offset_col);
531
cols.push_back(transaction_id_col);
532
cols.push_back(server_id_col);
533
cols.push_back(start_timestamp_col);
534
cols.push_back(end_timestamp_col);
535
cols.push_back(num_statements_col);
536
cols.push_back(checksum_col);
541
bool initViewColumns()
543
transaction_log_view_columns= new (nothrow) vector<const plugin::ColumnInfo *>;
544
if (transaction_log_view_columns == NULL)
548
transaction_log_entries_view_columns= new (nothrow) vector<const plugin::ColumnInfo *>;
549
if (transaction_log_entries_view_columns == NULL)
553
transaction_log_transactions_view_columns= new (nothrow) vector<const plugin::ColumnInfo *>;
554
if (transaction_log_transactions_view_columns == NULL)
559
if (createTransactionLogViewColumns(*transaction_log_view_columns))
564
if (createTransactionLogEntriesViewColumns(*transaction_log_entries_view_columns))
569
if (createTransactionLogTransactionsViewColumns(*transaction_log_transactions_view_columns))
577
static void clearViewColumns(vector<const plugin::ColumnInfo *> &cols)
579
for_each(cols.begin(), cols.end(), DeletePtr());
583
void cleanupViewColumns()
585
clearViewColumns(*transaction_log_view_columns);
586
delete transaction_log_view_columns;
587
clearViewColumns(*transaction_log_entries_view_columns);
588
delete transaction_log_entries_view_columns;
589
clearViewColumns(*transaction_log_transactions_view_columns);
590
delete transaction_log_transactions_view_columns;
593
bool initViewMethods()
595
transaction_log_view_methods= new (nothrow) TransactionLogViewISMethods();
596
if (transaction_log_view_methods == NULL)
598
errmsg_printf(ERRMSG_LVL_ERROR, _("Failed to allocate TransactionLogViewISMethods. Got error: %s\n"),
603
transaction_log_entries_view_methods= new (nothrow) TransactionLogEntriesViewISMethods();
604
if (transaction_log_entries_view_methods == NULL)
606
errmsg_printf(ERRMSG_LVL_ERROR, _("Failed to allocate TransactionLogEntriesViewISMethods. Got error: %s\n"),
611
transaction_log_transactions_view_methods= new (nothrow) TransactionLogTransactionsViewISMethods();
612
if (transaction_log_transactions_view_methods == NULL)
614
errmsg_printf(ERRMSG_LVL_ERROR, _("Failed to allocate TransactionLogTransactionsViewISMethods. Got error: %s\n"),
622
void cleanupViewMethods()
624
delete transaction_log_view_methods;
625
delete transaction_log_entries_view_methods;
626
delete transaction_log_transactions_view_methods;
631
transaction_log_view=
632
new (nothrow) plugin::InfoSchemaTable("TRANSACTION_LOG",
633
*transaction_log_view_columns,
634
-1, -1, false, false, 0,
635
transaction_log_view_methods);
636
if (transaction_log_view == NULL)
638
errmsg_printf(ERRMSG_LVL_ERROR, _("Failed to allocate InfoSchemaTable for %s. Got error: %s\n"),
644
transaction_log_entries_view=
645
new (nothrow) plugin::InfoSchemaTable("TRANSACTION_LOG_ENTRIES",
646
*transaction_log_entries_view_columns,
647
-1, -1, false, false, 0,
648
transaction_log_entries_view_methods);
649
if (transaction_log_entries_view == NULL)
651
errmsg_printf(ERRMSG_LVL_ERROR, _("Failed to allocate InfoSchemaTable for %s. Got error: %s\n"),
652
"TRANSACTION_LOG_ENTRIES",
657
transaction_log_transactions_view=
658
new (nothrow) plugin::InfoSchemaTable("TRANSACTION_LOG_TRANSACTIONS",
659
*transaction_log_transactions_view_columns,
660
-1, -1, false, false, 0,
661
transaction_log_transactions_view_methods);
662
if (transaction_log_transactions_view == NULL)
664
errmsg_printf(ERRMSG_LVL_ERROR, _("Failed to allocate InfoSchemaTable for %s. Got error: %s\n"),
665
"TRANSACTION_LOG_TRANSACTIONS",
675
delete transaction_log_view;
676
delete transaction_log_entries_view;
677
delete transaction_log_transactions_view;