From c862fda196126a324f70319ab167eecc68b18a09 Mon Sep 17 00:00:00 2001 From: "vva@eagle.mysql.r18.ru" <> Date: Fri, 19 Mar 2004 18:38:25 +0400 Subject: [PATCH 01/28] fixed bug #3200 "cannot compile with pstack" as downgrade of patch for bug #1661 "Compiling --with-pstack fails with binutils 2.13.90" --- pstack/bucomm.h | 6 ++++++ pstack/budbg.h | 6 ++++++ pstack/pstack.c | 3 ++- 3 files changed, 14 insertions(+), 1 deletion(-) diff --git a/pstack/bucomm.h b/pstack/bucomm.h index 7712a70f5a2..6b3633d8d63 100644 --- a/pstack/bucomm.h +++ b/pstack/bucomm.h @@ -50,6 +50,12 @@ void *alloca (); # endif /* HAVE_ALLOCA_H */ #endif +#ifndef BFD_TRUE_FALSE +#define boolean bfd_boolean +#define true TRUE +#define false FALSE +#endif + /* bucomm.c */ void bfd_nonfatal PARAMS ((CONST char *)); diff --git a/pstack/budbg.h b/pstack/budbg.h index d8ee8895e76..9f0203ad5e7 100644 --- a/pstack/budbg.h +++ b/pstack/budbg.h @@ -24,6 +24,12 @@ #include +#ifndef BFD_TRUE_FALSE +#define boolean bfd_boolean +#define true TRUE +#define false FALSE +#endif + /* Routine used to read generic debugging information. */ extern PTR read_debugging_info PARAMS ((bfd *, asymbol **, long)); diff --git a/pstack/pstack.c b/pstack/pstack.c index 48280d4aedb..5c6e2baf909 100644 --- a/pstack/pstack.c +++ b/pstack/pstack.c @@ -2667,7 +2667,8 @@ pstack_install_segv_action( const char* path_format_) if ((abfd = load_bfd(pid))==0) fprintf(stderr, "BFD load failed..\n"); else { - long storage_needed = bfd_get_symtab_upper_bound (abfd); + long storage_needed= (bfd_get_file_flags(abfd) & HAS_SYMS) ? + bfd_get_symtab_upper_bound (abfd) : 0; long i; (void)i; From 9832571c1efaf060ed0e33e55ef93f34cebe931f Mon Sep 17 00:00:00 2001 From: "gluh@gluh.mysql.r18.ru" <> Date: Mon, 29 Mar 2004 18:10:59 +0500 Subject: [PATCH 02/28] Fix bug #3181: insert_test client test missing mysql_init --- client/insert_test.c | 1 + 1 file changed, 1 insertion(+) diff --git a/client/insert_test.c b/client/insert_test.c index 42691df6875..052c12bfdf0 100644 --- a/client/insert_test.c +++ b/client/insert_test.c @@ -33,6 +33,7 @@ int main(int argc, char **argv) exit(1); } + mysql_init(&mysql); if (!(sock = mysql_real_connect(&mysql,NULL,NULL,NULL,argv[1],0,NULL,0))) { fprintf(stderr,"Couldn't connect to engine!\n%s\n",mysql_error(&mysql)); From 2ff3f487aa23a03eb65cb07df28350f46b9acc78 Mon Sep 17 00:00:00 2001 From: "Sinisa@sinisa.nasamreza.org" <> Date: Tue, 30 Mar 2004 13:50:00 +0300 Subject: [PATCH 03/28] A fix for the error message when database can not be dropped due to the extra files being present. --- sql/sql_db.cc | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/sql/sql_db.cc b/sql/sql_db.cc index 1217a909071..d91fdbaded0 100644 --- a/sql/sql_db.cc +++ b/sql/sql_db.cc @@ -325,7 +325,12 @@ static long mysql_rm_known_files(THD *thd, MY_DIR *dirp, const char *db, If the directory is a symbolic link, remove the link first, then remove the directory the symbolic link pointed at */ - if (!found_other_files) + if (found_other_files) + { + my_error(ER_DB_DROP_RMDIR, MYF(0), org_path, EEXIST); + DBUG_RETURN(-1); + } + else { char tmp_path[FN_REFLEN], *pos; char *path= tmp_path; From 80c37f6a920b56c8a4c664f07cc2fba9f000d904 Mon Sep 17 00:00:00 2001 From: "marko@hundin.mysql.fi" <> Date: Tue, 30 Mar 2004 17:26:20 +0300 Subject: [PATCH 04/28] InnoDB: parse CONSTRAINT FOREIGN KEY correctly (Bug #3332) --- innobase/dict/dict0dict.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/innobase/dict/dict0dict.c b/innobase/dict/dict0dict.c index dc19997de72..eb14d8bc80f 100644 --- a/innobase/dict/dict0dict.c +++ b/innobase/dict/dict0dict.c @@ -2811,8 +2811,15 @@ loop: goto loop; } - ptr = dict_scan_id(ptr, &constraint_name, &constraint_name_len, - FALSE); + do { + ptr++; + } while (isspace(*ptr)); + + /* read constraint name unless got "CONSTRAINT FOREIGN" */ + if (ptr != ptr2) { + ptr = dict_scan_id(ptr, &constraint_name, + &constraint_name_len, FALSE); + } } else { ptr = ptr2; } From 3476db87a0d1f8c50a95bb36723e7569792941a0 Mon Sep 17 00:00:00 2001 From: "marko@hundin.mysql.fi" <> Date: Wed, 31 Mar 2004 10:30:14 +0300 Subject: [PATCH 05/28] InnoDB: Remove unnecessary code, mostly related to stored procedures --- innobase/data/data0data.c | 4 - innobase/dict/dict0dict.c | 143 ---------------------------------- innobase/dict/dict0mem.c | 53 ------------- innobase/include/dict0dict.h | 37 --------- innobase/include/dict0dict.ic | 31 -------- innobase/include/dict0mem.h | 30 ------- innobase/include/dict0types.h | 1 - innobase/include/pars0pars.h | 12 --- innobase/include/pars0sym.h | 3 - innobase/include/pars0types.h | 1 - 10 files changed, 315 deletions(-) diff --git a/innobase/data/data0data.c b/innobase/data/data0data.c index c3c2b135717..96c15643096 100644 --- a/innobase/data/data0data.c +++ b/innobase/data/data0data.c @@ -25,10 +25,6 @@ byte data_error; /* data pointers of tuple fields are initialized ulint data_dummy; /* this is used to fool the compiler in dtuple_validate */ -byte data_buf[8192]; /* used in generating test tuples */ -ulint data_rnd = 756511; - - /* Some non-inlined functions used in the MySQL interface: */ void dfield_set_data_noninline( diff --git a/innobase/dict/dict0dict.c b/innobase/dict/dict0dict.c index eb14d8bc80f..40697578cc5 100644 --- a/innobase/dict/dict0dict.c +++ b/innobase/dict/dict0dict.c @@ -43,9 +43,6 @@ rw_lock_t dict_operation_lock; /* table create, drop, etc. reserve #define DICT_HEAP_SIZE 100 /* initial memory heap size when creating a table or index object */ -#define DICT_POOL_PER_PROCEDURE_HASH 512 /* buffer pool max size per stored - procedure hash table fixed size in - bytes */ #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 @@ -667,9 +664,6 @@ dict_init(void) dict_sys->col_hash = hash_create(buf_pool_get_max_size() / (DICT_POOL_PER_COL_HASH * UNIV_WORD_SIZE)); - dict_sys->procedure_hash = hash_create(buf_pool_get_max_size() / - (DICT_POOL_PER_PROCEDURE_HASH * - UNIV_WORD_SIZE)); dict_sys->size = 0; UT_LIST_INIT(dict_sys->table_LRU); @@ -2499,35 +2493,6 @@ dict_skip_word( return(ptr); } -#ifdef currentlynotused -/************************************************************************* -Returns the number of opening brackets '(' subtracted by the number -of closing brackets ')' between string and ptr. */ -static -int -dict_bracket_count( -/*===============*/ - /* out: bracket count */ - char* string, /* in: start of string */ - char* ptr) /* in: end of string */ -{ - int count = 0; - - while (string != ptr) { - if (*string == '(') { - count++; - } - if (*string == ')') { - count--; - } - - string++; - } - - return(count); -} -#endif - /************************************************************************* Removes MySQL comments from an SQL string. A comment is either (a) '#' to the end of the line, @@ -3409,114 +3374,6 @@ syntax_error: /*==================== END OF FOREIGN KEY PROCESSING ====================*/ -/************************************************************************** -Adds a stored procedure object to the dictionary cache. */ - -void -dict_procedure_add_to_cache( -/*========================*/ - dict_proc_t* proc) /* in: procedure */ -{ - ulint fold; - - mutex_enter(&(dict_sys->mutex)); - - fold = ut_fold_string(proc->name); - - /* Look for a procedure with the same name: error if such exists */ - { - dict_proc_t* proc2; - - HASH_SEARCH(name_hash, dict_sys->procedure_hash, fold, proc2, - (ut_strcmp(proc2->name, proc->name) == 0)); - ut_a(proc2 == NULL); - } - - /* Add the procedure to the hash table */ - - HASH_INSERT(dict_proc_t, name_hash, dict_sys->procedure_hash, fold, - proc); - mutex_exit(&(dict_sys->mutex)); -} - -/************************************************************************** -Reserves a parsed copy of a stored procedure to execute. If there are no -free parsed copies left at the moment, parses a new copy. Takes the copy off -the list of copies: the copy must be returned there with -dict_procedure_release_parsed_copy. */ - -que_t* -dict_procedure_reserve_parsed_copy( -/*===============================*/ - /* out: the query graph */ - dict_proc_t* proc) /* in: dictionary procedure node */ -{ - que_t* graph; - proc_node_t* proc_node; - -#ifdef UNIV_SYNC_DEBUG - ut_ad(!mutex_own(&kernel_mutex)); -#endif /* UNIV_SYNC_DEBUG */ - - mutex_enter(&(dict_sys->mutex)); - -#ifdef UNIV_DEBUG - UT_LIST_VALIDATE(graphs, que_t, proc->graphs); -#endif - graph = UT_LIST_GET_FIRST(proc->graphs); - - if (graph) { - UT_LIST_REMOVE(graphs, proc->graphs, graph); - -/* printf("Graph removed, list length %lu\n", - UT_LIST_GET_LEN(proc->graphs)); */ -#ifdef UNIV_DEBUG - UT_LIST_VALIDATE(graphs, que_t, proc->graphs); -#endif - } - - mutex_exit(&(dict_sys->mutex)); - - if (graph == NULL) { - graph = pars_sql(proc->sql_string); - - proc_node = que_fork_get_child(graph); - - proc_node->dict_proc = proc; - - printf("Parsed a new copy of graph %s\n", - proc_node->proc_id->name); - } - -/* printf("Returning graph %lu\n", (ulint)graph); */ - - return(graph); -} - -/************************************************************************** -Releases a parsed copy of an executed stored procedure. Puts the copy to the -list of copies. */ - -void -dict_procedure_release_parsed_copy( -/*===============================*/ - que_t* graph) /* in: query graph of a stored procedure */ -{ - proc_node_t* proc_node; - -#ifdef UNIV_SYNC_DEBUG - ut_ad(!mutex_own(&kernel_mutex)); -#endif /* UNIV_SYNC_DEBUG */ - - mutex_enter(&(dict_sys->mutex)); - - proc_node = que_fork_get_child(graph); - - UT_LIST_ADD_FIRST(graphs, (proc_node->dict_proc)->graphs, graph); - - mutex_exit(&(dict_sys->mutex)); -} - /************************************************************************** Returns an index object if it is found in the dictionary cache. */ diff --git a/innobase/dict/dict0mem.c b/innobase/dict/dict0mem.c index c9eb7a9d8bd..f8c54022c9e 100644 --- a/innobase/dict/dict0mem.c +++ b/innobase/dict/dict0mem.c @@ -301,56 +301,3 @@ dict_mem_index_free( { mem_heap_free(index->heap); } - -/************************************************************************** -Creates a procedure memory object. */ - -dict_proc_t* -dict_mem_procedure_create( -/*======================*/ - /* out, own: procedure object */ - char* name, /* in: procedure name */ - char* sql_string, /* in: procedure definition as an SQL - string */ - que_fork_t* graph) /* in: parsed procedure graph */ -{ - dict_proc_t* proc; - proc_node_t* proc_node; - mem_heap_t* heap; - char* str; - - ut_ad(name); - - heap = mem_heap_create(128); - - proc = mem_heap_alloc(heap, sizeof(dict_proc_t)); - - proc->heap = heap; - - str = mem_heap_alloc(heap, 1 + ut_strlen(name)); - - ut_strcpy(str, name); - - proc->name = str; - - str = mem_heap_alloc(heap, 1 + ut_strlen(sql_string)); - - ut_strcpy(str, sql_string); - - proc->sql_string = str; - - UT_LIST_INIT(proc->graphs); - -/* UT_LIST_ADD_LAST(graphs, proc->graphs, graph); */ - -#ifdef UNIV_DEBUG - UT_LIST_VALIDATE(graphs, que_t, proc->graphs); -#endif - proc->mem_fix = 0; - - proc_node = que_fork_get_child(graph); - - proc_node->dict_proc = proc; - - return(proc); -} diff --git a/innobase/include/dict0dict.h b/innobase/include/dict0dict.h index be5d3b5b465..2e51fecdb8d 100644 --- a/innobase/include/dict0dict.h +++ b/innobase/include/dict0dict.h @@ -59,41 +59,6 @@ Inits the data dictionary module. */ void dict_init(void); /*===========*/ -/************************************************************************** -Returns a stored procedure object and memoryfixes it. */ -UNIV_INLINE -dict_proc_t* -dict_procedure_get( -/*===============*/ - /* out: procedure, NULL if does not exist */ - char* proc_name, /* in: table name */ - trx_t* trx); /* in: transaction handle or NULL */ -/************************************************************************** -Adds a stored procedure object to the dictionary cache. */ - -void -dict_procedure_add_to_cache( -/*========================*/ - dict_proc_t* proc); /* in: procedure */ -/************************************************************************** -Reserves a parsed copy of a stored procedure to execute. If there are no -free parsed copies left at the moment, parses a new copy. Takes the copy off -the list of copies: the copy must be returned there with -dict_procedure_release_parsed_copy. */ - -que_t* -dict_procedure_reserve_parsed_copy( -/*===============================*/ - /* out: the query graph */ - dict_proc_t* proc); /* in: dictionary procedure node */ -/************************************************************************** -Releases a parsed copy of an executed stored procedure. Puts the copy to the -list of copies. */ - -void -dict_procedure_release_parsed_copy( -/*===============================*/ - que_t* graph); /* in: query graph of a stored procedure */ /************************************************************************* Gets the column data type. */ UNIV_INLINE @@ -901,8 +866,6 @@ struct dict_sys_struct{ hash_table_t* table_id_hash; /* hash table of the tables, based on id */ hash_table_t* col_hash; /* hash table of the columns */ - hash_table_t* procedure_hash; /* hash table of the stored - procedures */ UT_LIST_BASE_NODE_T(dict_table_t) table_LRU; /* LRU list of tables */ ulint size; /* varying space in bytes occupied diff --git a/innobase/include/dict0dict.ic b/innobase/include/dict0dict.ic index b70822e331f..57ef4b896f5 100644 --- a/innobase/include/dict0dict.ic +++ b/innobase/include/dict0dict.ic @@ -581,37 +581,6 @@ dict_table_get_low( return(table); } -/************************************************************************** -Returns a stored procedure object and memoryfixes it. */ -UNIV_INLINE -dict_proc_t* -dict_procedure_get( -/*===============*/ - /* out: procedure, NULL if does not exist */ - char* proc_name, /* in: table name */ - trx_t* trx) /* in: transaction handle or NULL */ -{ - dict_proc_t* proc; - ulint name_fold; - - UT_NOT_USED(trx); - - mutex_enter(&(dict_sys->mutex)); - - /* Look for the table name in the hash table */ - name_fold = ut_fold_string(proc_name); - - HASH_SEARCH(name_hash, dict_sys->procedure_hash, name_fold, proc, - ut_strcmp(proc->name, proc_name) == 0); - if (proc != NULL) { - proc->mem_fix++; - } - - mutex_exit(&(dict_sys->mutex)); - - return(proc); -} - /************************************************************************** Returns a table object, based on table id, and memoryfixes it. */ UNIV_INLINE diff --git a/innobase/include/dict0mem.h b/innobase/include/dict0mem.h index 1930825f601..439adf6f52e 100644 --- a/innobase/include/dict0mem.h +++ b/innobase/include/dict0mem.h @@ -132,18 +132,6 @@ dict_foreign_t* dict_mem_foreign_create(void); /*=========================*/ /* out, own: foreign constraint struct */ -/************************************************************************** -Creates a procedure memory object. */ - -dict_proc_t* -dict_mem_procedure_create( -/*======================*/ - /* out, own: procedure object */ - char* name, /* in: procedure name */ - char* sql_string, /* in: procedure definition as an SQL - string */ - que_fork_t* graph); /* in: parsed procedure graph */ - /* Data structure for a column in a table */ struct dict_col_struct{ @@ -420,24 +408,6 @@ struct dict_table_struct{ #endif /* UNIV_DEBUG */ }; -/* Data structure for a stored procedure */ -struct dict_proc_struct{ - mem_heap_t* heap; /* memory heap */ - char* name; /* procedure name */ - char* sql_string; - /* procedure definition as an SQL string: - we can produce more parsed instances of the - procedure by parsing this string */ - hash_node_t name_hash; - /* hash chain node */ - UT_LIST_BASE_NODE_T(que_fork_t) graphs; - /* list of parsed instances of the procedure: - there may be many of them, and they are - recycled */ - ulint mem_fix;/* count of how many times this struct - has been fixed in memory */ -}; - #ifndef UNIV_NONINL #include "dict0mem.ic" #endif diff --git a/innobase/include/dict0types.h b/innobase/include/dict0types.h index 498c6f46b7b..bd8a1a996d1 100644 --- a/innobase/include/dict0types.h +++ b/innobase/include/dict0types.h @@ -15,7 +15,6 @@ typedef struct dict_field_struct dict_field_t; typedef struct dict_index_struct dict_index_t; typedef struct dict_tree_struct dict_tree_t; typedef struct dict_table_struct dict_table_t; -typedef struct dict_proc_struct dict_proc_t; typedef struct dict_foreign_struct dict_foreign_t; /* A cluster object is a table object with the type field set to diff --git a/innobase/include/pars0pars.h b/innobase/include/pars0pars.h index 8ff226ebbd0..cad0942eeb1 100644 --- a/innobase/include/pars0pars.h +++ b/innobase/include/pars0pars.h @@ -456,18 +456,6 @@ struct proc_node_struct{ sym_node_t* param_list; /* input and output parameters */ que_node_t* stat_list; /* statement list */ sym_tab_t* sym_tab; /* symbol table of this procedure */ - dict_proc_t* dict_proc; /* stored procedure node in the - dictionary cache, if defined */ -}; - -/* Stored procedure call node */ -struct call_node_struct{ - que_common_t common; /* type: QUE_NODE_CALL */ - sym_node_t* proc_name; /* stored procedure name */ - dict_proc_t* procedure_def; /* pointer to a stored procedure graph - in the dictionary stored procedure - cache */ - sym_tab_t* sym_tab; /* symbol table of this query */ }; /* elsif-element node */ diff --git a/innobase/include/pars0sym.h b/innobase/include/pars0sym.h index 9fdeb1984a9..3060fd06c8f 100644 --- a/innobase/include/pars0sym.h +++ b/innobase/include/pars0sym.h @@ -127,9 +127,6 @@ struct sym_node_struct{ dict_table_t* table; /* table definition if a table id or a column id */ - dict_proc_t* procedure_def; /* stored procedure - definition, if a - stored procedure name */ ulint col_no; /* column number if a column */ sel_buf_t* prefetch_buf; /* NULL, or a buffer diff --git a/innobase/include/pars0types.h b/innobase/include/pars0types.h index e7471260501..9fbfd6efaa1 100644 --- a/innobase/include/pars0types.h +++ b/innobase/include/pars0types.h @@ -15,7 +15,6 @@ typedef struct pars_res_word_struct pars_res_word_t; typedef struct func_node_struct func_node_t; typedef struct order_node_struct order_node_t; typedef struct proc_node_struct proc_node_t; -typedef struct call_node_struct call_node_t; typedef struct elsif_node_struct elsif_node_t; typedef struct if_node_struct if_node_t; typedef struct while_node_struct while_node_t; From 16ac732cb93a75a071f0a44dd3e4ce6d423092b2 Mon Sep 17 00:00:00 2001 From: "marko@hundin.mysql.fi" <> Date: Wed, 31 Mar 2004 10:58:50 +0300 Subject: [PATCH 06/28] InnoDB: Remove unused hash table code and parameters --- innobase/ha/ha0ha.c | 31 ++-------------------------- innobase/include/ha0ha.ic | 43 +++------------------------------------ 2 files changed, 5 insertions(+), 69 deletions(-) diff --git a/innobase/ha/ha0ha.c b/innobase/ha/ha0ha.c index ad833312963..483fac4d8cf 100644 --- a/innobase/ha/ha0ha.c +++ b/innobase/ha/ha0ha.c @@ -205,7 +205,7 @@ ha_remove_all_nodes_to_page( node = ha_chain_get_first(table, fold); } else { - node = ha_chain_get_next(table, node); + node = ha_chain_get_next(node); } } @@ -216,7 +216,7 @@ ha_remove_all_nodes_to_page( while (node) { ut_a(buf_frame_align(ha_node_get_data(node)) != page); - node = ha_chain_get_next(table, node); + node = ha_chain_get_next(node); } } @@ -269,12 +269,6 @@ ha_print_info( hash_table_t* table) /* in: hash table */ { hash_cell_t* cell; -/* - ha_node_t* node; - ulint len = 0; - ulint max_len = 0; - ulint nodes = 0; -*/ ulint cells = 0; ulint n_bufs; ulint i; @@ -290,27 +284,6 @@ ha_print_info( if (cell->node) { cells++; -/* - len = 0; - - node = cell->node; - - for (;;) { - len++; - nodes++; - - if (ha_chain_get_next(table, node) == NULL) { - - break; - } - - node = node->next; - } - - if (len > max_len) { - max_len = len; - } -*/ } } diff --git a/innobase/include/ha0ha.ic b/innobase/include/ha0ha.ic index f6faf84b9f5..2f02f6bdb4e 100644 --- a/innobase/include/ha0ha.ic +++ b/innobase/include/ha0ha.ic @@ -49,11 +49,8 @@ ha_node_t* ha_chain_get_next( /*==============*/ /* out: next node, NULL if none */ - hash_table_t* table __attribute__((unused)), /* in: hash table */ ha_node_t* node) /* in: hash chain node */ { - ut_ad(table); - return(node->next); } @@ -96,7 +93,7 @@ ha_search( return(node); } - node = ha_chain_get_next(table, node); + node = ha_chain_get_next(node); } return(NULL); @@ -128,41 +125,7 @@ ha_search_and_get_data( return(node->data); } - node = ha_chain_get_next(table, node); - } - - return(NULL); -} - -/***************************************************************** -Returns the next matching hash table node in chain. */ -UNIV_INLINE -ha_node_t* -ha_next( -/*====*/ - /* out: pointer to the next hash table node - in chain with the fold value, NULL if not - found */ - hash_table_t* table, /* in: hash table */ - ha_node_t* node) /* in: hash table node */ -{ - ulint fold; - - fold = node->fold; - -#ifdef UNIV_SYNC_DEBUG - ut_ad(!table->mutexes || mutex_own(hash_get_mutex(table, fold))); -#endif /* UNIV_SYNC_DEBUG */ - - node = ha_chain_get_next(table, node); - - while (node) { - if (node->fold == fold) { - - return(node); - } - - node = ha_chain_get_next(table, node); + node = ha_chain_get_next(node); } return(NULL); @@ -194,7 +157,7 @@ ha_search_with_data( return(node); } - node = ha_chain_get_next(table, node); + node = ha_chain_get_next(node); } return(NULL); From 7f2a007496e2a9f7e14bd74e99e1d5af3241a5af Mon Sep 17 00:00:00 2001 From: "marko@hundin.mysql.fi" <> Date: Wed, 31 Mar 2004 11:26:56 +0300 Subject: [PATCH 07/28] InnoDB: Remove ut_str_contains() and replace it with strchr() --- innobase/dict/dict0dict.c | 6 +++--- innobase/include/ut0mem.h | 8 -------- innobase/row/row0mysql.c | 2 +- innobase/ut/ut0mem.c | 24 ------------------------ 4 files changed, 4 insertions(+), 36 deletions(-) diff --git a/innobase/dict/dict0dict.c b/innobase/dict/dict0dict.c index 40697578cc5..67452c154e7 100644 --- a/innobase/dict/dict0dict.c +++ b/innobase/dict/dict0dict.c @@ -1002,7 +1002,7 @@ dict_table_rename_in_cache( sprintf(foreign->foreign_table_name, "%s", table->name); - if (ut_str_contains(foreign->id, '/')) { + if (strchr(foreign->id, '/')) { ulint db_len; char old_id[2000]; @@ -3331,7 +3331,7 @@ loop: while (foreign != NULL) { if (0 == ut_strcmp(foreign->id, id) - || (ut_str_contains(foreign->id, '/') + || (strchr(foreign->id, '/') && 0 == ut_strcmp(id, dict_remove_db_name(foreign->id)))) { /* Found */ @@ -4059,7 +4059,7 @@ dict_print_info_on_foreign_key_in_create_format( ulint cpy_len; ulint i; - if (ut_str_contains(foreign->id, '/')) { + 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); diff --git a/innobase/include/ut0mem.h b/innobase/include/ut0mem.h index fea6fc243d8..13ee8d5f5fa 100644 --- a/innobase/include/ut0mem.h +++ b/innobase/include/ut0mem.h @@ -85,14 +85,6 @@ ut_str_catenate( /* out, own: catenated null-terminated string */ char* str1, /* in: null-terminated string */ char* str2); /* in: null-terminated string */ -/************************************************************************** -Checks if a null-terminated string contains a certain character. */ - -ibool -ut_str_contains( -/*============*/ - char* str, /* in: null-terminated string */ - char c); /* in: character */ #ifndef UNIV_NONINL #include "ut0mem.ic" diff --git a/innobase/row/row0mysql.c b/innobase/row/row0mysql.c index ab73dc2ad6d..693928dea3e 100644 --- a/innobase/row/row0mysql.c +++ b/innobase/row/row0mysql.c @@ -2362,7 +2362,7 @@ row_rename_table_for_mysql( db_name, constraints_to_drop[i], db_name, constraints_to_drop[i]); - if (!ut_str_contains(constraints_to_drop[i], '/')) { + if (!strchr(constraints_to_drop[i], '/')) { /* If this happens to be an old format constraint, let us delete it. Since all new format constraints contain '/', it does no diff --git a/innobase/ut/ut0mem.c b/innobase/ut/ut0mem.c index eca738f0924..f5d207d8bba 100644 --- a/innobase/ut/ut0mem.c +++ b/innobase/ut/ut0mem.c @@ -221,27 +221,3 @@ ut_str_catenate( return(str); } - -/************************************************************************** -Checks if a null-terminated string contains a certain character. */ - -ibool -ut_str_contains( -/*============*/ - char* str, /* in: null-terminated string */ - char c) /* in: character */ -{ - ulint len; - ulint i; - - len = ut_strlen(str); - - for (i = 0; i < len; i++) { - if (str[i] == c) { - - return(TRUE); - } - } - - return(FALSE); -} From 7f1f7b9391d21fb97ebcd135428ba0e8c456d037 Mon Sep 17 00:00:00 2001 From: "marko@hundin.mysql.fi" <> Date: Wed, 31 Mar 2004 11:40:07 +0300 Subject: [PATCH 08/28] InnoDB: cleanup of B-tree cursor operations --- innobase/btr/btr0cur.c | 32 ++++++++++++++++++-------------- 1 file changed, 18 insertions(+), 14 deletions(-) diff --git a/innobase/btr/btr0cur.c b/innobase/btr/btr0cur.c index e5c8762bdb9..c7863ba08e4 100644 --- a/innobase/btr/btr0cur.c +++ b/innobase/btr/btr0cur.c @@ -120,7 +120,6 @@ static void btr_cur_latch_leaves( /*=================*/ - dict_tree_t* tree __attribute__((unused)), /* in: index tree */ page_t* page, /* in: leaf page where the search converged */ ulint space, /* in: space id */ @@ -133,7 +132,7 @@ btr_cur_latch_leaves( ulint right_page_no; page_t* get_page; - ut_ad(tree && page && mtr); + ut_ad(page && mtr); if (latch_mode == BTR_SEARCH_LEAF) { @@ -365,17 +364,19 @@ btr_cur_search_to_nth_level( B-tree. These let us end up in the right B-tree leaf. In that leaf we use the original search mode. */ - if (mode == PAGE_CUR_GE) { + switch (mode) { + case PAGE_CUR_GE: page_mode = PAGE_CUR_L; - } else if (mode == PAGE_CUR_G) { + break; + case PAGE_CUR_G: page_mode = PAGE_CUR_LE; - } else if (mode == PAGE_CUR_LE) { - page_mode = PAGE_CUR_LE; - } else if (mode == PAGE_CUR_LE_OR_EXTENDS) { - page_mode = PAGE_CUR_LE_OR_EXTENDS; - } else { - ut_ad(mode == PAGE_CUR_L); - page_mode = PAGE_CUR_L; + break; + default: + ut_ad(mode == PAGE_CUR_L + || mode == PAGE_CUR_LE + || mode == PAGE_CUR_LE_OR_EXTENDS); + page_mode = mode; + break; } /* Loop and search until we arrive at the desired level */ @@ -450,7 +451,7 @@ retry_page_get: if (height == 0) { if (rw_latch == RW_NO_LATCH) { - btr_cur_latch_leaves(tree, page, space, + btr_cur_latch_leaves(page, space, page_no, latch_mode, cursor, mtr); } @@ -477,6 +478,9 @@ retry_page_get: /* If this is the desired level, leave the loop */ + ut_ad(height + == btr_page_get_level(page_cur_get_page(page_cursor), mtr)); + if (level == height) { if (level > 0) { @@ -588,7 +592,7 @@ btr_cur_open_at_index_side( } if (height == 0) { - btr_cur_latch_leaves(tree, page, space, page_no, + btr_cur_latch_leaves(page, space, page_no, latch_mode, cursor, mtr); /* In versions <= 3.23.52 we had forgotten to @@ -694,7 +698,7 @@ btr_cur_open_at_rnd_pos( } if (height == 0) { - btr_cur_latch_leaves(tree, page, space, page_no, + btr_cur_latch_leaves(page, space, page_no, latch_mode, cursor, mtr); } From f30da8edd5d89a9c1f2a133a6a342ce6ce226c20 Mon Sep 17 00:00:00 2001 From: "heikki@hundin.mysql.fi" <> Date: Wed, 31 Mar 2004 18:06:13 +0300 Subject: [PATCH 09/28] fil0fil.c: Add assertions to check that we do not go out of bounds of io thread status array os0file.c: Fix memory corruption (assertion failure on line 244 of sync0sync.c) reported by Miguel in a Windows build of MySQL-4.1.2. The bug is present in all InnoDB versions in Windows, but it depends on how the linker places a static array in srv0srv.c, whether the bug shows itself. 4 bytes were overwritten with a pointer to a statically allocated string: 'get windows aio return value'. --- innobase/fil/fil0fil.c | 5 +++++ innobase/os/os0file.c | 18 ++++++++++++++---- 2 files changed, 19 insertions(+), 4 deletions(-) diff --git a/innobase/fil/fil0fil.c b/innobase/fil/fil0fil.c index 9f33013d2f9..35a028822c0 100644 --- a/innobase/fil/fil0fil.c +++ b/innobase/fil/fil0fil.c @@ -1331,6 +1331,7 @@ fil_aio_wait( ut_ad(fil_validate()); if (os_aio_use_native_aio) { + ut_a(segment < SRV_MAX_N_IO_THREADS); srv_io_thread_op_info[segment] = (char *) "native aio handle"; #ifdef WIN_ASYNC_IO ret = os_aio_windows_handle(segment, 0, &fil_node, &message, @@ -1342,6 +1343,7 @@ fil_aio_wait( ut_error; #endif } else { + ut_a(segment < SRV_MAX_N_IO_THREADS); srv_io_thread_op_info[segment] =(char *)"simulated aio handle"; ret = os_aio_simulated_handle(segment, (void**) &fil_node, @@ -1350,6 +1352,7 @@ fil_aio_wait( ut_a(ret); + ut_a(segment < SRV_MAX_N_IO_THREADS); srv_io_thread_op_info[segment] = (char *) "complete io for fil node"; mutex_enter(&(system->mutex)); @@ -1363,10 +1366,12 @@ fil_aio_wait( /* Do the i/o handling */ if (buf_pool_is_block(message)) { + ut_a(segment < SRV_MAX_N_IO_THREADS); srv_io_thread_op_info[segment] = (char *) "complete io for buf page"; buf_page_io_complete(message); } else { + ut_a(segment < SRV_MAX_N_IO_THREADS); srv_io_thread_op_info[segment] =(char *) "complete io for log"; log_io_complete(message); } diff --git a/innobase/os/os0file.c b/innobase/os/os0file.c index abcb2259e84..34dbf767773 100644 --- a/innobase/os/os0file.c +++ b/innobase/os/os0file.c @@ -1586,6 +1586,7 @@ os_aio_init( os_io_init_simple(); for (i = 0; i < n_segments; i++) { + ut_a(i < SRV_MAX_N_IO_THREADS); srv_io_thread_op_info[i] = (char*)"not started yet"; } @@ -1606,12 +1607,14 @@ os_aio_init( os_aio_read_array = os_aio_array_create(n_read_segs * n_per_seg, 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] = (char*)"read thread"; } os_aio_write_array = os_aio_array_create(n_write_segs * n_per_seg, 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] = (char*)"write thread"; } @@ -2324,11 +2327,10 @@ os_aio_windows_handle( n = array->n_slots / array->n_segments; if (array == os_aio_sync_array) { - srv_io_thread_op_info[orig_seg] = - "wait Windows aio for 1 page"; os_event_wait(os_aio_array_get_nth_slot(array, pos)->event); i = pos; } else { + ut_a(orig_seg < SRV_MAX_N_IO_THREADS); srv_io_thread_op_info[orig_seg] = "wait Windows aio"; i = os_event_wait_multiple(n, @@ -2341,7 +2343,12 @@ os_aio_windows_handle( ut_a(slot->reserved); - srv_io_thread_op_info[orig_seg] = "get windows aio return value"; + if (orig_seg != ULINT_UNDEFINED) { + ut_a(orig_seg < SRV_MAX_N_IO_THREADS); + srv_io_thread_op_info[orig_seg] = + "get windows aio return value"; + } + ret = GetOverlappedResult(slot->file, &(slot->control), &len, TRUE); *message1 = slot->message1; @@ -2663,7 +2670,8 @@ consecutive_loop: offs += consecutive_ios[i]->len; } } - + + ut_a(global_segment < SRV_MAX_N_IO_THREADS); srv_io_thread_op_info[global_segment] = (char*) "doing file i/o"; if (os_aio_print_debug) { @@ -2714,6 +2722,7 @@ consecutive_loop: } ut_a(ret); + ut_a(global_segment < SRV_MAX_N_IO_THREADS); srv_io_thread_op_info[global_segment] = (char*) "file i/o done"; /* printf("aio: %lu consecutive %lu:th segment, first offs %lu blocks\n", @@ -2772,6 +2781,7 @@ wait_for_io: os_mutex_exit(array->mutex); recommended_sleep: + ut_a(global_segment < SRV_MAX_N_IO_THREADS); srv_io_thread_op_info[global_segment] = (char*)"waiting for i/o request"; From a169bfa6ae32648bcb97c78dd585767179eca1b7 Mon Sep 17 00:00:00 2001 From: "heikki@hundin.mysql.fi" <> Date: Thu, 1 Apr 2004 09:18:32 +0300 Subject: [PATCH 10/28] fil0fil.c, os0file.c, srv0srv.h, srv0srv.c: Add an accessor function to set srv_io_thread_op_info, change the type to const char*, also change the type of srv_io_thread_function to const char* --- innobase/fil/fil0fil.c | 16 +++++----------- innobase/include/srv0srv.h | 13 +++++++++++-- innobase/os/os0file.c | 30 +++++++++++------------------- innobase/srv/srv0srv.c | 18 ++++++++++++++++-- 4 files changed, 43 insertions(+), 34 deletions(-) diff --git a/innobase/fil/fil0fil.c b/innobase/fil/fil0fil.c index 35a028822c0..a363b3c462a 100644 --- a/innobase/fil/fil0fil.c +++ b/innobase/fil/fil0fil.c @@ -1331,8 +1331,7 @@ fil_aio_wait( ut_ad(fil_validate()); if (os_aio_use_native_aio) { - ut_a(segment < SRV_MAX_N_IO_THREADS); - srv_io_thread_op_info[segment] = (char *) "native aio handle"; + srv_set_io_thread_op_info(segment, "native aio handle"); #ifdef WIN_ASYNC_IO ret = os_aio_windows_handle(segment, 0, &fil_node, &message, &type); @@ -1343,8 +1342,7 @@ fil_aio_wait( ut_error; #endif } else { - ut_a(segment < SRV_MAX_N_IO_THREADS); - srv_io_thread_op_info[segment] =(char *)"simulated aio handle"; + srv_set_io_thread_op_info(segment, "simulated aio handle"); ret = os_aio_simulated_handle(segment, (void**) &fil_node, &message, &type); @@ -1352,8 +1350,7 @@ fil_aio_wait( ut_a(ret); - ut_a(segment < SRV_MAX_N_IO_THREADS); - srv_io_thread_op_info[segment] = (char *) "complete io for fil node"; + srv_set_io_thread_op_info(segment, "complete io for fil node"); mutex_enter(&(system->mutex)); @@ -1366,13 +1363,10 @@ fil_aio_wait( /* Do the i/o handling */ if (buf_pool_is_block(message)) { - ut_a(segment < SRV_MAX_N_IO_THREADS); - srv_io_thread_op_info[segment] = - (char *) "complete io for buf page"; + srv_set_io_thread_op_info(segment, "complete io for buf page"); buf_page_io_complete(message); } else { - ut_a(segment < SRV_MAX_N_IO_THREADS); - srv_io_thread_op_info[segment] =(char *) "complete io for log"; + srv_set_io_thread_op_info(segment, "complete io for log"); log_io_complete(message); } } diff --git a/innobase/include/srv0srv.h b/innobase/include/srv0srv.h index 769d55fb66c..3811f6ae167 100644 --- a/innobase/include/srv0srv.h +++ b/innobase/include/srv0srv.h @@ -155,8 +155,8 @@ extern mutex_t* kernel_mutex_temp;/* mutex protecting the server, trx structs, /* Array of English strings describing the current state of an i/o handler thread */ -extern char* srv_io_thread_op_info[]; -extern char* srv_io_thread_function[]; +extern const char* srv_io_thread_op_info[]; +extern const char* srv_io_thread_function[]; typedef struct srv_sys_struct srv_sys_t; @@ -234,6 +234,15 @@ srv_get_thread_type(void); /*=====================*/ /* out: SRV_COM, ... */ /************************************************************************* +Sets the info describing an i/o thread current state. */ + +void +srv_set_io_thread_op_info( +/*======================*/ + ulint i, /* in: the 'segment' of the i/o thread */ + const char* str); /* in: constant char string describing the + state */ +/************************************************************************* Releases threads of the type given from suspension in the thread table. NOTE! The server mutex has to be reserved by the caller! */ diff --git a/innobase/os/os0file.c b/innobase/os/os0file.c index 34dbf767773..acc6492fefc 100644 --- a/innobase/os/os0file.c +++ b/innobase/os/os0file.c @@ -1586,8 +1586,7 @@ os_aio_init( os_io_init_simple(); for (i = 0; i < n_segments; i++) { - ut_a(i < SRV_MAX_N_IO_THREADS); - srv_io_thread_op_info[i] = (char*)"not started yet"; + srv_set_io_thread_op_info(i, "not started yet"); } n_per_seg = n / n_segments; @@ -1598,24 +1597,24 @@ os_aio_init( os_aio_ibuf_array = os_aio_array_create(n_per_seg, 1); - srv_io_thread_function[0] = (char*)"insert buffer thread"; + srv_io_thread_function[0] = "insert buffer thread"; os_aio_log_array = os_aio_array_create(n_per_seg, 1); - srv_io_thread_function[1] = (char*)"log thread"; + srv_io_thread_function[1] = "log thread"; os_aio_read_array = os_aio_array_create(n_read_segs * n_per_seg, 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] = (char*)"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); for (i = 2 + n_read_segs; i < n_segments; i++) { ut_a(i < SRV_MAX_N_IO_THREADS); - srv_io_thread_function[i] = (char*)"write thread"; + srv_io_thread_function[i] = "write thread"; } os_aio_sync_array = os_aio_array_create(n_slots_sync, 1); @@ -2330,9 +2329,7 @@ os_aio_windows_handle( os_event_wait(os_aio_array_get_nth_slot(array, pos)->event); i = pos; } else { - ut_a(orig_seg < SRV_MAX_N_IO_THREADS); - srv_io_thread_op_info[orig_seg] = - "wait Windows aio"; + srv_set_io_thread_op_info(orig_seg, "wait Windows aio"); i = os_event_wait_multiple(n, (array->native_events) + segment * n); } @@ -2344,9 +2341,8 @@ os_aio_windows_handle( ut_a(slot->reserved); if (orig_seg != ULINT_UNDEFINED) { - ut_a(orig_seg < SRV_MAX_N_IO_THREADS); - srv_io_thread_op_info[orig_seg] = - "get windows aio return value"; + srv_set_io_thread_op_info(orig_seg, + "get windows aio return value"); } ret = GetOverlappedResult(slot->file, &(slot->control), &len, TRUE); @@ -2671,8 +2667,7 @@ consecutive_loop: } } - ut_a(global_segment < SRV_MAX_N_IO_THREADS); - srv_io_thread_op_info[global_segment] = (char*) "doing file i/o"; + srv_set_io_thread_op_info(global_segment, "doing file i/o"); if (os_aio_print_debug) { fprintf(stderr, @@ -2722,8 +2717,7 @@ consecutive_loop: } ut_a(ret); - ut_a(global_segment < SRV_MAX_N_IO_THREADS); - srv_io_thread_op_info[global_segment] = (char*) "file i/o done"; + srv_set_io_thread_op_info(global_segment, "file i/o done"); /* printf("aio: %lu consecutive %lu:th segment, first offs %lu blocks\n", n_consecutive, global_segment, slot->offset @@ -2781,9 +2775,7 @@ wait_for_io: os_mutex_exit(array->mutex); recommended_sleep: - ut_a(global_segment < SRV_MAX_N_IO_THREADS); - srv_io_thread_op_info[global_segment] = - (char*)"waiting for i/o request"; + srv_set_io_thread_op_info(global_segment, "waiting for i/o request"); os_event_wait(os_aio_segment_wait_events[global_segment]); diff --git a/innobase/srv/srv0srv.c b/innobase/srv/srv0srv.c index 0be0ab957af..ae7505dcd31 100644 --- a/innobase/srv/srv0srv.c +++ b/innobase/srv/srv0srv.c @@ -285,8 +285,8 @@ ulint srv_test_n_mutexes = ULINT_MAX; /* Array of English strings describing the current state of an i/o handler thread */ -char* srv_io_thread_op_info[SRV_MAX_N_IO_THREADS]; -char* srv_io_thread_function[SRV_MAX_N_IO_THREADS]; +const char* srv_io_thread_op_info[SRV_MAX_N_IO_THREADS]; +const char* srv_io_thread_function[SRV_MAX_N_IO_THREADS]; time_t srv_last_monitor_time; @@ -514,6 +514,20 @@ are indexed by the type of the thread. */ ulint srv_n_threads_active[SRV_MASTER + 1]; ulint srv_n_threads[SRV_MASTER + 1]; +/************************************************************************* +Sets the info describing an i/o thread current state. */ + +void +srv_set_io_thread_op_info( +/*======================*/ + ulint i, /* in: the 'segment' of the i/o thread */ + const char* str) /* in: constant char string describing the + state */ +{ + ut_a(i < SRV_MAX_N_IO_THREADS); + + srv_io_thread_op_info[i] = str; +} /************************************************************************* Accessor function to get pointer to n'th slot in the server thread From e00bf40360ce47ce718afe85cccfb28ac4c4e8ac Mon Sep 17 00:00:00 2001 From: "marko@hundin.mysql.fi" <> Date: Thu, 1 Apr 2004 16:51:34 +0300 Subject: [PATCH 11/28] InnoDB cleanup: fixing buffer overflows and quoting of quotes --- innobase/dict/dict0crea.c | 190 ++++----- innobase/dict/dict0dict.c | 540 ++++++++++++------------- innobase/dict/dict0load.c | 94 ++--- innobase/dict/dict0mem.c | 20 +- innobase/eval/eval0eval.c | 57 ++- innobase/fil/fil0fil.c | 14 +- innobase/ibuf/ibuf0ibuf.c | 43 +- innobase/include/data0data.h | 2 + innobase/include/data0data.ic | 4 +- innobase/include/dict0dict.h | 23 +- innobase/include/lock0lock.h | 4 +- innobase/include/log0log.h | 3 +- innobase/include/mem0mem.h | 53 +++ innobase/include/mem0mem.ic | 96 +++++ innobase/include/row0uins.h | 3 +- innobase/include/row0undo.h | 3 +- innobase/include/ut0byte.h | 16 +- innobase/include/ut0mem.h | 33 ++ innobase/include/ut0mem.ic | 20 + innobase/include/ut0ut.h | 4 +- innobase/lock/lock0lock.c | 3 - innobase/log/log0log.c | 17 +- innobase/log/log0recv.c | 8 +- innobase/mem/mem0mem.c | 7 +- innobase/mtr/mtr0log.c | 9 +- innobase/page/page0cur.c | 9 +- innobase/page/page0page.c | 9 +- innobase/pars/pars0opt.c | 4 +- innobase/pars/pars0pars.c | 10 +- innobase/row/row0ins.c | 36 +- innobase/row/row0mysql.c | 728 +++++++++++++++++----------------- innobase/row/row0purge.c | 42 +- innobase/row/row0row.c | 7 +- innobase/row/row0uins.c | 46 +-- innobase/row/row0umod.c | 28 +- innobase/row/row0undo.c | 7 +- innobase/srv/srv0srv.c | 17 +- innobase/srv/srv0start.c | 49 +-- innobase/trx/trx0roll.c | 3 +- innobase/trx/trx0sys.c | 3 +- innobase/ut/ut0byte.c | 44 +- innobase/ut/ut0mem.c | 49 ++- sql/ha_innodb.cc | 7 +- 43 files changed, 1183 insertions(+), 1181 deletions(-) diff --git a/innobase/dict/dict0crea.c b/innobase/dict/dict0crea.c index 48fcb9c1e79..967818a3784 100644 --- a/innobase/dict/dict0crea.c +++ b/innobase/dict/dict0crea.c @@ -37,67 +37,6 @@ static dtuple_t* dict_create_sys_tables_tuple( /*=========================*/ - /* out: the tuple which should be inserted */ - dict_table_t* table, /* in: table */ - mem_heap_t* heap); /* in: memory heap from which the memory for - the built tuple is allocated */ -/********************************************************************* -Based on a table object, this function builds the entry to be inserted -in the SYS_COLUMNS system table. */ -static -dtuple_t* -dict_create_sys_columns_tuple( -/*==========================*/ - /* out: the tuple which should be inserted */ - dict_table_t* table, /* in: table */ - ulint i, /* in: column number */ - mem_heap_t* heap); /* in: memory heap from which the memory for - the built tuple is allocated */ -/********************************************************************* -Based on an index object, this function builds the entry to be inserted -in the SYS_INDEXES system table. */ -static -dtuple_t* -dict_create_sys_indexes_tuple( -/*==========================*/ - /* out: the tuple which should be inserted */ - dict_index_t* index, /* in: index */ - mem_heap_t* heap, /* in: memory heap from which the memory for - the built tuple is allocated */ - trx_t* trx); /* in: transaction handle */ -/********************************************************************* -Based on an index object, this function builds the entry to be inserted -in the SYS_FIELDS system table. */ -static -dtuple_t* -dict_create_sys_fields_tuple( -/*=========================*/ - /* out: the tuple which should be inserted */ - dict_index_t* index, /* in: index */ - ulint i, /* in: field number */ - mem_heap_t* heap); /* in: memory heap from which the memory for - the built tuple is allocated */ -/********************************************************************* -Creates the tuple with which the index entry is searched for -writing the index tree root page number, if such a tree is created. */ -static -dtuple_t* -dict_create_search_tuple( -/*=====================*/ - /* out: the tuple for search */ - dtuple_t* tuple, /* in: the tuple inserted in the SYS_INDEXES - table */ - mem_heap_t* heap); /* in: memory heap from which the memory for - the built tuple is allocated */ - -/********************************************************************* -Based on a table object, this function builds the entry to be inserted -in the SYS_TABLES system table. */ -static -dtuple_t* -dict_create_sys_tables_tuple( -/*=========================*/ - /* out: the tuple which should be inserted */ dict_table_t* table, /* in: table */ mem_heap_t* heap) /* in: memory heap from which the memory for the built tuple is allocated */ @@ -331,9 +270,8 @@ dict_create_sys_indexes_tuple( /*==========================*/ /* out: the tuple which should be inserted */ dict_index_t* index, /* in: index */ - mem_heap_t* heap, /* in: memory heap from which the memory for + mem_heap_t* heap) /* in: memory heap from which the memory for the built tuple is allocated */ - trx_t* trx) /* in: transaction handle */ { dict_table_t* sys_indexes; dict_table_t* table; @@ -341,7 +279,6 @@ dict_create_sys_indexes_tuple( dfield_t* dfield; byte* ptr; - UT_NOT_USED(trx); #ifdef UNIV_SYNC_DEBUG ut_ad(mutex_own(&(dict_sys->mutex))); #endif /* UNIV_SYNC_DEBUG */ @@ -387,7 +324,9 @@ dict_create_sys_indexes_tuple( dfield_set_data(dfield, ptr, 4); /* 7: SPACE --------------------------*/ - ut_a(DICT_SYS_INDEXES_SPACE_NO_FIELD == 7); +#if DICT_SYS_INDEXES_SPACE_NO_FIELD != 7 +#error "DICT_SYS_INDEXES_SPACE_NO_FIELD != 7" +#endif dfield = dtuple_get_nth_field(entry, 5); @@ -397,7 +336,9 @@ dict_create_sys_indexes_tuple( dfield_set_data(dfield, ptr, 4); /* 8: PAGE_NO --------------------------*/ - ut_a(DICT_SYS_INDEXES_PAGE_NO_FIELD == 8); +#if DICT_SYS_INDEXES_PAGE_NO_FIELD != 8 +#error "DICT_SYS_INDEXES_PAGE_NO_FIELD != 8" +#endif dfield = dtuple_get_nth_field(entry, 6); @@ -565,8 +506,7 @@ dict_build_index_def_step( index->page_no = FIL_NULL; - row = dict_create_sys_indexes_tuple(index, node->heap, - thr_get_trx(thr)); + row = dict_create_sys_indexes_tuple(index, node->heap); node->ind_row = row; ins_node_set_new_row(node->ind_def, row); @@ -602,7 +542,6 @@ ulint dict_create_index_tree_step( /*========================*/ /* out: DB_SUCCESS or DB_OUT_OF_FILE_SPACE */ - que_thr_t* thr, /* in: query thread */ ind_node_t* node) /* in: index create node */ { dict_index_t* index; @@ -615,7 +554,6 @@ dict_create_index_tree_step( #ifdef UNIV_SYNC_DEBUG ut_ad(mutex_own(&(dict_sys->mutex))); #endif /* UNIV_SYNC_DEBUG */ - UT_NOT_USED(thr); index = node->index; table = node->table; @@ -963,7 +901,7 @@ dict_create_index_step( if (node->state == INDEX_CREATE_INDEX_TREE) { - err = dict_create_index_tree_step(thr, node); + err = dict_create_index_tree_step(node); if (err != DB_SUCCESS) { @@ -1166,11 +1104,22 @@ dict_create_add_foreigns_to_dictionary( que_t* graph; ulint number = start_id + 1; ulint len; - ulint namelen; ulint error; char* ebuf = dict_foreign_err_buf; ulint i; - char buf[10000]; + char* sql; + char* sqlend; + /* This procedure builds an InnoDB stored procedure which will insert + the necessary rows into SYS_FOREIGN and SYS_FOREIGN_COLS. */ + static const char str1[] = "PROCEDURE ADD_FOREIGN_DEFS_PROC () IS\n" + "BEGIN\n" + "INSERT INTO SYS_FOREIGN VALUES("; + static const char str2[] = ");\n"; + static const char str3[] = + "INSERT INTO SYS_FOREIGN_COLS VALUES("; + static const char str4[] = + "COMMIT WORK;\n" + "END;\n"; #ifdef UNIV_SYNC_DEBUG ut_ad(mutex_own(&(dict_sys->mutex))); @@ -1190,58 +1139,75 @@ loop: return(DB_SUCCESS); } - /* Build an InnoDB stored procedure which will insert the necessary - rows to SYS_FOREIGN and SYS_FOREIGN_COLS */ - - len = 0; - - len += sprintf(buf, - "PROCEDURE ADD_FOREIGN_DEFS_PROC () IS\n" - "BEGIN\n"); - - namelen = strlen(table->name); - ut_a(namelen < MAX_TABLE_NAME_LEN); - if (foreign->id == NULL) { /* Generate a new constraint id */ - foreign->id = mem_heap_alloc(foreign->heap, namelen + 20); + ulint namelen = strlen(table->name); + char* id = mem_heap_alloc(foreign->heap, namelen + 20); /* no overflow if number < 1e13 */ - sprintf(foreign->id, "%s_ibfk_%lu", table->name, number); - number++; + sprintf(id, "%s_ibfk_%lu", table->name, number++); + foreign->id = id; } - ut_a(strlen(foreign->id) < MAX_IDENTIFIER_LEN); - ut_a(len < (sizeof buf) - - 46 - 2 * MAX_TABLE_NAME_LEN - MAX_IDENTIFIER_LEN - 20); - - len += sprintf(buf + len, - "INSERT INTO SYS_FOREIGN VALUES('%s', '%s', '%s', %lu);\n", - foreign->id, - table->name, - foreign->referenced_table_name, - foreign->n_fields - + (foreign->type << 24)); + len = (sizeof str1) + (sizeof str2) + (sizeof str4) - 3 + + 9/* ' and , chars */ + 10/* 32-bit integer */ + + ut_strlenq(foreign->id, '\'') * (foreign->n_fields + 1) + + ut_strlenq(table->name, '\'') + + ut_strlenq(foreign->referenced_table_name, '\''); for (i = 0; i < foreign->n_fields; i++) { - ut_a(len < (sizeof buf) - - 51 - 2 * MAX_COLUMN_NAME_LEN - - MAX_IDENTIFIER_LEN - 20); - - len += sprintf(buf + len, - "INSERT INTO SYS_FOREIGN_COLS VALUES('%s', %lu, '%s', '%s');\n", - foreign->id, - i, - foreign->foreign_col_names[i], - foreign->referenced_col_names[i]); + len += 9/* ' and , chars */ + 10/* 32-bit integer */ + + (sizeof str3) + (sizeof str2) - 2 + + ut_strlenq(foreign->foreign_col_names[i], '\'') + + ut_strlenq(foreign->referenced_col_names[i], '\''); } - ut_a(len < (sizeof buf) - 19); - len += sprintf(buf + len,"COMMIT WORK;\nEND;\n"); + sql = sqlend = mem_alloc(len + 1); - graph = pars_sql(buf); + /* INSERT INTO SYS_FOREIGN VALUES(...); */ + memcpy(sqlend, str1, (sizeof str1) - 1); + sqlend += (sizeof str1) - 1; + *sqlend++ = '\''; + sqlend = ut_strcpyq(sqlend, '\'', foreign->id); + *sqlend++ = '\'', *sqlend++ = ',', *sqlend++ = '\''; + sqlend = ut_strcpyq(sqlend, '\'', table->name); + *sqlend++ = '\'', *sqlend++ = ',', *sqlend++ = '\''; + sqlend = ut_strcpyq(sqlend, '\'', foreign->referenced_table_name); + *sqlend++ = '\'', *sqlend++ = ','; + sqlend += sprintf(sqlend, "%010lu", + foreign->n_fields + (foreign->type << 24)); + memcpy(sqlend, str2, (sizeof str2) - 1); + sqlend += (sizeof str2) - 1; + + for (i = 0; i < foreign->n_fields; i++) { + /* INSERT INTO SYS_FOREIGN_COLS VALUES(...); */ + memcpy(sqlend, str3, (sizeof str3) - 1); + sqlend += (sizeof str3) - 1; + *sqlend++ = '\''; + sqlend = ut_strcpyq(sqlend, '\'', foreign->id); + *sqlend++ = '\''; *sqlend++ = ','; + sqlend += sprintf(sqlend, "%010lu", i); + *sqlend++ = ','; *sqlend++ = '\''; + sqlend = ut_strcpyq(sqlend, '\'', + foreign->foreign_col_names[i]); + *sqlend++ = '\''; *sqlend++ = ','; *sqlend++ = '\''; + sqlend = ut_strcpyq(sqlend, '\'', + foreign->referenced_col_names[i]); + *sqlend++ = '\''; + memcpy(sqlend, str2, (sizeof str2) - 1); + sqlend += (sizeof str2) - 1; + } + + memcpy(sqlend, str4, sizeof str4); + sqlend += sizeof str4; + + ut_a(sqlend == sql + len + 1); + + graph = pars_sql(sql); ut_a(graph); + mem_free(sql); + graph->trx = trx; trx->graph = NULL; diff --git a/innobase/dict/dict0dict.c b/innobase/dict/dict0dict.c index 67452c154e7..0efb9935800 100644 --- a/innobase/dict/dict0dict.c +++ b/innobase/dict/dict0dict.c @@ -49,7 +49,10 @@ rw_lock_t dict_operation_lock; /* table create, drop, etc. reserve hash table fixed size in bytes */ #define DICT_POOL_PER_VARYING 4 /* buffer pool max size per data dictionary varying size in bytes */ - + +/* Identifies generated InnoDB foreign key names */ +static char dict_ibfk[] = "_ibfk_"; + /************************************************************************** Adds a column to the data dictionary hash table. */ static @@ -129,16 +132,7 @@ dict_index_build_internal_non_clust( dict_index_t* index); /* in: user representation of a non-clustered index */ /************************************************************************** -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 */ -/************************************************************************** -Removes a foreign constraint struct from the dictionet cache. */ +Removes a foreign constraint struct from the dictionary cache. */ static void dict_foreign_remove_from_cache( @@ -187,26 +181,18 @@ static ibool dict_tables_have_same_db( /*=====================*/ - /* out: TRUE if same db name */ - char* name1, /* in: table name in the form dbname '/' tablename */ - char* name2) /* in: table name in the form dbname '/' tablename */ + /* out: TRUE if same db name */ + const char* name1, /* in: table name in the form + dbname '/' tablename */ + const char* name2) /* in: table name in the form + dbname '/' tablename */ { - ulint i; - - for (i = 0; i < 100000; i++) { - if (name1[i] == '/' && name2[i] == '/') { - + for (; *name1 == *name2; name1++, name2++) { + if (*name1 == '/') { return(TRUE); } - - if (name1[i] != name2[i]) { - - return(FALSE); - } + ut_a(*name1); /* the names must contain '/' */ } - - ut_error; - return(FALSE); } @@ -219,18 +205,11 @@ dict_remove_db_name( /* out: table name */ char* name) /* in: table name in the form dbname '/' tablename */ { - ulint i; - - for (i = 0; i < 100000 ; i++) { - if (name[i] == '/') { - - return(name + i + 1); - } - } - - ut_error; - - return(NULL); + char* s; + s = strchr(name, '/'); + ut_a(s); + if (s) s++; + return(s); } /************************************************************************ @@ -239,21 +218,14 @@ Get the database name length in a table name. */ ulint dict_get_db_name_len( /*=================*/ - /* out: database name length */ - char* name) /* in: table name in the form dbname '/' tablename */ + /* out: database name length */ + const char* name) /* in: table name in the form + dbname '/' tablename */ { - ulint i; - - for (i = 0; i < 100000 ; i++) { - if (name[i] == '/') { - - return(i); - } - } - - ut_error; - - return(0); + const char* s; + s = strchr(name, '/'); + ut_a(s); + return(s - name); } /************************************************************************ @@ -889,7 +861,6 @@ dict_table_rename_in_cache( dict_index_t* index; ulint fold; ulint old_size; - char* name_buf; char* old_name; ulint i; @@ -923,16 +894,9 @@ dict_table_rename_in_cache( /* 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); - old_name = mem_heap_alloc(table->heap, ut_strlen(table->name) + 1); - - ut_strcpy(old_name, table->name); + old_name = mem_heap_strdup(table->heap, table->name); + table->name = mem_heap_strdup(table->heap, new_name); - name_buf = mem_heap_alloc(table->heap, ut_strlen(new_name) + 1); - - ut_memcpy(name_buf, new_name, ut_strlen(new_name) + 1); - - table->name = name_buf; - /* Add table to hash table of tables */ HASH_INSERT(dict_table_t, name_hash, dict_sys->table_hash, fold, table); @@ -1000,30 +964,27 @@ dict_table_rename_in_cache( ut_strlen(table->name) + 1); } - sprintf(foreign->foreign_table_name, "%s", table->name); + strcpy(foreign->foreign_table_name, table->name); if (strchr(foreign->id, '/')) { ulint db_len; - char old_id[2000]; + char* old_id; /* This is a >= 4.0.18 format id */ - ut_a(ut_strlen(foreign->id) < 1999); - - ut_strcpy(old_id, foreign->id); + old_id = mem_strdup(foreign->id); if (ut_strlen(foreign->id) > ut_strlen(old_name) - + ut_strlen("_ibfk_") + + ((sizeof dict_ibfk) - 1) && 0 == ut_memcmp(foreign->id, old_name, ut_strlen(old_name)) && 0 == ut_memcmp( foreign->id + ut_strlen(old_name), - (char*)"_ibfk_", ut_strlen("_ibfk_"))) { + 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 (ut_strlen(table->name) > ut_strlen(old_name)) { foreign->id = mem_heap_alloc( foreign->heap, ut_strlen(table->name) @@ -1032,7 +993,8 @@ dict_table_rename_in_cache( /* Replace the prefix 'databasename/tablename' with the new names */ - sprintf(foreign->id, "%s%s", table->name, + strcpy(foreign->id, table->name); + strcat(foreign->id, old_id + ut_strlen(old_name)); } else { /* This is a >= 4.0.18 format id where the user @@ -1052,9 +1014,11 @@ dict_table_rename_in_cache( ut_memcpy(foreign->id, table->name, db_len); - sprintf(foreign->id + db_len, "%s", + strcpy(foreign->id + db_len, dict_remove_db_name(old_id)); } + + mem_free(old_id); } foreign = UT_LIST_GET_NEXT(foreign_list, foreign); @@ -1073,7 +1037,7 @@ dict_table_rename_in_cache( ut_strlen(table->name) + 1); } - sprintf(foreign->referenced_table_name, "%s", table->name); + strcpy(foreign->referenced_table_name, table->name); foreign = UT_LIST_GET_NEXT(referenced_list, foreign); } @@ -1971,7 +1935,7 @@ dict_foreign_find_index( /*====================*/ /* out: matching index, NULL if not found */ dict_table_t* table, /* in: table */ - char** columns,/* in: array of column names */ + const char** columns,/* in: array of column names */ 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 */ @@ -1996,11 +1960,8 @@ dict_foreign_find_index( break; } - if (ut_strlen(columns[i]) != - ut_strlen(col_name) - || 0 != ut_cmp_in_lower_case(columns[i], - col_name, - ut_strlen(col_name))) { + if (0 != ut_cmp_in_lower_case(columns[i], + col_name)) { break; } @@ -2072,9 +2033,9 @@ dict_foreign_add_to_cache( if (for_in_cache->referenced_table == NULL && ref_table) { index = dict_foreign_find_index(ref_table, - for_in_cache->referenced_col_names, - for_in_cache->n_fields, - for_in_cache->foreign_index); + (const char**) for_in_cache->referenced_col_names, + for_in_cache->n_fields, + for_in_cache->foreign_index); if (index == NULL) { mutex_enter(&dict_foreign_err_mutex); @@ -2113,9 +2074,9 @@ dict_foreign_add_to_cache( if (for_in_cache->foreign_table == NULL && for_table) { index = dict_foreign_find_index(for_table, - for_in_cache->foreign_col_names, - for_in_cache->n_fields, - for_in_cache->referenced_index); + (const char**) for_in_cache->foreign_col_names, + for_in_cache->n_fields, + for_in_cache->referenced_index); if (index == NULL) { mutex_enter(&dict_foreign_err_mutex); @@ -2165,12 +2126,12 @@ Scans from pointer onwards. Stops if is at the start of a copy of 'string' where characters are compared without case sensitivity. Stops also at '\0'. */ static -char* +const char* dict_scan_to( /*=========*/ /* out: scanned up to this */ - char* ptr, /* in: scan from */ - const char *string) /* in: look for this */ + const char* ptr, /* in: scan from */ + const char* string) /* in: look for this */ { ibool success; ulint i; @@ -2202,18 +2163,18 @@ loop: /************************************************************************* Accepts a specified string. Comparisons are case-insensitive. */ -char* +const char* dict_accept( /*========*/ - /* out: if string was accepted, the pointer - is moved after that, else ptr is returned */ - char* ptr, /* in: scan from this */ - const char* string,/* in: accept only this string as the next - non-whitespace string */ - ibool* success)/* out: TRUE if accepted */ + /* out: if string was accepted, the pointer + is moved after that, else ptr is returned */ + const char* ptr, /* in: scan from this */ + const char* string, /* in: accept only this string as the next + non-whitespace string */ + ibool* success)/* out: TRUE if accepted */ { - char* old_ptr = ptr; - char* old_ptr2; + const char* old_ptr = ptr; + const char* old_ptr2; *success = FALSE; @@ -2238,21 +2199,27 @@ dict_accept( Scans an id. For the lexical definition of an 'id', see the code below. Strips backquotes or double quotes from around the id. */ static -char* +const char* dict_scan_id( /*=========*/ /* out: scanned to */ - char* ptr, /* in: scanned to */ - char** start, /* out: start of the id; NULL if no id was + 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 */ - ulint* len, /* out: length of the id */ - ibool accept_also_dot)/* in: TRUE if also a dot can appear in a + ibool accept_also_dot) + /* in: TRUE if also a dot can appear in a non-quoted id; in a quoted id it can appear always */ { - char quote = '\0'; + char quote = '\0'; + ulint len = 0; + const char* s; + char* d; - *start = NULL; + *id = NULL; while (isspace(*ptr)) { ptr++; @@ -2266,12 +2233,23 @@ dict_scan_id( if (*ptr == '`' || *ptr == '"') { quote = *ptr++; } - - *start = ptr; + + s = ptr; if (quote) { - while (*ptr != quote && *ptr != '\0') { + for (;;) { + if (!*ptr) { + /* Syntax error */ + return(ptr); + } + if (*ptr == quote) { + ptr++; + if (*ptr != quote) { + break; + } + } ptr++; + len++; } } else { while (!isspace(*ptr) && *ptr != '(' && *ptr != ')' @@ -2280,17 +2258,25 @@ dict_scan_id( ptr++; } + + len = ptr - s; } - *len = (ulint) (ptr - *start); - - if (quote) { - if (*ptr == quote) { - ptr++; - } else { - /* Syntax error */ - *start = NULL; + if (quote && heap) { + *id = 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); + } else { + /* no heap given: id will point to source string */ + *id = (char*) s; } return(ptr); @@ -2299,26 +2285,26 @@ dict_scan_id( /************************************************************************* Tries to scan a column name. */ static -char* +const char* dict_scan_col( /*==========*/ /* out: scanned to */ - char* ptr, /* in: 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 */ - char** column_name,/* out: pointer to column->name if - success */ - ulint* column_name_len)/* out: column name length */ + 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 */ { dict_col_t* col; ulint i; - + *success = FALSE; - ptr = dict_scan_id(ptr, column_name, column_name_len, TRUE); + ptr = dict_scan_id(ptr, heap, name, TRUE); - if (column_name == NULL) { + if (*name == NULL) { return(ptr); /* Syntax error */ } @@ -2331,15 +2317,12 @@ dict_scan_col( col = dict_table_get_nth_col(table, i); - if (ut_strlen(col->name) == *column_name_len - && 0 == ut_cmp_in_lower_case(col->name, - *column_name, - *column_name_len)) { + if (0 == ut_cmp_in_lower_case(col->name, *name)) { /* Found */ *success = TRUE; *column = col; - *column_name = col->name; + strcpy((char*) *name, col->name); break; } @@ -2352,33 +2335,31 @@ dict_scan_col( /************************************************************************* Scans the referenced table name from an SQL string. */ static -char* +const char* dict_scan_table_name( /*=================*/ /* out: scanned to */ - char* ptr, /* in: scanned to */ + const char* ptr, /* in: scanned to */ dict_table_t** table, /* out: table object or NULL */ - char* name, /* in: foreign key table name */ + const char* name, /* in: foreign key table name */ ibool* success,/* out: TRUE if ok name found */ - char* second_table_name)/* in/out: buffer where to store - the referenced table name; must be at least - 2500 bytes */ + mem_heap_t* heap, /* in: heap where to allocate the id */ + const char** ref_name)/* out,own: the referenced table name; + NULL if no name was scannable */ { - char* database_name = NULL; - ulint database_name_len = 999999999; /* init to a dummy value to - suppress a compiler warning */ - char* table_name = NULL; - ulint table_name_len; - char* scanned_id; - ulint scanned_id_len; - ulint i; - + const char* database_name = NULL; + ulint database_name_len = 0; + const char* table_name = NULL; + ulint table_name_len; + const char* scan_name; + char* ref; + *success = FALSE; *table = NULL; - ptr = dict_scan_id(ptr, &scanned_id, &scanned_id_len, FALSE); + ptr = dict_scan_id(ptr, heap, &scan_name, FALSE); - if (scanned_id == NULL) { + if (scan_name == NULL) { return(ptr); /* Syntax error */ } @@ -2388,10 +2369,10 @@ dict_scan_table_name( ptr++; - database_name = scanned_id; - database_name_len = scanned_id_len; + database_name = scan_name; + database_name_len = strlen(database_name); - ptr = dict_scan_id(ptr, &table_name, &table_name_len, FALSE); + ptr = dict_scan_id(ptr, heap, &table_name, FALSE); if (table_name == NULL) { @@ -2405,65 +2386,57 @@ dict_scan_table_name( ... REFERENCES `databasename.tablename` ... starting from 4.0.18 it is ... REFERENCES `databasename`.`tablename` ... */ + const char* s; - for (i = 0; i < scanned_id_len; i++) { - if (scanned_id[i] == '.') { - database_name = scanned_id; - database_name_len = i; - - scanned_id = scanned_id + i + 1; - scanned_id_len -= i + 1; + for (s = scan_name; *s; s++) { + if (*s == '.') { + database_name = scan_name; + database_name_len = s - scan_name; + scan_name = ++s; + break;/* to do: multiple dots? */ } } - table_name = scanned_id; - table_name_len = scanned_id_len; + table_name = scan_name; } if (database_name == NULL) { /* Use the database name of the foreign key table */ database_name = name; - database_name_len = dict_get_db_name_len(name); } - if (table_name_len + database_name_len > 2000) { + table_name_len = strlen(table_name); - return(ptr); /* Too long name */ - } - -#ifdef __WIN__ - ut_cpy_in_lower_case(second_table_name, database_name, - database_name_len); -#else - if (srv_lower_case_table_names) { - ut_cpy_in_lower_case(second_table_name, database_name, - database_name_len); - } else { - ut_memcpy(second_table_name, database_name, - database_name_len); - } -#endif - second_table_name[database_name_len] = '/'; + ref = mem_heap_alloc(heap, database_name_len + table_name_len + 2); #ifdef __WIN__ - ut_cpy_in_lower_case(second_table_name + database_name_len + 1, - table_name, table_name_len); + ut_cpy_in_lower_case(ref, database_name, database_name_len); #else if (srv_lower_case_table_names) { - ut_cpy_in_lower_case(second_table_name + database_name_len + 1, - table_name, table_name_len); + ut_cpy_in_lower_case(ref, database_name, database_name_len); } else { - ut_memcpy(second_table_name + database_name_len + 1, - table_name, table_name_len); + memcpy(ref, database_name, database_name_len); + } +#endif + (ref)[database_name_len] = '/'; + +#ifdef __WIN__ + ut_cpy_in_lower_case(ref + database_name_len + 1, + table_name, table_name_len + 1); +#else + if (srv_lower_case_table_names) { + ut_cpy_in_lower_case(ref + database_name_len + 1, + table_name, table_name_len + 1); + } else { + strcpy(ref + database_name_len + 1, table_name); } #endif - second_table_name[database_name_len + 1 + table_name_len] = '\0'; *success = TRUE; - - *table = dict_table_get_low(second_table_name); + *ref_name = ref; + *table = dict_table_get_low(ref); return(ptr); } @@ -2471,20 +2444,19 @@ dict_scan_table_name( /************************************************************************* Skips one id. The id is allowed to contain also '.'. */ static -char* +const char* dict_skip_word( /*===========*/ - /* out: scanned to */ - char* ptr, /* in: scanned to */ - ibool* success)/* out: TRUE if success, FALSE if just spaces left in - string or a syntax error */ + /* out: scanned to */ + const char* ptr, /* in: scanned to */ + ibool* success)/* out: TRUE if success, FALSE if just spaces + left in string or a syntax error */ { - char* start; - ulint len; + const char* start; *success = FALSE; - ptr = dict_scan_id(ptr, &start, &len, TRUE); + ptr = dict_scan_id(ptr, NULL, &start, TRUE); if (start) { *success = TRUE; @@ -2528,10 +2500,10 @@ scan_more: } if (*sptr == '#' - || (strlen(sptr) >= 3 && 0 == memcmp("-- ", sptr, 3))) { + || (0 == memcmp("-- ", sptr, 3))) { for (;;) { - /* In Unix a newline is 0x0D while in Windows - it is 0x0A followed by 0x0D */ + /* In Unix a newline is 0x0A while in Windows + it is 0x0D followed by 0x0A */ if (*sptr == (char)0x0A || *sptr == (char)0x0D @@ -2544,10 +2516,9 @@ scan_more: } } - if (strlen(sptr) >= 2 && *sptr == '/' && *(sptr + 1) == '*') { + if (*sptr == '/' && *(sptr + 1) == '*') { for (;;) { - if (strlen(sptr) >= 2 - && *sptr == '*' && *(sptr + 1) == '/') { + if (*sptr == '*' && *(sptr + 1) == '/') { sptr += 2; @@ -2586,27 +2557,28 @@ dict_table_get_highest_foreign_id( char* endp; ulint biggest_id = 0; ulint id; + ulint len; ut_a(table); + len = ut_strlen(table->name); foreign = UT_LIST_GET_FIRST(table->foreign_list); while (foreign) { - if (ut_strlen(foreign->id) > ut_strlen("_ibfk_") - + ut_strlen(table->name) - && 0 == ut_memcmp(foreign->id, table->name, - ut_strlen(table->name)) - && 0 == ut_memcmp(foreign->id + ut_strlen(table->name), - (char*)"_ibfk_", ut_strlen("_ibfk_"))) { + 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)) { /* It is of the >= 4.0.18 format */ - id = strtoul(foreign->id + ut_strlen(table->name) - + ut_strlen("_ibfk_"), + id = strtoul(foreign->id + len + ((sizeof dict_ibfk) - 1), &endp, 10); - ut_a(id != biggest_id); + if (*endp == '\0') { + ut_a(id != biggest_id); - if (id > biggest_id) { - biggest_id = id; + if (id > biggest_id) { + biggest_id = id; + } } } @@ -2622,10 +2594,11 @@ static void dict_foreign_report_syntax_err( /*===========================*/ - char* name, /* in: table name */ - char* start_of_latest_foreign,/* in: start of the foreign key clause + const char* name, /* in: table name */ + const char* start_of_latest_foreign, + /* in: start of the foreign key clause in the SQL string */ - char* ptr) /* in: place of the syntax error */ + const char* ptr) /* in: place of the syntax error */ { char* buf = dict_foreign_err_buf; @@ -2652,14 +2625,16 @@ ulint dict_create_foreign_constraints_low( /*================================*/ /* out: error code or DB_SUCCESS */ - trx_t* trx, /* in: transaction */ - char* sql_string, /* in: table create or ALTER TABLE - statement where foreign keys are declared like: + trx_t* trx, /* in: transaction */ + mem_heap_t* heap, /* in: memory heap */ + const char* sql_string, + /* in: CREATE TABLE or ALTER TABLE statement + where foreign keys are declared like: FOREIGN KEY (a, b) REFERENCES table2(c, d), table2 can be written also with the database name before it: test.table2; the default database is the database of parameter name */ - char* name) /* in: table full name in the normalized form + const char* name) /* in: table full name in the normalized form database_name/table_name */ { dict_table_t* table; @@ -2668,31 +2643,28 @@ dict_create_foreign_constraints_low( ulint highest_id_so_far = 0; dict_index_t* index; dict_foreign_t* foreign; - char* ptr = sql_string; - char* start_of_latest_foreign = sql_string; + const char* ptr = sql_string; + const char* start_of_latest_foreign = sql_string; char* buf = dict_foreign_err_buf; - char* constraint_name; /* this is NOT a null- - terminated string */ - ulint constraint_name_len; + const char* constraint_name; ibool success; ulint error; - char* ptr1; - char* ptr2; + const char* ptr1; + const char* ptr2; ulint i; ulint j; ibool is_on_delete; ulint n_on_deletes; ulint n_on_updates; dict_col_t* columns[500]; - char* column_names[500]; - ulint column_name_lens[500]; - char referenced_table_name[2500]; + 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); + table = dict_table_get_low((char*) name); if (table == NULL) { mutex_enter(&dict_foreign_err_mutex); @@ -2700,7 +2672,7 @@ dict_create_foreign_constraints_low( sprintf(buf + strlen(buf), " Error in foreign key constraint of table %.500s.\n" "Cannot find the table from the internal data dictionary of InnoDB.\n" -"Create table statement:\n%.2000\n", name, sql_string); +"Create table statement:\n%.2000s\n", name, sql_string); ut_a(strlen(buf) < DICT_FOREIGN_ERR_BUF_LEN); mutex_exit(&dict_foreign_err_mutex); @@ -2729,7 +2701,7 @@ dict_create_foreign_constraints_low( buffer */ ptr = dict_scan_table_name(ptr, &table_to_alter, name, - &success, referenced_table_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); @@ -2757,8 +2729,8 @@ dict_create_foreign_constraints_low( loop: /* Scan either to "CONSTRAINT" or "FOREIGN", whichever is closer */ - ptr1 = dict_scan_to(ptr, (char *) "CONSTRAINT"); - ptr2 = dict_scan_to(ptr, (char *) "FOREIGN"); + ptr1 = dict_scan_to(ptr, "CONSTRAINT"); + ptr2 = dict_scan_to(ptr, "FOREIGN"); constraint_name = NULL; @@ -2768,7 +2740,7 @@ loop: the id of the constraint to system tables. */ ptr = ptr1; - ptr = dict_accept(ptr, (char *) "CONSTRAINT", &success); + ptr = dict_accept(ptr, "CONSTRAINT", &success); ut_a(success); @@ -2782,8 +2754,7 @@ loop: /* read constraint name unless got "CONSTRAINT FOREIGN" */ if (ptr != ptr2) { - ptr = dict_scan_id(ptr, &constraint_name, - &constraint_name_len, FALSE); + ptr = dict_scan_id(ptr, heap, &constraint_name, FALSE); } } else { ptr = ptr2; @@ -2801,19 +2772,19 @@ loop: start_of_latest_foreign = ptr; - ptr = dict_accept(ptr, (char *) "FOREIGN", &success); + ptr = dict_accept(ptr, "FOREIGN", &success); if (!isspace(*ptr)) { goto loop; } - ptr = dict_accept(ptr, (char *) "KEY", &success); + ptr = dict_accept(ptr, "KEY", &success); if (!success) { goto loop; } - ptr = dict_accept(ptr, (char *) "(", &success); + ptr = dict_accept(ptr, "(", &success); if (!success) { /* MySQL allows also an index id before the '('; we @@ -2827,7 +2798,7 @@ loop: return(DB_CANNOT_ADD_CONSTRAINT); } - ptr = dict_accept(ptr, (char *) "(", &success); + ptr = dict_accept(ptr, "(", &success); if (!success) { /* We do not flag a syntax error here because in an @@ -2841,8 +2812,9 @@ 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, - column_names + i, column_name_lens + i); + heap, column_names + i); if (!success) { mutex_enter(&dict_foreign_err_mutex); ut_sprintf_timestamp(buf); @@ -2858,13 +2830,13 @@ col_loop1: i++; - ptr = dict_accept(ptr, (char *) ",", &success); + ptr = dict_accept(ptr, ",", &success); if (success) { goto col_loop1; } - ptr = dict_accept(ptr, (char *) ")", &success); + ptr = dict_accept(ptr, ")", &success); if (!success) { dict_foreign_report_syntax_err(name, start_of_latest_foreign, @@ -2914,15 +2886,11 @@ col_loop1: db_len = dict_get_db_name_len(table->name); foreign->id = mem_heap_alloc(foreign->heap, - db_len + 1 + constraint_name_len + 1); - + db_len + strlen(constraint_name) + 2); + ut_memcpy(foreign->id, table->name, db_len); - foreign->id[db_len] = '/'; - - ut_memcpy(foreign->id + db_len + 1, constraint_name, - constraint_name_len); - foreign->id[db_len + 1 + constraint_name_len] = '\0'; + strcpy(foreign->id + db_len + 1, constraint_name); } foreign->foreign_table = table; @@ -2932,14 +2900,12 @@ col_loop1: foreign->foreign_col_names = mem_heap_alloc(foreign->heap, i * sizeof(void*)); for (i = 0; i < foreign->n_fields; i++) { - foreign->foreign_col_names[i] = mem_heap_alloc(foreign->heap, - 1 + ut_strlen(columns[i]->name)); - ut_memcpy(foreign->foreign_col_names[i], columns[i]->name, - 1 + ut_strlen(columns[i]->name)); + foreign->foreign_col_names[i] = + mem_heap_strdup(foreign->heap, columns[i]->name); } ptr = dict_scan_table_name(ptr, &referenced_table, name, - &success, 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! */ @@ -2973,7 +2939,7 @@ col_loop1: col_loop2: ptr = dict_scan_col(ptr, &success, referenced_table, columns + i, - column_names + i, column_name_lens + i); + heap, column_names + i); i++; if (!success) { @@ -3179,21 +3145,14 @@ try_find_index: foreign->referenced_index = index; foreign->referenced_table = referenced_table; - foreign->referenced_table_name = mem_heap_alloc(foreign->heap, - 1 + ut_strlen(referenced_table_name)); - - ut_memcpy(foreign->referenced_table_name, referenced_table_name, - 1 + ut_strlen(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*)); for (i = 0; i < foreign->n_fields; i++) { foreign->referenced_col_names[i] - = mem_heap_alloc(foreign->heap, - 1 + column_name_lens[i]); - ut_memcpy(foreign->referenced_col_names[i], column_names[i], - column_name_lens[i]); - (foreign->referenced_col_names[i])[column_name_lens[i]] = '\0'; + = mem_heap_strdup(foreign->heap, column_names[i]); } /* We found an ok constraint definition: add to the lists */ @@ -3230,15 +3189,18 @@ dict_create_foreign_constraints( char* name) /* in: table full name in the normalized form database_name/table_name */ { - char* str; - ulint err; + char* str; + ulint err; + mem_heap_t* heap; str = dict_strip_comments(sql_string); + heap = mem_heap_create(10000); - err = dict_create_foreign_constraints_low(trx, str, name); + err = dict_create_foreign_constraints_low(trx, heap, str, name); + + mem_heap_free(heap); + mem_free(str); - mem_free(str); - return(err); } @@ -3258,17 +3220,15 @@ dict_foreign_parse_drop_constraints( dict_table_t* table, /* in: table */ ulint* n, /* out: number of constraints to drop */ - char*** constraints_to_drop) /* out: id's of the + const char*** constraints_to_drop) /* out: id's of the constraints to drop */ { - dict_foreign_t* foreign; - ibool success; - char* str; - char* ptr; + dict_foreign_t* foreign; + ibool success; + char* str; + const char* ptr; char* buf = dict_foreign_err_buf; - char* start; - char* id; - ulint len; + const char* id; *n = 0; @@ -3281,47 +3241,43 @@ dict_foreign_parse_drop_constraints( ut_ad(mutex_own(&(dict_sys->mutex))); #endif /* UNIV_SYNC_DEBUG */ loop: - ptr = dict_scan_to(ptr, (char *) "DROP"); + ptr = dict_scan_to(ptr, "DROP"); if (*ptr == '\0') { - ut_a(*n < 1000); - mem_free(str); return(DB_SUCCESS); } - ptr = dict_accept(ptr, (char *) "DROP", &success); + ptr = dict_accept(ptr, "DROP", &success); if (!isspace(*ptr)) { goto loop; } - ptr = dict_accept(ptr, (char *) "FOREIGN", &success); + ptr = dict_accept(ptr, "FOREIGN", &success); if (!success) { goto loop; } - ptr = dict_accept(ptr, (char *) "KEY", &success); + ptr = dict_accept(ptr, "KEY", &success); if (!success) { goto syntax_error; } - ptr = dict_scan_id(ptr, &start, &len, TRUE); + ptr = dict_scan_id(ptr, heap, &id, TRUE); - if (start == NULL) { + if (id == NULL) { goto syntax_error; } - id = mem_heap_alloc(heap, len + 1); - ut_memcpy(id, start, len); - id[len] = '\0'; + ut_a(*n < 1000); (*constraints_to_drop)[*n] = id; (*n)++; @@ -3330,9 +3286,9 @@ loop: foreign = UT_LIST_GET_FIRST(table->foreign_list); while (foreign != NULL) { - if (0 == ut_strcmp(foreign->id, id) + if (0 == strcmp(foreign->id, id) || (strchr(foreign->id, '/') - && 0 == ut_strcmp(id, + && 0 == strcmp(id, dict_remove_db_name(foreign->id)))) { /* Found */ break; diff --git a/innobase/dict/dict0load.c b/innobase/dict/dict0load.c index 5a5830a2517..06306ca483a 100644 --- a/innobase/dict/dict0load.c +++ b/innobase/dict/dict0load.c @@ -39,7 +39,6 @@ dict_get_first_table_name_in_db( rec_t* rec; byte* field; ulint len; - char* table_name; mtr_t mtr; #ifdef UNIV_SYNC_DEBUG @@ -91,9 +90,7 @@ loop: /* We found one */ - table_name = mem_alloc(len + 1); - ut_memcpy(table_name, field, len); - table_name[len] = '\0'; + char* table_name = mem_strdupl(field, len); btr_pcur_close(&pcur); mtr_commit(&mtr); @@ -122,7 +119,6 @@ dict_print(void) rec_t* rec; byte* field; ulint len; - char table_name[10000]; mtr_t mtr; mutex_enter(&(dict_sys->mutex)); @@ -156,14 +152,14 @@ loop: /* We found one */ - ut_memcpy(table_name, field, len); - table_name[len] = '\0'; - + char* table_name = mem_strdupl(field, len); + btr_pcur_store_position(&pcur, &mtr); mtr_commit(&mtr); - + table = dict_table_get_low(table_name); + mem_free(table_name); if (table == NULL) { fprintf(stderr, "InnoDB: Failed to load table %s\n", @@ -205,7 +201,6 @@ dict_load_columns( byte* field; ulint len; byte* buf; - char* name_buf; char* name; ulint mtype; ulint prtype; @@ -256,12 +251,7 @@ dict_load_columns( dict_table_get_first_index(sys_columns), 4))->name)); field = rec_get_nth_field(rec, 4, &len); - - name_buf = mem_heap_alloc(heap, len + 1); - ut_memcpy(name_buf, field, len); - name_buf[len] = '\0'; - - name = name_buf; + name = mem_heap_strdupl(heap, field, len); field = rec_get_nth_field(rec, 5, &len); mtype = mach_read_from_4(field); @@ -304,7 +294,6 @@ dict_load_fields( btr_pcur_t pcur; dtuple_t* tuple; dfield_t* dfield; - char* col_name; ulint pos_and_prefix_len; ulint prefix_len; rec_t* rec; @@ -383,11 +372,8 @@ dict_load_fields( field = rec_get_nth_field(rec, 4, &len); - col_name = mem_heap_alloc(heap, len + 1); - ut_memcpy(col_name, field, len); - col_name[len] = '\0'; - - dict_mem_index_add_field(index, col_name, 0, prefix_len); + dict_mem_index_add_field(index, + mem_heap_strdupl(heap, field, len), 0, prefix_len); btr_pcur_move_to_next_user_rec(&pcur, &mtr); } @@ -492,10 +478,7 @@ dict_load_indexes( dict_table_get_first_index(sys_indexes), 4))->name)); field = rec_get_nth_field(rec, 4, &name_len); - - name_buf = mem_heap_alloc(heap, name_len + 1); - ut_memcpy(name_buf, field, name_len); - name_buf[name_len] = '\0'; + name_buf = mem_heap_strdupl(heap, field, name_len); field = rec_get_nth_field(rec, 5, &len); n_fields = mach_read_from_4(field); @@ -544,7 +527,7 @@ dict_load_indexes( if (is_sys_table && ((type & DICT_CLUSTERED) || ((table == dict_sys->sys_tables) - && (name_len == ut_strlen("ID_IND")) + && (name_len == (sizeof "ID_IND") - 1) && (0 == ut_memcmp(name_buf, (char*)"ID_IND", name_len))))) { @@ -593,7 +576,6 @@ dict_load_table( rec_t* rec; byte* field; ulint len; - char* buf; ulint space; ulint n_cols; ulint err; @@ -674,15 +656,13 @@ dict_load_table( if (table->type == DICT_TABLE_CLUSTER_MEMBER) { ut_error; - +#if 0 /* clustered tables have not been implemented yet */ field = rec_get_nth_field(rec, 6, &len); table->mix_id = mach_read_from_8(field); field = rec_get_nth_field(rec, 8, &len); - buf = mem_heap_alloc(heap, len); - ut_memcpy(buf, field, len); - - table->cluster_name = buf; + table->cluster_name = mem_heap_strdupl(heap, field, len); +#endif } if ((table->type == DICT_TABLE_CLUSTER) @@ -751,7 +731,6 @@ dict_load_table_on_id( byte* field; ulint len; dict_table_t* table; - char* name; mtr_t mtr; #ifdef UNIV_SYNC_DEBUG @@ -814,13 +793,8 @@ dict_load_table_on_id( /* Now we get the table name from the record */ field = rec_get_nth_field(rec, 1, &len); - - name = mem_heap_alloc(heap, len + 1); - ut_memcpy(name, field, len); - name[len] = '\0'; - /* Load the table definition to memory */ - table = dict_load_table(name); + table = dict_load_table(mem_heap_strdupl(heap, field, len)); btr_pcur_close(&pcur); mtr_commit(&mtr); @@ -867,7 +841,6 @@ dict_load_foreign_cols( btr_pcur_t pcur; dtuple_t* tuple; dfield_t* dfield; - char* col_name; rec_t* rec; byte* field; ulint len; @@ -912,21 +885,13 @@ dict_load_foreign_cols( ut_a(i == mach_read_from_4(field)); field = rec_get_nth_field(rec, 4, &len); - - col_name = mem_heap_alloc(foreign->heap, len + 1); - ut_memcpy(col_name, field, len); - col_name[len] = '\0'; - - foreign->foreign_col_names[i] = col_name; + foreign->foreign_col_names[i] = + mem_heap_strdupl(foreign->heap, field, len); field = rec_get_nth_field(rec, 5, &len); + foreign->referenced_col_names[i] = + mem_heap_strdupl(foreign->heap, field, len); - col_name = mem_heap_alloc(foreign->heap, len + 1); - ut_memcpy(col_name, field, len); - col_name[len] = '\0'; - - foreign->referenced_col_names[i] = col_name; - btr_pcur_move_to_next_user_rec(&pcur, &mtr); } @@ -1023,23 +988,15 @@ dict_load_foreign( foreign->type = foreign->n_fields >> 24; foreign->n_fields = foreign->n_fields & 0xFFFFFF; - foreign->id = mem_heap_alloc(foreign->heap, ut_strlen(id) + 1); - - ut_memcpy(foreign->id, id, ut_strlen(id) + 1); + foreign->id = mem_heap_strdup(foreign->heap, id); field = rec_get_nth_field(rec, 3, &len); - - foreign->foreign_table_name = mem_heap_alloc(foreign->heap, 1 + len); - - ut_memcpy(foreign->foreign_table_name, field, len); - foreign->foreign_table_name[len] = '\0'; + foreign->foreign_table_name = + mem_heap_strdupl(foreign->heap, field, len); field = rec_get_nth_field(rec, 4, &len); - - foreign->referenced_table_name = mem_heap_alloc(foreign->heap, - 1 + len); - ut_memcpy(foreign->referenced_table_name, field, len); - foreign->referenced_table_name[len] = '\0'; + foreign->referenced_table_name = + mem_heap_strdupl(foreign->heap, field, len); btr_pcur_close(&pcur); mtr_commit(&mtr); @@ -1153,10 +1110,7 @@ loop: /* Now we get a foreign key constraint id */ field = rec_get_nth_field(rec, 1, &len); - - id = mem_heap_alloc(heap, len + 1); - ut_memcpy(id, field, len); - id[len] = '\0'; + id = mem_heap_strdupl(heap, field, len); btr_pcur_store_position(&pcur, &mtr); diff --git a/innobase/dict/dict0mem.c b/innobase/dict/dict0mem.c index f8c54022c9e..c4b393d292b 100644 --- a/innobase/dict/dict0mem.c +++ b/innobase/dict/dict0mem.c @@ -49,9 +49,7 @@ dict_mem_table_create( table->heap = heap; - str = mem_heap_alloc(heap, 1 + ut_strlen(name)); - - ut_strcpy(str, name); + str = mem_heap_strdup(heap, name); table->type = DICT_TABLE_ORDINARY; table->name = str; @@ -146,7 +144,6 @@ dict_mem_table_add_col( ulint len, /* in: length */ ulint prec) /* in: precision */ { - char* str; dict_col_t* col; dtype_t* type; @@ -154,15 +151,11 @@ dict_mem_table_add_col( ut_ad(table->magic_n == DICT_TABLE_MAGIC_N); table->n_def++; - + col = dict_table_get_nth_col(table, table->n_def - 1); - str = mem_heap_alloc(table->heap, 1 + ut_strlen(name)); - - ut_strcpy(str, name); - col->ind = table->n_def - 1; - col->name = str; + col->name = mem_heap_strdup(table->heap, name); col->table = table; col->ord_part = 0; @@ -188,7 +181,6 @@ dict_mem_index_create( ulint type, /* in: DICT_UNIQUE, DICT_CLUSTERED, ... ORed */ ulint n_fields) /* in: number of fields */ { - char* str; dict_index_t* index; mem_heap_t* heap; @@ -199,13 +191,9 @@ dict_mem_index_create( index->heap = heap; - str = mem_heap_alloc(heap, 1 + ut_strlen(index_name)); - - ut_strcpy(str, index_name); - index->type = type; index->space = space; - index->name = str; + index->name = mem_heap_strdup(heap, index_name); index->table_name = table_name; index->table = NULL; index->n_def = 0; diff --git a/innobase/eval/eval0eval.c b/innobase/eval/eval0eval.c index 157d4e4f98d..4e16c36b056 100644 --- a/innobase/eval/eval0eval.c +++ b/innobase/eval/eval0eval.c @@ -667,7 +667,6 @@ eval_predefined( { que_node_t* arg1; lint int_val; - byte* str1; byte* data; int func; @@ -681,21 +680,63 @@ eval_predefined( } else if (func == PARS_TO_CHAR_TOKEN) { + /* Convert number to character string as a + signed decimal integer. */ + + ulint uint_val; + int int_len; + int_val = eval_node_get_int_val(arg1); - - data = eval_node_ensure_val_buf(func_node, 11); - sprintf((char*)data, "%10li", int_val); + /* Determine the length of the string. */ - dfield_set_len(que_node_get_val(func_node), 10); + if (int_val == 0) { + int_len = 1; /* the number 0 occupies 1 byte */ + } else { + int_len = 0; + if (int_val < 0) { + uint_val = ((ulint) -int_val - 1) + 1; + int_len++; /* reserve space for minus sign */ + } else { + uint_val = (ulint) int_val; + } + for (; uint_val > 0; int_len++) { + uint_val /= 10; + } + } + + /* allocate the string */ + data = eval_node_ensure_val_buf(func_node, int_len + 1); + + /* add terminating NUL character */ + data[int_len] = 0; + + /* convert the number */ + + if (int_val == 0) { + data[0] = '0'; + } else { + int tmp; + if (int_val < 0) { + data[0] = '-'; /* preceding minus sign */ + uint_val = ((ulint) -int_val - 1) + 1; + } else { + uint_val = (ulint) int_val; + } + for (tmp = int_len; uint_val > 0; uint_val /= 10) { + data[--tmp] = '0' + (uint_val % 10); + } + } + + dfield_set_len((dfield_t*) que_node_get_val(func_node), + int_len); return; } else if (func == PARS_TO_NUMBER_TOKEN) { - str1 = dfield_get_data(que_node_get_val(arg1)); - - int_val = atoi((char*)str1); + int_val = atoi((char*) + dfield_get_data(que_node_get_val(arg1))); } else if (func == PARS_SYSDATE_TOKEN) { int_val = (lint)ut_time(); diff --git a/innobase/fil/fil0fil.c b/innobase/fil/fil0fil.c index 9f33013d2f9..1abb1b926f2 100644 --- a/innobase/fil/fil0fil.c +++ b/innobase/fil/fil0fil.c @@ -288,7 +288,6 @@ fil_node_create( { fil_node_t* node; fil_space_t* space; - char* name2; fil_system_t* system = fil_system; ut_a(system); @@ -299,11 +298,7 @@ fil_node_create( node = mem_alloc(sizeof(fil_node_t)); - name2 = mem_alloc(ut_strlen(name) + 1); - - ut_strcpy(name2, name); - - node->name = name2; + node->name = mem_strdup(name); node->open = FALSE; node->size = size; node->magic_n = FIL_NODE_MAGIC_N; @@ -626,7 +621,6 @@ fil_space_create( ulint purpose)/* in: FIL_TABLESPACE, or FIL_LOG if log */ { fil_space_t* space; - char* name2; fil_system_t* system = fil_system; ut_a(system); @@ -642,11 +636,7 @@ fil_space_create( space = mem_alloc(sizeof(fil_space_t)); - name2 = mem_alloc(ut_strlen(name) + 1); - - ut_strcpy(name2, name); - - space->name = name2; + space->name = mem_strdup(name); space->id = id; space->purpose = purpose; space->size = 0; diff --git a/innobase/ibuf/ibuf0ibuf.c b/innobase/ibuf/ibuf0ibuf.c index f2c631d88cd..0af47a8ccc2 100644 --- a/innobase/ibuf/ibuf0ibuf.c +++ b/innobase/ibuf/ibuf0ibuf.c @@ -102,9 +102,10 @@ pages, as long as it obeys the access order rules. */ #define IBUF_POOL_SIZE_PER_MAX_SIZE 2 /* The insert buffer control structure */ -ibuf_t* ibuf = NULL; +ibuf_t* ibuf = NULL; -ulint ibuf_rnd = 986058871; +static +ulint ibuf_rnd = 986058871; ulint ibuf_flush_count = 0; @@ -113,9 +114,9 @@ ulint ibuf_flush_count = 0; #define IBUF_COUNT_N_PAGES 10000 /* Buffered entry counts for file pages, used in debugging */ -ulint* ibuf_counts[IBUF_COUNT_N_SPACES]; +static ulint* ibuf_counts[IBUF_COUNT_N_SPACES]; -ibool ibuf_counts_inited = FALSE; +static ibool ibuf_counts_inited = FALSE; /* The start address for an insert buffer bitmap page bitmap */ #define IBUF_BITMAP PAGE_DATA @@ -129,15 +130,18 @@ ibool ibuf_counts_inited = FALSE; /* Number of bits describing a single page */ #define IBUF_BITS_PER_PAGE 4 +#if IBUF_BITS_PER_PAGE % 2 +# error "IBUF_BITS_PER_PAGE must be an even number!" +#endif /* The mutex used to block pessimistic inserts to ibuf trees */ -mutex_t ibuf_pessimistic_insert_mutex; +static mutex_t ibuf_pessimistic_insert_mutex; /* The mutex protecting the insert buffer structs */ -mutex_t ibuf_mutex; +static mutex_t ibuf_mutex; /* The mutex protecting the insert buffer bitmaps */ -mutex_t ibuf_bitmap_mutex; +static mutex_t ibuf_bitmap_mutex; /* The area in pages from which contract looks for page numbers for merge */ #define IBUF_MERGE_AREA 8 @@ -2506,16 +2510,13 @@ ibuf_merge_or_delete_for_page( dtuple_t* entry; dtuple_t* search_tuple; rec_t* ibuf_rec; - ibool closed; buf_block_t* block; page_t* bitmap_page; ibuf_data_t* ibuf_data; - ibool success; ulint n_inserts; +#ifdef UNIV_IBUF_DEBUG ulint volume; - ulint old_bits; - ulint new_bits; - dulint max_trx_id; +#endif ibool corruption_noticed = FALSE; mtr_t mtr; char err_buf[500]; @@ -2605,12 +2606,14 @@ ibuf_merge_or_delete_for_page( } n_inserts = 0; +#ifdef UNIV_IBUF_DEBUG volume = 0; +#endif loop: mtr_start(&mtr); if (page) { - success = buf_page_get_known_nowait(RW_X_LATCH, page, + ibool success = buf_page_get_known_nowait(RW_X_LATCH, page, BUF_KEEP_OLD, IB__FILE__, __LINE__, &mtr); @@ -2667,7 +2670,7 @@ loop: keep the latch to the ibuf_rec page until the insertion is finished! */ - max_trx_id = page_get_max_trx_id( + dulint max_trx_id = page_get_max_trx_id( buf_frame_align(ibuf_rec)); page_update_max_trx_id(page, max_trx_id); @@ -2686,9 +2689,8 @@ loop: n_inserts++; /* Delete the record from ibuf */ - closed = ibuf_delete_rec(space, page_no, &pcur, search_tuple, - &mtr); - if (closed) { + if (ibuf_delete_rec(space, page_no, &pcur, search_tuple, + &mtr)) { /* Deletion was pessimistic and mtr was committed: we start from the beginning again */ @@ -2717,10 +2719,9 @@ reset_bit: ibuf_bitmap_page_set_bits(bitmap_page, page_no, IBUF_BITMAP_BUFFERED, FALSE, &mtr); if (page) { - old_bits = ibuf_bitmap_page_get_bits(bitmap_page, page_no, - IBUF_BITMAP_FREE, &mtr); - new_bits = ibuf_index_page_calc_free(page); - + ulint old_bits = ibuf_bitmap_page_get_bits(bitmap_page, + page_no, IBUF_BITMAP_FREE, &mtr); + ulint new_bits = ibuf_index_page_calc_free(page); #ifdef UNIV_IBUF_DEBUG /* printf("Old bits %lu new bits %lu max size %lu\n", old_bits, new_bits, diff --git a/innobase/include/data0data.h b/innobase/include/data0data.h index c4e93bec738..b100ef5b583 100644 --- a/innobase/include/data0data.h +++ b/innobase/include/data0data.h @@ -294,6 +294,7 @@ dtuple_check_typed_no_assert( /*=========================*/ /* out: TRUE if ok */ dtuple_t* tuple); /* in: tuple */ +#ifdef UNIV_DEBUG /************************************************************** Validates the consistency of a tuple which must be complete, i.e, all fields must have been set. */ @@ -303,6 +304,7 @@ dtuple_validate( /*============*/ /* out: TRUE if ok */ dtuple_t* tuple); /* in: tuple */ +#endif /* UNIV_DEBUG */ /***************************************************************** Pretty prints a dfield value according to its data type. */ diff --git a/innobase/include/data0data.ic b/innobase/include/data0data.ic index def80d3f430..697a272ccd6 100644 --- a/innobase/include/data0data.ic +++ b/innobase/include/data0data.ic @@ -299,7 +299,7 @@ dtuple_get_data_size( ut_ad(tuple); ut_ad(dtuple_check_typed(tuple)); - ut_ad(tuple->magic_n = DATA_TUPLE_MAGIC_N); + ut_ad(tuple->magic_n == DATA_TUPLE_MAGIC_N); n_fields = tuple->n_fields; @@ -355,7 +355,7 @@ dtuple_fold( ulint fold; ut_ad(tuple); - ut_ad(tuple->magic_n = DATA_TUPLE_MAGIC_N); + ut_ad(tuple->magic_n == DATA_TUPLE_MAGIC_N); ut_ad(dtuple_check_typed(tuple)); fold = ut_fold_dulint(tree_id); diff --git a/innobase/include/dict0dict.h b/innobase/include/dict0dict.h index 2e51fecdb8d..f0523c5f204 100644 --- a/innobase/include/dict0dict.h +++ b/innobase/include/dict0dict.h @@ -32,20 +32,21 @@ Get the database name length in a table name. */ ulint dict_get_db_name_len( /*=================*/ - /* out: database name length */ - char* name); /* in: table name in the form dbname '/' tablename */ + /* out: database name length */ + const char* name); /* in: table name in the form + dbname '/' tablename */ /************************************************************************* Accepts a specified string. Comparisons are case-insensitive. */ -char* +const char* dict_accept( /*========*/ - /* out: if string was accepted, the pointer - is moved after that, else ptr is returned */ - char* ptr, /* in: scan from this */ - const char* string,/* in: accept only this string as the next - non-whitespace string */ - ibool* success);/* out: TRUE if accepted */ + /* out: if string was accepted, the pointer + is moved after that, else ptr is returned */ + const char* ptr, /* in: scan from this */ + const char* string, /* in: accept only this string as the next + non-whitespace string */ + ibool* success);/* out: TRUE if accepted */ /************************************************************************ Decrements the count of open MySQL handles to a table. */ @@ -216,7 +217,7 @@ dict_foreign_parse_drop_constraints( dict_table_t* table, /* in: table */ ulint* n, /* out: number of constraints to drop */ - char*** constraints_to_drop); /* out: id's of the + const char*** constraints_to_drop); /* out: id's of the constraints to drop */ /************************************************************************** Returns a table object and memoryfixes it. NOTE! This is a high-level @@ -321,7 +322,7 @@ dict_table_print_by_name( /*=====================*/ char* name); /************************************************************************** -Sprintfs to a string info on foreign keys of a table. */ +Outputs info on foreign keys of a table. */ void dict_print_info_on_foreign_keys( diff --git a/innobase/include/lock0lock.h b/innobase/include/lock0lock.h index 0fd1696b882..103d28cd130 100644 --- a/innobase/include/lock0lock.h +++ b/innobase/include/lock0lock.h @@ -526,12 +526,12 @@ extern lock_sys_t* lock_sys; #define LOCK_X 5 /* exclusive */ #define LOCK_AUTO_INC 6 /* locks the auto-inc counter of a table in an exclusive mode */ -#define LOCK_MODE_MASK 0xF /* mask used to extract mode from the +#define LOCK_MODE_MASK 0xFUL /* mask used to extract mode from the type_mode field in a lock */ /* Lock types */ #define LOCK_TABLE 16 /* these type values should be so high that */ #define LOCK_REC 32 /* they can be ORed to the lock mode */ -#define LOCK_TYPE_MASK 0xF0 /* mask used to extract lock type from the +#define LOCK_TYPE_MASK 0xF0UL /* mask used to extract lock type from the type_mode field in a lock */ /* Waiting lock flag */ #define LOCK_WAIT 256 /* this wait bit should be so high that diff --git a/innobase/include/log0log.h b/innobase/include/log0log.h index 9fba0c46407..3295bc2d231 100644 --- a/innobase/include/log0log.h +++ b/innobase/include/log0log.h @@ -366,7 +366,6 @@ Writes a buffer to a log file group. */ void log_group_write_buf( /*================*/ - ulint type, /* in: LOG_FLUSH or LOG_RECOVER */ log_group_t* group, /* in: log group */ byte* buf, /* in: buffer */ ulint len, /* in: buffer len; must be divisible @@ -551,7 +550,7 @@ extern log_t* log_sys; highest bit is set to 1 if this is the first log block in a log flush write segment */ -#define LOG_BLOCK_FLUSH_BIT_MASK 0x80000000 +#define LOG_BLOCK_FLUSH_BIT_MASK 0x80000000UL /* mask used to get the highest bit in the preceding field */ #define LOG_BLOCK_HDR_DATA_LEN 4 /* number of bytes of log written to diff --git a/innobase/include/mem0mem.h b/innobase/include/mem0mem.h index 9ab3b2cd754..89e2a337c99 100644 --- a/innobase/include/mem0mem.h +++ b/innobase/include/mem0mem.h @@ -271,6 +271,59 @@ mem_realloc( ulint n, /* in: desired number of bytes */ char* file_name,/* in: file name where called */ ulint line); /* in: line where called */ + +/************************************************************************** +Duplicates a NUL-terminated string. */ +UNIV_INLINE +char* +mem_strdup( +/*=======*/ + /* out, own: a copy of the string, + must be deallocated with mem_free */ + const char* str); /* in: string to be copied */ +/************************************************************************** +Makes a NUL-terminated copy of a nonterminated string. */ +UNIV_INLINE +char* +mem_strdupl( +/*========*/ + /* out, own: a copy of the string, + must be deallocated with mem_free */ + const char* str, /* in: string to be copied */ + ulint len); /* in: length of str, in bytes */ + +/************************************************************************** +Makes a NUL-terminated quoted copy of a NUL-terminated string. */ +UNIV_INLINE +char* +mem_strdupq( +/*========*/ + /* out, own: a quoted copy of the string, + must be deallocated with mem_free */ + const char* str, /* in: string to be copied */ + char q); /* in: quote character */ + +/************************************************************************** +Duplicates a NUL-terminated string, allocated from a memory heap. */ +UNIV_INLINE +char* +mem_heap_strdup( +/*============*/ + /* out, own: a copy of the string */ + mem_heap_t* heap, /* in: memory heap where string is allocated */ + const char* str); /* in: string to be copied */ +/************************************************************************** +Makes a NUL-terminated copy of a nonterminated string, +allocated from a memory heap. */ +UNIV_INLINE +char* +mem_heap_strdupl( +/*=============*/ + /* out, own: a copy of the string */ + mem_heap_t* heap, /* in: memory heap where string is allocated */ + const char* str, /* in: string to be copied */ + ulint len); /* in: length of str, in bytes */ + #ifdef MEM_PERIODIC_CHECK /********************************************************************** Goes through the list of all allocated mem blocks, checks their magic diff --git a/innobase/include/mem0mem.ic b/innobase/include/mem0mem.ic index fb4cef49ec9..c250e6948ec 100644 --- a/innobase/include/mem0mem.ic +++ b/innobase/include/mem0mem.ic @@ -579,3 +579,99 @@ mem_realloc( return(mem_alloc_func(n, file_name, line)); } + +/************************************************************************** +Duplicates a NUL-terminated string. */ +UNIV_INLINE +char* +mem_strdup( +/*=======*/ + /* out, own: a copy of the string, + must be deallocated with mem_free */ + const char* str) /* in: string to be copied */ +{ + ulint len = strlen(str) + 1; + return(memcpy(mem_alloc(len), str, len)); +} + +/************************************************************************** +Makes a NUL-terminated copy of a nonterminated string. */ +UNIV_INLINE +char* +mem_strdupl( +/*========*/ + /* out, own: a copy of the string, + must be deallocated with mem_free */ + const char* str, /* in: string to be copied */ + ulint len) /* in: length of str, in bytes */ +{ + char* s = mem_alloc(len + 1); + s[len] = 0; + return(memcpy(s, str, len)); +} + +/************************************************************************** +Makes a NUL-terminated quoted copy of a NUL-terminated string. */ +UNIV_INLINE +char* +mem_strdupq( +/*========*/ + /* out, own: a quoted copy of the string, + must be deallocated with mem_free */ + const char* str, /* in: string to be copied */ + char q) /* in: quote character */ +{ + char* dst; + char* d; + const char* s = str; + int len = strlen(str) + 3; + /* calculate the number of quote characters in the string */ + while((s = strchr(s, q)) != NULL) { + s++; + len++; + } + /* allocate the quoted string, and copy it */ + d = dst = mem_alloc(len); + *d++ = q; + s = str; + while(*s) { + if ((*d++ = *s++) == q) { + *d++ = q; + } + } + *d++ = q; + *d++ = '\0'; + ut_ad(len == d - dst); + return(dst); +} + +/************************************************************************** +Duplicates a NUL-terminated string, allocated from a memory heap. */ +UNIV_INLINE +char* +mem_heap_strdup( +/*============*/ + /* out, own: a copy of the string */ + mem_heap_t* heap, /* in: memory heap where string is allocated */ + const char* str) /* in: string to be copied */ +{ + ulint len = strlen(str) + 1; + return(memcpy(mem_heap_alloc(heap, len), str, len)); +} + +/************************************************************************** +Makes a NUL-terminated copy of a nonterminated string, +allocated from a memory heap. */ +UNIV_INLINE +char* +mem_heap_strdupl( +/*=============*/ + /* out, own: a copy of the string */ + mem_heap_t* heap, /* in: memory heap where string is allocated */ + const char* str, /* in: string to be copied */ + ulint len) /* in: length of str, in bytes */ +{ + char* s = mem_heap_alloc(heap, len + 1); + s[len] = 0; + return(memcpy(s, str, len)); +} diff --git a/innobase/include/row0uins.h b/innobase/include/row0uins.h index df5e072487e..fc57881f691 100644 --- a/innobase/include/row0uins.h +++ b/innobase/include/row0uins.h @@ -26,8 +26,7 @@ ulint row_undo_ins( /*=========*/ /* out: DB_SUCCESS */ - undo_node_t* node, /* in: row undo node */ - que_thr_t* thr); /* in: query thread */ + undo_node_t* node); /* in: row undo node */ #ifndef UNIV_NONINL diff --git a/innobase/include/row0undo.h b/innobase/include/row0undo.h index 5402f1d9236..d64a00dcb8f 100644 --- a/innobase/include/row0undo.h +++ b/innobase/include/row0undo.h @@ -41,8 +41,7 @@ row_undo_search_clust_to_pcur( /* out: TRUE if found; NOTE the node->pcur must be closed by the caller, regardless of the return value */ - undo_node_t* node, /* in: row undo node */ - que_thr_t* thr); /* in: query thread */ + undo_node_t* node); /* in: row undo node */ /*************************************************************** Undoes a row operation in a table. This is a high-level function used in SQL execution graphs. */ diff --git a/innobase/include/ut0byte.h b/innobase/include/ut0byte.h index 4fb45221899..dd13b19b864 100644 --- a/innobase/include/ut0byte.h +++ b/innobase/include/ut0byte.h @@ -235,21 +235,19 @@ Copies a string to a memory location, setting characters to lower case. */ void ut_cpy_in_lower_case( /*=================*/ - char* dest, /* in: destination */ - char* source, /* in: source */ - ulint len); /* in: string length */ + char* dest, /* in: destination */ + const char* source, /* in: source */ + ulint len); /* in: string length */ /**************************************************************** Compares two strings when converted to lower case. */ int ut_cmp_in_lower_case( /*=================*/ - /* out: -1, 0, 1 if str1 < str2, str1 == str2, - str1 > str2, respectively */ - char* str1, /* in: string1 */ - char* str2, /* in: string2 */ - ulint len); /* in: length of both strings */ - + /* out: -1, 0, 1 if str1 < str2, str1 == str2, + str1 > str2, respectively */ + const char* str1, /* in: string1 */ + const char* str2); /* in: string2 */ #ifndef UNIV_NONINL #include "ut0byte.ic" diff --git a/innobase/include/ut0mem.h b/innobase/include/ut0mem.h index 13ee8d5f5fa..bfda5ded40c 100644 --- a/innobase/include/ut0mem.h +++ b/innobase/include/ut0mem.h @@ -75,6 +75,39 @@ UNIV_INLINE int ut_strcmp(void* str1, void* str2); +/************************************************************************** +Determine the length of a string when it is quoted with ut_strcpyq(). */ +UNIV_INLINE +ulint +ut_strlenq( +/*=======*/ + /* out: length of the string when quoted */ + const char* str, /* in: null-terminated string */ + char q); /* in: the quote character */ + +/************************************************************************** +Make a quoted copy of a string. */ + +char* +ut_strcpyq( +/*=======*/ + /* out: pointer to end of dest */ + char* dest, /* in: output buffer */ + char q, /* in: the quote character */ + const char* src); /* in: null-terminated string */ + +/************************************************************************** +Make a quoted copy of a fixed-length string. */ + +char* +ut_memcpyq( +/*=======*/ + /* out: pointer to end of dest */ + char* dest, /* in: output buffer */ + char q, /* in: the quote character */ + const char* src, /* in: string to be quoted */ + ulint len); /* in: length of src */ + /************************************************************************** Catenates two strings into newly allocated memory. The memory must be freed using mem_free. */ diff --git a/innobase/include/ut0mem.ic b/innobase/include/ut0mem.ic index 1049aee8ecc..951d9538424 100644 --- a/innobase/include/ut0mem.ic +++ b/innobase/include/ut0mem.ic @@ -48,3 +48,23 @@ ut_strcmp(void* str1, void* str2) return(strcmp((char*)str1, (char*)str2)); } +/************************************************************************** +Determine the length of a string when it is quoted with ut_strcpyq(). */ +UNIV_INLINE +ulint +ut_strlenq( +/*=======*/ + /* out: length of the string when quoted */ + const char* str, /* in: null-terminated string */ + char q) /* in: the quote character */ +{ + ulint len; + + for (len = 0; *str; len++, str++) { + if (*str == q) { + len++; + } + } + + return(len); +} diff --git a/innobase/include/ut0ut.h b/innobase/include/ut0ut.h index 8ec23b23dcd..637c9a68174 100644 --- a/innobase/include/ut0ut.h +++ b/innobase/include/ut0ut.h @@ -28,7 +28,9 @@ ut_sprintf( /*=======*/ char* buf, /* in/out: buffer where to print */ const char* format, /* in: format of prints */ - ...); /* in: arguments to be printed */ + ...) /* in: arguments to be printed */ + __attribute__((__format__ (__printf__, 2, 3))); + /************************************************************ Gets the high 32 bits in a ulint. That is makes a shift >> 32, but since there seem to be compiler bugs in both gcc and Visual C++, diff --git a/innobase/lock/lock0lock.c b/innobase/lock/lock0lock.c index c706ebceaec..812eea91d90 100644 --- a/innobase/lock/lock0lock.c +++ b/innobase/lock/lock0lock.c @@ -4592,7 +4592,6 @@ lock_clust_rec_modify_check_and_lock( dict_index_t* index, /* in: clustered index */ que_thr_t* thr) /* in: query thread */ { - trx_t* trx; ulint err; if (flags & BTR_NO_LOCKING_FLAG) { @@ -4602,8 +4601,6 @@ lock_clust_rec_modify_check_and_lock( ut_ad(index->type & DICT_CLUSTERED); - trx = thr_get_trx(thr); - lock_mutex_enter_kernel(); ut_ad(lock_table_has(thr_get_trx(thr), index->table, LOCK_IX)); diff --git a/innobase/log/log0log.c b/innobase/log/log0log.c index 8b4cbe034b9..3bc562eefb6 100644 --- a/innobase/log/log0log.c +++ b/innobase/log/log0log.c @@ -1015,7 +1015,7 @@ log_io_complete( return; } - if ((ulint)group & 0x1) { + if ((ulint)group & 0x1UL) { /* It was a checkpoint write */ group = (log_group_t*)((ulint)group - 1); @@ -1070,7 +1070,6 @@ static void log_group_file_header_flush( /*========================*/ - ulint type, /* in: LOG_FLUSH or LOG_RECOVER */ log_group_t* group, /* in: log group */ ulint nth_file, /* in: header to the nth file in the log file space */ @@ -1079,9 +1078,6 @@ log_group_file_header_flush( { byte* buf; ulint dest_offset; - - UT_NOT_USED(type); - #ifdef UNIV_SYNC_DEBUG ut_ad(mutex_own(&(log_sys->mutex))); #endif /* UNIV_SYNC_DEBUG */ @@ -1136,7 +1132,6 @@ Writes a buffer to a log file group. */ void log_group_write_buf( /*================*/ - ulint type, /* in: LOG_FLUSH or LOG_RECOVER */ log_group_t* group, /* in: log group */ byte* buf, /* in: buffer */ ulint len, /* in: buffer len; must be divisible @@ -1177,7 +1172,7 @@ loop: && write_header) { /* We start to write a new log file instance in the group */ - log_group_file_header_flush(type, group, + log_group_file_header_flush(group, next_offset / group->file_size, start_lsn); } @@ -1396,7 +1391,7 @@ loop: /* Do the write to the log files */ while (group) { - log_group_write_buf(LOG_FLUSH, group, + log_group_write_buf(group, log_sys->buf + area_start, area_end - area_start, ut_dulint_align_down(log_sys->written_to_all_lsn, @@ -2137,11 +2132,11 @@ void log_archived_file_name_gen( /*=======================*/ char* buf, /* in: buffer where to write */ - ulint id, /* in: group id */ + ulint id __attribute__((unused)), + /* in: group id; + currently we only archive the first group */ ulint file_no)/* in: file number */ { - UT_NOT_USED(id); /* Currently we only archive the first group */ - sprintf(buf, "%sib_arch_log_%010lu", srv_arch_dir, file_no); } diff --git a/innobase/log/log0recv.c b/innobase/log/log0recv.c index 7f06fb587cc..1e88b677093 100644 --- a/innobase/log/log0recv.c +++ b/innobase/log/log0recv.c @@ -274,8 +274,7 @@ recv_truncate_group( len = ut_dulint_minus(end_lsn, start_lsn); - log_group_write_buf(LOG_RECOVER, group, log_sys->buf, len, - start_lsn, 0); + log_group_write_buf(group, log_sys->buf, len, start_lsn, 0); if (ut_dulint_cmp(end_lsn, finish_lsn) >= 0) { return; @@ -330,8 +329,7 @@ recv_copy_group( len = ut_dulint_minus(end_lsn, start_lsn); - log_group_write_buf(LOG_RECOVER, group, log_sys->buf, len, - start_lsn, 0); + log_group_write_buf(group, log_sys->buf, len, start_lsn, 0); if (ut_dulint_cmp(end_lsn, recovered_lsn) >= 0) { @@ -523,7 +521,7 @@ recv_find_max_checkpoint( "InnoDB: the problem may be that during an earlier attempt you managed\n" "InnoDB: to create the InnoDB data files, but log file creation failed.\n" "InnoDB: If that is the case, please refer to section 3.1 of\n" -"InnoDB: http://www.innodb.com/ibman.html\n"); +"InnoDB: http://www.innodb.com/ibman.php\n"); return(DB_ERROR); } diff --git a/innobase/mem/mem0mem.c b/innobase/mem/mem0mem.c index 6de8d0c5f20..e1b9a762381 100644 --- a/innobase/mem/mem0mem.c +++ b/innobase/mem/mem0mem.c @@ -196,12 +196,7 @@ mem_heap_create_block( mem_block_set_start(block, MEM_BLOCK_HEADER_SIZE); block->free_block = NULL; - - if (init_block != NULL) { - block->init_block = TRUE; - } else { - block->init_block = FALSE; - } + block->init_block = (init_block != NULL); ut_ad((ulint)MEM_BLOCK_HEADER_SIZE < len); diff --git a/innobase/mtr/mtr0log.c b/innobase/mtr/mtr0log.c index 91ff588713d..e3ba531bcb8 100644 --- a/innobase/mtr/mtr0log.c +++ b/innobase/mtr/mtr0log.c @@ -95,6 +95,7 @@ mlog_parse_initial_log_record( } *type = (byte)((ulint)*ptr & ~MLOG_SINGLE_REC_FLAG); + ut_ad(*type <= MLOG_BIGGEST_TYPE); ptr++; @@ -171,13 +172,13 @@ mlog_parse_nbytes( } if (type == MLOG_1BYTE) { - if (val > 0xFF) { + if (val > 0xFFUL) { recv_sys->found_corrupt_log = TRUE; return(NULL); } } else if (type == MLOG_2BYTES) { - if (val > 0xFFFF) { + if (val > 0xFFFFUL) { recv_sys->found_corrupt_log = TRUE; return(NULL); @@ -234,7 +235,7 @@ mlog_write_ulint( mach_write_to_4(ptr, val); } - log_ptr = mlog_open(mtr, 30); + log_ptr = mlog_open(mtr, 11 + 2 + 5); /* If no logging is requested, we may return now */ if (log_ptr == NULL) { @@ -276,7 +277,7 @@ mlog_write_dulint( mach_write_to_8(ptr, val); - log_ptr = mlog_open(mtr, 30); + log_ptr = mlog_open(mtr, 11 + 2 + 9); /* If no logging is requested, we may return now */ if (log_ptr == NULL) { diff --git a/innobase/page/page0cur.c b/innobase/page/page0cur.c index 890452cfceb..ce9e4327c18 100644 --- a/innobase/page/page0cur.c +++ b/innobase/page/page0cur.c @@ -479,6 +479,7 @@ page_cur_insert_rec_write_log( ulint i; ut_a(rec_size < UNIV_PAGE_SIZE); + ut_ad(rec_size == rec_get_size(insert_rec)); log_ptr = mlog_open(mtr, 30 + MLOG_BUF_MARGIN); @@ -630,8 +631,8 @@ page_cur_parse_insert_rec( return(NULL); } - extra_info_yes = end_seg_len & 0x1; - end_seg_len = end_seg_len / 2; + extra_info_yes = end_seg_len & 0x1UL; + end_seg_len >>= 1; if (end_seg_len >= UNIV_PAGE_SIZE) { recv_sys->found_corrupt_log = TRUE; @@ -694,7 +695,7 @@ page_cur_parse_insert_rec( mismatch_index = rec_get_size(cursor_rec) - end_seg_len; } - if (mismatch_index + end_seg_len < 1024) { + if (mismatch_index + end_seg_len < sizeof buf1) { buf = buf1; } else { buf = mem_alloc(mismatch_index + end_seg_len); @@ -726,7 +727,7 @@ page_cur_parse_insert_rec( page_cur_rec_insert(&cursor, buf + origin_offset, mtr); - if (mismatch_index + end_seg_len >= 1024) { + if (buf != buf1) { mem_free(buf); } diff --git a/innobase/page/page0page.c b/innobase/page/page0page.c index 21adcdea635..7ebcb853448 100644 --- a/innobase/page/page0page.c +++ b/innobase/page/page0page.c @@ -1604,7 +1604,7 @@ page_validate( page_cur_set_before_first(page, &cur); for (;;) { - rec = (&cur)->rec; + rec = cur.rec; if (!page_rec_validate(rec)) { goto func_exit; @@ -1793,16 +1793,13 @@ page_find_rec_with_heap_no( ulint heap_no)/* in: heap number */ { page_cur_t cur; - rec_t* rec; page_cur_set_before_first(page, &cur); for (;;) { - rec = (&cur)->rec; + if (rec_get_heap_no(cur.rec) == heap_no) { - if (rec_get_heap_no(rec) == heap_no) { - - return(rec); + return(cur.rec); } if (page_cur_is_after_last(&cur)) { diff --git a/innobase/pars/pars0opt.c b/innobase/pars/pars0opt.c index 4faf83b47a3..e9ed59e5c00 100644 --- a/innobase/pars/pars0opt.c +++ b/innobase/pars/pars0opt.c @@ -532,8 +532,8 @@ opt_search_plan_for_table( ulint best_goodness; ulint best_last_op = 0; /* remove warning */ ulint mix_id_pos; - que_node_t* index_plan[128]; - que_node_t* best_index_plan[128]; + que_node_t* index_plan[256]; + que_node_t* best_index_plan[256]; plan = sel_node_get_nth_plan(sel_node, i); diff --git a/innobase/pars/pars0pars.c b/innobase/pars/pars0pars.c index 5bbfca831f2..dda97d295fb 100644 --- a/innobase/pars/pars0pars.c +++ b/innobase/pars/pars0pars.c @@ -1745,8 +1745,6 @@ pars_sql( sym_node_t* sym_node; mem_heap_t* heap; que_t* graph; - ulint len; - char* buf; ut_ad(str); @@ -1758,12 +1756,8 @@ pars_sql( #endif /* UNIV_SYNC_DEBUG */ pars_sym_tab_global = sym_tab_create(heap); - len = ut_strlen(str); - buf = mem_heap_alloc(heap, len + 1); - ut_memcpy(buf, str, len + 1); - - pars_sym_tab_global->sql_string = buf; - pars_sym_tab_global->string_len = len; + pars_sym_tab_global->sql_string = mem_heap_strdup(heap, str); + pars_sym_tab_global->string_len = strlen(str); pars_sym_tab_global->next_char_pos = 0; yyparse(); diff --git a/innobase/row/row0ins.c b/innobase/row/row0ins.c index 84968ea4e20..590d2b52e07 100644 --- a/innobase/row/row0ins.c +++ b/innobase/row/row0ins.c @@ -568,8 +568,7 @@ static void row_ins_foreign_report_add_err( /*===========================*/ - que_thr_t* thr, /* in: query thread whose run_node - is an insert node */ + trx_t* trx, /* in: transaction */ dict_foreign_t* foreign, /* in: foreign key constraint */ rec_t* rec, /* in: a record in the parent table: it does not match entry because we @@ -582,7 +581,7 @@ row_ins_foreign_report_add_err( mutex_enter(&dict_foreign_err_mutex); ut_sprintf_timestamp(buf); sprintf(buf + strlen(buf), " Transaction:\n"); - trx_print(buf + strlen(buf), thr_get_trx(thr)); + trx_print(buf + strlen(buf), trx); sprintf(buf + strlen(buf), "Foreign key constraint fails for table %.500s:\n", foreign->foreign_table_name); @@ -661,15 +660,10 @@ row_ins_foreign_check_on_constraint( the MySQL query cache for table */ ut_a(ut_strlen(table->name) < 998); - - ut_memcpy(table_name_buf, table->name, ut_strlen(table->name) + 1); - - ptr = table_name_buf; - - while (*ptr != '/') { - ptr++; - } + strcpy(table_name_buf, table->name); + ptr = strchr(table_name_buf, '/'); + ut_a(ptr); *ptr = '\0'; /* We call a function in ha_innodb.cc */ @@ -1200,11 +1194,6 @@ run_again: break; } -/* printf( -"FOREIGN: Found matching record from %s %s\n", - check_index->table_name, check_index->name); - rec_print(rec); -*/ if (check_ref) { err = DB_SUCCESS; @@ -1244,7 +1233,7 @@ run_again: if (check_ref) { err = DB_NO_REFERENCED_ROW; row_ins_foreign_report_add_err( - thr, foreign, rec, entry); + thr_get_trx(thr), foreign, rec, entry); } else { err = DB_SUCCESS; } @@ -1260,7 +1249,7 @@ next_rec: if (check_ref) { rec = btr_pcur_get_rec(&pcur); row_ins_foreign_report_add_err( - thr, foreign, rec, entry); + thr_get_trx(thr), foreign, rec, entry); err = DB_NO_REFERENCED_ROW; } else { err = DB_SUCCESS; @@ -2167,15 +2156,8 @@ row_ins_step( error_handling: trx->error_state = err; - if (err == DB_SUCCESS) { - /* Ok: do nothing */ - - } else if (err == DB_LOCK_WAIT) { - - return(NULL); - } else { - /* SQL error detected */ - + if (err != DB_SUCCESS) { + /* err == DB_LOCK_WAIT or SQL error detected */ return(NULL); } diff --git a/innobase/row/row0mysql.c b/innobase/row/row0mysql.c index 693928dea3e..006cce74859 100644 --- a/innobase/row/row0mysql.c +++ b/innobase/row/row0mysql.c @@ -44,6 +44,51 @@ struct row_mysql_drop_struct{ UT_LIST_BASE_NODE_T(row_mysql_drop_t) row_mysql_drop_list; ibool row_mysql_drop_list_inited = FALSE; +/* Magic table names for invoking various monitor threads */ +static const char S_innodb_monitor[] = "innodb_monitor"; +static const char S_innodb_lock_monitor[] = "innodb_lock_monitor"; +static const char S_innodb_tablespace_monitor[] = "innodb_tablespace_monitor"; +static const char S_innodb_table_monitor[] = "innodb_table_monitor"; +static const char S_innodb_mem_validate[] = "innodb_mem_validate"; + +/* Name suffix for recovered orphaned temporary tables */ +static const char S_recover_innodb_tmp_table[] = "_recover_innodb_tmp_table"; +/*********************************************************************** +Determine if the given name ends in the suffix reserved for recovered +orphaned temporary tables. */ +static +ibool +row_mysql_is_recovered_tmp_table( +/*=============================*/ + /* out: TRUE if table name ends in + the reserved suffix */ + const char* name) +{ + ulint namelen = strlen(name) + 1; + return(namelen >= sizeof S_recover_innodb_tmp_table + && !memcmp(name + namelen - + sizeof S_recover_innodb_tmp_table, + S_recover_innodb_tmp_table, + sizeof S_recover_innodb_tmp_table)); +} + +/*********************************************************************** +Determine if the given name is a name reserved for MySQL system tables. */ +static +ibool +row_mysql_is_system_table( +/*======================*/ + /* out: TRUE if name is a MySQL + system table name */ + const char* name) +{ + if (memcmp(name, "mysql/", 6)) { + return(FALSE); + } + return(0 == strcmp(name + 6, "host") + || 0 == strcmp(name + 6, "user") + || 0 == strcmp(name + 6, "db")); +} /*********************************************************************** Reads a MySQL format variable-length field (like VARCHAR) length and returns pointer to the field data. */ @@ -900,11 +945,7 @@ row_update_for_mysql( upd_node_t* node; dict_table_t* table = prebuilt->table; trx_t* trx = prebuilt->trx; -/* mem_heap_t* heap; - dtuple_t* search_tuple; - dtuple_t* row_tuple; - mtr_t mtr; */ - + ut_ad(prebuilt && trx); ut_ad(trx->mysql_thread_id == os_thread_get_curr_id()); UT_NOT_USED(mysql_rec); @@ -1147,34 +1188,30 @@ row_mysql_recover_tmp_table( dict_table_t* table, /* in: table definition */ trx_t* trx) /* in: transaction handle */ { - char* ptr; - char old_name[1000]; + const char* ptr = strstr(table->name, "/rsql"); - ut_memcpy(old_name, table->name, ut_strlen(table->name) + 1); - - ptr = old_name; - - for (;;) { - if (ptr >= old_name + ut_strlen(table->name) - 6) { - trx_commit_for_mysql(trx); - - return(DB_ERROR); - } - - if (0 == ut_memcmp(ptr, (char*)"/rsql", 5)) { - ptr++; - *ptr = '#'; - - break; - } - - ptr++; + if (!ptr) { + /* table name does not begin with "/rsql" */ + trx_commit_for_mysql(trx); + return(DB_ERROR); + } + else { + int status; + int namelen = strlen(table->name); + char* old_name = mem_strdupl(table->name, namelen); + /* replace "rsql" with "#sql" */ + old_name[ptr - table->name + 1] = '#'; + /* remove "_recover_innodb_tmp_table" suffix */ + ut_ad(namelen > (int) sizeof S_recover_innodb_tmp_table); + ut_ad(!strcmp(old_name + namelen + 1 - + sizeof S_recover_innodb_tmp_table, + S_recover_innodb_tmp_table)); + old_name[namelen + 1 - sizeof S_recover_innodb_tmp_table] = 0; + status = row_rename_table_for_mysql(old_name, + table->name, trx); + mem_free(old_name); + return(status); } - - old_name[ut_strlen(table->name) - - ut_strlen("_recover_innodb_tmp_table")] = '\0'; - - return(row_rename_table_for_mysql(old_name, table->name, trx)); } /************************************************************************* @@ -1248,10 +1285,10 @@ row_mysql_unlock_data_dictionary( } /************************************************************************* -Does a table creation operation for MySQL. If the name of the created -table ends to characters INNODB_MONITOR, then this also starts -printing of monitor output by the master thread. */ - +Does a table creation operation for MySQL. If the name of the table +to be created is equal with one of the predefined magic table names, +then this also starts printing the corresponding monitor output by +the master thread. */ int row_create_table_for_mysql( /*=======================*/ @@ -1263,7 +1300,6 @@ row_create_table_for_mysql( mem_heap_t* heap; que_thr_t* thr; ulint namelen; - ulint keywordlen; ulint err; ut_ad(trx->mysql_thread_id == os_thread_get_curr_id()); @@ -1288,10 +1324,8 @@ row_create_table_for_mysql( trx->op_info = (char *) "creating table"; - if (0 == ut_strcmp(table->name, (char*)"mysql/host") - || 0 == ut_strcmp(table->name, (char*)"mysql/user") - || 0 == ut_strcmp(table->name, (char*)"mysql/db")) { - + if (row_mysql_is_system_table(table->name)) { + fprintf(stderr, "InnoDB: Error: trying to create a MySQL system table %s of type InnoDB.\n" "InnoDB: MySQL system tables must be of the MyISAM type!\n", @@ -1304,13 +1338,7 @@ row_create_table_for_mysql( trx_start_if_not_started(trx); - namelen = ut_strlen(table->name); - - keywordlen = ut_strlen("_recover_innodb_tmp_table"); - - if (namelen >= keywordlen - && 0 == ut_memcmp(table->name + namelen - keywordlen, - (char*)"_recover_innodb_tmp_table", keywordlen)) { + if (row_mysql_is_recovered_tmp_table(table->name)) { /* MySQL prevents accessing of tables whose name begins with #sql, that is temporary tables. If mysqld crashes in @@ -1322,15 +1350,13 @@ row_create_table_for_mysql( return(row_mysql_recover_tmp_table(table, trx)); } - namelen = ut_strlen(table->name); + namelen = strlen(table->name) + 1; - keywordlen = ut_strlen((char *) "innodb_monitor"); + if (namelen == sizeof S_innodb_monitor + && !memcmp(table->name, S_innodb_monitor, + sizeof S_innodb_monitor)) { - if (namelen >= keywordlen - && 0 == ut_memcmp(table->name + namelen - keywordlen, - (char *) "innodb_monitor", keywordlen)) { - - /* Table name ends to characters innodb_monitor: + /* Table equals "innodb_monitor": start monitor prints */ srv_print_innodb_monitor = TRUE; @@ -1339,47 +1365,28 @@ row_create_table_for_mysql( of InnoDB monitor prints */ os_event_set(srv_lock_timeout_thread_event); - } - - keywordlen = ut_strlen((char *) "innodb_lock_monitor"); - - if (namelen >= keywordlen - && 0 == ut_memcmp(table->name + namelen - keywordlen, - (char *) "innodb_lock_monitor", keywordlen)) { + } else if (namelen == sizeof S_innodb_lock_monitor + && !memcmp(table->name, S_innodb_lock_monitor, + sizeof S_innodb_lock_monitor)) { srv_print_innodb_monitor = TRUE; srv_print_innodb_lock_monitor = TRUE; os_event_set(srv_lock_timeout_thread_event); - } - - keywordlen = ut_strlen((char *) "innodb_tablespace_monitor"); - - if (namelen >= keywordlen - && 0 == ut_memcmp(table->name + namelen - keywordlen, - (char *) "innodb_tablespace_monitor", - keywordlen)) { + } else if (namelen == sizeof S_innodb_tablespace_monitor + && !memcmp(table->name, S_innodb_tablespace_monitor, + sizeof S_innodb_tablespace_monitor)) { srv_print_innodb_tablespace_monitor = TRUE; os_event_set(srv_lock_timeout_thread_event); - } - - keywordlen = ut_strlen((char *) "innodb_table_monitor"); - - if (namelen >= keywordlen - && 0 == ut_memcmp(table->name + namelen - keywordlen, - (char *) "innodb_table_monitor", - keywordlen)) { + } else if (namelen == sizeof S_innodb_table_monitor + && !memcmp(table->name, S_innodb_table_monitor, + sizeof S_innodb_table_monitor)) { srv_print_innodb_table_monitor = TRUE; os_event_set(srv_lock_timeout_thread_event); - } - - keywordlen = ut_strlen("innodb_mem_validate"); - - if (namelen >= keywordlen - && 0 == ut_memcmp(table->name + namelen - keywordlen, - (char*)"innodb_mem_validate", keywordlen)) { - + } else if (namelen == sizeof S_innodb_mem_validate + && !memcmp(table->name, S_innodb_mem_validate, + sizeof S_innodb_mem_validate)) { /* We define here a debugging feature intended for developers */ @@ -1468,8 +1475,6 @@ row_create_index_for_mysql( ind_node_t* node; mem_heap_t* heap; que_thr_t* thr; - ulint namelen; - ulint keywordlen; ulint err; ulint i, j; @@ -1482,7 +1487,7 @@ row_create_index_for_mysql( trx->op_info = (char *) "creating index"; /* Check that the same column does not appear twice in the index. - Starting from 4.0.14 InnoDB should be able to cope with that, but + Starting from 4.0.14, InnoDB should be able to cope with that, but safer not to allow them. */ for (i = 0; i < dict_index_get_n_fields(index); i++) { @@ -1508,14 +1513,7 @@ row_create_index_for_mysql( trx_start_if_not_started(trx); - namelen = ut_strlen(index->table_name); - - keywordlen = ut_strlen("_recover_innodb_tmp_table"); - - if (namelen >= keywordlen - && 0 == ut_memcmp( - index->table_name + namelen - keywordlen, - (char*)"_recover_innodb_tmp_table", keywordlen)) { + if (row_mysql_is_recovered_tmp_table(index->table_name)) { return(DB_SUCCESS); } @@ -1576,8 +1574,6 @@ row_table_add_foreign_constraints( char* name) /* in: table full name in the normalized form database_name/table_name */ { - ulint namelen; - ulint keywordlen; ulint err; #ifdef UNIV_SYNC_DEBUG @@ -1590,14 +1586,7 @@ row_table_add_foreign_constraints( trx_start_if_not_started(trx); - namelen = ut_strlen(name); - - keywordlen = ut_strlen("_recover_innodb_tmp_table"); - - if (namelen >= keywordlen - && 0 == ut_memcmp( - name + namelen - keywordlen, - (char*)"_recover_innodb_tmp_table", keywordlen)) { + if (row_mysql_is_recovered_tmp_table(name)) { return(DB_SUCCESS); } @@ -1781,9 +1770,7 @@ row_add_table_to_background_drop_list( drop = mem_alloc(sizeof(row_mysql_drop_t)); - drop->table_name = mem_alloc(1 + ut_strlen(table->name)); - - ut_memcpy(drop->table_name, table->name, 1 + ut_strlen(table->name)); + drop->table_name = mem_strdup(table->name); mutex_enter(&kernel_mutex); @@ -1817,83 +1804,15 @@ row_drop_table_for_mysql( que_thr_t* thr; que_t* graph; ulint err; - char* str1; - char* str2; - ulint len; ulint namelen; - ulint keywordlen; ibool locked_dictionary = FALSE; - char buf[10000]; - - ut_ad(trx->mysql_thread_id == os_thread_get_curr_id()); - ut_a(name != NULL); - - if (srv_created_new_raw) { - fprintf(stderr, - "InnoDB: A new raw disk partition was initialized or\n" - "InnoDB: innodb_force_recovery is on: we do not allow\n" - "InnoDB: database modifications by the user. Shut down\n" - "InnoDB: mysqld and edit my.cnf so that newraw is replaced\n" - "InnoDB: with raw, and innodb_force_... is removed.\n"); - - return(DB_ERROR); - } - - trx->op_info = (char *) "dropping table"; - - trx_start_if_not_started(trx); - - namelen = ut_strlen(name); - keywordlen = ut_strlen((char *) "innodb_monitor"); - - if (namelen >= keywordlen - && 0 == ut_memcmp(name + namelen - keywordlen, - (char *) "innodb_monitor", keywordlen)) { - - /* Table name ends to characters innodb_monitor: - stop monitor prints */ - - srv_print_innodb_monitor = FALSE; - srv_print_innodb_lock_monitor = FALSE; - } - - keywordlen = ut_strlen((char *) "innodb_lock_monitor"); - - if (namelen >= keywordlen - && 0 == ut_memcmp(name + namelen - keywordlen, - (char *) "innodb_lock_monitor", - keywordlen)) { - - srv_print_innodb_monitor = FALSE; - srv_print_innodb_lock_monitor = FALSE; - } - - keywordlen = ut_strlen((char *) "innodb_tablespace_monitor"); - - if (namelen >= keywordlen - && 0 == ut_memcmp(name + namelen - keywordlen, - (char *) "innodb_tablespace_monitor", - keywordlen)) { - - srv_print_innodb_tablespace_monitor = FALSE; - } - - keywordlen = ut_strlen((char *) "innodb_table_monitor"); - - if (namelen >= keywordlen - && 0 == ut_memcmp(name + namelen - keywordlen, - (char *) "innodb_table_monitor", - keywordlen)) { - - srv_print_innodb_table_monitor = FALSE; - } - + char* quoted_name; + char* sql; /* We use the private SQL parser of Innobase to generate the query graphs needed in deleting the dictionary data from system tables in Innobase. Deleting a row from SYS_INDEXES table also frees the file segments of the B-tree associated with the index. */ - - str1 = (char *) + static const char str1[] = "PROCEDURE DROP_TABLE_PROC () IS\n" "table_name CHAR;\n" "sys_foreign_id CHAR;\n" @@ -1902,10 +1821,9 @@ row_drop_table_for_mysql( "foreign_id CHAR;\n" "found INT;\n" "BEGIN\n" - "table_name := '"; - - str2 = (char *) - "';\n" + "table_name := "; + static const char str2[] = + ";\n" "SELECT ID INTO table_id\n" "FROM SYS_TABLES\n" "WHERE NAME = table_name;\n" @@ -1955,14 +1873,60 @@ row_drop_table_for_mysql( "COMMIT WORK;\n" "END;\n"; - len = ut_strlen(str1); + ut_ad(trx->mysql_thread_id == os_thread_get_curr_id()); + ut_a(name != NULL); - ut_memcpy(buf, str1, len); - ut_memcpy(buf + len, name, ut_strlen(name)); + if (srv_created_new_raw) { + fputs( + "InnoDB: A new raw disk partition was initialized or\n" + "InnoDB: innodb_force_recovery is on: we do not allow\n" + "InnoDB: database modifications by the user. Shut down\n" + "InnoDB: mysqld and edit my.cnf so that newraw is replaced\n" + "InnoDB: with raw, and innodb_force_... is removed.\n", + stderr); - len += ut_strlen(name); + return(DB_ERROR); + } - ut_memcpy(buf + len, str2, ut_strlen(str2) + 1); + trx->op_info = (char *) "dropping table"; + + trx_start_if_not_started(trx); + + namelen = strlen(name) + 1; + + if (namelen == sizeof S_innodb_monitor + && !memcmp(name, S_innodb_monitor, + sizeof S_innodb_monitor)) { + + /* Table name equals "innodb_monitor": + stop monitor prints */ + + srv_print_innodb_monitor = FALSE; + srv_print_innodb_lock_monitor = FALSE; + } else if (namelen == sizeof S_innodb_lock_monitor + && !memcmp(name, S_innodb_lock_monitor, + sizeof S_innodb_lock_monitor)) { + + srv_print_innodb_monitor = FALSE; + srv_print_innodb_lock_monitor = FALSE; + } else if (namelen == sizeof S_innodb_tablespace_monitor + && !memcmp(name, S_innodb_tablespace_monitor, + sizeof S_innodb_tablespace_monitor)) { + + srv_print_innodb_tablespace_monitor = FALSE; + } else if (namelen == sizeof S_innodb_table_monitor + && !memcmp(name, S_innodb_table_monitor, + sizeof S_innodb_table_monitor)) { + + srv_print_innodb_table_monitor = FALSE; + } + + quoted_name = mem_strdupq(name, '\''); + namelen = strlen(quoted_name); + sql = mem_alloc((sizeof str1) + (sizeof str2) - 2 + 1 + namelen); + memcpy(sql, str1, (sizeof str1) - 1); + memcpy(sql + (sizeof str1) - 1, quoted_name, namelen); + memcpy(sql + (sizeof str1) - 1 + namelen, str2, sizeof str2); /* Serialize data dictionary operations with dictionary mutex: no deadlocks can occur then in these operations */ @@ -1981,9 +1945,10 @@ row_drop_table_for_mysql( ut_ad(rw_lock_own(&dict_operation_lock, RW_LOCK_EX)); #endif /* UNIV_SYNC_DEBUG */ - graph = pars_sql(buf); + graph = pars_sql(sql); ut_a(graph); + mem_free(sql); graph->trx = trx; trx->graph = NULL; @@ -2144,9 +2109,10 @@ loop: row_mysql_lock_data_dictionary(trx); while ((table_name = dict_get_first_table_name_in_db(name))) { - ut_a(memcmp(table_name, name, strlen(name)) == 0); + ut_a(strcmp(table_name, name) == 0); table = dict_table_get_low(table_name); +fprintf(stderr, "drop %p:%s\n", table, table_name); ut_a(table); @@ -2197,19 +2163,11 @@ static ibool row_is_mysql_tmp_table_name( /*========================*/ - /* out: TRUE if temporary table */ - char* name) /* in: table name in the form 'database/tablename' */ + /* out: TRUE if temporary table */ + const char* name) /* in: table name in the form + 'database/tablename' */ { - ulint i; - - for (i = 0; i + 5 <= ut_strlen(name); i++) { - if (ut_memcmp(name + i, (char*)"/#sql", 5) == 0) { - - return(TRUE); - } - } - - return(FALSE); + return(strstr(name, "/#sql") != NULL); } /************************************************************************* @@ -2227,79 +2185,11 @@ row_rename_table_for_mysql( que_thr_t* thr; que_t* graph = NULL; ulint err; - char* str1; - char* str2; - char* str3; - mem_heap_t* heap = NULL; - char** constraints_to_drop = NULL; - ulint n_constraints_to_drop = 0; - ibool recovering_temp_table = FALSE; - ulint namelen; - ulint keywordlen; - ulint len; - ulint i; - char* db_name; - char buf[10000]; - - ut_ad(trx->mysql_thread_id == os_thread_get_curr_id()); - ut_a(old_name != NULL); - ut_a(new_name != NULL); - - if (srv_created_new_raw || srv_force_recovery) { - fprintf(stderr, - "InnoDB: A new raw disk partition was initialized or\n" - "InnoDB: innodb_force_recovery is on: we do not allow\n" - "InnoDB: database modifications by the user. Shut down\n" - "InnoDB: mysqld and edit my.cnf so that newraw is replaced\n" - "InnoDB: with raw, and innodb_force_... is removed.\n"); - - trx_commit_for_mysql(trx); - return(DB_ERROR); - } - - if (0 == ut_strcmp(new_name, (char*)"mysql/host") - || 0 == ut_strcmp(new_name, (char*)"mysql/user") - || 0 == ut_strcmp(new_name, (char*)"mysql/db")) { - - fprintf(stderr, - "InnoDB: Error: trying to create a MySQL system table %s of type InnoDB.\n" - "InnoDB: MySQL system tables must be of the MyISAM type!\n", - new_name); - - trx_commit_for_mysql(trx); - return(DB_ERROR); - } - - trx->op_info = (char *) "renaming table"; - trx_start_if_not_started(trx); - - namelen = ut_strlen(new_name); - - keywordlen = ut_strlen("_recover_innodb_tmp_table"); - - if (namelen >= keywordlen - && 0 == ut_memcmp(new_name + namelen - keywordlen, - (char*)"_recover_innodb_tmp_table", keywordlen)) { - - recovering_temp_table = TRUE; - } - - /* Serialize data dictionary operations with dictionary mutex: - no deadlocks can occur then in these operations */ - - if (!recovering_temp_table) { - row_mysql_lock_data_dictionary(trx); - } - - table = dict_table_get_low(old_name); - - if (!table) { - err = DB_TABLE_NOT_FOUND; - - goto funct_exit; - } - - str1 = (char *) + /* We use the private SQL parser of Innobase to generate the + query graphs needed in deleting the dictionary data from system + tables in Innobase. Deleting a row from SYS_INDEXES table also + frees the file segments of the B-tree associated with the index. */ + static const char str1[] = "PROCEDURE RENAME_TABLE_PROC () IS\n" "new_table_name CHAR;\n" "old_table_name CHAR;\n" @@ -2313,12 +2203,133 @@ row_rename_table_for_mysql( "id_len INT;\n" "found INT;\n" "BEGIN\n" - "new_table_name :='"; - - str2 = (char *) + "new_table_name := '"; + static const char str2[] = "';\nold_table_name := '"; + static const char str3[] = + "';\n" + "UPDATE SYS_TABLES SET NAME = new_table_name\n" + "WHERE NAME = old_table_name;\n"; + static const char str4a1[] = /* drop some constraints of tmp tables */ + "DELETE FROM SYS_FOREIGN_COLS WHERE ID = '"; + static const char str4a2[] = "';\n" + "DELETE FROM SYS_FOREIGN WHERE ID = '"; + static const char str4a3[] = "';\n"; + static const char str4b[] = /* rename all constraints */ + "found := 1;\n" + "old_db_name_len := INSTR(old_table_name, '/') - 1;\n" + "new_db_name_len := INSTR(new_table_name, '/') - 1;\n" + "new_db_name := SUBSTR(new_table_name, 0, new_db_name_len);\n" + "old_t_name_len := LENGTH(old_table_name);\n" + "gen_constr_prefix := CONCAT(old_table_name, '_ibfk_');\n" + "WHILE found = 1 LOOP\n" + " SELECT ID INTO foreign_id\n" + " FROM SYS_FOREIGN\n" + " WHERE FOR_NAME = old_table_name;\n" + " IF (SQL % NOTFOUND) THEN\n" + " found := 0;\n" + " ELSE\n" + " UPDATE SYS_FOREIGN\n" + " SET FOR_NAME = new_table_name\n" + " WHERE ID = foreign_id;\n" + " id_len := LENGTH(foreign_id);\n" + " IF (INSTR(foreign_id, '/') > 0) THEN\n" + " IF (INSTR(foreign_id,\n" + " gen_constr_prefix) > 0)\n" + " THEN\n" + " new_foreign_id :=\n" + " CONCAT(new_table_name,\n" + " SUBSTR(foreign_id, old_t_name_len,\n" + " id_len - old_t_name_len));\n" + " ELSE\n" + " new_foreign_id :=\n" + " CONCAT(new_db_name,\n" + " SUBSTR(foreign_id,\n" + " old_db_name_len,\n" + " id_len - old_db_name_len));\n" + " END IF;\n" + " UPDATE SYS_FOREIGN\n" + " SET ID = new_foreign_id\n" + " WHERE ID = foreign_id;\n" + " UPDATE SYS_FOREIGN_COLS\n" + " SET ID = new_foreign_id\n" + " WHERE ID = foreign_id;\n" + " END IF;\n" + " END IF;\n" + "END LOOP;\n" + "UPDATE SYS_FOREIGN SET REF_NAME = new_table_name\n" + "WHERE REF_NAME = old_table_name;\n"; + static const char str5[] = + "END;\n"; + + mem_heap_t* heap = NULL; + const char** constraints_to_drop = NULL; + ulint n_constraints_to_drop = 0; + ibool recovering_temp_table = FALSE; + ulint len; + ulint i; + /* length of database name; 0 if not renaming to a temporary table */ + ulint db_name_len; + char* sql; + char* sqlend; + + ut_ad(trx->mysql_thread_id == os_thread_get_curr_id()); + ut_a(old_name != NULL); + ut_a(new_name != NULL); + + if (srv_created_new_raw || srv_force_recovery) { + fputs( + "InnoDB: A new raw disk partition was initialized or\n" + "InnoDB: innodb_force_recovery is on: we do not allow\n" + "InnoDB: database modifications by the user. Shut down\n" + "InnoDB: mysqld and edit my.cnf so that newraw is replaced\n" + "InnoDB: with raw, and innodb_force_... is removed.\n", + stderr); + + trx_commit_for_mysql(trx); + return(DB_ERROR); + } + + if (row_mysql_is_system_table(new_name)) { + + fprintf(stderr, + "InnoDB: Error: trying to create a MySQL system table %s of type InnoDB.\n" + "InnoDB: MySQL system tables must be of the MyISAM type!\n", + new_name); + + trx_commit_for_mysql(trx); + return(DB_ERROR); + } + + trx->op_info = (char *) "renaming table"; + trx_start_if_not_started(trx); + + if (row_mysql_is_recovered_tmp_table(new_name)) { + + recovering_temp_table = TRUE; + } + + /* Serialize data dictionary operations with dictionary mutex: + no deadlocks can occur then in these operations */ + + if (!recovering_temp_table) { + row_mysql_lock_data_dictionary(trx); + } + + table = dict_table_get_low(old_name); + + if (!table) { + err = DB_TABLE_NOT_FOUND; + + goto funct_exit; + } + + /* calculate the length of the SQL string */ + len = (sizeof str1) + (sizeof str2) + (sizeof str3) + (sizeof str5) - 4 + + ut_strlenq(new_name, '\'') + ut_strlenq(old_name, '\''); if (row_is_mysql_tmp_table_name(new_name)) { + db_name_len = dict_get_db_name_len(old_name) + 1; /* MySQL is doing an ALTER TABLE command and it renames the original table to a temporary table name. We want to preserve @@ -2336,31 +2347,57 @@ row_rename_table_for_mysql( goto funct_exit; } - - str3 = mem_heap_alloc(heap, - 1000 + 1000 * n_constraints_to_drop); - *str3 = '\0'; - sprintf(str3, - "';\n" - "UPDATE SYS_TABLES SET NAME = new_table_name\n" - "WHERE NAME = old_table_name;\n"); - db_name = mem_heap_alloc(heap, 1 + dict_get_db_name_len( - old_name)); - ut_memcpy(db_name, old_name, dict_get_db_name_len(old_name)); - db_name[dict_get_db_name_len(old_name)] = '\0'; + /* reserve space for all database names */ + len += 2 * n_constraints_to_drop + * (ut_strlenq(old_name, '\'') + - ut_strlenq(old_name + db_name_len, '\'')); + for (i = 0; i < n_constraints_to_drop; i++) { + ulint addlen + = 2 * ut_strlenq(constraints_to_drop[i], '\'') + + ((sizeof str4a1) + (sizeof str4a2) + + (sizeof str4a3) - 3); + if (!strchr(constraints_to_drop[i], '/')) { + addlen *= 2; + } + len += addlen; + } + } else { + db_name_len = 0; + len += (sizeof str4b) - 1; + } + + sql = sqlend = mem_alloc(len + 1); + memcpy(sql, str1, (sizeof str1) - 1); + sqlend += (sizeof str1) - 1; + sqlend = ut_strcpyq(sqlend, '\'', new_name); + memcpy(sqlend, str2, (sizeof str2) - 1); + sqlend += (sizeof str2) - 1; + sqlend = ut_strcpyq(sqlend, '\'', old_name); + memcpy(sqlend, str3, (sizeof str3) - 1); + sqlend += (sizeof str3) - 1; + + if (db_name_len) { /* Internally, old format < 4.0.18 constraints have as the constraint id _, while new format constraints have /. */ for (i = 0; i < n_constraints_to_drop; i++) { - - sprintf(str3 + strlen(str3), - "DELETE FROM SYS_FOREIGN_COLS WHERE ID = '%s/%s';\n" - "DELETE FROM SYS_FOREIGN WHERE ID = '%s/%s';\n", - db_name, constraints_to_drop[i], - db_name, constraints_to_drop[i]); + memcpy(sqlend, str4a1, (sizeof str4a1) - 1); + sqlend += (sizeof str4a1) - 1; + sqlend = ut_memcpyq(sqlend, '\'', + old_name, db_name_len); + sqlend = ut_strcpyq(sqlend, '\'', + constraints_to_drop[i]); + memcpy(sqlend, str4a2, (sizeof str4a2) - 1); + sqlend += (sizeof str4a2) - 1; + sqlend = ut_memcpyq(sqlend, '\'', + old_name, db_name_len); + sqlend = ut_strcpyq(sqlend, '\'', + constraints_to_drop[i]); + memcpy(sqlend, str4a3, (sizeof str4a3) - 1); + sqlend += (sizeof str4a3) - 1; if (!strchr(constraints_to_drop[i], '/')) { /* If this happens to be an old format @@ -2368,90 +2405,33 @@ row_rename_table_for_mysql( format constraints contain '/', it does no harm to run these DELETEs anyway. */ - sprintf(str3 + strlen(str3), - "DELETE FROM SYS_FOREIGN_COLS WHERE ID = '%s';\n" - "DELETE FROM SYS_FOREIGN WHERE ID = '%s';\n", - constraints_to_drop[i], - constraints_to_drop[i]); + memcpy(sqlend, str4a1, (sizeof str4a1) - 1); + sqlend += (sizeof str4a1) - 1; + sqlend = ut_strcpyq(sqlend, '\'', + constraints_to_drop[i]); + memcpy(sqlend, str4a2, (sizeof str4a2) - 1); + sqlend += (sizeof str4a2) - 1; + sqlend = ut_strcpyq(sqlend, '\'', + constraints_to_drop[i]); + memcpy(sqlend, str4a3, (sizeof str4a3) - 1); + sqlend += (sizeof str4a3) - 1; } } - - sprintf(str3 + strlen(str3), - "END;\n"); - - ut_a(strlen(str3) < 1000 + 1000 * n_constraints_to_drop); - } else { - str3 = (char*) - "';\n" - "UPDATE SYS_TABLES SET NAME = new_table_name\n" - "WHERE NAME = old_table_name;\n" - "found := 1;\n" - "old_db_name_len := INSTR(old_table_name, '/') - 1;\n" - "new_db_name_len := INSTR(new_table_name, '/') - 1;\n" - "new_db_name := SUBSTR(new_table_name, 0, new_db_name_len);\n" - "old_t_name_len := LENGTH(old_table_name);\n" - "gen_constr_prefix := CONCAT(old_table_name, '_ibfk_');\n" - "WHILE found = 1 LOOP\n" - " SELECT ID INTO foreign_id\n" - " FROM SYS_FOREIGN\n" - " WHERE FOR_NAME = old_table_name;\n" - " IF (SQL % NOTFOUND) THEN\n" - " found := 0;\n" - " ELSE\n" - " UPDATE SYS_FOREIGN\n" - " SET FOR_NAME = new_table_name\n" - " WHERE ID = foreign_id;\n" - " id_len := LENGTH(foreign_id);\n" - " IF (INSTR(foreign_id, '/') > 0) THEN\n" - " IF (INSTR(foreign_id,\n" - " gen_constr_prefix) > 0)\n" - " THEN\n" - " new_foreign_id :=\n" - " CONCAT(new_table_name,\n" - " SUBSTR(foreign_id, old_t_name_len,\n" - " id_len - old_t_name_len));\n" - " ELSE\n" - " new_foreign_id :=\n" - " CONCAT(new_db_name,\n" - " SUBSTR(foreign_id,\n" - " old_db_name_len,\n" - " id_len - old_db_name_len));\n" - " END IF;\n" - " UPDATE SYS_FOREIGN\n" - " SET ID = new_foreign_id\n" - " WHERE ID = foreign_id;\n" - " UPDATE SYS_FOREIGN_COLS\n" - " SET ID = new_foreign_id\n" - " WHERE ID = foreign_id;\n" - " END IF;\n" - " END IF;\n" - "END LOOP;\n" - "UPDATE SYS_FOREIGN SET REF_NAME = new_table_name\n" - "WHERE REF_NAME = old_table_name;\n" - "END;\n"; + } + else { + memcpy(sqlend, str4b, (sizeof str4b) - 1); + sqlend += (sizeof str4b) - 1; } - len = ut_strlen(str1); + memcpy(sqlend, str5, sizeof str5); + sqlend += sizeof str5; - ut_memcpy(buf, str1, len); - - ut_memcpy(buf + len, new_name, ut_strlen(new_name)); - - len += ut_strlen(new_name); - - ut_memcpy(buf + len, str2, ut_strlen(str2)); - - len += ut_strlen(str2); - - ut_memcpy(buf + len, old_name, ut_strlen(old_name)); - - len += ut_strlen(old_name); - - ut_memcpy(buf + len, str3, ut_strlen(str3) + 1); + ut_a(sqlend == sql + len + 1); - graph = pars_sql(buf); + graph = pars_sql(sql); ut_a(graph); + mem_free(sql); graph->trx = trx; trx->graph = NULL; @@ -2609,7 +2589,7 @@ loop: template */ rec = buf + mach_read_from_4(buf); - + if (prev_entry != NULL) { matched_fields = 0; matched_bytes = 0; diff --git a/innobase/row/row0purge.c b/innobase/row/row0purge.c index bd3742ad589..a2c60079e66 100644 --- a/innobase/row/row0purge.c +++ b/innobase/row/row0purge.c @@ -91,7 +91,6 @@ row_purge_remove_clust_if_poss_low( /* out: TRUE if success, or if not found, or if modified after the delete marking */ purge_node_t* node, /* in: row purge node */ - que_thr_t* thr, /* in: query thread */ ulint mode) /* in: BTR_MODIFY_LEAF or BTR_MODIFY_TREE */ { dict_index_t* index; @@ -101,8 +100,6 @@ row_purge_remove_clust_if_poss_low( ulint err; mtr_t mtr; - UT_NOT_USED(thr); - index = dict_table_get_first_index(node->table); pcur = &(node->pcur); @@ -156,23 +153,20 @@ static void row_purge_remove_clust_if_poss( /*===========================*/ - purge_node_t* node, /* in: row purge node */ - que_thr_t* thr) /* in: query thread */ + purge_node_t* node) /* in: row purge node */ { ibool success; ulint n_tries = 0; /* printf("Purge: Removing clustered record\n"); */ - success = row_purge_remove_clust_if_poss_low(node, thr, - BTR_MODIFY_LEAF); + success = row_purge_remove_clust_if_poss_low(node, BTR_MODIFY_LEAF); if (success) { return; } retry: - success = row_purge_remove_clust_if_poss_low(node, thr, - BTR_MODIFY_TREE); + success = row_purge_remove_clust_if_poss_low(node, BTR_MODIFY_TREE); /* The delete operation may fail if we have little file space left: TODO: easiest to crash the database and restart with more file space */ @@ -196,7 +190,6 @@ row_purge_remove_sec_if_poss_low( /*=============================*/ /* out: TRUE if success or if not found */ purge_node_t* node, /* in: row purge node */ - que_thr_t* thr, /* in: query thread */ dict_index_t* index, /* in: index */ dtuple_t* entry, /* in: index entry */ ulint mode) /* in: latch mode BTR_MODIFY_LEAF or @@ -211,8 +204,6 @@ row_purge_remove_sec_if_poss_low( mtr_t mtr; mtr_t* mtr_vers; - UT_NOT_USED(thr); - log_free_check(); mtr_start(&mtr); @@ -284,7 +275,6 @@ void row_purge_remove_sec_if_poss( /*=========================*/ purge_node_t* node, /* in: row purge node */ - que_thr_t* thr, /* in: query thread */ dict_index_t* index, /* in: index */ dtuple_t* entry) /* in: index entry */ { @@ -293,14 +283,14 @@ row_purge_remove_sec_if_poss( /* printf("Purge: Removing secondary record\n"); */ - success = row_purge_remove_sec_if_poss_low(node, thr, index, entry, + success = row_purge_remove_sec_if_poss_low(node, index, entry, BTR_MODIFY_LEAF); if (success) { return; } retry: - success = row_purge_remove_sec_if_poss_low(node, thr, index, entry, + success = row_purge_remove_sec_if_poss_low(node, index, entry, BTR_MODIFY_TREE); /* The delete operation may fail if we have little file space left: TODO: easiest to crash the database @@ -324,14 +314,13 @@ static void row_purge_del_mark( /*===============*/ - purge_node_t* node, /* in: row purge node */ - que_thr_t* thr) /* in: query thread */ + purge_node_t* node) /* in: row purge node */ { mem_heap_t* heap; dtuple_t* entry; dict_index_t* index; - ut_ad(node && thr); + ut_ad(node); heap = mem_heap_create(1024); @@ -341,14 +330,14 @@ row_purge_del_mark( /* Build the index entry */ entry = row_build_index_entry(node->row, index, heap); - row_purge_remove_sec_if_poss(node, thr, index, entry); + row_purge_remove_sec_if_poss(node, index, entry); node->index = dict_table_get_next_index(node->index); } mem_heap_free(heap); - row_purge_remove_clust_if_poss(node, thr); + row_purge_remove_clust_if_poss(node); } /*************************************************************** @@ -358,8 +347,7 @@ static void row_purge_upd_exist_or_extern( /*==========================*/ - purge_node_t* node, /* in: row purge node */ - que_thr_t* thr) /* in: query thread */ + purge_node_t* node) /* in: row purge node */ { mem_heap_t* heap; dtuple_t* entry; @@ -375,7 +363,7 @@ row_purge_upd_exist_or_extern( ulint i; mtr_t mtr; - ut_ad(node && thr); + ut_ad(node); if (node->rec_type == TRX_UNDO_UPD_DEL_REC) { @@ -392,7 +380,7 @@ row_purge_upd_exist_or_extern( /* Build the older version of the index entry */ entry = row_build_index_entry(node->row, index, heap); - row_purge_remove_sec_if_poss(node, thr, index, entry); + row_purge_remove_sec_if_poss(node, index, entry); } node->index = dict_table_get_next_index(node->index); @@ -519,7 +507,7 @@ row_purge_parse_undo_rec( mutex_enter(&(dict_sys->mutex)); - node->table = dict_table_get_on_id_low(table_id, thr_get_trx(thr)); + node->table = dict_table_get_on_id_low(table_id, trx); mutex_exit(&(dict_sys->mutex)); @@ -609,12 +597,12 @@ row_purge( dict_table_get_first_index(node->table)); if (node->rec_type == TRX_UNDO_DEL_MARK_REC) { - row_purge_del_mark(node, thr); + row_purge_del_mark(node); } else if (updated_extern || node->rec_type == TRX_UNDO_UPD_EXIST_REC) { - row_purge_upd_exist_or_extern(node, thr); + row_purge_upd_exist_or_extern(node); } if (node->found_clust) { diff --git a/innobase/row/row0row.c b/innobase/row/row0row.c index 6820cb5bccd..327a47f4009 100644 --- a/innobase/row/row0row.c +++ b/innobase/row/row0row.c @@ -568,7 +568,7 @@ row_get_clust_rec( found = row_search_on_row_ref(&pcur, mode, table, ref, mtr); - clust_rec = btr_pcur_get_rec(&pcur); + clust_rec = found ? btr_pcur_get_rec(&pcur) : NULL; mem_heap_free(heap); @@ -576,11 +576,6 @@ row_get_clust_rec( *clust_index = dict_table_get_first_index(table); - if (!found) { - - return(NULL); - } - return(clust_rec); } diff --git a/innobase/row/row0uins.c b/innobase/row/row0uins.c index fff67dcd627..df2cdb6359d 100644 --- a/innobase/row/row0uins.c +++ b/innobase/row/row0uins.c @@ -37,8 +37,7 @@ ulint row_undo_ins_remove_clust_rec( /*==========================*/ /* out: DB_SUCCESS or DB_OUT_OF_FILE_SPACE */ - undo_node_t* node, /* in: undo node */ - que_thr_t* thr) /* in: query thread */ + undo_node_t* node) /* in: undo node */ { btr_cur_t* btr_cur; ibool success; @@ -46,8 +45,6 @@ row_undo_ins_remove_clust_rec( ulint n_tries = 0; mtr_t mtr; - UT_NOT_USED(thr); - mtr_start(&mtr); success = btr_pcur_restore_position(BTR_MODIFY_LEAF, &(node->pcur), @@ -126,8 +123,7 @@ row_undo_ins_remove_sec_low( depending on whether we wish optimistic or pessimistic descent down the index tree */ dict_index_t* index, /* in: index */ - dtuple_t* entry, /* in: index entry to remove */ - que_thr_t* thr) /* in: query thread */ + dtuple_t* entry) /* in: index entry to remove */ { btr_pcur_t pcur; btr_cur_t* btr_cur; @@ -136,8 +132,6 @@ row_undo_ins_remove_sec_low( ulint err; mtr_t mtr; - UT_NOT_USED(thr); - log_free_check(); mtr_start(&mtr); @@ -148,15 +142,6 @@ row_undo_ins_remove_sec_low( if (!found) { /* Not found */ - /* FIXME: remove printfs in the final version */ - - /* printf( - "--UNDO INS: Record not found from page %lu index %s\n", - buf_frame_get_page_no(btr_cur_get_rec(btr_cur)), - index->name); */ - - /* ibuf_print(); */ - btr_pcur_close(&pcur); mtr_commit(&mtr); @@ -192,15 +177,14 @@ row_undo_ins_remove_sec( /*====================*/ /* out: DB_SUCCESS or DB_OUT_OF_FILE_SPACE */ dict_index_t* index, /* in: index */ - dtuple_t* entry, /* in: index entry to insert */ - que_thr_t* thr) /* in: query thread */ + dtuple_t* entry) /* in: index entry to insert */ { ulint err; ulint n_tries = 0; /* Try first optimistic descent to the B-tree */ - err = row_undo_ins_remove_sec_low(BTR_MODIFY_LEAF, index, entry, thr); + err = row_undo_ins_remove_sec_low(BTR_MODIFY_LEAF, index, entry); if (err == DB_SUCCESS) { @@ -209,7 +193,7 @@ row_undo_ins_remove_sec( /* Try then pessimistic descent to the B-tree */ retry: - err = row_undo_ins_remove_sec_low(BTR_MODIFY_TREE, index, entry, thr); + err = row_undo_ins_remove_sec_low(BTR_MODIFY_TREE, index, entry); /* The delete operation may fail if we have little file space left: TODO: easiest to crash the database @@ -233,8 +217,7 @@ static void row_undo_ins_parse_undo_rec( /*========================*/ - undo_node_t* node, /* in: row undo node */ - que_thr_t* thr __attribute__((unused))) /* in: query thread */ + undo_node_t* node) /* in: row undo node */ { dict_index_t* clust_index; byte* ptr; @@ -244,7 +227,7 @@ row_undo_ins_parse_undo_rec( ulint dummy; ibool dummy_extern; - ut_ad(node && thr); + ut_ad(node); ptr = trx_undo_rec_get_pars(node->undo_rec, &type, &dummy, &dummy_extern, &undo_no, &table_id); @@ -273,22 +256,21 @@ ulint row_undo_ins( /*=========*/ /* out: DB_SUCCESS or DB_OUT_OF_FILE_SPACE */ - undo_node_t* node, /* in: row undo node */ - que_thr_t* thr) /* in: query thread */ + undo_node_t* node) /* in: row undo node */ { dtuple_t* entry; ibool found; ulint err; - - ut_ad(node && thr); + + ut_ad(node); ut_ad(node->state == UNDO_NODE_INSERT); - row_undo_ins_parse_undo_rec(node, thr); + row_undo_ins_parse_undo_rec(node); if (node->table == NULL) { found = FALSE; } else { - found = row_undo_search_clust_to_pcur(node, thr); + found = row_undo_search_clust_to_pcur(node); } if (!found) { @@ -303,7 +285,7 @@ row_undo_ins( while (node->index != NULL) { entry = row_build_index_entry(node->row, node->index, node->heap); - err = row_undo_ins_remove_sec(node->index, entry, thr); + err = row_undo_ins_remove_sec(node->index, entry); if (err != DB_SUCCESS) { @@ -313,7 +295,7 @@ row_undo_ins( node->index = dict_table_get_next_index(node->index); } - err = row_undo_ins_remove_clust_rec(node, thr); + err = row_undo_ins_remove_clust_rec(node); return(err); } diff --git a/innobase/row/row0umod.c b/innobase/row/row0umod.c index 34c3aaf9142..5dde60029f0 100644 --- a/innobase/row/row0umod.c +++ b/innobase/row/row0umod.c @@ -95,14 +95,11 @@ row_undo_mod_clust_low( ulint mode) /* in: BTR_MODIFY_LEAF or BTR_MODIFY_TREE */ { big_rec_t* dummy_big_rec; - dict_index_t* index; btr_pcur_t* pcur; btr_cur_t* btr_cur; ulint err; ibool success; - index = dict_table_get_first_index(node->table); - pcur = &(node->pcur); btr_cur = btr_pcur_get_btr_cur(pcur); @@ -317,13 +314,6 @@ row_undo_mod_del_mark_or_remove_sec_low( if (!found) { /* Not found */ - /* FIXME: remove printfs in the final version */ - - /* printf( - "--UNDO MOD: Record not found from page %lu index %s\n", - buf_frame_get_page_no(btr_cur_get_rec(btr_cur)), - index->name); */ - btr_pcur_close(&pcur); mtr_commit(&mtr); @@ -421,7 +411,6 @@ row_undo_mod_del_unmark_sec_and_undo_update( DB_OUT_OF_FILE_SPACE */ ulint mode, /* in: search mode: BTR_MODIFY_LEAF or BTR_MODIFY_TREE */ - undo_node_t* node, /* in: row undo node */ que_thr_t* thr, /* in: query thread */ dict_index_t* index, /* in: index */ dtuple_t* entry) /* in: index entry */ @@ -430,15 +419,12 @@ row_undo_mod_del_unmark_sec_and_undo_update( btr_pcur_t pcur; btr_cur_t* btr_cur; upd_t* update; - rec_t* rec; ulint err = DB_SUCCESS; ibool found; big_rec_t* dummy_big_rec; mtr_t mtr; char err_buf[1000]; - UT_NOT_USED(node); - log_free_check(); mtr_start(&mtr); @@ -463,15 +449,13 @@ row_undo_mod_del_unmark_sec_and_undo_update( } else { btr_cur = btr_pcur_get_btr_cur(&pcur); - rec = btr_cur_get_rec(btr_cur); - err = btr_cur_del_mark_set_sec_rec(BTR_NO_LOCKING_FLAG, btr_cur, FALSE, thr, &mtr); ut_a(err == DB_SUCCESS); heap = mem_heap_create(100); update = row_upd_build_sec_rec_difference_binary(index, entry, - rec, heap); + btr_cur_get_rec(btr_cur), heap); if (upd_get_n_fields(update) == 0) { /* Do nothing */ @@ -566,11 +550,11 @@ row_undo_mod_del_mark_sec( err = row_undo_mod_del_unmark_sec_and_undo_update( BTR_MODIFY_LEAF, - node, thr, index, entry); + thr, index, entry); if (err == DB_FAIL) { err = row_undo_mod_del_unmark_sec_and_undo_update( BTR_MODIFY_TREE, - node, thr, index, entry); + thr, index, entry); } if (err != DB_SUCCESS) { @@ -649,12 +633,12 @@ row_undo_mod_upd_exist_sec( node->update, NULL); err = row_undo_mod_del_unmark_sec_and_undo_update( BTR_MODIFY_LEAF, - node, thr, index, entry); + thr, index, entry); if (err == DB_FAIL) { err = row_undo_mod_del_unmark_sec_and_undo_update( BTR_MODIFY_TREE, - node, thr, index, entry); + thr, index, entry); } if (err != DB_SUCCESS) { @@ -745,7 +729,7 @@ row_undo_mod( if (node->table == NULL) { found = FALSE; } else { - found = row_undo_search_clust_to_pcur(node, thr); + found = row_undo_search_clust_to_pcur(node); } if (!found) { diff --git a/innobase/row/row0undo.c b/innobase/row/row0undo.c index 78cfe70c260..a3ea42e1425 100644 --- a/innobase/row/row0undo.c +++ b/innobase/row/row0undo.c @@ -144,8 +144,7 @@ row_undo_search_clust_to_pcur( /* out: TRUE if found; NOTE the node->pcur must be closed by the caller, regardless of the return value */ - undo_node_t* node, /* in: row undo node */ - que_thr_t* thr) /* in: query thread */ + undo_node_t* node) /* in: row undo node */ { dict_index_t* clust_index; ibool found; @@ -153,8 +152,6 @@ row_undo_search_clust_to_pcur( ibool ret; rec_t* rec; - UT_NOT_USED(thr); - mtr_start(&mtr); clust_index = dict_table_get_first_index(node->table); @@ -269,7 +266,7 @@ row_undo( if (node->state == UNDO_NODE_INSERT) { - err = row_undo_ins(node, thr); + err = row_undo_ins(node); node->state = UNDO_NODE_FETCH_NEXT; } else { diff --git a/innobase/srv/srv0srv.c b/innobase/srv/srv0srv.c index 0be0ab957af..e4eb3a7f556 100644 --- a/innobase/srv/srv0srv.c +++ b/innobase/srv/srv0srv.c @@ -1576,7 +1576,8 @@ ulint srv_lock_timeout_and_monitor_thread( /*================================*/ /* out: a dummy parameter */ - void* arg) /* in: a dummy parameter required by + void* arg __attribute__((unused))) + /* in: a dummy parameter required by os_thread_create */ { srv_slot_t* slot; @@ -1593,7 +1594,6 @@ srv_lock_timeout_and_monitor_thread( printf("Lock timeout thread starts, id %lu\n", os_thread_pf(os_thread_get_curr_id())); #endif - UT_NOT_USED(arg); srv_last_monitor_time = time(NULL); last_table_monitor_time = time(NULL); last_monitor_time = time(NULL); @@ -1738,7 +1738,7 @@ exit_func: os_thread_exit(NULL); #ifndef __WIN__ - return(NULL); + return(NULL); #else return(0); #endif @@ -1756,12 +1756,12 @@ ulint srv_error_monitor_thread( /*=====================*/ /* out: a dummy parameter */ - void* arg) /* in: a dummy parameter required by + void* arg __attribute__((unused))) + /* in: a dummy parameter required by os_thread_create */ { ulint cnt = 0; - UT_NOT_USED(arg); #ifdef UNIV_DEBUG_THREAD_CREATION printf("Error monitor thread starts, id %lu\n", os_thread_pf(os_thread_get_curr_id())); @@ -1801,7 +1801,7 @@ loop: os_thread_exit(NULL); #ifndef __WIN__ - return(NULL); + return(NULL); #else return(0); #endif @@ -1857,7 +1857,8 @@ ulint srv_master_thread( /*==============*/ /* out: a dummy parameter */ - void* arg) /* in: a dummy parameter required by + void* arg __attribute__((unused))) + /* in: a dummy parameter required by os_thread_create */ { os_event_t event; @@ -1876,8 +1877,6 @@ srv_master_thread( ibool skip_sleep = FALSE; ulint i; - UT_NOT_USED(arg); - #ifdef UNIV_DEBUG_THREAD_CREATION printf("Master thread starts, id %lu\n", os_thread_pf(os_thread_get_curr_id())); diff --git a/innobase/srv/srv0start.c b/innobase/srv/srv0start.c index 0491aed29f5..d505c8779dc 100644 --- a/innobase/srv/srv0start.c +++ b/innobase/srv/srv0start.c @@ -159,17 +159,13 @@ srv_parse_data_file_paths_and_sizes( str++; } - if (strlen(str) >= ut_strlen(":autoextend") - && 0 == ut_memcmp(str, (char*)":autoextend", - ut_strlen(":autoextend"))) { + if (0 == memcmp(str, ":autoextend", (sizeof ":autoextend") - 1)) { - str += ut_strlen(":autoextend"); + str += (sizeof ":autoextend") - 1; - if (strlen(str) >= ut_strlen(":max:") - && 0 == ut_memcmp(str, (char*)":max:", - ut_strlen(":max:"))) { + if (0 == memcmp(str, ":max:", (sizeof ":max:") - 1)) { - str += ut_strlen(":max:"); + str += (sizeof ":max:") - 1; size = strtoul(str, &endp, 10); @@ -198,10 +194,7 @@ srv_parse_data_file_paths_and_sizes( str += 3; } - if (strlen(str) >= 3 - && *str == 'r' - && *(str + 1) == 'a' - && *(str + 2) == 'w') { + if (*str == 'r' && *(str + 1) == 'a' && *(str + 2) == 'w') { str += 3; } @@ -263,19 +256,15 @@ srv_parse_data_file_paths_and_sizes( (*data_file_names)[i] = path; (*data_file_sizes)[i] = size; - if (strlen(str) >= ut_strlen(":autoextend") - && 0 == ut_memcmp(str, (char*)":autoextend", - ut_strlen(":autoextend"))) { + if (0 == memcmp(str, ":autoextend", (sizeof ":autoextend") - 1)) { *is_auto_extending = TRUE; - str += ut_strlen(":autoextend"); + str += (sizeof ":autoextend") - 1; - if (strlen(str) >= ut_strlen(":max:") - && 0 == ut_memcmp(str, (char*)":max:", - ut_strlen(":max:"))) { + if (0 == memcmp(str, ":max:", (sizeof ":max:") - 1)) { - str += ut_strlen(":max:"); + str += (sizeof ":max:") - 1; size = strtoul(str, &endp, 10); @@ -309,10 +298,7 @@ srv_parse_data_file_paths_and_sizes( (*data_file_is_raw_partition)[i] = SRV_NEW_RAW; } - if (strlen(str) >= 3 - && *str == 'r' - && *(str + 1) == 'a' - && *(str + 2) == 'w') { + if (*str == 'r' && *(str + 1) == 'a' && *(str + 2) == 'w') { str += 3; if ((*data_file_is_raw_partition)[i] == 0) { @@ -454,12 +440,10 @@ srv_normalize_path_for_win( char* str __attribute__((unused))) /* in/out: null-terminated character string */ { #ifdef __WIN__ - ulint i; + for (; *str; str++) { - for (i = 0; i < ut_strlen(str); i++) { - - if (str[i] == '/') { - str[i] = '\\'; + if (*str == '/') { + *str = '\\'; } } #endif @@ -528,8 +512,6 @@ ulint open_or_create_log_file( /*====================*/ /* out: DB_SUCCESS or error code */ - ibool create_new_db, /* in: TRUE if we should create a - new database */ ibool* log_file_created, /* out: TRUE if new log file created */ ibool log_file_has_been_opened,/* in: TRUE if a log file has been @@ -544,8 +526,6 @@ open_or_create_log_file( ulint size_high; char name[10000]; - UT_NOT_USED(create_new_db); - *log_file_created = FALSE; srv_normalize_path_for_win(srv_log_group_home_dirs[k]); @@ -1149,8 +1129,7 @@ NetWare. */ for (i = 0; i < srv_n_log_files; i++) { - err = open_or_create_log_file(create_new_db, - &log_file_created, + err = open_or_create_log_file(&log_file_created, log_opened, k, i); if (err != DB_SUCCESS) { diff --git a/innobase/trx/trx0roll.c b/innobase/trx/trx0roll.c index c00c6f0c862..82d101304d5 100644 --- a/innobase/trx/trx0roll.c +++ b/innobase/trx/trx0roll.c @@ -301,8 +301,7 @@ trx_savepoint_for_mysql( savep = mem_alloc(sizeof(trx_named_savept_t)); - savep->name = mem_alloc(1 + ut_strlen(savepoint_name)); - ut_memcpy(savep->name, savepoint_name, 1 + ut_strlen(savepoint_name)); + savep->name = mem_strdup(savepoint_name); savep->savept = trx_savept_take(trx); diff --git a/innobase/trx/trx0sys.c b/innobase/trx/trx0sys.c index d4c14a5509c..493a5e94e79 100644 --- a/innobase/trx/trx0sys.c +++ b/innobase/trx/trx0sys.c @@ -576,8 +576,7 @@ trx_sys_update_mysql_binlog_offset( MLOG_4BYTES, mtr); } - if (0 != ut_memcmp(sys_header + field + TRX_SYS_MYSQL_LOG_NAME, - file_name, 1 + ut_strlen(file_name))) { + if (0 != strcmp(sys_header + field + TRX_SYS_MYSQL_LOG_NAME, file_name)) { mlog_write_string((byte*) (sys_header + field + TRX_SYS_MYSQL_LOG_NAME), diff --git a/innobase/ut/ut0byte.c b/innobase/ut/ut0byte.c index 02bdf2065ee..4ec7e0f405e 100644 --- a/innobase/ut/ut0byte.c +++ b/innobase/ut/ut0byte.c @@ -36,9 +36,9 @@ Copies a string to a memory location, setting characters to lower case. */ void ut_cpy_in_lower_case( /*=================*/ - char* dest, /* in: destination */ - char* source,/* in: source */ - ulint len) /* in: string length */ + char* dest, /* in: destination */ + const char* source, /* in: source */ + ulint len) /* in: string length */ { ulint i; @@ -53,23 +53,27 @@ Compares two strings when converted to lower case. */ int ut_cmp_in_lower_case( /*=================*/ - /* out: -1, 0, 1 if str1 < str2, str1 == str2, - str1 > str2, respectively */ - char* str1, /* in: string1 */ - char* str2, /* in: string2 */ - ulint len) /* in: length of both strings */ + /* out: -1, 0, 1 if str1 < str2, str1 == str2, + str1 > str2, respectively */ + const char* str1, /* in: string1 */ + const char* str2) /* in: string2 */ { - ulint i; + for (;;) { + int c1, c2; + if (!*str1) { + return(*str2 ? -1 : 0); + } else if (!*str2) { + return 1; + } + c1 = tolower(*str1++); + c2 = tolower(*str2++); + if (c1 < c2) { + return(-1); + } + if (c1 > c2) { + return(1); + } + } - for (i = 0; i < len; i++) { - if (tolower(str1[i]) < tolower(str2[i])) { - return(-1); - } - - if (tolower(str1[i]) > tolower(str2[i])) { - return(1); - } - } - - return(0); + return(0); } diff --git a/innobase/ut/ut0mem.c b/innobase/ut/ut0mem.c index f5d207d8bba..1fcaf9febbe 100644 --- a/innobase/ut/ut0mem.c +++ b/innobase/ut/ut0mem.c @@ -106,7 +106,7 @@ ut_malloc_low( /* Make an intentional seg fault so that we get a stack trace */ - printf("%lu\n", *ut_mem_null_ptr); + if (*ut_mem_null_ptr) ut_mem_null_ptr = 0; } if (set_to_zero) { @@ -194,6 +194,49 @@ ut_free_all_mem(void) } } +/************************************************************************** +Make a quoted copy of a string. */ + +char* +ut_strcpyq( +/*=======*/ + /* out: pointer to end of dest */ + char* dest, /* in: output buffer */ + char q, /* in: the quote character */ + const char* src) /* in: null-terminated string */ +{ + while (*src) { + if ((*dest++ = *src++) == q) { + *dest++ = q; + } + } + + return(dest); +} + +/************************************************************************** +Make a quoted copy of a fixed-length string. */ + +char* +ut_memcpyq( +/*=======*/ + /* out: pointer to end of dest */ + char* dest, /* in: output buffer */ + char q, /* in: the quote character */ + const char* src, /* in: string to be quoted */ + ulint len) /* in: length of src */ +{ + const char* srcend = src + len; + + while (src < srcend) { + if ((*dest++ = *src++) == q) { + *dest++ = q; + } + } + + return(dest); +} + /************************************************************************** Catenates two strings into newly allocated memory. The memory must be freed using mem_free. */ @@ -215,9 +258,7 @@ ut_str_catenate( str = mem_alloc(len1 + len2 + 1); ut_memcpy(str, str1, len1); - ut_memcpy(str + len1, str2, len2); - - str[len1 + len2] = '\0'; + ut_memcpy(str + len1, str2, len2 + 1); return(str); } diff --git a/sql/ha_innodb.cc b/sql/ha_innodb.cc index 4d1bbacc3ed..b0de417eb2f 100644 --- a/sql/ha_innodb.cc +++ b/sql/ha_innodb.cc @@ -3298,12 +3298,9 @@ create_index( field = form->field[j]; - if (strlen(field->field_name) - == strlen(key_part->field->field_name) - && 0 == ut_cmp_in_lower_case( + if (0 == ut_cmp_in_lower_case( (char*)field->field_name, - (char*)key_part->field->field_name, - strlen(field->field_name))) { + (char*)key_part->field->field_name)) { /* Found the corresponding column */ break; From cfae16667e56dbf57f0971c86082591300c72f47 Mon Sep 17 00:00:00 2001 From: "marko@hundin.mysql.fi" <> Date: Fri, 2 Apr 2004 11:58:54 +0300 Subject: [PATCH 12/28] InnoDB: Handle quotes properly in the InnoDB SQL parser --- innobase/include/pars0pars.h | 7 - innobase/pars/lexyy.c | 928 ++++++++++++++++++----------------- innobase/pars/pars0lex.l | 77 ++- innobase/pars/pars0pars.c | 11 - innobase/pars/pars0sym.c | 27 +- 5 files changed, 555 insertions(+), 495 deletions(-) diff --git a/innobase/include/pars0pars.h b/innobase/include/pars0pars.h index cad0942eeb1..2e86a7e5534 100644 --- a/innobase/include/pars0pars.h +++ b/innobase/include/pars0pars.h @@ -87,13 +87,6 @@ pars_get_lex_chars( int max_size); /* in: maximum number of characters which fit in the buffer */ /***************************************************************** -Instructs the lexical analyzer to stop when it receives the EOF integer. */ - -int -yywrap(void); -/*========*/ - /* out: returns TRUE */ -/***************************************************************** Called by yyparse on error. */ void diff --git a/innobase/pars/lexyy.c b/innobase/pars/lexyy.c index ab723cb635c..b96e82b414a 100644 --- a/innobase/pars/lexyy.c +++ b/innobase/pars/lexyy.c @@ -8,7 +8,6 @@ #define YY_FLEX_MAJOR_VERSION 2 #define YY_FLEX_MINOR_VERSION 5 -#include "univ.i" #include @@ -262,6 +261,9 @@ static void yy_flex_free YY_PROTO(( void * )); #define YY_AT_BOL() (yy_current_buffer->yy_at_bol) + +#define yywrap() 1 +#define YY_SKIP_YYWRAP typedef unsigned char YY_CHAR; FILE *yyin = (FILE *) 0, *yyout = (FILE *) 0; typedef int yy_state_type; @@ -285,48 +287,48 @@ static void yy_fatal_error YY_PROTO(( yyconst char msg[] )); #define YY_NUM_RULES 107 #define YY_END_OF_BUFFER 108 -static yyconst short int yy_accept[366] = +static yyconst short int yy_accept[367] = { 0, - 0, 0, 100, 100, 108, 106, 105, 105, 95, 106, - 84, 90, 93, 91, 88, 92, 106, 94, 1, 106, - 89, 87, 85, 86, 98, 78, 78, 78, 78, 78, - 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, - 78, 78, 78, 96, 97, 100, 101, 102, 105, 0, - 3, 79, 99, 2, 1, 80, 81, 83, 82, 78, - 78, 78, 78, 78, 36, 78, 78, 78, 78, 78, - 78, 78, 78, 78, 78, 78, 78, 78, 78, 19, - 10, 16, 78, 78, 78, 78, 46, 53, 78, 7, - 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, + 0, 0, 102, 102, 0, 0, 108, 106, 105, 105, + 97, 3, 86, 92, 95, 93, 90, 94, 106, 96, + 1, 106, 91, 89, 87, 88, 100, 80, 80, 80, + 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, + 80, 80, 80, 80, 80, 98, 99, 102, 103, 4, + 5, 105, 81, 101, 2, 1, 82, 83, 85, 84, + 80, 80, 80, 80, 80, 38, 80, 80, 80, 80, + 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, + 21, 12, 18, 80, 80, 80, 80, 48, 55, 80, + 9, 80, 80, 80, 80, 80, 80, 80, 80, 80, - 78, 78, 78, 78, 78, 78, 78, 100, 101, 102, - 103, 102, 104, 2, 6, 37, 78, 78, 78, 78, - 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, - 78, 78, 78, 18, 78, 78, 32, 78, 78, 78, - 12, 78, 78, 8, 78, 78, 78, 11, 78, 78, - 78, 78, 78, 72, 78, 78, 78, 43, 5, 78, - 27, 78, 78, 78, 78, 78, 78, 78, 78, 78, - 78, 78, 78, 78, 15, 78, 78, 78, 78, 78, - 78, 78, 78, 78, 78, 78, 38, 78, 78, 21, - 78, 78, 78, 30, 78, 78, 78, 78, 40, 78, + 80, 80, 80, 80, 80, 80, 80, 80, 102, 103, + 103, 104, 4, 5, 2, 8, 39, 80, 80, 80, + 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, + 80, 80, 80, 80, 20, 80, 80, 34, 80, 80, + 80, 14, 80, 80, 10, 80, 80, 80, 13, 80, + 80, 80, 80, 80, 74, 80, 80, 80, 45, 7, + 80, 29, 80, 80, 80, 80, 80, 80, 80, 80, + 80, 80, 80, 80, 80, 17, 80, 80, 80, 80, + 80, 80, 80, 80, 80, 80, 80, 40, 80, 80, + 23, 80, 80, 80, 32, 80, 80, 80, 80, 42, - 23, 78, 4, 56, 78, 78, 78, 34, 78, 78, - 78, 78, 78, 78, 78, 78, 78, 20, 78, 78, - 78, 78, 78, 78, 78, 78, 77, 78, 17, 78, - 58, 78, 78, 78, 78, 28, 78, 78, 78, 78, - 78, 78, 78, 22, 57, 14, 49, 78, 67, 78, - 78, 78, 35, 78, 78, 78, 78, 78, 78, 78, - 78, 78, 78, 48, 78, 78, 78, 78, 78, 78, - 31, 24, 71, 78, 78, 75, 66, 78, 47, 78, - 55, 78, 44, 78, 78, 39, 78, 68, 78, 70, - 78, 78, 25, 78, 78, 78, 26, 64, 78, 78, + 80, 25, 80, 6, 58, 80, 80, 80, 36, 80, + 80, 80, 80, 80, 80, 80, 80, 80, 22, 80, + 80, 80, 80, 80, 80, 80, 80, 79, 80, 19, + 80, 60, 80, 80, 80, 80, 30, 80, 80, 80, + 80, 80, 80, 80, 24, 59, 16, 51, 80, 69, + 80, 80, 80, 37, 80, 80, 80, 80, 80, 80, + 80, 80, 80, 80, 50, 80, 80, 80, 80, 80, + 80, 33, 26, 73, 80, 80, 77, 68, 80, 49, + 80, 57, 80, 46, 80, 80, 41, 80, 70, 80, + 72, 80, 80, 27, 80, 80, 80, 28, 66, 80, - 78, 78, 50, 42, 41, 78, 78, 78, 45, 54, - 78, 78, 13, 78, 78, 65, 73, 78, 78, 69, - 78, 60, 78, 78, 78, 78, 29, 78, 59, 78, - 76, 78, 78, 78, 78, 51, 78, 78, 9, 78, - 62, 61, 78, 33, 78, 74, 78, 78, 78, 78, - 78, 78, 78, 78, 78, 78, 63, 78, 78, 78, - 78, 78, 78, 52, 0 + 80, 80, 80, 52, 44, 43, 80, 80, 80, 47, + 56, 80, 80, 15, 80, 80, 67, 75, 80, 80, + 71, 80, 62, 80, 80, 80, 80, 31, 80, 61, + 80, 78, 80, 80, 80, 80, 53, 80, 80, 11, + 80, 64, 63, 80, 35, 80, 76, 80, 80, 80, + 80, 80, 80, 80, 80, 80, 80, 65, 80, 80, + 80, 80, 80, 80, 54, 0 } ; static yyconst int yy_ec[256] = @@ -363,205 +365,207 @@ static yyconst int yy_ec[256] = static yyconst int yy_meta[49] = { 0, - 1, 1, 1, 1, 1, 1, 1, 2, 1, 1, - 1, 1, 1, 3, 1, 1, 1, 1, 1, 1, - 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 1, 1 + 1, 1, 1, 1, 2, 1, 1, 3, 1, 1, + 1, 1, 1, 4, 1, 1, 1, 1, 1, 1, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 1, 1 } ; -static yyconst short int yy_base[371] = +static yyconst short int yy_base[373] = { 0, - 0, 0, 46, 47, 393, 394, 49, 54, 394, 387, - 394, 394, 394, 394, 394, 394, 379, 382, 46, 371, - 394, 43, 394, 370, 394, 25, 38, 37, 41, 39, - 49, 0, 51, 54, 45, 62, 349, 57, 68, 73, - 61, 365, 71, 394, 394, 382, 394, 99, 108, 379, - 394, 394, 394, 369, 102, 394, 394, 394, 394, 0, - 358, 81, 354, 346, 0, 358, 80, 84, 353, 339, - 96, 337, 350, 335, 349, 332, 336, 332, 334, 0, - 98, 0, 334, 332, 326, 333, 0, 0, 339, 339, - 322, 94, 103, 337, 98, 94, 328, 109, 320, 336, + 0, 0, 387, 386, 388, 387, 391, 396, 47, 49, + 396, 396, 396, 396, 396, 396, 396, 396, 378, 381, + 41, 370, 396, 38, 396, 369, 396, 20, 33, 32, + 36, 34, 44, 0, 46, 49, 40, 57, 348, 52, + 63, 68, 56, 364, 66, 396, 396, 0, 89, 0, + 379, 103, 396, 396, 369, 95, 396, 396, 396, 396, + 0, 358, 76, 354, 346, 0, 358, 75, 78, 353, + 339, 90, 337, 350, 335, 349, 332, 336, 332, 334, + 0, 93, 0, 334, 332, 326, 333, 0, 0, 339, + 339, 322, 85, 100, 337, 91, 86, 328, 102, 320, - 332, 310, 326, 330, 321, 107, 314, 348, 394, 137, - 394, 141, 394, 336, 0, 0, 324, 319, 326, 308, - 306, 305, 310, 123, 308, 320, 109, 308, 314, 315, - 297, 297, 126, 0, 312, 313, 0, 300, 307, 28, - 128, 304, 294, 303, 296, 293, 301, 0, 291, 301, - 299, 290, 280, 274, 287, 272, 292, 0, 0, 277, - 0, 291, 282, 279, 134, 275, 290, 269, 271, 276, - 276, 268, 271, 266, 0, 278, 262, 272, 279, 270, - 258, 257, 271, 260, 273, 253, 0, 263, 245, 0, - 264, 261, 248, 0, 243, 248, 247, 257, 0, 243, + 336, 332, 310, 326, 330, 321, 102, 314, 0, 117, + 129, 396, 0, 346, 336, 0, 0, 324, 319, 326, + 308, 306, 305, 310, 105, 308, 320, 100, 308, 314, + 315, 297, 297, 116, 0, 312, 313, 0, 300, 307, + 118, 121, 304, 294, 303, 296, 293, 301, 0, 291, + 301, 299, 290, 280, 274, 287, 272, 292, 0, 0, + 277, 0, 291, 282, 279, 125, 275, 290, 269, 271, + 276, 276, 268, 271, 266, 0, 278, 262, 272, 279, + 270, 258, 257, 271, 260, 273, 253, 0, 263, 245, + 0, 264, 261, 248, 0, 243, 248, 247, 257, 0, - 0, 247, 0, 0, 243, 240, 254, 0, 239, 239, - 237, 253, 238, 250, 232, 250, 245, 0, 240, 240, - 226, 225, 225, 239, 238, 237, 0, 221, 0, 215, - 0, 234, 218, 217, 217, 0, 230, 220, 215, 214, - 226, 216, 215, 0, 0, 0, 0, 208, 0, 222, - 218, 204, 0, 218, 219, 202, 207, 200, 218, 200, - 197, 198, 195, 0, 200, 212, 199, 206, 205, 190, - 0, 0, 0, 182, 189, 0, 0, 186, 0, 185, - 0, 199, 0, 200, 187, 0, 183, 0, 186, 0, - 178, 180, 0, 179, 193, 186, 0, 0, 189, 192, + 243, 0, 247, 0, 0, 243, 240, 254, 0, 239, + 239, 237, 253, 238, 250, 232, 250, 245, 0, 240, + 240, 226, 225, 225, 239, 238, 237, 0, 221, 0, + 215, 0, 234, 218, 217, 217, 0, 230, 220, 215, + 214, 226, 216, 215, 0, 0, 0, 0, 208, 0, + 222, 218, 204, 0, 218, 219, 202, 207, 200, 218, + 200, 197, 198, 195, 0, 200, 212, 199, 206, 205, + 190, 0, 0, 0, 182, 189, 0, 0, 186, 0, + 185, 0, 199, 0, 200, 187, 0, 183, 0, 186, + 0, 178, 180, 0, 179, 193, 186, 0, 0, 189, - 174, 189, 0, 0, 0, 170, 184, 183, 0, 0, - 167, 166, 0, 181, 166, 0, 0, 172, 168, 0, - 163, 0, 175, 164, 174, 163, 0, 150, 0, 170, - 0, 154, 148, 154, 145, 0, 150, 163, 0, 162, - 0, 0, 153, 0, 157, 0, 144, 144, 150, 136, - 159, 147, 142, 132, 127, 118, 0, 128, 135, 126, - 123, 114, 88, 0, 394, 168, 171, 124, 174, 177 + 192, 174, 189, 0, 0, 0, 170, 184, 183, 0, + 0, 167, 166, 0, 181, 166, 0, 0, 172, 168, + 0, 163, 0, 175, 164, 174, 163, 0, 150, 0, + 170, 0, 154, 148, 154, 145, 0, 150, 163, 0, + 162, 0, 0, 153, 0, 157, 0, 144, 144, 150, + 136, 159, 151, 152, 136, 119, 109, 0, 121, 128, + 119, 116, 112, 104, 0, 396, 159, 163, 59, 167, + 171, 175 } ; -static yyconst short int yy_def[371] = +static yyconst short int yy_def[373] = { 0, - 365, 1, 366, 366, 365, 365, 365, 365, 365, 367, - 365, 365, 365, 365, 365, 365, 365, 365, 365, 365, - 365, 365, 365, 365, 365, 368, 368, 368, 368, 368, - 368, 368, 368, 368, 368, 368, 368, 368, 368, 368, - 368, 368, 368, 365, 365, 369, 365, 370, 365, 367, - 365, 365, 365, 365, 365, 365, 365, 365, 365, 368, - 368, 368, 368, 368, 368, 368, 368, 368, 368, 368, - 368, 368, 368, 368, 368, 368, 368, 368, 368, 368, - 368, 368, 368, 368, 368, 368, 368, 368, 368, 368, - 368, 368, 368, 368, 368, 368, 368, 368, 368, 368, + 366, 1, 367, 367, 368, 368, 366, 366, 366, 366, + 366, 366, 366, 366, 366, 366, 366, 366, 366, 366, + 366, 366, 366, 366, 366, 366, 366, 369, 369, 369, + 369, 369, 369, 369, 369, 369, 369, 369, 369, 369, + 369, 369, 369, 369, 369, 366, 366, 370, 371, 372, + 366, 366, 366, 366, 366, 366, 366, 366, 366, 366, + 369, 369, 369, 369, 369, 369, 369, 369, 369, 369, + 369, 369, 369, 369, 369, 369, 369, 369, 369, 369, + 369, 369, 369, 369, 369, 369, 369, 369, 369, 369, + 369, 369, 369, 369, 369, 369, 369, 369, 369, 369, - 368, 368, 368, 368, 368, 368, 368, 369, 365, 370, - 365, 370, 365, 365, 368, 368, 368, 368, 368, 368, - 368, 368, 368, 368, 368, 368, 368, 368, 368, 368, - 368, 368, 368, 368, 368, 368, 368, 368, 368, 368, - 368, 368, 368, 368, 368, 368, 368, 368, 368, 368, - 368, 368, 368, 368, 368, 368, 368, 368, 368, 368, - 368, 368, 368, 368, 368, 368, 368, 368, 368, 368, - 368, 368, 368, 368, 368, 368, 368, 368, 368, 368, - 368, 368, 368, 368, 368, 368, 368, 368, 368, 368, - 368, 368, 368, 368, 368, 368, 368, 368, 368, 368, + 369, 369, 369, 369, 369, 369, 369, 369, 370, 371, + 371, 366, 372, 366, 366, 369, 369, 369, 369, 369, + 369, 369, 369, 369, 369, 369, 369, 369, 369, 369, + 369, 369, 369, 369, 369, 369, 369, 369, 369, 369, + 369, 369, 369, 369, 369, 369, 369, 369, 369, 369, + 369, 369, 369, 369, 369, 369, 369, 369, 369, 369, + 369, 369, 369, 369, 369, 369, 369, 369, 369, 369, + 369, 369, 369, 369, 369, 369, 369, 369, 369, 369, + 369, 369, 369, 369, 369, 369, 369, 369, 369, 369, + 369, 369, 369, 369, 369, 369, 369, 369, 369, 369, - 368, 368, 368, 368, 368, 368, 368, 368, 368, 368, - 368, 368, 368, 368, 368, 368, 368, 368, 368, 368, - 368, 368, 368, 368, 368, 368, 368, 368, 368, 368, - 368, 368, 368, 368, 368, 368, 368, 368, 368, 368, - 368, 368, 368, 368, 368, 368, 368, 368, 368, 368, - 368, 368, 368, 368, 368, 368, 368, 368, 368, 368, - 368, 368, 368, 368, 368, 368, 368, 368, 368, 368, - 368, 368, 368, 368, 368, 368, 368, 368, 368, 368, - 368, 368, 368, 368, 368, 368, 368, 368, 368, 368, - 368, 368, 368, 368, 368, 368, 368, 368, 368, 368, + 369, 369, 369, 369, 369, 369, 369, 369, 369, 369, + 369, 369, 369, 369, 369, 369, 369, 369, 369, 369, + 369, 369, 369, 369, 369, 369, 369, 369, 369, 369, + 369, 369, 369, 369, 369, 369, 369, 369, 369, 369, + 369, 369, 369, 369, 369, 369, 369, 369, 369, 369, + 369, 369, 369, 369, 369, 369, 369, 369, 369, 369, + 369, 369, 369, 369, 369, 369, 369, 369, 369, 369, + 369, 369, 369, 369, 369, 369, 369, 369, 369, 369, + 369, 369, 369, 369, 369, 369, 369, 369, 369, 369, + 369, 369, 369, 369, 369, 369, 369, 369, 369, 369, - 368, 368, 368, 368, 368, 368, 368, 368, 368, 368, - 368, 368, 368, 368, 368, 368, 368, 368, 368, 368, - 368, 368, 368, 368, 368, 368, 368, 368, 368, 368, - 368, 368, 368, 368, 368, 368, 368, 368, 368, 368, - 368, 368, 368, 368, 368, 368, 368, 368, 368, 368, - 368, 368, 368, 368, 368, 368, 368, 368, 368, 368, - 368, 368, 368, 368, 0, 365, 365, 365, 365, 365 + 369, 369, 369, 369, 369, 369, 369, 369, 369, 369, + 369, 369, 369, 369, 369, 369, 369, 369, 369, 369, + 369, 369, 369, 369, 369, 369, 369, 369, 369, 369, + 369, 369, 369, 369, 369, 369, 369, 369, 369, 369, + 369, 369, 369, 369, 369, 369, 369, 369, 369, 369, + 369, 369, 369, 369, 369, 369, 369, 369, 369, 369, + 369, 369, 369, 369, 369, 0, 366, 366, 366, 366, + 366, 366 } ; -static yyconst short int yy_nxt[443] = +static yyconst short int yy_nxt[445] = { 0, - 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, - 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, - 26, 27, 28, 29, 30, 31, 32, 32, 33, 32, - 32, 34, 32, 35, 36, 37, 32, 38, 39, 40, - 41, 42, 43, 32, 32, 32, 44, 45, 47, 47, - 49, 49, 196, 48, 48, 49, 49, 54, 61, 55, - 57, 58, 63, 62, 66, 71, 64, 197, 67, 72, - 74, 68, 75, 76, 69, 73, 80, 70, 83, 85, - 77, 93, 65, 78, 81, 86, 79, 87, 84, 82, - 94, 95, 96, 100, 103, 88, 104, 89, 106, 90, + 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, + 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, + 28, 29, 30, 31, 32, 33, 34, 34, 35, 34, + 34, 36, 34, 37, 38, 39, 34, 40, 41, 42, + 43, 44, 45, 34, 34, 34, 46, 47, 52, 52, + 52, 52, 55, 62, 56, 58, 59, 64, 63, 67, + 72, 65, 61, 68, 73, 75, 69, 76, 77, 70, + 74, 81, 71, 84, 86, 78, 94, 66, 79, 82, + 87, 80, 88, 85, 83, 95, 96, 97, 101, 104, + 89, 105, 90, 107, 91, 102, 111, 92, 117, 98, - 101, 111, 91, 116, 97, 107, 112, 102, 98, 49, - 49, 113, 99, 54, 121, 55, 123, 124, 128, 117, - 122, 139, 149, 151, 125, 157, 60, 129, 150, 155, - 160, 169, 364, 158, 130, 170, 140, 141, 152, 111, - 156, 161, 153, 111, 365, 179, 183, 184, 112, 365, - 190, 363, 198, 113, 191, 219, 220, 362, 361, 360, - 359, 180, 199, 358, 357, 356, 355, 221, 46, 46, - 46, 50, 50, 50, 108, 354, 108, 110, 110, 110, - 353, 352, 351, 350, 349, 348, 347, 346, 345, 344, - 343, 342, 341, 340, 339, 338, 337, 336, 335, 334, + 108, 112, 103, 99, 52, 52, 55, 100, 56, 122, + 124, 125, 129, 150, 118, 123, 140, 158, 126, 151, + 152, 130, 156, 161, 366, 159, 170, 180, 131, 366, + 171, 141, 142, 157, 162, 153, 111, 184, 185, 154, + 191, 112, 197, 181, 192, 199, 220, 221, 365, 364, + 363, 362, 361, 360, 359, 200, 358, 198, 222, 48, + 48, 48, 48, 50, 50, 50, 50, 109, 109, 357, + 109, 110, 110, 110, 110, 113, 356, 113, 113, 355, + 354, 353, 352, 351, 350, 349, 348, 347, 346, 345, + 344, 343, 342, 341, 340, 339, 338, 337, 336, 335, - 333, 332, 331, 330, 329, 328, 327, 326, 325, 324, - 323, 322, 321, 320, 319, 318, 317, 316, 315, 314, - 313, 312, 311, 310, 309, 308, 307, 306, 305, 304, - 303, 302, 301, 300, 299, 298, 297, 296, 295, 294, - 293, 292, 291, 290, 289, 288, 287, 286, 285, 284, - 283, 282, 281, 280, 279, 278, 277, 276, 275, 274, - 273, 272, 271, 270, 269, 268, 267, 266, 265, 264, - 263, 262, 261, 260, 259, 258, 257, 256, 255, 254, - 253, 252, 251, 250, 249, 248, 247, 246, 245, 244, - 243, 242, 241, 240, 239, 238, 237, 236, 235, 234, + 334, 333, 332, 331, 330, 329, 328, 327, 326, 325, + 324, 323, 322, 321, 320, 319, 318, 317, 316, 315, + 314, 313, 312, 311, 310, 309, 308, 307, 306, 305, + 304, 303, 302, 301, 300, 299, 298, 297, 296, 295, + 294, 293, 292, 291, 290, 289, 288, 287, 286, 285, + 284, 283, 282, 281, 280, 279, 278, 277, 276, 275, + 274, 273, 272, 271, 270, 269, 268, 267, 266, 265, + 264, 263, 262, 261, 260, 259, 258, 257, 256, 255, + 254, 253, 252, 251, 250, 249, 248, 247, 246, 245, + 244, 243, 242, 241, 240, 239, 238, 237, 236, 235, - 233, 232, 231, 230, 229, 228, 227, 226, 225, 224, - 223, 222, 218, 217, 216, 215, 214, 213, 212, 211, - 210, 209, 208, 207, 206, 205, 204, 203, 202, 201, - 200, 195, 194, 193, 192, 189, 188, 187, 186, 185, - 182, 181, 178, 177, 176, 175, 174, 173, 172, 114, - 109, 171, 168, 167, 166, 165, 164, 163, 162, 159, - 154, 148, 147, 146, 145, 144, 143, 142, 138, 137, - 136, 135, 134, 133, 132, 131, 127, 126, 120, 119, - 118, 115, 114, 51, 109, 105, 92, 59, 56, 53, - 52, 51, 365, 5, 365, 365, 365, 365, 365, 365, + 234, 233, 232, 231, 230, 229, 228, 227, 226, 225, + 224, 223, 219, 218, 217, 216, 215, 214, 213, 212, + 211, 210, 209, 208, 207, 206, 205, 204, 203, 202, + 201, 196, 195, 194, 193, 190, 189, 188, 187, 186, + 183, 182, 179, 178, 177, 176, 175, 174, 173, 115, + 114, 172, 169, 168, 167, 166, 165, 164, 163, 160, + 155, 149, 148, 147, 146, 145, 144, 143, 139, 138, + 137, 136, 135, 134, 133, 132, 128, 127, 121, 120, + 119, 116, 115, 114, 106, 93, 60, 57, 54, 53, + 366, 51, 51, 49, 49, 7, 366, 366, 366, 366, - 365, 365, 365, 365, 365, 365, 365, 365, 365, 365, - 365, 365, 365, 365, 365, 365, 365, 365, 365, 365, - 365, 365, 365, 365, 365, 365, 365, 365, 365, 365, - 365, 365, 365, 365, 365, 365, 365, 365, 365, 365, - 365, 365 + 366, 366, 366, 366, 366, 366, 366, 366, 366, 366, + 366, 366, 366, 366, 366, 366, 366, 366, 366, 366, + 366, 366, 366, 366, 366, 366, 366, 366, 366, 366, + 366, 366, 366, 366, 366, 366, 366, 366, 366, 366, + 366, 366, 366, 366 } ; -static yyconst short int yy_chk[443] = +static yyconst short int yy_chk[445] = { 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 3, 4, - 7, 7, 140, 3, 4, 8, 8, 19, 26, 19, - 22, 22, 27, 26, 28, 29, 27, 140, 28, 29, - 30, 28, 30, 31, 28, 29, 33, 28, 34, 35, - 31, 38, 27, 31, 33, 35, 31, 36, 34, 33, - 38, 38, 39, 40, 41, 36, 41, 36, 43, 36, + 1, 1, 1, 1, 1, 1, 1, 1, 9, 9, + 10, 10, 21, 28, 21, 24, 24, 29, 28, 30, + 31, 29, 369, 30, 31, 32, 30, 32, 33, 30, + 31, 35, 30, 36, 37, 33, 40, 29, 33, 35, + 37, 33, 38, 36, 35, 40, 40, 41, 42, 43, + 38, 43, 38, 45, 38, 42, 49, 38, 63, 41, - 40, 48, 36, 62, 39, 43, 48, 40, 39, 49, - 49, 48, 39, 55, 67, 55, 68, 68, 71, 62, - 67, 81, 92, 93, 68, 96, 368, 71, 92, 95, - 98, 106, 363, 96, 71, 106, 81, 81, 93, 110, - 95, 98, 93, 112, 110, 124, 127, 127, 112, 110, - 133, 362, 141, 112, 133, 165, 165, 361, 360, 359, - 358, 124, 141, 356, 355, 354, 353, 165, 366, 366, - 366, 367, 367, 367, 369, 352, 369, 370, 370, 370, - 351, 350, 349, 348, 347, 345, 343, 340, 338, 337, - 335, 334, 333, 332, 330, 328, 326, 325, 324, 323, + 45, 49, 42, 41, 52, 52, 56, 41, 56, 68, + 69, 69, 72, 93, 63, 68, 82, 97, 69, 93, + 94, 72, 96, 99, 110, 97, 107, 125, 72, 110, + 107, 82, 82, 96, 99, 94, 111, 128, 128, 94, + 134, 111, 141, 125, 134, 142, 166, 166, 364, 363, + 362, 361, 360, 359, 357, 142, 356, 141, 166, 367, + 367, 367, 367, 368, 368, 368, 368, 370, 370, 355, + 370, 371, 371, 371, 371, 372, 354, 372, 372, 353, + 352, 351, 350, 349, 348, 346, 344, 341, 339, 338, + 336, 335, 334, 333, 331, 329, 327, 326, 325, 324, - 321, 319, 318, 315, 314, 312, 311, 308, 307, 306, - 302, 301, 300, 299, 296, 295, 294, 292, 291, 289, - 287, 285, 284, 282, 280, 278, 275, 274, 270, 269, - 268, 267, 266, 265, 263, 262, 261, 260, 259, 258, - 257, 256, 255, 254, 252, 251, 250, 248, 243, 242, - 241, 240, 239, 238, 237, 235, 234, 233, 232, 230, - 228, 226, 225, 224, 223, 222, 221, 220, 219, 217, - 216, 215, 214, 213, 212, 211, 210, 209, 207, 206, - 205, 202, 200, 198, 197, 196, 195, 193, 192, 191, - 189, 188, 186, 185, 184, 183, 182, 181, 180, 179, + 322, 320, 319, 316, 315, 313, 312, 309, 308, 307, + 303, 302, 301, 300, 297, 296, 295, 293, 292, 290, + 288, 286, 285, 283, 281, 279, 276, 275, 271, 270, + 269, 268, 267, 266, 264, 263, 262, 261, 260, 259, + 258, 257, 256, 255, 253, 252, 251, 249, 244, 243, + 242, 241, 240, 239, 238, 236, 235, 234, 233, 231, + 229, 227, 226, 225, 224, 223, 222, 221, 220, 218, + 217, 216, 215, 214, 213, 212, 211, 210, 208, 207, + 206, 203, 201, 199, 198, 197, 196, 194, 193, 192, + 190, 189, 187, 186, 185, 184, 183, 182, 181, 180, - 178, 177, 176, 174, 173, 172, 171, 170, 169, 168, - 167, 166, 164, 163, 162, 160, 157, 156, 155, 154, - 153, 152, 151, 150, 149, 147, 146, 145, 144, 143, - 142, 139, 138, 136, 135, 132, 131, 130, 129, 128, - 126, 125, 123, 122, 121, 120, 119, 118, 117, 114, - 108, 107, 105, 104, 103, 102, 101, 100, 99, 97, - 94, 91, 90, 89, 86, 85, 84, 83, 79, 78, - 77, 76, 75, 74, 73, 72, 70, 69, 66, 64, - 63, 61, 54, 50, 46, 42, 37, 24, 20, 18, - 17, 10, 5, 365, 365, 365, 365, 365, 365, 365, + 179, 178, 177, 175, 174, 173, 172, 171, 170, 169, + 168, 167, 165, 164, 163, 161, 158, 157, 156, 155, + 154, 153, 152, 151, 150, 148, 147, 146, 145, 144, + 143, 140, 139, 137, 136, 133, 132, 131, 130, 129, + 127, 126, 124, 123, 122, 121, 120, 119, 118, 115, + 114, 108, 106, 105, 104, 103, 102, 101, 100, 98, + 95, 92, 91, 90, 87, 86, 85, 84, 80, 79, + 78, 77, 76, 75, 74, 73, 71, 70, 67, 65, + 64, 62, 55, 51, 44, 39, 26, 22, 20, 19, + 7, 6, 5, 4, 3, 366, 366, 366, 366, 366, - 365, 365, 365, 365, 365, 365, 365, 365, 365, 365, - 365, 365, 365, 365, 365, 365, 365, 365, 365, 365, - 365, 365, 365, 365, 365, 365, 365, 365, 365, 365, - 365, 365, 365, 365, 365, 365, 365, 365, 365, 365, - 365, 365 + 366, 366, 366, 366, 366, 366, 366, 366, 366, 366, + 366, 366, 366, 366, 366, 366, 366, 366, 366, 366, + 366, 366, 366, 366, 366, 366, 366, 366, 366, 366, + 366, 366, 366, 366, 366, 366, 366, 366, 366, 366, + 366, 366, 366, 366 } ; static yy_state_type yy_last_accepting_state; @@ -613,7 +617,13 @@ How to make the InnoDB parser and lexer C files: These instructions seem to work at least with bison-1.28 and flex-2.5.4 on Linux. *******************************************************/ -#line 36 "pars0lex.l" +#define YY_NEVER_INTERACTIVE 1 +#define YY_NO_INPUT 1 +#define YY_NO_UNPUT 1 +#define YY_NO_SCAN_BUFFER 1 +#define YY_NO_SCAN_BYTES 1 +#define YY_NO_SCAN_STRING 1 +#line 52 "pars0lex.l" #define YYSTYPE que_node_t* #include "univ.i" @@ -623,16 +633,46 @@ Linux. #include "mem0mem.h" #include "os0proc.h" -#define isatty(A) 0 #define malloc(A) mem_alloc(A) #define free(A) mem_free(A) #define realloc(P, A) mem_realloc(P, A, __FILE__, __LINE__) #define exit(A) ut_error #define YY_INPUT(buf, result, max_size) pars_get_lex_chars(buf, &result, max_size) + +/* String buffer for removing quotes */ +static ulint stringbuf_len_alloc = 0; /* Allocated length */ +static ulint stringbuf_len = 0; /* Current length */ +static char* stringbuf; /* Start of buffer */ +/* Appends a string to the buffer. */ +static +void +string_append( +/*==========*/ + const char* str, /* in: string to be appended */ + ulint len) /* in: length of the string */ +{ + if (stringbuf_len + len > stringbuf_len_alloc) { + if (stringbuf_len_alloc == 0) { + stringbuf_len_alloc++; + } + while (stringbuf_len + len > stringbuf_len_alloc) { + stringbuf_len_alloc <<= 1; + } + stringbuf = stringbuf + ? realloc(stringbuf, stringbuf_len_alloc) + : malloc(stringbuf_len_alloc); + } + + memcpy(stringbuf + stringbuf_len, str, len); + stringbuf_len += len; +} + #define comment 1 -#line 632 "lex.yy.c" +#define quoted 2 + +#line 676 "lex.yy.c" /* Macros after this point can all be overridden by user definitions in * section 1. @@ -783,10 +823,10 @@ YY_DECL register char *yy_cp, *yy_bp; register int yy_act; -#line 57 "pars0lex.l" +#line 102 "pars0lex.l" -#line 786 "lex.yy.c" +#line 830 "lex.yy.c" if ( yy_init ) { @@ -837,13 +877,13 @@ yy_match: while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) { yy_current_state = (int) yy_def[yy_current_state]; - if ( yy_current_state >= 366 ) + if ( yy_current_state >= 367 ) yy_c = yy_meta[(unsigned int) yy_c]; } yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; ++yy_cp; } - while ( yy_base[yy_current_state] != 394 ); + while ( yy_base[yy_current_state] != 396 ); yy_find_action: yy_act = yy_accept[yy_current_state]; @@ -871,7 +911,7 @@ do_action: /* This label is used only to access EOF actions. */ case 1: YY_RULE_SETUP -#line 59 "pars0lex.l" +#line 104 "pars0lex.l" { yylval = sym_tab_add_int_lit(pars_sym_tab_global, atoi(yytext)); @@ -880,7 +920,7 @@ YY_RULE_SETUP YY_BREAK case 2: YY_RULE_SETUP -#line 65 "pars0lex.l" +#line 110 "pars0lex.l" { ut_error; /* not implemented */ @@ -889,542 +929,556 @@ YY_RULE_SETUP YY_BREAK case 3: YY_RULE_SETUP -#line 71 "pars0lex.l" +#line 116 "pars0lex.l" { - /* Remove the single quotes around the string */ - - yylval = sym_tab_add_str_lit(pars_sym_tab_global, - (byte*)yytext, - ut_strlen(yytext)); - return(PARS_STR_LIT); + BEGIN(quoted); + stringbuf_len = 0; } YY_BREAK case 4: YY_RULE_SETUP -#line 80 "pars0lex.l" +#line 120 "pars0lex.l" +string_append(yytext, yyleng); + YY_BREAK +case 5: +YY_RULE_SETUP +#line 121 "pars0lex.l" +{ string_append(yytext, yyleng / 2); + if (yyleng % 2) { + BEGIN(INITIAL); + yylval = sym_tab_add_str_lit( + pars_sym_tab_global, + stringbuf, stringbuf_len); + return(PARS_STR_LIT); + } +} + YY_BREAK +case 6: +YY_RULE_SETUP +#line 131 "pars0lex.l" { yylval = sym_tab_add_null_lit(pars_sym_tab_global); return(PARS_NULL_LIT); } YY_BREAK -case 5: +case 7: YY_RULE_SETUP -#line 86 "pars0lex.l" +#line 137 "pars0lex.l" { /* Implicit cursor name */ yylval = sym_tab_add_str_lit(pars_sym_tab_global, - (byte*)"\'SQL\'", 5); + yytext, yyleng); return(PARS_SQL_TOKEN); } YY_BREAK -case 6: -YY_RULE_SETUP -#line 93 "pars0lex.l" -{ - return(PARS_AND_TOKEN); -} - YY_BREAK -case 7: -YY_RULE_SETUP -#line 97 "pars0lex.l" -{ - return(PARS_OR_TOKEN); -} - YY_BREAK case 8: YY_RULE_SETUP -#line 101 "pars0lex.l" +#line 144 "pars0lex.l" { - return(PARS_NOT_TOKEN); + return(PARS_AND_TOKEN); } YY_BREAK case 9: YY_RULE_SETUP -#line 105 "pars0lex.l" +#line 148 "pars0lex.l" { - return(PARS_PROCEDURE_TOKEN); + return(PARS_OR_TOKEN); } YY_BREAK case 10: YY_RULE_SETUP -#line 109 "pars0lex.l" +#line 152 "pars0lex.l" { - return(PARS_IN_TOKEN); + return(PARS_NOT_TOKEN); } YY_BREAK case 11: YY_RULE_SETUP -#line 113 "pars0lex.l" +#line 156 "pars0lex.l" { - return(PARS_OUT_TOKEN); + return(PARS_PROCEDURE_TOKEN); } YY_BREAK case 12: YY_RULE_SETUP -#line 117 "pars0lex.l" +#line 160 "pars0lex.l" { - return(PARS_INT_TOKEN); + return(PARS_IN_TOKEN); } YY_BREAK case 13: YY_RULE_SETUP -#line 121 "pars0lex.l" +#line 164 "pars0lex.l" { - return(PARS_INT_TOKEN); + return(PARS_OUT_TOKEN); } YY_BREAK case 14: YY_RULE_SETUP -#line 125 "pars0lex.l" +#line 168 "pars0lex.l" { - return(PARS_FLOAT_TOKEN); + return(PARS_INT_TOKEN); } YY_BREAK case 15: YY_RULE_SETUP -#line 129 "pars0lex.l" +#line 172 "pars0lex.l" { - return(PARS_CHAR_TOKEN); + return(PARS_INT_TOKEN); } YY_BREAK case 16: YY_RULE_SETUP -#line 133 "pars0lex.l" +#line 176 "pars0lex.l" { - return(PARS_IS_TOKEN); + return(PARS_FLOAT_TOKEN); } YY_BREAK case 17: YY_RULE_SETUP -#line 137 "pars0lex.l" +#line 180 "pars0lex.l" { - return(PARS_BEGIN_TOKEN); + return(PARS_CHAR_TOKEN); } YY_BREAK case 18: YY_RULE_SETUP -#line 141 "pars0lex.l" +#line 184 "pars0lex.l" { - return(PARS_END_TOKEN); + return(PARS_IS_TOKEN); } YY_BREAK case 19: YY_RULE_SETUP -#line 145 "pars0lex.l" +#line 188 "pars0lex.l" { - return(PARS_IF_TOKEN); + return(PARS_BEGIN_TOKEN); } YY_BREAK case 20: YY_RULE_SETUP -#line 149 "pars0lex.l" +#line 192 "pars0lex.l" { - return(PARS_THEN_TOKEN); + return(PARS_END_TOKEN); } YY_BREAK case 21: YY_RULE_SETUP -#line 153 "pars0lex.l" +#line 196 "pars0lex.l" { - return(PARS_ELSE_TOKEN); + return(PARS_IF_TOKEN); } YY_BREAK case 22: YY_RULE_SETUP -#line 157 "pars0lex.l" +#line 200 "pars0lex.l" { - return(PARS_ELSIF_TOKEN); + return(PARS_THEN_TOKEN); } YY_BREAK case 23: YY_RULE_SETUP -#line 161 "pars0lex.l" +#line 204 "pars0lex.l" { - return(PARS_LOOP_TOKEN); + return(PARS_ELSE_TOKEN); } YY_BREAK case 24: YY_RULE_SETUP -#line 165 "pars0lex.l" +#line 208 "pars0lex.l" { - return(PARS_WHILE_TOKEN); + return(PARS_ELSIF_TOKEN); } YY_BREAK case 25: YY_RULE_SETUP -#line 169 "pars0lex.l" +#line 212 "pars0lex.l" { - return(PARS_RETURN_TOKEN); + return(PARS_LOOP_TOKEN); } YY_BREAK case 26: YY_RULE_SETUP -#line 173 "pars0lex.l" +#line 216 "pars0lex.l" { - return(PARS_SELECT_TOKEN); + return(PARS_WHILE_TOKEN); } YY_BREAK case 27: YY_RULE_SETUP -#line 177 "pars0lex.l" +#line 220 "pars0lex.l" { - return(PARS_SUM_TOKEN); + return(PARS_RETURN_TOKEN); } YY_BREAK case 28: YY_RULE_SETUP -#line 181 "pars0lex.l" +#line 224 "pars0lex.l" { - return(PARS_COUNT_TOKEN); + return(PARS_SELECT_TOKEN); } YY_BREAK case 29: YY_RULE_SETUP -#line 185 "pars0lex.l" +#line 228 "pars0lex.l" { - return(PARS_DISTINCT_TOKEN); + return(PARS_SUM_TOKEN); } YY_BREAK case 30: YY_RULE_SETUP -#line 189 "pars0lex.l" +#line 232 "pars0lex.l" { - return(PARS_FROM_TOKEN); + return(PARS_COUNT_TOKEN); } YY_BREAK case 31: YY_RULE_SETUP -#line 193 "pars0lex.l" +#line 236 "pars0lex.l" { - return(PARS_WHERE_TOKEN); + return(PARS_DISTINCT_TOKEN); } YY_BREAK case 32: YY_RULE_SETUP -#line 197 "pars0lex.l" +#line 240 "pars0lex.l" { - return(PARS_FOR_TOKEN); + return(PARS_FROM_TOKEN); } YY_BREAK case 33: YY_RULE_SETUP -#line 201 "pars0lex.l" +#line 244 "pars0lex.l" { - return(PARS_CONSISTENT_TOKEN); + return(PARS_WHERE_TOKEN); } YY_BREAK case 34: YY_RULE_SETUP -#line 205 "pars0lex.l" +#line 248 "pars0lex.l" { - return(PARS_READ_TOKEN); + return(PARS_FOR_TOKEN); } YY_BREAK case 35: YY_RULE_SETUP -#line 209 "pars0lex.l" +#line 252 "pars0lex.l" { - return(PARS_ORDER_TOKEN); + return(PARS_CONSISTENT_TOKEN); } YY_BREAK case 36: YY_RULE_SETUP -#line 213 "pars0lex.l" +#line 256 "pars0lex.l" { - return(PARS_BY_TOKEN); + return(PARS_READ_TOKEN); } YY_BREAK case 37: YY_RULE_SETUP -#line 217 "pars0lex.l" +#line 260 "pars0lex.l" { - return(PARS_ASC_TOKEN); + return(PARS_ORDER_TOKEN); } YY_BREAK case 38: YY_RULE_SETUP -#line 221 "pars0lex.l" +#line 264 "pars0lex.l" { - return(PARS_DESC_TOKEN); + return(PARS_BY_TOKEN); } YY_BREAK case 39: YY_RULE_SETUP -#line 225 "pars0lex.l" +#line 268 "pars0lex.l" { - return(PARS_INSERT_TOKEN); + return(PARS_ASC_TOKEN); } YY_BREAK case 40: YY_RULE_SETUP -#line 229 "pars0lex.l" +#line 272 "pars0lex.l" { - return(PARS_INTO_TOKEN); + return(PARS_DESC_TOKEN); } YY_BREAK case 41: YY_RULE_SETUP -#line 233 "pars0lex.l" +#line 276 "pars0lex.l" { - return(PARS_VALUES_TOKEN); + return(PARS_INSERT_TOKEN); } YY_BREAK case 42: YY_RULE_SETUP -#line 237 "pars0lex.l" +#line 280 "pars0lex.l" { - return(PARS_UPDATE_TOKEN); + return(PARS_INTO_TOKEN); } YY_BREAK case 43: YY_RULE_SETUP -#line 241 "pars0lex.l" +#line 284 "pars0lex.l" { - return(PARS_SET_TOKEN); + return(PARS_VALUES_TOKEN); } YY_BREAK case 44: YY_RULE_SETUP -#line 245 "pars0lex.l" +#line 288 "pars0lex.l" { - return(PARS_DELETE_TOKEN); + return(PARS_UPDATE_TOKEN); } YY_BREAK case 45: YY_RULE_SETUP -#line 249 "pars0lex.l" +#line 292 "pars0lex.l" { - return(PARS_CURRENT_TOKEN); + return(PARS_SET_TOKEN); } YY_BREAK case 46: YY_RULE_SETUP -#line 253 "pars0lex.l" +#line 296 "pars0lex.l" { - return(PARS_OF_TOKEN); + return(PARS_DELETE_TOKEN); } YY_BREAK case 47: YY_RULE_SETUP -#line 257 "pars0lex.l" +#line 300 "pars0lex.l" { - return(PARS_CREATE_TOKEN); + return(PARS_CURRENT_TOKEN); } YY_BREAK case 48: YY_RULE_SETUP -#line 261 "pars0lex.l" +#line 304 "pars0lex.l" { - return(PARS_TABLE_TOKEN); + return(PARS_OF_TOKEN); } YY_BREAK case 49: YY_RULE_SETUP -#line 265 "pars0lex.l" +#line 308 "pars0lex.l" { - return(PARS_INDEX_TOKEN); + return(PARS_CREATE_TOKEN); } YY_BREAK case 50: YY_RULE_SETUP -#line 269 "pars0lex.l" +#line 312 "pars0lex.l" { - return(PARS_UNIQUE_TOKEN); + return(PARS_TABLE_TOKEN); } YY_BREAK case 51: YY_RULE_SETUP -#line 273 "pars0lex.l" +#line 316 "pars0lex.l" { - return(PARS_CLUSTERED_TOKEN); + return(PARS_INDEX_TOKEN); } YY_BREAK case 52: YY_RULE_SETUP -#line 277 "pars0lex.l" +#line 320 "pars0lex.l" { - return(PARS_DOES_NOT_FIT_IN_MEM_TOKEN); + return(PARS_UNIQUE_TOKEN); } YY_BREAK case 53: YY_RULE_SETUP -#line 281 "pars0lex.l" +#line 324 "pars0lex.l" { - return(PARS_ON_TOKEN); + return(PARS_CLUSTERED_TOKEN); } YY_BREAK case 54: YY_RULE_SETUP -#line 285 "pars0lex.l" +#line 328 "pars0lex.l" { - return(PARS_DECLARE_TOKEN); + return(PARS_DOES_NOT_FIT_IN_MEM_TOKEN); } YY_BREAK case 55: YY_RULE_SETUP -#line 289 "pars0lex.l" +#line 332 "pars0lex.l" { - return(PARS_CURSOR_TOKEN); + return(PARS_ON_TOKEN); } YY_BREAK case 56: YY_RULE_SETUP -#line 293 "pars0lex.l" +#line 336 "pars0lex.l" { - return(PARS_OPEN_TOKEN); + return(PARS_DECLARE_TOKEN); } YY_BREAK case 57: YY_RULE_SETUP -#line 297 "pars0lex.l" +#line 340 "pars0lex.l" { - return(PARS_FETCH_TOKEN); + return(PARS_CURSOR_TOKEN); } YY_BREAK case 58: YY_RULE_SETUP -#line 301 "pars0lex.l" +#line 344 "pars0lex.l" { - return(PARS_CLOSE_TOKEN); + return(PARS_OPEN_TOKEN); } YY_BREAK case 59: YY_RULE_SETUP -#line 305 "pars0lex.l" +#line 348 "pars0lex.l" { - return(PARS_NOTFOUND_TOKEN); + return(PARS_FETCH_TOKEN); } YY_BREAK case 60: YY_RULE_SETUP -#line 309 "pars0lex.l" +#line 352 "pars0lex.l" { - return(PARS_TO_CHAR_TOKEN); + return(PARS_CLOSE_TOKEN); } YY_BREAK case 61: YY_RULE_SETUP -#line 313 "pars0lex.l" +#line 356 "pars0lex.l" { - return(PARS_TO_NUMBER_TOKEN); + return(PARS_NOTFOUND_TOKEN); } YY_BREAK case 62: YY_RULE_SETUP -#line 317 "pars0lex.l" +#line 360 "pars0lex.l" { - return(PARS_TO_BINARY_TOKEN); + return(PARS_TO_CHAR_TOKEN); } YY_BREAK case 63: YY_RULE_SETUP -#line 321 "pars0lex.l" +#line 364 "pars0lex.l" { - return(PARS_BINARY_TO_NUMBER_TOKEN); + return(PARS_TO_NUMBER_TOKEN); } YY_BREAK case 64: YY_RULE_SETUP -#line 325 "pars0lex.l" +#line 368 "pars0lex.l" { - return(PARS_SUBSTR_TOKEN); + return(PARS_TO_BINARY_TOKEN); } YY_BREAK case 65: YY_RULE_SETUP -#line 329 "pars0lex.l" +#line 372 "pars0lex.l" { - return(PARS_REPLSTR_TOKEN); + return(PARS_BINARY_TO_NUMBER_TOKEN); } YY_BREAK case 66: YY_RULE_SETUP -#line 333 "pars0lex.l" +#line 376 "pars0lex.l" { - return(PARS_CONCAT_TOKEN); + return(PARS_SUBSTR_TOKEN); } YY_BREAK case 67: YY_RULE_SETUP -#line 337 "pars0lex.l" +#line 380 "pars0lex.l" { - return(PARS_INSTR_TOKEN); + return(PARS_REPLSTR_TOKEN); } YY_BREAK case 68: YY_RULE_SETUP -#line 341 "pars0lex.l" +#line 384 "pars0lex.l" { - return(PARS_LENGTH_TOKEN); + return(PARS_CONCAT_TOKEN); } YY_BREAK case 69: YY_RULE_SETUP -#line 345 "pars0lex.l" +#line 388 "pars0lex.l" { - return(PARS_SYSDATE_TOKEN); + return(PARS_INSTR_TOKEN); } YY_BREAK case 70: YY_RULE_SETUP -#line 349 "pars0lex.l" +#line 392 "pars0lex.l" { - return(PARS_PRINTF_TOKEN); + return(PARS_LENGTH_TOKEN); } YY_BREAK case 71: YY_RULE_SETUP -#line 353 "pars0lex.l" +#line 396 "pars0lex.l" { - return(PARS_ASSERT_TOKEN); + return(PARS_SYSDATE_TOKEN); } YY_BREAK case 72: YY_RULE_SETUP -#line 357 "pars0lex.l" +#line 400 "pars0lex.l" { - return(PARS_RND_TOKEN); + return(PARS_PRINTF_TOKEN); } YY_BREAK case 73: YY_RULE_SETUP -#line 361 "pars0lex.l" +#line 404 "pars0lex.l" { - return(PARS_RND_STR_TOKEN); + return(PARS_ASSERT_TOKEN); } YY_BREAK case 74: YY_RULE_SETUP -#line 365 "pars0lex.l" +#line 408 "pars0lex.l" { - return(PARS_ROW_PRINTF_TOKEN); + return(PARS_RND_TOKEN); } YY_BREAK case 75: YY_RULE_SETUP -#line 369 "pars0lex.l" +#line 412 "pars0lex.l" { - return(PARS_COMMIT_TOKEN); + return(PARS_RND_STR_TOKEN); } YY_BREAK case 76: YY_RULE_SETUP -#line 373 "pars0lex.l" +#line 416 "pars0lex.l" { - return(PARS_ROLLBACK_TOKEN); + return(PARS_ROW_PRINTF_TOKEN); } YY_BREAK case 77: YY_RULE_SETUP -#line 377 "pars0lex.l" +#line 420 "pars0lex.l" { - return(PARS_WORK_TOKEN); + return(PARS_COMMIT_TOKEN); } YY_BREAK case 78: YY_RULE_SETUP -#line 381 "pars0lex.l" +#line 424 "pars0lex.l" +{ + return(PARS_ROLLBACK_TOKEN); +} + YY_BREAK +case 79: +YY_RULE_SETUP +#line 428 "pars0lex.l" +{ + return(PARS_WORK_TOKEN); +} + YY_BREAK +case 80: +YY_RULE_SETUP +#line 432 "pars0lex.l" { yylval = sym_tab_add_id(pars_sym_tab_global, (byte*)yytext, @@ -1432,60 +1486,44 @@ YY_RULE_SETUP return(PARS_ID_TOKEN); } YY_BREAK -case 79: +case 81: YY_RULE_SETUP -#line 388 "pars0lex.l" +#line 439 "pars0lex.l" { return(PARS_DDOT_TOKEN); } YY_BREAK -case 80: +case 82: YY_RULE_SETUP -#line 392 "pars0lex.l" +#line 443 "pars0lex.l" { return(PARS_ASSIGN_TOKEN); } YY_BREAK -case 81: +case 83: YY_RULE_SETUP -#line 396 "pars0lex.l" +#line 447 "pars0lex.l" { return(PARS_LE_TOKEN); } YY_BREAK -case 82: +case 84: YY_RULE_SETUP -#line 400 "pars0lex.l" +#line 451 "pars0lex.l" { return(PARS_GE_TOKEN); } YY_BREAK -case 83: +case 85: YY_RULE_SETUP -#line 404 "pars0lex.l" +#line 455 "pars0lex.l" { return(PARS_NE_TOKEN); } YY_BREAK -case 84: -YY_RULE_SETUP -#line 408 "pars0lex.l" -{ - - return((int)(*yytext)); -} - YY_BREAK -case 85: -YY_RULE_SETUP -#line 413 "pars0lex.l" -{ - - return((int)(*yytext)); -} - YY_BREAK case 86: YY_RULE_SETUP -#line 418 "pars0lex.l" +#line 459 "pars0lex.l" { return((int)(*yytext)); @@ -1493,7 +1531,7 @@ YY_RULE_SETUP YY_BREAK case 87: YY_RULE_SETUP -#line 423 "pars0lex.l" +#line 464 "pars0lex.l" { return((int)(*yytext)); @@ -1501,7 +1539,7 @@ YY_RULE_SETUP YY_BREAK case 88: YY_RULE_SETUP -#line 428 "pars0lex.l" +#line 469 "pars0lex.l" { return((int)(*yytext)); @@ -1509,7 +1547,7 @@ YY_RULE_SETUP YY_BREAK case 89: YY_RULE_SETUP -#line 433 "pars0lex.l" +#line 474 "pars0lex.l" { return((int)(*yytext)); @@ -1517,7 +1555,7 @@ YY_RULE_SETUP YY_BREAK case 90: YY_RULE_SETUP -#line 438 "pars0lex.l" +#line 479 "pars0lex.l" { return((int)(*yytext)); @@ -1525,7 +1563,7 @@ YY_RULE_SETUP YY_BREAK case 91: YY_RULE_SETUP -#line 443 "pars0lex.l" +#line 484 "pars0lex.l" { return((int)(*yytext)); @@ -1533,7 +1571,7 @@ YY_RULE_SETUP YY_BREAK case 92: YY_RULE_SETUP -#line 448 "pars0lex.l" +#line 489 "pars0lex.l" { return((int)(*yytext)); @@ -1541,7 +1579,7 @@ YY_RULE_SETUP YY_BREAK case 93: YY_RULE_SETUP -#line 453 "pars0lex.l" +#line 494 "pars0lex.l" { return((int)(*yytext)); @@ -1549,7 +1587,7 @@ YY_RULE_SETUP YY_BREAK case 94: YY_RULE_SETUP -#line 458 "pars0lex.l" +#line 499 "pars0lex.l" { return((int)(*yytext)); @@ -1557,7 +1595,7 @@ YY_RULE_SETUP YY_BREAK case 95: YY_RULE_SETUP -#line 463 "pars0lex.l" +#line 504 "pars0lex.l" { return((int)(*yytext)); @@ -1565,7 +1603,7 @@ YY_RULE_SETUP YY_BREAK case 96: YY_RULE_SETUP -#line 468 "pars0lex.l" +#line 509 "pars0lex.l" { return((int)(*yytext)); @@ -1573,7 +1611,7 @@ YY_RULE_SETUP YY_BREAK case 97: YY_RULE_SETUP -#line 473 "pars0lex.l" +#line 514 "pars0lex.l" { return((int)(*yytext)); @@ -1581,7 +1619,7 @@ YY_RULE_SETUP YY_BREAK case 98: YY_RULE_SETUP -#line 478 "pars0lex.l" +#line 519 "pars0lex.l" { return((int)(*yytext)); @@ -1589,44 +1627,51 @@ YY_RULE_SETUP YY_BREAK case 99: YY_RULE_SETUP -#line 483 "pars0lex.l" -BEGIN(comment); /* eat up comment */ +#line 524 "pars0lex.l" +{ + + return((int)(*yytext)); +} YY_BREAK case 100: YY_RULE_SETUP -#line 485 "pars0lex.l" +#line 529 "pars0lex.l" +{ + return((int)(*yytext)); +} YY_BREAK case 101: YY_RULE_SETUP -#line 486 "pars0lex.l" - +#line 534 "pars0lex.l" +BEGIN(comment); /* eat up comment */ YY_BREAK case 102: YY_RULE_SETUP -#line 487 "pars0lex.l" +#line 536 "pars0lex.l" YY_BREAK case 103: YY_RULE_SETUP -#line 488 "pars0lex.l" +#line 537 "pars0lex.l" YY_BREAK case 104: YY_RULE_SETUP -#line 489 "pars0lex.l" +#line 538 "pars0lex.l" BEGIN(INITIAL); YY_BREAK case 105: YY_RULE_SETUP -#line 491 "pars0lex.l" +#line 540 "pars0lex.l" /* eat up whitespace */ YY_BREAK case 106: YY_RULE_SETUP -#line 494 "pars0lex.l" +#line 543 "pars0lex.l" { - printf("Unrecognized character: %s\n", yytext); + fprintf(stderr,"Unrecognized character: %02x\n", + *yytext); ut_error; @@ -1635,12 +1680,13 @@ YY_RULE_SETUP YY_BREAK case 107: YY_RULE_SETUP -#line 502 "pars0lex.l" -ECHO; +#line 552 "pars0lex.l" +YY_FATAL_ERROR( "flex scanner jammed" ); YY_BREAK -#line 1638 "lex.yy.c" +#line 1687 "lex.yy.c" case YY_STATE_EOF(INITIAL): case YY_STATE_EOF(comment): +case YY_STATE_EOF(quoted): yyterminate(); case YY_END_OF_BUFFER: @@ -1931,7 +1977,7 @@ static yy_state_type yy_get_previous_state() while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) { yy_current_state = (int) yy_def[yy_current_state]; - if ( yy_current_state >= 366 ) + if ( yy_current_state >= 367 ) yy_c = yy_meta[(unsigned int) yy_c]; } yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; @@ -1966,11 +2012,11 @@ yy_state_type yy_current_state; while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) { yy_current_state = (int) yy_def[yy_current_state]; - if ( yy_current_state >= 366 ) + if ( yy_current_state >= 367 ) yy_c = yy_meta[(unsigned int) yy_c]; } yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; - yy_is_jam = (yy_current_state == 365); + yy_is_jam = (yy_current_state == 366); return yy_is_jam ? 0 : yy_current_state; } @@ -2205,7 +2251,7 @@ YY_BUFFER_STATE b; #ifndef YY_ALWAYS_INTERACTIVE #ifndef YY_NEVER_INTERACTIVE - +extern int isatty YY_PROTO(( int )); #endif #endif @@ -2525,5 +2571,5 @@ int main() return 0; } #endif -#line 502 "pars0lex.l" +#line 552 "pars0lex.l" diff --git a/innobase/pars/pars0lex.l b/innobase/pars/pars0lex.l index 97875ffcc45..7b65770b3da 100644 --- a/innobase/pars/pars0lex.l +++ b/innobase/pars/pars0lex.l @@ -35,6 +35,19 @@ These instructions seem to work at least with bison-1.28 and flex-2.5.4 on Linux. *******************************************************/ +%option nostdinit +%option 8bit +%option warn +%option pointer +%option never-interactive +%option nodefault +%option noinput +%option nounput +%option noyywrap +%option noyy_scan_buffer +%option noyy_scan_bytes +%option noyy_scan_string + %{ #define YYSTYPE que_node_t* @@ -45,18 +58,47 @@ Linux. #include "mem0mem.h" #include "os0proc.h" -#define isatty(A) 0 #define malloc(A) mem_alloc(A) #define free(A) mem_free(A) #define realloc(P, A) mem_realloc(P, A, __FILE__, __LINE__) -#define exit(A) ut_a(0) +#define exit(A) ut_error #define YY_INPUT(buf, result, max_size) pars_get_lex_chars(buf, &result, max_size) + +/* String buffer for removing quotes */ +static ulint stringbuf_len_alloc = 0; /* Allocated length */ +static ulint stringbuf_len = 0; /* Current length */ +static char* stringbuf; /* Start of buffer */ +/* Appends a string to the buffer. */ +static +void +string_append( +/*==========*/ + const char* str, /* in: string to be appended */ + ulint len) /* in: length of the string */ +{ + if (stringbuf_len + len > stringbuf_len_alloc) { + if (stringbuf_len_alloc == 0) { + stringbuf_len_alloc++; + } + while (stringbuf_len + len > stringbuf_len_alloc) { + stringbuf_len_alloc <<= 1; + } + stringbuf = stringbuf + ? realloc(stringbuf, stringbuf_len_alloc) + : malloc(stringbuf_len_alloc); + } + + memcpy(stringbuf + stringbuf_len, str, len); + stringbuf_len += len; +} + %} DIGIT [0-9] ID [a-z_A-Z][a-z_A-Z0-9]* %x comment +%x quoted %% {DIGIT}+ { @@ -71,13 +113,19 @@ ID [a-z_A-Z][a-z_A-Z0-9]* return(PARS_FLOAT_LIT); } -"\'"[^\']*"\'" { - /* Remove the single quotes around the string */ - - yylval = sym_tab_add_str_lit(pars_sym_tab_global, - (byte*)yytext, - ut_strlen(yytext)); - return(PARS_STR_LIT); +"'" { + BEGIN(quoted); + stringbuf_len = 0; +} +[^\']+ string_append(yytext, yyleng); +"'"+ { string_append(yytext, yyleng / 2); + if (yyleng % 2) { + BEGIN(INITIAL); + yylval = sym_tab_add_str_lit( + pars_sym_tab_global, + stringbuf, stringbuf_len); + return(PARS_STR_LIT); + } } "NULL" { @@ -89,7 +137,7 @@ ID [a-z_A-Z][a-z_A-Z0-9]* "SQL" { /* Implicit cursor name */ yylval = sym_tab_add_str_lit(pars_sym_tab_global, - (byte*)"\'SQL\'", 5); + yytext, yyleng); return(PARS_SQL_TOKEN); } @@ -485,17 +533,16 @@ ID [a-z_A-Z][a-z_A-Z0-9]* "/*" BEGIN(comment); /* eat up comment */ -[^*\n]* -[^*\n]*\n -"*"+[^*/\n]* -"*"+[^*/\n]*\n +[^*]* +"*"+[^*/]* "*"+"/" BEGIN(INITIAL); [ \t\n]+ /* eat up whitespace */ . { - printf("Unrecognized character: %s\n", yytext); + fprintf(stderr,"Unrecognized character: %02x\n", + *yytext); ut_error; diff --git a/innobase/pars/pars0pars.c b/innobase/pars/pars0pars.c index dda97d295fb..a4124672df0 100644 --- a/innobase/pars/pars0pars.c +++ b/innobase/pars/pars0pars.c @@ -1707,17 +1707,6 @@ pars_get_lex_chars( pars_sym_tab_global->next_char_pos += len; } -/***************************************************************** -Instructs the lexical analyzer to stop when it receives the EOF integer. */ - -int -yywrap(void) -/*========*/ - /* out: returns TRUE */ -{ - return(1); -} - /***************************************************************** Called by yyparse on error. */ diff --git a/innobase/pars/pars0sym.c b/innobase/pars/pars0sym.c index 5d8fa306b2d..1a0608ed142 100644 --- a/innobase/pars/pars0sym.c +++ b/innobase/pars/pars0sym.c @@ -127,19 +127,13 @@ sym_tab_add_str_lit( /*================*/ /* out: symbol table node */ sym_tab_t* sym_tab, /* in: symbol table */ - byte* str, /* in: string starting with a single - quote; the string literal will - extend to the next single quote, but - the quotes are not included in it */ + byte* str, /* in: string with no quotes around + it */ ulint len) /* in: string length */ { sym_node_t* node; byte* data; - ulint i; - ut_a(len > 1); - ut_a(str[0] == '\''); - node = mem_heap_alloc(sym_tab->heap, sizeof(sym_node_t)); node->common.type = QUE_NODE_SYMBOL; @@ -151,23 +145,14 @@ sym_tab_add_str_lit( dtype_set(&(node->common.val.type), DATA_VARCHAR, DATA_ENGLISH, 0, 0); - for (i = 1;; i++) { - ut_a(i < len); - - if (str[i] == '\'') { - - break; - } - } - - if (i > 1) { - data = mem_heap_alloc(sym_tab->heap, i - 1); - ut_memcpy(data, str + 1, i - 1); + if (len) { + data = mem_heap_alloc(sym_tab->heap, len); + ut_memcpy(data, str, len); } else { data = NULL; } - dfield_set_data(&(node->common.val), data, i - 1); + dfield_set_data(&(node->common.val), data, len); node->common.val_buf_size = 0; node->prefetch_buf = NULL; From 23a5fc55588a2acea2d529ae4d7c8696c6f8522c Mon Sep 17 00:00:00 2001 From: "marko@hundin.mysql.fi" <> Date: Fri, 2 Apr 2004 16:25:48 +0300 Subject: [PATCH 13/28] InnoDB: ignore intra-database foreign key references between tables when dropping database (Bug #3058) --- innobase/dict/dict0crea.c | 8 ++++---- innobase/dict/dict0dict.c | 2 +- innobase/include/dict0dict.h | 11 +++++++++++ innobase/include/row0mysql.h | 3 ++- innobase/row/row0mysql.c | 22 ++++++++++++---------- innobase/trx/trx0roll.c | 2 +- sql/ha_innodb.cc | 7 +++++-- 7 files changed, 36 insertions(+), 19 deletions(-) diff --git a/innobase/dict/dict0crea.c b/innobase/dict/dict0crea.c index 967818a3784..87cdd4f5302 100644 --- a/innobase/dict/dict0crea.c +++ b/innobase/dict/dict0crea.c @@ -999,13 +999,13 @@ dict_create_or_check_foreign_constraint_tables(void) if (table1) { fprintf(stderr, "InnoDB: dropping incompletely created SYS_FOREIGN table\n"); - row_drop_table_for_mysql((char *) "SYS_FOREIGN", trx); + row_drop_table_for_mysql((char*)"SYS_FOREIGN", trx, TRUE); } if (table2) { fprintf(stderr, "InnoDB: dropping incompletely created SYS_FOREIGN_COLS table\n"); - row_drop_table_for_mysql((char *) "SYS_FOREIGN_COLS", trx); + row_drop_table_for_mysql((char*)"SYS_FOREIGN_COLS", trx, TRUE); } fprintf(stderr, @@ -1054,8 +1054,8 @@ dict_create_or_check_foreign_constraint_tables(void) fprintf(stderr, "InnoDB: dropping incompletely created SYS_FOREIGN tables\n"); - row_drop_table_for_mysql((char *) "SYS_FOREIGN", trx); - row_drop_table_for_mysql((char *) "SYS_FOREIGN_COLS", trx); + row_drop_table_for_mysql((char*)"SYS_FOREIGN", trx, TRUE); + row_drop_table_for_mysql((char*)"SYS_FOREIGN_COLS", trx, TRUE); error = DB_MUST_GET_MORE_FILE_SPACE; } diff --git a/innobase/dict/dict0dict.c b/innobase/dict/dict0dict.c index 0efb9935800..c0810ad45dc 100644 --- a/innobase/dict/dict0dict.c +++ b/innobase/dict/dict0dict.c @@ -177,7 +177,7 @@ mutex_t dict_foreign_err_mutex; /* mutex protecting the foreign /************************************************************************ Checks if the database name in two table names is the same. */ -static + ibool dict_tables_have_same_db( /*=====================*/ diff --git a/innobase/include/dict0dict.h b/innobase/include/dict0dict.h index f0523c5f204..7d7739021e2 100644 --- a/innobase/include/dict0dict.h +++ b/innobase/include/dict0dict.h @@ -834,6 +834,17 @@ Releases the dictionary system mutex for MySQL. */ void dict_mutex_exit_for_mysql(void); /*===========================*/ +/************************************************************************ +Checks if the database name in two table names is the same. */ + +ibool +dict_tables_have_same_db( +/*=====================*/ + /* out: TRUE if same db name */ + const char* name1, /* in: table name in the form + dbname '/' tablename */ + const char* name2); /* in: table name in the form + dbname '/' tablename */ /* The following len must be at least 10000 bytes! */ #define DICT_FOREIGN_ERR_BUF_LEN 10000 diff --git a/innobase/include/row0mysql.h b/innobase/include/row0mysql.h index 940b4c61b2f..f28e1b6f048 100644 --- a/innobase/include/row0mysql.h +++ b/innobase/include/row0mysql.h @@ -329,7 +329,8 @@ row_drop_table_for_mysql( /*=====================*/ /* out: error code or DB_SUCCESS */ char* name, /* in: table name */ - trx_t* trx); /* in: transaction handle */ + trx_t* trx, /* in: transaction handle */ + ibool drop_db);/* in: TRUE=dropping whole database */ /************************************************************************* Drops a database for MySQL. */ diff --git a/innobase/row/row0mysql.c b/innobase/row/row0mysql.c index 006cce74859..eca586b3a0a 100644 --- a/innobase/row/row0mysql.c +++ b/innobase/row/row0mysql.c @@ -1427,7 +1427,7 @@ row_create_table_for_mysql( fprintf(stderr, "InnoDB: Warning: cannot create table %s because tablespace full\n", table->name); - row_drop_table_for_mysql(table->name, trx); + row_drop_table_for_mysql(table->name, trx, FALSE); } else { ut_a(err == DB_DUPLICATE_KEY); @@ -1542,7 +1542,7 @@ error_handling: trx_general_rollback_for_mysql(trx, FALSE, NULL); - row_drop_table_for_mysql(index->table_name, trx); + row_drop_table_for_mysql(index->table_name, trx, FALSE); trx->error_state = DB_SUCCESS; } @@ -1607,7 +1607,7 @@ row_table_add_foreign_constraints( trx_general_rollback_for_mysql(trx, FALSE, NULL); - row_drop_table_for_mysql(name, trx); + row_drop_table_for_mysql(name, trx, FALSE); trx->error_state = DB_SUCCESS; } @@ -1638,7 +1638,7 @@ row_drop_table_for_mysql_in_background( name); */ /* Drop the table in InnoDB */ - error = row_drop_table_for_mysql(name, trx); + error = row_drop_table_for_mysql(name, trx, FALSE); if (error != DB_SUCCESS) { fprintf(stderr, @@ -1795,9 +1795,10 @@ output by the master thread. */ int row_drop_table_for_mysql( /*=====================*/ - /* out: error code or DB_SUCCESS */ - char* name, /* in: table name */ - trx_t* trx) /* in: transaction handle */ + /* out: error code or DB_SUCCESS */ + char* name, /* in: table name */ + trx_t* trx, /* in: transaction handle */ + ibool drop_db)/* in: TRUE=dropping whole database */ { dict_foreign_t* foreign; dict_table_t* table; @@ -1981,7 +1982,9 @@ row_drop_table_for_mysql( foreign = UT_LIST_GET_NEXT(referenced_list, foreign); } - if (foreign && trx->check_foreigns) { + if (foreign && trx->check_foreigns && + !(drop_db && dict_tables_have_same_db( + name, foreign->foreign_table_name))) { char* buf = dict_foreign_err_buf; /* We only allow dropping a referenced table if @@ -2112,7 +2115,6 @@ loop: ut_a(strcmp(table_name, name) == 0); table = dict_table_get_low(table_name); -fprintf(stderr, "drop %p:%s\n", table, table_name); ut_a(table); @@ -2135,7 +2137,7 @@ fprintf(stderr, "drop %p:%s\n", table, table_name); goto loop; } - err = row_drop_table_for_mysql(table_name, trx); + err = row_drop_table_for_mysql(table_name, trx, TRUE); mem_free(table_name); diff --git a/innobase/trx/trx0roll.c b/innobase/trx/trx0roll.c index 82d101304d5..2adebbc6b4b 100644 --- a/innobase/trx/trx0roll.c +++ b/innobase/trx/trx0roll.c @@ -469,7 +469,7 @@ loop: fprintf(stderr, "InnoDB: Table found: dropping table %s in recovery\n", table->name); - err = row_drop_table_for_mysql(table->name, trx); + err = row_drop_table_for_mysql(table->name, trx, TRUE); ut_a(err == (int) DB_SUCCESS); } diff --git a/sql/ha_innodb.cc b/sql/ha_innodb.cc index b0de417eb2f..5a929237e3b 100644 --- a/sql/ha_innodb.cc +++ b/sql/ha_innodb.cc @@ -3631,7 +3631,8 @@ ha_innobase::delete_table( /* Drop the table in InnoDB */ - error = row_drop_table_for_mysql(norm_name, trx); + error = row_drop_table_for_mysql(norm_name, trx, + thd->lex.sql_command == SQLCOM_DROP_DB); /* Flush the log to reduce probability that the .frm files and the InnoDB data dictionary get out-of-sync if the user runs @@ -3670,7 +3671,7 @@ innobase_drop_database( trx_t* trx; char* ptr; int error; - char namebuf[10000]; + char* namebuf; /* Get the transaction associated with the current thd, or create one if not yet created */ @@ -3690,6 +3691,7 @@ innobase_drop_database( } ptr++; + namebuf = my_malloc(len + 2, MYF(0)); memcpy(namebuf, ptr, len); namebuf[len] = '/'; @@ -3706,6 +3708,7 @@ innobase_drop_database( } error = row_drop_database_for_mysql(namebuf, trx); + my_free(namebuf, MYF(0)); /* Flush the log to reduce probability that the .frm files and the InnoDB data dictionary get out-of-sync if the user runs From a6c6bfe7e9c8f17ba83346831d3d0c8702daeffd Mon Sep 17 00:00:00 2001 From: "serg@serg.mylan" <> Date: Mon, 5 Apr 2004 11:36:30 +0200 Subject: [PATCH 14/28] made fulltext search aware of concurrent inserts --- myisam/ft_boolean_search.c | 19 +++++++++++++++---- myisam/ft_nlq_search.c | 14 ++++++++++++-- 2 files changed, 27 insertions(+), 6 deletions(-) diff --git a/myisam/ft_boolean_search.c b/myisam/ft_boolean_search.c index 799022a5a0d..d728c379ea5 100644 --- a/myisam/ft_boolean_search.c +++ b/myisam/ft_boolean_search.c @@ -262,8 +262,14 @@ static void _ftb_init_index_search(FT_INFO *ftb) else reset_tree(& ftb->no_dupes); } - r=_mi_search(info, keyinfo, (uchar*) ftbw->word, ftbw->len, - SEARCH_FIND | SEARCH_BIGGER, keyroot); + for ( + r=_mi_search(info, keyinfo, (uchar*) ftbw->word, ftbw->len, + SEARCH_FIND | SEARCH_BIGGER, keyroot) ; + !r && info->lastpos >= info->state->data_file_length; + r=_mi_search_next(info, keyinfo, info->lastkey, info->lastkey_length, + SEARCH_BIGGER, keyroot) + ); + if (!r) { r=_mi_compare_text(ftb->charset, @@ -488,8 +494,13 @@ int ft_boolean_read_next(FT_INFO *ftb, char *record) _ftb_climb_the_tree(ftb, ftbw, 0); /* update queue */ - r=_mi_search(info, keyinfo, (uchar*) ftbw->word, USE_WHOLE_KEY, - SEARCH_BIGGER , keyroot); + for ( + r=_mi_search(info, keyinfo, (uchar*) ftbw->word, USE_WHOLE_KEY, + SEARCH_BIGGER, keyroot) ; + !r && info->lastpos >= info->state->data_file_length ; + r=_mi_search_next(info, keyinfo, info->lastkey, info->lastkey_length, + SEARCH_BIGGER, keyroot) + ); if (!r) { r=_mi_compare_text(ftb->charset, diff --git a/myisam/ft_nlq_search.c b/myisam/ft_nlq_search.c index f426b88d77d..3ad983f0a37 100644 --- a/myisam/ft_nlq_search.c +++ b/myisam/ft_nlq_search.c @@ -85,8 +85,13 @@ static int walk_and_match(FT_WORD *word, uint32 count, ALL_IN_ONE *aio) doc_cnt=0; - r=_mi_search(aio->info, aio->keyinfo, aio->keybuff, keylen, - SEARCH_FIND | SEARCH_PREFIX, aio->key_root); + for ( + r=_mi_search(aio->info, aio->keyinfo, aio->keybuff, keylen, + SEARCH_FIND | SEARCH_PREFIX, aio->key_root) ; + !r && aio->info->lastpos >= aio->info->state->data_file_length ; + r=_mi_search_next(aio->info, aio->keyinfo, aio->info->lastkey, + aio->info->lastkey_length, SEARCH_BIGGER, aio->key_root) + ); aio->info->update|= HA_STATE_AKTIV; /* for _mi_test_if_changed() */ while (!r && gweight) @@ -132,6 +137,11 @@ static int walk_and_match(FT_WORD *word, uint32 count, ALL_IN_ONE *aio) r=_mi_search(aio->info, aio->keyinfo, aio->info->lastkey, aio->info->lastkey_length, SEARCH_BIGGER, aio->key_root); + + while (!r && aio->info->lastpos >= aio->info->state->data_file_length) + r=_mi_search(aio->info, aio->keyinfo, aio->info->lastkey, + aio->info->lastkey_length, SEARCH_BIGGER, + aio->key_root); } word->weight=gweight; From 0e39b9220be1979275875a12bddeb5b602999168 Mon Sep 17 00:00:00 2001 From: "lenz@mysql.com" <> Date: Mon, 5 Apr 2004 14:38:17 +0200 Subject: [PATCH 15/28] - added ncurses-devel to the build prerequisites (BUG#3377) --- support-files/mysql.spec.sh | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/support-files/mysql.spec.sh b/support-files/mysql.spec.sh index cea9c112b8b..714992e0826 100644 --- a/support-files/mysql.spec.sh +++ b/support-files/mysql.spec.sh @@ -23,6 +23,7 @@ Packager: Lenz Grimmer Vendor: MySQL AB Requires: fileutils sh-utils Provides: msqlormysql MySQL-server mysql +BuildPrereq: ncurses-devel Obsoletes: mysql # Think about what you use here since the first step is to @@ -574,6 +575,10 @@ fi # The spec file changelog only includes changes made to the spec file # itself %changelog +* Mon Apr 05 2004 Lenz Grimmer + +- added ncurses-devel to the build prerequisites (BUG 3377) + * Thu Feb 12 2004 Lenz Grimmer - when using gcc, _always_ use CXX=gcc From f7f8efc2638b35c95b1a26b2bc808aaa92a43c79 Mon Sep 17 00:00:00 2001 From: "marko@hundin.mysql.fi" <> Date: Mon, 5 Apr 2004 15:40:56 +0300 Subject: [PATCH 16/28] InnoDB: Backport fil_path_to_mysql_datadir from MySQL 4.1.x --- innobase/fil/fil0fil.c | 5 +++++ innobase/include/fil0fil.h | 5 +++++ sql/ha_innodb.cc | 1 + 3 files changed, 11 insertions(+) diff --git a/innobase/fil/fil0fil.c b/innobase/fil/fil0fil.c index 44f1777bb33..5d45b254afe 100644 --- a/innobase/fil/fil0fil.c +++ b/innobase/fil/fil0fil.c @@ -77,6 +77,11 @@ out of the LRU-list and keep a count of pending operations. When an operation completes, we decrement the count and return the file node to the LRU-list if the count drops to zero. */ +/* When mysqld is run, the default directory "." is the mysqld datadir, +but in the MySQL Embedded Server Library and ibbackup it is not the default +directory, and we must set the base file path explicitly */ +const char* fil_path_to_mysql_datadir = "."; + ulint fil_n_pending_log_flushes = 0; ulint fil_n_pending_tablespace_flushes = 0; diff --git a/innobase/include/fil0fil.h b/innobase/include/fil0fil.h index ad3149f0b36..ef41ca21d2c 100644 --- a/innobase/include/fil0fil.h +++ b/innobase/include/fil0fil.h @@ -16,6 +16,11 @@ Created 10/25/1995 Heikki Tuuri #include "ut0byte.h" #include "os0file.h" +/* When mysqld is run, the default directory "." is the mysqld datadir, but in +ibbackup we must set it explicitly; the path must NOT contain the trailing +'/' or '\' */ +extern const char* fil_path_to_mysql_datadir; + /* 'null' (undefined) page offset in the context of file spaces */ #define FIL_NULL ULINT32_UNDEFINED diff --git a/sql/ha_innodb.cc b/sql/ha_innodb.cc index 5a929237e3b..ff249b9d251 100644 --- a/sql/ha_innodb.cc +++ b/sql/ha_innodb.cc @@ -714,6 +714,7 @@ innobase_init(void) if (mysql_embedded) { default_path = mysql_real_data_home; + fil_path_to_mysql_datadir = mysql_real_data_home; } else { /* It's better to use current lib, to keep paths short */ current_dir[0] = FN_CURLIB; From 7b68b266239f1de612c50044064c0cd1cba5fb5d Mon Sep 17 00:00:00 2001 From: "vva@eagle.mysql.r18.ru" <> Date: Mon, 5 Apr 2004 23:18:16 +0500 Subject: [PATCH 17/28] fixed Bug #3361 "mysqldump quotes DECIMAL values" --- client/mysqldump.c | 8 ++++---- mysql-test/r/mysqldump.result | 18 ++++++++++++++++-- mysql-test/t/mysqldump.test | 28 ++++++++++++++++++++++++++++ 3 files changed, 48 insertions(+), 6 deletions(-) diff --git a/client/mysqldump.c b/client/mysqldump.c index 4aec31c8ff2..42b094d2902 100644 --- a/client/mysqldump.c +++ b/client/mysqldump.c @@ -1116,9 +1116,9 @@ static void dumpTable(uint numFields, char *table) if (field->type == FIELD_TYPE_DECIMAL) { /* add " signs around */ - dynstr_append(&extended_row, "\""); + dynstr_append(&extended_row, "\'"); dynstr_append(&extended_row, ptr); - dynstr_append(&extended_row, "\""); + dynstr_append(&extended_row, "\'"); } else dynstr_append(&extended_row, ptr); @@ -1162,9 +1162,9 @@ static void dumpTable(uint numFields, char *table) if (field->type == FIELD_TYPE_DECIMAL) { /* add " signs around */ - fputs("\"", md_result_file); + fputs("\'", md_result_file); fputs(ptr, md_result_file); - fputs("\"", md_result_file); + fputs("\'", md_result_file); } else fputs(ptr, md_result_file); diff --git a/mysql-test/r/mysqldump.result b/mysql-test/r/mysqldump.result index 837a3627647..714cb42af5e 100644 --- a/mysql-test/r/mysqldump.result +++ b/mysql-test/r/mysqldump.result @@ -22,8 +22,8 @@ CREATE TABLE t1 ( a decimal(240,20) default NULL ) TYPE=MyISAM; -INSERT INTO t1 VALUES ("1234567890123456789012345678901234567890.00000000000000000000"); -INSERT INTO t1 VALUES ("0987654321098765432109876543210987654321.00000000000000000000"); +INSERT INTO t1 VALUES ('1234567890123456789012345678901234567890.00000000000000000000'); +INSERT INTO t1 VALUES ('0987654321098765432109876543210987654321.00000000000000000000'); DROP TABLE t1; CREATE TABLE t1 (a double); @@ -35,3 +35,17 @@ CREATE TABLE t1 ( INSERT INTO t1 VALUES (RES); DROP TABLE t1; +CREATE TABLE t1 (a DECIMAL(10,5), b FLOAT); +INSERT INTO t1 VALUES (1.2345, 2.3456); +INSERT INTO t1 VALUES ('1.2345', 2.3456); +INSERT INTO t1 VALUES ("1.2345", 2.3456); +CREATE TABLE t1 ( + a decimal(10,5) default NULL, + b float default NULL +) TYPE=MyISAM; + +INSERT INTO t1 VALUES ('1.23450',2.3456); +INSERT INTO t1 VALUES ('1.23450',2.3456); +INSERT INTO t1 VALUES ('1.23450',2.3456); + +DROP TABLE t1; diff --git a/mysql-test/t/mysqldump.test b/mysql-test/t/mysqldump.test index bc63dc37d96..d1394e40a49 100644 --- a/mysql-test/t/mysqldump.test +++ b/mysql-test/t/mysqldump.test @@ -30,3 +30,31 @@ INSERT INTO t1 VALUES (-9e999999); --replace_result (-1.79769313486232e+308) (RES) (NULL) (RES) --exec $MYSQL_DUMP --skip-comments test t1 DROP TABLE t1; + +# +# Bug #3361 mysqldum quotes DECIMAL values +# + +CREATE TABLE t1 (a DECIMAL(10,5), b FLOAT); + +# check at first how mysql work with quoted decimal + +INSERT INTO t1 VALUES (1.2345, 2.3456); +INSERT INTO t1 VALUES ('1.2345', 2.3456); +INSERT INTO t1 VALUES ("1.2345", 2.3456); + +# The code below should be uncommented in mysql-4.1 to fix +# behaviour of quoting DECIMAL fields with different +# values of sql_mode +######## +#SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='ANSI_QUOTES'; +#INSERT INTO t1 VALUES (1.2345, 2.3456); +#INSERT INTO t1 VALUES ('1.2345', 2.3456); +#--error 1054 +#INSERT INTO t1 VALUES ("1.2345", 2.3456); +#SET SQL_MODE=@OLD_SQL_MODE; +######## + +# check how mysqldump make quoting +--exec $MYSQL_DUMP --skip-comments test t1 +DROP TABLE t1; From 6af38c65bebe79e36aaa57c0b4f9a78f047bccad Mon Sep 17 00:00:00 2001 From: "marko@hundin.mysql.fi" <> Date: Tue, 6 Apr 2004 16:14:43 +0300 Subject: [PATCH 18/28] InnoDB: send diagnostic output to stderr or files instead of stdout or fixed-size memory buffers --- innobase/btr/btr0btr.c | 258 +++++++++------- innobase/btr/btr0cur.c | 88 +++--- innobase/btr/btr0sea.c | 30 +- innobase/buf/buf0buf.c | 179 +++++------ innobase/buf/buf0flu.c | 32 +- innobase/buf/buf0lru.c | 54 ++-- innobase/buf/buf0rea.c | 18 +- innobase/data/data0data.c | 128 ++------ innobase/data/data0type.c | 30 +- innobase/dict/dict0boot.c | 3 +- innobase/dict/dict0crea.c | 38 ++- innobase/dict/dict0dict.c | 576 +++++++++++++++-------------------- innobase/dict/dict0load.c | 71 +++-- innobase/eval/eval0eval.c | 5 +- innobase/fil/fil0fil.c | 5 +- innobase/fsp/fsp0fsp.c | 91 +++--- innobase/fut/fut0lst.c | 5 +- innobase/ha/ha0ha.c | 14 +- innobase/ibuf/ibuf0ibuf.c | 112 ++++--- innobase/include/buf0buf.h | 3 +- innobase/include/buf0buf.ic | 18 +- innobase/include/data0data.h | 11 +- innobase/include/dict0dict.h | 28 +- innobase/include/ha0ha.h | 3 +- innobase/include/ibuf0ibuf.h | 3 +- innobase/include/lock0lock.h | 11 +- innobase/include/log0log.h | 3 +- innobase/include/mtr0log.ic | 7 +- innobase/include/os0file.h | 3 +- innobase/include/rem0rec.h | 11 +- innobase/include/rem0rec.ic | 2 +- innobase/include/row0sel.ic | 5 +- innobase/include/row0upd.ic | 8 +- innobase/include/srv0srv.h | 14 +- innobase/include/sync0arr.h | 3 +- innobase/include/sync0sync.h | 6 +- innobase/include/trx0sys.h | 2 +- innobase/include/trx0trx.h | 3 +- innobase/include/ut0ut.h | 42 ++- innobase/lock/lock0lock.c | 302 ++++++------------ innobase/log/log0log.c | 80 +++-- innobase/log/log0recv.c | 100 +++--- innobase/mem/mem0dbg.c | 48 ++- innobase/mtr/mtr0log.c | 15 +- innobase/mtr/mtr0mtr.c | 5 +- innobase/os/os0file.c | 84 +++-- innobase/os/os0proc.c | 5 +- innobase/os/os0thread.c | 2 +- innobase/page/page0cur.c | 8 +- innobase/page/page0page.c | 196 +++++------- innobase/pars/pars0opt.c | 22 +- innobase/rem/rem0rec.c | 88 +----- innobase/row/row0ins.c | 164 +++++----- innobase/row/row0mysql.c | 292 ++++++++++-------- innobase/row/row0purge.c | 6 +- innobase/row/row0row.c | 21 +- innobase/row/row0sel.c | 142 +++++---- innobase/row/row0umod.c | 33 +- innobase/row/row0undo.c | 4 +- innobase/row/row0upd.c | 28 +- innobase/srv/srv0srv.c | 237 +++++++------- innobase/srv/srv0start.c | 56 +++- innobase/sync/sync0arr.c | 121 +++----- innobase/sync/sync0rw.c | 63 ++-- innobase/sync/sync0sync.c | 68 ++--- innobase/trx/trx0purge.c | 10 +- innobase/trx/trx0rec.c | 115 ++++--- innobase/trx/trx0roll.c | 15 +- innobase/trx/trx0sys.c | 4 +- innobase/trx/trx0trx.c | 97 +++--- innobase/trx/trx0undo.c | 11 +- innobase/ut/ut0ut.c | 148 +++++---- sql/ha_innodb.cc | 292 ++++++++++-------- 73 files changed, 2235 insertions(+), 2570 deletions(-) diff --git a/innobase/btr/btr0btr.c b/innobase/btr/btr0btr.c index 1d22d107b12..2e9de9b39bf 100644 --- a/innobase/btr/btr0btr.c +++ b/innobase/btr/btr0btr.c @@ -588,28 +588,29 @@ btr_page_get_father_for_rec( if (btr_node_ptr_get_child_page_no(node_ptr) != buf_frame_get_page_no(page)) { - fprintf(stderr, -"InnoDB: Dump of the child page:\n"); + fputs("InnoDB: Dump of the child page:\n", stderr); buf_page_print(buf_frame_align(page)); - fprintf(stderr, -"InnoDB: Dump of the parent page:\n"); + fputs("InnoDB: Dump of the parent page:\n", stderr); buf_page_print(buf_frame_align(node_ptr)); - fprintf(stderr, -"InnoDB: Corruption of an index tree: table %s, index %s,\n" + fputs("InnoDB: Corruption of an index tree: table ", stderr); + ut_print_name(stderr, + UT_LIST_GET_FIRST(tree->tree_indexes)->table_name); + fputs(", index ", stderr); + ut_print_name(stderr, + UT_LIST_GET_FIRST(tree->tree_indexes)->name); + fprintf(stderr, ",\n" "InnoDB: father ptr page no %lu, child page no %lu\n", - (UT_LIST_GET_FIRST(tree->tree_indexes))->table_name, - (UT_LIST_GET_FIRST(tree->tree_indexes))->name, - btr_node_ptr_get_child_page_no(node_ptr), - buf_frame_get_page_no(page)); + btr_node_ptr_get_child_page_no(node_ptr), + buf_frame_get_page_no(page)); page_rec_print(page_rec_get_next(page_get_infimum_rec(page))); page_rec_print(node_ptr); - fprintf(stderr, + fputs( "InnoDB: You should dump + drop + reimport the table to fix the\n" "InnoDB: corruption. If the crash happens at the database startup, see\n" -"InnoDB: section 6.1 of http://www.innodb.com/ibman.html about forcing\n" -"InnoDB: recovery. Then dump + drop + reimport.\n"); +"InnoDB: section 6.1 of http://www.innodb.com/ibman.php about forcing\n" +"InnoDB: recovery. Then dump + drop + reimport.\n", stderr); } ut_a(btr_node_ptr_get_child_page_no(node_ptr) == @@ -1050,7 +1051,7 @@ btr_root_raise_and_insert( /* We play safe and reset the free bits for the new page */ -/* printf("Root raise new page no %lu\n", +/* fprintf(stderr, "Root raise new page no %lu\n", buf_frame_get_page_no(new_page)); */ ibuf_reset_free_bits(UT_LIST_GET_FIRST(tree->tree_indexes), @@ -1599,7 +1600,7 @@ func_start: /* 5. Move then the records to the new page */ if (direction == FSP_DOWN) { -/* printf("Split left\n"); */ +/* fputs("Split left\n", stderr); */ page_move_rec_list_start(new_page, page, move_limit, mtr); left_page = new_page; @@ -1607,7 +1608,7 @@ func_start: lock_update_split_left(right_page, left_page); } else { -/* printf("Split right\n"); */ +/* fputs("Split right\n", stderr); */ page_move_rec_list_end(new_page, page, move_limit, mtr); left_page = page; @@ -1643,7 +1644,7 @@ func_start: ibuf_update_free_bits_for_two_pages_low(cursor->index, left_page, right_page, mtr); - /* printf("Split and insert done %lu %lu\n", + /* fprintf(stderr, "Split and insert done %lu %lu\n", buf_frame_get_page_no(left_page), buf_frame_get_page_no(right_page)); */ return(rec); @@ -1663,7 +1664,7 @@ func_start: /* We play safe and reset the free bits for new_page */ ibuf_reset_free_bits(cursor->index, new_page); - /* printf("Split second round %lu\n", + /* fprintf(stderr, "Split second round %lu\n", buf_frame_get_page_no(page)); */ n_iterations++; ut_ad(n_iterations < 2); @@ -1677,7 +1678,7 @@ func_start: ibuf_update_free_bits_for_two_pages_low(cursor->index, left_page, right_page, mtr); - /* printf("Split and insert done %lu %lu\n", + /* fprintf(stderr, "Split and insert done %lu %lu\n", buf_frame_get_page_no(left_page), buf_frame_get_page_no(right_page)); */ @@ -1924,7 +1925,7 @@ btr_compress( left_page_no = btr_page_get_prev(page, mtr); right_page_no = btr_page_get_next(page, mtr); -/* printf("Merge left page %lu right %lu \n", left_page_no, +/* fprintf(stderr, "Merge left page %lu right %lu \n", left_page_no, right_page_no); */ node_ptr = btr_page_get_father_node_ptr(tree, page, mtr); @@ -2174,8 +2175,9 @@ btr_print_size( mtr_t mtr; if (tree->type & DICT_IBUF) { - printf( - "Sorry, cannot print info of an ibuf tree: use ibuf functions\n"); + fputs( + "Sorry, cannot print info of an ibuf tree: use ibuf functions\n", + stderr); return; } @@ -2186,14 +2188,14 @@ btr_print_size( seg = root + PAGE_HEADER + PAGE_BTR_SEG_TOP; - printf("INFO OF THE NON-LEAF PAGE SEGMENT\n"); + fputs("INFO OF THE NON-LEAF PAGE SEGMENT\n", stderr); fseg_print(seg, &mtr); if (!(tree->type & DICT_UNIVERSAL)) { seg = root + PAGE_HEADER + PAGE_BTR_SEG_LEAF; - printf("INFO OF THE LEAF PAGE SEGMENT\n"); + fputs("INFO OF THE LEAF PAGE SEGMENT\n", stderr); fseg_print(seg, &mtr); } @@ -2221,7 +2223,7 @@ btr_print_recursive( ut_ad(mtr_memo_contains(mtr, buf_block_align(page), MTR_MEMO_PAGE_X_FIX)); - printf("NODE ON LEVEL %lu page number %lu\n", + fprintf(stderr, "NODE ON LEVEL %lu page number %lu\n", btr_page_get_level(page, mtr), buf_frame_get_page_no(page)); page_print(page, width, width); @@ -2267,8 +2269,8 @@ btr_print_tree( mtr_t mtr; page_t* root; - printf("--------------------------\n"); - printf("INDEX TREE PRINT\n"); + fputs("--------------------------\n" + "INDEX TREE PRINT\n", stderr); mtr_start(&mtr); @@ -2324,6 +2326,22 @@ btr_check_node_ptr( return(TRUE); } +/**************************************************************** +Display identification information for a record. */ +static +void +btr_index_rec_validate_report( +/*==========================*/ + page_t* page, /* in: index page */ + rec_t* rec, /* in: index record */ + dict_index_t* index) /* in: index */ +{ + fputs("InnoDB: Record in ", stderr); + dict_index_name_print(stderr, index); + fprintf(stderr, ", page %lu, at offset %lu\n", + buf_frame_get_page_no(page), (ulint)(rec - page)); +} + /**************************************************************** Checks the size and number of fields in a record based on the definition of the index. */ @@ -2338,13 +2356,10 @@ btr_index_rec_validate( should print hex dump of record and page on error */ { - dtype_t* type; - byte* data; ulint len; ulint n; ulint i; page_t* page; - char err_buf[1000]; page = buf_frame_align(rec); @@ -2359,11 +2374,8 @@ btr_index_rec_validate( n = dict_index_get_n_fields(index); if (rec_get_n_fields(rec) != n) { - fprintf(stderr, -"InnoDB: Record in index %s in table %s, page %lu, at offset %lu\n" -"InnoDB: has %lu fields, should have %lu\n", - index->name, index->table_name, - buf_frame_get_page_no(page), (ulint)(rec - page), + btr_index_rec_validate_report(page, rec, index); + fprintf(stderr, "InnoDB: has %lu fields, should have %lu\n", rec_get_n_fields(rec), n); if (!dump_on_error) { @@ -2373,16 +2385,17 @@ btr_index_rec_validate( buf_page_print(page); - rec_sprintf(err_buf, 900, rec); - fprintf(stderr, "InnoDB: corrupt record %s\n", err_buf); + fputs("InnoDB: corrupt record ", stderr); + rec_print(stderr, rec); + putc('\n', stderr); return(FALSE); } for (i = 0; i < n; i++) { - data = rec_get_nth_field(rec, i, &len); + dtype_t* type = dict_index_get_nth_type(index, i); - type = dict_index_get_nth_type(index, i); + rec_get_nth_field(rec, i, &len); if ((dict_index_get_nth_field(index, i)->prefix_len == 0 && len != UNIV_SQL_NULL && dtype_is_fixed_size(type) @@ -2393,12 +2406,9 @@ btr_index_rec_validate( && len != dict_index_get_nth_field(index, i)->prefix_len)) { + btr_index_rec_validate_report(page, rec, index); fprintf(stderr, -"InnoDB: Record in index %s in table %s, page %lu, at offset %lu\n" "InnoDB: field %lu len is %lu, should be %lu\n", - index->name, index->table_name, - buf_frame_get_page_no(page), - (ulint)(rec - page), i, len, dtype_get_fixed_size(type)); if (!dump_on_error) { @@ -2408,9 +2418,9 @@ btr_index_rec_validate( buf_page_print(page); - rec_sprintf(err_buf, 900, rec); - fprintf(stderr, - "InnoDB: corrupt record %s\n", err_buf); + fputs("InnoDB: corrupt record ", stderr); + rec_print(stderr, rec); + putc('\n', stderr); return(FALSE); } @@ -2430,7 +2440,6 @@ btr_index_page_validate( page_t* page, /* in: index page */ dict_index_t* index) /* in: index */ { - rec_t* rec; page_cur_t cur; ibool ret = TRUE; @@ -2438,14 +2447,12 @@ btr_index_page_validate( page_cur_move_to_next(&cur); for (;;) { - rec = (&cur)->rec; - if (page_cur_is_after_last(&cur)) { break; } - if (!btr_index_rec_validate(rec, index, TRUE)) { + if (!btr_index_rec_validate(cur.rec, index, TRUE)) { return(FALSE); } @@ -2456,6 +2463,46 @@ btr_index_page_validate( return(ret); } +/**************************************************************** +Report an error on one page of an index tree. */ +static +void +btr_validate_report1( + /* out: TRUE if ok */ + dict_index_t* index, /* in: index */ + ulint level, /* in: B-tree level */ + page_t* page) /* in: index page */ +{ + fprintf(stderr, "InnoDB: Error in page %lu of ", + buf_frame_get_page_no(page)); + dict_index_name_print(stderr, index); + if (level) { + fprintf(stderr, ", index tree level %lu", level); + } + putc('\n', stderr); +} + +/**************************************************************** +Report an error on two pages of an index tree. */ +static +void +btr_validate_report2( + /* out: TRUE if ok */ + dict_index_t* index, /* in: index */ + ulint level, /* in: B-tree level */ + page_t* page1, /* in: first index page */ + page_t* page2) /* in: second index page */ +{ + fprintf(stderr, "InnoDB: Error in pages %lu and %lu of ", + buf_frame_get_page_no(page1), + buf_frame_get_page_no(page2)); + dict_index_name_print(stderr, index); + if (level) { + fprintf(stderr, ", index tree level %lu", level); + } + putc('\n', stderr); +} + /**************************************************************** Validates index tree level. */ static @@ -2481,7 +2528,6 @@ btr_validate_level( ibool ret = TRUE; dict_index_t* index; mtr_t mtr; - char err_buf[1000]; mtr_start(&mtr); @@ -2512,10 +2558,7 @@ loop: /* Check ordering etc. of records */ if (!page_validate(page, index)) { - fprintf(stderr, -"InnoDB: Error in page %lu in index %s table %s, index tree level %lu\n", - buf_frame_get_page_no(page), index->name, - index->table_name, level); + btr_validate_report1(index, level, page); ret = FALSE; } else if (level == 0) { @@ -2545,25 +2588,22 @@ loop: page_rec_get_next(page_get_infimum_rec(right_page)), UT_LIST_GET_FIRST(tree->tree_indexes)) >= 0) { - fprintf(stderr, - "InnoDB: Error on pages %lu and %lu in index %s table %s\n", - buf_frame_get_page_no(page), - right_page_no, - index->name, index->table_name); + btr_validate_report2(index, level, page, right_page); - fprintf(stderr, - "InnoDB: records in wrong order on adjacent pages\n"); + fputs("InnoDB: records in wrong order" + " on adjacent pages\n", stderr); buf_page_print(page); buf_page_print(right_page); - rec_sprintf(err_buf, 900, - page_rec_get_prev(page_get_supremum_rec(page))); - fprintf(stderr, "InnoDB: record %s\n", err_buf); - - rec_sprintf(err_buf, 900, - page_rec_get_next(page_get_infimum_rec(right_page))); - fprintf(stderr, "InnoDB: record %s\n", err_buf); + fputs("InnoDB: record ", stderr); + rec_print(stderr, page_rec_get_prev( + page_get_supremum_rec(page))); + putc('\n', stderr); + fputs("InnoDB: record ", stderr); + rec_print(stderr, page_rec_get_next( + page_get_infimum_rec(right_page))); + putc('\n', stderr); ret = FALSE; } @@ -2586,32 +2626,27 @@ loop: || node_ptr != btr_page_get_father_for_rec(tree, page, page_rec_get_prev(page_get_supremum_rec(page)), &mtr)) { - fprintf(stderr, - "InnoDB: Error on page %lu in index %s table %s\n", - buf_frame_get_page_no(page), - index->name, index->table_name); + btr_validate_report1(index, level, page); - fprintf(stderr, - "InnoDB: node pointer to the page is wrong\n"); + fputs("InnoDB: node pointer to the page is wrong\n", + stderr); buf_page_print(father_page); buf_page_print(page); - rec_sprintf(err_buf, 900, node_ptr); - - fprintf(stderr, "InnoDB: node ptr %s\n", err_buf); + fputs("InnoDB: node ptr ", stderr); + rec_print(stderr, node_ptr); - fprintf(stderr, + fprintf(stderr, "\n" "InnoDB: node ptr child page n:o %lu\n", btr_node_ptr_get_child_page_no(node_ptr)); - rec_sprintf(err_buf, 900, + fputs("InnoDB: record on page ", stderr); + rec_print(stderr, btr_page_get_father_for_rec(tree, page, page_rec_get_prev(page_get_supremum_rec(page)), &mtr)); - - fprintf(stderr, "InnoDB: record on page %s\n", - err_buf); + putc('\n', stderr); ret = FALSE; goto node_ptr_fails; @@ -2629,27 +2664,19 @@ loop: if (cmp_dtuple_rec(node_ptr_tuple, node_ptr) != 0) { - fprintf(stderr, - "InnoDB: Error on page %lu in index %s table %s\n", - buf_frame_get_page_no(page), - index->name, index->table_name); + btr_validate_report1(index, level, page); buf_page_print(father_page); buf_page_print(page); - fprintf(stderr, - "InnoDB: Error: node ptrs differ on levels > 0\n"); - - rec_sprintf(err_buf, 900, node_ptr); - - fprintf(stderr, "InnoDB: node ptr %s\n", - err_buf); - rec_sprintf(err_buf, 900, - page_rec_get_next( + fputs("InnoDB: Error: node ptrs differ" + " on levels > 0\n" + "InnoDB: node ptr ", stderr); + rec_print(stderr, node_ptr); + fputs("InnoDB: first rec ", stderr); + rec_print(stderr, page_rec_get_next( page_get_infimum_rec(page))); - - fprintf(stderr, "InnoDB: first rec %s\n", - err_buf); + putc('\n', stderr); ret = FALSE; mem_heap_free(heap); @@ -2681,13 +2708,12 @@ loop: if (right_node_ptr != page_rec_get_next(node_ptr)) { ret = FALSE; - fprintf(stderr, - "InnoDB: node pointer to the right page is wrong\n"); + fputs( + "InnoDB: node pointer to the right page is wrong\n", + stderr); - fprintf(stderr, - "InnoDB: Error on page %lu in index %s table %s\n", - buf_frame_get_page_no(page), - index->name, index->table_name); + btr_validate_report1(index, level, + page); buf_page_print(father_page); buf_page_print(page); @@ -2701,13 +2727,12 @@ loop: page_get_infimum_rec( right_father_page))) { ret = FALSE; - fprintf(stderr, - "InnoDB: node pointer 2 to the right page is wrong\n"); + fputs( + "InnoDB: node pointer 2 to the right page is wrong\n", + stderr); - fprintf(stderr, - "InnoDB: Error on page %lu in index %s table %s\n", - buf_frame_get_page_no(page), - index->name, index->table_name); + btr_validate_report1(index, level, + page); buf_page_print(father_page); buf_page_print(right_father_page); @@ -2719,13 +2744,12 @@ loop: != btr_page_get_next(father_page, &mtr)) { ret = FALSE; - fprintf(stderr, - "InnoDB: node pointer 3 to the right page is wrong\n"); + fputs( + "InnoDB: node pointer 3 to the right page is wrong\n", + stderr); - fprintf(stderr, - "InnoDB: Error on page %lu in index %s table %s\n", - buf_frame_get_page_no(page), - index->name, index->table_name); + btr_validate_report1(index, level, + page); buf_page_print(father_page); buf_page_print(right_father_page); diff --git a/innobase/btr/btr0cur.c b/innobase/btr/btr0cur.c index c7863ba08e4..8974200efe8 100644 --- a/innobase/btr/btr0cur.c +++ b/innobase/btr/btr0cur.c @@ -830,6 +830,24 @@ btr_cur_ins_lock_and_undo( return(DB_SUCCESS); } +/***************************************************************** +Report information about a transaction. */ +static +void +btr_cur_trx_report( +/*===============*/ + const trx_t* trx, /* in: transaction */ + const dict_index_t* index, /* in: index */ + const char* op) /* in: operation */ +{ + fprintf(stderr, "Trx with id %lu %lu going to ", + ut_dulint_get_high(trx->id), + ut_dulint_get_low(trx->id)); + fputs(op, stderr); + dict_index_name_print(stderr, index); + putc('\n', stderr); +} + /***************************************************************** Tries to perform an insert to a page in an index tree, next to cursor. It is assumed that mtr holds an x-latch on the page. The operation does @@ -877,18 +895,13 @@ btr_cur_optimistic_insert( index = cursor->index; if (!dtuple_check_typed_no_assert(entry)) { - fprintf(stderr, -"InnoDB: Error in a tuple to insert into table %s index %s\n", - index->table_name, index->name); + fputs("InnoDB: Error in a tuple to insert into ", stderr); + dict_index_name_print(stderr, index); } if (btr_cur_print_record_ops && thr) { - printf( - "Trx with id %lu %lu going to insert to table %s index %s\n", - ut_dulint_get_high(thr_get_trx(thr)->id), - ut_dulint_get_low(thr_get_trx(thr)->id), - index->table_name, index->name); - dtuple_print(entry); + btr_cur_trx_report(thr_get_trx(thr), index, "insert into "); + dtuple_print(stderr, entry); } ut_ad(mtr_memo_contains(mtr, buf_block_align(page), @@ -981,20 +994,15 @@ calculate_sizes_again: *rec = page_cur_tuple_insert(page_cursor, entry, mtr); - if (!(*rec)) { - char* err_buf = mem_alloc(1000); - - dtuple_sprintf(err_buf, 900, entry); - - fprintf(stderr, - "InnoDB: Error: cannot insert tuple %s to index %s of table %s\n" - "InnoDB: max insert size %lu\n", - err_buf, index->name, index->table->name, max_size); - - mem_free(err_buf); + if (!*rec) { + fputs("InnoDB: Error: cannot insert tuple ", stderr); + dtuple_print(stderr, entry); + fputs(" into ", stderr); + dict_index_name_print(stderr, index); + fprintf(stderr, "\nInnoDB: max insert size %lu\n", + max_size); + ut_error; } - - ut_a(*rec); /* <- We calculated above the record would fit */ } #ifdef BTR_CUR_HASH_ADAPT @@ -1010,7 +1018,8 @@ calculate_sizes_again: lock_update_insert(*rec); } -/* printf("Insert to page %lu, max ins size %lu, rec %lu ind type %lu\n", +/* fprintf(stderr, "Insert into page %lu, max ins size %lu," + " rec %lu ind type %lu\n", buf_frame_get_page_no(page), max_size, rec_size + PAGE_DIR_SLOT_SIZE, type); */ @@ -1361,12 +1370,8 @@ btr_cur_update_in_place( trx = thr_get_trx(thr); if (btr_cur_print_record_ops && thr) { - printf( - "Trx with id %lu %lu going to update table %s index %s\n", - ut_dulint_get_high(thr_get_trx(thr)->id), - ut_dulint_get_low(thr_get_trx(thr)->id), - index->table_name, index->name); - rec_print(rec); + btr_cur_trx_report(trx, index, "update "); + rec_print(stderr, rec); } /* Do lock checking and undo logging */ @@ -1465,12 +1470,8 @@ btr_cur_optimistic_update( index = cursor->index; if (btr_cur_print_record_ops && thr) { - printf( - "Trx with id %lu %lu going to update table %s index %s\n", - ut_dulint_get_high(thr_get_trx(thr)->id), - ut_dulint_get_low(thr_get_trx(thr)->id), - index->table_name, index->name); - rec_print(rec); + btr_cur_trx_report(thr_get_trx(thr), index, "update "); + rec_print(stderr, rec); } ut_ad(mtr_memo_contains(mtr, buf_block_align(page), @@ -2012,12 +2013,8 @@ btr_cur_del_mark_set_clust_rec( index = cursor->index; if (btr_cur_print_record_ops && thr) { - printf( - "Trx with id %lu %lu going to del mark table %s index %s\n", - ut_dulint_get_high(thr_get_trx(thr)->id), - ut_dulint_get_low(thr_get_trx(thr)->id), - index->table_name, index->name); - rec_print(rec); + btr_cur_trx_report(thr_get_trx(thr), index, "del mark "); + rec_print(stderr, rec); } ut_ad(index->type & DICT_CLUSTERED); @@ -2152,12 +2149,9 @@ btr_cur_del_mark_set_sec_rec( rec = btr_cur_get_rec(cursor); if (btr_cur_print_record_ops && thr) { - printf( - "Trx with id %lu %lu going to del mark table %s index %s\n", - ut_dulint_get_high(thr_get_trx(thr)->id), - ut_dulint_get_low(thr_get_trx(thr)->id), - cursor->index->table_name, cursor->index->name); - rec_print(rec); + btr_cur_trx_report(thr_get_trx(thr), cursor->index, + "del mark "); + rec_print(stderr, rec); } err = lock_sec_rec_modify_check_and_lock(flags, rec, cursor->index, diff --git a/innobase/btr/btr0sea.c b/innobase/btr/btr0sea.c index f629dea74de..e01ce94dc97 100644 --- a/innobase/btr/btr0sea.c +++ b/innobase/btr/btr0sea.c @@ -803,7 +803,7 @@ btr_search_guess_on_hash( success = FALSE; /* - printf("Tree id %lu, page index id %lu fold %lu\n", + fprintf(stderr, "Tree id %lu, page index id %lu fold %lu\n", ut_dulint_get_low(tree_id), ut_dulint_get_low(btr_page_get_index_id(page)), fold); @@ -1045,7 +1045,7 @@ btr_search_drop_page_hash_when_freed( /* We assume that if the caller has a latch on the page, then the caller has already dropped the hash index for the page, and we never get here. Therefore we can acquire the s-latch to - the page without fearing a deadlock. */ + the page without having to fear a deadlock. */ page = buf_page_get(space, page_no, RW_S_LATCH, &mtr); @@ -1515,8 +1515,9 @@ check_next_rec: ha_insert_for_fold(table, ins_fold, ins_rec); /* - printf("Hash insert for %s, fold %lu\n", - cursor->index->name, ins_fold); + fputs("Hash insert for ", stderr); + dict_index_name_print(stderr, cursor->index); + fprintf(stderr, " fold %lu\n", ins_fold); */ } else { ha_insert_for_fold(table, next_fold, next_rec); @@ -1543,7 +1544,6 @@ btr_search_validate(void) ulint n_page_dumps = 0; ibool ok = TRUE; ulint i; - char rec_str[500]; rw_lock_x_lock(&btr_search_latch); @@ -1564,9 +1564,9 @@ btr_search_validate(void) fprintf(stderr, " InnoDB: Error in an adaptive hash index pointer to page %lu\n" -"ptr mem address %lu index id %lu %lu, node fold %lu, rec fold %lu\n", - buf_frame_get_page_no(page), - (ulint)(node->data), +"ptr mem address %p index id %lu %lu, node fold %lu, rec fold %lu\n", + buf_frame_get_page_no(page), + node->data, ut_dulint_get_high(btr_page_get_index_id(page)), ut_dulint_get_low(btr_page_get_index_id(page)), node->fold, rec_fold((rec_t*)(node->data), @@ -1574,16 +1574,12 @@ btr_search_validate(void) block->curr_n_bytes, btr_page_get_index_id(page))); - rec_sprintf(rec_str, 450, (rec_t*)(node->data)); - - fprintf(stderr, - "InnoDB: Record %s\n" - "InnoDB: on that page.", rec_str); - - fprintf(stderr, -"Page mem address %lu, is hashed %lu, n fields %lu, n bytes %lu\n" + fputs("InnoDB: Record ", stderr); + rec_print(stderr, (rec_t*)(node->data)); + fprintf(stderr, "\nInnoDB: on that page." +"Page mem address %p, is hashed %lu, n fields %lu, n bytes %lu\n" "side %lu\n", - (ulint)page, block->is_hashed, block->curr_n_fields, + page, block->is_hashed, block->curr_n_fields, block->curr_n_bytes, block->curr_side); if (n_page_dumps < 20) { diff --git a/innobase/buf/buf0buf.c b/innobase/buf/buf0buf.c index e2661725912..b744430a76e 100644 --- a/innobase/buf/buf0buf.c +++ b/innobase/buf/buf0buf.c @@ -348,19 +348,12 @@ buf_page_print( dict_index_t* index; ulint checksum; ulint old_checksum; - char* buf; - - buf = mem_alloc(4 * UNIV_PAGE_SIZE); - - ut_sprintf_buf(buf, read_buf, UNIV_PAGE_SIZE); ut_print_timestamp(stderr); - fprintf(stderr, - " InnoDB: Page dump in ascii and hex (%lu bytes):\n%s", - (ulint)UNIV_PAGE_SIZE, buf); - fprintf(stderr, "InnoDB: End of page dump\n"); - - mem_free(buf); + fprintf(stderr, " InnoDB: Page dump in ascii and hex (%lu bytes):\n", + (ulint)UNIV_PAGE_SIZE); + ut_print_buf(stderr, read_buf, UNIV_PAGE_SIZE); + fputs("InnoDB: End of page dump\n", stderr); checksum = buf_calc_page_new_checksum(read_buf); old_checksum = buf_calc_page_old_checksum(read_buf); @@ -407,18 +400,17 @@ buf_page_print( index = dict_index_find_on_id_low( btr_page_get_index_id(read_buf)); if (index) { - fprintf(stderr, - "InnoDB: and table %s index %s\n", - index->table_name, - index->name); + fputs("InnoDB: (", stderr); + dict_index_name_print(stderr, index); + fputs(")\n", stderr); } } } else if (fil_page_get_type(read_buf) == FIL_PAGE_INODE) { - fprintf(stderr, "InnoDB: Page may be an 'inode' page\n"); + fputs("InnoDB: Page may be an 'inode' page\n", stderr); } else if (fil_page_get_type(read_buf) == FIL_PAGE_IBUF_FREE_LIST) { - fprintf(stderr, - "InnoDB: Page may be an insert buffer free list page\n"); + fputs("InnoDB: Page may be an insert buffer free list page\n", + stderr); } } @@ -1464,8 +1456,8 @@ buf_page_create( /* If we get here, the page was not in buf_pool: init it there */ if (buf_debug_prints) { - printf("Creating space %lu page %lu to buffer\n", space, - offset); + fprintf(stderr, "Creating space %lu page %lu to buffer\n", + space, offset); } block = free_block; @@ -1519,8 +1511,6 @@ buf_page_io_complete( /*=================*/ buf_block_t* block) /* in: pointer to the block in question */ { - dict_index_t* index; - dulint id; ulint io_type; ulint read_page_no; @@ -1551,17 +1541,17 @@ buf_page_io_complete( "InnoDB: Database page corruption on disk or a failed\n" "InnoDB: file read of page %lu.\n", block->offset); - fprintf(stderr, - "InnoDB: You may have to recover from a backup.\n"); + fputs( + "InnoDB: You may have to recover from a backup.\n", stderr); buf_page_print(block->frame); fprintf(stderr, "InnoDB: Database page corruption on disk or a failed\n" "InnoDB: file read of page %lu.\n", block->offset); - fprintf(stderr, - "InnoDB: You may have to recover from a backup.\n"); - fprintf(stderr, + fputs( + "InnoDB: You may have to recover from a backup.\n", stderr); + fputs( "InnoDB: It is also possible that your operating\n" "InnoDB: system has corrupted its own file cache\n" "InnoDB: and rebooting your computer removes the\n" @@ -1572,12 +1562,13 @@ buf_page_io_complete( "InnoDB: the corrupt table. You can use CHECK\n" "InnoDB: TABLE to scan your table for corruption.\n" "InnoDB: Look also at section 6.1 of\n" - "InnoDB: http://www.innodb.com/ibman.html about\n" - "InnoDB: forcing recovery.\n"); + "InnoDB: http://www.innodb.com/ibman.php about\n" + "InnoDB: forcing recovery.\n", stderr); if (srv_force_recovery < SRV_FORCE_IGNORE_CORRUPT) { - fprintf(stderr, - "InnoDB: Ending processing because of a corrupt database page.\n"); + fputs( + "InnoDB: Ending processing because of a corrupt database page.\n", + stderr); exit(1); } } @@ -1619,7 +1610,7 @@ buf_page_io_complete( rw_lock_x_unlock_gen(&(block->read_lock), BUF_IO_READ); if (buf_debug_prints) { - printf("Has read "); + fputs("Has read ", stderr); } } else { ut_ad(io_type == BUF_IO_WRITE); @@ -1634,29 +1625,15 @@ buf_page_io_complete( buf_pool->n_pages_written++; if (buf_debug_prints) { - printf("Has written "); + fputs("Has written ", stderr); } } mutex_exit(&(buf_pool->mutex)); if (buf_debug_prints) { - printf("page space %lu page no %lu", block->space, - block->offset); - id = btr_page_get_index_id(block->frame); - - index = NULL; - /* The following can cause deadlocks if used: */ - /* - index = dict_index_get_if_in_cache(id); - - if (index) { - printf(" index name %s table %s", index->name, - index->table->name); - } - */ - - printf("\n"); + fprintf(stderr, "page space %lu page no %lu\n", + block->space, block->offset); } } @@ -1757,14 +1734,14 @@ buf_validate(void) } if (n_lru + n_free > buf_pool->curr_size) { - printf("n LRU %lu, n free %lu\n", n_lru, n_free); + fprintf(stderr, "n LRU %lu, n free %lu\n", n_lru, n_free); ut_error; } ut_a(UT_LIST_GET_LEN(buf_pool->LRU) == n_lru); if (UT_LIST_GET_LEN(buf_pool->free) != n_free) { - printf("Free list len %lu, free blocks %lu\n", - UT_LIST_GET_LEN(buf_pool->free), n_free); + fprintf(stderr, "Free list len %lu, free blocks %lu\n", + UT_LIST_GET_LEN(buf_pool->free), n_free); ut_error; } ut_a(UT_LIST_GET_LEN(buf_pool->flush_list) == n_flush); @@ -1807,22 +1784,24 @@ buf_print(void) mutex_enter(&(buf_pool->mutex)); - printf("buf_pool size %lu \n", size); - printf("database pages %lu \n", UT_LIST_GET_LEN(buf_pool->LRU)); - printf("free pages %lu \n", UT_LIST_GET_LEN(buf_pool->free)); - printf("modified database pages %lu \n", - UT_LIST_GET_LEN(buf_pool->flush_list)); - - printf("n pending reads %lu \n", buf_pool->n_pend_reads); - - printf("n pending flush LRU %lu list %lu single page %lu\n", + fprintf(stderr, + "buf_pool size %lu \n" + "database pages %lu \n" + "free pages %lu \n" + "modified database pages %lu \n" + "n pending reads %lu \n" + "n pending flush LRU %lu list %lu single page %lu\n" + "pages read %lu, created %lu, written %lu\n", + size, + UT_LIST_GET_LEN(buf_pool->LRU), + UT_LIST_GET_LEN(buf_pool->free), + UT_LIST_GET_LEN(buf_pool->flush_list), + buf_pool->n_pend_reads, buf_pool->n_flush[BUF_FLUSH_LRU], buf_pool->n_flush[BUF_FLUSH_LIST], - buf_pool->n_flush[BUF_FLUSH_SINGLE_PAGE]); - - printf("pages read %lu, created %lu, written %lu\n", - buf_pool->n_pages_read, buf_pool->n_pages_created, - buf_pool->n_pages_written); + buf_pool->n_flush[BUF_FLUSH_SINGLE_PAGE], + buf_pool->n_pages_read, buf_pool->n_pages_created, + buf_pool->n_pages_written); /* Count the number of blocks belonging to each index in the buffer */ @@ -1865,15 +1844,16 @@ buf_print(void) for (i = 0; i < n_found; i++) { index = dict_index_get_if_in_cache(index_ids[i]); - printf("Block count for index %lu in buffer is about %lu", + fprintf(stderr, + "Block count for index %lu in buffer is about %lu", ut_dulint_get_low(index_ids[i]), counts[i]); if (index) { - printf(" index name %s table %s", index->name, - index->table->name); + putc(' ', stderr); + dict_index_name_print(stderr, index); } - printf("\n"); + putc('\n', stderr); } mem_free(index_ids); @@ -1924,44 +1904,29 @@ Prints info of the buffer i/o. */ void buf_print_io( /*=========*/ - char* buf, /* in/out: buffer where to print */ - char* buf_end)/* in: buffer end */ + FILE* file) /* in/out: buffer where to print */ { time_t current_time; double time_elapsed; ulint size; ut_ad(buf_pool); - - if (buf_end - buf < 400) { - - return; - } - size = buf_pool_get_curr_size() / UNIV_PAGE_SIZE; mutex_enter(&(buf_pool->mutex)); - buf += sprintf(buf, - "Buffer pool size %lu\n", size); - buf += sprintf(buf, - "Free buffers %lu\n", UT_LIST_GET_LEN(buf_pool->free)); - buf += sprintf(buf, - "Database pages %lu\n", UT_LIST_GET_LEN(buf_pool->LRU)); -/* - buf += sprintf(buf, - "Lock heap buffers %lu\n", buf_pool->n_lock_heap_pages); - buf += sprintf(buf, - "Hash index buffers %lu\n", buf_pool->n_adaptive_hash_pages); -*/ - buf += sprintf(buf, - "Modified db pages %lu\n", - UT_LIST_GET_LEN(buf_pool->flush_list)); - - buf += sprintf(buf, "Pending reads %lu \n", buf_pool->n_pend_reads); - - buf += sprintf(buf, + fprintf(file, + "Buffer pool size %lu\n" + "Free buffers %lu\n" + "Database pages %lu\n" + "Modified db pages %lu\n" + "Pending reads %lu \n" "Pending writes: LRU %lu, flush list %lu, single page %lu\n", + size, + UT_LIST_GET_LEN(buf_pool->free), + UT_LIST_GET_LEN(buf_pool->LRU), + UT_LIST_GET_LEN(buf_pool->flush_list), + buf_pool->n_pend_reads, buf_pool->n_flush[BUF_FLUSH_LRU] + buf_pool->init_flush[BUF_FLUSH_LRU], buf_pool->n_flush[BUF_FLUSH_LIST] @@ -1973,10 +1938,11 @@ buf_print_io( buf_pool->last_printout_time); buf_pool->last_printout_time = current_time; - buf += sprintf(buf, "Pages read %lu, created %lu, written %lu\n", - buf_pool->n_pages_read, buf_pool->n_pages_created, - buf_pool->n_pages_written); - buf += sprintf(buf, "%.2f reads/s, %.2f creates/s, %.2f writes/s\n", + fprintf(file, + "Pages read %lu, created %lu, written %lu\n" + "%.2f reads/s, %.2f creates/s, %.2f writes/s\n", + buf_pool->n_pages_read, buf_pool->n_pages_created, + buf_pool->n_pages_written, (buf_pool->n_pages_read - buf_pool->n_pages_read_old) / time_elapsed, (buf_pool->n_pages_created - buf_pool->n_pages_created_old) @@ -1985,14 +1951,14 @@ buf_print_io( / time_elapsed); if (buf_pool->n_page_gets > buf_pool->n_page_gets_old) { - buf += sprintf(buf, "Buffer pool hit rate %lu / 1000\n", + fprintf(file, "Buffer pool hit rate %lu / 1000\n", 1000 - ((1000 * (buf_pool->n_pages_read - buf_pool->n_pages_read_old)) / (buf_pool->n_page_gets - buf_pool->n_page_gets_old))); } else { - buf += sprintf(buf, - "No buffer pool page gets since the last printout\n"); + fputs("No buffer pool page gets since the last printout\n", + file); } buf_pool->n_page_gets_old = buf_pool->n_page_gets; @@ -2039,8 +2005,9 @@ buf_all_freed(void) if (!buf_flush_ready_for_replace(block)) { - /* printf("Page %lu %lu still fixed or dirty\n", - block->space, block->offset); */ + fprintf(stderr, + "Page %lu %lu still fixed or dirty\n", + block->space, block->offset); ut_error; } } diff --git a/innobase/buf/buf0flu.c b/innobase/buf/buf0flu.c index 66c9bb605dc..7456e5d6f61 100644 --- a/innobase/buf/buf0flu.c +++ b/innobase/buf/buf0flu.c @@ -189,7 +189,7 @@ buf_flush_write_complete( buf_pool->LRU_flush_ended++; } - /* printf("n pending flush %lu\n", + /* fprintf(stderr, "n pending flush %lu\n", buf_pool->n_flush[block->flush_type]); */ if ((buf_pool->n_flush[block->flush_type] == 0) @@ -411,8 +411,8 @@ buf_flush_write_block_low( ut_ad(!ut_dulint_is_zero(block->newest_modification)); #ifdef UNIV_LOG_DEBUG - printf( - "Warning: cannot force log to disk in the log debug version!\n"); + fputs("Warning: cannot force log to disk in the log debug version!\n", + stderr); #else /* Force the log to the disk before writing the modified block */ log_write_up_to(block->newest_modification, LOG_WAIT_ALL_GROUPS, TRUE); @@ -489,8 +489,9 @@ buf_flush_try_page( } if (buf_debug_prints) { - printf("Flushing page space %lu, page no %lu \n", - block->space, block->offset); + fprintf(stderr, + "Flushing page space %lu, page no %lu \n", + block->space, block->offset); } buf_flush_write_block_low(block); @@ -548,7 +549,7 @@ buf_flush_try_page( rw_lock_s_lock_gen(&(block->lock), BUF_IO_WRITE); if (buf_debug_prints) { - printf( + fprintf(stderr, "Flushing single page space %lu, page no %lu \n", block->space, block->offset); } @@ -592,7 +593,7 @@ buf_flush_try_neighbors( high = offset + 1; } - /* printf("Flush area: low %lu high %lu\n", low, high); */ + /* fprintf(stderr, "Flush area: low %lu high %lu\n", low, high); */ if (high > fil_space_get_size(space)) { high = fil_space_get_size(space); @@ -739,7 +740,7 @@ buf_flush_batch( page_count += buf_flush_try_neighbors(space, offset, flush_type); - /* printf( + /* fprintf(stderr, "Flush type %lu, page no %lu, neighb %lu\n", flush_type, offset, page_count - old_page_count); */ @@ -779,15 +780,12 @@ buf_flush_batch( buf_flush_buffered_writes(); if (buf_debug_prints && page_count > 0) { - if (flush_type == BUF_FLUSH_LRU) { - printf("Flushed %lu pages in LRU flush\n", - page_count); - } else if (flush_type == BUF_FLUSH_LIST) { - printf("Flushed %lu pages in flush list flush\n", - page_count); - } else { - ut_error; - } + ut_a(flush_type == BUF_FLUSH_LRU + || flush_type == BUF_FLUSH_LIST); + fprintf(stderr, flush_type == BUF_FLUSH_LRU + ? "Flushed %lu pages in LRU flush\n" + : "Flushed %lu pages in flush list flush\n", + page_count); } return(page_count); diff --git a/innobase/buf/buf0lru.c b/innobase/buf/buf0lru.c index 0128ee87871..0ced7e23abe 100644 --- a/innobase/buf/buf0lru.c +++ b/innobase/buf/buf0lru.c @@ -126,7 +126,7 @@ buf_LRU_search_and_free_block( if (buf_flush_ready_for_replace(block)) { if (buf_debug_prints) { - printf( + fprintf(stderr, "Putting space %lu page %lu to free list\n", block->space, block->offset); } @@ -301,26 +301,20 @@ loop: fprintf(stderr, "InnoDB: Warning: difficult to find free blocks from\n" "InnoDB: the buffer pool (%lu search iterations)! Consider\n" - "InnoDB: increasing the buffer pool size.\n", - n_iterations); - fprintf(stderr, + "InnoDB: increasing the buffer pool size.\n" "InnoDB: It is also possible that in your Unix version\n" "InnoDB: fsync is very slow, or completely frozen inside\n" "InnoDB: the OS kernel. Then upgrading to a newer version\n" "InnoDB: of your operating system may help. Look at the\n" - "InnoDB: number of fsyncs in diagnostic info below.\n"); - - fprintf(stderr, - "InnoDB: Pending flushes (fsync) log: %lu; buffer pool: %lu\n", - fil_n_pending_log_flushes, - fil_n_pending_tablespace_flushes); - fprintf(stderr, - "InnoDB: %lu OS file reads, %lu OS file writes, %lu OS fsyncs\n", - os_n_file_reads, os_n_file_writes, os_n_fsyncs); - - fprintf(stderr, + "InnoDB: number of fsyncs in diagnostic info below.\n" + "InnoDB: Pending flushes (fsync) log: %lu; buffer pool: %lu\n" + "InnoDB: %lu OS file reads, %lu OS file writes, %lu OS fsyncs\n" "InnoDB: Starting InnoDB Monitor to print further\n" - "InnoDB: diagnostics to the standard output.\n"); + "InnoDB: diagnostics to the standard output.\n", + n_iterations, + fil_n_pending_log_flushes, + fil_n_pending_tablespace_flushes, + os_n_file_reads, os_n_file_writes, os_n_fsyncs); mon_value_was = srv_print_innodb_monitor; started_monitor = TRUE; @@ -797,7 +791,7 @@ buf_LRU_print(void) ut_ad(buf_pool); mutex_enter(&(buf_pool->mutex)); - printf("Pool ulint clock %lu\n", buf_pool->ulint_clock); + fprintf(stderr, "Pool ulint clock %lu\n", buf_pool->ulint_clock); block = UT_LIST_GET_FIRST(buf_pool->LRU); @@ -805,37 +799,37 @@ buf_LRU_print(void) while (block != NULL) { - printf("BLOCK %lu ", block->offset); + fprintf(stderr, "BLOCK %lu ", block->offset); if (block->old) { - printf("old "); + fputs("old ", stderr); } if (block->buf_fix_count) { - printf("buffix count %lu ", block->buf_fix_count); + fprintf(stderr, "buffix count %lu ", + block->buf_fix_count); } if (block->io_fix) { - printf("io_fix %lu ", block->io_fix); + fprintf(stderr, "io_fix %lu ", block->io_fix); } if (ut_dulint_cmp(block->oldest_modification, ut_dulint_zero) > 0) { - printf("modif. "); + fputs("modif. ", stderr); } - printf("LRU pos %lu ", block->LRU_position); - frame = buf_block_get_frame(block); - printf("type %lu ", fil_page_get_type(frame)); - printf("index id %lu ", ut_dulint_get_low( - btr_page_get_index_id(frame))); + fprintf(stderr, "LRU pos %lu type %lu index id %lu ", + block->LRU_position, + fil_page_get_type(frame), + ut_dulint_get_low(btr_page_get_index_id(frame))); block = UT_LIST_GET_NEXT(LRU, block); - len++; - if (len % 10 == 0) { - printf("\n"); + if (++len == 10) { + len = 0; + putc('\n', stderr); } } diff --git a/innobase/buf/buf0rea.c b/innobase/buf/buf0rea.c index 475a5bd9cbd..83397c9c7fa 100644 --- a/innobase/buf/buf0rea.c +++ b/innobase/buf/buf0rea.c @@ -81,7 +81,8 @@ buf_read_page_low( log mutex: the read must be handled before other reads which might incur ibuf operations and thus write to the log */ - printf("Log debug: reading replicate page in sync mode\n"); + fputs("Log debug: reading replicate page in sync mode\n", + stderr); sync = TRUE; } @@ -101,7 +102,8 @@ buf_read_page_low( if (block != NULL) { if (buf_debug_prints) { - printf("Posting read request for page %lu, sync %lu\n", + fprintf(stderr, + "Posting read request for page %lu, sync %lu\n", offset, sync); } @@ -241,8 +243,8 @@ buf_read_ahead_random( os_aio_simulated_wake_handler_threads(); if (buf_debug_prints && (count > 0)) { - - printf("Random read-ahead space %lu offset %lu pages %lu\n", + fprintf(stderr, + "Random read-ahead space %lu offset %lu pages %lu\n", space, offset, count); } @@ -499,7 +501,7 @@ buf_read_ahead_linear( buf_flush_free_margin(); if (buf_debug_prints && (count > 0)) { - printf( + fprintf(stderr, "LINEAR read-ahead space %lu offset %lu pages %lu\n", space, offset, count); } @@ -548,7 +550,8 @@ buf_read_ibuf_merge_pages( buf_flush_free_margin(); if (buf_debug_prints) { - printf("Ibuf merge read-ahead space %lu pages %lu\n", + fprintf(stderr, + "Ibuf merge read-ahead space %lu pages %lu\n", space, n_stored); } } @@ -611,6 +614,7 @@ buf_read_recv_pages( buf_flush_free_margin(); if (buf_debug_prints) { - printf("Recovery applies read-ahead pages %lu\n", n_stored); + fprintf(stderr, + "Recovery applies read-ahead pages %lu\n", n_stored); } } diff --git a/innobase/data/data0data.c b/innobase/data/data0data.c index 96c15643096..11eb295f033 100644 --- a/innobase/data/data0data.c +++ b/innobase/data/data0data.c @@ -12,7 +12,6 @@ Created 5/30/1994 Heikki Tuuri #include "data0data.ic" #endif -#include "ut0rnd.h" #include "rem0rec.h" #include "rem0cmp.h" #include "page0page.h" @@ -22,8 +21,10 @@ Created 5/30/1994 Heikki Tuuri byte data_error; /* data pointers of tuple fields are initialized to point here for error checking */ +#ifdef UNIV_DEBUG ulint data_dummy; /* this is used to fool the compiler in dtuple_validate */ +#endif /* UNIV_DEBUG */ /* Some non-inlined functions used in the MySQL interface: */ void @@ -210,16 +211,15 @@ dtuple_check_typed_no_assert( { dfield_t* field; ulint i; - char err_buf[1000]; if (dtuple_get_n_fields(tuple) > REC_MAX_N_FIELDS) { fprintf(stderr, "InnoDB: Error: index entry has %lu fields\n", dtuple_get_n_fields(tuple)); - - dtuple_sprintf(err_buf, 900, tuple); - fprintf(stderr, -"InnoDB: Tuple contents: %s\n", err_buf); + dump: + fputs("InnoDB: Tuple contents: ", stderr); + dtuple_print(stderr, tuple); + putc('\n', stderr); return(FALSE); } @@ -229,12 +229,7 @@ dtuple_check_typed_no_assert( field = dtuple_get_nth_field(tuple, i); if (!dfield_check_typed_no_assert(field)) { - - dtuple_sprintf(err_buf, 900, tuple); - fprintf(stderr, -"InnoDB: Tuple contents: %s\n", err_buf); - - return(FALSE); + goto dump; } } @@ -285,6 +280,7 @@ dtuple_check_typed( return(TRUE); } +#ifdef UNIV_DEBUG /************************************************************** Validates the consistency of a tuple which must be complete, i.e, all fields must have been set. */ @@ -332,6 +328,7 @@ dtuple_validate( return(TRUE); } +#endif /* UNIV_DEBUG */ /***************************************************************** Pretty prints a dfield value according to its data type. */ @@ -350,7 +347,7 @@ dfield_print( data = dfield_get_data(dfield); if (len == UNIV_SQL_NULL) { - printf("NULL"); + fputs("NULL", stderr); return; } @@ -360,18 +357,12 @@ dfield_print( if ((mtype == DATA_CHAR) || (mtype == DATA_VARCHAR)) { for (i = 0; i < len; i++) { - - if (isprint((char)(*data))) { - printf("%c", (char)*data); - } else { - printf(" "); - } - - data++; + int c = *data++; + putc(isprint(c) ? c : ' ', stderr); } } else if (mtype == DATA_INT) { ut_a(len == 4); /* only works for 32-bit integers */ - printf("%i", (int)mach_read_from_4(data)); + fprintf(stderr, "%d", (int)mach_read_from_4(data)); } else { ut_error; } @@ -396,7 +387,7 @@ dfield_print_also_hex( data = dfield_get_data(dfield); if (len == UNIV_SQL_NULL) { - printf("NULL"); + fputs("NULL", stderr); return; } @@ -408,15 +399,12 @@ dfield_print_also_hex( print_also_hex = FALSE; for (i = 0; i < len; i++) { - - if (isprint((char)(*data))) { - printf("%c", (char)*data); - } else { + int c = *data++; + if (!isprint(c)) { print_also_hex = TRUE; - printf(" "); + c = ' '; } - - data++; + putc(c, stderr); } if (!print_also_hex) { @@ -424,18 +412,18 @@ dfield_print_also_hex( return; } - printf(" Hex: "); + fputs(" Hex: ", stderr); data = dfield_get_data(dfield); for (i = 0; i < len; i++) { - printf("%02lx", (ulint)*data); + fprintf(stderr, "%02lx", (ulint)*data); data++; } } else if (mtype == DATA_INT) { - ut_a(len == 4); /* inly works for 32-bit integers */ - printf("%i", (int)mach_read_from_4(data)); + ut_a(len == 4); /* only works for 32-bit integers */ + fprintf(stderr, "%d", (int)mach_read_from_4(data)); } else { ut_error; } @@ -447,6 +435,7 @@ The following function prints the contents of a tuple. */ void dtuple_print( /*=========*/ + FILE* f, /* in: output stream */ dtuple_t* tuple) /* in: tuple */ { dfield_t* field; @@ -455,73 +444,24 @@ dtuple_print( n_fields = dtuple_get_n_fields(tuple); - printf("DATA TUPLE: %lu fields;\n", n_fields); + fprintf(f, "DATA TUPLE: %lu fields;\n", n_fields); for (i = 0; i < n_fields; i++) { - printf(" %lu:", i); + fprintf(f, " %lu:", i); field = dtuple_get_nth_field(tuple, i); if (field->len != UNIV_SQL_NULL) { - ut_print_buf(field->data, field->len); + ut_print_buf(f, field->data, field->len); } else { - printf(" SQL NULL"); + fputs(" SQL NULL", f); } - printf(";"); + putc(';', f); } - printf("\n"); - - dtuple_validate(tuple); -} - -/************************************************************** -The following function prints the contents of a tuple to a buffer. */ - -ulint -dtuple_sprintf( -/*===========*/ - /* out: printed length in bytes */ - char* buf, /* in: print buffer */ - ulint buf_len,/* in: buf length in bytes */ - dtuple_t* tuple) /* in: tuple */ -{ - dfield_t* field; - ulint n_fields; - ulint len; - ulint i; - - len = 0; - - n_fields = dtuple_get_n_fields(tuple); - - for (i = 0; i < n_fields; i++) { - if (len + 30 > buf_len) { - - return(len); - } - - len += sprintf(buf + len, " %lu:", i); - - field = dtuple_get_nth_field(tuple, i); - - if (field->len != UNIV_SQL_NULL) { - if (5 * field->len + len + 30 > buf_len) { - - return(len); - } - - len += ut_sprintf_buf(buf + len, field->data, - field->len); - } else { - len += sprintf(buf + len, " SQL NULL"); - } - - len += sprintf(buf + len, ";"); - } - - return(len); + putc('\n', f); + ut_ad(dtuple_validate(tuple)); } /****************************************************************** @@ -555,7 +495,6 @@ dtuple_convert_big_rec( ibool is_externally_stored; ulint i; ulint j; - char err_buf[1000]; ut_a(dtuple_check_typed_no_assert(entry)); @@ -564,10 +503,9 @@ dtuple_convert_big_rec( if (size > 1000000000) { fprintf(stderr, "InnoDB: Warning: tuple size very big: %lu\n", size); - - dtuple_sprintf(err_buf, 900, entry); - fprintf(stderr, -"InnoDB: Tuple contents: %s\n", err_buf); + fputs("InnoDB: Tuple contents: ", stderr); + dtuple_print(stderr, entry); + putc('\n', stderr); } heap = mem_heap_create(size + dtuple_get_n_fields(entry) diff --git a/innobase/data/data0type.c b/innobase/data/data0type.c index df430f06bcb..077012553ba 100644 --- a/innobase/data/data0type.c +++ b/innobase/data/data0type.c @@ -51,19 +51,19 @@ dtype_print( mtype = type->mtype; prtype = type->prtype; if (mtype == DATA_VARCHAR) { - printf("DATA_VARCHAR"); + fputs("DATA_VARCHAR", stderr); } else if (mtype == DATA_CHAR) { - printf("DATA_CHAR"); + fputs("DATA_CHAR", stderr); } else if (mtype == DATA_BINARY) { - printf("DATA_BINARY"); + fputs("DATA_BINARY", stderr); } else if (mtype == DATA_INT) { - printf("DATA_INT"); + fputs("DATA_INT", stderr); } else if (mtype == DATA_MYSQL) { - printf("DATA_MYSQL"); + fputs("DATA_MYSQL", stderr); } else if (mtype == DATA_SYS) { - printf("DATA_SYS"); + fputs("DATA_SYS", stderr); } else { - printf("type %lu", mtype); + fprintf(stderr, "type %lu", mtype); } len = type->len; @@ -71,24 +71,24 @@ dtype_print( if ((type->mtype == DATA_SYS) || (type->mtype == DATA_VARCHAR) || (type->mtype == DATA_CHAR)) { - printf(" "); + putc(' ', stderr); if (prtype == DATA_ROW_ID) { - printf("DATA_ROW_ID"); + fputs("DATA_ROW_ID", stderr); len = DATA_ROW_ID_LEN; } else if (prtype == DATA_ROLL_PTR) { - printf("DATA_ROLL_PTR"); + fputs("DATA_ROLL_PTR", stderr); len = DATA_ROLL_PTR_LEN; } else if (prtype == DATA_TRX_ID) { - printf("DATA_TRX_ID"); + fputs("DATA_TRX_ID", stderr); len = DATA_TRX_ID_LEN; } else if (prtype == DATA_MIX_ID) { - printf("DATA_MIX_ID"); + fputs("DATA_MIX_ID", stderr); } else if (prtype == DATA_ENGLISH) { - printf("DATA_ENGLISH"); + fputs("DATA_ENGLISH", stderr); } else { - printf("prtype %lu", mtype); + fprintf(stderr, "prtype %lu", mtype); } } - printf(" len %lu prec %lu", len, type->prec); + fprintf(stderr, " len %lu prec %lu", len, type->prec); } diff --git a/innobase/dict/dict0boot.c b/innobase/dict/dict0boot.c index 3abb71a842d..1cae2750fbe 100644 --- a/innobase/dict/dict0boot.c +++ b/innobase/dict/dict0boot.c @@ -71,7 +71,8 @@ dict_hdr_get_new_id( compile wrong */ if (0 == ut_dulint_cmp(id, ut_dulint_max)) { - printf("Max id\n"); + /* TO DO: remove this code, or make it conditional */ + ut_dbg_null_ptr = 0; } id = ut_dulint_add(id, 1); diff --git a/innobase/dict/dict0crea.c b/innobase/dict/dict0crea.c index 87cdd4f5302..6ebefc98a24 100644 --- a/innobase/dict/dict0crea.c +++ b/innobase/dict/dict0crea.c @@ -25,11 +25,6 @@ Created 1/8/1996 Heikki Tuuri #include "trx0roll.h" #include "usr0sess.h" -/* Maximum lengths of identifiers in MySQL, in bytes */ -#define MAX_TABLE_NAME_LEN 64 -#define MAX_COLUMN_NAME_LEN 64 -#define MAX_IDENTIFIER_LEN 255 - /********************************************************************* Based on a table object, this function builds the entry to be inserted in the SYS_TABLES system table. */ @@ -1105,7 +1100,7 @@ dict_create_add_foreigns_to_dictionary( ulint number = start_id + 1; ulint len; ulint error; - char* ebuf = dict_foreign_err_buf; + FILE* ef = dict_foreign_err_file; ulint i; char* sql; char* sqlend; @@ -1223,14 +1218,17 @@ loop: if (error == DB_DUPLICATE_KEY) { mutex_enter(&dict_foreign_err_mutex); - ut_sprintf_timestamp(ebuf); - ut_a(strlen(ebuf) < DICT_FOREIGN_ERR_BUF_LEN - - MAX_TABLE_NAME_LEN - MAX_IDENTIFIER_LEN - 201); - sprintf(ebuf + strlen(ebuf), -" Error in foreign key constraint creation for table %s.\n" -"A foreign key constraint of name %s\n" -"already exists (note that internally InnoDB adds 'databasename/'\n" -"in front of the user-defined constraint name).\n", table->name, foreign->id); + rewind(ef); + ut_print_timestamp(ef); + fputs(" Error in foreign key constraint creation for table ", + ef); + ut_print_name(ef, table->name); + fputs(".\nA foreign key constraint of name ", ef); + ut_print_name(ef, foreign->id); + fputs("\nalready exists." + " (Note that internally InnoDB adds 'databasename/'\n" + "in front of the user-defined constraint name).\n", + ef); mutex_exit(&dict_foreign_err_mutex); @@ -1243,12 +1241,12 @@ loop: "InnoDB: internal error number %lu\n", error); mutex_enter(&dict_foreign_err_mutex); - ut_sprintf_timestamp(ebuf); - ut_a(strlen(ebuf) < DICT_FOREIGN_ERR_BUF_LEN - - MAX_TABLE_NAME_LEN - 124); - sprintf(ebuf + strlen(ebuf), -" Internal error in foreign key constraint creation for table %s.\n" -"See the MySQL .err log in the datadir for more information.\n", table->name); + ut_print_timestamp(ef); + fputs(" Internal error in foreign key constraint creation" + " for table ", ef); + ut_print_name(ef, table->name); + fputs(".\n" + "See the MySQL .err log in the datadir for more information.\n", ef); mutex_exit(&dict_foreign_err_mutex); return(error); diff --git a/innobase/dict/dict0dict.c b/innobase/dict/dict0dict.c index c0810ad45dc..d895f00b249 100644 --- a/innobase/dict/dict0dict.c +++ b/innobase/dict/dict0dict.c @@ -132,7 +132,7 @@ dict_index_build_internal_non_clust( dict_index_t* index); /* in: user representation of a non-clustered index */ /************************************************************************** -Removes a foreign constraint struct from the dictionary cache. */ +Removes a foreign constraint struct from the dictionet cache. */ static void dict_foreign_remove_from_cache( @@ -167,10 +167,9 @@ dict_foreign_free( /*==============*/ dict_foreign_t* foreign); /* in, own: foreign key struct */ -/* Buffers for storing detailed information about the latest foreign key +/* Stream for storing detailed information about the latest foreign key and unique key errors */ -char* dict_foreign_err_buf = NULL; -char* dict_unique_err_buf = NULL; +FILE* dict_foreign_err_file = NULL; mutex_t dict_foreign_err_mutex; /* mutex protecting the foreign and unique error buffers */ @@ -643,10 +642,7 @@ dict_init(void) rw_lock_create(&dict_operation_lock); rw_lock_set_level(&dict_operation_lock, SYNC_DICT_OPERATION); - dict_foreign_err_buf = mem_alloc(DICT_FOREIGN_ERR_BUF_LEN); - dict_foreign_err_buf[0] = '\0'; - dict_unique_err_buf = mem_alloc(DICT_FOREIGN_ERR_BUF_LEN); - dict_unique_err_buf[0] = '\0'; + dict_foreign_err_file = tmpfile(); mutex_create(&dict_foreign_err_mutex); mutex_set_level(&dict_foreign_err_mutex, SYNC_ANY_LATCH); } @@ -1064,7 +1060,11 @@ dict_table_remove_from_cache( #endif /* UNIV_SYNC_DEBUG */ ut_ad(table->magic_n == DICT_TABLE_MAGIC_N); - /* printf("Removing table %s from dictionary cache\n", table->name); */ +#if 0 + fputs("Removing table ", stderr); + ut_print_name(stderr, table->name, ULINT_UNDEFINED); + fputs(" from dictionary cache\n", stderr); +#endif /* Remove the foreign constraints from the cache */ foreign = UT_LIST_GET_LAST(table->foreign_list); @@ -1986,6 +1986,45 @@ dict_foreign_find_index( return(NULL); } +/************************************************************************** +Report an error in a foreign key definition. */ +static +void +dict_foreign_error_report_low( + FILE* file, /* in: output stream */ + const char* name) /* in: table name */ +{ + rewind(file); + ut_print_timestamp(file); + fputs(" Error in foreign key constraint of table ", file); + ut_print_name(file, name); + fputs(":\n", file); +} + +/************************************************************************** +Report an error in a foreign key definition. */ +static +void +dict_foreign_error_report( + FILE* file, /* in: output stream */ + dict_foreign_t* fk, /* in: foreign key constraint */ + const char* msg) /* in: the error message */ +{ + mutex_enter(&dict_foreign_err_mutex); + dict_foreign_error_report_low(file, fk->foreign_table_name); + fputs(msg, file); + fputs(" Constraint:\n", file); + dict_print_info_on_foreign_key_in_create_format(file, fk); + if (fk->foreign_index) { + fputs("\nThe index in the foreign key in table is ", file); + ut_print_name(file, fk->foreign_index->name); + fputs( +"See http://www.innodb.com/ibman.php for correct foreign key definition.\n", + file); + } + mutex_exit(&dict_foreign_err_mutex); +} + /************************************************************************** Adds a foreign key constraint object to the dictionary cache. May free the object if there already is an object with the same identifier in. @@ -2000,10 +2039,10 @@ dict_foreign_add_to_cache( { dict_table_t* for_table; dict_table_t* ref_table; - dict_foreign_t* for_in_cache = NULL; + dict_foreign_t* for_in_cache = NULL; dict_index_t* index; - ibool added_to_referenced_list = FALSE; - char* buf = dict_foreign_err_buf; + ibool added_to_referenced_list= FALSE; + FILE* ef = dict_foreign_err_file; #ifdef UNIV_SYNC_DEBUG ut_ad(mutex_own(&(dict_sys->mutex))); @@ -2038,25 +2077,11 @@ dict_foreign_add_to_cache( for_in_cache->foreign_index); if (index == NULL) { - mutex_enter(&dict_foreign_err_mutex); - ut_sprintf_timestamp(buf); - sprintf(buf + strlen(buf), -" Error in foreign key constraint of table %.500s:\n" + 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. Constraint:\n", - for_in_cache->foreign_table_name); - dict_print_info_on_foreign_key_in_create_format( - for_in_cache, buf + strlen(buf)); - if (for_in_cache->foreign_index) { - sprintf(buf + strlen(buf), -"\nThe index in the foreign key in table is %.500s\n" -"See http://www.innodb.com/ibman.html about correct foreign key definition.\n", - for_in_cache->foreign_index->name); - } - ut_a(strlen(buf) < DICT_FOREIGN_ERR_BUF_LEN); - mutex_exit(&dict_foreign_err_mutex); - +"referenced table do not match to the ones in table."); + if (for_in_cache == foreign) { mem_heap_free(foreign->heap); } @@ -2079,24 +2104,10 @@ dict_foreign_add_to_cache( for_in_cache->referenced_index); if (index == NULL) { - mutex_enter(&dict_foreign_err_mutex); - ut_sprintf_timestamp(buf); - sprintf(buf + strlen(buf), -" Error in foreign key constraint of table %.500s:\n" + 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. Constraint:\n", - for_in_cache->foreign_table_name); - dict_print_info_on_foreign_key_in_create_format( - for_in_cache, buf + strlen(buf)); - if (for_in_cache->foreign_index) { - sprintf(buf + strlen(buf), -"\nIndex of the foreign key in the referenced table is %.500s\n" -"See http://www.innodb.com/ibman.html about correct foreign key definition.\n", - for_in_cache->referenced_index->name); - } - ut_a(strlen(buf) < DICT_FOREIGN_ERR_BUF_LEN); - mutex_exit(&dict_foreign_err_mutex); +"table do not match to the ones in the referenced table."); if (for_in_cache == foreign) { if (added_to_referenced_list) { @@ -2600,17 +2611,12 @@ dict_foreign_report_syntax_err( in the SQL string */ const char* ptr) /* in: place of the syntax error */ { - char* buf = dict_foreign_err_buf; + FILE* ef = dict_foreign_err_file; mutex_enter(&dict_foreign_err_mutex); - - ut_sprintf_timestamp(buf); - - sprintf(buf + strlen(buf), -" Error in foreign key constraint of table %.500s,\n%.500s.\n" -"Syntax error close to:\n%.500s\n", name, start_of_latest_foreign, ptr); - - ut_a(strlen(buf) < DICT_FOREIGN_ERR_BUF_LEN); + dict_foreign_error_report_low(ef, name); + fprintf(ef, "%s:\nSyntax error close to:\n%s\n", + start_of_latest_foreign, ptr); mutex_exit(&dict_foreign_err_mutex); } @@ -2643,9 +2649,9 @@ 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; - char* buf = dict_foreign_err_buf; + FILE* ef = dict_foreign_err_file; const char* constraint_name; ibool success; ulint error; @@ -2668,12 +2674,10 @@ dict_create_foreign_constraints_low( if (table == NULL) { mutex_enter(&dict_foreign_err_mutex); - ut_sprintf_timestamp(buf); - sprintf(buf + strlen(buf), -" Error in foreign key constraint of table %.500s.\n" -"Cannot find the table from the internal data dictionary of InnoDB.\n" -"Create table statement:\n%.2000s\n", name, sql_string); - ut_a(strlen(buf) < DICT_FOREIGN_ERR_BUF_LEN); + 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); mutex_exit(&dict_foreign_err_mutex); return(DB_ERROR); @@ -2682,23 +2686,21 @@ 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, (char*) "ALTER", &success); + ptr = dict_accept(ptr, "ALTER", &success); if (!success) { goto loop; } - ptr = dict_accept(ptr, (char*) "TABLE", &success); + ptr = dict_accept(ptr, "TABLE", &success); if (!success) { goto loop; } - /* We are doing an ALTER TABLE: scan the table name we are altering; - in the call below we use the buffer 'referenced_table_name' as a dummy - buffer */ + /* 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); @@ -2817,12 +2819,9 @@ col_loop1: heap, column_names + i); if (!success) { mutex_enter(&dict_foreign_err_mutex); - ut_sprintf_timestamp(buf); - sprintf(buf + strlen(buf), -" Error in foreign key constraint of table %.500s,\n%.500s.\n" -"Cannot resolve column name close to:\n%.500s\n", name, + dict_foreign_error_report_low(ef, name); + fprintf(ef, "%s:\nCannot resolve column name close to:\n%s\n", start_of_latest_foreign, ptr); - ut_a(strlen(buf) < DICT_FOREIGN_ERR_BUF_LEN); mutex_exit(&dict_foreign_err_mutex); return(DB_CANNOT_ADD_CONSTRAINT); @@ -2851,19 +2850,18 @@ col_loop1: if (!index) { mutex_enter(&dict_foreign_err_mutex); - ut_sprintf_timestamp(buf); - sprintf(buf + strlen(buf), -" Error in foreign key constraint of table %.500s:\n" -"There is no index in the table %.500s where the columns appear\n" -"as the first columns. Constraint:\n%.500s\n" -"See http://www.innodb.com/ibman.html for correct foreign key definition.\n", - name, name, start_of_latest_foreign); - ut_a(strlen(buf) < DICT_FOREIGN_ERR_BUF_LEN); + dict_foreign_error_report_low(ef, name); + fputs("There is no index in table ", ef); + ut_print_name(ef, name); + fprintf(ef, " where the columns appear\n" +"as the first columns. Constraint:\n%s\n" +"See http://www.innodb.com/ibman.php 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, (char *) "REFERENCES", &success); + ptr = dict_accept(ptr, "REFERENCES", &success); if (!success || !isspace(*ptr)) { dict_foreign_report_syntax_err(name, start_of_latest_foreign, @@ -2914,18 +2912,16 @@ col_loop1: dict_foreign_free(foreign); mutex_enter(&dict_foreign_err_mutex); - ut_sprintf_timestamp(buf); - sprintf(buf + strlen(buf), -" Error in foreign key constraint of table %.500s,\n%.500s.\n" -"Cannot resolve table name close to:\n" -"%.500s\n", name, start_of_latest_foreign, ptr); - ut_a(strlen(buf) < DICT_FOREIGN_ERR_BUF_LEN); + dict_foreign_error_report_low(ef, name); + fprintf(ef, "%s:\nCannot resolve table name close to:\n" + "%s\n", + start_of_latest_foreign, ptr); mutex_exit(&dict_foreign_err_mutex); return(DB_CANNOT_ADD_CONSTRAINT); } - ptr = dict_accept(ptr, (char *) "(", &success); + ptr = dict_accept(ptr, "(", &success); if (!success) { dict_foreign_free(foreign); @@ -2946,24 +2942,22 @@ col_loop2: dict_foreign_free(foreign); mutex_enter(&dict_foreign_err_mutex); - ut_sprintf_timestamp(buf); - sprintf(buf + strlen(buf), -" Error in foreign key constraint of table %.500s,\n%.500s\n" -"Cannot resolve column name close to:\n" -"%.500s\n", name, start_of_latest_foreign, ptr); - ut_a(strlen(buf) < DICT_FOREIGN_ERR_BUF_LEN); + dict_foreign_error_report_low(ef, name); + fprintf(ef, "%s:\nCannot resolve column name close to:\n" + "%s\n", + start_of_latest_foreign, ptr); mutex_exit(&dict_foreign_err_mutex); return(DB_CANNOT_ADD_CONSTRAINT); } - ptr = dict_accept(ptr, (char *) ",", &success); + ptr = dict_accept(ptr, ",", &success); if (success) { goto col_loop2; } - ptr = dict_accept(ptr, (char *) ")", &success); + ptr = dict_accept(ptr, ")", &success); if (!success || foreign->n_fields != i) { dict_foreign_free(foreign); @@ -3075,12 +3069,10 @@ scan_on_conditions: dict_foreign_free(foreign); mutex_enter(&dict_foreign_err_mutex); - ut_sprintf_timestamp(buf); - sprintf(buf + strlen(buf), -" Error in foreign key constraint of table %.500s,\n%.500s.\n" -"You have defined a SET NULL condition though some of the\n" -"columns is defined as NOT NULL.\n", name, start_of_latest_foreign); - ut_a(strlen(buf) < DICT_FOREIGN_ERR_BUF_LEN); + 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); mutex_exit(&dict_foreign_err_mutex); return(DB_CANNOT_ADD_CONSTRAINT); @@ -3102,12 +3094,10 @@ try_find_index: dict_foreign_free(foreign); mutex_enter(&dict_foreign_err_mutex); - ut_sprintf_timestamp(buf); - sprintf(buf + strlen(buf), -" Error in foreign key constraint of table %.500s,\n%.500s.\n" + 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", - name, start_of_latest_foreign); - ut_a(strlen(buf) < DICT_FOREIGN_ERR_BUF_LEN); + start_of_latest_foreign); mutex_exit(&dict_foreign_err_mutex); return(DB_CANNOT_ADD_CONSTRAINT); @@ -3124,15 +3114,13 @@ try_find_index: if (!index) { dict_foreign_free(foreign); mutex_enter(&dict_foreign_err_mutex); - ut_sprintf_timestamp(buf); - sprintf(buf + strlen(buf), -" Error in foreign key constraint of table %.500s:\n" + 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%.500s\n" -"See http://www.innodb.com/ibman.html for correct foreign key definition.\n", - name, start_of_latest_foreign); - ut_a(strlen(buf) < DICT_FOREIGN_ERR_BUF_LEN); +"in the table and the referenced table do not match for constraint.\n" +"See http://www.innodb.com/ibman.php for correct foreign key definition.\n", + start_of_latest_foreign); mutex_exit(&dict_foreign_err_mutex); return(DB_CANNOT_ADD_CONSTRAINT); @@ -3227,8 +3215,8 @@ dict_foreign_parse_drop_constraints( ibool success; char* str; const char* ptr; - char* buf = dict_foreign_err_buf; const char* id; + FILE* ef = dict_foreign_err_file; *n = 0; @@ -3299,12 +3287,17 @@ loop: if (foreign == NULL) { mutex_enter(&dict_foreign_err_mutex); - ut_sprintf_timestamp(buf); - sprintf(buf + strlen(buf), -" Error in dropping of a foreign key constraint of table %.500s,\n" -"in SQL command\n%s\nCannot find a constraint with the\n" -"given id %s.\n", table->name, str, id); - ut_a(strlen(buf) < DICT_FOREIGN_ERR_BUF_LEN); + rewind(ef); + ut_print_timestamp(ef); + fputs( + " Error in dropping of a foreign key constraint of table ", ef); + ut_print_name(ef, table->name); + fputs(",\n" + "in SQL command\n", ef); + fputs(str, ef); + fputs("\nCannot find a constraint with the given id ", ef); + ut_print_name(ef, id); + fputs(".\n", ef); mutex_exit(&dict_foreign_err_mutex); mem_free(str); @@ -3316,11 +3309,13 @@ loop: syntax_error: mutex_enter(&dict_foreign_err_mutex); - ut_sprintf_timestamp(buf); - sprintf(buf + strlen(buf), -" Syntax error in dropping of a foreign key constraint of table %.500s,\n" -"close to:\n%s\n in SQL command\n%s\n", table->name, ptr, str); - ut_a(strlen(buf) < DICT_FOREIGN_ERR_BUF_LEN); + rewind(ef); + ut_print_timestamp(ef); + fputs( + " Syntax error in dropping of a foreign key constraint of table ", ef); + ut_print_name(ef, table->name); + fprintf(ef, ",\n" + "close to:\n%s\n in SQL command\n%s\n", ptr, str); mutex_exit(&dict_foreign_err_mutex); mem_free(str); @@ -3800,22 +3795,28 @@ dict_foreign_print_low( ut_ad(mutex_own(&(dict_sys->mutex))); #endif /* UNIV_SYNC_DEBUG */ - printf(" FOREIGN KEY CONSTRAINT %s: %s (", foreign->id, - foreign->foreign_table_name); - + fputs(" FOREIGN KEY CONSTRAINT ", stderr); + ut_print_name(stderr, foreign->id); + fputs(": ", stderr); + ut_print_name(stderr, foreign->foreign_table_name); + fputs(" (", stderr); + for (i = 0; i < foreign->n_fields; i++) { - printf(" %s", foreign->foreign_col_names[i]); + putc(' ', stderr); + ut_print_name(stderr, foreign->foreign_col_names[i]); } - printf(" )\n"); - - printf(" REFERENCES %s (", foreign->referenced_table_name); + fputs(" )\n" + " REFERENCES ", stderr); + ut_print_name(stderr, foreign->referenced_table_name); + fputs(" (", stderr); for (i = 0; i < foreign->n_fields; i++) { - printf(" %s", foreign->referenced_col_names[i]); + putc(' ', stderr); + ut_print_name(stderr, foreign->referenced_col_names[i]); } - printf(" )\n"); + fputs(" )\n", stderr); } /************************************************************************** @@ -3869,22 +3870,23 @@ dict_table_print_low( dict_update_statistics_low(table, TRUE); - printf("--------------------------------------\n"); - printf( - "TABLE: name %s, id %lu %lu, columns %lu, indexes %lu, appr.rows %lu\n", - table->name, + fputs("--------------------------------------\n" + "TABLE: name ", stderr); + ut_print_name(stderr, table->name); + fprintf(stderr, + ", id %lu %lu, columns %lu, indexes %lu, appr.rows %lu\n" + " COLUMNS: ", ut_dulint_get_high(table->id), ut_dulint_get_low(table->id), table->n_cols, UT_LIST_GET_LEN(table->indexes), (ulint)table->stat_n_rows); - printf(" COLUMNS: "); for (i = 0; i < table->n_cols - 1; i++) { dict_col_print_low(dict_table_get_nth_col(table, i)); - printf("; "); + fputs("; ", stderr); } - printf("\n"); + putc('\n', stderr); index = UT_LIST_GET_FIRST(table->indexes); @@ -3923,7 +3925,8 @@ dict_col_print_low( #endif /* UNIV_SYNC_DEBUG */ type = dict_col_get_type(col); - printf("%s: ", col->name); + ut_print_name(stderr, col->name); + fputs(": ", stderr); dtype_print(type); } @@ -3953,27 +3956,27 @@ dict_index_print_low( n_vals = index->stat_n_diff_key_vals[1]; } - printf( - " INDEX: name %s, table name %s, id %lu %lu, fields %lu/%lu, type %lu\n", - index->name, index->table_name, - ut_dulint_get_high(tree->id), - ut_dulint_get_low(tree->id), - index->n_user_defined_cols, - index->n_fields, index->type); - printf( - " root page %lu, appr.key vals %lu, leaf pages %lu, size pages %lu\n", + fputs(" INDEX: ", stderr); + dict_index_name_print(stderr, index); + fprintf(stderr, + ", id %lu %lu, fields %lu/%lu, type %lu\n" + " root page %lu, appr.key vals %lu," + " leaf pages %lu, size pages %lu\n" + " FIELDS: ", + ut_dulint_get_high(tree->id), + ut_dulint_get_low(tree->id), + index->n_user_defined_cols, + index->n_fields, index->type, tree->page, (ulint)n_vals, index->stat_n_leaf_pages, index->stat_index_size); - printf(" FIELDS: "); - for (i = 0; i < index->n_fields; i++) { dict_field_print_low(dict_index_get_nth_field(index, i)); } - printf("\n"); + putc('\n', stderr); /* btr_print_size(tree); */ @@ -3991,28 +3994,25 @@ dict_field_print_low( #ifdef UNIV_SYNC_DEBUG ut_ad(mutex_own(&(dict_sys->mutex))); #endif /* UNIV_SYNC_DEBUG */ - - printf(" %s", field->name); + putc(' ', stderr); + ut_print_name(stderr, field->name); if (field->prefix_len != 0) { - printf("(%lu)", field->prefix_len); + fprintf(stderr, "(%lu)", field->prefix_len); } } /************************************************************************** -Sprintfs to a string info on a foreign key of a table in a format suitable -for CREATE TABLE. */ +Outputs info on a foreign key of a table in a format suitable for +CREATE TABLE. */ -char* +void dict_print_info_on_foreign_key_in_create_format( /*============================================*/ - /* out: how far in buf we printed */ - dict_foreign_t* foreign,/* in: foreign key constraint */ - char* buf) /* in: buffer of at least 5000 bytes */ + FILE* file, /* in: file where to print */ + dict_foreign_t* foreign)/* in: foreign key constraint */ { - char* buf2 = buf; - char* stripped_id; - ulint cpy_len; + const char* stripped_id; ulint i; if (strchr(foreign->id, '/')) { @@ -4023,140 +4023,80 @@ dict_print_info_on_foreign_key_in_create_format( stripped_id = foreign->id; } - buf2 += sprintf(buf2, ",\n CONSTRAINT `%s` FOREIGN KEY (", - stripped_id); - for (i = 0; i < foreign->n_fields; i++) { - if ((ulint)(buf2 - buf) >= 4000) { + fputs(",\n CONSTRAINT ", file); + ut_print_name(file, stripped_id); + fputs(" FOREIGN KEY (", file); - goto no_space; - } - buf2 += sprintf(buf2, "`%.250s`", - foreign->foreign_col_names[i]); - - if (i + 1 < foreign->n_fields) { - buf2 += sprintf(buf2, ", "); + for (i = 0;;) { + ut_print_name(file, foreign->foreign_col_names[i]); + if (++i < foreign->n_fields) { + fputs(", ", file); + } else { + break; } } + fputs(") REFERENCES ", file); + if (dict_tables_have_same_db(foreign->foreign_table_name, foreign->referenced_table_name)) { /* Do not print the database name of the referenced table */ - buf2 += sprintf(buf2, ") REFERENCES `%.500s` (", - dict_remove_db_name( + ut_print_name(file, dict_remove_db_name( foreign->referenced_table_name)); } else { - buf2 += sprintf(buf2, ") REFERENCES `"); - /* Look for the '/' in the table name */ i = 0; while (foreign->referenced_table_name[i] != '/') { i++; } - - cpy_len = i; - if (cpy_len > 500) { - cpy_len = 500; - } - - memcpy(buf2, foreign->referenced_table_name, cpy_len); - buf2 += cpy_len; - - buf2 += sprintf(buf2, "`.`%.500s` (", - foreign->referenced_table_name + i + 1); + ut_print_namel(file, foreign->referenced_table_name, i); + putc('.', file); + ut_print_name(file, foreign->referenced_table_name + i + 1); } - - for (i = 0; i < foreign->n_fields; i++) { - if ((ulint)(buf2 - buf) >= 4000) { - goto no_space; - } - buf2 += sprintf(buf2, "`%.250s`", - foreign->referenced_col_names[i]); - if (i + 1 < foreign->n_fields) { - buf2 += sprintf(buf2, ", "); + putc(' ', file); + putc('(', file); + + for (i = 0;;) { + ut_print_name(file, foreign->referenced_col_names[i]); + if (++i < foreign->n_fields) { + fputs(", ", file); + } else { + break; } } - buf2 += sprintf(buf2, ")"); + putc(')', file); if (foreign->type & DICT_FOREIGN_ON_DELETE_CASCADE) { - buf2 += sprintf(buf2, " ON DELETE CASCADE"); + fputs(" ON DELETE CASCADE", file); } if (foreign->type & DICT_FOREIGN_ON_DELETE_SET_NULL) { - buf2 += sprintf(buf2, " ON DELETE SET NULL"); + fputs(" ON DELETE SET NULL", file); } if (foreign->type & DICT_FOREIGN_ON_DELETE_NO_ACTION) { - buf2 += sprintf(buf2, " ON DELETE NO ACTION"); + fputs(" ON DELETE NO ACTION", file); } if (foreign->type & DICT_FOREIGN_ON_UPDATE_CASCADE) { - buf2 += sprintf(buf2, " ON UPDATE CASCADE"); + fputs(" ON UPDATE CASCADE", file); } if (foreign->type & DICT_FOREIGN_ON_UPDATE_SET_NULL) { - buf2 += sprintf(buf2, " ON UPDATE SET NULL"); + fputs(" ON UPDATE SET NULL", file); } if (foreign->type & DICT_FOREIGN_ON_UPDATE_NO_ACTION) { - buf2 += sprintf(buf2, " ON UPDATE NO ACTION"); + fputs(" ON UPDATE NO ACTION", file); } - -no_space: - return(buf2); } /************************************************************************** -Sprintfs to a string info on foreign keys of a table in a format suitable -for CREATE TABLE. */ -static -void -dict_print_info_on_foreign_keys_in_create_format( -/*=============================================*/ - char* buf, /* in: auxiliary buffer */ - char* str, /* in/out: pointer to a string */ - ulint len, /* in: buf has to be a buffer of at least - len + 5000 bytes; str must have at least - len + 1 bytes */ - dict_table_t* table) /* in: table */ -{ - dict_foreign_t* foreign; - char* buf2; - - buf2 = buf; - - mutex_enter(&(dict_sys->mutex)); - - foreign = UT_LIST_GET_FIRST(table->foreign_list); - - if (foreign == NULL) { - mutex_exit(&(dict_sys->mutex)); - - return; - } - - while (foreign != NULL) { - if ((ulint)(buf2 - buf) >= len) { - goto no_space; - } - - buf2 = dict_print_info_on_foreign_key_in_create_format( - foreign, buf2); - - foreign = UT_LIST_GET_NEXT(foreign_list, foreign); - } -no_space: - mutex_exit(&(dict_sys->mutex)); - - buf[len - 1] = '\0'; - ut_memcpy(str, buf, len); -} - -/************************************************************************** -Sprintfs to a string info on foreign keys of a table. */ +Outputs info on foreign keys of a table. */ void dict_print_info_on_foreign_keys( @@ -4165,23 +4105,10 @@ dict_print_info_on_foreign_keys( a format suitable to be inserted into a CREATE TABLE, otherwise in the format of SHOW TABLE STATUS */ - char* str, /* in/out: pointer to a string */ - ulint len, /* in: space in str available for info */ + FILE* file, /* in: file where to print */ dict_table_t* table) /* in: table */ { dict_foreign_t* foreign; - ulint i; - char* buf2; - char* buf; - - buf = mem_alloc(len + 5000); - - if (create_table_format) { - dict_print_info_on_foreign_keys_in_create_format( - buf, str, len, table); - mem_free(buf); - return; - } mutex_enter(&(dict_sys->mutex)); @@ -4190,76 +4117,81 @@ dict_print_info_on_foreign_keys( if (foreign == NULL) { mutex_exit(&(dict_sys->mutex)); - mem_free(buf); return; } - buf2 = buf; - while (foreign != NULL) { + if (create_table_format) { + dict_print_info_on_foreign_key_in_create_format( + file, foreign); + } else { + ulint i; + fputs("; (", file); - buf2 += sprintf(buf2, "; ("); + for (i = 0; i < foreign->n_fields; i++) { + if (i) { + putc(' ', file); + } - for (i = 0; i < foreign->n_fields; i++) { - if ((ulint)(buf2 - buf) >= len) { - goto no_space; - } - - buf2 += sprintf(buf2, "%.500s", + ut_print_name(file, foreign->foreign_col_names[i]); - - if (i + 1 < foreign->n_fields) { - buf2 += sprintf(buf2, " "); } - } - buf2 += sprintf(buf2, ") REFER %.500s(", - foreign->referenced_table_name); - - for (i = 0; i < foreign->n_fields; i++) { - if ((ulint)(buf2 - buf) >= len) { - goto no_space; - } - buf2 += sprintf(buf2, "%.500s", + fputs(") REFER ", file); + ut_print_name(file, foreign->referenced_table_name); + putc('(', file); + + for (i = 0; i < foreign->n_fields; i++) { + if (i) { + putc(' ', file); + } + ut_print_name(file, foreign->referenced_col_names[i]); - if (i + 1 < foreign->n_fields) { - buf2 += sprintf(buf2, " "); } - } - buf2 += sprintf(buf2, ")"); + putc(')', file); - if (foreign->type == DICT_FOREIGN_ON_DELETE_CASCADE) { - buf2 += sprintf(buf2, " ON DELETE CASCADE"); - } + if (foreign->type == DICT_FOREIGN_ON_DELETE_CASCADE) { + fputs(" ON DELETE CASCADE", file); + } - if (foreign->type == DICT_FOREIGN_ON_DELETE_SET_NULL) { - buf2 += sprintf(buf2, " ON DELETE SET NULL"); - } + if (foreign->type == DICT_FOREIGN_ON_DELETE_SET_NULL) { + fputs(" ON DELETE SET NULL", file); + } - if (foreign->type & DICT_FOREIGN_ON_DELETE_NO_ACTION) { - buf2 += sprintf(buf2, " ON DELETE NO ACTION"); - } + if (foreign->type & DICT_FOREIGN_ON_DELETE_NO_ACTION) { + fputs(" ON DELETE NO ACTION", file); + } - if (foreign->type & DICT_FOREIGN_ON_UPDATE_CASCADE) { - buf2 += sprintf(buf2, " ON UPDATE CASCADE"); - } + if (foreign->type & DICT_FOREIGN_ON_UPDATE_CASCADE) { + fputs(" ON UPDATE CASCADE", file); + } - if (foreign->type & DICT_FOREIGN_ON_UPDATE_SET_NULL) { - buf2 += sprintf(buf2, " ON UPDATE SET NULL"); - } + if (foreign->type & DICT_FOREIGN_ON_UPDATE_SET_NULL) { + fputs(" ON UPDATE SET NULL", file); + } - if (foreign->type & DICT_FOREIGN_ON_UPDATE_NO_ACTION) { - buf2 += sprintf(buf2, " ON UPDATE NO ACTION"); + if (foreign->type & DICT_FOREIGN_ON_UPDATE_NO_ACTION) { + fputs(" ON UPDATE NO ACTION", file); + } } foreign = UT_LIST_GET_NEXT(foreign_list, foreign); } -no_space: + mutex_exit(&(dict_sys->mutex)); - - buf[len - 1] = '\0'; - ut_memcpy(str, buf, len); - - mem_free(buf); +} + +/************************************************************************ +Displays the names of the index and the table. */ +void +dict_index_name_print( +/*==================*/ + FILE* file, /* in: output stream */ + const dict_index_t* index) /* in: index to print */ +{ + fputs("index ", file); + ut_print_name(file, index->name); + fputs(" of table ", file); + ut_print_name(stderr, index->table_name); } diff --git a/innobase/dict/dict0load.c b/innobase/dict/dict0load.c index 06306ca483a..884ef95e183 100644 --- a/innobase/dict/dict0load.c +++ b/innobase/dict/dict0load.c @@ -162,8 +162,9 @@ loop: mem_free(table_name); if (table == NULL) { - fprintf(stderr, "InnoDB: Failed to load table %s\n", - table_name); + fputs("InnoDB: Failed to load table ", stderr); + ut_print_namel(stderr, field, len); + putc('\n', stderr); } else { /* The table definition was corrupt if there is no index */ @@ -279,6 +280,27 @@ dict_load_columns( mtr_commit(&mtr); } +/************************************************************************ +Report that an index field or index for a table has been delete marked. */ +static +void +dict_load_report_deleted_index( + char* name, /* in: table name */ + ulint field) /* in: index field, or ULINT_UNDEFINED */ +{ + fputs("InnoDB: Error: data dictionary entry" + " for table ", stderr); + ut_print_name(stderr, name); + fputs(" is corrupt!\n", stderr); + if (field != ULINT_UNDEFINED) { + fprintf(stderr, + "InnoDB: Index field %lu is delete marked.\n", field); + } + else { + fputs("InnoDB: An index is delete marked.\n", stderr); + } +} + /************************************************************************ Loads definitions for index fields. */ static @@ -331,10 +353,7 @@ dict_load_fields( ut_a(btr_pcur_is_on_user_rec(&pcur, &mtr)); if (rec_get_deleted_flag(rec)) { - fprintf(stderr, -"InnoDB: Error: data dictionary entry for table %s is corrupt!\n" -"InnoDB: An index field is delete marked.\n", - table->name); + dict_load_report_deleted_index(table->name, i); } field = rec_get_nth_field(rec, 0, &len); @@ -457,10 +476,8 @@ dict_load_indexes( } if (rec_get_deleted_flag(rec)) { - fprintf(stderr, -"InnoDB: Error: data dictionary entry for table %s is corrupt!\n" -"InnoDB: An index is delete marked.\n", - table->name); + dict_load_report_deleted_index(table->name, + ULINT_UNDEFINED); btr_pcur_close(&pcur); mtr_commit(&mtr); @@ -499,11 +516,13 @@ dict_load_indexes( if (page_no == FIL_NULL) { - fprintf(stderr, - "InnoDB: Error: trying to load index %s for table %s\n" - "InnoDB: but the index tree has been freed!\n", - name_buf, table->name); - + fputs("InnoDB: Error: trying to load index ", stderr); + ut_print_name(stderr, name_buf); + fputs(" for table ", stderr); + ut_print_name(stderr, table->name); + fputs("\n" + "InnoDB: but the index tree has been freed!\n", stderr); + btr_pcur_close(&pcur); mtr_commit(&mtr); @@ -513,10 +532,12 @@ dict_load_indexes( if ((type & DICT_CLUSTERED) == 0 && NULL == dict_table_get_first_index(table)) { - fprintf(stderr, - "InnoDB: Error: trying to load index %s for table %s\n" - "InnoDB: but the first index was not clustered!\n", - name_buf, table->name); + fputs("InnoDB: Error: trying to load index ", stderr); + ut_print_namel(stderr, name_buf, name_len); + fputs(" for table ", stderr); + ut_print_name(stderr, table->name); + fputs("\n" + "InnoDB: but the first index is not clustered!\n", stderr); btr_pcur_close(&pcur); mtr_commit(&mtr); @@ -947,8 +968,10 @@ dict_load_foreign( || rec_get_deleted_flag(rec)) { /* Not found */ - fprintf(stderr, - "InnoDB: Error A: cannot load foreign constraint %s\n", id); + fputs("InnoDB: Error A: cannot load foreign constraint ", + stderr); + ut_print_name(stderr, id); + putc('\n', stderr); btr_pcur_close(&pcur); mtr_commit(&mtr); @@ -962,8 +985,10 @@ dict_load_foreign( /* Check if the id in record is the searched one */ if (len != ut_strlen(id) || ut_memcmp(id, field, len) != 0) { - fprintf(stderr, - "InnoDB: Error B: cannot load foreign constraint %s\n", id); + fputs("InnoDB: Error B: cannot load foreign constraint ", + stderr); + ut_print_name(stderr, id); + putc('\n', stderr); btr_pcur_close(&pcur); mtr_commit(&mtr); diff --git a/innobase/eval/eval0eval.c b/innobase/eval/eval0eval.c index 4e16c36b056..053a10b3c23 100644 --- a/innobase/eval/eval0eval.c +++ b/innobase/eval/eval0eval.c @@ -311,12 +311,13 @@ eval_predefined_2( arg = que_node_get_next(arg); } - printf("\n"); + putc('\n', stderr); } else if (func == PARS_ASSERT_TOKEN) { if (!eval_node_get_ibool_val(arg1)) { - printf("SQL assertion fails in a stored procedure!\n"); + fputs("SQL assertion fails in a stored procedure!\n", + stderr); } ut_a(eval_node_get_ibool_val(arg1)); diff --git a/innobase/fil/fil0fil.c b/innobase/fil/fil0fil.c index 5d45b254afe..1750294ac94 100644 --- a/innobase/fil/fil0fil.c +++ b/innobase/fil/fil0fil.c @@ -1408,8 +1408,9 @@ fil_flush( will not crash or trap even if we pass a handle to a closed file below in os_file_flush! */ - /* printf("Flushing to file %s\n", node->name); */ - + /* fprintf(stderr, "Flushing to file %s\n", + node->name); */ + os_file_flush(file); mutex_enter(&(system->mutex)); diff --git a/innobase/fsp/fsp0fsp.c b/innobase/fsp/fsp0fsp.c index 49885df07d7..53f5e885df8 100644 --- a/innobase/fsp/fsp0fsp.c +++ b/innobase/fsp/fsp0fsp.c @@ -1273,7 +1273,7 @@ fsp_alloc_free_page( hint % FSP_EXTENT_SIZE, mtr); if (free == ULINT_UNDEFINED) { - ut_print_buf(((byte*)descr) - 500, 1000); + ut_print_buf(stderr, ((byte*)descr) - 500, 1000); ut_error; } @@ -1332,11 +1332,10 @@ fsp_free_page( xdes_t* descr; ulint state; ulint frag_n_used; - char buf[1000]; ut_ad(mtr); -/* printf("Freeing page %lu in space %lu\n", page, space); */ +/* fprintf(stderr, "Freeing page %lu in space %lu\n", page, space); */ header = fsp_get_space_header(space, mtr); @@ -1348,9 +1347,9 @@ fsp_free_page( fprintf(stderr, "InnoDB: Error: File space extent descriptor of page %lu has state %lu\n", page, state); - ut_sprintf_buf(buf, ((byte*)descr) - 50, 200); - - fprintf(stderr, "InnoDB: Dump of descriptor: %s\n", buf); + fputs("InnoDB: Dump of descriptor: ", stderr); + ut_print_buf(stderr, ((byte*)descr) - 50, 200); + putc('\n', stderr); if (state == XDES_FREE) { /* We put here some fault tolerance: if the page @@ -1362,14 +1361,12 @@ fsp_free_page( ut_error; } - if (xdes_get_bit(descr, XDES_FREE_BIT, page % FSP_EXTENT_SIZE, mtr) - == TRUE) { + if (xdes_get_bit(descr, XDES_FREE_BIT, page % FSP_EXTENT_SIZE, mtr)) { fprintf(stderr, -"InnoDB: Error: File space extent descriptor of page %lu says it is free\n", - page); - ut_sprintf_buf(buf, ((byte*)descr) - 50, 200); - - fprintf(stderr, "InnoDB: Dump of descriptor: %s\n", buf); +"InnoDB: Error: File space extent descriptor of page %lu says it is free\n" +"InnoDB: Dump of descriptor: ", page); + ut_print_buf(stderr, ((byte*)descr) - 50, 200); + putc('\n', stderr); /* We put here some fault tolerance: if the page is already free, return without doing anything! */ @@ -1427,7 +1424,7 @@ fsp_free_extent( if (xdes_get_state(descr, mtr) == XDES_FREE) { - ut_print_buf(((byte*)descr) - 500, 1000); + ut_print_buf(stderr, (byte*)descr - 500, 1000); ut_error; } @@ -2672,7 +2669,6 @@ fseg_free_page_low( ulint not_full_n_used; ulint state; ulint i; - char errbuf[200]; #ifdef __WIN__ dulint desm; @@ -2692,22 +2688,22 @@ fseg_free_page_low( descr = xdes_get_descriptor(space, page, mtr); ut_a(descr); - if (xdes_get_bit(descr, XDES_FREE_BIT, page % FSP_EXTENT_SIZE, mtr) - != FALSE) { - ut_sprintf_buf(errbuf, descr, 40); - fprintf(stderr, -"InnoDB: Dump of the tablespace extent descriptor: %s\n", errbuf); + if (xdes_get_bit(descr, XDES_FREE_BIT, page % FSP_EXTENT_SIZE, mtr)) { + fputs("InnoDB: Dump of the tablespace extent descriptor: ", + stderr); + ut_print_buf(stderr, descr, 40); - fprintf(stderr, + fprintf(stderr, "\n" "InnoDB: Serious error! InnoDB is trying to free page %lu\n" "InnoDB: though it is already marked as free in the tablespace!\n" "InnoDB: The tablespace free space info is corrupt.\n" "InnoDB: You may need to dump your InnoDB tables and recreate the whole\n" "InnoDB: database!\n", page); - - fprintf(stderr, + crash: + fputs( "InnoDB: If the InnoDB recovery crashes here, see section 6.1\n" -"InnoDB: of http://www.innodb.com/ibman.html about forcing recovery.\n"); +"InnoDB: of http://www.innodb.com/ibman.php about forcing recovery.\n", + stderr); ut_error; } @@ -2751,12 +2747,12 @@ fseg_free_page_low( mtr_read_dulint(descr + XDES_ID, mtr), mtr_read_dulint(seg_inode + FSEG_ID, mtr))) { - ut_sprintf_buf(errbuf, descr, 40); - fprintf(stderr, -"InnoDB: Dump of the tablespace extent descriptor: %s\n", errbuf); - ut_sprintf_buf(errbuf, seg_inode, 40); - fprintf(stderr, -"InnoDB: Dump of the segment inode: %s\n", errbuf); + fputs("InnoDB: Dump of the tablespace extent descriptor: ", + stderr); + ut_print_buf(stderr, descr, 40); + fputs("\nInnoDB: Dump of the segment inode: ", stderr); + ut_print_buf(stderr, seg_inode, 40); + putc('\n', stderr); #ifndef __WIN__ @@ -2794,11 +2790,7 @@ fseg_free_page_low( ut_dulint_get_low(segm)); #endif - - fprintf(stderr, -"InnoDB: If the InnoDB recovery crashes here, see section 6.1\n" -"InnoDB: of http://www.innodb.com/ibman.html about forcing recovery.\n"); - ut_error; + goto crash; } not_full_n_used = mtr_read_ulint(seg_inode + FSEG_NOT_FULL_N_USED, @@ -3311,12 +3303,11 @@ fseg_print_low( n_not_full = flst_get_len(inode + FSEG_NOT_FULL, mtr); n_full = flst_get_len(inode + FSEG_FULL, mtr); - printf( - "SEGMENT id %lu %lu space %lu; page %lu; res %lu used %lu; full ext %lu\n", + fprintf(stderr, +"SEGMENT id %lu %lu space %lu; page %lu; res %lu used %lu; full ext %lu\n" +"fragm pages %lu; free extents %lu; not full extents %lu: pages %lu\n", seg_id_high, seg_id_low, space, page_no, reserved, used, - n_full); - printf( - "fragm pages %lu; free extents %lu; not full extents %lu: pages %lu\n", + n_full, n_frag, n_free, n_not_full, n_used); } @@ -3620,15 +3611,15 @@ fsp_print( seg_id_low = ut_dulint_get_low(d_var); seg_id_high = ut_dulint_get_high(d_var); - printf("FILE SPACE INFO: id %lu\n", space); - - printf("size %lu, free limit %lu, free extents %lu\n", - size, free_limit, n_free); - printf( - "not full frag extents %lu: used pages %lu, full frag extents %lu\n", - n_free_frag, frag_n_used, n_full_frag); - - printf("first seg id not used %lu %lu\n", seg_id_high, seg_id_low); + fprintf(stderr, +"FILE SPACE INFO: id %lu\n" +"size %lu, free limit %lu, free extents %lu\n" +"not full frag extents %lu: used pages %lu, full frag extents %lu\n" +"first seg id not used %lu %lu\n", + space, + size, free_limit, n_free, + n_free_frag, frag_n_used, n_full_frag, + seg_id_high, seg_id_low); mtr_commit(&mtr); @@ -3707,5 +3698,5 @@ fsp_print( mtr_commit(&mtr2); - printf("NUMBER of file segments: %lu\n", n_segs); + fprintf(stderr, "NUMBER of file segments: %lu\n", n_segs); } diff --git a/innobase/fut/fut0lst.c b/innobase/fut/fut0lst.c index 4328fc97b33..ff112b586c4 100644 --- a/innobase/fut/fut0lst.c +++ b/innobase/fut/fut0lst.c @@ -509,8 +509,9 @@ flst_print( len = flst_get_len(base, mtr); - printf("FILE-BASED LIST:\n"); - printf("Base node in space %lu page %lu byte offset %lu; len %lu\n", + fprintf(stderr, + "FILE-BASED LIST:\n" + "Base node in space %lu page %lu byte offset %lu; len %lu\n", buf_frame_get_space_id(frame), buf_frame_get_page_no(frame), (ulint) (base - frame), len); } diff --git a/innobase/ha/ha0ha.c b/innobase/ha/ha0ha.c index 483fac4d8cf..c7c4fd46dc8 100644 --- a/innobase/ha/ha0ha.c +++ b/innobase/ha/ha0ha.c @@ -264,18 +264,13 @@ Prints info of a hash table. */ void ha_print_info( /*==========*/ - char* buf, /* in/out: buffer where to print */ - char* buf_end,/* in: buffer end */ + FILE* file, /* in: file where to print */ hash_table_t* table) /* in: hash table */ { hash_cell_t* cell; ulint cells = 0; ulint n_bufs; ulint i; - - if (buf_end - buf < 200) { - return; - } for (i = 0; i < hash_get_n_cells(table); i++) { @@ -287,8 +282,9 @@ ha_print_info( } } - buf += sprintf(buf, -"Hash table size %lu, used cells %lu", hash_get_n_cells(table), cells); + fprintf(file, + "Hash table size %lu, used cells %lu", + hash_get_n_cells(table), cells); if (table->heaps == NULL && table->heap != NULL) { @@ -301,6 +297,6 @@ ha_print_info( n_bufs++; } - buf += sprintf(buf, ", node heap has %lu buffer(s)\n", n_bufs); + fprintf(file, ", node heap has %lu buffer(s)\n", n_bufs); } } diff --git a/innobase/ibuf/ibuf0ibuf.c b/innobase/ibuf/ibuf0ibuf.c index 0af47a8ccc2..2745af42ff7 100644 --- a/innobase/ibuf/ibuf0ibuf.c +++ b/innobase/ibuf/ibuf0ibuf.c @@ -409,7 +409,7 @@ ibuf_data_sizes_update( ibuf->size = ibuf->size + data->size - old_size; -/* printf("ibuf size %lu, space ibuf size %lu\n", ibuf->size, +/* fprintf(stderr, "ibuf size %lu, space ibuf size %lu\n", ibuf->size, data->size); */ } @@ -438,7 +438,7 @@ ibuf_data_init_for_space( #ifdef UNIV_LOG_DEBUG if (space % 2 == 1) { - printf("No ibuf op in replicate space\n"); + fputs("No ibuf op in replicate space\n", stderr); return(NULL); } @@ -728,7 +728,8 @@ ibuf_set_free_bits_low( bitmap_page = ibuf_bitmap_get_map_page(buf_frame_get_space_id(page), buf_frame_get_page_no(page), mtr); #ifdef UNIV_IBUF_DEBUG - /* printf("Setting page no %lu free bits to %lu should be %lu\n", + /* fprintf(stderr, + "Setting page no %lu free bits to %lu should be %lu\n", buf_frame_get_page_no(page), val, ibuf_index_page_calc_free(page)); */ @@ -782,7 +783,7 @@ ibuf_set_free_bits( buf_frame_get_page_no(page), IBUF_BITMAP_FREE, &mtr); if (old_val != max_val) { - /* printf( + /* fprintf(stderr, "Ibuf: page %lu old val %lu max val %lu\n", buf_frame_get_page_no(page), old_val, max_val); */ } @@ -791,7 +792,7 @@ ibuf_set_free_bits( #endif } #ifdef UNIV_IBUF_DEBUG -/* printf("Setting page no %lu free bits to %lu should be %lu\n", +/* fprintf(stderr, "Setting page no %lu free bits to %lu should be %lu\n", buf_frame_get_page_no(page), val, ibuf_index_page_calc_free(page)); */ @@ -970,7 +971,7 @@ ibuf_page_low( #ifdef UNIV_LOG_DEBUG if (space % 2 != 0) { - printf("No ibuf in a replicate space\n"); + fputs("No ibuf in a replicate space\n", stderr); return(FALSE); } @@ -1481,7 +1482,8 @@ ibuf_free_excess_pages( /* Not yet initialized */ #ifdef UNIV_DEBUG - /*printf("Ibuf for space %lu not yet initialized\n", space); */ + /*fprintf(stderr, + "Ibuf for space %lu not yet initialized\n", space); */ #endif return; @@ -1645,7 +1647,7 @@ ibuf_get_merge_page_nos( #ifdef UNIV_IBUF_DEBUG ut_a(*n_stored <= IBUF_MAX_N_PAGES_MERGED); #endif -/* printf("Ibuf merge batch %lu pages %lu volume\n", *n_stored, +/* fprintf(stderr, "Ibuf merge batch %lu pages %lu volume\n", *n_stored, sum_volumes); */ return(sum_volumes); } @@ -1751,8 +1753,8 @@ loop: page_nos, &n_stored); #ifdef UNIV_IBUF_DEBUG - /* printf("Ibuf contract sync %lu pages %lu volume %lu\n", sync, - n_stored, sum_sizes); */ + /* fprintf(stderr, "Ibuf contract sync %lu pages %lu volume %lu\n", + sync, n_stored, sum_sizes); */ #endif ibuf_exit(); @@ -2074,7 +2076,7 @@ ibuf_insert_low( mutex_exit(&ibuf_mutex); #ifdef UNIV_IBUF_DEBUG - printf("Ibuf too big\n"); + fputs("Ibuf too big\n", stderr); #endif /* Use synchronous contract (== TRUE) */ ibuf_contract(TRUE); @@ -2302,8 +2304,8 @@ ibuf_insert( if (err == DB_SUCCESS) { #ifdef UNIV_IBUF_DEBUG - /* printf("Ibuf insert for page no %lu of index %s\n", page_no, - index->name); */ + /* fprintf(stderr, "Ibuf insert for page no %lu of index %s\n", + page_no, index->name); */ #endif return(TRUE); @@ -2331,7 +2333,6 @@ ibuf_insert_to_index_page( rec_t* rec; page_t* bitmap_page; ulint old_bits; - char errbuf[1000]; ut_ad(ibuf_inside()); ut_ad(dtuple_check_typed(entry)); @@ -2361,16 +2362,13 @@ ibuf_insert_to_index_page( "InnoDB: Error: Insert buffer insert fails; page free %lu, dtuple size %lu\n", page_get_max_insert_size(page, 1), rec_get_converted_size(entry)); - - dtuple_sprintf(errbuf, 900, entry); - - fprintf(stderr, -"InnoDB: Cannot insert index record %s\n", errbuf); - - fprintf(stderr, -"InnoDB: The table where where this index record belongs\n" + fputs("InnoDB: Cannot insert index record ", + stderr); + dtuple_print(stderr, entry); + fputs( +"\nInnoDB: The table where where this index record belongs\n" "InnoDB: is now probably corrupt. Please run CHECK TABLE on\n" -"InnoDB: that table.\n"); +"InnoDB: that table.\n", stderr); bitmap_page = ibuf_bitmap_get_map_page( buf_frame_get_space_id(page), @@ -2384,8 +2382,8 @@ ibuf_insert_to_index_page( fprintf(stderr, "Bitmap bits %lu\n", old_bits); - fprintf(stderr, -"InnoDB: Send a detailed bug report to mysql@lists.mysql.com!\n"); + fputs( +"InnoDB: Send a detailed bug report to mysql@lists.mysql.com!\n", stderr); } } @@ -2443,22 +2441,21 @@ ibuf_delete_rec( if (!success) { fprintf(stderr, - "InnoDB: ERROR: Send the output to heikki.tuuri@innodb.com\n"); - fprintf(stderr, "InnoDB: ibuf cursor restoration fails!\n"); - fprintf(stderr, "InnoDB: ibuf record inserted to page %lu\n", - page_no); + "InnoDB: ERROR: Send the output to mysql@lists.mysql.com\n" + "InnoDB: ibuf cursor restoration fails!\n" + "InnoDB: ibuf record inserted to page %lu\n", page_no); fflush(stderr); - rec_print(btr_pcur_get_rec(pcur)); - rec_print(pcur->old_rec); - dtuple_print(search_tuple); + rec_print(stderr, btr_pcur_get_rec(pcur)); + rec_print(stderr, pcur->old_rec); + dtuple_print(stderr, search_tuple); - rec_print(page_rec_get_next(btr_pcur_get_rec(pcur))); - fflush(stdout); + rec_print(stderr, page_rec_get_next(btr_pcur_get_rec(pcur))); + fflush(stderr); mtr_commit(mtr); - fprintf(stderr, "InnoDB: Validating insert buffer tree:\n"); + fputs("InnoDB: Validating insert buffer tree:\n", stderr); ut_a(btr_validate_tree(ibuf_data->index->tree)); fprintf(stderr, "InnoDB: ibuf tree ok\n"); @@ -2519,7 +2516,6 @@ ibuf_merge_or_delete_for_page( #endif ibool corruption_noticed = FALSE; mtr_t mtr; - char err_buf[500]; if (srv_force_recovery >= SRV_FORCE_NO_IBUF_MERGE) { @@ -2529,7 +2525,7 @@ ibuf_merge_or_delete_for_page( #ifdef UNIV_LOG_DEBUG if (space % 2 != 0) { - printf("No ibuf operation in a replicate space\n"); + fputs("No ibuf operation in a replicate space\n", stderr); return; } @@ -2579,8 +2575,8 @@ ibuf_merge_or_delete_for_page( mtr_start(&mtr); - fprintf(stderr, -" InnoDB: Dump of the ibuf bitmap page:\n"); + fputs(" InnoDB: Dump of the ibuf bitmap page:\n", + stderr); bitmap_page = ibuf_bitmap_get_map_page(space, page_no, &mtr); @@ -2588,7 +2584,7 @@ ibuf_merge_or_delete_for_page( mtr_commit(&mtr); - fprintf(stderr, "\nInnoDB: Dump of the page:\n"); + fputs("\nInnoDB: Dump of the page:\n", stderr); buf_page_print(page); @@ -2651,18 +2647,16 @@ loop: /* Do NOT merge to the 4.1 code base! */ if (trx_sys_downgrading_from_4_1_1) { - fprintf(stderr, + fputs( "InnoDB: Fatal error: you are downgrading from >= 4.1.1 to 4.0, but\n" -"InnoDB: the insert buffer was not empty.\n"); +"InnoDB: the insert buffer was not empty.\n", stderr); ut_error; } if (corruption_noticed) { - rec_sprintf(err_buf, 450, ibuf_rec); - - fprintf(stderr, -"InnoDB: Discarding record\n %s\n from the insert buffer!\n\n", err_buf); - + fputs("InnoDB: Discarding record\n ", stderr); + rec_print(stderr, ibuf_rec); + fputs("\n from the insert buffer!\n\n", stderr); } else if (page) { /* Now we have at pcur a record which should be inserted to the index page; NOTE that the call below @@ -2723,8 +2717,8 @@ reset_bit: page_no, IBUF_BITMAP_FREE, &mtr); ulint new_bits = ibuf_index_page_calc_free(page); #ifdef UNIV_IBUF_DEBUG - /* printf("Old bits %lu new bits %lu max size %lu\n", old_bits, - new_bits, + /* fprintf(stderr, "Old bits %lu new bits %lu max size %lu\n", + old_bits, new_bits, page_get_max_insert_size_after_reorganize(page, 1)); */ #endif if (old_bits != new_bits) { @@ -2736,7 +2730,8 @@ reset_bit: } #ifdef UNIV_IBUF_DEBUG - /* printf("Ibuf merge %lu records volume %lu to page no %lu\n", + /* fprintf(stderr, + "Ibuf merge %lu records volume %lu to page no %lu\n", n_inserts, volume, page_no); */ #endif mtr_commit(&mtr); @@ -2794,34 +2789,29 @@ Prints info of ibuf. */ void ibuf_print( /*=======*/ - char* buf, /* in/out: buffer where to print */ - char* buf_end)/* in: buffer end */ + FILE* file) /* in: file where to print */ { ibuf_data_t* data; #ifdef UNIV_IBUF_DEBUG ulint i; #endif - if (buf_end - buf < 500) { - return; - } mutex_enter(&ibuf_mutex); data = UT_LIST_GET_FIRST(ibuf->data_list); while (data) { - buf += sprintf(buf, - "Ibuf for space %lu: size %lu, free list len %lu, seg size %lu,\n", - data->space, data->size, data->free_list_len, data->seg_size); - - buf += sprintf(buf, + fprintf(file, + "Ibuf for space %lu: size %lu, free list len %lu, seg size %lu,\n" "%lu inserts, %lu merged recs, %lu merges\n", + data->space, data->size, data->free_list_len, data->seg_size, data->n_inserts, data->n_merged_recs, data->n_merges); #ifdef UNIV_IBUF_DEBUG for (i = 0; i < IBUF_COUNT_N_PAGES; i++) { if (ibuf_count_get(data->space, i) > 0) { - printf("Ibuf count for page %lu is %lu\n", + fprintf(stderr, + "Ibuf count for page %lu is %lu\n", i, ibuf_count_get(data->space, i)); } } diff --git a/innobase/include/buf0buf.h b/innobase/include/buf0buf.h index 72cedafa7e1..5ac9c83a5f9 100644 --- a/innobase/include/buf0buf.h +++ b/innobase/include/buf0buf.h @@ -483,8 +483,7 @@ Prints info of the buffer i/o. */ void buf_print_io( /*=========*/ - char* buf, /* in/out: buffer where to print */ - char* buf_end);/* in: buffer end */ + FILE* file); /* in: file where to print */ /************************************************************************* Returns the ratio in percents of modified pages in the buffer pool / database pages in the buffer pool. */ diff --git a/innobase/include/buf0buf.ic b/innobase/include/buf0buf.ic index 5a4c56b0c30..16deade0901 100644 --- a/innobase/include/buf0buf.ic +++ b/innobase/include/buf0buf.ic @@ -217,9 +217,9 @@ buf_block_align( || block >= buf_pool->blocks + buf_pool->max_size) { fprintf(stderr, -"InnoDB: Error: trying to access a stray pointer %lx\n" -"InnoDB: buf pool start is at %lx, number of pages %lu\n", (ulint)ptr, - (ulint)frame_zero, buf_pool->max_size); +"InnoDB: Error: trying to access a stray pointer %p\n" +"InnoDB: buf pool start is at %p, number of pages %lu\n", ptr, + frame_zero, buf_pool->max_size); ut_error; } @@ -251,9 +251,9 @@ buf_block_align_low( || block >= buf_pool->blocks + buf_pool->max_size) { fprintf(stderr, -"InnoDB: Error: trying to access a stray pointer %lx\n" -"InnoDB: buf pool start is at %lx, number of pages %lu\n", (ulint)ptr, - (ulint)frame_zero, buf_pool->max_size); +"InnoDB: Error: trying to access a stray pointer %p\n" +"InnoDB: buf pool start is at %p, number of pages %lu\n", ptr, + frame_zero, buf_pool->max_size); ut_error; } @@ -280,9 +280,9 @@ buf_frame_align( || ((ulint)frame > (ulint)(buf_pool_get_nth_block(buf_pool, buf_pool->max_size - 1)->frame))) { fprintf(stderr, -"InnoDB: Error: trying to access a stray pointer %lx\n" -"InnoDB: buf pool start is at %lx, number of pages %lu\n", (ulint)ptr, - (ulint)(buf_pool->frame_zero), buf_pool->max_size); +"InnoDB: Error: trying to access a stray pointer %p\n" +"InnoDB: buf pool start is at %p, number of pages %lu\n", ptr, + buf_pool->frame_zero, buf_pool->max_size); ut_error; } diff --git a/innobase/include/data0data.h b/innobase/include/data0data.h index b100ef5b583..99d3c297039 100644 --- a/innobase/include/data0data.h +++ b/innobase/include/data0data.h @@ -326,16 +326,7 @@ The following function prints the contents of a tuple. */ void dtuple_print( /*=========*/ - dtuple_t* tuple); /* in: tuple */ -/************************************************************** -The following function prints the contents of a tuple to a buffer. */ - -ulint -dtuple_sprintf( -/*===========*/ - /* out: printed length in bytes */ - char* buf, /* in: print buffer */ - ulint buf_len,/* in: buf length in bytes */ + FILE* f, /* in: output stream */ dtuple_t* tuple); /* in: tuple */ /****************************************************************** Moves parts of long fields in entry to the big record vector so that diff --git a/innobase/include/dict0dict.h b/innobase/include/dict0dict.h index 7d7739021e2..835c2c2b2e6 100644 --- a/innobase/include/dict0dict.h +++ b/innobase/include/dict0dict.h @@ -331,19 +331,23 @@ dict_print_info_on_foreign_keys( a format suitable to be inserted into a CREATE TABLE, otherwise in the format of SHOW TABLE STATUS */ - char* str, /* in/out: pointer to a string */ - ulint len, /* in: space in str available for info */ + FILE* file, /* in: file where to print */ dict_table_t* table); /* in: table */ /************************************************************************** -Sprintfs to a string info on a foreign key of a table in a format suitable -for CREATE TABLE. */ - -char* +Outputs info on a foreign key of a table in a format suitable for +CREATE TABLE. */ +void dict_print_info_on_foreign_key_in_create_format( /*============================================*/ - /* out: how far in buf we printed */ - dict_foreign_t* foreign,/* in: foreign key constraint */ - char* buf); /* in: buffer of at least 5000 bytes */ + FILE* file, /* in: file where to print */ + dict_foreign_t* foreign);/* in: foreign key constraint */ +/************************************************************************ +Displays the names of the index and the table. */ +void +dict_index_name_print( +/*==================*/ + FILE* file, /* in: output stream */ + const dict_index_t* index); /* in: index to print */ /************************************************************************ Gets the first index on the table (the clustered index). */ UNIV_INLINE @@ -846,13 +850,9 @@ dict_tables_have_same_db( const char* name2); /* in: table name in the form dbname '/' tablename */ -/* The following len must be at least 10000 bytes! */ -#define DICT_FOREIGN_ERR_BUF_LEN 10000 - /* Buffers for storing detailed information about the latest foreign key and unique key errors */ -extern char* dict_foreign_err_buf; -extern char* dict_unique_err_buf; +extern FILE* dict_foreign_err_file; extern mutex_t dict_foreign_err_mutex; /* mutex protecting the buffers */ extern dict_sys_t* dict_sys; /* the dictionary system */ diff --git a/innobase/include/ha0ha.h b/innobase/include/ha0ha.h index 0beac928b7e..908db0a6f26 100644 --- a/innobase/include/ha0ha.h +++ b/innobase/include/ha0ha.h @@ -127,8 +127,7 @@ Prints info of a hash table. */ void ha_print_info( /*==========*/ - char* buf, /* in/out: buffer where to print */ - char* buf_end,/* in: buffer end */ + FILE* file, /* in: file where to print */ hash_table_t* table); /* in: hash table */ /* The hash table external chain node */ diff --git a/innobase/include/ibuf0ibuf.h b/innobase/include/ibuf0ibuf.h index a64eb53bd19..80958a593cb 100644 --- a/innobase/include/ibuf0ibuf.h +++ b/innobase/include/ibuf0ibuf.h @@ -262,8 +262,7 @@ Prints info of ibuf. */ void ibuf_print( /*=======*/ - char* buf, /* in/out: buffer where to print */ - char* buf_end);/* in: buffer end */ + FILE* file); /* in: file where to print */ #define IBUF_HEADER_PAGE_NO FSP_IBUF_HEADER_PAGE_NO #define IBUF_TREE_ROOT_PAGE_NO FSP_IBUF_TREE_ROOT_PAGE_NO diff --git a/innobase/include/lock0lock.h b/innobase/include/lock0lock.h index 103d28cd130..94ef3b33ebc 100644 --- a/innobase/include/lock0lock.h +++ b/innobase/include/lock0lock.h @@ -20,6 +20,8 @@ Created 5/7/1996 Heikki Tuuri #include "hash0hash.h" extern ibool lock_print_waits; +/* Buffer for storing information about the most recent deadlock error */ +extern FILE* lock_latest_err_file; /************************************************************************* Gets the size of a lock struct. */ @@ -468,8 +470,7 @@ Prints info of a table lock. */ void lock_table_print( /*=============*/ - char* buf, /* in/out: buffer where to print, must be at least - 500 bytes */ + FILE* file, /* in: file where to print */ lock_t* lock); /* in: table type lock */ /************************************************************************* Prints info of a record lock. */ @@ -477,8 +478,7 @@ Prints info of a record lock. */ void lock_rec_print( /*===========*/ - char* buf, /* in/out: buffer where to print, must be at least - 500 bytes */ + FILE* file, /* in: file where to print */ lock_t* lock); /* in: record type lock */ /************************************************************************* Prints info of locks for all transactions. */ @@ -486,8 +486,7 @@ Prints info of locks for all transactions. */ void lock_print_info( /*============*/ - char* buf, /* in/out: buffer where to print */ - char* buf_end);/* in: buffer end */ + FILE* file); /* in: file where to print */ /************************************************************************* Validates the lock queue on a table. */ diff --git a/innobase/include/log0log.h b/innobase/include/log0log.h index 3295bc2d231..6eef8144c27 100644 --- a/innobase/include/log0log.h +++ b/innobase/include/log0log.h @@ -512,8 +512,7 @@ Prints info of the log. */ void log_print( /*======*/ - char* buf, /* in/out: buffer where to print */ - char* buf_end);/* in: buffer end */ + FILE* file); /* in: file where to print */ /********************************************************** Peeks the current lsn. */ diff --git a/innobase/include/mtr0log.ic b/innobase/include/mtr0log.ic index 54f15779078..ad40fa525db 100644 --- a/innobase/include/mtr0log.ic +++ b/innobase/include/mtr0log.ic @@ -165,8 +165,8 @@ mlog_write_initial_log_record_fast( if (space != 0 || offset > 0x8FFFFFFF) { fprintf(stderr, - "InnoDB: error: buffer page pointer %lx has nonsensical space id %lu\n" - "InnoDB: or page no %lu\n", (ulint)ptr, space, offset); + "InnoDB: error: buffer page pointer %p has nonsensical space id %lu\n" + "InnoDB: or page no %lu\n", ptr, space, offset); ut_error; } @@ -178,7 +178,8 @@ mlog_write_initial_log_record_fast( mtr->n_log_recs++; #ifdef UNIV_LOG_DEBUG -/* printf("Adding to mtr log record type %lu space %lu page no %lu\n", +/* fprintf(stderr, + "Adding to mtr log record type %lu space %lu page no %lu\n", type, space, offset); */ #endif diff --git a/innobase/include/os0file.h b/innobase/include/os0file.h index b221bf7aef9..108cf5520f1 100644 --- a/innobase/include/os0file.h +++ b/innobase/include/os0file.h @@ -443,8 +443,7 @@ Prints info of the aio arrays. */ void os_aio_print( /*=========*/ - char* buf, /* in/out: buffer where to print */ - char* buf_end);/* in: buffer end */ + FILE* file); /* in: file where to print */ /************************************************************************** Refreshes the statistics used to print per-second averages. */ diff --git a/innobase/include/rem0rec.h b/innobase/include/rem0rec.h index b28f39925c1..ff9d1495198 100644 --- a/innobase/include/rem0rec.h +++ b/innobase/include/rem0rec.h @@ -390,16 +390,7 @@ Prints a physical record. */ void rec_print( /*======*/ - rec_t* rec); /* in: physical record */ -/******************************************************************* -Prints a physical record to a buffer. */ - -ulint -rec_sprintf( -/*========*/ - /* out: printed length in bytes */ - char* buf, /* in: buffer to print to */ - ulint buf_len,/* in: buffer length */ + FILE* file, /* in: file where to print */ rec_t* rec); /* in: physical record */ #define REC_INFO_BITS 6 /* This is single byte bit-field */ diff --git a/innobase/include/rem0rec.ic b/innobase/include/rem0rec.ic index 9dfd4faeec8..75a8bdfd6bd 100644 --- a/innobase/include/rem0rec.ic +++ b/innobase/include/rem0rec.ic @@ -190,7 +190,7 @@ rec_set_bit_field_2( + (REC_N_OWNED_MASK << (8 * (REC_N_OWNED - 3))) + (REC_INFO_BITS_MASK << (8 * (REC_INFO_BITS - 3)))); if (m != ut_dbg_zero + 0xFFFFFFFF) { - printf("Sum of masks %lx\n", m); + fprintf(stderr, "Sum of masks %lx\n", m); ut_error; } } diff --git a/innobase/include/row0sel.ic b/innobase/include/row0sel.ic index 9005624b6ca..509838a3327 100644 --- a/innobase/include/row0sel.ic +++ b/innobase/include/row0sel.ic @@ -77,12 +77,9 @@ open_step( if (err != DB_SUCCESS) { /* SQL error detected */ - printf("SQL error %lu\n", err); + fprintf(stderr, "SQL error %lu\n", err); ut_error; - que_thr_handle_error(thr, err, NULL, 0); - - return(NULL); } thr->run_node = que_node_get_parent(node); diff --git a/innobase/include/row0upd.ic b/innobase/include/row0upd.ic index 3e00978be2f..65667f1f00d 100644 --- a/innobase/include/row0upd.ic +++ b/innobase/include/row0upd.ic @@ -84,9 +84,11 @@ upd_field_set_field_no( if (field_no >= dict_index_get_n_fields(index)) { fprintf(stderr, - "InnoDB: Error: trying to access field %lu in table %s\n" - "InnoDB: index %s, but index has only %lu fields\n", - field_no, index->table_name, index->name, + "InnoDB: Error: trying to access field %lu in ", + field_no); + dict_index_name_print(stderr, index); + fprintf(stderr, "\n" + "InnoDB: but index only has %lu fields\n", dict_index_get_n_fields(index)); } diff --git a/innobase/include/srv0srv.h b/innobase/include/srv0srv.h index 3811f6ae167..40a96e79973 100644 --- a/innobase/include/srv0srv.h +++ b/innobase/include/srv0srv.h @@ -32,6 +32,11 @@ at a time */ /* This is set to TRUE if the MySQL user has set it in MySQL */ extern ibool srv_lower_case_table_names; +/* Mutex for locking srv_monitor_file */ +extern mutex_t srv_monitor_file_mutex; +/* Temporary file for innodb monitor output */ +extern FILE* srv_monitor_file; + /* Server parameters which are read from the initfile */ extern char* srv_data_home; @@ -368,13 +373,12 @@ srv_error_monitor_thread( void* arg); /* in: a dummy parameter required by os_thread_create */ /********************************************************************** -Sprintfs to a buffer the output of the InnoDB Monitor. */ +Outputs to a file the output of the InnoDB Monitor. */ void -srv_sprintf_innodb_monitor( -/*=======================*/ - char* buf, /* in/out: buffer which must be at least 4 kB */ - ulint len); /* in: length of the buffer */ +srv_printf_innodb_monitor( +/*======================*/ + FILE* file); /* in: output stream */ /* Types for the threads existing in the system. Threads of types 4 - 9 diff --git a/innobase/include/sync0arr.h b/innobase/include/sync0arr.h index 765ad33afea..383d0c69fb2 100644 --- a/innobase/include/sync0arr.h +++ b/innobase/include/sync0arr.h @@ -114,8 +114,7 @@ Prints info of the wait array. */ void sync_array_print_info( /*==================*/ - char* buf, /* in/out: buffer where to print */ - char* buf_end,/* in: buffer end */ + FILE* file, /* in: file where to print */ sync_array_t* arr); /* in: wait array */ diff --git a/innobase/include/sync0sync.h b/innobase/include/sync0sync.h index 3acf3415889..3348da2851c 100644 --- a/innobase/include/sync0sync.h +++ b/innobase/include/sync0sync.h @@ -119,16 +119,14 @@ Prints wait info of the sync system. */ void sync_print_wait_info( /*=================*/ - char* buf, /* in/out: buffer where to print */ - char* buf_end); /* in: buffer end */ + FILE* file); /* in: file where to print */ /*********************************************************************** Prints info of the sync system. */ void sync_print( /*=======*/ - char* buf, /* in/out: buffer where to print */ - char* buf_end); /* in: buffer end */ + FILE* file); /* in: file where to print */ /********************************************************************** Checks that the mutex has been initialized. */ diff --git a/innobase/include/trx0sys.h b/innobase/include/trx0sys.h index a8ed675a8a5..755bcb28611 100644 --- a/innobase/include/trx0sys.h +++ b/innobase/include/trx0sys.h @@ -269,7 +269,7 @@ void trx_sys_print_mysql_binlog_offset(void); /*===================================*/ /********************************************************************* -Prints to stdout the MySQL binlog info in the system header if the +Prints to stderr the MySQL binlog info in the system header if the magic number shows it valid. */ void diff --git a/innobase/include/trx0trx.h b/innobase/include/trx0trx.h index d9b91ee62dc..bb2d7e8f64d 100644 --- a/innobase/include/trx0trx.h +++ b/innobase/include/trx0trx.h @@ -280,8 +280,7 @@ own the kernel mutex. */ void trx_print( /*======*/ - char* buf, /* in/out: buffer where to print, must be at least - 800 bytes */ + FILE* f, /* in: output stream */ trx_t* trx); /* in: transaction */ diff --git a/innobase/include/ut0ut.h b/innobase/include/ut0ut.h index 637c9a68174..b349fe26015 100644 --- a/innobase/include/ut0ut.h +++ b/innobase/include/ut0ut.h @@ -169,7 +169,7 @@ ut_print_timestamp( /*===============*/ FILE* file); /* in: file where to print */ /************************************************************** -Sprintfs a timestamp to a buffer. */ +Sprintfs a timestamp to a buffer, 13..14 chars plus terminating NUL. */ void ut_sprintf_timestamp( @@ -199,19 +199,37 @@ Prints the contents of a memory buffer in hex and ascii. */ void ut_print_buf( /*=========*/ - byte* buf, /* in: memory buffer */ - ulint len); /* in: length of the buffer */ -/***************************************************************** -Prints the contents of a memory buffer in hex and ascii. */ + FILE* file, /* in: file where to print */ + const byte* buf, /* in: memory buffer */ + ulint len); /* in: length of the buffer */ -ulint -ut_sprintf_buf( -/*===========*/ - /* out: printed length in bytes */ - char* str, /* in: buffer to print to */ - byte* buf, /* in: memory buffer */ - ulint len); /* in: length of the buffer */ +/************************************************************************** +Outputs a NUL-terminated string, quoted as an SQL identifier. */ +void +ut_print_name( +/*==========*/ + FILE* f, /* in: output stream */ + const char* name); /* in: name to print */ + +/************************************************************************** +Outputs a fixed-length string, quoted as an SQL identifier. */ + +void +ut_print_namel( +/*==========*/ + FILE* f, /* in: output stream */ + const char* name, /* in: name to print */ + ulint namelen);/* in: length of name */ + +/************************************************************************** +Catenate files. */ + +void +ut_copy_file( +/*=========*/ + FILE* dest, /* in: output file */ + FILE* src); /* in: input file to be appended to output */ #ifndef UNIV_NONINL #include "ut0ut.ic" diff --git a/innobase/lock/lock0lock.c b/innobase/lock/lock0lock.c index 812eea91d90..47bc37113c4 100644 --- a/innobase/lock/lock0lock.c +++ b/innobase/lock/lock0lock.c @@ -310,7 +310,7 @@ struct lock_struct{ /* We store info on the latest deadlock error to this buffer. InnoDB Monitor will then fetch it and print */ ibool lock_deadlock_found = FALSE; -char* lock_latest_err_buf; /* We allocate 5000 bytes for this */ +FILE* lock_latest_err_file; /* Flags for recursive deadlock search */ #define LOCK_VICTIM_IS_START 1 @@ -356,7 +356,6 @@ lock_check_trx_id_sanity( ibool has_kernel_mutex)/* in: TRUE if the caller owns the kernel mutex */ { - char err_buf[500]; ibool is_ok = TRUE; if (!has_kernel_mutex) { @@ -367,14 +366,16 @@ lock_check_trx_id_sanity( trx id counter */ if (ut_dulint_cmp(trx_id, trx_sys->max_trx_id) >= 0) { - rec_sprintf(err_buf, 400, rec); ut_print_timestamp(stderr); - fprintf(stderr, -"InnoDB: Error: transaction id associated with record\n%s\n" -"InnoDB: in table %s index %s\n" + fputs(" InnoDB: Error: transaction id associated" + " with record\n", + stderr); + rec_print(stderr, rec); + fputs("InnoDB: in ", stderr); + dict_index_name_print(stderr, index); + fprintf(stderr, "\n" "InnoDB: is %lu %lu which is higher than the global trx id counter %lu %lu!\n" "InnoDB: The table is corrupt. You have to do dump + drop + reimport.\n", - err_buf, index->table_name, index->name, ut_dulint_get_high(trx_id), ut_dulint_get_low(trx_id), ut_dulint_get_high(trx_sys->max_trx_id), @@ -481,7 +482,7 @@ lock_sys_create( /* hash_create_mutexes(lock_sys->rec_hash, 2, SYNC_REC_LOCK); */ - lock_latest_err_buf = mem_alloc(5000); + lock_latest_err_file = tmpfile(); } /************************************************************************* @@ -1620,11 +1621,12 @@ lock_rec_enqueue_waiting( if (trx->dict_operation) { ut_print_timestamp(stderr); - - fprintf(stderr, + fputs( " InnoDB: Error: a record lock wait happens in a dictionary operation!\n" -"InnoDB: Table name %s. Send a bug report to mysql@lists.mysql.com\n", -index->table_name); +"InnoDB: Table name ", stderr); + ut_print_name(stderr, index->table_name); + fputs(". Send a bug report to mysql@lists.mysql.com\n", + stderr); } /* Enqueue the lock request that will wait to be granted */ @@ -1656,8 +1658,9 @@ index->table_name); ut_a(que_thr_stop(thr)); if (lock_print_waits) { - printf("Lock wait for trx %lu in index %s\n", - ut_dulint_get_low(trx->id), index->name); + fprintf(stderr, "Lock wait for trx %lu in index ", + ut_dulint_get_low(trx->id)); + ut_print_name(stderr, index->name); } return(DB_LOCK_WAIT); @@ -1995,7 +1998,7 @@ lock_grant( } if (lock_print_waits) { - printf("Lock wait for trx %lu ends\n", + fprintf(stderr, "Lock wait for trx %lu ends\n", ut_dulint_get_low(lock->trx->id)); } @@ -2385,7 +2388,7 @@ lock_move_reorganize_page( /* if ((page_cur_get_rec(&cur1) == sup) && lock_get_wait(lock)) { - printf( + fprintf(stderr, "---\n--\n!!!Lock reorg: supr type %lu\n", lock->type_mode); } */ @@ -2901,7 +2904,6 @@ lock_deadlock_occurs( trx_t* mark_trx; ulint ret; ulint cost = 0; - char* err_buf; ut_ad(trx && lock); #ifdef UNIV_SYNC_DEBUG @@ -2939,14 +2941,8 @@ retry: lock_deadlock_found = TRUE; - err_buf = lock_latest_err_buf + strlen(lock_latest_err_buf); - - ut_a(err_buf <= lock_latest_err_buf + 4000); - - err_buf += sprintf(err_buf, - "*** WE ROLL BACK TRANSACTION (2)\n"); - - ut_a(strlen(lock_latest_err_buf) < 4100); + fputs("*** WE ROLL BACK TRANSACTION (2)\n", + lock_latest_err_file); return(TRUE); } @@ -2978,7 +2974,6 @@ lock_deadlock_recursive( lock_t* lock; ulint bit_no = ULINT_UNDEFINED; trx_t* lock_trx; - char* err_buf; ulint ret; ut_a(trx && start && wait_lock); @@ -3036,71 +3031,48 @@ lock_deadlock_recursive( if (lock_trx == start) { /* We came back to the recursion starting point: a deadlock detected */ + FILE* ef = lock_latest_err_file; - err_buf = lock_latest_err_buf; + rewind(ef); + ut_print_timestamp(ef); - ut_sprintf_timestamp(err_buf); - err_buf += strlen(err_buf); + fputs("\n*** (1) TRANSACTION:\n", ef); - err_buf += sprintf(err_buf, - "\n*** (1) TRANSACTION:\n"); + trx_print(ef, wait_lock->trx); - trx_print(err_buf, wait_lock->trx); - err_buf += strlen(err_buf); - - err_buf += sprintf(err_buf, - "*** (1) WAITING FOR THIS LOCK TO BE GRANTED:\n"); - - ut_a(err_buf <= lock_latest_err_buf + 4000); + fputs( + "*** (1) WAITING FOR THIS LOCK TO BE GRANTED:\n", ef); if (lock_get_type(wait_lock) == LOCK_REC) { - lock_rec_print(err_buf, wait_lock); - err_buf += strlen(err_buf); + lock_rec_print(ef, wait_lock); } else { - lock_table_print(err_buf, wait_lock); - err_buf += strlen(err_buf); + lock_table_print(ef, wait_lock); } - ut_a(err_buf <= lock_latest_err_buf + 4000); - err_buf += sprintf(err_buf, - "*** (2) TRANSACTION:\n"); + fputs("*** (2) TRANSACTION:\n", ef); - trx_print(err_buf, lock->trx); - err_buf += strlen(err_buf); + trx_print(ef, lock->trx); - err_buf += sprintf(err_buf, - "*** (2) HOLDS THE LOCK(S):\n"); - - ut_a(err_buf <= lock_latest_err_buf + 4000); + fputs("*** (2) HOLDS THE LOCK(S):\n", ef); if (lock_get_type(lock) == LOCK_REC) { - lock_rec_print(err_buf, lock); - err_buf += strlen(err_buf); + lock_rec_print(ef, lock); } else { - lock_table_print(err_buf, lock); - err_buf += strlen(err_buf); + lock_table_print(ef, lock); } - ut_a(err_buf <= lock_latest_err_buf + 4000); - - err_buf += sprintf(err_buf, - "*** (2) WAITING FOR THIS LOCK TO BE GRANTED:\n"); - - ut_a(err_buf <= lock_latest_err_buf + 4000); + fputs( + "*** (2) WAITING FOR THIS LOCK TO BE GRANTED:\n", ef); if (lock_get_type(start->wait_lock) == LOCK_REC) { - lock_rec_print(err_buf, - start->wait_lock); - err_buf += strlen(err_buf); + lock_rec_print(ef, start->wait_lock); } else { - lock_table_print(err_buf, - start->wait_lock); - err_buf += strlen(err_buf); + lock_table_print(ef, start->wait_lock); } if (lock_print_waits) { - printf("Deadlock detected\n"); + fputs("Deadlock detected\n", stderr); } if (ut_dulint_cmp(wait_lock->trx->undo_no, @@ -3115,14 +3087,12 @@ lock_deadlock_recursive( lock_deadlock_found = TRUE; - ut_a(err_buf <= lock_latest_err_buf + 4000); - /* Let us choose the transaction of wait_lock as a victim to try to avoid deadlocking our recursion starting point transaction */ - err_buf += sprintf(err_buf, - "*** WE ROLL BACK TRANSACTION (1)\n"); + fputs("*** WE ROLL BACK TRANSACTION (1)\n", + ef); wait_lock->trx->was_chosen_as_deadlock_victim = TRUE; @@ -3281,11 +3251,12 @@ lock_table_enqueue_waiting( if (trx->dict_operation) { ut_print_timestamp(stderr); - - fprintf(stderr, + fputs( " InnoDB: Error: a table lock wait happens in a dictionary operation!\n" -"InnoDB: Table name %s. Send a bug report to mysql@lists.mysql.com\n", -table->name); +"InnoDB: Table name ", stderr); + ut_print_name(stderr, table->name); + fputs(". Send a bug report to mysql@lists.mysql.com\n", + stderr); } /* Enqueue the lock request that will wait to be granted */ @@ -3702,8 +3673,7 @@ Prints info of a table lock. */ void lock_table_print( /*=============*/ - char* buf, /* in/out: buffer where to print, must be at least - 500 bytes */ + FILE* file, /* in: file where to print */ lock_t* lock) /* in: table type lock */ { #ifdef UNIV_SYNC_DEBUG @@ -3711,30 +3681,30 @@ lock_table_print( #endif /* UNIV_SYNC_DEBUG */ ut_a(lock_get_type(lock) == LOCK_TABLE); - buf += sprintf(buf, "TABLE LOCK table %s trx id %lu %lu", - lock->un_member.tab_lock.table->name, + fputs("TABLE LOCK table ", file); + ut_print_name(file, lock->un_member.tab_lock.table->name); + fprintf(file, " trx id %lu %lu", (lock->trx)->id.high, (lock->trx)->id.low); if (lock_get_mode(lock) == LOCK_S) { - buf += sprintf(buf, " lock mode S"); + fputs(" lock mode S", file); } else if (lock_get_mode(lock) == LOCK_X) { - buf += sprintf(buf, " lock_mode X"); + fputs(" lock mode X", file); } else if (lock_get_mode(lock) == LOCK_IS) { - buf += sprintf(buf, " lock_mode IS"); + fputs(" lock mode IS", file); } else if (lock_get_mode(lock) == LOCK_IX) { - buf += sprintf(buf, " lock_mode IX"); + fputs(" lock mode IX", file); } else if (lock_get_mode(lock) == LOCK_AUTO_INC) { - buf += sprintf(buf, " lock_mode AUTO-INC"); + fputs(" lock mode AUTO-INC", file); } else { - buf += sprintf(buf, - " unknown lock_mode %lu", lock_get_mode(lock)); + fprintf(file, " unknown lock mode %lu", lock_get_mode(lock)); } if (lock_get_wait(lock)) { - buf += sprintf(buf, " waiting"); + fputs(" waiting", file); } - buf += sprintf(buf, "\n"); + putc('\n', file); } /************************************************************************* @@ -3743,16 +3713,13 @@ Prints info of a record lock. */ void lock_rec_print( /*===========*/ - char* buf, /* in/out: buffer where to print, must be at least - 500 bytes */ + FILE* file, /* in: file where to print */ lock_t* lock) /* in: record type lock */ { page_t* page; ulint space; ulint page_no; ulint i; - ulint count = 0; - char* buf_start = buf; mtr_t mtr; #ifdef UNIV_SYNC_DEBUG @@ -3763,40 +3730,39 @@ lock_rec_print( space = lock->un_member.rec_lock.space; page_no = lock->un_member.rec_lock.page_no; - buf += sprintf(buf, "RECORD LOCKS space id %lu page no %lu n bits %lu", + fprintf(file, "RECORD LOCKS space id %lu page no %lu n bits %lu ", space, page_no, lock_rec_get_n_bits(lock)); - - buf += sprintf(buf, " table %s index %s trx id %lu %lu", - lock->index->table->name, lock->index->name, + dict_index_name_print(file, lock->index); + fprintf(file, " trx id %lu %lu", (lock->trx)->id.high, (lock->trx)->id.low); if (lock_get_mode(lock) == LOCK_S) { - buf += sprintf(buf, " lock mode S"); + fputs(" lock mode S", file); } else if (lock_get_mode(lock) == LOCK_X) { - buf += sprintf(buf, " lock_mode X"); + fputs(" lock_mode X", file); } else { ut_error; } if (lock_rec_get_gap(lock)) { - buf += sprintf(buf, " locks gap before rec"); + fputs(" locks gap before rec", file); } if (lock_rec_get_rec_not_gap(lock)) { - buf += sprintf(buf, " locks rec but not gap"); + fputs(" locks rec but not gap", file); } if (lock_rec_get_insert_intention(lock)) { - buf += sprintf(buf, " insert intention"); + fputs(" insert intention", file); } if (lock_get_wait(lock)) { - buf += sprintf(buf, " waiting"); + fputs(" waiting", file); } mtr_start(&mtr); - buf += sprintf(buf, "\n"); + putc('\n', file); /* If the page is not in the buffer pool, we cannot load it because we have the kernel mutex and ibuf operations would @@ -3826,28 +3792,16 @@ lock_rec_print( for (i = 0; i < lock_rec_get_n_bits(lock); i++) { - if (buf - buf_start > 300) { - - buf += sprintf(buf, - "Suppressing further record lock prints for this page\n"); - - mtr_commit(&mtr); - - return; - } - if (lock_rec_get_nth_bit(lock, i)) { - buf += sprintf(buf, "Record lock, heap no %lu ", i); + fprintf(file, "Record lock, heap no %lu ", i); if (page) { - buf += rec_sprintf(buf, 120, + rec_print(file, page_find_rec_with_heap_no(page, i)); - *buf = '\0'; } - buf += sprintf(buf, "\n"); - count++; + putc('\n', file); } } @@ -3889,8 +3843,7 @@ Prints info of locks for all transactions. */ void lock_print_info( /*============*/ - char* buf, /* in/out: buffer where to print */ - char* buf_end)/* in: buffer end */ + FILE* file) /* in: file where to print */ { lock_t* lock; trx_t* trx; @@ -3903,79 +3856,47 @@ lock_print_info( ulint i; mtr_t mtr; - if (buf_end - buf < 600) { - sprintf(buf, "... output truncated!\n"); - - return; - } - lock_mutex_enter_kernel(); if (lock_deadlock_found) { - - buf += sprintf(buf, + fputs( "------------------------\n" "LATEST DETECTED DEADLOCK\n" -"------------------------\n"); +"------------------------\n", file); - if ((ulint)(buf_end - buf) - < 100 + strlen(lock_latest_err_buf)) { - - lock_mutex_exit_kernel(); - sprintf(buf, "... output truncated!\n"); - - return; - } - - buf += sprintf(buf, "%s", lock_latest_err_buf); + ut_copy_file(file, lock_latest_err_file); } - if (buf_end - buf < 600) { - lock_mutex_exit_kernel(); - sprintf(buf, "... output truncated!\n"); - - return; - } - - buf += sprintf(buf, + fputs( "------------\n" "TRANSACTIONS\n" -"------------\n"); +"------------\n", file); - buf += sprintf(buf, "Trx id counter %lu %lu\n", + fprintf(file, "Trx id counter %lu %lu\n", ut_dulint_get_high(trx_sys->max_trx_id), ut_dulint_get_low(trx_sys->max_trx_id)); - buf += sprintf(buf, + fprintf(file, "Purge done for trx's n:o < %lu %lu undo n:o < %lu %lu\n", ut_dulint_get_high(purge_sys->purge_trx_no), ut_dulint_get_low(purge_sys->purge_trx_no), ut_dulint_get_high(purge_sys->purge_undo_no), ut_dulint_get_low(purge_sys->purge_undo_no)); - buf += sprintf(buf, + fprintf(file, "Total number of lock structs in row lock hash table %lu\n", lock_get_n_rec_locks()); - buf += sprintf(buf, "LIST OF TRANSACTIONS FOR EACH SESSION:\n"); + fprintf(file, "LIST OF TRANSACTIONS FOR EACH SESSION:\n"); /* First print info on non-active transactions */ trx = UT_LIST_GET_FIRST(trx_sys->mysql_trx_list); while (trx) { - if (buf_end - buf < 900) { - lock_mutex_exit_kernel(); - sprintf(buf, "... output truncated!\n"); - - return; - } - if (trx->conc_state == TRX_NOT_STARTED) { - buf += sprintf(buf, "---"); - trx_print(buf, trx); - - buf += strlen(buf); + fputs("---", file); + trx_print(file, trx); } trx = UT_LIST_GET_NEXT(mysql_trx_list, trx); @@ -4004,28 +3925,12 @@ loop: return; } - if (buf_end - buf < 900) { - lock_mutex_exit_kernel(); - sprintf(buf, "... output truncated!\n"); - - return; - } - if (nth_lock == 0) { - buf += sprintf(buf, "---"); - trx_print(buf, trx); - - buf += strlen(buf); - - if (buf_end - buf < 500) { - lock_mutex_exit_kernel(); - sprintf(buf, "... output truncated!\n"); - - return; - } + fputs("---", file); + trx_print(file, trx); if (trx->read_view) { - buf += sprintf(buf, + fprintf(file, "Trx read view will not see trx with id >= %lu %lu, sees < %lu %lu\n", ut_dulint_get_high(trx->read_view->low_limit_id), ut_dulint_get_low(trx->read_view->low_limit_id), @@ -4034,19 +3939,17 @@ loop: } if (trx->que_state == TRX_QUE_LOCK_WAIT) { - buf += sprintf(buf, + fprintf(file, "------- TRX HAS BEEN WAITING %lu SEC FOR THIS LOCK TO BE GRANTED:\n", (ulint)difftime(time(NULL), trx->wait_started)); if (lock_get_type(trx->wait_lock) == LOCK_REC) { - lock_rec_print(buf, trx->wait_lock); + lock_rec_print(file, trx->wait_lock); } else { - lock_table_print(buf, trx->wait_lock); + lock_table_print(file, trx->wait_lock); } - buf += strlen(buf); - buf += sprintf(buf, - "------------------\n"); + fputs("------------------\n", file); } } @@ -4074,13 +3977,6 @@ loop: goto loop; } - if (buf_end - buf < 500) { - lock_mutex_exit_kernel(); - sprintf(buf, "... output truncated!\n"); - - return; - } - if (lock_get_type(lock) == LOCK_REC) { space = lock->un_member.rec_lock.space; page_no = lock->un_member.rec_lock.page_no; @@ -4101,22 +3997,21 @@ loop: goto loop; } - lock_rec_print(buf, lock); + lock_rec_print(file, lock); } else { ut_ad(lock_get_type(lock) == LOCK_TABLE); - lock_table_print(buf, lock); + lock_table_print(file, lock); } - buf += strlen(buf); - load_page_first = TRUE; nth_lock++; if (nth_lock >= 10) { - buf += sprintf(buf, - "10 LOCKS PRINTED FOR THIS TRX: SUPPRESSING FURTHER PRINTS\n"); + fputs( + "10 LOCKS PRINTED FOR THIS TRX: SUPPRESSING FURTHER PRINTS\n", + file); nth_trx++; nth_lock = 0; @@ -4333,7 +4228,8 @@ loop: index = lock->index; rec = page_find_rec_with_heap_no(page, i); - printf("Validating %lu %lu\n", space, page_no); + fprintf(stderr, + "Validating %lu %lu\n", space, page_no); lock_mutex_exit_kernel(); diff --git a/innobase/log/log0log.c b/innobase/log/log0log.c index 3bc562eefb6..b058a65ce6e 100644 --- a/innobase/log/log0log.c +++ b/innobase/log/log0log.c @@ -517,7 +517,8 @@ log_group_calc_lsn_offset( ut_a(offset < (((ib_longlong) 1) << 32)); /* offset must be < 4 GB */ - /* printf("Offset is %lu gr_lsn_offset is %lu difference is %lu\n", + /* fprintf(stderr, + "Offset is %lu gr_lsn_offset is %lu difference is %lu\n", (ulint)offset,(ulint)gr_lsn_size_offset, (ulint)difference); */ @@ -934,7 +935,8 @@ log_group_check_flush_completion( if (!log_sys->one_flushed && group->n_pending_writes == 0) { #ifdef UNIV_LOG_DEBUG if (log_debug_writes) { - printf("Log flushed first to group %lu\n", group->id); + fprintf(stderr, + "Log flushed first to group %lu\n", group->id); } #endif /* UNIV_LOG_DEBUG */ @@ -947,7 +949,7 @@ log_group_check_flush_completion( #ifdef UNIV_LOG_DEBUG if (log_debug_writes && (group->n_pending_writes == 0)) { - printf("Log flushed to group %lu\n", group->id); + fprintf(stderr, "Log flushed to group %lu\n", group->id); } #endif /* UNIV_LOG_DEBUG */ @@ -1096,9 +1098,9 @@ log_group_file_header_flush( #ifdef UNIV_LOG_DEBUG if (log_debug_writes) { - printf( - "Writing log file header to group %lu file %lu\n", group->id, - nth_file); + fprintf(stderr, + "Writing log file header to group %lu file %lu\n", + group->id, nth_file); } #endif /* UNIV_LOG_DEBUG */ @@ -1186,14 +1188,13 @@ loop: #ifdef UNIV_LOG_DEBUG if (log_debug_writes) { - printf( + fprintf(stderr, "Writing log file segment to group %lu offset %lu len %lu\n" - "start lsn %lu %lu\n", + "start lsn %lu %lu\n" + "First block n:o %lu last block n:o %lu\n", group->id, next_offset, write_len, ut_dulint_get_high(start_lsn), - ut_dulint_get_low(start_lsn)); - printf( - "First block n:o %lu last block n:o %lu\n", + ut_dulint_get_low(start_lsn), log_block_get_hdr_no(buf), log_block_get_hdr_no( buf + write_len - OS_FILE_LOG_BLOCK_SIZE)); @@ -1274,7 +1275,7 @@ loop: ut_ad(loop_count < 5); if (loop_count > 2) { -/* printf("Log loop count %lu\n", loop_count); */ +/* fprintf(stderr, "Log loop count %lu\n", loop_count); */ } mutex_enter(&(log_sys->mutex)); @@ -1337,7 +1338,8 @@ loop: #ifdef UNIV_LOG_DEBUG if (log_debug_writes) { - printf("Writing log from %lu %lu up to lsn %lu %lu\n", + fprintf(stderr, + "Writing log from %lu %lu up to lsn %lu %lu\n", ut_dulint_get_high(log_sys->written_to_all_lsn), ut_dulint_get_low(log_sys->written_to_all_lsn), ut_dulint_get_high(log_sys->lsn), @@ -1757,11 +1759,11 @@ log_reset_first_header_and_checkpoint( lsn = ut_dulint_add(start, LOG_BLOCK_HDR_SIZE); /* Write the label of ibbackup --restore */ - sprintf((char*) hdr_buf + LOG_FILE_WAS_CREATED_BY_HOT_BACKUP, + strcpy((char*) hdr_buf + LOG_FILE_WAS_CREATED_BY_HOT_BACKUP, "ibbackup "); ut_sprintf_timestamp( - (char*) hdr_buf + LOG_FILE_WAS_CREATED_BY_HOT_BACKUP - + strlen("ibbackup ")); + (char*) hdr_buf + (LOG_FILE_WAS_CREATED_BY_HOT_BACKUP + + (sizeof "ibbackup ") - 1)); buf = hdr_buf + LOG_CHECKPOINT_1; mach_write_to_8(buf + LOG_CHECKPOINT_NO, ut_dulint_zero); @@ -1904,7 +1906,7 @@ log_checkpoint( #ifdef UNIV_LOG_DEBUG if (log_debug_writes) { - printf("Making checkpoint no %lu at lsn %lu %lu\n", + fprintf(stderr, "Making checkpoint no %lu at lsn %lu %lu\n", ut_dulint_get_low(log_sys->next_checkpoint_no), ut_dulint_get_high(oldest_lsn), ut_dulint_get_low(oldest_lsn)); @@ -2279,19 +2281,18 @@ loop: } if (!ret) { - fprintf(stderr, - "InnoDB: Cannot create or open archive log file %s.\n", - name); - fprintf(stderr, "InnoDB: Cannot continue operation.\n" - "InnoDB: Check that the log archive directory exists,\n" - "InnoDB: you have access rights to it, and\n" - "InnoDB: there is space available.\n"); - exit(1); + fprintf(stderr, + "InnoDB: Cannot create or open archive log file %s.\n" + "InnoDB: Cannot continue operation.\n" + "InnoDB: Check that the log archive directory exists,\n" + "InnoDB: you have access rights to it, and\n" + "InnoDB: there is space available.\n", name); + exit(1); } #ifdef UNIV_LOG_DEBUG if (log_debug_writes) { - printf("Created archive file %s\n", name); + fprintf(stderr, "Created archive file %s\n", name); } #endif /* UNIV_LOG_DEBUG */ @@ -2324,7 +2325,7 @@ loop: #ifdef UNIV_LOG_DEBUG if (log_debug_writes) { - printf( + fprintf(stderr, "Archiving starting at lsn %lu %lu, len %lu to group %lu\n", ut_dulint_get_high(start_lsn), ut_dulint_get_low(start_lsn), @@ -2423,7 +2424,8 @@ log_archive_write_complete_groups(void) #ifdef UNIV_LOG_DEBUG if (log_debug_writes && trunc_files) { - printf("Complete file(s) archived to group %lu\n", + fprintf(stderr, + "Complete file(s) archived to group %lu\n", group->id); } #endif /* UNIV_LOG_DEBUG */ @@ -2451,7 +2453,7 @@ log_archive_write_complete_groups(void) #ifdef UNIV_LOG_DEBUG if (log_debug_writes) { - printf("Archiving writes completed\n"); + fputs("Archiving writes completed\n", stderr); } #endif /* UNIV_LOG_DEBUG */ } @@ -2472,7 +2474,7 @@ log_archive_check_completion_low(void) #ifdef UNIV_LOG_DEBUG if (log_debug_writes) { - printf("Archiving read completed\n"); + fputs("Archiving read completed\n", stderr); } #endif /* UNIV_LOG_DEBUG */ @@ -2620,7 +2622,8 @@ loop: #ifdef UNIV_LOG_DEBUG if (log_debug_writes) { - printf("Archiving from lsn %lu %lu to lsn %lu %lu\n", + fprintf(stderr, + "Archiving from lsn %lu %lu to lsn %lu %lu\n", ut_dulint_get_high(log_sys->archived_lsn), ut_dulint_get_low(log_sys->archived_lsn), ut_dulint_get_high(limit_lsn), @@ -2727,7 +2730,7 @@ log_archive_close_groups( #ifdef UNIV_LOG_DEBUG if (log_debug_writes) { - printf( + fprintf(stderr, "Incrementing arch file no to %lu in log group %lu\n", group->archived_file_no + 2, group->id); } @@ -3262,20 +3265,15 @@ Prints info of the log. */ void log_print( /*======*/ - char* buf, /* in/out: buffer where to print */ - char* buf_end)/* in: buffer end */ + FILE* file) /* in: file where to print */ { double time_elapsed; time_t current_time; - if (buf_end - buf < 300) { - - return; - } - mutex_enter(&(log_sys->mutex)); - buf += sprintf(buf, "Log sequence number %lu %lu\n" + fprintf(file, + "Log sequence number %lu %lu\n" "Log flushed up to %lu %lu\n" "Last checkpoint at %lu %lu\n", ut_dulint_get_high(log_sys->lsn), @@ -3289,7 +3287,7 @@ log_print( time_elapsed = 0.001 + difftime(current_time, log_sys->last_printout_time); - buf += sprintf(buf, + fprintf(file, "%lu pending log writes, %lu pending chkp writes\n" "%lu log i/o's done, %.2f log i/o's/second\n", log_sys->n_pending_writes, diff --git a/innobase/log/log0recv.c b/innobase/log/log0recv.c index 1e88b677093..33321376929 100644 --- a/innobase/log/log0recv.c +++ b/innobase/log/log0recv.c @@ -589,7 +589,7 @@ recv_read_cp_info_for_backup( *fsp_limit = 1000000000; } -/* printf("fsp limit %lu MB\n", *fsp_limit); */ +/* fprintf(stderr, "fsp limit %lu MB\n", *fsp_limit); */ *cp_no = mach_read_from_8(cp_buf + LOG_CHECKPOINT_NO); @@ -665,7 +665,7 @@ recv_scan_log_seg_for_backup( if (no != log_block_convert_lsn_to_no(*scanned_lsn) || !log_block_checksum_is_ok_or_old_format(log_block)) { /* - printf( + fprintf(stderr, "Log block n:o %lu, scanned lsn n:o %lu\n", no, log_block_convert_lsn_to_no(*scanned_lsn)); */ @@ -673,7 +673,7 @@ recv_scan_log_seg_for_backup( log_block += OS_FILE_LOG_BLOCK_SIZE; /* - printf( + fprintf(stderr, "Next log block n:o %lu\n", log_block_get_hdr_no(log_block)); */ @@ -690,7 +690,8 @@ recv_scan_log_seg_for_backup( /* Garbage from a log buffer flush which was made before the most recent database recovery */ /* - printf("Scanned cp n:o %lu, block cp n:o %lu\n", + fprintf(stderr, + "Scanned cp n:o %lu, block cp n:o %lu\n", *scanned_checkpoint_no, log_block_get_checkpoint_no(log_block)); */ @@ -708,7 +709,8 @@ recv_scan_log_seg_for_backup( if (data_len < OS_FILE_LOG_BLOCK_SIZE) { /* Log data ends here */ - /* printf("Log block data len %lu\n", data_len); */ + /* fprintf(stderr, "Log block data len %lu\n", + data_len); */ break; } @@ -1211,7 +1213,7 @@ recv_read_in_area( buf_read_recv_pages(FALSE, space, page_nos, n); /* - printf("Recv pages at %lu n %lu\n", page_nos[0], n); + fprintf(stderr, "Recv pages at %lu n %lu\n", page_nos[0], n); */ return(n); } @@ -1398,16 +1400,16 @@ recv_apply_log_recs_for_backup( } if (recv_max_parsed_page_no >= n_pages_total) { - printf( + fprintf(stderr, "InnoDB: Error: tablespace size %lu pages, but a log record on page %lu!\n" "InnoDB: Are you sure you have specified all the ibdata files right in\n" "InnoDB: the my.cnf file you gave as the argument to ibbackup --restore?\n", n_pages_total, recv_max_parsed_page_no); } - printf( + fputs( "InnoDB: Starting an apply batch of log records to the database...\n" -"InnoDB: Progress in percents: "); +"InnoDB: Progress in percents: ", stderr); for (i = 0; i < n_pages_total; i++) { @@ -1424,7 +1426,7 @@ recv_apply_log_recs_for_backup( OS_FILE_READ_WRITE, &success); if (!success) { - printf( + fprintf(stderr, "InnoDB: Error: cannot open %lu'th data file\n", nth_file); exit(1); @@ -1440,7 +1442,7 @@ recv_apply_log_recs_for_backup( nth_page_in_file >> (32 - UNIV_PAGE_SIZE_SHIFT), UNIV_PAGE_SIZE); if (!success) { - printf( + fprintf(stderr, "InnoDB: Error: cannot read page no %lu from %lu'th data file\n", nth_page_in_file, nth_file); @@ -1468,7 +1470,7 @@ recv_apply_log_recs_for_backup( nth_page_in_file >> (32 - UNIV_PAGE_SIZE_SHIFT), UNIV_PAGE_SIZE); if (!success) { - printf( + fprintf(stderr, "InnoDB: Error: cannot write page no %lu to %lu'th data file\n", nth_page_in_file, nth_file); @@ -1478,8 +1480,8 @@ recv_apply_log_recs_for_backup( if ((100 * i) / n_pages_total != (100 * (i + 1)) / n_pages_total) { - printf("%lu ", (100 * i) / n_pages_total); - fflush(stdout); + fprintf(stderr, "%lu ", (100 * i) / n_pages_total); + fflush(stderr); } nth_page_in_file++; @@ -1821,21 +1823,15 @@ recv_report_corrupt_log( ulint space, /* in: space id, this may also be garbage */ ulint page_no)/* in: page number, this may also be garbage */ { - char* err_buf; - fprintf(stderr, "InnoDB: ############### CORRUPT LOG RECORD FOUND\n" "InnoDB: Log record type %lu, space id %lu, page number %lu\n" -"InnoDB: Log parsing proceeded successfully up to %lu %lu\n", - (ulint)type, space, page_no, - ut_dulint_get_high(recv_sys->recovered_lsn), - ut_dulint_get_low(recv_sys->recovered_lsn)); - - err_buf = ut_malloc(1000000); - - fprintf(stderr, +"InnoDB: Log parsing proceeded successfully up to %lu %lu\n" "InnoDB: Previous log record type %lu, is multi %lu\n" "InnoDB: Recv offset %lu, prev %lu\n", + (ulint)type, space, page_no, + ut_dulint_get_high(recv_sys->recovered_lsn), + ut_dulint_get_low(recv_sys->recovered_lsn), recv_previous_parsed_rec_type, recv_previous_parsed_rec_is_multi, (ulint)(ptr - recv_sys->buf), @@ -1846,28 +1842,27 @@ recv_report_corrupt_log( && (ulint)(ptr - recv_sys->buf + 100 - recv_previous_parsed_rec_offset) < 200000) { + fputs( +"InnoDB: Hex dump of corrupt log starting 100 bytes before the start\n" +"InnoDB: of the previous log rec,\n" +"InnoDB: and ending 100 bytes after the start of the corrupt rec:\n", + stderr); - ut_sprintf_buf(err_buf, + ut_print_buf(stderr, recv_sys->buf + recv_previous_parsed_rec_offset - 100, ptr - recv_sys->buf + 200 - recv_previous_parsed_rec_offset); - fprintf(stderr, -"InnoDB: Hex dump of corrupt log starting 100 bytes before the start\n" -"InnoDB: of the previous log rec,\n" -"InnoDB: and ending 100 bytes after the start of the corrupt rec:\n%s\n", - err_buf); + putc('\n', stderr); } - ut_free(err_buf); - - fprintf(stderr, + fputs( "InnoDB: WARNING: the log file may have been corrupt and it\n" "InnoDB: is possible that the log scan did not proceed\n" "InnoDB: far enough in recovery! Please run CHECK TABLE\n" "InnoDB: on your InnoDB tables to check that they are ok!\n" "InnoDB: If mysqld crashes after this recovery, look at\n" - "InnoDB: section 6.1 of http://www.innodb.com/ibman.html\n" - "InnoDB: about forcing recovery.\n"); + "InnoDB: section 6.1 of http://www.innodb.com/ibman.php\n" + "InnoDB: about forcing recovery.\n", stderr); fflush(stderr); } @@ -2517,7 +2512,7 @@ recv_recovery_from_checkpoint_start( log_hdr_buf, max_cp_group); if (0 == ut_memcmp(log_hdr_buf + LOG_FILE_WAS_CREATED_BY_HOT_BACKUP, - (byte*)"ibbackup", ut_strlen((char*)"ibbackup"))) { + (byte*)"ibbackup", (sizeof "ibbackup") - 1)) { /* This log file was created by ibbackup --restore: print a note to the user about it */ @@ -2865,33 +2860,43 @@ recv_reset_log_files_for_backup( ibool success; byte* buf; ulint i; - char name[5000]; - + ulint log_dir_len; + char* name; + static + char logfilename[] = "ib_logfile"; + + log_dir_len = strlen(log_dir); + /* reserve space for log_dir, "ib_logfile" and a number */ + name = memcpy(mem_alloc(log_dir_len + ((sizeof logfilename) + 11)), + log_dir, log_dir_len); + memcpy(name + log_dir_len, logfilename, sizeof logfilename); + buf = ut_malloc(LOG_FILE_HDR_SIZE + OS_FILE_LOG_BLOCK_SIZE); - + for (i = 0; i < n_log_files; i++) { - sprintf(name, "%sib_logfile%lu", log_dir, i); + sprintf(name + log_dir_len + sizeof logfilename, "%lu", i); log_file = os_file_create_simple(name, OS_FILE_CREATE, OS_FILE_READ_WRITE, &success); if (!success) { - printf( + fprintf(stderr, "InnoDB: Cannot create %s. Check that the file does not exist yet.\n", name); exit(1); } - printf( -"Setting log file size to %lu %lu\n", ut_get_high32(log_file_size), - log_file_size & 0xFFFFFFFF); + fprintf(stderr, + "Setting log file size to %lu %lu\n", + ut_get_high32(log_file_size), + log_file_size & 0xFFFFFFFF); success = os_file_set_size(name, log_file, log_file_size & 0xFFFFFFFF, ut_get_high32(log_file_size)); if (!success) { - printf( + fprintf(stderr, "InnoDB: Cannot set %s size to %lu %lu\n", name, ut_get_high32(log_file_size), log_file_size & 0xFFFFFFFF); exit(1); @@ -2908,12 +2913,12 @@ recv_reset_log_files_for_backup( log_block_init_in_old_format(buf + LOG_FILE_HDR_SIZE, lsn); log_block_set_first_rec_group(buf + LOG_FILE_HDR_SIZE, LOG_BLOCK_HDR_SIZE); - sprintf(name, "%sib_logfile%lu", log_dir, 0); + strcpy(name + log_dir_len + sizeof logfilename, "0"); log_file = os_file_create_simple(name, OS_FILE_OPEN, OS_FILE_READ_WRITE, &success); if (!success) { - printf("InnoDB: Cannot open %s.\n", name); + fprintf(stderr, "InnoDB: Cannot open %s.\n", name); exit(1); } @@ -2923,6 +2928,7 @@ recv_reset_log_files_for_backup( os_file_flush(log_file); os_file_close(log_file); + mem_free(name); ut_free(buf); } diff --git a/innobase/mem/mem0dbg.c b/innobase/mem/mem0dbg.c index 52a08e6faf1..92c1235220e 100644 --- a/innobase/mem/mem0dbg.c +++ b/innobase/mem/mem0dbg.c @@ -336,7 +336,7 @@ mem_hash_remove( } if (node == NULL) { - printf( + fprintf(stderr, "Memory heap or buffer freed in %s line %lu did not exist.\n", file_name, line); ut_error; @@ -351,20 +351,18 @@ mem_hash_remove( mem_heap_validate_or_print(node->heap, NULL, FALSE, &error, &size, NULL, NULL); if (error) { - printf("Inconsistency in memory heap or buffer n:o %lu created\n", - node->nth_heap); - printf("in %s line %lu and tried to free in %s line %lu.\n", - node->file_name, node->line, file_name, line); + fprintf(stderr, + "Inconsistency in memory heap or buffer n:o %lu created\n" + "in %s line %lu and tried to free in %s line %lu.\n" + "Hex dump of 400 bytes around memory heap first block start:\n", + node->nth_heap, node->file_name, node->line, + file_name, line); + ut_print_buf(stderr, (byte*)node->heap - 200, 400); - printf( - "Hex dump of 400 bytes around memory heap first block start:\n"); + fputs("\nDump of the mem heap:\n", stderr); - ut_print_buf((byte*)(node->heap) - 200, 400); - - printf("\nDump of the mem heap:\n"); - - mem_heap_validate_or_print(node->heap, NULL, TRUE, &error, &size, - NULL, NULL); + mem_heap_validate_or_print(node->heap, NULL, TRUE, &error, + &size, NULL, NULL); ut_error; } @@ -438,7 +436,7 @@ mem_heap_validate_or_print( } if (print) { - printf("Memory heap:"); + fputs("Memory heap:", stderr); } while (block != NULL) { @@ -456,7 +454,7 @@ mem_heap_validate_or_print( /* We can trace the fields of the block only in the debug version */ if (print) { - printf(" Block %ld:", block_count); + fprintf(stderr, " Block %ld:", block_count); } field = (byte*)block + mem_block_get_start(block); @@ -476,7 +474,7 @@ mem_heap_validate_or_print( len = mem_field_header_get_len(user_field); if (print) { - ut_print_buf(user_field, len); + ut_print_buf(stderr, user_field, len); } total_len += len; @@ -545,7 +543,7 @@ mem_heap_print( mem_heap_validate_or_print(heap, NULL, TRUE, &error, &us_size, &phys_size, &n_blocks); - printf( + fprintf(stderr, "\nheap type: %lu; size: user size %lu; physical size %lu; blocks %lu.\n", heap->type, us_size, phys_size, n_blocks); ut_a(!error); @@ -659,9 +657,11 @@ mem_validate_no_assert(void) &ph_size, &n_blocks); if (error) { - printf("\nERROR!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n\n"); - printf("Inconsistency in memory heap or buffer created\n"); - printf("in %s line %lu.\n", node->file_name, node->line); + fprintf(stderr, + "\nERROR!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n\n" + "Inconsistency in memory heap or buffer created\n" + "in %s line %lu.\n", + node->file_name, node->line); mutex_exit(&mem_hash_mutex); @@ -721,12 +721,10 @@ mem_analyze_corruption( ulint i; ulint dist; - ut_sprintf_buf(srv_fatal_errbuf, ptr - 250, 500); - fprintf(stderr, - "InnoDB: Apparent memory corruption: mem dump %s\n", srv_fatal_errbuf); + fputs("InnoDB: Apparent memory corruption: mem dump ", stderr); + ut_print_buf(stderr, ptr - 250, 500); - fprintf(stderr, - "InnoDB: Scanning backward trying to find previous allocated mem blocks\n"); + fputs("\nInnoDB: Scanning backward trying to find previous allocated mem blocks\n", stderr); p = ptr; dist = 0; diff --git a/innobase/mtr/mtr0log.c b/innobase/mtr/mtr0log.c index e3ba531bcb8..82baa8905ba 100644 --- a/innobase/mtr/mtr0log.c +++ b/innobase/mtr/mtr0log.c @@ -54,15 +54,15 @@ mlog_write_initial_log_record( byte* log_ptr; ut_ad(type <= MLOG_BIGGEST_TYPE); + ut_ad(type > MLOG_8BYTES); if (ptr < buf_pool->frame_zero || ptr >= buf_pool->high_end) { fprintf(stderr, - "InnoDB: Error: trying to write to a stray memory location %lx\n", - (ulint)ptr); + "InnoDB: Error: trying to write to a stray memory location %p\n", ptr); ut_error; } - log_ptr = mlog_open(mtr, 20); + log_ptr = mlog_open(mtr, 11); /* If no logging is requested, we may return now */ if (log_ptr == NULL) { @@ -221,8 +221,7 @@ mlog_write_ulint( if (ptr < buf_pool->frame_zero || ptr >= buf_pool->high_end) { fprintf(stderr, - "InnoDB: Error: trying to write to a stray memory location %lx\n", - (ulint)ptr); + "InnoDB: Error: trying to write to a stray memory location %p\n", ptr); ut_error; } @@ -268,8 +267,7 @@ mlog_write_dulint( if (ptr < buf_pool->frame_zero || ptr >= buf_pool->high_end) { fprintf(stderr, - "InnoDB: Error: trying to write to a stray memory location %lx\n", - (ulint)ptr); + "InnoDB: Error: trying to write to a stray memory location %p\n", ptr); ut_error; } @@ -312,8 +310,7 @@ mlog_write_string( if (ptr < buf_pool->frame_zero || ptr >= buf_pool->high_end) { fprintf(stderr, - "InnoDB: Error: trying to write to a stray memory location %lx\n", - (ulint)ptr); + "InnoDB: Error: trying to write to a stray memory location %p\n", ptr); ut_error; } ut_ad(ptr && mtr); diff --git a/innobase/mtr/mtr0mtr.c b/innobase/mtr/mtr0mtr.c index b2d8d022f8c..aaf2c9601f4 100644 --- a/innobase/mtr/mtr0mtr.c +++ b/innobase/mtr/mtr0mtr.c @@ -262,7 +262,8 @@ mtr_first_to_modify_page_after_backup( block->frame), backup_lsn) <= 0) { - printf("Page %lu newest %lu backup %lu\n", + fprintf(stderr, + "Page %lu newest %lu backup %lu\n", block->offset, ut_dulint_get_low( buf_frame_get_newest_modification( @@ -515,7 +516,7 @@ mtr_print( /*======*/ mtr_t* mtr) /* in: mtr */ { - printf( + fprintf(stderr, "Mini-transaction handle: memo size %lu bytes log size %lu bytes\n", dyn_array_get_data_size(&(mtr->memo)), dyn_array_get_data_size(&(mtr->log))); diff --git a/innobase/os/os0file.c b/innobase/os/os0file.c index acc6492fefc..50c15bcbd41 100644 --- a/innobase/os/os0file.c +++ b/innobase/os/os0file.c @@ -212,7 +212,7 @@ os_file_get_last_error(void) ut_print_timestamp(stderr); fprintf(stderr, " InnoDB: Operating system error number %lu in a file operation.\n" - "InnoDB: See http://www.innodb.com/ibman.html for installation help.\n", + "InnoDB: See http://www.innodb.com/ibman.php for installation help.\n", err); if (err == ERROR_PATH_NOT_FOUND) { @@ -227,7 +227,7 @@ os_file_get_last_error(void) "InnoDB: of the same name as a data file.\n"); } else { fprintf(stderr, - "InnoDB: See section 13.2 at http://www.innodb.com/ibman.html\n" + "InnoDB: See section 13.2 at http://www.innodb.com/ibman.php\n" "InnoDB: about operating system error numbers.\n"); } } @@ -251,7 +251,7 @@ os_file_get_last_error(void) fprintf(stderr, " InnoDB: Operating system error number %lu in a file operation.\n" - "InnoDB: See http://www.innodb.com/ibman.html for installation help.\n", + "InnoDB: See http://www.innodb.com/ibman.php for installation help.\n", err); if (err == ENOENT) { @@ -270,7 +270,7 @@ os_file_get_last_error(void) } fprintf(stderr, - "InnoDB: See also section 13.2 at http://www.innodb.com/ibman.html\n" + "InnoDB: See also section 13.2 at http://www.innodb.com/ibman.php\n" "InnoDB: about operating system error numbers.\n"); } } @@ -733,7 +733,7 @@ try_again: ut_error; } -/* printf("Opening file %s, mode %s, type %s, purpose %s\n", +/* fprintf(stderr, "Opening file %s, mode %s, type %s, purpose %s\n", name, mode_str, type_str, purpose_str); */ #ifdef O_SYNC /* We let O_SYNC only affect log files; note that we map O_DSYNC to @@ -742,7 +742,7 @@ try_again: if (type == OS_LOG_FILE && srv_unix_file_flush_method == SRV_UNIX_O_DSYNC) { -/* printf("Using O_SYNC for file %s\n", name); */ +/* fprintf(stderr, "Using O_SYNC for file %s\n", name); */ create_flag = create_flag | O_SYNC; } @@ -752,7 +752,7 @@ try_again: if (type != OS_LOG_FILE && srv_unix_file_flush_method == SRV_UNIX_O_DIRECT) { -/* printf("Using O_DIRECT for file %s\n", name); */ +/* fprintf(stderr, "Using O_DIRECT for file %s\n", name); */ create_flag = create_flag | O_DIRECT; } @@ -1025,7 +1025,7 @@ os_file_flush( #ifdef HAVE_FDATASYNC ret = fdatasync(file); #else -/* printf("Flushing to file %lu\n", (ulint)file); */ +/* fprintf(stderr, "Flushing to file %p\n", file); */ ret = fsync(file); #endif os_n_fsyncs++; @@ -1382,7 +1382,7 @@ retry: fprintf(stderr, " InnoDB: Error: File pointer positioning to file %s failed at\n" "InnoDB: offset %lu %lu. Operating system error number %lu.\n" -"InnoDB: Look from section 13.2 at http://www.innodb.com/ibman.html\n" +"InnoDB: Look from section 13.2 at http://www.innodb.com/ibman.php\n" "InnoDB: what the error number means.\n", name, offset_high, offset, (ulint)GetLastError()); @@ -1440,7 +1440,7 @@ retry: } fprintf(stderr, -"InnoDB: See also section 13.2 at http://www.innodb.com/ibman.html\n" +"InnoDB: See also section 13.2 at http://www.innodb.com/ibman.php\n" "InnoDB: about operating system error numbers.\n"); os_has_said_disk_full = TRUE; @@ -1475,7 +1475,7 @@ retry: } fprintf(stderr, -"InnoDB: See also section 13.2 at http://www.innodb.com/ibman.html\n" +"InnoDB: See also section 13.2 at http://www.innodb.com/ibman.php\n" "InnoDB: about operating system error numbers.\n"); os_has_said_disk_full = TRUE; @@ -1593,7 +1593,7 @@ os_aio_init( n_write_segs = (n_segments - 2) / 2; n_read_segs = n_segments - 2 - n_write_segs; - /* printf("Array n per seg %lu\n", n_per_seg); */ + /* fprintf(stderr, "Array n per seg %lu\n", n_per_seg); */ os_aio_ibuf_array = os_aio_array_create(n_per_seg, 1); @@ -1944,7 +1944,8 @@ loop: SIGRTMIN + 1 + os_aio_get_array_no(array); /* TODO: How to choose the signal numbers? */ /* - printf("AIO signal number %lu\n", (ulint) control->aio_sigevent.sigev_signo); + fprintf(stderr, "AIO signal number %lu\n", + (ulint) control->aio_sigevent.sigev_signo); */ control->aio_sigevent.sigev_value.sival_ptr = slot; #endif @@ -2198,7 +2199,7 @@ try_again: #elif defined(POSIX_ASYNC_IO) slot->control.aio_lio_opcode = LIO_READ; err = (ulint) aio_read(&(slot->control)); - printf("Starting Posix aio read %lu\n", err); + fprintf(stderr, "Starting POSIX aio read %lu\n", err); #endif } else { if (!wake_later) { @@ -2215,7 +2216,7 @@ try_again: #elif defined(POSIX_ASYNC_IO) slot->control.aio_lio_opcode = LIO_WRITE; err = (ulint) aio_write(&(slot->control)); - printf("Starting Posix aio write %lu\n", err); + fprintf(stderr, "Starting POSIX aio write %lu\n", err); #endif } else { if (!wake_later) { @@ -2411,7 +2412,7 @@ os_aio_posix_handle( pthread_sigmask(0, NULL, &thr_sigset); for (i = 32 ; i < 40; i++) { - printf("%lu : %lu %lu\n", (ulint)i, + fprintf(stderr, "%lu : %lu %lu\n", (ulint)i, (ulint)sigismember(&proc_sigset, i), (ulint)sigismember(&thr_sigset, i)); } @@ -2426,7 +2427,7 @@ os_aio_posix_handle( return(FALSE); } - printf("Handling Posix aio\n"); + fputs("Handling POSIX aio\n", stderr); array = os_aio_get_array_from_no(array_no); @@ -2719,9 +2720,9 @@ consecutive_loop: ut_a(ret); srv_set_io_thread_op_info(global_segment, "file i/o done"); -/* printf("aio: %lu consecutive %lu:th segment, first offs %lu blocks\n", - n_consecutive, global_segment, slot->offset - / UNIV_PAGE_SIZE); */ +/* fprintf(stderr, + "aio: %lu consecutive %lu:th segment, first offs %lu blocks\n", + n_consecutive, global_segment, slot->offset / UNIV_PAGE_SIZE); */ if (slot->type == OS_FILE_READ && n_consecutive > 1) { /* Copy the combined buffer to individual buffers */ @@ -2847,8 +2848,7 @@ Prints info of the aio arrays. */ void os_aio_print( /*=========*/ - char* buf, /* in/out: buffer where to print */ - char* buf_end)/* in: buffer end */ + FILE* file) /* in: file where to print */ { os_aio_array_t* array; os_aio_slot_t* slot; @@ -2858,18 +2858,13 @@ os_aio_print( double avg_bytes_read; ulint i; - if (buf_end - buf < 1200) { - - return; - } - for (i = 0; i < srv_n_file_io_threads; i++) { - buf += sprintf(buf, "I/O thread %lu state: %s (%s)\n", i, + fprintf(file, "I/O thread %lu state: %s (%s)\n", i, srv_io_thread_op_info[i], srv_io_thread_function[i]); } - buf += sprintf(buf, "Pending normal aio reads:"); + fputs("Pending normal aio reads:", file); array = os_aio_read_array; loop: @@ -2887,21 +2882,20 @@ loop: if (slot->reserved) { n_reserved++; - /* printf("Reserved slot, messages %lx %lx\n", - (ulint)slot->message1, - (ulint)slot->message2); - */ ut_a(slot->len > 0); + /* fprintf(stderr, "Reserved slot, messages %p %p\n", + slot->message1, slot->message2); */ + ut_a(slot->len > 0); } } ut_a(array->n_reserved == n_reserved); - buf += sprintf(buf, " %lu", n_reserved); + fprintf(file, " %lu", n_reserved); os_mutex_exit(array->mutex); if (array == os_aio_read_array) { - buf += sprintf(buf, ", aio writes:"); + fputs(", aio writes:", file); array = os_aio_write_array; @@ -2909,40 +2903,38 @@ loop: } if (array == os_aio_write_array) { - buf += sprintf(buf, ",\n ibuf aio reads:"); + fputs(",\n ibuf aio reads:", file); array = os_aio_ibuf_array; goto loop; } if (array == os_aio_ibuf_array) { - buf += sprintf(buf, ", log i/o's:"); + fputs(", log i/o's:", file); array = os_aio_log_array; goto loop; } if (array == os_aio_log_array) { - buf += sprintf(buf, ", sync i/o's:"); + fputs(", sync i/o's:", file); array = os_aio_sync_array; goto loop; } - buf += sprintf(buf, "\n"); - + putc('\n', file); current_time = time(NULL); time_elapsed = 0.001 + difftime(current_time, os_last_printout); - buf += sprintf(buf, - "Pending flushes (fsync) log: %lu; buffer pool: %lu\n", - fil_n_pending_log_flushes, fil_n_pending_tablespace_flushes); - buf += sprintf(buf, + fprintf(file, + "Pending flushes (fsync) log: %lu; buffer pool: %lu\n" "%lu OS file reads, %lu OS file writes, %lu OS fsyncs\n", + fil_n_pending_log_flushes, fil_n_pending_tablespace_flushes, os_n_file_reads, os_n_file_writes, os_n_fsyncs); if (os_file_n_pending_preads != 0 || os_file_n_pending_pwrites != 0) { - buf += sprintf(buf, + fprintf(file, "%lu pending preads, %lu pending pwrites\n", os_file_n_pending_preads, os_file_n_pending_pwrites); } @@ -2954,7 +2946,7 @@ loop: (os_n_file_reads - os_n_file_reads_old); } - buf += sprintf(buf, + fprintf(file, "%.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, diff --git a/innobase/os/os0proc.c b/innobase/os/os0proc.c index 2099d62e7fd..87a0bfb9e92 100644 --- a/innobase/os/os0proc.c +++ b/innobase/os/os0proc.c @@ -81,9 +81,8 @@ os_process_set_priority_boost( /* Does not do anything currently! SetProcessPriorityBoost(GetCurrentProcess(), no_boost); */ - printf( - "Warning: process priority boost setting currently not functional!\n" - ); + fputs("Warning: process priority boost setting currently not functional!\n", + stderr); #else UT_NOT_USED(do_boost); #endif diff --git a/innobase/os/os0thread.c b/innobase/os/os0thread.c index 1252cc5e4b7..59d0fdbd8c9 100644 --- a/innobase/os/os0thread.c +++ b/innobase/os/os0thread.c @@ -187,7 +187,7 @@ os_thread_exit( is cast as a DWORD */ { #ifdef UNIV_DEBUG_THREAD_CREATION - printf("Thread exits, id %lu\n", + fprintf(stderr, "Thread exits, id %lu\n", os_thread_pf(os_thread_get_curr_id())); #endif os_mutex_enter(os_sync_mutex); diff --git a/innobase/page/page0cur.c b/innobase/page/page0cur.c index ce9e4327c18..fd613d5d9e7 100644 --- a/innobase/page/page0cur.c +++ b/innobase/page/page0cur.c @@ -704,14 +704,16 @@ page_cur_parse_insert_rec( /* Build the inserted record to buf */ if (mismatch_index >= UNIV_PAGE_SIZE) { - printf("Is short %lu, info_bits %lu, offset %lu, o_offset %lu\n" + fprintf(stderr, + "Is short %lu, info_bits %lu, offset %lu, " + "o_offset %lu\n" "mismatch index %lu, end_seg_len %lu\n" "parsed len %lu\n", is_short, info_bits, offset, origin_offset, mismatch_index, end_seg_len, (ulint)(ptr - ptr2)); - printf("Dump of 300 bytes of log:\n"); - ut_print_buf(ptr2, 300); + fputs("Dump of 300 bytes of log:\n", stderr); + ut_print_buf(stderr, ptr2, 300); buf_page_print(page); diff --git a/innobase/page/page0page.c b/innobase/page/page0page.c index 7ebcb853448..76a0a950178 100644 --- a/innobase/page/page0page.c +++ b/innobase/page/page0page.c @@ -75,7 +75,6 @@ page_dir_find_owner_slot( page_t* page; page_dir_slot_t* slot; rec_t* original_rec = rec; - char err_buf[1000]; ut_ad(page_rec_check(rec)); @@ -93,20 +92,21 @@ page_dir_find_owner_slot( if (i == 0) { fprintf(stderr, - "InnoDB: Probable data corruption on page %lu\n", + "InnoDB: Probable data corruption on page %lu\n" + "InnoDB: Original record ", buf_frame_get_page_no(page)); - rec_sprintf(err_buf, 900, original_rec); + rec_print(stderr, original_rec); - fprintf(stderr, - "InnoDB: Original record %s\n" - "InnoDB: on that page. Steps %lu.\n", err_buf, steps); + fprintf(stderr, "\n" + "InnoDB: on that page. Steps %lu.\n", steps); - rec_sprintf(err_buf, 900, rec); - - fprintf(stderr, - "InnoDB: Cannot find the dir slot for record %s\n" - "InnoDB: on that page!\n", err_buf); + fputs( + "InnoDB: Cannot find the dir slot for record ", + stderr); + rec_print(stderr, rec); + fputs("\n" + "InnoDB: on that page!\n", stderr); buf_page_print(page); @@ -1120,8 +1120,8 @@ page_rec_print( /*===========*/ rec_t* rec) { - rec_print(rec); - printf( + rec_print(stderr, rec); + fprintf(stderr, " n_owned: %lu; heap_no: %lu; next rec: %lu\n", rec_get_n_owned(rec), rec_get_heap_no(rec), @@ -1147,25 +1147,26 @@ page_dir_print( n = page_dir_get_n_slots(page); - printf("--------------------------------\n"); - printf("PAGE DIRECTORY\n"); - printf("Page address %lx\n", (ulint)page); - printf("Directory stack top at offs: %lu; number of slots: %lu\n", - (ulint)(page_dir_get_nth_slot(page, n - 1) - page), n); + fprintf(stderr, "--------------------------------\n" + "PAGE DIRECTORY\n" + "Page address %p\n" + "Directory stack top at offs: %lu; number of slots: %lu\n", + page, (ulint)(page_dir_get_nth_slot(page, n - 1) - page), n); for (i = 0; i < n; i++) { slot = page_dir_get_nth_slot(page, i); if ((i == pr_n) && (i < n - pr_n)) { - printf(" ... \n"); + fputs(" ... \n", stderr); } if ((i < pr_n) || (i >= n - pr_n)) { - printf( + fprintf(stderr, "Contents of slot: %lu: n_owned: %lu, rec offs: %lu\n", i, page_dir_slot_get_n_owned(slot), (ulint)(page_dir_slot_get_rec(slot) - page)); } } - printf("Total of %lu records\n", 2 + page_get_n_recs(page)); - printf("--------------------------------\n"); + fprintf(stderr, "Total of %lu records\n" + "--------------------------------\n", + 2 + page_get_n_recs(page)); } /******************************************************************* @@ -1179,21 +1180,20 @@ page_print_list( ulint pr_n) /* in: print n first and n last entries */ { page_cur_t cur; - rec_t* rec; ulint count; ulint n_recs; - printf("--------------------------------\n"); - printf("PAGE RECORD LIST\n"); - printf("Page address %lu\n", (ulint)page); + fprintf(stderr, + "--------------------------------\n" + "PAGE RECORD LIST\n" + "Page address %p\n", page); n_recs = page_get_n_recs(page); page_cur_set_before_first(page, &cur); count = 0; for (;;) { - rec = (&cur)->rec; - page_rec_print(rec); + page_rec_print(cur.rec); if (count == pr_n) { break; @@ -1206,24 +1206,22 @@ page_print_list( } if (n_recs > 2 * pr_n) { - printf(" ... \n"); + fputs(" ... \n", stderr); } - for (;;) { - if (page_cur_is_after_last(&cur)) { - break; - } + while (!page_cur_is_after_last(&cur)) { page_cur_move_to_next(&cur); if (count + pr_n >= n_recs) { - rec = (&cur)->rec; - page_rec_print(rec); + page_rec_print(cur.rec); } count++; } - printf("Total of %lu records \n", count + 1); - printf("--------------------------------\n"); + fprintf(stderr, + "Total of %lu records \n" + "--------------------------------\n", + count + 1); } /******************************************************************* @@ -1234,21 +1232,19 @@ page_header_print( /*==============*/ page_t* page) { - printf("--------------------------------\n"); - printf("PAGE HEADER INFO\n"); - printf("Page address %lx, n records %lu\n", (ulint)page, - page_header_get_field(page, PAGE_N_RECS)); - - printf("n dir slots %lu, heap top %lu\n", + fprintf(stderr, + "--------------------------------\n" + "PAGE HEADER INFO\n" + "Page address %p, n records %lu\n" + "n dir slots %lu, heap top %lu\n" + "Page n heap %lu, free %lu, garbage %lu\n" + "Page last insert %lu, direction %lu, n direction %lu\n", + page, page_header_get_field(page, PAGE_N_RECS), page_header_get_field(page, PAGE_N_DIR_SLOTS), - page_header_get_field(page, PAGE_HEAP_TOP)); - - printf("Page n heap %lu, free %lu, garbage %lu\n", + page_header_get_field(page, PAGE_HEAP_TOP), page_header_get_field(page, PAGE_N_HEAP), page_header_get_field(page, PAGE_FREE), - page_header_get_field(page, PAGE_GARBAGE)); - - printf("Page last insert %lu, direction %lu, n direction %lu\n", + page_header_get_field(page, PAGE_GARBAGE), page_header_get_field(page, PAGE_LAST_INSERT), page_header_get_field(page, PAGE_DIRECTION), page_header_get_field(page, PAGE_N_DIRECTION)); @@ -1555,17 +1551,9 @@ page_validate( ulint n_slots; ibool ret = FALSE; ulint i; - char err_buf[1000]; if (!page_simple_validate(page)) { - fprintf(stderr, -"InnoDB: Apparent corruption in page %lu in index %s in table %s\n", - buf_frame_get_page_no(page), index->name, - index->table_name); - - buf_page_print(page); - - return(FALSE); + goto func_exit2; } heap = mem_heap_create(UNIV_PAGE_SIZE); @@ -1585,10 +1573,13 @@ page_validate( if (!(page_header_get_ptr(page, PAGE_HEAP_TOP) <= page_dir_get_nth_slot(page, n_slots - 1))) { - fprintf(stderr, -"InnoDB: Record heap and dir overlap on a page in index %s, %lu, %lu\n", - index->name, (ulint)page_header_get_ptr(page, PAGE_HEAP_TOP), - (ulint)page_dir_get_nth_slot(page, n_slots - 1)); + + fputs("InnoDB: Record heap and dir overlap on a page ", + stderr); + dict_index_name_print(stderr, index); + fprintf(stderr, ", %p, %p\n", + page_header_get_ptr(page, PAGE_HEAP_TOP), + page_dir_get_nth_slot(page, n_slots - 1)); goto func_exit; } @@ -1614,18 +1605,14 @@ page_validate( if ((count >= 2) && (!page_cur_is_after_last(&cur))) { if (!(1 == cmp_rec_rec(rec, old_rec, index))) { fprintf(stderr, -"InnoDB: Records in wrong order on page %lu index %s table %s\n", - buf_frame_get_page_no(page), - index->name, - index->table_name); - - rec_sprintf(err_buf, 900, old_rec); - fprintf(stderr, - "InnoDB: previous record %s\n", err_buf); - - rec_sprintf(err_buf, 900, rec); - fprintf(stderr, - "InnoDB: record %s\n", err_buf); + "InnoDB: Records in wrong order on page %lu", + buf_frame_get_page_no(page)); + dict_index_name_print(stderr, index); + fputs("\nInnoDB: previous record ", stderr); + rec_print(stderr, old_rec); + fputs("\nInnoDB: record ", stderr); + rec_print(stderr, rec); + putc('\n', stderr); goto func_exit; } @@ -1643,10 +1630,8 @@ page_validate( if (!buf[offs + i] == 0) { /* No other record may overlap this */ - fprintf(stderr, - "InnoDB: Record overlaps another in index %s \n", - index->name); - + fputs("InnoDB: Record overlaps another\n", + stderr); goto func_exit; } @@ -1657,18 +1642,15 @@ page_validate( /* This is a record pointed to by a dir slot */ if (rec_get_n_owned(rec) != own_count) { fprintf(stderr, - "InnoDB: Wrong owned count %lu, %lu, in index %s\n", - rec_get_n_owned(rec), own_count, - index->name); - + "InnoDB: Wrong owned count %lu, %lu\n", + rec_get_n_owned(rec), own_count); goto func_exit; } if (page_dir_slot_get_rec(slot) != rec) { - fprintf(stderr, - "InnoDB: Dir slot does not point to right rec in %s\n", - index->name); - + fputs( + "InnoDB: Dir slot does not point to right rec\n", + stderr); goto func_exit; } @@ -1688,9 +1670,8 @@ page_validate( if (rec_get_next_offs(rec) < FIL_PAGE_DATA || rec_get_next_offs(rec) >= UNIV_PAGE_SIZE) { fprintf(stderr, - "InnoDB: Next record offset wrong %lu in index %s\n", - rec_get_next_offs(rec), index->name); - + "InnoDB: Next record offset wrong %lu\n", + rec_get_next_offs(rec)); goto func_exit; } @@ -1701,23 +1682,19 @@ page_validate( } if (rec_get_n_owned(rec) == 0) { - fprintf(stderr, - "InnoDB: n owned is zero in index %s\n", index->name); - + fputs("InnoDB: n owned is zero\n", stderr); goto func_exit; } if (slot_no != n_slots - 1) { - fprintf(stderr, "InnoDB: n slots wrong %lu %lu in index %s\n", - slot_no, n_slots - 1, index->name); + fprintf(stderr, "InnoDB: n slots wrong %lu %lu\n", + slot_no, n_slots - 1); goto func_exit; } if (page_header_get_field(page, PAGE_N_RECS) + 2 != count + 1) { - fprintf(stderr, "InnoDB: n recs wrong %lu %lu in index %s\n", - page_header_get_field(page, PAGE_N_RECS) + 2, count + 1, - index->name); - + fprintf(stderr, "InnoDB: n recs wrong %lu %lu\n", + page_header_get_field(page, PAGE_N_RECS) + 2, count + 1); goto func_exit; } @@ -1743,10 +1720,8 @@ page_validate( for (i = 0; i < rec_get_size(rec); i++) { if (buf[offs + i] != 0) { - fprintf(stderr, - "InnoDB: Record overlaps another in free list, index %s \n", - index->name); - + fputs( + "InnoDB: Record overlaps another in free list\n", stderr); goto func_exit; } @@ -1757,11 +1732,8 @@ page_validate( } if (page_header_get_field(page, PAGE_N_HEAP) != count + 1) { - - fprintf(stderr, - "InnoDB: N heap is wrong %lu %lu in index %s\n", - page_header_get_field(page, PAGE_N_HEAP), count + 1, - index->name); + fprintf(stderr, "InnoDB: N heap is wrong %lu %lu\n", + page_header_get_field(page, PAGE_N_HEAP), count + 1); goto func_exit; } @@ -1771,11 +1743,11 @@ func_exit: mem_heap_free(heap); if (ret == FALSE) { - fprintf(stderr, -"InnoDB: Apparent corruption in page %lu in index %s in table %s\n", - buf_frame_get_page_no(page), index->name, - index->table_name); - + func_exit2: + fprintf(stderr, "InnoDB: Apparent corruption in page %lu in ", + buf_frame_get_page_no(page)); + dict_index_name_print(stderr, index); + putc('\n', stderr); buf_page_print(page); } diff --git a/innobase/pars/pars0opt.c b/innobase/pars/pars0opt.c index e9ed59e5c00..5cc2e39b438 100644 --- a/innobase/pars/pars0opt.c +++ b/innobase/pars/pars0opt.c @@ -1202,26 +1202,22 @@ opt_print_query_plan( ulint n_fields; ulint i; - printf("QUERY PLAN FOR A SELECT NODE\n"); + fputs("QUERY PLAN FOR A SELECT NODE\n", stderr); - if (sel_node->asc) { - printf("Asc. search; "); - } else { - printf("Desc. search; "); - } + fputs(sel_node->asc ? "Asc. search; " : "Desc. search; ", stderr); if (sel_node->set_x_locks) { - printf("sets row x-locks; "); + fputs("sets row x-locks; ", stderr); ut_a(sel_node->row_lock_mode == LOCK_X); ut_a(!sel_node->consistent_read); } else if (sel_node->consistent_read) { - printf("consistent read; "); + fputs("consistent read; ", stderr); } else { ut_a(sel_node->row_lock_mode == LOCK_S); - printf("sets row s-locks; "); + fputs("sets row s-locks; ", stderr); } - printf("\n"); + putc('\n', stderr); for (i = 0; i < sel_node->n_tables; i++) { plan = sel_node_get_nth_plan(sel_node, i); @@ -1232,9 +1228,9 @@ opt_print_query_plan( n_fields = 0; } - printf( - "Table %s index %s; exact m. %lu, match %lu, end conds %lu\n", - plan->table->name, plan->index->name, + fputs("Table ", stderr); + dict_index_name_print(stderr, plan->index); + fprintf(stderr,"; exact m. %lu, match %lu, end conds %lu\n", plan->n_exact_match, n_fields, UT_LIST_GET_LEN(plan->end_conds)); } diff --git a/innobase/rem/rem0rec.c b/innobase/rem/rem0rec.c index fddc8eab761..b9fa840d66d 100644 --- a/innobase/rem/rem0rec.c +++ b/innobase/rem/rem0rec.c @@ -112,7 +112,7 @@ rec_get_nth_field( } if (rec == NULL) { - fprintf(stderr, "Error: rec is NULL pointer\n"); + fputs("Error: rec is NULL pointer\n", stderr); ut_error; } @@ -517,109 +517,47 @@ Prints a physical record. */ void rec_print( /*======*/ + FILE* file, /* in: file where to print */ rec_t* rec) /* in: physical record */ { byte* data; ulint len; - char* offs; ulint n; ulint i; ut_ad(rec); - if (rec_get_1byte_offs_flag(rec)) { - offs = (char *) "TRUE"; - } else { - offs = (char *) "FALSE"; - } - n = rec_get_n_fields(rec); - printf( - "PHYSICAL RECORD: n_fields %lu; 1-byte offs %s; info bits %lu\n", - n, offs, rec_get_info_bits(rec)); + fprintf(file, "PHYSICAL RECORD: n_fields %lu;" + " 1-byte offs %s; info bits %lu\n", + n, rec_get_1byte_offs_flag(rec) ? "TRUE" : "FALSE", + rec_get_info_bits(rec)); for (i = 0; i < n; i++) { data = rec_get_nth_field(rec, i, &len); - printf(" %lu:", i); + fprintf(file, " %lu:", i); if (len != UNIV_SQL_NULL) { if (len <= 30) { - ut_print_buf(data, len); + ut_print_buf(file, data, len); } else { - ut_print_buf(data, 30); + ut_print_buf(file, data, 30); - printf("...(truncated)"); + fputs("...(truncated)", file); } } else { - printf(" SQL NULL, size %lu ", + fprintf(file, " SQL NULL, size %lu ", rec_get_nth_field_size(rec, i)); } - printf(";"); + putc(';', file); } - printf("\n"); + putc('\n', file); rec_validate(rec); } - -/******************************************************************* -Prints a physical record to a buffer. */ - -ulint -rec_sprintf( -/*========*/ - /* out: printed length in bytes */ - char* buf, /* in: buffer to print to */ - ulint buf_len,/* in: buffer length */ - rec_t* rec) /* in: physical record */ -{ - byte* data; - ulint len; - ulint k; - ulint n; - ulint i; - - ut_ad(rec); - - n = rec_get_n_fields(rec); - k = 0; - - if (k + 30 > buf_len) { - - return(k); - } - - k += sprintf(buf + k, "RECORD: info bits %lu", rec_get_info_bits(rec)); - - for (i = 0; i < n; i++) { - - if (k + 30 > buf_len) { - - return(k); - } - - data = rec_get_nth_field(rec, i, &len); - - k += sprintf(buf + k, " %lu:", i); - - if (len != UNIV_SQL_NULL) { - if (k + 30 + 5 * len > buf_len) { - - return(k); - } - - k += ut_sprintf_buf(buf + k, data, len); - } else { - k += sprintf(buf + k, " SQL NULL"); - } - - k += sprintf(buf + k, ";"); - } - - return(k); -} diff --git a/innobase/row/row0ins.c b/innobase/row/row0ins.c index 590d2b52e07..8bc6c9697c1 100644 --- a/innobase/row/row0ins.c +++ b/innobase/row/row0ins.c @@ -528,34 +528,37 @@ row_ins_foreign_report_err( dtuple_t* entry) /* in: index entry in the parent table */ { - char* buf = dict_foreign_err_buf; + FILE* ef = dict_foreign_err_file; mutex_enter(&dict_foreign_err_mutex); - ut_sprintf_timestamp(buf); - sprintf(buf + strlen(buf), " Transaction:\n"); - trx_print(buf + strlen(buf), thr_get_trx(thr)); + rewind(ef); + ut_print_timestamp(ef); + fputs(" Transaction:\n", ef); + trx_print(ef, thr_get_trx(thr)); - sprintf(buf + strlen(buf), -"Foreign key constraint fails for table %.500s:\n", - foreign->foreign_table_name); - dict_print_info_on_foreign_key_in_create_format( - foreign, buf + strlen(buf)); - sprintf(buf + strlen(buf), "\n%s", errstr); - sprintf(buf + strlen(buf), -" in parent table, in index %.500s tuple:\n", - foreign->referenced_index->name); + fputs("Foreign key constraint fails for table ", ef); + ut_print_name(ef, foreign->foreign_table_name); + fputs(":\n", ef); + dict_print_info_on_foreign_key_in_create_format(ef, foreign); + putc('\n', ef); + fputs(errstr, ef); + fputs(" in parent table, in index ", ef); + ut_print_name(ef, foreign->referenced_index->name); if (entry) { - dtuple_sprintf(buf + strlen(buf), 1000, entry); + fputs(" tuple:\n", ef); + dtuple_print(ef, entry); } - sprintf(buf + strlen(buf), -"\nBut in child table %.500s, in index %.500s, there is a record:\n", - foreign->foreign_table_name, foreign->foreign_index->name); + fputs("\nBut in child table ", ef); + ut_print_name(ef, foreign->foreign_table_name); + fputs(", in index ", ef); + ut_print_name(ef, foreign->foreign_index->name); if (rec) { - rec_sprintf(buf + strlen(buf), 1000, rec); + fputs(", there is a record:\n", ef); + rec_print(ef, rec); + } else { + fputs(", the record is not available\n", ef); } - sprintf(buf + strlen(buf), "\n"); - - ut_a(strlen(buf) < DICT_FOREIGN_ERR_BUF_LEN); + putc('\n', ef); mutex_exit(&dict_foreign_err_mutex); } @@ -576,28 +579,28 @@ row_ins_foreign_report_add_err( dtuple_t* entry) /* in: index entry to insert in the child table */ { - char* buf = dict_foreign_err_buf; + FILE* ef = dict_foreign_err_file; mutex_enter(&dict_foreign_err_mutex); - ut_sprintf_timestamp(buf); - sprintf(buf + strlen(buf), " Transaction:\n"); - trx_print(buf + strlen(buf), trx); - sprintf(buf + strlen(buf), -"Foreign key constraint fails for table %.500s:\n", - foreign->foreign_table_name); - dict_print_info_on_foreign_key_in_create_format( - foreign, buf + strlen(buf)); - sprintf(buf + strlen(buf), -"\nTrying to add in child table, in index %.500s tuple:\n", - foreign->foreign_index->name); + rewind(ef); + ut_print_timestamp(ef); + fputs(" Transaction:\n", ef); + trx_print(ef, trx); + fputs("Foreign key constraint fails for table ", ef); + ut_print_name(ef, foreign->foreign_table_name); + fputs(":\n", ef); + dict_print_info_on_foreign_key_in_create_format(ef, foreign); + fputs("\nTrying to add in child table, in index ", ef); + ut_print_name(ef, foreign->foreign_index->name); if (entry) { - dtuple_sprintf(buf + strlen(buf), 1000, entry); + fputs(" tuple:\n", ef); + dtuple_print(ef, entry); } - sprintf(buf + strlen(buf), -"\nBut in parent table %.500s, in index %.500s,\n" -"the closest match we can find is record:\n", - foreign->referenced_table_name, - foreign->referenced_index->name); + fputs("\nBut in parent table ", ef); + ut_print_name(ef, foreign->referenced_table_name); + fputs(", in index ", ef); + ut_print_name(ef, foreign->referenced_index->name); + fputs(",\nthe closest match we can find is record:\n", ef); if (rec && page_rec_is_supremum(rec)) { /* If the cursor ended on a supremum record, it is better to report the previous record in the error message, so that @@ -606,11 +609,9 @@ row_ins_foreign_report_add_err( } if (rec) { - rec_sprintf(buf + strlen(buf), 1000, rec); + rec_print(ef, rec); } - sprintf(buf + strlen(buf), "\n"); - - ut_a(strlen(buf) < DICT_FOREIGN_ERR_BUF_LEN); + putc('\n', ef); mutex_exit(&dict_foreign_err_mutex); } @@ -652,7 +653,6 @@ row_ins_foreign_check_on_constraint( ulint i; char* ptr; char table_name_buf[1000]; - char err_buf[1000]; ut_a(thr && foreign && pcur && mtr); @@ -791,20 +791,20 @@ row_ins_foreign_check_on_constraint( || btr_pcur_get_low_match(cascade->pcur) < dict_index_get_n_unique(clust_index)) { - fprintf(stderr, + fputs( "InnoDB: error in cascade of a foreign key op\n" - "InnoDB: index %s table %s\n", index->name, - index->table->name); + "InnoDB: ", stderr); + dict_index_name_print(stderr, index); - rec_sprintf(err_buf, 900, rec); - fprintf(stderr, "InnoDB: record %s\n", err_buf); - - rec_sprintf(err_buf, 900, clust_rec); - fprintf(stderr, "InnoDB: clustered record %s\n", - err_buf); - fprintf(stderr, - "InnoDB: Make a detailed bug report and send it\n"); - fprintf(stderr, "InnoDB: to mysql@lists.mysql.com\n"); + fputs("\n" + "InnoDB: record ", stderr); + rec_print(stderr, rec); + fputs("\n" + "InnoDB: clustered record ", stderr); + rec_print(stderr, clust_rec); + fputs("\n" + "InnoDB: Make a detailed bug report and send it\n" + "InnoDB: to mysql@lists.mysql.com\n", stderr); err = DB_SUCCESS; @@ -834,24 +834,6 @@ row_ins_foreign_check_on_constraint( /* This can happen if there is a circular reference of rows such that cascading delete comes to delete a row already in the process of being delete marked */ -/* - fprintf(stderr, - "InnoDB: error 2 in cascade of a foreign key op\n" - "InnoDB: index %s table %s\n", index->name, - index->table->name); - - rec_sprintf(err_buf, 900, rec); - fprintf(stderr, "InnoDB: record %s\n", err_buf); - - rec_sprintf(err_buf, 900, clust_rec); - fprintf(stderr, "InnoDB: clustered record %s\n", err_buf); - - fprintf(stderr, - "InnoDB: Make a detailed bug report and send it\n"); - fprintf(stderr, "InnoDB: to mysql@lists.mysql.com\n"); - - ut_error; -*/ err = DB_SUCCESS; goto nonstandard_exit_func; @@ -1022,7 +1004,6 @@ row_ins_check_foreign_constraint( int cmp; ulint err; ulint i; - char* buf = dict_foreign_err_buf; mtr_t mtr; run_again: @@ -1085,23 +1066,24 @@ run_again: if (check_table == NULL) { if (check_ref) { + FILE* ef = dict_foreign_err_file; mutex_enter(&dict_foreign_err_mutex); - ut_sprintf_timestamp(buf); - sprintf(buf + strlen(buf), " Transaction:\n"); - trx_print(buf + strlen(buf), thr_get_trx(thr)); - sprintf(buf + strlen(buf), -"Foreign key constraint fails for table %.500s:\n", - foreign->foreign_table_name); - dict_print_info_on_foreign_key_in_create_format( - foreign, buf + strlen(buf)); - sprintf(buf + strlen(buf), -"\nTrying to add to index %.500s tuple:\n", foreign->foreign_index->name); - dtuple_sprintf(buf + strlen(buf), 1000, entry); - sprintf(buf + strlen(buf), -"\nBut the parent table %.500s does not currently exist!\n", - foreign->referenced_table_name); - - ut_a(strlen(buf) < DICT_FOREIGN_ERR_BUF_LEN); + rewind(ef); + ut_print_timestamp(ef); + fputs(" Transaction:\n", ef); + trx_print(ef, thr_get_trx(thr)); + fputs("Foreign key constraint fails for table ", ef); + ut_print_name(ef, foreign->foreign_table_name); + fputs(":\n", ef); + dict_print_info_on_foreign_key_in_create_format(ef, + foreign); + fputs("\nTrying to add to index ", ef); + ut_print_name(ef, foreign->foreign_index->name); + fputs(" tuple:\n", ef); + dtuple_print(ef, entry); + fputs("\nBut the parent table ", ef); + ut_print_name(ef, foreign->referenced_table_name); + fputs(" does not currently exist!\n", ef); mutex_exit(&dict_foreign_err_mutex); return(DB_NO_REFERENCED_ROW); diff --git a/innobase/row/row0mysql.c b/innobase/row/row0mysql.c index eca586b3a0a..07c3f8c4867 100644 --- a/innobase/row/row0mysql.c +++ b/innobase/row/row0mysql.c @@ -296,22 +296,22 @@ handle_new_error: } else if (err == DB_MUST_GET_MORE_FILE_SPACE) { - fprintf(stderr, + fputs( "InnoDB: The database cannot continue operation because of\n" "InnoDB: lack of space. You must add a new data file to\n" - "InnoDB: my.cnf and restart the database.\n"); + "InnoDB: my.cnf and restart the database.\n", stderr); exit(1); } else if (err == DB_CORRUPTION) { - fprintf(stderr, + fputs( "InnoDB: We detected index corruption in an InnoDB type table.\n" "InnoDB: You have to dump + drop + reimport the table or, in\n" "InnoDB: a case of widespread corruption, dump all InnoDB\n" "InnoDB: tables and recreate the whole InnoDB tablespace.\n" "InnoDB: If the mysqld server crashes after the startup or when\n" "InnoDB: you dump the tables, look at section 6.1 of\n" - "InnoDB: http://www.innodb.com/ibman.html for help.\n"); + "InnoDB: http://www.innodb.com/ibman.php for help.\n", stderr); } else { fprintf(stderr, "InnoDB: unknown error code %lu\n", err); @@ -423,8 +423,10 @@ row_prebuilt_free( || prebuilt->magic_n2 != ROW_PREBUILT_ALLOCATED) { fprintf(stderr, "InnoDB: Error: trying to free a corrupt\n" -"InnoDB: table handle. Magic n %lu, magic n2 %lu, table name %s\n", - prebuilt->magic_n, prebuilt->magic_n2, prebuilt->table->name); +"InnoDB: table handle. Magic n %lu, magic n2 %lu, table name ", + prebuilt->magic_n, prebuilt->magic_n2); + ut_print_name(stderr, prebuilt->table->name); + putc('\n', stderr); mem_analyze_corruption((byte*)prebuilt); @@ -469,9 +471,9 @@ row_prebuilt_free( || (ROW_PREBUILT_FETCH_MAGIC_N != mach_read_from_4((prebuilt->fetch_cache[i]) + prebuilt->mysql_row_len))) { - fprintf(stderr, + fputs( "InnoDB: Error: trying to free a corrupt\n" - "InnoDB: fetch buffer.\n"); + "InnoDB: fetch buffer.\n", stderr); mem_analyze_corruption( prebuilt->fetch_cache[i]); @@ -514,8 +516,10 @@ row_update_prebuilt_trx( if (prebuilt->magic_n != ROW_PREBUILT_ALLOCATED) { fprintf(stderr, "InnoDB: Error: trying to use a corrupt\n" - "InnoDB: table handle. Magic n %lu, table name %s\n", - prebuilt->magic_n, prebuilt->table->name); + "InnoDB: table handle. Magic n %lu, table name ", + prebuilt->magic_n); + ut_print_name(stderr, prebuilt->table->name); + putc('\n', stderr); mem_analyze_corruption((byte*)prebuilt); @@ -741,8 +745,10 @@ row_insert_for_mysql( if (prebuilt->magic_n != ROW_PREBUILT_ALLOCATED) { fprintf(stderr, "InnoDB: Error: trying to free a corrupt\n" - "InnoDB: table handle. Magic n %lu, table name %s\n", - prebuilt->magic_n, prebuilt->table->name); + "InnoDB: table handle. Magic n %lu, table name ", + prebuilt->magic_n); + ut_print_name(stderr, prebuilt->table->name); + putc('\n', stderr); mem_analyze_corruption((byte*)prebuilt); @@ -750,12 +756,13 @@ row_insert_for_mysql( } if (srv_created_new_raw || srv_force_recovery) { - fprintf(stderr, + fputs( "InnoDB: A new raw disk partition was initialized or\n" "InnoDB: innodb_force_recovery is on: we do not allow\n" "InnoDB: database modifications by the user. Shut down\n" "InnoDB: mysqld and edit my.cnf so that newraw is replaced\n" - "InnoDB: with raw, and innodb_force_... is removed.\n"); + "InnoDB: with raw, and innodb_force_... is removed.\n", + stderr); return(DB_ERROR); } @@ -953,8 +960,10 @@ row_update_for_mysql( if (prebuilt->magic_n != ROW_PREBUILT_ALLOCATED) { fprintf(stderr, "InnoDB: Error: trying to free a corrupt\n" - "InnoDB: table handle. Magic n %lu, table name %s\n", - prebuilt->magic_n, prebuilt->table->name); + "InnoDB: table handle. Magic n %lu, table name ", + prebuilt->magic_n); + ut_print_name(stderr, prebuilt->table->name); + putc('\n', stderr); mem_analyze_corruption((byte*)prebuilt); @@ -962,12 +971,13 @@ row_update_for_mysql( } if (srv_created_new_raw || srv_force_recovery) { - fprintf(stderr, + fputs( "InnoDB: A new raw disk partition was initialized or\n" "InnoDB: innodb_force_recovery is on: we do not allow\n" "InnoDB: database modifications by the user. Shut down\n" "InnoDB: mysqld and edit my.cnf so that newraw is replaced\n" - "InnoDB: with raw, and innodb_force_... is removed.\n"); + "InnoDB: with raw, and innodb_force_... is removed.\n", + stderr); return(DB_ERROR); } @@ -1310,12 +1320,13 @@ row_create_table_for_mysql( ut_ad(trx->dict_operation_lock_mode == RW_X_LATCH); if (srv_created_new_raw) { - fprintf(stderr, + fputs( "InnoDB: A new raw disk partition was initialized or\n" "InnoDB: innodb_force_recovery is on: we do not allow\n" "InnoDB: database modifications by the user. Shut down\n" "InnoDB: mysqld and edit my.cnf so that newraw is replaced\n" - "InnoDB: with raw, and innodb_force_... is removed.\n"); + "InnoDB: with raw, and innodb_force_... is removed.\n", + stderr); trx_commit_for_mysql(trx); @@ -1390,16 +1401,17 @@ row_create_table_for_mysql( /* We define here a debugging feature intended for developers */ - printf("Validating InnoDB memory:\n" + fputs("Validating InnoDB memory:\n" "to use this feature you must compile InnoDB with\n" "UNIV_MEM_DEBUG defined in univ.i and the server must be\n" "quiet because allocation from a mem heap is not protected\n" - "by any semaphore.\n"); + "by any semaphore.\n", stderr); #ifdef UNIV_MEM_DEBUG ut_a(mem_validate()); - printf("Memory validated\n"); + fputs("Memory validated\n", stderr); #else /* UNIV_MEM_DEBUG */ - puts("Memory NOT validated (recompile with UNIV_MEM_DEBUG)"); + fputs("Memory NOT validated (recompile with UNIV_MEM_DEBUG)\n", + stderr); #endif /* UNIV_MEM_DEBUG */ } @@ -1424,30 +1436,29 @@ row_create_table_for_mysql( trx_general_rollback_for_mysql(trx, FALSE, NULL); if (err == DB_OUT_OF_FILE_SPACE) { - fprintf(stderr, - "InnoDB: Warning: cannot create table %s because tablespace full\n", - table->name); + fputs("InnoDB: Warning: cannot create table ", stderr); + ut_print_name(stderr, table->name); + fputs(" because tablespace full\n", stderr); row_drop_table_for_mysql(table->name, trx, FALSE); } else { ut_a(err == DB_DUPLICATE_KEY); ut_print_timestamp(stderr); - fprintf(stderr, - " InnoDB: Error: table %s already exists in InnoDB internal\n" + fputs(" InnoDB: Error: table ", stderr); + ut_print_name(stderr, table->name); + fputs(" already exists in InnoDB internal\n" "InnoDB: data dictionary. Have you deleted the .frm file\n" "InnoDB: and not used DROP TABLE? Have you used DROP DATABASE\n" "InnoDB: for InnoDB tables in MySQL version <= 3.23.43?\n" - "InnoDB: See the Restrictions section of the InnoDB manual.\n", - table->name); - fprintf(stderr, + "InnoDB: See the Restrictions section of the InnoDB manual.\n" "InnoDB: You can drop the orphaned table inside InnoDB by\n" "InnoDB: creating an InnoDB table with the same name in another\n" "InnoDB: database and moving the .frm file to the current database.\n" "InnoDB: Then MySQL thinks the table exists, and DROP TABLE will\n" "InnoDB: succeed.\n" - "InnoDB: You can look further help from section 15.1 of\n" - "InnoDB: http://www.innodb.com/ibman.html\n"); + "InnoDB: You can look for further help from section 15.1 of\n" + "InnoDB: http://www.innodb.com/ibman.php\n", stderr); } trx->error_state = DB_SUCCESS; @@ -1498,11 +1509,14 @@ row_create_index_for_mysql( ut_print_timestamp(stderr); - fprintf(stderr, -" InnoDB: Error: column %s appears twice in index %s of table %s\n" -"InnoDB: This is not allowed in InnoDB.\n", - dict_index_get_nth_field(index, i)->name, - index->name, index->table_name); + fputs(" InnoDB: Error: column ", stderr); + ut_print_name(stderr, + dict_index_get_nth_field(index, i)->name); + fputs(" appears twice in ", stderr); + dict_index_name_print(stderr, index); + fputs("\n" + "InnoDB: This is not allowed in InnoDB.\n", + stderr); err = DB_COL_APPEARS_TWICE_IN_INDEX; @@ -1634,16 +1648,19 @@ row_drop_table_for_mysql_in_background( trx = trx_allocate_for_background(); -/* fprintf(stderr, "InnoDB: Dropping table %s in background drop list\n", - name); */ +/* fputs("InnoDB: Error: Dropping table ", stderr); + ut_print_name(stderr, name); + fputs(" in background drop list\n", stderr); */ + /* Drop the table in InnoDB */ error = row_drop_table_for_mysql(name, trx, FALSE); if (error != DB_SUCCESS) { - fprintf(stderr, - "InnoDB: Error: Dropping table %s in background drop list failed\n", - name); + ut_print_timestamp(stderr); + fputs(" InnoDB: Error: Dropping table ", stderr); + ut_print_name(stderr, name); + fputs(" in background drop list failed\n", stderr); } /* Flush the log to reduce probability that the .frm files and @@ -1721,9 +1738,9 @@ already_dropped: UT_LIST_REMOVE(row_mysql_drop_list, row_mysql_drop_list, drop); ut_print_timestamp(stderr); - fprintf(stderr, - " InnoDB: Dropped table %s in background drop queue.\n", - drop->table_name); + fputs(" InnoDB: Dropped table ", stderr); + ut_print_name(stderr, drop->table_name); + fputs(" in background drop queue.\n", stderr); mem_free(drop->table_name); @@ -1782,15 +1799,17 @@ row_add_table_to_background_drop_list( UT_LIST_ADD_LAST(row_mysql_drop_list, row_mysql_drop_list, drop); -/* fprintf(stderr, "InnoDB: Adding table %s to background drop list\n", - drop->table_name); */ +/* fputs("InnoDB: Adding table ", stderr); + ut_print_name(stderr, drop->table_name); + fputs(" to background drop list\n", stderr); */ + mutex_exit(&kernel_mutex); } /************************************************************************* -Drops a table for MySQL. If the name of the dropped table ends to -characters INNODB_MONITOR, then this also stops printing of monitor -output by the master thread. */ +Drops a table for MySQL. If the name of the table to be dropped is equal +with one of the predefined magic table names, then this also stops printing +the corresponding monitor output by the master thread. */ int row_drop_table_for_mysql( @@ -1962,14 +1981,14 @@ row_drop_table_for_mysql( err = DB_TABLE_NOT_FOUND; ut_print_timestamp(stderr); - fprintf(stderr, - " InnoDB: Error: table %s does not exist in the InnoDB internal\n" + fputs(" InnoDB: Error: table ", stderr); + ut_print_name(stderr, name); + fputs(" does not exist in the InnoDB internal\n" "InnoDB: data dictionary though MySQL is trying to drop it.\n" "InnoDB: Have you copied the .frm file of the table to the\n" "InnoDB: MySQL database directory from another database?\n" - "InnoDB: You can look further help from section 15.1 of\n" - "InnoDB: http://www.innodb.com/ibman.html\n", - name); + "InnoDB: You can look for further help from section 15.1 of\n" + "InnoDB: http://www.innodb.com/ibman.php\n", stderr); goto funct_exit; } @@ -1985,7 +2004,7 @@ row_drop_table_for_mysql( if (foreign && trx->check_foreigns && !(drop_db && dict_tables_have_same_db( name, foreign->foreign_table_name))) { - char* buf = dict_foreign_err_buf; + FILE* ef = dict_foreign_err_file; /* We only allow dropping a referenced table if FOREIGN_KEY_CHECKS is set to 0 */ @@ -1993,28 +2012,30 @@ row_drop_table_for_mysql( err = DB_CANNOT_DROP_CONSTRAINT; mutex_enter(&dict_foreign_err_mutex); - ut_sprintf_timestamp(buf); - - sprintf(buf + strlen(buf), - " Cannot drop table %.500s\n", name); - sprintf(buf + strlen(buf), -"because it is referenced by %.500s\n", foreign->foreign_table_name); - - ut_a(strlen(buf) < DICT_FOREIGN_ERR_BUF_LEN); + rewind(ef); + ut_print_timestamp(ef); + fputs(" Cannot drop table ", ef); + ut_print_name(ef, name); + fputs("\n" + "because it is referenced by ", ef); + ut_print_name(ef, foreign->foreign_table_name); + putc('\n', ef); mutex_exit(&dict_foreign_err_mutex); goto funct_exit; } if (table->n_mysql_handles_opened > 0) { - + ut_print_timestamp(stderr); - fprintf(stderr, - " InnoDB: Warning: MySQL is trying to drop table %s\n" + fputs(" InnoDB: Warning: MySQL is trying to drop table ", + stderr); + ut_print_name(stderr, table->name); + fputs("\n" "InnoDB: though there are still open handles to it.\n" "InnoDB: Adding the table to the background drop queue.\n", - table->name); + stderr); row_add_table_to_background_drop_list(table); @@ -2024,13 +2045,14 @@ row_drop_table_for_mysql( } if (table->n_foreign_key_checks_running > 0) { - + ut_print_timestamp(stderr); - fprintf(stderr, - " InnoDB: You are trying to drop table %s\n" + fputs(" InnoDB: You are trying to drop table ", stderr); + ut_print_name(stderr, table->name); + fputs("\n" "InnoDB: though there are foreign key check running on it.\n" "InnoDB: Adding the table to the background drop queue.\n", - table->name); + stderr); row_add_table_to_background_drop_list(table); @@ -2065,9 +2087,11 @@ row_drop_table_for_mysql( if (dict_load_table(name) != NULL) { ut_print_timestamp(stderr); - fprintf(stderr, -" InnoDB: Error: dropping of table %s failed!\n", name); - + fputs(" InnoDB: Error: dropping of table ", + stderr); + ut_print_name(stderr, name); + fputs(" failed!\n", stderr); + err = DB_ERROR; } } funct_exit: @@ -2125,10 +2149,13 @@ loop: row_mysql_unlock_data_dictionary(trx); ut_print_timestamp(stderr); - fprintf(stderr, - " InnoDB: Warning: MySQL is trying to drop database %s\n" - "InnoDB: though there are still open handles to table %s.\n", - name, table_name); + fputs( + " InnoDB: Warning: MySQL is trying to drop database ", stderr); + ut_print_name(stderr, name); + fputs("\n" + "InnoDB: though there are still open handles to table ", stderr); + ut_print_name(stderr, table_name); + fputs(".\n", stderr); os_thread_sleep(1000000); @@ -2142,9 +2169,12 @@ loop: mem_free(table_name); if (err != DB_SUCCESS) { - fprintf(stderr, - "InnoDB: DROP DATABASE %s failed with error %lu for table %s\n", - name, (ulint)err, table_name); + fputs("InnoDB: DROP DATABASE ", stderr); + ut_print_name(stderr, name); + fprintf(stderr, " failed with error %lu for table ", + (ulint) err); + ut_print_name(stderr, table_name); + putc('\n', stderr); break; } } @@ -2309,12 +2339,10 @@ row_rename_table_for_mysql( if (row_mysql_is_recovered_tmp_table(new_name)) { recovering_temp_table = TRUE; - } + } else { + /* Serialize data dictionary operations with dictionary mutex: + no deadlocks can occur then in these operations */ - /* Serialize data dictionary operations with dictionary mutex: - no deadlocks can occur then in these operations */ - - if (!recovering_temp_table) { row_mysql_lock_data_dictionary(trx); } @@ -2450,25 +2478,26 @@ row_rename_table_for_mysql( if (err == DB_DUPLICATE_KEY) { ut_print_timestamp(stderr); - fprintf(stderr, - " InnoDB: Error: table %s exists in the InnoDB internal data\n" - "InnoDB: dictionary though MySQL is trying rename table %s to it.\n" + fputs(" InnoDB: Error: table ", stderr); + ut_print_name(stderr, new_name); + fputs(" exists in the InnoDB internal data\n" + "InnoDB: dictionary though MySQL is trying rename table ", stderr); + ut_print_name(stderr, old_name); + fputs(" to it.\n" "InnoDB: Have you deleted the .frm file and not used DROP TABLE?\n" - "InnoDB: You can look further help from section 15.1 of\n" - "InnoDB: http://www.innodb.com/ibman.html\n", - new_name, old_name); - - fprintf(stderr, - "InnoDB: If table %s is a temporary table #sql..., then it can be that\n" + "InnoDB: You can look for further help from section 15.1 of\n" + "InnoDB: http://www.innodb.com/ibman.php\n" + "InnoDB: If table ", stderr); + ut_print_name(stderr, new_name); + fputs( + " is a temporary table #sql..., then it can be that\n" "InnoDB: there are still queries running on the table, and it will be\n" - "InnoDB: dropped automatically when the queries end.\n", new_name); - - fprintf(stderr, + "InnoDB: dropped automatically when the queries end.\n" "InnoDB: You can drop the orphaned table inside InnoDB by\n" "InnoDB: creating an InnoDB table with the same name in another\n" "InnoDB: database and moving the .frm file to the current database.\n" "InnoDB: Then MySQL thinks the table exists, and DROP TABLE will\n" - "InnoDB: succeed.\n"); + "InnoDB: succeed.\n", stderr); } trx->error_state = DB_SUCCESS; @@ -2493,11 +2522,13 @@ row_rename_table_for_mysql( ut_print_timestamp(stderr); - fprintf(stderr, - " InnoDB: Error: in ALTER TABLE table %s\n" + fputs(" InnoDB: Error: in ALTER TABLE table ", + stderr); + ut_print_name(stderr, new_name); + fputs("\n" "InnoDB: has or is referenced in foreign key constraints\n" "InnoDB: which are not compatible with the new table definition.\n", - new_name); + stderr); ut_a(dict_table_rename_in_cache(table, old_name, FALSE)); @@ -2554,7 +2585,6 @@ row_scan_and_check_index( int cmp; ibool contains_null; ulint i; - char err_buf[1000]; *n_rows = 0; @@ -2615,32 +2645,25 @@ loop: } if (cmp > 0) { - fprintf(stderr, - "Error: index records in a wrong order in index %s\n", - index->name); - - dtuple_sprintf(err_buf, 900, prev_entry); - fprintf(stderr, "InnoDB: prev record %s\n", err_buf); - - rec_sprintf(err_buf, 900, rec); - fprintf(stderr, "InnoDB: record %s\n", err_buf); - + fputs("InnoDB: index records in a wrong order in ", + stderr); + not_ok: + dict_index_name_print(stderr, index); + fputs("\n" + "InnoDB: prev record ", stderr); + dtuple_print(stderr, prev_entry); + fputs("\n" + "InnoDB: record ", stderr); + rec_print(stderr, rec); + putc('\n', stderr); is_ok = FALSE; } else if ((index->type & DICT_UNIQUE) && !contains_null && matched_fields >= dict_index_get_n_ordering_defined_by_user(index)) { - fprintf(stderr, "Error: duplicate key in index %s\n", - index->name); - - dtuple_sprintf(err_buf, 900, prev_entry); - fprintf(stderr, "InnoDB: prev record %s\n", err_buf); - - rec_sprintf(err_buf, 900, rec); - fprintf(stderr, "InnoDB: record %s\n", err_buf); - - is_ok = FALSE; + fputs("InnoDB: duplicate key in ", stderr); + goto not_ok; } } @@ -2684,7 +2707,9 @@ row_check_table_for_mysql( index = dict_table_get_first_index(table); while (index != NULL) { - /* fprintf(stderr, "Validating index %s\n", index->name); */ + /* fputs("Validating index ", stderr); + ut_print_name(stderr, index->name); + putc('\n', stderr); */ if (!btr_validate_tree(index->tree)) { ret = DB_ERROR; @@ -2694,18 +2719,21 @@ row_check_table_for_mysql( ret = DB_ERROR; } - /* fprintf(stderr, "%lu entries in index %s\n", n_rows, - index->name); */ + /* fprintf(stderr, "%lu entries in index ", n_rows); + ut_print_name(stderr, index->name); + putc('\n', stderr); */ if (index == dict_table_get_first_index(table)) { n_rows_in_table = n_rows; } else if (n_rows != n_rows_in_table) { ret = DB_ERROR; - + + fputs("InnoDB: Error: ", stderr); + dict_index_name_print(stderr, index); fprintf(stderr, - "Error: index %s contains %lu entries, should be %lu\n", - index->name, n_rows, n_rows_in_table); + " contains %lu entries, should be %lu\n", + n_rows, n_rows_in_table); } } diff --git a/innobase/row/row0purge.c b/innobase/row/row0purge.c index a2c60079e66..2ddc60613fc 100644 --- a/innobase/row/row0purge.c +++ b/innobase/row/row0purge.c @@ -158,7 +158,7 @@ row_purge_remove_clust_if_poss( ibool success; ulint n_tries = 0; -/* printf("Purge: Removing clustered record\n"); */ +/* fputs("Purge: Removing clustered record\n", stderr); */ success = row_purge_remove_clust_if_poss_low(node, BTR_MODIFY_LEAF); if (success) { @@ -212,7 +212,7 @@ row_purge_remove_sec_if_poss_low( if (!found) { /* Not found */ - /* printf("PURGE:........sec entry not found\n"); */ + /* fputs("PURGE:........sec entry not found\n", stderr); */ /* dtuple_print(entry); */ btr_pcur_close(&pcur); @@ -281,7 +281,7 @@ row_purge_remove_sec_if_poss( ibool success; ulint n_tries = 0; -/* printf("Purge: Removing secondary record\n"); */ +/* fputs("Purge: Removing secondary record\n", stderr); */ success = row_purge_remove_sec_if_poss_low(node, index, entry, BTR_MODIFY_LEAF); diff --git a/innobase/row/row0row.c b/innobase/row/row0row.c index 327a47f4009..680539764fd 100644 --- a/innobase/row/row0row.c +++ b/innobase/row/row0row.c @@ -390,7 +390,6 @@ row_build_row_ref_in_tuple( at least s-latched and the latch held as long as the row reference is used! */ { - dict_table_t* table; dict_index_t* clust_index; dfield_t* dfield; byte* field; @@ -401,21 +400,21 @@ row_build_row_ref_in_tuple( ut_a(ref && index && rec); - table = index->table; - - if (!table) { - fprintf(stderr, "InnoDB: table %s for index %s not found\n", - index->table_name, index->name); + if (!index->table) { + fputs("InnoDB: table ", stderr); + notfound: + ut_print_name(stderr, index->table_name); + fputs(" for index ", stderr); + ut_print_name(stderr, index->name); + fputs(" not found\n", stderr); ut_error; } - clust_index = dict_table_get_first_index(table); + clust_index = dict_table_get_first_index(index->table); if (!clust_index) { - fprintf(stderr, - "InnoDB: clust index for table %s for index %s not found\n", - index->table_name, index->name); - ut_error; + fputs("InnoDB: clust index for table ", stderr); + goto notfound; } ref_len = dict_index_get_n_unique(clust_index); diff --git a/innobase/row/row0sel.c b/innobase/row/row0sel.c index 6ae4f791205..6f8ce120764 100644 --- a/innobase/row/row0sel.c +++ b/innobase/row/row0sel.c @@ -1756,7 +1756,7 @@ row_sel_step( return(NULL); } else { /* SQL error detected */ - printf("SQL error %lu\n", err); + fprintf(stderr, "SQL error %lu\n", err); que_thr_handle_error(thr, DB_ERROR, NULL, 0); @@ -1806,7 +1806,7 @@ fetch_step( if (sel_node->state == SEL_NODE_CLOSED) { /* SQL error detected */ - printf("SQL error %lu\n", (ulint)DB_ERROR); + fprintf(stderr, "SQL error %lu\n", (ulint)DB_ERROR); que_thr_handle_error(thr, DB_ERROR, NULL, 0); @@ -1867,12 +1867,12 @@ row_printf_step( while (arg) { dfield_print_also_hex(que_node_get_val(arg)); - printf(" ::: "); + fputs(" ::: ", stderr); arg = que_node_get_next(arg); } - printf("\n"); + putc('\n', stderr); /* Fetch next row to print */ @@ -1980,9 +1980,10 @@ row_sel_convert_mysql_key_to_innobase( MySQL */ if (key_ptr[data_offset + 1] != 0) { ut_print_timestamp(stderr); - fprintf(stderr, -" InnoDB: Error: BLOB or TEXT prefix > 255 bytes in query to table %s\n", - index->table_name); + fputs( +" InnoDB: Error: BLOB or TEXT prefix > 255 bytes in query to table ", stderr); + ut_print_name(stderr, index->table_name); + putc('\n', stderr); } data_len = key_ptr[data_offset]; @@ -2058,20 +2059,18 @@ row_sel_store_row_id_to_prebuilt( { byte* data; ulint len; - char err_buf[1000]; - data = rec_get_nth_field(index_rec, dict_index_get_sys_col_pos(index, DATA_ROW_ID), &len); if (len != DATA_ROW_ID_LEN) { - rec_sprintf(err_buf, 900, index_rec); - fprintf(stderr, -"InnoDB: Error: Row id field is wrong length %lu in table %s index %s\n" -"InnoDB: Field number %lu, record:\n%s\n", - len, index->table_name, index->name, - dict_index_get_sys_col_pos(index, DATA_ROW_ID), - err_buf); +"InnoDB: Error: Row id field is wrong length %lu in ", len); + dict_index_name_print(stderr, index); + fprintf(stderr, "\n" +"InnoDB: Field number %lu, record:\n", + dict_index_get_sys_col_pos(index, DATA_ROW_ID)); + rec_print(stderr, index_rec); + putc('\n', stderr); ut_error; } @@ -2239,9 +2238,11 @@ row_sel_store_mysql_rec( templ->mysql_col_len); if (!templ->mysql_null_bit_mask) { - fprintf(stderr, + fputs( "InnoDB: Error: trying to return an SQL NULL field in a non-null\n" -"innoDB: column! Table name %s\n", prebuilt->table->name); +"innoDB: column! Table name ", stderr); + ut_print_name(stderr, prebuilt->table->name); + putc('\n', stderr); } else { mysql_rec[templ->mysql_null_byte_offset] |= (byte) (templ->mysql_null_bit_mask); @@ -2310,8 +2311,7 @@ row_sel_get_clust_rec_for_mysql( rec_t* old_vers; ulint err; trx_t* trx; - char err_buf[1000]; - + *out_rec = NULL; row_build_row_ref_in_tuple(prebuilt->clust_ref, sec_index, rec); @@ -2344,26 +2344,22 @@ row_sel_get_clust_rec_for_mysql( || prebuilt->select_lock_type != LOCK_NONE) { ut_print_timestamp(stderr); - fprintf(stderr, - " InnoDB: error clustered record for sec rec not found\n" - "InnoDB: index %s table %s\n", sec_index->name, - sec_index->table->name); + fputs(" InnoDB: error clustered record" + " for sec rec not found\n" + "InnoDB: ", stderr); + dict_index_name_print(stderr, sec_index); + fputs("\n" + "InnoDB: sec index record ", stderr); + rec_print(stderr, rec); + fputs("\n" + "InnoDB: clust index record ", stderr); + rec_print(stderr, clust_rec); + putc('\n', stderr); + trx_print(stderr, thr_get_trx(thr)); - rec_sprintf(err_buf, 900, rec); - fprintf(stderr, - "InnoDB: sec index record %s\n", err_buf); - - rec_sprintf(err_buf, 900, clust_rec); - fprintf(stderr, - "InnoDB: clust index record %s\n", err_buf); - - trx = thr_get_trx(thr); - trx_print(err_buf, trx); - - fprintf(stderr, - "%s\nInnoDB: Make a detailed bug report and send it\n", - err_buf); - fprintf(stderr, "InnoDB: to mysql@lists.mysql.com\n"); + fputs("\n" + "InnoDB: Make a detailed bug report and send it\n" + "InnoDB: to mysql@lists.mysql.com\n", stderr); } clust_rec = NULL; @@ -2711,18 +2707,20 @@ row_search_for_mysql( if (prebuilt->magic_n != ROW_PREBUILT_ALLOCATED) { fprintf(stderr, "InnoDB: Error: trying to free a corrupt\n" - "InnoDB: table handle. Magic n %lu, table name %s\n", - prebuilt->magic_n, prebuilt->table->name); + "InnoDB: table handle. Magic n %lu, table name ", + prebuilt->magic_n); + ut_print_name(stderr, prebuilt->table->name); + putc('\n', stderr); mem_analyze_corruption((byte*)prebuilt); ut_error; } -/* printf("Match mode %lu\n search tuple ", match_mode); +/* fprintf(stderr, "Match mode %lu\n search tuple ", match_mode); dtuple_print(search_tuple); - printf("N tables locked %lu\n", trx->mysql_n_tables_locked); + fprintf(stderr, "N tables locked %lu\n", trx->mysql_n_tables_locked); */ /*-------------------------------------------------------------*/ /* PHASE 0: Release a possible s-latch we are holding on the @@ -2899,7 +2897,8 @@ row_search_for_mysql( mtr_commit(&mtr); - /* printf("%s shortcut\n", index->name); */ + /* ut_print_name(stderr, index->name); + fputs(" shortcut\n", stderr); */ srv_n_rows_read++; @@ -2923,8 +2922,8 @@ row_search_for_mysql( mtr_commit(&mtr); - /* printf("%s record not found 2\n", - index->name); */ + /* ut_print_name(stderr, index->name); + fputs(" record not found 2\n", stderr); */ if (trx->search_latch_timeout > 0 && trx->has_search_latch) { @@ -3044,8 +3043,9 @@ rec_loop: rec = btr_pcur_get_rec(pcur); /* - printf("Using index %s cnt %lu ", index->name, cnt); - printf("; Page no %lu\n", + fputs("Using ", stderr); + dict_index_name_print(stderr, index); + fprintf(stderr, " cnt %lu ; Page no %lu\n", cnt, buf_frame_get_page_no(buf_frame_align(rec))); rec_print(rec); */ @@ -3091,11 +3091,13 @@ rec_loop: ut_print_timestamp(stderr); fprintf(stderr, " InnoDB: Index corruption: rec offs %lu next offs %lu, page no %lu,\n" -"InnoDB: index %s, table %s. Run CHECK TABLE to table. You may need to\n" +"InnoDB: ", + (ulint)(rec - buf_frame_align(rec)), next_offs, + buf_frame_get_page_no(rec)); + dict_index_name_print(stderr, index); + fputs(". Run CHECK TABLE. You may need to\n" "InnoDB: restore from a backup, or dump + drop + reimport the table.\n", - (ulint)(rec - buf_frame_align(rec)), next_offs, - buf_frame_get_page_no(rec), index->name, - index->table_name); + stderr); err = DB_CORRUPTION; @@ -3106,10 +3108,12 @@ rec_loop: fprintf(stderr, "InnoDB: Index corruption: rec offs %lu next offs %lu, page no %lu,\n" -"InnoDB: index %s, table %s. We try to skip the rest of the page.\n", +"InnoDB: ", (ulint)(rec - buf_frame_align(rec)), next_offs, - buf_frame_get_page_no(rec), index->name, - index->table_name); + buf_frame_get_page_no(rec)); + dict_index_name_print(stderr, index); + fputs(". We try to skip the rest of the page.\n", + stderr); btr_pcur_move_to_last_on_page(pcur, &mtr); @@ -3121,11 +3125,13 @@ rec_loop: if (!rec_validate(rec) || !btr_index_rec_validate(rec, index, FALSE)) { fprintf(stderr, -"InnoDB: Index record corruption: rec offs %lu next offs %lu, page no %lu,\n" -"InnoDB: index %s, table %s. We try to skip the record.\n", +"InnoDB: Index corruption: rec offs %lu next offs %lu, page no %lu,\n" +"InnoDB: ", (ulint)(rec - buf_frame_align(rec)), next_offs, - buf_frame_get_page_no(rec), index->name, - index->table_name); + buf_frame_get_page_no(rec)); + dict_index_name_print(stderr, index); + fputs(". We try to skip the record.\n", + stderr); goto next_rec; } @@ -3142,7 +3148,7 @@ rec_loop: /* Test if the index record matches completely to search_tuple in prebuilt: if not, then we return with DB_RECORD_NOT_FOUND */ - /* printf("Comparing rec and search tuple\n"); */ + /* fputs("Comparing rec and search tuple\n", stderr); */ if (0 != cmp_dtuple_rec(search_tuple, rec)) { @@ -3162,7 +3168,8 @@ rec_loop: btr_pcur_store_position(pcur, &mtr); ret = DB_RECORD_NOT_FOUND; - /* printf("%s record not found 3\n", index->name); */ + /* ut_print_name(stderr, index->name); + fputs(" record not found 3\n", stderr); */ goto normal_return; } @@ -3187,7 +3194,8 @@ rec_loop: btr_pcur_store_position(pcur, &mtr); ret = DB_RECORD_NOT_FOUND; - /* printf("%s record not found 4\n", index->name); */ + /* ut_print_name(stderr, index->name); + fputs(" record not found 4\n", stderr); */ goto normal_return; } @@ -3453,8 +3461,9 @@ lock_wait_or_error: goto rec_loop; } - /* printf("Using index %s cnt %lu ret value %lu err\n", index->name, - cnt, err); */ +/* fputs("Using ", stderr); + dict_index_name_print(stderr, index); + fprintf(stderr, " cnt %lu ret value %lu err\n", cnt, err); */ trx->op_info = (char *) ""; return(err); @@ -3471,8 +3480,9 @@ normal_return: ret = DB_SUCCESS; } - /* printf("Using index %s cnt %lu ret value %lu\n", index->name, - cnt, err); */ +/* fputs("Using ", stderr); + dict_index_name_print(stderr, index); + fprintf(stderr, " cnt %lu ret value %lu err\n", cnt, err); */ if (ret == DB_SUCCESS) { srv_n_rows_read++; } diff --git a/innobase/row/row0umod.c b/innobase/row/row0umod.c index 5dde60029f0..5975bb164b9 100644 --- a/innobase/row/row0umod.c +++ b/innobase/row/row0umod.c @@ -417,13 +417,11 @@ row_undo_mod_del_unmark_sec_and_undo_update( { mem_heap_t* heap; btr_pcur_t pcur; - btr_cur_t* btr_cur; upd_t* update; ulint err = DB_SUCCESS; ibool found; big_rec_t* dummy_big_rec; mtr_t mtr; - char err_buf[1000]; log_free_check(); mtr_start(&mtr); @@ -431,23 +429,22 @@ row_undo_mod_del_unmark_sec_and_undo_update( found = row_search_index_entry(index, entry, mode, &pcur, &mtr); if (!found) { - fprintf(stderr, - "InnoDB: error in sec index entry del undo in\n" - "InnoDB: index %s table %s\n", index->name, - index->table->name); - dtuple_sprintf(err_buf, 900, entry); - fprintf(stderr, "InnoDB: tuple %s\n", err_buf); - - rec_sprintf(err_buf, 900, btr_pcur_get_rec(&pcur)); - fprintf(stderr, "InnoDB: record %s\n", err_buf); - - trx_print(err_buf, thr_get_trx(thr)); - fprintf(stderr, - "%s\nInnoDB: Make a detailed bug report and send it\n", - err_buf); - fprintf(stderr, "InnoDB: to mysql@lists.mysql.com\n"); + fputs("InnoDB: error in sec index entry del undo in\n" + "InnoDB: ", stderr); + dict_index_name_print(stderr, index); + fputs("\n" + "InnoDB: tuple ", stderr); + dtuple_print(stderr, entry); + fputs("\n" + "InnoDB: record ", stderr); + rec_print(stderr, btr_pcur_get_rec(&pcur)); + putc('\n', stderr); + trx_print(stderr, thr_get_trx(thr)); + fputs("\n" + "InnoDB: Make a detailed bug report and send it\n" + "InnoDB: to mysql@lists.mysql.com\n", stderr); } else { - btr_cur = btr_pcur_get_btr_cur(&pcur); + btr_cur_t* btr_cur = btr_pcur_get_btr_cur(&pcur); err = btr_cur_del_mark_set_sec_rec(BTR_NO_LOCKING_FLAG, btr_cur, FALSE, thr, &mtr); diff --git a/innobase/row/row0undo.c b/innobase/row/row0undo.c index a3ea42e1425..e1e44724752 100644 --- a/innobase/row/row0undo.c +++ b/innobase/row/row0undo.c @@ -169,8 +169,8 @@ row_undo_search_clust_to_pcur( is to make sure that some thread will eventually undo the modification corresponding to node->roll_ptr. */ - /* printf("--------------------undoing a previous version\n"); - */ + /* fputs("--------------------undoing a previous version\n", + stderr); */ ret = FALSE; } else { diff --git a/innobase/row/row0upd.c b/innobase/row/row0upd.c index ad6542845cb..02fe245ce8b 100644 --- a/innobase/row/row0upd.c +++ b/innobase/row/row0upd.c @@ -1202,7 +1202,6 @@ row_upd_sec_index_entry( rec_t* rec; ulint err = DB_SUCCESS; mtr_t mtr; - char err_buf[1000]; index = node->index; @@ -1223,21 +1222,22 @@ row_upd_sec_index_entry( rec = btr_cur_get_rec(btr_cur); if (!found) { - fprintf(stderr, "InnoDB: error in sec index entry update in\n" - "InnoDB: index %s table %s\n", index->name, - index->table->name); - dtuple_sprintf(err_buf, 900, entry); - fprintf(stderr, "InnoDB: tuple %s\n", err_buf); + fputs("InnoDB: error in sec index entry update in\n" + "InnoDB: ", stderr); + dict_index_name_print(stderr, index); + fputs("\n" + "InnoDB: tuple ", stderr); + dtuple_print(stderr, entry); + fputs("\n" + "InnoDB: record ", stderr); + rec_print(stderr, rec); + putc('\n', stderr); - rec_sprintf(err_buf, 900, rec); - fprintf(stderr, "InnoDB: record %s\n", err_buf); + trx_print(stderr, thr_get_trx(thr)); - trx_print(err_buf, thr_get_trx(thr)); - - fprintf(stderr, - "%s\nInnoDB: Make a detailed bug report and send it\n", - err_buf); - fprintf(stderr, "InnoDB: to mysql@lists.mysql.com\n"); + fputs("\n" + "InnoDB: Make a detailed bug report and send it\n" + "InnoDB: to mysql@lists.mysql.com\n", stderr); } else { /* Delete mark the old index record; it can already be delete marked if we return after a lock wait in diff --git a/innobase/srv/srv0srv.c b/innobase/srv/srv0srv.c index 87e15037fb6..cee6dec850e 100644 --- a/innobase/srv/srv0srv.c +++ b/innobase/srv/srv0srv.c @@ -52,9 +52,6 @@ Created 10/8/1995 Heikki Tuuri affects only FOREIGN KEY definition parsing */ ibool srv_lower_case_table_names = FALSE; -/* Buffer which can be used in printing fatal error messages */ -char srv_fatal_errbuf[5000]; - /* The following counter is incremented whenever there is some user activity in the server */ ulint srv_activity_count = 0; @@ -290,7 +287,12 @@ const char* srv_io_thread_function[SRV_MAX_N_IO_THREADS]; time_t srv_last_monitor_time; -mutex_t srv_innodb_monitor_mutex; +mutex_t srv_innodb_monitor_mutex; + +/* Mutex for locking srv_monitor_file */ +mutex_t srv_monitor_file_mutex; +/* Temporary file for innodb monitor output */ +FILE* srv_monitor_file; ulint srv_main_thread_process_no = 0; ulint srv_main_thread_id = 0; @@ -627,9 +629,10 @@ srv_suspend_thread(void) slot_no = thr_local_get_slot_no(os_thread_get_curr_id()); if (srv_print_thread_releases) { - - printf("Suspending thread %lu to slot %lu meter %lu\n", - os_thread_get_curr_id(), slot_no, srv_meter[SRV_RECOVERY]); + fprintf(stderr, + "Suspending thread %lu to slot %lu meter %lu\n", + os_thread_get_curr_id(), slot_no, + srv_meter[SRV_RECOVERY]); } slot = srv_table_get_nth_slot(slot_no); @@ -689,7 +692,7 @@ srv_release_threads( os_event_set(slot->event); if (srv_print_thread_releases) { - printf( + fprintf(stderr, "Releasing thread %lu type %lu from slot %lu meter %lu\n", slot->id, type, i, srv_meter[SRV_RECOVERY]); } @@ -847,7 +850,6 @@ srv_conc_enter_innodb( ibool has_slept = FALSE; srv_conc_slot_t* slot = NULL; ulint i; - char err_buf[1000]; if (srv_thread_concurrency >= 500) { /* Disable the concurrency check */ @@ -868,12 +870,11 @@ srv_conc_enter_innodb( retry: if (trx->declared_to_be_inside_innodb) { ut_print_timestamp(stderr); - - trx_print(err_buf, trx); - - fprintf(stderr, + fputs( " InnoDB: Error: trying to declare trx to enter InnoDB, but\n" -"InnoDB: it already is declared.\n%s\n", err_buf); +"InnoDB: it already is declared.\n", stderr); + trx_print(stderr, trx); + putc('\n', stderr); os_fast_mutex_unlock(&srv_conc_mutex); return; @@ -1403,15 +1404,13 @@ srv_refresh_innodb_monitor_stats(void) } /********************************************************************** -Sprintfs to a buffer the output of the InnoDB Monitor. */ +Outputs to a file the output of the InnoDB Monitor. */ void -srv_sprintf_innodb_monitor( -/*=======================*/ - char* buf, /* in/out: buffer which must be at least 4 kB */ - ulint len) /* in: length of the buffer */ +srv_printf_innodb_monitor( +/*======================*/ + FILE* file) /* in: output stream */ { - char* buf_end = buf + len - 2000; double time_elapsed; time_t current_time; ulint n_reserved; @@ -1429,28 +1428,20 @@ srv_sprintf_innodb_monitor( srv_last_monitor_time = time(NULL); - ut_a(len >= 4096); + rewind(file); + fputs("\n=====================================\n", file); - buf += sprintf(buf, "\n=====================================\n"); + ut_print_timestamp(file); + fprintf(file, + " INNODB MONITOR OUTPUT\n" + "=====================================\n" + "Per second averages calculated from the last %lu seconds\n", + (ulong)time_elapsed); - ut_sprintf_timestamp(buf); - buf = buf + strlen(buf); - ut_a(buf < buf_end + 1500); - - buf += sprintf(buf, " INNODB MONITOR OUTPUT\n" - "=====================================\n"); - - buf += sprintf(buf, -"Per second averages calculated from the last %lu seconds\n", - (ulint)time_elapsed); - - buf += sprintf(buf, "----------\n" - "SEMAPHORES\n" - "----------\n"); - sync_print(buf, buf_end); - - buf = buf + strlen(buf); - ut_a(buf < buf_end + 1500); + fputs("----------\n" + "SEMAPHORES\n" + "----------\n", file); + sync_print(file); /* Conceptually, srv_innodb_monitor_mutex has a very high latching order level in sync0sync.h, while dict_foreign_err_mutex has a very @@ -1459,43 +1450,29 @@ srv_sprintf_innodb_monitor( mutex_enter(&dict_foreign_err_mutex); - if (*dict_foreign_err_buf != '\0') { - buf += sprintf(buf, - "------------------------\n" - "LATEST FOREIGN KEY ERROR\n" - "------------------------\n"); - - if (buf_end - buf > 6000) { - buf+= sprintf(buf, "%.4000s", dict_foreign_err_buf); - } - } + if (ftell(dict_foreign_err_file) != 0L) { + fputs("------------------------\n" + "LATEST FOREIGN KEY ERROR\n" + "------------------------\n", file); + ut_copy_file(file, dict_foreign_err_file); + } mutex_exit(&dict_foreign_err_mutex); - ut_a(buf < buf_end + 1500); + lock_print_info(file); + fputs("--------\n" + "FILE I/O\n" + "--------\n", file); + os_aio_print(file); - lock_print_info(buf, buf_end); - buf = buf + strlen(buf); - - buf += sprintf(buf, "--------\n" - "FILE I/O\n" - "--------\n"); - os_aio_print(buf, buf_end); - buf = buf + strlen(buf); - ut_a(buf < buf_end + 1500); + fputs("-------------------------------------\n" + "INSERT BUFFER AND ADAPTIVE HASH INDEX\n" + "-------------------------------------\n", file); + ibuf_print(file); - buf += sprintf(buf, "-------------------------------------\n" - "INSERT BUFFER AND ADAPTIVE HASH INDEX\n" - "-------------------------------------\n"); - ibuf_print(buf, buf_end); - buf = buf + strlen(buf); - ut_a(buf < buf_end + 1500); + ha_print_info(file, btr_search_sys->hash_index); - ha_print_info(buf, buf_end, btr_search_sys->hash_index); - buf = buf + strlen(buf); - ut_a(buf < buf_end + 1500); - - buf += sprintf(buf, + fprintf(file, "%.2f hash searches/s, %.2f non-hash searches/s\n", (btr_cur_n_sea - btr_cur_n_sea_old) / time_elapsed, @@ -1504,57 +1481,50 @@ srv_sprintf_innodb_monitor( btr_cur_n_sea_old = btr_cur_n_sea; btr_cur_n_non_sea_old = btr_cur_n_non_sea; - buf += sprintf(buf,"---\n" + fputs("---\n" "LOG\n" - "---\n"); - log_print(buf, buf_end); - buf = buf + strlen(buf); - ut_a(buf < buf_end + 1500); - - buf += sprintf(buf, "----------------------\n" + "---\n", file); + log_print(file); + + fputs("----------------------\n" "BUFFER POOL AND MEMORY\n" - "----------------------\n"); - buf += sprintf(buf, + "----------------------\n", file); + fprintf(file, "Total memory allocated %lu; in additional pool allocated %lu\n", ut_total_allocated_memory, mem_pool_get_reserved(mem_comm_pool)); - buf_print_io(buf, buf_end); - buf = buf + strlen(buf); - ut_a(buf < buf_end + 1500); + buf_print_io(file); - buf += sprintf(buf, "--------------\n" - "ROW OPERATIONS\n" - "--------------\n"); - buf += sprintf(buf, - "%ld queries inside InnoDB, %lu queries in queue\n", + fputs("--------------\n" + "ROW OPERATIONS\n" + "--------------\n", file); + fprintf(file, "%ld queries inside InnoDB, %lu queries in queue\n", srv_conc_n_threads, srv_conc_n_waiting_threads); n_reserved = fil_space_get_n_reserved_extents(0); if (n_reserved > 0) { - buf += sprintf(buf, + fprintf(file, "%lu tablespace extents now reserved for B-tree split operations\n", n_reserved); } #ifdef UNIV_LINUX - buf += sprintf(buf, - "Main thread process no. %lu, id %lu, state: %.29s\n", + fprintf(file, "Main thread process no. %lu, id %lu, state: %s\n", srv_main_thread_process_no, srv_main_thread_id, srv_main_thread_op_info); #else - buf += sprintf(buf, - "Main thread id %lu, state: %.29s\n", + fprintf(file, "Main thread id %lu, state: %s\n", srv_main_thread_id, srv_main_thread_op_info); #endif - buf += sprintf(buf, + fprintf(file, "Number of rows inserted %lu, updated %lu, deleted %lu, read %lu\n", srv_n_rows_inserted, srv_n_rows_updated, srv_n_rows_deleted, srv_n_rows_read); - buf += sprintf(buf, + fprintf(file, "%.2f inserts/s, %.2f updates/s, %.2f deletes/s, %.2f reads/s\n", (srv_n_rows_inserted - srv_n_rows_inserted_old) / time_elapsed, @@ -1570,12 +1540,12 @@ srv_sprintf_innodb_monitor( srv_n_rows_deleted_old = srv_n_rows_deleted; srv_n_rows_read_old = srv_n_rows_read; - buf += sprintf(buf, "----------------------------\n" + fputs("----------------------------\n" "END OF INNODB MONITOR OUTPUT\n" - "============================\n"); - ut_a(buf < buf_end + 1900); + "============================\n", file); mutex_exit(&srv_innodb_monitor_mutex); + fflush(file); } /************************************************************************* @@ -1601,13 +1571,13 @@ srv_lock_timeout_and_monitor_thread( time_t last_monitor_time; ibool some_waits; double wait_time; - char* buf; ulint i; #ifdef UNIV_DEBUG_THREAD_CREATION - printf("Lock timeout thread starts, id %lu\n", + fprintf(stderr, "Lock timeout thread starts, id %lu\n", os_thread_pf(os_thread_get_curr_id())); #endif + UT_NOT_USED(arg); srv_last_monitor_time = time(NULL); last_table_monitor_time = time(NULL); last_monitor_time = time(NULL); @@ -1633,55 +1603,56 @@ loop: last_monitor_time = time(NULL); if (srv_print_innodb_monitor) { + srv_printf_innodb_monitor(stderr); + } - buf = mem_alloc(100000); + mutex_enter(&srv_monitor_file_mutex); + rewind(srv_monitor_file); + srv_printf_innodb_monitor(srv_monitor_file); + mutex_exit(&srv_monitor_file_mutex); - srv_sprintf_innodb_monitor(buf, 90000); - - ut_a(strlen(buf) < 99000); - - printf("%s", buf); - - mem_free(buf); - } - - if (srv_print_innodb_tablespace_monitor - && difftime(current_time, last_table_monitor_time) > 60) { + if (srv_print_innodb_tablespace_monitor + && difftime(current_time, last_table_monitor_time) > 60) { last_table_monitor_time = time(NULL); - printf("================================================\n"); + fputs("================================================\n", + stderr); - ut_print_timestamp(stdout); + ut_print_timestamp(stderr); - printf(" INNODB TABLESPACE MONITOR OUTPUT\n" - "================================================\n"); + fputs(" INNODB TABLESPACE MONITOR OUTPUT\n" + "================================================\n", + stderr); fsp_print(0); - fprintf(stderr, "Validating tablespace\n"); + fputs("Validating tablespace\n", stderr); fsp_validate(0); - fprintf(stderr, "Validation ok\n"); - printf("---------------------------------------\n" + fputs("Validation ok\n" + "---------------------------------------\n" "END OF INNODB TABLESPACE MONITOR OUTPUT\n" - "=======================================\n"); + "=======================================\n", + stderr); } if (srv_print_innodb_table_monitor - && difftime(current_time, last_table_monitor_time) > 60) { + && difftime(current_time, last_table_monitor_time) > 60) { last_table_monitor_time = time(NULL); - printf("===========================================\n"); + fputs("===========================================\n", stderr); - ut_print_timestamp(stdout); + ut_print_timestamp(stderr); - printf(" INNODB TABLE MONITOR OUTPUT\n" - "===========================================\n"); + fputs(" INNODB TABLE MONITOR OUTPUT\n" + "===========================================\n", + stderr); dict_print(); - printf("-----------------------------------\n" + fputs("-----------------------------------\n" "END OF INNODB TABLE MONITOR OUTPUT\n" - "==================================\n"); + "==================================\n", + stderr); } } @@ -1740,8 +1711,11 @@ loop: srv_lock_timeout_and_monitor_active = FALSE; +#if 0 + /* The following synchronisation is disabled, since + the InnoDB monitor output is to be updated every 15 seconds. */ os_event_wait(srv_lock_timeout_thread_event); - +#endif goto loop; exit_func: @@ -1777,7 +1751,7 @@ srv_error_monitor_thread( ulint cnt = 0; #ifdef UNIV_DEBUG_THREAD_CREATION - printf("Error monitor thread starts, id %lu\n", + fprintf(stderr, "Error monitor thread starts, id %lu\n", os_thread_pf(os_thread_get_curr_id())); #endif loop: @@ -1796,11 +1770,10 @@ loop: sync_array_print_long_waits(); - /* Flush stdout and stderr so that a database user gets their output + /* Flush stderr so that a database user gets the output to possible MySQL error file */ fflush(stderr); - fflush(stdout); if (srv_shutdown_state < SRV_SHUTDOWN_LAST_PHASE) { @@ -1892,7 +1865,7 @@ srv_master_thread( ulint i; #ifdef UNIV_DEBUG_THREAD_CREATION - printf("Master thread starts, id %lu\n", + fprintf(stderr, "Master thread starts, id %lu\n", os_thread_pf(os_thread_get_curr_id())); #endif srv_main_thread_process_no = os_proc_get_number(); diff --git a/innobase/srv/srv0start.c b/innobase/srv/srv0start.c index d505c8779dc..f9b66b6e5fc 100644 --- a/innobase/srv/srv0start.c +++ b/innobase/srv/srv0start.c @@ -55,13 +55,13 @@ Created 2/16/1996 Heikki Tuuri #include "srv0start.h" #include "que0que.h" -ibool srv_start_has_been_called = FALSE; +static ibool srv_start_has_been_called = FALSE; ulint srv_sizeof_trx_t_in_ha_innodb_cc; ibool srv_startup_is_before_trx_rollback_phase = FALSE; ibool srv_is_being_started = FALSE; -ibool srv_was_started = FALSE; +static ibool srv_was_started = FALSE; /* At a shutdown the value first climbs to SRV_SHUTDOWN_CLEANUP and then to SRV_SHUTDOWN_LAST_PHASE */ @@ -69,19 +69,20 @@ ulint srv_shutdown_state = 0; ibool measure_cont = FALSE; -os_file_t files[1000]; +static os_file_t files[1000]; -mutex_t ios_mutex; -ulint ios; +static mutex_t ios_mutex; +static ulint ios; -ulint n[SRV_MAX_N_IO_THREADS + 5]; -os_thread_id_t thread_ids[SRV_MAX_N_IO_THREADS + 5]; +static ulint n[SRV_MAX_N_IO_THREADS + 5]; +static os_thread_id_t thread_ids[SRV_MAX_N_IO_THREADS + 5]; /* We use this mutex to test the return value of pthread_mutex_trylock on successful locking. HP-UX does NOT return 0, though Linux et al do. */ -os_fast_mutex_t srv_os_test_mutex; +static os_fast_mutex_t srv_os_test_mutex; -ibool srv_os_test_mutex_is_locked = FALSE; +/* Name of srv_monitor_file */ +static char* srv_monitor_file_name; #define SRV_N_PENDING_IOS_PER_THREAD OS_AIO_N_PENDING_IOS_PER_THREAD #define SRV_MAX_N_PENDING_SYNC_IOS 100 @@ -400,8 +401,8 @@ io_handler_thread( segment = *((ulint*)arg); #ifdef UNIV_DEBUG_THREAD_CREATION - printf("Io handler thread %lu starts, id %lu\n", segment, - os_thread_pf(os_thread_get_curr_id())); + fprintf(stderr, "Io handler thread %lu starts, id %lu\n", segment, + os_thread_pf(os_thread_get_curr_id())); #endif for (i = 0;; i++) { fil_aio_wait(segment); @@ -532,6 +533,8 @@ open_or_create_log_file( srv_log_group_home_dirs[k] = srv_add_path_separator_if_needed( srv_log_group_home_dirs[k]); + ut_a(strlen(srv_log_group_home_dirs[k]) < + (sizeof name) - 10 - sizeof "ib_logfile"); sprintf(name, "%s%s%lu", srv_log_group_home_dirs[k], "ib_logfile", i); files[i] = os_file_create(name, OS_FILE_CREATE, OS_FILE_NORMAL, @@ -680,6 +683,8 @@ open_or_create_data_files( for (i = 0; i < srv_n_data_files; i++) { srv_normalize_path_for_win(srv_data_file_names[i]); + ut_a(strlen(srv_data_home) + strlen(srv_data_file_names[i]) + < (sizeof name) - 1); sprintf(name, "%s%s", srv_data_home, srv_data_file_names[i]); files[i] = os_file_create(name, OS_FILE_CREATE, @@ -1016,6 +1021,19 @@ NetWare. */ return((int) err); } + mutex_create(&srv_monitor_file_mutex); + srv_monitor_file_name = mem_alloc( + strlen(fil_path_to_mysql_datadir) + + 20 + sizeof "/innodb_status."); + sprintf(srv_monitor_file_name, "%s/innodb.status.%lu", + fil_path_to_mysql_datadir, os_proc_get_number()); + srv_monitor_file = fopen(srv_monitor_file_name, "w+"); + if (!srv_monitor_file) { + fprintf(stderr, "InnoDB: unable to create %s: %s\n", + srv_monitor_file_name, strerror(errno)); + return(DB_ERROR); + } + /* Restrict the maximum number of file i/o threads */ if (srv_n_file_io_threads > SRV_MAX_N_IO_THREADS) { @@ -1505,6 +1523,15 @@ innobase_shutdown_for_mysql(void) os_thread_count); } + if (srv_monitor_file) { + fclose(srv_monitor_file); + srv_monitor_file = 0; + unlink(srv_monitor_file_name); + mem_free(srv_monitor_file_name); + } + + mutex_free(&srv_monitor_file_mutex); + /* 3. Free all InnoDB's own mutexes and the os_fast_mutexes inside them */ @@ -1531,6 +1558,13 @@ innobase_shutdown_for_mysql(void) os_fast_mutex_count); } + if (dict_foreign_err_file) { + fclose(dict_foreign_err_file); + } + if (lock_latest_err_file) { + fclose(lock_latest_err_file); + } + if (srv_print_verbose_log) { ut_print_timestamp(stderr); fprintf(stderr, " InnoDB: Shutdown completed\n"); diff --git a/innobase/sync/sync0arr.c b/innobase/sync/sync0arr.c index 67671299e3d..ddc1472cf4c 100644 --- a/innobase/sync/sync0arr.c +++ b/innobase/sync/sync0arr.c @@ -425,7 +425,7 @@ sync_array_wait_event( if (TRUE == sync_array_detect_deadlock(arr, cell, cell, 0)) { - printf("########################################\n"); + fputs("########################################\n", stderr); ut_error; } @@ -444,8 +444,7 @@ static void sync_array_cell_print( /*==================*/ - char* buf, /* in: buffer where to print, must be - at least 400 characters */ + FILE* file, /* in: file where to print */ sync_cell_t* cell) /* in: sync cell */ { mutex_t* mutex; @@ -455,7 +454,7 @@ sync_array_cell_print( type = cell->request_type; - buf += sprintf(buf, + fprintf(file, "--Thread %lu has waited at %s line %lu for %.2f seconds the semaphore:\n", os_thread_pf(cell->thread), cell->file, cell->line, difftime(time(NULL), cell->reservation_time)); @@ -465,7 +464,7 @@ sync_array_cell_print( been freed meanwhile */ mutex = cell->old_wait_mutex; - buf += sprintf(buf, + fprintf(file, "Mutex at %p created file %s line %lu, lock var %lu\n" #ifdef UNIV_SYNC_DEBUG "Last time reserved in file %s line %lu, " @@ -480,48 +479,39 @@ sync_array_cell_print( } else if (type == RW_LOCK_EX || type == RW_LOCK_SHARED) { - if (type == RW_LOCK_EX) { - buf += sprintf(buf, "X-lock on"); - } else { - buf += sprintf(buf, "S-lock on"); - } + fputs(type == RW_LOCK_EX ? "X-lock on" : "S-lock on", file); rwlock = cell->old_wait_rw_lock; - buf += sprintf(buf, - " RW-latch at %lx created in file %s line %lu\n", - (ulint)rwlock, rwlock->cfile_name, rwlock->cline); + fprintf(file, + " RW-latch at %p created in file %s line %lu\n", + rwlock, rwlock->cfile_name, rwlock->cline); if (rwlock->writer != RW_LOCK_NOT_LOCKED) { - buf += sprintf(buf, - "a writer (thread id %lu) has reserved it in mode", - os_thread_pf(rwlock->writer_thread)); - if (rwlock->writer == RW_LOCK_EX) { - buf += sprintf(buf, " exclusive\n"); - } else { - buf += sprintf(buf, " wait exclusive\n"); - } + fprintf(file, + "a writer (thread id %lu) has reserved it in mode %s", + os_thread_pf(rwlock->writer_thread), + rwlock->writer == RW_LOCK_EX + ? " exclusive\n" + : " wait exclusive\n"); } - buf += sprintf(buf, - "number of readers %lu, waiters flag %lu\n", - rwlock->reader_count, rwlock->waiters); - - buf += sprintf(buf, - "Last time read locked in file %s line %lu\n", - rwlock->last_s_file_name, rwlock->last_s_line); - buf += sprintf(buf, + fprintf(file, + "number of readers %lu, waiters flag %lu\n" + "Last time read locked in file %s line %lu\n" "Last time write locked in file %s line %lu\n", + rwlock->reader_count, rwlock->waiters, + rwlock->last_s_file_name, rwlock->last_s_line, rwlock->last_x_file_name, rwlock->last_x_line); } else { ut_error; } if (!cell->waiting) { - buf += sprintf(buf, "wait has ended\n"); + fputs("wait has ended\n", file); } if (cell->event_set) { - buf += sprintf(buf, "wait is ending\n"); + fputs("wait is ending\n", file); } } @@ -590,8 +580,8 @@ sync_array_deadlock_step( ut_dbg_stop_threads = TRUE; /* Deadlock */ - printf("########################################\n"); - printf("DEADLOCK of threads detected!\n"); + fputs("########################################\n" + "DEADLOCK of threads detected!\n", stderr); return(TRUE); @@ -623,8 +613,8 @@ sync_array_detect_deadlock( rw_lock_t* lock; os_thread_id_t thread; ibool ret; - rw_lock_debug_t* debug; - char buf[500]; + rw_lock_t* lock; + rw_lock_debug_t*debug; ut_a(arr && start && cell); ut_ad(cell->wait_object); @@ -657,11 +647,11 @@ sync_array_detect_deadlock( ret = sync_array_deadlock_step(arr, start, thread, 0, depth); if (ret) { - sync_array_cell_print(buf, cell); - printf( - "Mutex %lx owned by thread %lu file %s line %lu\n%s", - (ulint)mutex, os_thread_pf(mutex->thread_id), - mutex->file_name, mutex->line, buf); + fprintf(stderr, + "Mutex %p owned by thread %lu file %s line %lu\n", + mutex, os_thread_pf(mutex->thread_id), + mutex->file_name, mutex->line); + sync_array_cell_print(stderr, cell); return(TRUE); } @@ -694,8 +684,9 @@ sync_array_detect_deadlock( debug->pass, depth); if (ret) { - sync_array_cell_print(buf, cell); - printf("rw-lock %lx %s ", (ulint) lock, buf); + print: + fprintf(stderr, "rw-lock %p ", lock); + sync_array_cell_print(stderr, cell); rw_lock_debug_print(debug); return(TRUE); } @@ -726,11 +717,7 @@ sync_array_detect_deadlock( debug->pass, depth); if (ret) { - sync_array_cell_print(buf, cell); - printf("rw-lock %lx %s ", (ulint) lock, buf); - rw_lock_debug_print(debug); - - return(TRUE); + goto print; } } @@ -914,7 +901,6 @@ sync_array_print_long_waits(void) sync_cell_t* cell; ibool old_val; ibool noticed = FALSE; - char buf[500]; ulint i; for (i = 0; i < sync_primary_wait_array->n_cells; i++) { @@ -923,22 +909,19 @@ sync_array_print_long_waits(void) if (cell->wait_object != NULL && difftime(time(NULL), cell->reservation_time) > 240) { - - sync_array_cell_print(buf, cell); - - fprintf(stderr, - "InnoDB: Warning: a long semaphore wait:\n%s", buf); - + fputs("InnoDB: Warning: a long semaphore wait:\n", + stderr); + sync_array_cell_print(stderr, cell); noticed = TRUE; } if (cell->wait_object != NULL && difftime(time(NULL), cell->reservation_time) > 600) { - fprintf(stderr, + fputs( "InnoDB: Error: semaphore wait has lasted > 600 seconds\n" -"InnoDB: We intentionally crash the server, because it appears to be hung.\n" - ); +"InnoDB: We intentionally crash the server, because it appears to be hung.\n", + stderr); ut_error; } @@ -966,7 +949,7 @@ sync_array_print_long_waits(void) srv_print_innodb_monitor = old_val; fprintf(stderr, -"InnoDB: ###### Diagnostic info printed to the standard output\n"); +"InnoDB: ###### Diagnostic info printed to the standard error stream\n"); } } @@ -976,8 +959,7 @@ static void sync_array_output_info( /*===================*/ - char* buf, /* in/out: buffer where to print */ - char* buf_end,/* in: buffer end */ + FILE* file, /* in: file where to print */ sync_array_t* arr) /* in: wait array; NOTE! caller must own the mutex */ { @@ -985,11 +967,7 @@ sync_array_output_info( ulint count; ulint i; - if (buf_end - buf < 500) { - return; - } - - buf += sprintf(buf, + fprintf(file, "OS WAIT ARRAY INFO: reservation count %ld, signal count %ld\n", arr->res_count, arr->sg_count); i = 0; @@ -997,17 +975,11 @@ sync_array_output_info( while (count < arr->n_reserved) { - if (buf_end - buf < 500) { - return; - } - cell = sync_array_get_nth_cell(arr, i); if (cell->wait_object != NULL) { count++; - sync_array_cell_print(buf, cell); - - buf = buf + strlen(buf); + sync_array_cell_print(file, cell); } i++; @@ -1020,13 +992,12 @@ Prints info of the wait array. */ void sync_array_print_info( /*==================*/ - char* buf, /* in/out: buffer where to print */ - char* buf_end,/* in: buffer end */ + FILE* file, /* in: file where to print */ sync_array_t* arr) /* in: wait array */ { sync_array_enter(arr); - sync_array_output_info(buf, buf_end, arr); + sync_array_output_info(file, arr); sync_array_exit(arr); } diff --git a/innobase/sync/sync0rw.c b/innobase/sync/sync0rw.c index 86924c437c7..e3caa24cb1e 100644 --- a/innobase/sync/sync0rw.c +++ b/innobase/sync/sync0rw.c @@ -225,9 +225,9 @@ lock_loop: } if (srv_print_latch_waits) { - printf( - "Thread %lu spin wait rw-s-lock at %lx cfile %s cline %lu rnds %lu\n", - os_thread_pf(os_thread_get_curr_id()), (ulint)lock, + fprintf(stderr, + "Thread %lu spin wait rw-s-lock at %p cfile %s cline %lu rnds %lu\n", + os_thread_pf(os_thread_get_curr_id()), lock, lock->cfile_name, lock->cline, i); } @@ -255,9 +255,9 @@ lock_loop: mutex_exit(rw_lock_get_mutex(lock)); if (srv_print_latch_waits) { - printf( - "Thread %lu OS wait rw-s-lock at %lx cfile %s cline %lu\n", - os_thread_pf(os_thread_get_curr_id()), (ulint)lock, + fprintf(stderr, + "Thread %lu OS wait rw-s-lock at %p cfile %s cline %lu\n", + os_thread_pf(os_thread_get_curr_id()), lock, lock->cfile_name, lock->cline); } @@ -474,9 +474,9 @@ lock_loop: } if (srv_print_latch_waits) { - printf( - "Thread %lu spin wait rw-x-lock at %lx cfile %s cline %lu rnds %lu\n", - os_thread_pf(os_thread_get_curr_id()), (ulint)lock, + fprintf(stderr, + "Thread %lu spin wait rw-x-lock at %p cfile %s cline %lu rnds %lu\n", + os_thread_pf(os_thread_get_curr_id()), lock, lock->cfile_name, lock->cline, i); } @@ -507,9 +507,9 @@ lock_loop: mutex_exit(rw_lock_get_mutex(lock)); if (srv_print_latch_waits) { - printf( - "Thread %lu OS wait for rw-x-lock at %lx cfile %s cline %lu\n", - os_thread_pf(os_thread_get_curr_id()), (ulint)lock, + fprintf(stderr, + "Thread %lu OS wait for rw-x-lock at %p cfile %s cline %lu\n", + os_thread_pf(os_thread_get_curr_id()), lock, lock->cfile_name, lock->cline); } @@ -752,9 +752,9 @@ rw_lock_list_print_info(void) mutex_enter(&rw_lock_list_mutex); - printf("-------------\n"); - printf("RW-LATCH INFO\n"); - printf("-------------\n"); + fputs("-------------\n" + "RW-LATCH INFO\n" + "-------------\n", stderr); lock = UT_LIST_GET_FIRST(rw_lock_list); @@ -768,12 +768,12 @@ rw_lock_list_print_info(void) || (rw_lock_get_reader_count(lock) != 0) || (rw_lock_get_waiters(lock) != 0)) { - printf("RW-LOCK: %lx ", (ulint)lock); + fprintf(stderr, "RW-LOCK: %p ", lock); if (rw_lock_get_waiters(lock)) { - printf(" Waiters for the lock exist\n"); + fputs(" Waiters for the lock exist\n", stderr); } else { - printf("\n"); + putc('\n', stderr); } info = UT_LIST_GET_FIRST(lock->debug_list); @@ -787,7 +787,7 @@ rw_lock_list_print_info(void) lock = UT_LIST_GET_NEXT(list, lock); } - printf("Total number of rw-locks %ld\n", count); + fprintf(stderr, "Total number of rw-locks %ld\n", count); mutex_exit(&rw_lock_list_mutex); } @@ -797,22 +797,23 @@ Prints debug info of an rw-lock. */ void rw_lock_print( /*==========*/ - rw_lock_t* lock __attribute__((unused))) /* in: rw-lock */ + rw_lock_t* lock) /* in: rw-lock */ { rw_lock_debug_t* info; - printf("-------------\n"); - printf("RW-LATCH INFO\n"); - printf("RW-LATCH: %lx ", (ulint)lock); + fprintf(stderr, + "-------------\n" + "RW-LATCH INFO\n" + "RW-LATCH: %p ", lock); if ((rw_lock_get_writer(lock) != RW_LOCK_NOT_LOCKED) || (rw_lock_get_reader_count(lock) != 0) || (rw_lock_get_waiters(lock) != 0)) { if (rw_lock_get_waiters(lock)) { - printf(" Waiters for the lock exist\n"); + fputs(" Waiters for the lock exist\n", stderr); } else { - printf("\n"); + putc('\n', stderr); } info = UT_LIST_GET_FIRST(lock->debug_list); @@ -835,21 +836,21 @@ rw_lock_debug_print( rwt = info->lock_type; - printf("Locked: thread %ld file %s line %ld ", + fprintf(stderr, "Locked: thread %ld file %s line %ld ", os_thread_pf(info->thread_id), info->file_name, info->line); if (rwt == RW_LOCK_SHARED) { - printf("S-LOCK"); + fputs("S-LOCK", stderr); } else if (rwt == RW_LOCK_EX) { - printf("X-LOCK"); + fputs("X-LOCK", stderr); } else if (rwt == RW_LOCK_WAIT_EX) { - printf("WAIT X-LOCK"); + fputs("WAIT X-LOCK", stderr); } else { ut_error; } if (info->pass != 0) { - printf(" pass value %lu", info->pass); + fprintf(stderr, " pass value %lu", info->pass); } - printf("\n"); + putc('\n', stderr); } /******************************************************************* diff --git a/innobase/sync/sync0sync.c b/innobase/sync/sync0sync.c index 72f6f0be390..3539d7de817 100644 --- a/innobase/sync/sync0sync.c +++ b/innobase/sync/sync0sync.c @@ -352,9 +352,9 @@ spin_loop: } if (srv_print_latch_waits) { - printf( - "Thread %lu spin wait mutex at %lx cfile %s cline %lu rnds %lu\n", - os_thread_pf(os_thread_get_curr_id()), (ulint)mutex, + fprintf(stderr, + "Thread %lu spin wait mutex at %p cfile %s cline %lu rnds %lu\n", + os_thread_pf(os_thread_get_curr_id()), mutex, mutex->cfile_name, mutex->cline, i); } @@ -412,9 +412,10 @@ spin_loop: #endif if (srv_print_latch_waits) { - printf( - "Thread %lu spin wait succeeds at 2: mutex at %lx\n", - os_thread_pf(os_thread_get_curr_id()), (ulint)mutex); + fprintf(stderr, + "Thread %lu spin wait succeeds at 2:" + " mutex at %p\n", + os_thread_pf(os_thread_get_curr_id()), mutex); } return; @@ -430,9 +431,9 @@ spin_loop: Now there is no risk of infinite wait on the event. */ if (srv_print_latch_waits) { - printf( - "Thread %lu OS wait mutex at %lx cfile %s cline %lu rnds %lu\n", - os_thread_pf(os_thread_get_curr_id()), (ulint)mutex, + fprintf(stderr, + "Thread %lu OS wait mutex at %p cfile %s cline %lu rnds %lu\n", + os_thread_pf(os_thread_get_curr_id()), mutex, mutex->cfile_name, mutex->cline, i); } @@ -552,9 +553,9 @@ mutex_list_print_info(void) os_thread_id_t thread_id; ulint count = 0; - printf("----------\n"); - printf("MUTEX INFO\n"); - printf("----------\n"); + fputs("----------\n" + "MUTEX INFO\n" + "----------\n", stderr); mutex_enter(&mutex_list_mutex); @@ -566,16 +567,16 @@ mutex_list_print_info(void) if (mutex_get_lock_word(mutex) != 0) { mutex_get_debug_info(mutex, &file_name, &line, &thread_id); - printf( - "Locked mutex: addr %lx thread %ld file %s line %ld\n", - (ulint)mutex, os_thread_pf(thread_id), + fprintf(stderr, + "Locked mutex: addr %p thread %ld file %s line %ld\n", + mutex, os_thread_pf(thread_id), file_name, line); } mutex = UT_LIST_GET_NEXT(list, mutex); } - printf("Total number of mutexes %ld\n", count); + fprintf(stderr, "Total number of mutexes %ld\n", count); mutex_exit(&mutex_list_mutex); } @@ -733,12 +734,14 @@ sync_thread_levels_g( lock = slot->latch; mutex = slot->latch; - printf( + fprintf(stderr, "InnoDB error: sync levels should be > %lu but a level is %lu\n", limit, slot->level); if (mutex->magic_n == MUTEX_MAGIC_N) { - printf("Mutex created at %s %lu\n", mutex->cfile_name, + fprintf(stderr, + "Mutex created at %s %lu\n", + mutex->cfile_name, mutex->cline); if (mutex_get_lock_word(mutex) != 0) { @@ -819,9 +822,6 @@ sync_thread_levels_empty_gen( sync_level_t* arr; sync_thread_t* thread_slot; sync_level_t* slot; - rw_lock_t* lock; - mutex_t* mutex; - char* buf; ulint i; if (!sync_order_checks_on) { @@ -850,13 +850,7 @@ sync_thread_levels_empty_gen( (slot->level != SYNC_DICT && slot->level != SYNC_DICT_OPERATION))) { - lock = slot->latch; - mutex = slot->latch; mutex_exit(&sync_thread_mutex); - - buf = mem_alloc(20000); - - sync_print(buf, buf + 18000); ut_error; return(FALSE); @@ -1211,19 +1205,14 @@ Prints wait info of the sync system. */ void sync_print_wait_info( /*=================*/ - char* buf, /* in/out: buffer where to print */ - char* buf_end) /* in: buffer end */ + FILE* file) /* in: file where to print */ { #ifdef UNIV_SYNC_DEBUG - printf("Mutex exits %lu, rws exits %lu, rwx exits %lu\n", + fprintf(stderr, "Mutex exits %lu, rws exits %lu, rwx exits %lu\n", mutex_exit_count, rw_s_exit_count, rw_x_exit_count); #endif - if (buf_end - buf < 500) { - return; - } - - sprintf(buf, + fprintf(file, "Mutex spin waits %lu, rounds %lu, OS waits %lu\n" "RW-shared spins %lu, OS waits %lu; RW-excl spins %lu, OS waits %lu\n", mutex_spin_wait_count, mutex_spin_round_count, @@ -1238,8 +1227,7 @@ Prints info of the sync system. */ void sync_print( /*=======*/ - char* buf, /* in/out: buffer where to print */ - char* buf_end) /* in: buffer end */ + FILE* file) /* in: file where to print */ { #ifdef UNIV_SYNC_DEBUG mutex_list_print_info(); @@ -1247,9 +1235,7 @@ sync_print( rw_lock_list_print_info(); #endif /* UNIV_SYNC_DEBUG */ - sync_array_print_info(buf, buf_end, sync_primary_wait_array); + sync_array_print_info(file, sync_primary_wait_array); - buf = buf + strlen(buf); - - sync_print_wait_info(buf, buf_end); + sync_print_wait_info(file); } diff --git a/innobase/trx/trx0purge.c b/innobase/trx/trx0purge.c index 6a509b163b3..a8b6b9fcc21 100644 --- a/innobase/trx/trx0purge.c +++ b/innobase/trx/trx0purge.c @@ -337,7 +337,7 @@ trx_purge_free_segment( ibool marked = FALSE; mtr_t mtr; -/* printf("Freeing an update undo log segment\n"); */ +/* fputs("Freeing an update undo log segment\n", stderr); */ #ifdef UNIV_SYNC_DEBUG ut_ad(mutex_own(&(purge_sys->mutex))); @@ -918,7 +918,7 @@ trx_purge_fetch_next_rec( trx_purge_truncate_if_arr_empty(); if (srv_print_thread_releases) { - printf( + fprintf(stderr, "Purge: No logs left in the history list; pages handled %lu\n", purge_sys->n_pages_handled); } @@ -951,7 +951,7 @@ trx_purge_fetch_next_rec( return(NULL); } -/* printf("Thread %lu purging trx %lu undo record %lu\n", +/* fprintf(stderr, "Thread %lu purging trx %lu undo record %lu\n", os_thread_get_curr_id(), ut_dulint_get_low(purge_sys->purge_trx_no), ut_dulint_get_low(purge_sys->purge_undo_no)); */ @@ -1064,14 +1064,14 @@ trx_purge(void) if (srv_print_thread_releases) { - printf("Starting purge\n"); + fputs("Starting purge\n", stderr); } que_run_threads(thr); if (srv_print_thread_releases) { - printf( + fprintf(stderr, "Purge ends; pages handled %lu\n", purge_sys->n_pages_handled); } diff --git a/innobase/trx/trx0rec.c b/innobase/trx/trx0rec.c index 9d944e16a1e..4926c776ae9 100644 --- a/innobase/trx/trx0rec.c +++ b/innobase/trx/trx0rec.c @@ -823,17 +823,18 @@ trx_undo_update_rec_get_update( if (field_no >= dict_index_get_n_fields(index)) { fprintf(stderr, - "InnoDB: Error: trying to access update undo rec field %lu in table %s\n" - "InnoDB: index %s, but index has only %lu fields\n", - field_no, index->table_name, index->name, - dict_index_get_n_fields(index)); - fprintf(stderr, - "InnoDB: Send a detailed bug report to mysql@lists.mysql.com"); - - fprintf(stderr, - "InnoDB: Run also CHECK TABLE on table %s\n", index->table_name); - fprintf(stderr, - "InnoDB: n_fields = %lu, i = %lu, ptr %lx\n", n_fields, i, (ulint)ptr); + "InnoDB: Error: trying to access" + " update undo rec field %lu in ", field_no); + dict_index_name_print(stderr, index); + fprintf(stderr, "\n" + "InnoDB: but index has only %lu fields\n" + "InnoDB: Send a detailed bug report to mysql@lists.mysql.com\n" + "InnoDB: Run also CHECK TABLE ", + dict_index_get_n_fields(index)); + ut_print_name(stderr, index->table_name); + fprintf(stderr, "\n" + "InnoDB: n_fields = %lu, i = %lu, ptr %p\n", + n_fields, i, ptr); return(NULL); } @@ -1258,8 +1259,6 @@ trx_undo_prev_version_build( byte* buf; ulint err; ulint i; - char err_buf[1000]; - #ifdef UNIV_SYNC_DEBUG ut_ad(rw_lock_own(&(purge_sys->latch), RW_LOCK_SHARED)); #endif /* UNIV_SYNC_DEBUG */ @@ -1268,19 +1267,18 @@ trx_undo_prev_version_build( mtr_memo_contains(index_mtr, buf_block_align(index_rec), MTR_MEMO_PAGE_X_FIX)); if (!(index->type & DICT_CLUSTERED)) { - fprintf(stderr, - "InnoDB: Error: trying to access update undo rec for table %s\n" - "InnoDB: index %s which is not a clustered index\n", - index->table_name, index->name); - fprintf(stderr, - "InnoDB: Send a detailed bug report to mysql@lists.mysql.com"); - - rec_sprintf(err_buf, 900, index_rec); - fprintf(stderr, "InnoDB: index record %s\n", err_buf); - - rec_sprintf(err_buf, 900, rec); - fprintf(stderr, "InnoDB: record version %s\n", err_buf); - + fputs("InnoDB: Error: trying to access" + " update undo rec for non-clustered ", stderr); + dict_index_name_print(stderr, index); + fputs("\n" + "InnoDB: Send a detailed bug report to" + " mysql@lists.mysql.com\n" + "InnoDB: index record ", stderr); + rec_print(stderr, index_rec); + fputs("\n" + "InnoDB: record version ", stderr); + rec_print(stderr, rec); + putc('\n', stderr); return(DB_ERROR); } @@ -1318,55 +1316,50 @@ trx_undo_prev_version_build( if (ut_dulint_cmp(table_id, index->table->id) != 0) { ptr = NULL; - fprintf(stderr, - "InnoDB: Error: trying to access update undo rec for table %s\n" - "InnoDB: but the table id in the undo record is wrong\n", - index->table_name); - fprintf(stderr, - "InnoDB: Send a detailed bug report to mysql@lists.mysql.com\n"); - - fprintf(stderr, - "InnoDB: Run also CHECK TABLE on table %s\n", index->table_name); + fputs("InnoDB: Error: trying to access" + " update undo rec for table ", stderr); + ut_print_name(stderr, index->table_name); + fputs("\n" + "InnoDB: but the table id in the" + " undo record is wrong\n" + "InnoDB: Send a detailed bug report to " + "mysql@lists.mysql.com\n" + "InnoDB: Run also CHECK TABLE ", stderr); + ut_print_name(stderr, index->table_name); + putc('\n', stderr); } if (ptr == NULL) { /* The record was corrupted, return an error; these printfs should catch an elusive bug in row_vers_old_has_index_entry */ - fprintf(stderr, - "InnoDB: Table name %s, index name %s, n_uniq %lu\n", - index->table_name, index->name, - dict_index_get_n_unique(index)); - - fprintf(stderr, - "InnoDB: undo rec address %lx, type %lu cmpl_info %lu\n", - (ulint)undo_rec, type, cmpl_info); - fprintf(stderr, - "InnoDB: undo rec table id %lu %lu, index table id %lu %lu\n", + fputs("InnoDB: ", stderr); + dict_index_name_print(stderr, index); + fprintf(stderr, ", n_uniq %lu\n" + "InnoDB: undo rec address %p, type %lu cmpl_info %lu\n" + "InnoDB: undo rec table id %lu %lu, index table id %lu %lu\n" + "InnoDB: dump of 150 bytes in undo rec: ", + dict_index_get_n_unique(index), + undo_rec, type, cmpl_info, ut_dulint_get_high(table_id), ut_dulint_get_low(table_id), ut_dulint_get_high(index->table->id), ut_dulint_get_low(index->table->id)); - ut_sprintf_buf(err_buf, undo_rec, 150); - - fprintf(stderr, "InnoDB: dump of 150 bytes in undo rec: %s\n", - err_buf); - rec_sprintf(err_buf, 900, index_rec); - fprintf(stderr, "InnoDB: index record %s\n", err_buf); - - rec_sprintf(err_buf, 900, rec); - fprintf(stderr, "InnoDB: record version %s\n", err_buf); - - fprintf(stderr, - "InnoDB: Record trx id %lu %lu, update rec trx id %lu %lu\n", + ut_print_buf(stderr, undo_rec, 150); + fputs("\n" + "InnoDB: index record ", stderr); + rec_print(stderr, index_rec); + fputs("\n" + "InnoDB: record version ", stderr); + rec_print(stderr, rec); + fprintf(stderr, "\n" + "InnoDB: Record trx id %lu %lu, update rec trx id %lu %lu\n" + "InnoDB: Roll ptr in rec %lu %lu, in update rec %lu %lu\n", ut_dulint_get_high(rec_trx_id), ut_dulint_get_low(rec_trx_id), ut_dulint_get_high(trx_id), - ut_dulint_get_low(trx_id)); - - fprintf(stderr, - "InnoDB: Roll ptr in rec %lu %lu, in update rec %lu %lu\n", + ut_dulint_get_low(trx_id), ut_dulint_get_high(old_roll_ptr), ut_dulint_get_low(old_roll_ptr), ut_dulint_get_high(roll_ptr), diff --git a/innobase/trx/trx0roll.c b/innobase/trx/trx0roll.c index 2adebbc6b4b..eed5e79a20f 100644 --- a/innobase/trx/trx0roll.c +++ b/innobase/trx/trx0roll.c @@ -228,9 +228,9 @@ trx_rollback_to_savepoint_for_mysql( if (trx->conc_state == TRX_NOT_STARTED) { ut_print_timestamp(stderr); - fprintf(stderr, -" InnoDB: Error: transaction has a savepoint %s though it is not started\n", - savep->name); + fputs(" InnoDB: Error: transaction has a savepoint ", stderr); + ut_print_name(stderr, savep->name); + fputs(" though it is not started\n", stderr); return(DB_ERROR); } @@ -466,8 +466,9 @@ loop: table = dict_table_get_on_id_low(trx->table_id, trx); if (table) { - fprintf(stderr, -"InnoDB: Table found: dropping table %s in recovery\n", table->name); + fputs("InnoDB: Table found: dropping table ", stderr); + ut_print_name(stderr, table->name); + fputs(" in recovery\n", stderr); err = row_drop_table_for_mysql(table->name, trx, TRUE); @@ -729,7 +730,7 @@ trx_roll_pop_top_rec( undo->top_page_no, mtr); offset = undo->top_offset; -/* printf("Thread %lu undoing trx %lu undo record %lu\n", +/* fprintf(stderr, "Thread %lu undoing trx %lu undo record %lu\n", os_thread_get_curr_id(), ut_dulint_get_low(trx->id), ut_dulint_get_low(undo->top_undo_no)); */ @@ -1140,7 +1141,7 @@ trx_finish_rollback_off_kernel( } if (lock_print_waits) { - printf("Trx %lu rollback finished\n", + fprintf(stderr, "Trx %lu rollback finished\n", ut_dulint_get_low(trx->id)); } diff --git a/innobase/trx/trx0sys.c b/innobase/trx/trx0sys.c index 493a5e94e79..e0c30df17af 100644 --- a/innobase/trx/trx0sys.c +++ b/innobase/trx/trx0sys.c @@ -600,7 +600,7 @@ trx_sys_update_mysql_binlog_offset( } /********************************************************************* -Prints to stdout the MySQL binlog info in the system header if the +Prints to stderr the MySQL binlog info in the system header if the magic number shows it valid. */ void @@ -617,7 +617,7 @@ trx_sys_print_mysql_binlog_offset_from_page( + TRX_SYS_MYSQL_LOG_MAGIC_N_FLD) == TRX_SYS_MYSQL_LOG_MAGIC_N) { - printf( + fprintf(stderr, "ibbackup: Last MySQL binlog file position %lu %lu, file name %s\n", mach_read_from_4(sys_header + TRX_SYS_MYSQL_LOG_INFO + TRX_SYS_MYSQL_LOG_OFFSET_HIGH), diff --git a/innobase/trx/trx0trx.c b/innobase/trx/trx0trx.c index 9b6e6904537..7a028c92060 100644 --- a/innobase/trx/trx0trx.c +++ b/innobase/trx/trx0trx.c @@ -26,10 +26,10 @@ Created 3/26/1996 Heikki Tuuri #include "os0proc.h" /* Copy of the prototype for innobase_mysql_print_thd: this -copy MUST be equal to the one in mysql/sql/ha_innobase.cc ! */ +copy MUST be equal to the one in mysql/sql/ha_innodb.cc ! */ void innobase_mysql_print_thd( - char* buf, + FILE* f, void* thd); /* Dummy session used currently in MySQL interface */ @@ -239,19 +239,17 @@ trx_free( /*=====*/ trx_t* trx) /* in, own: trx object */ { - char err_buf[1000]; - #ifdef UNIV_SYNC_DEBUG ut_ad(mutex_own(&kernel_mutex)); #endif /* UNIV_SYNC_DEBUG */ if (trx->declared_to_be_inside_innodb) { ut_print_timestamp(stderr); - trx_print(err_buf, trx); - - fprintf(stderr, + fputs( " InnoDB: Error: Freeing a trx which is declared to be processing\n" -"InnoDB: inside InnoDB.\n%s\n", err_buf); +"InnoDB: inside InnoDB.\n", stderr); + trx_print(stderr, trx); + putc('\n', stderr); } ut_a(trx->magic_n == TRX_MAGIC_N); @@ -756,7 +754,8 @@ trx_commit_off_kernel( trx->read_view = NULL; } -/* printf("Trx %lu commit finished\n", ut_dulint_get_low(trx->id)); */ +/* fprintf(stderr, "Trx %lu commit finished\n", + ut_dulint_get_low(trx->id)); */ if (must_flush_log) { @@ -1566,93 +1565,99 @@ own the kernel mutex. */ void trx_print( /*======*/ - char* buf, /* in/out: buffer where to print, must be at least - 800 bytes */ + FILE* f, /* in: output stream */ trx_t* trx) /* in: transaction */ { - char* start_of_line; + ibool newline; - buf += sprintf(buf, "TRANSACTION %lu %lu", + fprintf(f, "TRANSACTION %lu %lu", ut_dulint_get_high(trx->id), ut_dulint_get_low(trx->id)); switch (trx->conc_state) { - case TRX_NOT_STARTED: buf += sprintf(buf, - ", not started"); break; - case TRX_ACTIVE: buf += sprintf(buf, - ", ACTIVE %lu sec", - (ulint)difftime(time(NULL), trx->start_time)); break; - case TRX_COMMITTED_IN_MEMORY: buf += sprintf(buf, - ", COMMITTED IN MEMORY"); + case TRX_NOT_STARTED: + fputs(", not started", f); + break; + case TRX_ACTIVE: + fprintf(f, ", ACTIVE %lu sec", + (ulint)difftime(time(NULL), trx->start_time)); break; - default: buf += sprintf(buf, " state %lu", trx->conc_state); + case TRX_COMMITTED_IN_MEMORY: + fputs(", COMMITTED IN MEMORY", f); + break; + default: + fprintf(f, " state %lu", trx->conc_state); } #ifdef UNIV_LINUX - buf += sprintf(buf, ", process no %lu", trx->mysql_process_no); + fprintf(f, ", process no %lu", trx->mysql_process_no); #endif - buf += sprintf(buf, ", OS thread id %lu", + fprintf(f, ", OS thread id %lu", os_thread_pf(trx->mysql_thread_id)); - if (ut_strlen(trx->op_info) > 0) { - buf += sprintf(buf, " %s", trx->op_info); + if (*trx->op_info) { + putc(' ', f); + fputs(trx->op_info, f); } if (trx->type != TRX_USER) { - buf += sprintf(buf, " purge trx"); + fputs(" purge trx", f); } if (trx->declared_to_be_inside_innodb) { - buf += sprintf(buf, ", thread declared inside InnoDB %lu", + fprintf(f, ", thread declared inside InnoDB %lu", trx->n_tickets_to_enter_innodb); } - buf += sprintf(buf, "\n"); + putc('\n', f); if (trx->n_mysql_tables_in_use > 0 || trx->mysql_n_tables_locked > 0) { - buf += sprintf(buf, "mysql tables in use %lu, locked %lu\n", + fprintf(f, "mysql tables in use %lu, locked %lu\n", trx->n_mysql_tables_in_use, trx->mysql_n_tables_locked); } - start_of_line = buf; + newline = TRUE; switch (trx->que_state) { - case TRX_QUE_RUNNING: break; - case TRX_QUE_LOCK_WAIT: buf += sprintf(buf, - "LOCK WAIT "); break; - case TRX_QUE_ROLLING_BACK: buf += sprintf(buf, - "ROLLING BACK "); break; - case TRX_QUE_COMMITTING: buf += sprintf(buf, - "COMMITTING "); break; - default: buf += sprintf(buf, "que state %lu", trx->que_state); + case TRX_QUE_RUNNING: + newline = FALSE; break; + case TRX_QUE_LOCK_WAIT: + fputs("LOCK WAIT ", f); break; + case TRX_QUE_ROLLING_BACK: + fputs("ROLLING BACK ", f); break; + case TRX_QUE_COMMITTING: + fputs("COMMITTING ", f); break; + default: + fprintf(f, "que state %lu ", trx->que_state); } if (0 < UT_LIST_GET_LEN(trx->trx_locks) || mem_heap_get_size(trx->lock_heap) > 400) { + newline = TRUE; - buf += sprintf(buf, -"%lu lock struct(s), heap size %lu", + fprintf(f, "%lu lock struct(s), heap size %lu", UT_LIST_GET_LEN(trx->trx_locks), mem_heap_get_size(trx->lock_heap)); } if (trx->has_search_latch) { - buf += sprintf(buf, ", holds adaptive hash latch"); + newline = TRUE; + fputs(", holds adaptive hash latch", f); } if (ut_dulint_cmp(trx->undo_no, ut_dulint_zero) != 0) { - buf += sprintf(buf, ", undo log entries %lu", + newline = TRUE; + fprintf(f, ", undo log entries %lu", ut_dulint_get_low(trx->undo_no)); } - if (buf != start_of_line) { - - buf += sprintf(buf, "\n"); + if (newline) { + putc('\n', f); } if (trx->mysql_thd != NULL) { - innobase_mysql_print_thd(buf, trx->mysql_thd); + innobase_mysql_print_thd(f, trx->mysql_thd); } } diff --git a/innobase/trx/trx0undo.c b/innobase/trx/trx0undo.c index de3da382e83..cf8a69c8cca 100644 --- a/innobase/trx/trx0undo.c +++ b/innobase/trx/trx0undo.c @@ -393,13 +393,10 @@ trx_undo_seg_create( #ifdef UNIV_SYNC_DEBUG ut_ad(mutex_own(&(rseg->mutex))); #endif /* UNIV_SYNC_DEBUG */ -/* - if (type == TRX_UNDO_INSERT) { - printf("Creating insert undo log segment\n"); - } else { - printf("Creating update undo log segment\n"); - } -*/ + +/* fputs(type == TRX_UNDO_INSERT + ? "Creating insert undo log segment\n" + : "Creating update undo log segment\n", stderr); */ slot_no = trx_rsegf_undo_find_free(rseg_hdr, mtr); if (slot_no == ULINT_UNDEFINED) { diff --git a/innobase/ut/ut0ut.c b/innobase/ut/ut0ut.c index be311764261..1be4cc0e0d8 100644 --- a/innobase/ut/ut0ut.c +++ b/innobase/ut/ut0ut.c @@ -19,6 +19,16 @@ Created 5/11/1994 Heikki Tuuri ibool ut_always_false = FALSE; +/********************************************************************* +Get the quote character to be used in SQL identifiers. +This definition must match the one in sql/ha_innodb.cc! */ + +char +mysql_get_identifier_quote_char(void); +/*=================================*/ + /* out: quote character to be + used in SQL identifiers */ + /************************************************************ Uses vsprintf to emulate sprintf so that the function always returns the printed length. Apparently in some old SCO Unixes sprintf did not @@ -139,7 +149,7 @@ ut_print_timestamp( } /************************************************************** -Sprintfs a timestamp to a buffer. */ +Sprintfs a timestamp to a buffer, 13..14 chars plus terminating NUL. */ void ut_sprintf_timestamp( @@ -232,7 +242,7 @@ ut_delay( } if (ut_always_false) { - printf("%lu", j); + ut_always_false = (ibool) j; } return(j); @@ -244,78 +254,29 @@ Prints the contents of a memory buffer in hex and ascii. */ void ut_print_buf( /*=========*/ - byte* buf, /* in: memory buffer */ - ulint len) /* in: length of the buffer */ + FILE* file, /* in: file where to print */ + const byte* buf, /* in: memory buffer */ + ulint len) /* in: length of the buffer */ { - byte* data; - ulint i; + const byte* data; + ulint i; - printf(" len %lu; hex ", len); - - data = buf; + fprintf(file, " len %lu; hex ", len); - for (i = 0; i < len; i++) { - printf("%02lx", (ulint)*data); - data++; + for (data = buf, i = 0; i < len; i++) { + fprintf(file, "%02lx", (ulint)*data++); } - printf("; asc "); + fputs("; asc ", file); data = buf; for (i = 0; i < len; i++) { - if (isprint((int)(*data))) { - printf("%c", (char)*data); - } - data++; + int c = (int) *data++; + putc(isprint(c) ? c : ' ', file); } - printf(";"); -} - -/***************************************************************** -Prints the contents of a memory buffer in hex and ascii. */ - -ulint -ut_sprintf_buf( -/*===========*/ - /* out: printed length in bytes */ - char* str, /* in: buffer to print to */ - byte* buf, /* in: memory buffer */ - ulint len) /* in: length of the buffer */ -{ - byte* data; - ulint n; - ulint i; - - n = 0; - - n += sprintf(str + n, " len %lu; hex ", len); - - data = buf; - - for (i = 0; i < len; i++) { - n += sprintf(str + n, "%02lx", (ulint)*data); - data++; - } - - n += sprintf(str + n, "; asc "); - - data = buf; - - for (i = 0; i < len; i++) { - if (isprint((int)(*data))) { - n += sprintf(str + n, "%c", (char)*data); - } else { - n += sprintf(str + n, "."); - } - - data++; - } - - n += sprintf(str + n, ";"); - - return(n); + putc(';', file); } /**************************************************************** @@ -351,3 +312,64 @@ ut_2_power_up( return(res); } + +/************************************************************************** +Outputs a NUL-terminated string, quoted as an SQL identifier. */ + +void +ut_print_name( +/*==========*/ + FILE* f, /* in: output stream */ + const char* name) /* in: name to print */ +{ + ut_print_namel(f, name, strlen(name)); +} + +/************************************************************************** +Outputs a fixed-length string, quoted as an SQL identifier. */ + +void +ut_print_namel( +/*==========*/ + FILE* f, /* in: output stream */ + const char* name, /* in: name to print */ + ulint namelen)/* in: length of name */ +{ + const char* s = name; + const char* e = s + namelen; + char q = mysql_get_identifier_quote_char(); + putc(q, f); + while (s < e) { + int c = *s++; + if (c == q) { + putc(c, f); + } + putc(c, f); + } + putc(q, f); +} + +/************************************************************************** +Catenate files. */ + +void +ut_copy_file( +/*=========*/ + FILE* dest, /* in: output file */ + FILE* src) /* in: input file to be appended to output */ +{ + long len = ftell(src); + char buf[4096]; + + rewind(src); + do { + size_t maxs = + len < (long) sizeof buf ? (size_t) len : sizeof buf; + size_t size = fread(buf, 1, maxs, src); + fwrite(buf, 1, size, dest); + len -= size; + if (size < maxs) { + break; + } + } while (len > 0); +} diff --git a/sql/ha_innodb.cc b/sql/ha_innodb.cc index ff249b9d251..759679d5bd6 100644 --- a/sql/ha_innodb.cc +++ b/sql/ha_innodb.cc @@ -309,70 +309,49 @@ convert_error_code_to_mysql( } } -extern "C" { /***************************************************************** Prints info of a THD object (== user session thread) to the standard output. NOTE that /mysql/innobase/trx/trx0trx.c must contain the prototype for this function! */ - +extern "C" void innobase_mysql_print_thd( /*=====================*/ - char* buf, /* in/out: buffer where to print, must be at least - 400 bytes */ + FILE* f, /* in: output stream */ void* input_thd)/* in: pointer to a MySQL THD object */ { THD* thd; - char* old_buf = buf; thd = (THD*) input_thd; - /* We cannot use the return value of normal sprintf() as this is - not portable to some old non-Posix Unixes, e.g., some old SCO - Unixes */ + fprintf(f, "MySQL thread id %lu, query id %lu", + thd->thread_id, thd->query_id); + if (thd->host) { + putc(' ', f); + fputs(thd->host, f); + } - buf += my_sprintf(buf, - (buf, "MySQL thread id %lu, query id %lu", - thd->thread_id, thd->query_id)); - if (thd->host) { - *buf = ' '; - buf++; - buf = strnmov(buf, thd->host, 30); - } - - if (thd->ip) { - *buf = ' '; - buf++; - buf=strnmov(buf, thd->ip, 20); - } + if (thd->ip) { + putc(' ', f); + fputs(thd->ip, f); + } if (thd->user) { - *buf = ' '; - buf++; - buf=strnmov(buf, thd->user, 20); + putc(' ', f); + fputs(thd->user, f); } - if (thd->proc_info) { - *buf = ' '; - buf++; - buf=strnmov(buf, thd->proc_info, 50); - } + if (thd->proc_info) { + putc(' ', f); + fputs(thd->proc_info, f); + } - if (thd->query) { - *buf = '\n'; - buf++; - buf=strnmov(buf, thd->query, 150); - } + if (thd->query) { + putc(' ', f); + fputs(thd->query, f); + } - buf[0] = '\n'; - buf[1] = '\0'; /* Note that we must put a null character here to end - the printed string */ - - /* We test the printed length did not overrun the buffer length of - 400 bytes */ - - ut_a(strlen(old_buf) < 400); -} + putc('\n', f); } /************************************************************************* @@ -605,12 +584,11 @@ innobase_query_caching_of_table_permitted( return((my_bool)FALSE); } -extern "C" { /********************************************************************* Invalidates the MySQL query cache for the table. NOTE that the exact prototype of this function has to be in /innobase/row/row0ins.c! */ - +extern "C" void innobase_invalidate_query_cache( /*============================*/ @@ -630,6 +608,17 @@ innobase_invalidate_query_cache( TRUE); #endif } + +/********************************************************************* +Get the quote character to be used in SQL identifiers. */ +extern "C" +char +mysql_get_identifier_quote_char(void) +/*=================================*/ + /* out: quote character to be + used in SQL identifiers */ +{ + return '`'; } /********************************************************************* @@ -1244,19 +1233,6 @@ innobase_close_connection( return(0); } -/********************************************************************** -Prints an error message. */ -static -void -innobase_print_error( -/*=================*/ - const char* db_errpfx, /* in: error prefix text */ - char* buffer) /* in: error text */ -{ - sql_print_error("%s: %s", db_errpfx, buffer); -} - - /***************************************************************************** ** InnoDB database tables *****************************************************************************/ @@ -2017,24 +1993,20 @@ ha_innobase::write_row( if (prebuilt->trx != (trx_t*) current_thd->transaction.all.innobase_tid) { - char err_buf[2000]; - fprintf(stderr, "InnoDB: Error: the transaction object for the table handle is at\n" -"InnoDB: %lx, but for the current thread it is at %lx\n", - (ulong)prebuilt->trx, - (ulong)current_thd->transaction.all.innobase_tid); - - ut_sprintf_buf(err_buf, ((byte*)prebuilt) - 100, 200); - fprintf(stderr, -"InnoDB: Dump of 200 bytes around prebuilt: %.1000s\n", err_buf); - - ut_sprintf_buf(err_buf, +"InnoDB: %p, but for the current thread it is at %p\n", + prebuilt->trx, + current_thd->transaction.all.innobase_tid); + fputs("InnoDB: Dump of 200 bytes around prebuilt: ", stderr); + ut_print_buf(stderr, ((const byte*)prebuilt) - 100, 200); + fputs("\n" + "InnoDB: Dump of 200 bytes around transaction.all: ", + stderr); + ut_print_buf(stderr, ((byte*)(&(current_thd->transaction.all))) - 100, 200); - fprintf(stderr, -"InnoDB: Dump of 200 bytes around transaction.all: %.1000s\n", err_buf); - - ut_a(0); + putc('\n', stderr); + ut_error; } statistic_increment(ha_write_count, &LOCK_status); @@ -4225,15 +4197,18 @@ ha_innobase::update_table_comment( info on foreign keys */ const char* comment)/* in: table comment defined by user */ { - row_prebuilt_t* prebuilt = (row_prebuilt_t*)innobase_prebuilt; - uint length = strlen(comment); - char* str = my_malloc(length + 16500, MYF(0)); - char* pos; + uint length = strlen(comment); + char* str; + row_prebuilt_t* prebuilt = (row_prebuilt_t*)innobase_prebuilt; /* We do not know if MySQL can call this function before calling external_lock(). To be safe, update the thd of the current table handle. */ + if(length > 64000 - 3) { + return((char*)comment); /* string too long */ + } + update_thd(current_thd); prebuilt->trx->op_info = (char*)"returning table comment"; @@ -4242,36 +4217,45 @@ ha_innobase::update_table_comment( possible adaptive hash latch to avoid deadlocks of threads */ trx_search_latch_release_if_reserved(prebuilt->trx); - - if (!str) { - prebuilt->trx->op_info = (char*)""; + str = NULL; - return((char*)comment); - } + if (FILE* file = tmpfile()) { + long flen; - pos = str; - if (length) { - pos=strmov(str, comment); - *pos++=';'; - *pos++=' '; - } + /* output the data to a temporary file */ + fprintf(file, "InnoDB free: %lu kB", + (ulong) innobase_get_free_space()); + dict_print_info_on_foreign_keys(FALSE, file, prebuilt->table); + flen = ftell(file); + if(length + flen + 3 > 64000) { + flen = 64000 - 3 - length; + } - pos += my_sprintf(pos, - (pos,"InnoDB free: %lu kB", - (ulong) innobase_get_free_space())); + ut_ad(flen > 0); - /* We assume 16000 - length bytes of space to print info; the limit - 16000 bytes is arbitrary, and MySQL could handle at least 64000 - bytes */ - - if (length < 16000) { - dict_print_info_on_foreign_keys(FALSE, pos, 16000 - length, - prebuilt->table); + /* allocate buffer for the full string, and + read the contents of the temporary file */ + + str = my_malloc(length + flen + 3, MYF(0)); + + if (str) { + char* pos = str + length; + if(length) { + memcpy(str, comment, length); + *pos++ = ';'; + *pos++ = ' '; + } + rewind(file); + flen = fread(pos, 1, flen, file); + pos[flen] = 0; + } + + fclose(file); } prebuilt->trx->op_info = (char*)""; - return(str); + return(str ? str : (char*) comment); } /*********************************************************************** @@ -4285,7 +4269,7 @@ ha_innobase::get_foreign_key_create_info(void) MUST be freed with ::free_foreign_key_create_info */ { row_prebuilt_t* prebuilt = (row_prebuilt_t*)innobase_prebuilt; - char* str; + char* str = 0; ut_a(prebuilt != NULL); @@ -4295,20 +4279,45 @@ ha_innobase::get_foreign_key_create_info(void) update_thd(current_thd); - prebuilt->trx->op_info = (char*)"getting info on foreign keys"; + if (FILE* file = tmpfile()) { + long flen; - /* In case MySQL calls this in the middle of a SELECT query, release - possible adaptive hash latch to avoid deadlocks of threads */ + prebuilt->trx->op_info = (char*)"getting info on foreign keys"; - trx_search_latch_release_if_reserved(prebuilt->trx); - - str = (char*)ut_malloc(10000); + /* In case MySQL calls this in the middle of a SELECT query, + release possible adaptive hash latch to avoid + deadlocks of threads */ - str[0] = '\0'; - - dict_print_info_on_foreign_keys(TRUE, str, 9000, prebuilt->table); + trx_search_latch_release_if_reserved(prebuilt->trx); - prebuilt->trx->op_info = (char*)""; + /* output the data to a temporary file */ + dict_print_info_on_foreign_keys(TRUE, file, prebuilt->table); + prebuilt->trx->op_info = (char*)""; + + flen = ftell(file); + if(flen > 64000 - 1) { + flen = 64000 - 1; + } + + ut_ad(flen >= 0); + + /* allocate buffer for the string, and + read the contents of the temporary file */ + + str = my_malloc(flen + 1, MYF(0)); + + if (str) { + rewind(file); + flen = fread(str, 1, flen, file); + str[flen] = 0; + } + + fclose(file); + } else { + /* unable to create temporary file */ + str = my_malloc(1, MYF(0)); + str[0] = 0; + } return(str); } @@ -4344,7 +4353,7 @@ ha_innobase::free_foreign_key_create_info( char* str) /* in, own: create info string to free */ { if (str) { - ut_free(str); + my_free(str, MYF(0)); } } @@ -4615,39 +4624,56 @@ innodb_show_status( innobase_release_stat_resources(trx); - /* We let the InnoDB Monitor to output at most 60 kB of text, add - a safety margin of 100 kB for buffer overruns */ + /* We let the InnoDB Monitor to output at most 64000 bytes of text. */ + + long flen; + char* str; + + mutex_enter(&srv_monitor_file_mutex); + rewind(srv_monitor_file); + srv_printf_innodb_monitor(srv_monitor_file); + flen = ftell(srv_monitor_file); + if(flen > 64000 - 1) { + flen = 64000 - 1; + } + + ut_ad(flen > 0); + + /* allocate buffer for the string, and + read the contents of the temporary file */ + + str = my_malloc(flen + 1, MYF(0)); + + if (str) { + rewind(srv_monitor_file); + flen = fread(str, 1, flen, srv_monitor_file); + str[flen] = 0; + } + + mutex_exit(&srv_monitor_file_mutex); - buf = (char*)ut_malloc(160 * 1024); - - srv_sprintf_innodb_monitor(buf, 60 * 1024); - List field_list; - field_list.push_back(new Item_empty_string("Status", strlen(buf))); + field_list.push_back(new Item_empty_string("Status", flen)); if (send_fields(thd, field_list, 1)) { - ut_free(buf); + my_free(str, MYF(0)); - DBUG_RETURN(-1); + DBUG_RETURN(-1); } - packet->length(0); - - net_store_data(packet, buf); - - if (my_net_write(&thd->net, (char*)thd->packet.ptr(), - packet->length())) { - ut_free(buf); - - DBUG_RETURN(-1); - } + packet->length(0); + net_store_data(packet, str); + my_free(str, MYF(0)); - ut_free(buf); + if (my_net_write(&thd->net, (char*)thd->packet.ptr(), + packet->length())) { - send_eof(&thd->net); + DBUG_RETURN(-1); + } + send_eof(&thd->net); DBUG_RETURN(0); } From b5ffdec204f81156e50b9a0d3b07763eafd3ac7c Mon Sep 17 00:00:00 2001 From: "guilhem@mysql.com" <> Date: Wed, 7 Apr 2004 00:57:14 +0200 Subject: [PATCH 19/28] This is a fix for a bug in 3.23 -> 4.0 replication: Exec_master_log_pos is always too big by 6 bytes. So I add code to substract 6 bytes if the master is 3.23. This is not perfect (because it won't work if the slave I/O thread has not noticed yet that the master is 3.23), but as long as the slave I/O thread starts Exec_master_log_pos will be ok. It must be merged to 4.1 but not to 5.0 (or it can be, because of #if MYSQL_VERSION_ID), because 5.0 already works if the master is 3.23 (and in a more natural way: in 5.0 we store the end_log_pos in the binlog and relay log). I had to move functions from slave.h to slave.cc to satisfy gcc. --- sql/log_event.cc | 32 ++++++++++++++++++++++++++------ sql/slave.cc | 46 ++++++++++++++++++++++++++++++++++++++++++++++ sql/slave.h | 31 +++---------------------------- 3 files changed, 75 insertions(+), 34 deletions(-) diff --git a/sql/log_event.cc b/sql/log_event.cc index a484123b4c7..cd94ee2804d 100644 --- a/sql/log_event.cc +++ b/sql/log_event.cc @@ -1805,10 +1805,21 @@ int Query_log_event::exec_event(struct st_relay_log_info* rli) position to store is of the END of the current log event. */ #if MYSQL_VERSION_ID < 40100 - rli->future_master_log_pos= log_pos + get_event_len(); + /* + If the event was converted from a 3.23 format, get_event_len() has grown by + 6 bytes (at least for most events, except LOAD DATA INFILE which is already + a big problem for 3.23->4.0 replication); 6 bytes is the difference between + the header's size in 4.0 (LOG_EVENT_HEADER_LEN) and the header's size in + 3.23 (OLD_HEADER_LEN). Note that using mi->old_format will not help if the + I/O thread has not started yet. + */ + rli->future_master_log_pos= log_pos + get_event_len() - + (rli->mi->old_format ? (LOG_EVENT_HEADER_LEN - OLD_HEADER_LEN) : 0); #elif MYSQL_VERSION_ID < 50000 - rli->future_group_master_log_pos= log_pos + get_event_len(); + rli->future_group_master_log_pos= log_pos + get_event_len() - + (rli->mi->old_format ? (LOG_EVENT_HEADER_LEN - OLD_HEADER_LEN) : 0); #else + /* In 5.0 we store the end_log_pos in the relay log so no problem */ rli->future_group_master_log_pos= log_pos; #endif clear_all_errors(thd, rli); @@ -1960,9 +1971,11 @@ int Load_log_event::exec_event(NET* net, struct st_relay_log_info* rli, if (!use_rli_only_for_errors) { #if MYSQL_VERSION_ID < 40100 - rli->future_master_log_pos= log_pos + get_event_len(); + rli->future_master_log_pos= log_pos + get_event_len() - + (rli->mi->old_format ? (LOG_EVENT_HEADER_LEN - OLD_HEADER_LEN) : 0); #elif MYSQL_VERSION_ID < 50000 - rli->future_group_master_log_pos= log_pos + get_event_len(); + rli->future_group_master_log_pos= log_pos + get_event_len() - + (rli->mi->old_format ? (LOG_EVENT_HEADER_LEN - OLD_HEADER_LEN) : 0); #else rli->future_group_master_log_pos= log_pos; #endif @@ -2133,6 +2146,11 @@ Fatal error running LOAD DATA INFILE on table '%s'. Default database: '%s'", int Start_log_event::exec_event(struct st_relay_log_info* rli) { + /* + If the I/O thread has not started, mi->old_format is BINLOG_FORMAT_CURRENT + (that's what the MASTER_INFO constructor does), so the test below is not + perfect at all. + */ switch (rli->mi->old_format) { case BINLOG_FORMAT_CURRENT : /* @@ -2427,9 +2445,11 @@ int Execute_load_log_event::exec_event(struct st_relay_log_info* rli) */ #if MYSQL_VERSION_ID < 40100 - rli->future_master_log_pos= log_pos + get_event_len(); + rli->future_master_log_pos= log_pos + get_event_len() - + (rli->mi->old_format ? (LOG_EVENT_HEADER_LEN - OLD_HEADER_LEN) : 0); #elif MYSQL_VERSION_ID < 50000 - rli->future_group_master_log_pos= log_pos + get_event_len(); + rli->future_group_master_log_pos= log_pos + get_event_len() - + (rli->mi->old_format ? (LOG_EVENT_HEADER_LEN - OLD_HEADER_LEN) : 0); #else rli->future_group_master_log_pos= log_pos; #endif diff --git a/sql/slave.cc b/sql/slave.cc index d6dda473be0..9e82a521cb3 100644 --- a/sql/slave.cc +++ b/sql/slave.cc @@ -329,6 +329,52 @@ void init_slave_skip_errors(const char* arg) } } +void st_relay_log_info::inc_pending(ulonglong val) +{ + pending += val; +} + +/* TODO: this probably needs to be fixed */ +void st_relay_log_info::inc_pos(ulonglong val, ulonglong log_pos, bool skip_lock) +{ + if (!skip_lock) + pthread_mutex_lock(&data_lock); + relay_log_pos += val+pending; + pending = 0; + if (log_pos) +#if MYSQL_VERSION_ID < 50000 + /* + If the event was converted from a 3.23 format, get_event_len() has + grown by 6 bytes (at least for most events, except LOAD DATA INFILE + which is already a big problem for 3.23->4.0 replication); 6 bytes is + the difference between the header's size in 4.0 (LOG_EVENT_HEADER_LEN) + and the header's size in 3.23 (OLD_HEADER_LEN). Note that using + mi->old_format will not help if the I/O thread has not started yet. + Yes this is a hack but it's just to make 3.23->4.x replication work; + 3.23->5.0 replication is working much better. + + The line "mi->old_format ? : " below should NOT BE MERGED to 5.0 which + already works. But it SHOULD be merged to 4.1. + */ + master_log_pos= log_pos + val - + (mi->old_format ? (LOG_EVENT_HEADER_LEN - OLD_HEADER_LEN) : 0); +#endif + pthread_cond_broadcast(&data_cond); + if (!skip_lock) + pthread_mutex_unlock(&data_lock); +} + +/* + thread safe read of position - not needed if we are in the slave thread, + but required otherwise as var is a longlong +*/ +void st_relay_log_info::read_pos(ulonglong& var) +{ + pthread_mutex_lock(&data_lock); + var = relay_log_pos; + pthread_mutex_unlock(&data_lock); +} + void st_relay_log_info::close_temporary_tables() { TABLE *table,*next; diff --git a/sql/slave.h b/sql/slave.h index 4a6389e9f87..979c63af201 100644 --- a/sql/slave.h +++ b/sql/slave.h @@ -210,34 +210,9 @@ typedef struct st_relay_log_info st_relay_log_info(); ~st_relay_log_info(); - inline void inc_pending(ulonglong val) - { - pending += val; - } - /* TODO: this probably needs to be fixed */ - inline void inc_pos(ulonglong val, ulonglong log_pos, bool skip_lock=0) - { - if (!skip_lock) - pthread_mutex_lock(&data_lock); - relay_log_pos += val+pending; - pending = 0; - if (log_pos) - master_log_pos = log_pos+ val; - pthread_cond_broadcast(&data_cond); - if (!skip_lock) - pthread_mutex_unlock(&data_lock); - } - /* - thread safe read of position - not needed if we are in the slave thread, - but required otherwise as var is a longlong - */ - inline void read_pos(ulonglong& var) - { - pthread_mutex_lock(&data_lock); - var = relay_log_pos; - pthread_mutex_unlock(&data_lock); - } - + void inc_pending(ulonglong val); + void inc_pos(ulonglong val, ulonglong log_pos, bool skip_lock=0); + void read_pos(ulonglong& var); int wait_for_pos(THD* thd, String* log_name, longlong log_pos, longlong timeout); void close_temporary_tables(); From 44a6fcba2f357b3f74bde8673046b310ecfd6645 Mon Sep 17 00:00:00 2001 From: "guilhem@mysql.com" <> Date: Wed, 7 Apr 2004 01:14:11 +0200 Subject: [PATCH 20/28] Fix for BUG#3401 "Rare replication bug which leads to "Binlog has bad magic number" from slave": Backport of a part of this changeset of 4.1: ChangeSet@1.1753.1.1, 2004-04-05 13:56:05+03:00, monty@mysql.com which fixes the bug. --- sql/slave.cc | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/sql/slave.cc b/sql/slave.cc index 9e82a521cb3..1ef572e3a0a 100644 --- a/sql/slave.cc +++ b/sql/slave.cc @@ -1609,7 +1609,18 @@ int init_master_info(MASTER_INFO* mi, const char* master_info_fname, DBUG_ENTER("init_master_info"); if (mi->inited) + { + /* + We have to reset read position of relay-log-bin as we may have + already been reading from 'hotlog' when the slave was stopped + last time. If this case pos_in_file would be set and we would + get a crash when trying to read the signature for the binary + relay log. + */ + my_b_seek(mi->rli.cur_log, (my_off_t) 0); DBUG_RETURN(0); + } + mi->mysql=0; mi->file_id=1; mi->ignore_stop_event=0; From 253bf9861b06da3ea132aadfd5e1a60e7d9c3c2f Mon Sep 17 00:00:00 2001 From: "marko@hundin.mysql.fi" <> Date: Wed, 7 Apr 2004 14:19:26 +0300 Subject: [PATCH 21/28] InnoDB: Remove debug functions unless #ifdef UNIV_DEBUG --- innobase/btr/btr0btr.c | 2 ++ innobase/buf/buf0buf.c | 14 +++++++++++++- innobase/buf/buf0flu.c | 10 ++++++++++ innobase/buf/buf0lru.c | 4 ++++ innobase/buf/buf0rea.c | 10 ++++++++++ innobase/data/data0type.c | 2 ++ innobase/dict/dict0dict.c | 2 ++ innobase/fsp/fsp0fsp.c | 6 +++++- innobase/fut/fut0lst.c | 2 ++ innobase/ibuf/ibuf0ibuf.c | 8 ++++++-- innobase/include/btr0btr.h | 2 ++ innobase/include/buf0buf.h | 10 +++++++--- innobase/include/buf0buf.ic | 4 ---- innobase/include/buf0flu.h | 2 ++ innobase/include/buf0lru.h | 2 ++ innobase/include/data0type.h | 2 ++ innobase/include/dict0dict.h | 16 +++++++++------- innobase/include/fsp0fsp.h | 2 ++ innobase/include/fut0lst.h | 3 ++- innobase/include/lock0lock.h | 6 ++++++ innobase/include/mem0dbg.h | 4 ++++ innobase/include/mem0dbg.ic | 3 ++- innobase/include/mem0pool.h | 3 ++- innobase/include/mtr0mtr.h | 2 ++ innobase/include/pars0opt.h | 2 ++ innobase/include/sync0rw.h | 2 ++ innobase/include/sync0sync.h | 2 ++ innobase/include/trx0sys.h | 2 ++ innobase/lock/lock0lock.c | 16 ++++++++++++++-- innobase/mem/mem0dbg.c | 2 ++ innobase/mem/mem0pool.c | 2 ++ innobase/mtr/mtr0mtr.c | 2 ++ innobase/pars/pars0opt.c | 2 ++ innobase/srv/srv0start.c | 2 ++ innobase/sync/sync0rw.c | 2 ++ innobase/sync/sync0sync.c | 9 +++++++-- innobase/trx/trx0roll.c | 2 ++ innobase/trx/trx0sys.c | 2 ++ 38 files changed, 145 insertions(+), 25 deletions(-) diff --git a/innobase/btr/btr0btr.c b/innobase/btr/btr0btr.c index 2e9de9b39bf..70bcd1eea1f 100644 --- a/innobase/btr/btr0btr.c +++ b/innobase/btr/btr0btr.c @@ -2162,6 +2162,7 @@ btr_discard_page( ut_ad(btr_check_node_ptr(tree, merge_page, mtr)); } +#ifdef UNIV_DEBUG /***************************************************************** Prints size info of a B-tree. */ @@ -2282,6 +2283,7 @@ btr_print_tree( btr_validate_tree(tree); } +#endif /* UNIV_DEBUG */ /**************************************************************** Checks that the node pointer to a page is appropriate. */ diff --git a/innobase/buf/buf0buf.c b/innobase/buf/buf0buf.c index b744430a76e..a7bf9cf1d2f 100644 --- a/innobase/buf/buf0buf.c +++ b/innobase/buf/buf0buf.c @@ -201,12 +201,14 @@ the read requests for the whole area. */ buf_pool_t* buf_pool = NULL; /* The buffer buf_pool of the database */ -ulint buf_dbg_counter = 0; /* This is used to insert validation +#ifdef UNIV_DEBUG +static ulint buf_dbg_counter = 0; /* This is used to insert validation operations in excution in the debug version */ ibool buf_debug_prints = FALSE; /* If this is set TRUE, the program prints info whenever read-ahead or flush occurs */ +#endif /* UNIV_DEBUG */ /************************************************************************ Calculates a page checksum which is stored to the page when it is written @@ -1455,10 +1457,12 @@ buf_page_create( /* If we get here, the page was not in buf_pool: init it there */ +#ifdef UNIV_DEBUG if (buf_debug_prints) { fprintf(stderr, "Creating space %lu page %lu to buffer\n", space, offset); } +#endif /* UNIV_DEBUG */ block = free_block; @@ -1609,9 +1613,11 @@ buf_page_io_complete( rw_lock_x_unlock_gen(&(block->lock), BUF_IO_READ); rw_lock_x_unlock_gen(&(block->read_lock), BUF_IO_READ); +#ifdef UNIV_DEBUG if (buf_debug_prints) { fputs("Has read ", stderr); } +#endif /* UNIV_DEBUG */ } else { ut_ad(io_type == BUF_IO_WRITE); @@ -1624,17 +1630,21 @@ buf_page_io_complete( buf_pool->n_pages_written++; +#ifdef UNIV_DEBUG if (buf_debug_prints) { fputs("Has written ", stderr); } +#endif /* UNIV_DEBUG */ } mutex_exit(&(buf_pool->mutex)); +#ifdef UNIV_DEBUG if (buf_debug_prints) { fprintf(stderr, "page space %lu page no %lu\n", block->space, block->offset); } +#endif /* UNIV_DEBUG */ } /************************************************************************* @@ -1663,6 +1673,7 @@ buf_pool_invalidate(void) mutex_exit(&(buf_pool->mutex)); } +#ifdef UNIV_DEBUG /************************************************************************* Validates the buffer buf_pool data structure. */ @@ -1861,6 +1872,7 @@ buf_print(void) ut_a(buf_validate()); } +#endif /* UNIV_DEBUG */ /************************************************************************* Returns the number of pending buf pool ios. */ diff --git a/innobase/buf/buf0flu.c b/innobase/buf/buf0flu.c index 7456e5d6f61..8a4ae2ff369 100644 --- a/innobase/buf/buf0flu.c +++ b/innobase/buf/buf0flu.c @@ -31,6 +31,7 @@ flushed along with the original page. */ #define BUF_FLUSH_AREA ut_min(BUF_READ_AHEAD_AREA,\ buf_pool->curr_size / 16) +#ifdef UNIV_DEBUG /********************************************************************** Validates the flush list. */ static @@ -38,6 +39,7 @@ ibool buf_flush_validate_low(void); /*========================*/ /* out: TRUE if ok */ +#endif /* UNIV_DEBUG */ /************************************************************************ Inserts a modified block into the flush list. */ @@ -488,11 +490,13 @@ buf_flush_try_page( rw_lock_s_lock_gen(&(block->lock), BUF_IO_WRITE); } +#ifdef UNIV_DEBUG if (buf_debug_prints) { fprintf(stderr, "Flushing page space %lu, page no %lu \n", block->space, block->offset); } +#endif /* UNIV_DEBUG */ buf_flush_write_block_low(block); @@ -548,11 +552,13 @@ buf_flush_try_page( rw_lock_s_lock_gen(&(block->lock), BUF_IO_WRITE); +#ifdef UNIV_DEBUG if (buf_debug_prints) { fprintf(stderr, "Flushing single page space %lu, page no %lu \n", block->space, block->offset); } +#endif /* UNIV_DEBUG */ buf_flush_write_block_low(block); @@ -779,6 +785,7 @@ buf_flush_batch( buf_flush_buffered_writes(); +#ifdef UNIV_DEBUG if (buf_debug_prints && page_count > 0) { ut_a(flush_type == BUF_FLUSH_LRU || flush_type == BUF_FLUSH_LIST); @@ -787,6 +794,7 @@ buf_flush_batch( : "Flushed %lu pages in flush list flush\n", page_count); } +#endif /* UNIV_DEBUG */ return(page_count); } @@ -878,6 +886,7 @@ buf_flush_free_margin(void) } } +#ifdef UNIV_DEBUG /********************************************************************** Validates the flush list. */ static @@ -927,3 +936,4 @@ buf_flush_validate(void) return(ret); } +#endif /* UNIV_DEBUG */ diff --git a/innobase/buf/buf0lru.c b/innobase/buf/buf0lru.c index 0ced7e23abe..8ad47487607 100644 --- a/innobase/buf/buf0lru.c +++ b/innobase/buf/buf0lru.c @@ -125,11 +125,13 @@ buf_LRU_search_and_free_block( if (buf_flush_ready_for_replace(block)) { +#ifdef UNIV_DEBUG if (buf_debug_prints) { fprintf(stderr, "Putting space %lu page %lu to free list\n", block->space, block->offset); } +#endif /* UNIV_DEBUG */ buf_LRU_block_remove_hashed_page(block); @@ -705,6 +707,7 @@ buf_LRU_block_free_hashed_page( buf_LRU_block_free_non_file_page(block); } +#ifdef UNIV_DEBUG /************************************************************************** Validates the LRU list. */ @@ -835,3 +838,4 @@ buf_LRU_print(void) mutex_exit(&(buf_pool->mutex)); } +#endif /* UNIV_DEBUG */ diff --git a/innobase/buf/buf0rea.c b/innobase/buf/buf0rea.c index 83397c9c7fa..7de778a5956 100644 --- a/innobase/buf/buf0rea.c +++ b/innobase/buf/buf0rea.c @@ -101,11 +101,13 @@ buf_read_page_low( block = buf_page_init_for_read(mode, space, offset); if (block != NULL) { +#ifdef UNIV_DEBUG if (buf_debug_prints) { fprintf(stderr, "Posting read request for page %lu, sync %lu\n", offset, sync); } +#endif /* UNIV_DEBUG */ fil_io(OS_FILE_READ | wake_later, sync, space, offset, 0, UNIV_PAGE_SIZE, @@ -242,11 +244,13 @@ buf_read_ahead_random( os_aio_simulated_wake_handler_threads(); +#ifdef UNIV_DEBUG if (buf_debug_prints && (count > 0)) { fprintf(stderr, "Random read-ahead space %lu offset %lu pages %lu\n", space, offset, count); } +#endif /* UNIV_DEBUG */ return(count); } @@ -500,11 +504,13 @@ buf_read_ahead_linear( /* Flush pages from the end of the LRU list if necessary */ buf_flush_free_margin(); +#ifdef UNIV_DEBUG if (buf_debug_prints && (count > 0)) { fprintf(stderr, "LINEAR read-ahead space %lu offset %lu pages %lu\n", space, offset, count); } +#endif /* UNIV_DEBUG */ return(count); } @@ -549,11 +555,13 @@ buf_read_ibuf_merge_pages( /* Flush pages from the end of the LRU list if necessary */ buf_flush_free_margin(); +#ifdef UNIV_DEBUG if (buf_debug_prints) { fprintf(stderr, "Ibuf merge read-ahead space %lu pages %lu\n", space, n_stored); } +#endif /* UNIV_DEBUG */ } /************************************************************************ @@ -613,8 +621,10 @@ buf_read_recv_pages( /* Flush pages from the end of the LRU list if necessary */ buf_flush_free_margin(); +#ifdef UNIV_DEBUG if (buf_debug_prints) { fprintf(stderr, "Recovery applies read-ahead pages %lu\n", n_stored); } +#endif /* UNIV_DEBUG */ } diff --git a/innobase/data/data0type.c b/innobase/data/data0type.c index 077012553ba..0243ee64536 100644 --- a/innobase/data/data0type.c +++ b/innobase/data/data0type.c @@ -15,6 +15,7 @@ Created 1/16/1996 Heikki Tuuri dtype_t dtype_binary_val = {DATA_BINARY, 0, 0, 0}; dtype_t* dtype_binary = &dtype_binary_val; +#ifdef UNIV_DEBUG /************************************************************************* Validates a data type structure. */ @@ -33,6 +34,7 @@ dtype_validate( return(TRUE); } +#endif /* UNIV_DEBUG */ /************************************************************************* Prints a data type structure. */ diff --git a/innobase/dict/dict0dict.c b/innobase/dict/dict0dict.c index d895f00b249..fa80532a32d 100644 --- a/innobase/dict/dict0dict.c +++ b/innobase/dict/dict0dict.c @@ -3819,6 +3819,7 @@ dict_foreign_print_low( fputs(" )\n", stderr); } +#ifdef UNIV_DEBUG /************************************************************************** Prints a table data. */ @@ -3851,6 +3852,7 @@ dict_table_print_by_name( dict_table_print_low(table); mutex_exit(&(dict_sys->mutex)); } +#endif /* UNIV_DEBUG */ /************************************************************************** Prints a table data. */ diff --git a/innobase/fsp/fsp0fsp.c b/innobase/fsp/fsp0fsp.c index 53f5e885df8..7c9c072fadd 100644 --- a/innobase/fsp/fsp0fsp.c +++ b/innobase/fsp/fsp0fsp.c @@ -3236,7 +3236,8 @@ fseg_validate_low( return(TRUE); } - + +#ifdef UNIV_DEBUG /*********************************************************************** Validates a segment. */ @@ -3261,6 +3262,7 @@ fseg_validate( return(ret); } +#endif /* UNIV_DEBUG */ /*********************************************************************** Writes info of a segment. */ @@ -3311,6 +3313,7 @@ fseg_print_low( n_frag, n_free, n_not_full, n_used); } +#ifdef UNIV_DEBUG /*********************************************************************** Writes info of a segment. */ @@ -3331,6 +3334,7 @@ fseg_print( fseg_print_low(inode, mtr); } +#endif /* UNIV_DEBUG */ /*********************************************************************** Validates the file space system and its segments. */ diff --git a/innobase/fut/fut0lst.c b/innobase/fut/fut0lst.c index ff112b586c4..228670f6145 100644 --- a/innobase/fut/fut0lst.c +++ b/innobase/fut/fut0lst.c @@ -490,6 +490,7 @@ flst_validate( return(TRUE); } +#ifdef UNIV_DEBUG /************************************************************************ Prints info of a file-based list. */ @@ -515,3 +516,4 @@ flst_print( buf_frame_get_space_id(frame), buf_frame_get_page_no(frame), (ulint) (base - frame), len); } +#endif /* UNIV_DEBUG */ diff --git a/innobase/ibuf/ibuf0ibuf.c b/innobase/ibuf/ibuf0ibuf.c index 2745af42ff7..83bb23b036f 100644 --- a/innobase/ibuf/ibuf0ibuf.c +++ b/innobase/ibuf/ibuf0ibuf.c @@ -172,13 +172,15 @@ because ibuf merge is done to a page when it is read in, and it is still physically like the index page even if the index would have been dropped! So, there seems to be no problem. */ +#ifdef UNIV_DEBUG /********************************************************************** Validates the ibuf data structures when the caller owns ibuf_mutex. */ - +static ibool ibuf_validate_low(void); /*===================*/ /* out: TRUE if ok */ +#endif /* UNIV_DEBUG */ /********************************************************************** Sets the flag in the current OS thread local storage denoting that it is @@ -2753,9 +2755,10 @@ reset_bit: #endif } +#ifdef UNIV_DEBUG /********************************************************************** Validates the ibuf data structures when the caller owns ibuf_mutex. */ - +static ibool ibuf_validate_low(void) /*===================*/ @@ -2782,6 +2785,7 @@ ibuf_validate_low(void) return(TRUE); } +#endif /* UNIV_DEBUG */ /********************************************************************** Prints info of ibuf. */ diff --git a/innobase/include/btr0btr.h b/innobase/include/btr0btr.h index 8606fcd2a5c..e904db3272f 100644 --- a/innobase/include/btr0btr.h +++ b/innobase/include/btr0btr.h @@ -392,6 +392,7 @@ btr_page_free_low( page_t* page, /* in: page to be freed, x-latched */ ulint level, /* in: page level */ mtr_t* mtr); /* in: mtr */ +#ifdef UNIV_DEBUG /***************************************************************** Prints size info of a B-tree. */ @@ -408,6 +409,7 @@ btr_print_tree( dict_tree_t* tree, /* in: tree */ ulint width); /* in: print this many entries from start and end */ +#endif /* UNIV_DEBUG */ /**************************************************************** Checks the size and number of fields in a record based on the definition of the index. */ diff --git a/innobase/include/buf0buf.h b/innobase/include/buf0buf.h index 5ac9c83a5f9..11c9047a8fc 100644 --- a/innobase/include/buf0buf.h +++ b/innobase/include/buf0buf.h @@ -53,9 +53,11 @@ Created 11/5/1995 Heikki Tuuri #define BUF_KEEP_OLD 52 extern buf_pool_t* buf_pool; /* The buffer pool of the database */ +#ifdef UNIV_DEBUG extern ibool buf_debug_prints;/* If this is set TRUE, the program prints info whenever read or flush occurs */ +#endif /* UNIV_DEBUG */ /************************************************************************ Initializes the buffer pool of the database. */ @@ -452,12 +454,14 @@ buf_pool_is_block( /*==============*/ /* out: TRUE if pointer to block */ void* ptr); /* in: pointer to memory */ +#ifdef UNIV_DEBUG /************************************************************************* Validates the buffer pool data structure. */ ibool buf_validate(void); /*==============*/ +#endif /* UNIV_DEBUG */ /************************************************************************ Prints a page to stderr. */ @@ -816,7 +820,7 @@ struct buf_pool_struct{ ulint n_pend_reads; /* number of pending read operations */ - time_t last_printout_time; /* when buf_print was last time + time_t last_printout_time; /* when buf_print_io was last time called */ ulint n_pages_read; /* number read operations */ ulint n_pages_written;/* number write operations */ @@ -828,10 +832,10 @@ struct buf_pool_struct{ counted as page gets; this field is NOT protected by the buffer pool mutex */ - ulint n_page_gets_old;/* n_page_gets when buf_print was + ulint n_page_gets_old;/* n_page_gets when buf_print_io was last time called: used to calculate hit rate */ - ulint n_pages_read_old;/* n_pages_read when buf_print was + ulint n_pages_read_old;/* n_pages_read when buf_print_io was last time called */ ulint n_pages_written_old;/* number write operations */ ulint n_pages_created_old;/* number of pages created in diff --git a/innobase/include/buf0buf.ic b/innobase/include/buf0buf.ic index 16deade0901..7e2a9b59378 100644 --- a/innobase/include/buf0buf.ic +++ b/innobase/include/buf0buf.ic @@ -11,10 +11,6 @@ Created 11/5/1995 Heikki Tuuri #include "buf0rea.h" #include "mtr0mtr.h" -extern ulint buf_dbg_counter; /* This is used to insert validation - operations in execution in the - debug version */ - /************************************************************************ Recommends a move of a block to the start of the LRU list if there is danger of dropping from the buffer pool. NOTE: does not reserve the buffer pool diff --git a/innobase/include/buf0flu.h b/innobase/include/buf0flu.h index 1b40acaa269..6f39eef7210 100644 --- a/innobase/include/buf0flu.h +++ b/innobase/include/buf0flu.h @@ -97,6 +97,7 @@ buf_flush_ready_for_replace( /* out: TRUE if can replace immediately */ buf_block_t* block); /* in: buffer control block, must be in state BUF_BLOCK_FILE_PAGE and in the LRU list */ +#ifdef UNIV_DEBUG /********************************************************************** Validates the flush list. */ @@ -104,6 +105,7 @@ ibool buf_flush_validate(void); /*====================*/ /* out: TRUE if ok */ +#endif /* UNIV_DEBUG */ /* When buf_flush_free_margin is called, it tries to make this many blocks available to replacement in the free list and at the end of the LRU list (to diff --git a/innobase/include/buf0lru.h b/innobase/include/buf0lru.h index eb9d43d3b93..a9d57ecb36e 100644 --- a/innobase/include/buf0lru.h +++ b/innobase/include/buf0lru.h @@ -100,6 +100,7 @@ void buf_LRU_make_block_old( /*===================*/ buf_block_t* block); /* in: control block */ +#ifdef UNIV_DEBUG /************************************************************************** Validates the LRU list. */ @@ -112,6 +113,7 @@ Prints the LRU list. */ void buf_LRU_print(void); /*===============*/ +#endif /* UNIV_DEBUG */ #ifndef UNIV_NONINL #include "buf0lru.ic" diff --git a/innobase/include/data0type.h b/innobase/include/data0type.h index 4da686bf2e1..d10d20cf69e 100644 --- a/innobase/include/data0type.h +++ b/innobase/include/data0type.h @@ -190,6 +190,7 @@ dtype_read_for_order_and_null_size( /*===============================*/ dtype_t* type, /* in: type struct */ byte* buf); /* in: buffer for the stored order info */ +#ifdef UNIV_DEBUG /************************************************************************* Validates a data type structure. */ @@ -198,6 +199,7 @@ dtype_validate( /*===========*/ /* out: TRUE if ok */ dtype_t* type); /* in: type struct to validate */ +#endif /* UNIV_DEBUG */ /************************************************************************* Prints a data type structure. */ diff --git a/innobase/include/dict0dict.h b/innobase/include/dict0dict.h index 835c2c2b2e6..fadbcf37a43 100644 --- a/innobase/include/dict0dict.h +++ b/innobase/include/dict0dict.h @@ -301,19 +301,20 @@ dict_table_get_index_noninline( dict_table_t* table, /* in: table */ char* name); /* in: index name */ /************************************************************************** -Prints a table definition. */ - -void -dict_table_print( -/*=============*/ - dict_table_t* table); /* in: table */ -/************************************************************************** Prints a table data. */ void dict_table_print_low( /*=================*/ dict_table_t* table); /* in: table */ +#ifdef UNIV_DEBUG +/************************************************************************** +Prints a table definition. */ + +void +dict_table_print( +/*=============*/ + dict_table_t* table); /* in: table */ /************************************************************************** Prints a table data when we know the table name. */ @@ -321,6 +322,7 @@ void dict_table_print_by_name( /*=====================*/ char* name); +#endif /* UNIV_DEBUG */ /************************************************************************** Outputs info on foreign keys of a table. */ diff --git a/innobase/include/fsp0fsp.h b/innobase/include/fsp0fsp.h index 3494f336b1e..82c144bc766 100644 --- a/innobase/include/fsp0fsp.h +++ b/innobase/include/fsp0fsp.h @@ -297,6 +297,7 @@ void fsp_print( /*======*/ ulint space); /* in: space id */ +#ifdef UNIV_DEBUG /*********************************************************************** Validates a segment. */ @@ -314,6 +315,7 @@ fseg_print( /*=======*/ fseg_header_t* header, /* in: segment header */ mtr_t* mtr); /* in: mtr */ +#endif /* UNIV_DEBUG */ /* Flags for fsp_reserve_free_extents */ #define FSP_NORMAL 1000000 diff --git a/innobase/include/fut0lst.h b/innobase/include/fut0lst.h index 5427e2248da..3f679d61ab5 100644 --- a/innobase/include/fut0lst.h +++ b/innobase/include/fut0lst.h @@ -181,6 +181,7 @@ flst_validate( /* out: TRUE if ok */ flst_base_node_t* base, /* in: pointer to base node of list */ mtr_t* mtr1); /* in: mtr */ +#ifdef UNIV_DEBUG /************************************************************************ Prints info of a file-based list. */ @@ -189,7 +190,7 @@ flst_print( /*=======*/ flst_base_node_t* base, /* in: pointer to base node of list */ mtr_t* mtr); /* in: mtr */ - +#endif /* UNIV_DEBUG */ #ifndef UNIV_NONINL #include "fut0lst.ic" diff --git a/innobase/include/lock0lock.h b/innobase/include/lock0lock.h index 94ef3b33ebc..9ccea5ad7a4 100644 --- a/innobase/include/lock0lock.h +++ b/innobase/include/lock0lock.h @@ -19,7 +19,9 @@ Created 5/7/1996 Heikki Tuuri #include "read0types.h" #include "hash0hash.h" +#ifdef UNIV_DEBUG extern ibool lock_print_waits; +#endif /* UNIV_DEBUG */ /* Buffer for storing information about the most recent deadlock error */ extern FILE* lock_latest_err_file; @@ -455,6 +457,7 @@ lock_check_trx_id_sanity( dict_index_t* index, /* in: clustered index */ ibool has_kernel_mutex);/* in: TRUE if the caller owns the kernel mutex */ +#ifdef UNIV_DEBUG /************************************************************************* Validates the lock queue on a single record. */ @@ -464,6 +467,7 @@ lock_rec_queue_validate( /* out: TRUE if ok */ rec_t* rec, /* in: record to look at */ dict_index_t* index); /* in: index, or NULL if not known */ +#endif /* UNIV_DEBUG */ /************************************************************************* Prints info of a table lock. */ @@ -487,6 +491,7 @@ void lock_print_info( /*============*/ FILE* file); /* in: file where to print */ +#ifdef UNIV_DEBUG /************************************************************************* Validates the lock queue on a table. */ @@ -511,6 +516,7 @@ ibool lock_validate(void); /*===============*/ /* out: TRUE if ok */ +#endif /* UNIV_DEBUG */ /* The lock system */ extern lock_sys_t* lock_sys; diff --git a/innobase/include/mem0dbg.h b/innobase/include/mem0dbg.h index 6c92d669be3..61c66cc218c 100644 --- a/innobase/include/mem0dbg.h +++ b/innobase/include/mem0dbg.h @@ -31,6 +31,7 @@ check fields at the both ends of the field. */ #define MEM_SPACE_NEEDED(N) ut_calc_align((N), UNIV_MEM_ALIGNMENT) #endif +#ifdef UNIV_DEBUG /******************************************************************* Checks a memory heap for consistency and prints the contents if requested. Outputs the sum of sizes of buffers given to the user (only in @@ -60,6 +61,7 @@ mem_heap_validate_or_print( ulint* n_blocks); /* out: number of blocks in the heap, if a NULL pointer is passed as this argument, it is ignored */ +#endif /* UNIV_DEBUG */ #ifdef UNIV_MEM_DEBUG /****************************************************************** Prints the contents of a memory heap. */ @@ -69,6 +71,7 @@ mem_heap_print( /*===========*/ mem_heap_t* heap); /* in: memory heap */ #endif /* UNIV_MEM_DEBUG */ +#ifdef UNIV_DEBUG /****************************************************************** Checks that an object is a memory heap (or a block of it) */ @@ -85,6 +88,7 @@ mem_heap_validate( /*==============*/ /* out: TRUE if ok */ mem_heap_t* heap); /* in: memory heap */ +#endif /* UNIV_DEBUG */ #ifdef UNIV_MEM_DEBUG /********************************************************************* TRUE if no memory is currently allocated. */ diff --git a/innobase/include/mem0dbg.ic b/innobase/include/mem0dbg.ic index 6efac719760..2e79c814529 100644 --- a/innobase/include/mem0dbg.ic +++ b/innobase/include/mem0dbg.ic @@ -56,6 +56,7 @@ mem_hash_insert( mem_heap_t* heap, /* in: the created heap */ char* file_name, /* in: file name of creation */ ulint line); /* in: line where created */ +#ifdef UNIV_MEM_DEBUG /******************************************************************* Removes a memory heap (which is going to be freed by the caller) from the list of live memory heaps. Returns the size of the heap @@ -71,7 +72,7 @@ mem_hash_remove( mem_heap_t* heap, /* in: the heap to be freed */ char* file_name, /* in: file name of freeing */ ulint line); /* in: line where freed */ - +#endif /* UNIV_MEM_DEBUG */ void mem_field_header_set_len(byte* field, ulint len); diff --git a/innobase/include/mem0pool.h b/innobase/include/mem0pool.h index 43707bd5f61..95cf19676fb 100644 --- a/innobase/include/mem0pool.h +++ b/innobase/include/mem0pool.h @@ -83,6 +83,7 @@ Releases the mem pool mutex. */ void mem_pool_mutex_exit(void); /*=====================*/ +#ifdef UNIV_DEBUG /************************************************************************ Validates a memory pool. */ @@ -99,7 +100,7 @@ mem_pool_print_info( /*================*/ FILE* outfile,/* in: output file to write to */ mem_pool_t* pool); /* in: memory pool */ - +#endif /* UNIV_DEBUG */ #ifndef UNIV_NONINL #include "mem0pool.ic" diff --git a/innobase/include/mtr0mtr.h b/innobase/include/mtr0mtr.h index d999b7cc5b7..6117927504f 100644 --- a/innobase/include/mtr0mtr.h +++ b/innobase/include/mtr0mtr.h @@ -250,6 +250,7 @@ mtr_memo_contains( mtr_t* mtr, /* in: mtr */ void* object, /* in: object to search */ ulint type); /* in: type of object */ +#ifdef UNIV_DEBUG /************************************************************* Prints info of an mtr handle. */ @@ -257,6 +258,7 @@ void mtr_print( /*======*/ mtr_t* mtr); /* in: mtr */ +#endif /* UNIV_DEBUG */ /*######################################################################*/ #define MTR_BUF_MEMO_SIZE 200 /* number of slots in memo */ diff --git a/innobase/include/pars0opt.h b/innobase/include/pars0opt.h index d091c3ee2d0..ac0e885d05a 100644 --- a/innobase/include/pars0opt.h +++ b/innobase/include/pars0opt.h @@ -43,6 +43,7 @@ opt_find_all_cols( to add new found columns */ plan_t* plan, /* in: plan or NULL */ que_node_t* exp); /* in: expression or condition */ +#ifdef UNIV_SQL_DEBUG /************************************************************************ Prints info of a query plan. */ @@ -50,6 +51,7 @@ void opt_print_query_plan( /*=================*/ sel_node_t* sel_node); /* in: select node */ +#endif /* UNIV_SQL_DEBUG */ #ifndef UNIV_NONINL #include "pars0opt.ic" diff --git a/innobase/include/sync0rw.h b/innobase/include/sync0rw.h index d71691b4353..82123a529a3 100644 --- a/innobase/include/sync0rw.h +++ b/innobase/include/sync0rw.h @@ -85,6 +85,7 @@ void rw_lock_free( /*=========*/ rw_lock_t* lock); /* in: rw-lock */ +#ifdef UNIV_DEBUG /********************************************************************** Checks that the rw-lock has been initialized and that there are no simultaneous shared and exclusive locks. */ @@ -93,6 +94,7 @@ ibool rw_lock_validate( /*=============*/ rw_lock_t* lock); +#endif /* UNIV_DEBUG */ /****************************************************************** NOTE! The following macros should be used in rw s-locking, not the corresponding function. */ diff --git a/innobase/include/sync0sync.h b/innobase/include/sync0sync.h index 3348da2851c..abc5350b6c0 100644 --- a/innobase/include/sync0sync.h +++ b/innobase/include/sync0sync.h @@ -127,6 +127,7 @@ void sync_print( /*=======*/ FILE* file); /* in: file where to print */ +#ifdef UNIV_DEBUG /********************************************************************** Checks that the mutex has been initialized. */ @@ -134,6 +135,7 @@ ibool mutex_validate( /*===========*/ mutex_t* mutex); +#endif /* UNIV_DEBUG */ /********************************************************************** Sets the mutex latching level field. */ diff --git a/innobase/include/trx0sys.h b/innobase/include/trx0sys.h index 755bcb28611..c7ef4d1929d 100644 --- a/innobase/include/trx0sys.h +++ b/innobase/include/trx0sys.h @@ -268,6 +268,7 @@ the magic number shows it valid. */ void trx_sys_print_mysql_binlog_offset(void); /*===================================*/ +#ifdef UNIV_HOTBACKUP /********************************************************************* Prints to stderr the MySQL binlog info in the system header if the magic number shows it valid. */ @@ -277,6 +278,7 @@ trx_sys_print_mysql_binlog_offset_from_page( /*========================================*/ byte* page); /* in: buffer containing the trx system header page, i.e., page number TRX_SYS_PAGE_NO in the tablespace */ +#endif /* UNIV_HOTBACKUP */ /********************************************************************* Prints to stderr the MySQL master log offset info in the trx system header if the magic number shows it valid. */ diff --git a/innobase/lock/lock0lock.c b/innobase/lock/lock0lock.c index 47bc37113c4..e141e30ae97 100644 --- a/innobase/lock/lock0lock.c +++ b/innobase/lock/lock0lock.c @@ -266,7 +266,9 @@ waiting, in its lock queue. Solution: We can copy the locks as gap type locks, so that also the waiting locks are transformed to granted gap type locks on the inserted record. */ +#ifdef UNIV_DEBUG ibool lock_print_waits = FALSE; +#endif /* UNIV_DEBUG */ /* The lock system */ lock_sys_t* lock_sys = NULL; @@ -1326,7 +1328,8 @@ lock_rec_has_expl( return(NULL); } - + +#ifdef UNIV_DEBUG /************************************************************************* Checks if some other transaction has a lock request in the queue. */ static @@ -1369,6 +1372,7 @@ lock_rec_other_has_expl_req( return(NULL); } +#endif /* UNIV_DEBUG */ /************************************************************************* Checks if some other transaction has a conflicting explicit lock request @@ -1657,11 +1661,13 @@ lock_rec_enqueue_waiting( ut_a(que_thr_stop(thr)); +#ifdef UNIV_DEBUG if (lock_print_waits) { fprintf(stderr, "Lock wait for trx %lu in index ", ut_dulint_get_low(trx->id)); ut_print_name(stderr, index->name); } +#endif /* UNIV_DEBUG */ return(DB_LOCK_WAIT); } @@ -1997,10 +2003,12 @@ lock_grant( lock->trx->auto_inc_lock = lock; } +#ifdef UNIV_DEBUG if (lock_print_waits) { fprintf(stderr, "Lock wait for trx %lu ends\n", ut_dulint_get_low(lock->trx->id)); } +#endif /* UNIV_DEBUG */ /* If we are resolving a deadlock by choosing another transaction as a victim, then our original transaction may not be in the @@ -3071,9 +3079,11 @@ lock_deadlock_recursive( lock_table_print(ef, start->wait_lock); } +#ifdef UNIV_DEBUG if (lock_print_waits) { fputs("Deadlock detected\n", stderr); } +#endif /* UNIV_DEBUG */ if (ut_dulint_cmp(wait_lock->trx->undo_no, start->undo_no) >= 0) { @@ -3920,7 +3930,7 @@ loop: if (trx == NULL) { lock_mutex_exit_kernel(); - /* lock_validate(); */ + ut_ad(lock_validate()); return; } @@ -4022,6 +4032,7 @@ loop: goto loop; } +#ifdef UNIV_DEBUG /************************************************************************* Validates the lock queue on a table. */ @@ -4332,6 +4343,7 @@ lock_validate(void) return(TRUE); } +#endif /* UNIV_DEBUG */ /*============ RECORD LOCK CHECKS FOR ROW OPERATIONS ====================*/ diff --git a/innobase/mem/mem0dbg.c b/innobase/mem/mem0dbg.c index 92c1235220e..6c97ef9eb8e 100644 --- a/innobase/mem/mem0dbg.c +++ b/innobase/mem/mem0dbg.c @@ -375,6 +375,7 @@ mem_hash_remove( } #endif /* UNIV_MEM_DEBUG */ +#ifdef UNIV_DEBUG /******************************************************************* Checks a memory heap for consistency and prints the contents if requested. Outputs the sum of sizes of buffers given to the user (only in @@ -585,6 +586,7 @@ mem_heap_validate( return(TRUE); } +#endif /* UNIV_DEBUG */ #ifdef UNIV_MEM_DEBUG /********************************************************************* diff --git a/innobase/mem/mem0pool.c b/innobase/mem/mem0pool.c index 9a5d16cd4a2..3c409e3fceb 100644 --- a/innobase/mem/mem0pool.c +++ b/innobase/mem/mem0pool.c @@ -566,6 +566,7 @@ mem_area_free( ut_ad(mem_pool_validate(pool)); } +#ifdef UNIV_DEBUG /************************************************************************ Validates a memory pool. */ @@ -643,6 +644,7 @@ mem_pool_print_info( pool->reserved); mutex_exit(&(pool->mutex)); } +#endif /* UNIV_DEBUG */ /************************************************************************ Returns the amount of reserved memory. */ diff --git a/innobase/mtr/mtr0mtr.c b/innobase/mtr/mtr0mtr.c index aaf2c9601f4..46473cb3ffe 100644 --- a/innobase/mtr/mtr0mtr.c +++ b/innobase/mtr/mtr0mtr.c @@ -508,6 +508,7 @@ mtr_read_dulint( return(mach_read_from_8(ptr)); } +#ifdef UNIV_DEBUG /************************************************************* Prints info of an mtr handle. */ @@ -521,3 +522,4 @@ mtr_print( dyn_array_get_data_size(&(mtr->memo)), dyn_array_get_data_size(&(mtr->log))); } +#endif /* UNIV_DEBUG */ diff --git a/innobase/pars/pars0opt.c b/innobase/pars/pars0opt.c index 5cc2e39b438..98bb1b12396 100644 --- a/innobase/pars/pars0opt.c +++ b/innobase/pars/pars0opt.c @@ -1190,6 +1190,7 @@ opt_search_plan( #endif } +#ifdef UNIV_SQL_DEBUG /************************************************************************ Prints info of a query plan. */ @@ -1235,3 +1236,4 @@ opt_print_query_plan( UT_LIST_GET_LEN(plan->end_conds)); } } +#endif /* UNIV_SQL_DEBUG */ diff --git a/innobase/srv/srv0start.c b/innobase/srv/srv0start.c index f9b66b6e5fc..4a7d5448c52 100644 --- a/innobase/srv/srv0start.c +++ b/innobase/srv/srv0start.c @@ -1348,7 +1348,9 @@ NetWare. */ os_thread_create(&srv_master_thread, NULL, thread_ids + 1 + SRV_MAX_N_IO_THREADS); +#ifdef UNIV_DEBUG /* buf_debug_prints = TRUE; */ +#endif /* UNIV_DEBUG */ sum_of_data_file_sizes = 0; diff --git a/innobase/sync/sync0rw.c b/innobase/sync/sync0rw.c index e3caa24cb1e..9dd5148e27a 100644 --- a/innobase/sync/sync0rw.c +++ b/innobase/sync/sync0rw.c @@ -157,6 +157,7 @@ rw_lock_free( mutex_exit(&rw_lock_list_mutex); } +#ifdef UNIV_DEBUG /********************************************************************** Checks that the rw-lock has been initialized and that there are no simultaneous shared and exclusive locks. */ @@ -184,6 +185,7 @@ rw_lock_validate( return(TRUE); } +#endif /* UNIV_DEBUG */ /********************************************************************** Lock an rw-lock in shared mode for the current thread. If the rw-lock is diff --git a/innobase/sync/sync0sync.c b/innobase/sync/sync0sync.c index 3539d7de817..c534dc6823d 100644 --- a/innobase/sync/sync0sync.c +++ b/innobase/sync/sync0sync.c @@ -275,6 +275,7 @@ mutex_enter_nowait( return(1); } +#ifdef UNIV_DEBUG /********************************************************************** Checks that the mutex has been initialized. */ @@ -288,6 +289,7 @@ mutex_validate( return(TRUE); } +#endif /* UNIV_DEBUG */ /********************************************************************** Sets the waiters field in a mutex. */ @@ -1034,8 +1036,11 @@ sync_thread_add_level( } else if (level == SYNC_DICT_HEADER) { ut_a(sync_thread_levels_g(array, SYNC_DICT_HEADER)); } else if (level == SYNC_DICT) { - ut_a(buf_debug_prints - || sync_thread_levels_g(array, SYNC_DICT)); + ut_a( +#ifdef UNIV_DEBUG + buf_debug_prints || +#endif /* UNIV_DEBUG */ + sync_thread_levels_g(array, SYNC_DICT)); } else { ut_error; } diff --git a/innobase/trx/trx0roll.c b/innobase/trx/trx0roll.c index eed5e79a20f..92a5373aabd 100644 --- a/innobase/trx/trx0roll.c +++ b/innobase/trx/trx0roll.c @@ -1140,10 +1140,12 @@ trx_finish_rollback_off_kernel( return; } +#ifdef UNIV_DEBUG if (lock_print_waits) { fprintf(stderr, "Trx %lu rollback finished\n", ut_dulint_get_low(trx->id)); } +#endif /* UNIV_DEBUG */ trx_commit_off_kernel(trx); diff --git a/innobase/trx/trx0sys.c b/innobase/trx/trx0sys.c index e0c30df17af..b52ec2bae0f 100644 --- a/innobase/trx/trx0sys.c +++ b/innobase/trx/trx0sys.c @@ -599,6 +599,7 @@ trx_sys_update_mysql_binlog_offset( MLOG_4BYTES, mtr); } +#ifdef UNIV_HOTBACKUP /********************************************************************* Prints to stderr the MySQL binlog info in the system header if the magic number shows it valid. */ @@ -626,6 +627,7 @@ trx_sys_print_mysql_binlog_offset_from_page( sys_header + TRX_SYS_MYSQL_LOG_INFO + TRX_SYS_MYSQL_LOG_NAME); } } +#endif /* UNIV_HOTBACKUP */ /********************************************************************* Prints to stderr the MySQL binlog offset info in the trx system header if From 58e90107d987d8afef24751a7c6b40c8319efa96 Mon Sep 17 00:00:00 2001 From: "guilhem@mysql.com" <> Date: Wed, 7 Apr 2004 18:34:31 +0200 Subject: [PATCH 22/28] Fix for BUG#3415 "mysqlbinlog loses a USE command when LOAD DATA INFILE is involved": if you are printing LOAD DATA INFILE and its USE as comments, don't update 'last_db' (because you have not actually changed the db in the server). --- sql/log_event.cc | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/sql/log_event.cc b/sql/log_event.cc index cd94ee2804d..9c8676192a1 100644 --- a/sql/log_event.cc +++ b/sql/log_event.cc @@ -891,15 +891,15 @@ void Query_log_event::print(FILE* file, bool short_form, char* last_db) (ulong) thread_id, (ulong) exec_time, error_code); } - bool same_db = 0; + bool different_db= 1; if (db && last_db) { - if (!(same_db = !memcmp(last_db, db, db_len + 1))) + if (different_db= memcmp(last_db, db, db_len + 1)) memcpy(last_db, db, db_len + 1); } - if (db && db[0] && !same_db) + if (db && db[0] && different_db) fprintf(file, "use %s;\n", db); end=int10_to_str((long) when, strmov(buff,"SET TIMESTAMP="),10); *end++=';'; @@ -1324,14 +1324,21 @@ void Load_log_event::print(FILE* file, bool short_form, char* last_db, thread_id, exec_time); } - bool same_db = 0; + bool different_db= 1; if (db && last_db) { - if (!(same_db = !memcmp(last_db, db, db_len + 1))) + /* + If the database is different from the one of the previous statement, we + need to print the "use" command, and we update the last_db. + But if commented, the "use" is going to be commented so we should not + update the last_db. + */ + if ((different_db= memcmp(last_db, db, db_len + 1)) && + !commented) memcpy(last_db, db, db_len + 1); } - if (db && db[0] && !same_db) + if (db && db[0] && different_db) fprintf(file, "%suse %s;\n", commented ? "# " : "", db); From 7560f3bae729f4ef3fb3a6d1061483a7b3345bbd Mon Sep 17 00:00:00 2001 From: "heikki@hundin.mysql.fi" <> Date: Thu, 8 Apr 2004 09:25:48 +0300 Subject: [PATCH 23/28] sql_select.cc: Fix a glitch reported by Philippe Lewicki on the general mailing list: do not print a warning to the .err log if read_key fails with a lock wait timeout error 146 --- sql/sql_select.cc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 057f0bd9483..b299e3af0b7 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -4995,7 +4995,8 @@ join_read_key(JOIN_TAB *tab) tab->ref.key_length,HA_READ_KEY_EXACT); if (error && error != HA_ERR_KEY_NOT_FOUND) { - sql_print_error("read_key: Got error %d when reading table '%s'",error, + if (error != HA_ERR_LOCK_DEADLOCK && error != HA_ERR_LOCK_WAIT_TIMEOUT) + sql_print_error("read_key: Got error %d when reading table '%s'",error, table->path); table->file->print_error(error,MYF(0)); return 1; From 9dec81b89cf2700e86f77455f46e1dfa172e391b Mon Sep 17 00:00:00 2001 From: "marko@hundin.mysql.fi" <> Date: Thu, 8 Apr 2004 10:47:38 +0300 Subject: [PATCH 24/28] InnoDB: Fix a preprocessor error introduced in ChangeSet 1.1772 --- innobase/sync/sync0sync.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/innobase/sync/sync0sync.c b/innobase/sync/sync0sync.c index c534dc6823d..952510c49e3 100644 --- a/innobase/sync/sync0sync.c +++ b/innobase/sync/sync0sync.c @@ -1036,11 +1036,12 @@ sync_thread_add_level( } else if (level == SYNC_DICT_HEADER) { ut_a(sync_thread_levels_g(array, SYNC_DICT_HEADER)); } else if (level == SYNC_DICT) { - ut_a( #ifdef UNIV_DEBUG - buf_debug_prints || -#endif /* UNIV_DEBUG */ + ut_a(buf_debug_prints || sync_thread_levels_g(array, SYNC_DICT)); +#else /* UNIV_DEBUG */ + ut_a(sync_thread_levels_g(array, SYNC_DICT)); +#endif /* UNIV_DEBUG */ } else { ut_error; } From c640a3904a9fa90d7402810d380002283bab6c79 Mon Sep 17 00:00:00 2001 From: "guilhem@mysql.com" <> Date: Thu, 8 Apr 2004 22:12:22 +0200 Subject: [PATCH 25/28] Fix for BUG#3422 "In 3.23 -> 4.0 replication, slave segfault when replicating LOAD DATA INFILE": as we transform the 3.23 Load_log_event into a 4.0 Create_file_log_event which is one byte longer, we need to increment event_len. The bug was that we did not increment it, so later in code the end 0 was not seen so there was for example a segfault in strlen(fname) because fname was not 0-terminated. Other problems remain in 3.23->4.0 replication of LOAD DATA INFILE but they are less serious: Exec_master_log_pos and Relay_log_space are incorrect. I'll document them. They are not fixable without significant code changes (if you fix those problems in 4.0, you get assertion failures somewhere else etc), * which are already done in 5.0.0 *. --- sql/slave.cc | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/sql/slave.cc b/sql/slave.cc index 1ef572e3a0a..e79e70e0395 100644 --- a/sql/slave.cc +++ b/sql/slave.cc @@ -3030,8 +3030,16 @@ static int queue_old_event(MASTER_INFO *mi, const char *buf, DBUG_RETURN(1); } memcpy(tmp_buf,buf,event_len); - tmp_buf[event_len]=0; // Create_file constructor wants null-term buffer + /* + Create_file constructor wants a 0 as last char of buffer, this 0 will + serve as the string-termination char for the file's name (which is at the + end of the buffer) + We must increment event_len, otherwise the event constructor will not see + this end 0, which leads to segfault. + */ + tmp_buf[event_len++]=0; buf = (const char*)tmp_buf; + int4store(buf+EVENT_LEN_OFFSET, event_len); } /* This will transform LOAD_EVENT into CREATE_FILE_EVENT, ask the master to @@ -3079,7 +3087,11 @@ static int queue_old_event(MASTER_INFO *mi, const char *buf, DBUG_ASSERT(tmp_buf); int error = process_io_create_file(mi,(Create_file_log_event*)ev); delete ev; - mi->master_log_pos += event_len; + /* + We had incremented event_len, but now when it is used to calculate the + position in the master's log, we must use the original value. + */ + mi->master_log_pos += --event_len; DBUG_PRINT("info", ("master_log_pos: %d", (ulong) mi->master_log_pos)); pthread_mutex_unlock(&mi->data_lock); my_free((char*)tmp_buf, MYF(0)); From 96cb3ec0e9c3ace612b563e2cbd264c503595f85 Mon Sep 17 00:00:00 2001 From: "jani@rhols221.adsl.netsonic.fi" <> Date: Fri, 9 Apr 2004 09:59:11 +0300 Subject: [PATCH 26/28] - Merged in changes from mysqld_multi 2.6 - Changed reading of config file so that one can use a separate config file for [mysqld_multi] also. In other words --config-file=file will read group [mysqld_multi] from this file, earlier it wouldn't have. --- scripts/mysqld_multi.sh | 88 +++++++++++++++++++++++++++++++++++------ 1 file changed, 76 insertions(+), 12 deletions(-) diff --git a/scripts/mysqld_multi.sh b/scripts/mysqld_multi.sh index 3165a01362c..b75aa1a7c31 100644 --- a/scripts/mysqld_multi.sh +++ b/scripts/mysqld_multi.sh @@ -4,12 +4,12 @@ use Getopt::Long; use POSIX qw(strftime); $|=1; -$VER="2.5"; +$VER="2.7"; $opt_config_file = undef(); $opt_example = 0; $opt_help = 0; -$opt_log = "/tmp/mysqld_multi.log"; +$opt_log = undef(); $opt_mysqladmin = "@bindir@/mysqladmin"; $opt_mysqld = "@libexecdir@/mysqld"; $opt_no_log = 0; @@ -18,6 +18,9 @@ $opt_tcp_ip = 0; $opt_user = "root"; $opt_version = 0; +my $my_print_defaults_exists= 1; +my $logdir= undef(); + my ($mysqld, $mysqladmin, $groupids, $homedir, $my_progname); $homedir = $ENV{HOME}; @@ -42,16 +45,41 @@ sub main print "Please make sure you have this command available and\n"; print "in your path. The command is available from the latest\n"; print "MySQL distribution.\n"; + $my_print_defaults_exists= 0; + } + if ($my_print_defaults_exists) + { + foreach my $arg (@ARGV) + { + if ($arg =~ m/^--config-file=(.*)/) + { + if (!length($1)) + { + die "Option config-file requires an argument\n"; + } + elsif (!( -e $1 && -r $1)) + { + die "Option file '$1' doesn't exists, or is not readable\n"; + } + else + { + $opt_config_file= $1; + } + } + } + my $com= "my_print_defaults "; + $com.= "--config-file=$opt_config_file " if (defined($opt_config_file)); + $com.= "mysqld_multi"; + my @defops = `$com`; + chop @defops; + splice @ARGV, 0, 0, @defops; } - my @defops = `my_print_defaults mysqld_multi`; - chop @defops; - splice @ARGV, 0, 0, @defops; GetOptions("help","example","version","mysqld=s","mysqladmin=s", - "config-file=s","user=s","password=s","log=s","no-log","tcp-ip") + "config-file=s","user=s","password=s","log=s","no-log","tcp-ip") || die "Wrong option! See $my_progname --help for detailed information!\n"; + init_log(); $groupids = $ARGV[1]; - if ($opt_version) { print "$my_progname version $VER by Jani Tolonen\n"; @@ -112,6 +140,45 @@ sub main } } +#### +#### Init log file. Check for appropriate place for log file, in the following +#### order my_print_defaults mysqld datadir, @datadir@, /var/log, /tmp +#### + +sub init_log +{ + if ($my_print_defaults_exists) + { + @mysqld_opts= `my_print_defaults mysqld`; + chomp @mysqld_opts; + foreach my $opt (@mysqld_opts) + { + if ($opt =~ m/^\-\-datadir[=](.*)/) + { + if (-d "$1" && -w "$1") + { + $logdir= $1; + } + } + } + } + if (!defined($logdir)) + { + $logdir= "@datadir@" if (-d "@datadir@" && -w "@datadir@"); + } + if (!defined($logdir)) + { + # Log file was not specified and we could not log to a standard place, + # so log file be disabled for now. + print "WARNING: Log file disabled. Maybe directory/file isn't writable?\n"; + $opt_no_log= 1; + } + else + { + $opt_log= "$logdir/mysqld_multi.log"; + } +} + #### #### Report living and not running MySQL servers #### @@ -589,12 +656,9 @@ reported. Note that you must not have any white spaces in the GNR list. Anything after a white space are ignored. Options: ---config-file=... Alternative config file. NOTE: This will not affect - this program's own options (group [mysqld_multi]), - but only groups [mysqld#]. Without this option everything - will be searched from the ordinary my.cnf file. +--config-file=... Alternative config file. Using: $opt_config_file ---example Give an example of a config file. (PLEASE DO CHECK THIS!) +--example Give an example of a config file. --help Print this help and exit. --log=... Log file. Full path to and the name for the log file. NOTE: If the file exists, everything will be appended. From c8937dbcb767e53cda0b1296d8580bcf60bb5cf9 Mon Sep 17 00:00:00 2001 From: "ram@gw.mysql.r18.ru" <> Date: Fri, 9 Apr 2004 19:07:39 +0500 Subject: [PATCH 27/28] A fix. (Bug #3376: AVG(constant) returns constant if no rows in result set) --- mysql-test/r/func_group.result | 5 +++++ mysql-test/t/func_group.test | 8 ++++++++ sql/item_sum.h | 1 + 3 files changed, 14 insertions(+) diff --git a/mysql-test/r/func_group.result b/mysql-test/r/func_group.result index 99c42bb83cf..ef29d0f2f5b 100644 --- a/mysql-test/r/func_group.result +++ b/mysql-test/r/func_group.result @@ -256,3 +256,8 @@ bit_and(col) bit_or(col) 18446744073709551614 18446744073709551614 18446744073709551615 18446744073709551615 drop table t1; +create table t1 (a int); +select avg(2) from t1; +avg(2) +NULL +drop table t1; diff --git a/mysql-test/t/func_group.test b/mysql-test/t/func_group.test index d03e4b9b629..c03c39bec4a 100644 --- a/mysql-test/t/func_group.test +++ b/mysql-test/t/func_group.test @@ -155,3 +155,11 @@ insert into t1 values (-1), (-2), (-3); select bit_and(col), bit_or(col) from t1; select SQL_BIG_RESULT bit_and(col), bit_or(col) from t1 group by col; drop table t1; + +# +# Bug #3376: avg() and an empty table +# + +create table t1 (a int); +select avg(2) from t1; +drop table t1; diff --git a/sql/item_sum.h b/sql/item_sum.h index d3a328be032..6835b1e8fae 100644 --- a/sql/item_sum.h +++ b/sql/item_sum.h @@ -249,6 +249,7 @@ class Item_sum_avg :public Item_sum_num void update_field(); Item *result_item(Field *field) { return new Item_avg_field(this); } + void no_rows_in_result() {} const char *func_name() const { return "avg"; } unsigned int size_of() { return sizeof(*this);} }; From 7d3e633edc5db31c0698660ed644d7a18faea41c Mon Sep 17 00:00:00 2001 From: "heikki@hundin.mysql.fi" <> Date: Fri, 9 Apr 2004 22:18:18 +0300 Subject: [PATCH 28/28] ha_innodb.cc, sync0sync.h, sync0sync.c: Use only noninlined InnoDB functions in ha_innodb.cc --- innobase/include/sync0sync.h | 16 ++++++++++++++++ innobase/sync/sync0sync.c | 24 ++++++++++++++++++++++++ sql/ha_innodb.cc | 9 ++++++--- 3 files changed, 46 insertions(+), 3 deletions(-) diff --git a/innobase/include/sync0sync.h b/innobase/include/sync0sync.h index abc5350b6c0..38f1489682a 100644 --- a/innobase/include/sync0sync.h +++ b/innobase/include/sync0sync.h @@ -65,6 +65,15 @@ NOTE! The following macro should be used in mutex locking, not the corresponding function. */ #define mutex_enter(M) mutex_enter_func((M), IB__FILE__, __LINE__) +/********************************************************************** +A noninlined function that reserves a mutex. In ha_innodb.cc we have disabled +inlining of InnoDB functions, and no inlined functions should be called from +there. That is why we need to duplicate the inlined function here. */ + +void +mutex_enter_noninline( +/*==================*/ + mutex_t* mutex); /* in: mutex */ /****************************************************************** NOTE! The following macro should be used in mutex locking, not the corresponding function. */ @@ -105,6 +114,13 @@ mutex_exit( /*=======*/ mutex_t* mutex); /* in: pointer to mutex */ /********************************************************************** +Releases a mutex. */ + +void +mutex_exit_noninline( +/*=================*/ + mutex_t* mutex); /* in: mutex */ +/********************************************************************** Returns TRUE if no mutex or rw-lock is currently locked. Works only in the debug version. */ diff --git a/innobase/sync/sync0sync.c b/innobase/sync/sync0sync.c index 952510c49e3..eaeb56b4983 100644 --- a/innobase/sync/sync0sync.c +++ b/innobase/sync/sync0sync.c @@ -167,6 +167,30 @@ struct sync_level_struct{ ulint level; /* level of the latch in the latching order */ }; +/********************************************************************** +A noninlined function that reserves a mutex. In ha_innodb.cc we have disabled +inlining of InnoDB functions, and no inlined functions should be called from +there. That is why we need to duplicate the inlined function here. */ + +void +mutex_enter_noninline( +/*==================*/ + mutex_t* mutex) /* in: mutex */ +{ + mutex_enter(mutex); +} + +/********************************************************************** +Releases a mutex. */ + +void +mutex_exit_noninline( +/*=================*/ + mutex_t* mutex) /* in: mutex */ +{ + mutex_exit(mutex); +} + /********************************************************************** Creates, or rather, initializes a mutex object in a specified memory location (which must be appropriately aligned). The mutex is initialized diff --git a/sql/ha_innodb.cc b/sql/ha_innodb.cc index 759679d5bd6..7a651fc12d9 100644 --- a/sql/ha_innodb.cc +++ b/sql/ha_innodb.cc @@ -15,7 +15,9 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ /* This file defines the InnoDB handler: the interface between MySQL and -InnoDB */ +InnoDB +NOTE: You can only use noninlined InnoDB functions in this file, because we +have disables the InnoDB inlining in this file. */ #ifdef __GNUC__ #pragma implementation // gcc: Class implementation @@ -64,6 +66,7 @@ extern "C" { #include "../innobase/include/btr0cur.h" #include "../innobase/include/btr0btr.h" #include "../innobase/include/fsp0fsp.h" +#include "../innobase/include/sync0sync.h" } #define HA_INNOBASE_ROWS_IN_TABLE 10000 /* to get optimization right */ @@ -4629,7 +4632,7 @@ innodb_show_status( long flen; char* str; - mutex_enter(&srv_monitor_file_mutex); + mutex_enter_noninline(&srv_monitor_file_mutex); rewind(srv_monitor_file); srv_printf_innodb_monitor(srv_monitor_file); flen = ftell(srv_monitor_file); @@ -4650,7 +4653,7 @@ innodb_show_status( str[flen] = 0; } - mutex_exit(&srv_monitor_file_mutex); + mutex_exit_noninline(&srv_monitor_file_mutex); List field_list;