Commit 014214d0 authored by Sergei Golubchik's avatar Sergei Golubchik

percona-server-5.5.39-36.0

parent a9e8b577
/*****************************************************************************
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);
}
/*****************************************************************************
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;
const ib_rbt_node_t* node;
ut_ad(mutex_own(&(dict_sys->mutex)));
foreign = UT_LIST_GET_FIRST(table->foreign_list);
DBUG_ENTER("dict_foreign_find");
while (foreign) {
if (ut_strcmp(id, foreign->id) == 0) {
ut_ad(mutex_own(&(dict_sys->mutex)));
ut_ad(dict_table_check_foreign_keys(table));
return(foreign);
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 */
......
......@@ -1834,6 +1834,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);
......@@ -1867,7 +1869,7 @@ err_exit:
mtr_commit(&mtr);
mem_heap_free(heap);
return(NULL);
DBUG_RETURN(NULL);
}
field = rec_get_nth_field_old(rec, 0, &len);
......@@ -2029,8 +2031,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);
}
/***********************************************************************//**
......@@ -2255,6 +2257,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);
......@@ -2287,7 +2291,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);
......@@ -2303,7 +2307,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
......@@ -2400,7 +2404,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));
}
/***********************************************************************//**
......@@ -2435,6 +2439,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);
......@@ -2446,7 +2452,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));
......@@ -2526,7 +2532,7 @@ loop:
if (err != DB_SUCCESS) {
btr_pcur_close(&pcur);
return(err);
DBUG_RETURN(err);
}
mtr_start(&mtr);
......@@ -2555,5 +2561,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);
}
......@@ -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);
}
......
......@@ -8995,16 +8995,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
......
......@@ -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);
......
......@@ -42,6 +42,7 @@ Created July 18, 2007 Vasil Dimov
#include "i_s.h"
#include <sql_plugin.h>
#include <mysql/innodb_priv.h>
#include <debug_sync.h>
extern "C" {
#include "btr0pcur.h" /* for file sys_tables related info. */
......@@ -2708,6 +2709,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);
......@@ -7512,11 +7526,22 @@ i_s_innodb_changed_pages_fill(
&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) &&
......
/*****************************************************************************
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
......
/*****************************************************************************
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);
}
......@@ -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
......
/*****************************************************************************
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;
......
......@@ -581,6 +581,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 */
......
......@@ -459,3 +459,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
}
......@@ -64,7 +64,7 @@ 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 MYSQL_SERVER_VERSION
......
......@@ -214,25 +214,6 @@ log_buf_pool_get_oldest_modification(void)
return(lsn);
}
/****************************************************************//**
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
......
......@@ -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)) {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment