diff options
Diffstat (limited to 'storage')
-rw-r--r-- | storage/xtradb/dict/dict0crea.c | 42 | ||||
-rw-r--r-- | storage/xtradb/dict/dict0dict.c | 103 | ||||
-rw-r--r-- | storage/xtradb/dict/dict0load.c | 93 | ||||
-rw-r--r-- | storage/xtradb/dict/dict0mem.c | 15 | ||||
-rw-r--r-- | storage/xtradb/handler/ha_innodb.cc | 10 | ||||
-rw-r--r-- | storage/xtradb/handler/ha_innodb.h | 1 | ||||
-rw-r--r-- | storage/xtradb/handler/i_s.cc | 25 | ||||
-rw-r--r-- | storage/xtradb/include/dict0dict.h | 39 | ||||
-rw-r--r-- | storage/xtradb/include/dict0dict.ic | 61 | ||||
-rw-r--r-- | storage/xtradb/include/dict0load.h | 12 | ||||
-rw-r--r-- | storage/xtradb/include/dict0mem.h | 12 | ||||
-rw-r--r-- | storage/xtradb/include/log0log.h | 12 | ||||
-rw-r--r-- | storage/xtradb/include/log0log.ic | 21 | ||||
-rw-r--r-- | storage/xtradb/include/univ.i | 4 | ||||
-rw-r--r-- | storage/xtradb/log/log0log.c | 19 | ||||
-rw-r--r-- | storage/xtradb/log/log0online.c | 35 |
16 files changed, 421 insertions, 83 deletions
diff --git a/storage/xtradb/dict/dict0crea.c b/storage/xtradb/dict/dict0crea.c index d87d2942fef..c88979b20f9 100644 --- a/storage/xtradb/dict/dict0crea.c +++ b/storage/xtradb/dict/dict0crea.c @@ -1,6 +1,6 @@ /***************************************************************************** -Copyright (c) 1996, 2013, Oracle and/or its affiliates. All Rights Reserved. +Copyright (c) 1996, 2014, Oracle and/or its affiliates. All Rights Reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -1648,6 +1648,8 @@ dict_create_add_foreign_to_dictionary( ulint i; pars_info_t* info; + ut_ad(mutex_own(&(dict_sys->mutex))); + if (foreign->id == NULL) { /* Generate a new constraint id */ ulint namelen = strlen(table->name); @@ -1726,6 +1728,37 @@ dict_create_add_foreign_to_dictionary( "END;\n" , table, foreign, trx); + if (error == DB_SUCCESS) { + + + if (foreign->foreign_table != NULL) { + ib_rbt_t* rbt + = foreign->foreign_table->foreign_rbt; + + if (rbt == NULL) { + rbt = dict_table_init_foreign_rbt( + foreign->foreign_table); + } else { + rbt_delete(rbt, foreign->id); + } + + rbt_insert(rbt, foreign->id, &foreign); + } + + if (foreign->referenced_table != NULL) { + ib_rbt_t* rbt + = foreign->referenced_table->referenced_rbt; + + if (rbt == NULL) { + rbt = dict_table_init_referenced_rbt( + foreign->referenced_table); + } else { + rbt_delete(rbt, foreign->id); + } + rbt_insert(rbt, foreign->id, &foreign); + } + } + return(error); } @@ -1750,6 +1783,7 @@ dict_create_add_foreigns_to_dictionary( dict_foreign_t* foreign; ulint number = start_id + 1; ulint error; + DBUG_ENTER("dict_create_add_foreigns_to_dictionary"); ut_ad(mutex_own(&(dict_sys->mutex))); @@ -1758,7 +1792,7 @@ dict_create_add_foreigns_to_dictionary( "InnoDB: table SYS_FOREIGN not found" " in internal data dictionary\n"); - return(DB_ERROR); + DBUG_RETURN(DB_ERROR); } for (foreign = UT_LIST_GET_FIRST(table->foreign_list); @@ -1770,9 +1804,9 @@ dict_create_add_foreigns_to_dictionary( if (error != DB_SUCCESS) { - return(error); + DBUG_RETURN(error); } } - return(DB_SUCCESS); + DBUG_RETURN(DB_SUCCESS); } diff --git a/storage/xtradb/dict/dict0dict.c b/storage/xtradb/dict/dict0dict.c index de54bbfd929..ff0531457f8 100644 --- a/storage/xtradb/dict/dict0dict.c +++ b/storage/xtradb/dict/dict0dict.c @@ -1,6 +1,6 @@ /***************************************************************************** -Copyright (c) 1996, 2013, Oracle and/or its affiliates. All Rights Reserved. +Copyright (c) 1996, 2014, Oracle and/or its affiliates. All Rights Reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -26,6 +26,7 @@ Created 1/8/1996 Heikki Tuuri #include <my_sys.h> #include "dict0dict.h" +#include "ut0rbt.h" #ifdef UNIV_NONINL #include "dict0dict.ic" @@ -193,6 +194,7 @@ UNIV_INTERN FILE* dict_foreign_err_file = NULL; /* mutex protecting the foreign and unique error buffers */ UNIV_INTERN mutex_t dict_foreign_err_mutex; #endif /* !UNIV_HOTBACKUP */ + /******************************************************************//** Makes all characters in a NUL-terminated UTF-8 string lower case. */ UNIV_INTERN @@ -1110,6 +1112,10 @@ dict_table_rename_in_cache( UT_LIST_INIT(table->referenced_list); + if (table->referenced_rbt != NULL) { + rbt_clear(table->referenced_rbt); + } + return(TRUE); } @@ -1120,6 +1126,10 @@ dict_table_rename_in_cache( foreign = UT_LIST_GET_FIRST(table->foreign_list); while (foreign != NULL) { + + /* The id will be changed. So remove old one */ + rbt_delete(foreign->foreign_table->foreign_rbt, foreign->id); + if (ut_strlen(foreign->foreign_table_name) < ut_strlen(table->name)) { /* Allocate a longer name buffer; @@ -1267,6 +1277,9 @@ dict_table_rename_in_cache( mem_free(old_id); } + rbt_insert(foreign->foreign_table->foreign_rbt, + foreign->id, &foreign); + foreign = UT_LIST_GET_NEXT(foreign_list, foreign); } @@ -2614,22 +2627,40 @@ dict_foreign_remove_from_cache( /*===========================*/ dict_foreign_t* foreign) /*!< in, own: foreign constraint */ { + DBUG_ENTER("dict_foreign_remove_from_cache"); + ut_ad(mutex_own(&(dict_sys->mutex))); ut_a(foreign); if (foreign->referenced_table) { + ib_rbt_t* rbt; + UT_LIST_REMOVE(referenced_list, foreign->referenced_table->referenced_list, foreign); + + rbt = foreign->referenced_table->referenced_rbt; + if (rbt != NULL) { + rbt_delete(rbt, foreign->id); + } } if (foreign->foreign_table) { + ib_rbt_t* rbt; + UT_LIST_REMOVE(foreign_list, foreign->foreign_table->foreign_list, foreign); + rbt = foreign->foreign_table->foreign_rbt; + + if (rbt != NULL) { + rbt_delete(rbt, foreign->id); + } } dict_foreign_free(foreign); + + DBUG_VOID_RETURN; } /**********************************************************************//** @@ -2643,33 +2674,36 @@ dict_foreign_find( dict_table_t* table, /*!< in: table object */ const char* id) /*!< in: foreign constraint id */ { - dict_foreign_t* foreign; - - ut_ad(mutex_own(&(dict_sys->mutex))); - - foreign = UT_LIST_GET_FIRST(table->foreign_list); + const ib_rbt_node_t* node; - while (foreign) { - if (ut_strcmp(id, foreign->id) == 0) { + DBUG_ENTER("dict_foreign_find"); - return(foreign); + ut_ad(mutex_own(&(dict_sys->mutex))); + ut_ad(dict_table_check_foreign_keys(table)); + + if (table->foreign_rbt != NULL) { + ut_a(UT_LIST_GET_LEN(table->foreign_list) + == rbt_size(table->foreign_rbt)); + node = rbt_lookup(table->foreign_rbt, id); + if (node != NULL) { + DBUG_RETURN(*(dict_foreign_t**) node->value); } - - foreign = UT_LIST_GET_NEXT(foreign_list, foreign); + } else { + ut_a(UT_LIST_GET_LEN(table->foreign_list) == 0); } - foreign = UT_LIST_GET_FIRST(table->referenced_list); - - while (foreign) { - if (ut_strcmp(id, foreign->id) == 0) { - - return(foreign); + if (table->referenced_rbt != NULL) { + ut_a(UT_LIST_GET_LEN(table->referenced_list) + == rbt_size(table->referenced_rbt)); + node = rbt_lookup(table->referenced_rbt, id); + if (node != NULL) { + DBUG_RETURN(*(dict_foreign_t**) node->value); } - - foreign = UT_LIST_GET_NEXT(referenced_list, foreign); + } else { + ut_a(UT_LIST_GET_LEN(table->referenced_list) == 0); } - return(NULL); + DBUG_RETURN(NULL); } /*********************************************************************//** @@ -2907,6 +2941,8 @@ dict_foreign_add_to_cache( ibool added_to_referenced_list= FALSE; FILE* ef = dict_foreign_err_file; + DBUG_ENTER("dict_foreign_add_to_cache"); + ut_ad(mutex_own(&(dict_sys->mutex))); for_table = dict_table_check_if_in_cache_low( @@ -2916,7 +2952,14 @@ dict_foreign_add_to_cache( foreign->referenced_table_name_lookup); ut_a(for_table || ref_table); + if (ref_table != NULL && ref_table->referenced_rbt == NULL) { + dict_table_init_referenced_rbt(ref_table); + } + if (for_table) { + if (for_table->foreign_rbt == NULL) { + dict_table_init_foreign_rbt(for_table); + } for_in_cache = dict_foreign_find(for_table, foreign->id); } @@ -2953,18 +2996,22 @@ dict_foreign_add_to_cache( mem_heap_free(foreign->heap); } - return(DB_CANNOT_ADD_CONSTRAINT); + DBUG_RETURN(DB_CANNOT_ADD_CONSTRAINT); } for_in_cache->referenced_table = ref_table; for_in_cache->referenced_index = index; + UT_LIST_ADD_LAST(referenced_list, - ref_table->referenced_list, - for_in_cache); + ref_table->referenced_list, for_in_cache); added_to_referenced_list = TRUE; + + rbt_insert(ref_table->referenced_rbt, + for_in_cache->id, &for_in_cache); } if (for_in_cache->foreign_table == NULL && for_table) { + index = dict_foreign_find_index( for_table, for_in_cache->foreign_col_names, @@ -2993,22 +3040,28 @@ dict_foreign_add_to_cache( referenced_list, ref_table->referenced_list, for_in_cache); + rbt_delete(ref_table->referenced_rbt, + for_in_cache->id); } mem_heap_free(foreign->heap); } - return(DB_CANNOT_ADD_CONSTRAINT); + DBUG_RETURN(DB_CANNOT_ADD_CONSTRAINT); } for_in_cache->foreign_table = for_table; for_in_cache->foreign_index = index; + UT_LIST_ADD_LAST(foreign_list, for_table->foreign_list, for_in_cache); + + rbt_insert(for_table->foreign_rbt, for_in_cache->id, + &for_in_cache); } - return(DB_SUCCESS); + DBUG_RETURN(DB_SUCCESS); } #endif /* !UNIV_HOTBACKUP */ diff --git a/storage/xtradb/dict/dict0load.c b/storage/xtradb/dict/dict0load.c index 05a00c17325..90a09a27dc1 100644 --- a/storage/xtradb/dict/dict0load.c +++ b/storage/xtradb/dict/dict0load.c @@ -1833,6 +1833,8 @@ dict_load_table( const char* err_msg; mtr_t mtr; + DBUG_ENTER("dict_load_table"); + ut_ad(mutex_own(&(dict_sys->mutex))); heap = mem_heap_create(32000); @@ -1866,7 +1868,7 @@ err_exit: mtr_commit(&mtr); mem_heap_free(heap); - return(NULL); + DBUG_RETURN(NULL); } field = rec_get_nth_field_old(rec, 0, &len); @@ -2028,8 +2030,8 @@ err_exit: #endif /* 0 */ func_exit: mem_heap_free(heap); - - return(table); + ut_ad(table == NULL || dict_table_check_foreign_keys(table)); + DBUG_RETURN(table); } /***********************************************************************//** @@ -2271,6 +2273,8 @@ dict_load_foreign( dict_table_t* for_table; dict_table_t* ref_table; + DBUG_ENTER("dict_load_foreign"); + ut_ad(mutex_own(&(dict_sys->mutex))); heap2 = mem_heap_create(1000); @@ -2303,7 +2307,7 @@ dict_load_foreign( mtr_commit(&mtr); mem_heap_free(heap2); - return(DB_ERROR); + DBUG_RETURN(DB_ERROR); } field = rec_get_nth_field_old(rec, 0, &len); @@ -2319,7 +2323,7 @@ dict_load_foreign( mtr_commit(&mtr); mem_heap_free(heap2); - return(DB_ERROR); + DBUG_RETURN(DB_ERROR); } /* Read the table names and the number of columns associated @@ -2416,7 +2420,7 @@ dict_load_foreign( a new foreign key constraint but loading one from the data dictionary. */ - return(dict_foreign_add_to_cache(foreign, check_charsets, ignore_err)); + DBUG_RETURN(dict_foreign_add_to_cache(foreign, check_charsets, ignore_err)); } /***********************************************************************//** @@ -2451,6 +2455,8 @@ dict_load_foreigns( ulint err; mtr_t mtr; + DBUG_ENTER("dict_load_foreigns"); + ut_ad(mutex_own(&(dict_sys->mutex))); sys_foreign = dict_table_get_low("SYS_FOREIGN", DICT_ERR_IGNORE_NONE); @@ -2462,7 +2468,7 @@ dict_load_foreigns( "InnoDB: Error: no foreign key system tables" " in the database\n"); - return(DB_ERROR); + DBUG_RETURN(DB_ERROR); } ut_a(!dict_table_is_comp(sys_foreign)); @@ -2542,7 +2548,7 @@ loop: if (err != DB_SUCCESS) { btr_pcur_close(&pcur); - return(err); + DBUG_RETURN(err); } mtr_start(&mtr); @@ -2571,5 +2577,74 @@ load_next_index: goto start_load; } - return(DB_SUCCESS); + DBUG_RETURN(DB_SUCCESS); +} + +/********************************************************************//** +Check if dict_table_t::foreign_rbt and dict_table::foreign_list +contain the same set of foreign key objects; and check if +dict_table_t::referenced_rbt and dict_table::referenced_list contain +the same set of foreign key objects. +@return TRUE if correct, FALSE otherwise. */ +ibool +dict_table_check_foreign_keys( +/*==========================*/ + const dict_table_t* table) /* in: table object to check */ +{ + dict_foreign_t* foreign; + const ib_rbt_node_t* node; + + ut_ad(mutex_own(&(dict_sys->mutex))); + + if (table->foreign_rbt == NULL) { + + if (UT_LIST_GET_LEN(table->foreign_list) > 0) { + return(FALSE); + } + + } else { + + if (UT_LIST_GET_LEN(table->foreign_list) + != rbt_size(table->foreign_rbt)) { + return(FALSE); + } + + foreign = UT_LIST_GET_FIRST(table->foreign_list); + + while (foreign != NULL) { + + node = rbt_lookup(table->foreign_rbt, foreign->id); + if (node == NULL) { + return(FALSE); + } + foreign = UT_LIST_GET_NEXT(foreign_list, foreign); + } + } + + if (table->referenced_rbt == NULL ) { + + if (UT_LIST_GET_LEN(table->referenced_list) > 0) { + return(FALSE); + } + + } else { + + if (UT_LIST_GET_LEN(table->referenced_list) + != rbt_size(table->referenced_rbt)) { + return(FALSE); + } + + foreign = UT_LIST_GET_FIRST(table->referenced_list); + + while (foreign != NULL) { + + node = rbt_lookup(table->referenced_rbt, foreign->id); + if (node == NULL) { + return(FALSE); + } + foreign = UT_LIST_GET_NEXT(referenced_list, foreign); + } + } + + return(TRUE); } diff --git a/storage/xtradb/dict/dict0mem.c b/storage/xtradb/dict/dict0mem.c index 48ac4d28e24..40099c06823 100644 --- a/storage/xtradb/dict/dict0mem.c +++ b/storage/xtradb/dict/dict0mem.c @@ -66,6 +66,7 @@ dict_mem_table_create( { dict_table_t* table; mem_heap_t* heap; + DBUG_ENTER("dict_mem_table_create"); ut_ad(name); ut_a(!(flags & (~0 << DICT_TF2_BITS))); @@ -100,8 +101,11 @@ dict_mem_table_create( table->is_corrupt = FALSE; #endif /* !UNIV_HOTBACKUP */ + table->foreign_rbt = NULL; + table->referenced_rbt = NULL; + ut_d(table->magic_n = DICT_TABLE_MAGIC_N); - return(table); + DBUG_RETURN(table); } /****************************************************************//** @@ -120,6 +124,15 @@ dict_mem_table_free( #ifndef UNIV_HOTBACKUP mutex_free(&(table->autoinc_mutex)); #endif /* UNIV_HOTBACKUP */ + + if (table->foreign_rbt != NULL) { + rbt_free(table->foreign_rbt); + } + + if (table->referenced_rbt != NULL) { + rbt_free(table->referenced_rbt); + } + ut_free(table->name); mem_heap_free(table->heap); } diff --git a/storage/xtradb/handler/ha_innodb.cc b/storage/xtradb/handler/ha_innodb.cc index 245491a9194..c4f1e6d2b07 100644 --- a/storage/xtradb/handler/ha_innodb.cc +++ b/storage/xtradb/handler/ha_innodb.cc @@ -9166,16 +9166,6 @@ ha_innobase::read_time( return(ranges + (double) rows / (double) total_rows * time_for_scan); } -UNIV_INTERN -bool -ha_innobase::is_corrupt() const -{ - if (share->ib_table) - return ((bool)share->ib_table->is_corrupt); - else - return (FALSE); -} - /*********************************************************************//** Calculates the key number used inside MySQL for an Innobase index. We will first check the "index translation table" for a match of the index to get diff --git a/storage/xtradb/handler/ha_innodb.h b/storage/xtradb/handler/ha_innodb.h index cef5622ba21..39ca89cf6e8 100644 --- a/storage/xtradb/handler/ha_innodb.h +++ b/storage/xtradb/handler/ha_innodb.h @@ -141,7 +141,6 @@ class ha_innobase: public handler double scan_time(); double read_time(uint index, uint ranges, ha_rows rows); my_bool is_fake_change_enabled(THD *thd); - bool is_corrupt() const; int write_row(uchar * buf); int update_row(const uchar * old_data, uchar * new_data); diff --git a/storage/xtradb/handler/i_s.cc b/storage/xtradb/handler/i_s.cc index 4b0c77c4cfb..01e40222c22 100644 --- a/storage/xtradb/handler/i_s.cc +++ b/storage/xtradb/handler/i_s.cc @@ -43,6 +43,7 @@ Created July 18, 2007 Vasil Dimov #include "i_s.h" #include <sql_plugin.h> #include <innodb_priv.h> +#include <debug_sync.h> extern "C" { #include "btr0pcur.h" /* for file sys_tables related info. */ @@ -2665,6 +2666,19 @@ i_s_innodb_buffer_page_fill( table_name = mem_heap_strdup(heap, index->table_name); + DBUG_EXECUTE_IF("mysql_test_print_index_type", + { + char idx_type[3]; + + ut_snprintf(idx_type, + sizeof(idx_type), + "%d", + index->type); + + index_name=mem_heap_strcat(heap, + index_name, + idx_type); + };); } mutex_exit(&dict_sys->mutex); @@ -7384,12 +7398,23 @@ i_s_innodb_changed_pages_fill( limit_lsn_range_from_condition(table, cond, &min_lsn, &max_lsn); } + + /* If the log tracker is running and our max_lsn > current tracked LSN, + cap the max lsn so that we don't try to read any partial runs as the + tracked LSN advances. */ + if (srv_track_changed_pages) { + ib_uint64_t tracked_lsn = log_get_tracked_lsn(); + if (max_lsn > tracked_lsn) + max_lsn = tracked_lsn; + } if (!log_online_bitmap_iterator_init(&i, min_lsn, max_lsn)) { my_error(ER_CANT_FIND_SYSTEM_REC, MYF(0)); DBUG_RETURN(1); } + DEBUG_SYNC(thd, "i_s_innodb_changed_pages_range_ready"); + while(log_online_bitmap_iterator_next(&i) && (!srv_max_changed_pages || output_rows_num < srv_max_changed_pages) && diff --git a/storage/xtradb/include/dict0dict.h b/storage/xtradb/include/dict0dict.h index 8c6620b94b3..8908d7608ad 100644 --- a/storage/xtradb/include/dict0dict.h +++ b/storage/xtradb/include/dict0dict.h @@ -1,6 +1,6 @@ /***************************************************************************** -Copyright (c) 1996, 2013, Oracle and/or its affiliates. All Rights Reserved. +Copyright (c) 1996, 2014, Oracle and/or its affiliates. All Rights Reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -39,6 +39,7 @@ Created 1/8/1996 Heikki Tuuri #include "ut0rnd.h" #include "ut0byte.h" #include "trx0types.h" +#include "ut0rbt.h" #ifndef UNIV_HOTBACKUP # include "sync0sync.h" @@ -1355,6 +1356,42 @@ dict_table_set_corrupt_by_space( ulint space_id, ibool need_mutex); +/**********************************************************************//** +Compares the given foreign key identifier (the key in rb-tree) and the +foreign key identifier in the given fk object (value in rb-tree). +@return negative, 0, or positive if foreign_id is smaller, equal, +or greater than foreign_obj->id, respectively. */ +UNIV_INLINE +int +dict_foreign_rbt_cmp( +/*=================*/ + const void* foreign_id, /*!< in: the foreign key identifier + which is used as a key in rb-tree. */ + const void* foreign_obj); /*!< in: the foreign object itself + which is used as value in rb-tree. */ + +/**********************************************************************//** +Allocate the table->foreign_rbt, which stores all the foreign objects +that is available in table->foreign_list. +@return the allocated rbt object */ +UNIV_INLINE +ib_rbt_t* +dict_table_init_foreign_rbt( +/*========================*/ + dict_table_t* table); /*!< in: the table object whose + table->foreign_rbt will be initialized */ + +/**********************************************************************//** +Allocate the table->referened_rbt, which stores all the foreign objects +that is available in table->referenced_list. +@return the allocated rbt object */ +UNIV_INLINE +ib_rbt_t* +dict_table_init_referenced_rbt( +/*===========================*/ + dict_table_t* table); /*!< in: the table object whose + table->referenced_rbt will be initialized */ + #ifndef UNIV_NONINL #include "dict0dict.ic" #endif diff --git a/storage/xtradb/include/dict0dict.ic b/storage/xtradb/include/dict0dict.ic index 1d2eb34042d..00ae3d0a718 100644 --- a/storage/xtradb/include/dict0dict.ic +++ b/storage/xtradb/include/dict0dict.ic @@ -1,6 +1,6 @@ /***************************************************************************** -Copyright (c) 1996, 2013, Oracle and/or its affiliates. All Rights Reserved. +Copyright (c) 1996, 2014, Oracle and/or its affiliates. All Rights Reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -958,3 +958,62 @@ dict_index_is_corrupted( } #endif /* !UNIV_HOTBACKUP */ +/**********************************************************************//** +Compares the given foreign key identifier (the key in rb-tree) and the +foreign key identifier in the given fk object (value in rb-tree). +@return negative, 0, or positive if foreign_id is smaller, equal, +or greater than foreign_obj->id, respectively. */ +UNIV_INLINE +int +dict_foreign_rbt_cmp( +/*=================*/ + const void* foreign_id, /*!< in: the foreign key identifier + which is used as a key in rb-tree. */ + const void* foreign_obj) /*!< in: the foreign object itself + which is used as value in rb-tree. */ +{ + return(ut_strcmp((const char*) foreign_id, + (*(dict_foreign_t**) foreign_obj)->id)); +} + +/**********************************************************************//** +Allocate the table->foreign_rbt, which stores all the foreign objects +that is available in table->foreign_list. The caller must hold the +dict_sys->mutex. +@return the allocated rbt object */ +UNIV_INLINE +ib_rbt_t* +dict_table_init_foreign_rbt( +/*========================*/ + dict_table_t* table) /*!< in: the table object whose + table->foreign_rbt will be initialized */ +{ + ut_a(table->foreign_rbt == NULL); + ut_ad(mutex_own(&(dict_sys->mutex))); + + table->foreign_rbt = rbt_create(sizeof(dict_foreign_t*), + dict_foreign_rbt_cmp); + ut_a(table->foreign_rbt != NULL); + return(table->foreign_rbt); +} + +/**********************************************************************//** +Allocate the table->referened_rbt, which stores all the foreign objects +that is available in table->referenced_list. The caller must hold the +dict_sys->mutex. +@return the allocated rbt object */ +UNIV_INLINE +ib_rbt_t* +dict_table_init_referenced_rbt( +/*===========================*/ + dict_table_t* table) /*!< in: the table object whose + table->referenced_rbt will be initialized */ +{ + ut_a(table->referenced_rbt == NULL); + ut_ad(mutex_own(&(dict_sys->mutex))); + + table->referenced_rbt = rbt_create(sizeof(dict_foreign_t*), + dict_foreign_rbt_cmp); + ut_a(table->referenced_rbt != NULL); + return(table->referenced_rbt); +} diff --git a/storage/xtradb/include/dict0load.h b/storage/xtradb/include/dict0load.h index 5bb015346ac..dcfa7847a8b 100644 --- a/storage/xtradb/include/dict0load.h +++ b/storage/xtradb/include/dict0load.h @@ -32,6 +32,7 @@ Created 4/24/1996 Heikki Tuuri #include "ut0byte.h" #include "mem0mem.h" #include "btr0types.h" +#include "ut0rbt.h" /** enum that defines all 6 system table IDs */ enum dict_system_table_id { @@ -344,6 +345,17 @@ dict_process_sys_stats_rec( ulint* key_cols, /*!< out: KEY_COLS */ ib_uint64_t* diff_vals, /*!< out: DIFF_VALS */ ib_uint64_t* non_null_vals); /*!< out: NON_NULL_VALS */ +/********************************************************************//** +Check if dict_table_t::foreign_rbt and dict_table::foreign_list +contains the same set of foreign key objects; and check if +dict_table_t::referenced_rbt and dict_table::referenced_list contains +the same set of foreign key objects. +@return TRUE if correct, FALSE otherwise. */ +ibool +dict_table_check_foreign_keys( +/*==========================*/ + const dict_table_t* table); /* in: table object to check */ + #ifndef UNIV_NONINL #include "dict0load.ic" #endif diff --git a/storage/xtradb/include/dict0mem.h b/storage/xtradb/include/dict0mem.h index 717c7532dc9..ba98eed7701 100644 --- a/storage/xtradb/include/dict0mem.h +++ b/storage/xtradb/include/dict0mem.h @@ -1,6 +1,6 @@ /***************************************************************************** -Copyright (c) 1996, 2013, Oracle and/or its affiliates. All Rights Reserved. +Copyright (c) 1996, 2014, Oracle and/or its affiliates. All Rights Reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -43,6 +43,7 @@ Created 1/8/1996 Heikki Tuuri #include "ut0byte.h" #include "hash0hash.h" #include "trx0types.h" +#include "ut0rbt.h" /** Type flags of an index: OR'ing of the flags is allowed to define a combination of types */ @@ -510,7 +511,6 @@ a foreign key constraint is enforced, therefore RESTRICT just means no flag */ #define DICT_FOREIGN_ON_UPDATE_NO_ACTION 32 /*!< ON UPDATE NO ACTION */ /* @} */ - /** Data structure for a database table. Most fields will be initialized to 0, NULL or FALSE in dict_mem_table_create(). */ struct dict_table_struct{ @@ -562,6 +562,14 @@ struct dict_table_struct{ UT_LIST_BASE_NODE_T(dict_foreign_t) referenced_list;/*!< list of foreign key constraints which refer to this table */ + + ib_rbt_t* foreign_rbt; /*!< a rb-tree of all foreign keys + listed in foreign_list, sorted by + foreign->id */ + ib_rbt_t* referenced_rbt; /*!< a rb-tree of all foreign keys + listed in referenced_list, sorted by + foreign->id */ + UT_LIST_NODE_T(dict_table_t) table_LRU; /*!< node of the LRU list of tables */ ulint n_mysql_handles_opened; diff --git a/storage/xtradb/include/log0log.h b/storage/xtradb/include/log0log.h index 450d19e2a57..dffa0d0b4a4 100644 --- a/storage/xtradb/include/log0log.h +++ b/storage/xtradb/include/log0log.h @@ -603,6 +603,18 @@ void log_mem_free(void); /*==============*/ +/****************************************************************//** +Safely reads the log_sys->tracked_lsn value. Uses atomic operations +if available, otherwise this field is protected with the log system +mutex. The writer counterpart function is log_set_tracked_lsn() in +log0online.c. + +@return log_sys->tracked_lsn value. */ +UNIV_INLINE +ib_uint64_t +log_get_tracked_lsn(void); +/*=====================*/ + extern log_t* log_sys; /* Values used as flags */ diff --git a/storage/xtradb/include/log0log.ic b/storage/xtradb/include/log0log.ic index e4218861b66..82f1912c584 100644 --- a/storage/xtradb/include/log0log.ic +++ b/storage/xtradb/include/log0log.ic @@ -479,3 +479,24 @@ log_free_check(void) } } #endif /* !UNIV_HOTBACKUP */ + +/****************************************************************//** +Safely reads the log_sys->tracked_lsn value. Uses atomic operations +if available, otherwise this field is protected with the log system +mutex. The writer counterpart function is log_set_tracked_lsn() in +log0online.c. + +@return log_sys->tracked_lsn value. */ +UNIV_INLINE +ib_uint64_t +log_get_tracked_lsn(void) +/*=====================*/ +{ +#ifdef HAVE_ATOMIC_BUILTINS_64 + return os_atomic_increment_uint64(&log_sys->tracked_lsn, 0); +#else + ut_ad(mutex_own(&(log_sys->mutex))); + return log_sys->tracked_lsn; +#endif +} + diff --git a/storage/xtradb/include/univ.i b/storage/xtradb/include/univ.i index ca5f57808bd..b8c9ea852ec 100644 --- a/storage/xtradb/include/univ.i +++ b/storage/xtradb/include/univ.i @@ -64,10 +64,10 @@ component, i.e. we show M.N.P as M.N */ (INNODB_VERSION_MAJOR << 8 | INNODB_VERSION_MINOR) #ifndef PERCONA_INNODB_VERSION -#define PERCONA_INNODB_VERSION 35.2 +#define PERCONA_INNODB_VERSION 36.0 #endif -#define INNODB_VERSION_STR "5.5.38-MariaDB-" IB_TO_STR(PERCONA_INNODB_VERSION) +#define INNODB_VERSION_STR "5.5.39-MariaDB-" IB_TO_STR(PERCONA_INNODB_VERSION) #define REFMAN "http://dev.mysql.com/doc/refman/" \ IB_TO_STR(MYSQL_MAJOR_VERSION) "." \ diff --git a/storage/xtradb/log/log0log.c b/storage/xtradb/log/log0log.c index 493fa0202f8..ca866ab3036 100644 --- a/storage/xtradb/log/log0log.c +++ b/storage/xtradb/log/log0log.c @@ -223,25 +223,6 @@ log_buf_pool_get_oldest_modification(void) } /****************************************************************//** -Safely reads the log_sys->tracked_lsn value. Uses atomic operations -if available, otherwise this field is protected with the log system -mutex. The writer counterpart function is log_set_tracked_lsn() in -log0online.c. - -@return log_sys->tracked_lsn value. */ -UNIV_INLINE -ib_uint64_t -log_get_tracked_lsn() -{ -#ifdef HAVE_ATOMIC_BUILTINS_64 - return os_atomic_increment_uint64(&log_sys->tracked_lsn, 0); -#else - ut_ad(mutex_own(&(log_sys->mutex))); - return log_sys->tracked_lsn; -#endif -} - -/****************************************************************//** Checks if the log groups have a big enough margin of free space in so that a new log entry can be written without overwriting log data that is not read by the changed page bitmap thread. diff --git a/storage/xtradb/log/log0online.c b/storage/xtradb/log/log0online.c index d195a881348..58f86d1581a 100644 --- a/storage/xtradb/log/log0online.c +++ b/storage/xtradb/log/log0online.c @@ -1202,6 +1202,9 @@ log_online_write_bitmap(void) bmp_tree_node = (ib_rbt_node_t*) rbt_next(log_bmp_sys->modified_pages, bmp_tree_node); + + DBUG_EXECUTE_IF("bitmap_page_2_write_error", + DBUG_SET("+d,bitmap_page_write_error");); } rbt_reset(log_bmp_sys->modified_pages); @@ -1265,6 +1268,7 @@ log_online_follow_redo_log(void) /*********************************************************************//** Diagnose a bitmap file range setup failure and free the partially-initialized bitmap file range. */ +UNIV_COLD static void log_online_diagnose_inconsistent_dir( @@ -1444,26 +1448,30 @@ log_online_setup_bitmap_file_range( return FALSE; } -#ifdef UNIV_DEBUG - if (!bitmap_files->files[0].seq_num) { + if (!bitmap_files->files[0].seq_num + || bitmap_files->files[0].seq_num != first_file_seq_num) { log_online_diagnose_inconsistent_dir(bitmap_files); return FALSE; } - ut_ad(bitmap_files->files[0].seq_num == first_file_seq_num); + { size_t i; for (i = 1; i < bitmap_files->count; i++) { if (!bitmap_files->files[i].seq_num) { break; } - ut_ad(bitmap_files->files[i].seq_num - > bitmap_files->files[i - 1].seq_num); - ut_ad(bitmap_files->files[i].start_lsn - >= bitmap_files->files[i - 1].start_lsn); + if ((bitmap_files->files[i].seq_num + <= bitmap_files->files[i - 1].seq_num) + || (bitmap_files->files[i].start_lsn + < bitmap_files->files[i - 1].start_lsn)) { + + log_online_diagnose_inconsistent_dir( + bitmap_files); + return FALSE; + } } } -#endif return TRUE; } @@ -1590,6 +1598,17 @@ log_online_bitmap_iterator_init( { ut_a(i); + if (UNIV_UNLIKELY(min_lsn > max_lsn)) { + + /* Empty range */ + i->in_files.count = 0; + i->in_files.files = NULL; + i->in.file = os_file_invalid; + i->page = NULL; + i->failed = FALSE; + return TRUE; + } + if (!log_online_setup_bitmap_file_range(&i->in_files, min_lsn, max_lsn)) { |