Below is the list of changes that have just been committed into a local
5.1 repository of tsmith. When tsmith does a push these changes will
be propagated to the main repository and, within 24 hours after the
push, to the public repository.
For information on how to access the public repository
see http://dev.mysql.com/doc/mysql/en/installing-source-tree.html
ChangeSet@stripped, 2007-03-28 17:08:23-06:00, tsmith@stripped +3 -0
Merge siva.hindu.god:/home/tsmith/m/inno/mar28/50
into siva.hindu.god:/home/tsmith/m/inno/mar28/51
MERGE: 1.1810.2731.13
storage/innobase/dict/dict0dict.c@stripped, 2007-03-28 17:07:55-06:00, tsmith@stripped +0 -2
Use local (null merge)
MERGE: 1.65.22.2
storage/innobase/dict/dict0dict.c@stripped, 2007-03-28 17:07:40-06:00, tsmith@stripped +0 -0
Merge rename: innobase/dict/dict0dict.c -> storage/innobase/dict/dict0dict.c
storage/innobase/os/os0file.c@stripped, 2007-03-28 17:08:03-06:00, tsmith@stripped +0 -10
Use local (null merge)
MERGE: 1.103.15.2
storage/innobase/os/os0file.c@stripped, 2007-03-28 17:07:40-06:00, tsmith@stripped +0 -0
Merge rename: innobase/os/os0file.c -> storage/innobase/os/os0file.c
storage/innobase/row/row0undo.c@stripped, 2007-03-28 17:08:08-06:00, tsmith@stripped +0 -8
Use local (null merge)
MERGE: 1.13.2.2
storage/innobase/row/row0undo.c@stripped, 2007-03-28 17:07:40-06:00, tsmith@stripped +0 -0
Merge rename: innobase/row/row0undo.c -> storage/innobase/row/row0undo.c
# This is a BitKeeper patch. What follows are the unified diffs for the
# set of deltas contained in the patch. The rest of the patch, the part
# that BitKeeper cares about, is below these diffs.
# User: tsmith
# Host: siva.hindu.god
# Root: /home/tsmith/m/inno/mar28/51/RESYNC
--- 1.65.22.1/innobase/dict/dict0dict.c 2007-03-28 16:21:24 -06:00
+++ 1.105/storage/innobase/dict/dict0dict.c 2007-03-28 17:07:55 -06:00
@@ -26,9 +26,9 @@ Created 1/8/1996 Heikki Tuuri
#include "pars0sym.h"
#include "que0que.h"
#include "rem0cmp.h"
-
-/* Implement isspace() in a locale-independent way. (Bug #24299) */
-#define ib_isspace(c) ((char) (c) && strchr(" \v\f\t\r\n", c))
+#ifndef UNIV_HOTBACKUP
+# include "m_ctype.h" /* my_isspace() */
+#endif /* !UNIV_HOTBACKUP */
dict_sys_t* dict_sys = NULL; /* the dictionary system */
@@ -48,8 +48,6 @@ rw_lock_t dict_operation_lock; /* table
creating a table or index object */
#define DICT_POOL_PER_TABLE_HASH 512 /* buffer pool max size per table
hash table fixed size in bytes */
-#define DICT_POOL_PER_COL_HASH 128 /* buffer pool max size per column
- hash table fixed size in bytes */
#define DICT_POOL_PER_VARYING 4 /* buffer pool max size per data
dictionary varying size in bytes */
@@ -58,6 +56,42 @@ static char dict_ibfk[] = "_ibfk_";
#ifndef UNIV_HOTBACKUP
/**********************************************************************
+Converts an identifier to a table name.
+
+NOTE: the prototype of this function is copied from ha_innodb.cc! If you change
+this function, you MUST change also the prototype here! */
+extern
+void
+innobase_convert_from_table_id(
+/*===========================*/
+ char* to, /* out: converted identifier */
+ const char* from, /* in: identifier to convert */
+ ulint len); /* in: length of 'to', in bytes;
+ should be at least 5 * strlen(to) + 1 */
+/**********************************************************************
+Converts an identifier to UTF-8.
+
+NOTE: the prototype of this function is copied from ha_innodb.cc! If you change
+this function, you MUST change also the prototype here! */
+extern
+void
+innobase_convert_from_id(
+/*=====================*/
+ char* to, /* out: converted identifier */
+ const char* from, /* in: identifier to convert */
+ ulint len); /* in: length of 'to', in bytes;
+ should be at least 3 * strlen(to) + 1 */
+/**********************************************************************
+Removes the filename encoding of a table or database name.
+
+NOTE: the prototype of this function is copied from ha_innodb.cc! If you change
+this function, you MUST change also the prototype here! */
+extern
+void
+innobase_convert_from_filename(
+/*===========================*/
+ char* s); /* in: identifier; out: decoded identifier */
+/**********************************************************************
Compares NUL-terminated UTF-8 strings case insensitively.
NOTE: the prototype of this function is copied from ha_innodb.cc! If you change
@@ -80,34 +114,19 @@ void
innobase_casedn_str(
/*================*/
char* a); /* in/out: string to put in lower case */
-#endif /* !UNIV_HOTBACKUP */
/**************************************************************************
-Adds a column to the data dictionary hash table. */
-static
-void
-dict_col_add_to_cache(
-/*==================*/
- dict_table_t* table, /* in: table */
- dict_col_t* col); /* in: column */
-/**************************************************************************
-Repositions a column in the data dictionary hash table when the table name
-changes. */
-static
-void
-dict_col_reposition_in_cache(
-/*=========================*/
- dict_table_t* table, /* in: table */
- dict_col_t* col, /* in: column */
- const char* new_name); /* in: new table name */
-/**************************************************************************
-Removes a column from the data dictionary hash table. */
-static
-void
-dict_col_remove_from_cache(
-/*=======================*/
- dict_table_t* table, /* in: table */
- dict_col_t* col); /* in: column */
+Determines the connection character set.
+
+NOTE: the prototype of this function is copied from ha_innodb.cc! If you change
+this function, you MUST change also the prototype here! */
+struct charset_info_st*
+innobase_get_charset(
+/*=================*/
+ /* out: connection character set */
+ void* mysql_thd); /* in: MySQL thread handle */
+#endif /* !UNIV_HOTBACKUP */
+
/**************************************************************************
Removes an index from the dictionary cache. */
static
@@ -124,18 +143,18 @@ dict_index_copy(
/*============*/
dict_index_t* index1, /* in: index to copy to */
dict_index_t* index2, /* in: index to copy from */
+ dict_table_t* table, /* in: table */
ulint start, /* in: first position to copy */
ulint end); /* in: last position to copy */
/***********************************************************************
-Tries to find column names for the index in the column hash table and
-sets the col field of the index. */
+Tries to find column names for the index and sets the col field of the
+index. */
static
-ibool
+void
dict_index_find_cols(
/*=================*/
- /* out: TRUE if success */
dict_table_t* table, /* in: table */
- dict_index_t* index); /* in: index */
+ dict_index_t* index); /* in: index */
/***********************************************************************
Builds the internal dictionary cache representation for a clustered
index, containing also system fields not defined by the user. */
@@ -147,7 +166,7 @@ dict_index_build_internal_clust(
of the clustered index */
dict_table_t* table, /* in: table */
dict_index_t* index); /* in: user representation of a clustered
- index */
+ index */
/***********************************************************************
Builds the internal dictionary cache representation for a non-clustered
index, containing also system fields not defined by the user. */
@@ -159,7 +178,7 @@ dict_index_build_internal_non_clust(
of the non-clustered index */
dict_table_t* table, /* in: table */
dict_index_t* index); /* in: user representation of a non-clustered
- index */
+ index */
/**************************************************************************
Removes a foreign constraint struct from the dictionary cache. */
static
@@ -173,7 +192,8 @@ static
void
dict_col_print_low(
/*===============*/
- dict_col_t* col); /* in: column */
+ const dict_table_t* table, /* in: table */
+ const dict_col_t* col); /* in: column */
/**************************************************************************
Prints an index data. */
static
@@ -199,9 +219,10 @@ dict_foreign_free(
/* Stream for storing detailed information about the latest foreign key
and unique key errors */
FILE* dict_foreign_err_file = NULL;
-mutex_t dict_foreign_err_mutex; /* mutex protecting the foreign
+mutex_t dict_foreign_err_mutex; /* mutex protecting the foreign
and unique error buffers */
-
+
+#ifndef UNIV_HOTBACKUP
/**********************************************************************
Makes all characters in a NUL-terminated UTF-8 string lower case. */
@@ -212,6 +233,7 @@ dict_casedn_str(
{
innobase_casedn_str(a);
}
+#endif /* !UNIV_HOTBACKUP */
/************************************************************************
Checks if the database name in two table names is the same. */
@@ -236,7 +258,7 @@ dict_tables_have_same_db(
/************************************************************************
Return the end of table name where we have removed dbname and '/'. */
-static
+
const char*
dict_remove_db_name(
/*================*/
@@ -244,11 +266,10 @@ dict_remove_db_name(
const char* name) /* in: table name in the form
dbname '/' tablename */
{
- const char* s;
- s = strchr(name, '/');
+ const char* s = strchr(name, '/');
ut_a(s);
- if (s) s++;
- return(s);
+
+ return(s + 1);
}
/************************************************************************
@@ -266,7 +287,7 @@ dict_get_db_name_len(
ut_a(s);
return(s - name);
}
-
+
/************************************************************************
Reserves the dictionary system mutex for MySQL. */
@@ -276,7 +297,7 @@ dict_mutex_enter_for_mysql(void)
{
mutex_enter(&(dict_sys->mutex));
}
-
+
/************************************************************************
Releases the dictionary system mutex for MySQL. */
@@ -286,7 +307,7 @@ dict_mutex_exit_for_mysql(void)
{
mutex_exit(&(dict_sys->mutex));
}
-
+
/************************************************************************
Decrements the count of open MySQL handles to a table. */
@@ -300,19 +321,31 @@ dict_table_decrement_handle_count(
ut_a(table->n_mysql_handles_opened > 0);
table->n_mysql_handles_opened--;
-
+
mutex_exit(&(dict_sys->mutex));
}
+/*************************************************************************
+Gets the column data type. */
+
+void
+dict_col_copy_type_noninline(
+/*=========================*/
+ const dict_col_t* col, /* in: column */
+ dtype_t* type) /* out: data type */
+{
+ dict_col_copy_type(col, type);
+}
+
/************************************************************************
Gets the nth column of a table. */
-dict_col_t*
+const dict_col_t*
dict_table_get_nth_col_noninline(
/*=============================*/
- /* out: pointer to column object */
- dict_table_t* table, /* in: table */
- ulint pos) /* in: position of column */
+ /* out: pointer to column object */
+ const dict_table_t* table, /* in: table */
+ ulint pos) /* in: position of column */
{
return(dict_table_get_nth_col(table, pos));
}
@@ -353,7 +386,36 @@ dict_table_get_index_noninline(
{
return(dict_table_get_index(table, name));
}
-
+
+/**************************************************************************
+Returns a column's name. */
+
+const char*
+dict_table_get_col_name(
+/*====================*/
+ /* out: column name. NOTE: not
+ guaranteed to stay valid if table is
+ modified in any way (columns added,
+ etc.). */
+ const dict_table_t* table, /* in: table */
+ ulint col_nr) /* in: column number */
+{
+ ulint i;
+ const char* s;
+
+ ut_ad(table);
+ ut_ad(col_nr < table->n_def);
+ ut_ad(table->magic_n == DICT_TABLE_MAGIC_N);
+
+ s = table->col_names;
+
+ for (i = 0; i < col_nr; i++) {
+ s += strlen(s) + 1;
+ }
+
+ return(s);
+}
+
/************************************************************************
Initializes the autoinc counter. It is not an error to initialize an already
initialized counter. */
@@ -393,7 +455,7 @@ dict_table_autoinc_get(
value = table->autoinc;
table->autoinc = table->autoinc + 1;
}
-
+
mutex_exit(&(table->autoinc_mutex));
return(value);
@@ -410,7 +472,7 @@ dict_table_autoinc_decrement(
mutex_enter(&(table->autoinc_mutex));
table->autoinc = table->autoinc - 1;
-
+
mutex_exit(&(table->autoinc_mutex));
}
@@ -434,7 +496,7 @@ dict_table_autoinc_read(
} else {
value = table->autoinc;
}
-
+
mutex_exit(&(table->autoinc_mutex));
return(value);
@@ -479,7 +541,7 @@ dict_table_autoinc_update(
if (value >= table->autoinc) {
table->autoinc = value + 1;
}
- }
+ }
mutex_exit(&(table->autoinc_mutex));
}
@@ -496,11 +558,11 @@ dict_index_get_nth_col_pos(
dict_index_t* index, /* in: index */
ulint n) /* in: column number */
{
- dict_field_t* field;
- dict_col_t* col;
- ulint pos;
- ulint n_fields;
-
+ const dict_field_t* field;
+ const dict_col_t* col;
+ ulint pos;
+ ulint n_fields;
+
ut_ad(index);
ut_ad(index->magic_n == DICT_INDEX_MAGIC_N);
@@ -508,11 +570,11 @@ dict_index_get_nth_col_pos(
if (index->type & DICT_CLUSTERED) {
- return(col->clust_pos);
+ return(dict_col_get_clust_pos(col, index));
}
n_fields = dict_index_get_n_fields(index);
-
+
for (pos = 0; pos < n_fields; pos++) {
field = dict_index_get_nth_field(index, pos);
@@ -536,11 +598,11 @@ dict_index_contains_col_or_prefix(
dict_index_t* index, /* in: index */
ulint n) /* in: column number */
{
- dict_field_t* field;
- dict_col_t* col;
- ulint pos;
- ulint n_fields;
-
+ const dict_field_t* field;
+ const dict_col_t* col;
+ ulint pos;
+ ulint n_fields;
+
ut_ad(index);
ut_ad(index->magic_n == DICT_INDEX_MAGIC_N);
@@ -552,7 +614,7 @@ dict_index_contains_col_or_prefix(
col = dict_table_get_nth_col(index->table, n);
n_fields = dict_index_get_n_fields(index);
-
+
for (pos = 0; pos < n_fields; pos++) {
field = dict_index_get_nth_field(index, pos);
@@ -585,14 +647,14 @@ dict_index_get_nth_field_pos(
dict_field_t* field2;
ulint n_fields;
ulint pos;
-
+
ut_ad(index);
ut_ad(index->magic_n == DICT_INDEX_MAGIC_N);
field2 = dict_index_get_nth_field(index2, n);
n_fields = dict_index_get_n_fields(index);
-
+
for (pos = 0; pos < n_fields; pos++) {
field = dict_index_get_nth_field(index, pos);
@@ -609,7 +671,7 @@ dict_index_get_nth_field_pos(
}
/**************************************************************************
-Returns a table object, based on table id, and memoryfixes it. */
+Returns a table object based on table id. */
dict_table_t*
dict_table_get_on_id(
@@ -619,26 +681,24 @@ dict_table_get_on_id(
trx_t* trx) /* in: transaction handle */
{
dict_table_t* table;
-
+
if (ut_dulint_cmp(table_id, DICT_FIELDS_ID) <= 0
- || trx->dict_operation_lock_mode == RW_X_LATCH) {
+ || trx->dict_operation_lock_mode == RW_X_LATCH) {
/* It is a system table which will always exist in the table
cache: we avoid acquiring the dictionary mutex, because
if we are doing a rollback to handle an error in TABLE
CREATE, for example, we already have the mutex! */
-#ifdef UNIV_SYNC_DEBUG
ut_ad(mutex_own(&(dict_sys->mutex))
|| trx->dict_operation_lock_mode == RW_X_LATCH);
-#endif /* UNIV_SYNC_DEBUG */
- return(dict_table_get_on_id_low(table_id, trx));
+ return(dict_table_get_on_id_low(table_id));
}
mutex_enter(&(dict_sys->mutex));
- table = dict_table_get_on_id_low(table_id, trx);
-
+ table = dict_table_get_on_id_low(table_id);
+
mutex_exit(&(dict_sys->mutex));
return(table);
@@ -656,7 +716,20 @@ dict_table_get_nth_col_pos(
ulint n) /* in: column number */
{
return(dict_index_get_nth_col_pos(dict_table_get_first_index(table),
- n));
+ n));
+}
+
+/************************************************************************
+Check whether the table uses the compact page format. */
+
+ibool
+dict_table_is_comp_noninline(
+/*=========================*/
+ /* out: TRUE if table uses the
+ compact page format */
+ const dict_table_t* table) /* in: table */
+{
+ return(dict_table_is_comp(table));
}
/************************************************************************
@@ -671,12 +744,12 @@ dict_table_col_in_clustered_key(
dict_table_t* table, /* in: table */
ulint n) /* in: column number */
{
- dict_index_t* index;
- dict_field_t* field;
- dict_col_t* col;
- ulint pos;
- ulint n_fields;
-
+ dict_index_t* index;
+ const dict_field_t* field;
+ const dict_col_t* col;
+ ulint pos;
+ ulint n_fields;
+
ut_ad(table);
col = dict_table_get_nth_col(table, n);
@@ -684,7 +757,7 @@ dict_table_col_in_clustered_key(
index = dict_table_get_first_index(table);
n_fields = dict_index_get_n_unique(index);
-
+
for (pos = 0; pos < n_fields; pos++) {
field = dict_index_get_nth_field(index, pos);
@@ -706,35 +779,31 @@ dict_init(void)
{
dict_sys = mem_alloc(sizeof(dict_sys_t));
- mutex_create(&(dict_sys->mutex));
- mutex_set_level(&(dict_sys->mutex), SYNC_DICT);
+ mutex_create(&dict_sys->mutex, SYNC_DICT);
- dict_sys->table_hash = hash_create(buf_pool_get_max_size() /
- (DICT_POOL_PER_TABLE_HASH *
- UNIV_WORD_SIZE));
- dict_sys->table_id_hash = hash_create(buf_pool_get_max_size() /
- (DICT_POOL_PER_TABLE_HASH *
- UNIV_WORD_SIZE));
- dict_sys->col_hash = hash_create(buf_pool_get_max_size() /
- (DICT_POOL_PER_COL_HASH *
- UNIV_WORD_SIZE));
+ dict_sys->table_hash = hash_create(buf_pool_get_max_size()
+ / (DICT_POOL_PER_TABLE_HASH
+ * UNIV_WORD_SIZE));
+ dict_sys->table_id_hash = hash_create(buf_pool_get_max_size()
+ / (DICT_POOL_PER_TABLE_HASH
+ * UNIV_WORD_SIZE));
dict_sys->size = 0;
UT_LIST_INIT(dict_sys->table_LRU);
- rw_lock_create(&dict_operation_lock);
- rw_lock_set_level(&dict_operation_lock, SYNC_DICT_OPERATION);
+ rw_lock_create(&dict_operation_lock, SYNC_DICT_OPERATION);
dict_foreign_err_file = os_file_create_tmpfile();
ut_a(dict_foreign_err_file);
- mutex_create(&dict_foreign_err_mutex);
- mutex_set_level(&dict_foreign_err_mutex, SYNC_ANY_LATCH);
+
+ mutex_create(&dict_foreign_err_mutex, SYNC_ANY_LATCH);
}
/**************************************************************************
-Returns a table object and memoryfixes it. NOTE! This is a high-level
-function to be used mainly from outside the 'dict' directory. Inside this
-directory dict_table_get_low is usually the appropriate function. */
+Returns a table object and optionally increment its MySQL open handle count.
+NOTE! This is a high-level function to be used mainly from outside the
+'dict' directory. Inside this directory dict_table_get_low is usually the
+appropriate function. */
dict_table_t*
dict_table_get(
@@ -742,59 +811,31 @@ dict_table_get(
/* out: table, NULL if
does not exist */
const char* table_name, /* in: table name */
- trx_t* trx) /* in: transaction handle or NULL */
+ ibool inc_mysql_count)
+ /* in: whether to increment the open
+ handle count on the table */
{
dict_table_t* table;
- UT_NOT_USED(trx);
-
mutex_enter(&(dict_sys->mutex));
-
- table = dict_table_get_low(table_name);
-
- mutex_exit(&(dict_sys->mutex));
- if (table != NULL) {
- if (!table->stat_initialized) {
- dict_update_statistics(table);
- }
- }
-
- return(table);
-}
-
-/**************************************************************************
-Returns a table object and increments MySQL open handle count on the table. */
-
-dict_table_t*
-dict_table_get_and_increment_handle_count(
-/*======================================*/
- /* out: table, NULL if
- does not exist */
- const char* table_name, /* in: table name */
- trx_t* trx) /* in: transaction handle or NULL */
-{
- dict_table_t* table;
-
- UT_NOT_USED(trx);
-
- mutex_enter(&(dict_sys->mutex));
-
table = dict_table_get_low(table_name);
- if (table != NULL) {
-
- table->n_mysql_handles_opened++;
+ if (inc_mysql_count && table) {
+ table->n_mysql_handles_opened++;
}
mutex_exit(&(dict_sys->mutex));
if (table != NULL) {
- if (!table->stat_initialized && !table->ibd_file_missing) {
+ if (!table->stat_initialized) {
+ /* If table->ibd_file_missing == TRUE, this will
+ print an error message and return without doing
+ anything. */
dict_update_statistics(table);
}
}
-
+
return(table);
}
@@ -809,20 +850,19 @@ dict_table_add_to_cache(
ulint fold;
ulint id_fold;
ulint i;
-
+ ulint row_len;
+
ut_ad(table);
-#ifdef UNIV_SYNC_DEBUG
ut_ad(mutex_own(&(dict_sys->mutex)));
-#endif /* UNIV_SYNC_DEBUG */
ut_ad(table->n_def == table->n_cols - DATA_N_SYS_COLS);
ut_ad(table->magic_n == DICT_TABLE_MAGIC_N);
ut_ad(table->cached == FALSE);
-
+
fold = ut_fold_string(table->name);
id_fold = ut_fold_dulint(table->id);
-
+
table->cached = TRUE;
-
+
/* NOTE: the system columns MUST be added in the following order
(so that they can be indexed by the numerical value of DATA_ROW_ID,
etc.) and as the last columns of the table memory object.
@@ -830,37 +870,56 @@ dict_table_add_to_cache(
system columns. */
dict_mem_table_add_col(table, "DB_ROW_ID", DATA_SYS,
- DATA_ROW_ID | DATA_NOT_NULL, DATA_ROW_ID_LEN, 0);
+ DATA_ROW_ID | DATA_NOT_NULL,
+ DATA_ROW_ID_LEN);
#if DATA_ROW_ID != 0
#error "DATA_ROW_ID != 0"
#endif
dict_mem_table_add_col(table, "DB_TRX_ID", DATA_SYS,
- DATA_TRX_ID | DATA_NOT_NULL, DATA_TRX_ID_LEN, 0);
+ DATA_TRX_ID | DATA_NOT_NULL,
+ DATA_TRX_ID_LEN);
#if DATA_TRX_ID != 1
#error "DATA_TRX_ID != 1"
#endif
dict_mem_table_add_col(table, "DB_ROLL_PTR", DATA_SYS,
- DATA_ROLL_PTR | DATA_NOT_NULL, DATA_ROLL_PTR_LEN, 0);
+ DATA_ROLL_PTR | DATA_NOT_NULL,
+ DATA_ROLL_PTR_LEN);
#if DATA_ROLL_PTR != 2
#error "DATA_ROLL_PTR != 2"
#endif
- dict_mem_table_add_col(table, "DB_MIX_ID", DATA_SYS,
- DATA_MIX_ID | DATA_NOT_NULL, DATA_MIX_ID_LEN, 0);
-#if DATA_MIX_ID != 3
-#error "DATA_MIX_ID != 3"
-#endif
/* This check reminds that if a new system column is added to
- the program, it should be dealt with here */
-#if DATA_N_SYS_COLS != 4
-#error "DATA_N_SYS_COLS != 4"
+ the program, it should be dealt with here */
+#if DATA_N_SYS_COLS != 3
+#error "DATA_N_SYS_COLS != 3"
#endif
+ /* The lower limit for what we consider a "big" row */
+#define BIG_ROW_SIZE 1024
+
+ row_len = 0;
+ for (i = 0; i < table->n_def; i++) {
+ ulint col_len = dict_col_get_max_size(
+ dict_table_get_nth_col(table, i));
+
+ row_len += col_len;
+
+ /* If we have a single unbounded field, or several gigantic
+ fields, mark the maximum row size as BIG_ROW_SIZE. */
+ if (row_len >= BIG_ROW_SIZE || col_len >= BIG_ROW_SIZE) {
+ row_len = BIG_ROW_SIZE;
+
+ break;
+ }
+ }
+
+ table->big_rows = row_len >= BIG_ROW_SIZE;
+
/* Look for a table with the same name: error if such exists */
{
dict_table_t* table2;
HASH_SEARCH(name_hash, dict_sys->table_hash, fold, table2,
- (ut_strcmp(table2->name, table->name) == 0));
+ (ut_strcmp(table2->name, table->name) == 0));
ut_a(table2 == NULL);
}
@@ -868,36 +927,21 @@ dict_table_add_to_cache(
{
dict_table_t* table2;
HASH_SEARCH(id_hash, dict_sys->table_id_hash, id_fold, table2,
- (ut_dulint_cmp(table2->id, table->id) == 0));
+ (ut_dulint_cmp(table2->id, table->id) == 0));
ut_a(table2 == NULL);
}
- if (table->type == DICT_TABLE_CLUSTER_MEMBER) {
-
- table->mix_id_len = mach_dulint_get_compressed_size(
- table->mix_id);
- mach_dulint_write_compressed(table->mix_id_buf, table->mix_id);
- }
-
- /* Add the columns to the column hash table */
- for (i = 0; i < table->n_cols; i++) {
- dict_col_add_to_cache(table, dict_table_get_nth_col(table, i));
- }
-
/* Add table to hash table of tables */
HASH_INSERT(dict_table_t, name_hash, dict_sys->table_hash, fold,
- table);
+ table);
/* Add table to hash table of tables based on table id */
HASH_INSERT(dict_table_t, id_hash, dict_sys->table_id_hash, id_fold,
- table);
+ table);
/* Add table to LRU list of tables */
UT_LIST_ADD_FIRST(table_LRU, dict_sys->table_LRU, table);
- /* If the dictionary cache grows too big, trim the table LRU list */
-
dict_sys->size += mem_heap_get_size(table->heap);
- /* dict_table_LRU_trim(); */
}
/**************************************************************************
@@ -913,14 +957,14 @@ dict_index_find_on_id_low(
{
dict_table_t* table;
dict_index_t* index;
-
+
table = UT_LIST_GET_FIRST(dict_sys->table_LRU);
while (table) {
index = dict_table_get_first_index(table);
while (index) {
- if (0 == ut_dulint_cmp(id, index->tree->id)) {
+ if (0 == ut_dulint_cmp(id, index->id)) {
/* Found */
return(index);
@@ -954,26 +998,24 @@ dict_table_rename_in_cache(
ulint old_size;
char* old_name;
ibool success;
- ulint i;
-
+
ut_ad(table);
-#ifdef UNIV_SYNC_DEBUG
ut_ad(mutex_own(&(dict_sys->mutex)));
-#endif /* UNIV_SYNC_DEBUG */
old_size = mem_heap_get_size(table->heap);
-
+
fold = ut_fold_string(new_name);
-
+
/* Look for a table with the same name: error if such exists */
{
dict_table_t* table2;
HASH_SEARCH(name_hash, dict_sys->table_hash, fold, table2,
- (ut_strcmp(table2->name, new_name) == 0));
+ (ut_strcmp(table2->name, new_name) == 0));
if (table2) {
fprintf(stderr,
-"InnoDB: Error: dictionary cache already contains a table of name %s\n",
- new_name);
+ "InnoDB: Error: dictionary cache"
+ " already contains a table of name %s\n",
+ new_name);
return(FALSE);
}
}
@@ -984,12 +1026,14 @@ dict_table_rename_in_cache(
if (table->space != 0) {
if (table->dir_path_of_temp_table != NULL) {
fprintf(stderr,
-"InnoDB: Error: trying to rename a table %s (%s) created with CREATE\n"
-"InnoDB: TEMPORARY TABLE\n", table->name, table->dir_path_of_temp_table);
+ "InnoDB: Error: trying to rename a table"
+ " %s (%s) created with CREATE\n"
+ "InnoDB: TEMPORARY TABLE\n",
+ table->name, table->dir_path_of_temp_table);
success = FALSE;
} else {
- success = fil_rename_tablespace(table->name,
- table->space, new_name);
+ success = fil_rename_tablespace(
+ table->name, table->space, new_name);
}
if (!success) {
@@ -998,23 +1042,15 @@ dict_table_rename_in_cache(
}
}
- /* Reposition the columns in the column hash table; they are hashed
- according to the pair (table name, column name) */
-
- for (i = 0; i < table->n_cols; i++) {
- dict_col_reposition_in_cache(table,
- dict_table_get_nth_col(table, i), new_name);
- }
-
/* Remove table from the hash tables of tables */
HASH_DELETE(dict_table_t, name_hash, dict_sys->table_hash,
- ut_fold_string(table->name), table);
+ ut_fold_string(table->name), table);
old_name = mem_heap_strdup(table->heap, table->name);
table->name = mem_heap_strdup(table->heap, new_name);
/* Add table to hash table of tables */
HASH_INSERT(dict_table_t, name_hash, dict_sys->table_hash, fold,
- table);
+ table);
dict_sys->size += (mem_heap_get_size(table->heap) - old_size);
/* Update the table_name field in indexes */
@@ -1022,7 +1058,7 @@ dict_table_rename_in_cache(
while (index != NULL) {
index->table_name = table->name;
-
+
index = dict_table_get_next_index(index);
}
@@ -1034,7 +1070,7 @@ dict_table_rename_in_cache(
constraints from the dictionary cache here. The foreign key
constraints will be inherited to the new table from the
system tables through a call of dict_load_foreigns. */
-
+
/* Remove the foreign constraints from the cache */
foreign = UT_LIST_GET_LAST(table->foreign_list);
@@ -1050,14 +1086,14 @@ dict_table_rename_in_cache(
while (foreign != NULL) {
foreign->referenced_table = NULL;
foreign->referenced_index = NULL;
-
+
foreign = UT_LIST_GET_NEXT(referenced_list, foreign);
}
/* Make the list of referencing constraints empty */
UT_LIST_INIT(table->referenced_list);
-
+
return(TRUE);
}
@@ -1068,14 +1104,14 @@ dict_table_rename_in_cache(
foreign = UT_LIST_GET_FIRST(table->foreign_list);
while (foreign != NULL) {
- if (ut_strlen(foreign->foreign_table_name) <
- ut_strlen(table->name)) {
+ if (ut_strlen(foreign->foreign_table_name)
+ < ut_strlen(table->name)) {
/* Allocate a longer name buffer;
TODO: store buf len to save memory */
- foreign->foreign_table_name = mem_heap_alloc(
- foreign->heap,
- ut_strlen(table->name) + 1);
+ foreign->foreign_table_name
+ = mem_heap_alloc(foreign->heap,
+ ut_strlen(table->name) + 1);
}
strcpy(foreign->foreign_table_name, table->name);
@@ -1089,47 +1125,46 @@ dict_table_rename_in_cache(
old_id = mem_strdup(foreign->id);
if (ut_strlen(foreign->id) > ut_strlen(old_name)
- + ((sizeof dict_ibfk) - 1)
- && 0 == ut_memcmp(foreign->id, old_name,
- ut_strlen(old_name))
- && 0 == ut_memcmp(
- foreign->id + ut_strlen(old_name),
- dict_ibfk, (sizeof dict_ibfk) - 1)) {
+ + ((sizeof dict_ibfk) - 1)
+ && !memcmp(foreign->id, old_name,
+ ut_strlen(old_name))
+ && !memcmp(foreign->id + ut_strlen(old_name),
+ dict_ibfk, (sizeof dict_ibfk) - 1)) {
/* This is a generated >= 4.0.18 format id */
- if (ut_strlen(table->name) > ut_strlen(old_name)) {
+ if (strlen(table->name) > strlen(old_name)) {
foreign->id = mem_heap_alloc(
- foreign->heap,
- ut_strlen(table->name)
- + ut_strlen(old_id) + 1);
+ foreign->heap,
+ strlen(table->name)
+ + strlen(old_id) + 1);
}
-
+
/* Replace the prefix 'databasename/tablename'
with the new names */
strcpy(foreign->id, table->name);
strcat(foreign->id,
- old_id + ut_strlen(old_name));
+ old_id + ut_strlen(old_name));
} else {
/* This is a >= 4.0.18 format id where the user
gave the id name */
db_len = dict_get_db_name_len(table->name) + 1;
if (dict_get_db_name_len(table->name)
- > dict_get_db_name_len(foreign->id)) {
+ > dict_get_db_name_len(foreign->id)) {
foreign->id = mem_heap_alloc(
- foreign->heap,
- db_len + ut_strlen(old_id) + 1);
+ foreign->heap,
+ db_len + strlen(old_id) + 1);
}
/* Replace the database prefix in id with the
one from table->name */
-
+
ut_memcpy(foreign->id, table->name, db_len);
strcpy(foreign->id + db_len,
- dict_remove_db_name(old_id));
+ dict_remove_db_name(old_id));
}
mem_free(old_id);
@@ -1141,14 +1176,13 @@ dict_table_rename_in_cache(
foreign = UT_LIST_GET_FIRST(table->referenced_list);
while (foreign != NULL) {
- if (ut_strlen(foreign->referenced_table_name) <
- ut_strlen(table->name)) {
+ if (ut_strlen(foreign->referenced_table_name)
+ < ut_strlen(table->name)) {
/* Allocate a longer name buffer;
TODO: store buf len to save memory */
foreign->referenced_table_name = mem_heap_alloc(
- foreign->heap,
- ut_strlen(table->name) + 1);
+ foreign->heap, strlen(table->name) + 1);
}
strcpy(foreign->referenced_table_name, table->name);
@@ -1170,20 +1204,18 @@ dict_table_change_id_in_cache(
dulint new_id) /* in: new id to set */
{
ut_ad(table);
-#ifdef UNIV_SYNC_DEBUG
ut_ad(mutex_own(&(dict_sys->mutex)));
-#endif /* UNIV_SYNC_DEBUG */
ut_ad(table->magic_n == DICT_TABLE_MAGIC_N);
/* Remove the table from the hash table of id's */
HASH_DELETE(dict_table_t, id_hash, dict_sys->table_id_hash,
- ut_fold_dulint(table->id), table);
+ ut_fold_dulint(table->id), table);
table->id = new_id;
/* Add the table back to the hash table */
HASH_INSERT(dict_table_t, id_hash, dict_sys->table_id_hash,
- ut_fold_dulint(table->id), table);
+ ut_fold_dulint(table->id), table);
}
/**************************************************************************
@@ -1197,12 +1229,9 @@ dict_table_remove_from_cache(
dict_foreign_t* foreign;
dict_index_t* index;
ulint size;
- ulint i;
-
+
ut_ad(table);
-#ifdef UNIV_SYNC_DEBUG
ut_ad(mutex_own(&(dict_sys->mutex)));
-#endif /* UNIV_SYNC_DEBUG */
ut_ad(table->magic_n == DICT_TABLE_MAGIC_N);
#if 0
@@ -1226,7 +1255,7 @@ dict_table_remove_from_cache(
while (foreign != NULL) {
foreign->referenced_table = NULL;
foreign->referenced_index = NULL;
-
+
foreign = UT_LIST_GET_NEXT(referenced_list, foreign);
}
@@ -1238,17 +1267,11 @@ dict_table_remove_from_cache(
index = UT_LIST_GET_LAST(table->indexes);
}
- /* Remove the columns of the table from the cache */
- for (i = 0; i < table->n_cols; i++) {
- dict_col_remove_from_cache(table,
- dict_table_get_nth_col(table, i));
- }
-
/* Remove table from the hash tables of tables */
HASH_DELETE(dict_table_t, name_hash, dict_sys->table_hash,
- ut_fold_string(table->name), table);
+ ut_fold_string(table->name), table);
HASH_DELETE(dict_table_t, id_hash, dict_sys->table_id_hash,
- ut_fold_dulint(table->id), table);
+ ut_fold_dulint(table->id), table);
/* Remove table from LRU list of tables */
UT_LIST_REMOVE(table_LRU, dict_sys->table_LRU, table);
@@ -1262,122 +1285,16 @@ dict_table_remove_from_cache(
dict_mem_table_free(table);
}
-/**************************************************************************
-Frees tables from the end of table_LRU if the dictionary cache occupies
-too much space. Currently not used! */
-
-void
-dict_table_LRU_trim(void)
-/*=====================*/
-{
- dict_table_t* table;
- dict_table_t* prev_table;
-
- ut_error;
-
-#ifdef UNIV_SYNC_DEBUG
- ut_ad(mutex_own(&(dict_sys->mutex)));
-#endif /* UNIV_SYNC_DEBUG */
-
- table = UT_LIST_GET_LAST(dict_sys->table_LRU);
-
- while (table && (dict_sys->size >
- buf_pool_get_max_size() / DICT_POOL_PER_VARYING)) {
-
- prev_table = UT_LIST_GET_PREV(table_LRU, table);
-
- if (table->mem_fix == 0) {
- dict_table_remove_from_cache(table);
- }
-
- table = prev_table;
- }
-}
-
-/**************************************************************************
-Adds a column to the data dictionary hash table. */
-static
-void
-dict_col_add_to_cache(
-/*==================*/
- dict_table_t* table, /* in: table */
- dict_col_t* col) /* in: column */
-{
- ulint fold;
-
- ut_ad(table && col);
-#ifdef UNIV_SYNC_DEBUG
- ut_ad(mutex_own(&(dict_sys->mutex)));
-#endif /* UNIV_SYNC_DEBUG */
- ut_ad(table->magic_n == DICT_TABLE_MAGIC_N);
-
- fold = ut_fold_ulint_pair(ut_fold_string(table->name),
- ut_fold_string(col->name));
-
- /* Look for a column with same table name and column name: error */
- {
- dict_col_t* col2;
- HASH_SEARCH(hash, dict_sys->col_hash, fold, col2,
- (ut_strcmp(col->name, col2->name) == 0)
- && (ut_strcmp((col2->table)->name, table->name)
- == 0));
- ut_a(col2 == NULL);
- }
-
- HASH_INSERT(dict_col_t, hash, dict_sys->col_hash, fold, col);
-}
-
-/**************************************************************************
-Removes a column from the data dictionary hash table. */
-static
-void
-dict_col_remove_from_cache(
-/*=======================*/
- dict_table_t* table, /* in: table */
- dict_col_t* col) /* in: column */
-{
- ulint fold;
-
- ut_ad(table && col);
-#ifdef UNIV_SYNC_DEBUG
- ut_ad(mutex_own(&(dict_sys->mutex)));
-#endif /* UNIV_SYNC_DEBUG */
- ut_ad(table->magic_n == DICT_TABLE_MAGIC_N);
-
- fold = ut_fold_ulint_pair(ut_fold_string(table->name),
- ut_fold_string(col->name));
-
- HASH_DELETE(dict_col_t, hash, dict_sys->col_hash, fold, col);
-}
+/*************************************************************************
+Gets the column position in the clustered index. */
-/**************************************************************************
-Repositions a column in the data dictionary hash table when the table name
-changes. */
-static
-void
-dict_col_reposition_in_cache(
-/*=========================*/
- dict_table_t* table, /* in: table */
- dict_col_t* col, /* in: column */
- const char* new_name) /* in: new table name */
+ulint
+dict_col_get_clust_pos_noninline(
+/*=============================*/
+ const dict_col_t* col, /* in: table column */
+ const dict_index_t* clust_index) /* in: clustered index */
{
- ulint fold;
-
- ut_ad(table && col);
-#ifdef UNIV_SYNC_DEBUG
- ut_ad(mutex_own(&(dict_sys->mutex)));
-#endif /* UNIV_SYNC_DEBUG */
- ut_ad(table->magic_n == DICT_TABLE_MAGIC_N);
-
- fold = ut_fold_ulint_pair(ut_fold_string(table->name),
- ut_fold_string(col->name));
-
- HASH_DELETE(dict_col_t, hash, dict_sys->col_hash, fold, col);
-
- fold = ut_fold_ulint_pair(ut_fold_string(new_name),
- ut_fold_string(col->name));
-
- HASH_INSERT(dict_col_t, hash, dict_sys->col_hash, fold, col);
+ return(dict_col_get_clust_pos(col, clust_index));
}
/********************************************************************
@@ -1392,12 +1309,12 @@ dict_col_name_is_reserved(
{
/* This check reminds that if a new system column is added to
the program, it should be dealt with here. */
-#if DATA_N_SYS_COLS != 4
-#error "DATA_N_SYS_COLS != 4"
+#if DATA_N_SYS_COLS != 3
+#error "DATA_N_SYS_COLS != 3"
#endif
static const char* reserved_names[] = {
- "DB_ROW_ID", "DB_TRX_ID", "DB_ROLL_PTR", "DB_MIX_ID"
+ "DB_ROW_ID", "DB_TRX_ID", "DB_ROLL_PTR"
};
ulint i;
@@ -1415,32 +1332,26 @@ dict_col_name_is_reserved(
/**************************************************************************
Adds an index to the dictionary cache. */
-ibool
+void
dict_index_add_to_cache(
/*====================*/
- /* out: TRUE if success */
dict_table_t* table, /* in: table on which the index is */
dict_index_t* index, /* in, own: index; NOTE! The index memory
object is freed in this function! */
ulint page_no)/* in: root page number of the index */
{
dict_index_t* new_index;
- dict_tree_t* tree;
- dict_table_t* cluster;
- dict_field_t* field;
ulint n_ord;
- ibool success;
ulint i;
-
+
ut_ad(index);
-#ifdef UNIV_SYNC_DEBUG
ut_ad(mutex_own(&(dict_sys->mutex)));
-#endif /* UNIV_SYNC_DEBUG */
ut_ad(index->n_def == index->n_fields);
ut_ad(index->magic_n == DICT_INDEX_MAGIC_N);
-
+
ut_ad(mem_heap_validate(index->heap));
+#ifdef UNIV_DEBUG
{
dict_index_t* index2;
index2 = UT_LIST_GET_FIRST(table->indexes);
@@ -1450,19 +1361,14 @@ dict_index_add_to_cache(
index2 = UT_LIST_GET_NEXT(indexes, index2);
}
-
- ut_a(UT_LIST_GET_LEN(table->indexes) == 0
- || (index->type & DICT_CLUSTERED) == 0);
}
+#endif /* UNIV_DEBUG */
- success = dict_index_find_cols(table, index);
+ ut_a(!(index->type & DICT_CLUSTERED)
+ || UT_LIST_GET_LEN(table->indexes) == 0);
- if (!success) {
- dict_mem_index_free(index);
+ dict_index_find_cols(table, index);
- return(FALSE);
- }
-
/* Build the cache internal representation of the index,
containing also the added system fields */
@@ -1473,15 +1379,15 @@ dict_index_add_to_cache(
}
new_index->search_info = btr_search_info_create(new_index->heap);
-
+
/* Set the n_fields value in new_index to the actual defined
number of fields in the cache internal representation */
new_index->n_fields = new_index->n_def;
-
+
/* Add the new index as the last index for the table */
- UT_LIST_ADD_LAST(indexes, table->indexes, new_index);
+ UT_LIST_ADD_LAST(indexes, table->indexes, new_index);
new_index->table = table;
new_index->table_name = table->name;
@@ -1495,33 +1401,18 @@ dict_index_add_to_cache(
for (i = 0; i < n_ord; i++) {
- field = dict_index_get_nth_field(new_index, i);
-
- dict_field_get_col(field)->ord_part++;
+ dict_index_get_nth_field(new_index, i)->col->ord_part = 1;
}
- if (table->type == DICT_TABLE_CLUSTER_MEMBER) {
- /* The index tree is found from the cluster object */
-
- cluster = dict_table_get_low(table->cluster_name);
-
- tree = dict_index_get_tree(
- UT_LIST_GET_FIRST(cluster->indexes));
- new_index->tree = tree;
- } else {
- /* Create an index tree memory object for the index */
- tree = dict_tree_create(new_index, page_no);
- ut_ad(tree);
-
- new_index->tree = tree;
- }
+ new_index->page = (unsigned int) page_no;
+ rw_lock_create(&new_index->lock, SYNC_INDEX_TREE);
if (!UNIV_UNLIKELY(new_index->type & DICT_UNIVERSAL)) {
- new_index->stat_n_diff_key_vals =
- mem_heap_alloc(new_index->heap,
- (1 + dict_index_get_n_unique(new_index))
- * sizeof(ib_longlong));
+ new_index->stat_n_diff_key_vals = mem_heap_alloc(
+ new_index->heap,
+ (1 + dict_index_get_n_unique(new_index))
+ * sizeof(ib_longlong));
/* Give some sensible values to stat_n_... in case we do
not calculate statistics quickly enough */
@@ -1530,18 +1421,10 @@ dict_index_add_to_cache(
new_index->stat_n_diff_key_vals[i] = 100;
}
}
-
- /* Add the index to the list of indexes stored in the tree */
- UT_LIST_ADD_LAST(tree_indexes, tree->tree_indexes, new_index);
-
- /* If the dictionary cache grows too big, trim the table LRU list */
dict_sys->size += mem_heap_get_size(new_index->heap);
- /* dict_table_LRU_trim(); */
dict_mem_index_free(index);
-
- return(TRUE);
}
/**************************************************************************
@@ -1553,28 +1436,14 @@ dict_index_remove_from_cache(
dict_table_t* table, /* in: table */
dict_index_t* index) /* in, own: index */
{
- dict_field_t* field;
ulint size;
- ulint i;
ut_ad(table && index);
ut_ad(table->magic_n == DICT_TABLE_MAGIC_N);
ut_ad(index->magic_n == DICT_INDEX_MAGIC_N);
-#ifdef UNIV_SYNC_DEBUG
ut_ad(mutex_own(&(dict_sys->mutex)));
-#endif /* UNIV_SYNC_DEBUG */
-
- ut_ad(UT_LIST_GET_LEN((index->tree)->tree_indexes) == 1);
- dict_tree_free(index->tree);
-
- /* Decrement the ord_part counts in columns which are ordering */
- for (i = 0; i < dict_index_get_n_unique(index); i++) {
- field = dict_index_get_nth_field(index, i);
-
- ut_ad(dict_field_get_col(field)->ord_part > 0);
- (dict_field_get_col(field)->ord_part)--;
- }
+ rw_lock_free(&index->lock);
/* Remove the index from the list of indexes of the table */
UT_LIST_REMOVE(indexes, table->indexes, index);
@@ -1589,48 +1458,43 @@ dict_index_remove_from_cache(
}
/***********************************************************************
-Tries to find column names for the index in the column hash table and
-sets the col field of the index. */
+Tries to find column names for the index and sets the col field of the
+index. */
static
-ibool
+void
dict_index_find_cols(
/*=================*/
- /* out: TRUE if success */
dict_table_t* table, /* in: table */
- dict_index_t* index) /* in: index */
+ dict_index_t* index) /* in: index */
{
- dict_col_t* col;
- dict_field_t* field;
- ulint fold;
ulint i;
-
+
ut_ad(table && index);
ut_ad(table->magic_n == DICT_TABLE_MAGIC_N);
-#ifdef UNIV_SYNC_DEBUG
ut_ad(mutex_own(&(dict_sys->mutex)));
-#endif /* UNIV_SYNC_DEBUG */
for (i = 0; i < index->n_fields; i++) {
- field = dict_index_get_nth_field(index, i);
+ ulint j;
+ dict_field_t* field = dict_index_get_nth_field(index, i);
- fold = ut_fold_ulint_pair(ut_fold_string(table->name),
- ut_fold_string(field->name));
-
- HASH_SEARCH(hash, dict_sys->col_hash, fold, col,
- (ut_strcmp(col->name, field->name) == 0)
- && (ut_strcmp((col->table)->name, table->name)
- == 0));
- if (col == NULL) {
+ for (j = 0; j < table->n_cols; j++) {
+ if (!strcmp(dict_table_get_col_name(table, j),
+ field->name)) {
+ field->col = (dict_col_t*)
+ dict_table_get_nth_col(table, j);
- return(FALSE);
- } else {
- field->col = col;
+ goto found;
+ }
}
- }
- return(TRUE);
+ /* It is an error not to find a matching column. */
+ ut_error;
+
+ found:
+ ;
+ }
}
-
+
/***********************************************************************
Adds a column to index. */
@@ -1638,21 +1502,24 @@ void
dict_index_add_col(
/*===============*/
dict_index_t* index, /* in: index */
+ dict_table_t* table, /* in: table */
dict_col_t* col, /* in: column */
- ulint order, /* in: order criterion */
ulint prefix_len) /* in: column prefix length */
{
dict_field_t* field;
+ const char* col_name;
- dict_mem_index_add_field(index, col->name, order, prefix_len);
+ col_name = dict_table_get_col_name(table, dict_col_get_no(col));
+
+ dict_mem_index_add_field(index, col_name, prefix_len);
field = dict_index_get_nth_field(index, index->n_def - 1);
field->col = col;
- field->fixed_len = dtype_get_fixed_size(&col->type);
+ field->fixed_len = (unsigned int) dict_col_get_fixed_size(col);
if (prefix_len && field->fixed_len > prefix_len) {
- field->fixed_len = prefix_len;
+ field->fixed_len = (unsigned int) prefix_len;
}
/* Long fixed-length fields that need external storage are treated as
@@ -1663,20 +1530,9 @@ dict_index_add_col(
field->fixed_len = 0;
}
- if (!(dtype_get_prtype(&col->type) & DATA_NOT_NULL)) {
+ if (!(col->prtype & DATA_NOT_NULL)) {
index->n_nullable++;
}
-
- if (index->n_def > 1) {
- const dict_field_t* field2 =
- dict_index_get_nth_field(index, index->n_def - 2);
- field->fixed_offs = (!field2->fixed_len ||
- field2->fixed_offs == ULINT_UNDEFINED)
- ? ULINT_UNDEFINED
- : field2->fixed_len + field2->fixed_offs;
- } else {
- field->fixed_offs = 0;
- }
}
/***********************************************************************
@@ -1687,19 +1543,20 @@ dict_index_copy(
/*============*/
dict_index_t* index1, /* in: index to copy to */
dict_index_t* index2, /* in: index to copy from */
+ dict_table_t* table, /* in: table */
ulint start, /* in: first position to copy */
ulint end) /* in: last position to copy */
{
dict_field_t* field;
ulint i;
-
+
/* Copy fields contained in index2 */
for (i = start; i < end; i++) {
field = dict_index_get_nth_field(index2, i);
- dict_index_add_col(index1, field->col, field->order,
- field->prefix_len);
+ dict_index_add_col(index1, table, field->col,
+ field->prefix_len);
}
}
@@ -1713,8 +1570,6 @@ dict_index_copy_types(
dict_index_t* index, /* in: index */
ulint n_fields) /* in: number of field types to copy */
{
- dtype_t* dfield_type;
- dtype_t* type;
ulint i;
if (UNIV_UNLIKELY(index->type & DICT_UNIVERSAL)) {
@@ -1724,10 +1579,15 @@ dict_index_copy_types(
}
for (i = 0; i < n_fields; i++) {
+ dict_field_t* ifield;
+ dtype_t* dfield_type;
+
+ ifield = dict_index_get_nth_field(index, i);
dfield_type = dfield_get_type(dtuple_get_nth_field(tuple, i));
- type = dict_col_get_type(dict_field_get_col(
- dict_index_get_nth_field(index, i)));
- *dfield_type = *type;
+ dict_col_copy_type(dict_field_get_col(ifield), dfield_type);
+ if (UNIV_UNLIKELY(ifield->prefix_len)) {
+ dfield_type->len = ifield->prefix_len;
+ }
}
}
@@ -1741,17 +1601,13 @@ dict_table_copy_types(
dict_table_t* table) /* in: index */
{
dtype_t* dfield_type;
- dtype_t* type;
ulint i;
- ut_ad(!(table->type & DICT_UNIVERSAL));
-
for (i = 0; i < dtuple_get_n_fields(tuple); i++) {
dfield_type = dfield_get_type(dtuple_get_nth_field(tuple, i));
- type = dict_col_get_type(dict_table_get_nth_col(table, i));
-
- *dfield_type = *type;
+ dict_col_copy_type(dict_table_get_nth_col(table, i),
+ dfield_type);
}
}
@@ -1766,58 +1622,41 @@ dict_index_build_internal_clust(
of the clustered index */
dict_table_t* table, /* in: table */
dict_index_t* index) /* in: user representation of a clustered
- index */
+ index */
{
dict_index_t* new_index;
dict_field_t* field;
- dict_col_t* col;
ulint fixed_size;
ulint trx_id_pos;
ulint i;
+ ibool* indexed;
ut_ad(table && index);
ut_ad(index->type & DICT_CLUSTERED);
-#ifdef UNIV_SYNC_DEBUG
ut_ad(mutex_own(&(dict_sys->mutex)));
-#endif /* UNIV_SYNC_DEBUG */
ut_ad(table->magic_n == DICT_TABLE_MAGIC_N);
/* Create a new index object with certainly enough fields */
new_index = dict_mem_index_create(table->name,
- index->name,
- table->space,
- index->type,
- index->n_fields + table->n_cols);
+ index->name, table->space,
+ index->type,
+ index->n_fields + table->n_cols);
/* Copy other relevant data from the old index struct to the new
struct: it inherits the values */
new_index->n_user_defined_cols = index->n_fields;
-
+
new_index->id = index->id;
- if (table->type != DICT_TABLE_ORDINARY) {
- /* The index is mixed: copy common key prefix fields */
-
- dict_index_copy(new_index, index, 0, table->mix_len);
-
- /* Add the mix id column */
- dict_index_add_col(new_index,
- dict_table_get_sys_col(table, DATA_MIX_ID), 0, 0);
-
- /* Copy the rest of fields */
- dict_index_copy(new_index, index, table->mix_len,
- index->n_fields);
- } else {
- /* Copy the fields of index */
- dict_index_copy(new_index, index, 0, index->n_fields);
- }
+ /* Copy the fields of index */
+ dict_index_copy(new_index, index, table, 0, index->n_fields);
if (UNIV_UNLIKELY(index->type & DICT_UNIVERSAL)) {
/* No fixed number of fields determines an entry uniquely */
- new_index->n_uniq = ULINT_MAX;
-
+ new_index->n_uniq = REC_MAX_N_FIELDS;
+
} else if (index->type & DICT_UNIQUE) {
/* Only the fields defined so far are needed to identify
the index entry uniquely */
@@ -1835,26 +1674,37 @@ dict_index_build_internal_clust(
trx_id_pos = new_index->n_def;
- ut_ad(DATA_ROW_ID == 0);
- ut_ad(DATA_TRX_ID == 1);
- ut_ad(DATA_ROLL_PTR == 2);
+#if DATA_ROW_ID != 0
+# error "DATA_ROW_ID != 0"
+#endif
+#if DATA_TRX_ID != 1
+# error "DATA_TRX_ID != 1"
+#endif
+#if DATA_ROLL_PTR != 2
+# error "DATA_ROLL_PTR != 2"
+#endif
if (!(index->type & DICT_UNIQUE)) {
- dict_index_add_col(new_index,
- dict_table_get_sys_col(table, DATA_ROW_ID), 0, 0);
+ dict_index_add_col(new_index, table, (dict_col_t*)
+ dict_table_get_sys_col(
+ table, DATA_ROW_ID),
+ 0);
trx_id_pos++;
}
- dict_index_add_col(new_index,
- dict_table_get_sys_col(table, DATA_TRX_ID), 0, 0);
-
- dict_index_add_col(new_index,
- dict_table_get_sys_col(table, DATA_ROLL_PTR), 0, 0);
+ dict_index_add_col(new_index, table, (dict_col_t*)
+ dict_table_get_sys_col(table, DATA_TRX_ID),
+ 0);
+
+ dict_index_add_col(new_index, table, (dict_col_t*)
+ dict_table_get_sys_col(table,
+ DATA_ROLL_PTR),
+ 0);
for (i = 0; i < trx_id_pos; i++) {
- fixed_size = dtype_get_fixed_size(
- dict_index_get_nth_type(new_index, i));
+ fixed_size = dict_col_get_fixed_size(
+ dict_index_get_nth_col(new_index, i));
if (fixed_size == 0) {
new_index->trx_id_offset = 0;
@@ -1869,17 +1719,14 @@ dict_index_build_internal_clust(
break;
}
- new_index->trx_id_offset += fixed_size;
+ new_index->trx_id_offset += (unsigned int) fixed_size;
}
}
- /* Set auxiliary variables in table columns as undefined */
- for (i = 0; i < table->n_cols; i++) {
-
- col = dict_table_get_nth_col(table, i);
- col->aux = ULINT_UNDEFINED;
- }
+ /* Remember the table columns already contained in new_index */
+ indexed = mem_alloc(table->n_cols * sizeof *indexed);
+ memset(indexed, 0, table->n_cols * sizeof *indexed);
/* Mark with 0 the table columns already contained in new_index */
for (i = 0; i < new_index->n_def; i++) {
@@ -1891,41 +1738,32 @@ dict_index_build_internal_clust(
if (field->prefix_len == 0) {
- field->col->aux = 0;
+ indexed[field->col->ind] = TRUE;
}
}
-
+
/* Add to new_index non-system columns of table not yet included
there */
- for (i = 0; i < table->n_cols - DATA_N_SYS_COLS; i++) {
+ for (i = 0; i + DATA_N_SYS_COLS < (ulint) table->n_cols; i++) {
- col = dict_table_get_nth_col(table, i);
- ut_ad(col->type.mtype != DATA_SYS);
+ dict_col_t* col = (dict_col_t*)
+ dict_table_get_nth_col(table, i);
+ ut_ad(col->mtype != DATA_SYS);
- if (col->aux == ULINT_UNDEFINED) {
- dict_index_add_col(new_index, col, 0, 0);
+ if (!indexed[col->ind]) {
+ dict_index_add_col(new_index, table, col, 0);
}
}
- ut_ad((index->type & DICT_IBUF)
- || (UT_LIST_GET_LEN(table->indexes) == 0));
-
- /* Store to the column structs the position of the table columns
- in the clustered index */
-
- for (i = 0; i < new_index->n_def; i++) {
- field = dict_index_get_nth_field(new_index, i);
+ mem_free(indexed);
- if (field->prefix_len == 0) {
+ ut_ad((index->type & DICT_IBUF)
+ || (UT_LIST_GET_LEN(table->indexes) == 0));
- field->col->clust_pos = i;
- }
- }
-
new_index->cached = TRUE;
return(new_index);
-}
+}
/***********************************************************************
Builds the internal dictionary cache representation for a non-clustered
@@ -1938,52 +1776,44 @@ dict_index_build_internal_non_clust(
of the non-clustered index */
dict_table_t* table, /* in: table */
dict_index_t* index) /* in: user representation of a non-clustered
- index */
+ index */
{
dict_field_t* field;
dict_index_t* new_index;
dict_index_t* clust_index;
ulint i;
+ ibool* indexed;
ut_ad(table && index);
ut_ad(0 == (index->type & DICT_CLUSTERED));
-#ifdef UNIV_SYNC_DEBUG
ut_ad(mutex_own(&(dict_sys->mutex)));
-#endif /* UNIV_SYNC_DEBUG */
ut_ad(table->magic_n == DICT_TABLE_MAGIC_N);
/* The clustered index should be the first in the list of indexes */
clust_index = UT_LIST_GET_FIRST(table->indexes);
-
+
ut_ad(clust_index);
ut_ad(clust_index->type & DICT_CLUSTERED);
ut_ad(!(clust_index->type & DICT_UNIVERSAL));
/* Create a new index */
- new_index = dict_mem_index_create(table->name,
- index->name,
- index->space,
- index->type,
- index->n_fields
- + 1 + clust_index->n_uniq);
+ new_index = dict_mem_index_create(
+ table->name, index->name, index->space, index->type,
+ index->n_fields + 1 + clust_index->n_uniq);
/* Copy other relevant data from the old index
struct to the new struct: it inherits the values */
new_index->n_user_defined_cols = index->n_fields;
-
+
new_index->id = index->id;
/* Copy fields from index to new_index */
- dict_index_copy(new_index, index, 0, index->n_fields);
+ dict_index_copy(new_index, index, table, 0, index->n_fields);
- /* Set the auxiliary variables in the clust_index unique columns
- as undefined */
- for (i = 0; i < clust_index->n_uniq; i++) {
-
- field = dict_index_get_nth_field(clust_index, i);
- field->col->aux = ULINT_UNDEFINED;
- }
+ /* Remember the table columns already contained in new_index */
+ indexed = mem_alloc(table->n_cols * sizeof *indexed);
+ memset(indexed, 0, table->n_cols * sizeof *indexed);
/* Mark with 0 table columns already contained in new_index */
for (i = 0; i < new_index->n_def; i++) {
@@ -1995,7 +1825,7 @@ dict_index_build_internal_non_clust(
if (field->prefix_len == 0) {
- field->col->aux = 0;
+ indexed[field->col->ind] = TRUE;
}
}
@@ -2006,12 +1836,14 @@ dict_index_build_internal_non_clust(
field = dict_index_get_nth_field(clust_index, i);
- if (field->col->aux == ULINT_UNDEFINED) {
- dict_index_add_col(new_index, field->col, 0,
- field->prefix_len);
+ if (!indexed[field->col->ind]) {
+ dict_index_add_col(new_index, table, field->col,
+ field->prefix_len);
}
}
+ mem_free(indexed);
+
if ((index->type) & DICT_UNIQUE) {
new_index->n_uniq = index->n_fields;
} else {
@@ -2026,7 +1858,7 @@ dict_index_build_internal_non_clust(
new_index->cached = TRUE;
return(new_index);
-}
+}
/*====================== FOREIGN KEY PROCESSING ========================*/
@@ -2041,7 +1873,7 @@ dict_table_referenced_by_foreign_key(
dict_table_t* table) /* in: InnoDB table */
{
if (UT_LIST_GET_LEN(table->referenced_list) > 0) {
-
+
return(TRUE);
}
@@ -2067,19 +1899,19 @@ dict_foreign_remove_from_cache(
/*===========================*/
dict_foreign_t* foreign) /* in, own: foreign constraint */
{
-#ifdef UNIV_SYNC_DEBUG
ut_ad(mutex_own(&(dict_sys->mutex)));
-#endif /* UNIV_SYNC_DEBUG */
ut_a(foreign);
-
+
if (foreign->referenced_table) {
UT_LIST_REMOVE(referenced_list,
- foreign->referenced_table->referenced_list, foreign);
+ foreign->referenced_table->referenced_list,
+ foreign);
}
if (foreign->foreign_table) {
UT_LIST_REMOVE(foreign_list,
- foreign->foreign_table->foreign_list, foreign);
+ foreign->foreign_table->foreign_list,
+ foreign);
}
dict_foreign_free(foreign);
@@ -2098,9 +1930,7 @@ dict_foreign_find(
{
dict_foreign_t* foreign;
-#ifdef UNIV_SYNC_DEBUG
ut_ad(mutex_own(&(dict_sys->mutex)));
-#endif /* UNIV_SYNC_DEBUG */
foreign = UT_LIST_GET_FIRST(table->foreign_list);
@@ -2112,7 +1942,7 @@ dict_foreign_find(
foreign = UT_LIST_GET_NEXT(foreign_list, foreign);
}
-
+
foreign = UT_LIST_GET_FIRST(table->referenced_list);
while (foreign) {
@@ -2125,8 +1955,9 @@ dict_foreign_find(
}
return(NULL);
-}
+}
+#ifndef UNIV_HOTBACKUP
/*************************************************************************
Tries to find an index whose first fields are the columns in the array,
in the same order. */
@@ -2140,54 +1971,55 @@ dict_foreign_find_index(
ulint n_cols, /* in: number of columns */
dict_index_t* types_idx, /* in: NULL or an index to whose types the
column types must match */
- ibool check_charsets, /* in: whether to check charsets.
- only has an effect if types_idx !=
- NULL. */
+ ibool check_charsets,
+ /* in: whether to check charsets.
+ only has an effect if types_idx != NULL */
ulint check_null)
/* in: nonzero if none of the columns must
be declared NOT NULL */
{
-#ifndef UNIV_HOTBACKUP
dict_index_t* index;
+ dict_field_t* field;
const char* col_name;
ulint i;
-
+
index = dict_table_get_first_index(table);
while (index != NULL) {
if (dict_index_get_n_fields(index) >= n_cols) {
for (i = 0; i < n_cols; i++) {
- dict_field_t* field
- = dict_index_get_nth_field(index, i);
+ field = dict_index_get_nth_field(index, i);
+
+ col_name = dict_table_get_col_name(
+ table, dict_col_get_no(field->col));
- col_name = field->col->name;
if (field->prefix_len != 0) {
/* We do not accept column prefix
indexes here */
-
+
break;
}
if (0 != innobase_strcasecmp(columns[i],
- col_name)) {
- break;
+ col_name)) {
+ break;
}
if (check_null
- && (field->col->type.prtype
- & DATA_NOT_NULL)) {
+ && (field->col->prtype & DATA_NOT_NULL)) {
return(NULL);
}
- if (types_idx && !cmp_types_are_equal(
- dict_index_get_nth_type(index, i),
- dict_index_get_nth_type(types_idx, i),
- check_charsets)) {
+ if (types_idx && !cmp_cols_are_equal(
+ dict_index_get_nth_col(index, i),
+ dict_index_get_nth_col(types_idx,
+ i),
+ check_charsets)) {
- break;
- }
+ break;
+ }
}
if (i == n_cols) {
@@ -2201,12 +2033,6 @@ dict_foreign_find_index(
}
return(NULL);
-#else /* UNIV_HOTBACKUP */
- /* This function depends on MySQL code that is not included in
- InnoDB Hot Backup builds. Besides, this function should never
- be called in InnoDB Hot Backup. */
- ut_error;
-#endif /* UNIV_HOTBACKUP */
}
/**************************************************************************
@@ -2242,11 +2068,12 @@ dict_foreign_error_report(
putc('\n', file);
if (fk->foreign_index) {
fputs("The index in the foreign key in table is ", file);
- ut_print_name(file, NULL, fk->foreign_index->name);
+ ut_print_name(file, NULL, FALSE, fk->foreign_index->name);
fputs("\n"
-"See http://dev.mysql.com/doc/refman/5.0/en/innodb-foreign-key-constraints.html\n"
-"for correct foreign key definition.\n",
- file);
+ "See http://dev.mysql.com/doc/refman/5.1/en/"
+ "innodb-foreign-key-constraints.html\n"
+ "for correct foreign key definition.\n",
+ file);
}
mutex_exit(&dict_foreign_err_mutex);
}
@@ -2270,17 +2097,15 @@ dict_foreign_add_to_cache(
dict_foreign_t* for_in_cache = NULL;
dict_index_t* index;
ibool added_to_referenced_list= FALSE;
- FILE* ef = dict_foreign_err_file;
+ FILE* ef = dict_foreign_err_file;
-#ifdef UNIV_SYNC_DEBUG
ut_ad(mutex_own(&(dict_sys->mutex)));
-#endif /* UNIV_SYNC_DEBUG */
for_table = dict_table_check_if_in_cache_low(
- foreign->foreign_table_name);
-
+ foreign->foreign_table_name);
+
ref_table = dict_table_check_if_in_cache_low(
- foreign->referenced_table_name);
+ foreign->referenced_table_name);
ut_a(for_table || ref_table);
if (for_table) {
@@ -2299,34 +2124,40 @@ dict_foreign_add_to_cache(
}
if (for_in_cache->referenced_table == NULL && ref_table) {
- index = dict_foreign_find_index(ref_table,
+ index = dict_foreign_find_index(
+ ref_table,
(const char**) for_in_cache->referenced_col_names,
- for_in_cache->n_fields,
- for_in_cache->foreign_index, check_charsets, FALSE);
+ for_in_cache->n_fields, for_in_cache->foreign_index,
+ check_charsets, FALSE);
if (index == NULL) {
- dict_foreign_error_report(ef, for_in_cache,
-"there is no index in referenced table which would contain\n"
-"the columns as the first columns, or the data types in the\n"
-"referenced table do not match to the ones in table.");
+ dict_foreign_error_report(
+ ef, for_in_cache,
+ "there is no index in referenced table"
+ " which would contain\n"
+ "the columns as the first columns,"
+ " or the data types in the\n"
+ "referenced table do not match"
+ " the ones in table.");
if (for_in_cache == foreign) {
mem_heap_free(foreign->heap);
}
- return(DB_CANNOT_ADD_CONSTRAINT);
+ return(DB_CANNOT_ADD_CONSTRAINT);
}
for_in_cache->referenced_table = ref_table;
for_in_cache->referenced_index = index;
UT_LIST_ADD_LAST(referenced_list,
- ref_table->referenced_list,
- for_in_cache);
+ ref_table->referenced_list,
+ for_in_cache);
added_to_referenced_list = TRUE;
}
if (for_in_cache->foreign_table == NULL && for_table) {
- index = dict_foreign_find_index(for_table,
+ index = dict_foreign_find_index(
+ for_table,
(const char**) for_in_cache->foreign_col_names,
for_in_cache->n_fields,
for_in_cache->referenced_index, check_charsets,
@@ -2335,30 +2166,36 @@ dict_foreign_add_to_cache(
| DICT_FOREIGN_ON_UPDATE_SET_NULL));
if (index == NULL) {
- dict_foreign_error_report(ef, for_in_cache,
-"there is no index in the table which would contain\n"
-"the columns as the first columns, or the data types in the\n"
-"table do not match to the ones in the referenced table\n"
-"or one of the ON ... SET NULL columns is declared NOT NULL.");
+ dict_foreign_error_report(
+ ef, for_in_cache,
+ "there is no index in the table"
+ " which would contain\n"
+ "the columns as the first columns,"
+ " or the data types in the\n"
+ "table do not match"
+ " the ones in the referenced table\n"
+ "or one of the ON ... SET NULL columns"
+ " is declared NOT NULL.");
if (for_in_cache == foreign) {
if (added_to_referenced_list) {
- UT_LIST_REMOVE(referenced_list,
+ UT_LIST_REMOVE(
+ referenced_list,
ref_table->referenced_list,
for_in_cache);
}
-
+
mem_heap_free(foreign->heap);
}
- return(DB_CANNOT_ADD_CONSTRAINT);
+ return(DB_CANNOT_ADD_CONSTRAINT);
}
for_in_cache->foreign_table = for_table;
for_in_cache->foreign_index = index;
UT_LIST_ADD_LAST(foreign_list,
- for_table->foreign_list,
- for_in_cache);
+ for_table->foreign_list,
+ for_in_cache);
}
return(DB_SUCCESS);
@@ -2393,13 +2230,13 @@ dict_scan_to(
ulint i;
for (i = 0; string[i]; i++) {
if (toupper((int)(unsigned char)(ptr[i]))
- != toupper((int)(unsigned char)
- (string[i]))) {
+ != toupper((int)(unsigned char)
+ (string[i]))) {
goto nomatch;
}
}
break;
- nomatch:
+nomatch:
;
}
}
@@ -2409,12 +2246,13 @@ dict_scan_to(
/*************************************************************************
Accepts a specified string. Comparisons are case-insensitive. */
-
+static
const char*
dict_accept(
/*========*/
/* out: if string was accepted, the pointer
is moved after that, else ptr is returned */
+ struct charset_info_st* cs,/* in: the character set of ptr */
const char* ptr, /* in: scan from this */
const char* string, /* in: accept only this string as the next
non-whitespace string */
@@ -2424,15 +2262,15 @@ dict_accept(
const char* old_ptr2;
*success = FALSE;
-
- while (ib_isspace(*ptr)) {
+
+ while (my_isspace(cs, *ptr)) {
ptr++;
}
old_ptr2 = ptr;
-
+
ptr = dict_scan_to(ptr, string);
-
+
if (*ptr == '\0' || old_ptr2 != ptr) {
return(old_ptr);
}
@@ -2450,12 +2288,15 @@ const char*
dict_scan_id(
/*=========*/
/* out: scanned to */
+ struct charset_info_st* cs,/* in: the character set of ptr */
const char* ptr, /* in: scanned to */
mem_heap_t* heap, /* in: heap where to allocate the id
(NULL=id will not be allocated, but it
will point to string near ptr) */
const char** id, /* out,own: the id; NULL if no id was
scannable */
+ ibool table_id,/* in: TRUE=convert the allocated id
+ as a table name; FALSE=convert to UTF-8 */
ibool accept_also_dot)
/* in: TRUE if also a dot can appear in a
non-quoted id; in a quoted id it can appear
@@ -2464,13 +2305,12 @@ dict_scan_id(
char quote = '\0';
ulint len = 0;
const char* s;
- char* d;
- ulint id_len;
- byte* b;
+ char* str;
+ char* dst;
*id = NULL;
- while (ib_isspace(*ptr)) {
+ while (my_isspace(cs, *ptr)) {
ptr++;
}
@@ -2501,7 +2341,7 @@ dict_scan_id(
len++;
}
} else {
- while (!ib_isspace(*ptr) && *ptr != '(' && *ptr != ')'
+ while (!my_isspace(cs, *ptr) && *ptr != '(' && *ptr != ')'
&& (accept_also_dot || *ptr != '.')
&& *ptr != ',' && *ptr != '\0') {
@@ -2511,43 +2351,50 @@ dict_scan_id(
len = ptr - s;
}
- if (quote && heap) {
- *id = d = mem_heap_alloc(heap, len + 1);
+ if (UNIV_UNLIKELY(!heap)) {
+ /* no heap given: id will point to source string */
+ *id = s;
+ return(ptr);
+ }
+
+ if (quote) {
+ char* d;
+ str = d = mem_heap_alloc(heap, len + 1);
while (len--) {
if ((*d++ = *s++) == quote) {
s++;
}
}
*d++ = 0;
- ut_a(*s == quote);
- ut_a(s + 1 == ptr);
- } else if (heap) {
- *id = mem_heap_strdupl(heap, s, len);
+ len = d - str;
+ ut_ad(*s == quote);
+ ut_ad(s + 1 == ptr);
} else {
- /* no heap given: id will point to source string */
- *id = s;
+ str = mem_heap_strdupl(heap, s, len);
}
- if (heap && !quote) {
- /* EMS MySQL Manager sometimes adds characters 0xA0 (in
- latin1, a 'non-breakable space') to the end of a table name.
- After the UTF-8 conversion in ha_innodb.cc, bytes 0xC2
- and 0xA0 are at the end of the string, and ib_isspace()
- does not work for multi-byte UTF-8 characters.
-
- In MySQL 5.1 we lex the string using thd->charset_info, and
- my_isspace(). This workaround is not needed there. */
-
- b = (byte*)(*id);
- id_len = strlen((char*) b);
-
- if (id_len >= 3 && b[id_len - 1] == 0xA0
- && b[id_len - 2] == 0xC2) {
-
- /* Strip the 2 last bytes */
+ if (!table_id) {
+convert_id:
+ /* Convert the identifier from connection character set
+ to UTF-8. */
+ len = 3 * len + 1;
+ *id = dst = mem_heap_alloc(heap, len);
+
+ innobase_convert_from_id(dst, str, len);
+ } else if (!strncmp(str, srv_mysql50_table_name_prefix,
+ sizeof srv_mysql50_table_name_prefix)) {
+ /* This is a pre-5.1 table name
+ containing chars other than [A-Za-z0-9].
+ Discard the prefix and use raw UTF-8 encoding. */
+ str += sizeof srv_mysql50_table_name_prefix;
+ len -= sizeof srv_mysql50_table_name_prefix;
+ goto convert_id;
+ } else {
+ /* Encode using filename-safe characters. */
+ len = 5 * len + 1;
+ *id = dst = mem_heap_alloc(heap, len);
- b[id_len - 2] = '\0';
- }
+ innobase_convert_from_table_id(dst, str, len);
}
return(ptr);
@@ -2559,22 +2406,21 @@ static
const char*
dict_scan_col(
/*==========*/
- /* out: scanned to */
- const char* ptr, /* in: scanned to */
- ibool* success,/* out: TRUE if success */
- dict_table_t* table, /* in: table in which the column is */
- dict_col_t** column, /* out: pointer to column if success */
- mem_heap_t* heap, /* in: heap where to allocate the name */
- const char** name) /* out,own: the column name; NULL if no name
- was scannable */
+ /* out: scanned to */
+ struct charset_info_st* cs, /* in: the character set of ptr */
+ const char* ptr, /* in: scanned to */
+ ibool* success,/* out: TRUE if success */
+ dict_table_t* table, /* in: table in which the column is */
+ const dict_col_t** column, /* out: pointer to column if success */
+ mem_heap_t* heap, /* in: heap where to allocate */
+ const char** name) /* out,own: the column name;
+ NULL if no name was scannable */
{
-#ifndef UNIV_HOTBACKUP
- dict_col_t* col;
ulint i;
*success = FALSE;
- ptr = dict_scan_id(ptr, heap, name, TRUE);
+ ptr = dict_scan_id(cs, ptr, heap, name, FALSE, TRUE);
if (*name == NULL) {
@@ -2585,29 +2431,24 @@ dict_scan_col(
*success = TRUE;
*column = NULL;
} else {
- for (i = 0; i < dict_table_get_n_cols(table); i++) {
+ for (i = 0; i < dict_table_get_n_cols(table); i++) {
- col = dict_table_get_nth_col(table, i);
+ const char* col_name = dict_table_get_col_name(
+ table, i);
- if (0 == innobase_strcasecmp(col->name, *name)) {
- /* Found */
+ if (0 == innobase_strcasecmp(col_name, *name)) {
+ /* Found */
- *success = TRUE;
- *column = col;
- strcpy((char*) *name, col->name);
+ *success = TRUE;
+ *column = dict_table_get_nth_col(table, i);
+ strcpy((char*) *name, col_name);
- break;
+ break;
}
}
}
-
+
return(ptr);
-#else /* UNIV_HOTBACKUP */
- /* This function depends on MySQL code that is not included in
- InnoDB Hot Backup builds. Besides, this function should never
- be called in InnoDB Hot Backup. */
- ut_error;
-#endif /* UNIV_HOTBACKUP */
}
/*************************************************************************
@@ -2617,6 +2458,7 @@ const char*
dict_scan_table_name(
/*=================*/
/* out: scanned to */
+ struct charset_info_st* cs,/* in: the character set of ptr */
const char* ptr, /* in: scanned to */
dict_table_t** table, /* out: table object or NULL */
const char* name, /* in: foreign key table name */
@@ -2625,7 +2467,6 @@ dict_scan_table_name(
const char** ref_name)/* out,own: the table name;
NULL if no name was scannable */
{
-#ifndef UNIV_HOTBACKUP
const char* database_name = NULL;
ulint database_name_len = 0;
const char* table_name = NULL;
@@ -2635,11 +2476,11 @@ dict_scan_table_name(
*success = FALSE;
*table = NULL;
-
- ptr = dict_scan_id(ptr, heap, &scan_name, FALSE);
+
+ ptr = dict_scan_id(cs, ptr, heap, &scan_name, TRUE, FALSE);
if (scan_name == NULL) {
-
+
return(ptr); /* Syntax error */
}
@@ -2651,7 +2492,7 @@ dict_scan_table_name(
database_name = scan_name;
database_name_len = strlen(database_name);
- ptr = dict_scan_id(ptr, heap, &table_name, FALSE);
+ ptr = dict_scan_id(cs, ptr, heap, &table_name, TRUE, FALSE);
if (table_name == NULL) {
@@ -2662,9 +2503,9 @@ dict_scan_table_name(
earlier, we must allow the dot separator between the database
name and the table name also to appear within a quoted
identifier! InnoDB used to print a constraint as:
- ... REFERENCES `databasename.tablename` ...
+ ... REFERENCES `databasename.tablename` ...
starting from 4.0.18 it is
- ... REFERENCES `databasename`.`tablename` ... */
+ ... REFERENCES `databasename`.`tablename` ... */
const char* s;
for (s = scan_name; *s; s++) {
@@ -2707,12 +2548,6 @@ dict_scan_table_name(
*table = dict_table_get_low(ref);
return(ptr);
-#else /* UNIV_HOTBACKUP */
- /* This function depends on MySQL code that is not included in
- InnoDB Hot Backup builds. Besides, this function should never
- be called in InnoDB Hot Backup. */
- ut_error;
-#endif /* UNIV_HOTBACKUP */
}
/*************************************************************************
@@ -2722,20 +2557,21 @@ const char*
dict_skip_word(
/*===========*/
/* out: scanned to */
+ struct charset_info_st* cs,/* in: the character set of ptr */
const char* ptr, /* in: scanned to */
ibool* success)/* out: TRUE if success, FALSE if just spaces
left in string or a syntax error */
{
const char* start;
-
+
*success = FALSE;
- ptr = dict_scan_id(ptr, NULL, &start, TRUE);
+ ptr = dict_scan_id(cs, ptr, NULL, &start, FALSE, TRUE);
if (start) {
*success = TRUE;
}
-
+
return(ptr);
}
@@ -2757,8 +2593,8 @@ dict_strip_comments(
char* str;
const char* sptr;
char* ptr;
- /* unclosed quote character (0 if none) */
- char quote = 0;
+ /* unclosed quote character (0 if none) */
+ char quote = 0;
str = mem_alloc(strlen(sql_string) + 1);
@@ -2786,8 +2622,8 @@ scan_more:
/* Starting quote: remember the quote character. */
quote = *sptr;
} else if (*sptr == '#'
- || (sptr[0] == '-' && sptr[1] == '-' &&
- sptr[2] == ' ')) {
+ || (sptr[0] == '-' && sptr[1] == '-'
+ && sptr[2] == ' ')) {
for (;;) {
/* In Unix a newline is 0x0A while in Windows
it is 0x0D followed by 0x0A */
@@ -2805,7 +2641,7 @@ scan_more:
for (;;) {
if (*sptr == '*' && *(sptr + 1) == '/') {
- sptr += 2;
+ sptr += 2;
goto scan_more;
}
@@ -2853,12 +2689,13 @@ dict_table_get_highest_foreign_id(
if (ut_strlen(foreign->id) > ((sizeof dict_ibfk) - 1) + len
&& 0 == ut_memcmp(foreign->id, table->name, len)
&& 0 == ut_memcmp(foreign->id + len,
- dict_ibfk, (sizeof dict_ibfk) - 1)
+ dict_ibfk, (sizeof dict_ibfk) - 1)
&& foreign->id[len + ((sizeof dict_ibfk) - 1)] != '0') {
/* It is of the >= 4.0.18 format */
- id = strtoul(foreign->id + len + ((sizeof dict_ibfk) - 1),
- &endp, 10);
+ id = strtoul(foreign->id + len
+ + ((sizeof dict_ibfk) - 1),
+ &endp, 10);
if (*endp == '\0') {
ut_a(id != biggest_id);
@@ -2908,6 +2745,7 @@ dict_create_foreign_constraints_low(
/* out: error code or DB_SUCCESS */
trx_t* trx, /* in: transaction */
mem_heap_t* heap, /* in: memory heap */
+ struct charset_info_st* cs,/* in: the character set of sql_string */
const char* sql_string,
/* in: CREATE TABLE or ALTER TABLE statement
where foreign keys are declared like:
@@ -2928,7 +2766,7 @@ dict_create_foreign_constraints_low(
ulint highest_id_so_far = 0;
dict_index_t* index;
dict_foreign_t* foreign;
- const char* ptr = sql_string;
+ const char* ptr = sql_string;
const char* start_of_latest_foreign = sql_string;
FILE* ef = dict_foreign_err_file;
const char* constraint_name;
@@ -2941,13 +2779,11 @@ dict_create_foreign_constraints_low(
ibool is_on_delete;
ulint n_on_deletes;
ulint n_on_updates;
- dict_col_t* columns[500];
+ const dict_col_t*columns[500];
const char* column_names[500];
const char* referenced_table_name;
-
-#ifdef UNIV_SYNC_DEBUG
+
ut_ad(mutex_own(&(dict_sys->mutex)));
-#endif /* UNIV_SYNC_DEBUG */
table = dict_table_get_low(name);
@@ -2955,8 +2791,9 @@ dict_create_foreign_constraints_low(
mutex_enter(&dict_foreign_err_mutex);
dict_foreign_error_report_low(ef, name);
fprintf(ef,
-"Cannot find the table in the internal data dictionary of InnoDB.\n"
-"Create table statement:\n%s\n", sql_string);
+ "Cannot find the table in the internal"
+ " data dictionary of InnoDB.\n"
+ "Create table statement:\n%s\n", sql_string);
mutex_exit(&dict_foreign_err_mutex);
return(DB_ERROR);
@@ -2965,14 +2802,14 @@ dict_create_foreign_constraints_low(
/* First check if we are actually doing an ALTER TABLE, and in that
case look for the table being altered */
- ptr = dict_accept(ptr, "ALTER", &success);
+ ptr = dict_accept(cs, ptr, "ALTER", &success);
if (!success) {
goto loop;
}
- ptr = dict_accept(ptr, "TABLE", &success);
+ ptr = dict_accept(cs, ptr, "TABLE", &success);
if (!success) {
@@ -2981,11 +2818,13 @@ dict_create_foreign_constraints_low(
/* We are doing an ALTER TABLE: scan the table name we are altering */
- ptr = dict_scan_table_name(ptr, &table_to_alter, name,
- &success, heap, &referenced_table_name);
+ ptr = dict_scan_table_name(cs, ptr, &table_to_alter, name,
+ &success, heap, &referenced_table_name);
if (!success) {
fprintf(stderr,
-"InnoDB: Error: could not find the table being ALTERED in:\n%s\n", sql_string);
+ "InnoDB: Error: could not find"
+ " the table being ALTERED in:\n%s\n",
+ sql_string);
return(DB_ERROR);
}
@@ -3003,7 +2842,7 @@ dict_create_foreign_constraints_low(
highest_id_so_far = 0;
} else {
highest_id_so_far = dict_table_get_highest_foreign_id(
- table_to_alter);
+ table_to_alter);
}
/* Scan for foreign key declarations in a loop */
@@ -3021,21 +2860,22 @@ loop:
of the constraint to system tables. */
ptr = ptr1;
- ptr = dict_accept(ptr, "CONSTRAINT", &success);
+ ptr = dict_accept(cs, ptr, "CONSTRAINT", &success);
ut_a(success);
- if (!ib_isspace(*ptr) && *ptr != '"' && *ptr != '`') {
- goto loop;
+ if (!my_isspace(cs, *ptr) && *ptr != '"' && *ptr != '`') {
+ goto loop;
}
- while (ib_isspace(*ptr)) {
+ while (my_isspace(cs, *ptr)) {
ptr++;
}
/* read constraint name unless got "CONSTRAINT FOREIGN" */
if (ptr != ptr2) {
- ptr = dict_scan_id(ptr, heap, &constraint_name, FALSE);
+ ptr = dict_scan_id(cs, ptr, heap,
+ &constraint_name, FALSE, FALSE);
}
} else {
ptr = ptr2;
@@ -3043,65 +2883,65 @@ loop:
if (*ptr == '\0') {
/* The proper way to reject foreign keys for temporary
- tables would be to split the lexing and syntactical
- analysis of foreign key clauses from the actual adding
- of them, so that ha_innodb.cc could first parse the SQL
- command, determine if there are any foreign keys, and
- if so, immediately reject the command if the table is a
- temporary one. For now, this kludge will work. */
- if (reject_fks && (UT_LIST_GET_LEN(table->foreign_list) > 0))
- {
- return DB_CANNOT_ADD_CONSTRAINT;
+ tables would be to split the lexing and syntactical
+ analysis of foreign key clauses from the actual adding
+ of them, so that ha_innodb.cc could first parse the SQL
+ command, determine if there are any foreign keys, and
+ if so, immediately reject the command if the table is a
+ temporary one. For now, this kludge will work. */
+ if (reject_fks && (UT_LIST_GET_LEN(table->foreign_list) > 0)) {
+
+ return(DB_CANNOT_ADD_CONSTRAINT);
}
-
+
/**********************************************************/
/* The following call adds the foreign key constraints
to the data dictionary system tables on disk */
-
+
error = dict_create_add_foreigns_to_dictionary(
- highest_id_so_far, table, trx);
+ highest_id_so_far, table, trx);
return(error);
}
start_of_latest_foreign = ptr;
- ptr = dict_accept(ptr, "FOREIGN", &success);
-
+ ptr = dict_accept(cs, ptr, "FOREIGN", &success);
+
if (!success) {
goto loop;
}
- if (!ib_isspace(*ptr)) {
- goto loop;
+ if (!my_isspace(cs, *ptr)) {
+ goto loop;
}
- ptr = dict_accept(ptr, "KEY", &success);
+ ptr = dict_accept(cs, ptr, "KEY", &success);
if (!success) {
goto loop;
}
- ptr = dict_accept(ptr, "(", &success);
+ ptr = dict_accept(cs, ptr, "(", &success);
if (!success) {
/* MySQL allows also an index id before the '('; we
skip it */
- ptr = dict_skip_word(ptr, &success);
+ ptr = dict_skip_word(cs, ptr, &success);
if (!success) {
- dict_foreign_report_syntax_err(name,
- start_of_latest_foreign, ptr);
+ dict_foreign_report_syntax_err(
+ name, start_of_latest_foreign, ptr);
return(DB_CANNOT_ADD_CONSTRAINT);
}
- ptr = dict_accept(ptr, "(", &success);
+ ptr = dict_accept(cs, ptr, "(", &success);
if (!success) {
/* We do not flag a syntax error here because in an
ALTER TABLE we may also have DROP FOREIGN KEY abc */
- goto loop;
+ goto loop;
}
}
@@ -3110,31 +2950,31 @@ loop:
/* Scan the columns in the first list */
col_loop1:
ut_a(i < (sizeof column_names) / sizeof *column_names);
- ptr = dict_scan_col(ptr, &success, table, columns + i,
- heap, column_names + i);
+ ptr = dict_scan_col(cs, ptr, &success, table, columns + i,
+ heap, column_names + i);
if (!success) {
mutex_enter(&dict_foreign_err_mutex);
dict_foreign_error_report_low(ef, name);
fprintf(ef, "%s:\nCannot resolve column name close to:\n%s\n",
- start_of_latest_foreign, ptr);
+ start_of_latest_foreign, ptr);
mutex_exit(&dict_foreign_err_mutex);
return(DB_CANNOT_ADD_CONSTRAINT);
}
i++;
-
- ptr = dict_accept(ptr, ",", &success);
+
+ ptr = dict_accept(cs, ptr, ",", &success);
if (success) {
goto col_loop1;
}
-
- ptr = dict_accept(ptr, ")", &success);
+
+ ptr = dict_accept(cs, ptr, ")", &success);
if (!success) {
- dict_foreign_report_syntax_err(name, start_of_latest_foreign,
- ptr);
+ dict_foreign_report_syntax_err(
+ name, start_of_latest_foreign, ptr);
return(DB_CANNOT_ADD_CONSTRAINT);
}
@@ -3148,21 +2988,22 @@ col_loop1:
mutex_enter(&dict_foreign_err_mutex);
dict_foreign_error_report_low(ef, name);
fputs("There is no index in table ", ef);
- ut_print_name(ef, NULL, name);
+ ut_print_name(ef, NULL, TRUE, name);
fprintf(ef, " where the columns appear\n"
-"as the first columns. Constraint:\n%s\n"
-"See http://dev.mysql.com/doc/refman/5.0/en/innodb-foreign-key-constraints.html\n"
-"for correct foreign key definition.\n",
+ "as the first columns. Constraint:\n%s\n"
+ "See http://dev.mysql.com/doc/refman/5.1/en/"
+ "innodb-foreign-key-constraints.html\n"
+ "for correct foreign key definition.\n",
start_of_latest_foreign);
mutex_exit(&dict_foreign_err_mutex);
return(DB_CANNOT_ADD_CONSTRAINT);
}
- ptr = dict_accept(ptr, "REFERENCES", &success);
+ ptr = dict_accept(cs, ptr, "REFERENCES", &success);
- if (!success || !ib_isspace(*ptr)) {
- dict_foreign_report_syntax_err(name, start_of_latest_foreign,
- ptr);
+ if (!success || !my_isspace(cs, *ptr)) {
+ dict_foreign_report_syntax_err(
+ name, start_of_latest_foreign, ptr);
return(DB_CANNOT_ADD_CONSTRAINT);
}
@@ -3171,7 +3012,7 @@ col_loop1:
foreign = dict_mem_foreign_create();
if (constraint_name) {
- ulint db_len;
+ ulint db_len;
/* Catenate 'databasename/' to the constraint name specified
by the user: we conceive the constraint as belonging to the
@@ -3180,8 +3021,8 @@ col_loop1:
db_len = dict_get_db_name_len(table->name);
- foreign->id = mem_heap_alloc(foreign->heap,
- db_len + strlen(constraint_name) + 2);
+ foreign->id = mem_heap_alloc(
+ foreign->heap, db_len + strlen(constraint_name) + 2);
ut_memcpy(foreign->id, table->name, db_len);
foreign->id[db_len] = '/';
@@ -3190,18 +3031,20 @@ col_loop1:
foreign->foreign_table = table;
foreign->foreign_table_name = mem_heap_strdup(foreign->heap,
- table->name);
+ table->name);
foreign->foreign_index = index;
- foreign->n_fields = i;
+ foreign->n_fields = (unsigned int) i;
foreign->foreign_col_names = mem_heap_alloc(foreign->heap,
- i * sizeof(void*));
+ i * sizeof(void*));
for (i = 0; i < foreign->n_fields; i++) {
- foreign->foreign_col_names[i] =
- mem_heap_strdup(foreign->heap, columns[i]->name);
+ foreign->foreign_col_names[i] = mem_heap_strdup(
+ foreign->heap,
+ dict_table_get_col_name(table,
+ dict_col_get_no(columns[i])));
}
-
- ptr = dict_scan_table_name(ptr, &referenced_table, name,
- &success, heap, &referenced_table_name);
+
+ ptr = dict_scan_table_name(cs, ptr, &referenced_table, name,
+ &success, heap, &referenced_table_name);
/* Note that referenced_table can be NULL if the user has suppressed
checking of foreign key constraints! */
@@ -3218,13 +3061,13 @@ col_loop1:
return(DB_CANNOT_ADD_CONSTRAINT);
}
-
- ptr = dict_accept(ptr, "(", &success);
+
+ ptr = dict_accept(cs, ptr, "(", &success);
if (!success) {
dict_foreign_free(foreign);
dict_foreign_report_syntax_err(name, start_of_latest_foreign,
- ptr);
+ ptr);
return(DB_CANNOT_ADD_CONSTRAINT);
}
@@ -3232,10 +3075,10 @@ col_loop1:
i = 0;
col_loop2:
- ptr = dict_scan_col(ptr, &success, referenced_table, columns + i,
- heap, column_names + i);
+ ptr = dict_scan_col(cs, ptr, &success, referenced_table, columns + i,
+ heap, column_names + i);
i++;
-
+
if (!success) {
dict_foreign_free(foreign);
@@ -3249,45 +3092,45 @@ col_loop2:
return(DB_CANNOT_ADD_CONSTRAINT);
}
- ptr = dict_accept(ptr, ",", &success);
+ ptr = dict_accept(cs, ptr, ",", &success);
if (success) {
goto col_loop2;
}
-
- ptr = dict_accept(ptr, ")", &success);
+
+ ptr = dict_accept(cs, ptr, ")", &success);
if (!success || foreign->n_fields != i) {
dict_foreign_free(foreign);
-
+
dict_foreign_report_syntax_err(name, start_of_latest_foreign,
- ptr);
+ ptr);
return(DB_CANNOT_ADD_CONSTRAINT);
}
n_on_deletes = 0;
n_on_updates = 0;
-
+
scan_on_conditions:
/* Loop here as long as we can find ON ... conditions */
- ptr = dict_accept(ptr, "ON", &success);
+ ptr = dict_accept(cs, ptr, "ON", &success);
if (!success) {
goto try_find_index;
}
- ptr = dict_accept(ptr, "DELETE", &success);
+ ptr = dict_accept(cs, ptr, "DELETE", &success);
if (!success) {
- ptr = dict_accept(ptr, "UPDATE", &success);
+ ptr = dict_accept(cs, ptr, "UPDATE", &success);
if (!success) {
dict_foreign_free(foreign);
-
- dict_foreign_report_syntax_err(name,
- start_of_latest_foreign, ptr);
+
+ dict_foreign_report_syntax_err(
+ name, start_of_latest_foreign, ptr);
return(DB_CANNOT_ADD_CONSTRAINT);
}
@@ -3298,13 +3141,13 @@ scan_on_conditions:
n_on_deletes++;
}
- ptr = dict_accept(ptr, "RESTRICT", &success);
+ ptr = dict_accept(cs, ptr, "RESTRICT", &success);
if (success) {
goto scan_on_conditions;
}
- ptr = dict_accept(ptr, "CASCADE", &success);
+ ptr = dict_accept(cs, ptr, "CASCADE", &success);
if (success) {
if (is_on_delete) {
@@ -3316,16 +3159,16 @@ scan_on_conditions:
goto scan_on_conditions;
}
- ptr = dict_accept(ptr, "NO", &success);
+ ptr = dict_accept(cs, ptr, "NO", &success);
if (success) {
- ptr = dict_accept(ptr, "ACTION", &success);
+ ptr = dict_accept(cs, ptr, "ACTION", &success);
if (!success) {
dict_foreign_free(foreign);
- dict_foreign_report_syntax_err(name,
- start_of_latest_foreign, ptr);
-
+ dict_foreign_report_syntax_err(
+ name, start_of_latest_foreign, ptr);
+
return(DB_CANNOT_ADD_CONSTRAINT);
}
@@ -3338,28 +3181,27 @@ scan_on_conditions:
goto scan_on_conditions;
}
- ptr = dict_accept(ptr, "SET", &success);
+ ptr = dict_accept(cs, ptr, "SET", &success);
if (!success) {
dict_foreign_free(foreign);
dict_foreign_report_syntax_err(name, start_of_latest_foreign,
- ptr);
+ ptr);
return(DB_CANNOT_ADD_CONSTRAINT);
}
- ptr = dict_accept(ptr, "NULL", &success);
+ ptr = dict_accept(cs, ptr, "NULL", &success);
if (!success) {
dict_foreign_free(foreign);
dict_foreign_report_syntax_err(name, start_of_latest_foreign,
- ptr);
+ ptr);
return(DB_CANNOT_ADD_CONSTRAINT);
}
for (j = 0; j < foreign->n_fields; j++) {
- if ((dict_index_get_nth_type(
- foreign->foreign_index, j)->prtype)
- & DATA_NOT_NULL) {
+ if ((dict_index_get_nth_col(foreign->foreign_index, j)->prtype)
+ & DATA_NOT_NULL) {
/* It is not sensible to define SET NULL
if the column is not allowed to be NULL! */
@@ -3369,8 +3211,10 @@ scan_on_conditions:
mutex_enter(&dict_foreign_err_mutex);
dict_foreign_error_report_low(ef, name);
fprintf(ef, "%s:\n"
- "You have defined a SET NULL condition though some of the\n"
- "columns are defined as NOT NULL.\n", start_of_latest_foreign);
+ "You have defined a SET NULL condition"
+ " though some of the\n"
+ "columns are defined as NOT NULL.\n",
+ start_of_latest_foreign);
mutex_exit(&dict_foreign_err_mutex);
return(DB_CANNOT_ADD_CONSTRAINT);
@@ -3382,19 +3226,20 @@ scan_on_conditions:
} else {
foreign->type |= DICT_FOREIGN_ON_UPDATE_SET_NULL;
}
-
+
goto scan_on_conditions;
try_find_index:
if (n_on_deletes > 1 || n_on_updates > 1) {
/* It is an error to define more than 1 action */
-
+
dict_foreign_free(foreign);
mutex_enter(&dict_foreign_err_mutex);
dict_foreign_error_report_low(ef, name);
fprintf(ef, "%s:\n"
-"You have twice an ON DELETE clause or twice an ON UPDATE clause.\n",
+ "You have twice an ON DELETE clause"
+ " or twice an ON UPDATE clause.\n",
start_of_latest_foreign);
mutex_exit(&dict_foreign_err_mutex);
@@ -3407,20 +3252,29 @@ try_find_index:
if (referenced_table) {
index = dict_foreign_find_index(referenced_table,
- column_names, i, foreign->foreign_index, TRUE, FALSE);
+ column_names, i,
+ foreign->foreign_index,
+ TRUE, FALSE);
if (!index) {
dict_foreign_free(foreign);
mutex_enter(&dict_foreign_err_mutex);
dict_foreign_error_report_low(ef, name);
fprintf(ef, "%s:\n"
-"Cannot find an index in the referenced table where the\n"
-"referenced columns appear as the first columns, or column types\n"
-"in the table and the referenced table do not match for constraint.\n"
-"Note that the internal storage type of ENUM and SET changed in\n"
-"tables created with >= InnoDB-4.1.12, and such columns in old tables\n"
-"cannot be referenced by such columns in new tables.\n"
-"See http://dev.mysql.com/doc/refman/5.0/en/innodb-foreign-key-constraints.html\n"
-"for correct foreign key definition.\n",
+ "Cannot find an index in the"
+ " referenced table where the\n"
+ "referenced columns appear as the"
+ " first columns, or column types\n"
+ "in the table and the referenced table"
+ " do not match for constraint.\n"
+ "Note that the internal storage type of"
+ " ENUM and SET changed in\n"
+ "tables created with >= InnoDB-4.1.12,"
+ " and such columns in old tables\n"
+ "cannot be referenced by such columns"
+ " in new tables.\n"
+ "See http://dev.mysql.com/doc/refman/5.1/en/"
+ "innodb-foreign-key-constraints.html\n"
+ "for correct foreign key definition.\n",
start_of_latest_foreign);
mutex_exit(&dict_foreign_err_mutex);
@@ -3434,29 +3288,48 @@ try_find_index:
foreign->referenced_index = index;
foreign->referenced_table = referenced_table;
- foreign->referenced_table_name = mem_heap_strdup(foreign->heap,
- referenced_table_name);
-
+ foreign->referenced_table_name
+ = mem_heap_strdup(foreign->heap, referenced_table_name);
+
foreign->referenced_col_names = mem_heap_alloc(foreign->heap,
- i * sizeof(void*));
+ i * sizeof(void*));
for (i = 0; i < foreign->n_fields; i++) {
foreign->referenced_col_names[i]
= mem_heap_strdup(foreign->heap, column_names[i]);
}
/* We found an ok constraint definition: add to the lists */
-
+
UT_LIST_ADD_LAST(foreign_list, table->foreign_list, foreign);
if (referenced_table) {
UT_LIST_ADD_LAST(referenced_list,
- referenced_table->referenced_list,
- foreign);
+ referenced_table->referenced_list,
+ foreign);
}
goto loop;
}
+/**************************************************************************
+Determines whether a string starts with the specified keyword. */
+
+ibool
+dict_str_starts_with_keyword(
+/*=========================*/
+ /* out: TRUE if str starts
+ with keyword */
+ void* mysql_thd, /* in: MySQL thread handle */
+ const char* str, /* in: string to scan for keyword */
+ const char* keyword) /* in: keyword to look for */
+{
+ struct charset_info_st* cs = innobase_get_charset(mysql_thd);
+ ibool success;
+
+ dict_accept(cs, str, keyword, &success);
+ return(success);
+}
+
/*************************************************************************
Scans a table create SQL string and adds to the data dictionary the foreign
key constraints declared in the string. This function should be called after
@@ -3484,20 +3357,23 @@ dict_create_foreign_constraints(
code DB_CANNOT_ADD_CONSTRAINT if
any foreign keys are found. */
{
- char* str;
- ulint err;
- mem_heap_t* heap;
+ char* str;
+ ulint err;
+ mem_heap_t* heap;
+
+ ut_a(trx && trx->mysql_thd);
str = dict_strip_comments(sql_string);
heap = mem_heap_create(10000);
- err = dict_create_foreign_constraints_low(trx, heap, str, name,
+ err = dict_create_foreign_constraints_low(
+ trx, heap, innobase_get_charset(trx->mysql_thd), str, name,
reject_fks);
mem_heap_free(heap);
mem_free(str);
- return(err);
+ return(err);
}
/**************************************************************************
@@ -3519,13 +3395,18 @@ dict_foreign_parse_drop_constraints(
const char*** constraints_to_drop) /* out: id's of the
constraints to drop */
{
- dict_foreign_t* foreign;
- ibool success;
- char* str;
- const char* ptr;
- const char* id;
- FILE* ef = dict_foreign_err_file;
-
+ dict_foreign_t* foreign;
+ ibool success;
+ char* str;
+ const char* ptr;
+ const char* id;
+ FILE* ef = dict_foreign_err_file;
+ struct charset_info_st* cs;
+
+ ut_a(trx && trx->mysql_thd);
+
+ cs = innobase_get_charset(trx->mysql_thd);
+
*n = 0;
*constraints_to_drop = mem_heap_alloc(heap, 1000 * sizeof(char*));
@@ -3533,40 +3414,38 @@ dict_foreign_parse_drop_constraints(
str = dict_strip_comments(*(trx->mysql_query_str));
ptr = str;
-#ifdef UNIV_SYNC_DEBUG
ut_ad(mutex_own(&(dict_sys->mutex)));
-#endif /* UNIV_SYNC_DEBUG */
loop:
ptr = dict_scan_to(ptr, "DROP");
if (*ptr == '\0') {
mem_free(str);
-
+
return(DB_SUCCESS);
}
- ptr = dict_accept(ptr, "DROP", &success);
+ ptr = dict_accept(cs, ptr, "DROP", &success);
- if (!ib_isspace(*ptr)) {
+ if (!my_isspace(cs, *ptr)) {
- goto loop;
+ goto loop;
}
- ptr = dict_accept(ptr, "FOREIGN", &success);
-
+ ptr = dict_accept(cs, ptr, "FOREIGN", &success);
+
if (!success) {
- goto loop;
+ goto loop;
}
- ptr = dict_accept(ptr, "KEY", &success);
+ ptr = dict_accept(cs, ptr, "KEY", &success);
if (!success) {
goto syntax_error;
}
- ptr = dict_scan_id(ptr, heap, &id, TRUE);
+ ptr = dict_scan_id(cs, ptr, heap, &id, FALSE, TRUE);
if (id == NULL) {
@@ -3576,7 +3455,7 @@ loop:
ut_a(*n < 1000);
(*constraints_to_drop)[*n] = id;
(*n)++;
-
+
/* Look for the given constraint id */
foreign = UT_LIST_GET_FIRST(table->foreign_list);
@@ -3585,11 +3464,11 @@ loop:
if (0 == strcmp(foreign->id, id)
|| (strchr(foreign->id, '/')
&& 0 == strcmp(id,
- dict_remove_db_name(foreign->id)))) {
+ dict_remove_db_name(foreign->id)))) {
/* Found */
break;
}
-
+
foreign = UT_LIST_GET_NEXT(foreign_list, foreign);
}
@@ -3597,14 +3476,14 @@ loop:
mutex_enter(&dict_foreign_err_mutex);
rewind(ef);
ut_print_timestamp(ef);
- fputs(
- " Error in dropping of a foreign key constraint of table ", ef);
- ut_print_name(ef, NULL, table->name);
+ fputs(" Error in dropping of a foreign key constraint"
+ " of table ", ef);
+ ut_print_name(ef, NULL, TRUE, table->name);
fputs(",\n"
- "in SQL command\n", ef);
+ "in SQL command\n", ef);
fputs(str, ef);
fputs("\nCannot find a constraint with the given id ", ef);
- ut_print_name(ef, NULL, id);
+ ut_print_name(ef, NULL, FALSE, id);
fputs(".\n", ef);
mutex_exit(&dict_foreign_err_mutex);
@@ -3613,15 +3492,15 @@ loop:
return(DB_CANNOT_DROP_CONSTRAINT);
}
- goto loop;
+ goto loop;
syntax_error:
mutex_enter(&dict_foreign_err_mutex);
rewind(ef);
ut_print_timestamp(ef);
- fputs(
- " Syntax error in dropping of a foreign key constraint of table ", ef);
- ut_print_name(ef, NULL, table->name);
+ fputs(" Syntax error in dropping of a"
+ " foreign key constraint of table ", ef);
+ ut_print_name(ef, NULL, TRUE, table->name);
fprintf(ef, ",\n"
"close to:\n%s\n in SQL command\n%s\n", ptr, str);
mutex_exit(&dict_foreign_err_mutex);
@@ -3630,9 +3509,11 @@ syntax_error:
return(DB_CANNOT_DROP_CONSTRAINT);
}
+#endif /* UNIV_HOTBACKUP */
/*==================== END OF FOREIGN KEY PROCESSING ====================*/
+#ifdef UNIV_DEBUG
/**************************************************************************
Returns an index object if it is found in the dictionary cache. */
@@ -3642,7 +3523,6 @@ dict_index_get_if_in_cache(
/* out: index, NULL if not found */
dulint index_id) /* in: index id */
{
- dict_table_t* table;
dict_index_t* index;
if (dict_sys == NULL) {
@@ -3650,273 +3530,69 @@ dict_index_get_if_in_cache(
}
mutex_enter(&(dict_sys->mutex));
-
- table = UT_LIST_GET_FIRST(dict_sys->table_LRU);
- while (table) {
- index = UT_LIST_GET_FIRST(table->indexes);
+ index = dict_index_find_on_id_low(index_id);
- while (index) {
- if (0 == ut_dulint_cmp(index->id, index_id)) {
-
- goto found;
- }
-
- index = UT_LIST_GET_NEXT(indexes, index);
- }
-
- table = UT_LIST_GET_NEXT(table_LRU, table);
- }
-
- index = NULL;
-found:
mutex_exit(&(dict_sys->mutex));
return(index);
}
+#endif /* UNIV_DEBUG */
-/**************************************************************************
-Creates an index tree struct. */
-
-dict_tree_t*
-dict_tree_create(
-/*=============*/
- /* out, own: created tree */
- dict_index_t* index, /* in: the index for which to create: in the
- case of a mixed tree, this should be the
- index of the cluster object */
- ulint page_no)/* in: root page number of the index */
-{
- dict_tree_t* tree;
-
- tree = mem_alloc(sizeof(dict_tree_t));
-
- /* Inherit info from the index */
-
- tree->type = index->type;
- tree->space = index->space;
- tree->page = page_no;
-
- tree->id = index->id;
-
- UT_LIST_INIT(tree->tree_indexes);
-
- tree->magic_n = DICT_TREE_MAGIC_N;
-
- rw_lock_create(&(tree->lock));
-
- rw_lock_set_level(&(tree->lock), SYNC_INDEX_TREE);
-
- return(tree);
-}
-
-/**************************************************************************
-Frees an index tree struct. */
-
-void
-dict_tree_free(
-/*===========*/
- dict_tree_t* tree) /* in, own: index tree */
-{
- ut_a(tree);
- ut_ad(tree->magic_n == DICT_TREE_MAGIC_N);
-
- rw_lock_free(&(tree->lock));
- mem_free(tree);
-}
-
-/**************************************************************************
-In an index tree, finds the index corresponding to a record in the tree. */
-UNIV_INLINE
-dict_index_t*
-dict_tree_find_index_low(
-/*=====================*/
- /* out: index */
- dict_tree_t* tree, /* in: index tree */
- rec_t* rec) /* in: record for which to find correct
- index */
-{
- dict_index_t* index;
- dict_table_t* table;
- dulint mix_id;
- ulint len;
-
- index = UT_LIST_GET_FIRST(tree->tree_indexes);
- ut_ad(index);
- table = index->table;
-
- if ((index->type & DICT_CLUSTERED)
- && UNIV_UNLIKELY(table->type != DICT_TABLE_ORDINARY)) {
-
- /* Get the mix id of the record */
- ut_a(!table->comp);
-
- mix_id = mach_dulint_read_compressed(
- rec_get_nth_field_old(rec, table->mix_len, &len));
-
- while (ut_dulint_cmp(table->mix_id, mix_id) != 0) {
-
- index = UT_LIST_GET_NEXT(tree_indexes, index);
- table = index->table;
- ut_ad(index);
- }
- }
-
- return(index);
-}
-
-/**************************************************************************
-In an index tree, finds the index corresponding to a record in the tree. */
-
-dict_index_t*
-dict_tree_find_index(
-/*=================*/
- /* out: index */
- dict_tree_t* tree, /* in: index tree */
- rec_t* rec) /* in: record for which to find correct
- index */
-{
- dict_index_t* index;
-
- index = dict_tree_find_index_low(tree, rec);
-
- return(index);
-}
-
-/**************************************************************************
-In an index tree, finds the index corresponding to a dtuple which is used
-in a search to a tree. */
-
-dict_index_t*
-dict_tree_find_index_for_tuple(
-/*===========================*/
- /* out: index; NULL if the tuple does not
- contain the mix id field in a mixed tree */
- dict_tree_t* tree, /* in: index tree */
- dtuple_t* tuple) /* in: tuple for which to find index */
-{
- dict_index_t* index;
- dict_table_t* table;
- dulint mix_id;
-
- ut_ad(dtuple_check_typed(tuple));
-
- if (UT_LIST_GET_LEN(tree->tree_indexes) == 1) {
-
- return(UT_LIST_GET_FIRST(tree->tree_indexes));
- }
-
- index = UT_LIST_GET_FIRST(tree->tree_indexes);
- ut_ad(index);
- table = index->table;
-
- if (dtuple_get_n_fields(tuple) <= table->mix_len) {
-
- return(NULL);
- }
-
- /* Get the mix id of the record */
-
- mix_id = mach_dulint_read_compressed(
- dfield_get_data(
- dtuple_get_nth_field(tuple, table->mix_len)));
-
- while (ut_dulint_cmp(table->mix_id, mix_id) != 0) {
-
- index = UT_LIST_GET_NEXT(tree_indexes, index);
- table = index->table;
- ut_ad(index);
- }
-
- return(index);
-}
-
-/***********************************************************************
-Checks if a table which is a mixed cluster member owns a record. */
-
-ibool
-dict_is_mixed_table_rec(
-/*====================*/
- /* out: TRUE if the record belongs to this
- table */
- dict_table_t* table, /* in: table in a mixed cluster */
- rec_t* rec) /* in: user record in the clustered index */
-{
- byte* mix_id_field;
- ulint len;
-
- ut_ad(!table->comp);
-
- mix_id_field = rec_get_nth_field_old(rec,
- table->mix_len, &len);
-
- return(len == table->mix_id_len
- && !ut_memcmp(table->mix_id_buf, mix_id_field, len));
-}
-
+#ifdef UNIV_DEBUG
/**************************************************************************
Checks that a tuple has n_fields_cmp value in a sensible range, so that
no comparison can occur with the page number field in a node pointer. */
ibool
-dict_tree_check_search_tuple(
-/*=========================*/
+dict_index_check_search_tuple(
+/*==========================*/
/* out: TRUE if ok */
- dict_tree_t* tree, /* in: index tree */
+ dict_index_t* index, /* in: index tree */
dtuple_t* tuple) /* in: tuple used in a search */
{
- dict_index_t* index;
-
- index = dict_tree_find_index_for_tuple(tree, tuple);
-
- if (index == NULL) {
-
- return(TRUE);
- }
-
+ ut_a(index);
ut_a(dtuple_get_n_fields_cmp(tuple)
- <= dict_index_get_n_unique_in_tree(index));
+ <= dict_index_get_n_unique_in_tree(index));
return(TRUE);
}
+#endif /* UNIV_DEBUG */
/**************************************************************************
Builds a node pointer out of a physical record and a page number. */
dtuple_t*
-dict_tree_build_node_ptr(
-/*=====================*/
+dict_index_build_node_ptr(
+/*======================*/
/* out, own: node pointer */
- dict_tree_t* tree, /* in: index tree */
+ dict_index_t* index, /* in: index tree */
rec_t* rec, /* in: record for which to build node
pointer */
ulint page_no,/* in: page number to put in node pointer */
mem_heap_t* heap, /* in: memory heap where pointer created */
- ulint level) /* in: level of rec in tree: 0 means leaf
+ ulint level) /* in: level of rec in tree: 0 means leaf
level */
{
dtuple_t* tuple;
- dict_index_t* ind;
dfield_t* field;
byte* buf;
ulint n_unique;
- ind = dict_tree_find_index_low(tree, rec);
-
- if (UNIV_UNLIKELY(tree->type & DICT_UNIVERSAL)) {
+ if (UNIV_UNLIKELY(index->type & DICT_UNIVERSAL)) {
/* In a universal index tree, we take the whole record as
- the node pointer if the reord is on the leaf level,
+ the node pointer if the record is on the leaf level,
on non-leaf levels we remove the last field, which
contains the page number of the child page */
- ut_a(!ind->table->comp);
+ ut_a(!dict_table_is_comp(index->table));
n_unique = rec_get_n_fields_old(rec);
if (level > 0) {
- ut_a(n_unique > 1);
- n_unique--;
+ ut_a(n_unique > 1);
+ n_unique--;
}
- } else {
- n_unique = dict_index_get_n_unique_in_tree(ind);
+ } else {
+ n_unique = dict_index_get_n_unique_in_tree(index);
}
tuple = dtuple_create(heap, n_unique + 1);
@@ -3926,52 +3602,50 @@ dict_tree_build_node_ptr(
levels in the tree there may be identical node pointers with a
different page number; therefore, we set the n_fields_cmp to one
less: */
-
+
dtuple_set_n_fields_cmp(tuple, n_unique);
- dict_index_copy_types(tuple, ind, n_unique);
-
+ dict_index_copy_types(tuple, index, n_unique);
+
buf = mem_heap_alloc(heap, 4);
mach_write_to_4(buf, page_no);
-
+
field = dtuple_get_nth_field(tuple, n_unique);
dfield_set_data(field, buf, 4);
- dtype_set(dfield_get_type(field), DATA_SYS_CHILD, DATA_NOT_NULL, 4, 0);
+ dtype_set(dfield_get_type(field), DATA_SYS_CHILD, DATA_NOT_NULL, 4);
- rec_copy_prefix_to_dtuple(tuple, rec, ind, n_unique, heap);
- dtuple_set_info_bits(tuple, dtuple_get_info_bits(tuple) |
- REC_STATUS_NODE_PTR);
+ rec_copy_prefix_to_dtuple(tuple, rec, index, n_unique, heap);
+ dtuple_set_info_bits(tuple, dtuple_get_info_bits(tuple)
+ | REC_STATUS_NODE_PTR);
ut_ad(dtuple_check_typed(tuple));
return(tuple);
-}
-
+}
+
/**************************************************************************
Copies an initial segment of a physical record, long enough to specify an
index entry uniquely. */
rec_t*
-dict_tree_copy_rec_order_prefix(
-/*============================*/
+dict_index_copy_rec_order_prefix(
+/*=============================*/
/* out: pointer to the prefix record */
- dict_tree_t* tree, /* in: index tree */
+ dict_index_t* index, /* in: index tree */
rec_t* rec, /* in: record for which to copy prefix */
ulint* n_fields,/* out: number of fields copied */
byte** buf, /* in/out: memory buffer for the copied prefix,
or NULL */
ulint* buf_size)/* in/out: buffer size */
{
- dict_index_t* index;
ulint n;
UNIV_PREFETCH_R(rec);
- index = dict_tree_find_index_low(tree, rec);
- if (UNIV_UNLIKELY(tree->type & DICT_UNIVERSAL)) {
- ut_a(!index->table->comp);
+ if (UNIV_UNLIKELY(index->type & DICT_UNIVERSAL)) {
+ ut_a(!dict_table_is_comp(index->table));
n = rec_get_n_fields_old(rec);
} else {
n = dict_index_get_n_unique_in_tree(index);
@@ -3985,32 +3659,30 @@ dict_tree_copy_rec_order_prefix(
Builds a typed data tuple out of a physical record. */
dtuple_t*
-dict_tree_build_data_tuple(
-/*=======================*/
+dict_index_build_data_tuple(
+/*========================*/
/* out, own: data tuple */
- dict_tree_t* tree, /* in: index tree */
+ dict_index_t* index, /* in: index tree */
rec_t* rec, /* in: record for which to build data tuple */
ulint n_fields,/* in: number of data fields */
mem_heap_t* heap) /* in: memory heap where tuple created */
{
dtuple_t* tuple;
- dict_index_t* ind;
- ind = dict_tree_find_index_low(tree, rec);
+ ut_ad(dict_table_is_comp(index->table)
+ || n_fields <= rec_get_n_fields_old(rec));
- ut_ad(ind->table->comp || n_fields <= rec_get_n_fields_old(rec));
-
- tuple = dtuple_create(heap, n_fields);
+ tuple = dtuple_create(heap, n_fields);
- dict_index_copy_types(tuple, ind, n_fields);
+ dict_index_copy_types(tuple, index, n_fields);
- rec_copy_prefix_to_dtuple(tuple, rec, ind, n_fields, heap);
+ rec_copy_prefix_to_dtuple(tuple, rec, index, n_fields, heap);
ut_ad(dtuple_check_typed(tuple));
return(tuple);
-}
-
+}
+
/*************************************************************************
Calculates the minimum record length in an index. */
@@ -4022,19 +3694,21 @@ dict_index_calc_min_rec_len(
ulint sum = 0;
ulint i;
- if (UNIV_LIKELY(index->table->comp)) {
+ if (dict_table_is_comp(index->table)) {
ulint nullable = 0;
sum = REC_N_NEW_EXTRA_BYTES;
for (i = 0; i < dict_index_get_n_fields(index); i++) {
- dtype_t*t = dict_index_get_nth_type(index, i);
- ulint size = dtype_get_fixed_size(t);
+ const dict_col_t* col
+ = dict_index_get_nth_col(index, i);
+ ulint size = dict_col_get_fixed_size(col);
sum += size;
if (!size) {
- size = dtype_get_len(t);
+ size = col->len;
sum += size < 128 ? 1 : 2;
}
- if (!(dtype_get_prtype(t) & DATA_NOT_NULL))
+ if (!(col->prtype & DATA_NOT_NULL)) {
nullable++;
+ }
}
/* round the NULL flags up to full bytes */
@@ -4044,7 +3718,8 @@ dict_index_calc_min_rec_len(
}
for (i = 0; i < dict_index_get_n_fields(index); i++) {
- sum += dtype_get_fixed_size(dict_index_get_nth_type(index, i));
+ sum += dict_col_get_fixed_size(
+ dict_index_get_nth_col(index, i));
}
if (sum > 127) {
@@ -4067,8 +3742,8 @@ dict_update_statistics_low(
/*=======================*/
dict_table_t* table, /* in: table */
ibool has_dict_mutex __attribute__((unused)))
- /* in: TRUE if the caller has the
- dictionary mutex */
+ /* in: TRUE if the caller has the
+ dictionary mutex */
{
dict_index_t* index;
ulint size;
@@ -4078,8 +3753,10 @@ dict_update_statistics_low(
ut_print_timestamp(stderr);
fprintf(stderr,
" InnoDB: cannot calculate statistics for table %s\n"
-"InnoDB: because the .ibd file is missing. For help, please refer to\n"
-"InnoDB: http://dev.mysql.com/doc/refman/5.0/en/innodb-troubleshooting.html\n",
+ "InnoDB: because the .ibd file is missing. For help,"
+ " please refer to\n"
+ "InnoDB: http://dev.mysql.com/doc/refman/5.1/en/"
+ "innodb-troubleshooting.html\n",
table->name);
return;
@@ -4096,11 +3773,11 @@ dict_update_statistics_low(
/* Find out the sizes of the indexes and how many different values
for the key they approximately have */
- index = dict_table_get_first_index(table);
+ index = dict_table_get_first_index(table);
if (index == NULL) {
/* Table definition is corrupt */
-
+
return;
}
@@ -4119,7 +3796,7 @@ dict_update_statistics_low(
}
index->stat_n_leaf_pages = size;
-
+
btr_estimate_number_of_different_key_vals(index);
index = dict_table_get_next_index(index);
@@ -4128,16 +3805,16 @@ dict_update_statistics_low(
index = dict_table_get_first_index(table);
table->stat_n_rows = index->stat_n_diff_key_vals[
- dict_index_get_n_unique(index)];
+ dict_index_get_n_unique(index)];
table->stat_clustered_index_size = index->stat_index_size;
table->stat_sum_of_other_index_sizes = sum_of_index_sizes
- - index->stat_index_size;
+ - index->stat_index_size;
table->stat_initialized = TRUE;
- table->stat_modified_counter = 0;
+ table->stat_modified_counter = 0;
}
/*************************************************************************
@@ -4153,6 +3830,18 @@ dict_update_statistics(
}
/**************************************************************************
+A noninlined version of dict_table_get_low. */
+
+dict_table_t*
+dict_table_get_low_noninlined(
+/*==========================*/
+ /* out: table, NULL if not found */
+ const char* table_name) /* in: table name */
+{
+ return(dict_table_get_low(table_name));
+}
+
+/**************************************************************************
Prints info of a foreign key constraint. */
static
void
@@ -4162,9 +3851,7 @@ dict_foreign_print_low(
{
ulint i;
-#ifdef UNIV_SYNC_DEBUG
ut_ad(mutex_own(&(dict_sys->mutex)));
-#endif /* UNIV_SYNC_DEBUG */
fprintf(stderr, " FOREIGN KEY CONSTRAINT %s: %s (",
foreign->id, foreign->foreign_table_name);
@@ -4176,7 +3863,7 @@ dict_foreign_print_low(
fprintf(stderr, " )\n"
" REFERENCES %s (",
foreign->referenced_table_name);
-
+
for (i = 0; i < foreign->n_fields; i++) {
fprintf(stderr, " %s", foreign->referenced_col_names[i]);
}
@@ -4212,7 +3899,7 @@ dict_table_print_by_name(
table = dict_table_get_low(name);
ut_a(table);
-
+
dict_table_print_low(table);
mutex_exit(&(dict_sys->mutex));
}
@@ -4229,25 +3916,24 @@ dict_table_print_low(
dict_foreign_t* foreign;
ulint i;
-#ifdef UNIV_SYNC_DEBUG
ut_ad(mutex_own(&(dict_sys->mutex)));
-#endif /* UNIV_SYNC_DEBUG */
dict_update_statistics_low(table, TRUE);
-
+
fprintf(stderr,
-"--------------------------------------\n"
-"TABLE: name %s, id %lu %lu, columns %lu, indexes %lu, appr.rows %lu\n"
-" COLUMNS: ",
- table->name,
- (ulong) ut_dulint_get_high(table->id),
- (ulong) ut_dulint_get_low(table->id),
- (ulong) table->n_cols,
- (ulong) UT_LIST_GET_LEN(table->indexes),
- (ulong) table->stat_n_rows);
+ "--------------------------------------\n"
+ "TABLE: name %s, id %lu %lu, columns %lu, indexes %lu,"
+ " appr.rows %lu\n"
+ " COLUMNS: ",
+ table->name,
+ (ulong) ut_dulint_get_high(table->id),
+ (ulong) ut_dulint_get_low(table->id),
+ (ulong) table->n_cols,
+ (ulong) UT_LIST_GET_LEN(table->indexes),
+ (ulong) table->stat_n_rows);
- for (i = 0; i < table->n_cols - 1; i++) {
- dict_col_print_low(dict_table_get_nth_col(table, i));
+ for (i = 0; i + 1 < (ulint) table->n_cols; i++) {
+ dict_col_print_low(table, dict_table_get_nth_col(table, i));
fputs("; ", stderr);
}
@@ -4281,18 +3967,18 @@ static
void
dict_col_print_low(
/*===============*/
- dict_col_t* col) /* in: column */
+ const dict_table_t* table, /* in: table */
+ const dict_col_t* col) /* in: column */
{
- dtype_t* type;
+ dtype_t type;
-#ifdef UNIV_SYNC_DEBUG
ut_ad(mutex_own(&(dict_sys->mutex)));
-#endif /* UNIV_SYNC_DEBUG */
- type = dict_col_get_type(col);
- fprintf(stderr, "%s: ", col->name);
+ dict_col_copy_type(col, &type);
+ fprintf(stderr, "%s: ", dict_table_get_col_name(table,
+ dict_col_get_no(col)));
- dtype_print(type);
+ dtype_print(&type);
}
/**************************************************************************
@@ -4303,38 +3989,36 @@ dict_index_print_low(
/*=================*/
dict_index_t* index) /* in: index */
{
- dict_tree_t* tree;
ib_longlong n_vals;
ulint i;
-#ifdef UNIV_SYNC_DEBUG
ut_ad(mutex_own(&(dict_sys->mutex)));
-#endif /* UNIV_SYNC_DEBUG */
-
- tree = index->tree;
if (index->n_user_defined_cols > 0) {
n_vals = index->stat_n_diff_key_vals[
- index->n_user_defined_cols];
+ index->n_user_defined_cols];
} else {
n_vals = index->stat_n_diff_key_vals[1];
}
fprintf(stderr,
- " INDEX: name %s, id %lu %lu, fields %lu/%lu, type %lu\n"
+ " INDEX: name %s, id %lu %lu, fields %lu/%lu,"
+ " uniq %lu, type %lu\n"
" root page %lu, appr.key vals %lu,"
" leaf pages %lu, size pages %lu\n"
" FIELDS: ",
index->name,
- (ulong) ut_dulint_get_high(tree->id),
- (ulong) ut_dulint_get_low(tree->id),
+ (ulong) ut_dulint_get_high(index->id),
+ (ulong) ut_dulint_get_low(index->id),
(ulong) index->n_user_defined_cols,
- (ulong) index->n_fields, (ulong) index->type,
- (ulong) tree->page,
+ (ulong) index->n_fields,
+ (ulong) index->n_uniq,
+ (ulong) index->type,
+ (ulong) index->page,
(ulong) n_vals,
(ulong) index->stat_n_leaf_pages,
(ulong) index->stat_index_size);
-
+
for (i = 0; i < index->n_fields; i++) {
dict_field_print_low(dict_index_get_nth_field(index, i));
}
@@ -4342,9 +4026,9 @@ dict_index_print_low(
putc('\n', stderr);
#ifdef UNIV_BTR_PRINT
- btr_print_size(tree);
+ btr_print_size(index);
- btr_print_tree(tree, 7);
+ btr_print_index(index, 7);
#endif /* UNIV_BTR_PRINT */
}
@@ -4356,9 +4040,8 @@ dict_field_print_low(
/*=================*/
dict_field_t* field) /* in: field */
{
-#ifdef UNIV_SYNC_DEBUG
ut_ad(mutex_own(&(dict_sys->mutex)));
-#endif /* UNIV_SYNC_DEBUG */
+
fprintf(stderr, " %s", field->name);
if (field->prefix_len != 0) {
@@ -4380,33 +4063,33 @@ dict_print_info_on_foreign_key_in_create
{
const char* stripped_id;
ulint i;
-
+
if (strchr(foreign->id, '/')) {
/* Strip the preceding database name from the constraint id */
stripped_id = foreign->id + 1
- + dict_get_db_name_len(foreign->id);
+ + dict_get_db_name_len(foreign->id);
} else {
stripped_id = foreign->id;
}
putc(',', file);
-
+
if (add_newline) {
/* SHOW CREATE TABLE wants constraints each printed nicely
on its own line, while error messages want no newlines
inserted. */
fputs("\n ", file);
}
-
+
fputs(" CONSTRAINT ", file);
- ut_print_name(file, trx, stripped_id);
+ ut_print_name(file, trx, FALSE, stripped_id);
fputs(" FOREIGN KEY (", file);
for (i = 0;;) {
- ut_print_name(file, trx, foreign->foreign_col_names[i]);
+ ut_print_name(file, trx, FALSE, foreign->foreign_col_names[i]);
if (++i < foreign->n_fields) {
fputs(", ", file);
- } else {
+ } else {
break;
}
}
@@ -4414,29 +4097,22 @@ dict_print_info_on_foreign_key_in_create
fputs(") REFERENCES ", file);
if (dict_tables_have_same_db(foreign->foreign_table_name,
- foreign->referenced_table_name)) {
+ foreign->referenced_table_name)) {
/* Do not print the database name of the referenced table */
- ut_print_name(file, trx, dict_remove_db_name(
- foreign->referenced_table_name));
+ ut_print_name(file, trx, TRUE,
+ dict_remove_db_name(
+ foreign->referenced_table_name));
} else {
- /* Look for the '/' in the table name */
-
- i = 0;
- while (foreign->referenced_table_name[i] != '/') {
- i++;
- }
-
- ut_print_namel(file, trx, foreign->referenced_table_name, i);
- putc('.', file);
- ut_print_name(file, trx,
- foreign->referenced_table_name + i + 1);
+ ut_print_name(file, trx, TRUE,
+ foreign->referenced_table_name);
}
putc(' ', file);
putc('(', file);
for (i = 0;;) {
- ut_print_name(file, trx, foreign->referenced_col_names[i]);
+ ut_print_name(file, trx, FALSE,
+ foreign->referenced_col_names[i]);
if (++i < foreign->n_fields) {
fputs(", ", file);
} else {
@@ -4449,7 +4125,7 @@ dict_print_info_on_foreign_key_in_create
if (foreign->type & DICT_FOREIGN_ON_DELETE_CASCADE) {
fputs(" ON DELETE CASCADE", file);
}
-
+
if (foreign->type & DICT_FOREIGN_ON_DELETE_SET_NULL) {
fputs(" ON DELETE SET NULL", file);
}
@@ -4461,7 +4137,7 @@ dict_print_info_on_foreign_key_in_create
if (foreign->type & DICT_FOREIGN_ON_UPDATE_CASCADE) {
fputs(" ON UPDATE CASCADE", file);
}
-
+
if (foreign->type & DICT_FOREIGN_ON_UPDATE_SET_NULL) {
fputs(" ON UPDATE SET NULL", file);
}
@@ -4500,7 +4176,7 @@ dict_print_info_on_foreign_keys(
while (foreign != NULL) {
if (create_table_format) {
dict_print_info_on_foreign_key_in_create_format(
- file, trx, foreign, TRUE);
+ file, trx, foreign, TRUE);
} else {
ulint i;
fputs("; (", file);
@@ -4510,20 +4186,21 @@ dict_print_info_on_foreign_keys(
putc(' ', file);
}
- ut_print_name(file, trx,
- foreign->foreign_col_names[i]);
+ ut_print_name(file, trx, FALSE,
+ foreign->foreign_col_names[i]);
}
fputs(") REFER ", file);
- ut_print_name(file, trx,
- foreign->referenced_table_name);
+ ut_print_name(file, trx, TRUE,
+ foreign->referenced_table_name);
putc('(', file);
for (i = 0; i < foreign->n_fields; i++) {
if (i) {
putc(' ', file);
}
- ut_print_name(file, trx,
+ ut_print_name(
+ file, trx, FALSE,
foreign->referenced_col_names[i]);
}
@@ -4532,7 +4209,7 @@ dict_print_info_on_foreign_keys(
if (foreign->type == DICT_FOREIGN_ON_DELETE_CASCADE) {
fputs(" ON DELETE CASCADE", file);
}
-
+
if (foreign->type == DICT_FOREIGN_ON_DELETE_SET_NULL) {
fputs(" ON DELETE SET NULL", file);
}
@@ -4544,7 +4221,7 @@ dict_print_info_on_foreign_keys(
if (foreign->type & DICT_FOREIGN_ON_UPDATE_CASCADE) {
fputs(" ON UPDATE CASCADE", file);
}
-
+
if (foreign->type & DICT_FOREIGN_ON_UPDATE_SET_NULL) {
fputs(" ON UPDATE SET NULL", file);
}
@@ -4570,7 +4247,7 @@ dict_index_name_print(
const dict_index_t* index) /* in: index to print */
{
fputs("index ", file);
- ut_print_name(file, trx, index->name);
+ ut_print_name(file, trx, FALSE, index->name);
fputs(" of table ", file);
- ut_print_name(file, trx, index->table_name);
+ ut_print_name(file, trx, TRUE, index->table_name);
}
--- 1.103.15.1/innobase/os/os0file.c 2007-03-28 16:21:24 -06:00
+++ 1.127/storage/innobase/os/os0file.c 2007-03-28 17:08:03 -06:00
@@ -93,7 +93,7 @@ struct os_aio_slot_struct{
which pending aio operation was
completed */
#ifdef WIN_ASYNC_IO
- os_event_t event; /* event object we need in the
+ os_event_t event; /* event object we need in the
OVERLAPPED struct */
OVERLAPPED control; /* Windows control block for the
aio request */
@@ -121,9 +121,9 @@ struct os_aio_array_struct{
separately for any one of the segments. */
ulint n_reserved;/* Number of reserved slots in the
aio array outside the ibuf segment */
- os_aio_slot_t* slots; /* Pointer to the slots in the array */
+ os_aio_slot_t* slots; /* Pointer to the slots in the array */
#ifdef __WIN__
- os_native_event_t* native_events;
+ os_native_event_t* native_events;
/* Pointer to an array of OS native event
handles where we copied the handles from
slots, in the same order. This can be used
@@ -173,33 +173,33 @@ Gets the operating system version. Curre
ulint
os_get_os_version(void)
/*===================*/
- /* out: OS_WIN95, OS_WIN31, OS_WINNT, OS_WIN2000 */
+ /* out: OS_WIN95, OS_WIN31, OS_WINNT, OS_WIN2000 */
{
#ifdef __WIN__
- OSVERSIONINFO os_info;
+ OSVERSIONINFO os_info;
- os_info.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
+ os_info.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
ut_a(GetVersionEx(&os_info));
- if (os_info.dwPlatformId == VER_PLATFORM_WIN32s) {
- return(OS_WIN31);
- } else if (os_info.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS) {
- return(OS_WIN95);
- } else if (os_info.dwPlatformId == VER_PLATFORM_WIN32_NT) {
+ if (os_info.dwPlatformId == VER_PLATFORM_WIN32s) {
+ return(OS_WIN31);
+ } else if (os_info.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS) {
+ return(OS_WIN95);
+ } else if (os_info.dwPlatformId == VER_PLATFORM_WIN32_NT) {
if (os_info.dwMajorVersion <= 4) {
- return(OS_WINNT);
- } else {
+ return(OS_WINNT);
+ } else {
return(OS_WIN2000);
- }
- } else {
- ut_error;
- return(0);
- }
+ }
+ } else {
+ ut_error;
+ return(0);
+ }
#else
- ut_error;
+ ut_error;
- return(0);
+ return(0);
#endif
}
@@ -227,28 +227,36 @@ os_file_get_last_error(
|| (err != ERROR_DISK_FULL && err != ERROR_FILE_EXISTS)) {
ut_print_timestamp(stderr);
- fprintf(stderr,
- " InnoDB: Operating system error number %lu in a file operation.\n", (ulong) err);
+ fprintf(stderr,
+ " InnoDB: Operating system error number %lu"
+ " in a file operation.\n", (ulong) err);
if (err == ERROR_PATH_NOT_FOUND) {
fprintf(stderr,
- "InnoDB: The error means the system cannot find the path specified.\n");
+ "InnoDB: The error means the system"
+ " cannot find the path specified.\n");
if (srv_is_being_started) {
fprintf(stderr,
- "InnoDB: If you are installing InnoDB, remember that you must create\n"
- "InnoDB: directories yourself, InnoDB does not create them.\n");
+ "InnoDB: If you are installing InnoDB,"
+ " remember that you must create\n"
+ "InnoDB: directories yourself, InnoDB"
+ " does not create them.\n");
}
} else if (err == ERROR_ACCESS_DENIED) {
fprintf(stderr,
- "InnoDB: The error means mysqld does not have the access rights to\n"
- "InnoDB: the directory. It may also be you have created a subdirectory\n"
- "InnoDB: of the same name as a data file.\n");
+ "InnoDB: The error means mysqld does not have"
+ " the access rights to\n"
+ "InnoDB: the directory. It may also be"
+ " you have created a subdirectory\n"
+ "InnoDB: of the same name as a data file.\n");
} else {
fprintf(stderr,
- "InnoDB: Some operating system error numbers are described at\n"
- "InnoDB: "
- "http://dev.mysql.com/doc/refman/5.0/en/operating-system-error-codes.html\n");
+ "InnoDB: Some operating system error numbers"
+ " are described at\n"
+ "InnoDB: "
+ "http://dev.mysql.com/doc/refman/5.1/en/"
+ "operating-system-error-codes.html\n");
}
}
@@ -270,32 +278,41 @@ os_file_get_last_error(
|| (err != ENOSPC && err != EEXIST)) {
ut_print_timestamp(stderr);
- fprintf(stderr,
- " InnoDB: Operating system error number %lu in a file operation.\n", (ulong) err);
+ fprintf(stderr,
+ " InnoDB: Operating system error number %lu"
+ " in a file operation.\n", (ulong) err);
if (err == ENOENT) {
fprintf(stderr,
- "InnoDB: The error means the system cannot find the path specified.\n");
-
+ "InnoDB: The error means the system"
+ " cannot find the path specified.\n");
+
if (srv_is_being_started) {
fprintf(stderr,
- "InnoDB: If you are installing InnoDB, remember that you must create\n"
- "InnoDB: directories yourself, InnoDB does not create them.\n");
+ "InnoDB: If you are installing InnoDB,"
+ " remember that you must create\n"
+ "InnoDB: directories yourself, InnoDB"
+ " does not create them.\n");
}
} else if (err == EACCES) {
fprintf(stderr,
- "InnoDB: The error means mysqld does not have the access rights to\n"
- "InnoDB: the directory.\n");
+ "InnoDB: The error means mysqld does not have"
+ " the access rights to\n"
+ "InnoDB: the directory.\n");
} else {
if (strerror((int)err) != NULL) {
fprintf(stderr,
- "InnoDB: Error number %lu means '%s'.\n", err, strerror((int)err));
+ "InnoDB: Error number %lu"
+ " means '%s'.\n",
+ err, strerror((int)err));
}
fprintf(stderr,
- "InnoDB: Some operating system error numbers are described at\n"
- "InnoDB: "
- "http://dev.mysql.com/doc/refman/5.0/en/operating-system-error-codes.html\n");
+ "InnoDB: Some operating system"
+ " error numbers are described at\n"
+ "InnoDB: "
+ "http://dev.mysql.com/doc/refman/5.1/en/"
+ "operating-system-error-codes.html\n");
}
}
@@ -333,7 +350,7 @@ os_file_handle_error(
ulint err;
err = os_file_get_last_error(FALSE);
-
+
if (err == OS_FILE_DISK_FULL) {
/* We only print a warning about disk full once */
@@ -341,16 +358,18 @@ os_file_handle_error(
return(FALSE);
}
-
+
if (name) {
ut_print_timestamp(stderr);
fprintf(stderr,
- " InnoDB: Encountered a problem with file %s\n", name);
+ " InnoDB: Encountered a problem with"
+ " file %s\n", name);
}
ut_print_timestamp(stderr);
- fprintf(stderr,
- " InnoDB: Disk is full. Try to clean the disk to free space.\n");
+ fprintf(stderr,
+ " InnoDB: Disk is full. Try to clean the disk"
+ " to free space.\n");
os_has_said_disk_full = TRUE;
@@ -363,16 +382,16 @@ os_file_handle_error(
return(TRUE);
} else if (err == OS_FILE_ALREADY_EXISTS
- || err == OS_FILE_PATH_ERROR) {
+ || err == OS_FILE_PATH_ERROR) {
return(FALSE);
} else {
- if (name) {
- fprintf(stderr, "InnoDB: File name %s\n", name);
- }
-
+ if (name) {
+ fprintf(stderr, "InnoDB: File name %s\n", name);
+ }
+
fprintf(stderr, "InnoDB: File operation call: '%s'.\n",
- operation);
+ operation);
fprintf(stderr, "InnoDB: Cannot continue operation.\n");
fflush(stderr);
@@ -380,7 +399,7 @@ os_file_handle_error(
exit(1);
}
- return(FALSE);
+ return(FALSE);
}
#undef USE_FILE_LOCK
@@ -413,8 +432,10 @@ os_file_lock(
if (errno == EAGAIN || errno == EACCES) {
fprintf(stderr,
-"InnoDB: Check that you do not already have another mysqld process\n"
-"InnoDB: using the same InnoDB data or log files.\n");
+ "InnoDB: Check that you do not already have"
+ " another mysqld process\n"
+ "InnoDB: using the same InnoDB data"
+ " or log files.\n");
}
return(-1);
@@ -438,7 +459,7 @@ os_file_handle_error_no_exit(
ulint err;
err = os_file_get_last_error(FALSE);
-
+
if (err == OS_FILE_DISK_FULL) {
/* We only print a warning about disk full once */
@@ -446,16 +467,18 @@ os_file_handle_error_no_exit(
return(FALSE);
}
-
+
if (name) {
ut_print_timestamp(stderr);
fprintf(stderr,
- " InnoDB: Encountered a problem with file %s\n", name);
+ " InnoDB: Encountered a problem with"
+ " file %s\n", name);
}
ut_print_timestamp(stderr);
- fprintf(stderr,
- " InnoDB: Disk is full. Try to clean the disk to free space.\n");
+ fprintf(stderr,
+ " InnoDB: Disk is full. Try to clean the disk"
+ " to free space.\n");
os_has_said_disk_full = TRUE;
@@ -468,16 +491,16 @@ os_file_handle_error_no_exit(
return(TRUE);
} else if (err == OS_FILE_ALREADY_EXISTS
- || err == OS_FILE_PATH_ERROR) {
+ || err == OS_FILE_PATH_ERROR) {
return(FALSE);
} else {
- if (name) {
- fprintf(stderr, "InnoDB: File name %s\n", name);
- }
-
+ if (name) {
+ fprintf(stderr, "InnoDB: File name %s\n", name);
+ }
+
fprintf(stderr, "InnoDB: File operation call: '%s'.\n",
- operation);
+ operation);
return (FALSE);
}
@@ -502,7 +525,8 @@ os_io_init_simple(void)
#if !defined(UNIV_HOTBACKUP) && !defined(__NETWARE__)
/*************************************************************************
-Creates a temporary file. This function is defined in ha_innodb.cc. */
+Creates a temporary file that will be deleted on close.
+This function is defined in ha_innodb.cc. */
int
innobase_mysql_tmpfile(void);
@@ -511,68 +535,46 @@ innobase_mysql_tmpfile(void);
#endif /* !UNIV_HOTBACKUP && !__NETWARE__ */
/***************************************************************************
-Creates a temporary file. */
+Creates a temporary file. This function is like tmpfile(3), but
+the temporary file is created in the MySQL temporary directory.
+On Netware, this function is like tmpfile(3), because the C run-time
+library of Netware does not expose the delete-on-close flag. */
FILE*
os_file_create_tmpfile(void)
/*========================*/
/* out: temporary file handle, or NULL on error */
{
-#ifdef __NETWARE__
+#ifdef UNIV_HOTBACKUP
+ ut_error;
+
+ return(NULL);
+#else
+# ifdef __NETWARE__
FILE* file = tmpfile();
-#else /* __NETWARE__ */
+# else /* __NETWARE__ */
FILE* file = NULL;
- int fd = -1;
-# ifdef UNIV_HOTBACKUP
- int tries;
- for (tries = 10; tries--; ) {
- char* name = tempnam(fil_path_to_mysql_datadir, "ib");
- if (!name) {
- break;
- }
-
- fd = open(name,
-# ifdef __WIN__
- O_SEQUENTIAL | O_SHORT_LIVED | O_TEMPORARY |
-# endif /* __WIN__ */
- O_CREAT | O_EXCL | O_RDWR,
- S_IREAD | S_IWRITE);
- if (fd >= 0) {
-# ifndef __WIN__
- unlink(name);
-# endif /* !__WIN__ */
- free(name);
- break;
- }
-
- ut_print_timestamp(stderr);
- fprintf(stderr, " InnoDB: Warning: "
- "unable to create temporary file %s, retrying\n",
- name);
- free(name);
- }
-# else /* UNIV_HOTBACKUP */
- fd = innobase_mysql_tmpfile();
-# endif /* UNIV_HOTBACKUP */
+ int fd = innobase_mysql_tmpfile();
if (fd >= 0) {
file = fdopen(fd, "w+b");
}
-#endif /* __NETWARE__ */
+# endif /* __NETWARE__ */
if (!file) {
ut_print_timestamp(stderr);
fprintf(stderr,
" InnoDB: Error: unable to create temporary file;"
" errno: %d\n", errno);
-#ifndef __NETWARE__
+# ifndef __NETWARE__
if (fd >= 0) {
close(fd);
}
-#endif /* !__NETWARE__ */
+# endif /* !__NETWARE__ */
}
return(file);
+#endif /* UNIV_HOTBACKUP */
}
/***************************************************************************
@@ -596,7 +598,7 @@ os_file_opendir(
{
os_file_dir_t dir;
#ifdef __WIN__
- LPWIN32_FIND_DATA lpFindFileData;
+ LPWIN32_FIND_DATA lpFindFileData;
char path[OS_FILE_MAX_PATH + 3];
ut_a(strlen(dirname) < OS_FILE_MAX_PATH);
@@ -617,18 +619,18 @@ os_file_opendir(
if (dir == INVALID_HANDLE_VALUE) {
if (error_is_fatal) {
- os_file_handle_error(dirname, "opendir");
+ os_file_handle_error(dirname, "opendir");
}
return(NULL);
}
- return(dir);
+ return(dir);
#else
dir = opendir(dirname);
if (dir == NULL && error_is_fatal) {
- os_file_handle_error(dirname, "opendir");
+ os_file_handle_error(dirname, "opendir");
}
return(dir);
@@ -650,19 +652,19 @@ os_file_closedir(
ret = FindClose(dir);
if (!ret) {
- os_file_handle_error_no_exit(NULL, "closedir");
-
+ os_file_handle_error_no_exit(NULL, "closedir");
+
return(-1);
}
-
+
return(0);
#else
int ret;
-
+
ret = closedir(dir);
if (ret) {
- os_file_handle_error_no_exit(NULL, "closedir");
+ os_file_handle_error_no_exit(NULL, "closedir");
}
return(ret);
@@ -691,29 +693,33 @@ next_file:
ret = FindNextFile(dir, lpFindFileData);
if (ret) {
- ut_a(strlen((char *) lpFindFileData->cFileName) < OS_FILE_MAX_PATH);
+ ut_a(strlen((char *) lpFindFileData->cFileName)
+ < OS_FILE_MAX_PATH);
if (strcmp((char *) lpFindFileData->cFileName, ".") == 0
|| strcmp((char *) lpFindFileData->cFileName, "..") == 0) {
- goto next_file;
+ goto next_file;
}
strcpy(info->name, (char *) lpFindFileData->cFileName);
info->size = (ib_longlong)(lpFindFileData->nFileSizeLow)
- + (((ib_longlong)(lpFindFileData->nFileSizeHigh)) << 32);
+ + (((ib_longlong)(lpFindFileData->nFileSizeHigh))
+ << 32);
if (lpFindFileData->dwFileAttributes
- & FILE_ATTRIBUTE_REPARSE_POINT) {
-/* TODO: test Windows symlinks */
-/* TODO: MySQL has apparently its own symlink implementation in Windows,
-dbname.sym can redirect a database directory:
-http://dev.mysql.com/doc/refman/5.0/en/windows-symbolic-links.html */
+ & FILE_ATTRIBUTE_REPARSE_POINT) {
+ /* TODO: test Windows symlinks */
+ /* TODO: MySQL has apparently its own symlink
+ implementation in Windows, dbname.sym can
+ redirect a database directory:
+ http://dev.mysql.com/doc/refman/5.1/en/
+ windows-symbolic-links.html */
info->type = OS_FILE_TYPE_LINK;
} else if (lpFindFileData->dwFileAttributes
- & FILE_ATTRIBUTE_DIRECTORY) {
- info->type = OS_FILE_TYPE_DIR;
+ & FILE_ATTRIBUTE_DIRECTORY) {
+ info->type = OS_FILE_TYPE_DIR;
} else {
/* It is probably safest to assume that all other
file types are normal. Better to check them rather
@@ -732,7 +738,7 @@ http://dev.mysql.com/doc/refman/5.0/en/w
return(1);
} else {
os_file_handle_error_no_exit(dirname,
- "readdir_next_file");
+ "readdir_next_file");
return(-1);
}
#else
@@ -741,11 +747,11 @@ http://dev.mysql.com/doc/refman/5.0/en/w
int ret;
struct stat statinfo;
#ifdef HAVE_READDIR_R
- char dirent_buf[sizeof(struct dirent) + _POSIX_PATH_MAX +
- 100];
- /* In /mysys/my_lib.c, _POSIX_PATH_MAX + 1 is used as
- the max file name len; but in most standards, the
- length is NAME_MAX; we add 100 to be even safer */
+ char dirent_buf[sizeof(struct dirent)
+ + _POSIX_PATH_MAX + 100];
+ /* In /mysys/my_lib.c, _POSIX_PATH_MAX + 1 is used as
+ the max file name len; but in most standards, the
+ length is NAME_MAX; we add 100 to be even safer */
#endif
next_file:
@@ -755,14 +761,15 @@ next_file:
if (ret != 0) {
fprintf(stderr,
-"InnoDB: cannot read directory %s, error %lu\n", dirname, (ulong)ret);
+ "InnoDB: cannot read directory %s, error %lu\n",
+ dirname, (ulong)ret);
return(-1);
}
if (ent == NULL) {
/* End of directory */
-
+
return(1);
}
@@ -785,7 +792,7 @@ next_file:
strcpy(info->name, ent->d_name);
full_path = ut_malloc(strlen(dirname) + strlen(ent->d_name) + 10);
-
+
sprintf(full_path, "%s/%s", dirname, ent->d_name);
ret = stat(full_path, &statinfo);
@@ -803,13 +810,13 @@ next_file:
if (S_ISDIR(statinfo.st_mode)) {
info->type = OS_FILE_TYPE_DIR;
} else if (S_ISLNK(statinfo.st_mode)) {
- info->type = OS_FILE_TYPE_LINK;
+ info->type = OS_FILE_TYPE_LINK;
} else if (S_ISREG(statinfo.st_mode)) {
- info->type = OS_FILE_TYPE_FILE;
+ info->type = OS_FILE_TYPE_FILE;
} else {
- info->type = OS_FILE_TYPE_UNKNOWN;
+ info->type = OS_FILE_TYPE_UNKNOWN;
}
-
+
ut_free(full_path);
return(0);
@@ -834,16 +841,17 @@ os_file_create_directory(
{
#ifdef __WIN__
BOOL rcode;
-
+
rcode = CreateDirectory((LPCTSTR) pathname, NULL);
- if (!(rcode != 0 ||
- (GetLastError() == ERROR_ALREADY_EXISTS && !fail_if_exists))) {
+ if (!(rcode != 0
+ || (GetLastError() == ERROR_ALREADY_EXISTS
+ && !fail_if_exists))) {
/* failure */
os_file_handle_error(pathname, "CreateDirectory");
return(FALSE);
}
-
+
return (TRUE);
#else
int rcode;
@@ -856,9 +864,9 @@ os_file_create_directory(
return(FALSE);
}
-
+
return (TRUE);
-#endif
+#endif
}
/********************************************************************
@@ -876,7 +884,7 @@ os_file_create_simple(
opened (if does not exist, error), or
OS_FILE_CREATE if a new file is created
(if exists, error), or
- OS_FILE_CREATE_PATH if new file
+ OS_FILE_CREATE_PATH if new file
(if exists, error) and subdirectories along
its path are created (if needed)*/
ulint access_type,/* in: OS_FILE_READ_ONLY or
@@ -889,22 +897,22 @@ os_file_create_simple(
DWORD access;
DWORD attributes = 0;
ibool retry;
-
-try_again:
+
+try_again:
ut_a(name);
if (create_mode == OS_FILE_OPEN) {
create_flag = OPEN_EXISTING;
} else if (create_mode == OS_FILE_CREATE) {
create_flag = CREATE_NEW;
- } else if (create_mode == OS_FILE_CREATE_PATH) {
- /* create subdirs along the path if needed */
- *success = os_file_create_subdirs_if_needed(name);
- if (!*success) {
- ut_error;
- }
- create_flag = CREATE_NEW;
- create_mode = OS_FILE_CREATE;
+ } else if (create_mode == OS_FILE_CREATE_PATH) {
+ /* create subdirs along the path if needed */
+ *success = os_file_create_subdirs_if_needed(name);
+ if (!*success) {
+ ut_error;
+ }
+ create_flag = CREATE_NEW;
+ create_mode = OS_FILE_CREATE;
} else {
create_flag = 0;
ut_error;
@@ -933,8 +941,8 @@ try_again:
*success = FALSE;
retry = os_file_handle_error(name,
- create_mode == OS_FILE_OPEN ?
- "open" : "create");
+ create_mode == OS_FILE_OPEN ?
+ "open" : "create");
if (retry) {
goto try_again;
}
@@ -947,8 +955,8 @@ try_again:
os_file_t file;
int create_flag;
ibool retry;
-
-try_again:
+
+try_again:
ut_a(name);
if (create_mode == OS_FILE_OPEN) {
@@ -959,38 +967,38 @@ try_again:
}
} else if (create_mode == OS_FILE_CREATE) {
create_flag = O_RDWR | O_CREAT | O_EXCL;
- } else if (create_mode == OS_FILE_CREATE_PATH) {
- /* create subdirs along the path if needed */
- *success = os_file_create_subdirs_if_needed(name);
- if (!*success) {
- return (-1);
- }
- create_flag = O_RDWR | O_CREAT | O_EXCL;
- create_mode = OS_FILE_CREATE;
+ } else if (create_mode == OS_FILE_CREATE_PATH) {
+ /* create subdirs along the path if needed */
+ *success = os_file_create_subdirs_if_needed(name);
+ if (!*success) {
+ return (-1);
+ }
+ create_flag = O_RDWR | O_CREAT | O_EXCL;
+ create_mode = OS_FILE_CREATE;
} else {
create_flag = 0;
ut_error;
}
if (create_mode == OS_FILE_CREATE) {
- file = open(name, create_flag, S_IRUSR | S_IWUSR
- | S_IRGRP | S_IWGRP);
- } else {
- file = open(name, create_flag);
- }
-
+ file = open(name, create_flag, S_IRUSR | S_IWUSR
+ | S_IRGRP | S_IWGRP);
+ } else {
+ file = open(name, create_flag);
+ }
+
if (file == -1) {
*success = FALSE;
retry = os_file_handle_error(name,
- create_mode == OS_FILE_OPEN ?
- "open" : "create");
+ create_mode == OS_FILE_OPEN ?
+ "open" : "create");
if (retry) {
goto try_again;
}
#ifdef USE_FILE_LOCK
} else if (access_type == OS_FILE_READ_WRITE
- && os_file_lock(file, name)) {
+ && os_file_lock(file, name)) {
*success = FALSE;
close(file);
file = -1;
@@ -999,7 +1007,7 @@ try_again:
*success = TRUE;
}
- return(file);
+ return(file);
#endif /* __WIN__ */
}
@@ -1030,7 +1038,7 @@ os_file_create_simple_no_error_handling(
DWORD access;
DWORD attributes = 0;
DWORD share_mode = FILE_SHARE_READ | FILE_SHARE_WRITE;
-
+
ut_a(name);
if (create_mode == OS_FILE_OPEN) {
@@ -1049,7 +1057,7 @@ os_file_create_simple_no_error_handling(
} else if (access_type == OS_FILE_READ_ALLOW_DELETE) {
access = GENERIC_READ;
share_mode = FILE_SHARE_DELETE | FILE_SHARE_READ
- | FILE_SHARE_WRITE; /* A backup program has to give
+ | FILE_SHARE_WRITE; /* A backup program has to give
mysqld the maximum freedom to
do what it likes with the
file */
@@ -1059,12 +1067,12 @@ os_file_create_simple_no_error_handling(
}
file = CreateFile((LPCTSTR) name,
- access,
- share_mode,
- NULL, /* default security attributes */
- create_flag,
- attributes,
- NULL); /* no template file */
+ access,
+ share_mode,
+ NULL, /* default security attributes */
+ create_flag,
+ attributes,
+ NULL); /* no template file */
if (file == INVALID_HANDLE_VALUE) {
*success = FALSE;
@@ -1076,7 +1084,7 @@ os_file_create_simple_no_error_handling(
#else /* __WIN__ */
os_file_t file;
int create_flag;
-
+
ut_a(name);
if (create_mode == OS_FILE_OPEN) {
@@ -1093,17 +1101,17 @@ os_file_create_simple_no_error_handling(
}
if (create_mode == OS_FILE_CREATE) {
- file = open(name, create_flag, S_IRUSR | S_IWUSR
- | S_IRGRP | S_IWGRP);
- } else {
- file = open(name, create_flag);
- }
-
+ file = open(name, create_flag, S_IRUSR | S_IWUSR
+ | S_IRGRP | S_IWGRP);
+ } else {
+ file = open(name, create_flag);
+ }
+
if (file == -1) {
*success = FALSE;
#ifdef USE_FILE_LOCK
} else if (access_type == OS_FILE_READ_WRITE
- && os_file_lock(file, name)) {
+ && os_file_lock(file, name)) {
*success = FALSE;
close(file);
file = -1;
@@ -1112,7 +1120,7 @@ os_file_create_simple_no_error_handling(
*success = TRUE;
}
- return(file);
+ return(file);
#endif /* __WIN__ */
}
@@ -1151,14 +1159,14 @@ os_file_create(
DWORD create_flag;
DWORD attributes;
ibool retry;
-try_again:
+try_again:
ut_a(name);
if (create_mode == OS_FILE_OPEN_RAW) {
create_flag = OPEN_EXISTING;
share_mode = FILE_SHARE_WRITE;
} else if (create_mode == OS_FILE_OPEN
- || create_mode == OS_FILE_OPEN_RETRY) {
+ || create_mode == OS_FILE_OPEN_RETRY) {
create_flag = OPEN_EXISTING;
} else if (create_mode == OS_FILE_CREATE) {
create_flag = CREATE_NEW;
@@ -1177,27 +1185,27 @@ try_again:
if (os_aio_use_native_aio) {
attributes = attributes | FILE_FLAG_OVERLAPPED;
}
-#endif
+#endif
#ifdef UNIV_NON_BUFFERED_IO
if (type == OS_LOG_FILE && srv_flush_log_at_trx_commit == 2) {
- /* Do not use unbuffered i/o to log files because
- value 2 denotes that we do not flush the log at every
- commit, but only once per second */
- } else if (srv_win_file_flush_method ==
- SRV_WIN_IO_UNBUFFERED) {
- attributes = attributes | FILE_FLAG_NO_BUFFERING;
+ /* Do not use unbuffered i/o to log files because
+ value 2 denotes that we do not flush the log at every
+ commit, but only once per second */
+ } else if (srv_win_file_flush_method
+ == SRV_WIN_IO_UNBUFFERED) {
+ attributes = attributes | FILE_FLAG_NO_BUFFERING;
}
#endif
} else if (purpose == OS_FILE_NORMAL) {
- attributes = 0;
+ attributes = 0;
#ifdef UNIV_NON_BUFFERED_IO
if (type == OS_LOG_FILE && srv_flush_log_at_trx_commit == 2) {
- /* Do not use unbuffered i/o to log files because
- value 2 denotes that we do not flush the log at every
- commit, but only once per second */
- } else if (srv_win_file_flush_method ==
- SRV_WIN_IO_UNBUFFERED) {
- attributes = attributes | FILE_FLAG_NO_BUFFERING;
+ /* Do not use unbuffered i/o to log files because
+ value 2 denotes that we do not flush the log at every
+ commit, but only once per second */
+ } else if (srv_win_file_flush_method
+ == SRV_WIN_IO_UNBUFFERED) {
+ attributes = attributes | FILE_FLAG_NO_BUFFERING;
}
#endif
} else {
@@ -1206,9 +1214,9 @@ try_again:
}
file = CreateFile((LPCTSTR) name,
- GENERIC_READ | GENERIC_WRITE, /* read and write
+ GENERIC_READ | GENERIC_WRITE, /* read and write
access */
- share_mode, /* File can be read also by other
+ share_mode, /* File can be read also by other
processes; we must give the read
permission because of ibbackup. We do
not give the write permission to
@@ -1219,17 +1227,17 @@ try_again:
raw disk partitions, Microsoft manuals
say that we must give also the write
permission. */
- NULL, /* default security attributes */
- create_flag,
- attributes,
- NULL); /* no template file */
+ NULL, /* default security attributes */
+ create_flag,
+ attributes,
+ NULL); /* no template file */
if (file == INVALID_HANDLE_VALUE) {
*success = FALSE;
retry = os_file_handle_error(name,
- create_mode == OS_FILE_CREATE ?
- "create" : "open");
+ create_mode == OS_FILE_CREATE ?
+ "create" : "open");
if (retry) {
goto try_again;
}
@@ -1245,12 +1253,12 @@ try_again:
const char* mode_str = NULL;
const char* type_str = NULL;
const char* purpose_str = NULL;
-
-try_again:
+
+try_again:
ut_a(name);
if (create_mode == OS_FILE_OPEN || create_mode == OS_FILE_OPEN_RAW
- || create_mode == OS_FILE_OPEN_RETRY) {
+ || create_mode == OS_FILE_OPEN_RETRY) {
mode_str = "OPEN";
create_flag = O_RDWR;
} else if (create_mode == OS_FILE_CREATE) {
@@ -1269,65 +1277,70 @@ try_again:
} else if (type == OS_DATA_FILE) {
type_str = "DATA";
} else {
- ut_error;
+ ut_error;
}
-
+
if (purpose == OS_FILE_AIO) {
purpose_str = "AIO";
} else if (purpose == OS_FILE_NORMAL) {
purpose_str = "NORMAL";
} else {
- ut_error;
+ ut_error;
}
-/* fprintf(stderr, "Opening file %s, mode %s, type %s, purpose %s\n",
- name, mode_str, type_str, purpose_str); */
+#if 0
+ fprintf(stderr, "Opening file %s, mode %s, type %s, purpose %s\n",
+ name, mode_str, type_str, purpose_str);
+#endif
#ifdef O_SYNC
- /* We let O_SYNC only affect log files; note that we map O_DSYNC to
+ /* We let O_SYNC only affect log files; note that we map O_DSYNC to
O_SYNC because the datasync options seemed to corrupt files in 2001
in both Linux and Solaris */
if (type == OS_LOG_FILE
&& srv_unix_file_flush_method == SRV_UNIX_O_DSYNC) {
-/* fprintf(stderr, "Using O_SYNC for file %s\n", name); */
+# if 0
+ fprintf(stderr, "Using O_SYNC for file %s\n", name);
+# endif
- create_flag = create_flag | O_SYNC;
+ create_flag = create_flag | O_SYNC;
}
-#endif
+#endif /* O_SYNC */
#ifdef O_DIRECT
- /* We let O_DIRECT only affect data files */
+ /* We let O_DIRECT only affect data files */
if (type != OS_LOG_FILE
&& srv_unix_file_flush_method == SRV_UNIX_O_DIRECT) {
-
-/* fprintf(stderr, "Using O_DIRECT for file %s\n", name); */
-
- create_flag = create_flag | O_DIRECT;
+# if 0
+ fprintf(stderr, "Using O_DIRECT for file %s\n", name);
+# endif
+ create_flag = create_flag | O_DIRECT;
}
-#endif
+#endif /* O_DIRECT */
if (create_mode == OS_FILE_CREATE) {
- file = open(name, create_flag, os_innodb_umask);
- } else {
- file = open(name, create_flag);
- }
-
+ file = open(name, create_flag, os_innodb_umask);
+ } else {
+ file = open(name, create_flag);
+ }
+
if (file == -1) {
*success = FALSE;
retry = os_file_handle_error(name,
- create_mode == OS_FILE_CREATE ?
- "create" : "open");
+ create_mode == OS_FILE_CREATE ?
+ "create" : "open");
if (retry) {
goto try_again;
}
#ifdef USE_FILE_LOCK
} else if (create_mode != OS_FILE_OPEN_RAW
- && os_file_lock(file, name)) {
+ && os_file_lock(file, name)) {
*success = FALSE;
if (create_mode == OS_FILE_OPEN_RETRY) {
int i;
ut_print_timestamp(stderr);
- fputs(" InnoDB: Retrying to lock the first data file\n",
- stderr);
+ fputs(" InnoDB: Retrying to lock"
+ " the first data file\n",
+ stderr);
for (i = 0; i < 100; i++) {
os_thread_sleep(1000000);
if (!os_file_lock(file, name)) {
@@ -1337,7 +1350,7 @@ try_again:
}
ut_print_timestamp(stderr);
fputs(" InnoDB: Unable to open the first data file\n",
- stderr);
+ stderr);
}
close(file);
file = -1;
@@ -1346,7 +1359,7 @@ try_again:
*success = TRUE;
}
- return(file);
+ return(file);
#endif /* __WIN__ */
}
@@ -1382,9 +1395,10 @@ loop:
if (count > 100 && 0 == (count % 10)) {
fprintf(stderr,
-"InnoDB: Warning: cannot delete file %s\n"
-"InnoDB: Are you running ibbackup to back up the file?\n", name);
-
+ "InnoDB: Warning: cannot delete file %s\n"
+ "InnoDB: Are you running ibbackup"
+ " to back up the file?\n", name);
+
os_file_get_last_error(TRUE); /* print error information */
}
@@ -1444,9 +1458,10 @@ loop:
if (count > 100 && 0 == (count % 10)) {
fprintf(stderr,
-"InnoDB: Warning: cannot delete file %s\n"
-"InnoDB: Are you running ibbackup to back up the file?\n", name);
-
+ "InnoDB: Warning: cannot delete file %s\n"
+ "InnoDB: Are you running ibbackup"
+ " to back up the file?\n", name);
+
os_file_get_last_error(TRUE); /* print error information */
}
@@ -1621,16 +1636,16 @@ os_file_get_size(
return(FALSE);
}
-
+
if (sizeof(off_t) > 4) {
- *size = (ulint)(offs & 0xFFFFFFFFUL);
+ *size = (ulint)(offs & 0xFFFFFFFFUL);
*size_high = (ulint)(offs >> 32);
} else {
*size = (ulint) offs;
*size_high = 0;
}
-
- return(TRUE);
+
+ return(TRUE);
#endif
}
@@ -1674,8 +1689,8 @@ os_file_set_size(
ib_longlong current_size;
ib_longlong desired_size;
ibool ret;
- byte* buf;
- byte* buf2;
+ byte* buf;
+ byte* buf2;
ulint buf_size;
ut_a(size == (size & 0xFFFFFFFF));
@@ -1685,7 +1700,7 @@ os_file_set_size(
/* Write up to 1 megabyte at a time. */
buf_size = ut_min(64, (ulint) (desired_size / UNIV_PAGE_SIZE))
- * UNIV_PAGE_SIZE;
+ * UNIV_PAGE_SIZE;
buf2 = ut_malloc(buf_size + UNIV_PAGE_SIZE);
/* Align the buffer for possible raw i/o */
@@ -1695,7 +1710,7 @@ os_file_set_size(
memset(buf, 0, buf_size);
if (desired_size >= (ib_longlong)(100 * 1024 * 1024)) {
-
+
fprintf(stderr, "InnoDB: Progress in MB:");
}
@@ -1708,29 +1723,29 @@ os_file_set_size(
n_bytes = buf_size;
}
- ret = os_file_write(name, file, buf,
- (ulint)(current_size & 0xFFFFFFFF),
+ ret = os_file_write(name, file, buf,
+ (ulint)(current_size & 0xFFFFFFFF),
(ulint)(current_size >> 32),
- n_bytes);
- if (!ret) {
+ n_bytes);
+ if (!ret) {
ut_free(buf2);
- goto error_handling;
- }
-
+ goto error_handling;
+ }
+
/* Print about progress for each 100 MB written */
if ((ib_longlong) (current_size + n_bytes) / (ib_longlong)(100 * 1024 * 1024)
!= current_size / (ib_longlong)(100 * 1024 * 1024)) {
- fprintf(stderr, " %lu00",
+ fprintf(stderr, " %lu00",
(ulong) ((current_size + n_bytes)
- / (ib_longlong)(100 * 1024 * 1024)));
+ / (ib_longlong)(100 * 1024 * 1024)));
}
-
- current_size += n_bytes;
+
+ current_size += n_bytes;
}
if (desired_size >= (ib_longlong)(100 * 1024 * 1024)) {
-
+
fprintf(stderr, "\n");
}
@@ -1739,7 +1754,7 @@ os_file_set_size(
ret = os_file_flush(file);
if (ret) {
- return(TRUE);
+ return(TRUE);
}
error_handling:
@@ -1790,8 +1805,8 @@ os_file_flush(
raw disks */
if (srv_start_raw_disk_in_use && GetLastError()
- == ERROR_INVALID_FUNCTION) {
- return(TRUE);
+ == ERROR_INVALID_FUNCTION) {
+ return(TRUE);
}
os_file_handle_error(NULL, "flush");
@@ -1818,7 +1833,7 @@ os_file_flush(
if (!srv_have_fullfsync) {
/* If we are not on an operating system that supports this,
- then fall back to a plain fsync. */
+ then fall back to a plain fsync. */
ret = fsync(file);
} else {
@@ -1826,14 +1841,14 @@ os_file_flush(
if (ret) {
/* If we are not on a file system that supports this,
- then fall back to a plain fsync. */
+ then fall back to a plain fsync. */
ret = fsync(file);
}
}
#elif HAVE_FDATASYNC
ret = fdatasync(file);
#else
-/* fprintf(stderr, "Flushing to file %p\n", file); */
+ /* fprintf(stderr, "Flushing to file %p\n", file); */
ret = fsync(file);
#endif
os_n_fsyncs++;
@@ -1841,17 +1856,17 @@ os_file_flush(
if (ret == 0) {
return(TRUE);
}
-
+
/* Since Linux returns EINVAL if the 'file' is actually a raw device,
we choose to ignore that error if we are using raw disks */
if (srv_start_raw_disk_in_use && errno == EINVAL) {
- return(TRUE);
+ return(TRUE);
}
ut_print_timestamp(stderr);
-
+
fprintf(stderr,
" InnoDB: Error: the OS said file flush did not succeed\n");
@@ -1875,78 +1890,78 @@ os_file_pread(
/* out: number of bytes read, -1 if error */
os_file_t file, /* in: handle to a file */
void* buf, /* in: buffer where to read */
- ulint n, /* in: number of bytes to read */
+ ulint n, /* in: number of bytes to read */
ulint offset, /* in: least significant 32 bits of file
offset from where to read */
ulint offset_high) /* in: most significant 32 bits of
offset */
{
- off_t offs;
+ off_t offs;
ssize_t n_bytes;
ut_a((offset & 0xFFFFFFFFUL) == offset);
-
- /* If off_t is > 4 bytes in size, then we assume we can pass a
+
+ /* If off_t is > 4 bytes in size, then we assume we can pass a
64-bit address */
- if (sizeof(off_t) > 4) {
- offs = (off_t)offset + (((off_t)offset_high) << 32);
-
- } else {
- offs = (off_t)offset;
-
- if (offset_high > 0) {
- fprintf(stderr,
- "InnoDB: Error: file read at offset > 4 GB\n");
+ if (sizeof(off_t) > 4) {
+ offs = (off_t)offset + (((off_t)offset_high) << 32);
+
+ } else {
+ offs = (off_t)offset;
+
+ if (offset_high > 0) {
+ fprintf(stderr,
+ "InnoDB: Error: file read at offset > 4 GB\n");
}
- }
+ }
os_n_file_reads++;
#if defined(HAVE_PREAD) && !defined(HAVE_BROKEN_PREAD)
- os_mutex_enter(os_file_count_mutex);
+ os_mutex_enter(os_file_count_mutex);
os_file_n_pending_preads++;
os_n_pending_reads++;
- os_mutex_exit(os_file_count_mutex);
+ os_mutex_exit(os_file_count_mutex);
- n_bytes = pread(file, buf, (ssize_t)n, offs);
+ n_bytes = pread(file, buf, (ssize_t)n, offs);
- os_mutex_enter(os_file_count_mutex);
+ os_mutex_enter(os_file_count_mutex);
os_file_n_pending_preads--;
os_n_pending_reads--;
- os_mutex_exit(os_file_count_mutex);
+ os_mutex_exit(os_file_count_mutex);
return(n_bytes);
#else
{
- off_t ret_offset;
- ssize_t ret;
- ulint i;
+ off_t ret_offset;
+ ssize_t ret;
+ ulint i;
- os_mutex_enter(os_file_count_mutex);
- os_n_pending_reads++;
- os_mutex_exit(os_file_count_mutex);
+ os_mutex_enter(os_file_count_mutex);
+ os_n_pending_reads++;
+ os_mutex_exit(os_file_count_mutex);
- /* Protect the seek / read operation with a mutex */
- i = ((ulint) file) % OS_FILE_N_SEEK_MUTEXES;
-
- os_mutex_enter(os_file_seek_mutexes[i]);
+ /* Protect the seek / read operation with a mutex */
+ i = ((ulint) file) % OS_FILE_N_SEEK_MUTEXES;
- ret_offset = lseek(file, offs, SEEK_SET);
+ os_mutex_enter(os_file_seek_mutexes[i]);
- if (ret_offset < 0) {
- ret = -1;
- } else {
- ret = read(file, buf, (ssize_t)n);
- }
+ ret_offset = lseek(file, offs, SEEK_SET);
- os_mutex_exit(os_file_seek_mutexes[i]);
+ if (ret_offset < 0) {
+ ret = -1;
+ } else {
+ ret = read(file, buf, (ssize_t)n);
+ }
- os_mutex_enter(os_file_count_mutex);
- os_n_pending_reads--;
- os_mutex_exit(os_file_count_mutex);
+ os_mutex_exit(os_file_seek_mutexes[i]);
- return(ret);
+ os_mutex_enter(os_file_count_mutex);
+ os_n_pending_reads--;
+ os_mutex_exit(os_file_count_mutex);
+
+ return(ret);
}
#endif
}
@@ -1960,105 +1975,106 @@ os_file_pwrite(
/* out: number of bytes written, -1 if error */
os_file_t file, /* in: handle to a file */
const void* buf, /* in: buffer from where to write */
- ulint n, /* in: number of bytes to write */
+ ulint n, /* in: number of bytes to write */
ulint offset, /* in: least significant 32 bits of file
offset where to write */
ulint offset_high) /* in: most significant 32 bits of
offset */
{
ssize_t ret;
- off_t offs;
+ off_t offs;
ut_a((offset & 0xFFFFFFFFUL) == offset);
- /* If off_t is > 4 bytes in size, then we assume we can pass a
+ /* If off_t is > 4 bytes in size, then we assume we can pass a
64-bit address */
- if (sizeof(off_t) > 4) {
- offs = (off_t)offset + (((off_t)offset_high) << 32);
- } else {
- offs = (off_t)offset;
-
- if (offset_high > 0) {
- fprintf(stderr,
- "InnoDB: Error: file write at offset > 4 GB\n");
+ if (sizeof(off_t) > 4) {
+ offs = (off_t)offset + (((off_t)offset_high) << 32);
+ } else {
+ offs = (off_t)offset;
+
+ if (offset_high > 0) {
+ fprintf(stderr,
+ "InnoDB: Error: file write"
+ " at offset > 4 GB\n");
}
- }
+ }
os_n_file_writes++;
#if defined(HAVE_PWRITE) && !defined(HAVE_BROKEN_PREAD)
- os_mutex_enter(os_file_count_mutex);
+ os_mutex_enter(os_file_count_mutex);
os_file_n_pending_pwrites++;
os_n_pending_writes++;
- os_mutex_exit(os_file_count_mutex);
+ os_mutex_exit(os_file_count_mutex);
ret = pwrite(file, buf, (ssize_t)n, offs);
- os_mutex_enter(os_file_count_mutex);
+ os_mutex_enter(os_file_count_mutex);
os_file_n_pending_pwrites--;
os_n_pending_writes--;
- os_mutex_exit(os_file_count_mutex);
+ os_mutex_exit(os_file_count_mutex);
# ifdef UNIV_DO_FLUSH
if (srv_unix_file_flush_method != SRV_UNIX_LITTLESYNC
&& srv_unix_file_flush_method != SRV_UNIX_NOSYNC
&& !os_do_not_call_flush_at_each_write) {
-
- /* Always do fsync to reduce the probability that when
- the OS crashes, a database page is only partially
- physically written to disk. */
- ut_a(TRUE == os_file_flush(file));
+ /* Always do fsync to reduce the probability that when
+ the OS crashes, a database page is only partially
+ physically written to disk. */
+
+ ut_a(TRUE == os_file_flush(file));
}
# endif /* UNIV_DO_FLUSH */
- return(ret);
+ return(ret);
#else
{
- off_t ret_offset;
- ulint i;
+ off_t ret_offset;
+ ulint i;
- os_mutex_enter(os_file_count_mutex);
- os_n_pending_writes++;
- os_mutex_exit(os_file_count_mutex);
+ os_mutex_enter(os_file_count_mutex);
+ os_n_pending_writes++;
+ os_mutex_exit(os_file_count_mutex);
- /* Protect the seek / write operation with a mutex */
- i = ((ulint) file) % OS_FILE_N_SEEK_MUTEXES;
-
- os_mutex_enter(os_file_seek_mutexes[i]);
+ /* Protect the seek / write operation with a mutex */
+ i = ((ulint) file) % OS_FILE_N_SEEK_MUTEXES;
- ret_offset = lseek(file, offs, SEEK_SET);
+ os_mutex_enter(os_file_seek_mutexes[i]);
- if (ret_offset < 0) {
- ret = -1;
+ ret_offset = lseek(file, offs, SEEK_SET);
- goto func_exit;
- }
-
- ret = write(file, buf, (ssize_t)n);
+ if (ret_offset < 0) {
+ ret = -1;
-# ifdef UNIV_DO_FLUSH
- if (srv_unix_file_flush_method != SRV_UNIX_LITTLESYNC
- && srv_unix_file_flush_method != SRV_UNIX_NOSYNC
- && !os_do_not_call_flush_at_each_write) {
+ goto func_exit;
+ }
- /* Always do fsync to reduce the probability that when
- the OS crashes, a database page is only partially
- physically written to disk. */
+ ret = write(file, buf, (ssize_t)n);
- ut_a(TRUE == os_file_flush(file));
- }
+# ifdef UNIV_DO_FLUSH
+ if (srv_unix_file_flush_method != SRV_UNIX_LITTLESYNC
+ && srv_unix_file_flush_method != SRV_UNIX_NOSYNC
+ && !os_do_not_call_flush_at_each_write) {
+
+ /* Always do fsync to reduce the probability that when
+ the OS crashes, a database page is only partially
+ physically written to disk. */
+
+ ut_a(TRUE == os_file_flush(file));
+ }
# endif /* UNIV_DO_FLUSH */
func_exit:
- os_mutex_exit(os_file_seek_mutexes[i]);
+ os_mutex_exit(os_file_seek_mutexes[i]);
- os_mutex_enter(os_file_count_mutex);
- os_n_pending_writes--;
- os_mutex_exit(os_file_count_mutex);
+ os_mutex_enter(os_file_count_mutex);
+ os_n_pending_writes--;
+ os_mutex_exit(os_file_count_mutex);
- return(ret);
+ return(ret);
}
#endif
}
@@ -2078,7 +2094,7 @@ os_file_read(
offset where to read */
ulint offset_high, /* in: most significant 32 bits of
offset */
- ulint n) /* in: number of bytes to read */
+ ulint n) /* in: number of bytes to read */
{
#ifdef __WIN__
BOOL ret;
@@ -2088,13 +2104,13 @@ os_file_read(
DWORD high;
ibool retry;
ulint i;
-
+
ut_a((offset & 0xFFFFFFFFUL) == offset);
os_n_file_reads++;
os_bytes_read_since_printout += n;
-try_again:
+try_again:
ut_ad(file);
ut_ad(buf);
ut_ad(n > 0);
@@ -2122,19 +2138,19 @@ try_again:
os_mutex_exit(os_file_count_mutex);
goto error_handling;
- }
-
+ }
+
ret = ReadFile(file, buf, (DWORD) n, &len, NULL);
os_mutex_exit(os_file_seek_mutexes[i]);
-
+
os_mutex_enter(os_file_count_mutex);
os_n_pending_reads--;
os_mutex_exit(os_file_count_mutex);
if (ret && len == n) {
return(TRUE);
- }
+ }
#else
ibool retry;
ssize_t ret;
@@ -2150,21 +2166,23 @@ try_again:
}
fprintf(stderr,
-"InnoDB: Error: tried to read %lu bytes at offset %lu %lu.\n"
-"InnoDB: Was only able to read %ld.\n", (ulong)n, (ulong)offset_high,
- (ulong)offset, (long)ret);
-#endif
+ "InnoDB: Error: tried to read %lu bytes at offset %lu %lu.\n"
+ "InnoDB: Was only able to read %ld.\n",
+ (ulong)n, (ulong)offset_high,
+ (ulong)offset, (long)ret);
+#endif
#ifdef __WIN__
error_handling:
#endif
- retry = os_file_handle_error(NULL, "read");
+ retry = os_file_handle_error(NULL, "read");
if (retry) {
goto try_again;
}
-
+
fprintf(stderr,
-"InnoDB: Fatal error: cannot read from file. OS error number %lu.\n",
+ "InnoDB: Fatal error: cannot read from file."
+ " OS error number %lu.\n",
#ifdef __WIN__
(ulong) GetLastError()
#else
@@ -2193,7 +2211,7 @@ os_file_read_no_error_handling(
offset where to read */
ulint offset_high, /* in: most significant 32 bits of
offset */
- ulint n) /* in: number of bytes to read */
+ ulint n) /* in: number of bytes to read */
{
#ifdef __WIN__
BOOL ret;
@@ -2203,13 +2221,13 @@ os_file_read_no_error_handling(
DWORD high;
ibool retry;
ulint i;
-
+
ut_a((offset & 0xFFFFFFFFUL) == offset);
os_n_file_reads++;
os_bytes_read_since_printout += n;
-try_again:
+try_again:
ut_ad(file);
ut_ad(buf);
ut_ad(n > 0);
@@ -2223,7 +2241,7 @@ try_again:
/* Protect the seek / read operation with a mutex */
i = ((ulint) file) % OS_FILE_N_SEEK_MUTEXES;
-
+
os_mutex_enter(os_file_seek_mutexes[i]);
ret2 = SetFilePointer(file, low, &high, FILE_BEGIN);
@@ -2237,19 +2255,19 @@ try_again:
os_mutex_exit(os_file_count_mutex);
goto error_handling;
- }
-
+ }
+
ret = ReadFile(file, buf, (DWORD) n, &len, NULL);
os_mutex_exit(os_file_seek_mutexes[i]);
-
+
os_mutex_enter(os_file_count_mutex);
os_n_pending_reads--;
os_mutex_exit(os_file_count_mutex);
if (ret && len == n) {
return(TRUE);
- }
+ }
#else
ibool retry;
ssize_t ret;
@@ -2263,16 +2281,16 @@ try_again:
return(TRUE);
}
-#endif
+#endif
#ifdef __WIN__
error_handling:
#endif
- retry = os_file_handle_error_no_exit(NULL, "read");
+ retry = os_file_handle_error_no_exit(NULL, "read");
if (retry) {
goto try_again;
}
-
+
return(FALSE);
}
@@ -2293,7 +2311,7 @@ os_file_read_string(
if (size == 0) {
return;
}
-
+
rewind(file);
flen = fread(str, 1, size - 1, file);
str[flen] = '\0';
@@ -2315,7 +2333,7 @@ os_file_write(
offset where to write */
ulint offset_high, /* in: most significant 32 bits of
offset */
- ulint n) /* in: number of bytes to write */
+ ulint n) /* in: number of bytes to write */
{
#ifdef __WIN__
BOOL ret;
@@ -2337,14 +2355,14 @@ os_file_write(
retry:
low = (DWORD) offset;
high = (DWORD) offset_high;
-
+
os_mutex_enter(os_file_count_mutex);
os_n_pending_writes++;
os_mutex_exit(os_file_count_mutex);
/* Protect the seek / write operation with a mutex */
i = ((ulint) file) % OS_FILE_N_SEEK_MUTEXES;
-
+
os_mutex_enter(os_file_seek_mutexes[i]);
ret2 = SetFilePointer(file, low, &high, FILE_BEGIN);
@@ -2352,7 +2370,7 @@ retry:
if (ret2 == 0xFFFFFFFF && GetLastError() != NO_ERROR) {
os_mutex_exit(os_file_seek_mutexes[i]);
-
+
os_mutex_enter(os_file_count_mutex);
os_n_pending_writes--;
os_mutex_exit(os_file_count_mutex);
@@ -2360,16 +2378,20 @@ retry:
ut_print_timestamp(stderr);
fprintf(stderr,
-" InnoDB: Error: File pointer positioning to file %s failed at\n"
-"InnoDB: offset %lu %lu. Operating system error number %lu.\n"
-"InnoDB: Some operating system error numbers are described at\n"
-"InnoDB: "
-"http://dev.mysql.com/doc/refman/5.0/en/operating-system-error-codes.html\n",
+ " InnoDB: Error: File pointer positioning to"
+ " file %s failed at\n"
+ "InnoDB: offset %lu %lu. Operating system"
+ " error number %lu.\n"
+ "InnoDB: Some operating system error numbers"
+ " are described at\n"
+ "InnoDB: "
+ "http://dev.mysql.com/doc/refman/5.1/en/"
+ "operating-system-error-codes.html\n",
name, (ulong) offset_high, (ulong) offset,
(ulong) GetLastError());
return(FALSE);
- }
+ }
ret = WriteFile(file, buf, (DWORD) n, &len, NULL);
@@ -2396,40 +2418,47 @@ retry:
/* If some background file system backup tool is running, then, at
least in Windows 2000, we may get here a specific error. Let us
retry the operation 100 times, with 1 second waits. */
-
+
if (GetLastError() == ERROR_LOCK_VIOLATION && n_retries < 100) {
os_thread_sleep(1000000);
-
+
n_retries++;
goto retry;
- }
-
+ }
+
if (!os_has_said_disk_full) {
-
+
err = (ulint)GetLastError();
ut_print_timestamp(stderr);
fprintf(stderr,
-" InnoDB: Error: Write to file %s failed at offset %lu %lu.\n"
-"InnoDB: %lu bytes should have been written, only %lu were written.\n"
-"InnoDB: Operating system error number %lu.\n"
-"InnoDB: Check that your OS and file system support files of this size.\n"
-"InnoDB: Check also that the disk is not full or a disk quota exceeded.\n",
+ " InnoDB: Error: Write to file %s failed"
+ " at offset %lu %lu.\n"
+ "InnoDB: %lu bytes should have been written,"
+ " only %lu were written.\n"
+ "InnoDB: Operating system error number %lu.\n"
+ "InnoDB: Check that your OS and file system"
+ " support files of this size.\n"
+ "InnoDB: Check also that the disk is not full"
+ " or a disk quota exceeded.\n",
name, (ulong) offset_high, (ulong) offset,
(ulong) n, (ulong) len, (ulong) err);
if (strerror((int)err) != NULL) {
fprintf(stderr,
-"InnoDB: Error number %lu means '%s'.\n", (ulong) err, strerror((int)err));
+ "InnoDB: Error number %lu means '%s'.\n",
+ (ulong) err, strerror((int)err));
}
fprintf(stderr,
-"InnoDB: Some operating system error numbers are described at\n"
-"InnoDB: "
-"http://dev.mysql.com/doc/refman/5.0/en/operating-system-error-codes.html\n");
+ "InnoDB: Some operating system error numbers"
+ " are described at\n"
+ "InnoDB: "
+ "http://dev.mysql.com/doc/refman/5.1/en/"
+ "operating-system-error-codes.html\n");
os_has_said_disk_full = TRUE;
}
@@ -2437,40 +2466,47 @@ retry:
return(FALSE);
#else
ssize_t ret;
-
+
ret = os_file_pwrite(file, buf, n, offset, offset_high);
-
+
if ((ulint)ret == n) {
return(TRUE);
}
if (!os_has_said_disk_full) {
-
+
ut_print_timestamp(stderr);
fprintf(stderr,
-" InnoDB: Error: Write to file %s failed at offset %lu %lu.\n"
-"InnoDB: %lu bytes should have been written, only %ld were written.\n"
-"InnoDB: Operating system error number %lu.\n"
-"InnoDB: Check that your OS and file system support files of this size.\n"
-"InnoDB: Check also that the disk is not full or a disk quota exceeded.\n",
+ " InnoDB: Error: Write to file %s failed"
+ " at offset %lu %lu.\n"
+ "InnoDB: %lu bytes should have been written,"
+ " only %ld were written.\n"
+ "InnoDB: Operating system error number %lu.\n"
+ "InnoDB: Check that your OS and file system"
+ " support files of this size.\n"
+ "InnoDB: Check also that the disk is not full"
+ " or a disk quota exceeded.\n",
name, offset_high, offset, n, (long int)ret,
- (ulint)errno);
+ (ulint)errno);
if (strerror(errno) != NULL) {
fprintf(stderr,
-"InnoDB: Error number %lu means '%s'.\n", (ulint)errno, strerror(errno));
+ "InnoDB: Error number %lu means '%s'.\n",
+ (ulint)errno, strerror(errno));
}
fprintf(stderr,
-"InnoDB: Some operating system error numbers are described at\n"
-"InnoDB: "
-"http://dev.mysql.com/doc/refman/5.0/en/operating-system-error-codes.html\n");
+ "InnoDB: Some operating system error numbers"
+ " are described at\n"
+ "InnoDB: "
+ "http://dev.mysql.com/doc/refman/5.1/en/"
+ "operating-system-error-codes.html\n");
os_has_said_disk_full = TRUE;
}
- return(FALSE);
+ return(FALSE);
#endif
}
@@ -2481,14 +2517,14 @@ ibool
os_file_status(
/*===========*/
/* out: TRUE if call succeeded */
- const char* path, /* in: pathname of the file */
+ const char* path, /* in: pathname of the file */
ibool* exists, /* out: TRUE if file exists */
os_file_type_t* type) /* out: type of the file (if it exists) */
{
#ifdef __WIN__
int ret;
struct _stat statinfo;
-
+
ret = _stat(path, &statinfo);
if (ret && (errno == ENOENT || errno == ENOTDIR)) {
/* file does not exist */
@@ -2496,27 +2532,27 @@ os_file_status(
return(TRUE);
} else if (ret) {
/* file exists, but stat call failed */
-
+
os_file_handle_error_no_exit(path, "stat");
-
+
return(FALSE);
}
-
+
if (_S_IFDIR & statinfo.st_mode) {
*type = OS_FILE_TYPE_DIR;
} else if (_S_IFREG & statinfo.st_mode) {
- *type = OS_FILE_TYPE_FILE;
+ *type = OS_FILE_TYPE_FILE;
} else {
- *type = OS_FILE_TYPE_UNKNOWN;
+ *type = OS_FILE_TYPE_UNKNOWN;
}
*exists = TRUE;
-
+
return(TRUE);
#else
int ret;
struct stat statinfo;
-
+
ret = stat(path, &statinfo);
if (ret && (errno == ENOENT || errno == ENOTDIR)) {
/* file does not exist */
@@ -2524,24 +2560,24 @@ os_file_status(
return(TRUE);
} else if (ret) {
/* file exists, but stat call failed */
-
+
os_file_handle_error_no_exit(path, "stat");
-
+
return(FALSE);
}
-
+
if (S_ISDIR(statinfo.st_mode)) {
*type = OS_FILE_TYPE_DIR;
} else if (S_ISLNK(statinfo.st_mode)) {
- *type = OS_FILE_TYPE_LINK;
+ *type = OS_FILE_TYPE_LINK;
} else if (S_ISREG(statinfo.st_mode)) {
- *type = OS_FILE_TYPE_FILE;
+ *type = OS_FILE_TYPE_FILE;
} else {
- *type = OS_FILE_TYPE_UNKNOWN;
+ *type = OS_FILE_TYPE_UNKNOWN;
}
*exists = TRUE;
-
+
return(TRUE);
#endif
}
@@ -2551,15 +2587,17 @@ This function returns information about
ibool
os_file_get_status(
-/*===========*/
- /* out: TRUE if stat information found */
- const char* path, /* in: pathname of the file */
- os_file_stat_t* stat_info) /* information of a file in a directory */
+/*===============*/
+ /* out: TRUE if stat
+ information found */
+ const char* path, /* in: pathname of the file */
+ os_file_stat_t* stat_info) /* information of a file in a
+ directory */
{
#ifdef __WIN__
int ret;
struct _stat statinfo;
-
+
ret = _stat(path, &statinfo);
if (ret && (errno == ENOENT || errno == ENOTDIR)) {
/* file does not exist */
@@ -2567,29 +2605,29 @@ os_file_get_status(
return(FALSE);
} else if (ret) {
/* file exists, but stat call failed */
-
+
os_file_handle_error_no_exit(path, "stat");
-
+
return(FALSE);
}
if (_S_IFDIR & statinfo.st_mode) {
stat_info->type = OS_FILE_TYPE_DIR;
} else if (_S_IFREG & statinfo.st_mode) {
- stat_info->type = OS_FILE_TYPE_FILE;
+ stat_info->type = OS_FILE_TYPE_FILE;
} else {
- stat_info->type = OS_FILE_TYPE_UNKNOWN;
+ stat_info->type = OS_FILE_TYPE_UNKNOWN;
}
stat_info->ctime = statinfo.st_ctime;
stat_info->atime = statinfo.st_atime;
stat_info->mtime = statinfo.st_mtime;
- stat_info->size = statinfo.st_size;
-
+ stat_info->size = statinfo.st_size;
+
return(TRUE);
#else
int ret;
struct stat statinfo;
-
+
ret = stat(path, &statinfo);
if (ret && (errno == ENOENT || errno == ENOTDIR)) {
@@ -2598,27 +2636,27 @@ os_file_get_status(
return(FALSE);
} else if (ret) {
/* file exists, but stat call failed */
-
+
os_file_handle_error_no_exit(path, "stat");
-
+
return(FALSE);
}
-
+
if (S_ISDIR(statinfo.st_mode)) {
stat_info->type = OS_FILE_TYPE_DIR;
} else if (S_ISLNK(statinfo.st_mode)) {
- stat_info->type = OS_FILE_TYPE_LINK;
+ stat_info->type = OS_FILE_TYPE_LINK;
} else if (S_ISREG(statinfo.st_mode)) {
- stat_info->type = OS_FILE_TYPE_FILE;
+ stat_info->type = OS_FILE_TYPE_FILE;
} else {
- stat_info->type = OS_FILE_TYPE_UNKNOWN;
+ stat_info->type = OS_FILE_TYPE_UNKNOWN;
}
stat_info->ctime = statinfo.st_ctime;
stat_info->atime = statinfo.st_atime;
stat_info->mtime = statinfo.st_mtime;
- stat_info->size = statinfo.st_size;
-
+ stat_info->size = statinfo.st_size;
+
return(TRUE);
#endif
}
@@ -2644,18 +2682,18 @@ yields a complete pathname.
The return value is a copy of the directory component of the pathname.
The copy is allocated from heap. It is the caller responsibility
-to free it after it is no longer needed.
+to free it after it is no longer needed.
The following list of examples (taken from SUSv2) shows the strings
returned by dirname and basename for different paths:
- path dirname basename
- "/usr/lib" "/usr" "lib"
- "/usr/" "/" "usr"
- "usr" "." "usr"
- "/" "/" "/"
- "." "." "."
- ".." "." ".."
+ path dirname basename
+ "/usr/lib" "/usr" "lib"
+ "/usr/" "/" "usr"
+ "usr" "." "usr"
+ "/" "/" "/"
+ "." "." "."
+ ".." "." ".."
*/
char*
@@ -2685,10 +2723,10 @@ os_file_dirname(
return(mem_strdupl(path, last_slash - path));
}
-
+
/********************************************************************
Creates all missing subdirectories along the given path. */
-
+
ibool
os_file_create_subdirs_if_needed(
/*=============================*/
@@ -2697,7 +2735,7 @@ os_file_create_subdirs_if_needed(
const char* path) /* in: path name */
{
char* subdir;
- ibool success, subdir_exists;
+ ibool success, subdir_exists;
os_file_type_t type;
subdir = os_file_dirname(path);
@@ -2751,32 +2789,32 @@ os_aio_array_create(
/* out, own: aio array */
ulint n, /* in: maximum number of pending aio operations
allowed; n must be divisible by n_segments */
- ulint n_segments) /* in: number of segments in the aio array */
+ ulint n_segments) /* in: number of segments in the aio array */
{
os_aio_array_t* array;
ulint i;
os_aio_slot_t* slot;
#ifdef WIN_ASYNC_IO
OVERLAPPED* over;
-#endif
+#endif
ut_a(n > 0);
ut_a(n_segments > 0);
array = ut_malloc(sizeof(os_aio_array_t));
- array->mutex = os_mutex_create(NULL);
+ array->mutex = os_mutex_create(NULL);
array->not_full = os_event_create(NULL);
array->is_empty = os_event_create(NULL);
os_event_set(array->is_empty);
-
- array->n_slots = n;
+
+ array->n_slots = n;
array->n_segments = n_segments;
array->n_reserved = 0;
array->slots = ut_malloc(n * sizeof(os_aio_slot_t));
#ifdef __WIN__
array->native_events = ut_malloc(n * sizeof(os_native_event_t));
-#endif
+#endif
for (i = 0; i < n; i++) {
slot = os_aio_array_get_nth_slot(array, i);
@@ -2792,7 +2830,7 @@ os_aio_array_create(
*((array->native_events) + i) = over->hEvent;
#endif
}
-
+
return(array);
}
@@ -2828,13 +2866,13 @@ os_aio_init(
os_io_init_simple();
for (i = 0; i < n_segments; i++) {
- srv_set_io_thread_op_info(i, "not started yet");
+ srv_set_io_thread_op_info(i, "not started yet");
}
n_per_seg = n / n_segments;
n_write_segs = (n_segments - 2) / 2;
n_read_segs = n_segments - 2 - n_write_segs;
-
+
/* fprintf(stderr, "Array n per seg %lu\n", n_per_seg); */
os_aio_ibuf_array = os_aio_array_create(n_per_seg, 1);
@@ -2846,17 +2884,17 @@ os_aio_init(
srv_io_thread_function[1] = "log thread";
os_aio_read_array = os_aio_array_create(n_read_segs * n_per_seg,
- n_read_segs);
+ n_read_segs);
for (i = 2; i < 2 + n_read_segs; i++) {
ut_a(i < SRV_MAX_N_IO_THREADS);
- srv_io_thread_function[i] = "read thread";
+ srv_io_thread_function[i] = "read thread";
}
os_aio_write_array = os_aio_array_create(n_write_segs * n_per_seg,
- n_write_segs);
+ n_write_segs);
for (i = 2 + n_read_segs; i < n_segments; i++) {
ut_a(i < SRV_MAX_N_IO_THREADS);
- srv_io_thread_function[i] = "write thread";
+ srv_io_thread_function[i] = "write thread";
}
os_aio_sync_array = os_aio_array_create(n_slots_sync, 1);
@@ -2878,10 +2916,10 @@ os_aio_init(
for this to work, the current thread must be the first created
in the database, so that all its children will inherit its
signal mask */
-
+
/* TODO: to work MySQL needs the SIGALARM signal; the following
will not work yet! */
- sigemptyset(&sigset);
+ sigemptyset(&sigset);
sigaddset(&sigset, SIGRTMIN + 1 + 0);
sigaddset(&sigset, SIGRTMIN + 1 + 1);
sigaddset(&sigset, SIGRTMIN + 1 + 2);
@@ -2889,7 +2927,7 @@ os_aio_init(
pthread_sigmask(SIG_BLOCK, &sigset, NULL); */
#endif
-}
+ }
#ifdef WIN_ASYNC_IO
/****************************************************************************
@@ -2905,7 +2943,7 @@ os_aio_array_wake_win_aio_at_shutdown(
for (i = 0; i < array->n_slots; i++) {
- os_event_set((array->slots + i)->event);
+ os_event_set((array->slots + i)->event);
}
}
#endif
@@ -2921,7 +2959,7 @@ os_aio_wake_all_threads_at_shutdown(void
ulint i;
#ifdef WIN_ASYNC_IO
- /* This code wakes up all ai/o threads in Windows native aio */
+ /* This code wakes up all ai/o threads in Windows native aio */
os_aio_array_wake_win_aio_at_shutdown(os_aio_read_array);
os_aio_array_wake_win_aio_at_shutdown(os_aio_write_array);
os_aio_array_wake_win_aio_at_shutdown(os_aio_ibuf_array);
@@ -2930,11 +2968,11 @@ os_aio_wake_all_threads_at_shutdown(void
/* This loop wakes up all simulated ai/o threads */
for (i = 0; i < os_aio_n_segments; i++) {
-
+
os_event_set(os_aio_segment_wait_events[i]);
- }
+ }
}
-
+
/****************************************************************************
Waits until there are no pending writes in os_aio_write_array. There can
be other, synchronous, pending writes. */
@@ -2965,19 +3003,19 @@ os_aio_get_segment_no_from_slot(
} else if (array == os_aio_log_array) {
segment = 1;
-
+
} else if (array == os_aio_read_array) {
- seg_len = os_aio_read_array->n_slots /
- os_aio_read_array->n_segments;
+ seg_len = os_aio_read_array->n_slots
+ / os_aio_read_array->n_segments;
segment = 2 + slot->pos / seg_len;
} else {
ut_a(array == os_aio_write_array);
- seg_len = os_aio_write_array->n_slots /
- os_aio_write_array->n_segments;
+ seg_len = os_aio_write_array->n_slots
+ / os_aio_write_array->n_segments;
segment = os_aio_read_array->n_segments + 2
- + slot->pos / seg_len;
+ + slot->pos / seg_len;
}
return(segment);
@@ -2996,7 +3034,7 @@ os_aio_get_array_and_local_segment(
{
ulint segment;
- ut_a(global_segment < os_aio_n_segments);
+ ut_a(global_segment < os_aio_n_segments);
if (global_segment == 0) {
*array = os_aio_ibuf_array;
@@ -3005,7 +3043,7 @@ os_aio_get_array_and_local_segment(
} else if (global_segment == 1) {
*array = os_aio_log_array;
segment = 0;
-
+
} else if (global_segment < os_aio_read_array->n_segments + 2) {
*array = os_aio_read_array;
@@ -3029,9 +3067,9 @@ ulint
os_aio_get_array_no(
/*================*/
os_aio_array_t* array) /* in: aio array */
-{
+{
if (array == os_aio_ibuf_array) {
-
+
return(0);
} else if (array == os_aio_log_array) {
@@ -3059,7 +3097,7 @@ os_aio_get_array_from_no(
/*=====================*/
/* out: aio array */
ulint n) /* in: array number */
-{
+{
if (n == 0) {
return(os_aio_ibuf_array);
} else if (n == 1) {
@@ -3125,7 +3163,7 @@ loop:
os_aio_simulated_wake_handler_threads();
}
-
+
os_event_wait(array->not_full);
goto loop;
@@ -3148,7 +3186,7 @@ loop:
if (array->n_reserved == array->n_slots) {
os_event_reset(array->not_full);
}
-
+
slot->reserved = TRUE;
slot->reservation_time = time(NULL);
slot->message1 = message1;
@@ -3161,8 +3199,8 @@ loop:
slot->offset = offset;
slot->offset_high = offset_high;
slot->io_already_done = FALSE;
-
-#ifdef WIN_ASYNC_IO
+
+#ifdef WIN_ASYNC_IO
control = &(slot->control);
control->Offset = (DWORD)offset;
control->OffsetHigh = (DWORD)offset_high;
@@ -3174,7 +3212,7 @@ loop:
offset = offset + (offset_high << 32);
#else
ut_a(offset_high == 0);
-#endif
+#endif
control = &(slot->control);
control->aio_fildes = file;
control->aio_buf = buf;
@@ -3182,13 +3220,13 @@ loop:
control->aio_offset = offset;
control->aio_reqprio = 0;
control->aio_sigevent.sigev_notify = SIGEV_SIGNAL;
- control->aio_sigevent.sigev_signo =
- SIGRTMIN + 1 + os_aio_get_array_no(array);
- /* TODO: How to choose the signal numbers? */
-/*
+ control->aio_sigevent.sigev_signo
+ = SIGRTMIN + 1 + os_aio_get_array_no(array);
+ /* TODO: How to choose the signal numbers? */
+ /*
fprintf(stderr, "AIO signal number %lu\n",
- (ulint) control->aio_sigevent.sigev_signo);
-*/
+ (ulint) control->aio_sigevent.sigev_signo);
+ */
control->aio_sigevent.sigev_value.sival_ptr = slot;
#endif
os_mutex_exit(array->mutex);
@@ -3211,7 +3249,7 @@ os_aio_array_free_slot(
os_mutex_enter(array->mutex);
ut_ad(slot->reserved);
-
+
slot->reserved = FALSE;
array->n_reserved--;
@@ -3224,7 +3262,7 @@ os_aio_array_free_slot(
os_event_set(array->is_empty);
}
-#ifdef WIN_ASYNC_IO
+#ifdef WIN_ASYNC_IO
os_event_reset(slot->event);
#endif
os_mutex_exit(array->mutex);
@@ -3260,7 +3298,7 @@ os_aio_simulated_wake_handler_thread(
if (slot->reserved) {
/* Found an i/o request */
-
+
break;
}
}
@@ -3285,7 +3323,7 @@ os_aio_simulated_wake_handler_threads(vo
/* We do not use simulated aio: do nothing */
return;
- }
+ }
os_aio_recommend_sleep_for_read_threads = FALSE;
@@ -3313,7 +3351,7 @@ os_aio_simulated_put_read_threads_to_sle
os_aio_get_array_and_local_segment(&array, g);
if (array == os_aio_read_array) {
-
+
os_event_reset(os_aio_segment_wait_events[g]);
}
}
@@ -3380,12 +3418,12 @@ os_aio(
wake_later = mode & OS_AIO_SIMULATED_WAKE_LATER;
mode = mode & (~OS_AIO_SIMULATED_WAKE_LATER);
-
+
if (mode == OS_AIO_SYNC
#ifdef WIN_ASYNC_IO
- && !os_aio_use_native_aio
+ && !os_aio_use_native_aio
#endif
- ) {
+ ) {
/* This is actually an ordinary synchronous read or write:
no need to use an i/o-handler thread. NOTE that if we use
Windows async i/o, Windows does not allow us to use
@@ -3395,7 +3433,7 @@ os_aio(
if (type == OS_FILE_READ) {
return(os_file_read(file, buf, offset,
- offset_high, n));
+ offset_high, n));
}
ut_a(type == OS_FILE_WRITE);
@@ -3427,17 +3465,17 @@ try_again:
array = NULL; /* Eliminate compiler warning */
ut_error;
}
-
+
slot = os_aio_array_reserve_slot(type, array, message1, message2, file,
- name, buf, offset, offset_high, n);
+ name, buf, offset, offset_high, n);
if (type == OS_FILE_READ) {
if (os_aio_use_native_aio) {
#ifdef WIN_ASYNC_IO
os_n_file_reads++;
os_bytes_read_since_printout += len;
-
+
ret = ReadFile(file, buf, (DWORD)n, &len,
- &(slot->control));
+ &(slot->control));
#elif defined(POSIX_ASYNC_IO)
slot->control.aio_lio_opcode = LIO_READ;
err = (ulint) aio_read(&(slot->control));
@@ -3446,7 +3484,8 @@ try_again:
} else {
if (!wake_later) {
os_aio_simulated_wake_handler_thread(
- os_aio_get_segment_no_from_slot(array, slot));
+ os_aio_get_segment_no_from_slot(
+ array, slot));
}
}
} else if (type == OS_FILE_WRITE) {
@@ -3454,7 +3493,7 @@ try_again:
#ifdef WIN_ASYNC_IO
os_n_file_writes++;
ret = WriteFile(file, buf, (DWORD)n, &len,
- &(slot->control));
+ &(slot->control));
#elif defined(POSIX_ASYNC_IO)
slot->control.aio_lio_opcode = LIO_WRITE;
err = (ulint) aio_write(&(slot->control));
@@ -3463,7 +3502,8 @@ try_again:
} else {
if (!wake_later) {
os_aio_simulated_wake_handler_thread(
- os_aio_get_segment_no_from_slot(array, slot));
+ os_aio_get_segment_no_from_slot(
+ array, slot));
}
}
} else {
@@ -3475,19 +3515,21 @@ try_again:
if ((ret && len == n)
|| (!ret && GetLastError() == ERROR_IO_PENDING)) {
/* aio was queued successfully! */
-
- if (mode == OS_AIO_SYNC) {
- /* We want a synchronous i/o operation on a file
- where we also use async i/o: in Windows we must
- use the same wait mechanism as for async i/o */
-
- retval = os_aio_windows_handle(ULINT_UNDEFINED,
- slot->pos,
- &dummy_mess1, &dummy_mess2,
- &dummy_type);
- return(retval);
- }
+ if (mode == OS_AIO_SYNC) {
+ /* We want a synchronous i/o operation on a
+ file where we also use async i/o: in Windows
+ we must use the same wait mechanism as for
+ async i/o */
+
+ retval = os_aio_windows_handle(ULINT_UNDEFINED,
+ slot->pos,
+ &dummy_mess1,
+ &dummy_mess2,
+ &dummy_type);
+
+ return(retval);
+ }
return(TRUE);
}
@@ -3504,11 +3546,12 @@ try_again:
os_aio_array_free_slot(array, slot);
retry = os_file_handle_error(name,
- type == OS_FILE_READ ? "aio read" : "aio write");
+ type == OS_FILE_READ
+ ? "aio read" : "aio write");
if (retry) {
goto try_again;
- }
+ }
return(FALSE);
}
@@ -3535,7 +3578,7 @@ os_aio_windows_handle(
sync aio is used, and this parameter is
ignored */
ulint pos, /* this parameter is used only in sync aio:
- wait for the aio slot at this position */
+ wait for the aio slot at this position */
fil_node_t**message1, /* out: the messages passed with the aio
request; note that also in the case where
the aio operation failed, these output
@@ -3559,7 +3602,7 @@ os_aio_windows_handle(
} else {
segment = os_aio_get_array_and_local_segment(&array, segment);
}
-
+
/* NOTE! We only access constant fields in os_aio_array. Therefore
we do not have to acquire the protecting mutex yet */
@@ -3574,7 +3617,8 @@ os_aio_windows_handle(
} else {
srv_set_io_thread_op_info(orig_seg, "wait Windows aio");
i = os_event_wait_multiple(n,
- (array->native_events) + segment * n);
+ (array->native_events)
+ + segment * n);
}
os_mutex_enter(array->mutex);
@@ -3585,7 +3629,7 @@ os_aio_windows_handle(
if (orig_seg != ULINT_UNDEFINED) {
srv_set_io_thread_op_info(orig_seg,
- "get windows aio return value");
+ "get windows aio return value");
}
ret = GetOverlappedResult(slot->file, &(slot->control), &len, TRUE);
@@ -3600,20 +3644,20 @@ os_aio_windows_handle(
# ifdef UNIV_DO_FLUSH
if (slot->type == OS_FILE_WRITE
- && !os_do_not_call_flush_at_each_write) {
- ut_a(TRUE == os_file_flush(slot->file));
+ && !os_do_not_call_flush_at_each_write) {
+ ut_a(TRUE == os_file_flush(slot->file));
}
# endif /* UNIV_DO_FLUSH */
} else {
os_file_handle_error(slot->name, "Windows aio");
-
+
ret_val = FALSE;
- }
+ }
os_mutex_exit(array->mutex);
os_aio_array_free_slot(array, slot);
-
+
return(ret_val);
}
#endif
@@ -3640,37 +3684,37 @@ os_aio_posix_handle(
os_aio_slot_t* slot;
siginfo_t info;
sigset_t sigset;
- sigset_t proc_sigset;
- sigset_t thr_sigset;
+ sigset_t proc_sigset;
+ sigset_t thr_sigset;
int ret;
- int i;
- int sig;
-
- sigemptyset(&sigset);
+ int i;
+ int sig;
+
+ sigemptyset(&sigset);
sigaddset(&sigset, SIGRTMIN + 1 + array_no);
pthread_sigmask(SIG_UNBLOCK, &sigset, NULL);
- /*
+#if 0
sigprocmask(0, NULL, &proc_sigset);
pthread_sigmask(0, NULL, &thr_sigset);
for (i = 32 ; i < 40; i++) {
fprintf(stderr, "%lu : %lu %lu\n", (ulint)i,
- (ulint)sigismember(&proc_sigset, i),
- (ulint)sigismember(&thr_sigset, i));
+ (ulint) sigismember(&proc_sigset, i),
+ (ulint) sigismember(&thr_sigset, i));
}
- */
+#endif
ret = sigwaitinfo(&sigset, &info);
if (sig != SIGRTMIN + 1 + array_no) {
ut_error;
-
+
return(FALSE);
}
-
+
fputs("Handling POSIX aio\n", stderr);
array = os_aio_get_array_from_no(array_no);
@@ -3686,7 +3730,7 @@ os_aio_posix_handle(
# ifdef UNIV_DO_FLUSH
if (slot->type == OS_FILE_WRITE
- && !os_do_not_call_flush_at_each_write) {
+ && !os_do_not_call_flush_at_each_write) {
ut_a(TRUE == os_file_flush(slot->file));
}
# endif /* UNIV_DO_FLUSH */
@@ -3694,7 +3738,7 @@ os_aio_posix_handle(
os_mutex_exit(array->mutex);
os_aio_array_free_slot(array, slot);
-
+
return(TRUE);
}
#endif
@@ -3713,19 +3757,24 @@ os_file_check_page_trailers(
ulint len;
for (len = 0; len + UNIV_PAGE_SIZE <= total_len;
- len += UNIV_PAGE_SIZE) {
+ len += UNIV_PAGE_SIZE) {
byte* buf = combined_buf + len;
- if (memcmp(buf + (FIL_PAGE_LSN + 4), buf + (UNIV_PAGE_SIZE
- - FIL_PAGE_END_LSN_OLD_CHKSUM + 4), 4)) {
+ if (UNIV_UNLIKELY
+ (memcmp(buf + (FIL_PAGE_LSN + 4),
+ buf + (UNIV_PAGE_SIZE
+ - FIL_PAGE_END_LSN_OLD_CHKSUM + 4), 4))) {
ut_print_timestamp(stderr);
fprintf(stderr,
-" InnoDB: ERROR: The page to be written seems corrupt!\n"
-"InnoDB: Writing a block of %lu bytes, currently at offset %lu\n",
- (ulong)total_len, (ulong)len);
+ " InnoDB: ERROR: The page to be written"
+ " seems corrupt!\n"
+ "InnoDB: Writing a block of %lu bytes,"
+ " currently at offset %lu\n",
+ (ulong)total_len, (ulong)len);
buf_page_print(buf);
fprintf(stderr,
-"InnoDB: ERROR: The page to be written seems corrupt!\n");
+ "InnoDB: ERROR: The page to be written"
+ " seems corrupt!\n");
}
}
}
@@ -3767,15 +3816,15 @@ os_aio_simulated_handle(
ibool ret;
ulint n;
ulint i;
-
+
segment = os_aio_get_array_and_local_segment(&array, global_segment);
-
+
restart:
/* NOTE! We only access constant fields in os_aio_array. Therefore
we do not have to acquire the protecting mutex yet */
srv_set_io_thread_op_info(global_segment,
- "looking for i/o requests (a)");
+ "looking for i/o requests (a)");
ut_ad(os_aio_validate());
ut_ad(segment < array->n_segments);
@@ -3791,15 +3840,15 @@ restart:
goto recommended_sleep;
}
-
+
os_mutex_enter(array->mutex);
srv_set_io_thread_op_info(global_segment,
- "looking for i/o requests (b)");
+ "looking for i/o requests (b)");
/* Check if there is a slot for which the i/o has already been
done */
-
+
for (i = 0; i < n; i++) {
slot = os_aio_array_get_nth_slot(array, i + segment * n);
@@ -3807,11 +3856,13 @@ restart:
if (os_aio_print_debug) {
fprintf(stderr,
-"InnoDB: i/o for slot %lu already done, returning\n", (ulong) i);
+ "InnoDB: i/o for slot %lu"
+ " already done, returning\n",
+ (ulong) i);
}
ret = TRUE;
-
+
goto slot_io_done;
}
}
@@ -3829,14 +3880,14 @@ restart:
slot = os_aio_array_get_nth_slot(array, i + segment * n);
if (slot->reserved) {
- age = (ulint)difftime(time(NULL),
- slot->reservation_time);
+ age = (ulint)difftime(time(NULL),
+ slot->reservation_time);
if ((age >= 2 && age > biggest_age)
|| (age >= 2 && age == biggest_age
- && slot->offset < lowest_offset)) {
+ && slot->offset < lowest_offset)) {
- /* Found an i/o request */
+ /* Found an i/o request */
consecutive_ios[0] = slot;
n_consecutive = 1;
@@ -3848,19 +3899,19 @@ restart:
}
if (n_consecutive == 0) {
- /* There were no old requests. Look for an i/o request at the
+ /* There were no old requests. Look for an i/o request at the
lowest offset in the array (we ignore the high 32 bits of the
offset in these heuristics) */
lowest_offset = ULINT_MAX;
-
+
for (i = 0; i < n; i++) {
- slot = os_aio_array_get_nth_slot(array,
- i + segment * n);
+ slot = os_aio_array_get_nth_slot(array,
+ i + segment * n);
if (slot->reserved && slot->offset < lowest_offset) {
- /* Found an i/o request */
+ /* Found an i/o request */
consecutive_ios[0] = slot;
n_consecutive = 1;
@@ -3881,14 +3932,14 @@ restart:
/* Check if there are several consecutive blocks to read or write */
-consecutive_loop:
+consecutive_loop:
for (i = 0; i < n; i++) {
slot2 = os_aio_array_get_nth_slot(array, i + segment * n);
if (slot2->reserved && slot2 != slot
&& slot2->offset == slot->offset + slot->len
- && slot->offset + slot->len > slot->offset /* check that
- sum does not wrap over */
+ /* check that sum does not wrap over */
+ && slot->offset + slot->len > slot->offset
&& slot2->offset_high == slot->offset_high
&& slot2->type == slot->type
&& slot2->file == slot->file) {
@@ -3901,7 +3952,7 @@ consecutive_loop:
slot = slot2;
if (n_consecutive < OS_AIO_MERGE_N_CONSECUTIVE) {
-
+
goto consecutive_loop;
} else {
break;
@@ -3917,7 +3968,7 @@ consecutive_loop:
total_len = 0;
slot = consecutive_ios[0];
-
+
for (i = 0; i < n_consecutive; i++) {
total_len += consecutive_ios[i]->len;
}
@@ -3933,7 +3984,7 @@ consecutive_loop:
combined_buf = ut_align(combined_buf2, UNIV_PAGE_SIZE);
}
-
+
/* We release the array mutex for the time of the i/o: NOTE that
this assumes that there is just one i/o-handler thread serving
a single segment of slots! */
@@ -3943,20 +3994,21 @@ consecutive_loop:
if (slot->type == OS_FILE_WRITE && n_consecutive > 1) {
/* Copy the buffers to the combined buffer */
offs = 0;
-
+
for (i = 0; i < n_consecutive; i++) {
ut_memcpy(combined_buf + offs, consecutive_ios[i]->buf,
- consecutive_ios[i]->len);
+ consecutive_ios[i]->len);
offs += consecutive_ios[i]->len;
}
}
-
+
srv_set_io_thread_op_info(global_segment, "doing file i/o");
if (os_aio_print_debug) {
fprintf(stderr,
-"InnoDB: doing i/o of type %lu at offset %lu %lu, length %lu\n",
+ "InnoDB: doing i/o of type %lu at offset %lu %lu,"
+ " length %lu\n",
(ulong) slot->type, (ulong) slot->offset_high,
(ulong) slot->offset, (ulong) total_len);
}
@@ -3967,7 +4019,8 @@ consecutive_loop:
if ((total_len % UNIV_PAGE_SIZE != 0)
|| (slot->offset % UNIV_PAGE_SIZE != 0)) {
fprintf(stderr,
-"InnoDB: Error: trying a displaced write to %s %lu %lu, len %lu\n",
+ "InnoDB: Error: trying a displaced"
+ " write to %s %lu %lu, len %lu\n",
slot->name, (ulong) slot->offset_high,
(ulong) slot->offset,
(ulong) total_len);
@@ -3978,31 +4031,34 @@ consecutive_loop:
}
ret = os_file_write(slot->name, slot->file, combined_buf,
- slot->offset, slot->offset_high, total_len);
+ slot->offset, slot->offset_high,
+ total_len);
if (array == os_aio_write_array) {
os_file_check_page_trailers(combined_buf, total_len);
}
} else {
ret = os_file_read(slot->file, combined_buf,
- slot->offset, slot->offset_high, total_len);
+ slot->offset, slot->offset_high, total_len);
}
ut_a(ret);
srv_set_io_thread_op_info(global_segment, "file i/o done");
-/* fprintf(stderr,
- "aio: %lu consecutive %lu:th segment, first offs %lu blocks\n",
- n_consecutive, global_segment, slot->offset / UNIV_PAGE_SIZE); */
+#if 0
+ fprintf(stderr,
+ "aio: %lu consecutive %lu:th segment, first offs %lu blocks\n",
+ n_consecutive, global_segment, slot->offset / UNIV_PAGE_SIZE);
+#endif
if (slot->type == OS_FILE_READ && n_consecutive > 1) {
/* Copy the combined buffer to individual buffers */
offs = 0;
-
+
for (i = 0; i < n_consecutive; i++) {
- ut_memcpy(consecutive_ios[i]->buf, combined_buf + offs,
- consecutive_ios[i]->len);
+ ut_memcpy(consecutive_ios[i]->buf, combined_buf + offs,
+ consecutive_ios[i]->len);
offs += consecutive_ios[i]->len;
}
}
@@ -4022,7 +4078,7 @@ consecutive_loop:
/* We return the messages for the first slot now, and if there were
several slots, the messages will be returned with subsequent calls
of this function */
-
+
slot_io_done:
ut_a(slot->reserved);
@@ -4035,7 +4091,7 @@ slot_io_done:
os_mutex_exit(array->mutex);
os_aio_array_free_slot(array, slot);
-
+
return(ret);
wait_for_io:
@@ -4043,7 +4099,7 @@ wait_for_io:
/* We wait here until there again can be i/os in the segment
of this thread */
-
+
os_event_reset(os_aio_segment_wait_events[global_segment]);
os_mutex_exit(array->mutex);
@@ -4055,10 +4111,11 @@ recommended_sleep:
if (os_aio_print_debug) {
fprintf(stderr,
-"InnoDB: i/o handler thread for i/o segment %lu wakes up\n",
+ "InnoDB: i/o handler thread for i/o"
+ " segment %lu wakes up\n",
(ulong) global_segment);
}
-
+
goto restart;
}
@@ -4074,17 +4131,17 @@ os_aio_array_validate(
os_aio_slot_t* slot;
ulint n_reserved = 0;
ulint i;
-
+
ut_a(array);
os_mutex_enter(array->mutex);
ut_a(array->n_slots > 0);
ut_a(array->n_segments > 0);
-
+
for (i = 0; i < array->n_slots; i++) {
slot = os_aio_array_get_nth_slot(array, i);
-
+
if (slot->reserved) {
n_reserved++;
ut_a(slot->len > 0);
@@ -4133,15 +4190,15 @@ os_aio_print(
for (i = 0; i < srv_n_file_io_threads; i++) {
fprintf(file, "I/O thread %lu state: %s (%s)", (ulong) i,
- srv_io_thread_op_info[i],
- srv_io_thread_function[i]);
+ srv_io_thread_op_info[i],
+ srv_io_thread_function[i]);
#ifndef __WIN__
- if (os_aio_segment_wait_events[i]->is_set) {
+ if (os_aio_segment_wait_events[i]->is_set) {
fprintf(file, " ev set");
}
#endif
-
+
fprintf(file, "\n");
}
@@ -4150,21 +4207,24 @@ os_aio_print(
array = os_aio_read_array;
loop:
ut_a(array);
-
+
os_mutex_enter(array->mutex);
ut_a(array->n_slots > 0);
ut_a(array->n_segments > 0);
-
+
n_reserved = 0;
for (i = 0; i < array->n_slots; i++) {
slot = os_aio_array_get_nth_slot(array, i);
-
+
if (slot->reserved) {
n_reserved++;
- /* fprintf(stderr, "Reserved slot, messages %p %p\n",
- slot->message1, slot->message2); */
+#if 0
+ fprintf(stderr, "Reserved slot, messages %p %p\n",
+ (void*) slot->message1,
+ (void*) slot->message2);
+#endif
ut_a(slot->len > 0);
}
}
@@ -4172,12 +4232,12 @@ loop:
ut_a(array->n_reserved == n_reserved);
fprintf(file, " %lu", (ulong) n_reserved);
-
+
os_mutex_exit(array->mutex);
if (array == os_aio_read_array) {
fputs(", aio writes:", file);
-
+
array = os_aio_write_array;
goto loop;
@@ -4218,20 +4278,21 @@ loop:
if (os_file_n_pending_preads != 0 || os_file_n_pending_pwrites != 0) {
fprintf(file,
- "%lu pending preads, %lu pending pwrites\n",
- (ulong) os_file_n_pending_preads,
- (ulong) os_file_n_pending_pwrites);
+ "%lu pending preads, %lu pending pwrites\n",
+ (ulong) os_file_n_pending_preads,
+ (ulong) os_file_n_pending_pwrites);
}
if (os_n_file_reads == os_n_file_reads_old) {
avg_bytes_read = 0.0;
} else {
- avg_bytes_read = (double) os_bytes_read_since_printout /
- (os_n_file_reads - os_n_file_reads_old);
+ avg_bytes_read = (double) os_bytes_read_since_printout
+ / (os_n_file_reads - os_n_file_reads_old);
}
fprintf(file,
-"%.2f reads/s, %lu avg bytes/read, %.2f writes/s, %.2f fsyncs/s\n",
+ "%.2f reads/s, %lu avg bytes/read,"
+ " %.2f writes/s, %.2f fsyncs/s\n",
(os_n_file_reads - os_n_file_reads_old)
/ time_elapsed,
(ulong)avg_bytes_read,
@@ -4244,7 +4305,7 @@ loop:
os_n_file_writes_old = os_n_file_writes;
os_n_fsyncs_old = os_n_fsyncs;
os_bytes_read_since_printout = 0;
-
+
os_last_printout = current_time;
}
@@ -4259,7 +4320,7 @@ os_aio_refresh_stats(void)
os_n_file_writes_old = os_n_file_writes;
os_n_fsyncs_old = os_n_fsyncs;
os_bytes_read_since_printout = 0;
-
+
os_last_printout = time(NULL);
}
@@ -4275,45 +4336,45 @@ os_aio_all_slots_free(void)
{
os_aio_array_t* array;
ulint n_res = 0;
-
+
array = os_aio_read_array;
os_mutex_enter(array->mutex);
- n_res += array->n_reserved;
-
+ n_res += array->n_reserved;
+
os_mutex_exit(array->mutex);
array = os_aio_write_array;
os_mutex_enter(array->mutex);
- n_res += array->n_reserved;
-
+ n_res += array->n_reserved;
+
os_mutex_exit(array->mutex);
array = os_aio_ibuf_array;
os_mutex_enter(array->mutex);
- n_res += array->n_reserved;
-
+ n_res += array->n_reserved;
+
os_mutex_exit(array->mutex);
array = os_aio_log_array;
os_mutex_enter(array->mutex);
- n_res += array->n_reserved;
-
+ n_res += array->n_reserved;
+
os_mutex_exit(array->mutex);
array = os_aio_sync_array;
os_mutex_enter(array->mutex);
- n_res += array->n_reserved;
-
+ n_res += array->n_reserved;
+
os_mutex_exit(array->mutex);
if (n_res == 0) {
--- 1.13.2.1/innobase/row/row0undo.c 2007-03-28 16:21:24 -06:00
+++ 1.19/storage/innobase/row/row0undo.c 2007-03-28 17:08:08 -06:00
@@ -159,30 +159,31 @@ row_undo_search_clust_to_pcur(
mtr_start(&mtr);
clust_index = dict_table_get_first_index(node->table);
-
+
found = row_search_on_row_ref(&(node->pcur), BTR_MODIFY_LEAF,
- node->table, node->ref, &mtr);
+ node->table, node->ref, &mtr);
rec = btr_pcur_get_rec(&(node->pcur));
offsets = rec_get_offsets(rec, clust_index, offsets,
- ULINT_UNDEFINED, &heap);
+ ULINT_UNDEFINED, &heap);
if (!found || 0 != ut_dulint_cmp(node->roll_ptr,
- row_get_rec_roll_ptr(rec, clust_index, offsets))) {
+ row_get_rec_roll_ptr(rec, clust_index,
+ offsets))) {
/* We must remove the reservation on the undo log record
BEFORE releasing the latch on the clustered index page: this
is to make sure that some thread will eventually undo the
modification corresponding to node->roll_ptr. */
-
+
/* fputs("--------------------undoing a previous version\n",
- stderr); */
-
+ stderr); */
+
ret = FALSE;
} else {
node->row = row_build(ROW_COPY_DATA, clust_index, rec,
- offsets, node->heap);
+ offsets, node->heap);
btr_pcur_store_position(&(node->pcur), &mtr);
ret = TRUE;
@@ -195,7 +196,7 @@ row_undo_search_clust_to_pcur(
}
return(ret);
}
-
+
/***************************************************************
Fetches an undo log record and does the undo for the recorded operation.
If none left, or a partial rollback completed, returns control to the
@@ -213,17 +214,17 @@ row_undo(
trx_t* trx;
dulint roll_ptr;
ibool locked_data_dict;
-
+
ut_ad(node && thr);
-
+
trx = node->trx;
if (node->state == UNDO_NODE_FETCH_NEXT) {
node->undo_rec = trx_roll_pop_top_rec_of_trx(trx,
- trx->roll_limit,
- &roll_ptr,
- node->heap);
+ trx->roll_limit,
+ &roll_ptr,
+ node->heap);
if (!node->undo_rec) {
/* Rollback completed for this query thread */
@@ -248,12 +249,12 @@ row_undo(
again in this same rollback, restoring the previous version */
roll_ptr = node->new_roll_ptr;
-
+
node->undo_rec = trx_undo_get_undo_rec_low(roll_ptr,
- node->heap);
+ node->heap);
node->roll_ptr = roll_ptr;
node->undo_no = trx_undo_rec_get_undo_no(node->undo_rec);
-
+
if (trx_undo_roll_ptr_is_insert(roll_ptr)) {
node->state = UNDO_NODE_INSERT;
@@ -293,7 +294,7 @@ row_undo(
btr_pcur_close(&(node->pcur));
mem_heap_empty(node->heap);
-
+
thr->run_node = node;
return(err);
@@ -316,9 +317,9 @@ row_undo_step(
ut_ad(thr);
srv_activity_count++;
-
+
trx = thr_get_trx(thr);
-
+
node = thr->run_node;
ut_ad(que_node_get_type(node) == QUE_NODE_UNDO);
@@ -335,16 +336,17 @@ row_undo_step(
if (err == DB_OUT_OF_FILE_SPACE) {
fprintf(stderr,
- "InnoDB: Error 13 means out of tablespace.\n"
- "InnoDB: Consider increasing your tablespace.\n");
+ "InnoDB: Error 13 means out of tablespace.\n"
+ "InnoDB: Consider increasing"
+ " your tablespace.\n");
- exit(1);
+ exit(1);
}
-
+
ut_error;
return(NULL);
}
return(thr);
-}
+}
| Thread |
|---|
| • bk commit into 5.1 tree (tsmith:1.2528) | tim | 29 Mar |