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>
64
#include <drizzled/util/functors.h>
66
#include "transaction_log.h"
67
#include "transaction_log_entry.h"
68
#include "transaction_log_index.h"
69
#include "info_schema.h"
79
using namespace drizzled;
81
extern TransactionLog *transaction_log; /* the singleton transaction log */
82
extern TransactionLogIndex *transaction_log_index; /* the singleton transaction log index */
85
* Vectors of columns for I_S tables.
87
static vector<const plugin::ColumnInfo *> *transaction_log_view_columns= NULL;
88
static vector<const plugin::ColumnInfo *> *transaction_log_entries_view_columns= NULL;
89
static vector<const plugin::ColumnInfo *> *transaction_log_transactions_view_columns= NULL;
92
* Methods for I_S tables.
94
static plugin::InfoSchemaMethods *transaction_log_view_methods= NULL;
95
static plugin::InfoSchemaMethods *transaction_log_entries_view_methods= NULL;
96
static plugin::InfoSchemaMethods *transaction_log_transactions_view_methods= NULL;
101
plugin::InfoSchemaTable *transaction_log_view= NULL;
102
plugin::InfoSchemaTable *transaction_log_entries_view= NULL;
103
plugin::InfoSchemaTable *transaction_log_transactions_view= NULL;
105
static bool createTransactionLogViewColumns(vector<const drizzled::plugin::ColumnInfo *> &cols);
106
static bool createTransactionLogEntriesViewColumns(vector<const drizzled::plugin::ColumnInfo *> &cols);
107
static bool createTransactionLogTransactionsViewColumns(vector<const drizzled::plugin::ColumnInfo *> &cols);
109
int TransactionLogViewISMethods::fillTable(Session *,
111
plugin::InfoSchemaTable *schema_table)
113
if (transaction_log != NULL)
115
table->restoreRecordAsDefault();
117
table->setWriteSet(0);
118
table->setWriteSet(1);
119
table->setWriteSet(2);
120
table->setWriteSet(3);
121
table->setWriteSet(4);
122
table->setWriteSet(5);
123
table->setWriteSet(6);
124
table->setWriteSet(7);
126
const string &filename= transaction_log->getLogFilename();
127
table->field[0]->store(filename.c_str(), filename.length(), system_charset_info);
129
/* Grab the file size of the log */
130
struct stat file_stat;
131
(void) stat(filename.c_str(), &file_stat);
133
table->field[1]->store(static_cast<int64_t>(file_stat.st_size));
135
table->field[2]->store(static_cast<int64_t>(transaction_log_index->getNumLogEntries()));
136
table->field[3]->store(static_cast<int64_t>(transaction_log_index->getNumTransactionEntries()));
137
table->field[4]->store(static_cast<int64_t>(transaction_log_index->getMinTransactionId()));
138
table->field[5]->store(static_cast<int64_t>(transaction_log_index->getMaxTransactionId()));
139
table->field[6]->store(static_cast<int64_t>(transaction_log_index->getMinEndTimestamp()));
140
table->field[7]->store(static_cast<int64_t>(transaction_log_index->getMaxEndTimestamp()));
142
/* store the actual record now */
143
schema_table->addRow(table->record[0], table->s->reclength);
148
int TransactionLogEntriesViewISMethods::fillTable(Session *,
150
plugin::InfoSchemaTable *schema_table)
152
if (transaction_log != NULL)
154
/** @todo trigger indexing update here. */
155
for (TransactionLog::Entries::iterator entry_iter= transaction_log_index->getEntries().begin();
156
entry_iter != transaction_log_index->getEntries().end();
159
TransactionLogEntry &entry= *entry_iter;
161
table->restoreRecordAsDefault();
163
table->setWriteSet(0);
164
table->setWriteSet(1);
165
table->setWriteSet(2);
167
table->field[0]->store(static_cast<int64_t>(entry.getOffset()));
168
const char *type_string= entry.getTypeAsString();
169
table->field[1]->store(type_string, strlen(type_string), system_charset_info);
170
table->field[2]->store(static_cast<int64_t>(entry.getLengthInBytes()));
172
/* store the actual record now */
173
schema_table->addRow(table->record[0], table->s->reclength);
179
int TransactionLogTransactionsViewISMethods::fillTable(Session *,
181
plugin::InfoSchemaTable *schema_table)
183
if (transaction_log != NULL)
185
/** @todo trigger indexing update here. */
186
for (TransactionLog::TransactionEntries::iterator entry_iter= transaction_log_index->getTransactionEntries().begin();
187
entry_iter != transaction_log_index->getTransactionEntries().end();
190
TransactionLogTransactionEntry &entry= *entry_iter;
192
table->restoreRecordAsDefault();
194
table->setWriteSet(0);
195
table->setWriteSet(1);
196
table->setWriteSet(2);
197
table->setWriteSet(3);
198
table->setWriteSet(4);
199
table->setWriteSet(5);
200
table->setWriteSet(6);
202
table->field[0]->store(static_cast<int64_t>(entry.getOffset()));
203
table->field[1]->store(static_cast<int64_t>(entry.getTransactionId()));
204
table->field[2]->store(static_cast<int64_t>(entry.getServerId()));
205
table->field[3]->store(static_cast<int64_t>(entry.getStartTimestamp()));
206
table->field[4]->store(static_cast<int64_t>(entry.getEndTimestamp()));
207
table->field[5]->store(static_cast<int64_t>(entry.getNumStatements()));
208
table->field[6]->store(static_cast<int64_t>(entry.getChecksum()));
210
/* store the actual record now */
211
schema_table->addRow(table->record[0], table->s->reclength);
217
static bool createTransactionLogViewColumns(vector<const plugin::ColumnInfo *> &cols)
220
* Create each column for the INFORMATION_SCHEMA.TRANSACTION_LOG view
222
const plugin::ColumnInfo *file_name_col=
223
new (nothrow) plugin::ColumnInfo("FILE_NAME",
225
DRIZZLE_TYPE_VARCHAR,
228
"Filename of the transaction log");
229
if (file_name_col == NULL)
231
errmsg_printf(ERRMSG_LVL_ERROR, _("Failed to allocate ColumnInfo %s. Got error: %s\n"),
237
const plugin::ColumnInfo *file_length_col=
238
new (nothrow) plugin::ColumnInfo("FILE_LENGTH",
240
DRIZZLE_TYPE_LONGLONG,
243
"Length in bytes of the transaction log");
244
if (file_length_col == NULL)
246
errmsg_printf(ERRMSG_LVL_ERROR, _("Failed to allocate ColumnInfo %s. Got error: %s\n"),
252
const plugin::ColumnInfo *num_log_entries_col=
253
new (nothrow) plugin::ColumnInfo("NUM_LOG_ENTRIES",
255
DRIZZLE_TYPE_LONGLONG,
258
"Total number of entries in the transaction log");
259
if (num_log_entries_col == NULL)
261
errmsg_printf(ERRMSG_LVL_ERROR, _("Failed to allocate ColumnInfo %s. Got error: %s\n"),
267
const plugin::ColumnInfo *num_transactions_col=
268
new (nothrow) plugin::ColumnInfo("NUM_TRANSACTIONS",
270
DRIZZLE_TYPE_LONGLONG,
273
"Total number of transaction message entries in the transaction log");
274
if (num_transactions_col == NULL)
276
errmsg_printf(ERRMSG_LVL_ERROR, _("Failed to allocate ColumnInfo %s. Got error: %s\n"),
282
const plugin::ColumnInfo *min_transaction_id_col=
283
new (nothrow) plugin::ColumnInfo("MIN_TRANSACTION_ID",
285
DRIZZLE_TYPE_LONGLONG,
288
"Minimum transaction ID in the transaction log");
289
if (min_transaction_id_col == NULL)
291
errmsg_printf(ERRMSG_LVL_ERROR, _("Failed to allocate ColumnInfo %s. Got error: %s\n"),
292
"MIN_TRANSACTION_ID",
297
const plugin::ColumnInfo *max_transaction_id_col=
298
new (nothrow) plugin::ColumnInfo("MAX_TRANSACTION_ID",
300
DRIZZLE_TYPE_LONGLONG,
303
"Maximum transaction ID in the transaction log");
304
if (max_transaction_id_col == NULL)
306
errmsg_printf(ERRMSG_LVL_ERROR, _("Failed to allocate ColumnInfo %s. Got error: %s\n"),
307
"MAX_TRANSACTION_ID",
312
const plugin::ColumnInfo *min_timestamp_col=
313
new (nothrow) plugin::ColumnInfo("MIN_END_TIMESTAMP",
315
DRIZZLE_TYPE_LONGLONG,
318
"Minimum end timestamp for a transaction in the transaction log");
319
if (min_timestamp_col == NULL)
321
errmsg_printf(ERRMSG_LVL_ERROR, _("Failed to allocate ColumnInfo %s. Got error: %s\n"),
327
const plugin::ColumnInfo *max_timestamp_col=
328
new (nothrow) plugin::ColumnInfo("MAX_END_TIMESTAMP",
330
DRIZZLE_TYPE_LONGLONG,
333
"Maximum end timestamp for a transaction in the transaction log");
334
if (max_timestamp_col == NULL)
336
errmsg_printf(ERRMSG_LVL_ERROR, _("Failed to allocate ColumnInfo %s. Got error: %s\n"),
342
cols.push_back(file_name_col);
343
cols.push_back(file_length_col);
344
cols.push_back(num_log_entries_col);
345
cols.push_back(num_transactions_col);
346
cols.push_back(min_transaction_id_col);
347
cols.push_back(max_transaction_id_col);
348
cols.push_back(min_timestamp_col);
349
cols.push_back(max_timestamp_col);
354
static bool createTransactionLogEntriesViewColumns(vector<const plugin::ColumnInfo *> &cols)
357
* Create each column for the INFORMATION_SCHEMA.TRANSACTION_LOG_ENTRIES view
359
const plugin::ColumnInfo *entry_offset_col=
360
new (nothrow) plugin::ColumnInfo("ENTRY_OFFSET",
362
DRIZZLE_TYPE_LONGLONG,
365
"Offset of this entry into the transaction log");
366
if (entry_offset_col == NULL)
368
errmsg_printf(ERRMSG_LVL_ERROR, _("Failed to allocate ColumnInfo %s. Got error: %s\n"),
374
const plugin::ColumnInfo *entry_type_col=
375
new (nothrow) plugin::ColumnInfo("ENTRY_TYPE",
377
DRIZZLE_TYPE_VARCHAR,
380
"Type of this entry");
381
if (entry_type_col == NULL)
383
errmsg_printf(ERRMSG_LVL_ERROR, _("Failed to allocate ColumnInfo %s. Got error: %s\n"),
389
const plugin::ColumnInfo *entry_length_col=
390
new (nothrow) plugin::ColumnInfo("ENTRY_LENGTH",
392
DRIZZLE_TYPE_LONGLONG,
395
"Length in bytes of this entry");
396
if (entry_length_col == NULL)
398
errmsg_printf(ERRMSG_LVL_ERROR, _("Failed to allocate ColumnInfo %s. Got error: %s\n"),
404
cols.push_back(entry_offset_col);
405
cols.push_back(entry_type_col);
406
cols.push_back(entry_length_col);
411
static bool createTransactionLogTransactionsViewColumns(vector<const plugin::ColumnInfo *> &cols)
414
* Create each column for the INFORMATION_SCHEMA.TRANSACTION_LOG_TRANSACTIONS view
416
const plugin::ColumnInfo *entry_offset_col=
417
new (nothrow) plugin::ColumnInfo("ENTRY_OFFSET",
419
DRIZZLE_TYPE_LONGLONG,
422
"Offset of this entry into the transaction log");
423
if (entry_offset_col == NULL)
425
errmsg_printf(ERRMSG_LVL_ERROR, _("Failed to allocate ColumnInfo %s. Got error: %s\n"),
431
const plugin::ColumnInfo *transaction_id_col=
432
new (nothrow) plugin::ColumnInfo("TRANSACTION_ID",
434
DRIZZLE_TYPE_LONGLONG,
437
"Transaction ID for this entry");
438
if (transaction_id_col == NULL)
440
errmsg_printf(ERRMSG_LVL_ERROR, _("Failed to allocate ColumnInfo %s. Got error: %s\n"),
446
const plugin::ColumnInfo *server_id_col=
447
new (nothrow) plugin::ColumnInfo("SERVER_ID",
449
DRIZZLE_TYPE_LONGLONG,
452
"Server ID for this entry");
453
if (server_id_col == NULL)
455
errmsg_printf(ERRMSG_LVL_ERROR, _("Failed to allocate ColumnInfo %s. Got error: %s\n"),
461
const plugin::ColumnInfo *start_timestamp_col=
462
new (nothrow) plugin::ColumnInfo("START_TIMESTAMP",
464
DRIZZLE_TYPE_LONGLONG,
467
"Start timestamp for this transaction");
468
if (start_timestamp_col == NULL)
470
errmsg_printf(ERRMSG_LVL_ERROR, _("Failed to allocate ColumnInfo %s. Got error: %s\n"),
476
const plugin::ColumnInfo *end_timestamp_col=
477
new (nothrow) plugin::ColumnInfo("END_TIMESTAMP",
479
DRIZZLE_TYPE_LONGLONG,
482
"End timestamp for this transaction");
483
if (end_timestamp_col == NULL)
485
errmsg_printf(ERRMSG_LVL_ERROR, _("Failed to allocate ColumnInfo %s. Got error: %s\n"),
491
const plugin::ColumnInfo *num_statements_col=
492
new (nothrow) plugin::ColumnInfo("NUM_STATEMENTS",
494
DRIZZLE_TYPE_LONGLONG,
497
"Number of statements in this transaction");
498
if (num_statements_col == NULL)
500
errmsg_printf(ERRMSG_LVL_ERROR, _("Failed to allocate ColumnInfo %s. Got error: %s\n"),
506
const plugin::ColumnInfo *checksum_col=
507
new (nothrow) plugin::ColumnInfo("CHECKSUM",
509
DRIZZLE_TYPE_LONGLONG,
512
"Checksum of this transaction");
513
if (checksum_col == NULL)
515
errmsg_printf(ERRMSG_LVL_ERROR, _("Failed to allocate ColumnInfo %s. Got error: %s\n"),
521
cols.push_back(entry_offset_col);
522
cols.push_back(transaction_id_col);
523
cols.push_back(server_id_col);
524
cols.push_back(start_timestamp_col);
525
cols.push_back(end_timestamp_col);
526
cols.push_back(num_statements_col);
527
cols.push_back(checksum_col);
532
bool initViewColumns()
534
transaction_log_view_columns= new (nothrow) vector<const plugin::ColumnInfo *>;
535
if (transaction_log_view_columns == NULL)
539
transaction_log_entries_view_columns= new (nothrow) vector<const plugin::ColumnInfo *>;
540
if (transaction_log_entries_view_columns == NULL)
544
transaction_log_transactions_view_columns= new (nothrow) vector<const plugin::ColumnInfo *>;
545
if (transaction_log_transactions_view_columns == NULL)
550
if (createTransactionLogViewColumns(*transaction_log_view_columns))
555
if (createTransactionLogEntriesViewColumns(*transaction_log_entries_view_columns))
560
if (createTransactionLogTransactionsViewColumns(*transaction_log_transactions_view_columns))
568
static void clearViewColumns(vector<const plugin::ColumnInfo *> &cols)
570
for_each(cols.begin(), cols.end(), DeletePtr());
574
void cleanupViewColumns()
576
clearViewColumns(*transaction_log_view_columns);
577
delete transaction_log_view_columns;
578
clearViewColumns(*transaction_log_entries_view_columns);
579
delete transaction_log_entries_view_columns;
580
clearViewColumns(*transaction_log_transactions_view_columns);
581
delete transaction_log_transactions_view_columns;
584
bool initViewMethods()
586
transaction_log_view_methods= new (nothrow) TransactionLogViewISMethods();
587
if (transaction_log_view_methods == NULL)
589
errmsg_printf(ERRMSG_LVL_ERROR, _("Failed to allocate TransactionLogViewISMethods. Got error: %s\n"),
594
transaction_log_entries_view_methods= new (nothrow) TransactionLogEntriesViewISMethods();
595
if (transaction_log_entries_view_methods == NULL)
597
errmsg_printf(ERRMSG_LVL_ERROR, _("Failed to allocate TransactionLogEntriesViewISMethods. Got error: %s\n"),
602
transaction_log_transactions_view_methods= new (nothrow) TransactionLogTransactionsViewISMethods();
603
if (transaction_log_transactions_view_methods == NULL)
605
errmsg_printf(ERRMSG_LVL_ERROR, _("Failed to allocate TransactionLogTransactionsViewISMethods. Got error: %s\n"),
613
void cleanupViewMethods()
615
delete transaction_log_view_methods;
616
delete transaction_log_entries_view_methods;
617
delete transaction_log_transactions_view_methods;
622
transaction_log_view=
623
new (nothrow) plugin::InfoSchemaTable("TRANSACTION_LOG",
624
*transaction_log_view_columns,
625
-1, -1, false, false, 0,
626
transaction_log_view_methods);
627
if (transaction_log_view == NULL)
629
errmsg_printf(ERRMSG_LVL_ERROR, _("Failed to allocate InfoSchemaTable for %s. Got error: %s\n"),
635
transaction_log_entries_view=
636
new (nothrow) plugin::InfoSchemaTable("TRANSACTION_LOG_ENTRIES",
637
*transaction_log_entries_view_columns,
638
-1, -1, false, false, 0,
639
transaction_log_entries_view_methods);
640
if (transaction_log_entries_view == NULL)
642
errmsg_printf(ERRMSG_LVL_ERROR, _("Failed to allocate InfoSchemaTable for %s. Got error: %s\n"),
643
"TRANSACTION_LOG_ENTRIES",
648
transaction_log_transactions_view=
649
new (nothrow) plugin::InfoSchemaTable("TRANSACTION_LOG_TRANSACTIONS",
650
*transaction_log_transactions_view_columns,
651
-1, -1, false, false, 0,
652
transaction_log_transactions_view_methods);
653
if (transaction_log_transactions_view == NULL)
655
errmsg_printf(ERRMSG_LVL_ERROR, _("Failed to allocate InfoSchemaTable for %s. Got error: %s\n"),
656
"TRANSACTION_LOG_TRANSACTIONS",
666
delete transaction_log_view;
667
delete transaction_log_entries_view;
668
delete transaction_log_transactions_view;