summaryrefslogtreecommitdiff
path: root/storage/pbxt
diff options
context:
space:
mode:
authorMichael Widenius <monty@askmonty.org>2010-05-12 17:27:18 +0300
committerMichael Widenius <monty@askmonty.org>2010-05-12 17:27:18 +0300
commit8b2abdcf41da724c3685be85611ace237f085374 (patch)
treebd034274b6b4129c0a5883fc1bcd358a449df207 /storage/pbxt
parentf6615e4898cc8b611b9c398731d69d141345dffb (diff)
parent6248c89a4bfc66c7f9319f406bee08dc39ef5378 (diff)
downloadmariadb-git-8b2abdcf41da724c3685be85611ace237f085374.tar.gz
Merge to get PBXT's xstat program
scripts/make_binary_distribution.sh: Added copying of xstat scripts/make_win_bin_dist: Added copying of xstat
Diffstat (limited to 'storage/pbxt')
-rw-r--r--storage/pbxt/Makefile.am2
-rw-r--r--storage/pbxt/bin/Makefile.am14
-rw-r--r--storage/pbxt/bin/xtstat_xt.cc819
-rw-r--r--storage/pbxt/src/ha_pbxt.cc1
-rw-r--r--storage/pbxt/src/myxt_xt.cc1
-rw-r--r--storage/pbxt/src/xt_config.h4
6 files changed, 840 insertions, 1 deletions
diff --git a/storage/pbxt/Makefile.am b/storage/pbxt/Makefile.am
index 4ef1eab50c2..371756c84be 100644
--- a/storage/pbxt/Makefile.am
+++ b/storage/pbxt/Makefile.am
@@ -1,3 +1,3 @@
-SUBDIRS = src
+SUBDIRS = src bin
EXTRA_DIST = CMakeLists.txt plug.in
diff --git a/storage/pbxt/bin/Makefile.am b/storage/pbxt/bin/Makefile.am
new file mode 100644
index 00000000000..9408545d3b8
--- /dev/null
+++ b/storage/pbxt/bin/Makefile.am
@@ -0,0 +1,14 @@
+# Used to build Makefile.in
+
+INCLUDES = -I$(top_srcdir)/include -I$(top_builddir)/include \
+ -I$(top_srcdir)/regex \
+ -I$(top_srcdir)/storage/innobase/include \
+ -I$(top_srcdir)/sql \
+ -I$(srcdir) \
+ -I../src
+
+bin_PROGRAMS = xtstat
+
+xtstat_SOURCES = xtstat_xt.cc ../src/strutil_xt.cc
+
+xtstat_LDADD = $(top_srcdir)/libmysql/libmysqlclient.la
diff --git a/storage/pbxt/bin/xtstat_xt.cc b/storage/pbxt/bin/xtstat_xt.cc
new file mode 100644
index 00000000000..2656057e65e
--- /dev/null
+++ b/storage/pbxt/bin/xtstat_xt.cc
@@ -0,0 +1,819 @@
+/* Copyright (c) 2005 PrimeBase Technologies GmbH
+ *
+ * PrimeBase XT
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * 2008-11-19 Paul McCullagh
+ *
+ * H&G2JCtL
+ */
+
+#include "xt_config.h"
+
+#include <mysql.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <ctype.h>
+#include <string.h>
+
+#include "strutil_xt.h"
+#include "util_xt.h"
+
+//#define DEBUG_INTERRUPT
+
+#define OPT_NONE -1
+#define OPT_HELP 0
+#define OPT_HOST 1
+#define OPT_USER 2
+#define OPT_PASSWORD 3
+#define OPT_DATABASE 4
+#define OPT_PORT 5
+#define OPT_SOCKET 6
+#define OPT_DELAY 7
+#define OPT_PROTOCOL 8
+#define OPT_DISPLAY 9
+
+#define OPT_HAS_VALUE 1
+#define OPT_OPTIONAL 2
+#define OPT_INTEGER 4
+
+llong record_cache_size;
+llong index_cache_size;
+llong log_cache_size;
+
+llong accumulative_values[XT_STAT_CURRENT_MAX];
+int columns_used;
+int use_i_s = 0;
+
+struct DisplayOrder {
+ int do_statistic;
+ bool do_combo;
+} display_order[XT_STAT_CURRENT_MAX];
+
+struct Options {
+ int opt_id;
+ const char opt_char;
+ const char *opt_name;
+ int opt_flags;
+ const char *opt_desc;
+ const char *opt_value_str;
+ int opt_value_int;
+ bool opt_value_bool;
+} options[] = {
+ { OPT_HELP, '?', "help", 0,
+ "Prints help text", NULL, 0, false },
+ { OPT_HOST, 'h', "host", OPT_HAS_VALUE,
+ "Connect to host", NULL, 0, false },
+ { OPT_USER, 'u', "user", OPT_HAS_VALUE,
+ "User for login if not current user", NULL, 0, false },
+ { OPT_PASSWORD, 'p', "password", OPT_HAS_VALUE | OPT_OPTIONAL,
+ "Password to use when connecting to server. If password is not given it's asked from the tty", NULL, 0, false },
+ { OPT_DATABASE, 'd', "database", OPT_HAS_VALUE,
+ "Database to be used (pbxt or information_schema required), default is information_schema", "information_schema", 0, false },
+ { OPT_PORT, 'P', "port", OPT_HAS_VALUE | OPT_INTEGER,
+ "Port number to use for connection", NULL, 3306, false },
+ { OPT_SOCKET, 'S', "socket", OPT_HAS_VALUE,
+ "Socket file to use for connection", NULL, 0, false },
+ { OPT_DELAY, 'D', "delay", OPT_HAS_VALUE | OPT_INTEGER,
+ "Delay in seconds between polls of the database", NULL, 1, false },
+ { OPT_PROTOCOL, 0, "protocol", OPT_HAS_VALUE,
+ "Connection protocol to use: default/tcp/socket/pipe/memory", "default", MYSQL_PROTOCOL_DEFAULT, false },
+ { OPT_DISPLAY, 0, "display", OPT_HAS_VALUE,
+ "Columns to display: use short names separated by |, partial match allowed", "time-msec,commt,row-ins,rec,ind,ilog,xlog,data,to,dirty", 0, false },
+ { OPT_NONE, 0, NULL, 0, NULL, 0, false }
+};
+
+#ifdef XT_WIN
+#define atoll _atoi64
+#endif
+
+void add_statistic(int stat)
+{
+ /* Check if column has already been added: */
+ for (int i=0; i<columns_used; i++) {
+ if (display_order[i].do_statistic == stat)
+ return;
+ }
+ display_order[columns_used].do_statistic = stat;
+ display_order[columns_used].do_combo = false;
+ columns_used++;
+}
+
+void determine_display_order()
+{
+ const char *cols = options[OPT_DISPLAY].opt_value_str;
+ char column_1[21], column_2[21];
+ int i;
+ bool add, added, add_combo;
+ XTStatMetaDataPtr meta, meta2;
+
+ if (strcmp(cols, "all") == 0)
+ cols = "time,xact,stat,rec,ind,ilog,xlog,data,to,sweep,scan,row";
+ columns_used = 0;
+ while (*cols) {
+ i = 0;
+ while (*cols && *cols != '-' && *cols != ',') {
+ if (i < 20) {
+ column_1[i] = *cols;
+ i++;
+ }
+ cols++;
+ }
+ column_1[i] = 0;
+
+ i = 0;
+ if (*cols == '-') {
+ cols++;
+ while (*cols && *cols != '-' && *cols != ',') {
+ if (i < 20) {
+ column_2[i] = *cols;
+ i++;
+ }
+ cols++;
+ }
+ }
+ column_2[i] = 0;
+
+ if (*cols == ',')
+ cols++;
+
+ if (strcmp(column_1, "ms") == 0)
+ strcpy(column_1, "msec");
+ if (strcmp(column_2, "ms") == 0)
+ strcpy(column_2, "msec");
+ add_combo = false;
+ if (strcmp(column_1, "syncs/ms") == 0) {
+ strcpy(column_1, "syncs");
+ add_combo = true;
+ }
+ if (strcmp(column_2, "syncs/ms") == 0) {
+ strcpy(column_2, "syncs");
+ add_combo = true;
+ }
+
+ added = false;
+ for (i=0; i<XT_STAT_MAXIMUM; i++) {
+ meta = xt_get_stat_meta_data(i);
+ add = false;
+ if (strcmp(meta->sm_short_line_1, column_1) == 0) {
+ if (column_2[0]) {
+ if (strcmp(meta->sm_short_line_2, column_2) == 0)
+ add = true;
+ }
+ else {
+ if (i != XT_STAT_XLOG_CACHE_USAGE)
+ add = true;
+ }
+ }
+ else if (!column_2[0]) {
+ if (strcmp(meta->sm_short_line_2, column_1) == 0) {
+ /* XT_STAT_XLOG_CACHE_USAGE is ignored, unless explicity listed! */
+ if (i != XT_STAT_XLOG_CACHE_USAGE)
+ add = true;
+ }
+ }
+ if (add) {
+ added = true;
+ add_statistic(i);
+ if (add_combo)
+ add_statistic(i+1);
+ }
+ }
+ if (!added) {
+ if (column_2[0])
+ fprintf(stderr, "ERROR: No statistic matches display option: '%s-%s'\n", column_1, column_2);
+ else
+ fprintf(stderr, "ERROR: No statistic matches display option: '%s'\n", column_1);
+ fprintf(stderr, "Display options: %s\n", options[OPT_DISPLAY].opt_value_str);
+ exit(1);
+ }
+ }
+
+ /* Setup "combo" fields: */
+ for (i=0; i<columns_used; i++) {
+ meta = xt_get_stat_meta_data(display_order[i].do_statistic);
+ if (meta->sm_flags & XT_STAT_COMBO_FIELD) {
+ if (i+1 < columns_used) {
+ meta2 = xt_get_stat_meta_data(display_order[i+1].do_statistic);
+ if (meta2->sm_flags & XT_STAT_COMBO_FIELD_2) {
+ if (strcmp(meta->sm_short_line_1, meta2->sm_short_line_1) == 0)
+ display_order[i].do_combo = true;
+ }
+ }
+ }
+ }
+}
+
+void format_percent_value(char *buffer, double value, double perc)
+{
+ value = value * (double) 100 / (double) perc;
+ if (value >= 100)
+ sprintf(buffer, "%.0f", value);
+ else
+ sprintf(buffer, "%.1f", value);
+ buffer[4] = 0;
+ if (buffer[3] == '.')
+ buffer[3] = 0;
+}
+
+#define XT_1_K ((double) 1024)
+#define XT_1_M ((double) 1024 * (double) 1024)
+#define XT_1_G ((double) 1024 * (double) 1024 * (double) 1024)
+#define XT_1_T ((double) 1024 * (double) 1024 * (double) 1024 * (double) 1024)
+#define XT_10000_K ((double) 10000 * XT_1_K)
+#define XT_10000_M ((double) 10000 * XT_1_M)
+#define XT_10000_G ((double) 10000 * XT_1_G)
+
+void format_byte_value(char *buffer, double value)
+{
+ double dval;
+ char string[100];
+ char ch;
+
+ if (value < (double) 100000) {
+ /* byte value from 0 to 99999: */
+ sprintf(buffer, "%.0f", value);
+ return;
+ }
+
+ if (value < XT_10000_K) {
+ dval = value / XT_1_K;
+ ch = 'K';
+ }
+ else if (value < XT_10000_M) {
+ dval = value / XT_1_M;
+ ch = 'M';
+ }
+ else if (value < XT_10000_G) {
+ dval = value / XT_1_G;
+ ch = 'G';
+ }
+ else {
+ dval = value / XT_1_T;
+ ch = 'T';
+ }
+
+ if (dval < (double) 10.0)
+ sprintf(string, "%.2f", dval);
+ else if (dval < (double) 100.0)
+ sprintf(string, "%.1f", dval);
+ else
+ sprintf(string, "%.0f", dval);
+ if (string[3] == '.')
+ string[3] = 0;
+ else
+ string[4] = 0;
+ sprintf(buffer, "%s%c", string, ch);
+}
+
+/*
+ * Uses:
+ * t = thousands
+ * m = millions
+ * b = billions
+ */
+void format_mini_count_value(char *buffer, double value)
+{
+ double dval;
+ char string[100];
+ char ch;
+
+ if (value < (double) 100) {
+ /* Value from 0 to 99: */
+ sprintf(buffer, "%.0f", value);
+ return;
+ }
+
+ if (value < (double) 1000) {
+ sprintf(buffer, "<t");
+ return;
+ }
+
+ if (value < (double) 10000) {
+ /* Value is less than 1m */
+ dval = value / (double) 1000.0;
+ ch = 't';
+ }
+ else if (value < (double) 1000000) {
+ sprintf(buffer, "<m");
+ return;
+ }
+ else if (value < (double) 10000000) {
+ /* Value is less than 1b */
+ dval = value / (double) 1000000.0;
+ ch = 'm';
+ }
+ else if (value < (double) 1000000000) {
+ sprintf(buffer, "<b");
+ return;
+ }
+ else {
+ /* Value is greater than 1 billion */
+ dval = value / (double) 1000000000.0;
+ ch = 'b';
+ }
+
+ sprintf(string, "%1.0f", dval);
+ string[1] = 0;
+ sprintf(buffer, "%s%c", string, ch);
+}
+
+#define XT_1_THOUSAND ((double) 1000)
+#define XT_1_MILLION ((double) 1000 * (double) 1000)
+#define XT_1_BILLION ((double) 1000 * (double) 1000 * (double) 1000)
+#define XT_1_TRILLION ((double) 1000 * (double) 1000 * (double) 1000 * (double) 1000)
+#define XT_10_THOUSAND ((double) 10 * (double) 1000)
+#define XT_10_MILLION ((double) 10 * (double) 1000 * (double) 1000)
+#define XT_10_BILLION ((double) 10 * (double) 1000 * (double) 1000 * (double) 1000)
+#define XT_10_TRILLION ((double) 10 * (double) 1000 * (double) 1000 * (double) 1000 * (double) 1000)
+
+void format_count_value(char *buffer, double value)
+{
+ double dval;
+ char string[100];
+ char ch;
+
+ if (value < (double) 0) {
+ strcpy(buffer, "0");
+ return;
+ }
+
+ if (value < XT_10_THOUSAND) {
+ /* byte value from 0 to 99999: */
+ sprintf(buffer, "%.0f", value);
+ return;
+ }
+
+ if (value < XT_10_MILLION) {
+ /* Value is less than 10 million */
+ dval = value / XT_1_THOUSAND;
+ ch = 't';
+ }
+ else if (value < XT_10_BILLION) {
+ /* Value is less than 10 million */
+ dval = value / XT_1_MILLION;
+ ch = 'm';
+ }
+ else if (value < XT_10_TRILLION) {
+ /* Value is less than 10 trillion */
+ dval = value / XT_1_BILLION;
+ ch = 'b';
+ }
+ else {
+ dval = value / XT_1_TRILLION;
+ ch = 't';
+ }
+
+ if (dval < (double) 10.0)
+ sprintf(string, "%.2f", dval);
+ else if (dval < (double) 100.0)
+ sprintf(string, "%.1f", dval);
+ else
+ sprintf(string, "%.0f", dval);
+ if (string[3] == '.')
+ string[3] = 0;
+ else
+ string[4] = 0;
+ sprintf(buffer, "%s%c", string, ch);
+}
+
+void print_help()
+{
+ struct Options *opt;
+ char command[100];
+
+ printf("Usage: xtstat [ options ]\n");
+ printf("e.g. xtstat -D10 : Poll every 10 seconds\n");
+ opt = options;
+ printf("Options :-\n");
+ while (opt->opt_id != OPT_NONE) {
+ strcpy(command, opt->opt_name);
+ if (opt->opt_flags & OPT_HAS_VALUE) {
+ if (opt->opt_flags & OPT_OPTIONAL)
+ strcat(command, "[=value]");
+ else
+ strcat(command, "=value");
+ }
+ if (opt->opt_char)
+ printf("-%c, --%-16s %s.\n", opt->opt_char, command, opt->opt_desc);
+ else
+ printf(" --%-16s %s.\n", command, opt->opt_desc);
+ opt++;
+ }
+}
+
+void print_stat_key()
+{
+ printf("Key :-\n");
+ printf("K = Kilobytes (1,024 bytes)\n");
+ printf("M = Megabytes (1,048,576 bytes)\n");
+ printf("G = Gigabytes (1,073,741,024 bytes)\n");
+ printf("T = Terabytes (1,099,511,627,776 bytes)\n");
+ printf("t = thousands (1,000s)\n");
+ printf("m = millions (1,000,000s)\n");
+ printf("b = billions (1,000,000,000s)\n");
+}
+
+void print_stat_info()
+{
+ XTStatMetaDataPtr meta;
+ char buffer[40];
+ char desc[400];
+
+ printf("Statistics :-\n");
+ for (int i=0; i<XT_STAT_CURRENT_MAX; i++) {
+ meta = xt_get_stat_meta_data(i);
+ sprintf(desc, meta->sm_description, "milli");
+ sprintf(buffer, "%s-%s", meta->sm_short_line_1, meta->sm_short_line_2);
+ if (meta->sm_flags & XT_STAT_COMBO_FIELD) {
+ /* Combine next 2 fields: */
+ i++;
+ strcat(buffer, "/ms");
+ strcat(desc, "/time taken in milliseconds");
+ }
+ printf("%-13s %-21s - %s.\n", buffer, meta->sm_name, desc);
+ }
+}
+
+bool match_arg(char *what, const char *opt, char **value)
+{
+ while (*what && *opt && isalpha(*what)) {
+ if (*what != *opt)
+ return false;
+ what++;
+ opt++;
+ }
+ if (*opt)
+ return false;
+ if (*what == '=')
+ *value = what + 1;
+ else if (*what)
+ return false;
+ else
+ *value = NULL;
+ return true;
+}
+
+void parse_args(int argc, char **argv)
+{
+ char *ptr;
+ char *value;
+ int i = 1;
+ struct Options *opt;
+ bool found;
+
+ while (i < argc) {
+ ptr = argv[i];
+ found = false;
+ if (*ptr == '-') {
+ ptr++;
+ if (*ptr == '-') {
+ ptr++;
+ opt = options;
+ while (opt->opt_id != OPT_NONE) {
+ if (match_arg(ptr, opt->opt_name, &value)) {
+ found = true;
+ opt->opt_value_str = value;
+ opt->opt_value_bool = true;
+ break;
+ }
+ opt++;
+ }
+ }
+ else {
+ opt = options;
+ while (opt->opt_id != OPT_NONE) {
+ if (*ptr == opt->opt_char) {
+ ptr++;
+ if (*ptr)
+ opt->opt_value_str = ptr;
+ else {
+ opt->opt_value_str = NULL;
+ if (i+1 < argc) {
+ ptr = argv[i+1];
+ if (*ptr != '-') {
+ opt->opt_value_str = ptr;
+ i++;
+ }
+ }
+ }
+ found = true;
+ opt->opt_value_bool = true;
+ break;
+ }
+ opt++;
+ }
+ }
+ }
+
+ if (!found) {
+ fprintf(stderr, "Unknown option: %s\n", argv[i]);
+ print_help();
+ exit(1);
+ }
+
+ if (opt->opt_flags & OPT_HAS_VALUE) {
+ if (!(opt->opt_flags & OPT_OPTIONAL)) {
+ if (!opt->opt_value_str) {
+ fprintf(stderr, "Option requires a value: %s\n", argv[i]);
+ printf("Use --help for help on commands and usage\n");
+ exit(1);
+ }
+ }
+ }
+ else {
+ if (opt->opt_value_str) {
+ fprintf(stderr, "Option does not accept a value: %s\n", argv[i]);
+ printf("Use --help for help on commands and usage\n");
+ exit(1);
+ }
+ }
+
+ if (opt->opt_value_str && (opt->opt_flags & OPT_INTEGER))
+ opt->opt_value_int = atoi(opt->opt_value_str);
+
+ if (opt->opt_id == OPT_HELP) {
+ print_help();
+ print_stat_key();
+ print_stat_info();
+ exit(1);
+ }
+
+ i++;
+ }
+}
+
+#ifdef DEBUG_INTERRUPT
+void interrupt_pbxt(MYSQL *conn)
+{
+ MYSQL_RES *res;
+
+ if (mysql_query(conn, "show engine pbxt status")) {
+ fprintf(stderr, "%s\n", mysql_error(conn));
+ exit(1);
+ }
+
+ res = mysql_use_result(conn);
+ mysql_free_result(res);
+}
+#endif
+
+static bool display_parameters(MYSQL *conn)
+{
+ MYSQL_RES *res;
+ MYSQL_ROW row;
+
+ /* send SQL query */
+ if (mysql_query(conn, "show variables like 'pbxt_%'"))
+ return false;
+
+ if (!(res = mysql_use_result(conn)))
+ return false;
+
+ /* output table name */
+ printf("-- PBXT System Variables --\n");
+ while ((row = mysql_fetch_row(res)) != NULL) {
+ if (strcmp(row[0], "pbxt_index_cache_size") == 0)
+ index_cache_size = xt_byte_size_to_int8(row[1]);
+ else if (strcmp(row[0], "pbxt_record_cache_size") == 0)
+ record_cache_size = xt_byte_size_to_int8(row[1]);
+ else if (strcmp(row[0], "pbxt_log_cache_size") == 0)
+ log_cache_size = xt_byte_size_to_int8(row[1]);
+ printf("%-29s= %s\n", row[0], row[1]);
+ }
+
+ mysql_free_result(res);
+
+ for (int i=0; i<XT_STAT_CURRENT_MAX; i++)
+ accumulative_values[i] = 0;
+
+ printf("Display options: %s\n", options[OPT_DISPLAY].opt_value_str);
+ return true;
+}
+
+static bool connect(MYSQL *conn)
+{
+ unsigned int type;
+
+ if (strcasecmp(options[OPT_PROTOCOL].opt_value_str, "tcp") == 0)
+ type = MYSQL_PROTOCOL_TCP;
+ else if (strcasecmp(options[OPT_PROTOCOL].opt_value_str, "socket") == 0)
+ type = MYSQL_PROTOCOL_SOCKET;
+ else if (strcasecmp(options[OPT_PROTOCOL].opt_value_str, "pipe") == 0)
+ type = MYSQL_PROTOCOL_PIPE;
+ else if (strcasecmp(options[OPT_PROTOCOL].opt_value_str, "memory") == 0)
+ type = MYSQL_PROTOCOL_MEMORY;
+ else
+ type = MYSQL_PROTOCOL_DEFAULT;
+
+ if (mysql_options(conn, MYSQL_OPT_PROTOCOL, (char *) &type))
+ return false;
+
+ if (mysql_options(conn, MYSQL_READ_DEFAULT_GROUP, "xtstat"))
+ return false;
+
+ if (strcasecmp(options[OPT_DATABASE].opt_value_str, "pbxt") == 0)
+ use_i_s = FALSE;
+ else if (strcasecmp(options[OPT_DATABASE].opt_value_str, "information_schema") == 0)
+ use_i_s = TRUE;
+ else
+ use_i_s = TRUE;
+
+ /* Connect to database */
+ if (!mysql_real_connect(conn,
+ options[OPT_HOST].opt_value_str,
+ options[OPT_USER].opt_value_str,
+ options[OPT_PASSWORD].opt_value_str,
+ options[OPT_DATABASE].opt_value_str,
+ options[OPT_PORT].opt_value_int,
+ options[OPT_SOCKET].opt_value_str,
+ 0))
+ return false;
+
+ return true;
+}
+
+int main(int argc, char **argv)
+{
+ MYSQL *conn;
+ MYSQL_RES *res;
+ MYSQL_ROW row;
+ llong current_values[XT_STAT_CURRENT_MAX];
+ double value;
+ char str_value[100];
+ XTStatMetaDataPtr meta;
+ int len;
+ int stat;
+ int err;
+ bool select_worked = true;
+
+ xt_set_time_unit("msec");
+ parse_args(argc, argv);
+
+ determine_display_order();
+
+ if (!(conn = mysql_init(NULL))) {
+ fprintf(stderr, "Insufficient memory\n");
+ exit(1);
+ }
+
+ if (!connect(conn) || !display_parameters(conn)) {
+ fprintf(stderr, "%s\n", mysql_error(conn));
+ exit(1);
+ }
+
+ retry:
+ for (int loop = 0; ; loop++) {
+ if (use_i_s)
+ err = mysql_query(conn, "select id, Value from information_schema.pbxt_statistics order by ID");
+ else
+ err = mysql_query(conn, "select id, Value from pbxt.statistics order by ID");
+ if (err)
+ goto reconnect;
+
+ if (!(res = mysql_use_result(conn)))
+ goto reconnect;
+ select_worked = true;
+
+ while ((row = mysql_fetch_row(res)) != NULL) {
+ stat = atoi(row[0])-1;
+ current_values[stat] = atoll(row[1]);
+ }
+ mysql_free_result(res);
+
+#ifdef DEBUG_INTERRUPT
+ if (current_values[XT_STAT_STAT_WRITES] - accumulative_values[XT_STAT_STAT_WRITES] == 0 &&
+ current_values[XT_STAT_REC_SYNC_TIME] - accumulative_values[XT_STAT_REC_SYNC_TIME] == 0 &&
+ current_values[XT_STAT_IND_SYNC_TIME] - accumulative_values[XT_STAT_IND_SYNC_TIME] == 0)
+ interrupt_pbxt();
+#endif
+
+ if ((loop % 25) == 0) {
+ for (int column=0; column<columns_used; column++) {
+ len = 5;
+ meta = xt_get_stat_meta_data(display_order[column].do_statistic);
+ strcpy(str_value, meta->sm_short_line_1);
+ if (display_order[column].do_combo) {
+ /* Combine next 2 fields: */
+ len = 8;
+ column++;
+ }
+ else if (meta->sm_flags & XT_STAT_PERCENTAGE)
+ len = 4;
+ else if (meta->sm_flags & XT_STAT_DATE)
+ len = 15;
+ printf("%*s ", len, str_value);
+ }
+ printf("\n");
+ for (int column=0; column<columns_used; column++) {
+ len = 5;
+ meta = xt_get_stat_meta_data(display_order[column].do_statistic);
+ strcpy(str_value, meta->sm_short_line_2);
+ if (display_order[column].do_combo) {
+ /* Combine next 2 fields: */
+ len = 8;
+ column++;
+ strcat(str_value, "/ms");
+ }
+ else if (meta->sm_flags & XT_STAT_PERCENTAGE)
+ len = 4;
+ else if (meta->sm_flags & XT_STAT_DATE)
+ len = 15;
+ printf("%*s ", len, str_value);
+ }
+ printf("\n");
+ }
+
+ for (int column=0; column<columns_used; column++) {
+ len = 5;
+ stat = display_order[column].do_statistic;
+ meta = xt_get_stat_meta_data(stat);
+ if (meta->sm_flags & XT_STAT_ACCUMULATIVE) {
+ /* Take care of overflow! */
+ if (current_values[stat] < accumulative_values[stat])
+ value = (double) (0xFFFFFFFF - (accumulative_values[stat] - current_values[stat]));
+ else
+ value = (double) (current_values[stat] - accumulative_values[stat]);
+ }
+ else
+ value = (double) current_values[stat];
+ accumulative_values[stat] = current_values[stat];
+ if (meta->sm_flags & XT_STAT_TIME_VALUE)
+ value = value / (double) 1000;
+ if (display_order[column].do_combo) {
+ format_mini_count_value(str_value, value);
+ strcat(str_value, "/");
+ column++;
+ stat = display_order[column].do_statistic;
+ value = (double) (current_values[stat] - accumulative_values[stat]);
+ accumulative_values[stat] = current_values[stat];
+ value = value / (double) 1000;
+ format_count_value(&str_value[strlen(str_value)], value);
+ len = 8;
+ }
+ else if (meta->sm_flags & XT_STAT_PERCENTAGE) {
+ double perc = 100;
+ switch (stat) {
+ case XT_STAT_REC_CACHE_USAGE: perc = (double)record_cache_size; break;
+ case XT_STAT_IND_CACHE_USAGE: perc = (double)index_cache_size; break;
+ case XT_STAT_XLOG_CACHE_USAGE: perc = (double)log_cache_size; break;
+ }
+ format_percent_value(str_value, value, perc);
+ len = 4;
+ }
+ else if (meta->sm_flags & XT_STAT_DATE) {
+ time_t ticks = (time_t) value;
+ const struct tm *ltime = localtime(&ticks);
+ strftime(str_value, 99, "%y%m%d %H:%M:%S", ltime);
+ len = 15;
+ }
+ else if (meta->sm_flags & XT_STAT_BYTE_COUNT)
+ format_byte_value(str_value, value);
+ else
+ format_count_value(str_value, value);
+ if (column == columns_used-1)
+ printf("%*s\n", len, str_value);
+ else
+ printf("%*s ", len, str_value);
+ }
+
+ sleep(options[OPT_DELAY].opt_value_int);
+ }
+
+ /* close connection */
+ mysql_close(conn);
+ return 0;
+
+ reconnect:
+ /* Reconnect... */
+ if (select_worked) {
+ /* Only print message if the SELECT worked.
+ * or we will get a screen full of messages:
+ */
+ fprintf(stderr, "%s\n", mysql_error(conn));
+ printf("Reconnecting...\n");
+ }
+ mysql_close(conn);
+ if (!(conn = mysql_init(NULL))) {
+ fprintf(stderr, "Insufficient memory\n");
+ exit(1);
+ }
+ do {
+ sleep(2);
+ } while (!connect(conn));
+ select_worked = false;
+ goto retry;
+}
diff --git a/storage/pbxt/src/ha_pbxt.cc b/storage/pbxt/src/ha_pbxt.cc
index 8d89b86904c..8ea6494240e 100644
--- a/storage/pbxt/src/ha_pbxt.cc
+++ b/storage/pbxt/src/ha_pbxt.cc
@@ -80,6 +80,7 @@ using drizzled::plugin::InfoSchemaMethods;
#include "systab_xt.h"
#include "xaction_xt.h"
#include "backup_xt.h"
+#include "heap_xt.h"
#ifdef DEBUG
//#define XT_USE_SYS_PAR_DEBUG_SIZES
diff --git a/storage/pbxt/src/myxt_xt.cc b/storage/pbxt/src/myxt_xt.cc
index 18c8d5fee78..51490fc00f5 100644
--- a/storage/pbxt/src/myxt_xt.cc
+++ b/storage/pbxt/src/myxt_xt.cc
@@ -54,6 +54,7 @@ extern pthread_key_t THR_Session;
#include "database_xt.h"
#include "cache_xt.h"
#include "datalog_xt.h"
+#include "memory_xt.h"
static void myxt_bitmap_init(XTThreadPtr self, MX_BITMAP *map, u_int n_bits);
static void myxt_bitmap_free(XTThreadPtr self, MX_BITMAP *map);
diff --git a/storage/pbxt/src/xt_config.h b/storage/pbxt/src/xt_config.h
index f3749071087..cb3009ecb79 100644
--- a/storage/pbxt/src/xt_config.h
+++ b/storage/pbxt/src/xt_config.h
@@ -128,4 +128,8 @@ const int max_connections = 500;
#endif
#endif
+#if defined(DBUG_ON) && !defined(DBUG_OFF) && !defined(DEBUG)
+#define DEBUG
+#endif // DBUG_ON
+
#endif