Viewing file:
test0aux.c (18.43 KB) -rw-r--r--Select action/file-type:

(
+) |

(
+) |

(
+) |
Code (
+) |
Session (
+) |

(
+) |
SDB (
+) |

(
+) |

(
+) |

(
+) |

(
+) |

(
+) |
/***********************************************************************
Copyright (c) 2008 Innobase Oy. All rights reserved.
Copyright (c) 2008 Oracle. All rights reserved.
Copyright (c) 2009 Oracle. All rights reserved.
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; version 2 of the License.
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
************************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <string.h>
#include <ctype.h>
#ifdef __WIN__
#include <windows.h>
#else
#include <errno.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <getopt.h> /* For getopt_long() */
#endif
#include "test0aux.h"
#define COMMENT '#'
/* Runtime config */
static const char log_group_home_dir[] = "log";
static const char data_file_path[] = "ibdata1:32M:autoextend";
static
void
create_directory(
/*=============*/
const char* path)
{
#ifdef __WIN__
BOOL ret;
ret = CreateDirectory((LPCTSTR) path, NULL);
if (ret == 0 && GetLastError() != ERROR_ALREADY_EXISTS) {
fprintf(stderr, "CreateDirectory failed for: %s\n", path);
exit(EXIT_FAILURE);
}
#else
int ret;
/* Try and create the log sub-directory */
ret = mkdir(path, S_IRWXU);
/* Note: This doesn't catch all errors. EEXIST can also refer to
dangling symlinks. */
if (ret == -1 && errno != EEXIST) {
perror(path);
exit(EXIT_FAILURE);
}
#endif
}
/*****************************************************************
Read a value from an integer column in an InnoDB tuple.
@return column value */
ib_u64_t
read_int_from_tuple(
/*================*/
ib_tpl_t tpl, /*!< in: InnoDB tuple */
const ib_col_meta_t* col_meta, /*!< in: col meta data */
int i) /*!< in: column number */
{
ib_u64_t ival = 0;
switch (col_meta->type_len) {
case 1: {
ib_u8_t v;
ib_col_copy_value(tpl, i, &v, sizeof(v));
ival = (col_meta->attr & IB_COL_UNSIGNED) ? v : (ib_i8_t) v;
break;
}
case 2: {
ib_u16_t v;
ib_col_copy_value(tpl, i, &v, sizeof(v));
ival = (col_meta->attr & IB_COL_UNSIGNED) ? v : (ib_i16_t) v;
break;
}
case 4: {
ib_u32_t v;
ib_col_copy_value(tpl, i, &v, sizeof(v));
ival = (col_meta->attr & IB_COL_UNSIGNED) ? v : (ib_i32_t) v;
break;
}
case 8: {
ib_col_copy_value(tpl, i, &ival, sizeof(ival));
break;
}
default:
assert(IB_FALSE);
}
return(ival);
}
/*********************************************************************
Print all columns in a tuple. */
void
print_int_col(
/*==========*/
FILE* stream,
const ib_tpl_t tpl,
int i,
ib_col_meta_t* col_meta)
{
ib_err_t err = DB_SUCCESS;
switch (col_meta->type_len) {
case 1: {
if (col_meta->attr & IB_COL_UNSIGNED) {
ib_u8_t u8;
err = ib_tuple_read_u8(tpl, i, &u8);
fprintf(stream, "%u", u8);
} else {
ib_i8_t i8;
err = ib_tuple_read_i8(tpl, i, &i8);
fprintf(stream, "%d", i8);
}
break;
}
case 2: {
if (col_meta->attr & IB_COL_UNSIGNED) {
ib_u16_t u16;
err = ib_tuple_read_u16(tpl, i, &u16);
fprintf(stream, "%u", u16);
} else {
ib_i16_t i16;
err = ib_tuple_read_i16(tpl, i, &i16);
fprintf(stream, "%d", i16);
}
break;
}
case 4: {
if (col_meta->attr & IB_COL_UNSIGNED) {
ib_u32_t u32;
err = ib_tuple_read_u32(tpl, i, &u32);
fprintf(stream, "%u", u32);
} else {
ib_i32_t i32;
err = ib_tuple_read_i32(tpl, i, &i32);
fprintf(stream, "%d", i32);
}
break;
}
case 8: {
if (col_meta->attr & IB_COL_UNSIGNED) {
ib_u64_t u64;
err = ib_tuple_read_u64(tpl, i, &u64);
fprintf(stream, "%llu", (unsigned long long) u64);
} else {
ib_i64_t i64;
err = ib_tuple_read_i64(tpl, i, &i64);
fprintf(stream, "%lld", (long long) i64);
}
break;
}
default:
assert(0);
break;
}
assert(err == DB_SUCCESS);
}
/**********************************************************************
Print character array of give size or upto 256 chars */
void
print_char_array(
/*=============*/
FILE* stream, /*!< in: stream to print to */
const char* array, /*!< in: char array */
int len) /*!< in: length of data */
{
int i;
const char* ptr = array;
for (i = 0; i < len; ++i) {
fprintf(stream, "%c", *(ptr + i));
}
}
/*********************************************************************
Print all columns in a tuple. */
void
print_tuple(
/*========*/
FILE* stream,
const ib_tpl_t tpl)
{
int i;
int n_cols = ib_tuple_get_n_cols(tpl);
for (i = 0; i < n_cols; ++i) {
ib_ulint_t data_len;
ib_col_meta_t col_meta;
data_len = ib_col_get_meta(tpl, i, &col_meta);
/* Skip system columns. */
if (col_meta.type == IB_SYS) {
continue;
/* Nothing to print. */
} else if (data_len == IB_SQL_NULL) {
fprintf(stream, "|");
continue;
} else {
switch (col_meta.type) {
case IB_INT: {
print_int_col(stream, tpl, i, &col_meta);
break;
}
case IB_FLOAT: {
float v;
ib_err_t err;
err = ib_tuple_read_float(tpl, i, &v);
assert(err == DB_SUCCESS);
fprintf(stream, "%f", v);
break;
}
case IB_DOUBLE: {
double v;
ib_err_t err;
err = ib_tuple_read_double(tpl, i, &v);
assert(err == DB_SUCCESS);
fprintf(stream, "%lf", v);
break;
}
case IB_CHAR:
case IB_BLOB:
case IB_DECIMAL:
case IB_VARCHAR: {
const char* ptr;
ptr = ib_col_get_value(tpl, i);
fprintf(stream, "%d:", (int) data_len);
print_char_array(stream, ptr, (int) data_len);
break;
}
default:
assert(IB_FALSE);
break;
}
}
fprintf(stream, "|");
}
fprintf(stream, "\n");
}
/*********************************************************************
Setup the InnoDB configuration parameters. */
void
test_configure(void)
/*================*/
{
ib_err_t err;
create_directory(log_group_home_dir);
#ifndef __WIN__
err = ib_cfg_set_text("flush_method", "O_DIRECT");
assert(err == DB_SUCCESS);
#else
err = ib_cfg_set_text("flush_method", "async_unbuffered");
assert(err == DB_SUCCESS);
#endif
err = ib_cfg_set_int("log_files_in_group", 2);
assert(err == DB_SUCCESS);
err = ib_cfg_set_int("log_file_size", 32 * 1024 * 1024);
assert(err == DB_SUCCESS);
err = ib_cfg_set_int("log_buffer_size", 24 * 16384);
assert(err == DB_SUCCESS);
err = ib_cfg_set_int("buffer_pool_size", 5 * 1024 * 1024);
assert(err == DB_SUCCESS);
err = ib_cfg_set_int("additional_mem_pool_size", 4 * 1024 * 1024);
assert(err == DB_SUCCESS);
err = ib_cfg_set_int("flush_log_at_trx_commit", 1);
assert(err == DB_SUCCESS);
err = ib_cfg_set_int("file_io_threads", 4);
assert(err == DB_SUCCESS);
err = ib_cfg_set_int("lock_wait_timeout", 60);
assert(err == DB_SUCCESS);
err = ib_cfg_set_int("open_files", 300);
assert(err == DB_SUCCESS);
err = ib_cfg_set_bool_on("doublewrite");
assert(err == DB_SUCCESS);
err = ib_cfg_set_bool_on("checksums");
assert(err == DB_SUCCESS);
err = ib_cfg_set_bool_on("rollback_on_timeout");
assert(err == DB_SUCCESS);
err = ib_cfg_set_bool_on("print_verbose_log");
assert(err == DB_SUCCESS);
err = ib_cfg_set_bool_on("file_per_table");
assert(err == DB_SUCCESS);
err = ib_cfg_set_text("data_home_dir", "./");
assert(err == DB_SUCCESS);
err = ib_cfg_set_text("log_group_home_dir", log_group_home_dir);
if (err != DB_SUCCESS) {
fprintf(stderr,
"syntax error in log_group_home_dir, or a "
"wrong number of mirrored log groups\n");
exit(1);
}
err = ib_cfg_set_text("data_file_path", data_file_path);
if (err != DB_SUCCESS) {
fprintf(stderr,
"InnoDB: syntax error in data_file_path\n");
exit(1);
}
}
/*********************************************************************
Generate random text upto max size. */
int
gen_rand_text(
/*==========*/
char* ptr, /*!< in,out: text written here */
int max_size) /*!< in: max size of ptr */
{
int i;
int len = 0;
static char txt[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
"abcdefghijklmnopqrstuvwxyz"
"0123456789";
do {
#ifdef __WIN__
len = rand() % max_size;
#else
len = random() % max_size;
#endif
} while (len == 0);
for (i = 0; i < len; ++i, ++ptr) {
#ifdef __WIN__
*ptr = txt[rand() % (sizeof(txt) - 1)];
#else
*ptr = txt[random() % (sizeof(txt) - 1)];
#endif
}
return(len);
}
#ifndef __WIN__
struct option ib_longopts[] = {
{"ib-buffer-pool-size", required_argument, NULL, 1},
{"ib-log-file-size", required_argument, NULL, 2},
{"ib-disable-ahi", no_argument, NULL, 3},
{"ib-io-capacity", required_argument, NULL, 4},
{"ib-use-sys-malloc", required_argument, NULL, 5},
{"ib-lru-old-ratio", required_argument, NULL, 6},
{"ib-lru-access-threshold",required_argument, NULL, 7},
{"ib-force-recovery", required_argument, NULL, 8},
{"ib-log-dir", required_argument, NULL, 9},
{"ib-data-dir", required_argument, NULL, 10},
{"ib-data-file-path", required_argument, NULL, 11},
{"ib-disble-dblwr", no_argument, NULL, 12},
{"ib-disble-checksum", no_argument, NULL, 13},
{"ib-disble-file-per-table",no_argument, NULL, 14},
{"ib-flush-log-at-trx-commit",required_argument,NULL, 15},
{"ib-flush-method", required_argument, NULL, 16},
{"ib-read-threads", required_argument, NULL, 17},
{"ib-write-threads", required_argument, NULL, 18},
{"ib-max-open-files", required_argument, NULL, 19},
{"ib-lock-wait-timeout",required_argument, NULL, 20},
{NULL, 0, NULL, 0}};
#endif /* __WIN__ */
/*********************************************************************
Print usage. */
void
print_usage(
/*========*/
const char* progname)
{
fprintf(stderr,
"usage: %s "
"[--ib-buffer-pool-size size in mb]\n"
"[--ib-log-file-size size in mb]\n"
"[--ib-disable-ahi]\n"
"[--ib-io-capacity number of records]\n"
"[--ib-use-sys-malloc]\n"
"[--ib-lru-old-ratio as %% e.g. 38]\n"
"[--ib-lru-access-threshold in ms]\n"
"[--ib-force-recovery 1-6]\n"
"[--ib-log-dir path]\n"
"[--ib-data-dir path]\n"
"[--ib-data-file-path string]\n"
"[--ib-disble-dblwr]\n"
"[--ib-disble-checksum]\n"
"[--ib-disble-file-per-table]\n"
"[--ib-flush-log-at-trx-commit 1-3]\n"
"[--ib-flush-method method]\n"
"[--ib-read-threads count]\n"
"[--ib-write-threads count]\n"
"[--ib-max-open-files count]\n"
"[--ib-lock-wait-timeout seconds]\n",
progname);
}
/*********************************************************************
Set the runtime global options. */
ib_err_t
set_global_option(
/*==============*/
int opt,
const char* arg)
{
ib_err_t err = DB_ERROR;
/* FIXME: Change numbers to enums or #defines */
switch(opt) {
case 1: {
ib_ulint_t size;
size = abs(strtoul(arg, NULL, 10));
size *= 1024UL * 1024UL;
err = ib_cfg_set_int("buffer_pool_size", size);
assert(err == DB_SUCCESS);
break;
}
case 2: {
ib_ulint_t size;
size = abs(strtoul(arg, NULL, 10));
size *= 1024UL * 1024UL;
err = ib_cfg_set_int("log_file_size", size);
assert(err == DB_SUCCESS);
break;
}
case 3:
err = ib_cfg_set_bool_off("adaptive_hash_index");
assert(err == DB_SUCCESS);
break;
case 4: {
ib_ulint_t size;
size = abs(strtoul(arg, NULL, 10));
err = ib_cfg_set_int("io_capacity", size);
assert(err == DB_SUCCESS);
break;
}
case 5:
err = ib_cfg_set_bool_on("use_sys_malloc");
assert(err == DB_SUCCESS);
break;
case 6: {
ib_ulint_t pct;
pct = abs(strtoul(arg, NULL, 10));
err = ib_cfg_set_int("lru_old_blocks_pct", pct);
assert(err == DB_SUCCESS);
break;
}
case 7: {
ib_ulint_t pct;
pct = abs(strtoul(arg, NULL, 10));
err = ib_cfg_set_int("lru_block_access_recency", pct);
assert(err == DB_SUCCESS);
break;
}
case 8: {
ib_ulint_t level;
level = abs(strtoul(arg, NULL, 10));
err = ib_cfg_set_int("force_recovery", level);
assert(err == DB_SUCCESS);
break;
}
case 9: {
err = ib_cfg_set_text("log_group_home_dir", arg);
assert(err == DB_SUCCESS);
break;
}
case 10: {
err = ib_cfg_set_text("data_home_dir", arg);
assert(err == DB_SUCCESS);
break;
}
case 11: {
err = ib_cfg_set_text("data_file_path", arg);
assert(err == DB_SUCCESS);
break;
}
case 12: {
err = ib_cfg_set_bool_off("doublewrite");
assert(err == DB_SUCCESS);
break;
}
case 13: {
err = ib_cfg_set_bool_off("checksum");
assert(err == DB_SUCCESS);
break;
}
case 14: {
err = ib_cfg_set_bool_off("file_per_table");
assert(err == DB_SUCCESS);
break;
}
case 15: {
ib_ulint_t level;
level = abs(strtoul(arg, NULL, 10));
err = ib_cfg_set_int("flush_log_at_trx_commit", level);
assert(err == DB_SUCCESS);
break;
}
case 16: {
err = ib_cfg_set_int("flush_method", arg);
assert(err == DB_SUCCESS);
break;
}
case 17: {
ib_ulint_t threads;
threads = abs(strtoul(arg, NULL, 10));
err = ib_cfg_set_int("read_io_threads", threads);
assert(err == DB_SUCCESS);
break;
}
case 18: {
ib_ulint_t threads;
threads = abs(strtoul(arg, NULL, 10));
err = ib_cfg_set_int("write_io_threads", threads);
assert(err == DB_SUCCESS);
break;
}
case 19: {
ib_ulint_t n;
n = abs(strtoul(arg, NULL, 10));
err = ib_cfg_set_int("open_files", n);
assert(err == DB_SUCCESS);
break;
}
case 20: {
ib_ulint_t secs;
secs = abs(strtoul(arg, NULL, 10));
err = ib_cfg_set_int("lock_wait_timeout", secs);
assert(err == DB_SUCCESS);
break;
}
default:
err = DB_ERROR;
break;
} /* switch */
return(err);
}
/*********************************************************************
Print API version to stdout. */
void
print_version(void)
/*===============*/
{
ib_u64_t version;
version = ib_api_version();
printf("API: %d.%d.%d\n",
(int) (version >> 32), /* Current version */
(int) ((version >> 16)) & 0xffff, /* Revisiion */
(int) (version & 0xffff)); /* Age */
}
/*********************************************************************
Skip line. */
static
int
config_skip_line(
/*=============*/
FILE* fp)
{
int ch;
while ((ch = getc(fp)) != -1 && ch != '\n') ;
return(ch);
}
/*********************************************************************
Add an element to the config. */
static
void
config_add_elem(
/*============*/
ib_config_t* config,
const ib_string_t* key,
const ib_string_t* val)
{
ib_var_t* var;
if (config->n_count == 0) {
int size;
config->n_count = 4;
size = config->n_count * sizeof(ib_var_t);
config->elems = (ib_var_t*) malloc(size);
} else if (config->n_elems == config->n_count - 1) {
int size;
config->n_count *= 2;
size = config->n_count * sizeof(ib_var_t);
config->elems = (ib_var_t*) realloc(config->elems, size);
}
assert(config->n_elems < config->n_count);
var = &config->elems[config->n_elems];
assert(key->len > 0);
assert(key->ptr != NULL);
var->name.len = key->len;
var->name.ptr = (ib_byte_t*) malloc(var->name.len);
memcpy(var->name.ptr, key->ptr, var->name.len);
/* Value can be NULL for boolean variables */
if (val->len > 0) {
var->value.len = val->len;
var->value.ptr = (ib_byte_t*) malloc(var->value.len);
memcpy(var->value.ptr, val->ptr, var->value.len);
}
++config->n_elems;
}
/*********************************************************************
Parse an InnoDB config file, the file has a very simply format:
Lines beginning with '#' are ignored. Characters after '#' (inclusive)
are also ignored. Empty lines are also ignored. Variable syntax is:
\s*var_name\s*=\s*value\s*\n */
int
config_parse_file(
/*==============*/
const char* filename,
ib_config_t* config)
{
int ch;
FILE* fp;
ib_string_t key;
ib_string_t val;
ib_string_t* str;
ib_byte_t name[BUFSIZ];
ib_byte_t value[BUFSIZ];
fp = fopen(filename, "r");
if (fp == NULL) {
return(-1);
}
memset(&key, 0x0, sizeof(key));
memset(&val, 0x0, sizeof(val));
key.ptr = name;
val.ptr = value;
str = &key;
while ((ch = getc(fp)) != -1) {
/* Skip comments. */
if (ch == COMMENT) {
if (config_skip_line(fp) == -1) {
break;
}
continue;
}
/* Skip white space. */
while (ch != '\n' && isspace(ch)) {
if ((ch = getc(fp)) == -1) {
break;
}
}
/* Skip comments. */
if (ch == COMMENT) {
if (config_skip_line(fp) == -1) {
break;
}
continue;
}
if (ch == -1) {
break;
}
switch (ch) {
case '\r':
break;
case '\n':
key.ptr = name;
val.ptr = value;
if (key.len > 0) {
config_add_elem(config, &key, &val);
}
memset(&key, 0x0, sizeof(key));
memset(&val, 0x0, sizeof(val));
/* Anything by default is a variable name */
str = &key;
str->ptr = name;
break;
case '=':
/* Anything that follows an '=' is a value. */
str = &val;
str->ptr = value;
break;
default:
++str->len;
*str->ptr++ = ch;
}
assert(str->len < sizeof(name));
}
if (str->len > 0) {
key.ptr = name;
val.ptr = value;
config_add_elem(config, &key, &val);
}
fclose(fp);
return(0);
}
/*********************************************************************
Print the elements. */
void
config_print(
/*=========*/
const ib_config_t* config)
{
ib_ulint_t i;
for (i = 0; i < config->n_elems; ++i) {
if (config->elems[i].value.ptr != NULL) {
printf("%.*s=%.*s\n",
config->elems[i].name.len,
config->elems[i].name.ptr,
config->elems[i].value.len,
config->elems[i].value.ptr);
} else {
printf("%.*s\n",
config->elems[i].name.len,
config->elems[i].name.ptr);
}
}
}
/*********************************************************************
Free the the elements. */
void
config_free(
/*=========*/
ib_config_t* config)
{
ib_ulint_t i;
for (i = 0; i < config->n_elems; ++i) {
free(config->elems[i].name.ptr);
free(config->elems[i].value.ptr);
}
free(config->elems);
memset(config, 0x0, sizeof(*config));
}
/*********************************************************************
Drop the table. */
ib_err_t
drop_table(
/*=======*/
const char* dbname, /*!< in: database name */
const char* name) /*!< in: table to drop */
{
ib_err_t err;
ib_trx_t ib_trx;
char table_name[IB_MAX_TABLE_NAME_LEN];
#ifdef __WIN__
sprintf(table_name, "%s/%s", dbname, name);
#else
snprintf(table_name, sizeof(table_name), "%s/%s", dbname, name);
#endif
ib_trx = ib_trx_begin(IB_TRX_REPEATABLE_READ);
assert(ib_trx != NULL);
err = ib_schema_lock_exclusive(ib_trx);
assert(err == DB_SUCCESS);
err = ib_table_drop(ib_trx, table_name);
assert(err == DB_SUCCESS);
err = ib_trx_commit(ib_trx);
assert(err == DB_SUCCESS);
return(err);
}