Commit f657606d authored by Vadim Tkachenko's avatar Vadim Tkachenko

sync with rev73 extensions

parent 121461f6
...@@ -713,7 +713,8 @@ check_have_atomic_pthread_t: ...@@ -713,7 +713,8 @@ check_have_atomic_pthread_t:
echo '#define HAVE_ATOMIC_PTHREAD_T' > include/ut0auxconf.h ; \ echo '#define HAVE_ATOMIC_PTHREAD_T' > include/ut0auxconf.h ; \
fi fi
all: check_have_atomic_pthread_t all-am # This is temprary fix for http://bugs.mysql.com/43740
all: all-am
.SUFFIXES: .SUFFIXES:
.SUFFIXES: .c .cc .lo .o .obj .SUFFIXES: .c .cc .lo .o .obj
......
...@@ -3202,7 +3202,9 @@ btr_estimate_number_of_different_key_vals( ...@@ -3202,7 +3202,9 @@ btr_estimate_number_of_different_key_vals(
ulint n_cols; ulint n_cols;
ulint matched_fields; ulint matched_fields;
ulint matched_bytes; ulint matched_bytes;
ib_int64_t n_recs = 0;
ib_int64_t* n_diff; ib_int64_t* n_diff;
ib_int64_t* n_not_nulls;
ullint n_sample_pages; /* number of pages to sample */ ullint n_sample_pages; /* number of pages to sample */
ulint not_empty_flag = 0; ulint not_empty_flag = 0;
ulint total_external_size = 0; ulint total_external_size = 0;
...@@ -3215,6 +3217,7 @@ btr_estimate_number_of_different_key_vals( ...@@ -3215,6 +3217,7 @@ btr_estimate_number_of_different_key_vals(
ulint offsets_next_rec_[REC_OFFS_NORMAL_SIZE]; ulint offsets_next_rec_[REC_OFFS_NORMAL_SIZE];
ulint* offsets_rec = offsets_rec_; ulint* offsets_rec = offsets_rec_;
ulint* offsets_next_rec= offsets_next_rec_; ulint* offsets_next_rec= offsets_next_rec_;
ulint stats_method = srv_stats_method;
rec_offs_init(offsets_rec_); rec_offs_init(offsets_rec_);
rec_offs_init(offsets_next_rec_); rec_offs_init(offsets_next_rec_);
...@@ -3222,6 +3225,10 @@ btr_estimate_number_of_different_key_vals( ...@@ -3222,6 +3225,10 @@ btr_estimate_number_of_different_key_vals(
n_diff = mem_zalloc((n_cols + 1) * sizeof(ib_int64_t)); n_diff = mem_zalloc((n_cols + 1) * sizeof(ib_int64_t));
if (stats_method == SRV_STATS_METHOD_IGNORE_NULLS) {
n_not_nulls = mem_zalloc((n_cols + 1) * sizeof(ib_int64_t));
}
/* It makes no sense to test more pages than are contained /* It makes no sense to test more pages than are contained
in the index, thus we lower the number if it is too high */ in the index, thus we lower the number if it is too high */
if (srv_stats_sample_pages > index->stat_index_size) { if (srv_stats_sample_pages > index->stat_index_size) {
...@@ -3260,6 +3267,20 @@ btr_estimate_number_of_different_key_vals( ...@@ -3260,6 +3267,20 @@ btr_estimate_number_of_different_key_vals(
} }
while (rec != supremum) { while (rec != supremum) {
/* count recs */
if (stats_method == SRV_STATS_METHOD_IGNORE_NULLS) {
n_recs++;
for (j = 0; j <= n_cols; j++) {
ulint f_len;
rec_get_nth_field(rec, offsets_rec,
j, &f_len);
if (f_len == UNIV_SQL_NULL)
break;
n_not_nulls[j]++;
}
}
rec_t* next_rec = page_rec_get_next(rec); rec_t* next_rec = page_rec_get_next(rec);
if (next_rec == supremum) { if (next_rec == supremum) {
break; break;
...@@ -3274,7 +3295,7 @@ btr_estimate_number_of_different_key_vals( ...@@ -3274,7 +3295,7 @@ btr_estimate_number_of_different_key_vals(
cmp_rec_rec_with_match(rec, next_rec, cmp_rec_rec_with_match(rec, next_rec,
offsets_rec, offsets_next_rec, offsets_rec, offsets_next_rec,
index, &matched_fields, index, &matched_fields,
&matched_bytes); &matched_bytes, srv_stats_method);
for (j = matched_fields + 1; j <= n_cols; j++) { for (j = matched_fields + 1; j <= n_cols; j++) {
/* We add one if this index record has /* We add one if this index record has
...@@ -3359,9 +3380,21 @@ btr_estimate_number_of_different_key_vals( ...@@ -3359,9 +3380,21 @@ btr_estimate_number_of_different_key_vals(
} }
index->stat_n_diff_key_vals[j] += add_on; index->stat_n_diff_key_vals[j] += add_on;
/* revision for 'nulls_ignored' */
if (stats_method == SRV_STATS_METHOD_IGNORE_NULLS) {
if (!n_not_nulls[j])
n_not_nulls[j] = 1;
index->stat_n_diff_key_vals[j] =
index->stat_n_diff_key_vals[j] * n_recs
/ n_not_nulls[j];
}
} }
mem_free(n_diff); mem_free(n_diff);
if (stats_method == SRV_STATS_METHOD_IGNORE_NULLS) {
mem_free(n_not_nulls);
}
if (UNIV_LIKELY_NULL(heap)) { if (UNIV_LIKELY_NULL(heap)) {
mem_heap_free(heap); mem_heap_free(heap);
} }
...@@ -3733,7 +3766,8 @@ btr_blob_free( ...@@ -3733,7 +3766,8 @@ btr_blob_free(
mtr_commit(mtr); mtr_commit(mtr);
buf_pool_mutex_enter(); //buf_pool_mutex_enter();
mutex_enter(&LRU_list_mutex);
mutex_enter(&block->mutex); mutex_enter(&block->mutex);
/* Only free the block if it is still allocated to /* Only free the block if it is still allocated to
...@@ -3744,17 +3778,22 @@ btr_blob_free( ...@@ -3744,17 +3778,22 @@ btr_blob_free(
&& buf_block_get_space(block) == space && buf_block_get_space(block) == space
&& buf_block_get_page_no(block) == page_no) { && buf_block_get_page_no(block) == page_no) {
if (buf_LRU_free_block(&block->page, all, NULL) if (buf_LRU_free_block(&block->page, all, NULL, TRUE)
!= BUF_LRU_FREED != BUF_LRU_FREED
&& all && block->page.zip.data) { && all && block->page.zip.data
/* Now, buf_LRU_free_block() may release mutex temporarily */
&& buf_block_get_state(block) == BUF_BLOCK_FILE_PAGE
&& buf_block_get_space(block) == space
&& buf_block_get_page_no(block) == page_no) {
/* Attempt to deallocate the uncompressed page /* Attempt to deallocate the uncompressed page
if the whole block cannot be deallocted. */ if the whole block cannot be deallocted. */
buf_LRU_free_block(&block->page, FALSE, NULL); buf_LRU_free_block(&block->page, FALSE, NULL, TRUE);
} }
} }
buf_pool_mutex_exit(); //buf_pool_mutex_exit();
mutex_exit(&LRU_list_mutex);
mutex_exit(&block->mutex); mutex_exit(&block->mutex);
} }
......
...@@ -1731,7 +1731,8 @@ btr_search_validate(void) ...@@ -1731,7 +1731,8 @@ btr_search_validate(void)
rec_offs_init(offsets_); rec_offs_init(offsets_);
rw_lock_x_lock(&btr_search_latch); rw_lock_x_lock(&btr_search_latch);
buf_pool_mutex_enter(); //buf_pool_mutex_enter();
rw_lock_x_lock(&page_hash_latch);
cell_count = hash_get_n_cells(btr_search_sys->hash_index); cell_count = hash_get_n_cells(btr_search_sys->hash_index);
...@@ -1739,11 +1740,13 @@ btr_search_validate(void) ...@@ -1739,11 +1740,13 @@ btr_search_validate(void)
/* We release btr_search_latch every once in a while to /* We release btr_search_latch every once in a while to
give other queries a chance to run. */ give other queries a chance to run. */
if ((i != 0) && ((i % chunk_size) == 0)) { if ((i != 0) && ((i % chunk_size) == 0)) {
buf_pool_mutex_exit(); //buf_pool_mutex_exit();
rw_lock_x_unlock(&page_hash_latch);
rw_lock_x_unlock(&btr_search_latch); rw_lock_x_unlock(&btr_search_latch);
os_thread_yield(); os_thread_yield();
rw_lock_x_lock(&btr_search_latch); rw_lock_x_lock(&btr_search_latch);
buf_pool_mutex_enter(); //buf_pool_mutex_enter();
rw_lock_x_lock(&page_hash_latch);
} }
node = hash_get_nth_cell(btr_search_sys->hash_index, i)->node; node = hash_get_nth_cell(btr_search_sys->hash_index, i)->node;
...@@ -1850,11 +1853,13 @@ btr_search_validate(void) ...@@ -1850,11 +1853,13 @@ btr_search_validate(void)
/* We release btr_search_latch every once in a while to /* We release btr_search_latch every once in a while to
give other queries a chance to run. */ give other queries a chance to run. */
if (i != 0) { if (i != 0) {
buf_pool_mutex_exit(); //buf_pool_mutex_exit();
rw_lock_x_unlock(&page_hash_latch);
rw_lock_x_unlock(&btr_search_latch); rw_lock_x_unlock(&btr_search_latch);
os_thread_yield(); os_thread_yield();
rw_lock_x_lock(&btr_search_latch); rw_lock_x_lock(&btr_search_latch);
buf_pool_mutex_enter(); //buf_pool_mutex_enter();
rw_lock_x_lock(&page_hash_latch);
} }
if (!ha_validate(btr_search_sys->hash_index, i, end_index)) { if (!ha_validate(btr_search_sys->hash_index, i, end_index)) {
...@@ -1862,7 +1867,8 @@ btr_search_validate(void) ...@@ -1862,7 +1867,8 @@ btr_search_validate(void)
} }
} }
buf_pool_mutex_exit(); //buf_pool_mutex_exit();
rw_lock_x_unlock(&page_hash_latch);
rw_lock_x_unlock(&btr_search_latch); rw_lock_x_unlock(&btr_search_latch);
if (UNIV_LIKELY_NULL(heap)) { if (UNIV_LIKELY_NULL(heap)) {
mem_heap_free(heap); mem_heap_free(heap);
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
...@@ -246,18 +246,22 @@ buf_read_ahead_random( ...@@ -246,18 +246,22 @@ buf_read_ahead_random(
LRU_recent_limit = buf_LRU_get_recent_limit(); LRU_recent_limit = buf_LRU_get_recent_limit();
buf_pool_mutex_enter(); //buf_pool_mutex_enter();
mutex_enter(&buf_pool_mutex);
if (buf_pool->n_pend_reads if (buf_pool->n_pend_reads
> buf_pool->curr_size / BUF_READ_AHEAD_PEND_LIMIT) { > buf_pool->curr_size / BUF_READ_AHEAD_PEND_LIMIT) {
buf_pool_mutex_exit(); //buf_pool_mutex_exit();
mutex_exit(&buf_pool_mutex);
return(0); return(0);
} }
mutex_exit(&buf_pool_mutex);
/* Count how many blocks in the area have been recently accessed, /* Count how many blocks in the area have been recently accessed,
that is, reside near the start of the LRU list. */ that is, reside near the start of the LRU list. */
rw_lock_s_lock(&page_hash_latch);
for (i = low; i < high; i++) { for (i = low; i < high; i++) {
const buf_page_t* bpage = buf_page_hash_get(space, i); const buf_page_t* bpage = buf_page_hash_get(space, i);
...@@ -269,13 +273,15 @@ buf_read_ahead_random( ...@@ -269,13 +273,15 @@ buf_read_ahead_random(
if (recent_blocks >= BUF_READ_AHEAD_RANDOM_THRESHOLD) { if (recent_blocks >= BUF_READ_AHEAD_RANDOM_THRESHOLD) {
buf_pool_mutex_exit(); //buf_pool_mutex_exit();
rw_lock_s_unlock(&page_hash_latch);
goto read_ahead; goto read_ahead;
} }
} }
} }
buf_pool_mutex_exit(); //buf_pool_mutex_exit();
rw_lock_s_unlock(&page_hash_latch);
/* Do nothing */ /* Do nothing */
return(0); return(0);
...@@ -469,10 +475,12 @@ buf_read_ahead_linear( ...@@ -469,10 +475,12 @@ buf_read_ahead_linear(
tablespace_version = fil_space_get_version(space); tablespace_version = fil_space_get_version(space);
buf_pool_mutex_enter(); //buf_pool_mutex_enter();
mutex_enter(&buf_pool_mutex);
if (high > fil_space_get_size(space)) { if (high > fil_space_get_size(space)) {
buf_pool_mutex_exit(); //buf_pool_mutex_exit();
mutex_exit(&buf_pool_mutex);
/* The area is not whole, return */ /* The area is not whole, return */
return(0); return(0);
...@@ -480,10 +488,12 @@ buf_read_ahead_linear( ...@@ -480,10 +488,12 @@ buf_read_ahead_linear(
if (buf_pool->n_pend_reads if (buf_pool->n_pend_reads
> buf_pool->curr_size / BUF_READ_AHEAD_PEND_LIMIT) { > buf_pool->curr_size / BUF_READ_AHEAD_PEND_LIMIT) {
buf_pool_mutex_exit(); //buf_pool_mutex_exit();
mutex_exit(&buf_pool_mutex);
return(0); return(0);
} }
mutex_exit(&buf_pool_mutex);
/* Check that almost all pages in the area have been accessed; if /* Check that almost all pages in the area have been accessed; if
offset == low, the accesses must be in a descending order, otherwise, offset == low, the accesses must be in a descending order, otherwise,
...@@ -497,6 +507,7 @@ buf_read_ahead_linear( ...@@ -497,6 +507,7 @@ buf_read_ahead_linear(
fail_count = 0; fail_count = 0;
rw_lock_s_lock(&page_hash_latch);
for (i = low; i < high; i++) { for (i = low; i < high; i++) {
bpage = buf_page_hash_get(space, i); bpage = buf_page_hash_get(space, i);
...@@ -520,7 +531,8 @@ buf_read_ahead_linear( ...@@ -520,7 +531,8 @@ buf_read_ahead_linear(
* LINEAR_AREA_THRESHOLD_COEF) { * LINEAR_AREA_THRESHOLD_COEF) {
/* Too many failures: return */ /* Too many failures: return */
buf_pool_mutex_exit(); //buf_pool_mutex_exit();
rw_lock_s_unlock(&page_hash_latch);
return(0); return(0);
} }
...@@ -531,7 +543,8 @@ buf_read_ahead_linear( ...@@ -531,7 +543,8 @@ buf_read_ahead_linear(
bpage = buf_page_hash_get(space, offset); bpage = buf_page_hash_get(space, offset);
if (bpage == NULL) { if (bpage == NULL) {
buf_pool_mutex_exit(); //buf_pool_mutex_exit();
rw_lock_s_unlock(&page_hash_latch);
return(0); return(0);
} }
...@@ -557,7 +570,8 @@ buf_read_ahead_linear( ...@@ -557,7 +570,8 @@ buf_read_ahead_linear(
pred_offset = fil_page_get_prev(frame); pred_offset = fil_page_get_prev(frame);
succ_offset = fil_page_get_next(frame); succ_offset = fil_page_get_next(frame);
buf_pool_mutex_exit(); //buf_pool_mutex_exit();
rw_lock_s_unlock(&page_hash_latch);
if ((offset == low) && (succ_offset == offset + 1)) { if ((offset == low) && (succ_offset == offset + 1)) {
......
...@@ -265,6 +265,7 @@ dict_boot(void) ...@@ -265,6 +265,7 @@ dict_boot(void)
system tables */ system tables */
/*-------------------------*/ /*-------------------------*/
table = dict_mem_table_create("SYS_TABLES", DICT_HDR_SPACE, 8, 0); table = dict_mem_table_create("SYS_TABLES", DICT_HDR_SPACE, 8, 0);
table->n_mysql_handles_opened = 1; /* for pin */
dict_mem_table_add_col(table, heap, "NAME", DATA_BINARY, 0, 0); dict_mem_table_add_col(table, heap, "NAME", DATA_BINARY, 0, 0);
dict_mem_table_add_col(table, heap, "ID", DATA_BINARY, 0, 0); dict_mem_table_add_col(table, heap, "ID", DATA_BINARY, 0, 0);
...@@ -314,6 +315,7 @@ dict_boot(void) ...@@ -314,6 +315,7 @@ dict_boot(void)
/*-------------------------*/ /*-------------------------*/
table = dict_mem_table_create("SYS_COLUMNS", DICT_HDR_SPACE, 7, 0); table = dict_mem_table_create("SYS_COLUMNS", DICT_HDR_SPACE, 7, 0);
table->n_mysql_handles_opened = 1; /* for pin */
dict_mem_table_add_col(table, heap, "TABLE_ID", DATA_BINARY, 0, 0); dict_mem_table_add_col(table, heap, "TABLE_ID", DATA_BINARY, 0, 0);
dict_mem_table_add_col(table, heap, "POS", DATA_INT, 0, 4); dict_mem_table_add_col(table, heap, "POS", DATA_INT, 0, 4);
...@@ -346,6 +348,7 @@ dict_boot(void) ...@@ -346,6 +348,7 @@ dict_boot(void)
/*-------------------------*/ /*-------------------------*/
table = dict_mem_table_create("SYS_INDEXES", DICT_HDR_SPACE, 7, 0); table = dict_mem_table_create("SYS_INDEXES", DICT_HDR_SPACE, 7, 0);
table->n_mysql_handles_opened = 1; /* for pin */
dict_mem_table_add_col(table, heap, "TABLE_ID", DATA_BINARY, 0, 0); dict_mem_table_add_col(table, heap, "TABLE_ID", DATA_BINARY, 0, 0);
dict_mem_table_add_col(table, heap, "ID", DATA_BINARY, 0, 0); dict_mem_table_add_col(table, heap, "ID", DATA_BINARY, 0, 0);
...@@ -388,6 +391,7 @@ dict_boot(void) ...@@ -388,6 +391,7 @@ dict_boot(void)
/*-------------------------*/ /*-------------------------*/
table = dict_mem_table_create("SYS_FIELDS", DICT_HDR_SPACE, 3, 0); table = dict_mem_table_create("SYS_FIELDS", DICT_HDR_SPACE, 3, 0);
table->n_mysql_handles_opened = 1; /* for pin */
dict_mem_table_add_col(table, heap, "INDEX_ID", DATA_BINARY, 0, 0); dict_mem_table_add_col(table, heap, "INDEX_ID", DATA_BINARY, 0, 0);
dict_mem_table_add_col(table, heap, "POS", DATA_INT, 0, 4); dict_mem_table_add_col(table, heap, "POS", DATA_INT, 0, 4);
......
...@@ -1184,6 +1184,9 @@ dict_create_or_check_foreign_constraint_tables(void) ...@@ -1184,6 +1184,9 @@ dict_create_or_check_foreign_constraint_tables(void)
/* Foreign constraint system tables have already been /* Foreign constraint system tables have already been
created, and they are ok */ created, and they are ok */
table1->n_mysql_handles_opened = 1; /* for pin */
table2->n_mysql_handles_opened = 1; /* for pin */
mutex_exit(&(dict_sys->mutex)); mutex_exit(&(dict_sys->mutex));
return(DB_SUCCESS); return(DB_SUCCESS);
...@@ -1265,6 +1268,11 @@ dict_create_or_check_foreign_constraint_tables(void) ...@@ -1265,6 +1268,11 @@ dict_create_or_check_foreign_constraint_tables(void)
trx_commit_for_mysql(trx); trx_commit_for_mysql(trx);
table1 = dict_table_get_low("SYS_FOREIGN");
table2 = dict_table_get_low("SYS_FOREIGN_COLS");
table1->n_mysql_handles_opened = 1; /* for pin */
table2->n_mysql_handles_opened = 1; /* for pin */
row_mysql_unlock_data_dictionary(trx); row_mysql_unlock_data_dictionary(trx);
trx_free_for_mysql(trx); trx_free_for_mysql(trx);
......
...@@ -545,6 +545,8 @@ dict_table_get_on_id( ...@@ -545,6 +545,8 @@ dict_table_get_on_id(
table = dict_table_get_on_id_low(table_id); table = dict_table_get_on_id_low(table_id);
dict_table_LRU_trim(table);
mutex_exit(&(dict_sys->mutex)); mutex_exit(&(dict_sys->mutex));
return(table); return(table);
...@@ -659,6 +661,8 @@ dict_table_get( ...@@ -659,6 +661,8 @@ dict_table_get(
table->n_mysql_handles_opened++; table->n_mysql_handles_opened++;
} }
dict_table_LRU_trim(table);
mutex_exit(&(dict_sys->mutex)); mutex_exit(&(dict_sys->mutex));
if (table != NULL) { if (table != NULL) {
...@@ -1153,6 +1157,64 @@ dict_table_remove_from_cache( ...@@ -1153,6 +1157,64 @@ dict_table_remove_from_cache(
dict_mem_table_free(table); dict_mem_table_free(table);
} }
/**************************************************************************
Frees tables from the end of table_LRU if the dictionary cache occupies
too much space. */
UNIV_INTERN
void
dict_table_LRU_trim(
/*================*/
dict_table_t* self)
{
dict_table_t* table;
dict_table_t* prev_table;
dict_foreign_t* foreign;
ulint n_removed;
ulint n_have_parent;
ulint cached_foreign_tables;
#ifdef UNIV_SYNC_DEBUG
ut_ad(mutex_own(&(dict_sys->mutex)));
#endif /* UNIV_SYNC_DEBUG */
retry:
n_removed = n_have_parent = 0;
table = UT_LIST_GET_LAST(dict_sys->table_LRU);
while ( srv_dict_size_limit && table
&& ((dict_sys->table_hash->n_cells
+ dict_sys->table_id_hash->n_cells) * sizeof(hash_cell_t)
+ dict_sys->size) > srv_dict_size_limit ) {
prev_table = UT_LIST_GET_PREV(table_LRU, table);
if (table == self || table->n_mysql_handles_opened)
goto next_loop;
cached_foreign_tables = 0;
foreign = UT_LIST_GET_FIRST(table->foreign_list);
while (foreign != NULL) {
if (foreign->referenced_table)
cached_foreign_tables++;
foreign = UT_LIST_GET_NEXT(foreign_list, foreign);
}
if (cached_foreign_tables == 0) {
dict_table_remove_from_cache(table);
n_removed++;
} else {
n_have_parent++;
}
next_loop:
table = prev_table;
}
if ( srv_dict_size_limit && n_have_parent && n_removed
&& ((dict_sys->table_hash->n_cells
+ dict_sys->table_id_hash->n_cells) * sizeof(hash_cell_t)
+ dict_sys->size) > srv_dict_size_limit )
goto retry;
}
/******************************************************************** /********************************************************************
If the given column name is reserved for InnoDB system columns, return If the given column name is reserved for InnoDB system columns, return
TRUE. */ TRUE. */
...@@ -4276,7 +4338,8 @@ dict_table_print_low( ...@@ -4276,7 +4338,8 @@ dict_table_print_low(
ut_ad(mutex_own(&(dict_sys->mutex))); ut_ad(mutex_own(&(dict_sys->mutex)));
dict_update_statistics_low(table, TRUE); if (srv_stats_auto_update)
dict_update_statistics_low(table, TRUE);
fprintf(stderr, fprintf(stderr,
"--------------------------------------\n" "--------------------------------------\n"
......
...@@ -223,7 +223,7 @@ dict_print(void) ...@@ -223,7 +223,7 @@ dict_print(void)
/* The table definition was corrupt if there /* The table definition was corrupt if there
is no index */ is no index */
if (dict_table_get_first_index(table)) { if (srv_stats_auto_update && dict_table_get_first_index(table)) {
dict_update_statistics_low(table, TRUE); dict_update_statistics_low(table, TRUE);
} }
......
...@@ -42,6 +42,10 @@ Created 10/25/1995 Heikki Tuuri ...@@ -42,6 +42,10 @@ Created 10/25/1995 Heikki Tuuri
#include "mtr0log.h" #include "mtr0log.h"
#include "dict0dict.h" #include "dict0dict.h"
#include "page0zip.h" #include "page0zip.h"
#include "trx0trx.h"
#include "trx0sys.h"
#include "pars0pars.h"
#include "row0mysql.h"
/* /*
...@@ -2977,7 +2981,7 @@ fil_open_single_table_tablespace( ...@@ -2977,7 +2981,7 @@ fil_open_single_table_tablespace(
ut_a(flags != DICT_TF_COMPACT); ut_a(flags != DICT_TF_COMPACT);
file = os_file_create_simple_no_error_handling( file = os_file_create_simple_no_error_handling(
filepath, OS_FILE_OPEN, OS_FILE_READ_ONLY, &success); filepath, OS_FILE_OPEN, OS_FILE_READ_WRITE, &success);
if (!success) { if (!success) {
/* The following call prints an error message */ /* The following call prints an error message */
os_file_get_last_error(TRUE); os_file_get_last_error(TRUE);
...@@ -3025,6 +3029,275 @@ fil_open_single_table_tablespace( ...@@ -3025,6 +3029,275 @@ fil_open_single_table_tablespace(
space_id = fsp_header_get_space_id(page); space_id = fsp_header_get_space_id(page);
space_flags = fsp_header_get_flags(page); space_flags = fsp_header_get_flags(page);
if (srv_expand_import && (space_id != id || space_flags != flags)) {
dulint old_id[31];
dulint new_id[31];
ulint root_page[31];
ulint n_index;
os_file_t info_file = -1;
char* info_file_path;
ulint i;
int len;
ib_uint64_t current_lsn;
current_lsn = log_get_lsn();
/* overwrite fsp header */
fsp_header_init_fields(page, id, flags);
mach_write_to_4(page + FIL_PAGE_ARCH_LOG_NO_OR_SPACE_ID, id);
space_id = id;
space_flags = flags;
if (mach_read_ull(page + FIL_PAGE_FILE_FLUSH_LSN) > current_lsn)
mach_write_ull(page + FIL_PAGE_FILE_FLUSH_LSN, current_lsn);
mach_write_to_4(page + FIL_PAGE_SPACE_OR_CHKSUM,
srv_use_checksums
? buf_calc_page_new_checksum(page)
: BUF_NO_CHECKSUM_MAGIC);
mach_write_to_4(page + UNIV_PAGE_SIZE - FIL_PAGE_END_LSN_OLD_CHKSUM,
srv_use_checksums
? buf_calc_page_old_checksum(page)
: BUF_NO_CHECKSUM_MAGIC);
success = os_file_write(filepath, file, page, 0, 0, UNIV_PAGE_SIZE);
/* get file size */
ulint size_low, size_high, size;
ib_int64_t size_bytes;
os_file_get_size(file, &size_low, &size_high);
size_bytes = (((ib_int64_t)size_high) << 32)
+ (ib_int64_t)size_low;
/* get cruster index information */
dict_table_t* table;
dict_index_t* index;
table = dict_table_get_low(name);
index = dict_table_get_first_index(table);
ut_a(index->page==3);
/* read metadata from .exp file */
n_index = 0;
bzero(old_id, sizeof(old_id));
bzero(new_id, sizeof(new_id));
bzero(root_page, sizeof(root_page));
info_file_path = fil_make_ibd_name(name, FALSE);
len = strlen(info_file_path);
info_file_path[len - 3] = 'e';
info_file_path[len - 2] = 'x';
info_file_path[len - 1] = 'p';
info_file = os_file_create_simple_no_error_handling(
info_file_path, OS_FILE_OPEN, OS_FILE_READ_ONLY, &success);
if (!success) {
fprintf(stderr, "InnoDB: cannot open %s\n", info_file_path);
goto skip_info;
}
success = os_file_read(info_file, page, 0, 0, UNIV_PAGE_SIZE);
if (!success) {
fprintf(stderr, "InnoDB: cannot read %s\n", info_file_path);
goto skip_info;
}
if (mach_read_from_4(page) != 0x78706f72UL
|| mach_read_from_4(page + 4) != 0x74696e66UL) {
fprintf(stderr, "InnoDB: %s seems not to be a correct .exp file\n", info_file_path);
goto skip_info;
}
fprintf(stderr, "InnoDB: import: extended import of %s is started.\n", name);
n_index = mach_read_from_4(page + 8);
fprintf(stderr, "InnoDB: import: %lu indexes are detected.\n", (ulong)n_index);
for (i = 0; i < n_index; i++) {
new_id[i] =
dict_table_get_index_on_name(table,
(page + (i + 1) * 512 + 12))->id;
old_id[i] = mach_read_from_8(page + (i + 1) * 512);
root_page[i] = mach_read_from_4(page + (i + 1) * 512 + 8);
}
skip_info:
if (info_file != -1)
os_file_close(info_file);
/*
if (size_bytes >= 1024 * 1024) {
size_bytes = ut_2pow_round(size_bytes, 1024 * 1024);
}
*/
if (!(flags & DICT_TF_ZSSIZE_MASK)) {
mem_heap_t* heap = NULL;
ulint offsets_[REC_OFFS_NORMAL_SIZE];
ulint* offsets = offsets_;
size = (ulint) (size_bytes / UNIV_PAGE_SIZE);
/* over write space id of all pages */
ib_int64_t offset;
rec_offs_init(offsets_);
fprintf(stderr, "InnoDB: Progress in %:");
for (offset = 0; offset < size_bytes; offset += UNIV_PAGE_SIZE) {
success = os_file_read(file, page,
(ulint)(offset & 0xFFFFFFFFUL),
(ulint)(offset >> 32), UNIV_PAGE_SIZE);
if (mach_read_from_4(page + FIL_PAGE_OFFSET) || !offset) {
mach_write_to_4(page + FIL_PAGE_ARCH_LOG_NO_OR_SPACE_ID, id);
for (i = 0; i < n_index; i++) {
if (offset / UNIV_PAGE_SIZE == root_page[i]) {
/* this is index root page */
mach_write_to_4(page + FIL_PAGE_DATA + PAGE_BTR_SEG_LEAF
+ FSEG_HDR_SPACE, id);
mach_write_to_4(page + FIL_PAGE_DATA + PAGE_BTR_SEG_TOP
+ FSEG_HDR_SPACE, id);
break;
}
}
if (fil_page_get_type(page) == FIL_PAGE_INDEX) {
dulint tmp = mach_read_from_8(page + (PAGE_HEADER + PAGE_INDEX_ID));
if (mach_read_from_2(page + PAGE_HEADER + PAGE_LEVEL) == 0
&& ut_dulint_cmp(old_id[0], tmp) == 0) {
/* leaf page of cluster index, reset trx_id of records */
rec_t* rec;
rec_t* supremum;
ulint n_recs;
supremum = page_get_supremum_rec(page);
rec = page_rec_get_next(page_get_infimum_rec(page));
n_recs = page_get_n_recs(page);
while (rec && rec != supremum && n_recs > 0) {
ulint offset = index->trx_id_offset;
if (!offset) {
offsets = rec_get_offsets(rec, index, offsets,
ULINT_UNDEFINED, &heap);
offset = row_get_trx_id_offset(rec, index, offsets);
}
trx_write_trx_id(rec + offset, ut_dulint_create(0, 1));
rec = page_rec_get_next(rec);
n_recs--;
}
}
for (i = 0; i < n_index; i++) {
if (ut_dulint_cmp(old_id[i], tmp) == 0) {
mach_write_to_8(page + (PAGE_HEADER + PAGE_INDEX_ID), new_id[i]);
break;
}
}
}
if (mach_read_ull(page + FIL_PAGE_LSN) > current_lsn) {
mach_write_ull(page + FIL_PAGE_LSN, current_lsn);
mach_write_ull(page + UNIV_PAGE_SIZE - FIL_PAGE_END_LSN_OLD_CHKSUM,
current_lsn);
}
mach_write_to_4(page + FIL_PAGE_SPACE_OR_CHKSUM,
srv_use_checksums
? buf_calc_page_new_checksum(page)
: BUF_NO_CHECKSUM_MAGIC);
mach_write_to_4(page + UNIV_PAGE_SIZE - FIL_PAGE_END_LSN_OLD_CHKSUM,
srv_use_checksums
? buf_calc_page_old_checksum(page)
: BUF_NO_CHECKSUM_MAGIC);
success = os_file_write(filepath, file, page,
(ulint)(offset & 0xFFFFFFFFUL),
(ulint)(offset >> 32), UNIV_PAGE_SIZE);
}
if (size_bytes
&& ((ib_int64_t)((offset + UNIV_PAGE_SIZE) * 100) / size_bytes)
!= ((offset * 100) / size_bytes)) {
fprintf(stderr, " %lu",
(ulong)((ib_int64_t)((offset + UNIV_PAGE_SIZE) * 100) / size_bytes));
}
}
fprintf(stderr, " done.\n");
/* update SYS_INDEXES set root page */
index = dict_table_get_first_index(table);
while (index) {
for (i = 0; i < n_index; i++) {
if (ut_dulint_cmp(new_id[i], index->id) == 0) {
break;
}
}
if (i != n_index
&& root_page[i] != index->page) {
/* must update */
ulint error;
trx_t* trx;
pars_info_t* info = NULL;
trx = trx_allocate_for_mysql();
trx->op_info = "extended import";
info = pars_info_create();
pars_info_add_dulint_literal(info, "indexid", new_id[i]);
pars_info_add_int4_literal(info, "new_page", (lint) root_page[i]);
error = que_eval_sql(info,
"PROCEDURE UPDATE_INDEX_PAGE () IS\n"
"BEGIN\n"
"UPDATE SYS_INDEXES"
" SET PAGE_NO = :new_page"
" WHERE ID = :indexid;\n"
"COMMIT WORK;\n"
"END;\n",
FALSE, trx);
if (error != DB_SUCCESS) {
fprintf(stderr, "InnoDB: failed to update SYS_INDEXES\n");
}
trx_commit_for_mysql(trx);
trx_free_for_mysql(trx);
index->page = root_page[i];
}
index = dict_table_get_next_index(index);
}
if (UNIV_LIKELY_NULL(heap)) {
mem_heap_free(heap);
}
} else {
/* zip page? */
size = (ulint)
(size_bytes
/ dict_table_flags_to_zip_size(flags));
fprintf(stderr, "InnoDB: import: table %s seems to be in newer format."
" It may not be able to treated for now.\n", name);
}
/* .exp file should be removed */
success = os_file_delete(info_file_path);
if (!success) {
success = os_file_delete_if_exists(info_file_path);
}
mem_free(info_file_path);
fil_system_t* system = fil_system;
mutex_enter(&(system->mutex));
fil_node_t* node = NULL;
fil_space_t* space;
space = fil_space_get_by_id(id);
if (space)
node = UT_LIST_GET_FIRST(space->chain);
if (node && node->size < size) {
space->size += (size - node->size);
node->size = size;
}
mutex_exit(&(system->mutex));
}
ut_free(buf2); ut_free(buf2);
if (UNIV_UNLIKELY(space_id != id || space_flags != flags)) { if (UNIV_UNLIKELY(space_id != id || space_flags != flags)) {
......
This diff is collapsed.
...@@ -45,6 +45,7 @@ extern "C" { ...@@ -45,6 +45,7 @@ extern "C" {
#include "dict0dict.h" /* for dict_index_get_if_in_cache */ #include "dict0dict.h" /* for dict_index_get_if_in_cache */
#include "trx0rseg.h" /* for trx_rseg_struct */ #include "trx0rseg.h" /* for trx_rseg_struct */
#include "trx0sys.h" /* for trx_sys */ #include "trx0sys.h" /* for trx_sys */
#include "dict0dict.h" /* for dict_sys */
/* from buf0buf.c */ /* from buf0buf.c */
struct buf_chunk_struct{ struct buf_chunk_struct{
ulint mem_size; /* allocated size of the chunk */ ulint mem_size; /* allocated size of the chunk */
...@@ -2282,7 +2283,8 @@ i_s_cmpmem_fill_low( ...@@ -2282,7 +2283,8 @@ i_s_cmpmem_fill_low(
RETURN_IF_INNODB_NOT_STARTED(tables->schema_table_name); RETURN_IF_INNODB_NOT_STARTED(tables->schema_table_name);
buf_pool_mutex_enter(); //buf_pool_mutex_enter();
mutex_enter(&zip_free_mutex);
for (uint x = 0; x <= BUF_BUDDY_SIZES; x++) { for (uint x = 0; x <= BUF_BUDDY_SIZES; x++) {
buf_buddy_stat_t* buddy_stat = &buf_buddy_stat[x]; buf_buddy_stat_t* buddy_stat = &buf_buddy_stat[x];
...@@ -2308,7 +2310,8 @@ i_s_cmpmem_fill_low( ...@@ -2308,7 +2310,8 @@ i_s_cmpmem_fill_low(
} }
} }
buf_pool_mutex_exit(); //buf_pool_mutex_exit();
mutex_exit(&zip_free_mutex);
DBUG_RETURN(status); DBUG_RETURN(status);
} }
...@@ -2653,3 +2656,299 @@ UNIV_INTERN struct st_mysql_plugin i_s_innodb_rseg = ...@@ -2653,3 +2656,299 @@ UNIV_INTERN struct st_mysql_plugin i_s_innodb_rseg =
/* void* */ /* void* */
STRUCT_FLD(__reserved1, NULL) STRUCT_FLD(__reserved1, NULL)
}; };
/***********************************************************************
*/
static ST_FIELD_INFO i_s_innodb_table_stats_info[] =
{
{STRUCT_FLD(field_name, "table_name"),
STRUCT_FLD(field_length, NAME_LEN),
STRUCT_FLD(field_type, MYSQL_TYPE_STRING),
STRUCT_FLD(value, 0),
STRUCT_FLD(field_flags, 0),
STRUCT_FLD(old_name, ""),
STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
{STRUCT_FLD(field_name, "rows"),
STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS),
STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG),
STRUCT_FLD(value, 0),
STRUCT_FLD(field_flags, MY_I_S_UNSIGNED),
STRUCT_FLD(old_name, ""),
STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
{STRUCT_FLD(field_name, "clust_size"),
STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS),
STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG),
STRUCT_FLD(value, 0),
STRUCT_FLD(field_flags, MY_I_S_UNSIGNED),
STRUCT_FLD(old_name, ""),
STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
{STRUCT_FLD(field_name, "other_size"),
STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS),
STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG),
STRUCT_FLD(value, 0),
STRUCT_FLD(field_flags, MY_I_S_UNSIGNED),
STRUCT_FLD(old_name, ""),
STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
{STRUCT_FLD(field_name, "modified"),
STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS),
STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG),
STRUCT_FLD(value, 0),
STRUCT_FLD(field_flags, MY_I_S_UNSIGNED),
STRUCT_FLD(old_name, ""),
STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
END_OF_ST_FIELD_INFO
};
static ST_FIELD_INFO i_s_innodb_index_stats_info[] =
{
{STRUCT_FLD(field_name, "table_name"),
STRUCT_FLD(field_length, NAME_LEN),
STRUCT_FLD(field_type, MYSQL_TYPE_STRING),
STRUCT_FLD(value, 0),
STRUCT_FLD(field_flags, 0),
STRUCT_FLD(old_name, ""),
STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
{STRUCT_FLD(field_name, "index_name"),
STRUCT_FLD(field_length, NAME_LEN),
STRUCT_FLD(field_type, MYSQL_TYPE_STRING),
STRUCT_FLD(value, 0),
STRUCT_FLD(field_flags, 0),
STRUCT_FLD(old_name, ""),
STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
{STRUCT_FLD(field_name, "fields"),
STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS),
STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG),
STRUCT_FLD(value, 0),
STRUCT_FLD(field_flags, MY_I_S_UNSIGNED),
STRUCT_FLD(old_name, ""),
STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
{STRUCT_FLD(field_name, "row_per_keys"),
STRUCT_FLD(field_length, 256),
STRUCT_FLD(field_type, MYSQL_TYPE_STRING),
STRUCT_FLD(value, 0),
STRUCT_FLD(field_flags, 0),
STRUCT_FLD(old_name, ""),
STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
{STRUCT_FLD(field_name, "index_size"),
STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS),
STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG),
STRUCT_FLD(value, 0),
STRUCT_FLD(field_flags, MY_I_S_UNSIGNED),
STRUCT_FLD(old_name, ""),
STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
{STRUCT_FLD(field_name, "leaf_pages"),
STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS),
STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG),
STRUCT_FLD(value, 0),
STRUCT_FLD(field_flags, MY_I_S_UNSIGNED),
STRUCT_FLD(old_name, ""),
STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
END_OF_ST_FIELD_INFO
};
static
int
i_s_innodb_table_stats_fill(
/*========================*/
THD* thd,
TABLE_LIST* tables,
COND* cond)
{
TABLE* i_s_table = (TABLE *) tables->table;
int status = 0;
dict_table_t* table;
DBUG_ENTER("i_s_innodb_table_stats_fill");
/* deny access to non-superusers */
if (check_global_access(thd, PROCESS_ACL)) {
DBUG_RETURN(0);
}
mutex_enter(&(dict_sys->mutex));
table = UT_LIST_GET_FIRST(dict_sys->table_LRU);
while (table) {
if (table->stat_clustered_index_size == 0) {
table = UT_LIST_GET_NEXT(table_LRU, table);
continue;
}
field_store_string(i_s_table->field[0], table->name);
i_s_table->field[1]->store(table->stat_n_rows);
i_s_table->field[2]->store(table->stat_clustered_index_size);
i_s_table->field[3]->store(table->stat_sum_of_other_index_sizes);
i_s_table->field[4]->store(table->stat_modified_counter);
if (schema_table_store_record(thd, i_s_table)) {
status = 1;
break;
}
table = UT_LIST_GET_NEXT(table_LRU, table);
}
mutex_exit(&(dict_sys->mutex));
DBUG_RETURN(status);
}
static
int
i_s_innodb_index_stats_fill(
/*========================*/
THD* thd,
TABLE_LIST* tables,
COND* cond)
{
TABLE* i_s_table = (TABLE *) tables->table;
int status = 0;
dict_table_t* table;
dict_index_t* index;
DBUG_ENTER("i_s_innodb_index_stats_fill");
/* deny access to non-superusers */
if (check_global_access(thd, PROCESS_ACL)) {
DBUG_RETURN(0);
}
mutex_enter(&(dict_sys->mutex));
table = UT_LIST_GET_FIRST(dict_sys->table_LRU);
while (table) {
if (table->stat_clustered_index_size == 0) {
table = UT_LIST_GET_NEXT(table_LRU, table);
continue;
}
ib_int64_t n_rows = table->stat_n_rows;
if (n_rows < 0) {
n_rows = 0;
}
index = dict_table_get_first_index(table);
while (index) {
char buff[256+1];
char row_per_keys[256+1];
ulint i;
field_store_string(i_s_table->field[0], table->name);
field_store_string(i_s_table->field[1], index->name);
i_s_table->field[2]->store(index->n_uniq);
row_per_keys[0] = '\0';
if (index->stat_n_diff_key_vals) {
for (i = 1; i <= index->n_uniq; i++) {
ib_int64_t rec_per_key;
if (index->stat_n_diff_key_vals[i]) {
rec_per_key = n_rows / index->stat_n_diff_key_vals[i];
} else {
rec_per_key = n_rows;
}
snprintf(buff, 256, (i == index->n_uniq)?"%llu":"%llu, ",
rec_per_key);
strncat(row_per_keys, buff, 256 - strlen(row_per_keys));
}
}
field_store_string(i_s_table->field[3], row_per_keys);
i_s_table->field[4]->store(index->stat_index_size);
i_s_table->field[5]->store(index->stat_n_leaf_pages);
if (schema_table_store_record(thd, i_s_table)) {
status = 1;
break;
}
index = dict_table_get_next_index(index);
}
if (status == 1) {
break;
}
table = UT_LIST_GET_NEXT(table_LRU, table);
}
mutex_exit(&(dict_sys->mutex));
DBUG_RETURN(status);
}
static
int
i_s_innodb_table_stats_init(
/*========================*/
void* p)
{
DBUG_ENTER("i_s_innodb_table_stats_init");
ST_SCHEMA_TABLE* schema = (ST_SCHEMA_TABLE*) p;
schema->fields_info = i_s_innodb_table_stats_info;
schema->fill_table = i_s_innodb_table_stats_fill;
DBUG_RETURN(0);
}
static
int
i_s_innodb_index_stats_init(
/*========================*/
void* p)
{
DBUG_ENTER("i_s_innodb_index_stats_init");
ST_SCHEMA_TABLE* schema = (ST_SCHEMA_TABLE*) p;
schema->fields_info = i_s_innodb_index_stats_info;
schema->fill_table = i_s_innodb_index_stats_fill;
DBUG_RETURN(0);
}
UNIV_INTERN struct st_mysql_plugin i_s_innodb_table_stats =
{
STRUCT_FLD(type, MYSQL_INFORMATION_SCHEMA_PLUGIN),
STRUCT_FLD(info, &i_s_info),
STRUCT_FLD(name, "INNODB_TABLE_STATS"),
STRUCT_FLD(author, plugin_author),
STRUCT_FLD(descr, "InnoDB table statistics in memory"),
STRUCT_FLD(license, PLUGIN_LICENSE_GPL),
STRUCT_FLD(init, i_s_innodb_table_stats_init),
STRUCT_FLD(deinit, i_s_common_deinit),
STRUCT_FLD(version, 0x0100 /* 1.0 */),
STRUCT_FLD(status_vars, NULL),
STRUCT_FLD(system_vars, NULL),
STRUCT_FLD(__reserved1, NULL)
};
UNIV_INTERN struct st_mysql_plugin i_s_innodb_index_stats =
{
STRUCT_FLD(type, MYSQL_INFORMATION_SCHEMA_PLUGIN),
STRUCT_FLD(info, &i_s_info),
STRUCT_FLD(name, "INNODB_INDEX_STATS"),
STRUCT_FLD(author, plugin_author),
STRUCT_FLD(descr, "InnoDB index statistics in memory"),
STRUCT_FLD(license, PLUGIN_LICENSE_GPL),
STRUCT_FLD(init, i_s_innodb_index_stats_init),
STRUCT_FLD(deinit, i_s_common_deinit),
STRUCT_FLD(version, 0x0100 /* 1.0 */),
STRUCT_FLD(status_vars, NULL),
STRUCT_FLD(system_vars, NULL),
STRUCT_FLD(__reserved1, NULL)
};
...@@ -37,5 +37,7 @@ extern struct st_mysql_plugin i_s_innodb_cmpmem; ...@@ -37,5 +37,7 @@ extern struct st_mysql_plugin i_s_innodb_cmpmem;
extern struct st_mysql_plugin i_s_innodb_cmpmem_reset; extern struct st_mysql_plugin i_s_innodb_cmpmem_reset;
extern struct st_mysql_plugin i_s_innodb_patches; extern struct st_mysql_plugin i_s_innodb_patches;
extern struct st_mysql_plugin i_s_innodb_rseg; extern struct st_mysql_plugin i_s_innodb_rseg;
extern struct st_mysql_plugin i_s_innodb_table_stats;
extern struct st_mysql_plugin i_s_innodb_index_stats;
#endif /* i_s_h */ #endif /* i_s_h */
...@@ -31,5 +31,11 @@ struct innodb_enhancement { ...@@ -31,5 +31,11 @@ struct innodb_enhancement {
{"innodb_expand_undo_slots","expandable maximum number of undo slots","from 1024 (default) to about 4000","http://www.percona.com/docs/wiki/percona-xtradb"}, {"innodb_expand_undo_slots","expandable maximum number of undo slots","from 1024 (default) to about 4000","http://www.percona.com/docs/wiki/percona-xtradb"},
{"innodb_extra_rseg","allow to create extra rollback segments","When create new db, the new parameter allows to create more rollback segments","http://www.percona.com/docs/wiki/percona-xtradb"}, {"innodb_extra_rseg","allow to create extra rollback segments","When create new db, the new parameter allows to create more rollback segments","http://www.percona.com/docs/wiki/percona-xtradb"},
{"innodb_overwrite_relay_log_info","overwrite relay-log.info when slave recovery","Building as plugin, it is not used.","http://www.percona.com/docs/wiki/percona-xtradb:innodb_overwrite_relay_log_info"}, {"innodb_overwrite_relay_log_info","overwrite relay-log.info when slave recovery","Building as plugin, it is not used.","http://www.percona.com/docs/wiki/percona-xtradb:innodb_overwrite_relay_log_info"},
{"innodb_pause_in_spin","use 'pause' instruction during spin loop for x86 (gcc)","","http://www.percona.com/docs/wiki/percona-xtradb"},
{"innodb_thread_concurrency_timer_based","use InnoDB timer based concurrency throttling (backport from MySQL 5.4.0)","",""},
{"innodb_expand_import","convert .ibd file automatically when import tablespace","the files are generated by xtrabackup export mode.","http://www.percona.com/docs/wiki/percona-xtradb"},
{"innodb_dict_size_limit","Limit dictionary cache size","Variable innodb_dict_size_limit in bytes","http://www.percona.com/docs/wiki/percona-xtradb"},
{"innodb_split_buf_pool_mutex","More fix of buffer_pool mutex","Spliting buf_pool_mutex and optimizing based on innodb_opt_lru_count","http://www.percona.com/docs/wiki/percona-xtradb"},
{"innodb_stats","Additional features about InnoDB statistics/optimizer","","http://www.percona.com/docs/wiki/percona-xtradb"},
{NULL, NULL, NULL, NULL} {NULL, NULL, NULL, NULL}
}; };
...@@ -472,6 +472,7 @@ ibuf_init_at_db_start(void) ...@@ -472,6 +472,7 @@ ibuf_init_at_db_start(void)
/* Use old-style record format for the insert buffer. */ /* Use old-style record format for the insert buffer. */
table = dict_mem_table_create(IBUF_TABLE_NAME, IBUF_SPACE_ID, 1, 0); table = dict_mem_table_create(IBUF_TABLE_NAME, IBUF_SPACE_ID, 1, 0);
table->n_mysql_handles_opened = 1; /* for pin */
dict_mem_table_add_col(table, heap, "DUMMY_COLUMN", DATA_BINARY, 0, 0); dict_mem_table_add_col(table, heap, "DUMMY_COLUMN", DATA_BINARY, 0, 0);
......
...@@ -49,10 +49,11 @@ buf_buddy_alloc( ...@@ -49,10 +49,11 @@ buf_buddy_alloc(
/* out: allocated block, /* out: allocated block,
possibly NULL if lru == NULL */ possibly NULL if lru == NULL */
ulint size, /* in: block size, up to UNIV_PAGE_SIZE */ ulint size, /* in: block size, up to UNIV_PAGE_SIZE */
ibool* lru) /* in: pointer to a variable that will be assigned ibool* lru, /* in: pointer to a variable that will be assigned
TRUE if storage was allocated from the LRU list TRUE if storage was allocated from the LRU list
and buf_pool_mutex was temporarily released, and buf_pool_mutex was temporarily released,
or NULL if the LRU list should not be used */ or NULL if the LRU list should not be used */
ibool have_page_hash_mutex)
__attribute__((malloc)); __attribute__((malloc));
/************************************************************************** /**************************************************************************
...@@ -63,7 +64,8 @@ buf_buddy_free( ...@@ -63,7 +64,8 @@ buf_buddy_free(
/*===========*/ /*===========*/
void* buf, /* in: block to be freed, must not be void* buf, /* in: block to be freed, must not be
pointed to by the buffer pool */ pointed to by the buffer pool */
ulint size) /* in: block size, up to UNIV_PAGE_SIZE */ ulint size, /* in: block size, up to UNIV_PAGE_SIZE */
ibool have_page_hash_mutex)
__attribute__((nonnull)); __attribute__((nonnull));
/** Statistics of buddy blocks of a given size. */ /** Statistics of buddy blocks of a given size. */
......
...@@ -44,10 +44,11 @@ buf_buddy_alloc_low( ...@@ -44,10 +44,11 @@ buf_buddy_alloc_low(
possibly NULL if lru==NULL */ possibly NULL if lru==NULL */
ulint i, /* in: index of buf_pool->zip_free[], ulint i, /* in: index of buf_pool->zip_free[],
or BUF_BUDDY_SIZES */ or BUF_BUDDY_SIZES */
ibool* lru) /* in: pointer to a variable that will be assigned ibool* lru, /* in: pointer to a variable that will be assigned
TRUE if storage was allocated from the LRU list TRUE if storage was allocated from the LRU list
and buf_pool_mutex was temporarily released, and buf_pool_mutex was temporarily released,
or NULL if the LRU list should not be used */ or NULL if the LRU list should not be used */
ibool have_page_hash_mutex)
__attribute__((malloc)); __attribute__((malloc));
/************************************************************************** /**************************************************************************
...@@ -58,8 +59,9 @@ buf_buddy_free_low( ...@@ -58,8 +59,9 @@ buf_buddy_free_low(
/*===============*/ /*===============*/
void* buf, /* in: block to be freed, must not be void* buf, /* in: block to be freed, must not be
pointed to by the buffer pool */ pointed to by the buffer pool */
ulint i) /* in: index of buf_pool->zip_free[], ulint i, /* in: index of buf_pool->zip_free[],
or BUF_BUDDY_SIZES */ or BUF_BUDDY_SIZES */
ibool have_page_hash_mutex)
__attribute__((nonnull)); __attribute__((nonnull));
/************************************************************************** /**************************************************************************
...@@ -98,14 +100,15 @@ buf_buddy_alloc( ...@@ -98,14 +100,15 @@ buf_buddy_alloc(
/* out: allocated block, /* out: allocated block,
possibly NULL if lru == NULL */ possibly NULL if lru == NULL */
ulint size, /* in: block size, up to UNIV_PAGE_SIZE */ ulint size, /* in: block size, up to UNIV_PAGE_SIZE */
ibool* lru) /* in: pointer to a variable that will be assigned ibool* lru, /* in: pointer to a variable that will be assigned
TRUE if storage was allocated from the LRU list TRUE if storage was allocated from the LRU list
and buf_pool_mutex was temporarily released, and buf_pool_mutex was temporarily released,
or NULL if the LRU list should not be used */ or NULL if the LRU list should not be used */
ibool have_page_hash_mutex)
{ {
ut_ad(buf_pool_mutex_own()); //ut_ad(buf_pool_mutex_own());
return(buf_buddy_alloc_low(buf_buddy_get_slot(size), lru)); return(buf_buddy_alloc_low(buf_buddy_get_slot(size), lru, have_page_hash_mutex));
} }
/************************************************************************** /**************************************************************************
...@@ -116,11 +119,24 @@ buf_buddy_free( ...@@ -116,11 +119,24 @@ buf_buddy_free(
/*===========*/ /*===========*/
void* buf, /* in: block to be freed, must not be void* buf, /* in: block to be freed, must not be
pointed to by the buffer pool */ pointed to by the buffer pool */
ulint size) /* in: block size, up to UNIV_PAGE_SIZE */ ulint size, /* in: block size, up to UNIV_PAGE_SIZE */
ibool have_page_hash_mutex)
{ {
ut_ad(buf_pool_mutex_own()); //ut_ad(buf_pool_mutex_own());
if (!have_page_hash_mutex) {
mutex_enter(&LRU_list_mutex);
rw_lock_x_lock(&page_hash_latch);
}
mutex_enter(&zip_free_mutex);
buf_buddy_free_low(buf, buf_buddy_get_slot(size), TRUE);
mutex_exit(&zip_free_mutex);
buf_buddy_free_low(buf, buf_buddy_get_slot(size)); if (!have_page_hash_mutex) {
mutex_exit(&LRU_list_mutex);
rw_lock_x_unlock(&page_hash_latch);
}
} }
#ifdef UNIV_MATERIALIZE #ifdef UNIV_MATERIALIZE
......
...@@ -1024,7 +1024,7 @@ struct buf_page_struct{ ...@@ -1024,7 +1024,7 @@ struct buf_page_struct{
/* 2. Page flushing fields; protected by buf_pool_mutex */ /* 2. Page flushing fields; protected by buf_pool_mutex */
UT_LIST_NODE_T(buf_page_t) list; /* UT_LIST_NODE_T(buf_page_t) list; */
/* based on state, this is a list /* based on state, this is a list
node in one of the following lists node in one of the following lists
in buf_pool: in buf_pool:
...@@ -1034,6 +1034,10 @@ struct buf_page_struct{ ...@@ -1034,6 +1034,10 @@ struct buf_page_struct{
BUF_BLOCK_ZIP_DIRTY: flush_list BUF_BLOCK_ZIP_DIRTY: flush_list
BUF_BLOCK_ZIP_PAGE: zip_clean BUF_BLOCK_ZIP_PAGE: zip_clean
BUF_BLOCK_ZIP_FREE: zip_free[] */ BUF_BLOCK_ZIP_FREE: zip_free[] */
/* resplit for optimistic use */
UT_LIST_NODE_T(buf_page_t) free;
UT_LIST_NODE_T(buf_page_t) flush_list;
UT_LIST_NODE_T(buf_page_t) zip_list; /* zip_clean or zip_free[] */
#ifdef UNIV_DEBUG #ifdef UNIV_DEBUG
ibool in_flush_list; /* TRUE if in buf_pool->flush_list; ibool in_flush_list; /* TRUE if in buf_pool->flush_list;
when buf_pool_mutex is free, the when buf_pool_mutex is free, the
...@@ -1104,11 +1108,11 @@ struct buf_block_struct{ ...@@ -1104,11 +1108,11 @@ struct buf_block_struct{
a block is in the unzip_LRU list a block is in the unzip_LRU list
if page.state == BUF_BLOCK_FILE_PAGE if page.state == BUF_BLOCK_FILE_PAGE
and page.zip.data != NULL */ and page.zip.data != NULL */
#ifdef UNIV_DEBUG //#ifdef UNIV_DEBUG
ibool in_unzip_LRU_list;/* TRUE if the page is in the ibool in_unzip_LRU_list;/* TRUE if the page is in the
decompressed LRU list; decompressed LRU list;
used in debugging */ used in debugging */
#endif /* UNIV_DEBUG */ //#endif /* UNIV_DEBUG */
byte* frame; /* pointer to buffer frame which byte* frame; /* pointer to buffer frame which
is of size UNIV_PAGE_SIZE, and is of size UNIV_PAGE_SIZE, and
aligned to an address divisible by aligned to an address divisible by
...@@ -1316,6 +1320,12 @@ struct buf_pool_struct{ ...@@ -1316,6 +1320,12 @@ struct buf_pool_struct{
/* mutex protecting the buffer pool struct and control blocks, except the /* mutex protecting the buffer pool struct and control blocks, except the
read-write lock in them */ read-write lock in them */
extern mutex_t buf_pool_mutex; extern mutex_t buf_pool_mutex;
extern mutex_t LRU_list_mutex;
extern mutex_t flush_list_mutex;
extern rw_lock_t page_hash_latch;
extern mutex_t free_list_mutex;
extern mutex_t zip_free_mutex;
extern mutex_t zip_hash_mutex;
/* mutex protecting the control blocks of compressed-only pages /* mutex protecting the control blocks of compressed-only pages
(of type buf_page_t, not buf_block_t) */ (of type buf_page_t, not buf_block_t) */
extern mutex_t buf_pool_zip_mutex; extern mutex_t buf_pool_zip_mutex;
......
...@@ -100,7 +100,9 @@ buf_pool_get_oldest_modification(void) ...@@ -100,7 +100,9 @@ buf_pool_get_oldest_modification(void)
buf_page_t* bpage; buf_page_t* bpage;
ib_uint64_t lsn; ib_uint64_t lsn;
buf_pool_mutex_enter(); try_again:
//buf_pool_mutex_enter();
mutex_enter(&flush_list_mutex);
bpage = UT_LIST_GET_LAST(buf_pool->flush_list); bpage = UT_LIST_GET_LAST(buf_pool->flush_list);
...@@ -109,9 +111,14 @@ buf_pool_get_oldest_modification(void) ...@@ -109,9 +111,14 @@ buf_pool_get_oldest_modification(void)
} else { } else {
ut_ad(bpage->in_flush_list); ut_ad(bpage->in_flush_list);
lsn = bpage->oldest_modification; lsn = bpage->oldest_modification;
if (lsn == 0) {
mutex_exit(&flush_list_mutex);
goto try_again;
}
} }
buf_pool_mutex_exit(); //buf_pool_mutex_exit();
mutex_exit(&flush_list_mutex);
/* The returned answer may be out of date: the flush_list can /* The returned answer may be out of date: the flush_list can
change after the mutex has been released. */ change after the mutex has been released. */
...@@ -128,7 +135,8 @@ buf_pool_clock_tic(void) ...@@ -128,7 +135,8 @@ buf_pool_clock_tic(void)
/*====================*/ /*====================*/
/* out: new clock value */ /* out: new clock value */
{ {
ut_ad(buf_pool_mutex_own()); //ut_ad(buf_pool_mutex_own());
ut_ad(mutex_own(&LRU_list_mutex));
buf_pool->ulint_clock++; buf_pool->ulint_clock++;
...@@ -246,7 +254,7 @@ buf_page_in_file( ...@@ -246,7 +254,7 @@ buf_page_in_file(
case BUF_BLOCK_ZIP_FREE: case BUF_BLOCK_ZIP_FREE:
/* This is a free page in buf_pool->zip_free[]. /* This is a free page in buf_pool->zip_free[].
Such pages should only be accessed by the buddy allocator. */ Such pages should only be accessed by the buddy allocator. */
ut_error; /* ut_error; */ /* optimistic */
break; break;
case BUF_BLOCK_ZIP_PAGE: case BUF_BLOCK_ZIP_PAGE:
case BUF_BLOCK_ZIP_DIRTY: case BUF_BLOCK_ZIP_DIRTY:
...@@ -288,7 +296,7 @@ buf_page_get_LRU_position( ...@@ -288,7 +296,7 @@ buf_page_get_LRU_position(
const buf_page_t* bpage) /* in: control block */ const buf_page_t* bpage) /* in: control block */
{ {
ut_ad(buf_page_in_file(bpage)); ut_ad(buf_page_in_file(bpage));
ut_ad(buf_pool_mutex_own()); //ut_ad(buf_pool_mutex_own()); /* This is used in optimistic */
return(bpage->LRU_position); return(bpage->LRU_position);
} }
...@@ -305,7 +313,7 @@ buf_page_get_mutex( ...@@ -305,7 +313,7 @@ buf_page_get_mutex(
{ {
switch (buf_page_get_state(bpage)) { switch (buf_page_get_state(bpage)) {
case BUF_BLOCK_ZIP_FREE: case BUF_BLOCK_ZIP_FREE:
ut_error; /* ut_error; */ /* optimistic */
return(NULL); return(NULL);
case BUF_BLOCK_ZIP_PAGE: case BUF_BLOCK_ZIP_PAGE:
case BUF_BLOCK_ZIP_DIRTY: case BUF_BLOCK_ZIP_DIRTY:
...@@ -410,7 +418,7 @@ buf_page_set_io_fix( ...@@ -410,7 +418,7 @@ buf_page_set_io_fix(
buf_page_t* bpage, /* in/out: control block */ buf_page_t* bpage, /* in/out: control block */
enum buf_io_fix io_fix) /* in: io_fix state */ enum buf_io_fix io_fix) /* in: io_fix state */
{ {
ut_ad(buf_pool_mutex_own()); //ut_ad(buf_pool_mutex_own());
ut_ad(mutex_own(buf_page_get_mutex(bpage))); ut_ad(mutex_own(buf_page_get_mutex(bpage)));
bpage->io_fix = io_fix; bpage->io_fix = io_fix;
...@@ -438,12 +446,13 @@ buf_page_can_relocate( ...@@ -438,12 +446,13 @@ buf_page_can_relocate(
/*==================*/ /*==================*/
const buf_page_t* bpage) /* control block being relocated */ const buf_page_t* bpage) /* control block being relocated */
{ {
ut_ad(buf_pool_mutex_own()); //ut_ad(buf_pool_mutex_own());
ut_ad(mutex_own(buf_page_get_mutex(bpage))); ut_ad(mutex_own(buf_page_get_mutex(bpage)));
ut_ad(buf_page_in_file(bpage)); ut_ad(buf_page_in_file(bpage));
ut_ad(bpage->in_LRU_list); /* optimistic */
//ut_ad(bpage->in_LRU_list);
return(buf_page_get_io_fix(bpage) == BUF_IO_NONE return(bpage->in_LRU_list && bpage->io_fix == BUF_IO_NONE
&& bpage->buf_fix_count == 0); && bpage->buf_fix_count == 0);
} }
...@@ -457,7 +466,7 @@ buf_page_is_old( ...@@ -457,7 +466,7 @@ buf_page_is_old(
const buf_page_t* bpage) /* in: control block */ const buf_page_t* bpage) /* in: control block */
{ {
ut_ad(buf_page_in_file(bpage)); ut_ad(buf_page_in_file(bpage));
ut_ad(buf_pool_mutex_own()); //ut_ad(buf_pool_mutex_own()); /* This is used in optimistic */
return(bpage->old); return(bpage->old);
} }
...@@ -472,7 +481,8 @@ buf_page_set_old( ...@@ -472,7 +481,8 @@ buf_page_set_old(
ibool old) /* in: old */ ibool old) /* in: old */
{ {
ut_a(buf_page_in_file(bpage)); ut_a(buf_page_in_file(bpage));
ut_ad(buf_pool_mutex_own()); //ut_ad(buf_pool_mutex_own());
ut_ad(mutex_own(&LRU_list_mutex));
ut_ad(bpage->in_LRU_list); ut_ad(bpage->in_LRU_list);
#ifdef UNIV_LRU_DEBUG #ifdef UNIV_LRU_DEBUG
...@@ -728,17 +738,17 @@ buf_block_free( ...@@ -728,17 +738,17 @@ buf_block_free(
/*===========*/ /*===========*/
buf_block_t* block) /* in, own: block to be freed */ buf_block_t* block) /* in, own: block to be freed */
{ {
buf_pool_mutex_enter(); //buf_pool_mutex_enter();
mutex_enter(&block->mutex); mutex_enter(&block->mutex);
ut_a(buf_block_get_state(block) != BUF_BLOCK_FILE_PAGE); ut_a(buf_block_get_state(block) != BUF_BLOCK_FILE_PAGE);
buf_LRU_block_free_non_file_page(block); buf_LRU_block_free_non_file_page(block, FALSE);
mutex_exit(&block->mutex); mutex_exit(&block->mutex);
buf_pool_mutex_exit(); //buf_pool_mutex_exit();
} }
/************************************************************************* /*************************************************************************
...@@ -783,14 +793,23 @@ buf_page_io_query( ...@@ -783,14 +793,23 @@ buf_page_io_query(
buf_page_t* bpage) /* in: buf_pool block, must be bufferfixed */ buf_page_t* bpage) /* in: buf_pool block, must be bufferfixed */
{ {
ibool io_fixed; ibool io_fixed;
mutex_t* block_mutex = buf_page_get_mutex(bpage);
buf_pool_mutex_enter(); //buf_pool_mutex_enter();
retry_lock:
mutex_enter(block_mutex);
if (block_mutex != buf_page_get_mutex(bpage)) {
mutex_exit(block_mutex);
block_mutex = buf_page_get_mutex(bpage);
goto retry_lock;
}
ut_ad(buf_page_in_file(bpage)); ut_ad(buf_page_in_file(bpage));
ut_ad(bpage->buf_fix_count > 0); ut_ad(bpage->buf_fix_count > 0);
io_fixed = buf_page_get_io_fix(bpage) != BUF_IO_NONE; io_fixed = buf_page_get_io_fix(bpage) != BUF_IO_NONE;
buf_pool_mutex_exit(); //buf_pool_mutex_exit();
mutex_exit(block_mutex);
return(io_fixed); return(io_fixed);
} }
...@@ -809,7 +828,13 @@ buf_page_get_newest_modification( ...@@ -809,7 +828,13 @@ buf_page_get_newest_modification(
ib_uint64_t lsn; ib_uint64_t lsn;
mutex_t* block_mutex = buf_page_get_mutex(bpage); mutex_t* block_mutex = buf_page_get_mutex(bpage);
retry_lock:
mutex_enter(block_mutex); mutex_enter(block_mutex);
if (block_mutex != buf_page_get_mutex(bpage)) {
mutex_exit(block_mutex);
block_mutex = buf_page_get_mutex(bpage);
goto retry_lock;
}
if (buf_page_in_file(bpage)) { if (buf_page_in_file(bpage)) {
lsn = bpage->newest_modification; lsn = bpage->newest_modification;
...@@ -833,7 +858,7 @@ buf_block_modify_clock_inc( ...@@ -833,7 +858,7 @@ buf_block_modify_clock_inc(
buf_block_t* block) /* in: block */ buf_block_t* block) /* in: block */
{ {
#ifdef UNIV_SYNC_DEBUG #ifdef UNIV_SYNC_DEBUG
ut_ad((buf_pool_mutex_own() ut_ad((mutex_own(&LRU_list_mutex)
&& (block->page.buf_fix_count == 0)) && (block->page.buf_fix_count == 0))
|| rw_lock_own(&(block->lock), RW_LOCK_EXCLUSIVE)); || rw_lock_own(&(block->lock), RW_LOCK_EXCLUSIVE));
#endif /* UNIV_SYNC_DEBUG */ #endif /* UNIV_SYNC_DEBUG */
...@@ -917,7 +942,11 @@ buf_page_hash_get( ...@@ -917,7 +942,11 @@ buf_page_hash_get(
ulint fold; ulint fold;
ut_ad(buf_pool); ut_ad(buf_pool);
ut_ad(buf_pool_mutex_own()); //ut_ad(buf_pool_mutex_own());
#ifdef UNIV_SYNC_DEBUG
ut_ad(rw_lock_own(&page_hash_latch, RW_LOCK_EX)
|| rw_lock_own(&page_hash_latch, RW_LOCK_SHARED));
#endif
/* Look for the page in the hash table */ /* Look for the page in the hash table */
...@@ -966,11 +995,13 @@ buf_page_peek( ...@@ -966,11 +995,13 @@ buf_page_peek(
{ {
const buf_page_t* bpage; const buf_page_t* bpage;
buf_pool_mutex_enter(); //buf_pool_mutex_enter();
rw_lock_s_lock(&page_hash_latch);
bpage = buf_page_hash_get(space, offset); bpage = buf_page_hash_get(space, offset);
buf_pool_mutex_exit(); //buf_pool_mutex_exit();
rw_lock_s_unlock(&page_hash_latch);
return(bpage != NULL); return(bpage != NULL);
} }
...@@ -1032,11 +1063,14 @@ buf_page_release( ...@@ -1032,11 +1063,14 @@ buf_page_release(
ut_a(buf_block_get_state(block) == BUF_BLOCK_FILE_PAGE); ut_a(buf_block_get_state(block) == BUF_BLOCK_FILE_PAGE);
ut_a(block->page.buf_fix_count > 0); ut_a(block->page.buf_fix_count > 0);
/* buf_flush_note_modification() should be called before this function. */
/*
if (rw_latch == RW_X_LATCH && mtr->modifications) { if (rw_latch == RW_X_LATCH && mtr->modifications) {
buf_pool_mutex_enter(); buf_pool_mutex_enter();
buf_flush_note_modification(block, mtr); buf_flush_note_modification(block, mtr);
buf_pool_mutex_exit(); buf_pool_mutex_exit();
} }
*/
mutex_enter(&block->mutex); mutex_enter(&block->mutex);
......
...@@ -53,13 +53,23 @@ buf_flush_note_modification( ...@@ -53,13 +53,23 @@ buf_flush_note_modification(
buf_block_t* block, /* in: block which is modified */ buf_block_t* block, /* in: block which is modified */
mtr_t* mtr) /* in: mtr */ mtr_t* mtr) /* in: mtr */
{ {
ibool use_LRU_mutex = FALSE;
if (UT_LIST_GET_LEN(buf_pool->unzip_LRU))
use_LRU_mutex = TRUE;
if (use_LRU_mutex)
mutex_enter(&LRU_list_mutex);
mutex_enter(&block->mutex);
ut_ad(block); ut_ad(block);
ut_ad(buf_block_get_state(block) == BUF_BLOCK_FILE_PAGE); ut_ad(buf_block_get_state(block) == BUF_BLOCK_FILE_PAGE);
ut_ad(block->page.buf_fix_count > 0); ut_ad(block->page.buf_fix_count > 0);
#ifdef UNIV_SYNC_DEBUG #ifdef UNIV_SYNC_DEBUG
ut_ad(rw_lock_own(&(block->lock), RW_LOCK_EX)); ut_ad(rw_lock_own(&(block->lock), RW_LOCK_EX));
#endif /* UNIV_SYNC_DEBUG */ #endif /* UNIV_SYNC_DEBUG */
ut_ad(buf_pool_mutex_own()); //ut_ad(buf_pool_mutex_own());
ut_ad(mtr->start_lsn != 0); ut_ad(mtr->start_lsn != 0);
ut_ad(mtr->modifications); ut_ad(mtr->modifications);
...@@ -68,16 +78,23 @@ buf_flush_note_modification( ...@@ -68,16 +78,23 @@ buf_flush_note_modification(
block->page.newest_modification = mtr->end_lsn; block->page.newest_modification = mtr->end_lsn;
if (!block->page.oldest_modification) { if (!block->page.oldest_modification) {
mutex_enter(&flush_list_mutex);
block->page.oldest_modification = mtr->start_lsn; block->page.oldest_modification = mtr->start_lsn;
ut_ad(block->page.oldest_modification != 0); ut_ad(block->page.oldest_modification != 0);
buf_flush_insert_into_flush_list(block); buf_flush_insert_into_flush_list(block);
mutex_exit(&flush_list_mutex);
} else { } else {
ut_ad(block->page.oldest_modification <= mtr->start_lsn); ut_ad(block->page.oldest_modification <= mtr->start_lsn);
} }
mutex_exit(&block->mutex);
++srv_buf_pool_write_requests; ++srv_buf_pool_write_requests;
if (use_LRU_mutex)
mutex_exit(&LRU_list_mutex);
} }
/************************************************************************ /************************************************************************
...@@ -92,6 +109,16 @@ buf_flush_recv_note_modification( ...@@ -92,6 +109,16 @@ buf_flush_recv_note_modification(
ib_uint64_t end_lsn) /* in: end lsn of the last mtr in the ib_uint64_t end_lsn) /* in: end lsn of the last mtr in the
set of mtr's */ set of mtr's */
{ {
ibool use_LRU_mutex = FALSE;
if(UT_LIST_GET_LEN(buf_pool->unzip_LRU))
use_LRU_mutex = TRUE;
if (use_LRU_mutex)
mutex_enter(&LRU_list_mutex);
mutex_enter(&(block->mutex));
ut_ad(block); ut_ad(block);
ut_ad(buf_block_get_state(block) == BUF_BLOCK_FILE_PAGE); ut_ad(buf_block_get_state(block) == BUF_BLOCK_FILE_PAGE);
ut_ad(block->page.buf_fix_count > 0); ut_ad(block->page.buf_fix_count > 0);
...@@ -99,22 +126,27 @@ buf_flush_recv_note_modification( ...@@ -99,22 +126,27 @@ buf_flush_recv_note_modification(
ut_ad(rw_lock_own(&(block->lock), RW_LOCK_EX)); ut_ad(rw_lock_own(&(block->lock), RW_LOCK_EX));
#endif /* UNIV_SYNC_DEBUG */ #endif /* UNIV_SYNC_DEBUG */
buf_pool_mutex_enter(); //buf_pool_mutex_enter();
ut_ad(block->page.newest_modification <= end_lsn); ut_ad(block->page.newest_modification <= end_lsn);
block->page.newest_modification = end_lsn; block->page.newest_modification = end_lsn;
if (!block->page.oldest_modification) { if (!block->page.oldest_modification) {
mutex_enter(&flush_list_mutex);
block->page.oldest_modification = start_lsn; block->page.oldest_modification = start_lsn;
ut_ad(block->page.oldest_modification != 0); ut_ad(block->page.oldest_modification != 0);
buf_flush_insert_sorted_into_flush_list(block); buf_flush_insert_sorted_into_flush_list(block);
mutex_exit(&flush_list_mutex);
} else { } else {
ut_ad(block->page.oldest_modification <= start_lsn); ut_ad(block->page.oldest_modification <= start_lsn);
} }
buf_pool_mutex_exit(); //buf_pool_mutex_exit();
if (use_LRU_mutex)
mutex_exit(&LRU_list_mutex);
mutex_exit(&(block->mutex));
} }
...@@ -122,10 +122,11 @@ buf_LRU_free_block( ...@@ -122,10 +122,11 @@ buf_LRU_free_block(
buf_page_t* bpage, /* in: block to be freed */ buf_page_t* bpage, /* in: block to be freed */
ibool zip, /* in: TRUE if should remove also the ibool zip, /* in: TRUE if should remove also the
compressed page of an uncompressed page */ compressed page of an uncompressed page */
ibool* buf_pool_mutex_released); ibool* buf_pool_mutex_released,
/* in: pointer to a variable that will /* in: pointer to a variable that will
be assigned TRUE if buf_pool_mutex be assigned TRUE if buf_pool_mutex
was temporarily released, or NULL */ was temporarily released, or NULL */
ibool have_LRU_mutex);
/********************************************************************** /**********************************************************************
Try to free a replaceable block. */ Try to free a replaceable block. */
UNIV_INTERN UNIV_INTERN
...@@ -169,7 +170,8 @@ UNIV_INTERN ...@@ -169,7 +170,8 @@ UNIV_INTERN
void void
buf_LRU_block_free_non_file_page( buf_LRU_block_free_non_file_page(
/*=============================*/ /*=============================*/
buf_block_t* block); /* in: block, must not contain a file page */ buf_block_t* block, /* in: block, must not contain a file page */
ibool have_page_hash_mutex);
/********************************************************************** /**********************************************************************
Adds a block to the LRU list. */ Adds a block to the LRU list. */
UNIV_INTERN UNIV_INTERN
......
...@@ -1102,6 +1102,12 @@ dict_table_get_index_on_name_and_min_id( ...@@ -1102,6 +1102,12 @@ dict_table_get_index_on_name_and_min_id(
/* out: index, NULL if does not exist */ /* out: index, NULL if does not exist */
dict_table_t* table, /* in: table */ dict_table_t* table, /* in: table */
const char* name); /* in: name of the index to find */ const char* name); /* in: name of the index to find */
UNIV_INTERN
void
dict_table_LRU_trim(
/*================*/
dict_table_t* self);
/* Buffers for storing detailed information about the latest foreign key /* Buffers for storing detailed information about the latest foreign key
and unique key errors */ and unique key errors */
extern FILE* dict_foreign_err_file; extern FILE* dict_foreign_err_file;
......
...@@ -723,6 +723,13 @@ dict_table_check_if_in_cache_low( ...@@ -723,6 +723,13 @@ dict_table_check_if_in_cache_low(
HASH_SEARCH(name_hash, dict_sys->table_hash, table_fold, HASH_SEARCH(name_hash, dict_sys->table_hash, table_fold,
dict_table_t*, table, ut_ad(table->cached), dict_table_t*, table, ut_ad(table->cached),
!strcmp(table->name, table_name)); !strcmp(table->name, table_name));
/* make young in table_LRU */
if (table) {
UT_LIST_REMOVE(table_LRU, dict_sys->table_LRU, table);
UT_LIST_ADD_FIRST(table_LRU, dict_sys->table_LRU, table);
}
return(table); return(table);
} }
...@@ -776,6 +783,12 @@ dict_table_get_on_id_low( ...@@ -776,6 +783,12 @@ dict_table_get_on_id_low(
table = dict_load_table_on_id(table_id); table = dict_load_table_on_id(table_id);
} }
/* make young in table_LRU */
if (table) {
UT_LIST_REMOVE(table_LRU, dict_sys->table_LRU, table);
UT_LIST_ADD_FIRST(table_LRU, dict_sys->table_LRU, table);
}
ut_ad(!table || table->cached); ut_ad(!table || table->cached);
/* TODO: should get the type information from MySQL */ /* TODO: should get the type information from MySQL */
......
...@@ -186,6 +186,13 @@ void ...@@ -186,6 +186,13 @@ void
log_buffer_flush_to_disk(void); log_buffer_flush_to_disk(void);
/*==========================*/ /*==========================*/
/******************************************************************** /********************************************************************
Flushes the log buffer. Forces it to disk depending on the value of
the configuration parameter innodb_flush_log_at_trx_commit. */
UNIV_INTERN
void
log_buffer_flush_maybe_sync(void);
/*=============================*/
/********************************************************************
Advances the smallest lsn for which there are unflushed dirty blocks in the Advances the smallest lsn for which there are unflushed dirty blocks in the
buffer pool and also may make a new checkpoint. NOTE: this function may only buffer pool and also may make a new checkpoint. NOTE: this function may only
be called if the calling thread owns no synchronization objects! */ be called if the calling thread owns no synchronization objects! */
......
...@@ -177,10 +177,11 @@ cmp_rec_rec_with_match( ...@@ -177,10 +177,11 @@ cmp_rec_rec_with_match(
matched fields; when the function returns, matched fields; when the function returns,
contains the value the for current contains the value the for current
comparison */ comparison */
ulint* matched_bytes);/* in/out: number of already matched ulint* matched_bytes, /* in/out: number of already matched
bytes within the first field not completely bytes within the first field not completely
matched; when the function returns, contains matched; when the function returns, contains
the value for the current comparison */ the value for the current comparison */
ulint stats_method);
/***************************************************************** /*****************************************************************
This function is used to compare two physical records. Only the common This function is used to compare two physical records. Only the common
first fields are compared. */ first fields are compared. */
......
...@@ -88,5 +88,5 @@ cmp_rec_rec( ...@@ -88,5 +88,5 @@ cmp_rec_rec(
ulint match_b = 0; ulint match_b = 0;
return(cmp_rec_rec_with_match(rec1, rec2, offsets1, offsets2, index, return(cmp_rec_rec_with_match(rec1, rec2, offsets1, offsets2, index,
&match_f, &match_b)); &match_f, &match_b, 0));
} }
...@@ -127,6 +127,8 @@ extern ulint srv_buf_pool_curr_size; /* current size in bytes */ ...@@ -127,6 +127,8 @@ extern ulint srv_buf_pool_curr_size; /* current size in bytes */
extern ulint srv_mem_pool_size; extern ulint srv_mem_pool_size;
extern ulint srv_lock_table_size; extern ulint srv_lock_table_size;
extern ibool srv_thread_concurrency_timer_based;
extern ulint srv_n_file_io_threads; extern ulint srv_n_file_io_threads;
extern ulint srv_n_read_io_threads; extern ulint srv_n_read_io_threads;
extern ulint srv_n_write_io_threads; extern ulint srv_n_write_io_threads;
...@@ -163,6 +165,11 @@ extern ulint srv_fast_shutdown; /* If this is 1, do not do a ...@@ -163,6 +165,11 @@ extern ulint srv_fast_shutdown; /* If this is 1, do not do a
extern ibool srv_innodb_status; extern ibool srv_innodb_status;
extern unsigned long long srv_stats_sample_pages; extern unsigned long long srv_stats_sample_pages;
extern ulint srv_stats_method;
#define SRV_STATS_METHOD_NULLS_EQUAL 0
#define SRV_STATS_METHOD_NULLS_NOT_EQUAL 1
#define SRV_STATS_METHOD_IGNORE_NULLS 2
extern ulint srv_stats_auto_update;
extern ibool srv_use_doublewrite_buf; extern ibool srv_use_doublewrite_buf;
extern ibool srv_use_checksums; extern ibool srv_use_checksums;
...@@ -184,8 +191,10 @@ extern ulint srv_enable_unsafe_group_commit; ...@@ -184,8 +191,10 @@ extern ulint srv_enable_unsafe_group_commit;
extern ulint srv_read_ahead; extern ulint srv_read_ahead;
extern ulint srv_adaptive_checkpoint; extern ulint srv_adaptive_checkpoint;
extern ulint srv_extra_rsegments; extern ulint srv_expand_import;
extern ulint srv_extra_rsegments;
extern ulint srv_dict_size_limit;
/*-------------------------------------------*/ /*-------------------------------------------*/
extern ulint srv_n_rows_inserted; extern ulint srv_n_rows_inserted;
...@@ -552,6 +561,7 @@ struct export_var_struct{ ...@@ -552,6 +561,7 @@ struct export_var_struct{
ulint innodb_data_writes; ulint innodb_data_writes;
ulint innodb_data_written; ulint innodb_data_written;
ulint innodb_data_reads; ulint innodb_data_reads;
ulint innodb_dict_tables;
ulint innodb_buffer_pool_pages_total; ulint innodb_buffer_pool_pages_total;
ulint innodb_buffer_pool_pages_data; ulint innodb_buffer_pool_pages_data;
ulint innodb_buffer_pool_pages_dirty; ulint innodb_buffer_pool_pages_dirty;
......
...@@ -464,8 +464,14 @@ or row lock! */ ...@@ -464,8 +464,14 @@ or row lock! */
SYNC_SEARCH_SYS, as memory allocation SYNC_SEARCH_SYS, as memory allocation
can call routines there! Otherwise can call routines there! Otherwise
the level is SYNC_MEM_HASH. */ the level is SYNC_MEM_HASH. */
#define SYNC_BUF_LRU_LIST 157
#define SYNC_BUF_PAGE_HASH 156
#define SYNC_BUF_BLOCK 155
#define SYNC_BUF_FREE_LIST 153
#define SYNC_BUF_ZIP_FREE 152
#define SYNC_BUF_ZIP_HASH 151
#define SYNC_BUF_POOL 150 #define SYNC_BUF_POOL 150
#define SYNC_BUF_BLOCK 149 #define SYNC_BUF_FLUSH_LIST 149
#define SYNC_DOUBLEWRITE 140 #define SYNC_DOUBLEWRITE 140
#define SYNC_ANY_LATCH 135 #define SYNC_ANY_LATCH 135
#define SYNC_THR_LOCAL 133 #define SYNC_THR_LOCAL 133
......
...@@ -12,3 +12,8 @@ If by any chance Makefile.in and ./configure are regenerated and thus ...@@ -12,3 +12,8 @@ If by any chance Makefile.in and ./configure are regenerated and thus
the hack from Makefile.in wiped away then the "real" check from plug.in the hack from Makefile.in wiped away then the "real" check from plug.in
will take over. will take over.
*/ */
/* This is temprary fix for http://bugs.mysql.com/43740 */
/* force to enable */
#ifdef HAVE_GCC_ATOMIC_BUILTINS
#define HAVE_ATOMIC_PTHREAD_T
#endif
...@@ -1525,6 +1525,26 @@ log_buffer_flush_to_disk(void) ...@@ -1525,6 +1525,26 @@ log_buffer_flush_to_disk(void)
log_write_up_to(lsn, LOG_WAIT_ALL_GROUPS, TRUE); log_write_up_to(lsn, LOG_WAIT_ALL_GROUPS, TRUE);
} }
/********************************************************************
Flush the log buffer. Force it to disk depending on the value of
innodb_flush_log_at_trx_commit. */
UNIV_INTERN
void
log_buffer_flush_maybe_sync(void)
/*=============================*/
{
ib_uint64_t lsn;
mutex_enter(&(log_sys->mutex));
lsn = log_sys->lsn;
mutex_exit(&(log_sys->mutex));
/* Force log buffer to disk when innodb_flush_log_at_trx_commit = 1. */
log_write_up_to(lsn, LOG_WAIT_ALL_GROUPS,
srv_flush_log_at_trx_commit == 1 ? TRUE : FALSE);
}
/******************************************************************** /********************************************************************
Tries to establish a big enough margin of free space in the log buffer, such Tries to establish a big enough margin of free space in the log buffer, such
that a new log entry can be catenated without an immediate need for a flush. */ that a new log entry can be catenated without an immediate need for a flush. */
......
...@@ -102,6 +102,38 @@ mtr_memo_pop_all( ...@@ -102,6 +102,38 @@ mtr_memo_pop_all(
} }
} }
UNIV_INLINE
void
mtr_memo_note_modification_all(
/*===========================*/
mtr_t* mtr) /* in: mtr */
{
mtr_memo_slot_t* slot;
dyn_array_t* memo;
ulint offset;
ut_ad(mtr);
ut_ad(mtr->magic_n == MTR_MAGIC_N);
ut_ad(mtr->state == MTR_COMMITTING); /* Currently only used in
commit */
ut_ad(mtr->modifications);
memo = &(mtr->memo);
offset = dyn_array_get_data_size(memo);
while (offset > 0) {
offset -= sizeof(mtr_memo_slot_t);
slot = dyn_array_get_element(memo, offset);
if (UNIV_LIKELY(slot->object != NULL) &&
slot->type == MTR_MEMO_PAGE_X_FIX) {
buf_flush_note_modification(
(buf_block_t*)slot->object, mtr);
}
}
}
/**************************************************************** /****************************************************************
Writes the contents of a mini-transaction log, if any, to the database log. */ Writes the contents of a mini-transaction log, if any, to the database log. */
static static
...@@ -180,6 +212,8 @@ mtr_commit( ...@@ -180,6 +212,8 @@ mtr_commit(
if (write_log) { if (write_log) {
mtr_log_reserve_and_write(mtr); mtr_log_reserve_and_write(mtr);
mtr_memo_note_modification_all(mtr);
} }
/* We first update the modification info to buffer pages, and only /* We first update the modification info to buffer pages, and only
...@@ -190,12 +224,13 @@ mtr_commit( ...@@ -190,12 +224,13 @@ mtr_commit(
required when we insert modified buffer pages in to the flush list required when we insert modified buffer pages in to the flush list
which must be sorted on oldest_modification. */ which must be sorted on oldest_modification. */
mtr_memo_pop_all(mtr);
if (write_log) { if (write_log) {
log_release(); log_release();
} }
/* All unlocking has been moved here, after log_sys mutex release. */
mtr_memo_pop_all(mtr);
ut_d(mtr->state = MTR_COMMITTED); ut_d(mtr->state = MTR_COMMITTED);
dyn_array_free(&(mtr->memo)); dyn_array_free(&(mtr->memo));
dyn_array_free(&(mtr->log)); dyn_array_free(&(mtr->log));
...@@ -263,6 +298,12 @@ mtr_memo_release( ...@@ -263,6 +298,12 @@ mtr_memo_release(
slot = dyn_array_get_element(memo, offset); slot = dyn_array_get_element(memo, offset);
if ((object == slot->object) && (type == slot->type)) { if ((object == slot->object) && (type == slot->type)) {
if (mtr->modifications &&
UNIV_LIKELY(slot->object != NULL) &&
slot->type == MTR_MEMO_PAGE_X_FIX) {
buf_flush_note_modification(
(buf_block_t*)slot->object, mtr);
}
mtr_memo_slot_release(mtr, slot); mtr_memo_slot_release(mtr, slot);
......
...@@ -46,13 +46,6 @@ t1 CREATE TABLE `t1` ( ...@@ -46,13 +46,6 @@ t1 CREATE TABLE `t1` (
KEY `d2` (`d`), KEY `d2` (`d`),
KEY `b` (`b`) KEY `b` (`b`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 ) ENGINE=InnoDB DEFAULT CHARSET=latin1
CREATE TABLE `t1#1`(a INT PRIMARY KEY) ENGINE=InnoDB;
alter table t1 add unique index (c), add index (d);
ERROR HY000: Table 'test.t1#1' already exists
rename table `t1#1` to `t1#2`;
alter table t1 add unique index (c), add index (d);
ERROR HY000: Table 'test.t1#2' already exists
drop table `t1#2`;
alter table t1 add unique index (c), add index (d); alter table t1 add unique index (c), add index (d);
show create table t1; show create table t1;
Table Create Table Table Create Table
......
...@@ -17,16 +17,6 @@ show create table t1; ...@@ -17,16 +17,6 @@ show create table t1;
alter table t1 add index (b); alter table t1 add index (b);
show create table t1; show create table t1;
# Check how existing tables interfere with temporary tables.
CREATE TABLE `t1#1`(a INT PRIMARY KEY) ENGINE=InnoDB;
--error 156
alter table t1 add unique index (c), add index (d);
rename table `t1#1` to `t1#2`;
--error 156
alter table t1 add unique index (c), add index (d);
drop table `t1#2`;
alter table t1 add unique index (c), add index (d); alter table t1 add unique index (c), add index (d);
show create table t1; show create table t1;
explain select * from t1 force index(c) order by c; explain select * from t1 force index(c) order by c;
......
...@@ -30,3 +30,4 @@ ALTER TABLE bug34300 ADD COLUMN (f10 INT); ...@@ -30,3 +30,4 @@ ALTER TABLE bug34300 ADD COLUMN (f10 INT);
SELECT f4, f8 FROM bug34300; SELECT f4, f8 FROM bug34300;
DROP TABLE bug34300; DROP TABLE bug34300;
SET @@global.max_allowed_packet=1048576;
set @old_innodb_file_per_table=@@innodb_file_per_table;
set @old_innodb_file_format=@@innodb_file_format;
set @old_innodb_file_format_check=@@innodb_file_format_check;
SET GLOBAL innodb_file_format='Barracuda'; SET GLOBAL innodb_file_format='Barracuda';
SET GLOBAL innodb_file_per_table=ON; SET GLOBAL innodb_file_per_table=ON;
...@@ -4,6 +4,9 @@ ...@@ -4,6 +4,9 @@
# #
-- source include/have_innodb.inc -- source include/have_innodb.inc
set @old_innodb_file_per_table=@@innodb_file_per_table;
set @old_innodb_file_format=@@innodb_file_format;
set @old_innodb_file_format_check=@@innodb_file_format_check;
SET GLOBAL innodb_file_format='Barracuda'; SET GLOBAL innodb_file_format='Barracuda';
SET GLOBAL innodb_file_per_table=ON; SET GLOBAL innodb_file_per_table=ON;
...@@ -1153,3 +1156,7 @@ DROP TABLE IF EXISTS table4; ...@@ -1153,3 +1156,7 @@ DROP TABLE IF EXISTS table4;
DROP TABLE IF EXISTS table5; DROP TABLE IF EXISTS table5;
DROP TABLE IF EXISTS table6; DROP TABLE IF EXISTS table6;
set global innodb_file_per_table=@old_innodb_file_per_table;
set global innodb_file_format=@old_innodb_file_format;
set global innodb_file_format_check=@old_innodb_file_format_check;
...@@ -13,6 +13,9 @@ SET storage_engine=InnoDB; ...@@ -13,6 +13,9 @@ SET storage_engine=InnoDB;
-- disable_query_log -- disable_query_log
-- disable_result_log -- disable_result_log
set @old_innodb_file_per_table=@@innodb_file_per_table;
set @old_innodb_file_format=@@innodb_file_format;
set @old_innodb_file_format_check=@@innodb_file_format_check;
SET GLOBAL innodb_file_format='Barracuda'; SET GLOBAL innodb_file_format='Barracuda';
SET GLOBAL innodb_file_per_table=on; SET GLOBAL innodb_file_per_table=on;
...@@ -24,3 +27,7 @@ CHECK TABLE table0 EXTENDED; ...@@ -24,3 +27,7 @@ CHECK TABLE table0 EXTENDED;
INSERT IGNORE INTO `table0` SET `col19` = '19940127002709', `col20` = 2383927.9055146948, `col21` = 4293243420.5621204000, `col22` = '20511211123705', `col23` = 4289899778.6573381000, `col24` = 4293449279.0540481000, `col25` = 'emphysemic', `col26` = 'dentally', `col27` = '2347406', `col28` = 'eruct', `col30` = 1222, `col31` = 4294372994.9941406000, `col32` = 4291385574.1173744000, `col33` = 'borrowing\'s', `col34` = 'septics', `col35` = 'ratter\'s', `col36` = 'Kaye', `col37` = 'Florentia', `col38` = 'allium', `col39` = 'barkeep', `col40` = '19510407003441', `col41` = 4293559200.4215522000, `col42` = 22482, `col43` = 'decussate', `col44` = 'Brom\'s', `col45` = 'violated', `col46` = 4925506.4635456400, `col47` = 930549, `col48` = '51296066', `col49` = 'voluminously', `col50` = '29306676', `col51` = -88, `col52` = -2153690, `col53` = 4290250202.1464887000, `col54` = 'expropriation', `col55` = 'Aberdeen\'s', `col56` = 20343, `col58` = '19640415171532', `col59` = 'extern', `col60` = 'Ubana', `col61` = 4290487961.8539081000, `col62` = '2147', `col63` = -24271, `col64` = '20750801194548', `col65` = 'Cunaxa\'s', `col66` = 'pasticcio', `col67` = 2795817, `col68` = 'Indore\'s', `col70` = 6864127, `col71` = '1817832', `col72` = '20540506114211', `col73` = '20040101012300', `col74` = 'rationalized', `col75` = '45522', `col76` = 'indene', `col77` = -6964559, `col78` = 4247535.5266884370, `col79` = '20720416124357', `col80` = '2143', `col81` = 4292060102.4466386000, `col82` = 'striving', `col83` = 'boneblack\'s', `col84` = 'redolent', `col85` = 6489697.9009369183, `col86` = 4287473465.9731131000, `col87` = 7726015, `col88` = 'perplexed', `col89` = '17153791', `col90` = 5478587.1108127078, `col91` = 4287091404.7004304000, `col92` = 'Boulez\'s', `col93` = '2931278'; INSERT IGNORE INTO `table0` SET `col19` = '19940127002709', `col20` = 2383927.9055146948, `col21` = 4293243420.5621204000, `col22` = '20511211123705', `col23` = 4289899778.6573381000, `col24` = 4293449279.0540481000, `col25` = 'emphysemic', `col26` = 'dentally', `col27` = '2347406', `col28` = 'eruct', `col30` = 1222, `col31` = 4294372994.9941406000, `col32` = 4291385574.1173744000, `col33` = 'borrowing\'s', `col34` = 'septics', `col35` = 'ratter\'s', `col36` = 'Kaye', `col37` = 'Florentia', `col38` = 'allium', `col39` = 'barkeep', `col40` = '19510407003441', `col41` = 4293559200.4215522000, `col42` = 22482, `col43` = 'decussate', `col44` = 'Brom\'s', `col45` = 'violated', `col46` = 4925506.4635456400, `col47` = 930549, `col48` = '51296066', `col49` = 'voluminously', `col50` = '29306676', `col51` = -88, `col52` = -2153690, `col53` = 4290250202.1464887000, `col54` = 'expropriation', `col55` = 'Aberdeen\'s', `col56` = 20343, `col58` = '19640415171532', `col59` = 'extern', `col60` = 'Ubana', `col61` = 4290487961.8539081000, `col62` = '2147', `col63` = -24271, `col64` = '20750801194548', `col65` = 'Cunaxa\'s', `col66` = 'pasticcio', `col67` = 2795817, `col68` = 'Indore\'s', `col70` = 6864127, `col71` = '1817832', `col72` = '20540506114211', `col73` = '20040101012300', `col74` = 'rationalized', `col75` = '45522', `col76` = 'indene', `col77` = -6964559, `col78` = 4247535.5266884370, `col79` = '20720416124357', `col80` = '2143', `col81` = 4292060102.4466386000, `col82` = 'striving', `col83` = 'boneblack\'s', `col84` = 'redolent', `col85` = 6489697.9009369183, `col86` = 4287473465.9731131000, `col87` = 7726015, `col88` = 'perplexed', `col89` = '17153791', `col90` = 5478587.1108127078, `col91` = 4287091404.7004304000, `col92` = 'Boulez\'s', `col93` = '2931278';
CHECK TABLE table0 EXTENDED; CHECK TABLE table0 EXTENDED;
DROP TABLE table0; DROP TABLE table0;
set global innodb_file_per_table=@old_innodb_file_per_table;
set global innodb_file_format=@old_innodb_file_format;
set global innodb_file_format_check=@old_innodb_file_format_check;
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
...@@ -892,10 +892,11 @@ cmp_rec_rec_with_match( ...@@ -892,10 +892,11 @@ cmp_rec_rec_with_match(
matched fields; when the function returns, matched fields; when the function returns,
contains the value the for current contains the value the for current
comparison */ comparison */
ulint* matched_bytes) /* in/out: number of already matched ulint* matched_bytes, /* in/out: number of already matched
bytes within the first field not completely bytes within the first field not completely
matched; when the function returns, contains matched; when the function returns, contains
the value for the current comparison */ the value for the current comparison */
ulint stats_method)
{ {
#ifndef UNIV_HOTBACKUP #ifndef UNIV_HOTBACKUP
ulint rec1_n_fields; /* the number of fields in rec */ ulint rec1_n_fields; /* the number of fields in rec */
...@@ -989,7 +990,11 @@ cmp_rec_rec_with_match( ...@@ -989,7 +990,11 @@ cmp_rec_rec_with_match(
if (rec1_f_len == rec2_f_len) { if (rec1_f_len == rec2_f_len) {
goto next_field; if (stats_method == SRV_STATS_METHOD_NULLS_EQUAL) {
goto next_field;
} else {
ret = -1;
}
} else if (rec2_f_len == UNIV_SQL_NULL) { } else if (rec2_f_len == UNIV_SQL_NULL) {
......
...@@ -854,6 +854,9 @@ row_update_statistics_if_needed( ...@@ -854,6 +854,9 @@ row_update_statistics_if_needed(
table->stat_modified_counter = counter + 1; table->stat_modified_counter = counter + 1;
if (!srv_stats_auto_update)
return;
/* Calculate new statistics if 1 / 16 of table has been modified /* Calculate new statistics if 1 / 16 of table has been modified
since the last time a statistics batch was run, or if since the last time a statistics batch was run, or if
stat_modified_counter > 2 000 000 000 (to avoid wrap-around). stat_modified_counter > 2 000 000 000 (to avoid wrap-around).
......
...@@ -12,3 +12,5 @@ INSTALL PLUGIN INNODB_BUFFER_POOL_PAGES SONAME 'ha_innodb.so'; ...@@ -12,3 +12,5 @@ INSTALL PLUGIN INNODB_BUFFER_POOL_PAGES SONAME 'ha_innodb.so';
INSTALL PLUGIN INNODB_BUFFER_POOL_PAGES_BLOB SONAME 'ha_innodb.so'; INSTALL PLUGIN INNODB_BUFFER_POOL_PAGES_BLOB SONAME 'ha_innodb.so';
INSTALL PLUGIN INNODB_BUFFER_POOL_PAGES_INDEX SONAME 'ha_innodb.so'; INSTALL PLUGIN INNODB_BUFFER_POOL_PAGES_INDEX SONAME 'ha_innodb.so';
INSTALL PLUGIN innodb_rseg SONAME 'ha_innodb.so'; INSTALL PLUGIN innodb_rseg SONAME 'ha_innodb.so';
INSTALL PLUGIN innodb_table_stats SONAME 'ha_innodb.so';
INSTALL PLUGIN innodb_index_stats SONAME 'ha_innodb.so';
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
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