#!!! notice !!!
# Any small change to this file in the main branch
# should be done or reviewed by the maintainer!
-diff -ruN a/sql/sql_base.cc b/sql/sql_base.cc
---- a/sql/sql_base.cc 2011-04-09 18:49:00.000000000 +0400
-+++ b/sql/sql_base.cc 2011-04-09 18:49:02.000000000 +0400
+--- a/sql/sql_base.cc
++++ b/sql/sql_base.cc
@@ -251,8 +251,12 @@
const TABLE_LIST *table_list,
bool tmp_table)
if (tmp_table)
{
int4store(key + key_length, thd->server_id);
-diff -ruN a/sql/sql_parse.cc b/sql/sql_parse.cc
---- a/sql/sql_parse.cc 2011-04-09 18:49:00.000000000 +0400
-+++ b/sql/sql_parse.cc 2011-04-09 18:49:02.000000000 +0400
+--- a/sql/sql_parse.cc
++++ b/sql/sql_parse.cc
@@ -1112,11 +1112,18 @@
break;
#else
thd->set_query(fields, query_length);
general_log_print(thd, command, "%s %s", table_list.table_name, fields);
-diff -ruN a/strings/ctype-utf8.c b/strings/ctype-utf8.c
---- a/strings/ctype-utf8.c 2011-04-09 18:48:03.000000000 +0400
-+++ b/strings/ctype-utf8.c 2011-04-09 18:49:02.000000000 +0400
+--- a/strings/ctype-utf8.c
++++ b/strings/ctype-utf8.c
@@ -4212,6 +4212,10 @@
{
int code;
--- /dev/null
+# name : bug813587.patch
+# maintainer : Alexey
+#
+# Fix for LP bug #813587 / MySQL bug #51196 / MySQL bug #61790
+#
+# Clear MySQL connection errors in ha_federated::close(), since they
+# can affect queries on other tables due to table cache eviction.
+#
+--- a/storage/federated/ha_federated.cc
++++ b/storage/federated/ha_federated.cc
+@@ -1675,6 +1675,8 @@
+
+ int ha_federated::close(void)
+ {
++ THD *thd= current_thd;
++
+ DBUG_ENTER("ha_federated::close");
+
+ free_result();
+@@ -1685,6 +1687,10 @@
+ mysql_close(mysql);
+ mysql= NULL;
+
++ /* Clear possible errors from mysql_close(), see LP bug #813587. */
++ if (thd)
++ thd->clear_error();
++
+ DBUG_RETURN(free_share(share));
+ }
+
#!!! notice !!!
# Any small change to this file in the main branch
# should be done or reviewed by the maintainer!
-diff -ruN a/sql/handler.h b/sql/handler.h
---- a/sql/handler.h 2010-11-03 07:01:14.000000000 +0900
-+++ b/sql/handler.h 2010-12-03 13:51:04.727293058 +0900
-@@ -205,6 +205,8 @@
+--- a/sql/handler.h
++++ b/sql/handler.h
+@@ -206,6 +206,8 @@
#define HA_INPLACE_DROP_UNIQUE_INDEX_NO_WRITE (1L << 9)
#define HA_INPLACE_ADD_PK_INDEX_NO_WRITE (1L << 10)
#define HA_INPLACE_DROP_PK_INDEX_NO_WRITE (1L << 11)
/*
HA_PARTITION_FUNCTION_SUPPORTED indicates that the function is
supported at all.
-diff -ruN a/sql/sql_class.h b/sql/sql_class.h
---- a/sql/sql_class.h 2010-12-02 20:31:56.200956501 +0900
-+++ b/sql/sql_class.h 2010-12-03 13:51:04.744953174 +0900
+--- a/sql/sql_class.h
++++ b/sql/sql_class.h
@@ -481,6 +481,8 @@
my_bool engine_condition_pushdown;
my_bool keep_files_on_create;
my_bool old_alter_table;
my_bool old_passwords;
my_bool big_tables;
-diff -ruN a/sql/sql_partition.cc b/sql/sql_partition.cc
---- a/sql/sql_partition.cc 2010-11-03 07:01:14.000000000 +0900
-+++ b/sql/sql_partition.cc 2010-12-03 13:59:56.444039002 +0900
-@@ -4636,7 +4636,12 @@
+--- a/sql/sql_partition.cc
++++ b/sql/sql_partition.cc
+@@ -4637,7 +4637,12 @@
alter_info->num_parts= curr_part_no - new_part_no;
}
}
{
my_error(ER_PARTITION_FUNCTION_FAILURE, MYF(0));
goto err;
-diff -ruN a/sql/sql_table.cc b/sql/sql_table.cc
---- a/sql/sql_table.cc 2010-11-03 07:01:14.000000000 +0900
-+++ b/sql/sql_table.cc 2010-12-03 13:51:04.768955495 +0900
-@@ -6112,6 +6112,10 @@
+--- a/sql/sql_table.cc
++++ b/sql/sql_table.cc
+@@ -6140,6 +6140,10 @@
uint *idx_end_p;
alter_flags= table->file->alter_table_flags(alter_info->flags);
DBUG_PRINT("info", ("alter_flags: %lu", alter_flags));
/* Check dropped indexes. */
for (idx_p= index_drop_buffer, idx_end_p= idx_p + index_drop_count;
-diff -ruN a/sql/sys_vars.cc b/sql/sys_vars.cc
---- a/sql/sys_vars.cc 2010-12-02 21:23:05.569356468 +0900
-+++ b/sql/sys_vars.cc 2010-12-03 14:05:28.857356603 +0900
+--- a/sql/sys_vars.cc
++++ b/sql/sys_vars.cc
@@ -2186,6 +2186,13 @@
GLOBAL_VAR(opt_optimizer_fix),
NO_CMD_LINE, DEFAULT(TRUE));
#!!! notice !!!
# Any small change to this file in the main branch
# should be done or reviewed by the maintainer!
-diff -ruN a/extra/comp_err.c b/extra/comp_err.c
---- a/extra/comp_err.c 2011-04-09 18:48:04.000000000 +0400
-+++ b/extra/comp_err.c 2011-04-09 18:48:56.000000000 +0400
-@@ -30,11 +30,12 @@
+--- a/extra/comp_err.c
++++ b/extra/comp_err.c
+@@ -32,11 +32,12 @@
#include <assert.h>
#include <my_dir.h>
static char *OUTFILE= (char*) "errmsg.sys";
static char *HEADERFILE= (char*) "mysqld_error.h";
static char *NAMEFILE= (char*) "mysqld_ername.h";
-@@ -89,6 +90,7 @@
+@@ -91,6 +92,7 @@
const char *sql_code1; /* sql state */
const char *sql_code2; /* ODBC state */
struct errors *next_error; /* Pointer to next error */
DYNAMIC_ARRAY msg; /* All language texts for this error */
};
-@@ -127,6 +129,7 @@
+@@ -129,6 +131,7 @@
static struct languages *parse_charset_string(char *str);
static struct errors *parse_error_string(char *ptr, int er_count);
static struct message *parse_message_string(struct message *new_message,
char *str);
-@@ -251,6 +254,11 @@
+@@ -253,6 +256,11 @@
for (tmp_error= error_head; tmp_error; tmp_error= tmp_error->next_error)
{
/*
generating mysqld_error.h
fprintf() will automatically add \r on windows
-@@ -343,12 +351,29 @@
+@@ -345,12 +353,29 @@
"language\n", tmp_error->er_name, tmp_lang->lang_short_name);
goto err;
}
}
/* continue with header of the errmsg.sys file */
-@@ -499,14 +524,26 @@
+@@ -501,14 +526,26 @@
DBUG_RETURN(0);
continue;
}
/* add error to the list */
*tail_error= current_error;
-@@ -847,78 +884,122 @@
+@@ -849,78 +886,122 @@
DBUG_RETURN(new_message);
}
--- a/mysql-test/t/file_contents.test
+++ b/mysql-test/t/file_contents.test
-@@ -20,7 +20,7 @@ if ($dir_bin =~ m|/usr/|) {
+@@ -20,7 +20,7 @@
$dir_docs = "$dir_docs/packages/MySQL-server";
} else {
# RedHat: version number in directory name
}
} elsif ($dir_bin =~ m|/usr$|) {
# RPM build during development
-@@ -28,9 +28,12 @@ if ($dir_bin =~ m|/usr/|) {
+@@ -28,9 +28,12 @@
if(-d "$dir_docs/packages/MySQL-server") {
# SuSE
$dir_docs = "$dir_docs/packages/MySQL-server";
#!!! notice !!!
# Any small change to this file in the main branch
# should be done or reviewed by the maintainer!
-diff -ruN a/storage/innobase/btr/btr0btr.c b/storage/innobase/btr/btr0btr.c
---- a/storage/innobase/btr/btr0btr.c 2010-12-04 15:52:23.355483176 +0900
-+++ b/storage/innobase/btr/btr0btr.c 2010-12-04 16:12:48.639514256 +0900
+--- a/storage/innobase/btr/btr0btr.c
++++ b/storage/innobase/btr/btr0btr.c
@@ -1518,7 +1518,7 @@
}
ut_a(block);
btr_blob_dbg_remove(page, index, "btr_page_empty");
/* Recreate the page: note that global data on page (possible
-@@ -3065,7 +3065,7 @@
+@@ -3066,7 +3066,7 @@
mem_heap_free(heap);
}
/* Make the father empty */
btr_page_empty(father_block, father_page_zip, index, page_level, mtr);
-@@ -3289,7 +3289,7 @@
+@@ -3300,7 +3300,7 @@
goto err_exit;
}
/* Remove the page from the level list */
btr_level_list_remove(space, zip_size, page, mtr);
-@@ -3330,7 +3330,7 @@
+@@ -3345,7 +3345,7 @@
goto err_exit;
}
#ifdef UNIV_BTR_DEBUG
if (UNIV_LIKELY_NULL(merge_page_zip)) {
-@@ -3445,7 +3445,7 @@
+@@ -3469,7 +3469,7 @@
ut_a(btr_page_get_next(page, mtr) == FIL_NULL);
ut_ad(mtr_memo_contains(mtr, block, MTR_MEMO_PAGE_X_FIX));
btr_page_get_father(index, block, mtr, &cursor);
father = btr_cur_get_block(&cursor);
-@@ -3550,7 +3550,7 @@
+@@ -3574,7 +3574,7 @@
page = buf_block_get_frame(block);
ut_a(page_is_comp(merge_page) == page_is_comp(page));
if (left_page_no == FIL_NULL && !page_is_leaf(page)) {
-diff -ruN a/storage/innobase/btr/btr0cur.c b/storage/innobase/btr/btr0cur.c
---- a/storage/innobase/btr/btr0cur.c 2010-12-04 15:52:23.359513820 +0900
-+++ b/storage/innobase/btr/btr0cur.c 2010-12-04 16:12:48.643551837 +0900
+--- a/storage/innobase/btr/btr0cur.c
++++ b/storage/innobase/btr/btr0cur.c
@@ -498,7 +498,7 @@
#ifdef UNIV_SEARCH_PERF_STAT
info->n_searches++;
}
if (page_zip && !dict_index_is_clust(index)
-@@ -2763,7 +2763,7 @@
+@@ -2824,7 +2824,7 @@
}
if (block->is_hashed) {
}
page_zip = buf_block_get_page_zip(block);
-@@ -2779,7 +2779,7 @@
+@@ -2840,7 +2840,7 @@
}
if (block->is_hashed) {
}
btr_cur_del_mark_set_clust_rec_log(flags, rec, index, val, trx,
-@@ -2906,13 +2906,13 @@
+@@ -2967,13 +2967,13 @@
== dict_table_is_comp(cursor->index->table));
if (block->is_hashed) {
}
btr_cur_del_mark_set_sec_rec_log(rec, val, mtr);
-diff -ruN a/storage/innobase/btr/btr0sea.c b/storage/innobase/btr/btr0sea.c
---- a/storage/innobase/btr/btr0sea.c 2010-12-04 15:52:23.387513429 +0900
-+++ b/storage/innobase/btr/btr0sea.c 2010-12-04 16:14:51.721884049 +0900
+--- a/storage/innobase/btr/btr0sea.c
++++ b/storage/innobase/btr/btr0sea.c
@@ -48,6 +48,8 @@
UNIV_INTERN char btr_search_enabled = TRUE;
UNIV_INTERN ibool btr_search_fully_disabled = FALSE;
if (UNIV_LIKELY_NULL(heap)) {
mem_heap_free(heap);
}
-diff -ruN a/storage/innobase/buf/buf0buf.c b/storage/innobase/buf/buf0buf.c
---- a/storage/innobase/buf/buf0buf.c 2010-12-04 15:55:21.351597052 +0900
-+++ b/storage/innobase/buf/buf0buf.c 2010-12-04 16:12:48.654550708 +0900
+--- a/storage/innobase/buf/buf0buf.c
++++ b/storage/innobase/buf/buf0buf.c
@@ -949,6 +949,7 @@
block->check_index_page_at_flush = FALSE;
block->is_hashed = FALSE;
-@@ -1481,7 +1482,7 @@
+@@ -1413,7 +1414,7 @@
/* To follow the latching order, we
have to release btr_search_latch
before acquiring block->latch. */
/* When we release the search latch,
we must rescan all blocks, because
some may become hashed again. */
-@@ -1512,11 +1513,11 @@
+@@ -1444,11 +1445,11 @@
anything. block->is_hashed can only
be set on uncompressed file pages. */
ut_ad(!btr_search_enabled);
}
-@@ -1535,7 +1536,11 @@
+@@ -1467,7 +1468,11 @@
ibool released_search_latch;
#ifdef UNIV_SYNC_DEBUG
#endif /* UNIV_SYNC_DEBUG */
ut_ad(!btr_search_enabled);
-@@ -2655,6 +2660,7 @@
+@@ -2203,6 +2208,7 @@
{
block->check_index_page_at_flush = FALSE;
block->index = NULL;
block->n_hash_helps = 0;
block->is_hashed = FALSE;
-diff -ruN a/storage/innobase/buf/buf0lru.c b/storage/innobase/buf/buf0lru.c
---- a/storage/innobase/buf/buf0lru.c 2010-12-04 15:35:29.137347521 +0900
-+++ b/storage/innobase/buf/buf0lru.c 2010-12-04 16:12:48.658550840 +0900
-@@ -1798,7 +1798,7 @@
+--- a/storage/innobase/buf/buf0lru.c
++++ b/storage/innobase/buf/buf0lru.c
+@@ -560,7 +560,7 @@
+
+ mutex_exit(&buf_pool->LRU_list_mutex);
+
+- rw_lock_s_lock(&btr_search_latch);
++ btr_search_s_lock_all();
+ chunk = buf_pool->chunks;
+ for (j = buf_pool->n_chunks; j--; chunk++) {
+ buf_block_t* block = chunk->blocks;
+@@ -572,16 +572,16 @@
+ continue;
+ }
+
+- rw_lock_s_unlock(&btr_search_latch);
++ btr_search_s_unlock_all();
+
+ rw_lock_x_lock(&block->lock);
+- btr_search_drop_page_hash_index(block);
++ btr_search_drop_page_hash_index(block, NULL);
+ rw_lock_x_unlock(&block->lock);
+
+- rw_lock_s_lock(&btr_search_latch);
++ btr_search_s_lock_all();
+ }
+ }
+- rw_lock_s_unlock(&btr_search_latch);
++ btr_search_s_unlock_all();
+ }
+ }
+
+@@ -1744,7 +1744,7 @@
UNIV_MEM_VALID(((buf_block_t*) bpage)->frame,
UNIV_PAGE_SIZE);
UNIV_MEM_INVALID(((buf_block_t*) bpage)->frame,
UNIV_PAGE_SIZE);
-diff -ruN a/storage/innobase/dict/dict0dict.c b/storage/innobase/dict/dict0dict.c
---- a/storage/innobase/dict/dict0dict.c 2010-12-04 15:52:23.398513916 +0900
-+++ b/storage/innobase/dict/dict0dict.c 2010-12-04 16:12:48.662550715 +0900
-@@ -1811,7 +1811,7 @@
+--- a/storage/innobase/dict/dict0dict.c
++++ b/storage/innobase/dict/dict0dict.c
+@@ -1845,7 +1845,7 @@
zero. */
for (;;) {
if (ref_count == 0) {
break;
}
-diff -ruN a/storage/innobase/ha/ha0ha.c b/storage/innobase/ha/ha0ha.c
---- a/storage/innobase/ha/ha0ha.c 2010-11-03 07:01:13.000000000 +0900
-+++ b/storage/innobase/ha/ha0ha.c 2010-12-04 16:12:48.665593752 +0900
+--- a/storage/innobase/ha/ha0ha.c
++++ b/storage/innobase/ha/ha0ha.c
@@ -102,7 +102,8 @@
ut_ad(table);
ut_ad(table->magic_n == HASH_TABLE_MAGIC_N);
#endif /* UNIV_SYNC_DEBUG */
#ifndef UNIV_HOTBACKUP
-diff -ruN a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc
---- a/storage/innobase/handler/ha_innodb.cc 2010-12-04 16:12:20.185850734 +0900
-+++ b/storage/innobase/handler/ha_innodb.cc 2010-12-04 16:12:48.674552412 +0900
-@@ -11702,6 +11702,11 @@
+--- a/storage/innobase/handler/ha_innodb.cc
++++ b/storage/innobase/handler/ha_innodb.cc
+@@ -11718,6 +11718,11 @@
"Disable with --skip-innodb-adaptive-hash-index.",
NULL, innodb_adaptive_hash_index_update, TRUE);
static MYSQL_SYSVAR_ULONG(replication_delay, srv_replication_delay,
PLUGIN_VAR_RQCMDARG,
"Replication thread delay (ms) on the slave server if "
-@@ -12068,6 +12073,7 @@
+@@ -12085,6 +12090,7 @@
MYSQL_SYSVAR(use_sys_stats_table),
MYSQL_SYSVAR(stats_sample_pages),
MYSQL_SYSVAR(adaptive_hash_index),
MYSQL_SYSVAR(stats_method),
MYSQL_SYSVAR(replication_delay),
MYSQL_SYSVAR(status_file),
-diff -ruN a/storage/innobase/include/btr0sea.h b/storage/innobase/include/btr0sea.h
---- a/storage/innobase/include/btr0sea.h 2010-12-03 15:48:03.070987226 +0900
-+++ b/storage/innobase/include/btr0sea.h 2010-12-04 16:12:48.707551382 +0900
+--- a/storage/innobase/include/btr0sea.h
++++ b/storage/innobase/include/btr0sea.h
@@ -85,7 +85,8 @@
ulint
btr_search_info_get_ref_count(
#ifdef UNIV_SEARCH_PERF_STAT
/** Number of successful adaptive hash index lookups */
-diff -ruN a/storage/innobase/include/btr0sea.ic b/storage/innobase/include/btr0sea.ic
---- a/storage/innobase/include/btr0sea.ic 2010-11-03 07:01:13.000000000 +0900
-+++ b/storage/innobase/include/btr0sea.ic 2010-12-04 16:12:48.709511202 +0900
+--- a/storage/innobase/include/btr0sea.ic
++++ b/storage/innobase/include/btr0sea.ic
@@ -62,8 +62,8 @@
btr_search_t* info;
+ }
+}
+
-diff -ruN a/storage/innobase/include/buf0buf.h b/storage/innobase/include/buf0buf.h
---- a/storage/innobase/include/buf0buf.h 2010-12-15 19:00:07.713604580 +0900
-+++ b/storage/innobase/include/buf0buf.h 2010-12-15 20:58:03.546839883 +0900
-@@ -1546,7 +1546,7 @@
+--- a/storage/innobase/include/buf0buf.h
++++ b/storage/innobase/include/buf0buf.h
+@@ -1585,7 +1585,7 @@
pointers in the adaptive hash index
pointing to this frame */
#endif /* UNIV_AHI_DEBUG || UNIV_DEBUG */
already been built on this
page; note that it does not
guarantee that the index is
-@@ -1560,6 +1560,7 @@
+@@ -1599,6 +1599,7 @@
unsigned curr_left_side:1;/*!< TRUE or FALSE in hash indexing */
dict_index_t* index; /*!< Index for which the adaptive
hash index has been created. */
/* @} */
# ifdef UNIV_SYNC_DEBUG
/** @name Debug fields */
-diff -ruN a/storage/innobase/include/row0upd.ic b/storage/innobase/include/row0upd.ic
---- a/storage/innobase/include/row0upd.ic 2010-11-03 07:01:13.000000000 +0900
-+++ b/storage/innobase/include/row0upd.ic 2010-12-04 16:12:48.710551113 +0900
+--- a/storage/innobase/include/row0upd.ic
++++ b/storage/innobase/include/row0upd.ic
@@ -158,7 +158,7 @@
ut_ad(dict_index_is_clust(index));
ut_ad(rec_offs_validate(rec, index, offsets));
ut_ad(!buf_block_align(rec)->is_hashed);
}
#endif /* UNIV_SYNC_DEBUG */
-diff -ruN a/storage/innobase/page/page0page.c b/storage/innobase/page/page0page.c
---- a/storage/innobase/page/page0page.c 2010-11-03 07:01:13.000000000 +0900
-+++ b/storage/innobase/page/page0page.c 2010-12-04 16:12:48.712550963 +0900
+--- a/storage/innobase/page/page0page.c
++++ b/storage/innobase/page/page0page.c
@@ -218,7 +218,7 @@
const ibool is_hashed = block->is_hashed;
}
#endif /* !UNIV_HOTBACKUP */
}
-diff -ruN a/storage/innobase/page/page0zip.c b/storage/innobase/page/page0zip.c
---- a/storage/innobase/page/page0zip.c 2010-12-04 15:57:13.061494433 +0900
-+++ b/storage/innobase/page/page0zip.c 2010-12-04 16:12:48.716470334 +0900
-@@ -4444,7 +4444,7 @@
+--- a/storage/innobase/page/page0zip.c
++++ b/storage/innobase/page/page0zip.c
+@@ -4456,7 +4456,7 @@
#ifndef UNIV_HOTBACKUP
temp_block = buf_block_alloc(buf_pool);
block->check_index_page_at_flush = TRUE;
#else /* !UNIV_HOTBACKUP */
ut_ad(block == back_block1);
-diff -ruN a/storage/innobase/row/row0sel.c b/storage/innobase/row/row0sel.c
---- a/storage/innobase/row/row0sel.c 2010-12-04 16:09:53.204513572 +0900
-+++ b/storage/innobase/row/row0sel.c 2010-12-04 16:12:48.722551273 +0900
-@@ -1210,7 +1210,7 @@
+--- a/storage/innobase/row/row0mysql.c
++++ b/storage/innobase/row/row0mysql.c
+@@ -2593,7 +2593,7 @@
+ /* check adaptive hash entries */
+ index = dict_table_get_first_index(table);
+ while (index) {
+- ulint ref_count = btr_search_info_get_ref_count(index->search_info);
++ ulint ref_count = btr_search_info_get_ref_count(index->search_info, index->id);
+ if (ref_count) {
+ fprintf(stderr, "InnoDB: Warning:"
+ " hash index ref_count (%lu) is not zero"
+@@ -2954,7 +2954,7 @@
+ table->space = space;
+ index = dict_table_get_first_index(table);
+ do {
+- ulint ref_count = btr_search_info_get_ref_count(index->search_info);
++ ulint ref_count = btr_search_info_get_ref_count(index->search_info, index->id);
+ /* check adaptive hash entries */
+ if (ref_count) {
+ fprintf(stderr, "InnoDB: Warning:"
+--- a/storage/innobase/row/row0sel.c
++++ b/storage/innobase/row/row0sel.c
+@@ -1211,7 +1211,7 @@
ut_ad(plan->unique_search);
ut_ad(!plan->must_get_clust);
#ifdef UNIV_SYNC_DEBUG
#endif /* UNIV_SYNC_DEBUG */
row_sel_open_pcur(plan, TRUE, mtr);
-@@ -1381,10 +1381,10 @@
+@@ -1382,10 +1382,10 @@
&& !plan->must_get_clust
&& !plan->table->big_rows) {
if (!search_latch_locked) {
/* There is an x-latch request waiting: release the
s-latch for a moment; as an s-latch here is often
-@@ -1393,8 +1393,8 @@
+@@ -1394,8 +1394,8 @@
from acquiring an s-latch for a long time, lowering
performance significantly in multiprocessors. */
}
found_flag = row_sel_try_search_shortcut(node, plan, &mtr);
-@@ -1417,7 +1417,7 @@
+@@ -1418,7 +1418,7 @@
}
if (search_latch_locked) {
search_latch_locked = FALSE;
}
-@@ -1993,7 +1993,7 @@
+@@ -1994,7 +1994,7 @@
func_exit:
if (search_latch_locked) {
}
if (UNIV_LIKELY_NULL(heap)) {
mem_heap_free(heap);
-@@ -3356,6 +3356,8 @@
+@@ -3357,6 +3357,8 @@
/* if the returned record was locked and we did a semi-consistent
read (fetch the newest committed version), then this is set to
TRUE */
#ifdef UNIV_SEARCH_DEBUG
ulint cnt = 0;
#endif /* UNIV_SEARCH_DEBUG */
-@@ -3446,18 +3448,33 @@
+@@ -3447,18 +3449,33 @@
/* PHASE 0: Release a possible s-latch we are holding on the
adaptive hash index latch if there is someone waiting behind */
}
/* Reset the new record lock info if srv_locks_unsafe_for_binlog
-@@ -3608,9 +3625,28 @@
+@@ -3609,9 +3626,28 @@
hash index semaphore! */
#ifndef UNIV_SEARCH_DEBUG
}
#endif
switch (row_sel_try_search_shortcut_for_mysql(
-@@ -3671,7 +3707,11 @@
+@@ -3672,7 +3708,11 @@
trx->search_latch_timeout--;
trx->has_search_latch = FALSE;
}
-@@ -3695,7 +3735,12 @@
+@@ -3696,7 +3736,12 @@
/* PHASE 3: Open or restore index cursor position */
if (trx->has_search_latch) {
trx->has_search_latch = FALSE;
}
-diff -ruN a/storage/innobase/srv/srv0srv.c b/storage/innobase/srv/srv0srv.c
---- a/storage/innobase/srv/srv0srv.c 2010-12-04 16:12:20.231484679 +0900
-+++ b/storage/innobase/srv/srv0srv.c 2010-12-04 16:12:48.726551018 +0900
+--- a/storage/innobase/srv/srv0srv.c
++++ b/storage/innobase/srv/srv0srv.c
@@ -2045,7 +2045,9 @@
"-------------------------------------\n", file);
ibuf_print(file);
(ulong) btr_search_sys_subtotal,
(ulong) (buf_pool_from_array(0)->page_hash->n_cells * sizeof(hash_cell_t)),
-diff -ruN a/storage/innobase/sync/sync0sync.c b/storage/innobase/sync/sync0sync.c
---- a/storage/innobase/sync/sync0sync.c 2010-12-03 17:36:44.300986571 +0900
-+++ b/storage/innobase/sync/sync0sync.c 2010-12-04 16:12:48.729513564 +0900
-@@ -1223,7 +1223,6 @@
+--- a/storage/innobase/sync/sync0sync.c
++++ b/storage/innobase/sync/sync0sync.c
+@@ -1228,7 +1228,6 @@
case SYNC_OUTER_ANY_LATCH:
case SYNC_FILE_FORMAT_TAG:
case SYNC_DOUBLEWRITE:
case SYNC_SEARCH_SYS_CONF:
case SYNC_TRX_LOCK_HEAP:
case SYNC_KERNEL:
-@@ -1244,6 +1243,7 @@
+@@ -1249,6 +1248,7 @@
ut_error;
}
break;
case SYNC_BUF_LRU_LIST:
case SYNC_BUF_FLUSH_LIST:
case SYNC_BUF_PAGE_HASH:
-diff -ruN a/storage/innobase/trx/trx0trx.c b/storage/innobase/trx/trx0trx.c
---- a/storage/innobase/trx/trx0trx.c 2010-12-03 17:49:11.623953784 +0900
-+++ b/storage/innobase/trx/trx0trx.c 2010-12-04 16:12:48.731513275 +0900
+--- a/storage/innobase/trx/trx0trx.c
++++ b/storage/innobase/trx/trx0trx.c
@@ -265,8 +265,14 @@
/*=================================*/
trx_t* trx) /*!< in: transaction */
#!!! notice !!!
# Any small change to this file in the main branch
# should be done or reviewed by the maintainer!
-diff -ruN a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc
---- a/storage/innobase/handler/ha_innodb.cc 2010-12-03 17:32:15.624039043 +0900
-+++ b/storage/innobase/handler/ha_innodb.cc 2010-12-03 17:32:35.424957827 +0900
-@@ -11863,7 +11863,8 @@
+--- a/storage/innobase/handler/ha_innodb.cc
++++ b/storage/innobase/handler/ha_innodb.cc
+@@ -11880,7 +11880,8 @@
i_s_innodb_sys_foreign_cols,
i_s_innodb_sys_stats,
i_s_innodb_table_stats,
mysql_declare_plugin_end;
/** @brief Initialize the default value of innodb_commit_concurrency.
-diff -ruN a/storage/innobase/handler/i_s.cc b/storage/innobase/handler/i_s.cc
---- a/storage/innobase/handler/i_s.cc 2010-12-03 17:30:16.299955549 +0900
-+++ b/storage/innobase/handler/i_s.cc 2010-12-03 17:32:35.425989972 +0900
+--- a/storage/innobase/handler/i_s.cc
++++ b/storage/innobase/handler/i_s.cc
@@ -4177,3 +4177,139 @@
STRUCT_FLD(system_vars, NULL),
STRUCT_FLD(__reserved1, NULL)
+ STRUCT_FLD(system_vars, NULL),
+ STRUCT_FLD(__reserved1, NULL)
+};
-diff -ruN a/storage/innobase/handler/i_s.h b/storage/innobase/handler/i_s.h
---- a/storage/innobase/handler/i_s.h 2010-12-03 17:30:16.301987692 +0900
-+++ b/storage/innobase/handler/i_s.h 2010-12-03 17:32:35.426954555 +0900
+--- a/storage/innobase/handler/i_s.h
++++ b/storage/innobase/handler/i_s.h
@@ -46,5 +46,6 @@
extern struct st_mysql_plugin i_s_innodb_sys_stats;
extern struct st_mysql_plugin i_s_innodb_table_stats;
#!!! notice !!!
# Any small change to this file in the main branch
# should be done or reviewed by the maintainer!
-diff -ruN a/storage/innobase/buf/buf0buf.c b/storage/innobase/buf/buf0buf.c
---- a/storage/innobase/buf/buf0buf.c 2010-12-04 20:20:44.595483291 +0900
-+++ b/storage/innobase/buf/buf0buf.c 2010-12-06 19:28:04.055227506 +0900
-@@ -4560,6 +4560,36 @@
+--- a/storage/innobase/buf/buf0buf.c
++++ b/storage/innobase/buf/buf0buf.c
+@@ -4157,6 +4157,36 @@
mutex_exit(block_mutex);
}
/*********************************************************************//**
Asserts that all file pages in the buffer are in a replaceable state.
@return TRUE */
-diff -ruN a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc
---- a/storage/innobase/handler/ha_innodb.cc 2010-12-04 20:20:44.614551139 +0900
-+++ b/storage/innobase/handler/ha_innodb.cc 2010-12-06 19:23:47.622195800 +0900
-@@ -12148,6 +12148,9 @@
+--- a/storage/innobase/handler/ha_innodb.cc
++++ b/storage/innobase/handler/ha_innodb.cc
+@@ -12165,6 +12165,9 @@
i_s_innodb_sys_stats,
i_s_innodb_table_stats,
i_s_innodb_index_stats,
i_s_innodb_admin_command
mysql_declare_plugin_end;
-diff -ruN a/storage/innobase/handler/i_s.cc b/storage/innobase/handler/i_s.cc
---- a/storage/innobase/handler/i_s.cc 2010-12-04 19:46:39.786513783 +0900
-+++ b/storage/innobase/handler/i_s.cc 2010-12-06 19:28:52.270226921 +0900
+--- a/storage/innobase/handler/i_s.cc
++++ b/storage/innobase/handler/i_s.cc
@@ -51,6 +51,7 @@
#include "trx0sys.h" /* for trx_sys */
#include "dict0dict.h" /* for dict_sys */
+ STRUCT_FLD(__reserved1, NULL)
+};
+
-diff -ruN a/storage/innobase/handler/i_s.h b/storage/innobase/handler/i_s.h
---- a/storage/innobase/handler/i_s.h 2010-12-04 19:46:39.657513849 +0900
-+++ b/storage/innobase/handler/i_s.h 2010-12-06 19:23:47.635192988 +0900
+--- a/storage/innobase/handler/i_s.h
++++ b/storage/innobase/handler/i_s.h
@@ -47,5 +47,8 @@
extern struct st_mysql_plugin i_s_innodb_table_stats;
extern struct st_mysql_plugin i_s_innodb_index_stats;
+extern struct st_mysql_plugin i_s_innodb_buffer_pool_pages_blob;
#endif /* i_s_h */
-diff -ruN a/storage/innobase/include/buf0buf.h b/storage/innobase/include/buf0buf.h
---- a/storage/innobase/include/buf0buf.h 2010-12-04 19:46:40.197471531 +0900
-+++ b/storage/innobase/include/buf0buf.h 2010-12-06 19:23:47.638195824 +0900
-@@ -1144,6 +1144,14 @@
+--- a/storage/innobase/include/buf0buf.h
++++ b/storage/innobase/include/buf0buf.h
+@@ -1183,6 +1183,14 @@
/*===========*/
const buf_pool_t* buf_pool) /*!< in: buffer pool */
__attribute__((nonnull, const));
#!!! notice !!!
# Any small change to this file in the main branch
# should be done or reviewed by the maintainer!
-diff -ruN a/storage/innobase/buf/buf0buf.c b/storage/innobase/buf/buf0buf.c
---- a/storage/innobase/buf/buf0buf.c 2011-04-09 18:48:47.000000000 +0400
-+++ b/storage/innobase/buf/buf0buf.c 2011-04-09 18:48:48.000000000 +0400
+--- a/storage/innobase/buf/buf0buf.c
++++ b/storage/innobase/buf/buf0buf.c
@@ -1006,10 +1006,12 @@
buf_block_t* block;
byte* frame;
/* Init block structs and assign frames for them. Then we
assign the frames to the first blocks (we already mapped the
memory above). */
-diff -ruN a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc
---- a/storage/innobase/handler/ha_innodb.cc 2011-04-09 18:48:47.000000000 +0400
-+++ b/storage/innobase/handler/ha_innodb.cc 2011-04-09 18:48:48.000000000 +0400
-@@ -194,6 +194,8 @@
- static my_bool innobase_create_status_file = FALSE;
+--- a/storage/innobase/handler/ha_innodb.cc
++++ b/storage/innobase/handler/ha_innodb.cc
+@@ -195,6 +195,8 @@
static my_bool innobase_stats_on_metadata = TRUE;
+ static my_bool innobase_large_prefix = FALSE;
static my_bool innobase_use_sys_stats_table = FALSE;
+static my_bool innobase_buffer_pool_shm_checksum = TRUE;
+static uint innobase_buffer_pool_shm_key = 0;
static char* internal_innobase_data_file_path = NULL;
-@@ -2670,6 +2672,12 @@
+@@ -2675,6 +2677,12 @@
srv_buf_pool_size = (ulint) innobase_buffer_pool_size;
srv_buf_pool_instances = (ulint) innobase_buffer_pool_instances;
srv_mem_pool_size = (ulint) innobase_additional_mem_pool_size;
srv_n_file_io_threads = (ulint) innobase_file_io_threads;
-@@ -11733,6 +11741,16 @@
+@@ -11749,6 +11757,16 @@
"Number of buffer pool instances, set to higher value on high-end machines to increase scalability",
NULL, NULL, 1L, 1L, MAX_BUFFER_POOLS, 1L);
static MYSQL_SYSVAR_ULONG(commit_concurrency, innobase_commit_concurrency,
PLUGIN_VAR_RQCMDARG,
"Helps in performance tuning in heavily concurrent environments.",
-@@ -12027,6 +12045,8 @@
+@@ -12043,6 +12061,8 @@
MYSQL_SYSVAR(autoextend_increment),
MYSQL_SYSVAR(buffer_pool_size),
MYSQL_SYSVAR(buffer_pool_instances),
# Changes InnoDB IO code so that fsync(), pread() and pwrite() are restarted
# when interrupted by a signal.
#
-diff -ruN a/storage/innobase/os/os0file.c b/storage/innobase/os/os0file.c
---- a/storage/innobase/os/os0file.c 2011-04-20 12:09:57.000000000 +0400
-+++ b/storage/innobase/os/os0file.c 2011-04-20 12:10:04.000000000 +0400
-@@ -2092,6 +2092,9 @@
+--- a/storage/innobase/os/os0file.c
++++ b/storage/innobase/os/os0file.c
+@@ -2093,6 +2093,9 @@
failures++;
retry = TRUE;
} else {
retry = FALSE;
-@@ -2222,6 +2225,7 @@
+@@ -2223,6 +2226,7 @@
off_t offs;
#if defined(HAVE_PREAD) && !defined(HAVE_BROKEN_PREAD)
ssize_t n_bytes;
#endif /* HAVE_PREAD && !HAVE_BROKEN_PREAD */
ulint sec;
ulint ms;
-@@ -2262,7 +2266,18 @@
+@@ -2263,7 +2267,18 @@
os_n_pending_reads++;
os_mutex_exit(os_file_count_mutex);
os_mutex_enter(os_file_count_mutex);
os_file_n_pending_preads--;
-@@ -2281,6 +2296,7 @@
+@@ -2282,6 +2297,7 @@
{
off_t ret_offset;
ssize_t ret;
#ifndef UNIV_HOTBACKUP
ulint i;
#endif /* !UNIV_HOTBACKUP */
-@@ -2301,7 +2317,17 @@
+@@ -2302,7 +2318,17 @@
if (ret_offset < 0) {
ret = -1;
} else {
}
#ifndef UNIV_HOTBACKUP
-@@ -2340,6 +2366,7 @@
+@@ -2341,6 +2367,7 @@
offset */
{
ssize_t ret;
off_t offs;
ut_a((offset & 0xFFFFFFFFUL) == offset);
-@@ -2367,7 +2394,18 @@
+@@ -2368,7 +2395,18 @@
os_n_pending_writes++;
os_mutex_exit(os_file_count_mutex);
os_mutex_enter(os_file_count_mutex);
os_file_n_pending_pwrites--;
-@@ -2414,7 +2452,17 @@
+@@ -2415,7 +2453,17 @@
goto func_exit;
}
#!!! notice !!!
# Any small change to this file in the main branch
# should be done or reviewed by the maintainer!
-diff -ruN a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc
---- a/storage/innobase/handler/ha_innodb.cc 2010-12-04 16:09:53.145500265 +0900
-+++ b/storage/innobase/handler/ha_innodb.cc 2010-12-04 16:10:24.605515894 +0900
-@@ -686,6 +686,8 @@
+--- a/storage/innobase/handler/ha_innodb.cc
++++ b/storage/innobase/handler/ha_innodb.cc
+@@ -687,6 +687,8 @@
(char*) &export_vars.innodb_dblwr_pages_written, SHOW_LONG},
{"dblwr_writes",
(char*) &export_vars.innodb_dblwr_writes, SHOW_LONG},
{"dict_tables",
(char*) &export_vars.innodb_dict_tables, SHOW_LONG},
{"have_atomic_builtins",
-diff -ruN a/storage/innobase/include/lock0lock.h b/storage/innobase/include/lock0lock.h
---- a/storage/innobase/include/lock0lock.h 2010-11-03 07:01:13.000000000 +0900
-+++ b/storage/innobase/include/lock0lock.h 2010-12-04 16:10:24.605515894 +0900
+--- a/storage/innobase/include/lock0lock.h
++++ b/storage/innobase/include/lock0lock.h
@@ -43,6 +43,7 @@
#endif /* UNIV_DEBUG */
/* Buffer for storing information about the most recent deadlock error */
/*********************************************************************//**
Gets the size of a lock struct.
-diff -ruN a/storage/innobase/include/srv0srv.h b/storage/innobase/include/srv0srv.h
---- a/storage/innobase/include/srv0srv.h 2010-12-04 15:55:21.378480843 +0900
-+++ b/storage/innobase/include/srv0srv.h 2010-12-04 16:10:24.606550983 +0900
+--- a/storage/innobase/include/srv0srv.h
++++ b/storage/innobase/include/srv0srv.h
@@ -758,6 +758,7 @@
ulint innodb_buffer_pool_read_ahead_evicted;/*!< srv_read_ahead evicted*/
ulint innodb_dblwr_pages_written; /*!< srv_dblwr_pages_written */
ibool innodb_have_atomic_builtins; /*!< HAVE_ATOMIC_BUILTINS */
ulint innodb_log_waits; /*!< srv_log_waits */
ulint innodb_log_write_requests; /*!< srv_log_write_requests */
-diff -ruN a/storage/innobase/lock/lock0lock.c b/storage/innobase/lock/lock0lock.c
---- a/storage/innobase/lock/lock0lock.c 2010-12-03 17:49:11.609953956 +0900
-+++ b/storage/innobase/lock/lock0lock.c 2010-12-04 16:10:24.608513889 +0900
-@@ -3328,6 +3328,7 @@
+--- a/storage/innobase/lock/lock0lock.c
++++ b/storage/innobase/lock/lock0lock.c
+@@ -3330,6 +3330,7 @@
break;
case LOCK_VICTIM_IS_START:
fputs("*** WE ROLL BACK TRANSACTION (2)\n",
lock_latest_err_file);
break;
-diff -ruN a/storage/innobase/srv/srv0srv.c b/storage/innobase/srv/srv0srv.c
---- a/storage/innobase/srv/srv0srv.c 2010-12-04 15:57:13.069513371 +0900
-+++ b/storage/innobase/srv/srv0srv.c 2010-12-04 16:10:24.610593039 +0900
+--- a/storage/innobase/srv/srv0srv.c
++++ b/storage/innobase/srv/srv0srv.c
@@ -468,6 +468,7 @@
static ulint srv_n_rows_deleted_old = 0;
static ulint srv_n_rows_read_old = 0;
#!!! notice !!!
# Any small change to this file in the main branch
# should be done or reviewed by the maintainer!
-diff -ruN a/storage/innobase/btr/btr0sea.c b/storage/innobase/btr/btr0sea.c
---- a/storage/innobase/btr/btr0sea.c 2010-11-03 07:01:13.000000000 +0900
-+++ b/storage/innobase/btr/btr0sea.c 2010-12-03 15:45:47.503988924 +0900
+--- a/storage/innobase/btr/btr0sea.c
++++ b/storage/innobase/btr/btr0sea.c
@@ -1185,6 +1185,179 @@
mem_free(folds);
}
/********************************************************************//**
Drops a page hash index when a page is freed from a fseg to the file system.
Drops possible hash index if the page happens to be in the buffer pool. */
-diff -ruN a/storage/innobase/buf/buf0buf.c b/storage/innobase/buf/buf0buf.c
---- a/storage/innobase/buf/buf0buf.c 2011-02-01 18:00:03.000000000 +0900
-+++ b/storage/innobase/buf/buf0buf.c 2011-02-01 18:01:59.000000000 +0900
+--- a/storage/innobase/buf/buf0buf.c
++++ b/storage/innobase/buf/buf0buf.c
@@ -294,14 +294,14 @@
# endif /* !PFS_SKIP_BUFFER_MUTEX_RWLOCK */
#endif /* UNIV_PFS_MUTEX || UNIV_PFS_RWLOCK */
#endif /* !UNIV_HOTBACKUP */
/********************************************************************//**
-diff -ruN a/storage/innobase/dict/dict0boot.c b/storage/innobase/dict/dict0boot.c
---- a/storage/innobase/dict/dict0boot.c 2010-11-03 07:01:13.000000000 +0900
-+++ b/storage/innobase/dict/dict0boot.c 2010-12-03 15:45:47.503988924 +0900
+--- a/storage/innobase/dict/dict0boot.c
++++ b/storage/innobase/dict/dict0boot.c
@@ -284,6 +284,7 @@
system tables */
/*-------------------------*/
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);
-diff -ruN a/storage/innobase/dict/dict0crea.c b/storage/innobase/dict/dict0crea.c
---- a/storage/innobase/dict/dict0crea.c 2010-11-03 07:01:13.000000000 +0900
-+++ b/storage/innobase/dict/dict0crea.c 2010-12-03 15:45:47.521955810 +0900
-@@ -1210,6 +1210,9 @@
+--- a/storage/innobase/dict/dict0crea.c
++++ b/storage/innobase/dict/dict0crea.c
+@@ -1209,6 +1209,9 @@
/* Foreign constraint system tables have already been
created, and they are ok */
mutex_exit(&(dict_sys->mutex));
return(DB_SUCCESS);
-@@ -1291,6 +1294,11 @@
+@@ -1290,6 +1293,11 @@
trx_commit_for_mysql(trx);
row_mysql_unlock_data_dictionary(trx);
trx_free_for_mysql(trx);
-diff -ruN a/storage/innobase/dict/dict0dict.c b/storage/innobase/dict/dict0dict.c
---- a/storage/innobase/dict/dict0dict.c 2010-11-03 07:01:13.000000000 +0900
-+++ b/storage/innobase/dict/dict0dict.c 2010-12-03 15:45:47.525953769 +0900
+--- a/storage/innobase/dict/dict0dict.c
++++ b/storage/innobase/dict/dict0dict.c
@@ -626,6 +626,8 @@
table = dict_table_get_on_id_low(table_id);
/****************************************************************//**
If the given column name is reserved for InnoDB system columns, return
TRUE.
-@@ -1728,6 +1790,11 @@
+@@ -1762,6 +1824,11 @@
ut_ad(index->magic_n == DICT_INDEX_MAGIC_N);
ut_ad(mutex_own(&(dict_sys->mutex)));
/* We always create search info whether or not adaptive
hash index is enabled or not. */
info = index->search_info;
-diff -ruN a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc
---- a/storage/innobase/handler/ha_innodb.cc 2010-12-03 15:43:57.294986852 +0900
-+++ b/storage/innobase/handler/ha_innodb.cc 2010-12-03 15:45:47.534959966 +0900
-@@ -674,6 +674,8 @@
+--- a/storage/innobase/handler/ha_innodb.cc
++++ b/storage/innobase/handler/ha_innodb.cc
+@@ -675,6 +675,8 @@
(char*) &export_vars.innodb_dblwr_pages_written, SHOW_LONG},
{"dblwr_writes",
(char*) &export_vars.innodb_dblwr_writes, SHOW_LONG},
{"have_atomic_builtins",
(char*) &export_vars.innodb_have_atomic_builtins, SHOW_BOOL},
{"log_waits",
-@@ -11642,6 +11644,11 @@
+@@ -11658,6 +11660,11 @@
"Choose method of innodb_adaptive_flushing. (native, [estimate], keep_average)",
NULL, innodb_adaptive_flushing_method_update, 1, &adaptive_flushing_method_typelib);
static struct st_mysql_sys_var* innobase_system_variables[]= {
MYSQL_SYSVAR(additional_mem_pool_size),
MYSQL_SYSVAR(autoextend_increment),
-@@ -11709,6 +11716,7 @@
+@@ -11726,6 +11733,7 @@
MYSQL_SYSVAR(flush_neighbor_pages),
MYSQL_SYSVAR(read_ahead),
MYSQL_SYSVAR(adaptive_flushing_method),
MYSQL_SYSVAR(use_sys_malloc),
MYSQL_SYSVAR(use_native_aio),
MYSQL_SYSVAR(change_buffering),
-diff -ruN a/storage/innobase/ibuf/ibuf0ibuf.c b/storage/innobase/ibuf/ibuf0ibuf.c
---- a/storage/innobase/ibuf/ibuf0ibuf.c 2010-12-03 15:18:48.889024455 +0900
-+++ b/storage/innobase/ibuf/ibuf0ibuf.c 2010-12-03 15:45:47.553025057 +0900
+--- a/storage/innobase/ibuf/ibuf0ibuf.c
++++ b/storage/innobase/ibuf/ibuf0ibuf.c
@@ -566,6 +566,7 @@
/* Use old-style record format for the insert buffer. */
dict_mem_table_add_col(table, heap, "DUMMY_COLUMN", DATA_BINARY, 0, 0);
-diff -ruN a/storage/innobase/include/btr0sea.h b/storage/innobase/include/btr0sea.h
---- a/storage/innobase/include/btr0sea.h 2010-11-03 07:01:13.000000000 +0900
-+++ b/storage/innobase/include/btr0sea.h 2010-12-03 15:45:47.555024229 +0900
+--- a/storage/innobase/include/btr0sea.h
++++ b/storage/innobase/include/btr0sea.h
@@ -140,6 +140,13 @@
s- or x-latched, or an index page
for which we know that
/********************************************************************//**
Drops a page hash index when a page is freed from a fseg to the file system.
Drops possible hash index if the page happens to be in the buffer pool. */
-diff -ruN a/storage/innobase/include/buf0buf.h b/storage/innobase/include/buf0buf.h
---- a/storage/innobase/include/buf0buf.h 2011-02-01 18:00:03.000000000 +0900
-+++ b/storage/innobase/include/buf0buf.h 2011-02-01 18:03:29.000000000 +0900
-@@ -1555,6 +1555,15 @@
+--- a/storage/innobase/include/buf0buf.h
++++ b/storage/innobase/include/buf0buf.h
+@@ -1594,6 +1594,15 @@
#define BUF_POOL_ZIP_FOLD_BPAGE(b) BUF_POOL_ZIP_FOLD((buf_block_t*) (b))
/* @} */
/** @brief The buffer pool statistics structure. */
struct buf_pool_stat_struct{
ulint n_page_gets; /*!< number of page gets performed;
-diff -ruN a/storage/innobase/include/dict0dict.h b/storage/innobase/include/dict0dict.h
---- a/storage/innobase/include/dict0dict.h 2010-11-03 07:01:13.000000000 +0900
-+++ b/storage/innobase/include/dict0dict.h 2010-12-03 15:45:47.558024515 +0900
-@@ -1170,6 +1170,12 @@
+--- a/storage/innobase/include/dict0dict.h
++++ b/storage/innobase/include/dict0dict.h
+@@ -1183,6 +1183,12 @@
/*====================================*/
dict_table_t* table, /*!< in: table */
const char* name); /*!< in: name of the index to find */
/* Buffers for storing detailed information about the latest foreign key
and unique key errors */
extern FILE* dict_foreign_err_file;
-diff -ruN a/storage/innobase/include/dict0dict.ic b/storage/innobase/include/dict0dict.ic
---- a/storage/innobase/include/dict0dict.ic 2010-11-03 07:01:13.000000000 +0900
-+++ b/storage/innobase/include/dict0dict.ic 2010-12-03 15:45:47.560024398 +0900
+--- a/storage/innobase/include/dict0dict.ic
++++ b/storage/innobase/include/dict0dict.ic
@@ -824,6 +824,13 @@
HASH_SEARCH(name_hash, dict_sys->table_hash, table_fold,
dict_table_t*, table, ut_ad(table->cached),
ut_ad(!table || table->cached);
/* TODO: should get the type information from MySQL */
-diff -ruN a/storage/innobase/include/srv0srv.h b/storage/innobase/include/srv0srv.h
---- a/storage/innobase/include/srv0srv.h 2010-12-03 15:43:57.297067100 +0900
-+++ b/storage/innobase/include/srv0srv.h 2010-12-03 15:45:47.562024404 +0900
+--- a/storage/innobase/include/srv0srv.h
++++ b/storage/innobase/include/srv0srv.h
@@ -229,6 +229,7 @@
extern ulint srv_read_ahead;
extern ulint srv_adaptive_flushing_method;
ulint innodb_buffer_pool_pages_total; /*!< Buffer pool size */
ulint innodb_buffer_pool_pages_data; /*!< Data pages */
ulint innodb_buffer_pool_pages_dirty; /*!< Dirty data pages */
-diff -ruN a/storage/innobase/srv/srv0srv.c b/storage/innobase/srv/srv0srv.c
---- a/storage/innobase/srv/srv0srv.c 2010-12-03 15:43:57.301024390 +0900
-+++ b/storage/innobase/srv/srv0srv.c 2010-12-03 15:45:47.565023830 +0900
+--- a/storage/innobase/srv/srv0srv.c
++++ b/storage/innobase/srv/srv0srv.c
@@ -415,6 +415,8 @@
UNIV_INTERN ulint srv_enable_unsafe_group_commit = 0; /* 0:disable 1:enable */
UNIV_INTERN ulint srv_read_ahead = 3; /* 1: random 2: linear 3: Both */
# ALTER TABLE and OPTIMIZE TABLE.
#
#
-diff -ruN a/client/client_priv.h b/client/client_priv.h
---- a/client/client_priv.h 2011-04-11 08:57:20.000000000 +0400
-+++ b/client/client_priv.h 2011-04-11 08:57:21.000000000 +0400
-@@ -90,6 +90,7 @@
+--- a/client/client_priv.h
++++ b/client/client_priv.h
+@@ -92,6 +92,7 @@
OPT_NO_REMOVE_EOL_CARRET,
OPT_DEFAULT_AUTH,
OPT_DEFAULT_PLUGIN,
OPT_MAX_CLIENT_OPTION
};
-diff -ruN a/client/mysqldump.c b/client/mysqldump.c
---- a/client/mysqldump.c 2011-04-11 08:57:17.000000000 +0400
-+++ b/client/mysqldump.c 2011-04-11 08:57:21.000000000 +0400
-@@ -45,6 +45,7 @@
+--- a/client/mysqldump.c
++++ b/client/mysqldump.c
+@@ -47,6 +47,7 @@
#include <m_ctype.h>
#include <hash.h>
#include <stdarg.h>
#include "client_priv.h"
#include "mysql.h"
-@@ -141,6 +142,8 @@
+@@ -143,6 +144,8 @@
static my_bool server_supports_sql_no_fcache= FALSE;
/*
Dynamic_string wrapper functions. In this file use these
wrappers, they will terminate the process if there is
-@@ -186,6 +189,8 @@
+@@ -188,6 +191,8 @@
HASH ignore_table;
static struct my_option my_long_options[] =
{
{"all-databases", 'A',
-@@ -349,6 +354,11 @@
+@@ -351,6 +356,11 @@
"in dump produced with --dump-slave.", &opt_include_master_host_port,
&opt_include_master_host_port, 0, GET_BOOL, NO_ARG,
0, 0, 0, 0, 0, 0},
{"insert-ignore", OPT_INSERT_IGNORE, "Insert rows with INSERT IGNORE.",
&opt_ignore, &opt_ignore, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0,
0, 0},
-@@ -2236,6 +2246,77 @@
+@@ -2238,6 +2248,77 @@
}
/*
get_table_structure -- retrievs database structure, prints out corresponding
CREATE statement and fills out insert_pat if the table is the type we will
be dumping.
-@@ -2476,6 +2557,9 @@
+@@ -2478,6 +2559,9 @@
row= mysql_fetch_row(result);
fprintf(sql_file, (opt_compatible_mode & 3) ? "%s;\n" :
"/*!40101 SET @saved_cs_client = @@character_set_client */;\n"
"/*!40101 SET character_set_client = utf8 */;\n"
-@@ -3570,6 +3654,27 @@
+@@ -3572,6 +3656,27 @@
goto err;
}
/* Moved enable keys to before unlock per bug 15977 */
if (opt_disable_keys)
{
-diff -ruN /dev/null b/mysql-test/r/percona_mysqldump_innodb_optimize_keys.result
---- /dev/null 1970-01-01 00:00:00.000000000 +0000
-+++ b/mysql-test/r/percona_mysqldump_innodb_optimize_keys.result 2011-04-11 08:57:21.000000000 +0400
+--- /dev/null
++++ b/mysql-test/r/percona_mysqldump_innodb_optimize_keys.result
@@ -0,0 +1,109 @@
+#
+# Test the --innodb-optimize-keys option.
+
+######################################
+DROP TABLE t1, t2;
-diff -ruN a/mysql-test/suite/innodb/r/innodb.result b/mysql-test/suite/innodb/r/innodb.result
---- a/mysql-test/suite/innodb/r/innodb.result 2011-03-31 17:36:17.000000000 +0400
-+++ b/mysql-test/suite/innodb/r/innodb.result 2011-04-11 23:26:45.000000000 +0400
+--- a/mysql-test/suite/innodb/r/innodb.result
++++ b/mysql-test/suite/innodb/r/innodb.result
@@ -1673,7 +1673,7 @@
71
SELECT variable_value - @innodb_rows_inserted_orig FROM information_schema.global_status WHERE LOWER(variable_name) = 'innodb_rows_inserted';
SELECT variable_value - @innodb_rows_updated_orig FROM information_schema.global_status WHERE LOWER(variable_name) = 'innodb_rows_updated';
variable_value - @innodb_rows_updated_orig
866
-diff -ruN a/mysql-test/suite/innodb/t/innodb-index.test b/mysql-test/suite/innodb/t/innodb-index.test
---- a/mysql-test/suite/innodb/t/innodb-index.test 2011-03-31 17:36:17.000000000 +0400
-+++ b/mysql-test/suite/innodb/t/innodb-index.test 2011-04-11 08:57:21.000000000 +0400
-@@ -28,6 +28,11 @@
+--- a/mysql-test/suite/innodb/t/innodb-index.test
++++ b/mysql-test/suite/innodb/t/innodb-index.test
+@@ -87,6 +87,11 @@
show create table t1;
--error ER_MULTIPLE_PRI_KEY
alter table t1 add primary key (c);
--error ER_DUP_ENTRY
alter table t1 drop primary key, add primary key (b);
create unique index c on t1 (c);
-diff -ruN a/mysql-test/suite/innodb/t/innodb.test b/mysql-test/suite/innodb/t/innodb.test
---- a/mysql-test/suite/innodb/t/innodb.test 2011-03-31 17:36:17.000000000 +0400
-+++ b/mysql-test/suite/innodb/t/innodb.test 2011-04-11 08:57:21.000000000 +0400
+--- a/mysql-test/suite/innodb/t/innodb.test
++++ b/mysql-test/suite/innodb/t/innodb.test
@@ -21,6 +21,12 @@
-- source include/have_innodb.inc
let $MYSQLD_DATADIR= `select @@datadir`;
# Save the original values of some variables in order to be able to
-diff -ruN /dev/null b/mysql-test/t/percona_mysqldump_innodb_optimize_keys.test
---- /dev/null 1970-01-01 00:00:00.000000000 +0000
-+++ b/mysql-test/t/percona_mysqldump_innodb_optimize_keys.test 2011-04-11 08:57:21.000000000 +0400
+--- /dev/null
++++ b/mysql-test/t/percona_mysqldump_innodb_optimize_keys.test
@@ -0,0 +1,62 @@
+# Embedded server doesn't support external clients
+--source include/not_embedded.inc
+
+# Wait till we reached the initial number of concurrent sessions
+--source include/wait_until_count_sessions.inc
-diff -ruN a/sql/sql_lex.cc b/sql/sql_lex.cc
---- a/sql/sql_lex.cc 2011-04-11 08:57:17.000000000 +0400
-+++ b/sql/sql_lex.cc 2011-04-11 08:57:21.000000000 +0400
+--- a/sql/sql_lex.cc
++++ b/sql/sql_lex.cc
@@ -1630,6 +1630,9 @@
alter_list(rhs.alter_list, mem_root),
key_list(rhs.key_list, mem_root),
/* partition_names are not deeply copied currently */
}
-diff -ruN a/sql/sql_lex.h b/sql/sql_lex.h
---- a/sql/sql_lex.h 2011-04-11 08:57:19.000000000 +0400
-+++ b/sql/sql_lex.h 2011-04-11 08:57:21.000000000 +0400
-@@ -1003,6 +1003,9 @@
+--- a/sql/sql_lex.h
++++ b/sql/sql_lex.h
+@@ -1009,6 +1009,9 @@
List<Alter_column> alter_list;
List<Key> key_list;
List<Create_field> create_list;
uint flags;
enum enum_enable_or_disable keys_onoff;
enum tablespace_op_type tablespace_op;
-@@ -1014,6 +1017,8 @@
+@@ -1020,6 +1023,8 @@
Alter_info() :
flags(0),
keys_onoff(LEAVE_AS_IS),
tablespace_op(NO_TABLESPACE_OP),
-@@ -1029,6 +1034,9 @@
+@@ -1035,6 +1040,9 @@
alter_list.empty();
key_list.empty();
create_list.empty();
flags= 0;
keys_onoff= LEAVE_AS_IS;
tablespace_op= NO_TABLESPACE_OP;
-diff -ruN a/sql/sql_table.cc b/sql/sql_table.cc
---- a/sql/sql_table.cc 2011-04-11 08:56:57.000000000 +0400
-+++ b/sql/sql_table.cc 2011-04-11 23:30:02.000000000 +0400
-@@ -2773,7 +2773,7 @@
+--- a/sql/sql_table.cc
++++ b/sql/sql_table.cc
+@@ -2776,7 +2776,7 @@
file The handler for the new table.
key_info_buffer OUT An array of KEY structs for the indexes.
key_count OUT The number of elements in the array.
DESCRIPTION
Prepares the table and key structures for table creation.
-@@ -3119,7 +3119,6 @@
+@@ -3122,7 +3122,6 @@
}
/* Create keys */
List_iterator<Key> key_iterator(alter_info->key_list);
List_iterator<Key> key_iterator2(alter_info->key_list);
uint key_parts=0, fk_key_count=0;
-@@ -3217,6 +3216,14 @@
+@@ -3220,6 +3219,14 @@
if (!*key_info_buffer || ! key_part_info)
DBUG_RETURN(TRUE); // Out of memory
key_iterator.rewind();
key_number=0;
for (; (key=key_iterator++) ; key_number++)
-@@ -3635,6 +3642,22 @@
+@@ -3638,6 +3645,22 @@
key_info->comment.str= key->key_create_info.comment.str;
}
key_info++;
}
if (!unique_key && !primary_key &&
-@@ -5247,6 +5270,10 @@
+@@ -5256,6 +5279,10 @@
List<Create_field> new_create_list;
/* New key definitions are added here */
List<Key> new_key_list;
List_iterator<Alter_drop> drop_it(alter_info->drop_list);
List_iterator<Create_field> def_it(alter_info->create_list);
List_iterator<Alter_column> alter_it(alter_info->alter_list);
-@@ -5259,6 +5286,7 @@
+@@ -5268,6 +5295,7 @@
uint used_fields= create_info->used_fields;
KEY *key_info=table->key_info;
bool rc= TRUE;
DBUG_ENTER("mysql_prepare_alter_table");
-@@ -5431,7 +5459,23 @@
+@@ -5457,7 +5485,23 @@
/*
Collect all keys which isn't in drop list. Add only those
for which some fields exists.
for (uint i=0 ; i < table->s->keys ; i++,key_info++)
{
-@@ -5548,6 +5592,8 @@
+@@ -5574,6 +5618,8 @@
test(key_info->flags & HA_GENERATED_KEY),
key_parts);
new_key_list.push_back(key);
}
}
{
-@@ -5555,7 +5601,21 @@
+@@ -5581,7 +5627,21 @@
while ((key=key_it++)) // Add new keys
{
if (key->type != Key::FOREIGN_KEY)
if (key->name.str &&
!my_strcasecmp(system_charset_info, key->name.str, primary_key_name))
{
-@@ -5604,12 +5664,100 @@
+@@ -5630,12 +5690,104 @@
rc= FALSE;
alter_info->create_list.swap(new_create_list);
alter_info->key_list.swap(new_key_list);
+ for (key_part= key->key_part; key_part < part_end; key_part++)
+ key_part->field= table->field[key_part->fieldnr];
+ }
-+
++ handler_add_index *add;
+ if ((error= table->file->add_index(table, alter_info->delayed_key_info,
-+ alter_info->delayed_key_count)))
++ alter_info->delayed_key_count, &add)))
+ {
+ /*
+ Exchange the key_info for the error message. If we exchange
+
+ DBUG_RETURN(error);
+ }
++ if ((error= table->file->final_add_index(add, true)))
++ {
++ table->file->print_error(error, MYF(0));
++ }
+
-+ DBUG_RETURN(0);
++ DBUG_RETURN(error);
+}
+
+/*
Alter table
SYNOPSIS
-@@ -6400,19 +6548,38 @@
+@@ -6428,19 +6580,38 @@
*/
if (new_table && !(new_table->file->ha_table_flags() & HA_NO_COPY_ON_ALTER))
{
#!!! notice !!!
# Any small change to this file in the main branch
# should be done or reviewed by the maintainer!
-diff -ruN a/storage/innobase/btr/btr0btr.c b/storage/innobase/btr/btr0btr.c
---- a/storage/innobase/btr/btr0btr.c 2011-04-11 19:44:03.000000000 +0900
-+++ b/storage/innobase/btr/btr0btr.c 2011-05-24 20:30:12.455852287 +0900
+--- a/storage/innobase/btr/btr0btr.c
++++ b/storage/innobase/btr/btr0btr.c
@@ -837,7 +837,7 @@
/**************************************************************//**
Creates a new index page (not the root, and also not
void
btr_attach_half_pages(
/*==================*/
-diff -ruN a/storage/innobase/fil/fil0fil.c b/storage/innobase/fil/fil0fil.c
---- a/storage/innobase/fil/fil0fil.c 2010-12-03 15:09:51.274957577 +0900
-+++ b/storage/innobase/fil/fil0fil.c 2010-12-03 15:52:23.553986552 +0900
+--- a/storage/innobase/fil/fil0fil.c
++++ b/storage/innobase/fil/fil0fil.c
@@ -40,6 +40,14 @@
#include "dict0dict.h"
#include "page0page.h"
#ifndef UNIV_HOTBACKUP
# include "buf0lru.h"
# include "ibuf0ibuf.h"
-@@ -3032,6 +3040,84 @@
+@@ -3033,6 +3041,84 @@
}
/********************************************************************//**
Tries to open a single-table tablespace and optionally checks the space id is
right in it. If does not succeed, prints an error message to the .err log. This
function is used to open a tablespace when we start up mysqld, and also in
-@@ -3078,7 +3164,7 @@
+@@ -3079,7 +3165,7 @@
file = os_file_create_simple_no_error_handling(
innodb_file_data_key, filepath, OS_FILE_OPEN,
if (!success) {
/* The following call prints an error message */
os_file_get_last_error(TRUE);
-@@ -3125,6 +3211,445 @@
+@@ -3126,6 +3212,445 @@
space_id = fsp_header_get_space_id(page);
space_flags = fsp_header_get_flags(page);
+ ULINT_UNDEFINED, &heap);
+ n_fields = rec_offs_n_fields(offsets);
+ if (!offset) {
-+ offset = row_get_trx_id_offset(rec, index, offsets);
++ offset = row_get_trx_id_offset(index, offsets);
+ }
+ trx_write_trx_id(rec + offset, 1);
+
ut_free(buf2);
if (UNIV_UNLIKELY(space_id != id
-@@ -3166,6 +3691,271 @@
+@@ -3167,6 +3692,271 @@
os_file_close(file);
mem_free(filepath);
+ ULINT_UNDEFINED, &heap);
+ n_fields = rec_offs_n_fields(offsets);
+ if (!offset) {
-+ offset = row_get_trx_id_offset(rec, index, offsets);
++ offset = row_get_trx_id_offset(index, offsets);
+ }
+ trx_write_trx_id(rec + offset, 1);
+
return(success);
}
#endif /* !UNIV_HOTBACKUP */
-diff -ruN a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc
---- a/storage/innobase/handler/ha_innodb.cc 2010-12-03 15:49:59.195023983 +0900
-+++ b/storage/innobase/handler/ha_innodb.cc 2010-12-03 15:52:23.555957062 +0900
-@@ -7377,6 +7377,14 @@
+--- a/storage/innobase/handler/ha_innodb.cc
++++ b/storage/innobase/handler/ha_innodb.cc
+@@ -7388,6 +7388,14 @@
err = row_discard_tablespace_for_mysql(dict_table->name, trx);
} else {
err = row_import_tablespace_for_mysql(dict_table->name, trx);
}
err = convert_error_code_to_mysql(err, dict_table->flags, NULL);
-@@ -11649,6 +11657,11 @@
+@@ -11665,6 +11673,11 @@
"Choose method of innodb_adaptive_flushing. (native, [estimate], keep_average)",
NULL, innodb_adaptive_flushing_method_update, 1, &adaptive_flushing_method_typelib);
static MYSQL_SYSVAR_ULONG(dict_size_limit, srv_dict_size_limit,
PLUGIN_VAR_RQCMDARG,
"Limit the allocated memory for dictionary cache. (0: unlimited)",
-@@ -11721,6 +11734,7 @@
+@@ -11738,6 +11751,7 @@
MYSQL_SYSVAR(flush_neighbor_pages),
MYSQL_SYSVAR(read_ahead),
MYSQL_SYSVAR(adaptive_flushing_method),
MYSQL_SYSVAR(dict_size_limit),
MYSQL_SYSVAR(use_sys_malloc),
MYSQL_SYSVAR(use_native_aio),
-diff -ruN a/storage/innobase/include/btr0btr.h b/storage/innobase/include/btr0btr.h
---- a/storage/innobase/include/btr0btr.h 2011-04-11 19:44:03.000000000 +0900
-+++ b/storage/innobase/include/btr0btr.h 2011-05-24 20:30:12.459853343 +0900
+--- a/storage/innobase/include/btr0btr.h
++++ b/storage/innobase/include/btr0btr.h
@@ -219,6 +219,17 @@
@return the uncompressed page frame */
# define btr_page_get(space,zip_size,page_no,mode,mtr) \
+/*==================*/
+ dict_index_t* index, /*!< in: the index tree */
+ buf_block_t* block, /*!< in/out: page to be split */
-+ rec_t* split_rec, /*!< in: first record on upper
++ const rec_t* split_rec, /*!< in: first record on upper
+ half page */
+ buf_block_t* new_block, /*!< in/out: the new half page */
+ ulint direction, /*!< in: FSP_UP or FSP_DOWN */
/****************************************************************//**
Sets a record as the predefined minimum record. */
UNIV_INTERN
-diff -ruN a/storage/innobase/include/srv0srv.h b/storage/innobase/include/srv0srv.h
---- a/storage/innobase/include/srv0srv.h 2010-12-03 15:48:03.077954270 +0900
-+++ b/storage/innobase/include/srv0srv.h 2010-12-03 15:52:23.561986996 +0900
+--- a/storage/innobase/include/srv0srv.h
++++ b/storage/innobase/include/srv0srv.h
@@ -229,6 +229,8 @@
extern ulint srv_read_ahead;
extern ulint srv_adaptive_flushing_method;
extern ulint srv_dict_size_limit;
/*-------------------------------------------*/
-diff -ruN a/storage/innobase/row/row0mysql.c b/storage/innobase/row/row0mysql.c
---- a/storage/innobase/row/row0mysql.c 2011-04-11 19:44:03.000000000 +0900
-+++ b/storage/innobase/row/row0mysql.c 2011-06-06 11:53:18.395764565 +0900
-@@ -2568,6 +2568,11 @@
+--- a/storage/innobase/row/row0mysql.c
++++ b/storage/innobase/row/row0mysql.c
+@@ -2546,6 +2546,11 @@
current_lsn = log_get_lsn();
/* It is possible, though very improbable, that the lsn's in the
tablespace to be imported have risen above the current system lsn, if
a lengthy purge, ibuf merge, or rollback was performed on a backup
-@@ -2679,6 +2684,11 @@
+@@ -2657,6 +2662,11 @@
trx->op_info = "";
return((int) err);
}
-diff -ruN a/storage/innobase/srv/srv0srv.c b/storage/innobase/srv/srv0srv.c
---- a/storage/innobase/srv/srv0srv.c 2010-12-03 15:49:59.230956118 +0900
-+++ b/storage/innobase/srv/srv0srv.c 2010-12-03 15:52:23.562954411 +0900
+--- a/storage/innobase/srv/srv0srv.c
++++ b/storage/innobase/srv/srv0srv.c
@@ -416,6 +416,8 @@
UNIV_INTERN ulint srv_read_ahead = 3; /* 1: random 2: linear 3: Both */
UNIV_INTERN ulint srv_adaptive_flushing_method = 0; /* 0: native 1: estimate 2: keep_average */
#!!! notice !!!
# Any small change to this file in the main branch
# should be done or reviewed by the maintainer!
-diff -ruN a/storage/innobase/buf/buf0buf.c b/storage/innobase/buf/buf0buf.c
---- a/storage/innobase/buf/buf0buf.c 2010-12-03 15:49:59.175955882 +0900
-+++ b/storage/innobase/buf/buf0buf.c 2010-12-03 17:42:42.074307123 +0900
+--- a/storage/innobase/buf/buf0buf.c
++++ b/storage/innobase/buf/buf0buf.c
@@ -51,6 +51,40 @@
#include "dict0dict.h"
#include "log0recv.h"
/*
IMPLEMENTATION OF THE BUFFER POOL
-@@ -2403,8 +2437,16 @@
+@@ -1930,8 +1964,16 @@
mutex_t* block_mutex;
ibool must_read;
unsigned access_time;
buf_pool->stat.n_page_gets++;
for (;;) {
-@@ -2422,7 +2464,7 @@
+@@ -1949,7 +1991,7 @@
//buf_pool_mutex_exit(buf_pool);
rw_lock_s_unlock(&buf_pool->page_hash_latch);
#if defined UNIV_DEBUG || defined UNIV_BUF_DEBUG
ut_a(++buf_dbg_counter % 37 || buf_validate());
-@@ -2518,6 +2560,13 @@
+@@ -2045,6 +2087,13 @@
/* Let us wait until the read operation
completes */
for (;;) {
enum buf_io_fix io_fix;
-@@ -2532,6 +2581,12 @@
+@@ -2059,6 +2108,12 @@
break;
}
}
}
#ifdef UNIV_IBUF_COUNT_DEBUG
-@@ -2847,6 +2902,11 @@
+@@ -2374,6 +2429,11 @@
ibool must_read;
ulint retries = 0;
mutex_t* block_mutex = NULL;
buf_pool_t* buf_pool = buf_pool_get(space, offset);
ut_ad(mtr);
-@@ -2875,6 +2935,9 @@
+@@ -2403,6 +2463,9 @@
|| ibuf_page_low(space, zip_size, offset,
FALSE, file, line, NULL));
#endif
buf_pool->stat.n_page_gets++;
fold = buf_page_address_fold(space, offset);
loop:
-@@ -2949,7 +3012,7 @@
+@@ -2473,7 +2536,7 @@
return(NULL);
}
retries = 0;
} else if (retries < BUF_PAGE_READ_MAX_RETRIES) {
++retries;
-@@ -3258,6 +3321,13 @@
+@@ -2782,6 +2845,13 @@
/* Let us wait until the read operation
completes */
for (;;) {
enum buf_io_fix io_fix;
-@@ -3272,6 +3342,12 @@
+@@ -2796,6 +2866,12 @@
break;
}
}
}
fix_type = MTR_MEMO_BUF_FIX;
-@@ -3298,13 +3374,17 @@
+@@ -2822,13 +2898,17 @@
read-ahead */
buf_read_ahead_linear(space, zip_size, offset,
return(block);
}
-@@ -3328,6 +3408,7 @@
+@@ -2852,6 +2932,7 @@
unsigned access_time;
ibool success;
ulint fix_type;
ut_ad(block);
ut_ad(mtr);
-@@ -3405,6 +3486,10 @@
+@@ -2929,6 +3010,10 @@
#if defined UNIV_DEBUG_FILE_ACCESSES || defined UNIV_DEBUG
ut_a(block->page.file_page_was_freed == FALSE);
#endif
if (UNIV_UNLIKELY(!access_time)) {
/* In the case of a first access, try to apply linear
read-ahead */
-@@ -3412,7 +3497,7 @@
+@@ -2936,7 +3021,7 @@
buf_read_ahead_linear(buf_block_get_space(block),
buf_block_get_zip_size(block),
buf_block_get_page_no(block),
}
#ifdef UNIV_IBUF_COUNT_DEBUG
-@@ -3422,6 +3507,9 @@
+@@ -2946,6 +3031,9 @@
buf_pool = buf_pool_from_block(block);
buf_pool->stat.n_page_gets++;
return(TRUE);
}
-@@ -3444,6 +3532,7 @@
+@@ -2968,6 +3056,7 @@
buf_pool_t* buf_pool;
ibool success;
ulint fix_type;
ut_ad(mtr);
ut_ad(mtr->state == MTR_ACTIVE);
-@@ -3530,6 +3619,11 @@
+@@ -3054,6 +3143,11 @@
#endif
buf_pool->stat.n_page_gets++;
return(TRUE);
}
-diff -ruN a/storage/innobase/buf/buf0rea.c b/storage/innobase/buf/buf0rea.c
---- a/storage/innobase/buf/buf0rea.c 2010-12-03 17:32:15.617037263 +0900
-+++ b/storage/innobase/buf/buf0rea.c 2010-12-03 17:42:42.075297193 +0900
+--- a/storage/innobase/buf/buf0rea.c
++++ b/storage/innobase/buf/buf0rea.c
@@ -77,7 +77,8 @@
treat the tablespace as dropped; this is a timestamp we
use to stop dangling page reads from a tablespace
}
}
-diff -ruN a/storage/innobase/fil/fil0fil.c b/storage/innobase/fil/fil0fil.c
---- a/storage/innobase/fil/fil0fil.c 2010-12-03 15:53:54.610037199 +0900
-+++ b/storage/innobase/fil/fil0fil.c 2010-12-03 17:42:42.079064198 +0900
-@@ -4747,7 +4747,7 @@
+--- a/storage/innobase/fil/fil0fil.c
++++ b/storage/innobase/fil/fil0fil.c
+@@ -4748,7 +4748,7 @@
node->name, node->handle, buf,
offset_low, offset_high,
page_size * n_pages,
#endif
if (success) {
node->size += n_pages;
-@@ -5074,7 +5074,7 @@
+@@ -5075,7 +5075,7 @@
i/o on a tablespace which does not exist */
UNIV_INTERN
ulint
/*===*/
ulint type, /*!< in: OS_FILE_READ or OS_FILE_WRITE,
ORed to OS_FILE_LOG, if a log i/o
-@@ -5099,8 +5099,9 @@
+@@ -5100,8 +5100,9 @@
void* buf, /*!< in/out: buffer where to store read data
or from where to write; in aio this must be
appropriately aligned */
{
ulint mode;
fil_space_t* space;
-@@ -5268,7 +5269,7 @@
+@@ -5269,7 +5270,7 @@
#else
/* Queue the aio request */
ret = os_aio(type, mode | wake_later, node->name, node->handle, buf,
#endif
ut_a(ret);
-diff -ruN a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc
---- a/storage/innobase/handler/ha_innodb.cc 2010-12-03 17:36:44.293955189 +0900
-+++ b/storage/innobase/handler/ha_innodb.cc 2010-12-03 17:42:42.090024586 +0900
-@@ -1573,6 +1573,16 @@
+--- a/storage/innobase/handler/ha_innodb.cc
++++ b/storage/innobase/handler/ha_innodb.cc
+@@ -1578,6 +1578,16 @@
trx->check_unique_secondary = !thd_test_options(
thd, OPTION_RELAXED_UNIQUE_CHECKS);
DBUG_VOID_RETURN;
}
-@@ -1627,6 +1637,32 @@
+@@ -1632,6 +1642,32 @@
return(trx);
}
/*********************************************************************//**
Note that a transaction has been registered with MySQL.
@return true if transaction is registered with MySQL 2PC coordinator */
-@@ -9301,6 +9337,25 @@
+@@ -9312,6 +9348,25 @@
statement has ended */
if (trx->n_mysql_tables_in_use == 0) {
trx->mysql_n_tables_locked = 0;
prebuilt->used_in_HANDLER = FALSE;
-diff -ruN a/storage/innobase/include/buf0rea.h b/storage/innobase/include/buf0rea.h
---- a/storage/innobase/include/buf0rea.h 2010-12-03 15:18:48.891024406 +0900
-+++ b/storage/innobase/include/buf0rea.h 2010-12-03 17:42:42.096026873 +0900
+--- a/storage/innobase/include/buf0rea.h
++++ b/storage/innobase/include/buf0rea.h
@@ -27,6 +27,7 @@
#define buf0rea_h
/********************************************************************//**
Issues read requests for pages which the ibuf module wants to read in, in
order to contract the insert buffer tree. Technically, this function is like
-diff -ruN a/storage/innobase/include/fil0fil.h b/storage/innobase/include/fil0fil.h
---- a/storage/innobase/include/fil0fil.h 2010-12-03 15:09:51.290958543 +0900
-+++ b/storage/innobase/include/fil0fil.h 2010-12-03 17:42:42.097027548 +0900
+--- a/storage/innobase/include/fil0fil.h
++++ b/storage/innobase/include/fil0fil.h
@@ -611,9 +611,12 @@
Reads or writes data. This operation is asynchronous (aio).
@return DB_SUCCESS, or DB_TABLESPACE_DELETED if we are trying to do
/**********************************************************************//**
Waits for an aio operation to complete. This function is used to write the
handler for completed requests. The aio array of pending requests is divided
-diff -ruN a/storage/innobase/include/os0file.h b/storage/innobase/include/os0file.h
---- a/storage/innobase/include/os0file.h 2010-11-03 07:01:13.000000000 +0900
-+++ b/storage/innobase/include/os0file.h 2010-12-03 17:42:42.100023783 +0900
+--- a/storage/innobase/include/os0file.h
++++ b/storage/innobase/include/os0file.h
@@ -36,6 +36,7 @@
#define os0file_h
/************************************************************************//**
Wakes up all async i/o threads so that they know to exit themselves in
shutdown. */
-diff -ruN a/storage/innobase/include/os0file.ic b/storage/innobase/include/os0file.ic
---- a/storage/innobase/include/os0file.ic 2010-11-03 07:01:13.000000000 +0900
-+++ b/storage/innobase/include/os0file.ic 2010-12-03 17:42:42.102024458 +0900
+--- a/storage/innobase/include/os0file.ic
++++ b/storage/innobase/include/os0file.ic
@@ -229,6 +229,7 @@
(can be used to identify a completed
aio operation); ignored if mode is
register_pfs_file_io_end(locker, n);
-diff -ruN a/storage/innobase/include/srv0srv.h b/storage/innobase/include/srv0srv.h
---- a/storage/innobase/include/srv0srv.h 2010-12-03 17:32:15.634987408 +0900
-+++ b/storage/innobase/include/srv0srv.h 2010-12-03 17:42:42.104028644 +0900
+--- a/storage/innobase/include/srv0srv.h
++++ b/storage/innobase/include/srv0srv.h
@@ -71,6 +71,9 @@
#define SRV_AUTO_EXTEND_INCREMENT \
(srv_auto_extend_increment * ((1024 * 1024) / UNIV_PAGE_SIZE))
/* Mutex for locking srv_monitor_file */
extern mutex_t srv_monitor_file_mutex;
/* Temporary file for innodb monitor output */
-diff -ruN a/storage/innobase/include/trx0trx.h b/storage/innobase/include/trx0trx.h
---- a/storage/innobase/include/trx0trx.h 2010-12-03 15:41:52.049372966 +0900
-+++ b/storage/innobase/include/trx0trx.h 2010-12-03 17:42:42.107024532 +0900
+--- a/storage/innobase/include/trx0trx.h
++++ b/storage/innobase/include/trx0trx.h
@@ -743,6 +743,17 @@
/*------------------------------*/
char detailed_error[256]; /*!< detailed error message for last
};
#define TRX_MAX_N_THREADS 32 /* maximum number of
-diff -ruN a/storage/innobase/lock/lock0lock.c b/storage/innobase/lock/lock0lock.c
---- a/storage/innobase/lock/lock0lock.c 2010-12-03 15:09:51.297986437 +0900
-+++ b/storage/innobase/lock/lock0lock.c 2010-12-03 17:42:42.111024587 +0900
-@@ -1755,6 +1755,8 @@
+--- a/storage/innobase/lock/lock0lock.c
++++ b/storage/innobase/lock/lock0lock.c
+@@ -1765,6 +1765,8 @@
{
lock_t* lock;
trx_t* trx;
ut_ad(mutex_own(&kernel_mutex));
-@@ -1813,6 +1815,10 @@
+@@ -1823,6 +1825,10 @@
trx->que_state = TRX_QUE_LOCK_WAIT;
trx->was_chosen_as_deadlock_victim = FALSE;
trx->wait_started = time(NULL);
ut_a(que_thr_stop(thr));
-@@ -3764,6 +3770,8 @@
+@@ -3766,6 +3772,8 @@
{
lock_t* lock;
trx_t* trx;
ut_ad(mutex_own(&kernel_mutex));
-@@ -3819,6 +3827,10 @@
+@@ -3821,6 +3829,10 @@
return(DB_SUCCESS);
}
trx->que_state = TRX_QUE_LOCK_WAIT;
trx->was_chosen_as_deadlock_victim = FALSE;
trx->wait_started = time(NULL);
-diff -ruN a/storage/innobase/os/os0file.c b/storage/innobase/os/os0file.c
---- a/storage/innobase/os/os0file.c 2010-12-03 17:32:15.644024974 +0900
-+++ b/storage/innobase/os/os0file.c 2010-12-03 17:42:42.117023467 +0900
+--- a/storage/innobase/os/os0file.c
++++ b/storage/innobase/os/os0file.c
@@ -43,6 +43,8 @@
#include "srv0start.h"
#include "fil0fil.h"
#include "log0recv.h"
#ifndef UNIV_HOTBACKUP
# include "os0sync.h"
-@@ -2212,13 +2214,18 @@
+@@ -2213,13 +2215,18 @@
ulint n, /*!< in: number of bytes to read */
ulint offset, /*!< in: least significant 32 bits of file
offset from where to read */
ut_a((offset & 0xFFFFFFFFUL) == offset);
-@@ -2239,6 +2246,15 @@
+@@ -2240,6 +2247,15 @@
os_n_file_reads++;
#if defined(HAVE_PREAD) && !defined(HAVE_BROKEN_PREAD)
os_mutex_enter(os_file_count_mutex);
os_file_n_pending_preads++;
-@@ -2252,6 +2268,13 @@
+@@ -2253,6 +2269,13 @@
os_n_pending_reads--;
os_mutex_exit(os_file_count_mutex);
return(n_bytes);
#else
{
-@@ -2288,6 +2311,13 @@
+@@ -2289,6 +2312,13 @@
os_n_pending_reads--;
os_mutex_exit(os_file_count_mutex);
return(ret);
}
#endif
-@@ -2428,7 +2458,8 @@
+@@ -2429,7 +2459,8 @@
offset where to read */
ulint offset_high, /*!< in: most significant 32 bits of
offset */
{
#ifdef __WIN__
BOOL ret;
-@@ -2503,7 +2534,7 @@
+@@ -2504,7 +2535,7 @@
os_bytes_read_since_printout += n;
try_again:
if ((ulint)ret == n) {
-@@ -2632,7 +2663,7 @@
+@@ -2633,7 +2664,7 @@
os_bytes_read_since_printout += n;
try_again:
if ((ulint)ret == n) {
-@@ -4026,10 +4057,11 @@
+@@ -4027,10 +4058,11 @@
(can be used to identify a completed
aio operation); ignored if mode is
OS_AIO_SYNC */
{
os_aio_array_t* array;
os_aio_slot_t* slot;
-@@ -4070,8 +4102,8 @@
- wait in the Windows case. */
+@@ -4078,7 +4110,7 @@
if (type == OS_FILE_READ) {
-- return(os_file_read(file, buf, offset,
+ return(os_file_read_func(file, buf, offset,
- offset_high, n));
-+ return(os_file_read_trx(file, buf, offset,
+ offset_high, n, trx));
}
ut_a(type == OS_FILE_WRITE);
-@@ -4111,6 +4143,11 @@
+@@ -4119,6 +4151,11 @@
array = NULL; /* Eliminate compiler warning */
}
slot = os_aio_array_reserve_slot(type, array, message1, message2, file,
name, buf, offset, offset_high, n);
if (type == OS_FILE_READ) {
-diff -ruN a/storage/innobase/srv/srv0srv.c b/storage/innobase/srv/srv0srv.c
---- a/storage/innobase/srv/srv0srv.c 2010-12-03 17:32:15.648024399 +0900
-+++ b/storage/innobase/srv/srv0srv.c 2010-12-03 17:45:05.067023254 +0900
+--- a/storage/innobase/srv/srv0srv.c
++++ b/storage/innobase/srv/srv0srv.c
@@ -87,6 +87,9 @@
#include "mysql/plugin.h"
#include "mysql/service_thd_wait.h"
+
trx->op_info = "waiting in InnoDB queue";
- thd_wait_begin(trx->mysql_thd, THD_WAIT_ROW_TABLE_LOCK);
+ thd_wait_begin(trx->mysql_thd, THD_WAIT_USER_LOCK);
@@ -1379,6 +1395,12 @@
trx->op_info = "";
os_fast_mutex_lock(&srv_conc_mutex);
srv_conc_n_waiting_threads--;
-diff -ruN a/storage/innobase/trx/trx0trx.c b/storage/innobase/trx/trx0trx.c
---- a/storage/innobase/trx/trx0trx.c 2010-12-03 15:41:52.053955669 +0900
-+++ b/storage/innobase/trx/trx0trx.c 2010-12-03 17:42:42.127023410 +0900
+--- a/storage/innobase/trx/trx0trx.c
++++ b/storage/innobase/trx/trx0trx.c
@@ -188,6 +188,15 @@
trx->global_read_view = NULL;
trx->read_view = NULL;
#!!! notice !!!
# Any small change to this file in the main branch
# should be done or reviewed by the maintainer!
-diff -ruN a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc
---- a/storage/innobase/handler/ha_innodb.cc 2010-12-03 15:18:48.879955903 +0900
-+++ b/storage/innobase/handler/ha_innodb.cc 2010-12-03 15:22:53.779955671 +0900
-@@ -11528,6 +11528,7 @@
+--- a/storage/innobase/handler/ha_innodb.cc
++++ b/storage/innobase/handler/ha_innodb.cc
+@@ -11545,6 +11545,7 @@
innobase_system_variables, /* system variables */
NULL /* reserved */
},
i_s_innodb_trx,
i_s_innodb_locks,
i_s_innodb_lock_waits,
-diff -ruN a/storage/innobase/handler/i_s.cc b/storage/innobase/handler/i_s.cc
---- a/storage/innobase/handler/i_s.cc 2010-12-03 15:06:58.742986460 +0900
-+++ b/storage/innobase/handler/i_s.cc 2010-12-03 15:33:08.790070078 +0900
+--- a/storage/innobase/handler/i_s.cc
++++ b/storage/innobase/handler/i_s.cc
@@ -45,6 +45,8 @@
#include "srv0start.h" /* for srv_was_started */
#include "trx0i_s.h"
+ /* void* */
+ STRUCT_FLD(__reserved1, NULL)
+};
-diff -ruN a/storage/innobase/handler/i_s.h b/storage/innobase/handler/i_s.h
---- a/storage/innobase/handler/i_s.h 2010-12-03 15:06:58.744953398 +0900
-+++ b/storage/innobase/handler/i_s.h 2010-12-03 15:22:53.783953418 +0900
+--- a/storage/innobase/handler/i_s.h
++++ b/storage/innobase/handler/i_s.h
@@ -35,5 +35,6 @@
extern struct st_mysql_plugin i_s_innodb_cmp_reset;
extern struct st_mysql_plugin i_s_innodb_cmpmem;
#!!! notice !!!
# Any small change to this file in the main branch
# should be done or reviewed by the maintainer!
-diff -ruN a/storage/innobase/buf/buf0buf.c b/storage/innobase/buf/buf0buf.c
---- a/storage/innobase/buf/buf0buf.c 2010-12-04 15:52:23.391514910 +0900
-+++ b/storage/innobase/buf/buf0buf.c 2010-12-04 15:53:45.013513772 +0900
+--- a/storage/innobase/buf/buf0buf.c
++++ b/storage/innobase/buf/buf0buf.c
@@ -511,6 +511,27 @@
return(checksum);
}
(ulong) mach_read_from_4(read_buf + FIL_PAGE_SPACE_OR_CHKSUM),
(ulong) mach_read_from_4(read_buf + UNIV_PAGE_SIZE
- FIL_PAGE_END_LSN_OLD_CHKSUM),
-diff -ruN a/storage/innobase/buf/buf0flu.c b/storage/innobase/buf/buf0flu.c
---- a/storage/innobase/buf/buf0flu.c 2010-12-04 15:37:50.555568346 +0900
-+++ b/storage/innobase/buf/buf0flu.c 2010-12-04 15:53:45.015513917 +0900
-@@ -1055,7 +1055,9 @@
+--- a/storage/innobase/buf/buf0flu.c
++++ b/storage/innobase/buf/buf0flu.c
+@@ -1057,7 +1057,9 @@
mach_write_to_4(page + FIL_PAGE_SPACE_OR_CHKSUM,
srv_use_checksums
: BUF_NO_CHECKSUM_MAGIC);
/* We overwrite the first 4 bytes of the end lsn field to store
-diff -ruN a/storage/innobase/fil/fil0fil.c b/storage/innobase/fil/fil0fil.c
---- a/storage/innobase/fil/fil0fil.c 2010-12-04 15:52:23.406513743 +0900
-+++ b/storage/innobase/fil/fil0fil.c 2010-12-04 15:53:45.020513800 +0900
-@@ -3094,13 +3094,24 @@
+--- a/storage/innobase/fil/fil0fil.c
++++ b/storage/innobase/fil/fil0fil.c
+@@ -3095,13 +3095,24 @@
return(TRUE);
}
return(FALSE);
}
-@@ -3116,7 +3127,9 @@
+@@ -3117,7 +3128,9 @@
if (!zip_size) {
mach_write_to_4(page + FIL_PAGE_SPACE_OR_CHKSUM,
srv_use_checksums
: BUF_NO_CHECKSUM_MAGIC);
mach_write_to_4(page + UNIV_PAGE_SIZE - FIL_PAGE_END_LSN_OLD_CHKSUM,
srv_use_checksums
-diff -ruN a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc
---- a/storage/innobase/handler/ha_innodb.cc 2010-12-04 15:52:23.420480329 +0900
-+++ b/storage/innobase/handler/ha_innodb.cc 2010-12-04 15:53:45.029551892 +0900
+--- a/storage/innobase/handler/ha_innodb.cc
++++ b/storage/innobase/handler/ha_innodb.cc
@@ -183,6 +183,7 @@
#endif /* UNIV_LOG_ARCHIVE */
static my_bool innobase_use_doublewrite = TRUE;
static my_bool innobase_recovery_stats = TRUE;
static my_bool innobase_locks_unsafe_for_binlog = FALSE;
static my_bool innobase_overwrite_relay_log_info = FALSE;
-@@ -2620,6 +2621,7 @@
+@@ -2625,6 +2626,7 @@
srv_use_doublewrite_buf = (ibool) innobase_use_doublewrite;
srv_use_checksums = (ibool) innobase_use_checksums;
#ifdef HAVE_LARGE_PAGES
if ((os_use_large_pages = (ibool) my_use_large_pages))
-@@ -11421,6 +11423,15 @@
+@@ -11432,6 +11434,15 @@
"Disable with --skip-innodb-checksums.",
NULL, NULL, TRUE);
static MYSQL_SYSVAR_STR(data_home_dir, innobase_data_home_dir,
PLUGIN_VAR_READONLY,
"The common part for InnoDB table spaces.",
-@@ -11930,6 +11941,7 @@
+@@ -11946,6 +11957,7 @@
MYSQL_SYSVAR(buffer_pool_size),
MYSQL_SYSVAR(buffer_pool_instances),
MYSQL_SYSVAR(checksums),
MYSQL_SYSVAR(commit_concurrency),
MYSQL_SYSVAR(concurrency_tickets),
MYSQL_SYSVAR(data_file_path),
-diff -ruN a/storage/innobase/include/buf0buf.h b/storage/innobase/include/buf0buf.h
---- a/storage/innobase/include/buf0buf.h 2010-12-04 15:52:23.458514045 +0900
-+++ b/storage/innobase/include/buf0buf.h 2010-12-04 15:53:45.044514150 +0900
-@@ -604,6 +604,11 @@
+--- a/storage/innobase/include/buf0buf.h
++++ b/storage/innobase/include/buf0buf.h
+@@ -643,6 +643,11 @@
buf_calc_page_new_checksum(
/*=======================*/
const byte* page); /*!< in: buffer page */
/********************************************************************//**
In versions < 4.0.14 and < 4.1.1 there was a bug that the checksum only
looked at the first few bytes of the page. This calculates that old
-diff -ruN a/storage/innobase/include/fil0fil.h b/storage/innobase/include/fil0fil.h
---- a/storage/innobase/include/fil0fil.h 2010-12-04 15:52:23.466513796 +0900
-+++ b/storage/innobase/include/fil0fil.h 2010-12-04 15:53:45.046513558 +0900
+--- a/storage/innobase/include/fil0fil.h
++++ b/storage/innobase/include/fil0fil.h
@@ -118,6 +118,7 @@
#define FIL_PAGE_ARCH_LOG_NO_OR_SPACE_ID 34 /*!< starting from 4.1.x this
contains the space id of the page */
/* @} */
/** File page trailer @{ */
#define FIL_PAGE_END_LSN_OLD_CHKSUM 8 /*!< the low 4 bytes of this are used
-diff -ruN a/storage/innobase/include/srv0srv.h b/storage/innobase/include/srv0srv.h
---- a/storage/innobase/include/srv0srv.h 2010-12-04 15:52:23.474482590 +0900
-+++ b/storage/innobase/include/srv0srv.h 2010-12-04 15:53:45.048512100 +0900
+--- a/storage/innobase/include/srv0srv.h
++++ b/storage/innobase/include/srv0srv.h
@@ -224,6 +224,7 @@
extern ibool srv_use_doublewrite_buf;
extern ulong srv_max_buf_pool_modified_pct;
extern ulong srv_max_purge_lag;
-diff -ruN a/storage/innobase/include/ut0rnd.h b/storage/innobase/include/ut0rnd.h
---- a/storage/innobase/include/ut0rnd.h 2010-11-03 07:01:13.000000000 +0900
-+++ b/storage/innobase/include/ut0rnd.h 2010-12-04 15:53:45.049510146 +0900
+--- a/storage/innobase/include/ut0rnd.h
++++ b/storage/innobase/include/ut0rnd.h
@@ -124,6 +124,13 @@
const byte* str, /*!< in: string of bytes */
ulint len) /*!< in: length */
/***********************************************************//**
Looks for a prime number slightly greater than the given argument.
The prime is chosen so that it is not near any power of 2.
-diff -ruN a/storage/innobase/include/ut0rnd.ic b/storage/innobase/include/ut0rnd.ic
---- a/storage/innobase/include/ut0rnd.ic 2010-11-03 07:01:13.000000000 +0900
-+++ b/storage/innobase/include/ut0rnd.ic 2010-12-04 15:53:45.050565975 +0900
+--- a/storage/innobase/include/ut0rnd.ic
++++ b/storage/innobase/include/ut0rnd.ic
@@ -226,3 +226,28 @@
return(fold);
+
+ return(fold);
+}
-diff -ruN a/storage/innobase/srv/srv0srv.c b/storage/innobase/srv/srv0srv.c
---- a/storage/innobase/srv/srv0srv.c 2010-12-04 15:52:23.498513634 +0900
-+++ b/storage/innobase/srv/srv0srv.c 2010-12-04 15:53:45.053550283 +0900
+--- a/storage/innobase/srv/srv0srv.c
++++ b/storage/innobase/srv/srv0srv.c
@@ -414,6 +414,7 @@
UNIV_INTERN ibool srv_use_doublewrite_buf = TRUE;
#!!! notice !!!
# Any small change to this file in the main branch
# should be done or reviewed by the maintainer!
-diff -ruN a/storage/innobase/fil/fil0fil.c b/storage/innobase/fil/fil0fil.c
---- a/storage/innobase/fil/fil0fil.c 2010-12-04 15:55:21.358513751 +0900
-+++ b/storage/innobase/fil/fil0fil.c 2010-12-04 15:55:58.243481131 +0900
+--- a/storage/innobase/fil/fil0fil.c
++++ b/storage/innobase/fil/fil0fil.c
@@ -731,7 +731,7 @@
ut_a(space->purpose != FIL_LOG);
ut_a(!trx_sys_sys_space(space->id));
fprintf(stderr,
"InnoDB: Error: the size of single-table"
" tablespace file %s\n"
-@@ -4151,7 +4151,7 @@
+@@ -4152,7 +4152,7 @@
size = (((ib_int64_t)size_high) << 32) + (ib_int64_t)size_low;
#ifndef UNIV_HOTBACKUP
fprintf(stderr,
"InnoDB: Error: the size of single-table tablespace"
" file %s\n"
-@@ -4171,7 +4171,7 @@
+@@ -4172,7 +4172,7 @@
/* Align the memory for file i/o if we might have O_DIRECT set */
page = ut_align(buf2, UNIV_PAGE_SIZE);
success = os_file_read(file, page, 0, 0, UNIV_PAGE_SIZE);
/* We have to read the tablespace id from the file */
-@@ -5149,9 +5149,9 @@
+@@ -5150,9 +5150,9 @@
ut_ad(ut_is_2pow(zip_size));
ut_ad(buf);
ut_ad(len > 0);
ut_ad(fil_validate_skip());
#ifndef UNIV_HOTBACKUP
# ifndef UNIV_LOG_DEBUG
-diff -ruN a/storage/innobase/fsp/fsp0fsp.c b/storage/innobase/fsp/fsp0fsp.c
---- a/storage/innobase/fsp/fsp0fsp.c 2010-12-04 15:52:23.411513754 +0900
-+++ b/storage/innobase/fsp/fsp0fsp.c 2010-12-04 15:55:58.244514273 +0900
+--- a/storage/innobase/fsp/fsp0fsp.c
++++ b/storage/innobase/fsp/fsp0fsp.c
@@ -656,16 +656,18 @@
0 for uncompressed pages */
ulint offset) /*!< in: page offset */
if (UNIV_UNLIKELY(init_xdes)) {
-diff -ruN a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc
---- a/storage/innobase/handler/ha_innodb.cc 2010-12-04 15:55:21.367482924 +0900
-+++ b/storage/innobase/handler/ha_innodb.cc 2010-12-04 15:55:58.248549631 +0900
+--- a/storage/innobase/handler/ha_innodb.cc
++++ b/storage/innobase/handler/ha_innodb.cc
@@ -148,6 +148,9 @@
static ulong innobase_write_io_threads;
static long innobase_buffer_pool_instances = 1;
static my_bool innobase_thread_concurrency_timer_based;
static long long innobase_buffer_pool_size, innobase_log_file_size;
-@@ -2316,6 +2319,65 @@
+@@ -2321,6 +2324,65 @@
}
#endif /* DBUG_OFF */
#ifndef MYSQL_SERVER
innodb_overwrite_relay_log_info = FALSE;
#endif
-@@ -7241,9 +7303,9 @@
+@@ -7252,9 +7314,9 @@
| DICT_TF_COMPACT
| DICT_TF_FORMAT_ZIP
<< DICT_TF_FORMAT_SHIFT;
}
}
-@@ -11432,6 +11494,16 @@
+@@ -11443,6 +11505,16 @@
"#### Attention: The checksum is not compatible for normal or disabled version! ####",
NULL, NULL, FALSE);
static MYSQL_SYSVAR_STR(data_home_dir, innobase_data_home_dir,
PLUGIN_VAR_READONLY,
"The common part for InnoDB table spaces.",
-@@ -11936,6 +12008,8 @@
+@@ -11952,6 +12024,8 @@
NULL, NULL, 0, &corrupt_table_action_typelib);
static struct st_mysql_sys_var* innobase_system_variables[]= {
MYSQL_SYSVAR(additional_mem_pool_size),
MYSQL_SYSVAR(autoextend_increment),
MYSQL_SYSVAR(buffer_pool_size),
-diff -ruN a/storage/innobase/include/buf0buf.h b/storage/innobase/include/buf0buf.h
---- a/storage/innobase/include/buf0buf.h 2010-12-04 15:55:21.375482937 +0900
-+++ b/storage/innobase/include/buf0buf.h 2010-12-04 15:55:58.258469088 +0900
-@@ -1683,7 +1683,7 @@
+--- a/storage/innobase/include/buf0buf.h
++++ b/storage/innobase/include/buf0buf.h
+@@ -1722,7 +1722,7 @@
time_t last_printout_time;
/*!< when buf_print_io was last time
called */
/*!< Statistics of buddy system,
indexed by block size */
buf_pool_stat_t stat; /*!< current statistics */
-@@ -1779,7 +1779,7 @@
- /* @{ */
+@@ -1820,7 +1820,7 @@
UT_LIST_BASE_NODE_T(buf_page_t) zip_clean;
/*!< unmodified compressed pages */
+ #endif /* UNIV_DEBUG || UNIV_BUF_DEBUG */
- UT_LIST_BASE_NODE_T(buf_page_t) zip_free[BUF_BUDDY_SIZES];
+ UT_LIST_BASE_NODE_T(buf_page_t) zip_free[BUF_BUDDY_SIZES_MAX];
/*!< buddy free lists */
buf_page_t watch[BUF_POOL_WATCH_SIZE];
-@@ -1787,9 +1787,9 @@
+@@ -1828,9 +1828,9 @@
pool watches. Protected by
buf_pool->mutex. */
#if BUF_BUDDY_LOW > PAGE_ZIP_MIN_SIZE
# error "BUF_BUDDY_LOW > PAGE_ZIP_MIN_SIZE"
#endif
-diff -ruN a/storage/innobase/include/buf0types.h b/storage/innobase/include/buf0types.h
---- a/storage/innobase/include/buf0types.h 2010-11-03 07:01:13.000000000 +0900
-+++ b/storage/innobase/include/buf0types.h 2010-12-04 15:55:58.259482590 +0900
-@@ -72,12 +72,13 @@
- buddy system; must be at least
- sizeof(buf_page_t) */
+--- a/storage/innobase/include/buf0types.h
++++ b/storage/innobase/include/buf0types.h
+@@ -67,12 +67,13 @@
+ #define BUF_BUDDY_LOW (1 << BUF_BUDDY_LOW_SHIFT)
+
#define BUF_BUDDY_SIZES (UNIV_PAGE_SIZE_SHIFT - BUF_BUDDY_LOW_SHIFT)
+#define BUF_BUDDY_SIZES_MAX (UNIV_PAGE_SIZE_SHIFT_MAX - BUF_BUDDY_LOW_SHIFT)
/*!< number of buddy sizes */
/* @} */
#endif
-diff -ruN a/storage/innobase/include/fsp0types.h b/storage/innobase/include/fsp0types.h
---- a/storage/innobase/include/fsp0types.h 2010-12-04 02:58:26.000000000 +0900
-+++ b/storage/innobase/include/fsp0types.h 2011-02-03 15:14:21.000000000 +0900
+--- a/storage/innobase/include/fsp0types.h
++++ b/storage/innobase/include/fsp0types.h
@@ -42,7 +42,7 @@
/* @} */
/** On a page of any file segment, data may be put starting from this
offset */
-diff -ruN a/storage/innobase/include/log0log.h b/storage/innobase/include/log0log.h
---- a/storage/innobase/include/log0log.h 2010-11-03 07:01:13.000000000 +0900
-+++ b/storage/innobase/include/log0log.h 2010-12-09 18:16:47.737728305 +0900
+--- a/storage/innobase/include/log0log.h
++++ b/storage/innobase/include/log0log.h
@@ -672,6 +672,9 @@
when mysqld is first time started
on the restored database, it can
#define LOG_FILE_ARCH_COMPLETED OS_FILE_LOG_BLOCK_SIZE
/* this 4-byte field is TRUE when
the writing of an archived log file
-diff -ruN a/storage/innobase/include/mtr0log.ic b/storage/innobase/include/mtr0log.ic
---- a/storage/innobase/include/mtr0log.ic 2010-12-04 15:37:50.590551517 +0900
-+++ b/storage/innobase/include/mtr0log.ic 2010-12-04 15:55:58.260482404 +0900
+--- a/storage/innobase/include/mtr0log.ic
++++ b/storage/innobase/include/mtr0log.ic
@@ -203,7 +203,7 @@
system tablespace */
if ((space == TRX_SYS_SPACE
if (trx_doublewrite_buf_is_being_created) {
/* Do nothing: we only come to this branch in an
InnoDB database creation. We do not redo log
-diff -ruN a/storage/innobase/include/os0file.h b/storage/innobase/include/os0file.h
---- a/storage/innobase/include/os0file.h 2010-12-09 18:16:02.323727427 +0900
-+++ b/storage/innobase/include/os0file.h 2010-12-09 18:16:47.738694194 +0900
+--- a/storage/innobase/include/os0file.h
++++ b/storage/innobase/include/os0file.h
@@ -101,7 +101,7 @@
if this fails for a log block, then it is equivalent to a media failure in the
log. */
#ifdef UNIV_PFS_IO
/* Keys to register InnoDB I/O with performance schema */
extern mysql_pfs_key_t innodb_file_data_key;
-diff -ruN a/storage/innobase/include/page0types.h b/storage/innobase/include/page0types.h
---- a/storage/innobase/include/page0types.h 2010-11-03 07:01:13.000000000 +0900
-+++ b/storage/innobase/include/page0types.h 2010-12-04 15:55:58.261483930 +0900
+--- a/storage/innobase/include/page0types.h
++++ b/storage/innobase/include/page0types.h
@@ -56,8 +56,9 @@
/** Number of supported compressed page sizes */
/**********************************************************************//**
Write the "deleted" flag of a record on a compressed page. The flag must
-diff -ruN a/storage/innobase/include/trx0sys.h b/storage/innobase/include/trx0sys.h
---- a/storage/innobase/include/trx0sys.h 2010-12-04 15:37:50.593480594 +0900
-+++ b/storage/innobase/include/trx0sys.h 2010-12-04 15:55:58.262549554 +0900
-@@ -515,9 +515,9 @@
+--- a/storage/innobase/include/trx0sys.h
++++ b/storage/innobase/include/trx0sys.h
+@@ -526,9 +526,9 @@
/** Contents of TRX_SYS_MYSQL_LOG_MAGIC_N_FLD */
#define TRX_SYS_MYSQL_LOG_MAGIC_N 873422344
/** The offset of the MySQL replication info in the trx system header;
this contains the same fields as TRX_SYS_MYSQL_LOG_INFO below */
#define TRX_SYS_MYSQL_MASTER_LOG_INFO (UNIV_PAGE_SIZE - 2000)
-diff -ruN a/storage/innobase/include/univ.i b/storage/innobase/include/univ.i
---- a/storage/innobase/include/univ.i 2010-11-03 07:01:13.000000000 +0900
-+++ b/storage/innobase/include/univ.i 2010-12-04 15:55:58.263549721 +0900
-@@ -311,9 +311,13 @@
+--- a/storage/innobase/include/univ.i
++++ b/storage/innobase/include/univ.i
+@@ -310,9 +310,13 @@
*/
/* The 2-logarithm of UNIV_PAGE_SIZE: */
/* Maximum number of parallel threads in a parallelized operation */
#define UNIV_MAX_PARALLELISM 32
-@@ -432,7 +436,7 @@
+@@ -431,7 +435,7 @@
stored part of the field in the tablespace. The length field then
contains the sum of the following flag and the locally stored len. */
/* Some macros to improve branch prediction and reduce cache misses */
#if defined(__GNUC__) && (__GNUC__ > 2) && ! defined(__INTEL_COMPILER)
-@@ -535,4 +539,6 @@
+@@ -534,4 +538,6 @@
UNIV_MEM_ALLOC(addr, size); \
} while (0)
+extern ulint srv_page_size_shift;
+extern ulint srv_page_size;
#endif
-diff -ruN a/storage/innobase/log/log0log.c b/storage/innobase/log/log0log.c
---- a/storage/innobase/log/log0log.c 2010-12-03 15:18:48.899986203 +0900
-+++ b/storage/innobase/log/log0log.c 2010-12-04 15:55:58.266551567 +0900
+--- a/storage/innobase/log/log0log.c
++++ b/storage/innobase/log/log0log.c
@@ -604,7 +604,9 @@
offset = (gr_lsn_size_offset + difference) % group_size;
#endif /* UNIV_LOG_ARCHIVE */
for (i = 0; i < LOG_MAX_N_GROUPS; i++) {
-diff -ruN a/storage/innobase/log/log0recv.c b/storage/innobase/log/log0recv.c
---- a/storage/innobase/log/log0recv.c 2010-12-03 17:32:15.638986405 +0900
-+++ b/storage/innobase/log/log0recv.c 2010-12-04 15:55:58.269550689 +0900
+--- a/storage/innobase/log/log0recv.c
++++ b/storage/innobase/log/log0recv.c
@@ -712,8 +712,22 @@
group->lsn = mach_read_from_8(
#ifdef UNIV_LOG_ARCHIVE
group = UT_LIST_GET_FIRST(log_sys->log_groups);
-diff -ruN a/storage/innobase/page/page0zip.c b/storage/innobase/page/page0zip.c
---- a/storage/innobase/page/page0zip.c 2010-12-04 15:52:23.484482786 +0900
-+++ b/storage/innobase/page/page0zip.c 2010-12-04 15:55:58.274551431 +0900
+--- a/storage/innobase/page/page0zip.c
++++ b/storage/innobase/page/page0zip.c
@@ -49,7 +49,7 @@
#ifndef UNIV_HOTBACKUP
#endif /* !UNIV_HOTBACKUP */
/* Please refer to ../include/page0zip.ic for a description of the
-diff -ruN a/storage/innobase/row/row0merge.c b/storage/innobase/row/row0merge.c
---- a/storage/innobase/row/row0merge.c 2010-12-04 15:52:23.490513562 +0900
-+++ b/storage/innobase/row/row0merge.c 2010-12-04 15:55:58.277550562 +0900
+--- a/storage/innobase/row/row0merge.c
++++ b/storage/innobase/row/row0merge.c
@@ -97,7 +97,7 @@
row_merge_block_t. Thus, it must be able to hold one merge record,
whose maximum size is the same as the minimum size of
/** @brief Merge record in row_merge_block_t.
-diff -ruN a/storage/innobase/srv/srv0srv.c b/storage/innobase/srv/srv0srv.c
---- a/storage/innobase/srv/srv0srv.c 2010-12-04 15:55:21.384486344 +0900
-+++ b/storage/innobase/srv/srv0srv.c 2010-12-04 15:55:58.282550845 +0900
+--- a/storage/innobase/srv/srv0srv.c
++++ b/storage/innobase/srv/srv0srv.c
@@ -234,6 +234,13 @@
UNIV_INTERN ulint srv_n_read_io_threads = ULINT_MAX;
UNIV_INTERN ulint srv_n_write_io_threads = ULINT_MAX;
/* User settable value of the number of pages that must be present
in the buffer cache and accessed sequentially for InnoDB to trigger a
readahead request. */
-diff -ruN a/storage/innobase/srv/srv0start.c b/storage/innobase/srv/srv0start.c
---- a/storage/innobase/srv/srv0start.c 2010-12-04 15:52:23.502513556 +0900
-+++ b/storage/innobase/srv/srv0start.c 2010-12-04 15:55:58.285550583 +0900
+--- a/storage/innobase/srv/srv0start.c
++++ b/storage/innobase/srv/srv0start.c
@@ -1561,11 +1561,13 @@
}
#endif /* UNIV_LOG_ARCHIVE */
#!!! notice !!!
# Any small change to this file in the main branch
# should be done or reviewed by the maintainer!
-diff -ruN a/storage/innobase/buf/buf0buf.c b/storage/innobase/buf/buf0buf.c
---- a/storage/innobase/buf/buf0buf.c 2011-02-23 19:00:48.178696354 +0900
-+++ b/storage/innobase/buf/buf0buf.c 2011-02-23 19:01:19.138826278 +0900
-@@ -4084,6 +4084,7 @@
+--- a/storage/innobase/buf/buf0buf.c
++++ b/storage/innobase/buf/buf0buf.c
+@@ -2040,6 +2040,27 @@
+ #endif /* UNIV_DEBUG || UNIV_BUF_DEBUG */
+ }
+
++ if (UNIV_UNLIKELY(bpage->space_was_being_deleted)) {
++ /* This page is obsoleted, should discard and retry */
++ rw_lock_s_unlock(&buf_pool->page_hash_latch);
++
++ mutex_enter(&buf_pool->LRU_list_mutex);
++ block_mutex = buf_page_get_mutex_enter(bpage);
++
++ if (UNIV_UNLIKELY(!block_mutex)) {
++ mutex_exit(&buf_pool->LRU_list_mutex);
++ goto lookup;
++ }
++
++ buf_LRU_free_block(bpage, TRUE, TRUE);
++
++ mutex_exit(&buf_pool->LRU_list_mutex);
++ mutex_exit(block_mutex);
++ block_mutex = NULL;
++
++ goto lookup;
++ }
++
+ if (UNIV_UNLIKELY(!bpage->zip.data)) {
+ /* There is no compressed page. */
+ err_exit:
+@@ -2549,6 +2570,27 @@
+ block = (buf_block_t*) buf_page_hash_get_low(
+ buf_pool, space, offset, fold);
+ if (block) {
++ if (UNIV_UNLIKELY(block->page.space_was_being_deleted)) {
++ /* This page is obsoleted, should discard and retry */
++ rw_lock_s_unlock(&buf_pool->page_hash_latch);
++
++ mutex_enter(&buf_pool->LRU_list_mutex);
++ block_mutex = buf_page_get_mutex_enter((buf_page_t*)block);
++
++ if (UNIV_UNLIKELY(!block_mutex)) {
++ mutex_exit(&buf_pool->LRU_list_mutex);
++ goto loop;
++ }
++
++ buf_LRU_free_block((buf_page_t*)block, TRUE, TRUE);
++
++ mutex_exit(&buf_pool->LRU_list_mutex);
++ mutex_exit(block_mutex);
++ block_mutex = NULL;
++
++ goto loop;
++ }
++
+ block_mutex = buf_page_get_mutex_enter((buf_page_t*)block);
+ ut_a(block_mutex);
+ }
+@@ -3467,11 +3509,28 @@
+
+ fold = buf_page_address_fold(space, offset);
+
++retry:
+ //buf_pool_mutex_enter(buf_pool);
+ mutex_enter(&buf_pool->LRU_list_mutex);
+ rw_lock_x_lock(&buf_pool->page_hash_latch);
+
+ watch_page = buf_page_hash_get_low(buf_pool, space, offset, fold);
++
++ if (UNIV_UNLIKELY(watch_page && watch_page->space_was_being_deleted)) {
++ mutex_t* block_mutex = buf_page_get_mutex_enter(watch_page);
++
++ /* This page is obsoleted, should discard and retry */
++ rw_lock_x_unlock(&buf_pool->page_hash_latch);
++ ut_a(block_mutex);
++
++ buf_LRU_free_block(watch_page, TRUE, TRUE);
++
++ mutex_exit(&buf_pool->LRU_list_mutex);
++ mutex_exit(block_mutex);
++
++ goto retry;
++ }
++
+ if (watch_page && !buf_pool_watch_is_sentinel(buf_pool, watch_page)) {
+ /* The page is already in the buffer pool. */
+ watch_page = NULL;
+@@ -3602,6 +3661,7 @@
bpage->state = BUF_BLOCK_ZIP_PAGE;
bpage->space = space;
bpage->offset = offset;
+ bpage->space_was_being_deleted = FALSE;
-
#ifdef UNIV_DEBUG
-diff -ruN a/storage/innobase/buf/buf0flu.c b/storage/innobase/buf/buf0flu.c
---- a/storage/innobase/buf/buf0flu.c 2011-02-23 19:00:48.182659256 +0900
-+++ b/storage/innobase/buf/buf0flu.c 2011-02-23 19:01:19.138826278 +0900
+ bpage->in_page_hash = FALSE;
+@@ -3686,6 +3746,7 @@
+
+ fold = buf_page_address_fold(space, offset);
+
++retry:
+ //buf_pool_mutex_enter(buf_pool);
+ mutex_enter(&buf_pool->LRU_list_mutex);
+ rw_lock_x_lock(&buf_pool->page_hash_latch);
+@@ -3693,6 +3754,21 @@
+ block = (buf_block_t*) buf_page_hash_get_low(
+ buf_pool, space, offset, fold);
+
++ if (UNIV_UNLIKELY(block && block->page.space_was_being_deleted)) {
++ mutex_t* block_mutex = buf_page_get_mutex_enter((buf_page_t*)block);
++
++ /* This page is obsoleted, should discard and retry */
++ rw_lock_x_unlock(&buf_pool->page_hash_latch);
++ ut_a(block_mutex);
++
++ buf_LRU_free_block((buf_page_t*)block, TRUE, TRUE);
++
++ mutex_exit(&buf_pool->LRU_list_mutex);
++ mutex_exit(block_mutex);
++
++ goto retry;
++ }
++
+ if (block
+ && buf_page_in_file(&block->page)
+ && !buf_pool_watch_is_sentinel(buf_pool, &block->page)) {
+@@ -3984,8 +4060,11 @@
+ }
+
+ if (io_type == BUF_IO_WRITE
+- && (buf_page_get_state(bpage) == BUF_BLOCK_ZIP_DIRTY
+- || buf_page_get_flush_type(bpage) == BUF_FLUSH_LRU)) {
++ && (
++#if defined UNIV_DEBUG || defined UNIV_BUF_DEBUG
++ buf_page_get_state(bpage) == BUF_BLOCK_ZIP_DIRTY ||
++#endif /* UNIV_DEBUG || UNIV_BUF_DEBUG */
++ buf_page_get_flush_type(bpage) == BUF_FLUSH_LRU)) {
+ /* to keep consistency at buf_LRU_insert_zip_clean() */
+ have_LRU_mutex = TRUE; /* optimistic */
+ }
+--- a/storage/innobase/buf/buf0flu.c
++++ b/storage/innobase/buf/buf0flu.c
@@ -439,7 +439,7 @@
if (UNIV_LIKELY(bpage->in_LRU_list && buf_page_in_file(bpage))) {
if (flush_type != BUF_FLUSH_LRU) {
return(TRUE);
-diff -ruN a/storage/innobase/buf/buf0lru.c b/storage/innobase/buf/buf0lru.c
---- a/storage/innobase/buf/buf0lru.c 2011-02-23 19:00:47.939695791 +0900
-+++ b/storage/innobase/buf/buf0lru.c 2011-02-23 19:01:19.142741970 +0900
-@@ -574,6 +574,37 @@
+--- a/storage/innobase/buf/buf0lru.c
++++ b/storage/innobase/buf/buf0lru.c
+@@ -529,6 +529,62 @@
}
}
+ for (i = 0; i < srv_buf_pool_instances; i++) {
+ buf_pool_t* buf_pool;
+ buf_page_t* bpage;
++ buf_chunk_t* chunk;
++ ulint j, k;
+
+ buf_pool = buf_pool_from_array(i);
+
+ }
+
+ mutex_exit(&buf_pool->LRU_list_mutex);
++
++ rw_lock_s_lock(&btr_search_latch);
++ chunk = buf_pool->chunks;
++ for (j = buf_pool->n_chunks; j--; chunk++) {
++ buf_block_t* block = chunk->blocks;
++ for (k = chunk->size; k--; block++) {
++ if (buf_block_get_state(block)
++ != BUF_BLOCK_FILE_PAGE
++ || !block->is_hashed
++ || buf_page_get_space(&block->page) != id) {
++ continue;
++ }
++
++ rw_lock_s_unlock(&btr_search_latch);
++
++ rw_lock_x_lock(&block->lock);
++ btr_search_drop_page_hash_index(block);
++ rw_lock_x_unlock(&block->lock);
++
++ rw_lock_s_lock(&btr_search_latch);
++ }
++ }
++ rw_lock_s_unlock(&btr_search_latch);
+ }
+}
+
+ #if defined UNIV_DEBUG || defined UNIV_BUF_DEBUG
/********************************************************************//**
Insert a compressed block into buf_pool->zip_clean in the LRU order. */
- UNIV_INTERN
-@@ -1558,6 +1589,10 @@
- return(BUF_LRU_NOT_FREED);
+@@ -1483,6 +1539,10 @@
+ return(FALSE);
}
+ if (bpage->space_was_being_deleted && bpage->oldest_modification != 0) {
#ifdef UNIV_IBUF_COUNT_DEBUG
ut_a(ibuf_count_get(bpage->space, bpage->offset) == 0);
#endif /* UNIV_IBUF_COUNT_DEBUG */
-diff -ruN a/storage/innobase/fil/fil0fil.c b/storage/innobase/fil/fil0fil.c
---- a/storage/innobase/fil/fil0fil.c 2011-02-23 19:00:48.223696428 +0900
-+++ b/storage/innobase/fil/fil0fil.c 2011-02-23 19:01:19.147655510 +0900
+--- a/storage/innobase/fil/fil0fil.c
++++ b/storage/innobase/fil/fil0fil.c
@@ -254,6 +254,7 @@
struct fil_system_struct {
#ifndef UNIV_HOTBACKUP
- ut_a(node->n_pending == 0);
+ ut_a(node->n_pending == 0 || node->space->is_being_deleted);
ut_a(node->n_pending_flushes == 0);
- ut_a(node->modification_counter == node->flush_counter);
-
-@@ -876,7 +877,7 @@
+ ut_a(node->modification_counter == node->flush_counter
+ || srv_fast_shutdown == 2);
+@@ -877,7 +878,7 @@
ut_a(system->n_open > 0);
system->n_open--;
ut_a(UT_LIST_GET_LEN(system->LRU) > 0);
/* The node is in the LRU list, remove it */
-@@ -1075,7 +1076,7 @@
+@@ -1076,7 +1077,7 @@
ut_ad(node && system && space);
ut_ad(mutex_own(&(system->mutex)));
ut_a(node->magic_n == FIL_NODE_MAGIC_N);
if (node->open) {
/* We fool the assertion in fil_node_close_file() to think
-@@ -1597,6 +1598,8 @@
+@@ -1598,6 +1599,8 @@
mutex_create(fil_system_mutex_key,
&fil_system->mutex, SYNC_ANY_LATCH);
fil_system->spaces = hash_create(hash_size);
fil_system->name_hash = hash_create(hash_size);
-@@ -2343,7 +2346,11 @@
+@@ -2344,7 +2347,11 @@
completely and permanently. The flag is_being_deleted also prevents
fil_flush() from being applied to this tablespace. */
#endif
/* printf("Deleting tablespace %s id %lu\n", space->name, id); */
-@@ -4721,6 +4728,10 @@
+@@ -4722,6 +4729,10 @@
ulint page_size;
ibool success = TRUE;
fil_mutex_enter_and_prepare_for_io(space_id);
space = fil_space_get_by_id(space_id);
-@@ -4732,6 +4743,7 @@
+@@ -4733,6 +4744,7 @@
*actual_size = space->size;
mutex_exit(&fil_system->mutex);
return(TRUE);
}
-@@ -4764,6 +4776,8 @@
+@@ -4765,6 +4777,8 @@
offset_low = ((start_page_no - file_start_page_no)
% (4096 * ((1024 * 1024) / page_size)))
* page_size;
#ifdef UNIV_HOTBACKUP
success = os_file_write(node->name, node->handle, buf,
offset_low, offset_high,
-@@ -4773,8 +4787,10 @@
+@@ -4774,8 +4788,10 @@
node->name, node->handle, buf,
offset_low, offset_high,
page_size * n_pages,
if (success) {
node->size += n_pages;
space->size += n_pages;
-@@ -4820,6 +4836,7 @@
+@@ -4821,6 +4837,7 @@
printf("Extended %s to %lu, actual size %lu pages\n", space->name,
size_after_extend, *actual_size); */
mutex_exit(&fil_system->mutex);
fil_flush(space_id, TRUE);
-@@ -5182,6 +5199,22 @@
+@@ -5183,6 +5200,22 @@
srv_data_written+= len;
}
/* Reserve the fil_system mutex and make sure that we can open at
least one file while holding it, if the file is not already open */
-@@ -5323,10 +5356,24 @@
+@@ -5324,10 +5357,24 @@
#else
/* Queue the aio request */
ret = os_aio(type, mode | wake_later, node->name, node->handle, buf,
ut_a(ret);
if (mode == OS_AIO_SYNC) {
-@@ -5426,6 +5473,7 @@
+@@ -5427,6 +5474,7 @@
fil_node_t* fil_node;
void* message;
ulint type;
ut_ad(fil_validate_skip());
-@@ -5433,10 +5481,10 @@
+@@ -5434,10 +5482,10 @@
srv_set_io_thread_op_info(segment, "native aio handle");
#ifdef WIN_ASYNC_IO
ret = os_aio_windows_handle(segment, 0, &fil_node,
#else
ut_error;
ret = 0; /* Eliminate compiler warning */
-@@ -5445,7 +5493,22 @@
+@@ -5446,7 +5494,22 @@
srv_set_io_thread_op_info(segment, "simulated aio handle");
ret = os_aio_simulated_handle(segment, &fil_node,
}
ut_a(ret);
-diff -ruN a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc
---- a/storage/innobase/handler/ha_innodb.cc 2010-12-04 15:57:13.035513990 +0900
-+++ b/storage/innobase/handler/ha_innodb.cc 2010-12-04 15:57:53.084513775 +0900
-@@ -12007,6 +12007,12 @@
+--- a/storage/innobase/handler/ha_innodb.cc
++++ b/storage/innobase/handler/ha_innodb.cc
+@@ -12023,6 +12023,12 @@
"except for the deletion.",
NULL, NULL, 0, &corrupt_table_action_typelib);
static struct st_mysql_sys_var* innobase_system_variables[]= {
MYSQL_SYSVAR(page_size),
MYSQL_SYSVAR(log_block_size),
-@@ -12097,6 +12103,7 @@
+@@ -12114,6 +12120,7 @@
MYSQL_SYSVAR(purge_batch_size),
MYSQL_SYSVAR(rollback_segments),
MYSQL_SYSVAR(corrupt_table_action),
NULL
};
-@@ -12106,7 +12113,7 @@
+@@ -12123,7 +12130,7 @@
&innobase_storage_engine,
innobase_hton_name,
plugin_author,
PLUGIN_LICENSE_GPL,
innobase_init, /* Plugin Init */
NULL, /* Plugin Deinit */
-diff -ruN a/storage/innobase/include/buf0buf.h b/storage/innobase/include/buf0buf.h
---- a/storage/innobase/include/buf0buf.h 2011-02-23 19:00:48.252696774 +0900
-+++ b/storage/innobase/include/buf0buf.h 2011-02-23 19:01:19.182655902 +0900
-@@ -1438,6 +1438,7 @@
+--- a/storage/innobase/include/buf0buf.h
++++ b/storage/innobase/include/buf0buf.h
+@@ -1477,6 +1477,7 @@
0 if the block was never accessed
in the buffer pool */
/* @} */
ibool is_corrupt;
# if defined UNIV_DEBUG_FILE_ACCESSES || defined UNIV_DEBUG
ibool file_page_was_freed;
-diff -ruN a/storage/innobase/include/buf0buf.ic b/storage/innobase/include/buf0buf.ic
---- a/storage/innobase/include/buf0buf.ic 2011-02-23 19:00:48.130659154 +0900
-+++ b/storage/innobase/include/buf0buf.ic 2011-02-23 19:01:19.185655906 +0900
+--- a/storage/innobase/include/buf0buf.ic
++++ b/storage/innobase/include/buf0buf.ic
@@ -408,6 +408,7 @@
buf_block_set_state(block, BUF_BLOCK_FILE_PAGE);
block->page.space = space;
}
/*********************************************************************//**
-diff -ruN a/storage/innobase/include/buf0lru.h b/storage/innobase/include/buf0lru.h
---- a/storage/innobase/include/buf0lru.h 2011-02-23 19:00:47.977658923 +0900
-+++ b/storage/innobase/include/buf0lru.h 2011-02-23 19:01:19.188625768 +0900
-@@ -85,6 +85,13 @@
+--- a/storage/innobase/include/buf0lru.h
++++ b/storage/innobase/include/buf0lru.h
+@@ -73,6 +73,14 @@
buf_LRU_invalidate_tablespace(
/*==========================*/
ulint id); /*!< in: space id */
++
+/******************************************************************//**
+*/
+UNIV_INTERN
+buf_LRU_mark_space_was_deleted(
+/*===========================*/
+ ulint id); /*!< in: space id */
+ #if defined UNIV_DEBUG || defined UNIV_BUF_DEBUG
/********************************************************************//**
Insert a compressed block into buf_pool->zip_clean in the LRU order. */
- UNIV_INTERN
-diff -ruN a/storage/innobase/include/os0file.h b/storage/innobase/include/os0file.h
---- a/storage/innobase/include/os0file.h 2011-02-23 19:00:48.260696646 +0900
-+++ b/storage/innobase/include/os0file.h 2011-02-23 19:01:19.190656054 +0900
+--- a/storage/innobase/include/os0file.h
++++ b/storage/innobase/include/os0file.h
@@ -280,9 +280,9 @@
pfs_os_file_close_func(file, __FILE__, __LINE__)
#endif /* LINUX_NATIVE_AIO */
#ifndef UNIV_NONINL
-diff -ruN a/storage/innobase/include/os0file.ic b/storage/innobase/include/os0file.ic
---- a/storage/innobase/include/os0file.ic 2011-02-23 19:00:47.915696756 +0900
-+++ b/storage/innobase/include/os0file.ic 2011-02-23 19:01:19.191625891 +0900
+--- a/storage/innobase/include/os0file.ic
++++ b/storage/innobase/include/os0file.ic
@@ -229,6 +229,7 @@
(can be used to identify a completed
aio operation); ignored if mode is
register_pfs_file_io_end(locker, n);
-diff -ruN a/storage/innobase/include/srv0srv.h b/storage/innobase/include/srv0srv.h
---- a/storage/innobase/include/srv0srv.h 2011-02-23 19:00:48.212625715 +0900
-+++ b/storage/innobase/include/srv0srv.h 2011-02-23 19:01:19.193655990 +0900
+--- a/storage/innobase/include/srv0srv.h
++++ b/storage/innobase/include/srv0srv.h
@@ -244,6 +244,8 @@
extern ulint srv_pass_corrupt_table;
/*-------------------------------------------*/
extern ulint srv_n_rows_inserted;
-diff -ruN a/storage/innobase/include/sync0sync.h b/storage/innobase/include/sync0sync.h
---- a/storage/innobase/include/sync0sync.h 2011-02-23 19:00:47.875625940 +0900
-+++ b/storage/innobase/include/sync0sync.h 2011-02-23 19:01:19.195703856 +0900
-@@ -691,6 +691,7 @@
+--- a/storage/innobase/include/sync0sync.h
++++ b/storage/innobase/include/sync0sync.h
+@@ -693,6 +693,7 @@
#define SYNC_BUF_POOL 150 /* Buffer pool mutex */
#define SYNC_BUF_FLUSH_LIST 145 /* Buffer flush list mutex */
#define SYNC_DOUBLEWRITE 140
#define SYNC_ANY_LATCH 135
#define SYNC_THR_LOCAL 133
#define SYNC_MEM_HASH 131
-diff -ruN a/storage/innobase/include/univ.i b/storage/innobase/include/univ.i
---- a/storage/innobase/include/univ.i 2010-12-04 15:57:13.050485224 +0900
-+++ b/storage/innobase/include/univ.i 2010-12-04 15:57:53.091592933 +0900
-@@ -53,6 +53,11 @@
+--- a/storage/innobase/include/univ.i
++++ b/storage/innobase/include/univ.i
+@@ -52,6 +52,11 @@
#define INNODB_VERSION_MINOR 1
- #define INNODB_VERSION_BUGFIX 7
+ #define INNODB_VERSION_BUGFIX 8
+#ifndef PERCONA_INNODB_VERSION
+#define PERCONA_INNODB_VERSION 20.1
/* The following is the InnoDB version as shown in
SELECT plugin_version FROM information_schema.plugins;
calculated in make_version_string() in sql/sql_show.cc like this:
-@@ -65,7 +70,8 @@
+@@ -64,7 +69,8 @@
#define INNODB_VERSION_STR \
IB_TO_STR(INNODB_VERSION_MAJOR) "." \
IB_TO_STR(INNODB_VERSION_MINOR) "." \
#define REFMAN "http://dev.mysql.com/doc/refman/" \
IB_TO_STR(MYSQL_MAJOR_VERSION) "." \
-diff -ruN a/storage/innobase/os/os0file.c b/storage/innobase/os/os0file.c
---- a/storage/innobase/os/os0file.c 2011-02-23 19:00:47.928696481 +0900
-+++ b/storage/innobase/os/os0file.c 2011-02-23 19:01:19.200696353 +0900
+--- a/storage/innobase/os/os0file.c
++++ b/storage/innobase/os/os0file.c
@@ -180,6 +180,7 @@
made and only the slot message
needs to be passed to the caller
fil_node_t* message1; /*!< message which is given by the */
void* message2; /*!< the requester of an aio operation
and which can be used to identify
-@@ -3685,7 +3686,8 @@
+@@ -3686,7 +3687,8 @@
offset */
ulint offset_high, /*!< in: most significant 32 bits of
offset */
{
os_aio_slot_t* slot = NULL;
#ifdef WIN_ASYNC_IO
-@@ -3774,6 +3776,7 @@
+@@ -3775,6 +3777,7 @@
slot->offset = offset;
slot->offset_high = offset_high;
slot->io_already_done = FALSE;
#ifdef WIN_ASYNC_IO
control = &(slot->control);
-@@ -4061,6 +4064,7 @@
+@@ -4062,6 +4065,7 @@
(can be used to identify a completed
aio operation); ignored if mode is
OS_AIO_SYNC */
trx_t* trx)
{
os_aio_array_t* array;
-@@ -4149,7 +4153,7 @@
+@@ -4157,7 +4161,7 @@
trx->io_read += n;
}
slot = os_aio_array_reserve_slot(type, array, message1, message2, file,
if (type == OS_FILE_READ) {
if (srv_use_native_aio) {
os_n_file_reads++;
-@@ -4268,7 +4272,8 @@
+@@ -4276,7 +4280,8 @@
parameters are valid and can be used to
restart the operation, for example */
void** message2,
{
ulint orig_seg = segment;
os_aio_array_t* array;
-@@ -4347,6 +4352,7 @@
+@@ -4355,6 +4360,7 @@
*message2 = slot->message2;
*type = slot->type;
if (ret && len == slot->len) {
ret_val = TRUE;
-@@ -4575,7 +4581,8 @@
+@@ -4583,7 +4589,8 @@
aio operation failed, these output
parameters are valid and can be used to
restart the operation. */
{
ulint segment;
os_aio_array_t* array;
-@@ -4648,6 +4655,7 @@
+@@ -4656,6 +4663,7 @@
*message2 = slot->message2;
*type = slot->type;
if ((slot->ret == 0) && (slot->n_bytes == (long)slot->len)) {
ret = TRUE;
-@@ -4701,7 +4709,8 @@
+@@ -4709,7 +4717,8 @@
parameters are valid and can be used to
restart the operation, for example */
void** message2,
{
os_aio_array_t* array;
ulint segment;
-@@ -4997,6 +5006,7 @@
+@@ -5005,6 +5014,7 @@
*message2 = slot->message2;
*type = slot->type;
os_mutex_exit(array->mutex);
-diff -ruN a/storage/innobase/row/row0mysql.c b/storage/innobase/row/row0mysql.c
---- a/storage/innobase/row/row0mysql.c 2010-12-04 15:37:50.598481116 +0900
-+++ b/storage/innobase/row/row0mysql.c 2010-12-04 15:57:53.092563335 +0900
+--- a/storage/innobase/row/row0mysql.c
++++ b/storage/innobase/row/row0mysql.c
@@ -51,6 +51,7 @@
#include "btr0sea.h"
#include "fil0fil.h"
if (prebuilt->sql_stat_start) {
node->state = INS_NODE_SET_IX_LOCK;
prebuilt->sql_stat_start = FALSE;
-diff -ruN a/storage/innobase/row/row0sel.c b/storage/innobase/row/row0sel.c
---- a/storage/innobase/row/row0sel.c 2010-12-04 15:52:23.494514495 +0900
-+++ b/storage/innobase/row/row0sel.c 2010-12-04 16:01:38.320883699 +0900
-@@ -3366,6 +3366,7 @@
+@@ -2575,10 +2583,29 @@
+
+ err = DB_ERROR;
+ } else {
++ dict_index_t* index;
++
+ /* Set the flag which tells that now it is legal to
+ IMPORT a tablespace for this table */
+ table->tablespace_discarded = TRUE;
+ table->ibd_file_missing = TRUE;
++
++ /* check adaptive hash entries */
++ index = dict_table_get_first_index(table);
++ while (index) {
++ ulint ref_count = btr_search_info_get_ref_count(index->search_info);
++ if (ref_count) {
++ fprintf(stderr, "InnoDB: Warning:"
++ " hash index ref_count (%lu) is not zero"
++ " after fil_discard_tablespace().\n"
++ "index: \"%s\""
++ " table: \"%s\"\n",
++ ref_count,
++ index->name,
++ table->name);
++ }
++ index = dict_table_get_next_index(index);
++ }
+ }
+ }
+
+@@ -2927,6 +2954,19 @@
+ table->space = space;
+ index = dict_table_get_first_index(table);
+ do {
++ ulint ref_count = btr_search_info_get_ref_count(index->search_info);
++ /* check adaptive hash entries */
++ if (ref_count) {
++ fprintf(stderr, "InnoDB: Warning:"
++ " hash index ref_count (%lu) is not zero"
++ " after fil_discard_tablespace().\n"
++ "index: \"%s\""
++ " table: \"%s\"\n",
++ ref_count,
++ index->name,
++ table->name);
++ }
++
+ index->space = space;
+ index = dict_table_get_next_index(index);
+ } while (index);
+--- a/storage/innobase/row/row0sel.c
++++ b/storage/innobase/row/row0sel.c
+@@ -3367,6 +3367,7 @@
ulint offsets_[REC_OFFS_NORMAL_SIZE];
ulint* offsets = offsets_;
ibool table_lock_waited = FALSE;
rec_offs_init(offsets_);
-@@ -3737,6 +3738,17 @@
+@@ -3738,6 +3739,17 @@
/* Do some start-of-statement preparations */
if (!prebuilt->sql_stat_start) {
/* No need to set an intention lock or assign a read view */
-@@ -3747,6 +3759,18 @@
+@@ -3748,6 +3760,18 @@
" perform a consistent read\n"
"InnoDB: but the read view is not assigned!\n",
stderr);
trx_print(stderr, trx, 600);
fputc('\n', stderr);
ut_error;
-diff -ruN a/storage/innobase/srv/srv0srv.c b/storage/innobase/srv/srv0srv.c
---- a/storage/innobase/srv/srv0srv.c 2011-02-23 19:00:48.283695497 +0900
-+++ b/storage/innobase/srv/srv0srv.c 2011-02-23 19:01:19.204696643 +0900
+--- a/storage/innobase/srv/srv0srv.c
++++ b/storage/innobase/srv/srv0srv.c
@@ -441,6 +441,8 @@
UNIV_INTERN ulint srv_pass_corrupt_table = 0; /* 0:disable 1:enable */
/*-------------------------------------------*/
UNIV_INTERN ulong srv_n_spin_wait_rounds = 30;
UNIV_INTERN ulong srv_n_free_tickets_to_enter = 500;
-diff -ruN a/storage/innobase/srv/srv0start.c b/storage/innobase/srv/srv0start.c
---- a/storage/innobase/srv/srv0start.c 2010-12-04 15:57:13.073495392 +0900
-+++ b/storage/innobase/srv/srv0start.c 2010-12-04 16:02:50.704884053 +0900
+--- a/storage/innobase/srv/srv0start.c
++++ b/storage/innobase/srv/srv0start.c
@@ -2161,7 +2161,7 @@
if (srv_print_verbose_log) {
ut_print_timestamp(stderr);
"log sequence number %llu\n",
INNODB_VERSION_STR, srv_start_lsn);
}
-diff -ruN a/storage/innobase/sync/sync0sync.c b/storage/innobase/sync/sync0sync.c
---- a/storage/innobase/sync/sync0sync.c 2011-02-25 14:18:55.817202060 +0900
-+++ b/storage/innobase/sync/sync0sync.c 2011-02-25 14:19:44.596202017 +0900
-@@ -1220,6 +1220,7 @@
+--- a/storage/innobase/sync/sync0sync.c
++++ b/storage/innobase/sync/sync0sync.c
+@@ -1225,6 +1225,7 @@
case SYNC_LOG_FLUSH_ORDER:
case SYNC_THR_LOCAL:
case SYNC_ANY_LATCH:
case SYNC_FILE_FORMAT_TAG:
case SYNC_DOUBLEWRITE:
case SYNC_SEARCH_SYS:
-diff -ruN a/storage/innobase/trx/trx0purge.c b/storage/innobase/trx/trx0purge.c
---- a/storage/innobase/trx/trx0purge.c 2010-11-03 07:01:13.000000000 +0900
-+++ b/storage/innobase/trx/trx0purge.c 2010-12-04 15:57:53.106551154 +0900
+--- a/storage/innobase/trx/trx0purge.c
++++ b/storage/innobase/trx/trx0purge.c
@@ -1149,8 +1149,7 @@
/* If we cannot advance the 'purge view' because of an old
'consistent read view', then the DML statements cannot be delayed.
#!!! notice !!!
# Any small change to this file in the main branch
# should be done or reviewed by the maintainer!
-diff -ruN a/storage/innobase/buf/buf0buf.c b/storage/innobase/buf/buf0buf.c
---- a/storage/innobase/buf/buf0buf.c 2010-12-03 15:09:51.273986410 +0900
-+++ b/storage/innobase/buf/buf0buf.c 2010-12-03 15:10:08.934990091 +0900
+--- a/storage/innobase/buf/buf0buf.c
++++ b/storage/innobase/buf/buf0buf.c
@@ -320,6 +320,7 @@
/* When we traverse all the flush lists we don't want another
log_flush_order_mutex_exit();
/* The returned answer may be out of date: the flush_list can
-diff -ruN a/storage/innobase/buf/buf0flu.c b/storage/innobase/buf/buf0flu.c
---- a/storage/innobase/buf/buf0flu.c 2010-11-03 07:01:13.000000000 +0900
-+++ b/storage/innobase/buf/buf0flu.c 2010-12-03 15:10:08.934990091 +0900
-@@ -855,7 +855,7 @@
+--- a/storage/innobase/buf/buf0flu.c
++++ b/storage/innobase/buf/buf0flu.c
+@@ -857,7 +857,7 @@
flush:
/* Now flush the doublewrite buffer data to disk */
/* We know that the writes have been flushed to disk now
and in recovery we will find them in the doublewrite buffer
-@@ -1376,7 +1376,7 @@
+@@ -1378,7 +1378,7 @@
ut_ad(flush_type == BUF_FLUSH_LRU || flush_type == BUF_FLUSH_LIST);
/* If there is little space, it is better not to flush
any block except from the end of the LRU list */
-diff -ruN a/storage/innobase/buf/buf0rea.c b/storage/innobase/buf/buf0rea.c
---- a/storage/innobase/buf/buf0rea.c 2010-11-03 07:01:13.000000000 +0900
-+++ b/storage/innobase/buf/buf0rea.c 2010-12-03 15:10:08.937050537 +0900
+--- a/storage/innobase/buf/buf0rea.c
++++ b/storage/innobase/buf/buf0rea.c
@@ -260,6 +260,10 @@
= BUF_READ_AHEAD_LINEAR_AREA(buf_pool);
ulint threshold;
if (UNIV_UNLIKELY(srv_startup_is_before_trx_rollback_phase)) {
/* No read-ahead to avoid thread deadlocks */
return(0);
-diff -ruN a/storage/innobase/fil/fil0fil.c b/storage/innobase/fil/fil0fil.c
---- a/storage/innobase/fil/fil0fil.c 2011-06-29 17:48:24.797971571 +0900
-+++ b/storage/innobase/fil/fil0fil.c 2011-06-29 18:04:02.548053286 +0900
-@@ -2600,7 +2600,7 @@
+--- a/storage/innobase/fil/fil0fil.c
++++ b/storage/innobase/fil/fil0fil.c
+@@ -2601,7 +2601,7 @@
os_thread_sleep(20000);
goto retry;
-@@ -2814,7 +2814,7 @@
+@@ -2815,7 +2815,7 @@
goto error_exit;
}
if (!ret) {
fputs("InnoDB: Error: file flush of tablespace ", stderr);
-@@ -3000,7 +3000,7 @@
+@@ -3001,7 +3001,7 @@
}
}
if (!success) {
goto func_exit;
-@@ -3022,7 +3022,7 @@
+@@ -3023,7 +3023,7 @@
goto func_exit;
}
func_exit:
os_file_close(file);
ut_free(buf2);
-@@ -4005,7 +4005,7 @@
+@@ -4006,7 +4006,7 @@
size_after_extend, *actual_size); */
mutex_exit(&fil_system->mutex);
return(success);
}
-@@ -4576,8 +4576,9 @@
+@@ -4577,8 +4577,9 @@
void
fil_flush(
/*======*/
{
fil_space_t* space;
fil_node_t* node;
-@@ -4648,7 +4649,7 @@
+@@ -4649,7 +4650,7 @@
/* fprintf(stderr, "Flushing to file %s\n",
node->name); */
mutex_enter(&fil_system->mutex);
-@@ -4731,7 +4732,7 @@
+@@ -4732,7 +4733,7 @@
a non-existing space id. */
for (i = 0; i < n_space_ids; i++) {
}
mem_free(space_ids);
-diff -ruN a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc
---- a/storage/innobase/handler/ha_innodb.cc 2010-12-03 15:09:51.283956391 +0900
-+++ b/storage/innobase/handler/ha_innodb.cc 2010-12-03 15:10:08.963980444 +0900
-@@ -444,6 +444,12 @@
+--- a/storage/innobase/handler/ha_innodb.cc
++++ b/storage/innobase/handler/ha_innodb.cc
+@@ -445,6 +445,12 @@
"Timeout in seconds an InnoDB transaction may wait for a lock before being rolled back. Values above 100000000 disable the timeout.",
NULL, NULL, 50, 1, 1024 * 1024 * 1024, 0);
static handler *innobase_create_handler(handlerton *hton,
TABLE_SHARE *table,
-@@ -838,6 +844,17 @@
+@@ -839,6 +845,17 @@
}
}
/********************************************************************//**
Obtain the InnoDB transaction of a MySQL thread.
@return reference to transaction pointer */
-@@ -2437,6 +2454,9 @@
+@@ -2442,6 +2459,9 @@
srv_n_read_io_threads = (ulint) innobase_read_io_threads;
srv_n_write_io_threads = (ulint) innobase_write_io_threads;
srv_force_recovery = (ulint) innobase_force_recovery;
srv_use_doublewrite_buf = (ibool) innobase_use_doublewrite;
-@@ -11025,7 +11045,7 @@
+@@ -11036,7 +11056,7 @@
PLUGIN_VAR_OPCMDARG | PLUGIN_VAR_READONLY,
"Purge threads can be either 0 or 1.",
NULL, NULL,
0, /* Minimum value */
1, 0); /* Maximum value */
-@@ -11067,12 +11087,18 @@
+@@ -11078,12 +11098,18 @@
innodb_file_format_max_validate,
innodb_file_format_max_update, "Antelope");
static MYSQL_SYSVAR_STR(flush_method, innobase_file_flush_method,
PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY,
-@@ -11167,7 +11193,7 @@
+@@ -11183,7 +11209,7 @@
static MYSQL_SYSVAR_LONGLONG(buffer_pool_size, innobase_buffer_pool_size,
PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY,
"The size of the memory buffer InnoDB uses to cache data and indexes of its tables.",
static MYSQL_SYSVAR_LONG(buffer_pool_instances, innobase_buffer_pool_instances,
PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY,
-@@ -11319,6 +11345,95 @@
+@@ -11335,6 +11361,95 @@
"trigger a readahead.",
NULL, NULL, 56, 0, 64, 0);
static struct st_mysql_sys_var* innobase_system_variables[]= {
MYSQL_SYSVAR(additional_mem_pool_size),
MYSQL_SYSVAR(autoextend_increment),
-@@ -11339,6 +11454,7 @@
+@@ -11355,6 +11470,7 @@
MYSQL_SYSVAR(file_format_check),
MYSQL_SYSVAR(file_format_max),
MYSQL_SYSVAR(flush_log_at_trx_commit),
+ MYSQL_SYSVAR(use_global_flush_log_at_trx_commit),
MYSQL_SYSVAR(flush_method),
MYSQL_SYSVAR(force_recovery),
- MYSQL_SYSVAR(locks_unsafe_for_binlog),
-@@ -11376,6 +11492,13 @@
+ MYSQL_SYSVAR(large_prefix),
+@@ -11393,6 +11509,13 @@
MYSQL_SYSVAR(show_verbose_locks),
MYSQL_SYSVAR(show_locks_held),
MYSQL_SYSVAR(version),
MYSQL_SYSVAR(use_sys_malloc),
MYSQL_SYSVAR(use_native_aio),
MYSQL_SYSVAR(change_buffering),
-diff -ruN a/storage/innobase/ibuf/ibuf0ibuf.c b/storage/innobase/ibuf/ibuf0ibuf.c
---- a/storage/innobase/ibuf/ibuf0ibuf.c 2010-11-03 07:01:13.000000000 +0900
-+++ b/storage/innobase/ibuf/ibuf0ibuf.c 2010-12-03 15:10:09.073984282 +0900
+--- a/storage/innobase/ibuf/ibuf0ibuf.c
++++ b/storage/innobase/ibuf/ibuf0ibuf.c
@@ -514,8 +514,10 @@
grow in size, as the references on the upper levels of the tree can
change */
sync = (size >= max_size + IBUF_CONTRACT_ON_INSERT_SYNC);
-diff -ruN a/storage/innobase/include/buf0rea.h b/storage/innobase/include/buf0rea.h
---- a/storage/innobase/include/buf0rea.h 2010-11-03 07:01:13.000000000 +0900
-+++ b/storage/innobase/include/buf0rea.h 2010-12-03 15:10:09.076066335 +0900
+--- a/storage/innobase/include/buf0rea.h
++++ b/storage/innobase/include/buf0rea.h
@@ -124,8 +124,7 @@
/** The size in pages of the area which the read-ahead algorithms read if
/** @name Modes used in read-ahead @{ */
/** read only pages belonging to the insert buffer tree */
-diff -ruN a/storage/innobase/include/fil0fil.h b/storage/innobase/include/fil0fil.h
---- a/storage/innobase/include/fil0fil.h 2011-06-29 17:48:24.818969583 +0900
-+++ b/storage/innobase/include/fil0fil.h 2011-06-29 17:58:49.215971540 +0900
+--- a/storage/innobase/include/fil0fil.h
++++ b/storage/innobase/include/fil0fil.h
@@ -658,8 +658,9 @@
void
fil_flush(
/**********************************************************************//**
Flushes to disk writes in file spaces of the given type possibly cached by
the OS. */
-diff -ruN a/storage/innobase/include/ha_prototypes.h b/storage/innobase/include/ha_prototypes.h
---- a/storage/innobase/include/ha_prototypes.h 2010-11-03 07:01:13.000000000 +0900
-+++ b/storage/innobase/include/ha_prototypes.h 2010-12-03 15:10:09.078026360 +0900
+--- a/storage/innobase/include/ha_prototypes.h
++++ b/storage/innobase/include/ha_prototypes.h
@@ -284,6 +284,13 @@
/*===================*/
void* thd, /*!< in: thread handle (THD*) */
/**********************************************************************//**
Get the current setting of the lower_case_table_names global parameter from
-diff -ruN a/storage/innobase/include/os0file.h b/storage/innobase/include/os0file.h
---- a/storage/innobase/include/os0file.h 2011-05-11 20:54:12.000000000 +0900
-+++ b/storage/innobase/include/os0file.h 2011-06-29 17:55:21.947041132 +0900
+--- a/storage/innobase/include/os0file.h
++++ b/storage/innobase/include/os0file.h
@@ -296,8 +296,8 @@
pfs_os_file_write_func(name, file, buf, offset, offset_high, \
n, __FILE__, __LINE__)
/***********************************************************************//**
Retrieves the last error number if an error occurs in a file io function.
The number should be retrieved before any other OS calls (because they may
-diff -ruN a/storage/innobase/include/os0file.ic b/storage/innobase/include/os0file.ic
---- a/storage/innobase/include/os0file.ic 2011-05-11 20:54:12.000000000 +0900
-+++ b/storage/innobase/include/os0file.ic 2011-06-29 17:56:01.510958172 +0900
+--- a/storage/innobase/include/os0file.ic
++++ b/storage/innobase/include/os0file.ic
@@ -369,6 +369,7 @@
pfs_os_file_flush_func(
/*===================*/
register_pfs_file_io_end(locker, 0);
-diff -ruN a/storage/innobase/include/srv0srv.h b/storage/innobase/include/srv0srv.h
---- a/storage/innobase/include/srv0srv.h 2010-12-03 15:09:51.291955835 +0900
-+++ b/storage/innobase/include/srv0srv.h 2010-12-03 15:10:09.079029047 +0900
+--- a/storage/innobase/include/srv0srv.h
++++ b/storage/innobase/include/srv0srv.h
@@ -138,7 +138,8 @@
extern ulint srv_n_log_files;
extern ulint srv_log_file_size;
};
/** Alternatives for file i/o in Windows */
-diff -ruN a/storage/innobase/log/log0log.c b/storage/innobase/log/log0log.c
---- a/storage/innobase/log/log0log.c 2010-11-03 07:01:13.000000000 +0900
-+++ b/storage/innobase/log/log0log.c 2010-12-03 15:10:09.084023562 +0900
+--- a/storage/innobase/log/log0log.c
++++ b/storage/innobase/log/log0log.c
@@ -48,6 +48,7 @@
#include "srv0start.h"
#include "trx0sys.h"
current_time = time(NULL);
time_elapsed = 0.001 + difftime(current_time,
-diff -ruN a/storage/innobase/log/log0recv.c b/storage/innobase/log/log0recv.c
---- a/storage/innobase/log/log0recv.c 2010-11-03 07:01:13.000000000 +0900
-+++ b/storage/innobase/log/log0recv.c 2010-12-03 15:10:09.089024191 +0900
+--- a/storage/innobase/log/log0recv.c
++++ b/storage/innobase/log/log0recv.c
@@ -2906,9 +2906,12 @@
ib_uint64_t archived_lsn;
#endif /* UNIV_LOG_ARCHIVE */
os_file_close(log_file);
ut_free(buf);
-diff -ruN a/storage/innobase/os/os0file.c b/storage/innobase/os/os0file.c
---- a/storage/innobase/os/os0file.c 2010-11-03 07:01:13.000000000 +0900
-+++ b/storage/innobase/os/os0file.c 2010-12-03 15:10:09.093023540 +0900
+--- a/storage/innobase/os/os0file.c
++++ b/storage/innobase/os/os0file.c
@@ -1424,7 +1424,7 @@
#endif
#ifdef UNIV_NON_BUFFERED_IO
{
int ret;
int failures;
-@@ -2055,7 +2061,15 @@
+@@ -2055,7 +2061,16 @@
failures = 0;
do {
-+#ifdef HAVE_FDATASYNC
++#if defined(HAVE_FDATASYNC) && HAVE_DECL_FDATASYNC
+ if (metadata) {
+ ret = fsync(file);
+ } else {
+ ret = fdatasync(file);
+ }
+#else
++ (void) metadata;
ret = fsync(file);
+#endif
os_n_fsyncs++;
-@@ -2092,7 +2106,8 @@
+@@ -2092,7 +2107,8 @@
ibool
os_file_flush_func(
/*===============*/
{
#ifdef __WIN__
BOOL ret;
-@@ -2142,18 +2157,18 @@
+@@ -2142,18 +2158,18 @@
/* If we are not on an operating system that supports this,
then fall back to a plain fsync. */
#endif
if (ret == 0) {
-@@ -2336,7 +2351,7 @@
+@@ -2336,7 +2352,7 @@
the OS crashes, a database page is only partially
physically written to disk. */
}
# endif /* UNIV_DO_FLUSH */
-@@ -2378,7 +2393,7 @@
+@@ -2378,7 +2394,7 @@
the OS crashes, a database page is only partially
physically written to disk. */
}
# endif /* UNIV_DO_FLUSH */
-@@ -2750,7 +2765,7 @@
+@@ -2750,7 +2766,7 @@
# ifdef UNIV_DO_FLUSH
if (!os_do_not_call_flush_at_each_write) {
}
# endif /* UNIV_DO_FLUSH */
-@@ -4289,7 +4304,7 @@
+@@ -4296,7 +4312,7 @@
#ifdef UNIV_DO_FLUSH
if (slot->type == OS_FILE_WRITE
&& !os_do_not_call_flush_at_each_write) {
ut_error;
}
}
-@@ -4590,7 +4605,7 @@
+@@ -4597,7 +4613,7 @@
#ifdef UNIV_DO_FLUSH
if (slot->type == OS_FILE_WRITE
&& !os_do_not_call_flush_at_each_write)
ut_error;
}
#endif /* UNIV_DO_FLUSH */
-diff -ruN a/storage/innobase/srv/srv0srv.c b/storage/innobase/srv/srv0srv.c
---- a/storage/innobase/srv/srv0srv.c 2010-12-03 15:09:51.301987792 +0900
-+++ b/storage/innobase/srv/srv0srv.c 2010-12-03 15:13:29.369986988 +0900
+--- a/storage/innobase/srv/srv0srv.c
++++ b/storage/innobase/srv/srv0srv.c
@@ -183,7 +183,8 @@
UNIV_INTERN ulint srv_log_file_size = ULINT_MAX;
/* size in database pages */
/*-------------------------------------------*/
UNIV_INTERN ulong srv_n_spin_wait_rounds = 30;
UNIV_INTERN ulong srv_n_free_tickets_to_enter = 500;
+@@ -2709,7 +2721,7 @@
+
+ ut_ad(!mutex_own(&kernel_mutex));
+
+- ut_a(srv_n_purge_threads == 0);
++ ut_a(srv_n_purge_threads == 0 || (srv_shutdown_state > 0 && srv_n_threads_active[SRV_WORKER] == 0));
+
+ do {
+ /* Check for shutdown and change in purge config. */
@@ -2742,6 +2754,7 @@
ulint n_pages_purged = 0;
ulint n_bytes_merged;
}
if (srv_activity_count == old_activity_count) {
-@@ -2941,7 +3213,7 @@
+@@ -2941,12 +3213,12 @@
even if the server were active */
srv_main_thread_op_info = "doing insert buffer merge";
/* Flush logs if needed */
srv_sync_log_buffer_in_background();
+
+- if (srv_n_purge_threads == 0) {
++ if (srv_n_purge_threads == 0 || (srv_shutdown_state > 0 && srv_n_threads_active[SRV_WORKER] == 0)) {
+ srv_main_thread_op_info = "master purging";
+
+ srv_master_do_purge();
+@@ -3024,7 +3296,7 @@
+ }
+ }
+
+- if (srv_n_purge_threads == 0) {
++ if (srv_n_purge_threads == 0 || (srv_shutdown_state > 0 && srv_n_threads_active[SRV_WORKER] == 0)) {
+ srv_main_thread_op_info = "master purging";
+
+ srv_master_do_purge();
@@ -3049,7 +3321,7 @@
buf_flush_list below. Otherwise, the system favors
clean pages over cleanup throughput. */
}
mutex_enter(&kernel_mutex);
-diff -ruN a/storage/innobase/srv/srv0start.c b/storage/innobase/srv/srv0start.c
---- a/storage/innobase/srv/srv0start.c 2010-11-03 07:01:13.000000000 +0900
-+++ b/storage/innobase/srv/srv0start.c 2010-12-03 15:10:09.103023543 +0900
+--- a/storage/innobase/srv/srv0start.c
++++ b/storage/innobase/srv/srv0start.c
@@ -1217,6 +1217,9 @@
} else if (0 == ut_strcmp(srv_file_flush_method_str, "O_DIRECT")) {
srv_unix_file_flush_method = SRV_UNIX_O_DIRECT;
} else if (0 == ut_strcmp(srv_file_flush_method_str, "littlesync")) {
srv_unix_file_flush_method = SRV_UNIX_LITTLESYNC;
-diff -ruN a/storage/innobase/trx/trx0purge.c b/storage/innobase/trx/trx0purge.c
---- a/storage/innobase/trx/trx0purge.c 2011-04-12 14:14:14.000000000 +0900
-+++ b/storage/innobase/trx/trx0purge.c 2011-04-12 14:15:44.000000000 +0900
+--- a/storage/innobase/trx/trx0purge.c
++++ b/storage/innobase/trx/trx0purge.c
@@ -392,10 +392,10 @@
trx_sys->rseg_history_len++;
mutex_exit(&kernel_mutex);
}
/**********************************************************************//**
-diff -ruN a/storage/innobase/trx/trx0trx.c b/storage/innobase/trx/trx0trx.c
---- a/storage/innobase/trx/trx0trx.c 2010-11-03 07:01:13.000000000 +0900
-+++ b/storage/innobase/trx/trx0trx.c 2010-12-03 15:10:09.106023937 +0900
+--- a/storage/innobase/trx/trx0trx.c
++++ b/storage/innobase/trx/trx0trx.c
@@ -984,6 +984,7 @@
trx->read_view = NULL;
#!!! notice !!!
# Any small change to this file in the main branch
# should be done or reviewed by the maintainer!
-diff -ruN a/storage/innobase/buf/buf0lru.c b/storage/innobase/buf/buf0lru.c
---- a/storage/innobase/buf/buf0lru.c 2010-12-03 15:49:59.185023424 +0900
-+++ b/storage/innobase/buf/buf0lru.c 2010-12-04 15:33:37.626482350 +0900
-@@ -2247,6 +2247,284 @@
+--- a/storage/innobase/buf/buf0lru.c
++++ b/storage/innobase/buf/buf0lru.c
+@@ -2167,6 +2167,284 @@
memset(&buf_LRU_stat_cur, 0, sizeof buf_LRU_stat_cur);
}
#if defined UNIV_DEBUG || defined UNIV_BUF_DEBUG
/**********************************************************************//**
Validates the LRU list for one buffer pool instance. */
-diff -ruN a/storage/innobase/buf/buf0rea.c b/storage/innobase/buf/buf0rea.c
---- a/storage/innobase/buf/buf0rea.c 2010-12-03 17:49:11.576124814 +0900
-+++ b/storage/innobase/buf/buf0rea.c 2010-12-04 15:33:37.628480605 +0900
+--- a/storage/innobase/buf/buf0rea.c
++++ b/storage/innobase/buf/buf0rea.c
@@ -58,7 +58,7 @@
which case it is never read into the pool, or if the tablespace does
not exist or is being dropped
ulint
buf_read_page_low(
/*==============*/
-diff -ruN a/storage/innobase/fil/fil0fil.c b/storage/innobase/fil/fil0fil.c
---- a/storage/innobase/fil/fil0fil.c 2010-12-03 17:49:11.581025127 +0900
-+++ b/storage/innobase/fil/fil0fil.c 2010-12-04 15:33:37.632482885 +0900
-@@ -5289,6 +5289,70 @@
+--- a/storage/innobase/fil/fil0fil.c
++++ b/storage/innobase/fil/fil0fil.c
+@@ -5290,6 +5290,70 @@
return(DB_SUCCESS);
}
#ifndef UNIV_HOTBACKUP
/**********************************************************************//**
Waits for an aio operation to complete. This function is used to write the
-diff -ruN a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc
---- a/storage/innobase/handler/ha_innodb.cc 2010-12-03 17:49:11.589956135 +0900
-+++ b/storage/innobase/handler/ha_innodb.cc 2010-12-04 15:33:37.645555490 +0900
-@@ -11793,6 +11793,12 @@
+--- a/storage/innobase/handler/ha_innodb.cc
++++ b/storage/innobase/handler/ha_innodb.cc
+@@ -11809,6 +11809,12 @@
"Limit the allocated memory for dictionary cache. (0: unlimited)",
NULL, NULL, 0, 0, LONG_MAX, 0);
static struct st_mysql_sys_var* innobase_system_variables[]= {
MYSQL_SYSVAR(additional_mem_pool_size),
MYSQL_SYSVAR(autoextend_increment),
-@@ -11874,6 +11880,7 @@
+@@ -11891,6 +11897,7 @@
#endif /* UNIV_DEBUG || UNIV_IBUF_DEBUG */
MYSQL_SYSVAR(read_ahead_threshold),
MYSQL_SYSVAR(io_capacity),
MYSQL_SYSVAR(purge_threads),
MYSQL_SYSVAR(purge_batch_size),
MYSQL_SYSVAR(rollback_segments),
-diff -ruN a/storage/innobase/handler/i_s.cc b/storage/innobase/handler/i_s.cc
---- a/storage/innobase/handler/i_s.cc 2010-12-03 17:34:35.286211349 +0900
-+++ b/storage/innobase/handler/i_s.cc 2010-12-04 15:33:37.677480733 +0900
+--- a/storage/innobase/handler/i_s.cc
++++ b/storage/innobase/handler/i_s.cc
@@ -50,6 +50,7 @@
#include "trx0rseg.h" /* for trx_rseg_struct */
#include "trx0sys.h" /* for trx_sys */
field_store_string(i_s_table->field[0],
"Undefined XTRA_* command.");
-diff -ruN a/storage/innobase/include/buf0lru.h b/storage/innobase/include/buf0lru.h
---- a/storage/innobase/include/buf0lru.h 2010-12-03 15:49:59.223956070 +0900
-+++ b/storage/innobase/include/buf0lru.h 2010-12-04 15:33:37.681481467 +0900
-@@ -215,6 +215,18 @@
+--- a/storage/innobase/include/buf0lru.h
++++ b/storage/innobase/include/buf0lru.h
+@@ -204,6 +204,18 @@
void
buf_LRU_stat_update(void);
/*=====================*/
#if defined UNIV_DEBUG || defined UNIV_BUF_DEBUG
/**********************************************************************//**
-diff -ruN a/storage/innobase/include/buf0rea.h b/storage/innobase/include/buf0rea.h
---- a/storage/innobase/include/buf0rea.h 2010-12-03 17:49:11.596953870 +0900
-+++ b/storage/innobase/include/buf0rea.h 2010-12-04 15:33:37.682563900 +0900
+--- a/storage/innobase/include/buf0rea.h
++++ b/storage/innobase/include/buf0rea.h
@@ -31,6 +31,37 @@
#include "buf0types.h"
High-level function which reads a page asynchronously from a file to the
buffer buf_pool if it is not already there. Sets the io_fix flag and sets
an exclusive lock on the buffer frame. The flag is cleared and the x-lock
-diff -ruN a/storage/innobase/include/fil0fil.h b/storage/innobase/include/fil0fil.h
---- a/storage/innobase/include/fil0fil.h 2010-12-03 17:49:11.597953501 +0900
-+++ b/storage/innobase/include/fil0fil.h 2010-12-04 15:33:37.684551372 +0900
+--- a/storage/innobase/include/fil0fil.h
++++ b/storage/innobase/include/fil0fil.h
@@ -644,6 +644,14 @@
void* message, /*!< in: message for aio handler if non-sync
aio used, else ignored */
/**********************************************************************//**
Waits for an aio operation to complete. This function is used to write the
handler for completed requests. The aio array of pending requests is divided
-diff -ruN a/storage/innobase/include/srv0srv.h b/storage/innobase/include/srv0srv.h
---- a/storage/innobase/include/srv0srv.h 2010-12-03 17:49:11.603969747 +0900
-+++ b/storage/innobase/include/srv0srv.h 2010-12-04 15:33:37.685550816 +0900
+--- a/storage/innobase/include/srv0srv.h
++++ b/storage/innobase/include/srv0srv.h
@@ -356,6 +356,9 @@
reading of a disk page */
extern ulint srv_buf_pool_reads;
/******************************************************************//**
Outputs to a file the output of the InnoDB Monitor.
@return FALSE if not all information printed
-diff -ruN a/storage/innobase/srv/srv0srv.c b/storage/innobase/srv/srv0srv.c
---- a/storage/innobase/srv/srv0srv.c 2010-12-03 17:49:11.620986661 +0900
-+++ b/storage/innobase/srv/srv0srv.c 2010-12-04 15:33:37.708550811 +0900
+--- a/storage/innobase/srv/srv0srv.c
++++ b/storage/innobase/srv/srv0srv.c
@@ -330,6 +330,9 @@
reading of a disk page */
UNIV_INTERN ulint srv_buf_pool_reads = 0;
/* structure to pass status variables to MySQL */
UNIV_INTERN export_struc export_vars;
-@@ -2701,6 +2704,56 @@
- /* We count the number of threads in os_thread_exit(). A created
- thread should always use that to exit and not use return() to exit. */
+@@ -2706,6 +2709,56 @@
+ OS_THREAD_DUMMY_RETURN;
+ }
-+ os_thread_exit(NULL);
-+
-+ OS_THREAD_DUMMY_RETURN;
-+}
-+
+/*********************************************************************//**
+A thread which restores the buffer pool from a dump file on startup and does
+periodic buffer pool dumps.
+ /* We count the number of threads in os_thread_exit(). A created
+ thread should always use that to exit and not use return() to exit. */
+
- os_thread_exit(NULL);
-
- OS_THREAD_DUMMY_RETURN;
-diff -ruN a/storage/innobase/srv/srv0start.c b/storage/innobase/srv/srv0start.c
---- a/storage/innobase/srv/srv0start.c 2010-12-03 15:18:48.916955609 +0900
-+++ b/storage/innobase/srv/srv0start.c 2010-12-04 15:33:37.711484798 +0900
++ os_thread_exit(NULL);
++
++ OS_THREAD_DUMMY_RETURN;
++}
++
+ /**********************************************************************//**
+ Check whether any background thread is active.
+ @return FALSE if all are are suspended or have exited. */
+--- a/storage/innobase/srv/srv0start.c
++++ b/storage/innobase/srv/srv0start.c
@@ -120,9 +120,9 @@
static os_file_t files[1000];
#!!! notice !!!
# Any small change to this file in the main branch
# should be done or reviewed by the maintainer!
-diff -ruN a/storage/innobase/buf/buf0buddy.c b/storage/innobase/buf/buf0buddy.c
---- a/storage/innobase/buf/buf0buddy.c 2010-11-03 07:01:13.000000000 +0900
-+++ b/storage/innobase/buf/buf0buddy.c 2010-12-03 15:20:49.593024343 +0900
-@@ -137,7 +137,7 @@
- ut_ad(buf_page_get_state(ut_list_node_313)
- == BUF_BLOCK_ZIP_FREE)));
- #endif /* !UNIV_DEBUG_VALGRIND */
+--- a/storage/innobase/buf/buf0buddy.c
++++ b/storage/innobase/buf/buf0buddy.c
+@@ -123,7 +123,7 @@
+
+ ut_d(BUF_BUDDY_LIST_VALIDATE(buf_pool, i));
+
- bpage = UT_LIST_GET_FIRST(buf_pool->zip_free[i]);
+ bpage = UT_LIST_GET_LAST(buf_pool->zip_free[i]);
if (bpage) {
- UNIV_MEM_VALID(bpage, BUF_BUDDY_LOW << i);
-diff -ruN a/storage/innobase/buf/buf0buf.c b/storage/innobase/buf/buf0buf.c
---- a/storage/innobase/buf/buf0buf.c 2010-12-03 15:18:48.866986963 +0900
-+++ b/storage/innobase/buf/buf0buf.c 2010-12-03 15:20:49.595987311 +0900
+ ut_a(buf_page_get_state(bpage) == BUF_BLOCK_ZIP_FREE);
+--- a/storage/innobase/buf/buf0buf.c
++++ b/storage/innobase/buf/buf0buf.c
@@ -881,9 +881,9 @@
block->page.in_zip_hash = FALSE;
block->page.in_flush_list = FALSE;
#if defined UNIV_AHI_DEBUG || defined UNIV_DEBUG
block->n_pointers = 0;
#endif /* UNIV_AHI_DEBUG || UNIV_DEBUG */
-@@ -1494,7 +1494,7 @@
+@@ -1428,7 +1428,7 @@
memcpy(dpage, bpage, sizeof *dpage);
ut_d(bpage->in_page_hash = FALSE);
/* relocate buf_pool->LRU */
-@@ -3747,8 +3747,8 @@
+@@ -3279,8 +3279,8 @@
bpage->in_zip_hash = FALSE;
bpage->in_flush_list = FALSE;
bpage->in_free_list = FALSE;
ut_d(bpage->in_page_hash = TRUE);
-@@ -3911,7 +3911,7 @@
+@@ -3445,7 +3445,7 @@
ibuf_merge_or_delete_for_page(NULL, space, offset, zip_size, TRUE);
/* Flush pages from the end of the LRU list if necessary */
frame = block->frame;
-diff -ruN a/storage/innobase/buf/buf0flu.c b/storage/innobase/buf/buf0flu.c
---- a/storage/innobase/buf/buf0flu.c 2010-12-03 15:18:48.868953442 +0900
-+++ b/storage/innobase/buf/buf0flu.c 2010-12-03 15:20:49.599986956 +0900
+--- a/storage/innobase/buf/buf0flu.c
++++ b/storage/innobase/buf/buf0flu.c
@@ -431,19 +431,21 @@
buf_page_in_file(bpage) and in the LRU list */
{
return(FALSE);
}
-@@ -1983,8 +1986,14 @@
+@@ -1985,8 +1988,14 @@
buf_page_t* bpage;
ulint n_replaceable;
ulint distance = 0;
n_replaceable = UT_LIST_GET_LEN(buf_pool->free);
-@@ -1995,7 +2004,13 @@
+@@ -1997,7 +2006,13 @@
+ BUF_FLUSH_EXTRA_MARGIN(buf_pool))
&& (distance < BUF_LRU_FREE_SEARCH_LEN(buf_pool))) {
mutex_enter(block_mutex);
-@@ -2010,11 +2025,18 @@
+@@ -2012,11 +2027,18 @@
bpage = UT_LIST_GET_PREV(LRU, bpage);
}
}
return(BUF_FLUSH_FREE_BLOCK_MARGIN(buf_pool)
-@@ -2032,7 +2054,8 @@
+@@ -2034,7 +2056,8 @@
void
buf_flush_free_margin(
/*==================*/
{
ulint n_to_flush;
-@@ -2043,7 +2066,7 @@
+@@ -2045,7 +2068,7 @@
n_flushed = buf_flush_LRU(buf_pool, n_to_flush);
/* There was an LRU type flush batch already running;
let us wait for it to end */
-@@ -2056,8 +2079,9 @@
+@@ -2058,8 +2081,9 @@
Flushes pages from the end of all the LRU lists. */
UNIV_INTERN
void
{
ulint i;
-@@ -2066,7 +2090,7 @@
+@@ -2068,7 +2092,7 @@
buf_pool = buf_pool_from_array(i);
}
}
-diff -ruN a/storage/innobase/buf/buf0lru.c b/storage/innobase/buf/buf0lru.c
---- a/storage/innobase/buf/buf0lru.c 2010-11-03 07:01:13.000000000 +0900
-+++ b/storage/innobase/buf/buf0lru.c 2010-12-03 15:20:49.602952786 +0900
-@@ -996,7 +996,7 @@
+--- a/storage/innobase/buf/buf0lru.c
++++ b/storage/innobase/buf/buf0lru.c
+@@ -923,7 +923,7 @@
/* No free block was found: try to flush the LRU list */
++srv_buf_pool_wait_free;
os_aio_simulated_wake_handler_threads();
-@@ -1193,7 +1193,7 @@
+@@ -1120,7 +1120,7 @@
/* Remove the block from the LRU list */
UT_LIST_REMOVE(LRU, buf_pool->LRU, bpage);
buf_unzip_LRU_remove_block_if_needed(bpage);
-@@ -1272,7 +1272,7 @@
+@@ -1199,7 +1199,7 @@
ut_ad(!bpage->in_LRU_list);
UT_LIST_ADD_LAST(LRU, buf_pool->LRU, bpage);
if (UT_LIST_GET_LEN(buf_pool->LRU) > BUF_LRU_OLD_MIN_LEN) {
-@@ -1342,7 +1342,7 @@
+@@ -1269,7 +1269,7 @@
buf_pool->LRU_old_len++;
}
if (UT_LIST_GET_LEN(buf_pool->LRU) > BUF_LRU_OLD_MIN_LEN) {
-@@ -1593,7 +1593,7 @@
+@@ -1513,7 +1513,7 @@
buf_page_set_old(b, buf_page_is_old(b));
#endif /* UNIV_LRU_DEBUG */
} else {
buf_LRU_add_block_low(b, buf_page_is_old(b));
}
-diff -ruN a/storage/innobase/buf/buf0rea.c b/storage/innobase/buf/buf0rea.c
---- a/storage/innobase/buf/buf0rea.c 2010-12-03 15:18:48.870953384 +0900
-+++ b/storage/innobase/buf/buf0rea.c 2010-12-03 15:20:49.604956032 +0900
+--- a/storage/innobase/buf/buf0rea.c
++++ b/storage/innobase/buf/buf0rea.c
@@ -200,7 +200,7 @@
}
#ifdef UNIV_DEBUG
if (buf_debug_prints) {
-diff -ruN a/storage/innobase/include/buf0buf.h b/storage/innobase/include/buf0buf.h
---- a/storage/innobase/include/buf0buf.h 2010-11-03 07:01:13.000000000 +0900
-+++ b/storage/innobase/include/buf0buf.h 2010-12-03 15:20:49.608986590 +0900
-@@ -1387,11 +1387,11 @@
+--- a/storage/innobase/include/buf0buf.h
++++ b/storage/innobase/include/buf0buf.h
+@@ -1426,11 +1426,11 @@
UT_LIST_NODE_T(buf_page_t) LRU;
/*!< node of the LRU list */
unsigned old:1; /*!< TRUE if the block is in the old
blocks in buf_pool->LRU_old */
unsigned freed_page_clock:31;/*!< the value of
-diff -ruN a/storage/innobase/include/buf0flu.h b/storage/innobase/include/buf0flu.h
---- a/storage/innobase/include/buf0flu.h 2010-11-03 07:01:13.000000000 +0900
-+++ b/storage/innobase/include/buf0flu.h 2010-12-03 15:20:49.609953185 +0900
+--- a/storage/innobase/include/buf0flu.h
++++ b/storage/innobase/include/buf0flu.h
@@ -65,13 +65,15 @@
void
buf_flush_free_margin(
#!!! notice !!!
# Any small change to this file in the main branch
# should be done or reviewed by the maintainer!
-diff -ruN a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc
---- a/storage/innobase/handler/ha_innodb.cc 2010-12-03 15:37:45.516105468 +0900
-+++ b/storage/innobase/handler/ha_innodb.cc 2010-12-03 15:38:20.318952987 +0900
+--- a/storage/innobase/handler/ha_innodb.cc
++++ b/storage/innobase/handler/ha_innodb.cc
@@ -42,6 +42,8 @@
#pragma implementation // gcc: Class implementation
#endif
static my_bool innobase_rollback_on_timeout = FALSE;
static my_bool innobase_create_status_file = FALSE;
static my_bool innobase_stats_on_metadata = TRUE;
-@@ -2248,6 +2268,89 @@
+@@ -2253,6 +2273,89 @@
}
#endif /* DBUG_OFF */
/* Check that values don't overflow on 32-bit systems. */
if (sizeof(ulint) == 4) {
if (innobase_buffer_pool_size > UINT_MAX32) {
-@@ -2546,6 +2649,76 @@
+@@ -2551,6 +2654,76 @@
goto mem_free_and_error;
}
innobase_old_blocks_pct = buf_LRU_old_ratio_update(
innobase_old_blocks_pct, TRUE);
-@@ -2658,6 +2831,25 @@
+@@ -2665,6 +2838,25 @@
trx_t* trx) /*!< in: transaction handle */
{
if (trx_is_started(trx)) {
trx_commit_for_mysql(trx);
}
-@@ -11014,6 +11206,12 @@
+@@ -11025,6 +11217,12 @@
"The common part for InnoDB table spaces.",
NULL, NULL, NULL);
static MYSQL_SYSVAR_BOOL(doublewrite, innobase_use_doublewrite,
PLUGIN_VAR_NOCMDARG | PLUGIN_VAR_READONLY,
"Enable InnoDB doublewrite buffer (enabled by default). "
-@@ -11474,6 +11672,7 @@
+@@ -11491,6 +11689,7 @@
MYSQL_SYSVAR(old_blocks_pct),
MYSQL_SYSVAR(old_blocks_time),
MYSQL_SYSVAR(open_files),
MYSQL_SYSVAR(rollback_on_timeout),
MYSQL_SYSVAR(stats_on_metadata),
MYSQL_SYSVAR(stats_sample_pages),
-diff -ruN a/storage/innobase/include/trx0sys.h b/storage/innobase/include/trx0sys.h
---- a/storage/innobase/include/trx0sys.h 2010-11-03 07:01:13.000000000 +0900
-+++ b/storage/innobase/include/trx0sys.h 2010-12-03 15:38:20.321953297 +0900
+--- a/storage/innobase/include/trx0sys.h
++++ b/storage/innobase/include/trx0sys.h
@@ -53,6 +53,9 @@
extern ib_int64_t trx_sys_mysql_master_log_pos;
/* @} */
/** If this MySQL server uses binary logging, after InnoDB has been inited
and if it has done a crash recovery, we store the binlog file name and position
here. */
-@@ -287,7 +290,8 @@
+@@ -298,7 +301,8 @@
void
trx_sys_update_mysql_binlog_offset(
/*===============================*/
ib_int64_t offset, /*!< in: position in that log file */
ulint field, /*!< in: offset of the MySQL log info field in
the trx sys header */
-@@ -482,6 +486,7 @@
+@@ -493,6 +497,7 @@
@see trx_sys_mysql_master_log_name
@see trx_sys_mysql_bin_log_name */
#define TRX_SYS_MYSQL_LOG_NAME_LEN 512
/** Contents of TRX_SYS_MYSQL_LOG_MAGIC_N_FLD */
#define TRX_SYS_MYSQL_LOG_MAGIC_N 873422344
-@@ -491,6 +496,7 @@
+@@ -502,6 +507,7 @@
/** The offset of the MySQL replication info in the trx system header;
this contains the same fields as TRX_SYS_MYSQL_LOG_INFO below */
#define TRX_SYS_MYSQL_MASTER_LOG_INFO (UNIV_PAGE_SIZE - 2000)
/** The offset of the MySQL binlog offset info in the trx system header */
#define TRX_SYS_MYSQL_LOG_INFO (UNIV_PAGE_SIZE - 1000)
-diff -ruN a/storage/innobase/include/trx0trx.h b/storage/innobase/include/trx0trx.h
---- a/storage/innobase/include/trx0trx.h 2010-12-03 15:18:48.894955550 +0900
-+++ b/storage/innobase/include/trx0trx.h 2010-12-03 15:38:20.323953416 +0900
+--- a/storage/innobase/include/trx0trx.h
++++ b/storage/innobase/include/trx0trx.h
@@ -580,6 +580,20 @@
ib_int64_t mysql_log_offset;/* if MySQL binlog is used, this field
contains the end offset of the binlog
/*------------------------------*/
ulint n_mysql_tables_in_use; /* number of Innobase tables
used in the processing of the current
-diff -ruN a/storage/innobase/trx/trx0sys.c b/storage/innobase/trx/trx0sys.c
---- a/storage/innobase/trx/trx0sys.c 2010-11-03 07:01:13.000000000 +0900
-+++ b/storage/innobase/trx/trx0sys.c 2010-12-03 15:38:20.325956917 +0900
+--- a/storage/innobase/trx/trx0sys.c
++++ b/storage/innobase/trx/trx0sys.c
@@ -76,13 +76,16 @@
file name and position here. */
/* @{ */
mtr_commit(&mtr);
}
-diff -ruN a/storage/innobase/trx/trx0trx.c b/storage/innobase/trx/trx0trx.c
---- a/storage/innobase/trx/trx0trx.c 2010-12-03 15:37:45.549028990 +0900
-+++ b/storage/innobase/trx/trx0trx.c 2010-12-03 15:38:20.328957217 +0900
+--- a/storage/innobase/trx/trx0trx.c
++++ b/storage/innobase/trx/trx0trx.c
@@ -138,6 +138,10 @@
trx->mysql_log_file_name = NULL;
#!!! notice !!!
# Any small change to this file in the main branch
# should be done or reviewed by the maintainer!
-diff -ruN a/storage/innobase/btr/btr0btr.c b/storage/innobase/btr/btr0btr.c
---- a/storage/innobase/btr/btr0btr.c 2010-11-03 07:01:13.000000000 +0900
-+++ b/storage/innobase/btr/btr0btr.c 2010-12-04 15:38:18.110513593 +0900
+--- a/storage/innobase/btr/btr0btr.c
++++ b/storage/innobase/btr/btr0btr.c
@@ -691,6 +691,12 @@
root_page_no = dict_index_get_page(index);
btr_search_drop_page_hash_index(block);
header = buf_block_get_frame(block) + PAGE_HEADER + PAGE_BTR_SEG_TOP;
-diff -ruN a/storage/innobase/btr/btr0cur.c b/storage/innobase/btr/btr0cur.c
---- a/storage/innobase/btr/btr0cur.c 2010-12-03 17:30:16.239038936 +0900
-+++ b/storage/innobase/btr/btr0cur.c 2010-12-04 15:38:18.114551906 +0900
+--- a/storage/innobase/btr/btr0cur.c
++++ b/storage/innobase/btr/btr0cur.c
@@ -250,6 +250,11 @@
case BTR_MODIFY_LEAF:
mode = latch_mode == BTR_SEARCH_LEAF ? RW_S_LATCH : RW_X_LATCH;
page = buf_block_get_frame(block);
index = cursor->index;
zip_size = buf_block_get_zip_size(block);
-@@ -2925,6 +3003,11 @@
+@@ -2988,6 +3066,11 @@
block = btr_cur_get_block(cursor);
ut_ad(page_is_leaf(buf_block_get_frame(block)));
rec = btr_cur_get_rec(cursor);
-@@ -3628,6 +3711,11 @@
+@@ -3701,6 +3784,11 @@
page = btr_cur_get_page(&cursor);
rec = page_rec_get_next(page_get_infimum_rec(page));
if (!page_rec_is_supremum(rec)) {
-diff -ruN a/storage/innobase/btr/btr0pcur.c b/storage/innobase/btr/btr0pcur.c
---- a/storage/innobase/btr/btr0pcur.c 2010-11-03 07:01:13.000000000 +0900
-+++ b/storage/innobase/btr/btr0pcur.c 2010-12-04 15:38:18.116563877 +0900
+--- a/storage/innobase/btr/btr0pcur.c
++++ b/storage/innobase/btr/btr0pcur.c
@@ -32,7 +32,7 @@
#include "ut0byte.h"
#include "rem0cmp.h"
#ifdef UNIV_BTR_DEBUG
ut_a(page_is_comp(next_page) == page_is_comp(page));
ut_a(btr_page_get_prev(next_page, mtr)
-diff -ruN a/storage/innobase/btr/btr0sea.c b/storage/innobase/btr/btr0sea.c
---- a/storage/innobase/btr/btr0sea.c 2010-12-03 15:49:59.166193407 +0900
-+++ b/storage/innobase/btr/btr0sea.c 2010-12-04 15:38:18.118548961 +0900
+--- a/storage/innobase/btr/btr0sea.c
++++ b/storage/innobase/btr/btr0sea.c
@@ -42,7 +42,7 @@
#include "btr0pcur.h"
#include "btr0btr.h"
/* NOTE that the following two function calls do NOT protect
info or block->n_fields etc. with any semaphore, to save CPU time!
We cannot assume the fields are consistent when we return from
-diff -ruN a/storage/innobase/buf/buf0buf.c b/storage/innobase/buf/buf0buf.c
---- a/storage/innobase/buf/buf0buf.c 2010-12-04 15:37:50.554565654 +0900
-+++ b/storage/innobase/buf/buf0buf.c 2010-12-04 15:38:18.119548922 +0900
+--- a/storage/innobase/buf/buf0buf.c
++++ b/storage/innobase/buf/buf0buf.c
@@ -52,6 +52,7 @@
#include "log0recv.h"
#include "page0zip.h"
if (!ready) {
return(block);
-@@ -2479,6 +2485,13 @@
+@@ -2006,6 +2012,13 @@
return(NULL);
}
block_mutex = buf_page_get_mutex_enter(bpage);
rw_lock_s_unlock(&buf_pool->page_hash_latch);
-@@ -3059,6 +3072,13 @@
+@@ -2583,6 +2596,13 @@
return(NULL);
}
switch (buf_block_get_state(block)) {
buf_page_t* bpage;
ibool success;
-@@ -3733,6 +3753,7 @@
+@@ -3257,6 +3277,7 @@
bpage->newest_modification = 0;
bpage->oldest_modification = 0;
HASH_INVALIDATE(bpage, hash);
#if defined UNIV_DEBUG_FILE_ACCESSES || defined UNIV_DEBUG
bpage->file_page_was_freed = FALSE;
#endif /* UNIV_DEBUG_FILE_ACCESSES || UNIV_DEBUG */
-@@ -4322,6 +4343,7 @@
+@@ -3841,6 +3862,7 @@
(ulong) bpage->offset);
}
/* From version 3.23.38 up we store the page checksum
to the 4 first bytes of the page end lsn field */
-@@ -4363,6 +4385,23 @@
+@@ -3882,6 +3904,23 @@
REFMAN "forcing-innodb-recovery.html\n"
"InnoDB: about forcing recovery.\n", stderr);
if (srv_force_recovery < SRV_FORCE_IGNORE_CORRUPT) {
fputs("InnoDB: Ending processing because of"
" a corrupt database page.\n",
-@@ -4370,6 +4409,7 @@
+@@ -3889,6 +3928,7 @@
exit(1);
}
}
if (recv_recovery_is_on()) {
/* Pages must be uncompressed for crash recovery. */
-@@ -4379,8 +4419,11 @@
+@@ -3898,8 +3938,11 @@
if (uncompressed && !recv_no_ibuf_operations) {
ibuf_merge_or_delete_for_page(
TRUE);
}
}
-diff -ruN a/storage/innobase/buf/buf0rea.c b/storage/innobase/buf/buf0rea.c
---- a/storage/innobase/buf/buf0rea.c 2010-12-04 15:37:50.557553380 +0900
-+++ b/storage/innobase/buf/buf0rea.c 2010-12-04 15:41:09.784467585 +0900
+--- a/storage/innobase/buf/buf0rea.c
++++ b/storage/innobase/buf/buf0rea.c
@@ -193,7 +193,14 @@
((buf_block_t*) bpage)->frame, bpage, trx);
}
if (sync) {
/* The i/o is already completed when we arrive from
-diff -ruN a/storage/innobase/dict/dict0dict.c b/storage/innobase/dict/dict0dict.c
---- a/storage/innobase/dict/dict0dict.c 2010-12-03 17:30:16.248987063 +0900
-+++ b/storage/innobase/dict/dict0dict.c 2010-12-04 15:45:23.808513973 +0900
+--- a/storage/innobase/dict/dict0dict.c
++++ b/storage/innobase/dict/dict0dict.c
@@ -54,6 +54,7 @@
#include "row0merge.h"
#include "m_ctype.h" /* my_isspace() */
goto next_loop;
cached_foreign_tables = 0;
-@@ -4332,6 +4333,12 @@
+@@ -4366,6 +4367,12 @@
heap = mem_heap_create(1000);
while (index) {
size = btr_get_size(index, BTR_TOTAL_SIZE);
index->stat_index_size = size;
-@@ -4479,6 +4486,12 @@
+@@ -4513,6 +4520,12 @@
heap = mem_heap_create(1000);
while (index) {
/*===========================================*/
{
dict_table_t* sys_stats;
-@@ -4671,6 +4684,13 @@
+@@ -4705,6 +4718,13 @@
|| (srv_force_recovery < SRV_FORCE_NO_LOG_REDO
&& dict_index_is_clust(index)))) {
ulint size;
size = btr_get_size(index, BTR_TOTAL_SIZE);
index->stat_index_size = size;
-@@ -5467,4 +5487,42 @@
+@@ -5501,4 +5521,42 @@
rw_lock_free(&dict_table_stats_latches[i]);
}
}
+ }
+}
#endif /* !UNIV_HOTBACKUP */
-diff -ruN a/storage/innobase/dict/dict0mem.c b/storage/innobase/dict/dict0mem.c
---- a/storage/innobase/dict/dict0mem.c 2010-11-03 07:01:13.000000000 +0900
-+++ b/storage/innobase/dict/dict0mem.c 2010-12-04 15:38:18.126549463 +0900
+--- a/storage/innobase/dict/dict0mem.c
++++ b/storage/innobase/dict/dict0mem.c
@@ -96,6 +96,8 @@
/* The number of transactions that are either waiting on the
AUTOINC lock or have been granted the lock. */
#endif /* !UNIV_HOTBACKUP */
ut_d(table->magic_n = DICT_TABLE_MAGIC_N);
-diff -ruN a/storage/innobase/fil/fil0fil.c b/storage/innobase/fil/fil0fil.c
---- a/storage/innobase/fil/fil0fil.c 2010-12-04 15:37:50.564551587 +0900
-+++ b/storage/innobase/fil/fil0fil.c 2010-12-04 15:38:18.128549252 +0900
+--- a/storage/innobase/fil/fil0fil.c
++++ b/storage/innobase/fil/fil0fil.c
@@ -235,6 +235,7 @@
file we have written to */
ibool is_in_unflushed_spaces; /*!< TRUE if this space is
UT_LIST_NODE_T(fil_space_t) space_list;
/*!< list of all spaces */
ulint magic_n;/*!< FIL_SPACE_MAGIC_N */
-@@ -1293,6 +1294,8 @@
+@@ -1294,6 +1295,8 @@
ut_fold_string(name), space);
space->is_in_unflushed_spaces = FALSE;
UT_LIST_ADD_LAST(space_list, fil_system->space_list, space);
mutex_exit(&fil_system->mutex);
-@@ -5267,6 +5270,34 @@
+@@ -5268,6 +5271,34 @@
ut_a(byte_offset % OS_FILE_LOG_BLOCK_SIZE == 0);
ut_a((len % OS_FILE_LOG_BLOCK_SIZE) == 0);
#ifdef UNIV_HOTBACKUP
/* In ibbackup do normal i/o, not aio */
if (type == OS_FILE_READ) {
-@@ -5281,6 +5312,8 @@
+@@ -5282,6 +5313,8 @@
ret = os_aio(type, mode | wake_later, node->name, node->handle, buf,
offset_low, offset_high, len, node, message, trx);
#endif
ut_a(ret);
if (mode == OS_AIO_SYNC) {
-@@ -5781,3 +5814,46 @@
+@@ -5782,3 +5815,46 @@
return 0;
}
}
+ mutex_exit(&fil_system->mutex);
+}
+
-diff -ruN a/storage/innobase/fsp/fsp0fsp.c b/storage/innobase/fsp/fsp0fsp.c
---- a/storage/innobase/fsp/fsp0fsp.c 2010-12-04 15:37:50.569480615 +0900
-+++ b/storage/innobase/fsp/fsp0fsp.c 2010-12-04 15:38:18.131550103 +0900
+--- a/storage/innobase/fsp/fsp0fsp.c
++++ b/storage/innobase/fsp/fsp0fsp.c
@@ -369,6 +369,12 @@
ut_ad(id || !zip_size);
descr = fseg_get_first_extent(inode, space, zip_size, mtr);
if (descr != NULL) {
-diff -ruN a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc
---- a/storage/innobase/handler/ha_innodb.cc 2010-12-04 15:37:50.578486593 +0900
-+++ b/storage/innobase/handler/ha_innodb.cc 2010-12-04 15:38:18.137549396 +0900
-@@ -3972,6 +3972,12 @@
+--- a/storage/innobase/handler/ha_innodb.cc
++++ b/storage/innobase/handler/ha_innodb.cc
+@@ -3979,6 +3979,12 @@
DBUG_RETURN(1);
}
/* Create buffers for packing the fields of a record. Why
table->reclength did not work here? Obviously, because char
fields when packed actually became 1 byte longer, when we also
-@@ -3999,6 +4005,19 @@
+@@ -4006,6 +4012,19 @@
/* Get pointer to a table object in InnoDB dictionary cache */
ib_table = dict_table_get(norm_name, TRUE);
if (NULL == ib_table) {
if (is_part && retries < 10) {
++retries;
-@@ -5163,6 +5182,10 @@
+@@ -5174,6 +5193,10 @@
ha_statistic_increment(&SSV::ha_write_count);
if (table->timestamp_field_type & TIMESTAMP_AUTO_SET_ON_INSERT)
table->timestamp_field->set_time();
-@@ -5380,6 +5403,10 @@
+@@ -5391,6 +5414,10 @@
func_exit:
innobase_active_small();
DBUG_RETURN(error_result);
}
-@@ -5556,6 +5583,10 @@
+@@ -5567,6 +5594,10 @@
ha_statistic_increment(&SSV::ha_update_count);
if (table->timestamp_field_type & TIMESTAMP_AUTO_SET_ON_UPDATE)
table->timestamp_field->set_time();
-@@ -5645,6 +5676,10 @@
+@@ -5656,6 +5687,10 @@
innobase_active_small();
DBUG_RETURN(error);
}
-@@ -5666,6 +5701,10 @@
+@@ -5677,6 +5712,10 @@
ha_statistic_increment(&SSV::ha_delete_count);
if (!prebuilt->upd_node) {
row_get_prebuilt_update_vector(prebuilt);
}
-@@ -5692,6 +5731,10 @@
+@@ -5703,6 +5742,10 @@
innobase_active_small();
DBUG_RETURN(error);
}
-@@ -5931,6 +5974,10 @@
+@@ -5942,6 +5985,10 @@
ha_statistic_increment(&SSV::ha_read_key_count);
index = prebuilt->index;
if (UNIV_UNLIKELY(index == NULL)) {
-@@ -5996,6 +6043,10 @@
+@@ -6007,6 +6054,10 @@
ret = DB_UNSUPPORTED;
}
switch (ret) {
case DB_SUCCESS:
error = 0;
-@@ -6111,6 +6162,10 @@
+@@ -6122,6 +6173,10 @@
{
DBUG_ENTER("change_active_index");
ut_ad(user_thd == ha_thd());
ut_a(prebuilt->trx == thd_to_trx(user_thd));
-@@ -6201,6 +6256,10 @@
+@@ -6212,6 +6267,10 @@
DBUG_ENTER("general_fetch");
ut_a(prebuilt->trx == thd_to_trx(user_thd));
innodb_srv_conc_enter_innodb(prebuilt->trx);
-@@ -6210,6 +6269,10 @@
+@@ -6221,6 +6280,10 @@
innodb_srv_conc_exit_innodb(prebuilt->trx);
switch (ret) {
case DB_SUCCESS:
error = 0;
-@@ -7476,10 +7539,18 @@
+@@ -7487,10 +7550,18 @@
update_thd(ha_thd());
error = convert_error_code_to_mysql(error, prebuilt->table->flags,
NULL);
-@@ -7980,6 +8051,16 @@
+@@ -7991,6 +8062,16 @@
return(ranges + (double) rows / (double) total_rows * time_for_scan);
}
/*********************************************************************//**
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
-@@ -8157,7 +8238,7 @@
+@@ -8168,7 +8249,7 @@
ib_table = prebuilt->table;
if (flag & HA_STATUS_TIME) {
/* In sql_show we call with this flag: update
then statistics so that they are up-to-date */
-@@ -8450,10 +8531,18 @@
+@@ -8461,10 +8542,18 @@
THD* thd, /*!< in: connection thread handle */
HA_CHECK_OPT* check_opt) /*!< in: currently ignored */
{
return(0);
}
-@@ -8635,6 +8724,10 @@
+@@ -8646,6 +8735,10 @@
my_error(ER_QUERY_INTERRUPTED, MYF(0));
}
DBUG_RETURN(is_ok ? HA_ADMIN_OK : HA_ADMIN_CORRUPT);
}
-@@ -9405,6 +9498,10 @@
+@@ -9416,6 +9509,10 @@
update_thd(thd);
if (prebuilt->table->ibd_file_missing && !thd_tablespace_op(thd)) {
ut_print_timestamp(stderr);
fprintf(stderr,
-@@ -11807,6 +11904,26 @@
+@@ -11823,6 +11920,26 @@
"0 (the default) disables automatic dumps.",
NULL, NULL, 0, 0, UINT_MAX32, 0);
static struct st_mysql_sys_var* innobase_system_variables[]= {
MYSQL_SYSVAR(additional_mem_pool_size),
MYSQL_SYSVAR(autoextend_increment),
-@@ -11893,6 +12010,7 @@
+@@ -11910,6 +12027,7 @@
MYSQL_SYSVAR(purge_threads),
MYSQL_SYSVAR(purge_batch_size),
MYSQL_SYSVAR(rollback_segments),
NULL
};
-diff -ruN a/storage/innobase/handler/ha_innodb.h b/storage/innobase/handler/ha_innodb.h
---- a/storage/innobase/handler/ha_innodb.h 2010-11-03 07:01:13.000000000 +0900
-+++ b/storage/innobase/handler/ha_innodb.h 2010-12-04 15:38:18.159588579 +0900
+--- a/storage/innobase/handler/ha_innodb.h
++++ b/storage/innobase/handler/ha_innodb.h
@@ -52,6 +52,7 @@
innodb_idx_translate_t idx_trans_tbl; /*!< index translation
table between MySQL and
int write_row(uchar * buf);
int update_row(const uchar * old_data, uchar * new_data);
-diff -ruN a/storage/innobase/include/btr0btr.ic b/storage/innobase/include/btr0btr.ic
---- a/storage/innobase/include/btr0btr.ic 2010-11-03 07:01:13.000000000 +0900
-+++ b/storage/innobase/include/btr0btr.ic 2010-12-04 15:38:18.162515035 +0900
+--- a/storage/innobase/include/btr0btr.ic
++++ b/storage/innobase/include/btr0btr.ic
@@ -28,7 +28,7 @@
#include "mtr0mtr.h"
#include "mtr0log.h"
buf_block_dbg_add_level(block, SYNC_TREE_NODE);
}
-diff -ruN a/storage/innobase/include/buf0buf.h b/storage/innobase/include/buf0buf.h
---- a/storage/innobase/include/buf0buf.h 2010-12-03 15:49:59.218956083 +0900
-+++ b/storage/innobase/include/buf0buf.h 2010-12-04 15:38:18.164513667 +0900
-@@ -986,7 +986,7 @@
+--- a/storage/innobase/include/buf0buf.h
++++ b/storage/innobase/include/buf0buf.h
+@@ -1025,7 +1025,7 @@
const buf_block_t* block) /*!< in: pointer to the control block */
__attribute__((pure));
#else /* UNIV_DEBUG */
#endif /* UNIV_DEBUG */
/*********************************************************************//**
Gets the space id of a block.
-@@ -1433,6 +1433,7 @@
+@@ -1472,6 +1472,7 @@
0 if the block was never accessed
in the buffer pool */
/* @} */
# if defined UNIV_DEBUG_FILE_ACCESSES || defined UNIV_DEBUG
ibool file_page_was_freed;
/*!< this is set to TRUE when fsp
-diff -ruN a/storage/innobase/include/buf0buf.ic b/storage/innobase/include/buf0buf.ic
---- a/storage/innobase/include/buf0buf.ic 2010-12-03 15:49:59.221956024 +0900
-+++ b/storage/innobase/include/buf0buf.ic 2010-12-04 15:38:18.167513925 +0900
+--- a/storage/innobase/include/buf0buf.ic
++++ b/storage/innobase/include/buf0buf.ic
@@ -34,7 +34,7 @@
#include "buf0flu.h"
#include "buf0lru.h"
ut_ad(block);
switch (buf_block_get_state(block)) {
-diff -ruN a/storage/innobase/include/dict0dict.h b/storage/innobase/include/dict0dict.h
---- a/storage/innobase/include/dict0dict.h 2010-12-03 17:30:16.306955940 +0900
-+++ b/storage/innobase/include/dict0dict.h 2010-12-04 15:38:18.169513750 +0900
-@@ -1245,6 +1245,15 @@
+--- a/storage/innobase/include/dict0dict.h
++++ b/storage/innobase/include/dict0dict.h
+@@ -1258,6 +1258,15 @@
dict_close(void);
/*============*/
#ifndef UNIV_NONINL
#include "dict0dict.ic"
#endif
-diff -ruN a/storage/innobase/include/dict0mem.h b/storage/innobase/include/dict0mem.h
---- a/storage/innobase/include/dict0mem.h 2010-11-03 07:01:13.000000000 +0900
-+++ b/storage/innobase/include/dict0mem.h 2010-12-04 15:38:18.171513956 +0900
-@@ -640,6 +640,7 @@
+--- a/storage/innobase/include/dict0mem.h
++++ b/storage/innobase/include/dict0mem.h
+@@ -666,6 +666,7 @@
the AUTOINC lock on this table. */
/* @} */
/*----------------------*/
#endif /* !UNIV_HOTBACKUP */
#ifdef UNIV_DEBUG
-diff -ruN a/storage/innobase/include/fil0fil.h b/storage/innobase/include/fil0fil.h
---- a/storage/innobase/include/fil0fil.h 2010-12-04 15:35:29.175520016 +0900
-+++ b/storage/innobase/include/fil0fil.h 2010-12-04 15:38:18.172483391 +0900
+--- a/storage/innobase/include/fil0fil.h
++++ b/storage/innobase/include/fil0fil.h
@@ -750,6 +750,19 @@
fil_system_hash_nodes(void);
/*========================*/
typedef struct fil_space_struct fil_space_t;
#endif
-diff -ruN a/storage/innobase/include/fut0fut.ic b/storage/innobase/include/fut0fut.ic
---- a/storage/innobase/include/fut0fut.ic 2010-11-03 07:01:13.000000000 +0900
-+++ b/storage/innobase/include/fut0fut.ic 2010-12-04 15:38:18.174481728 +0900
+--- a/storage/innobase/include/fut0fut.ic
++++ b/storage/innobase/include/fut0fut.ic
@@ -23,6 +23,7 @@
Created 12/13/1995 Heikki Tuuri
***********************************************************************/
ptr = buf_block_get_frame(block) + addr.boffset;
buf_block_dbg_add_level(block, SYNC_NO_ORDER_CHECK);
-diff -ruN a/storage/innobase/include/page0page.h b/storage/innobase/include/page0page.h
---- a/storage/innobase/include/page0page.h 2010-11-03 07:01:13.000000000 +0900
-+++ b/storage/innobase/include/page0page.h 2010-12-04 15:38:18.175514037 +0900
-@@ -500,7 +500,7 @@
+--- a/storage/innobase/include/page0page.h
++++ b/storage/innobase/include/page0page.h
+@@ -527,7 +527,7 @@
page_is_leaf(
/*=========*/
const page_t* page) /*!< in: page */
/************************************************************//**
Gets the pointer to the next record on the page.
@return pointer to next record */
-diff -ruN a/storage/innobase/include/page0page.ic b/storage/innobase/include/page0page.ic
---- a/storage/innobase/include/page0page.ic 2010-11-03 07:01:13.000000000 +0900
-+++ b/storage/innobase/include/page0page.ic 2010-12-04 15:38:18.177482672 +0900
+--- a/storage/innobase/include/page0page.ic
++++ b/storage/innobase/include/page0page.ic
@@ -274,6 +274,9 @@
/*=========*/
const page_t* page) /*!< in: page */
return(!*(const uint16*) (page + (PAGE_HEADER + PAGE_LEVEL)));
}
-diff -ruN a/storage/innobase/include/page0zip.h b/storage/innobase/include/page0zip.h
---- a/storage/innobase/include/page0zip.h 2010-11-03 07:01:13.000000000 +0900
-+++ b/storage/innobase/include/page0zip.h 2010-12-04 15:38:18.179513974 +0900
+--- a/storage/innobase/include/page0zip.h
++++ b/storage/innobase/include/page0zip.h
@@ -114,7 +114,7 @@
const page_t* page, /*!< in: uncompressed page */
dict_index_t* index, /*!< in: index of the B-tree node */
/**********************************************************************//**
Decompress a page. This function should tolerate errors on the compressed
-diff -ruN a/storage/innobase/include/srv0srv.h b/storage/innobase/include/srv0srv.h
---- a/storage/innobase/include/srv0srv.h 2010-12-04 15:37:50.591516341 +0900
-+++ b/storage/innobase/include/srv0srv.h 2010-12-04 15:38:18.180563749 +0900
+--- a/storage/innobase/include/srv0srv.h
++++ b/storage/innobase/include/srv0srv.h
@@ -240,6 +240,7 @@
extern ulint srv_adaptive_flushing_method;
extern ulint srv_dict_size_limit;
/*-------------------------------------------*/
-diff -ruN a/storage/innobase/page/page0zip.c b/storage/innobase/page/page0zip.c
---- a/storage/innobase/page/page0zip.c 2010-11-03 07:01:13.000000000 +0900
-+++ b/storage/innobase/page/page0zip.c 2010-12-04 15:38:18.195515935 +0900
-@@ -1153,6 +1153,10 @@
+--- a/storage/innobase/page/page0zip.c
++++ b/storage/innobase/page/page0zip.c
+@@ -1195,6 +1195,10 @@
FILE* logfile = NULL;
#endif
ut_a(page_is_comp(page));
ut_a(fil_page_get_type(page) == FIL_PAGE_INDEX);
ut_ad(page_simple_validate_new((page_t*) page));
-diff -ruN a/storage/innobase/row/row0ins.c b/storage/innobase/row/row0ins.c
---- a/storage/innobase/row/row0ins.c 2010-11-03 07:01:13.000000000 +0900
-+++ b/storage/innobase/row/row0ins.c 2010-12-04 15:38:18.198514028 +0900
+--- a/storage/innobase/row/row0ins.c
++++ b/storage/innobase/row/row0ins.c
@@ -1335,6 +1335,12 @@
const rec_t* rec = btr_pcur_get_rec(&pcur);
const buf_block_t* block = btr_pcur_get_block(&pcur);
if (page_rec_is_infimum(rec)) {
continue;
-diff -ruN a/storage/innobase/row/row0merge.c b/storage/innobase/row/row0merge.c
---- a/storage/innobase/row/row0merge.c 2010-12-03 17:30:16.330986655 +0900
-+++ b/storage/innobase/row/row0merge.c 2010-12-04 15:38:18.201513966 +0900
+--- a/storage/innobase/row/row0merge.c
++++ b/storage/innobase/row/row0merge.c
@@ -1245,6 +1245,13 @@
if (UNIV_LIKELY(has_next)) {
offsets = rec_get_offsets(rec, clust_index, NULL,
ULINT_UNDEFINED, &row_heap);
-diff -ruN a/storage/innobase/row/row0sel.c b/storage/innobase/row/row0sel.c
---- a/storage/innobase/row/row0sel.c 2010-11-03 07:01:13.000000000 +0900
-+++ b/storage/innobase/row/row0sel.c 2010-12-04 15:38:18.205551115 +0900
-@@ -3853,6 +3853,13 @@
+--- a/storage/innobase/row/row0sel.c
++++ b/storage/innobase/row/row0sel.c
+@@ -3854,6 +3854,13 @@
/* PHASE 4: Look for matching records in a loop */
rec = btr_pcur_get_rec(pcur);
ut_ad(!!page_rec_is_comp(rec) == comp);
#ifdef UNIV_SEARCH_DEBUG
/*
-@@ -3930,7 +3937,13 @@
+@@ -3931,7 +3938,13 @@
if (UNIV_UNLIKELY(next_offs >= UNIV_PAGE_SIZE - PAGE_DIR)) {
wrong_offs:
ut_print_timestamp(stderr);
buf_page_print(page_align(rec), 0);
fprintf(stderr,
-@@ -3981,7 +3994,8 @@
+@@ -3982,7 +3995,8 @@
offsets = rec_get_offsets(rec, index, offsets, ULINT_UNDEFINED, &heap);
if (!rec_validate(rec, offsets)
|| !btr_index_rec_validate(rec, index, FALSE)) {
fprintf(stderr,
-diff -ruN a/storage/innobase/srv/srv0srv.c b/storage/innobase/srv/srv0srv.c
---- a/storage/innobase/srv/srv0srv.c 2010-12-04 15:37:50.602481253 +0900
-+++ b/storage/innobase/srv/srv0srv.c 2010-12-04 15:38:18.209513823 +0900
+--- a/storage/innobase/srv/srv0srv.c
++++ b/storage/innobase/srv/srv0srv.c
@@ -430,6 +430,7 @@
UNIV_INTERN ulint srv_adaptive_flushing_method = 0; /* 0: native 1: estimate 2: keep_average */
UNIV_INTERN ulint srv_dict_size_limit = 0;
/*-------------------------------------------*/
-diff -ruN a/storage/innobase/srv/srv0start.c b/storage/innobase/srv/srv0start.c
---- a/storage/innobase/srv/srv0start.c 2010-12-04 15:37:50.605491300 +0900
-+++ b/storage/innobase/srv/srv0start.c 2010-12-04 15:38:18.212513722 +0900
+--- a/storage/innobase/srv/srv0start.c
++++ b/storage/innobase/srv/srv0start.c
@@ -2149,6 +2149,13 @@
os_fast_mutex_free(&srv_os_test_mutex);
#!!! notice !!!
# Any small change to this file in the main branch
# should be done or reviewed by the maintainer!
-diff -ruN a/storage/innobase/buf/buf0rea.c b/storage/innobase/buf/buf0rea.c
---- a/storage/innobase/buf/buf0rea.c 2010-12-03 15:49:59.187028943 +0900
-+++ b/storage/innobase/buf/buf0rea.c 2010-12-03 17:30:41.579956150 +0900
+--- a/storage/innobase/buf/buf0rea.c
++++ b/storage/innobase/buf/buf0rea.c
@@ -122,6 +122,46 @@
bpage = buf_page_init_for_read(err, mode, space, zip_size, unzip,
tablespace_version, offset);
return;
}
-diff -ruN a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc
---- a/storage/innobase/handler/ha_innodb.cc 2010-12-03 17:30:16.261955714 +0900
-+++ b/storage/innobase/handler/ha_innodb.cc 2010-12-03 17:30:41.584971130 +0900
+--- a/storage/innobase/handler/ha_innodb.cc
++++ b/storage/innobase/handler/ha_innodb.cc
@@ -182,6 +182,7 @@
#endif /* UNIV_LOG_ARCHIVE */
static my_bool innobase_use_doublewrite = TRUE;
static my_bool innobase_locks_unsafe_for_binlog = FALSE;
static my_bool innobase_overwrite_relay_log_info = FALSE;
static my_bool innobase_rollback_on_timeout = FALSE;
-@@ -2576,6 +2577,8 @@
+@@ -2581,6 +2582,8 @@
srv_force_recovery = (ulint) innobase_force_recovery;
srv_use_doublewrite_buf = (ibool) innobase_use_doublewrite;
srv_use_checksums = (ibool) innobase_use_checksums;
-@@ -11274,6 +11277,11 @@
+@@ -11285,6 +11288,11 @@
"The common part for InnoDB table spaces.",
NULL, NULL, NULL);
static MYSQL_SYSVAR_BOOL(recovery_update_relay_log, innobase_overwrite_relay_log_info,
PLUGIN_VAR_NOCMDARG | PLUGIN_VAR_READONLY,
"During InnoDB crash recovery on slave overwrite relay-log.info "
-@@ -11747,6 +11755,7 @@
+@@ -11763,6 +11771,7 @@
MYSQL_SYSVAR(data_file_path),
MYSQL_SYSVAR(data_home_dir),
MYSQL_SYSVAR(doublewrite),
MYSQL_SYSVAR(fast_shutdown),
MYSQL_SYSVAR(file_io_threads),
MYSQL_SYSVAR(read_io_threads),
-diff -ruN a/storage/innobase/include/log0recv.h b/storage/innobase/include/log0recv.h
---- a/storage/innobase/include/log0recv.h 2010-11-03 07:01:13.000000000 +0900
-+++ b/storage/innobase/include/log0recv.h 2010-12-03 17:30:41.592958318 +0900
+--- a/storage/innobase/include/log0recv.h
++++ b/storage/innobase/include/log0recv.h
@@ -438,6 +438,39 @@
hash_table_t* addr_hash;/*!< hash table of file addresses of pages */
ulint n_addrs;/*!< number of not processed hashed file
};
/** The recovery system */
-diff -ruN a/storage/innobase/include/srv0srv.h b/storage/innobase/include/srv0srv.h
---- a/storage/innobase/include/srv0srv.h 2010-12-03 17:30:16.321953515 +0900
-+++ b/storage/innobase/include/srv0srv.h 2010-12-03 17:30:41.593985184 +0900
+--- a/storage/innobase/include/srv0srv.h
++++ b/storage/innobase/include/srv0srv.h
@@ -126,6 +126,8 @@
extern ulint* srv_data_file_sizes;
extern ulint* srv_data_file_is_raw_partition;
extern ibool srv_auto_extend_last_data_file;
extern ulint srv_last_file_size_max;
extern char** srv_log_group_home_dirs;
-diff -ruN a/storage/innobase/log/log0recv.c b/storage/innobase/log/log0recv.c
---- a/storage/innobase/log/log0recv.c 2010-12-03 15:18:48.903987466 +0900
-+++ b/storage/innobase/log/log0recv.c 2010-12-03 17:30:41.598022536 +0900
+--- a/storage/innobase/log/log0recv.c
++++ b/storage/innobase/log/log0recv.c
@@ -187,6 +187,9 @@
recv_sys->heap = NULL;
if (recv_needed_recovery) {
trx_sys_print_mysql_master_log_pos();
trx_sys_print_mysql_binlog_offset();
-diff -ruN a/storage/innobase/os/os0file.c b/storage/innobase/os/os0file.c
---- a/storage/innobase/os/os0file.c 2010-12-03 15:18:48.908955759 +0900
-+++ b/storage/innobase/os/os0file.c 2010-12-03 17:30:41.602022989 +0900
+--- a/storage/innobase/os/os0file.c
++++ b/storage/innobase/os/os0file.c
@@ -43,6 +43,7 @@
#include "srv0start.h"
#include "fil0fil.h"
#ifndef UNIV_HOTBACKUP
# include "os0sync.h"
# include "os0thread.h"
-@@ -4270,6 +4271,18 @@
+@@ -4278,6 +4279,18 @@
INFINITE);
}
os_mutex_enter(array->mutex);
if (srv_shutdown_state == SRV_SHUTDOWN_EXIT_THREADS
-diff -ruN a/storage/innobase/srv/srv0srv.c b/storage/innobase/srv/srv0srv.c
---- a/storage/innobase/srv/srv0srv.c 2010-12-03 17:30:16.339955597 +0900
-+++ b/storage/innobase/srv/srv0srv.c 2010-12-03 17:30:41.604958138 +0900
+--- a/storage/innobase/srv/srv0srv.c
++++ b/storage/innobase/srv/srv0srv.c
@@ -160,6 +160,8 @@
/* size in database pages */
UNIV_INTERN ulint* srv_data_file_sizes = NULL;
/* if TRUE, then we auto-extend the last data file */
UNIV_INTERN ibool srv_auto_extend_last_data_file = FALSE;
/* if != 0, this tells the max size auto-extending may increase the
-diff -ruN a/storage/innobase/trx/trx0sys.c b/storage/innobase/trx/trx0sys.c
---- a/storage/innobase/trx/trx0sys.c 2010-12-03 15:41:52.051986524 +0900
-+++ b/storage/innobase/trx/trx0sys.c 2010-12-03 17:30:41.607026818 +0900
+--- a/storage/innobase/trx/trx0sys.c
++++ b/storage/innobase/trx/trx0sys.c
@@ -567,6 +567,12 @@
zip_size ? zip_size : UNIV_PAGE_SIZE,
read_buf, NULL);
#!!! notice !!!
# Any small change to this file in the main branch
# should be done or reviewed by the maintainer!
-diff -ruN a/storage/innobase/buf/buf0buf.c b/storage/innobase/buf/buf0buf.c
---- a/storage/innobase/buf/buf0buf.c 2010-12-03 17:49:11.574962867 +0900
-+++ b/storage/innobase/buf/buf0buf.c 2010-12-04 15:35:58.624514033 +0900
-@@ -4291,7 +4291,8 @@
+--- a/storage/innobase/buf/buf0buf.c
++++ b/storage/innobase/buf/buf0buf.c
+@@ -3810,7 +3810,8 @@
read_space_id = mach_read_from_4(
frame + FIL_PAGE_ARCH_LOG_NO_OR_SPACE_ID);
&& trx_doublewrite_page_inside(bpage->offset)) {
ut_print_timestamp(stderr);
-diff -ruN a/storage/innobase/buf/buf0flu.c b/storage/innobase/buf/buf0flu.c
---- a/storage/innobase/buf/buf0flu.c 2010-12-03 15:49:59.179956111 +0900
-+++ b/storage/innobase/buf/buf0flu.c 2010-12-04 15:35:58.624514033 +0900
-@@ -791,7 +791,8 @@
+--- a/storage/innobase/buf/buf0flu.c
++++ b/storage/innobase/buf/buf0flu.c
+@@ -793,7 +793,8 @@
write_buf = trx_doublewrite->write_buf;
i = 0;
trx_doublewrite->block1, 0, len,
(void*) write_buf, NULL);
-@@ -828,7 +829,8 @@
+@@ -830,7 +831,8 @@
+ TRX_SYS_DOUBLEWRITE_BLOCK_SIZE * UNIV_PAGE_SIZE;
ut_ad(i == TRX_SYS_DOUBLEWRITE_BLOCK_SIZE);
trx_doublewrite->block2, 0, len,
(void*) write_buf, NULL);
-@@ -858,7 +860,7 @@
+@@ -860,7 +862,7 @@
flush:
/* Now flush the doublewrite buffer data to disk */
/* We know that the writes have been flushed to disk now
and in recovery we will find them in the doublewrite buffer
-diff -ruN a/storage/innobase/buf/buf0rea.c b/storage/innobase/buf/buf0rea.c
---- a/storage/innobase/buf/buf0rea.c 2010-12-04 15:35:29.138514157 +0900
-+++ b/storage/innobase/buf/buf0rea.c 2010-12-04 15:35:58.626486771 +0900
+--- a/storage/innobase/buf/buf0rea.c
++++ b/storage/innobase/buf/buf0rea.c
@@ -88,7 +88,9 @@
wake_later = mode & OS_AIO_SIMULATED_WAKE_LATER;
mode = mode & ~OS_AIO_SIMULATED_WAKE_LATER;
&& ( (offset >= trx_doublewrite->block1
&& offset < trx_doublewrite->block1
+ TRX_SYS_DOUBLEWRITE_BLOCK_SIZE)
-diff -ruN a/storage/innobase/dict/dict0load.c b/storage/innobase/dict/dict0load.c
---- a/storage/innobase/dict/dict0load.c 2010-12-03 17:30:16.252956569 +0900
-+++ b/storage/innobase/dict/dict0load.c 2010-12-04 15:35:58.627482825 +0900
+--- a/storage/innobase/dict/dict0load.c
++++ b/storage/innobase/dict/dict0load.c
@@ -41,6 +41,7 @@
#include "srv0start.h"
#include "srv0srv.h"
/* The system tablespace always exists. */
} else if (in_crash_recovery) {
/* Check that the tablespace (the .ibd file) really
-@@ -1623,7 +1624,7 @@
+@@ -1682,7 +1683,7 @@
space = mach_read_from_4(field);
/* Check if the tablespace exists and has the right name */
flags = dict_sys_tables_get_flags(rec);
if (UNIV_UNLIKELY(flags == ULINT_UNDEFINED)) {
-@@ -1776,7 +1777,7 @@
+@@ -1835,7 +1836,7 @@
goto err_exit;
}
/* The system tablespace is always available. */
} else if (!fil_space_for_table_exists_in_mem(
table->space, name,
-diff -ruN a/storage/innobase/fil/fil0fil.c b/storage/innobase/fil/fil0fil.c
---- a/storage/innobase/fil/fil0fil.c 2010-12-04 15:35:29.143813775 +0900
-+++ b/storage/innobase/fil/fil0fil.c 2010-12-04 15:35:58.628498870 +0900
+--- a/storage/innobase/fil/fil0fil.c
++++ b/storage/innobase/fil/fil0fil.c
@@ -657,7 +657,7 @@
UT_LIST_ADD_LAST(chain, space->chain, node);
/* Put the node to the LRU list */
UT_LIST_ADD_FIRST(LRU, system->LRU, node);
}
-@@ -875,7 +875,7 @@
+@@ -876,7 +876,7 @@
ut_a(system->n_open > 0);
system->n_open--;
ut_a(UT_LIST_GET_LEN(system->LRU) > 0);
/* The node is in the LRU list, remove it */
-@@ -961,7 +961,7 @@
+@@ -962,7 +962,7 @@
retry:
mutex_enter(&fil_system->mutex);
/* We keep log files and system tablespace files always open;
this is important in preventing deadlocks in this module, as
a page read completion often performs another read from the
-@@ -1192,7 +1192,7 @@
+@@ -1193,7 +1193,7 @@
" tablespace memory cache!\n",
(ulong) space->id);
mutex_exit(&fil_system->mutex);
-@@ -1254,6 +1254,7 @@
+@@ -1255,6 +1255,7 @@
space->mark = FALSE;
if (UNIV_LIKELY(purpose == FIL_TABLESPACE && !recv_recovery_on)
&& UNIV_UNLIKELY(id > fil_system->max_assigned_id)) {
if (!fil_system->space_id_reuse_warned) {
fil_system->space_id_reuse_warned = TRUE;
-@@ -1337,7 +1338,7 @@
+@@ -1338,7 +1339,7 @@
(ulong) SRV_LOG_SPACE_FIRST_ID);
}
if (success) {
*space_id = fil_system->max_assigned_id = id;
-@@ -1600,6 +1601,8 @@
+@@ -1601,6 +1602,8 @@
UT_LIST_INIT(fil_system->LRU);
fil_system->max_n_open = max_n_open;
}
/*******************************************************************//**
-@@ -1621,7 +1624,7 @@
+@@ -1622,7 +1625,7 @@
space = UT_LIST_GET_FIRST(fil_system->space_list);
while (space != NULL) {
node = UT_LIST_GET_FIRST(space->chain);
while (node != NULL) {
-@@ -1711,6 +1714,10 @@
+@@ -1712,6 +1715,10 @@
ut_error;
}
mutex_enter(&fil_system->mutex);
if (fil_system->max_assigned_id < max_id) {
-@@ -1729,6 +1736,7 @@
+@@ -1730,6 +1737,7 @@
ulint
fil_write_lsn_and_arch_no_to_file(
/*==============================*/
ulint sum_of_sizes, /*!< in: combined size of previous files
in space, in database pages */
ib_uint64_t lsn, /*!< in: lsn to write */
-@@ -1738,14 +1746,16 @@
+@@ -1739,14 +1747,16 @@
byte* buf1;
byte* buf;
mem_free(buf1);
-@@ -1781,7 +1791,7 @@
+@@ -1782,7 +1792,7 @@
always open. */
if (space->purpose == FIL_TABLESPACE
sum_of_sizes = 0;
node = UT_LIST_GET_FIRST(space->chain);
-@@ -1789,7 +1799,7 @@
+@@ -1790,7 +1800,7 @@
mutex_exit(&fil_system->mutex);
err = fil_write_lsn_and_arch_no_to_file(
if (err != DB_SUCCESS) {
return(err);
-@@ -4158,7 +4168,7 @@
+@@ -4159,7 +4169,7 @@
}
#ifndef UNIV_HOTBACKUP
fprintf(stderr,
"InnoDB: Error: tablespace id %lu in file %s"
" is not sensible\n",
-@@ -4167,7 +4177,7 @@
+@@ -4168,7 +4178,7 @@
goto func_exit;
}
#else
char* new_path;
fprintf(stderr,
-@@ -4988,7 +4998,7 @@
+@@ -4989,7 +4999,7 @@
}
if (node->n_pending == 0 && space->purpose == FIL_TABLESPACE
/* The node is in the LRU list, remove it */
ut_a(UT_LIST_GET_LEN(system->LRU) > 0);
-@@ -5034,7 +5044,7 @@
+@@ -5035,7 +5045,7 @@
}
if (node->n_pending == 0 && node->space->purpose == FIL_TABLESPACE
/* The node must be put back to the LRU list */
UT_LIST_ADD_FIRST(LRU, system->LRU, node);
}
-@@ -5645,7 +5655,7 @@
+@@ -5646,7 +5656,7 @@
ut_a(fil_node->n_pending == 0);
ut_a(fil_node->open);
ut_a(fil_node->space->purpose == FIL_TABLESPACE);
fil_node = UT_LIST_GET_NEXT(LRU, fil_node);
}
-diff -ruN a/storage/innobase/fsp/fsp0fsp.c b/storage/innobase/fsp/fsp0fsp.c
---- a/storage/innobase/fsp/fsp0fsp.c 2010-11-03 07:01:13.000000000 +0900
-+++ b/storage/innobase/fsp/fsp0fsp.c 2010-12-04 15:35:58.632513243 +0900
+--- a/storage/innobase/fsp/fsp0fsp.c
++++ b/storage/innobase/fsp/fsp0fsp.c
@@ -48,7 +48,7 @@
# include "log0log.h"
#endif /* UNIV_HOTBACKUP */
dict_ind_redundant, mtr);
} else {
fsp_fill_free_list(TRUE, space, header, mtr);
-diff -ruN a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc
---- a/storage/innobase/handler/ha_innodb.cc 2010-12-04 15:35:29.153514047 +0900
-+++ b/storage/innobase/handler/ha_innodb.cc 2010-12-04 15:35:58.636549909 +0900
+--- a/storage/innobase/handler/ha_innodb.cc
++++ b/storage/innobase/handler/ha_innodb.cc
@@ -163,6 +163,7 @@
static char* innobase_log_group_home_dir = NULL;
static char* innobase_file_format_name = NULL;
/* The highest file format being used in the database. The value can be
set by user, however, it will be adjusted to the newer file format if
-@@ -2472,6 +2473,8 @@
+@@ -2477,6 +2478,8 @@
goto error;
}
srv_use_sys_stats_table = (ibool) innobase_use_sys_stats_table;
/* -------------- Log files ---------------------------*/
-@@ -11641,6 +11644,11 @@
+@@ -11657,6 +11660,11 @@
"Path to individual files and their sizes.",
NULL, NULL, NULL);
static MYSQL_SYSVAR_LONG(autoinc_lock_mode, innobase_autoinc_lock_mode,
PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY,
"The AUTOINC lock modes supported by InnoDB: "
-@@ -11808,6 +11816,7 @@
+@@ -11824,6 +11832,7 @@
MYSQL_SYSVAR(commit_concurrency),
MYSQL_SYSVAR(concurrency_tickets),
MYSQL_SYSVAR(data_file_path),
MYSQL_SYSVAR(data_home_dir),
MYSQL_SYSVAR(doublewrite),
MYSQL_SYSVAR(recovery_stats),
-diff -ruN a/storage/innobase/include/mtr0log.ic b/storage/innobase/include/mtr0log.ic
---- a/storage/innobase/include/mtr0log.ic 2010-11-03 07:01:13.000000000 +0900
-+++ b/storage/innobase/include/mtr0log.ic 2010-12-04 15:35:58.644607059 +0900
+--- a/storage/innobase/include/mtr0log.ic
++++ b/storage/innobase/include/mtr0log.ic
@@ -27,8 +27,8 @@
#include "ut0lst.h"
#include "buf0buf.h"
&& offset >= FSP_EXTENT_SIZE && offset < 3 * FSP_EXTENT_SIZE) {
if (trx_doublewrite_buf_is_being_created) {
/* Do nothing: we only come to this branch in an
-diff -ruN a/storage/innobase/include/srv0srv.h b/storage/innobase/include/srv0srv.h
---- a/storage/innobase/include/srv0srv.h 2010-12-04 15:35:29.177480351 +0900
-+++ b/storage/innobase/include/srv0srv.h 2010-12-04 15:35:58.646556250 +0900
+--- a/storage/innobase/include/srv0srv.h
++++ b/storage/innobase/include/srv0srv.h
@@ -129,6 +129,8 @@
extern ulint* srv_data_file_sizes;
extern ulint* srv_data_file_is_raw_partition;
extern ibool srv_recovery_stats;
extern ibool srv_auto_extend_last_data_file;
-diff -ruN a/storage/innobase/include/srv0start.h b/storage/innobase/include/srv0start.h
---- a/storage/innobase/include/srv0start.h 2010-11-03 07:01:13.000000000 +0900
-+++ b/storage/innobase/include/srv0start.h 2010-12-08 17:15:07.602605797 +0900
+--- a/storage/innobase/include/srv0start.h
++++ b/storage/innobase/include/srv0start.h
@@ -127,4 +127,7 @@
/** Log 'spaces' have id's >= this */
#define SRV_LOG_SPACE_FIRST_ID 0xFFFFFFF0UL
+#define SRV_EXTRA_SYS_SPACE_FIRST_ID 0xFFFFFFE0UL
+
#endif
-diff -ruN a/storage/innobase/include/trx0sys.h b/storage/innobase/include/trx0sys.h
---- a/storage/innobase/include/trx0sys.h 2010-12-03 15:41:52.047049291 +0900
-+++ b/storage/innobase/include/trx0sys.h 2010-12-04 15:35:58.647551222 +0900
+--- a/storage/innobase/include/trx0sys.h
++++ b/storage/innobase/include/trx0sys.h
@@ -125,6 +125,22 @@
/*=============*/
ulint space, /*!< in: space */
/****************************************************************//**
Looks for a free slot for a rollback segment in the trx system file copy.
@return slot index or ULINT_UNDEFINED if not found */
-@@ -442,6 +465,8 @@
+@@ -453,6 +476,8 @@
/* Space id and page no where the trx system file copy resides */
#define TRX_SYS_SPACE 0 /* the SYSTEM tablespace */
#include "fsp0fsp.h"
#define TRX_SYS_PAGE_NO FSP_TRX_SYS_PAGE_NO
-diff -ruN a/storage/innobase/include/trx0sys.ic b/storage/innobase/include/trx0sys.ic
---- a/storage/innobase/include/trx0sys.ic 2010-11-03 07:01:13.000000000 +0900
-+++ b/storage/innobase/include/trx0sys.ic 2010-12-04 15:35:58.649473284 +0900
+--- a/storage/innobase/include/trx0sys.ic
++++ b/storage/innobase/include/trx0sys.ic
@@ -71,6 +71,40 @@
}
Gets the pointer in the nth slot of the rseg array.
@return pointer to rseg object, NULL if slot not in use */
UNIV_INLINE
-diff -ruN a/storage/innobase/row/row0mysql.c b/storage/innobase/row/row0mysql.c
---- a/storage/innobase/row/row0mysql.c 2010-12-03 17:30:16.334989510 +0900
-+++ b/storage/innobase/row/row0mysql.c 2010-12-04 15:35:58.652496484 +0900
-@@ -3447,7 +3447,7 @@
+--- a/storage/innobase/row/row0mysql.c
++++ b/storage/innobase/row/row0mysql.c
+@@ -3425,7 +3425,7 @@
/* Do not drop possible .ibd tablespace if something went
wrong: we do not want to delete valuable data of the user */
if (!fil_space_for_table_exists_in_mem(space_id,
name_or_path,
is_temp, FALSE,
-diff -ruN a/storage/innobase/srv/srv0srv.c b/storage/innobase/srv/srv0srv.c
---- a/storage/innobase/srv/srv0srv.c 2010-12-04 15:35:29.180483212 +0900
-+++ b/storage/innobase/srv/srv0srv.c 2010-12-04 15:35:58.656550107 +0900
+--- a/storage/innobase/srv/srv0srv.c
++++ b/storage/innobase/srv/srv0srv.c
@@ -163,6 +163,8 @@
/* size in database pages */
UNIV_INTERN ulint* srv_data_file_sizes = NULL;
UNIV_INTERN ibool srv_recovery_stats = FALSE;
/* if TRUE, then we auto-extend the last data file */
-diff -ruN a/storage/innobase/srv/srv0start.c b/storage/innobase/srv/srv0start.c
---- a/storage/innobase/srv/srv0start.c 2010-12-04 15:35:29.183481330 +0900
-+++ b/storage/innobase/srv/srv0start.c 2010-12-04 15:35:58.661550545 +0900
+--- a/storage/innobase/srv/srv0start.c
++++ b/storage/innobase/srv/srv0start.c
@@ -714,6 +714,7 @@
/*======================*/
ibool* create_new_db, /*!< out: TRUE if new database should be
}
if (!create_new_db && sum_of_new_sizes > 0) {
-diff -ruN a/storage/innobase/trx/trx0sys.c b/storage/innobase/trx/trx0sys.c
---- a/storage/innobase/trx/trx0sys.c 2010-12-03 17:32:15.651024019 +0900
-+++ b/storage/innobase/trx/trx0sys.c 2010-12-04 15:35:58.664550291 +0900
+--- a/storage/innobase/trx/trx0sys.c
++++ b/storage/innobase/trx/trx0sys.c
@@ -415,6 +415,152 @@
goto start_again;
#!!! notice !!!
# Any small change to this file in the main branch
# should be done or reviewed by the maintainer!
-diff -ruN a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc
---- a/storage/innobase/handler/ha_innodb.cc 2010-12-03 17:34:35.285040381 +0900
-+++ b/storage/innobase/handler/ha_innodb.cc 2010-12-03 17:35:12.974975252 +0900
-@@ -9593,9 +9593,8 @@
+--- a/storage/innobase/handler/ha_innodb.cc
++++ b/storage/innobase/handler/ha_innodb.cc
+@@ -9604,9 +9604,8 @@
rw_lock_wait_time += mutex->lspent_time;
}
#else /* UNIV_DEBUG */
buf2len= (uint) my_snprintf(buf2, sizeof(buf2), "os_waits=%lu",
(ulong) mutex->count_os_wait);
-@@ -9610,10 +9609,8 @@
+@@ -9621,10 +9620,8 @@
if (block_mutex) {
buf1len = (uint) my_snprintf(buf1, sizeof buf1,
buf2len = (uint) my_snprintf(buf2, sizeof buf2,
"os_waits=%lu",
(ulong) block_mutex_oswait_count);
-@@ -9642,9 +9639,8 @@
+@@ -9653,9 +9650,8 @@
continue;
}
buf2len = my_snprintf(buf2, sizeof buf2, "os_waits=%lu",
(ulong) lock->count_os_wait);
-@@ -9658,10 +9654,8 @@
+@@ -9669,10 +9665,8 @@
if (block_lock) {
buf1len = (uint) my_snprintf(buf1, sizeof buf1,
buf2len = (uint) my_snprintf(buf2, sizeof buf2,
"os_waits=%lu",
(ulong) block_lock_oswait_count);
-diff -ruN a/storage/innobase/include/sync0rw.h b/storage/innobase/include/sync0rw.h
---- a/storage/innobase/include/sync0rw.h 2010-12-03 15:49:59.225953164 +0900
-+++ b/storage/innobase/include/sync0rw.h 2010-12-03 17:35:12.978024458 +0900
+--- a/storage/innobase/include/sync0rw.h
++++ b/storage/innobase/include/sync0rw.h
@@ -138,14 +138,14 @@
# ifdef UNIV_DEBUG
# ifdef UNIV_SYNC_DEBUG
/******************************************************************//**
Performance schema instrumented wrap function for rw_lock_x_lock_func()
-diff -ruN a/storage/innobase/include/sync0rw.ic b/storage/innobase/include/sync0rw.ic
---- a/storage/innobase/include/sync0rw.ic 2010-11-03 07:01:13.000000000 +0900
-+++ b/storage/innobase/include/sync0rw.ic 2010-12-03 17:35:12.980024605 +0900
+--- a/storage/innobase/include/sync0rw.ic
++++ b/storage/innobase/include/sync0rw.ic
@@ -640,10 +640,10 @@
# ifdef UNIV_SYNC_DEBUG
ulint level, /*!< in: level */
}
/******************************************************************//**
Performance schema instrumented wrap function for rw_lock_x_lock_func()
-diff -ruN a/storage/innobase/include/sync0sync.h b/storage/innobase/include/sync0sync.h
---- a/storage/innobase/include/sync0sync.h 2010-12-03 15:49:59.227955503 +0900
-+++ b/storage/innobase/include/sync0sync.h 2010-12-03 17:35:12.982023946 +0900
+--- a/storage/innobase/include/sync0sync.h
++++ b/storage/innobase/include/sync0sync.h
@@ -158,14 +158,14 @@
# ifdef UNIV_DEBUG
# ifdef UNIV_SYNC_DEBUG
/******************************************************************//**
NOTE! Please use the corresponding macro mutex_enter(), not directly
this function!
-@@ -731,9 +731,9 @@
+@@ -733,9 +733,9 @@
ulint line; /*!< Line where the mutex was locked */
ulint level; /*!< Level in the global latching order */
#endif /* UNIV_SYNC_DEBUG */
os_thread_id_t thread_id; /*!< The thread id of the thread
which locked the mutex. */
ulint magic_n; /*!< MUTEX_MAGIC_N */
-@@ -748,9 +748,9 @@
+@@ -750,9 +750,9 @@
ulong count_os_yield; /*!< count of os_wait */
ulonglong lspent_time; /*!< mutex os_wait timer msec */
ulonglong lmax_spent_time;/*!< mutex os_wait timer msec */
#ifdef UNIV_PFS_MUTEX
struct PSI_mutex* pfs_psi; /*!< The performance schema
instrumentation hook */
-diff -ruN a/storage/innobase/include/sync0sync.ic b/storage/innobase/include/sync0sync.ic
---- a/storage/innobase/include/sync0sync.ic 2010-11-03 07:01:13.000000000 +0900
-+++ b/storage/innobase/include/sync0sync.ic 2010-12-03 17:35:12.984024599 +0900
+--- a/storage/innobase/include/sync0sync.ic
++++ b/storage/innobase/include/sync0sync.ic
@@ -321,13 +321,13 @@
mysql_pfs_key_t key, /*!< in: Performance Schema key */
mutex_t* mutex, /*!< in: pointer to memory */
}
/******************************************************************//**
NOTE! Please use the corresponding macro mutex_free(), not directly
-diff -ruN a/storage/innobase/sync/sync0arr.c b/storage/innobase/sync/sync0arr.c
---- a/storage/innobase/sync/sync0arr.c 2010-12-03 15:09:51.304953409 +0900
-+++ b/storage/innobase/sync/sync0arr.c 2010-12-03 17:35:12.985024561 +0900
+--- a/storage/innobase/sync/sync0arr.c
++++ b/storage/innobase/sync/sync0arr.c
@@ -489,13 +489,12 @@
mutex = cell->old_wait_mutex;
writer = rw_lock_get_writer(rwlock);
if (writer != RW_LOCK_NOT_LOCKED) {
fprintf(file,
-diff -ruN a/storage/innobase/sync/sync0rw.c b/storage/innobase/sync/sync0rw.c
---- a/storage/innobase/sync/sync0rw.c 2010-11-03 07:01:13.000000000 +0900
-+++ b/storage/innobase/sync/sync0rw.c 2010-12-03 17:35:12.987029059 +0900
+--- a/storage/innobase/sync/sync0rw.c
++++ b/storage/innobase/sync/sync0rw.c
@@ -242,10 +242,10 @@
# ifdef UNIV_SYNC_DEBUG
ulint level, /*!< in: level */
}
/* these stats may not be accurate */
-diff -ruN a/storage/innobase/sync/sync0sync.c b/storage/innobase/sync/sync0sync.c
---- a/storage/innobase/sync/sync0sync.c 2010-12-03 15:49:59.233955565 +0900
-+++ b/storage/innobase/sync/sync0sync.c 2010-12-03 17:35:12.989024400 +0900
+--- a/storage/innobase/sync/sync0sync.c
++++ b/storage/innobase/sync/sync0sync.c
@@ -270,13 +270,13 @@
/*==============*/
mutex_t* mutex, /*!< in: pointer to memory */
#!!! notice !!!
# Any small change to this file in the main branch
# should be done or reviewed by the maintainer!
-diff -ruN a/storage/innobase/buf/buf0buf.c b/storage/innobase/buf/buf0buf.c
---- a/storage/innobase/buf/buf0buf.c 2010-11-03 07:01:13.000000000 +0900
-+++ b/storage/innobase/buf/buf0buf.c 2010-12-03 15:07:31.786968193 +0900
-@@ -4831,6 +4831,7 @@
+--- a/storage/innobase/buf/buf0buf.c
++++ b/storage/innobase/buf/buf0buf.c
+@@ -4365,6 +4365,7 @@
}
total_info->pool_size += pool_info->pool_size;
total_info->lru_len += pool_info->lru_len;
total_info->old_lru_len += pool_info->old_lru_len;
total_info->free_list_len += pool_info->free_list_len;
-@@ -4894,6 +4895,8 @@
+@@ -4428,6 +4429,8 @@
pool_info->pool_size = buf_pool->curr_size;
pool_info->lru_len = UT_LIST_GET_LEN(buf_pool->LRU);
pool_info->old_lru_len = buf_pool->LRU_old_len;
-@@ -5010,14 +5013,16 @@
+@@ -4544,14 +4547,16 @@
ut_ad(pool_info);
fprintf(file,
pool_info->free_list_len,
pool_info->lru_len,
pool_info->old_lru_len,
-diff -ruN a/storage/innobase/buf/buf0flu.c b/storage/innobase/buf/buf0flu.c
---- a/storage/innobase/buf/buf0flu.c 2010-12-03 20:58:26.000000000 +0300
-+++ b/storage/innobase/buf/buf0flu.c 2011-01-07 03:37:41.000000000 +0300
+--- a/storage/innobase/buf/buf0flu.c
++++ b/storage/innobase/buf/buf0flu.c
@@ -75,7 +75,7 @@
static buf_flush_stat_t buf_flush_stat_sum;
/* @} */
-diff -ruN a/storage/innobase/fil/fil0fil.c b/storage/innobase/fil/fil0fil.c
---- a/storage/innobase/fil/fil0fil.c 2010-11-03 07:01:13.000000000 +0900
-+++ b/storage/innobase/fil/fil0fil.c 2010-12-03 15:07:31.790357112 +0900
-@@ -4888,3 +4888,30 @@
+--- a/storage/innobase/fil/fil0fil.c
++++ b/storage/innobase/fil/fil0fil.c
+@@ -4889,3 +4889,30 @@
fil_system = NULL;
}
+ return 0;
+ }
+}
-diff -ruN a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc
---- a/storage/innobase/handler/ha_innodb.cc 2010-12-03 15:06:58.727955654 +0900
-+++ b/storage/innobase/handler/ha_innodb.cc 2010-12-03 15:07:31.799376984 +0900
-@@ -603,6 +603,8 @@
+--- a/storage/innobase/handler/ha_innodb.cc
++++ b/storage/innobase/handler/ha_innodb.cc
+@@ -604,6 +604,8 @@
(char*) &export_vars.innodb_buffer_pool_pages_dirty, SHOW_LONG},
{"buffer_pool_pages_flushed",
(char*) &export_vars.innodb_buffer_pool_pages_flushed, SHOW_LONG},
{"buffer_pool_pages_free",
(char*) &export_vars.innodb_buffer_pool_pages_free, SHOW_LONG},
#ifdef UNIV_DEBUG
-@@ -11081,6 +11083,16 @@
+@@ -11097,6 +11099,16 @@
"Force InnoDB to not use next-key locking, to use only row-level locking.",
NULL, NULL, FALSE);
#ifdef UNIV_LOG_ARCHIVE
static MYSQL_SYSVAR_STR(log_arch_dir, innobase_log_arch_dir,
PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY,
-@@ -11268,7 +11280,7 @@
+@@ -11284,7 +11296,7 @@
static MYSQL_SYSVAR_STR(version, innodb_version_str,
PLUGIN_VAR_NOCMDOPT | PLUGIN_VAR_READONLY,
static MYSQL_SYSVAR_BOOL(use_sys_malloc, srv_use_sys_malloc,
PLUGIN_VAR_NOCMDARG | PLUGIN_VAR_READONLY,
-@@ -11361,6 +11373,8 @@
+@@ -11378,6 +11390,8 @@
MYSQL_SYSVAR(thread_concurrency),
MYSQL_SYSVAR(thread_sleep_delay),
MYSQL_SYSVAR(autoinc_lock_mode),
MYSQL_SYSVAR(version),
MYSQL_SYSVAR(use_sys_malloc),
MYSQL_SYSVAR(use_native_aio),
-diff -ruN a/storage/innobase/include/buf0buf.h b/storage/innobase/include/buf0buf.h
---- a/storage/innobase/include/buf0buf.h 2011-01-20 07:37:08.000000000 +0900
-+++ b/storage/innobase/include/buf0buf.h 2011-02-14 15:25:20.859126532 +0900
-@@ -125,6 +125,7 @@
+--- a/storage/innobase/include/buf0buf.h
++++ b/storage/innobase/include/buf0buf.h
+@@ -128,6 +128,7 @@
/* General buffer pool info */
ulint pool_unique_id; /*!< Buffer Pool ID */
ulint pool_size; /*!< Buffer Pool size in pages */
ulint lru_len; /*!< Length of buf_pool->LRU */
ulint old_lru_len; /*!< buf_pool->LRU_old_len */
ulint free_list_len; /*!< Length of buf_pool->free list */
-diff -ruN a/storage/innobase/include/fil0fil.h b/storage/innobase/include/fil0fil.h
---- a/storage/innobase/include/fil0fil.h 2010-11-03 07:01:13.000000000 +0900
-+++ b/storage/innobase/include/fil0fil.h 2010-12-03 15:07:31.812028575 +0900
+--- a/storage/innobase/include/fil0fil.h
++++ b/storage/innobase/include/fil0fil.h
@@ -726,6 +726,17 @@
/*============================*/
ulint id); /*!< in: space id */
typedef struct fil_space_struct fil_space_t;
#endif
-diff -ruN a/storage/innobase/include/read0read.h b/storage/innobase/include/read0read.h
---- a/storage/innobase/include/read0read.h 2010-12-04 02:58:26.000000000 +0900
-+++ b/storage/innobase/include/read0read.h 2011-01-21 19:35:44.127631727 +0900
+--- a/storage/innobase/include/read0read.h
++++ b/storage/innobase/include/read0read.h
@@ -88,6 +88,7 @@
void
read_view_print(
const read_view_t* view); /*!< in: read view */
/*********************************************************************//**
Create a consistent cursor view for mysql to be used in cursors. In this
-diff -ruN a/storage/innobase/include/srv0srv.h b/storage/innobase/include/srv0srv.h
---- a/storage/innobase/include/srv0srv.h 2010-11-03 07:01:13.000000000 +0900
-+++ b/storage/innobase/include/srv0srv.h 2010-12-03 15:07:31.813958103 +0900
+--- a/storage/innobase/include/srv0srv.h
++++ b/storage/innobase/include/srv0srv.h
@@ -142,6 +142,9 @@
extern char srv_adaptive_flushing;
ulint innodb_buffer_pool_write_requests;/*!< srv_buf_pool_write_requests */
ulint innodb_buffer_pool_read_ahead; /*!< srv_read_ahead */
ulint innodb_buffer_pool_read_ahead_evicted;/*!< srv_read_ahead evicted*/
-diff -ruN a/storage/innobase/lock/lock0lock.c b/storage/innobase/lock/lock0lock.c
---- a/storage/innobase/lock/lock0lock.c 2010-11-03 07:01:13.000000000 +0900
-+++ b/storage/innobase/lock/lock0lock.c 2010-12-03 15:07:31.819023998 +0900
-@@ -4374,6 +4374,7 @@
+--- a/storage/innobase/lock/lock0lock.c
++++ b/storage/innobase/lock/lock0lock.c
+@@ -4377,6 +4377,7 @@
putc('\n', file);
block = buf_page_try_get(space, page_no, &mtr);
for (i = 0; i < lock_rec_get_n_bits(lock); ++i) {
-@@ -4400,6 +4401,7 @@
+@@ -4403,6 +4404,7 @@
putc('\n', file);
}
mtr_commit(&mtr);
if (UNIV_LIKELY_NULL(heap)) {
-@@ -4583,7 +4585,7 @@
+@@ -4586,7 +4588,7 @@
}
}
nth_trx++;
goto loop;
}
-@@ -4655,8 +4657,8 @@
+@@ -4658,8 +4660,8 @@
nth_lock++;
" SUPPRESSING FURTHER PRINTS\n",
file);
-diff -ruN a/storage/innobase/read/read0read.c b/storage/innobase/read/read0read.c
---- a/storage/innobase/read/read0read.c 2010-12-04 02:58:26.000000000 +0900
-+++ b/storage/innobase/read/read0read.c 2011-01-21 19:37:08.292650181 +0900
+--- a/storage/innobase/read/read0read.c
++++ b/storage/innobase/read/read0read.c
@@ -357,34 +357,35 @@
void
read_view_print(
(ullint) read_view_get_nth_trx_id(view, i));
}
}
-diff -ruN a/storage/innobase/srv/srv0srv.c b/storage/innobase/srv/srv0srv.c
---- a/storage/innobase/srv/srv0srv.c 2010-11-03 07:01:13.000000000 +0900
-+++ b/storage/innobase/srv/srv0srv.c 2010-12-03 15:07:31.824022673 +0900
+--- a/storage/innobase/srv/srv0srv.c
++++ b/storage/innobase/srv/srv0srv.c
@@ -83,6 +83,7 @@
#include "ha_prototypes.h"
#include "trx0i_s.h"
export_vars.innodb_buffer_pool_reads = srv_buf_pool_reads;
export_vars.innodb_buffer_pool_read_ahead
= stat.n_ra_pages_read;
-diff -ruN a/storage/innobase/sync/sync0arr.c b/storage/innobase/sync/sync0arr.c
---- a/storage/innobase/sync/sync0arr.c 2010-11-03 07:01:13.000000000 +0900
-+++ b/storage/innobase/sync/sync0arr.c 2010-12-03 15:07:31.826041368 +0900
+--- a/storage/innobase/sync/sync0arr.c
++++ b/storage/innobase/sync/sync0arr.c
@@ -478,7 +478,7 @@
fprintf(file,
(ulong) os_thread_pf(cell->thread),
innobase_basename(cell->file), (ulong) cell->line,
difftime(time(NULL), cell->reservation_time));
-diff -ruN a/storage/innobase/trx/trx0purge.c b/storage/innobase/trx/trx0purge.c
---- a/storage/innobase/trx/trx0purge.c 2010-12-04 02:58:26.000000000 +0900
-+++ b/storage/innobase/trx/trx0purge.c 2011-01-21 19:40:42.086683671 +0900
+--- a/storage/innobase/trx/trx0purge.c
++++ b/storage/innobase/trx/trx0purge.c
@@ -1212,7 +1212,7 @@
/*=====================*/
{
#!!! notice !!!
# Any small change to this file in the main branch
# should be done or reviewed by the maintainer!
-diff -ruN a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc
---- a/storage/innobase/handler/ha_innodb.cc 2011-01-21 19:53:42.369599743 +0900
-+++ b/storage/innobase/handler/ha_innodb.cc 2011-01-21 19:54:44.659599699 +0900
-@@ -638,6 +638,16 @@
+--- a/storage/innobase/handler/ha_innodb.cc
++++ b/storage/innobase/handler/ha_innodb.cc
+@@ -639,6 +639,16 @@
trx_t* trx); /*!< in: transaction handle */
static SHOW_VAR innodb_status_variables[]= {
{"buffer_pool_pages_data",
(char*) &export_vars.innodb_buffer_pool_pages_data, SHOW_LONG},
{"buffer_pool_pages_dirty",
-@@ -652,8 +662,14 @@
+@@ -653,8 +663,14 @@
{"buffer_pool_pages_latched",
(char*) &export_vars.innodb_buffer_pool_pages_latched, SHOW_LONG},
#endif /* UNIV_DEBUG */
{"buffer_pool_pages_total",
(char*) &export_vars.innodb_buffer_pool_pages_total, SHOW_LONG},
{"buffer_pool_read_ahead",
-@@ -668,6 +684,12 @@
+@@ -669,6 +685,12 @@
(char*) &export_vars.innodb_buffer_pool_wait_free, SHOW_LONG},
{"buffer_pool_write_requests",
(char*) &export_vars.innodb_buffer_pool_write_requests, SHOW_LONG},
{"data_fsyncs",
(char*) &export_vars.innodb_data_fsyncs, SHOW_LONG},
{"data_pending_fsyncs",
-@@ -694,12 +716,66 @@
+@@ -695,12 +717,66 @@
(char*) &export_vars.innodb_dict_tables, SHOW_LONG},
{"have_atomic_builtins",
(char*) &export_vars.innodb_have_atomic_builtins, SHOW_BOOL},
{"os_log_fsyncs",
(char*) &export_vars.innodb_os_log_fsyncs, SHOW_LONG},
{"os_log_pending_fsyncs",
-@@ -716,8 +792,14 @@
+@@ -717,8 +793,14 @@
(char*) &export_vars.innodb_pages_read, SHOW_LONG},
{"pages_written",
(char*) &export_vars.innodb_pages_written, SHOW_LONG},
{"row_lock_time",
(char*) &export_vars.innodb_row_lock_time, SHOW_LONGLONG},
{"row_lock_time_avg",
-@@ -734,8 +816,20 @@
+@@ -735,8 +817,20 @@
(char*) &export_vars.innodb_rows_read, SHOW_LONG},
{"rows_updated",
(char*) &export_vars.innodb_rows_updated, SHOW_LONG},
{NullS, NullS, SHOW_LONG}
};
-diff -ruN a/storage/innobase/ibuf/ibuf0ibuf.c b/storage/innobase/ibuf/ibuf0ibuf.c
---- a/storage/innobase/ibuf/ibuf0ibuf.c 2011-02-03 15:05:04.000000000 +0900
-+++ b/storage/innobase/ibuf/ibuf0ibuf.c 2011-02-03 15:19:47.000000000 +0900
+--- a/storage/innobase/ibuf/ibuf0ibuf.c
++++ b/storage/innobase/ibuf/ibuf0ibuf.c
@@ -469,6 +469,45 @@
}
Updates the size information of the ibuf, assuming the segment size has not
changed. */
static
-diff -ruN a/storage/innobase/include/ibuf0ibuf.h b/storage/innobase/include/ibuf0ibuf.h
---- a/storage/innobase/include/ibuf0ibuf.h 2010-12-04 02:58:26.000000000 +0900
-+++ b/storage/innobase/include/ibuf0ibuf.h 2011-02-03 15:19:47.000000000 +0900
+--- a/storage/innobase/include/ibuf0ibuf.h
++++ b/storage/innobase/include/ibuf0ibuf.h
@@ -438,6 +438,22 @@
void
ibuf_close(void);
#define IBUF_HEADER_PAGE_NO FSP_IBUF_HEADER_PAGE_NO
#define IBUF_TREE_ROOT_PAGE_NO FSP_IBUF_TREE_ROOT_PAGE_NO
-diff -ruN a/storage/innobase/include/lock0lock.h b/storage/innobase/include/lock0lock.h
---- a/storage/innobase/include/lock0lock.h 2011-01-21 19:52:38.967683738 +0900
-+++ b/storage/innobase/include/lock0lock.h 2011-01-21 19:54:44.660599140 +0900
-@@ -816,6 +816,7 @@
+--- a/storage/innobase/include/lock0lock.h
++++ b/storage/innobase/include/lock0lock.h
+@@ -817,6 +817,7 @@
/** The lock system struct */
struct lock_sys_struct{
hash_table_t* rec_hash; /*!< hash table of the record locks */
};
/** The lock system */
-diff -ruN a/storage/innobase/include/srv0srv.h b/storage/innobase/include/srv0srv.h
---- a/storage/innobase/include/srv0srv.h 2011-01-21 19:53:42.380638228 +0900
-+++ b/storage/innobase/include/srv0srv.h 2011-01-21 19:54:44.662600032 +0900
+--- a/storage/innobase/include/srv0srv.h
++++ b/storage/innobase/include/srv0srv.h
@@ -731,6 +731,11 @@
/** Status variables to be passed to MySQL */
};
/** Thread slot in the thread table */
-diff -ruN a/storage/innobase/include/sync0sync.h b/storage/innobase/include/sync0sync.h
---- a/storage/innobase/include/sync0sync.h 2011-01-21 19:48:45.982637372 +0900
-+++ b/storage/innobase/include/sync0sync.h 2011-01-21 19:54:44.664638235 +0900
-@@ -769,6 +769,10 @@
+--- a/storage/innobase/include/sync0sync.h
++++ b/storage/innobase/include/sync0sync.h
+@@ -771,6 +771,10 @@
#define SYNC_SPIN_ROUNDS srv_n_spin_wait_rounds
/** The number of mutex_exit calls. Intended for performance monitoring. */
extern ib_int64_t mutex_exit_count;
-diff -ruN a/storage/innobase/lock/lock0lock.c b/storage/innobase/lock/lock0lock.c
---- a/storage/innobase/lock/lock0lock.c 2011-01-21 19:52:38.998600121 +0900
-+++ b/storage/innobase/lock/lock0lock.c 2011-01-21 19:54:44.668637536 +0900
-@@ -571,6 +571,7 @@
+--- a/storage/innobase/lock/lock0lock.c
++++ b/storage/innobase/lock/lock0lock.c
+@@ -569,6 +569,7 @@
lock_sys = mem_alloc(sizeof(lock_sys_t));
lock_sys->rec_hash = hash_create(n_cells);
/* hash_create_mutexes(lock_sys->rec_hash, 2, SYNC_REC_LOCK); */
-@@ -1719,6 +1720,7 @@
+@@ -1729,6 +1730,7 @@
HASH_INSERT(lock_t, hash, lock_sys->rec_hash,
lock_rec_fold(space, page_no), lock);
if (UNIV_UNLIKELY(type_mode & LOCK_WAIT)) {
lock_set_lock_and_trx_wait(lock, trx);
-@@ -2265,6 +2267,7 @@
+@@ -2275,6 +2277,7 @@
HASH_DELETE(lock_t, hash, lock_sys->rec_hash,
lock_rec_fold(space, page_no), in_lock);
UT_LIST_REMOVE(trx_locks, trx->trx_locks, in_lock);
-@@ -2308,6 +2311,7 @@
+@@ -2318,6 +2321,7 @@
HASH_DELETE(lock_t, hash, lock_sys->rec_hash,
lock_rec_fold(space, page_no), in_lock);
UT_LIST_REMOVE(trx_locks, trx->trx_locks, in_lock);
}
-diff -ruN a/storage/innobase/srv/srv0srv.c b/storage/innobase/srv/srv0srv.c
---- a/storage/innobase/srv/srv0srv.c 2011-01-21 19:53:42.390637840 +0900
-+++ b/storage/innobase/srv/srv0srv.c 2011-01-21 19:54:44.673637084 +0900
+--- a/storage/innobase/srv/srv0srv.c
++++ b/storage/innobase/srv/srv0srv.c
@@ -2253,12 +2253,49 @@
ulint LRU_len;
ulint free_len;
#ifdef HAVE_ATOMIC_BUILTINS
export_vars.innodb_have_atomic_builtins = 1;
#else
-diff -ruN a/storage/innobase/sync/sync0sync.c b/storage/innobase/sync/sync0sync.c
---- a/storage/innobase/sync/sync0sync.c 2011-01-21 19:53:03.458637954 +0900
-+++ b/storage/innobase/sync/sync0sync.c 2011-01-21 19:54:44.676637686 +0900
+--- a/storage/innobase/sync/sync0sync.c
++++ b/storage/innobase/sync/sync0sync.c
@@ -171,13 +171,13 @@
/** The number of iterations in the mutex_spin_wait() spin loop.
#!!! notice !!!
# Any small change to this file in the main branch
# should be done or reviewed by the maintainer!
-diff -ruN a/storage/innobase/dict/dict0load.c b/storage/innobase/dict/dict0load.c
---- a/storage/innobase/dict/dict0load.c 2011-01-20 07:37:08.000000000 +0900
-+++ b/storage/innobase/dict/dict0load.c 2011-02-14 18:59:40.774162959 +0900
+--- a/storage/innobase/dict/dict0load.c
++++ b/storage/innobase/dict/dict0load.c
@@ -437,7 +437,7 @@
}
/********************************************************************//**
Determine the flags of a table described in SYS_TABLES.
-diff -ruN a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc
---- a/storage/innobase/handler/ha_innodb.cc 2010-12-03 15:53:54.615040167 +0900
-+++ b/storage/innobase/handler/ha_innodb.cc 2010-12-03 16:07:26.851357007 +0900
-@@ -11772,7 +11772,14 @@
+--- a/storage/innobase/handler/ha_innodb.cc
++++ b/storage/innobase/handler/ha_innodb.cc
+@@ -11789,7 +11789,14 @@
i_s_innodb_cmp,
i_s_innodb_cmp_reset,
i_s_innodb_cmpmem,
mysql_declare_plugin_end;
/** @brief Initialize the default value of innodb_commit_concurrency.
-diff -ruN a/storage/innobase/handler/i_s.cc b/storage/innobase/handler/i_s.cc
---- a/storage/innobase/handler/i_s.cc 2010-12-03 15:49:59.207956807 +0900
-+++ b/storage/innobase/handler/i_s.cc 2010-12-03 17:10:02.719210529 +0900
+--- a/storage/innobase/handler/i_s.cc
++++ b/storage/innobase/handler/i_s.cc
@@ -36,9 +36,11 @@
#include <mysql/innodb_priv.h>
/***********************************************************************
*/
static ST_FIELD_INFO i_s_innodb_rseg_fields_info[] =
-diff -ruN a/storage/innobase/handler/i_s.h b/storage/innobase/handler/i_s.h
---- a/storage/innobase/handler/i_s.h 2010-12-03 15:37:45.540456499 +0900
-+++ b/storage/innobase/handler/i_s.h 2010-12-03 16:08:57.596941207 +0900
+--- a/storage/innobase/handler/i_s.h
++++ b/storage/innobase/handler/i_s.h
@@ -35,6 +35,13 @@
extern struct st_mysql_plugin i_s_innodb_cmp_reset;
extern struct st_mysql_plugin i_s_innodb_cmpmem;
#!!! notice !!!
# Any small change to this file in the main branch
# should be done or reviewed by the maintainer!
-diff -ruN a/storage/innobase/btr/btr0cur.c b/storage/innobase/btr/btr0cur.c
---- a/storage/innobase/btr/btr0cur.c 2010-11-03 07:01:13.000000000 +0900
-+++ b/storage/innobase/btr/btr0cur.c 2010-12-03 15:48:29.268957148 +0900
-@@ -4069,7 +4069,8 @@
+--- a/storage/innobase/btr/btr0cur.c
++++ b/storage/innobase/btr/btr0cur.c
+@@ -4142,7 +4142,8 @@
mtr_commit(mtr);
mutex_enter(&block->mutex);
/* Only free the block if it is still allocated to
-@@ -4080,16 +4081,21 @@
+@@ -4153,16 +4154,21 @@
&& buf_block_get_space(block) == space
&& buf_block_get_page_no(block) == page_no) {
-- if (buf_LRU_free_block(&block->page, all) != BUF_LRU_FREED
+- if (!buf_LRU_free_block(&block->page, all)
- && all && block->page.zip.data) {
-+ if (buf_LRU_free_block(&block->page, all, TRUE) != BUF_LRU_FREED
++ if (!buf_LRU_free_block(&block->page, all, TRUE)
+ && all && block->page.zip.data
+ /* Now, buf_LRU_free_block() may release mutex temporarily */
+ && buf_block_get_state(block) == BUF_BLOCK_FILE_PAGE
mutex_exit(&block->mutex);
}
-diff -ruN a/storage/innobase/btr/btr0sea.c b/storage/innobase/btr/btr0sea.c
---- a/storage/innobase/btr/btr0sea.c 2010-12-03 15:48:03.033037049 +0900
-+++ b/storage/innobase/btr/btr0sea.c 2010-12-03 15:48:29.271024260 +0900
+--- a/storage/innobase/btr/btr0sea.c
++++ b/storage/innobase/btr/btr0sea.c
@@ -1943,7 +1943,7 @@
rec_offs_init(offsets_);
rw_lock_x_unlock(&btr_search_latch);
if (UNIV_LIKELY_NULL(heap)) {
mem_heap_free(heap);
-diff -ruN a/storage/innobase/buf/buf0buddy.c b/storage/innobase/buf/buf0buddy.c
---- a/storage/innobase/buf/buf0buddy.c 2010-12-03 15:22:36.307986907 +0900
-+++ b/storage/innobase/buf/buf0buddy.c 2010-12-03 15:48:29.275025723 +0900
-@@ -73,10 +73,11 @@
- if (b) UNIV_MEM_VALID(b, BUF_BUDDY_LOW << i);
- #endif /* UNIV_DEBUG_VALGRIND */
-
+--- a/storage/innobase/buf/buf0buddy.c
++++ b/storage/innobase/buf/buf0buddy.c
+@@ -58,7 +58,7 @@
+
+ /** Validate a given zip_free list. */
+ #define BUF_BUDDY_LIST_VALIDATE(b, i) \
+- UT_LIST_VALIDATE(list, buf_page_t, \
++ UT_LIST_VALIDATE(zip_list, buf_page_t, \
+ b->zip_free[i], \
+ ut_ad(buf_page_get_state( \
+ ut_list_node_313) \
+@@ -75,10 +75,11 @@
+ ulint i) /*!< in: index of
+ buf_pool->zip_free[] */
+ {
- ut_ad(buf_pool_mutex_own(buf_pool));
+ //ut_ad(buf_pool_mutex_own(buf_pool));
+ ut_ad(mutex_own(&buf_pool->zip_free_mutex));
ut_ad(buf_pool->zip_free[i].start != bpage);
- UT_LIST_ADD_FIRST(list, buf_pool->zip_free[i], bpage);
+ UT_LIST_ADD_FIRST(zip_list, buf_pool->zip_free[i], bpage);
+ }
- #ifdef UNIV_DEBUG_VALGRIND
- if (b) UNIV_MEM_FREE(b, BUF_BUDDY_LOW << i);
-@@ -96,8 +97,8 @@
+ /**********************************************************************//**
+@@ -93,16 +94,17 @@
buf_pool->zip_free[] */
{
- #ifdef UNIV_DEBUG_VALGRIND
+ #ifdef UNIV_DEBUG
- buf_page_t* prev = UT_LIST_GET_PREV(list, bpage);
- buf_page_t* next = UT_LIST_GET_NEXT(list, bpage);
+ buf_page_t* prev = UT_LIST_GET_PREV(zip_list, bpage);
+ buf_page_t* next = UT_LIST_GET_NEXT(zip_list, bpage);
- if (prev) UNIV_MEM_VALID(prev, BUF_BUDDY_LOW << i);
- if (next) UNIV_MEM_VALID(next, BUF_BUDDY_LOW << i);
-@@ -106,9 +107,10 @@
+ ut_ad(!prev || buf_page_get_state(prev) == BUF_BLOCK_ZIP_FREE);
ut_ad(!next || buf_page_get_state(next) == BUF_BLOCK_ZIP_FREE);
- #endif /* UNIV_DEBUG_VALGRIND */
+ #endif /* UNIV_DEBUG */
- ut_ad(buf_pool_mutex_own(buf_pool));
+ //ut_ad(buf_pool_mutex_own(buf_pool));
ut_ad(buf_page_get_state(bpage) == BUF_BLOCK_ZIP_FREE);
- UT_LIST_REMOVE(list, buf_pool->zip_free[i], bpage);
+ UT_LIST_REMOVE(zip_list, buf_pool->zip_free[i], bpage);
+ }
- #ifdef UNIV_DEBUG_VALGRIND
- if (prev) UNIV_MEM_FREE(prev, BUF_BUDDY_LOW << i);
-@@ -128,12 +130,13 @@
+ /**********************************************************************//**
+@@ -117,7 +119,8 @@
{
buf_page_t* bpage;
+ //ut_ad(buf_pool_mutex_own(buf_pool));
+ ut_ad(mutex_own(&buf_pool->zip_free_mutex));
ut_a(i < BUF_BUDDY_SIZES);
+ ut_a(i >= buf_buddy_get_slot(PAGE_ZIP_MIN_SIZE));
- #ifndef UNIV_DEBUG_VALGRIND
- /* Valgrind would complain about accessing free memory. */
-- ut_d(UT_LIST_VALIDATE(list, buf_page_t, buf_pool->zip_free[i],
-+ ut_d(UT_LIST_VALIDATE(zip_list, buf_page_t, buf_pool->zip_free[i],
- ut_ad(buf_page_get_state(ut_list_node_313)
- == BUF_BLOCK_ZIP_FREE)));
- #endif /* !UNIV_DEBUG_VALGRIND */
-@@ -177,16 +180,19 @@
+@@ -159,16 +162,19 @@
buf_buddy_block_free(
/*=================*/
buf_pool_t* buf_pool, /*!< in: buffer pool instance */
HASH_SEARCH(hash, buf_pool->zip_hash, fold, buf_page_t*, bpage,
ut_ad(buf_page_get_state(bpage) == BUF_BLOCK_MEMORY
&& bpage->in_zip_hash && !bpage->in_page_hash),
-@@ -198,12 +204,14 @@
+@@ -180,12 +186,14 @@
ut_d(bpage->in_zip_hash = FALSE);
HASH_DELETE(buf_page_t, hash, buf_pool->zip_hash, fold, bpage);
mutex_exit(&block->mutex);
ut_ad(buf_pool->buddy_n_frames > 0);
-@@ -220,7 +228,7 @@
+@@ -202,7 +210,7 @@
{
buf_pool_t* buf_pool = buf_pool_from_block(block);
const ulint fold = BUF_POOL_ZIP_FOLD(block);
ut_ad(!mutex_own(&buf_pool->zip_mutex));
ut_ad(buf_block_get_state(block) == BUF_BLOCK_READY_FOR_USE);
-@@ -232,7 +240,10 @@
+@@ -214,7 +222,10 @@
ut_ad(!block->page.in_page_hash);
ut_ad(!block->page.in_zip_hash);
ut_d(block->page.in_zip_hash = TRUE);
ut_d(buf_pool->buddy_n_frames++);
}
-@@ -268,7 +279,7 @@
- bpage->state = BUF_BLOCK_ZIP_FREE;
- #ifndef UNIV_DEBUG_VALGRIND
- /* Valgrind would complain about accessing free memory. */
-- ut_d(UT_LIST_VALIDATE(list, buf_page_t, buf_pool->zip_free[i],
-+ ut_d(UT_LIST_VALIDATE(zip_list, buf_page_t, buf_pool->zip_free[i],
- ut_ad(buf_page_get_state(
- ut_list_node_313)
- == BUF_BLOCK_ZIP_FREE)));
-@@ -291,25 +302,29 @@
- buf_pool_t* buf_pool, /*!< in: buffer pool instance */
+@@ -268,26 +279,30 @@
+ buf_pool_t* buf_pool, /*!< in/out: buffer pool instance */
ulint i, /*!< in: index of buf_pool->zip_free[],
or BUF_BUDDY_SIZES */
- ibool* lru) /*!< in: pointer to a variable that
will be assigned TRUE if storage was
allocated from the LRU list and
buf_pool->mutex was temporarily
- released, or NULL if the LRU list
- should not be used */
+ released */
+ ibool have_page_hash_mutex)
{
buf_block_t* block;
+ ut_ad(lru);
- ut_ad(buf_pool_mutex_own(buf_pool));
+ //ut_ad(buf_pool_mutex_own(buf_pool));
+ ut_ad(mutex_own(&buf_pool->LRU_list_mutex));
ut_ad(!mutex_own(&buf_pool->zip_mutex));
+ ut_ad(i >= buf_buddy_get_slot(PAGE_ZIP_MIN_SIZE));
if (i < BUF_BUDDY_SIZES) {
/* Try to allocate from the buddy system. */
}
/* Try allocating from the buf_pool->free list. */
-@@ -326,19 +341,30 @@
+@@ -299,19 +314,30 @@
}
/* Try replacing an uncompressed page in the buffer pool. */
return(block);
}
-@@ -355,7 +381,10 @@
- buf_page_t* b;
- buf_pool_t* buf_pool = buf_pool_from_bpage(bpage);
-
-- ut_ad(buf_pool_mutex_own(buf_pool));
-+ //ut_ad(buf_pool_mutex_own(buf_pool));
-+#ifdef UNIV_SYNC_DEBUG
-+ ut_ad(rw_lock_own(&buf_pool->page_hash_latch, RW_LOCK_EX));
-+#endif
-
- switch (buf_page_get_state(bpage)) {
- case BUF_BLOCK_ZIP_FREE:
-@@ -364,7 +393,7 @@
- case BUF_BLOCK_FILE_PAGE:
- case BUF_BLOCK_MEMORY:
- case BUF_BLOCK_REMOVE_HASH:
-- ut_error;
-+ /* ut_error; */ /* optimistic */
- case BUF_BLOCK_ZIP_DIRTY:
- /* Cannot relocate dirty pages. */
- return(FALSE);
-@@ -374,9 +403,18 @@
- }
-
- mutex_enter(&buf_pool->zip_mutex);
-+ mutex_enter(&buf_pool->zip_free_mutex);
-
- if (!buf_page_can_relocate(bpage)) {
- mutex_exit(&buf_pool->zip_mutex);
-+ mutex_exit(&buf_pool->zip_free_mutex);
-+ return(FALSE);
-+ }
-+
-+ if (bpage != buf_page_hash_get(buf_pool,
-+ bpage->space, bpage->offset)) {
-+ mutex_exit(&buf_pool->zip_mutex);
-+ mutex_exit(&buf_pool->zip_free_mutex);
- return(FALSE);
- }
-
-@@ -384,18 +422,19 @@
- ut_d(bpage->state = BUF_BLOCK_ZIP_FREE);
-
- /* relocate buf_pool->zip_clean */
-- b = UT_LIST_GET_PREV(list, dpage);
-- UT_LIST_REMOVE(list, buf_pool->zip_clean, dpage);
-+ b = UT_LIST_GET_PREV(zip_list, dpage);
-+ UT_LIST_REMOVE(zip_list, buf_pool->zip_clean, dpage);
-
- if (b) {
-- UT_LIST_INSERT_AFTER(list, buf_pool->zip_clean, b, dpage);
-+ UT_LIST_INSERT_AFTER(zip_list, buf_pool->zip_clean, b, dpage);
- } else {
-- UT_LIST_ADD_FIRST(list, buf_pool->zip_clean, dpage);
-+ UT_LIST_ADD_FIRST(zip_list, buf_pool->zip_clean, dpage);
- }
-
- UNIV_MEM_INVALID(bpage, sizeof *bpage);
-
- mutex_exit(&buf_pool->zip_mutex);
-+ mutex_exit(&buf_pool->zip_free_mutex);
- return(TRUE);
- }
-
-@@ -409,14 +448,16 @@
+@@ -325,8 +351,9 @@
buf_pool_t* buf_pool, /*!< in: buffer pool instance */
void* src, /*!< in: block to relocate */
void* dst, /*!< in: free block to relocate to */
{
buf_page_t* bpage;
const ulint size = BUF_BUDDY_LOW << i;
- ullint usec = ut_time_us(NULL);
+@@ -335,13 +362,20 @@
+ ulint space;
+ ulint page_no;
- ut_ad(buf_pool_mutex_own(buf_pool));
+ //ut_ad(buf_pool_mutex_own(buf_pool));
ut_ad(!mutex_own(&buf_pool->zip_mutex));
ut_ad(!ut_align_offset(src, size));
ut_ad(!ut_align_offset(dst, size));
-@@ -437,6 +478,13 @@
- if (size >= PAGE_ZIP_MIN_SIZE) {
- /* This is a compressed page. */
- mutex_t* mutex;
-+ ulint space, page_no;
-+
-+ if (!have_page_hash_mutex) {
-+ mutex_exit(&buf_pool->zip_free_mutex);
-+ mutex_enter(&buf_pool->LRU_list_mutex);
-+ rw_lock_x_lock(&buf_pool->page_hash_latch);
-+ }
-
- /* The src block may be split into smaller blocks,
- some of which may be free. Thus, the
-@@ -446,9 +494,9 @@
- pool), so there is nothing wrong about this. The
- mach_read_from_4() calls here will only trigger bogus
- Valgrind memcheck warnings in UNIV_DEBUG_VALGRIND builds. */
-- ulint space = mach_read_from_4(
-+ space = mach_read_from_4(
- (const byte*) src + FIL_PAGE_ARCH_LOG_NO_OR_SPACE_ID);
-- ulint page_no = mach_read_from_4(
-+ page_no = mach_read_from_4(
- (const byte*) src + FIL_PAGE_OFFSET);
- /* Suppress Valgrind warnings about conditional jump
- on uninitialized value. */
-@@ -462,6 +510,11 @@
- added to buf_pool->page_hash yet. Obviously,
- it cannot be relocated. */
-
-+ if (!have_page_hash_mutex) {
-+ mutex_enter(&buf_pool->zip_free_mutex);
-+ mutex_exit(&buf_pool->LRU_list_mutex);
-+ rw_lock_x_unlock(&buf_pool->page_hash_latch);
-+ }
- return(FALSE);
- }
-
-@@ -473,18 +526,27 @@
- For the sake of simplicity, give up. */
- ut_ad(page_zip_get_size(&bpage->zip) < size);
-
-+ if (!have_page_hash_mutex) {
-+ mutex_enter(&buf_pool->zip_free_mutex);
-+ mutex_exit(&buf_pool->LRU_list_mutex);
-+ rw_lock_x_unlock(&buf_pool->page_hash_latch);
-+ }
- return(FALSE);
- }
+ ut_ad(i >= buf_buddy_get_slot(PAGE_ZIP_MIN_SIZE));
+ UNIV_MEM_ASSERT_W(dst, size);
-+ /* To keep latch order */
-+ if (have_page_hash_mutex)
-+ mutex_exit(&buf_pool->zip_free_mutex);
++ if (!have_page_hash_mutex) {
++ mutex_exit(&buf_pool->zip_free_mutex);
++ mutex_enter(&buf_pool->LRU_list_mutex);
++ rw_lock_x_lock(&buf_pool->page_hash_latch);
++ }
+
- /* The block must have been allocated, but it may
- contain uninitialized data. */
- UNIV_MEM_ASSERT_W(src, size);
+ /* We assume that all memory from buf_buddy_alloc()
+ is used for compressed page frames. */
-- mutex = buf_page_get_mutex(bpage);
-+ mutex = buf_page_get_mutex_enter(bpage);
+@@ -375,6 +409,11 @@
+ added to buf_pool->page_hash yet. Obviously,
+ it cannot be relocated. */
-- mutex_enter(mutex);
-+ mutex_enter(&buf_pool->zip_free_mutex);
++ if (!have_page_hash_mutex) {
++ mutex_enter(&buf_pool->zip_free_mutex);
++ mutex_exit(&buf_pool->LRU_list_mutex);
++ rw_lock_x_unlock(&buf_pool->page_hash_latch);
++ }
+ return(FALSE);
+ }
-- if (buf_page_can_relocate(bpage)) {
-+ if (mutex && buf_page_can_relocate(bpage)) {
- /* Relocate the compressed page. */
- ut_a(bpage->zip.data == src);
- memcpy(dst, src, size);
-@@ -499,10 +561,22 @@
- buddy_stat->relocated_usec
- += ut_time_us(NULL) - usec;
- }
-+
-+ if (!have_page_hash_mutex) {
-+ mutex_exit(&buf_pool->LRU_list_mutex);
-+ rw_lock_x_unlock(&buf_pool->page_hash_latch);
-+ }
- return(TRUE);
- }
+@@ -384,18 +423,27 @@
+ For the sake of simplicity, give up. */
+ ut_ad(page_zip_get_size(&bpage->zip) < size);
-- mutex_exit(mutex);
+ if (!have_page_hash_mutex) {
++ mutex_enter(&buf_pool->zip_free_mutex);
+ mutex_exit(&buf_pool->LRU_list_mutex);
+ rw_lock_x_unlock(&buf_pool->page_hash_latch);
+ }
-+
-+ if (mutex) {
-+ mutex_exit(mutex);
-+ }
- } else if (i == buf_buddy_get_slot(sizeof(buf_page_t))) {
- /* This must be a buf_page_t object. */
- #if UNIV_WORD_SIZE == 4
-@@ -511,10 +585,31 @@
- about uninitialized pad bytes. */
- UNIV_MEM_ASSERT_RW(src, size);
- #endif
-+
+ return(FALSE);
+ }
+
++ /* To keep latch order */
++ if (have_page_hash_mutex)
+ mutex_exit(&buf_pool->zip_free_mutex);
+
-+ if (!have_page_hash_mutex) {
-+ mutex_enter(&buf_pool->LRU_list_mutex);
-+ rw_lock_x_lock(&buf_pool->page_hash_latch);
-+ }
-+
- if (buf_buddy_relocate_block(src, dst)) {
-+ mutex_enter(&buf_pool->zip_free_mutex);
-+
-+ if (!have_page_hash_mutex) {
-+ mutex_exit(&buf_pool->LRU_list_mutex);
-+ rw_lock_x_unlock(&buf_pool->page_hash_latch);
-+ }
+ /* The block must have been allocated, but it may
+ contain uninitialized data. */
+ UNIV_MEM_ASSERT_W(src, size);
+
+- mutex = buf_page_get_mutex(bpage);
++ mutex = buf_page_get_mutex_enter(bpage);
+
+- mutex_enter(mutex);
++ mutex_enter(&buf_pool->zip_free_mutex);
- goto success;
+- if (buf_page_can_relocate(bpage)) {
++ if (mutex && buf_page_can_relocate(bpage)) {
+ /* Relocate the compressed page. */
+ ut_a(bpage->zip.data == src);
+ memcpy(dst, src, size);
+@@ -409,10 +457,22 @@
+ buddy_stat->relocated_usec
+ += ut_time_us(NULL) - usec;
}
+
-+ mutex_enter(&buf_pool->zip_free_mutex);
-+
+ if (!have_page_hash_mutex) {
+ mutex_exit(&buf_pool->LRU_list_mutex);
+ rw_lock_x_unlock(&buf_pool->page_hash_latch);
+ }
+ return(TRUE);
}
+- mutex_exit(mutex);
++ if (!have_page_hash_mutex) {
++ mutex_exit(&buf_pool->LRU_list_mutex);
++ rw_lock_x_unlock(&buf_pool->page_hash_latch);
++ }
++
++ if (mutex) {
++ mutex_exit(mutex);
++ }
return(FALSE);
-@@ -529,13 +624,15 @@
+ }
+
+@@ -425,13 +485,15 @@
buf_pool_t* buf_pool, /*!< in: buffer pool instance */
void* buf, /*!< in: block to be freed, must not be
pointed to by the buffer pool */
+ ut_ad(mutex_own(&buf_pool->zip_free_mutex));
ut_ad(!mutex_own(&buf_pool->zip_mutex));
ut_ad(i <= BUF_BUDDY_SIZES);
- ut_ad(buf_pool->buddy_stat[i].used > 0);
-@@ -546,7 +643,9 @@
- ut_d(((buf_page_t*) buf)->state = BUF_BLOCK_ZIP_FREE);
+ ut_ad(i >= buf_buddy_get_slot(PAGE_ZIP_MIN_SIZE));
+@@ -443,7 +505,9 @@
+ ((buf_page_t*) buf)->state = BUF_BLOCK_ZIP_FREE;
if (i == BUF_BUDDY_SIZES) {
- buf_buddy_block_free(buf_pool, buf);
return;
}
-@@ -591,7 +690,7 @@
+@@ -491,7 +555,7 @@
+
ut_a(bpage != buf);
+ UNIV_MEM_ASSERT_W(bpage, BUF_BUDDY_LOW << i);
+- bpage = UT_LIST_GET_NEXT(list, bpage);
++ bpage = UT_LIST_GET_NEXT(zip_list, bpage);
+ }
- {
-- buf_page_t* next = UT_LIST_GET_NEXT(list, bpage);
-+ buf_page_t* next = UT_LIST_GET_NEXT(zip_list, bpage);
- UNIV_MEM_ASSERT_AND_FREE(bpage, BUF_BUDDY_LOW << i);
- bpage = next;
- }
-@@ -600,13 +699,13 @@
#ifndef UNIV_DEBUG_VALGRIND
- buddy_nonfree:
- /* Valgrind would complain about accessing free memory. */
-- ut_d(UT_LIST_VALIDATE(list, buf_page_t, buf_pool->zip_free[i],
-+ ut_d(UT_LIST_VALIDATE(zip_list, buf_page_t, buf_pool->zip_free[i],
- ut_ad(buf_page_get_state(ut_list_node_313)
- == BUF_BLOCK_ZIP_FREE)));
- #endif /* UNIV_DEBUG_VALGRIND */
+@@ -501,7 +565,7 @@
+ ut_d(BUF_BUDDY_LIST_VALIDATE(buf_pool, i));
/* The buddy is not free. Is there a free block of this size? */
- bpage = UT_LIST_GET_FIRST(buf_pool->zip_free[i]);
+ bpage = UT_LIST_GET_LAST(buf_pool->zip_free[i]);
if (bpage) {
- /* Remove the block from the free list, because a successful
-@@ -616,7 +715,7 @@
+
+@@ -510,7 +574,7 @@
buf_buddy_remove_from_free(buf_pool, bpage, i);
/* Try to relocate the buddy of buf to the free block. */
- if (buf_buddy_relocate(buf_pool, buddy, bpage, i)) {
+ if (buf_buddy_relocate(buf_pool, buddy, bpage, i, have_page_hash_mutex)) {
- ut_d(buddy->state = BUF_BLOCK_ZIP_FREE);
- goto buddy_free2;
-@@ -636,14 +735,14 @@
-
- (Parts of the buddy can be free in
- buf_pool->zip_free[j] with j < i.) */
-- ut_d(UT_LIST_VALIDATE(list, buf_page_t, buf_pool->zip_free[i],
-+ ut_d(UT_LIST_VALIDATE(zip_list, buf_page_t, buf_pool->zip_free[i],
- ut_ad(buf_page_get_state(
- ut_list_node_313)
- == BUF_BLOCK_ZIP_FREE
- && ut_list_node_313 != buddy)));
- #endif /* !UNIV_DEBUG_VALGRIND */
-
-- if (buf_buddy_relocate(buf_pool, buddy, buf, i)) {
-+ if (buf_buddy_relocate(buf_pool, buddy, buf, i, have_page_hash_mutex)) {
-
- buf = bpage;
- UNIV_MEM_VALID(bpage, BUF_BUDDY_LOW << i);
-diff -ruN a/storage/innobase/buf/buf0buf.c b/storage/innobase/buf/buf0buf.c
---- a/storage/innobase/buf/buf0buf.c 2010-12-03 15:22:36.314943336 +0900
-+++ b/storage/innobase/buf/buf0buf.c 2010-12-03 15:48:29.282947357 +0900
+ buddy->state = BUF_BLOCK_ZIP_FREE;
+ goto buddy_is_free;
+--- a/storage/innobase/buf/buf0buf.c
++++ b/storage/innobase/buf/buf0buf.c
@@ -263,6 +263,7 @@
#ifdef UNIV_PFS_RWLOCK
/* Keys to register buffer block related rwlocks and mutexes with
for (n = buf_pool->n_chunks; n--; chunk++) {
buf_block_t* block = buf_chunk_contains_zip(chunk, data);
-@@ -1138,7 +1150,7 @@
- buf_block_t* block;
- const buf_block_t* block_end;
-
-- ut_ad(buf_pool_mutex_own(buf_pool));
-+ //ut_ad(buf_pool_mutex_own(buf_pool)); /* but we need all mutex here */
-
- block_end = chunk->blocks + chunk->size;
-
-@@ -1150,8 +1162,10 @@
- ut_ad(!block->in_unzip_LRU_list);
- ut_ad(!block->page.in_flush_list);
- /* Remove the block from the free list. */
-+ mutex_enter(&buf_pool->free_list_mutex);
- ut_ad(block->page.in_free_list);
-- UT_LIST_REMOVE(list, buf_pool->free, (&block->page));
-+ UT_LIST_REMOVE(free, buf_pool->free, (&block->page));
-+ mutex_exit(&buf_pool->free_list_mutex);
-
- /* Free the latches. */
- mutex_free(&block->mutex);
-@@ -1208,9 +1222,21 @@
+@@ -1144,9 +1156,21 @@
------------------------------- */
mutex_create(buf_pool_mutex_key,
&buf_pool->mutex, SYNC_BUF_POOL);
buf_pool_mutex_enter(buf_pool);
if (buf_pool_size > 0) {
-@@ -1223,6 +1249,8 @@
+@@ -1159,6 +1183,8 @@
mem_free(chunk);
mem_free(buf_pool);
buf_pool_mutex_exit(buf_pool);
return(DB_ERROR);
-@@ -1253,6 +1281,8 @@
+@@ -1189,6 +1215,8 @@
/* All fields are initialized by mem_zalloc(). */
buf_pool_mutex_exit(buf_pool);
return(DB_SUCCESS);
-@@ -1467,7 +1497,11 @@
+@@ -1401,7 +1429,11 @@
ulint fold;
buf_pool_t* buf_pool = buf_pool_from_bpage(bpage);
ut_ad(mutex_own(buf_page_get_mutex(bpage)));
ut_a(buf_page_get_io_fix(bpage) == BUF_IO_NONE);
ut_a(bpage->buf_fix_count == 0);
-@@ -1554,7 +1588,8 @@
-
- try_again:
- btr_search_disable(); /* Empty the adaptive hash index again */
-- buf_pool_mutex_enter(buf_pool);
-+ //buf_pool_mutex_enter(buf_pool);
-+ mutex_enter(&buf_pool->LRU_list_mutex);
-
- shrink_again:
- if (buf_pool->n_chunks <= 1) {
-@@ -1625,7 +1660,7 @@
-
- buf_LRU_make_block_old(&block->page);
- dirty++;
-- } else if (buf_LRU_free_block(&block->page, TRUE)
-+ } else if (buf_LRU_free_block(&block->page, TRUE, TRUE)
- != BUF_LRU_FREED) {
- nonfree++;
- }
-@@ -1633,7 +1668,8 @@
- mutex_exit(&block->mutex);
- }
-
-- buf_pool_mutex_exit(buf_pool);
-+ //buf_pool_mutex_exit(buf_pool);
-+ mutex_exit(&buf_pool->LRU_list_mutex);
-
- /* Request for a flush of the chunk if it helps.
- Do not flush if there are non-free blocks, since
-@@ -1683,7 +1719,8 @@
- func_done:
- buf_pool->old_pool_size = buf_pool->curr_pool_size;
- func_exit:
-- buf_pool_mutex_exit(buf_pool);
-+ //buf_pool_mutex_exit(buf_pool);
-+ mutex_exit(&buf_pool->LRU_list_mutex);
- btr_search_enable();
- }
-
-@@ -1724,7 +1761,9 @@
- hash_table_t* zip_hash;
- hash_table_t* page_hash;
-
-- buf_pool_mutex_enter(buf_pool);
-+ //buf_pool_mutex_enter(buf_pool);
-+ mutex_enter(&buf_pool->LRU_list_mutex);
-+ rw_lock_x_lock(&buf_pool->page_hash_latch);
-
- /* Free, create, and populate the hash table. */
- hash_table_free(buf_pool->page_hash);
-@@ -1765,8 +1804,9 @@
- All such blocks are either in buf_pool->zip_clean or
- in buf_pool->flush_list. */
-
-+ mutex_enter(&buf_pool->zip_mutex);
- for (b = UT_LIST_GET_FIRST(buf_pool->zip_clean); b;
-- b = UT_LIST_GET_NEXT(list, b)) {
-+ b = UT_LIST_GET_NEXT(zip_list, b)) {
- ut_a(buf_page_get_state(b) == BUF_BLOCK_ZIP_PAGE);
- ut_ad(!b->in_flush_list);
- ut_ad(b->in_LRU_list);
-@@ -1776,10 +1816,11 @@
- HASH_INSERT(buf_page_t, hash, page_hash,
- buf_page_address_fold(b->space, b->offset), b);
- }
-+ mutex_exit(&buf_pool->zip_mutex);
-
- buf_flush_list_mutex_enter(buf_pool);
- for (b = UT_LIST_GET_FIRST(buf_pool->flush_list); b;
-- b = UT_LIST_GET_NEXT(list, b)) {
-+ b = UT_LIST_GET_NEXT(flush_list, b)) {
- ut_ad(b->in_flush_list);
- ut_ad(b->in_LRU_list);
- ut_ad(b->in_page_hash);
-@@ -1806,7 +1847,9 @@
- }
-
- buf_flush_list_mutex_exit(buf_pool);
-- buf_pool_mutex_exit(buf_pool);
-+ //buf_pool_mutex_exit(buf_pool);
-+ mutex_exit(&buf_pool->LRU_list_mutex);
-+ rw_lock_x_unlock(&buf_pool->page_hash_latch);
- }
-
- /********************************************************************
-@@ -1853,21 +1896,32 @@
+@@ -1512,21 +1544,32 @@
buf_page_t* bpage;
ulint i;
buf_pool_t* buf_pool = buf_pool_get(space, offset);
for (i = 0; i < BUF_POOL_WATCH_SIZE; i++) {
bpage = &buf_pool->watch[i];
-@@ -1891,10 +1945,12 @@
+@@ -1550,10 +1593,12 @@
bpage->space = space;
bpage->offset = offset;
bpage->buf_fix_count = 1;
return(NULL);
case BUF_BLOCK_ZIP_PAGE:
ut_ad(bpage->in_page_hash);
-@@ -1912,6 +1968,8 @@
+@@ -1571,6 +1616,8 @@
ut_error;
/* Fix compiler warning */
return(NULL);
}
-@@ -1941,6 +1999,8 @@
- buf_chunk_t* chunks;
- buf_chunk_t* chunk;
-
-+ mutex_enter(&buf_pool->LRU_list_mutex);
-+ rw_lock_x_lock(&buf_pool->page_hash_latch);
- buf_pool_mutex_enter(buf_pool);
- chunks = mem_alloc((buf_pool->n_chunks + 1) * sizeof *chunks);
-
-@@ -1959,6 +2019,8 @@
- buf_pool->n_chunks++;
- }
-
-+ mutex_exit(&buf_pool->LRU_list_mutex);
-+ rw_lock_x_unlock(&buf_pool->page_hash_latch);
- buf_pool_mutex_exit(buf_pool);
- }
-
-@@ -2046,7 +2108,11 @@
+@@ -1588,7 +1635,11 @@
space, offset) */
buf_page_t* watch) /*!< in/out: sentinel for watch */
{
HASH_DELETE(buf_page_t, hash, buf_pool->page_hash, fold, watch);
ut_d(watch->in_page_hash = FALSE);
-@@ -2068,28 +2134,31 @@
+@@ -1610,28 +1661,31 @@
buf_pool_t* buf_pool = buf_pool_get(space, offset);
ulint fold = buf_page_address_fold(space, offset);
}
/****************************************************************//**
-@@ -2109,14 +2178,16 @@
+@@ -1651,14 +1705,16 @@
buf_pool_t* buf_pool = buf_pool_get(space, offset);
ulint fold = buf_page_address_fold(space, offset);
return(ret);
}
-@@ -2133,13 +2204,15 @@
+@@ -1675,13 +1731,15 @@
{
buf_pool_t* buf_pool = buf_pool_from_bpage(bpage);
}
/********************************************************************//**
-@@ -2163,14 +2236,20 @@
+@@ -1705,14 +1763,20 @@
ut_a(buf_page_in_file(bpage));
if (buf_page_peek_if_too_old(bpage)) {
}
}
-@@ -2187,7 +2266,8 @@
+@@ -1729,7 +1793,8 @@
buf_block_t* block;
buf_pool_t* buf_pool = buf_pool_get(space, offset);
block = (buf_block_t*) buf_page_hash_get(buf_pool, space, offset);
-@@ -2196,7 +2276,8 @@
+@@ -1738,7 +1803,8 @@
block->check_index_page_at_flush = FALSE;
}
}
/********************************************************************//**
-@@ -2215,7 +2296,8 @@
+@@ -1757,7 +1823,8 @@
ibool is_hashed;
buf_pool_t* buf_pool = buf_pool_get(space, offset);
block = (buf_block_t*) buf_page_hash_get(buf_pool, space, offset);
-@@ -2226,7 +2308,8 @@
+@@ -1768,7 +1835,8 @@
is_hashed = block->is_hashed;
}
return(is_hashed);
}
-@@ -2248,7 +2331,8 @@
+@@ -1790,7 +1858,8 @@
buf_page_t* bpage;
buf_pool_t* buf_pool = buf_pool_get(space, offset);
bpage = buf_page_hash_get(buf_pool, space, offset);
-@@ -2259,7 +2343,8 @@
+@@ -1801,7 +1870,8 @@
bpage->file_page_was_freed = TRUE;
}
return(bpage);
}
-@@ -2280,7 +2365,8 @@
+@@ -1822,7 +1892,8 @@
buf_page_t* bpage;
buf_pool_t* buf_pool = buf_pool_get(space, offset);
bpage = buf_page_hash_get(buf_pool, space, offset);
-@@ -2289,7 +2375,8 @@
+@@ -1831,7 +1902,8 @@
bpage->file_page_was_freed = FALSE;
}
return(bpage);
}
-@@ -2321,8 +2408,9 @@
+@@ -1863,8 +1935,9 @@
buf_pool->stat.n_page_gets++;
for (;;) {
bpage = buf_page_hash_get(buf_pool, space, offset);
if (bpage) {
ut_ad(!buf_pool_watch_is_sentinel(buf_pool, bpage));
-@@ -2331,7 +2419,8 @@
+@@ -1873,7 +1946,8 @@
/* Page not in buf_pool: needs to be read from file */
buf_read_page(space, zip_size, offset);
-@@ -2343,10 +2432,15 @@
+@@ -1885,10 +1959,15 @@
if (UNIV_UNLIKELY(!bpage->zip.data)) {
/* There is no compressed page. */
err_exit:
ut_ad(!buf_pool_watch_is_sentinel(buf_pool, bpage));
switch (buf_page_get_state(bpage)) {
-@@ -2355,24 +2449,43 @@
+@@ -1897,24 +1976,43 @@
case BUF_BLOCK_MEMORY:
case BUF_BLOCK_REMOVE_HASH:
case BUF_BLOCK_ZIP_FREE:
mutex_enter(block_mutex);
- /* Discard the uncompressed page frame if possible. */
-- if (buf_LRU_free_block(bpage, FALSE) == BUF_LRU_FREED) {
+- if (buf_LRU_free_block(bpage, FALSE)) {
+ if (UNIV_UNLIKELY(bpage->space != space
+ || bpage->offset != offset
+ || !bpage->in_LRU_list
+ }
+ /* Discard the uncompressed page frame if possible. */
-+ if (buf_LRU_free_block(bpage, FALSE, TRUE) == BUF_LRU_FREED) {
++ if (buf_LRU_free_block(bpage, FALSE, TRUE)) {
+ mutex_exit(&buf_pool->LRU_list_mutex);
mutex_exit(block_mutex);
goto lookup;
buf_block_buf_fix_inc((buf_block_t*) bpage,
__FILE__, __LINE__);
goto got_block;
-@@ -2385,7 +2498,7 @@
+@@ -1927,7 +2025,7 @@
must_read = buf_page_get_io_fix(bpage) == BUF_IO_READ;
access_time = buf_page_is_accessed(bpage);
mutex_exit(block_mutex);
-@@ -2697,7 +2810,7 @@
+@@ -2239,7 +2337,7 @@
const buf_block_t* block) /*!< in: pointer to block,
not dereferenced */
{
if (UNIV_UNLIKELY((((ulint) block) % sizeof *block) != 0)) {
/* The pointer should be aligned. */
-@@ -2733,6 +2846,7 @@
+@@ -2275,6 +2373,7 @@
ulint fix_type;
ibool must_read;
ulint retries = 0;
buf_pool_t* buf_pool = buf_pool_get(space, offset);
ut_ad(mtr);
-@@ -2765,9 +2879,11 @@
+@@ -2308,18 +2407,24 @@
fold = buf_page_address_fold(space, offset);
loop:
block = guess;
+ block_mutex = buf_page_get_mutex_enter((buf_page_t*)block);
+
/* If the guess is a compressed page descriptor that
- has been allocated by buf_buddy_alloc(), it may have
- been invalidated by buf_buddy_relocate(). In that
-@@ -2776,11 +2892,15 @@
- the guess may be pointing to a buffer pool chunk that
- has been released when resizing the buffer pool. */
+ has been allocated by buf_page_alloc_descriptor(),
+ it may have been freed by buf_relocate(). */
- if (!buf_block_is_uncompressed(buf_pool, block)
+ if (!block_mutex) {
block = guess = NULL;
} else {
ut_ad(!block->page.in_zip_hash);
-@@ -2789,12 +2909,19 @@
+@@ -2328,12 +2433,19 @@
}
if (block == NULL) {
block = NULL;
}
-@@ -2806,12 +2933,14 @@
+@@ -2345,12 +2457,14 @@
space, offset, fold);
if (UNIV_LIKELY_NULL(block)) {
if (mode == BUF_GET_IF_IN_POOL
|| mode == BUF_PEEK_IF_IN_POOL
-@@ -2861,7 +2990,8 @@
+@@ -2400,7 +2514,8 @@
/* The page is being read to buffer pool,
but we cannot wait around for the read to
complete. */
return(NULL);
}
-@@ -2871,38 +3001,49 @@
+@@ -2410,38 +2525,49 @@
ibool success;
case BUF_BLOCK_FILE_PAGE:
{
buf_page_t* hash_bpage;
-@@ -2915,35 +3056,47 @@
+@@ -2454,35 +2580,47 @@
while buf_pool->mutex was released.
Free the block that was allocated. */
buf_block_init_low(block);
block->lock_hash_val = lock_rec_hash(space, offset);
-@@ -2952,7 +3105,7 @@
-
+@@ -2492,7 +2630,7 @@
if (buf_page_get_state(&block->page)
== BUF_BLOCK_ZIP_PAGE) {
+ #if defined UNIV_DEBUG || defined UNIV_BUF_DEBUG
- UT_LIST_REMOVE(list, buf_pool->zip_clean,
+ UT_LIST_REMOVE(zip_list, buf_pool->zip_clean,
&block->page);
+ #endif /* UNIV_DEBUG || UNIV_BUF_DEBUG */
ut_ad(!block->page.in_flush_list);
- } else {
-@@ -2969,20 +3122,25 @@
+@@ -2510,18 +2648,23 @@
/* Insert at the front of unzip_LRU list */
buf_unzip_LRU_add_block(block, FALSE);
- mutex_exit(&block->mutex);
+ mutex_exit(block_mutex);
mutex_exit(&buf_pool->zip_mutex);
-+
-+ buf_pool_mutex_enter(buf_pool);
- buf_pool->n_pend_unzip++;
-+ buf_pool_mutex_exit(buf_pool);
+- buf_pool->n_pend_unzip++;
- bpage->state = BUF_BLOCK_ZIP_FREE;
-- buf_buddy_free(buf_pool, bpage, sizeof *bpage);
-+ buf_buddy_free(buf_pool, bpage, sizeof *bpage, FALSE);
++ buf_pool_mutex_enter(buf_pool);
++ buf_pool->n_pend_unzip++;
+ buf_pool_mutex_exit(buf_pool);
-- buf_pool_mutex_exit(buf_pool);
+ //buf_pool_mutex_exit(buf_pool);
++
+ buf_page_free_descriptor(bpage);
/* Decompress the page and apply buffered operations
- while not holding buf_pool->mutex or block->mutex. */
-@@ -2995,12 +3153,15 @@
+@@ -2535,12 +2678,15 @@
}
/* Unfix and unlatch the block. */
rw_lock_x_unlock(&block->lock);
break;
-@@ -3016,7 +3177,7 @@
+@@ -2556,7 +2702,7 @@
ut_ad(buf_block_get_state(block) == BUF_BLOCK_FILE_PAGE);
#if UNIV_WORD_SIZE == 4
/* On 32-bit systems, there is no padding in buf_page_t. On
other systems, Valgrind could complain about uninitialized pad
-@@ -3029,8 +3190,8 @@
+@@ -2569,8 +2715,8 @@
/* Try to evict the block from the buffer pool, to use the
insert buffer (change buffer) as much as possible. */
-- if (buf_LRU_free_block(&block->page, TRUE) == BUF_LRU_FREED) {
+- if (buf_LRU_free_block(&block->page, TRUE)) {
- mutex_exit(&block->mutex);
-+ if (buf_LRU_free_block(&block->page, TRUE, FALSE) == BUF_LRU_FREED) {
++ if (buf_LRU_free_block(&block->page, TRUE, FALSE)) {
+ mutex_exit(block_mutex);
if (mode == BUF_GET_IF_IN_POOL_OR_WATCH) {
/* Set the watch, as it would have
been set if the page were not in the
-@@ -3039,6 +3200,9 @@
+@@ -2579,6 +2725,9 @@
space, offset, fold);
if (UNIV_LIKELY_NULL(block)) {
/* The page entered the buffer
pool for some reason. Try to
-@@ -3046,7 +3210,7 @@
+@@ -2586,7 +2735,7 @@
goto got_block;
}
}
fprintf(stderr,
"innodb_change_buffering_debug evict %u %u\n",
(unsigned) space, (unsigned) offset);
-@@ -3065,13 +3229,14 @@
-
- buf_block_buf_fix_inc(block, file, line);
-
+@@ -2608,13 +2757,14 @@
+ ut_a(mode == BUF_GET_POSSIBLY_FREED
+ || !block->page.file_page_was_freed);
+ #endif
- mutex_exit(&block->mutex);
+ //mutex_exit(&block->mutex);
if (UNIV_LIKELY(mode != BUF_PEEK_IF_IN_POOL)) {
buf_page_set_accessed_make_young(&block->page, access_time);
-@@ -3308,9 +3473,11 @@
+@@ -2847,9 +2997,11 @@
buf_pool = buf_pool_from_block(block);
if (mode == BUF_MAKE_YOUNG && buf_page_peek_if_too_old(&block->page)) {
} else if (!buf_page_is_accessed(&block->page)) {
/* Above, we do a dirty read on purpose, to avoid
mutex contention. The field buf_page_t::access_time
-@@ -3318,9 +3485,11 @@
+@@ -2857,9 +3009,11 @@
field must be protected by mutex, however. */
ulint time_ms = ut_time_ms();
}
ut_ad(!ibuf_inside(mtr) || mode == BUF_KEEP_OLD);
-@@ -3387,18 +3556,21 @@
+@@ -2926,18 +3080,21 @@
ut_ad(mtr);
ut_ad(mtr->state == MTR_ACTIVE);
#if defined UNIV_DEBUG || defined UNIV_BUF_DEBUG
ut_a(buf_block_get_state(block) == BUF_BLOCK_FILE_PAGE);
-@@ -3487,7 +3659,10 @@
+@@ -3026,7 +3183,10 @@
buf_page_t* hash_page;
buf_pool_t* buf_pool = buf_pool_get(space, offset);
ut_ad(mutex_own(&(block->mutex)));
ut_a(buf_block_get_state(block) != BUF_BLOCK_FILE_PAGE);
-@@ -3516,11 +3691,14 @@
+@@ -3055,11 +3215,14 @@
if (UNIV_LIKELY(!hash_page)) {
} else if (buf_pool_watch_is_sentinel(buf_pool, hash_page)) {
/* Preserve the reference count. */
} else {
fprintf(stderr,
"InnoDB: Error: page %lu %lu already found"
-@@ -3530,7 +3708,8 @@
+@@ -3069,7 +3232,8 @@
(const void*) hash_page, (const void*) block);
#if defined UNIV_DEBUG || defined UNIV_BUF_DEBUG
mutex_exit(&block->mutex);
buf_print();
buf_LRU_print();
buf_validate();
-@@ -3613,7 +3792,9 @@
+@@ -3152,7 +3316,9 @@
fold = buf_page_address_fold(space, offset);
watch_page = buf_page_hash_get_low(buf_pool, space, offset, fold);
if (watch_page && !buf_pool_watch_is_sentinel(buf_pool, watch_page)) {
-@@ -3622,9 +3803,15 @@
+@@ -3161,9 +3327,15 @@
err_exit:
if (block) {
mutex_enter(&block->mutex);
bpage = NULL;
goto func_exit;
-@@ -3647,6 +3834,8 @@
+@@ -3186,6 +3358,8 @@
buf_page_init(space, offset, fold, block);
/* The block must be put to the LRU list, to the old blocks */
buf_LRU_add_block(bpage, TRUE/* to old blocks */);
-@@ -3674,7 +3863,7 @@
+@@ -3213,7 +3387,7 @@
been added to buf_pool->LRU and
buf_pool->page_hash. */
mutex_exit(&block->mutex);
mutex_enter(&block->mutex);
block->page.zip.data = data;
-@@ -3687,6 +3876,7 @@
+@@ -3226,13 +3400,14 @@
buf_unzip_LRU_add_block(block, TRUE);
}
+ mutex_exit(&buf_pool->LRU_list_mutex);
mutex_exit(&block->mutex);
} else {
- /* Defer buf_buddy_alloc() until after the block has
-@@ -3698,8 +3888,8 @@
+ /* The compressed page must be allocated before the
control block (bpage), in order to avoid the
invocation of buf_buddy_relocate_block() on
uninitialized data. */
- data = buf_buddy_alloc(buf_pool, zip_size, &lru);
-- bpage = buf_buddy_alloc(buf_pool, sizeof *bpage, &lru);
+ data = buf_buddy_alloc(buf_pool, zip_size, &lru, TRUE);
-+ bpage = buf_buddy_alloc(buf_pool, sizeof *bpage, &lru, TRUE);
- /* Initialize the buf_pool pointer. */
- bpage->buf_pool_index = buf_pool_index(buf_pool);
-@@ -3719,8 +3909,11 @@
+ /* If buf_buddy_alloc() allocated storage from the LRU list,
+ it released and reacquired buf_pool->mutex. Thus, we must
+@@ -3248,7 +3423,10 @@
+
/* The block was added by some other thread. */
watch_page = NULL;
- bpage->state = BUF_BLOCK_ZIP_FREE;
-- buf_buddy_free(buf_pool, bpage, sizeof *bpage);
- buf_buddy_free(buf_pool, data, zip_size);
-+ buf_buddy_free(buf_pool, bpage, sizeof *bpage, TRUE);
+ buf_buddy_free(buf_pool, data, zip_size, TRUE);
+
+ mutex_exit(&buf_pool->LRU_list_mutex);
bpage = NULL;
goto func_exit;
-@@ -3764,18 +3957,24 @@
+@@ -3296,20 +3474,26 @@
HASH_INSERT(buf_page_t, hash, buf_pool->page_hash, fold,
bpage);
+
/* The block must be put to the LRU list, to the old blocks */
buf_LRU_add_block(bpage, TRUE/* to old blocks */);
+ #if defined UNIV_DEBUG || defined UNIV_BUF_DEBUG
buf_LRU_insert_zip_clean(bpage);
+ #endif /* UNIV_DEBUG || UNIV_BUF_DEBUG */
+ mutex_exit(&buf_pool->LRU_list_mutex);
+
if (mode == BUF_READ_IBUF_PAGES_ONLY) {
-@@ -3817,7 +4016,9 @@
+@@ -3351,7 +3535,9 @@
fold = buf_page_address_fold(space, offset);
block = (buf_block_t*) buf_page_hash_get_low(
buf_pool, space, offset, fold);
-@@ -3833,7 +4034,9 @@
+@@ -3367,7 +3553,9 @@
#endif /* UNIV_DEBUG_FILE_ACCESSES || UNIV_DEBUG */
/* Page can be found in buf_pool */
buf_block_free(free_block);
-@@ -3855,6 +4058,7 @@
+@@ -3389,6 +3577,7 @@
mutex_enter(&block->mutex);
buf_page_init(space, offset, fold, block);
/* The block must be put to the LRU list */
buf_LRU_add_block(&block->page, FALSE);
-@@ -3881,7 +4085,7 @@
+@@ -3415,7 +3604,7 @@
the reacquisition of buf_pool->mutex. We also must
defer this operation until after the block descriptor
has been added to buf_pool->LRU and buf_pool->page_hash. */
mutex_enter(&block->mutex);
block->page.zip.data = data;
-@@ -3899,7 +4103,8 @@
+@@ -3433,7 +3622,8 @@
buf_page_set_accessed(&block->page, time_ms);
mtr_memo_push(mtr, block, MTR_MEMO_BUF_FIX);
-@@ -3950,6 +4155,8 @@
+@@ -3484,6 +3674,8 @@
buf_pool_t* buf_pool = buf_pool_from_bpage(bpage);
const ibool uncompressed = (buf_page_get_state(bpage)
== BUF_BLOCK_FILE_PAGE);
ut_a(buf_page_in_file(bpage));
-@@ -4083,8 +4290,26 @@
+@@ -3617,8 +3809,26 @@
}
}
#ifdef UNIV_IBUF_COUNT_DEBUG
if (io_type == BUF_IO_WRITE || uncompressed) {
-@@ -4107,6 +4332,7 @@
+@@ -3641,6 +3851,7 @@
the x-latch to this OS thread: do not let this confuse you in
debugging! */
ut_ad(buf_pool->n_pend_reads > 0);
buf_pool->n_pend_reads--;
buf_pool->stat.n_pages_read++;
-@@ -4124,6 +4350,9 @@
+@@ -3658,6 +3869,9 @@
buf_flush_write_complete(bpage);
if (uncompressed) {
rw_lock_s_unlock_gen(&((buf_block_t*) bpage)->lock,
BUF_IO_WRITE);
-@@ -4146,8 +4375,8 @@
+@@ -3680,8 +3894,8 @@
}
#endif /* UNIV_DEBUG */
}
/*********************************************************************//**
-@@ -4164,7 +4393,9 @@
+@@ -3698,7 +3912,9 @@
ut_ad(buf_pool);
chunk = buf_pool->chunks;
-@@ -4181,7 +4412,9 @@
+@@ -3715,7 +3931,9 @@
}
}
return(TRUE);
}
-@@ -4229,7 +4462,8 @@
+@@ -3763,7 +3981,8 @@
freed = buf_LRU_search_and_free_block(buf_pool, 100);
}
ut_ad(UT_LIST_GET_LEN(buf_pool->LRU) == 0);
ut_ad(UT_LIST_GET_LEN(buf_pool->unzip_LRU) == 0);
-@@ -4242,7 +4476,8 @@
+@@ -3776,7 +3995,8 @@
memset(&buf_pool->stat, 0x00, sizeof(buf_pool->stat));
buf_refresh_io_stats(buf_pool);
}
/*********************************************************************//**
-@@ -4284,7 +4519,10 @@
+@@ -3818,7 +4038,10 @@
ut_ad(buf_pool);
chunk = buf_pool->chunks;
-@@ -4379,7 +4617,7 @@
+@@ -3913,7 +4136,7 @@
/* Check clean compressed-only blocks. */
for (b = UT_LIST_GET_FIRST(buf_pool->zip_clean); b;
ut_a(buf_page_get_state(b) == BUF_BLOCK_ZIP_PAGE);
switch (buf_page_get_io_fix(b)) {
case BUF_IO_NONE:
-@@ -4410,7 +4648,7 @@
+@@ -3944,7 +4167,7 @@
buf_flush_list_mutex_enter(buf_pool);
for (b = UT_LIST_GET_FIRST(buf_pool->flush_list); b;
ut_ad(b->in_flush_list);
ut_a(b->oldest_modification);
n_flush++;
-@@ -4469,6 +4707,8 @@
+@@ -4003,6 +4226,8 @@
}
ut_a(UT_LIST_GET_LEN(buf_pool->LRU) == n_lru);
if (UT_LIST_GET_LEN(buf_pool->free) != n_free) {
fprintf(stderr, "Free list len %lu, free blocks %lu\n",
(ulong) UT_LIST_GET_LEN(buf_pool->free),
-@@ -4479,8 +4719,11 @@
+@@ -4013,8 +4238,11 @@
ut_a(buf_pool->n_flush[BUF_FLUSH_SINGLE_PAGE] == n_single_flush);
ut_a(buf_pool->n_flush[BUF_FLUSH_LIST] == n_list_flush);
ut_a(buf_pool->n_flush[BUF_FLUSH_LRU] == n_lru_flush);
ut_a(buf_LRU_validate());
ut_a(buf_flush_validate(buf_pool));
-@@ -4536,7 +4779,9 @@
+@@ -4070,7 +4298,9 @@
index_ids = mem_alloc(size * sizeof *index_ids);
counts = mem_alloc(sizeof(ulint) * size);
buf_flush_list_mutex_enter(buf_pool);
fprintf(stderr,
-@@ -4605,7 +4850,9 @@
+@@ -4139,7 +4369,9 @@
}
}
for (i = 0; i < n_found; i++) {
index = dict_index_get_if_in_cache(index_ids[i]);
-@@ -4662,7 +4909,7 @@
+@@ -4196,7 +4428,7 @@
buf_chunk_t* chunk;
ulint fixed_pages_number = 0;
chunk = buf_pool->chunks;
-@@ -4696,7 +4943,7 @@
+@@ -4230,7 +4462,7 @@
/* Traverse the lists of clean and dirty compressed-only blocks. */
for (b = UT_LIST_GET_FIRST(buf_pool->zip_clean); b;
ut_a(buf_page_get_state(b) == BUF_BLOCK_ZIP_PAGE);
ut_a(buf_page_get_io_fix(b) != BUF_IO_WRITE);
-@@ -4708,7 +4955,7 @@
+@@ -4242,7 +4474,7 @@
buf_flush_list_mutex_enter(buf_pool);
for (b = UT_LIST_GET_FIRST(buf_pool->flush_list); b;
ut_ad(b->in_flush_list);
switch (buf_page_get_state(b)) {
-@@ -4734,7 +4981,7 @@
+@@ -4268,7 +4500,7 @@
buf_flush_list_mutex_exit(buf_pool);
mutex_exit(&buf_pool->zip_mutex);
return(fixed_pages_number);
}
-@@ -4890,6 +5137,8 @@
+@@ -4424,6 +4656,8 @@
/* Find appropriate pool_info to store stats for this buffer pool */
pool_info = &all_pool_info[pool_id];
buf_pool_mutex_enter(buf_pool);
buf_flush_list_mutex_enter(buf_pool);
-@@ -5000,6 +5249,8 @@
+@@ -4534,6 +4768,8 @@
pool_info->unzip_cur = buf_LRU_stat_cur.unzip;
buf_refresh_io_stats(buf_pool);
buf_pool_mutex_exit(buf_pool);
}
-@@ -5241,11 +5492,13 @@
+@@ -4775,11 +5011,13 @@
{
ulint len;
return(len);
}
-diff -ruN a/storage/innobase/buf/buf0flu.c b/storage/innobase/buf/buf0flu.c
---- a/storage/innobase/buf/buf0flu.c 2010-12-03 15:22:36.318955693 +0900
-+++ b/storage/innobase/buf/buf0flu.c 2010-12-03 15:48:29.289024083 +0900
+--- a/storage/innobase/buf/buf0flu.c
++++ b/storage/innobase/buf/buf0flu.c
@@ -307,7 +307,7 @@
ut_d(block->page.in_flush_list = TRUE);
ut_ad(mutex_own(buf_page_get_mutex(bpage)));
ut_ad(bpage->in_flush_list);
-@@ -526,11 +526,11 @@
+@@ -526,13 +526,13 @@
return;
case BUF_BLOCK_ZIP_DIRTY:
buf_page_set_state(bpage, BUF_BLOCK_ZIP_PAGE);
- UT_LIST_REMOVE(list, buf_pool->flush_list, bpage);
+ UT_LIST_REMOVE(flush_list, buf_pool->flush_list, bpage);
+ #if defined UNIV_DEBUG || defined UNIV_BUF_DEBUG
buf_LRU_insert_zip_clean(bpage);
+ #endif /* UNIV_DEBUG || UNIV_BUF_DEBUG */
break;
case BUF_BLOCK_FILE_PAGE:
- UT_LIST_REMOVE(list, buf_pool->flush_list, bpage);
break;
}
-@@ -574,7 +574,7 @@
+@@ -576,7 +576,7 @@
buf_page_t* prev_b = NULL;
buf_pool_t* buf_pool = buf_pool_from_bpage(bpage);
/* Must reside in the same buffer pool. */
ut_ad(buf_pool == buf_pool_from_bpage(dpage));
-@@ -603,18 +603,18 @@
+@@ -605,18 +605,18 @@
because we assert on in_flush_list in comparison function. */
ut_d(bpage->in_flush_list = FALSE);
buf_pool->flush_list,
dpage);
}
-@@ -1083,7 +1083,7 @@
+@@ -1085,7 +1085,7 @@
#ifdef UNIV_DEBUG
buf_pool_t* buf_pool = buf_pool_from_bpage(bpage);
#endif
#ifdef UNIV_LOG_DEBUG
-@@ -1097,7 +1097,8 @@
+@@ -1099,7 +1099,8 @@
io_fixed and oldest_modification != 0. Thus, it cannot be
relocated in the buffer pool or removed from flush_list or
LRU_list. */
ut_ad(!buf_flush_list_mutex_own(buf_pool));
ut_ad(!mutex_own(buf_page_get_mutex(bpage)));
ut_ad(buf_page_get_io_fix(bpage) == BUF_IO_WRITE);
-@@ -1177,7 +1178,7 @@
+@@ -1179,7 +1180,7 @@
buf_pool_t* buf_pool, /*!< in/out: buffer pool instance */
buf_block_t* block) /*!< in/out: buffer control block */
{
ut_ad(buf_block_get_state(block) == BUF_BLOCK_FILE_PAGE);
ut_ad(mutex_own(&block->mutex));
-@@ -1185,8 +1186,11 @@
+@@ -1187,8 +1188,11 @@
return(FALSE);
}
/* There is already a flush batch of the same type running */
return(FALSE);
}
-@@ -1260,12 +1264,18 @@
+@@ -1262,12 +1266,18 @@
ibool is_uncompressed;
ut_ad(flush_type == BUF_FLUSH_LRU || flush_type == BUF_FLUSH_LIST);
ut_ad(buf_flush_ready_for_flush(bpage, flush_type));
buf_page_set_io_fix(bpage, BUF_IO_WRITE);
-@@ -1427,14 +1437,16 @@
+@@ -1429,14 +1439,16 @@
buf_pool = buf_pool_get(space, i);
continue;
}
-@@ -1446,11 +1458,9 @@
+@@ -1448,11 +1460,9 @@
if (flush_type != BUF_FLUSH_LRU
|| i == offset
|| buf_page_is_old(bpage)) {
&& (i == offset || !bpage->buf_fix_count)) {
/* We only try to flush those
neighbors != offset where the buf fix
-@@ -1466,11 +1476,12 @@
+@@ -1468,11 +1478,12 @@
ut_ad(!buf_pool_mutex_own(buf_pool));
count++;
continue;
}
return(count);
-@@ -1503,21 +1514,25 @@
+@@ -1505,21 +1516,25 @@
buf_pool_t* buf_pool = buf_pool_from_bpage(bpage);
#endif /* UNIV_DEBUG */
/* These fields are protected by both the
buffer pool mutex and block mutex. */
-@@ -1533,13 +1548,18 @@
+@@ -1535,13 +1550,18 @@
*count,
n_to_flush);
return(flushed);
}
-@@ -1560,7 +1580,8 @@
+@@ -1562,7 +1582,8 @@
buf_page_t* bpage;
ulint count = 0;
do {
/* Start from the end of the list looking for a
-@@ -1582,7 +1603,8 @@
+@@ -1584,7 +1605,8 @@
should be flushed, we factor in this value. */
buf_lru_flush_page_count += count;
return(count);
}
-@@ -1610,9 +1632,10 @@
+@@ -1612,9 +1634,10 @@
{
ulint len;
buf_page_t* bpage;
/* If we have flushed enough, leave the loop */
do {
-@@ -1631,6 +1654,7 @@
+@@ -1633,6 +1656,7 @@
if (bpage) {
ut_a(bpage->oldest_modification > 0);
}
if (!bpage || bpage->oldest_modification >= lsn_limit) {
-@@ -1672,9 +1696,17 @@
+@@ -1674,9 +1698,17 @@
break;
}
buf_flush_list_mutex_exit(buf_pool);
-@@ -1683,7 +1715,7 @@
+@@ -1685,7 +1717,7 @@
} while (count < min_n && bpage != NULL && len > 0);
return(count);
}
-@@ -1722,13 +1754,15 @@
+@@ -1724,13 +1756,15 @@
|| sync_thread_levels_empty_except_dict());
#endif /* UNIV_SYNC_DEBUG */
break;
case BUF_FLUSH_LIST:
count = buf_flush_flush_list_batch(buf_pool, min_n, lsn_limit);
-@@ -1737,7 +1771,7 @@
+@@ -1739,7 +1773,7 @@
ut_error;
}
buf_flush_buffered_writes();
-@@ -1993,7 +2027,7 @@
+@@ -1995,7 +2029,7 @@
retry:
//buf_pool_mutex_enter(buf_pool);
if (have_LRU_mutex)
n_replaceable = UT_LIST_GET_LEN(buf_pool->free);
-@@ -2010,15 +2044,15 @@
+@@ -2012,15 +2046,15 @@
bpage = UT_LIST_GET_LAST(buf_pool->LRU);
continue;
}
distance++;
-@@ -2027,7 +2061,7 @@
+@@ -2029,7 +2063,7 @@
//buf_pool_mutex_exit(buf_pool);
if (have_LRU_mutex)
if (n_replaceable >= BUF_FLUSH_FREE_BLOCK_MARGIN(buf_pool)) {
-@@ -2226,7 +2260,7 @@
+@@ -2228,7 +2262,7 @@
ut_ad(buf_flush_list_mutex_own(buf_pool));
ut_ad(ut_list_node_313->in_flush_list));
bpage = UT_LIST_GET_FIRST(buf_pool->flush_list);
-@@ -2266,7 +2300,7 @@
+@@ -2268,7 +2302,7 @@
rnode = rbt_next(buf_pool->flush_rbt, rnode);
}
ut_a(!bpage || om >= bpage->oldest_modification);
}
-diff -ruN a/storage/innobase/buf/buf0lru.c b/storage/innobase/buf/buf0lru.c
---- a/storage/innobase/buf/buf0lru.c 2010-12-03 15:22:36.321987250 +0900
-+++ b/storage/innobase/buf/buf0lru.c 2010-12-03 15:48:29.293023197 +0900
+--- a/storage/innobase/buf/buf0lru.c
++++ b/storage/innobase/buf/buf0lru.c
@@ -143,8 +143,9 @@
void
buf_LRU_block_free_hashed_page(
all_freed = TRUE;
-@@ -373,8 +410,16 @@
-
+@@ -375,8 +412,15 @@
all_freed = FALSE;
+ goto next_page;
} else {
-- mutex_t* block_mutex = buf_page_get_mutex(bpage);
+- block_mutex = buf_page_get_mutex(bpage);
- mutex_enter(block_mutex);
-+ mutex_t* block_mutex = buf_page_get_mutex_enter(bpage);
++ block_mutex = buf_page_get_mutex_enter(bpage);
+
+ if (!block_mutex) {
+ /* It may be impossible case...
+ Something wrong, so will be scan_again */
+
+ all_freed = FALSE;
-+
-+ goto next_page_no_mutex;
++ goto next_page;
+ }
if (bpage->buf_fix_count > 0) {
-@@ -433,7 +478,9 @@
- ulint page_no;
- ulint zip_size;
+@@ -409,7 +453,9 @@
+ ulint page_no;
+ ulint zip_size;
-- buf_pool_mutex_exit(buf_pool);
-+ //buf_pool_mutex_exit(buf_pool);
-+ mutex_exit(&buf_pool->LRU_list_mutex);
-+ rw_lock_x_unlock(&buf_pool->page_hash_latch);
+- buf_pool_mutex_exit(buf_pool);
++ //buf_pool_mutex_exit(buf_pool);
++ mutex_exit(&buf_pool->LRU_list_mutex);
++ rw_lock_x_unlock(&buf_pool->page_hash_latch);
+
+ zip_size = buf_page_get_zip_size(bpage);
+ page_no = buf_page_get_page_no(bpage);
+@@ -433,7 +479,7 @@
- zip_size = buf_page_get_zip_size(bpage);
- page_no = buf_page_get_page_no(bpage);
-@@ -458,7 +505,7 @@
- if (buf_LRU_block_remove_hashed_page(bpage, TRUE)
- != BUF_BLOCK_ZIP_FREE) {
- buf_LRU_block_free_hashed_page((buf_block_t*)
-- bpage);
-+ bpage, TRUE);
- } else {
- /* The block_mutex should have been
- released by buf_LRU_block_remove_hashed_page()
-@@ -490,7 +537,9 @@
+ if (buf_LRU_block_remove_hashed_page(bpage, TRUE)
+ != BUF_BLOCK_ZIP_FREE) {
+- buf_LRU_block_free_hashed_page((buf_block_t*) bpage);
++ buf_LRU_block_free_hashed_page((buf_block_t*) bpage, TRUE);
+ mutex_exit(block_mutex);
+ } else {
+ /* The block_mutex should have been released
+@@ -446,7 +492,9 @@
bpage = prev_bpage;
}
if (!all_freed) {
os_thread_sleep(20000);
-@@ -536,7 +585,9 @@
+@@ -493,7 +541,9 @@
buf_page_t* b;
buf_pool_t* buf_pool = buf_pool_from_bpage(bpage);
ut_ad(buf_page_get_state(bpage) == BUF_BLOCK_ZIP_PAGE);
/* Find the first successor of bpage in the LRU list
-@@ -544,17 +595,17 @@
+@@ -501,17 +551,17 @@
b = bpage;
do {
b = UT_LIST_GET_NEXT(LRU, b);
+ UT_LIST_ADD_FIRST(zip_list, buf_pool->zip_clean, bpage);
}
}
-
-@@ -567,18 +618,19 @@
+ #endif /* UNIV_DEBUG || UNIV_BUF_DEBUG */
+@@ -525,18 +575,19 @@
buf_LRU_free_from_unzip_LRU_list(
/*=============================*/
buf_pool_t* buf_pool, /*!< in: buffer pool instance */
/* Theoratically it should be much easier to find a victim
from unzip_LRU as we can choose even a dirty block (as we'll
-@@ -588,7 +640,7 @@
+@@ -546,7 +597,7 @@
if we have done five iterations so far. */
if (UNIV_UNLIKELY(n_iterations >= 5)
return(FALSE);
}
-@@ -596,18 +648,25 @@
+@@ -554,18 +605,25 @@
distance = 100 + (n_iterations
* UT_LIST_GET_LEN(buf_pool->unzip_LRU)) / 5;
UNIV_LIKELY(block != NULL) && UNIV_LIKELY(distance > 0);
block = UT_LIST_GET_PREV(unzip_LRU, block), distance--) {
- enum buf_lru_free_block_status freed;
+ ibool freed;
+ mutex_enter(&block->mutex);
+ if (!block->in_unzip_LRU_list || !block->page.in_LRU_list
+ freed = buf_LRU_free_block(&block->page, FALSE, have_LRU_mutex);
mutex_exit(&block->mutex);
- switch (freed) {
-@@ -641,21 +700,23 @@
+ if (freed) {
+@@ -584,35 +642,46 @@
buf_LRU_free_from_common_LRU_list(
/*==============================*/
buf_pool_t* buf_pool,
for (bpage = UT_LIST_GET_LAST(buf_pool->LRU);
UNIV_LIKELY(bpage != NULL) && UNIV_LIKELY(distance > 0);
bpage = UT_LIST_GET_PREV(LRU, bpage), distance--) {
-@@ -663,14 +724,23 @@
- enum buf_lru_free_block_status freed;
- unsigned accessed;
- mutex_t* block_mutex
-- = buf_page_get_mutex(bpage);
-+ = buf_page_get_mutex_enter(bpage);
+
+ ibool freed;
+ unsigned accessed;
+- mutex_t* block_mutex = buf_page_get_mutex(bpage);
++ mutex_t* block_mutex = buf_page_get_mutex_enter(bpage);
+
+ if (!block_mutex) {
+ goto restart;
+ freed = buf_LRU_free_block(bpage, TRUE, have_LRU_mutex);
mutex_exit(block_mutex);
- switch (freed) {
-@@ -722,16 +792,23 @@
+ if (freed) {
+@@ -649,16 +718,23 @@
n_iterations / 5 of the unzip_LRU list. */
{
ibool freed = FALSE;
- buf_pool_mutex_enter(buf_pool);
+ if (UT_LIST_GET_LEN(buf_pool->unzip_LRU))
+ have_LRU_mutex = TRUE;
-+
+
+- freed = buf_LRU_free_from_unzip_LRU_list(buf_pool, n_iterations);
+ //buf_pool_mutex_enter(buf_pool);
+ if (have_LRU_mutex)
+ mutex_enter(&buf_pool->LRU_list_mutex);
-
-- freed = buf_LRU_free_from_unzip_LRU_list(buf_pool, n_iterations);
++
+ freed = buf_LRU_free_from_unzip_LRU_list(buf_pool, n_iterations, have_LRU_mutex);
if (!freed) {
if (!freed) {
buf_pool->LRU_flush_ended = 0;
} else if (buf_pool->LRU_flush_ended > 0) {
-@@ -739,6 +816,8 @@
+@@ -666,6 +742,8 @@
}
buf_pool_mutex_exit(buf_pool);
return(freed);
}
-@@ -799,7 +878,9 @@
+@@ -726,7 +804,9 @@
buf_pool = buf_pool_from_array(i);
if (!recv_recovery_on
&& UT_LIST_GET_LEN(buf_pool->free)
-@@ -809,7 +890,9 @@
+@@ -736,7 +816,9 @@
ret = TRUE;
}
}
return(ret);
-@@ -827,9 +910,10 @@
+@@ -754,9 +836,10 @@
{
buf_block_t* block;
if (block) {
-@@ -838,7 +922,9 @@
+@@ -765,7 +848,9 @@
ut_ad(!block->page.in_flush_list);
ut_ad(!block->page.in_LRU_list);
ut_a(!buf_page_in_file(&block->page));
mutex_enter(&block->mutex);
-@@ -848,6 +934,8 @@
+@@ -775,6 +860,8 @@
ut_ad(buf_pool_from_block(block) == buf_pool);
mutex_exit(&block->mutex);
}
return(block);
-@@ -870,7 +958,7 @@
+@@ -797,7 +884,7 @@
ibool mon_value_was = FALSE;
ibool started_monitor = FALSE;
loop:
if (!recv_recovery_on && UT_LIST_GET_LEN(buf_pool->free)
+ UT_LIST_GET_LEN(buf_pool->LRU) < buf_pool->curr_size / 20) {
-@@ -938,7 +1026,7 @@
+@@ -865,7 +952,7 @@
/* If there is a block in the free list, take it */
block = buf_LRU_get_free_only(buf_pool);
if (block) {
ut_ad(buf_pool_from_block(block) == buf_pool);
-@@ -1038,7 +1126,8 @@
+@@ -965,7 +1052,8 @@
ulint new_len;
ut_a(buf_pool->LRU_old);
ut_ad(buf_pool->LRU_old_ratio >= BUF_LRU_OLD_RATIO_MIN);
ut_ad(buf_pool->LRU_old_ratio <= BUF_LRU_OLD_RATIO_MAX);
#if BUF_LRU_OLD_RATIO_MIN * BUF_LRU_OLD_MIN_LEN <= BUF_LRU_OLD_RATIO_DIV * (BUF_LRU_OLD_TOLERANCE + 5)
-@@ -1104,7 +1193,8 @@
+@@ -1031,7 +1119,8 @@
{
buf_page_t* bpage;
ut_a(UT_LIST_GET_LEN(buf_pool->LRU) == BUF_LRU_OLD_MIN_LEN);
/* We first initialize all blocks in the LRU list as old and then use
-@@ -1139,13 +1229,14 @@
+@@ -1066,13 +1155,14 @@
ut_ad(buf_pool);
ut_ad(bpage);
ut_ad(buf_page_in_file(bpage));
UT_LIST_REMOVE(unzip_LRU, buf_pool->unzip_LRU, block);
}
-@@ -1163,7 +1254,8 @@
+@@ -1090,7 +1180,8 @@
ut_ad(buf_pool);
ut_ad(bpage);
ut_a(buf_page_in_file(bpage));
-@@ -1240,12 +1332,13 @@
+@@ -1167,12 +1258,13 @@
ut_ad(buf_pool);
ut_ad(block);
if (old) {
UT_LIST_ADD_LAST(unzip_LRU, buf_pool->unzip_LRU, block);
-@@ -1266,7 +1359,8 @@
+@@ -1193,7 +1285,8 @@
ut_ad(buf_pool);
ut_ad(bpage);
ut_a(buf_page_in_file(bpage));
-@@ -1317,7 +1411,8 @@
+@@ -1244,7 +1337,8 @@
ut_ad(buf_pool);
ut_ad(bpage);
ut_a(buf_page_in_file(bpage));
ut_ad(!bpage->in_LRU_list);
-@@ -1396,7 +1491,8 @@
+@@ -1323,7 +1417,8 @@
{
buf_pool_t* buf_pool = buf_pool_from_bpage(bpage);
if (bpage->old) {
buf_pool->stat.n_pages_made_young++;
-@@ -1436,17 +1532,18 @@
+@@ -1362,17 +1457,18 @@
buf_LRU_free_block(
/*===============*/
buf_page_t* bpage, /*!< in: block to be freed */
ut_ad(!bpage->in_flush_list == !bpage->oldest_modification);
#if UNIV_WORD_SIZE == 4
/* On 32-bit systems, there is no padding in buf_page_t. On
-@@ -1455,7 +1552,7 @@
+@@ -1381,7 +1477,7 @@
UNIV_MEM_ASSERT_RW(bpage, sizeof *bpage);
#endif
+ if (!bpage->in_LRU_list || !block_mutex || !buf_page_can_relocate(bpage)) {
/* Do not free buffer-fixed or I/O-fixed blocks. */
- return(BUF_LRU_NOT_FREED);
-@@ -1487,15 +1584,15 @@
- If it cannot be allocated (without freeing a block
- from the LRU list), refuse to free bpage. */
+ return(FALSE);
+@@ -1415,7 +1511,7 @@
alloc:
-- buf_pool_mutex_exit_forbid(buf_pool);
-- b = buf_buddy_alloc(buf_pool, sizeof *b, NULL);
-- buf_pool_mutex_exit_allow(buf_pool);
-+ //buf_pool_mutex_exit_forbid(buf_pool);
-+ b = buf_buddy_alloc(buf_pool, sizeof *b, NULL, FALSE);
-+ //buf_pool_mutex_exit_allow(buf_pool);
-
- if (UNIV_UNLIKELY(!b)) {
- return(BUF_LRU_CANNOT_RELOCATE);
- }
-
+ b = buf_page_alloc_descriptor();
+ ut_a(b);
- memcpy(b, bpage, sizeof *b);
+ //memcpy(b, bpage, sizeof *b);
}
#ifdef UNIV_DEBUG
-@@ -1506,6 +1603,39 @@
+@@ -1426,6 +1522,39 @@
}
#endif /* UNIV_DEBUG */
+ if (!have_LRU_mutex)
+ mutex_exit(&buf_pool->LRU_list_mutex);
+ rw_lock_x_unlock(&buf_pool->page_hash_latch);
-+ return(BUF_LRU_NOT_FREED);
++ return(FALSE);
+ } else if (zip || !bpage->zip.data) {
+ if (bpage->oldest_modification)
+ goto not_freed;
if (buf_LRU_block_remove_hashed_page(bpage, zip)
!= BUF_BLOCK_ZIP_FREE) {
ut_a(bpage->buf_fix_count == 0);
-@@ -1522,6 +1652,10 @@
+@@ -1442,6 +1571,10 @@
ut_a(!hash_b);
b->state = b->oldest_modification
? BUF_BLOCK_ZIP_DIRTY
: BUF_BLOCK_ZIP_PAGE;
-@@ -1597,6 +1731,7 @@
+@@ -1517,6 +1650,7 @@
buf_LRU_add_block_low(b, buf_page_is_old(b));
}
+ mutex_enter(&buf_pool->zip_mutex);
if (b->state == BUF_BLOCK_ZIP_PAGE) {
+ #if defined UNIV_DEBUG || defined UNIV_BUF_DEBUG
buf_LRU_insert_zip_clean(b);
- } else {
-@@ -1612,9 +1747,12 @@
+@@ -1534,9 +1668,12 @@
buf_pool->mutex and block_mutex. */
b->buf_fix_count++;
b->io_fix = BUF_IO_READ;
mutex_exit(block_mutex);
/* Remove possible adaptive hash index on the page.
-@@ -1646,7 +1784,9 @@
+@@ -1568,7 +1705,9 @@
: BUF_NO_CHECKSUM_MAGIC);
}
mutex_enter(block_mutex);
if (b) {
-@@ -1656,13 +1796,17 @@
+@@ -1578,13 +1717,17 @@
mutex_exit(&buf_pool->zip_mutex);
}
+ rw_lock_x_unlock(&buf_pool->page_hash_latch);
}
- return(BUF_LRU_FREED);
-@@ -1674,13 +1818,14 @@
+ return(TRUE);
+@@ -1596,13 +1739,14 @@
void
buf_LRU_block_free_non_file_page(
/*=============================*/
ut_ad(mutex_own(&block->mutex));
switch (buf_block_get_state(block)) {
-@@ -1714,18 +1859,21 @@
+@@ -1636,18 +1780,21 @@
if (data) {
block->page.zip.data = NULL;
mutex_exit(&block->mutex);
UNIV_MEM_ASSERT_AND_FREE(block->frame, UNIV_PAGE_SIZE);
}
-@@ -1755,7 +1903,11 @@
+@@ -1677,7 +1824,11 @@
buf_pool_t* buf_pool = buf_pool_from_bpage(bpage);
ut_ad(bpage);
ut_ad(mutex_own(buf_page_get_mutex(bpage)));
ut_a(buf_page_get_io_fix(bpage) == BUF_IO_NONE);
-@@ -1863,7 +2015,9 @@
+@@ -1785,7 +1936,9 @@
#if defined UNIV_DEBUG || defined UNIV_BUF_DEBUG
mutex_exit(buf_page_get_mutex(bpage));
buf_print();
buf_LRU_print();
buf_validate();
-@@ -1884,18 +2038,18 @@
- ut_a(bpage->zip.data);
+@@ -1807,17 +1960,17 @@
ut_a(buf_page_get_zip_size(bpage));
+ #if defined UNIV_DEBUG || defined UNIV_BUF_DEBUG
- UT_LIST_REMOVE(list, buf_pool->zip_clean, bpage);
+ UT_LIST_REMOVE(zip_list, buf_pool->zip_clean, bpage);
+ #endif /* UNIV_DEBUG || UNIV_BUF_DEBUG */
mutex_exit(&buf_pool->zip_mutex);
- buf_pool_mutex_exit_forbid(buf_pool);
- page_zip_get_size(&bpage->zip));
+ page_zip_get_size(&bpage->zip), TRUE);
- bpage->state = BUF_BLOCK_ZIP_FREE;
-- buf_buddy_free(buf_pool, bpage, sizeof(*bpage));
- buf_pool_mutex_exit_allow(buf_pool);
-+ buf_buddy_free(buf_pool, bpage, sizeof(*bpage), TRUE);
+ //buf_pool_mutex_exit_allow(buf_pool);
-
- UNIV_MEM_UNDESC(bpage);
+ buf_page_free_descriptor(bpage);
return(BUF_BLOCK_ZIP_FREE);
-@@ -1918,13 +2072,13 @@
+
+@@ -1839,13 +1992,13 @@
ut_ad(!bpage->in_flush_list);
ut_ad(!bpage->in_LRU_list);
mutex_exit(&((buf_block_t*) bpage)->mutex);
mutex_enter(&((buf_block_t*) bpage)->mutex);
page_zip_set_size(&bpage->zip, 0);
}
-@@ -1950,18 +2104,19 @@
+@@ -1871,18 +2024,19 @@
void
buf_LRU_block_free_hashed_page(
/*===========================*/
}
/**********************************************************************//**
-@@ -1988,7 +2143,8 @@
+@@ -1909,7 +2063,8 @@
}
if (adjust) {
if (ratio != buf_pool->LRU_old_ratio) {
buf_pool->LRU_old_ratio = ratio;
-@@ -2000,7 +2156,8 @@
+@@ -1921,7 +2076,8 @@
}
}
} else {
buf_pool->LRU_old_ratio = ratio;
}
-@@ -2105,7 +2262,8 @@
+@@ -2026,7 +2182,8 @@
ulint new_len;
ut_ad(buf_pool);
if (UT_LIST_GET_LEN(buf_pool->LRU) >= BUF_LRU_OLD_MIN_LEN) {
-@@ -2166,16 +2324,22 @@
+@@ -2087,16 +2244,22 @@
ut_a(buf_pool->LRU_old_len == old_len);
UT_LIST_VALIDATE(unzip_LRU, buf_block_t, buf_pool->unzip_LRU,
ut_ad(ut_list_node_313->in_unzip_LRU_list
&& ut_list_node_313->page.in_LRU_list));
-@@ -2189,7 +2353,8 @@
+@@ -2110,7 +2273,8 @@
ut_a(buf_page_belongs_to_unzip_LRU(&block->page));
}
}
/**********************************************************************//**
-@@ -2225,7 +2390,8 @@
+@@ -2146,7 +2310,8 @@
const buf_page_t* bpage;
ut_ad(buf_pool);
bpage = UT_LIST_GET_FIRST(buf_pool->LRU);
-@@ -2282,7 +2448,8 @@
+@@ -2203,7 +2368,8 @@
bpage = UT_LIST_GET_NEXT(LRU, bpage);
}
}
/**********************************************************************//**
-diff -ruN a/storage/innobase/buf/buf0rea.c b/storage/innobase/buf/buf0rea.c
---- a/storage/innobase/buf/buf0rea.c 2010-12-03 15:22:36.323977308 +0900
-+++ b/storage/innobase/buf/buf0rea.c 2010-12-03 15:48:29.296024468 +0900
+--- a/storage/innobase/buf/buf0rea.c
++++ b/storage/innobase/buf/buf0rea.c
@@ -311,6 +311,7 @@
return(0);
if ((offset == low) && (succ_offset == offset + 1)) {
-diff -ruN a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc
---- a/storage/innobase/handler/ha_innodb.cc 2010-12-03 15:48:03.048955897 +0900
-+++ b/storage/innobase/handler/ha_innodb.cc 2010-12-03 15:48:29.304024564 +0900
-@@ -264,6 +264,10 @@
+--- a/storage/innobase/handler/ha_innodb.cc
++++ b/storage/innobase/handler/ha_innodb.cc
+@@ -265,6 +265,10 @@
# endif /* !PFS_SKIP_BUFFER_MUTEX_RWLOCK */
{&buf_pool_mutex_key, "buf_pool_mutex", 0},
{&buf_pool_zip_mutex_key, "buf_pool_zip_mutex", 0},
{&cache_last_read_mutex_key, "cache_last_read_mutex", 0},
{&dict_foreign_err_mutex_key, "dict_foreign_err_mutex", 0},
{&dict_sys_mutex_key, "dict_sys_mutex", 0},
-@@ -313,6 +317,7 @@
+@@ -314,6 +318,7 @@
{&archive_lock_key, "archive_lock", 0},
# endif /* UNIV_LOG_ARCHIVE */
{&btr_search_latch_key, "btr_search_latch", 0},
# ifndef PFS_SKIP_BUFFER_MUTEX_RWLOCK
{&buf_block_lock_key, "buf_block_lock", 0},
# endif /* !PFS_SKIP_BUFFER_MUTEX_RWLOCK */
-diff -ruN a/storage/innobase/handler/i_s.cc b/storage/innobase/handler/i_s.cc
---- a/storage/innobase/handler/i_s.cc 2010-12-03 15:37:45.517105700 +0900
-+++ b/storage/innobase/handler/i_s.cc 2010-12-03 15:48:29.331024462 +0900
+--- a/storage/innobase/handler/i_s.cc
++++ b/storage/innobase/handler/i_s.cc
@@ -1563,7 +1563,8 @@
buf_pool = buf_pool_from_array(i);
if (status) {
break;
-diff -ruN a/storage/innobase/ibuf/ibuf0ibuf.c b/storage/innobase/ibuf/ibuf0ibuf.c
---- a/storage/innobase/ibuf/ibuf0ibuf.c 2010-12-03 15:48:03.068954202 +0900
-+++ b/storage/innobase/ibuf/ibuf0ibuf.c 2010-12-03 15:48:29.335988682 +0900
+--- a/storage/innobase/ibuf/ibuf0ibuf.c
++++ b/storage/innobase/ibuf/ibuf0ibuf.c
@@ -3821,9 +3821,11 @@
ulint fold = buf_page_address_fold(space, page_no);
buf_pool_t* buf_pool = buf_pool_get(space, page_no);
if (UNIV_LIKELY_NULL(bpage)) {
/* A buffer pool watch has been set or the
-diff -ruN a/storage/innobase/include/buf0buddy.h b/storage/innobase/include/buf0buddy.h
---- a/storage/innobase/include/buf0buddy.h 2010-11-03 07:01:13.000000000 +0900
-+++ b/storage/innobase/include/buf0buddy.h 2010-12-03 15:48:29.338023826 +0900
-@@ -51,10 +51,11 @@
- buf_pool_t* buf_pool,
- /*!< buffer pool in which the block resides */
- 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
- and buf_pool->mutex was temporarily released,
- or NULL if the LRU list should not be used */
-+ ibool have_page_hash_mutex)
- __attribute__((malloc));
+--- a/storage/innobase/include/buf0buddy.h
++++ b/storage/innobase/include/buf0buddy.h
+@@ -49,11 +49,12 @@
+ ulint size, /*!< in: compressed page size
+ (between PAGE_ZIP_MIN_SIZE and
+ UNIV_PAGE_SIZE) */
+- ibool* lru) /*!< in: pointer to a variable
++ ibool* lru, /*!< in: pointer to a variable
+ that will be assigned TRUE if
+ storage was allocated from the
+ LRU list and buf_pool->mutex was
+ temporarily released */
++ ibool have_page_hash_mutex)
+ __attribute__((malloc, nonnull));
/**********************************************************************//**
-@@ -67,7 +68,8 @@
- /*!< buffer pool in which the block resides */
- void* buf, /*!< in: block to be freed, must not be
- 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)
+@@ -66,8 +67,9 @@
+ the block resides */
+ void* buf, /*!< in: block to be freed, must not
+ be pointed to by the buffer pool */
+- ulint size) /*!< in: block size,
++ ulint size, /*!< in: block size,
+ up to UNIV_PAGE_SIZE */
++ ibool have_page_hash_mutex)
__attribute__((nonnull));
#ifndef UNIV_NONINL
-diff -ruN a/storage/innobase/include/buf0buddy.ic b/storage/innobase/include/buf0buddy.ic
---- a/storage/innobase/include/buf0buddy.ic 2010-11-03 07:01:13.000000000 +0900
-+++ b/storage/innobase/include/buf0buddy.ic 2010-12-03 15:48:29.339040413 +0900
-@@ -46,10 +46,11 @@
- /*!< in: buffer pool in which the page resides */
- ulint i, /*!< in: index of buf_pool->zip_free[],
- 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
- and buf_pool->mutex was temporarily released,
- or NULL if the LRU list should not be used */
-+ ibool have_page_hash_mutex)
- __attribute__((malloc));
+--- a/storage/innobase/include/buf0buddy.ic
++++ b/storage/innobase/include/buf0buddy.ic
+@@ -45,11 +45,12 @@
+ buf_pool_t* buf_pool, /*!< in/out: buffer pool instance */
+ ulint i, /*!< in: index of buf_pool->zip_free[],
+ or BUF_BUDDY_SIZES */
+- ibool* lru) /*!< in: pointer to a variable that
++ ibool* lru, /*!< in: pointer to a variable that
+ will be assigned TRUE if storage was
+ allocated from the LRU list and
+ buf_pool->mutex was temporarily
+ released */
++ ibool have_page_hash_mutex)
+ __attribute__((malloc, nonnull));
/**********************************************************************//**
@@ -61,8 +62,9 @@
__attribute__((nonnull));
/**********************************************************************//**
-@@ -102,16 +104,17 @@
- the page resides */
- ulint size, /*!< in: block size, up to
- UNIV_PAGE_SIZE */
+@@ -101,19 +103,20 @@
+ ulint size, /*!< in: compressed page size
+ (between PAGE_ZIP_MIN_SIZE and
+ UNIV_PAGE_SIZE) */
- ibool* lru) /*!< in: pointer to a variable
+ ibool* lru, /*!< in: pointer to a variable
that will be assigned TRUE if
storage was allocated from the
LRU list and buf_pool->mutex was
- temporarily released, or NULL if
- the LRU list should not be used */
+ temporarily released */
+ ibool have_page_hash_mutex)
{
- ut_ad(buf_pool_mutex_own(buf_pool));
+ //ut_ad(buf_pool_mutex_own(buf_pool));
+ ut_ad(ut_is_2pow(size));
+ ut_ad(size >= PAGE_ZIP_MIN_SIZE);
+ ut_ad(size <= UNIV_PAGE_SIZE);
-- return(buf_buddy_alloc_low(buf_pool, buf_buddy_get_slot(size), lru));
-+ return(buf_buddy_alloc_low(buf_pool, buf_buddy_get_slot(size), lru, have_page_hash_mutex));
+ return((byte*) buf_buddy_alloc_low(buf_pool, buf_buddy_get_slot(size),
+- lru));
++ lru, have_page_hash_mutex));
}
/**********************************************************************//**
-@@ -123,12 +126,25 @@
- buf_pool_t* buf_pool, /*!< in: buffer pool instance */
- void* buf, /*!< in: block to be freed, must not be
- pointed to by the buffer pool */
-- ulint size) /*!< in: block size, up to
-+ ulint size, /*!< in: block size, up to
- UNIV_PAGE_SIZE */
+@@ -126,15 +129,28 @@
+ the block resides */
+ void* buf, /*!< in: block to be freed, must not
+ be pointed to by the buffer pool */
+- ulint size) /*!< in: block size,
++ ulint size, /*!< in: block size,
+ up to UNIV_PAGE_SIZE */
+ ibool have_page_hash_mutex)
{
- ut_ad(buf_pool_mutex_own(buf_pool));
+ //ut_ad(buf_pool_mutex_own(buf_pool));
-+
+ ut_ad(ut_is_2pow(size));
+ ut_ad(size >= PAGE_ZIP_MIN_SIZE);
+ ut_ad(size <= UNIV_PAGE_SIZE);
+
+- buf_buddy_free_low(buf_pool, buf, buf_buddy_get_slot(size));
+ if (!have_page_hash_mutex) {
+ mutex_enter(&buf_pool->LRU_list_mutex);
+ rw_lock_x_lock(&buf_pool->page_hash_latch);
+ }
-
-- buf_buddy_free_low(buf_pool, buf, buf_buddy_get_slot(size));
++
+ mutex_enter(&buf_pool->zip_free_mutex);
+ buf_buddy_free_low(buf_pool, buf, buf_buddy_get_slot(size), TRUE);
+ mutex_exit(&buf_pool->zip_free_mutex);
}
#ifdef UNIV_MATERIALIZE
-diff -ruN a/storage/innobase/include/buf0buf.h b/storage/innobase/include/buf0buf.h
---- a/storage/innobase/include/buf0buf.h 2010-12-03 15:22:36.327954660 +0900
-+++ b/storage/innobase/include/buf0buf.h 2010-12-03 15:48:29.343024683 +0900
-@@ -205,6 +205,20 @@
+--- a/storage/innobase/include/buf0buf.h
++++ b/storage/innobase/include/buf0buf.h
+@@ -208,6 +208,20 @@
/*==========================*/
/********************************************************************//**
Creates the buffer pool.
@return own: buf_pool object, NULL if not enough memory or error */
UNIV_INTERN
-@@ -834,6 +848,15 @@
+@@ -873,6 +887,15 @@
const buf_page_t* bpage) /*!< in: pointer to control block */
__attribute__((pure));
/*********************************************************************//**
Get the flush type of a page.
@return flush type */
-@@ -1315,7 +1338,7 @@
+@@ -1354,7 +1377,7 @@
All these are protected by buf_pool->mutex. */
/* @{ */
/*!< based on state, this is a
list node, protected either by
buf_pool->mutex or by
-@@ -1343,6 +1366,10 @@
+@@ -1382,6 +1405,10 @@
BUF_BLOCK_REMOVE_HASH or
BUF_BLOCK_READY_IN_USE. */
#ifdef UNIV_DEBUG
ibool in_flush_list; /*!< TRUE if in buf_pool->flush_list;
when buf_pool->flush_list_mutex is
-@@ -1435,11 +1462,11 @@
+@@ -1474,11 +1501,11 @@
a block is in the unzip_LRU list
if page.state == BUF_BLOCK_FILE_PAGE
and page.zip.data != NULL */
mutex_t mutex; /*!< mutex protecting this block:
state (also protected by the buffer
pool mutex), io_fix, buf_fix_count,
-@@ -1614,6 +1641,11 @@
+@@ -1653,6 +1680,11 @@
pool instance, protects compressed
only pages (of type buf_page_t, not
buf_block_t */
ulint instance_no; /*!< Array index of this buffer
pool instance */
ulint old_pool_size; /*!< Old pool size in bytes */
-@@ -1765,8 +1797,8 @@
+@@ -1806,8 +1838,8 @@
/** Test if a buffer pool mutex is owned. */
#define buf_pool_mutex_own(b) mutex_own(&b->mutex)
/** Acquire a buffer pool mutex. */
mutex_enter(&b->mutex); \
} while (0)
-diff -ruN a/storage/innobase/include/buf0buf.ic b/storage/innobase/include/buf0buf.ic
---- a/storage/innobase/include/buf0buf.ic 2010-11-03 07:01:13.000000000 +0900
-+++ b/storage/innobase/include/buf0buf.ic 2010-12-03 15:48:29.345024524 +0900
+--- a/storage/innobase/include/buf0buf.ic
++++ b/storage/innobase/include/buf0buf.ic
@@ -274,7 +274,7 @@
case BUF_BLOCK_ZIP_FREE:
/* This is a free page in buf_pool->zip_free[].
ut_a(buf_page_in_file(bpage));
if (!bpage->access_time) {
-@@ -761,19 +792,19 @@
+@@ -790,19 +821,19 @@
/*===========*/
buf_block_t* block) /*!< in, own: block to be freed */
{
}
#endif /* !UNIV_HOTBACKUP */
-@@ -821,17 +852,17 @@
+@@ -850,17 +881,17 @@
page frame */
{
ib_uint64_t lsn;
return(lsn);
}
-@@ -849,7 +880,7 @@
+@@ -878,7 +909,7 @@
#ifdef UNIV_SYNC_DEBUG
buf_pool_t* buf_pool = buf_pool_from_bpage((buf_page_t*)block);
&& (block->page.buf_fix_count == 0))
|| rw_lock_own(&(block->lock), RW_LOCK_EXCLUSIVE));
#endif /* UNIV_SYNC_DEBUG */
-@@ -979,7 +1010,11 @@
+@@ -995,7 +1026,11 @@
buf_page_t* bpage;
ut_ad(buf_pool);
ut_ad(fold == buf_page_address_fold(space, offset));
/* Look for the page in the hash table */
-@@ -1064,11 +1099,13 @@
+@@ -1080,11 +1115,13 @@
const buf_page_t* bpage;
buf_pool_t* buf_pool = buf_pool_get(space, offset);
return(bpage != NULL);
}
-@@ -1196,4 +1233,38 @@
+@@ -1212,4 +1249,38 @@
buf_pool_mutex_exit(buf_pool);
}
}
+ }
+}
#endif /* !UNIV_HOTBACKUP */
-diff -ruN a/storage/innobase/include/buf0lru.h b/storage/innobase/include/buf0lru.h
---- a/storage/innobase/include/buf0lru.h 2010-11-03 07:01:13.000000000 +0900
-+++ b/storage/innobase/include/buf0lru.h 2010-12-03 15:48:29.349024701 +0900
-@@ -111,8 +111,9 @@
+--- a/storage/innobase/include/buf0lru.h
++++ b/storage/innobase/include/buf0lru.h
+@@ -100,8 +100,9 @@
buf_LRU_free_block(
/*===============*/
buf_page_t* bpage, /*!< in: block to be freed */
__attribute__((nonnull));
/******************************************************************//**
Try to free a replaceable block.
-@@ -159,7 +160,8 @@
+@@ -148,7 +149,8 @@
void
buf_LRU_block_free_non_file_page(
/*=============================*/
/******************************************************************//**
Adds a block to the LRU list. */
UNIV_INTERN
-diff -ruN a/storage/innobase/include/sync0rw.h b/storage/innobase/include/sync0rw.h
---- a/storage/innobase/include/sync0rw.h 2010-11-03 07:01:13.000000000 +0900
-+++ b/storage/innobase/include/sync0rw.h 2010-12-03 15:48:29.349942993 +0900
+--- a/storage/innobase/include/sync0rw.h
++++ b/storage/innobase/include/sync0rw.h
@@ -112,6 +112,7 @@
extern mysql_pfs_key_t archive_lock_key;
# endif /* UNIV_LOG_ARCHIVE */
extern mysql_pfs_key_t buf_block_lock_key;
# ifdef UNIV_SYNC_DEBUG
extern mysql_pfs_key_t buf_block_debug_latch_key;
-diff -ruN a/storage/innobase/include/sync0sync.h b/storage/innobase/include/sync0sync.h
---- a/storage/innobase/include/sync0sync.h 2010-11-03 07:01:13.000000000 +0900
-+++ b/storage/innobase/include/sync0sync.h 2010-12-03 15:48:29.352024614 +0900
+--- a/storage/innobase/include/sync0sync.h
++++ b/storage/innobase/include/sync0sync.h
@@ -75,6 +75,10 @@
extern mysql_pfs_key_t buffer_block_mutex_key;
extern mysql_pfs_key_t buf_pool_mutex_key;
extern mysql_pfs_key_t cache_last_read_mutex_key;
extern mysql_pfs_key_t dict_foreign_err_mutex_key;
extern mysql_pfs_key_t dict_sys_mutex_key;
-@@ -668,7 +672,7 @@
+@@ -670,7 +674,7 @@
#define SYNC_TRX_SYS_HEADER 290
#define SYNC_PURGE_QUEUE 200
#define SYNC_LOG 170
#define SYNC_RECV 168
#define SYNC_WORK_QUEUE 162
#define SYNC_SEARCH_SYS_CONF 161 /* for assigning btr_search_enabled */
-@@ -678,8 +682,13 @@
+@@ -680,8 +684,13 @@
SYNC_SEARCH_SYS, as memory allocation
can call routines there! Otherwise
the level is SYNC_MEM_HASH. */
#define SYNC_BUF_FLUSH_LIST 145 /* Buffer flush list mutex */
#define SYNC_DOUBLEWRITE 140
#define SYNC_ANY_LATCH 135
-@@ -711,7 +720,7 @@
+@@ -713,7 +722,7 @@
os_fast_mutex; /*!< We use this OS mutex in place of lock_word
when atomic operations are not enabled */
#endif
may be) threads waiting in the global wait
array for this mutex to be released.
Otherwise, this is 0. */
-diff -ruN a/storage/innobase/srv/srv0srv.c b/storage/innobase/srv/srv0srv.c
---- a/storage/innobase/srv/srv0srv.c 2010-12-03 15:48:03.080956216 +0900
-+++ b/storage/innobase/srv/srv0srv.c 2010-12-03 15:48:29.355023766 +0900
+--- a/storage/innobase/srv/srv0srv.c
++++ b/storage/innobase/srv/srv0srv.c
@@ -3098,7 +3098,7 @@
level += log_sys->max_checkpoint_age
- (lsn - oldest_modification);
new_blocks_num++;
}
if (!found) {
-diff -ruN a/storage/innobase/sync/sync0sync.c b/storage/innobase/sync/sync0sync.c
---- a/storage/innobase/sync/sync0sync.c 2010-11-03 07:01:13.000000000 +0900
-+++ b/storage/innobase/sync/sync0sync.c 2010-12-03 15:48:29.358023890 +0900
+--- a/storage/innobase/sync/sync0sync.c
++++ b/storage/innobase/sync/sync0sync.c
@@ -285,7 +285,7 @@
mutex->lock_word = 0;
#endif
}
/******************************************************************//**
-@@ -1234,7 +1244,12 @@
+@@ -1239,7 +1249,12 @@
ut_error;
}
break;
case SYNC_BUF_POOL:
/* We can have multiple mutexes of this type therefore we
can only check whether the greater than condition holds. */
-@@ -1252,7 +1267,8 @@
+@@ -1257,7 +1272,8 @@
buffer block (block->mutex or buf_pool->zip_mutex). */
if (!sync_thread_levels_g(array, level, FALSE)) {
ut_a(sync_thread_levels_g(array, level - 1, TRUE));
#!!! notice !!!
# Any small change to this file in the main branch
# should be done or reviewed by the maintainer!
-diff -ruN a/storage/innobase/dict/dict0boot.c b/storage/innobase/dict/dict0boot.c
---- a/storage/innobase/dict/dict0boot.c 2010-12-03 15:48:03.034036843 +0900
-+++ b/storage/innobase/dict/dict0boot.c 2010-12-03 17:19:24.835112632 +0900
+--- a/storage/innobase/dict/dict0boot.c
++++ b/storage/innobase/dict/dict0boot.c
@@ -266,6 +266,29 @@
/* Get the dictionary header */
dict_hdr = dict_hdr_get(&mtr);
mutex_exit(&(dict_sys->mutex));
}
-diff -ruN a/storage/innobase/dict/dict0crea.c b/storage/innobase/dict/dict0crea.c
---- a/storage/innobase/dict/dict0crea.c 2010-12-03 15:48:03.036081059 +0900
-+++ b/storage/innobase/dict/dict0crea.c 2010-12-03 17:19:24.836964976 +0900
+--- a/storage/innobase/dict/dict0crea.c
++++ b/storage/innobase/dict/dict0crea.c
@@ -508,6 +508,56 @@
}
Creates an index tree for the index if it is not a member of a cluster.
@return DB_SUCCESS or DB_OUT_OF_FILE_SPACE */
static
-@@ -937,6 +1008,49 @@
+@@ -936,6 +1007,49 @@
dict_sys->sys_fields, heap);
node->field_def->common.parent = node;
node->commit_node = commit_node_create(heap);
node->commit_node->common.parent = node;
-@@ -1087,6 +1201,7 @@
+@@ -1086,6 +1200,7 @@
node->state = INDEX_BUILD_FIELD_DEF;
node->field_no = 0;
thr->run_node = node->ind_def;
-@@ -1132,7 +1247,31 @@
+@@ -1131,7 +1246,31 @@
goto function_exit;
}
}
if (node->state == INDEX_CREATE_INDEX_TREE) {
-@@ -1178,6 +1317,66 @@
- return(NULL);
- }
+@@ -1183,6 +1322,66 @@
+ }
-+ thr->run_node = que_node_get_parent(node);
-+
-+ return(thr);
-+}
-+
-+/****************************************************************//**
+ /****************************************************************//**
+*/
+UNIV_INTERN
+que_thr_t*
+ return(NULL);
+ }
+
- thr->run_node = que_node_get_parent(node);
-
- return(thr);
-diff -ruN a/storage/innobase/dict/dict0dict.c b/storage/innobase/dict/dict0dict.c
---- a/storage/innobase/dict/dict0dict.c 2010-12-03 15:48:03.040222428 +0900
-+++ b/storage/innobase/dict/dict0dict.c 2010-12-03 17:19:24.841947690 +0900
++ thr->run_node = que_node_get_parent(node);
++
++ return(thr);
++}
++
++/****************************************************************//**
+ Creates the foreign key constraints system tables inside InnoDB
+ at database creation or database start if they are not found or are
+ not of the right form.
+--- a/storage/innobase/dict/dict0dict.c
++++ b/storage/innobase/dict/dict0dict.c
@@ -755,7 +755,7 @@
print an error message and return without doing
anything. */
}
return(table);
-@@ -4309,6 +4309,295 @@
+@@ -4343,6 +4343,295 @@
}
/*********************************************************************//**
Calculates new estimates for table and index statistics. The statistics
are used in query optimization. */
UNIV_INTERN
-@@ -4316,10 +4605,11 @@
+@@ -4350,10 +4639,11 @@
dict_update_statistics(
/*===================*/
dict_table_t* table, /*!< in/out: table */
{
dict_index_t* index;
ulint sum_of_index_sizes = 0;
-@@ -4336,6 +4626,27 @@
+@@ -4370,6 +4660,27 @@
return;
}
/* Find out the sizes of the indexes and how many different values
for the key they approximately have */
-@@ -4400,6 +4711,11 @@
+@@ -4434,6 +4745,11 @@
index = dict_table_get_next_index(index);
} while (index);
index = dict_table_get_first_index(table);
table->stat_n_rows = index->stat_n_diff_key_vals[
-@@ -4417,6 +4733,78 @@
+@@ -4451,6 +4767,78 @@
dict_table_stats_unlock(table, RW_X_LATCH);
}
/**********************************************************************//**
Prints info of a foreign key constraint. */
static
-@@ -4494,7 +4882,8 @@
+@@ -4528,7 +4916,8 @@
ut_ad(mutex_own(&(dict_sys->mutex)));
dict_table_stats_lock(table, RW_S_LATCH);
-diff -ruN a/storage/innobase/dict/dict0load.c b/storage/innobase/dict/dict0load.c
---- a/storage/innobase/dict/dict0load.c 2010-11-03 07:01:13.000000000 +0900
-+++ b/storage/innobase/dict/dict0load.c 2010-12-03 17:19:24.845947460 +0900
+--- a/storage/innobase/dict/dict0load.c
++++ b/storage/innobase/dict/dict0load.c
@@ -50,7 +50,8 @@
"SYS_COLUMNS",
"SYS_FIELDS",
Determine the flags of a table described in SYS_TABLES.
@return compressed page size in kilobytes; or 0 if the tablespace is
uncompressed, ULINT_UNDEFINED on error */
-diff -ruN a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc
---- a/storage/innobase/handler/ha_innodb.cc 2010-12-03 17:17:03.665960357 +0900
-+++ b/storage/innobase/handler/ha_innodb.cc 2010-12-03 17:22:21.586939783 +0900
-@@ -187,6 +187,7 @@
- static my_bool innobase_rollback_on_timeout = FALSE;
+--- a/storage/innobase/handler/ha_innodb.cc
++++ b/storage/innobase/handler/ha_innodb.cc
+@@ -188,6 +188,7 @@
static my_bool innobase_create_status_file = FALSE;
static my_bool innobase_stats_on_metadata = TRUE;
+ static my_bool innobase_large_prefix = FALSE;
+static my_bool innobase_use_sys_stats_table = FALSE;
static char* internal_innobase_data_file_path = NULL;
-@@ -2434,6 +2435,8 @@
+@@ -2439,6 +2440,8 @@
goto error;
}
/* -------------- Log files ---------------------------*/
/* The default dir for log files is the datadir of MySQL */
-@@ -5236,6 +5239,10 @@
+@@ -5247,6 +5250,10 @@
error = row_insert_for_mysql((byte*) record, prebuilt);
/* Handle duplicate key errors */
if (auto_inc_used) {
ulint err;
-@@ -5572,6 +5579,10 @@
+@@ -5583,6 +5590,10 @@
}
}
innodb_srv_conc_exit_innodb(trx);
error = convert_error_code_to_mysql(error,
-@@ -5625,6 +5636,10 @@
+@@ -5636,6 +5647,10 @@
error = row_update_for_mysql((byte*) record, prebuilt);
innodb_srv_conc_exit_innodb(trx);
error = convert_error_code_to_mysql(
-@@ -5943,6 +5958,11 @@
+@@ -5954,6 +5969,11 @@
case DB_SUCCESS:
error = 0;
table->status = 0;
+#ifdef EXTENDED_FOR_USERSTAT
+ rows_read++;
-+ if (active_index >= 0 && active_index < MAX_KEY)
++ if (active_index < MAX_KEY)
+ index_rows_read[active_index]++;
+#endif
break;
case DB_RECORD_NOT_FOUND:
error = HA_ERR_KEY_NOT_FOUND;
-@@ -6152,6 +6172,11 @@
+@@ -6163,6 +6183,11 @@
case DB_SUCCESS:
error = 0;
table->status = 0;
+#ifdef EXTENDED_FOR_USERSTAT
+ rows_read++;
-+ if (active_index >= 0 && active_index < MAX_KEY)
++ if (active_index < MAX_KEY)
+ index_rows_read[active_index]++;
+#endif
break;
case DB_RECORD_NOT_FOUND:
error = HA_ERR_END_OF_FILE;
-@@ -8094,11 +8119,35 @@
+@@ -8105,11 +8130,35 @@
/* In sql_show we call with this flag: update
then statistics so that they are up-to-date */
prebuilt->trx->op_info = "returning various info to MySQL";
}
-@@ -8176,7 +8225,7 @@
+@@ -8187,7 +8236,7 @@
are asked by MySQL to avoid locking. Another reason to
avoid the call is that it uses quite a lot of CPU.
See Bug#38185. */
|| !(flag & HA_STATUS_VARIABLE_EXTRA)) {
/* We do not update delete_length if no
locking is requested so the "old" value can
-@@ -11385,6 +11434,26 @@
+@@ -11401,6 +11450,26 @@
"The number of index pages to sample when calculating statistics (default 8)",
NULL, NULL, 8, 1, ~0ULL, 0);
static MYSQL_SYSVAR_BOOL(adaptive_hash_index, btr_search_enabled,
PLUGIN_VAR_OPCMDARG,
"Enable InnoDB adaptive hash index (enabled by default). "
-@@ -11710,6 +11779,9 @@
+@@ -11727,6 +11796,9 @@
MYSQL_SYSVAR(recovery_update_relay_log),
MYSQL_SYSVAR(rollback_on_timeout),
MYSQL_SYSVAR(stats_on_metadata),
MYSQL_SYSVAR(stats_sample_pages),
MYSQL_SYSVAR(adaptive_hash_index),
MYSQL_SYSVAR(stats_method),
-@@ -11779,7 +11851,10 @@
+@@ -11796,7 +11868,10 @@
i_s_innodb_sys_columns,
i_s_innodb_sys_fields,
i_s_innodb_sys_foreign,
mysql_declare_plugin_end;
/** @brief Initialize the default value of innodb_commit_concurrency.
-diff -ruN a/storage/innobase/handler/i_s.cc b/storage/innobase/handler/i_s.cc
---- a/storage/innobase/handler/i_s.cc 2010-12-03 17:17:03.666956117 +0900
-+++ b/storage/innobase/handler/i_s.cc 2010-12-03 17:19:24.880964526 +0900
+--- a/storage/innobase/handler/i_s.cc
++++ b/storage/innobase/handler/i_s.cc
@@ -49,6 +49,7 @@
#include "trx0trx.h" /* for TRX_QUE_STATE_STR_MAX_LEN */
#include "trx0rseg.h" /* for trx_rseg_struct */
+ STRUCT_FLD(system_vars, NULL),
+ STRUCT_FLD(__reserved1, NULL)
+};
-diff -ruN a/storage/innobase/handler/i_s.h b/storage/innobase/handler/i_s.h
---- a/storage/innobase/handler/i_s.h 2010-12-03 17:17:03.668953884 +0900
-+++ b/storage/innobase/handler/i_s.h 2010-12-03 17:19:24.882947826 +0900
+--- a/storage/innobase/handler/i_s.h
++++ b/storage/innobase/handler/i_s.h
@@ -43,5 +43,8 @@
extern struct st_mysql_plugin i_s_innodb_sys_foreign;
extern struct st_mysql_plugin i_s_innodb_sys_foreign_cols;
+extern struct st_mysql_plugin i_s_innodb_index_stats;
#endif /* i_s_h */
-diff -ruN a/storage/innobase/include/dict0boot.h b/storage/innobase/include/dict0boot.h
---- a/storage/innobase/include/dict0boot.h 2010-11-03 07:01:13.000000000 +0900
-+++ b/storage/innobase/include/dict0boot.h 2010-12-03 17:19:24.885947372 +0900
+--- a/storage/innobase/include/dict0boot.h
++++ b/storage/innobase/include/dict0boot.h
@@ -104,6 +104,7 @@
#define DICT_COLUMNS_ID 2
#define DICT_INDEXES_ID 3
#ifndef UNIV_NONINL
#include "dict0boot.ic"
#endif
-diff -ruN a/storage/innobase/include/dict0crea.h b/storage/innobase/include/dict0crea.h
---- a/storage/innobase/include/dict0crea.h 2010-11-03 07:01:13.000000000 +0900
-+++ b/storage/innobase/include/dict0crea.h 2010-12-03 17:19:24.886949643 +0900
+--- a/storage/innobase/include/dict0crea.h
++++ b/storage/innobase/include/dict0crea.h
@@ -53,6 +53,14 @@
dict_index_t* index, /*!< in: index to create, built as a memory data
structure */
#ifndef UNIV_NONINL
#include "dict0crea.ic"
-diff -ruN a/storage/innobase/include/dict0dict.h b/storage/innobase/include/dict0dict.h
---- a/storage/innobase/include/dict0dict.h 2010-12-03 15:48:03.073024387 +0900
-+++ b/storage/innobase/include/dict0dict.h 2010-12-03 17:19:24.888965622 +0900
-@@ -1096,10 +1096,18 @@
+--- a/storage/innobase/include/dict0dict.h
++++ b/storage/innobase/include/dict0dict.h
+@@ -1109,10 +1109,18 @@
dict_update_statistics(
/*===================*/
dict_table_t* table, /*!< in/out: table */
/********************************************************************//**
Reserves the dictionary system mutex for MySQL. */
UNIV_INTERN
-@@ -1214,6 +1222,7 @@
+@@ -1227,6 +1235,7 @@
dict_table_t* sys_columns; /*!< SYS_COLUMNS table */
dict_table_t* sys_indexes; /*!< SYS_INDEXES table */
dict_table_t* sys_fields; /*!< SYS_FIELDS table */
};
#endif /* !UNIV_HOTBACKUP */
-diff -ruN a/storage/innobase/include/dict0load.h b/storage/innobase/include/dict0load.h
---- a/storage/innobase/include/dict0load.h 2010-11-03 07:01:13.000000000 +0900
-+++ b/storage/innobase/include/dict0load.h 2010-12-03 17:19:24.889947481 +0900
+--- a/storage/innobase/include/dict0load.h
++++ b/storage/innobase/include/dict0load.h
@@ -41,6 +41,7 @@
SYS_FIELDS,
SYS_FOREIGN,
/* This must be last item. Defines the number of system tables. */
SYS_NUM_SYSTEM_TABLES
-@@ -322,6 +323,20 @@
+@@ -327,6 +328,20 @@
const char** ref_col_name, /*!< out: referenced column name
in referenced table */
ulint* pos); /*!< out: column position */
#ifndef UNIV_NONINL
#include "dict0load.ic"
#endif
-diff -ruN a/storage/innobase/include/que0que.h b/storage/innobase/include/que0que.h
---- a/storage/innobase/include/que0que.h 2010-11-03 07:01:13.000000000 +0900
-+++ b/storage/innobase/include/que0que.h 2010-12-03 17:19:24.892947946 +0900
+--- a/storage/innobase/include/que0que.h
++++ b/storage/innobase/include/que0que.h
@@ -492,6 +492,8 @@
#define QUE_NODE_CALL 31
#define QUE_NODE_EXIT 32
/* Query thread states */
#define QUE_THR_RUNNING 1
#define QUE_THR_PROCEDURE_WAIT 2
-diff -ruN a/storage/innobase/include/row0mysql.h b/storage/innobase/include/row0mysql.h
---- a/storage/innobase/include/row0mysql.h 2010-11-03 07:01:13.000000000 +0900
-+++ b/storage/innobase/include/row0mysql.h 2010-12-03 17:19:24.904973020 +0900
+--- a/storage/innobase/include/row0mysql.h
++++ b/storage/innobase/include/row0mysql.h
@@ -387,6 +387,22 @@
then checked for not being too
large. */
Scans a table create SQL string and adds to the data dictionary
the foreign key constraints declared in the string. This function
should be called after the indexes for a table have been created.
-diff -ruN a/storage/innobase/include/srv0srv.h b/storage/innobase/include/srv0srv.h
---- a/storage/innobase/include/srv0srv.h 2010-12-03 15:53:54.622036720 +0900
-+++ b/storage/innobase/include/srv0srv.h 2010-12-03 17:19:24.906953188 +0900
+--- a/storage/innobase/include/srv0srv.h
++++ b/storage/innobase/include/srv0srv.h
@@ -211,6 +211,9 @@
extern ibool srv_innodb_status;
extern ibool srv_use_doublewrite_buf;
extern ibool srv_use_checksums;
-diff -ruN a/storage/innobase/que/que0que.c b/storage/innobase/que/que0que.c
---- a/storage/innobase/que/que0que.c 2010-11-03 07:01:13.000000000 +0900
-+++ b/storage/innobase/que/que0que.c 2010-12-03 17:19:24.910953422 +0900
+--- a/storage/innobase/que/que0que.c
++++ b/storage/innobase/que/que0que.c
@@ -621,11 +621,21 @@
que_graph_free_recursive(cre_ind->ind_def);
} else if (type == QUE_NODE_ROW_PRINTF) {
thr = row_printf_step(thr);
} else {
-diff -ruN a/storage/innobase/row/row0ins.c b/storage/innobase/row/row0ins.c
---- a/storage/innobase/row/row0ins.c 2011-03-10 00:11:38.000000000 +0900
-+++ b/storage/innobase/row/row0ins.c 2011-03-30 11:44:58.000000000 +0900
-@@ -2012,6 +2012,8 @@
+--- a/storage/innobase/row/row0ins.c
++++ b/storage/innobase/row/row0ins.c
+@@ -2013,6 +2013,8 @@
}
#ifdef UNIV_DEBUG
{
page_t* page = btr_cur_get_page(&cursor);
rec_t* first_rec = page_rec_get_next(
-diff -ruN a/storage/innobase/row/row0merge.c b/storage/innobase/row/row0merge.c
---- a/storage/innobase/row/row0merge.c 2010-11-03 07:01:13.000000000 +0900
-+++ b/storage/innobase/row/row0merge.c 2010-12-03 17:19:24.914955391 +0900
+--- a/storage/innobase/row/row0merge.c
++++ b/storage/innobase/row/row0merge.c
@@ -2019,6 +2019,8 @@
"UPDATE SYS_INDEXES SET NAME=CONCAT('"
TEMP_INDEX_PREFIX_STR "', NAME) WHERE ID = :indexid;\n"
/* Drop the field definitions of the index. */
"DELETE FROM SYS_FIELDS WHERE INDEX_ID = :indexid;\n"
/* Drop the index definition and the B-tree. */
-diff -ruN a/storage/innobase/row/row0mysql.c b/storage/innobase/row/row0mysql.c
---- a/storage/innobase/row/row0mysql.c 2010-11-03 07:01:13.000000000 +0900
-+++ b/storage/innobase/row/row0mysql.c 2010-12-03 17:19:24.918953476 +0900
+--- a/storage/innobase/row/row0mysql.c
++++ b/storage/innobase/row/row0mysql.c
@@ -921,6 +921,9 @@
table->stat_modified_counter = counter + 1;
}
}
-@@ -2098,6 +2101,71 @@
+@@ -2076,6 +2079,71 @@
}
/*********************************************************************//**
Scans a table create SQL string and adds to the data dictionary
the foreign key constraints declared in the string. This function
should be called after the indexes for a table have been created.
-@@ -3022,7 +3090,7 @@
+@@ -3000,7 +3068,7 @@
dict_table_autoinc_initialize(table, 1);
dict_table_autoinc_unlock(table);
dict_update_statistics(table, FALSE /* update even if stats are
trx_commit_for_mysql(trx);
-@@ -3324,6 +3392,8 @@
+@@ -3302,6 +3370,8 @@
" IF (SQL % NOTFOUND) THEN\n"
" found := 0;\n"
" ELSE\n"
" DELETE FROM SYS_FIELDS\n"
" WHERE INDEX_ID = index_id;\n"
" DELETE FROM SYS_INDEXES\n"
-diff -ruN a/storage/innobase/row/row0row.c b/storage/innobase/row/row0row.c
---- a/storage/innobase/row/row0row.c 2011-03-10 00:11:38.000000000 +0900
-+++ b/storage/innobase/row/row0row.c 2011-03-30 11:44:58.000000000 +0900
-@@ -347,6 +347,14 @@
+--- a/storage/innobase/row/row0row.c
++++ b/storage/innobase/row/row0row.c
+@@ -373,6 +373,14 @@
rec_len = rec_offs_n_fields(offsets);
entry = dtuple_create(heap, rec_len);
dtuple_set_n_fields_cmp(entry,
-@@ -358,6 +366,14 @@
+@@ -384,6 +392,14 @@
for (i = 0; i < rec_len; i++) {
dfield = dtuple_get_nth_field(entry, i);
field = rec_get_nth_field(rec, offsets, i, &len);
dfield_set_data(dfield, field, len);
-diff -ruN a/storage/innobase/row/row0upd.c b/storage/innobase/row/row0upd.c
---- a/storage/innobase/row/row0upd.c 2011-03-10 00:11:38.000000000 +0900
-+++ b/storage/innobase/row/row0upd.c 2011-03-30 11:44:58.000000000 +0900
+--- a/storage/innobase/row/row0upd.c
++++ b/storage/innobase/row/row0upd.c
@@ -439,6 +439,12 @@
0);
}
data = rec_get_nth_field(rec, offsets, i, &len);
dfield = dtuple_get_nth_field(entry, i);
-diff -ruN a/storage/innobase/srv/srv0srv.c b/storage/innobase/srv/srv0srv.c
---- a/storage/innobase/srv/srv0srv.c 2010-12-03 15:53:54.625288512 +0900
-+++ b/storage/innobase/srv/srv0srv.c 2010-12-03 17:19:24.922953561 +0900
+--- a/storage/innobase/srv/srv0srv.c
++++ b/storage/innobase/srv/srv0srv.c
@@ -398,6 +398,9 @@
/* When estimating number of different key values in an index, sample
this many index pages */
UNIV_INTERN ibool srv_use_doublewrite_buf = TRUE;
UNIV_INTERN ibool srv_use_checksums = TRUE;
-diff -ruN a/storage/innobase/trx/trx0rec.c b/storage/innobase/trx/trx0rec.c
---- a/storage/innobase/trx/trx0rec.c 2011-03-10 00:11:38.000000000 +0900
-+++ b/storage/innobase/trx/trx0rec.c 2011-03-30 11:44:58.000000000 +0900
-@@ -665,14 +665,27 @@
+--- a/storage/innobase/trx/trx0rec.c
++++ b/storage/innobase/trx/trx0rec.c
+@@ -669,15 +669,27 @@
/* Save to the undo log the old values of the columns to be updated. */
if (update) {
+ ulint extended = 0;
-+
+
if (trx_undo_left(undo_page, ptr) < 5) {
return(0);
+ && index == UT_LIST_GET_FIRST(dict_sys->sys_stats->indexes)) {
+ for (i = 0; i < upd_get_n_fields(update); i++) {
+ ulint pos = upd_get_nth_field(update, i)->field_no;
-+
+
+- for (i = 0; i < upd_get_n_fields(update); i++) {
+ if (pos >= rec_offs_n_fields(offsets)) {
+ extended++;
+ }
+ }
+
+ ptr += mach_write_compressed(ptr, upd_get_n_fields(update) - extended);
-
-- for (i = 0; i < upd_get_n_fields(update); i++) {
++
+ for (i = 0; i < upd_get_n_fields(update) - extended; i++) {
ulint pos = upd_get_nth_field(update, i)->field_no;
#!!! notice !!!
# Any small change to this file in the main branch
# should be done or reviewed by the maintainer!
-diff -ruN a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc
---- a/storage/innobase/handler/ha_innodb.cc 2010-12-03 15:41:52.045404706 +0900
-+++ b/storage/innobase/handler/ha_innodb.cc 2010-12-03 15:42:11.568959457 +0900
+--- a/storage/innobase/handler/ha_innodb.cc
++++ b/storage/innobase/handler/ha_innodb.cc
@@ -148,6 +148,7 @@
static ulong innobase_write_io_threads;
static long innobase_buffer_pool_instances = 1;
static long long innobase_buffer_pool_size, innobase_log_file_size;
/** Percentage of the buffer pool to reserve for 'old' blocks.
-@@ -2543,6 +2544,9 @@
+@@ -2548,6 +2549,9 @@
srv_n_log_files = (ulint) innobase_log_files_in_group;
srv_log_file_size = (ulint) innobase_log_file_size;
#ifdef UNIV_LOG_ARCHIVE
srv_log_archive_on = (ulint) innobase_log_archive;
#endif /* UNIV_LOG_ARCHIVE */
-@@ -11475,6 +11479,12 @@
+@@ -11491,6 +11495,12 @@
"Maximum delay between polling for a spin lock (6 by default)",
NULL, NULL, 6L, 0L, ~0L, 0);
static MYSQL_SYSVAR_ULONG(thread_concurrency, srv_thread_concurrency,
PLUGIN_VAR_RQCMDARG,
"Helps in performance tuning in heavily concurrent environments. Sets the maximum number of threads allowed inside InnoDB. Value 0 will disable the thread throttling.",
-@@ -11686,6 +11696,7 @@
+@@ -11703,6 +11713,7 @@
MYSQL_SYSVAR(spin_wait_delay),
MYSQL_SYSVAR(table_locks),
MYSQL_SYSVAR(thread_concurrency),
MYSQL_SYSVAR(thread_sleep_delay),
MYSQL_SYSVAR(autoinc_lock_mode),
MYSQL_SYSVAR(show_verbose_locks),
-diff -ruN a/storage/innobase/include/srv0srv.h b/storage/innobase/include/srv0srv.h
---- a/storage/innobase/include/srv0srv.h 2010-12-03 15:37:45.543027751 +0900
-+++ b/storage/innobase/include/srv0srv.h 2010-12-03 15:42:11.571024631 +0900
+--- a/storage/innobase/include/srv0srv.h
++++ b/storage/innobase/include/srv0srv.h
@@ -161,6 +161,8 @@
extern ulint srv_mem_pool_size;
extern ulint srv_lock_table_size;
extern ulint srv_n_file_io_threads;
extern ulong srv_read_ahead_threshold;
extern ulint srv_n_read_io_threads;
-diff -ruN a/storage/innobase/srv/srv0srv.c b/storage/innobase/srv/srv0srv.c
---- a/storage/innobase/srv/srv0srv.c 2010-12-03 15:37:45.546023493 +0900
-+++ b/storage/innobase/srv/srv0srv.c 2010-12-03 15:42:11.574955879 +0900
+--- a/storage/innobase/srv/srv0srv.c
++++ b/storage/innobase/srv/srv0srv.c
@@ -347,6 +347,7 @@
computer. Bigger computers need bigger values. Value 0 will disable the
concurrency check. */
#!!! notice !!!
# Any small change to this file in the main branch
# should be done or reviewed by the maintainer!
-diff -ruN /dev/null b/patch_info/log_connection_error.patch
---- /dev/null 1970-01-01 00:00:00.000000000 +0000
-+++ b/patch_info/log_connection_error.patch 2011-04-09 18:48:54.000000000 +0400
+--- /dev/null
++++ b/patch_info/log_connection_error.patch
@@ -0,0 +1,6 @@
+File=log_connection_error.patch
+Name=logging abandoned connections
+Author=Percona <info@percona.com>
+License=GPL
+Comment=
-diff -ruN a/sql/mysqld.cc b/sql/mysqld.cc
---- a/sql/mysqld.cc 2011-04-09 18:48:53.000000000 +0400
-+++ b/sql/mysqld.cc 2011-04-09 18:48:54.000000000 +0400
-@@ -5040,6 +5040,10 @@
+--- a/sql/mysqld.cc
++++ b/sql/mysqld.cc
+@@ -5098,6 +5098,10 @@
DBUG_PRINT("error",("Too many connections"));
close_connection(thd, ER_CON_COUNT_ERROR);
delete thd;
DBUG_VOID_RETURN;
}
-@@ -5420,6 +5424,10 @@
+@@ -5481,6 +5485,10 @@
if (!(thd->net.vio= vio_new_win32pipe(hConnectedPipe)) ||
my_net_init(&thd->net, thd->net.vio))
{
close_connection(thd, ER_OUT_OF_RESOURCES);
delete thd;
continue;
-@@ -5615,6 +5623,10 @@
+@@ -5676,6 +5684,10 @@
event_conn_closed)) ||
my_net_init(&thd->net, thd->net.vio))
{
#!!! notice !!!
# Any small change to this file in the main branch
# should be done or reviewed by the maintainer!
-diff -ruN /dev/null b/patch_info/log_warnings_suppress.patch
---- /dev/null 1970-01-01 00:00:00.000000000 +0000
-+++ b/patch_info/log_warnings_suppress.patch 2011-04-09 18:48:59.000000000 +0400
+--- /dev/null
++++ b/patch_info/log_warnings_suppress.patch
@@ -0,0 +1,9 @@
+File=log_warnings_suppress.patch
+Name=Disable log warnings for enumerated warnings (old name:suppress_log_warning_1592.patch)
+Changelog
+2011-01-05 rename patch suppress_log_warning_1592.patch to log_warnings_silence.patch. Also remove boolean system variable "suppress_log_warning_1592" and add set varbile "log_warnings_silence" (possible values: 1592)
+2011-02-21 rename patch log_warning_silence.patch to log_warnings_suppress.patch. Also rename variable "log_warning_silence" to "log_warning_suppress".
-diff -ruN a/sql/mysqld.cc b/sql/mysqld.cc
---- a/sql/mysqld.cc 2011-04-09 18:48:59.000000000 +0400
-+++ b/sql/mysqld.cc 2011-04-09 18:48:59.000000000 +0400
-@@ -623,6 +623,8 @@
+--- a/sql/mysqld.cc
++++ b/sql/mysqld.cc
+@@ -628,6 +628,8 @@
SHOW_COMP_OPTION have_crypt, have_compress;
SHOW_COMP_OPTION have_profiling;
/* Thread specific variables */
pthread_key(MEM_ROOT**,THR_MALLOC);
-diff -ruN a/sql/mysqld.h b/sql/mysqld.h
---- a/sql/mysqld.h 2011-04-09 18:48:58.000000000 +0400
-+++ b/sql/mysqld.h 2011-04-09 18:48:59.000000000 +0400
+--- a/sql/mysqld.h
++++ b/sql/mysqld.h
@@ -228,6 +228,8 @@
extern TYPELIB thread_handling_typelib;
extern my_decimal decimal_zero;
+extern ulonglong opt_log_warnings_suppress;
+
- extern pthread_key(MEM_ROOT**,THR_MALLOC);
-
- #ifdef HAVE_PSI_INTERFACE
-diff -ruN a/sql/sql_class.cc b/sql/sql_class.cc
---- a/sql/sql_class.cc 2011-04-09 18:48:50.000000000 +0400
-+++ b/sql/sql_class.cc 2011-04-09 18:48:59.000000000 +0400
-@@ -4575,7 +4575,7 @@
+ /*
+ THR_MALLOC is a key which will be used to set/get MEM_ROOT** for a thread,
+ using my_pthread_setspecific_ptr()/my_thread_getspecific_ptr().
+--- a/sql/sql_class.cc
++++ b/sql/sql_class.cc
+@@ -4854,7 +4854,7 @@
ER_BINLOG_UNSAFE_STATEMENT,
ER(ER_BINLOG_UNSAFE_STATEMENT),
ER(LEX::binlog_stmt_unsafe_errcode[unsafe_type]));
{
char buf[MYSQL_ERRMSG_SIZE * 2];
sprintf(buf, ER(ER_BINLOG_UNSAFE_STATEMENT),
-diff -ruN a/sql/sql_class.h b/sql/sql_class.h
---- a/sql/sql_class.h 2011-04-09 18:48:53.000000000 +0400
-+++ b/sql/sql_class.h 2011-04-09 18:48:59.000000000 +0400
+--- a/sql/sql_class.h
++++ b/sql/sql_class.h
@@ -90,6 +90,7 @@
SLOG_F_TMP_TABLE, SLOG_F_TMP_DISK, SLOG_F_FILESORT,
SLOG_F_FILESORT_DISK
enum enum_slave_exec_mode { SLAVE_EXEC_MODE_STRICT,
SLAVE_EXEC_MODE_IDEMPOTENT,
SLAVE_EXEC_MODE_LAST_BIT};
-diff -ruN a/sql/sys_vars.cc b/sql/sys_vars.cc
---- a/sql/sys_vars.cc 2011-04-09 18:48:55.000000000 +0400
-+++ b/sql/sys_vars.cc 2011-04-09 18:48:59.000000000 +0400
+--- a/sql/sys_vars.cc
++++ b/sql/sys_vars.cc
@@ -1470,6 +1470,15 @@
READ_ONLY GLOBAL_VAR(mysqld_port), CMD_LINE(REQUIRED_ARG, 'P'),
VALID_RANGE(0, UINT_MAX32), DEFAULT(0), BLOCK_SIZE(1));
--- /dev/null
+--- a/include/heap.h
++++ b/include/heap.h
+@@ -34,7 +34,17 @@
+ #include "my_compare.h"
+ #include "my_tree.h"
+
+- /* defines used by heap-funktions */
++/* Define index limits to be identical to MyISAM ones for compatibility. */
++
++#if MAX_INDEXES > HA_MAX_POSSIBLE_KEY
++#define HP_MAX_KEY HA_MAX_POSSIBLE_KEY /* Max allowed keys */
++#else
++#define HP_MAX_KEY MAX_INDEXES /* Max allowed keys */
++#endif
++
++#define HP_MAX_KEY_LENGTH 1000 /* Max length in bytes */
++
++/* defines used by heap-funktions */
+
+ #define HP_MAX_LEVELS 4 /* 128^5 records is enough */
+ #define HP_PTRS_IN_NOD 128
+@@ -130,22 +140,58 @@
+ uint (*get_key_length)(struct st_hp_keydef *keydef, const uchar *key);
+ } HP_KEYDEF;
+
+-typedef struct st_heap_share
++typedef struct st_heap_columndef /* column information */
++{
++ int16 type; /* en_fieldtype */
++ uint32 length; /* length of field */
++ uint32 offset; /* Offset to position in row */
++ uint8 null_bit; /* If column may be 0 */
++ uint16 null_pos; /* position for null marker */
++ uint8 length_bytes; /* length of the size, 1 o 2 bytes */
++} HP_COLUMNDEF;
++
++typedef struct st_heap_dataspace /* control data for data space */
+ {
+ HP_BLOCK block;
++ /* Total chunks ever allocated in this dataspace */
++ uint chunk_count;
++ uint del_chunk_count; /* Deleted chunks count */
++ uchar *del_link; /* Link to last deleted chunk */
++ uint chunk_length; /* Total length of one chunk */
++ /* Length of payload that will be placed into one chunk */
++ uint chunk_dataspace_length;
++ /* Offset of the status flag relative to the chunk start */
++ uint offset_status;
++ /* Offset of the linking pointer relative to the chunk start */
++ uint offset_link;
++ /* Test whether records have variable size and so "next" pointer */
++ uint is_variable_size;
++ /* Total size allocated within this data space */
++ ulonglong total_data_length;
++} HP_DATASPACE;
++
++typedef struct st_heap_share
++{
+ HP_KEYDEF *keydef;
++ HP_COLUMNDEF *column_defs;
++ /* Describes "block", which contains actual records */
++ HP_DATASPACE recordspace;
+ ulong min_records,max_records; /* Params to open */
+- ulonglong data_length,index_length,max_table_size;
++ ulonglong index_length, max_table_size;
+ uint key_stat_version; /* version to indicate insert/delete */
+- uint records; /* records */
+- uint blength; /* records rounded up to 2^n */
+- uint deleted; /* Deleted records in database */
+- uint reclength; /* Length of one record */
++ uint records; /* Actual record (row) count */
++ uint blength; /* used_chunk_count rounded up to 2^n */
++ /*
++ Length of record's fixed part, which contains keys and always fits into the
++ first chunk.
++ */
++ uint fixed_data_length;
++ uint fixed_column_count; /* Number of columns stored in fixed_data_length */
+ uint changed;
+ uint keys,max_key_length;
++ uint column_count;
+ uint currently_disabled_keys; /* saved value from "keys" when disabled */
+ uint open_count;
+- uchar *del_link; /* Link to next block with del. rec */
+ char * name; /* Name of "memory-file" */
+ THR_LOCK lock;
+ mysql_mutex_t intern_lock; /* Locking for use with _locking */
+@@ -154,6 +200,7 @@
+ uint auto_key;
+ uint auto_key_type; /* real type of the auto key segment */
+ ulonglong auto_increment;
++ uint blobs; /* Number of blobs in table */
+ } HP_SHARE;
+
+ struct st_hp_hash_info;
+@@ -163,7 +210,7 @@
+ HP_SHARE *s;
+ uchar *current_ptr;
+ struct st_hp_hash_info *current_hash_ptr;
+- ulong current_record,next_block;
++ ulong current_record;
+ int lastinx,errkey;
+ int mode; /* Mode of file (READONLY..) */
+ uint opt_flag,update;
+@@ -176,6 +223,9 @@
+ my_bool implicit_emptied;
+ THR_LOCK_DATA lock;
+ LIST open_list;
++ uchar *blob_buffer; /* Temporary buffer used to return BLOB values */
++ uint blob_size; /* Current blob_buffer size */
++ uint blob_offset; /* Current offset in blob_buffer */
+ } HP_INFO;
+
+
+@@ -197,6 +247,14 @@
+ open_count to 1. Is only looked at if not internal_table.
+ */
+ my_bool pin_share;
++ uint columns;
++ HP_COLUMNDEF *columndef;
++ uint fixed_key_fieldnr;
++ uint fixed_data_size;
++ uint keys_memory_size;
++ uint max_chunk_size;
++ uint is_dynamic;
++ uint blobs;
+ } HP_CREATE_INFO;
+
+ /* Prototypes for heap-functions */
+@@ -213,9 +271,8 @@
+ extern int heap_scan(register HP_INFO *info, uchar *record);
+ extern int heap_delete(HP_INFO *info,const uchar *buff);
+ extern int heap_info(HP_INFO *info,HEAPINFO *x,int flag);
+-extern int heap_create(const char *name,
+- HP_CREATE_INFO *create_info, HP_SHARE **share,
+- my_bool *created_new_share);
++extern int heap_create(const char *name, HP_CREATE_INFO *create_info,
++ HP_SHARE **res, my_bool *created_new_share);
+ extern int heap_delete_table(const char *name);
+ extern void heap_drop_table(HP_INFO *info);
+ extern int heap_extra(HP_INFO *info,enum ha_extra_function function);
+--- a/mysql-test/r/create.result
++++ b/mysql-test/r/create.result
+@@ -33,10 +33,7 @@
+ create table t1 (b char(0) not null, index(b));
+ ERROR 42000: The used storage engine can't index column 'b'
+ create table t1 (a int not null,b text) engine=heap;
+-ERROR 42000: The used table type doesn't support BLOB/TEXT columns
+ drop table if exists t1;
+-Warnings:
+-Note 1051 Unknown table 't1'
+ create table t1 (ordid int(8) not null auto_increment, ord varchar(50) not null, primary key (ord,ordid)) engine=heap;
+ ERROR 42000: Incorrect table definition; there can be only one auto column and it must be defined as a key
+ create table not_existing_database.test (a int);
+--- a/mysql-test/r/ctype_utf8mb4_heap.result
++++ b/mysql-test/r/ctype_utf8mb4_heap.result
+@@ -1124,6 +1124,8 @@
+ a varchar(255) NOT NULL default '',
+ KEY a (a)
+ ) ENGINE=heap DEFAULT CHARSET=utf8mb4 COLLATE utf8mb4_general_ci;
++Warnings:
++Warning 1071 Specified key was too long; max key length is 1000 bytes
+ insert into t1 values (_utf8mb4 0xe880bd);
+ insert into t1 values (_utf8mb4 0x5b);
+ select hex(a) from t1;
+@@ -1162,6 +1164,8 @@
+ Warnings:
+ Note 1051 Unknown table 't1'
+ CREATE TABLE t1(a VARCHAR(255), KEY(a)) ENGINE=heap DEFAULT CHARSET=utf8mb4;
++Warnings:
++Warning 1071 Specified key was too long; max key length is 1000 bytes
+ INSERT INTO t1 VALUES('uuABCDEFGHIGKLMNOPRSTUVWXYZ̈bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb');
+ INSERT INTO t1 VALUES('uu');
+ check table t1;
+--- a/mysql-test/t/create.test
++++ b/mysql-test/t/create.test
+@@ -33,7 +33,7 @@
+ drop table if exists t1,t2;
+ --error 1167
+ create table t1 (b char(0) not null, index(b));
+---error 1163
++# BLOB/TEXT fields are now supported by HEAP
+ create table t1 (a int not null,b text) engine=heap;
+ drop table if exists t1;
+
+--- a/storage/heap/CMakeLists.txt
++++ b/storage/heap/CMakeLists.txt
+@@ -20,6 +20,7 @@
+ ha_heap.cc
+ hp_delete.c hp_extra.c hp_hash.c hp_info.c hp_open.c hp_panic.c
+ hp_rename.c hp_rfirst.c hp_rkey.c hp_rlast.c hp_rnext.c hp_rprev.c
++ hp_dspace.c hp_record.c
+ hp_rrnd.c hp_rsame.c hp_scan.c hp_static.c hp_update.c hp_write.c)
+
+ MYSQL_ADD_PLUGIN(heap ${HEAP_SOURCES} STORAGE_ENGINE MANDATORY RECOMPILE_FOR_EMBEDDED)
+--- a/storage/heap/_check.c
++++ b/storage/heap/_check.c
+@@ -43,7 +43,7 @@
+ {
+ int error;
+ uint key;
+- ulong records=0, deleted=0, pos, next_block;
++ ulong records= 0, deleted= 0, chunk_count= 0, pos, next_block;
+ HP_SHARE *share=info->s;
+ HP_INFO save_info= *info; /* Needed because scan_init */
+ DBUG_ENTER("heap_check_heap");
+@@ -64,31 +64,55 @@
+ {
+ if (pos < next_block)
+ {
+- info->current_ptr+= share->block.recbuffer;
++ info->current_ptr+= share->recordspace.block.recbuffer;
+ }
+ else
+ {
+- next_block+= share->block.records_in_block;
+- if (next_block >= share->records+share->deleted)
++ next_block+= share->recordspace.block.records_in_block;
++ if (next_block >= share->recordspace.chunk_count)
+ {
+- next_block= share->records+share->deleted;
+- if (pos >= next_block)
+- break; /* End of file */
++ next_block= share->recordspace.chunk_count;
++ if (pos >= next_block)
++ break; /* End of file */
+ }
+ }
+ hp_find_record(info,pos);
+
+- if (!info->current_ptr[share->reclength])
++ switch (get_chunk_status(&share->recordspace, info->current_ptr)) {
++ case CHUNK_STATUS_DELETED:
+ deleted++;
+- else
++ chunk_count++;
++ break;
++ case CHUNK_STATUS_ACTIVE:
+ records++;
++ chunk_count++;
++ break;
++ case CHUNK_STATUS_LINKED:
++ chunk_count++;
++ break;
++ default:
++ DBUG_PRINT("error",
++ ("Unknown record status: Record: 0x%lx Status %lu",
++ (long) info->current_ptr,
++ (ulong) get_chunk_status(&share->recordspace,
++ info->current_ptr)));
++ error|= 1;
++ break;
++ }
+ }
+
+- if (records != share->records || deleted != share->deleted)
+- {
+- DBUG_PRINT("error",("Found rows: %lu (%lu) deleted %lu (%lu)",
+- records, (ulong) share->records,
+- deleted, (ulong) share->deleted));
++ /* TODO: verify linked chunks (no orphans, no cycles, no bad links) */
++
++ if (records != share->records ||
++ chunk_count != share->recordspace.chunk_count ||
++ deleted != share->recordspace.del_chunk_count)
++ {
++ DBUG_PRINT("error",
++ ("Found rows: %lu (%lu) total chunks %lu (%lu) deleted chunks "
++ "%lu (%lu)",
++ records, (ulong) share->records,
++ chunk_count, (ulong) share->recordspace.chunk_count,
++ deleted, (ulong) share->recordspace.del_chunk_count));
+ error= 1;
+ }
+ *info= save_info;
+@@ -177,7 +201,7 @@
+ do
+ {
+ memcpy(&recpos, key + (*keydef->get_key_length)(keydef,key), sizeof(uchar*));
+- key_length= hp_rb_make_key(keydef, info->recbuf, recpos, 0);
++ key_length= hp_rb_make_key(keydef, info->recbuf, recpos, 0, TRUE);
+ if (ha_key_cmp(keydef->seg, (uchar*) info->recbuf, (uchar*) key,
+ key_length, SEARCH_FIND | SEARCH_SAME, not_used))
+ {
+--- a/storage/heap/_rectest.c
++++ b/storage/heap/_rectest.c
+@@ -22,7 +22,9 @@
+ {
+ DBUG_ENTER("hp_rectest");
+
+- if (memcmp(info->current_ptr,old,(size_t) info->s->reclength))
++ if (hp_process_record_data_to_chunkset(info->s, old,
++ info->current_ptr,
++ 1))
+ {
+ DBUG_RETURN((my_errno=HA_ERR_RECORD_CHANGED)); /* Record have changed */
+ }
+--- a/storage/heap/ha_heap.cc
++++ b/storage/heap/ha_heap.cc
+@@ -114,6 +114,7 @@
+
+ rc= heap_create(name, &create_info, &internal_share, &created_new_share);
+ my_free(create_info.keydef);
++ my_free(create_info.columndef);
+ if (rc)
+ goto end;
+
+@@ -195,6 +196,12 @@
+ {
+ if (table->key_info[i].algorithm == HA_KEY_ALG_BTREE)
+ btree_keys.set_bit(i);
++ /*
++ Reset per-key block size specification so they are not shown
++ in SHOW CREATE TABLE.
++ */
++ table->key_info[i].block_size= 0;
++ table->key_info[i].flags&= ~HA_USES_BLOCK_SIZE;
+ }
+ }
+
+@@ -428,6 +435,13 @@
+ return 0;
+ }
+
++enum row_type ha_heap::get_row_type() const
++{
++ if (file->s->recordspace.is_variable_size)
++ return ROW_TYPE_DYNAMIC;
++
++ return ROW_TYPE_FIXED;
++}
+
+ int ha_heap::extra(enum ha_extra_function operation)
+ {
+@@ -645,23 +659,70 @@
+ heap_prepare_hp_create_info(TABLE *table_arg, bool internal_table,
+ HP_CREATE_INFO *hp_create_info)
+ {
+- uint key, parts, mem_per_row= 0, keys= table_arg->s->keys;
++ uint key, parts, mem_per_row_keys= 0, keys= table_arg->s->keys;
+ uint auto_key= 0, auto_key_type= 0;
+- ha_rows max_rows;
++ uint fixed_key_fieldnr = 0, fixed_data_size = 0, next_field_pos = 0;
++ uint column_idx, column_count= table_arg->s->fields;
++ HP_COLUMNDEF *columndef;
+ HP_KEYDEF *keydef;
+ HA_KEYSEG *seg;
+ TABLE_SHARE *share= table_arg->s;
+ bool found_real_auto_increment= 0;
++ uint blobs= 0;
+
+ bzero(hp_create_info, sizeof(*hp_create_info));
+
++ if (!(columndef= (HP_COLUMNDEF*) my_malloc(column_count *
++ sizeof(HP_COLUMNDEF),
++ MYF(MY_WME))))
++ return my_errno;
++
++ for (column_idx= 0; column_idx < column_count; column_idx++)
++ {
++ Field* field= *(table_arg->field + column_idx);
++ HP_COLUMNDEF* column= columndef + column_idx;
++ column->type= (uint16) field->type();
++ column->length= field->pack_length();
++ column->offset= field->offset(table_arg->record[0]);
++
++ if (field->null_bit)
++ {
++ column->null_bit= field->null_bit;
++ column->null_pos= (uint) (field->null_ptr -
++ (uchar*) table_arg->record[0]);
++ }
++ else
++ {
++ column->null_bit= 0;
++ column->null_pos= 0;
++ }
++
++ if (field->type() == MYSQL_TYPE_VARCHAR)
++ {
++ column->length_bytes= (uint8) (((Field_varstring *) field)->length_bytes);
++ }
++ else if (field->type() == MYSQL_TYPE_BLOB)
++ {
++ blobs++;
++ column->length_bytes= (uint8)
++ (((Field_blob *) field)->pack_length_no_ptr());
++ }
++ else
++ {
++ column->length_bytes= 0;
++ }
++ }
++
+ for (key= parts= 0; key < keys; key++)
+ parts+= table_arg->key_info[key].key_parts;
+
+ if (!(keydef= (HP_KEYDEF*) my_malloc(keys * sizeof(HP_KEYDEF) +
+ parts * sizeof(HA_KEYSEG),
+ MYF(MY_WME))))
++ {
++ my_free((uchar *) columndef);
+ return my_errno;
++ }
+ seg= reinterpret_cast<HA_KEYSEG*>(keydef + keys);
+ for (key= 0; key < keys; key++)
+ {
+@@ -677,11 +738,11 @@
+ case HA_KEY_ALG_UNDEF:
+ case HA_KEY_ALG_HASH:
+ keydef[key].algorithm= HA_KEY_ALG_HASH;
+- mem_per_row+= sizeof(char*) * 2; // = sizeof(HASH_INFO)
++ mem_per_row_keys+= sizeof(char*) * 2; // = sizeof(HASH_INFO)
+ break;
+ case HA_KEY_ALG_BTREE:
+ keydef[key].algorithm= HA_KEY_ALG_BTREE;
+- mem_per_row+=sizeof(TREE_ELEMENT)+pos->key_length+sizeof(char*);
++ mem_per_row_keys+=sizeof(TREE_ELEMENT)+pos->key_length+sizeof(char*);
+ break;
+ default:
+ DBUG_ASSERT(0); // cannot happen
+@@ -706,6 +767,16 @@
+ seg->length= (uint) key_part->length;
+ seg->flag= key_part->key_part_flag;
+
++ next_field_pos= seg->start;
++ if (field->type() == MYSQL_TYPE_VARCHAR)
++ {
++ Field *orig_field= *(table_arg->field + key_part->field->field_index);
++ next_field_pos+= orig_field->pack_length();
++ }
++ else
++ {
++ next_field_pos+= seg->length;
++ }
+ if (field->flags & (ENUM_FLAG | SET_FLAG))
+ seg->charset= &my_charset_bin;
+ else
+@@ -731,9 +802,75 @@
+ auto_key= key+ 1;
+ auto_key_type= field->key_type();
+ }
++
++ switch (seg->type) {
++ case HA_KEYTYPE_SHORT_INT:
++ case HA_KEYTYPE_LONG_INT:
++ case HA_KEYTYPE_FLOAT:
++ case HA_KEYTYPE_DOUBLE:
++ case HA_KEYTYPE_USHORT_INT:
++ case HA_KEYTYPE_ULONG_INT:
++ case HA_KEYTYPE_LONGLONG:
++ case HA_KEYTYPE_ULONGLONG:
++ case HA_KEYTYPE_INT24:
++ case HA_KEYTYPE_UINT24:
++ case HA_KEYTYPE_INT8:
++ seg->flag|= HA_SWAP_KEY;
++ break;
++ case HA_KEYTYPE_VARBINARY1:
++ /* Case-insensitiveness is handled in coll->hash_sort */
++ seg->type= HA_KEYTYPE_VARTEXT1;
++ /* fall through */
++ case HA_KEYTYPE_VARTEXT1:
++ keydef[key].flag|= HA_VAR_LENGTH_KEY;
++ /* Save number of bytes used to store length */
++ if (seg->flag & HA_BLOB_PART)
++ seg->bit_start= field->pack_length() - share->blob_ptr_size;
++ else
++ seg->bit_start= 1;
++ break;
++ case HA_KEYTYPE_VARBINARY2:
++ /* Case-insensitiveness is handled in coll->hash_sort */
++ /* fall_through */
++ case HA_KEYTYPE_VARTEXT2:
++ keydef[key].flag|= HA_VAR_LENGTH_KEY;
++ /* Save number of bytes used to store length */
++ if (seg->flag & HA_BLOB_PART)
++ seg->bit_start= field->pack_length() - share->blob_ptr_size;
++ else
++ seg->bit_start= 2;
++ /*
++ Make future comparison simpler by only having to check for
++ one type
++ */
++ seg->type= HA_KEYTYPE_VARTEXT1;
++ break;
++ default:
++ break;
++ }
++
++ if (next_field_pos > fixed_data_size)
++ {
++ fixed_data_size= next_field_pos;
++ }
++
++
++ if (field->field_index >= fixed_key_fieldnr)
++ {
++ /*
++ Do not use seg->fieldnr as it's not reliable in case of temp tables
++ */
++ fixed_key_fieldnr= field->field_index + 1;
++ }
+ }
+ }
+- mem_per_row+= MY_ALIGN(share->reclength + 1, sizeof(char*));
++
++ if (fixed_data_size < share->null_bytes)
++ {
++ /* Make sure to include null fields regardless of the presense of keys */
++ fixed_data_size = share->null_bytes;
++ }
++
+ if (table_arg->found_next_number_field)
+ {
+ keydef[share->next_number_index].flag|= HA_AUTO_KEY;
+@@ -744,16 +881,19 @@
+ hp_create_info->max_table_size=current_thd->variables.max_heap_table_size;
+ hp_create_info->with_auto_increment= found_real_auto_increment;
+ hp_create_info->internal_table= internal_table;
+-
+- max_rows= (ha_rows) (hp_create_info->max_table_size / mem_per_row);
+- if (share->max_rows && share->max_rows < max_rows)
+- max_rows= share->max_rows;
+-
+- hp_create_info->max_records= (ulong) max_rows;
++ hp_create_info->max_chunk_size= share->key_block_size;
++ hp_create_info->is_dynamic= (share->row_type == ROW_TYPE_DYNAMIC);
++ hp_create_info->columns= column_count;
++ hp_create_info->columndef= columndef;
++ hp_create_info->fixed_key_fieldnr= fixed_key_fieldnr;
++ hp_create_info->fixed_data_size= fixed_data_size;
++ hp_create_info->max_records= (ulong) share->max_rows;
+ hp_create_info->min_records= (ulong) share->min_rows;
+ hp_create_info->keys= share->keys;
+ hp_create_info->reclength= share->reclength;
++ hp_create_info->keys_memory_size= mem_per_row_keys;
+ hp_create_info->keydef= keydef;
++ hp_create_info->blobs= blobs;
+ return 0;
+ }
+
+@@ -773,6 +913,7 @@
+ create_info->auto_increment_value - 1 : 0);
+ error= heap_create(name, &hp_create_info, &internal_share, &created);
+ my_free(hp_create_info.keydef);
++ my_free(hp_create_info.columndef);
+ DBUG_ASSERT(file == 0);
+ return (error);
+ }
+@@ -783,6 +924,13 @@
+ table->file->info(HA_STATUS_AUTO);
+ if (!(create_info->used_fields & HA_CREATE_USED_AUTO))
+ create_info->auto_increment_value= stats.auto_increment_value;
++ if (!(create_info->used_fields & HA_CREATE_USED_KEY_BLOCK_SIZE))
++ {
++ if (file->s->recordspace.is_variable_size)
++ create_info->key_block_size= file->s->recordspace.chunk_length;
++ else
++ create_info->key_block_size= 0;
++ }
+ }
+
+ void ha_heap::get_auto_increment(ulonglong offset, ulonglong increment,
+--- a/storage/heap/ha_heap.h
++++ b/storage/heap/ha_heap.h
+@@ -47,12 +47,11 @@
+ return ((table_share->key_info[inx].algorithm == HA_KEY_ALG_BTREE) ?
+ "BTREE" : "HASH");
+ }
+- /* Rows also use a fixed-size format */
+- enum row_type get_row_type() const { return ROW_TYPE_FIXED; }
++ enum row_type get_row_type() const;
+ const char **bas_ext() const;
+ ulonglong table_flags() const
+ {
+- return (HA_FAST_KEY_READ | HA_NO_BLOBS | HA_NULL_IN_KEY |
++ return (HA_FAST_KEY_READ | HA_NULL_IN_KEY |
+ HA_BINLOG_ROW_CAPABLE | HA_BINLOG_STMT_CAPABLE |
+ HA_REC_NOT_IN_SEQ | HA_CAN_INSERT_DELAYED | HA_NO_TRANSACTIONS |
+ HA_HAS_RECORDS | HA_STATS_RECORDS_IS_EXACT);
+@@ -64,8 +63,9 @@
+ HA_ONLY_WHOLE_INDEX | HA_KEY_SCAN_NOT_ROR);
+ }
+ const key_map *keys_to_use_for_scanning() { return &btree_keys; }
+- uint max_supported_keys() const { return MAX_KEY; }
+- uint max_supported_key_part_length() const { return MAX_KEY_LENGTH; }
++ uint max_supported_keys() const { return HP_MAX_KEY; }
++ uint max_supported_key_length() const { return HP_MAX_KEY_LENGTH; }
++ uint max_supported_key_part_length() const { return HP_MAX_KEY_LENGTH; }
+ double scan_time()
+ { return (double) (stats.records+stats.deleted) / 20.0+10; }
+ double read_time(uint index, uint ranges, ha_rows rows)
+--- a/storage/heap/heapdef.h
++++ b/storage/heap/heapdef.h
+@@ -32,6 +32,13 @@
+ #define HP_MIN_RECORDS_IN_BLOCK 16
+ #define HP_MAX_RECORDS_IN_BLOCK 8192
+
++/* this chunk has been deleted and can be reused */
++#define CHUNK_STATUS_DELETED 0
++/* this chunk represents the first part of a live record */
++#define CHUNK_STATUS_ACTIVE 1
++/* this chunk is a continuation from another chunk (part of chunkset) */
++#define CHUNK_STATUS_LINKED 2
++
+ /* Some extern variables */
+
+ extern LIST *heap_open_list,*heap_share_list;
+@@ -42,7 +49,14 @@
+ #define hp_find_hash(A,B) ((HASH_INFO*) hp_find_block((A),(B)))
+
+ /* Find pos for record and update it in info->current_ptr */
+-#define hp_find_record(info,pos) (info)->current_ptr= hp_find_block(&(info)->s->block,pos)
++#define hp_find_record(info,pos) \
++ (info)->current_ptr= hp_find_block(&(info)->s->recordspace.block,pos)
++
++#define get_chunk_status(info,ptr) (ptr[(info)->offset_status])
++
++#define get_chunk_count(info,rec_length) \
++ ((rec_length + (info)->chunk_dataspace_length - 1) / \
++ (info)->chunk_dataspace_length)
+
+ typedef struct st_hp_hash_info
+ {
+@@ -90,7 +104,7 @@
+ const uchar *key);
+ extern void hp_make_key(HP_KEYDEF *keydef,uchar *key,const uchar *rec);
+ extern uint hp_rb_make_key(HP_KEYDEF *keydef, uchar *key,
+- const uchar *rec, uchar *recpos);
++ const uchar *rec, uchar *recpos, my_bool packed);
+ extern uint hp_rb_key_length(HP_KEYDEF *keydef, const uchar *key);
+ extern uint hp_rb_null_key_length(HP_KEYDEF *keydef, const uchar *key);
+ extern uint hp_rb_var_key_length(HP_KEYDEF *keydef, const uchar *key);
+@@ -100,6 +114,23 @@
+ extern void hp_clear_keys(HP_SHARE *info);
+ extern uint hp_rb_pack_key(HP_KEYDEF *keydef, uchar *key, const uchar *old,
+ key_part_map keypart_map);
++extern uint hp_calc_blob_length(uint length, const uchar *pos);
++
++/* Chunkset management (alloc/free/encode/decode) functions */
++extern uchar *hp_allocate_chunkset(HP_DATASPACE *info, uint chunk_count);
++extern int hp_reallocate_chunkset(HP_DATASPACE *info, uint chunk_count,
++ uchar *pos);
++extern void hp_free_chunks(HP_DATASPACE *info, uchar *pos);
++extern void hp_clear_dataspace(HP_DATASPACE *info);
++
++extern uint hp_get_encoded_data_length(HP_SHARE *info, const uchar *record,
++ uint *chunk_count);
++extern void hp_copy_record_data_to_chunkset(HP_SHARE *info, const uchar *record,
++ uchar *pos);
++extern int hp_extract_record(HP_INFO *info, uchar *record, const uchar *pos);
++extern uint hp_process_record_data_to_chunkset(HP_SHARE *info,
++ const uchar *record, uchar *pos,
++ uint is_compare);
+
+ extern mysql_mutex_t THR_LOCK_heap;
+
+--- a/storage/heap/hp_clear.c
++++ b/storage/heap/hp_clear.c
+@@ -31,16 +31,11 @@
+ {
+ DBUG_ENTER("hp_clear");
+
+- if (info->block.levels)
+- (void) hp_free_level(&info->block,info->block.levels,info->block.root,
+- (uchar*) 0);
+- info->block.levels=0;
++ hp_clear_dataspace(&info->recordspace);
+ hp_clear_keys(info);
+- info->records= info->deleted= 0;
+- info->data_length= 0;
++ info->records= 0;
+ info->blength=1;
+ info->changed=0;
+- info->del_link=0;
+ DBUG_VOID_RETURN;
+ }
+
+@@ -158,7 +153,7 @@
+ int error= 0;
+ HP_SHARE *share= info->s;
+
+- if (share->data_length || share->index_length)
++ if (share->recordspace.total_data_length || share->index_length)
+ error= HA_ERR_CRASHED;
+ else
+ if (share->currently_disabled_keys)
+--- a/storage/heap/hp_close.c
++++ b/storage/heap/hp_close.c
+@@ -46,6 +46,10 @@
+ heap_open_list=list_delete(heap_open_list,&info->open_list);
+ if (!--info->s->open_count && info->s->delete_on_close)
+ hp_free(info->s); /* Table was deleted */
++ if (info->blob_buffer)
++ {
++ my_free(info->blob_buffer);
++ }
+ my_free(info);
+ DBUG_RETURN(error);
+ }
+--- a/storage/heap/hp_create.c
++++ b/storage/heap/hp_create.c
+@@ -14,11 +14,21 @@
+ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
+
+ #include "heapdef.h"
++#include <mysql_com.h>
++#include <mysqld_error.h>
+
+ static int keys_compare(heap_rb_param *param, uchar *key1, uchar *key2);
+-static void init_block(HP_BLOCK *block,uint reclength,ulong min_records,
++static void init_block(HP_BLOCK *block,uint chunk_length, ulong min_records,
+ ulong max_records);
+
++#define FIXED_REC_OVERHEAD (sizeof(uchar))
++#define VARIABLE_REC_OVERHEAD (sizeof(uchar **) + sizeof(uchar))
++
++/* Minimum size that a chunk can take, 12 bytes on 32bit, 24 bytes on 64bit */
++#define VARIABLE_MIN_CHUNK_SIZE \
++ ((sizeof(uchar **) + VARIABLE_REC_OVERHEAD + sizeof(uchar **) - 1) & \
++ ~(sizeof(uchar **) - 1))
++
+ /* Create a heap table */
+
+ int heap_create(const char *name, HP_CREATE_INFO *create_info,
+@@ -32,6 +42,7 @@
+ uint keys= create_info->keys;
+ ulong min_records= create_info->min_records;
+ ulong max_records= create_info->max_records;
++ ulong max_rows_for_stated_memory;
+ DBUG_ENTER("heap_create");
+
+ if (!create_info->internal_table)
+@@ -48,15 +59,147 @@
+
+ if (!share)
+ {
++ uint chunk_dataspace_length, chunk_length, is_variable_size;
++ uint fixed_data_length, fixed_column_count;
+ HP_KEYDEF *keyinfo;
+ DBUG_PRINT("info",("Initializing new table"));
+-
++
++ if (create_info->max_chunk_size)
++ {
++ uint configured_chunk_size= create_info->max_chunk_size;
++
++ /* User requested variable-size records, let's see if they're possible */
++
++ if (configured_chunk_size < create_info->fixed_data_size)
++ {
++ /*
++ The resulting chunk_size cannot be smaller than fixed data part
++ at the start of the first chunk which allows faster copying
++ with a single memcpy().
++ */
++ my_error(ER_CANT_USE_OPTION_HERE, MYF(0), "key_block_size");
++ goto err;
++ }
++
++ if (reclength > configured_chunk_size + VARIABLE_REC_OVERHEAD ||
++ create_info->blobs > 0)
++ {
++ /*
++ Allow variable size only if we're saving some space, i.e.
++ if a fixed-size record would take more space than variable-size
++ one plus the variable-size overhead.
++ There has to be at least one field after indexed fields.
++ Note that NULL bits are already included in key_part_size.
++ */
++ is_variable_size= 1;
++ chunk_dataspace_length= configured_chunk_size;
++ }
++ else
++ {
++ /* max_chunk_size is near the full reclength, let's use fixed size */
++ is_variable_size= 0;
++ chunk_dataspace_length= reclength;
++ }
++ }
++ else if ((create_info->is_dynamic && reclength >
++ 256 + VARIABLE_REC_OVERHEAD)
++ || create_info->blobs > 0)
++ {
++ /*
++ User asked for dynamic records - use 256 as the chunk size, if that
++ will may save some memory. Otherwise revert to fixed size format.
++ */
++ if ((create_info->fixed_data_size + VARIABLE_REC_OVERHEAD) > 256)
++ chunk_dataspace_length= create_info->fixed_data_size;
++ else
++ chunk_dataspace_length= 256 - VARIABLE_REC_OVERHEAD;
++
++ is_variable_size= 1;
++ }
++ else
++ {
++ /*
++ If max_chunk_size is not specified, put the whole record in one chunk
++ */
++ is_variable_size= 0;
++ chunk_dataspace_length= reclength;
++ }
++
++ if (is_variable_size)
++ {
++ /* Check whether we have any variable size records past key data */
++ uint has_variable_fields= 0;
++
++ fixed_data_length= create_info->fixed_data_size;
++ fixed_column_count= create_info->fixed_key_fieldnr;
++
++ for (i= create_info->fixed_key_fieldnr; i < create_info->columns; i++)
++ {
++ HP_COLUMNDEF *column= create_info->columndef + i;
++ if ((column->type == MYSQL_TYPE_VARCHAR &&
++ (column->length - column->length_bytes) >= 32) ||
++ column->type == MYSQL_TYPE_BLOB)
++ {
++ /*
++ The field has to be either blob or >= 5.0.3 true VARCHAR
++ and have substantial length.
++ TODO: do we want to calculate minimum length?
++ */
++ has_variable_fields= 1;
++ break;
++ }
++
++ if (has_variable_fields)
++ {
++ break;
++ }
++
++ if ((column->offset + column->length) <= chunk_dataspace_length)
++ {
++ /* Still no variable-size columns, add one fixed-length */
++ fixed_column_count= i + 1;
++ fixed_data_length= column->offset + column->length;
++ }
++ }
++
++ if (!has_variable_fields && create_info->blobs == 0)
++ {
++ /*
++ There is no need to use variable-size records without variable-size
++ columns.
++ Reset sizes if it's not variable size anymore.
++ */
++ is_variable_size= 0;
++ chunk_dataspace_length= reclength;
++ fixed_data_length= reclength;
++ fixed_column_count= create_info->columns;
++ }
++ }
++ else
++ {
++ fixed_data_length= reclength;
++ fixed_column_count= create_info->columns;
++ }
++
+ /*
+- We have to store sometimes uchar* del_link in records,
+- so the record length should be at least sizeof(uchar*)
++ We store uchar* del_link inside the data area of deleted records,
++ so the data length should be at least sizeof(uchar*)
+ */
+- set_if_bigger(reclength, sizeof (uchar*));
+-
++ set_if_bigger(chunk_dataspace_length, sizeof (uchar **));
++
++ if (is_variable_size)
++ {
++ chunk_length= chunk_dataspace_length + VARIABLE_REC_OVERHEAD;
++ }
++ else
++ {
++ chunk_length= chunk_dataspace_length + FIXED_REC_OVERHEAD;
++ }
++
++ /* Align chunk length to the next pointer */
++ chunk_length= (uint) (chunk_length + sizeof(uchar **) - 1) &
++ ~(sizeof(uchar **) - 1);
++
+ for (i= key_segs= max_length= 0, keyinfo= keydef; i < keys; i++, keyinfo++)
+ {
+ bzero((char*) &keyinfo->block,sizeof(keyinfo->block));
+@@ -73,42 +216,11 @@
+ keyinfo->rb_tree.size_of_element++;
+ }
+ switch (keyinfo->seg[j].type) {
+- case HA_KEYTYPE_SHORT_INT:
+- case HA_KEYTYPE_LONG_INT:
+- case HA_KEYTYPE_FLOAT:
+- case HA_KEYTYPE_DOUBLE:
+- case HA_KEYTYPE_USHORT_INT:
+- case HA_KEYTYPE_ULONG_INT:
+- case HA_KEYTYPE_LONGLONG:
+- case HA_KEYTYPE_ULONGLONG:
+- case HA_KEYTYPE_INT24:
+- case HA_KEYTYPE_UINT24:
+- case HA_KEYTYPE_INT8:
+- keyinfo->seg[j].flag|= HA_SWAP_KEY;
+- break;
+ case HA_KEYTYPE_VARBINARY1:
+- /* Case-insensitiveness is handled in coll->hash_sort */
+- keyinfo->seg[j].type= HA_KEYTYPE_VARTEXT1;
+- /* fall_through */
+ case HA_KEYTYPE_VARTEXT1:
+- keyinfo->flag|= HA_VAR_LENGTH_KEY;
+- length+= 2;
+- /* Save number of bytes used to store length */
+- keyinfo->seg[j].bit_start= 1;
+- break;
+ case HA_KEYTYPE_VARBINARY2:
+- /* Case-insensitiveness is handled in coll->hash_sort */
+- /* fall_through */
+ case HA_KEYTYPE_VARTEXT2:
+- keyinfo->flag|= HA_VAR_LENGTH_KEY;
+ length+= 2;
+- /* Save number of bytes used to store length */
+- keyinfo->seg[j].bit_start= 2;
+- /*
+- Make future comparison simpler by only having to check for
+- one type
+- */
+- keyinfo->seg[j].type= HA_KEYTYPE_VARTEXT1;
+ break;
+ default:
+ break;
+@@ -133,13 +245,34 @@
+ }
+ if (!(share= (HP_SHARE*) my_malloc((uint) sizeof(HP_SHARE)+
+ keys*sizeof(HP_KEYDEF)+
++ (create_info->columns *
++ sizeof(HP_COLUMNDEF)) +
+ key_segs*sizeof(HA_KEYSEG),
+ MYF(MY_ZEROFILL))))
+ goto err;
+- share->keydef= (HP_KEYDEF*) (share + 1);
++
++ /*
++ Max_records is used for estimating block sizes and for enforcement.
++ Calculate the very maximum number of rows (if everything was one chunk)
++ and then take either that value or configured max_records (pick smallest
++ one).
++ */
++ max_rows_for_stated_memory= (ha_rows) (create_info->max_table_size /
++ (create_info->keys_memory_size +
++ chunk_length));
++ max_records = ((max_records && max_records < max_rows_for_stated_memory) ?
++ max_records : max_rows_for_stated_memory);
++
++ share->column_defs= (HP_COLUMNDEF*) (share + 1);
++ memcpy(share->column_defs, create_info->columndef,
++ (size_t) (sizeof(create_info->columndef[0]) *
++ create_info->columns));
++
++ share->keydef= (HP_KEYDEF*) (share->column_defs + create_info->columns);
+ share->key_stat_version= 1;
+ keyseg= (HA_KEYSEG*) (share->keydef + keys);
+- init_block(&share->block, reclength + 1, min_records, max_records);
++ init_block(&share->recordspace.block, chunk_length, min_records,
++ max_records);
+ /* Fix keys */
+ memcpy(share->keydef, keydef, (size_t) (sizeof(keydef[0]) * keys));
+ for (i= 0, keyinfo= share->keydef; i < keys; i++, keyinfo++)
+@@ -177,15 +310,35 @@
+ share->min_records= min_records;
+ share->max_records= max_records;
+ share->max_table_size= create_info->max_table_size;
+- share->data_length= share->index_length= 0;
+- share->reclength= reclength;
++ share->index_length= 0;
+ share->blength= 1;
+ share->keys= keys;
+ share->max_key_length= max_length;
++ share->column_count= create_info->columns;
+ share->changed= 0;
+ share->auto_key= create_info->auto_key;
+ share->auto_key_type= create_info->auto_key_type;
+ share->auto_increment= create_info->auto_increment;
++
++ share->fixed_data_length= fixed_data_length;
++ share->fixed_column_count= fixed_column_count;
++ share->blobs= create_info->blobs;
++
++ share->recordspace.chunk_length= chunk_length;
++ share->recordspace.chunk_dataspace_length= chunk_dataspace_length;
++ share->recordspace.is_variable_size= is_variable_size;
++ share->recordspace.total_data_length= 0;
++
++ if (is_variable_size) {
++ share->recordspace.offset_link= chunk_dataspace_length;
++ share->recordspace.offset_status= share->recordspace.offset_link +
++ sizeof(uchar **);
++ } else {
++ /* Make it likely to fail if anyone uses this offset */
++ share->recordspace.offset_link= 1 << 22;
++ share->recordspace.offset_status= chunk_dataspace_length;
++ }
++
+ /* Must be allocated separately for rename to work */
+ if (!(share->name= my_strdup(name,MYF(0))))
+ {
+@@ -227,7 +380,7 @@
+ param->search_flag, not_used);
+ }
+
+-static void init_block(HP_BLOCK *block, uint reclength, ulong min_records,
++static void init_block(HP_BLOCK *block, uint chunk_length, ulong min_records,
+ ulong max_records)
+ {
+ uint i,recbuffer,records_in_block;
+@@ -235,7 +388,12 @@
+ max_records= max(min_records,max_records);
+ if (!max_records)
+ max_records= 1000; /* As good as quess as anything */
+- recbuffer= (uint) (reclength + sizeof(uchar**) - 1) & ~(sizeof(uchar**) - 1);
++ /*
++ We want to start each chunk at 8 bytes boundary, round recbuffer to the
++ next 8.
++ */
++ recbuffer= (uint) (chunk_length + sizeof(uchar**) - 1) &
++ ~(sizeof(uchar**) - 1);
+ records_in_block= max_records / 10;
+ if (records_in_block < 10 && max_records)
+ records_in_block= 10;
+--- a/storage/heap/hp_delete.c
++++ b/storage/heap/hp_delete.c
+@@ -22,6 +22,8 @@
+ uchar *pos;
+ HP_SHARE *share=info->s;
+ HP_KEYDEF *keydef, *end, *p_lastinx;
++ uint rec_length, chunk_count;
++
+ DBUG_ENTER("heap_delete");
+ DBUG_PRINT("enter",("info: 0x%lx record: 0x%lx", (long) info, (long) record));
+
+@@ -31,6 +33,8 @@
+ DBUG_RETURN(my_errno); /* Record changed */
+ share->changed=1;
+
++ rec_length = hp_get_encoded_data_length(share, record, &chunk_count);
++
+ if ( --(share->records) < share->blength >> 1) share->blength>>=1;
+ pos=info->current_ptr;
+
+@@ -43,10 +47,7 @@
+ }
+
+ info->update=HA_STATE_DELETED;
+- *((uchar**) pos)=share->del_link;
+- share->del_link=pos;
+- pos[share->reclength]=0; /* Record deleted */
+- share->deleted++;
++ hp_free_chunks(&share->recordspace, pos);
+ info->current_hash_ptr=0;
+ #if !defined(DBUG_OFF) && defined(EXTRA_HEAP_DEBUG)
+ DBUG_EXECUTE("check_heap",heap_check_heap(info, 0););
+@@ -75,7 +76,8 @@
+ info->last_pos= NULL; /* For heap_rnext/heap_rprev */
+
+ custom_arg.keyseg= keyinfo->seg;
+- custom_arg.key_length= hp_rb_make_key(keyinfo, info->recbuf, record, recpos);
++ custom_arg.key_length= hp_rb_make_key(keyinfo, info->recbuf, record, recpos,
++ FALSE);
+ custom_arg.search_flag= SEARCH_SAME;
+ old_allocated= keyinfo->rb_tree.allocated;
+ res= tree_delete(&keyinfo->rb_tree, info->recbuf, custom_arg.key_length,
+@@ -112,6 +114,7 @@
+ blength=share->blength;
+ if (share->records+1 == blength)
+ blength+= blength;
++
+ lastpos=hp_find_hash(&keyinfo->block,share->records);
+ last_ptr=0;
+
+--- /dev/null
++++ b/storage/heap/hp_dspace.c
+@@ -0,0 +1,440 @@
++/* Copyright (C) 2000-2002 MySQL AB
++ Copyright (C) 2008 eBay, Inc
++
++ 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 Foundation; version 2 of the License.
++
++ This program is distributed in the hope that it will be useful,
++ but WITHOUT ANY WARRANTY; without even the implied warranty of
++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ GNU General Public License for more details.
++
++ You should have received a copy of the GNU General Public License
++ along with this program; if not, write to the Free Software
++ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
++
++/*
++ Implements various base dataspace-related functions - allocate, free, clear
++*/
++
++#include "heapdef.h"
++
++
++/*
++ MySQL Heap tables keep data in arrays of fixed-size chunks.
++ These chunks are organized into two groups of HP_BLOCK structures:
++ - group1 contains indexes, with one HP_BLOCK per key
++ (part of HP_KEYDEF)
++ - group2 contains record data, with single HP_BLOCK
++ for all records, referenced by HP_SHARE.recordspace.block
++
++ While columns used in index are usually small, other columns
++ in the table may need to accomodate larger data. Typically,
++ larger data is placed into VARCHAR or BLOB columns. With actual
++ sizes varying, Heap Engine has to support variable-sized records
++ in memory. Heap Engine implements the concept of dataspace
++ (HP_DATASPACE), which incorporates HP_BLOCK for the record data,
++ and adds more information for managing variable-sized records.
++
++ Variable-size records are stored in multiple "chunks",
++ which means that a single record of data (database "row") can
++ consist of multiple chunks organized into one "set". HP_BLOCK
++ contains chunks. In variable-size format, one record
++ is represented as one or many chunks, depending on the actual
++ data, while in fixed-size mode, one record is always represented
++ as one chunk. The index structures would always point to the first
++ chunk in the chunkset.
++
++ At the time of table creation, Heap Engine attempts to find out if
++ variable-size records are desired. A user can request
++ variable-size records by providing either row_type=dynamic or
++ key_block_size=NNN table create option. Heap Engine will check
++ whether key_block_size provides enough space in the first chunk
++ to keep all null bits and columns that are used in indexes.
++ If key_block_size is too small, table creation will be aborted
++ with an error. Heap Engine will revert to fixed-size allocation
++ mode if key_block_size provides no memory benefits (if the
++ fixed-size record would always be shorter then the first chunk
++ in the chunkset with the specified key_block_size).
++
++ In order to improve index search performance, Heap Engine needs
++ to keep all null flags and all columns used as keys inside
++ the first chunk of a chunkset. In particular, this means that
++ all columns used as keys should be defined first in the table
++ creation SQL. The length of data used by null bits and key columns
++ is stored as fixed_data_length inside HP_SHARE. fixed_data_length
++ will extend past last key column if more fixed-length fields can
++ fit into the first chunk.
++
++ Variable-size records are necessary only in the presence of
++ variable-size columns. Heap Engine will be looking for BLOB
++ columns or VARCHAR columns, which declare length of 32 or more. If
++ no such columns are found, table will be switched to fixed-size
++ format. You should always try to put such columns at the end of
++ the table definition.
++
++ Whenever data is being inserted or updated in the table
++ Heap Engine will calculate how many chunks are necessary.
++ For insert operations, Heap Engine allocates new chunkset in
++ the recordspace. For update operations it will modify length of
++ the existing chunkset, unlinking unnecessary chunks at the end,
++ or allocating and adding more if larger length is necessary.
++
++ When writing data to chunks or copying data back to record,
++ fixed-size columns are copied in their full format. VARCHARs and
++ BLOBs are copied based on their actual length. Any NULL values
++ after fixed_data_length are skipped.
++
++ The allocation and contents of the actual chunks varies between
++ fixed and variable-size modes. Total chunk length is always
++ aligned to the next sizeof(uchar*). Here is the format of
++ fixed-size chunk:
++ uchar[] - sizeof=chunk_dataspace_length, but at least
++ sizeof(uchar*) bytes. Keeps actual data or pointer
++ to the next deleted chunk.
++ chunk_dataspace_length equals to full record length
++ uchar - status field (1 means "in use", 0 means "deleted")
++
++ Variable-size chunk uses different format:
++ uchar[] - sizeof=chunk_dataspace_length, but at least
++ sizeof(uchar*) bytes. Keeps actual data or pointer
++ to the next deleted chunk.
++ chunk_dataspace_length is set according to table
++ setup (key_block_size)
++ uchar* - pointer to the next chunk in this chunkset,
++ or NULL for the last chunk
++ uchar - status field (1 means "first", 0 means "deleted",
++ 2 means "linked")
++
++ When allocating a new chunkset of N chunks, Heap Engine will try
++ to allocate chunks one-by-one, linking them as they become
++ allocated. Allocation of a single chunk will attempt to reuse
++ a deleted (freed) chunk. If no free chunks are available,
++ it will attempt to allocate a new area inside HP_BLOCK.
++ Freeing chunks will place them at the front of free list
++ referenced by del_link in HP_DATASPACE. The newly freed chunk
++ will contain reference to the previously freed chunk in its first
++ sizeof(uchar*) of the payload space.
++
++ Here is open issues:
++ - It is not very nice to require people to keep key columns
++ at the beginning of the table creation SQL. There are three
++ proposed resolutions:
++ a. Leave it as is. It's a reasonable limitation
++ b. Add new HA_KEEP_KEY_COLUMNS_TO_FRONT flag to handler.h and
++ make table.cpp align columns when it creates the table
++ c. Make HeapEngine reorder columns in the chunk data, so that
++ key columns go first. Add parallel HA_KEYSEG structures
++ to distinguish positions in record vs. positions in
++ the first chunk. Copy all data field-by-field rather than
++ using single memcpy unless DBA kept key columns to
++ the beginning.
++ - heap_check_heap needs verify linked chunks, looking for
++ issues such as orphans, cycles, and bad links. However,
++ Heap Engine today does not do similar things even for
++ free list.
++ - In a more sophisticated implementation, some space can
++ be saved even with all fixed-size columns if many of them
++ have NULL value, as long as these columns are not used
++ in indexes
++ - In variable-size format status should be moved to lower
++ bits of the "next" pointer. Pointer is always aligned
++ to sizeof(byte*), which is at least 4, leaving 2 lower
++ bits free. This will save 8 bytes per chunk
++ on 64-bit platform.
++ - As we do not want to modify FRM format or to add new SQL
++ keywords, KEY_BLOCK_SIZE option of "CREATE TABLE" is reused
++ to specify block size for Heap Engine tables.
++ - since all key columns must fit in the first chunk, having keys
++ on BLOB columns is currently impossible. This limitation is
++ relatively easiy to remove in future.
++*/
++
++static uchar *hp_allocate_one_chunk(HP_DATASPACE *info);
++
++
++/**
++ Clear a dataspace
++
++ Frees memory and zeros-out any relevant counters in the dataspace
++
++ @param info the dataspace to clear
++*/
++
++void hp_clear_dataspace(HP_DATASPACE *info)
++{
++ if (info->block.levels)
++ {
++ hp_free_level(&info->block,info->block.levels,info->block.root,
++ (uchar *) 0);
++ }
++ info->block.levels= 0;
++ info->del_chunk_count= info->chunk_count= 0;
++ info->del_link= 0;
++ info->total_data_length= 0;
++}
++
++
++/**
++ Allocate or reallocate a chunkset in the dataspace
++
++ Attempts to allocate a new chunkset or change the size of an existing chunkset
++
++ @param info the hosting dataspace
++ @param chunk_count the number of chunks that we expect as the result
++ @param existing_set non-null value asks function to resize existing
++ chunkset, return value would point to this set
++
++ @return Pointer to the first chunk in the new or updated chunkset, or NULL
++ if unsuccessful
++*/
++
++static uchar *hp_allocate_variable_chunkset(HP_DATASPACE *info,
++ uint chunk_count,
++ uchar *existing_set)
++{
++ int alloc_count= chunk_count, i;
++ uchar *first_chunk= 0, *curr_chunk= 0, *prev_chunk= 0;
++ uchar *last_existing_chunk= 0;
++
++ DBUG_ASSERT(alloc_count);
++
++ if (existing_set)
++ {
++ first_chunk= existing_set;
++
++ curr_chunk= existing_set;
++ while (curr_chunk && alloc_count)
++ {
++ prev_chunk= curr_chunk;
++ curr_chunk= *((uchar **) (curr_chunk + info->offset_link));
++ alloc_count--;
++ }
++
++ if (!alloc_count)
++ {
++ if (curr_chunk)
++ {
++ /*
++ We came through all chunks and there is more left, let's truncate the
++ list.
++ */
++ *((uchar **) (prev_chunk + info->offset_link))= NULL;
++ hp_free_chunks(info, curr_chunk);
++ }
++
++ return first_chunk;
++ }
++
++ last_existing_chunk= prev_chunk;
++ }
++
++ /*
++ We can reach this point only if we're allocating new chunkset or more chunks
++ in existing set.
++ */
++
++ for (i= 0; i < alloc_count; i++)
++ {
++ curr_chunk= hp_allocate_one_chunk(info);
++ if (!curr_chunk)
++ {
++ /* no space in the current block */
++
++ if (last_existing_chunk)
++ {
++ /* Truncate whatever was added at the end of the existing chunkset */
++ prev_chunk= last_existing_chunk;
++ curr_chunk= *((uchar **)(prev_chunk + info->offset_link));
++ *((uchar **)(prev_chunk + info->offset_link))= NULL;
++ hp_free_chunks(info, curr_chunk);
++ }
++ else if (first_chunk)
++ {
++ /* free any chunks previously allocated */
++ hp_free_chunks(info, first_chunk);
++ }
++
++ return NULL;
++ }
++
++ /* mark as if this chunk is last in the chunkset */
++ *((uchar **) (curr_chunk + info->offset_link))= 0;
++
++ if (prev_chunk)
++ {
++ /* tie them into a linked list */
++ *((uchar **) (prev_chunk + info->offset_link))= curr_chunk;
++ /* Record linked from active */
++ curr_chunk[info->offset_status]= CHUNK_STATUS_LINKED;
++ }
++ else
++ {
++ /* Record active */
++ curr_chunk[info->offset_status]= CHUNK_STATUS_ACTIVE;
++ }
++
++ if (!first_chunk)
++ {
++ first_chunk= curr_chunk;
++ }
++
++ prev_chunk= curr_chunk;
++}
++
++ return first_chunk;
++}
++
++
++/**
++ Allocate a new chunkset in the dataspace
++
++ Attempts to allocate a new chunkset
++
++ @param info the hosting dataspace
++ @param chunk_count the number of chunks that we expect as the result
++
++ @return Pointer to the first chunk in the new or updated chunkset, or NULL if
++ unsuccessful
++*/
++
++uchar *hp_allocate_chunkset(HP_DATASPACE *info, uint chunk_count)
++{
++ uchar *result;
++
++ DBUG_ENTER("hp_allocate_chunks");
++
++ if (info->is_variable_size)
++ {
++ result = hp_allocate_variable_chunkset(info, chunk_count, NULL);
++ }
++ else
++ {
++ result= hp_allocate_one_chunk(info);
++ if (result)
++ {
++ result[info->offset_status]= CHUNK_STATUS_ACTIVE;
++ }
++
++ DBUG_RETURN(result);
++ }
++
++ DBUG_RETURN(result);
++}
++
++
++/**
++ Reallocate an existing chunkset in the dataspace
++
++ Attempts to change the size of an existing chunkset
++
++ @param info the hosting dataspace
++ @param chunk_count the number of chunks that we expect as the result
++ @param pos pointer to the existing chunkset
++
++ @return Error code or zero if successful
++*/
++
++int hp_reallocate_chunkset(HP_DATASPACE *info, uint chunk_count, uchar *pos)
++{
++ DBUG_ENTER("hp_reallocate_chunks");
++
++ if (!info->is_variable_size)
++ {
++ /* Update should never change chunk_count in fixed-size mode */
++ my_errno= HA_ERR_WRONG_COMMAND;
++ return my_errno;
++ }
++
++ /* Reallocate never moves the first chunk */
++ if (!hp_allocate_variable_chunkset(info, chunk_count, pos))
++ DBUG_RETURN(my_errno);
++
++ DBUG_RETURN(0);
++}
++
++
++/**
++ Allocate a single chunk in the dataspace
++
++ Attempts to allocate a new chunk or reuse one from deleted list
++
++ @param info the hosting dataspace
++
++ @return Pointer to the chunk, or NULL if unsuccessful
++*/
++
++static uchar *hp_allocate_one_chunk(HP_DATASPACE *info)
++{
++ uchar *curr_chunk;
++ size_t length;
++ ulong block_pos;
++
++ if (info->del_link)
++ {
++ curr_chunk= info->del_link;
++ info->del_link= *((uchar **) curr_chunk);
++ info->del_chunk_count--;
++
++ DBUG_PRINT("hp_allocate_one_chunk",
++ ("Used old position: 0x%lx",(long) curr_chunk));
++ return curr_chunk;
++ }
++
++ block_pos= (info->chunk_count % info->block.records_in_block);
++ if (!block_pos)
++ {
++ if (hp_get_new_block(&info->block, &length))
++ {
++ /* no space in the current block */
++ return NULL;
++ }
++
++ info->total_data_length+= length;
++ }
++
++ info->chunk_count++;
++ curr_chunk= ((uchar *) info->block.level_info[0].last_blocks +
++ block_pos * info->block.recbuffer);
++
++ DBUG_PRINT("hp_allocate_one_chunk",
++ ("Used new position: 0x%lx", (long) curr_chunk));
++
++ return curr_chunk;
++}
++
++
++/**
++ Free a list of chunks
++
++ Reclaims all chunks linked by the pointer,
++ which could be the whole chunkset or a part of an existing chunkset
++
++ @param info the hosting dataspace
++ @param pos pointer to the head of the chunkset
++*/
++
++void hp_free_chunks(HP_DATASPACE *info, uchar *pos)
++{
++ uchar *curr_chunk= pos;
++
++ while (curr_chunk)
++ {
++ info->del_chunk_count++;
++ *((uchar **) curr_chunk)= info->del_link;
++ info->del_link= curr_chunk;
++
++ curr_chunk[info->offset_status]= CHUNK_STATUS_DELETED;
++
++ DBUG_PRINT("hp_free_chunks",("Freed position: 0x%lx", (long) curr_chunk));
++
++ if (!info->is_variable_size)
++ {
++ break;
++ }
++
++ /* Delete next chunk in this chunkset */
++ curr_chunk= *((uchar **)(curr_chunk + info->offset_link));
++ }
++}
+--- a/storage/heap/hp_extra.c
++++ b/storage/heap/hp_extra.c
+@@ -56,7 +56,6 @@
+ info->current_record= (ulong) ~0L;
+ info->current_hash_ptr=0;
+ info->update=0;
+- info->next_block=0;
+ return 0;
+ }
+
+--- a/storage/heap/hp_hash.c
++++ b/storage/heap/hp_hash.c
+@@ -336,16 +336,26 @@
+ {
+ CHARSET_INFO *cs= seg->charset;
+ uint pack_length= seg->bit_start;
+- uint length= (pack_length == 1 ? (uint) *(uchar*) pos : uint2korr(pos));
++ uint length= hp_calc_blob_length(pack_length, pos);
++
++ if (seg->flag & HA_BLOB_PART)
++ {
++ memcpy(&pos, pos + pack_length, sizeof(char *));
++ }
++ else
++ {
++ pos+= pack_length;
++ }
++
+ if (cs->mbmaxlen > 1)
+ {
+ uint char_length;
+- char_length= my_charpos(cs, pos + pack_length,
+- pos + pack_length + length,
++ char_length= my_charpos(cs, pos,
++ pos + length,
+ seg->length/cs->mbmaxlen);
+ set_if_smaller(length, char_length);
+ }
+- cs->coll->hash_sort(cs, pos+pack_length, length, &nr, &nr2);
++ cs->coll->hash_sort(cs, pos, length, &nr, &nr2);
+ }
+ else
+ {
+@@ -545,18 +555,18 @@
+ uint char_length1, char_length2;
+ uint pack_length= seg->bit_start;
+ CHARSET_INFO *cs= seg->charset;
+- if (pack_length == 1)
+- {
+- char_length1= (uint) *(uchar*) pos1++;
+- char_length2= (uint) *(uchar*) pos2++;
+- }
+- else
++
++ char_length1= hp_calc_blob_length(pack_length, pos1);
++ char_length2= hp_calc_blob_length(pack_length, pos2);
++ pos1+= pack_length;
++ pos2+= pack_length;
++
++ if (seg->flag & HA_BLOB_PART)
+ {
+- char_length1= uint2korr(pos1);
+- char_length2= uint2korr(pos2);
+- pos1+= 2;
+- pos2+= 2;
++ memcpy(&pos1, pos1, sizeof(char *));
++ memcpy(&pos2, pos2, sizeof(char *));
+ }
++
+ if (cs->mbmaxlen > 1)
+ {
+ uint safe_length1= char_length1;
+@@ -668,6 +678,34 @@
+ }
+
+
++/**
++ Returns a BLOB length stored in the specified number of bytes at the
++ specified location.
++
++ @param length the number of bytes used to store length
++ @param pos pointer to length bytes
++
++ @return Length of BLOB data.
++*/
++
++uint hp_calc_blob_length(uint bytes, const uchar *pos)
++{
++ switch (bytes) {
++ case 1:
++ return (uint) *pos;
++ case 2:
++ return uint2korr(pos);
++ case 3:
++ return uint3korr(pos);
++ case 4:
++ return uint4korr(pos);
++ default:
++ break;
++ }
++
++ return 0; /* Impossible */
++}
++
+ /* Copy a key from a record to a keybuffer */
+
+ void hp_make_key(HP_KEYDEF *keydef, uchar *key, const uchar *rec)
+@@ -678,18 +716,37 @@
+ {
+ CHARSET_INFO *cs= seg->charset;
+ uint char_length= seg->length;
+- uchar *pos= (uchar*) rec + seg->start;
++ const uchar *pos= rec + seg->start;
+ if (seg->null_bit)
+ *key++= test(rec[seg->null_pos] & seg->null_bit);
+- if (cs->mbmaxlen > 1)
++
++ if (seg->flag & HA_BLOB_PART)
+ {
+- char_length= my_charpos(cs, pos, pos + seg->length,
+- char_length / cs->mbmaxlen);
+- set_if_smaller(char_length, seg->length); /* QQ: ok to remove? */
++ uint tmp_length= hp_calc_blob_length(seg->bit_start, pos);
++ uint length= min(seg->length, tmp_length);
++
++ memcpy(&pos, rec + seg->bit_start, sizeof(char *));
++ if (cs->mbmaxlen > 1)
++ {
++ char_length= my_charpos(cs, pos, pos + seg->length,
++ char_length / cs->mbmaxlen);
++ set_if_smaller(char_length, length); /* QQ: ok to remove? */
++ }
++ store_key_length_inc(key, char_length);
+ }
+- if (seg->type == HA_KEYTYPE_VARTEXT1)
+- char_length+= seg->bit_start; /* Copy also length */
+- memcpy(key,rec+seg->start,(size_t) char_length);
++ else
++ {
++ if (cs->mbmaxlen > 1)
++ {
++ char_length= my_charpos(cs, pos, pos + seg->length,
++ char_length / cs->mbmaxlen);
++ set_if_smaller(char_length, seg->length); /* QQ: ok to remove? */
++ }
++ if (seg->type == HA_KEYTYPE_VARTEXT1)
++ char_length+= seg->bit_start; /* Copy also length */
++ }
++
++ memcpy(key, pos, (size_t) char_length);
+ key+= char_length;
+ }
+ }
+@@ -702,8 +759,8 @@
+ } while(0)
+
+
+-uint hp_rb_make_key(HP_KEYDEF *keydef, uchar *key,
+- const uchar *rec, uchar *recpos)
++uint hp_rb_make_key(HP_KEYDEF *keydef, uchar *key,
++ const uchar *rec, uchar *recpos, my_bool packed)
+ {
+ uchar *start_key= key;
+ HA_KEYSEG *seg, *endseg;
+@@ -772,6 +829,29 @@
+ key+= char_length;
+ continue;
+ }
++ else if (seg->flag & HA_BLOB_PART)
++ {
++ uchar *pos= (uchar*) rec + seg->start;
++ uint tmp_length= hp_calc_blob_length(seg->bit_start, pos);
++ uint length= min(seg->length, tmp_length);
++ CHARSET_INFO *cs= seg->charset;
++ char_length= seg->length / cs->mbmaxlen;
++
++ /* check_one_rb_key() calls hp_rb_make_key() for already packed records */
++ if (!packed)
++ {
++ memcpy(&pos, pos + seg->bit_start, sizeof(char *));
++ }
++ else
++ {
++ pos+= seg->bit_start;
++ }
++ FIX_LENGTH(cs, pos, length, char_length);
++ store_key_length_inc(key, char_length);
++ memcpy(key, pos, (size_t) char_length);
++ key+= char_length;
++ continue;
++ }
+
+ char_length= seg->length;
+ if (seg->charset->mbmaxlen > 1)
+--- a/storage/heap/hp_info.c
++++ b/storage/heap/hp_info.c
+@@ -47,9 +47,22 @@
+ {
+ DBUG_ENTER("heap_info");
+ x->records = info->s->records;
+- x->deleted = info->s->deleted;
+- x->reclength = info->s->reclength;
+- x->data_length = info->s->data_length;
++ x->deleted = info->s->recordspace.del_chunk_count;
++
++ if (info->s->recordspace.is_variable_size)
++ {
++ if (info->s->records)
++ x->reclength = (uint) (info->s->recordspace.total_data_length /
++ (ulonglong) info->s->records);
++ else
++ x->reclength = info->s->recordspace.chunk_length;
++ }
++ else
++ {
++ x->reclength = info->s->recordspace.chunk_dataspace_length;
++ }
++
++ x->data_length = info->s->recordspace.total_data_length;
+ x->index_length = info->s->index_length;
+ x->max_records = info->s->max_records;
+ x->errkey = info->errkey;
+--- a/storage/heap/hp_open.c
++++ b/storage/heap/hp_open.c
+@@ -47,9 +47,9 @@
+ #ifndef DBUG_OFF
+ info->opt_flag= READ_CHECK_USED; /* Check when changing */
+ #endif
+- DBUG_PRINT("exit",("heap: 0x%lx reclength: %d records_in_block: %d",
+- (long) info, share->reclength,
+- share->block.records_in_block));
++ DBUG_PRINT("exit",("heap: 0x%lx chunk_length: %d records_in_block: %d",
++ (long) info, share->recordspace.chunk_length,
++ share->recordspace.block.records_in_block));
+ DBUG_RETURN(info);
+ }
+
+--- /dev/null
++++ b/storage/heap/hp_record.c
+@@ -0,0 +1,498 @@
++/* Copyright (C) 2000-2002 MySQL AB
++ Copyright (C) 2008 eBay, Inc
++
++ 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 Foundation; version 2 of the License.
++
++ This program is distributed in the hope that it will be useful,
++ but WITHOUT ANY WARRANTY; without even the implied warranty of
++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ GNU General Public License for more details.
++
++ You should have received a copy of the GNU General Public License
++ along with this program; if not, write to the Free Software
++ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
++
++/*
++ Implements various base record-related functions, such as encode and decode
++ into chunks.
++*/
++
++#include "heapdef.h"
++#include <mysql_com.h>
++
++/**
++ Calculate size of the record for the purpose of storing in chunks
++
++ Walk through the fields of the record and calculates the exact space
++ needed in chunks as well the the total chunk count
++
++ @param info the hosting table
++ @param record the record in standard unpacked format
++ @param[out] chunk_count the number of chunks needed for this record
++
++ @return The size of the required storage in bytes
++*/
++
++uint hp_get_encoded_data_length(HP_SHARE *info, const uchar *record,
++ uint *chunk_count)
++{
++ uint i, dst_offset;
++
++ dst_offset= info->fixed_data_length;
++
++ if (!info->recordspace.is_variable_size)
++ {
++ /* Nothing more to copy */
++ *chunk_count= 1;
++ return dst_offset;
++ }
++
++ for (i= info->fixed_column_count; i < info->column_count; i++)
++ {
++ uint src_offset, length;
++
++ HP_COLUMNDEF *column= info->column_defs + i;
++
++ if (column->null_bit)
++ {
++ if (record[column->null_pos] & column->null_bit)
++ {
++ /* Skip all NULL values */
++ continue;
++ }
++ }
++
++ src_offset= column->offset;
++ if (column->type == MYSQL_TYPE_VARCHAR)
++ {
++ uint pack_length;
++
++ /* >= 5.0.3 true VARCHAR */
++
++ pack_length= column->length_bytes;
++ length= pack_length + (pack_length == 1 ?
++ (uint) *(uchar *) (record + src_offset) :
++ uint2korr(record + src_offset));
++ }
++ else if (column->type == MYSQL_TYPE_BLOB)
++ {
++ uint pack_length= column->length_bytes;
++
++ length= pack_length + hp_calc_blob_length(pack_length,
++ record + src_offset);
++ }
++ else
++ {
++ length= column->length;
++ }
++
++ dst_offset+= length;
++ }
++
++ *chunk_count= get_chunk_count(&info->recordspace, dst_offset);
++
++ return dst_offset;
++}
++
++
++#if !defined(DBUG_OFF) && defined(EXTRA_HEAP_DEBUG)
++static void dump_chunk(HP_SHARE *info, const uchar *curr_chunk)
++{
++ uint i;
++ fprintf(stdout, "Chunk dump at 0x%lx: ", (long) curr_chunk);
++ for (i= 0; i < info->recordspace.chunk_dataspace_length; i++)
++ {
++ uint b= *((uchar *)(curr_chunk + i));
++ if (b < 0x10)
++ {
++ fprintf(stdout, "0");
++ }
++ fprintf(stdout, "%lx ", (long) b);
++ }
++ fprintf(stdout, ". Next = 0x%lx, Status = %d\n",
++ (long) (*((uchar **) (curr_chunk + info->recordspace.offset_link))),
++ (uint) (*((uchar *) (curr_chunk + info->recordspace.offset_status))));
++}
++#endif
++
++/**
++ Stores data from packed field into the preallocated chunkset,
++ or performs data comparison
++
++ @param info the hosting table
++ @param data the field data in packed format
++ @param length the field data length
++ @param pos_ptr the target chunkset
++ @param off_ptr the pointer to the offset within the current chunkset
++ @param is_compare flag indicating whether we should compare data or store
++ it
++
++ @return Status of comparison
++ @retval non-zero if comparison found data differences
++ @retval zero otherwise
++*/
++
++static inline uint
++hp_process_field_data_to_chunkset(HP_SHARE *info, const uchar *data,
++ uint length, uchar **pos_ptr, uint *off_ptr,
++ uint is_compare)
++{
++ uint to_copy;
++ uchar *curr_chunk= *pos_ptr;
++ uint dst_offset= *off_ptr;
++ uint rc= 1;
++
++ while (length > 0)
++ {
++
++ to_copy= info->recordspace.chunk_dataspace_length - dst_offset;
++ if (to_copy == 0)
++ {
++ /* Jump to the next chunk */
++#if !defined(DBUG_OFF) && defined(EXTRA_HEAP_DEBUG)
++ dump_chunk(info, curr_chunk);
++#endif
++ curr_chunk= *((uchar **) (curr_chunk + info->recordspace.offset_link));
++ dst_offset= 0;
++ continue;
++ }
++
++ to_copy= min(length, to_copy);
++
++ if (is_compare)
++ {
++ if (memcmp(curr_chunk + dst_offset, data, (size_t) to_copy))
++ {
++ goto end;
++ }
++ }
++ else
++ {
++ memcpy(curr_chunk + dst_offset, data, (size_t) to_copy);
++ }
++
++ data+= to_copy;
++ dst_offset+= to_copy;
++ length-= to_copy;
++ }
++
++ rc= 0;
++
++end:
++ *pos_ptr= curr_chunk;
++ *off_ptr= dst_offset;
++
++ return rc;
++}
++
++/**
++ Encodes or compares record
++
++ Copies data from original unpacked record into the preallocated chunkset,
++ or performs data comparison
++
++ @param info the hosting table
++ @param record the record in standard unpacked format
++ @param pos the target chunkset
++ @param is_compare flag indicating whether we should compare data or store
++ it
++
++ @return Status of comparison
++ @retval non-zero if comparison fond data differences
++ @retval zero otherwise
++*/
++
++uint hp_process_record_data_to_chunkset(HP_SHARE *info, const uchar *record,
++ uchar *pos, uint is_compare)
++{
++ uint i, dst_offset;
++ uchar *curr_chunk= pos;
++
++ if (is_compare)
++ {
++ if (memcmp(curr_chunk, record, (size_t) info->fixed_data_length))
++ {
++ return 1;
++ }
++ }
++ else
++ {
++ memcpy(curr_chunk, record, (size_t) info->fixed_data_length);
++ }
++
++ if (!info->recordspace.is_variable_size)
++ {
++ /* Nothing more to copy */
++ return 0;
++ }
++
++ dst_offset= info->fixed_data_length;
++
++ for (i= info->fixed_column_count; i < info->column_count; i++)
++ {
++ uint length;
++ const uchar *data;
++
++ HP_COLUMNDEF *column= info->column_defs + i;
++
++ if (column->null_bit)
++ {
++ if (record[column->null_pos] & column->null_bit)
++ {
++ /* Skip all NULL values */
++ continue;
++ }
++ }
++
++ data= record + column->offset;
++ if (column->type == MYSQL_TYPE_VARCHAR)
++ {
++ uint pack_length;
++
++ /* >= 5.0.3 true VARCHAR */
++
++ /* Make sure to copy length indicator and actuals string bytes */
++ pack_length= column->length_bytes;
++ length= pack_length + (pack_length == 1 ? (uint) *data : uint2korr(data));
++ }
++ else if (column->type == MYSQL_TYPE_BLOB)
++ {
++ uint pack_length;
++
++ pack_length= column->length_bytes;
++ /* Just want to store the length, so not interested in the return code */
++ (void) hp_process_field_data_to_chunkset(info, data, pack_length,
++ &curr_chunk, &dst_offset, 0);
++ length= hp_calc_blob_length(pack_length, data);
++ memcpy(&data, data + pack_length, sizeof(char *));
++ }
++ else
++ {
++ length= column->length;
++ }
++
++ if (hp_process_field_data_to_chunkset(info, data, length, &curr_chunk,
++ &dst_offset, is_compare))
++ {
++ return 1;
++ }
++ }
++
++#if !defined(DBUG_OFF) && defined(EXTRA_HEAP_DEBUG)
++ dump_chunk(info, curr_chunk);
++#endif
++
++ return 0;
++}
++
++
++/**
++ Stores record in the heap table chunks
++
++ Copies data from original unpacked record into the preallocated chunkset
++
++ @param info the hosting table
++ @param record the record in standard unpacked format
++ @param pos the target chunkset
++*/
++
++void hp_copy_record_data_to_chunkset(HP_SHARE *info, const uchar *record,
++ uchar *pos)
++{
++ DBUG_ENTER("hp_copy_record_data_to_chunks");
++
++ hp_process_record_data_to_chunkset(info, record, pos, 0);
++
++ DBUG_VOID_RETURN;
++}
++
++
++/*
++ Macro to switch curr_chunk to the next chunk in the chunkset and reset
++ src_offset.
++*/
++#if !defined(DBUG_OFF) && defined(EXTRA_HEAP_DEBUG)
++#define SWITCH_TO_NEXT_CHUNK_FOR_READ(share, curr_chunk, src_offset) \
++ { \
++ curr_chunk= *((uchar**) (curr_chunk + share->recordspace.offset_link)); \
++ src_offset= 0; \
++ dump_chunk(share, curr_chunk); \
++ }
++#else
++#define SWITCH_TO_NEXT_CHUNK_FOR_READ(share, curr_chunk, src_offset) \
++ { \
++ curr_chunk= *((uchar**) (curr_chunk + share->recordspace.offset_link)); \
++ src_offset= 0; \
++ }
++#endif
++
++/**
++ Copies record data from storage to unpacked record format
++
++ Copies data from chunkset into its original unpacked record
++
++ @param info the hosting table
++ @param[out] record the target record in standard unpacked format
++ @param pos the source chunkset
++
++ @return Status of conversion
++ @retval 0 success
++ @retval 1 out of memory
++*/
++
++int hp_extract_record(HP_INFO *info, uchar *record, const uchar *pos)
++{
++ uint i, src_offset;
++ const uchar *curr_chunk= pos;
++ HP_SHARE *share= info->s;
++ uint *rec_offsets= NULL;
++ uint *buf_offsets= NULL;
++ uint nblobs= 0;
++ uint init_offset= share->blobs * sizeof(uint) * 2;
++
++ DBUG_ENTER("hp_extract_record");
++
++#if !defined(DBUG_OFF) && defined(EXTRA_HEAP_DEBUG)
++ if (share->recordspace.is_variable_size)
++ {
++ dump_chunk(share, curr_chunk);
++ }
++#endif
++
++ memcpy(record, curr_chunk, (size_t) share->fixed_data_length);
++
++ if (!share->recordspace.is_variable_size)
++ {
++ /* Nothing more to copy */
++ DBUG_RETURN(0);
++ }
++
++ /* Reserve space for rec_offsets and buf_offsets.*/
++ info->blob_offset= init_offset;
++ src_offset= share->fixed_data_length;
++
++ for (i= share->fixed_column_count; i < share->column_count; i++)
++ {
++ uint length, is_null= 0;
++ uchar *to;
++
++ HP_COLUMNDEF *column= share->column_defs + i;
++
++ if (column->null_bit)
++ {
++ if (record[column->null_pos] & column->null_bit)
++ {
++ is_null= 1;
++ }
++ }
++
++ if (is_null)
++ {
++ /* TODO: is memset really needed? */
++ memset(record + column->offset, 0, column->length);
++ continue;
++ }
++
++ to= record + column->offset;
++ if (column->type == MYSQL_TYPE_VARCHAR || column->type == MYSQL_TYPE_BLOB)
++ {
++ uint pack_length, i;
++ uchar *tmp= to;
++
++ pack_length= column->length_bytes;
++
++ for (i= 0; i < pack_length; i++)
++ {
++ if (src_offset == share->recordspace.chunk_dataspace_length)
++ {
++ SWITCH_TO_NEXT_CHUNK_FOR_READ(share, curr_chunk, src_offset);
++ }
++ *to++= curr_chunk[src_offset++];
++ }
++ /*
++ We copy byte-by-byte and then use hp_calc_blob_length to combine bytes
++ in the right order.
++ */
++ length= hp_calc_blob_length(pack_length, tmp);
++
++ if (column->type == MYSQL_TYPE_BLOB && length == 0)
++ {
++ /*
++ Store a zero pointer for zero-length BLOBs because the server
++ relies on that (see Field_blob::val_*().
++ */
++ *(uchar **) to= 0;
++ }
++ else if (column->type == MYSQL_TYPE_BLOB && length > 0)
++ {
++ uint newsize= info->blob_offset + length;
++
++ DBUG_ASSERT(share->blobs > 0);
++ /*
++ Make sure we have enough space in blob_buffer and store the pointer
++ to this blob in record.
++ */
++ if (info->blob_size < newsize)
++ {
++ uchar *ptr;
++ ptr= my_realloc(info->blob_buffer, newsize, MYF(MY_ALLOW_ZERO_PTR));
++ if (ptr == NULL)
++ {
++ DBUG_RETURN(1);
++ }
++
++ if (info->blob_buffer == NULL)
++ {
++ memset(ptr, 0, init_offset);
++ }
++ info->blob_buffer= ptr;
++ info->blob_size= newsize;
++ }
++
++ rec_offsets= (uint *) info->blob_buffer;
++ buf_offsets= rec_offsets + share->blobs;
++
++ rec_offsets[nblobs]= (uint) (to - record);
++ buf_offsets[nblobs]= info->blob_offset;
++ nblobs++;
++
++ /* Change 'to' so blob data is copied into blob_buffer */
++ to= info->blob_buffer + info->blob_offset;
++ info->blob_offset= newsize;
++ }
++ }
++ else
++ {
++ length= column->length;
++ }
++
++ while (length > 0)
++ {
++ uint to_copy;
++
++ to_copy= share->recordspace.chunk_dataspace_length - src_offset;
++ if (to_copy == 0)
++ {
++ SWITCH_TO_NEXT_CHUNK_FOR_READ(share, curr_chunk, src_offset);
++ to_copy= share->recordspace.chunk_dataspace_length;
++ }
++
++ to_copy= min(length, to_copy);
++
++ memcpy(to, curr_chunk + src_offset, (size_t) to_copy);
++ src_offset+= to_copy;
++ to+= to_copy;
++ length-= to_copy;
++ }
++ }
++
++ /* Store pointers to blob data in record */
++ for (i= 0; i < nblobs; i++)
++ {
++ *(uchar **) (record + rec_offsets[i]) = info->blob_buffer + buf_offsets[i];
++ }
++
++ DBUG_RETURN(0);
++}
+--- a/storage/heap/hp_rfirst.c
++++ b/storage/heap/hp_rfirst.c
+@@ -34,7 +34,10 @@
+ memcpy(&pos, pos + (*keyinfo->get_key_length)(keyinfo, pos),
+ sizeof(uchar*));
+ info->current_ptr = pos;
+- memcpy(record, pos, (size_t)share->reclength);
++ if (hp_extract_record(info, record, pos))
++ {
++ DBUG_RETURN(my_errno);
++ }
+ /*
+ If we're performing index_first on a table that was taken from
+ table cache, info->lastkey_len is initialized to previous query.
+--- a/storage/heap/hp_rkey.c
++++ b/storage/heap/hp_rkey.c
+@@ -67,7 +67,10 @@
+ if (!(keyinfo->flag & HA_NOSAME))
+ memcpy(info->lastkey, key, (size_t) keyinfo->length);
+ }
+- memcpy(record, pos, (size_t) share->reclength);
++ if (hp_extract_record(info, record, pos))
++ {
++ DBUG_RETURN(my_errno);
++ }
+ info->update= HA_STATE_AKTIV;
+ DBUG_RETURN(0);
+ }
+--- a/storage/heap/hp_rlast.c
++++ b/storage/heap/hp_rlast.c
+@@ -35,7 +35,10 @@
+ memcpy(&pos, pos + (*keyinfo->get_key_length)(keyinfo, pos),
+ sizeof(uchar*));
+ info->current_ptr = pos;
+- memcpy(record, pos, (size_t)share->reclength);
++ if (hp_extract_record(info, record, pos))
++ {
++ DBUG_RETURN(my_errno);
++ }
+ info->update = HA_STATE_AKTIV;
+ }
+ else
+--- a/storage/heap/hp_rnext.c
++++ b/storage/heap/hp_rnext.c
+@@ -109,7 +109,10 @@
+ my_errno=HA_ERR_END_OF_FILE;
+ DBUG_RETURN(my_errno);
+ }
+- memcpy(record,pos,(size_t) share->reclength);
++ if (hp_extract_record(info, record, pos))
++ {
++ DBUG_RETURN(my_errno);
++ }
+ info->update=HA_STATE_AKTIV | HA_STATE_NEXT_FOUND;
+ DBUG_RETURN(0);
+ }
+--- a/storage/heap/hp_rprev.c
++++ b/storage/heap/hp_rprev.c
+@@ -77,7 +77,10 @@
+ my_errno=HA_ERR_END_OF_FILE;
+ DBUG_RETURN(my_errno);
+ }
+- memcpy(record,pos,(size_t) share->reclength);
++ if (hp_extract_record(info, record, pos))
++ {
++ DBUG_RETURN(my_errno);
++ }
+ info->update=HA_STATE_AKTIV | HA_STATE_PREV_FOUND;
+ DBUG_RETURN(0);
+ }
+--- a/storage/heap/hp_rrnd.c
++++ b/storage/heap/hp_rrnd.c
+@@ -36,13 +36,18 @@
+ info->update= 0;
+ DBUG_RETURN(my_errno= HA_ERR_END_OF_FILE);
+ }
+- if (!info->current_ptr[share->reclength])
++ if (get_chunk_status(&share->recordspace, info->current_ptr) !=
++ CHUNK_STATUS_ACTIVE)
+ {
++ /* treat deleted and linked chunks as deleted */
+ info->update= HA_STATE_PREV_FOUND | HA_STATE_NEXT_FOUND;
+ DBUG_RETURN(my_errno=HA_ERR_RECORD_DELETED);
+ }
+ info->update=HA_STATE_PREV_FOUND | HA_STATE_NEXT_FOUND | HA_STATE_AKTIV;
+- memcpy(record,info->current_ptr,(size_t) share->reclength);
++ if (hp_extract_record(info, record, info->current_ptr))
++ {
++ DBUG_RETURN(my_errno);
++ }
+ DBUG_PRINT("exit", ("found record at 0x%lx", (long) info->current_ptr));
+ info->current_hash_ptr=0; /* Can't use rnext */
+ DBUG_RETURN(0);
+@@ -70,17 +75,17 @@
+ {
+ pos= ++info->current_record;
+ if (pos % share->block.records_in_block && /* Quick next record */
+- pos < share->records+share->deleted &&
+- (info->update & HA_STATE_PREV_FOUND))
++ pos < share->used_chunk_count + share->deleted_chunk_count &&
++ (info->update & HA_STATE_PREV_FOUND))
+ {
+- info->current_ptr+=share->block.recbuffer;
++ info->current_ptr+= share->block.recbufferlen;
+ goto end;
+ }
+ }
+ else
+ info->current_record=pos;
+
+- if (pos >= share->records+share->deleted)
++ if (pos >= share->used_chunk_count + share->deleted_chunk_count)
+ {
+ info->update= 0;
+ DBUG_RETURN(my_errno= HA_ERR_END_OF_FILE);
+@@ -90,13 +95,17 @@
+ hp_find_record(info, pos);
+
+ end:
+- if (!info->current_ptr[share->reclength])
++ if (GET_CHUNK_STATUS(info, info->current_ptr) != CHUNK_STATUS_ACTIVE)
+ {
++ /* treat deleted and linked chunks as deleted */
+ info->update= HA_STATE_PREV_FOUND | HA_STATE_NEXT_FOUND;
+ DBUG_RETURN(my_errno=HA_ERR_RECORD_DELETED);
+ }
+ info->update=HA_STATE_PREV_FOUND | HA_STATE_NEXT_FOUND | HA_STATE_AKTIV;
+- memcpy(record,info->current_ptr,(size_t) share->reclength);
++ if (hp_extract_record(info, record, info->current_ptr))
++ {
++ DBUG_RETURN(my_errno);
++ }
+ DBUG_PRINT("exit",("found record at 0x%lx",info->current_ptr));
+ info->current_hash_ptr=0; /* Can't use rnext */
+ DBUG_RETURN(0);
+--- a/storage/heap/hp_rsame.c
++++ b/storage/heap/hp_rsame.c
+@@ -31,7 +31,8 @@
+ DBUG_ENTER("heap_rsame");
+
+ test_active(info);
+- if (info->current_ptr[share->reclength])
++ if (get_chunk_status(&share->recordspace, info->current_ptr) ==
++ CHUNK_STATUS_ACTIVE)
+ {
+ if (inx < -1 || inx >= (int) share->keys)
+ {
+@@ -47,9 +48,15 @@
+ DBUG_RETURN(my_errno);
+ }
+ }
+- memcpy(record,info->current_ptr,(size_t) share->reclength);
++ if (hp_extract_record(info, record, info->current_ptr))
++ {
++ DBUG_RETURN(my_errno);
++ }
+ DBUG_RETURN(0);
+ }
++
++ /* treat deleted and linked chunks as deleted */
++
+ info->update=0;
+
+ DBUG_RETURN(my_errno=HA_ERR_RECORD_DELETED);
+--- a/storage/heap/hp_scan.c
++++ b/storage/heap/hp_scan.c
+@@ -30,7 +30,6 @@
+ info->lastinx= -1;
+ info->current_record= (ulong) ~0L; /* No current record */
+ info->update=0;
+- info->next_block=0;
+ DBUG_RETURN(0);
+ }
+
+@@ -41,32 +40,26 @@
+ DBUG_ENTER("heap_scan");
+
+ pos= ++info->current_record;
+- if (pos < info->next_block)
++ if (pos >= share->recordspace.chunk_count)
+ {
+- info->current_ptr+=share->block.recbuffer;
++ info->update= 0;
++ DBUG_RETURN(my_errno= HA_ERR_END_OF_FILE);
+ }
+- else
+- {
+- info->next_block+=share->block.records_in_block;
+- if (info->next_block >= share->records+share->deleted)
+- {
+- info->next_block= share->records+share->deleted;
+- if (pos >= info->next_block)
+- {
+- info->update= 0;
+- DBUG_RETURN(my_errno= HA_ERR_END_OF_FILE);
+- }
+- }
+- hp_find_record(info, pos);
+- }
+- if (!info->current_ptr[share->reclength])
++
++ hp_find_record(info, pos);
++
++ if (get_chunk_status(&share->recordspace, info->current_ptr) !=
++ CHUNK_STATUS_ACTIVE)
+ {
+- DBUG_PRINT("warning",("Found deleted record"));
++ DBUG_PRINT("warning",("Found deleted record or secondary chunk"));
+ info->update= HA_STATE_PREV_FOUND | HA_STATE_NEXT_FOUND;
+ DBUG_RETURN(my_errno=HA_ERR_RECORD_DELETED);
+ }
+ info->update= HA_STATE_PREV_FOUND | HA_STATE_NEXT_FOUND | HA_STATE_AKTIV;
+- memcpy(record,info->current_ptr,(size_t) share->reclength);
++ if (hp_extract_record(info, record, info->current_ptr))
++ {
++ DBUG_RETURN(my_errno);
++ }
+ info->current_hash_ptr=0; /* Can't use read_next */
+ DBUG_RETURN(0);
+ } /* heap_scan */
+--- a/storage/heap/hp_test1.c
++++ b/storage/heap/hp_test1.c
+@@ -22,6 +22,7 @@
+ #include <my_global.h>
+ #include <my_sys.h>
+ #include <m_string.h>
++#include <mysql_com.h>
+ #include "heap.h"
+
+ static int get_options(int argc, char *argv[]);
+@@ -35,6 +36,7 @@
+ uchar record[128],key[32];
+ const char *filename;
+ HP_KEYDEF keyinfo[10];
++ HP_COLUMNDEF columndef[2];
+ HA_KEYSEG keyseg[4];
+ HP_CREATE_INFO hp_create_info;
+ HP_SHARE *tmp_share;
+@@ -51,6 +53,10 @@
+ hp_create_info.reclength= 30;
+ hp_create_info.max_records= (ulong) flag*100000L;
+ hp_create_info.min_records= 10UL;
++ hp_create_info.columns= 2;
++ hp_create_info.columndef= columndef;
++ hp_create_info.fixed_key_fieldnr= 30;
++ hp_create_info.fixed_data_size= sizeof(char*) * 2;
+
+ keyinfo[0].keysegs=1;
+ keyinfo[0].seg=keyseg;
+@@ -62,11 +68,20 @@
+ keyinfo[0].seg[0].null_bit= 0;
+ keyinfo[0].flag = HA_NOSAME;
+
++ memset(columndef, 0, 2 * sizeof(HP_COLUMNDEF));
++ columndef[0].type= MYSQL_TYPE_STRING;
++ columndef[0].offset= 1;
++ columndef[0].length= 6;
++ columndef[1].type= MYSQL_TYPE_STRING;
++ columndef[1].offset= 7;
++ columndef[1].length= 23;
++
+ deleted=0;
+ bzero((uchar*) flags,sizeof(flags));
+
+ printf("- Creating heap-file\n");
+- if (heap_create(filename, &hp_create_info, &tmp_share, &unused) ||
++ if (heap_create(filename, &hp_create_info,
++ &tmp_share, &unused) ||
+ !(file= heap_open(filename, 2)))
+ goto err;
+ printf("- Writing records:s\n");
+--- a/storage/heap/hp_test2.c
++++ b/storage/heap/hp_test2.c
+@@ -18,6 +18,7 @@
+
+ #include "heapdef.h" /* Because of hp_find_block */
+ #include <signal.h>
++#include <mysql_com.h>
+
+ #define MAX_RECORDS 100000
+ #define MAX_KEYS 4
+@@ -44,6 +45,7 @@
+ register uint i,j;
+ uint ant,n1,n2,n3;
+ uint write_count,update,opt_delete,check2,dupp_keys,found_key;
++ uint mem_per_keys;
+ int error;
+ ulong pos;
+ unsigned long key_check;
+@@ -53,6 +55,7 @@
+ HP_SHARE *tmp_share;
+ HP_KEYDEF keyinfo[MAX_KEYS];
+ HA_KEYSEG keyseg[MAX_KEYS*5];
++ HP_COLUMNDEF columndef[4];
+ HEAP_PTR UNINIT_VAR(position);
+ HP_CREATE_INFO hp_create_info;
+ CHARSET_INFO *cs= &my_charset_latin1;
+@@ -65,12 +68,16 @@
+ get_options(argc,argv);
+
+ bzero(&hp_create_info, sizeof(hp_create_info));
+- hp_create_info.max_table_size= 1024L*1024L;
++ hp_create_info.max_table_size= 1024L*1024L*1024L;
+ hp_create_info.keys= keys;
+ hp_create_info.keydef= keyinfo;
+ hp_create_info.reclength= reclength;
+ hp_create_info.max_records= (ulong) flag*100000L;
+ hp_create_info.min_records= (ulong) recant/2;
++ hp_create_info.columns= 4;
++ hp_create_info.columndef= columndef;
++ hp_create_info.fixed_key_fieldnr= 4;
++ hp_create_info.fixed_data_size= 39;
+
+ write_count=update=opt_delete=0;
+ key_check=0;
+@@ -118,11 +125,30 @@
+ keyinfo[3].seg[0].null_pos=38;
+ keyinfo[3].seg[0].charset=cs;
+
++ memset(columndef, 0, 4 * sizeof(HP_COLUMNDEF));
++ columndef[0].type= MYSQL_TYPE_STRING;
++ columndef[0].offset= 0;
++ columndef[0].length= 6;
++ columndef[1].type= MYSQL_TYPE_STRING;
++ columndef[1].offset= 7;
++ columndef[1].length= 6;
++ columndef[2].type= MYSQL_TYPE_STRING;
++ columndef[2].offset= 12;
++ columndef[2].length= 8;
++ columndef[3].type= MYSQL_TYPE_TINY;
++ columndef[3].offset= 37;
++ columndef[3].length= 1;
++ columndef[3].null_bit= 1;
++ columndef[3].null_pos= 38;
++
++ mem_per_keys= (sizeof(char*) * 2) * 4;
++
+ bzero((char*) key1,sizeof(key1));
+ bzero((char*) key3,sizeof(key3));
+
+ printf("- Creating heap-file\n");
+- if (heap_create(filename, &hp_create_info, &tmp_share, &unused) ||
++ if (heap_create(filename, &hp_create_info,
++ &tmp_share, &unused) ||
+ !(file= heap_open(filename, 2)))
+ goto err;
+ signal(SIGINT,endprog);
+--- a/storage/heap/hp_write.c
++++ b/storage/heap/hp_write.c
+@@ -26,7 +26,6 @@
+ #define HIGHFIND 4
+ #define HIGHUSED 8
+
+-static uchar *next_free_record_pos(HP_SHARE *info);
+ static HASH_INFO *hp_find_free_hash(HP_SHARE *info, HP_BLOCK *block,
+ ulong records);
+
+@@ -35,6 +34,8 @@
+ HP_KEYDEF *keydef, *end;
+ uchar *pos;
+ HP_SHARE *share=info->s;
++ uint rec_length, chunk_count;
++
+ DBUG_ENTER("heap_write");
+ #ifndef DBUG_OFF
+ if (info->mode & O_RDONLY)
+@@ -42,7 +43,18 @@
+ DBUG_RETURN(my_errno=EACCES);
+ }
+ #endif
+- if (!(pos=next_free_record_pos(share)))
++
++ if ((share->records >= share->max_records && share->max_records) ||
++ (share->recordspace.total_data_length + share->index_length >=
++ share->max_table_size))
++ {
++ my_errno= HA_ERR_RECORD_FILE_FULL;
++ DBUG_RETURN(my_errno);
++ }
++
++ rec_length= hp_get_encoded_data_length(share, record, &chunk_count);
++
++ if (!(pos= hp_allocate_chunkset(&share->recordspace, chunk_count)))
+ DBUG_RETURN(my_errno);
+ share->changed=1;
+
+@@ -53,8 +65,8 @@
+ goto err;
+ }
+
+- memcpy(pos,record,(size_t) share->reclength);
+- pos[share->reclength]=1; /* Mark record as not deleted */
++ hp_copy_record_data_to_chunkset(share, record, pos);
++
+ if (++share->records == share->blength)
+ share->blength+= share->blength;
+ info->current_ptr=pos;
+@@ -88,10 +100,7 @@
+ keydef--;
+ }
+
+- share->deleted++;
+- *((uchar**) pos)=share->del_link;
+- share->del_link=pos;
+- pos[share->reclength]=0; /* Record deleted */
++ hp_free_chunks(&share->recordspace, pos);
+
+ DBUG_RETURN(my_errno);
+ } /* heap_write */
+@@ -107,7 +116,8 @@
+ uint old_allocated;
+
+ custom_arg.keyseg= keyinfo->seg;
+- custom_arg.key_length= hp_rb_make_key(keyinfo, info->recbuf, record, recpos);
++ custom_arg.key_length= hp_rb_make_key(keyinfo, info->recbuf, record, recpos,
++ FALSE);
+ if (keyinfo->flag & HA_NOSAME)
+ {
+ custom_arg.search_flag= SEARCH_FIND | SEARCH_UPDATE;
+@@ -129,42 +139,6 @@
+ return 0;
+ }
+
+- /* Find where to place new record */
+-
+-static uchar *next_free_record_pos(HP_SHARE *info)
+-{
+- int block_pos;
+- uchar *pos;
+- size_t length;
+- DBUG_ENTER("next_free_record_pos");
+-
+- if (info->del_link)
+- {
+- pos=info->del_link;
+- info->del_link= *((uchar**) pos);
+- info->deleted--;
+- DBUG_PRINT("exit",("Used old position: 0x%lx",(long) pos));
+- DBUG_RETURN(pos);
+- }
+- if (!(block_pos=(info->records % info->block.records_in_block)))
+- {
+- if ((info->records > info->max_records && info->max_records) ||
+- (info->data_length + info->index_length >= info->max_table_size))
+- {
+- my_errno=HA_ERR_RECORD_FILE_FULL;
+- DBUG_RETURN(NULL);
+- }
+- if (hp_get_new_block(&info->block,&length))
+- DBUG_RETURN(NULL);
+- info->data_length+=length;
+- }
+- DBUG_PRINT("exit",("Used new position: 0x%lx",
+- (long) ((uchar*) info->block.level_info[0].last_blocks+
+- block_pos * info->block.recbuffer)));
+- DBUG_RETURN((uchar*) info->block.level_info[0].last_blocks+
+- block_pos*info->block.recbuffer);
+-}
+-
+
+ /*
+ Write a hash-key to the hash-index
+--- a/storage/heap/hp_update.c
++++ b/storage/heap/hp_update.c
+@@ -17,43 +17,66 @@
+
+ #include "heapdef.h"
+
+-int heap_update(HP_INFO *info, const uchar *old, const uchar *heap_new)
++int heap_update(HP_INFO *info, const uchar *old_record, const uchar *new_record)
+ {
+ HP_KEYDEF *keydef, *end, *p_lastinx;
+ uchar *pos;
+ my_bool auto_key_changed= 0;
+ HP_SHARE *share= info->s;
++ uint old_length, new_length;
++ uint old_chunk_count, new_chunk_count;
++
+ DBUG_ENTER("heap_update");
+
+ test_active(info);
+ pos=info->current_ptr;
+
+- if (info->opt_flag & READ_CHECK_USED && hp_rectest(info,old))
++ if (info->opt_flag & READ_CHECK_USED && hp_rectest(info, old_record))
+ DBUG_RETURN(my_errno); /* Record changed */
++
++ old_length = hp_get_encoded_data_length(share, old_record, &old_chunk_count);
++ new_length = hp_get_encoded_data_length(share, new_record, &new_chunk_count);
++
++ if (new_chunk_count > old_chunk_count)
++ {
++ /* extend the old chunkset size as necessary, but do not shrink yet */
++ if (hp_reallocate_chunkset(&share->recordspace, new_chunk_count, pos))
++ {
++ DBUG_RETURN(my_errno); /* Out of memory or table space */
++ }
++ }
++
+ if (--(share->records) < share->blength >> 1) share->blength>>= 1;
+ share->changed=1;
+
+ p_lastinx= share->keydef + info->lastinx;
+ for (keydef= share->keydef, end= keydef + share->keys; keydef < end; keydef++)
+ {
+- if (hp_rec_key_cmp(keydef, old, heap_new, 0))
++ if (hp_rec_key_cmp(keydef, old_record, new_record, 0))
+ {
+- if ((*keydef->delete_key)(info, keydef, old, pos, keydef == p_lastinx) ||
+- (*keydef->write_key)(info, keydef, heap_new, pos))
++ if ((*keydef->delete_key)(info, keydef, old_record, pos,
++ keydef == p_lastinx) ||
++ (*keydef->write_key)(info, keydef, new_record, pos))
+ goto err;
+ if (share->auto_key == (uint) (keydef - share->keydef + 1))
+ auto_key_changed= 1;
+ }
+ }
+
+- memcpy(pos,heap_new,(size_t) share->reclength);
++ hp_copy_record_data_to_chunkset(share, new_record, pos);
+ if (++(share->records) == share->blength) share->blength+= share->blength;
+
++ if (new_chunk_count < old_chunk_count)
++ {
++ /* Shrink the chunkset to its new size */
++ hp_reallocate_chunkset(&share->recordspace, new_chunk_count, pos);
++ }
++
+ #if !defined(DBUG_OFF) && defined(EXTRA_HEAP_DEBUG)
+ DBUG_EXECUTE("check_heap",heap_check_heap(info, 0););
+ #endif
+ if (auto_key_changed)
+- heap_update_auto_increment(info, heap_new);
++ heap_update_auto_increment(info, new_record);
+ DBUG_RETURN(0);
+
+ err:
+@@ -63,7 +86,7 @@
+ if (keydef->algorithm == HA_KEY_ALG_BTREE)
+ {
+ /* we don't need to delete non-inserted key from rb-tree */
+- if ((*keydef->write_key)(info, keydef, old, pos))
++ if ((*keydef->write_key)(info, keydef, old_record, pos))
+ {
+ if (++(share->records) == share->blength)
+ share->blength+= share->blength;
+@@ -73,10 +96,10 @@
+ }
+ while (keydef >= share->keydef)
+ {
+- if (hp_rec_key_cmp(keydef, old, heap_new, 0))
++ if (hp_rec_key_cmp(keydef, old_record, new_record, 0))
+ {
+- if ((*keydef->delete_key)(info, keydef, heap_new, pos, 0) ||
+- (*keydef->write_key)(info, keydef, old, pos))
++ if ((*keydef->delete_key)(info, keydef, new_record, pos, 0) ||
++ (*keydef->write_key)(info, keydef, old_record, pos))
+ break;
+ }
+ keydef--;
+@@ -84,5 +107,12 @@
+ }
+ if (++(share->records) == share->blength)
+ share->blength+= share->blength;
++
++ if (new_chunk_count > old_chunk_count)
++ {
++ /* Shrink the chunkset to its original size */
++ hp_reallocate_chunkset(&share->recordspace, old_chunk_count, pos);
++ }
++
+ DBUG_RETURN(my_errno);
+ } /* heap_update */
#!!! notice !!!
# Any small change to this file in the main branch
# should be done or reviewed by the maintainer!
-diff -ruN /dev/null b/patch_info/microsec_process.info
---- /dev/null 1970-01-01 09:00:00.000000000 +0900
-+++ b/patch_info/microsec_process.info 2010-12-02 20:41:41.616069579 +0900
+--- /dev/null
++++ b/patch_info/microsec_process.info
@@ -0,0 +1,8 @@
+File=microsec_process.patch
+Name=Adds INFOMATION_SCHEMA.PROCESSLIST with TIME_MS column
+Comment=
+2010-01
+Ported to 5.1.42
-diff -ruN a/sql/sql_show.cc b/sql/sql_show.cc
---- a/sql/sql_show.cc 2010-12-02 19:22:40.054024541 +0900
-+++ b/sql/sql_show.cc 2010-12-02 20:41:41.622941425 +0900
+--- a/sql/sql_show.cc
++++ b/sql/sql_show.cc
@@ -1890,7 +1890,8 @@
TABLE *table= tables->table;
CHARSET_INFO *cs= system_charset_info;
if (schema_table_store_record(thd, table))
{
mysql_mutex_unlock(&LOCK_thread_count);
-@@ -7409,6 +7414,8 @@
+@@ -7441,6 +7446,8 @@
{"STATE", 64, MYSQL_TYPE_STRING, 0, 1, "State", SKIP_OPEN_TABLE},
{"INFO", PROCESS_LIST_INFO_WIDTH, MYSQL_TYPE_STRING, 0, 1, "Info",
SKIP_OPEN_TABLE},
Summary(uk.UTF-8): MySQL - швидкий SQL-сервер
Summary(zh_CN.UTF-8): MySQL数据库服务器
Name: mysql
-Version: 5.5.13
-Release: 5
+Version: 5.5.15
+Release: 1
License: GPL + MySQL FLOSS Exception
Group: Applications/Databases
# Source0Download: http://dev.mysql.com/downloads/mysql/5.5.html#downloads
Source0: http://vesta.informatik.rwth-aachen.de/mysql/Downloads/MySQL-5.5/%{name}-%{version}.tar.gz
-# Source0-md5: f0e519e90ee7c00fceb0730edf859d7b
+# Source0-md5: 306b5549c7bd72e8e705a890db0da82b
Source100: http://www.sphinxsearch.com/downloads/sphinx-0.9.9.tar.gz
# Source100-md5: 7b9b618cb9b378f949bb1b91ddcc4f54
Source1: %{name}.init
Patch148: start-stop-messages.patch
Patch149: file-contents.patch
Patch150: slave_timeout_fix.patch
+Patch151: utf8_general50_ci.patch
+Patch152: bug813587.patch
+Patch153: valgrind_zlib_suppression.patch
+Patch154: memory_dynamic_rows.patch
# </percona>
URL: http://www.mysql.com/products/community/
BuildRequires: bison
%patch148 -p1
%patch149 -p1
%patch150 -p1
+%patch151 -p1
+%patch152 -p1
+%patch153 -p1
+%patch154 -p1
# </percona>
# to get these files rebuild
#!!! notice !!!
# Any small change to this file in the main branch
# should be done or reviewed by the maintainer!
-diff -ruN a/client/client_priv.h b/client/client_priv.h
---- a/client/client_priv.h 2011-04-09 18:48:54.000000000 +0400
-+++ b/client/client_priv.h 2011-04-09 18:49:03.000000000 +0400
-@@ -87,6 +87,7 @@
+--- a/client/client_priv.h
++++ b/client/client_priv.h
+@@ -89,6 +89,7 @@
OPT_SYSLOG,
#endif
OPT_PLUGIN_DIR,
OPT_DEFAULT_AUTH,
OPT_DEFAULT_PLUGIN,
OPT_MAX_CLIENT_OPTION
-diff -ruN a/client/mysql.cc b/client/mysql.cc
---- a/client/mysql.cc 2011-04-09 18:48:54.000000000 +0400
-+++ b/client/mysql.cc 2011-04-09 18:49:03.000000000 +0400
-@@ -133,6 +133,8 @@
+--- a/client/mysql.cc
++++ b/client/mysql.cc
+@@ -135,6 +135,8 @@
enum enum_info_type { INFO_INFO,INFO_ERROR,INFO_RESULT};
typedef enum enum_info_type INFO_TYPE;
static MYSQL mysql; /* The connection */
static my_bool ignore_errors=0,wait_flag=0,quick=0,
connected=0,opt_raw_data=0,unbuffered=0,output_tables=0,
-@@ -1452,6 +1454,10 @@
+@@ -1454,6 +1456,10 @@
NO_ARG, 1, 0, 0, 0, 0, 0},
{"skip-line-numbers", 'L', "Don't write line number for errors.", 0, 0, 0, GET_NO_ARG,
NO_ARG, 0, 0, 0, 0, 0, 0},
{"unbuffered", 'n', "Flush buffer after each query.", &unbuffered,
&unbuffered, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
{"column-names", OPT_COLUMN_NAMES, "Write column names in results.",
-diff -ruN a/client/readline.cc b/client/readline.cc
---- a/client/readline.cc 2011-04-09 18:48:03.000000000 +0400
-+++ b/client/readline.cc 2011-04-09 18:49:03.000000000 +0400
-@@ -21,6 +21,8 @@
+--- a/client/readline.cc
++++ b/client/readline.cc
+@@ -23,6 +23,8 @@
#include <my_dir.h>
#include "my_readline.h"
static bool init_line_buffer(LINE_BUFFER *buffer,File file,ulong size,
ulong max_size);
static bool init_line_buffer_from_string(LINE_BUFFER *buffer,char * str);
-@@ -60,7 +62,7 @@
+@@ -62,7 +64,7 @@
if (!(pos=intern_read_line(line_buff, &out_length)))
return 0;
if (out_length && pos[out_length-1] == '\n')
out_length--; /* Remove '\r' */
line_buff->read_length=out_length;
pos[out_length]=0;
-diff -ruN /dev/null b/patch_info/mysql_remove_eol_carret.patch
---- /dev/null 1970-01-01 00:00:00.000000000 +0000
-+++ b/patch_info/mysql_remove_eol_carret.patch 2011-04-09 18:49:03.000000000 +0400
+--- /dev/null
++++ b/patch_info/mysql_remove_eol_carret.patch
@@ -0,0 +1,7 @@
+File=mysql_remove_eol_carret.patch
+Name=
#!!! notice !!!
# Any small change to this file in the main branch
# should be done or reviewed by the maintainer!
-diff -ruN a/client/client_priv.h b/client/client_priv.h
---- a/client/client_priv.h 2011-04-09 18:48:18.000000000 +0400
-+++ b/client/client_priv.h 2011-04-09 18:48:54.000000000 +0400
-@@ -83,6 +83,9 @@
+--- a/client/client_priv.h
++++ b/client/client_priv.h
+@@ -85,6 +85,9 @@
OPT_DEBUG_INFO, OPT_DEBUG_CHECK, OPT_COLUMN_TYPES, OPT_ERROR_LOG_FILE,
OPT_WRITE_BINLOG, OPT_DUMP_DATE,
OPT_INIT_COMMAND,
OPT_PLUGIN_DIR,
OPT_DEFAULT_AUTH,
OPT_DEFAULT_PLUGIN,
-diff -ruN a/client/mysql.cc b/client/mysql.cc
---- a/client/mysql.cc 2011-04-09 18:48:04.000000000 +0400
-+++ b/client/mysql.cc 2011-04-09 18:48:54.000000000 +0400
-@@ -38,6 +38,11 @@
+--- a/client/mysql.cc
++++ b/client/mysql.cc
+@@ -40,6 +40,11 @@
#include "my_readline.h"
#include <signal.h>
#include <violite.h>
#if defined(USE_LIBEDIT_INTERFACE) && defined(HAVE_LOCALE_H)
#include <locale.h>
-@@ -140,7 +145,7 @@
+@@ -142,7 +147,7 @@
default_pager_set= 0, opt_sigint_ignore= 0,
auto_vertical_output= 0,
show_warnings= 0, executing_query= 0, interrupted_query= 0,
static my_bool debug_info_flag, debug_check_flag;
static my_bool column_types_flag;
static my_bool preserve_comments= 0;
-@@ -198,6 +203,7 @@
+@@ -200,6 +205,7 @@
void tee_fputs(const char *s, FILE *file);
void tee_puts(const char *s, FILE *file);
void tee_putc(int c, FILE *file);
static void tee_print_sized_data(const char *, unsigned int, unsigned int, bool);
/* The names of functions that actually do the manipulation. */
static int get_options(int argc,char **argv);
-@@ -1563,6 +1569,10 @@
+@@ -1565,6 +1571,10 @@
{"show-warnings", OPT_SHOW_WARNINGS, "Show warnings after every statement.",
&show_warnings, &show_warnings, 0, GET_BOOL, NO_ARG,
0, 0, 0, 0, 0, 0},
+ NO_ARG, 0, 0, 0, 0, 0, 0},
+#endif
{"plugin_dir", OPT_PLUGIN_DIR, "Directory for client-side plugins.",
- (uchar**) &opt_plugin_dir, (uchar**) &opt_plugin_dir, 0,
+ &opt_plugin_dir, &opt_plugin_dir, 0,
GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
-@@ -1667,6 +1677,11 @@
+@@ -1669,6 +1679,11 @@
opt->name);
#endif
break;
case OPT_SERVER_ARG:
#ifdef EMBEDDED_LIBRARY
/*
-@@ -2020,6 +2035,40 @@
+@@ -2022,6 +2037,40 @@
DBUG_RETURN((COMMANDS *) 0);
}
static bool add_line(String &buffer,char *line,char *in_string,
bool *ml_comment, bool truncated)
-@@ -2996,6 +3045,11 @@
+@@ -2998,6 +3047,11 @@
fix_history(buffer);
}
#endif
#!!! notice !!!
# Any small change to this file in the main branch
# should be done or reviewed by the maintainer!
-diff -ruN /dev/null b/patch_info/optimizer_fix.info
---- /dev/null 1970-01-01 09:00:00.000000000 +0900
-+++ b/patch_info/optimizer_fix.info 2010-12-02 20:47:55.781968475 +0900
+--- /dev/null
++++ b/patch_info/optimizer_fix.info
@@ -0,0 +1,8 @@
+File=optimizer_fix.patch
+Name=Unofficial optimizer fixes
+Comment=
+2010-01
+Ported to 5.1.42
-diff -ruN a/sql/mysqld.cc b/sql/mysqld.cc
---- a/sql/mysqld.cc 2010-12-02 19:22:40.027024953 +0900
-+++ b/sql/mysqld.cc 2010-12-02 20:51:50.811356434 +0900
-@@ -425,6 +425,7 @@
- uint opt_debug_sync_timeout= 0;
+--- a/sql/mysqld.cc
++++ b/sql/mysqld.cc
+@@ -430,6 +430,7 @@
+ MYSQL_PLUGIN_IMPORT uint opt_debug_sync_timeout= 0;
#endif /* defined(ENABLED_DEBUG_SYNC) */
my_bool opt_old_style_user_limits= 0, trust_function_creators= 0;
+my_bool opt_optimizer_fix= 0;
/*
True if there is at least one per-hour limit for some user, so we should
check them before each query (and possibly reset counters when hour is
-diff -ruN a/sql/mysqld.h b/sql/mysqld.h
---- a/sql/mysqld.h 2010-11-03 07:01:14.000000000 +0900
-+++ b/sql/mysqld.h 2010-12-02 20:51:10.392070356 +0900
+--- a/sql/mysqld.h
++++ b/sql/mysqld.h
@@ -109,6 +109,7 @@
extern ulonglong slave_type_conversions_options;
extern my_bool read_only, opt_readonly;
extern my_bool opt_enable_named_pipe, opt_sync_frm, opt_allow_suspicious_udfs;
extern my_bool opt_secure_auth;
extern char* opt_secure_file_priv;
-diff -ruN a/sql/opt_range.cc b/sql/opt_range.cc
---- a/sql/opt_range.cc 2010-11-03 07:01:14.000000000 +0900
-+++ b/sql/opt_range.cc 2010-12-02 20:47:55.795969853 +0900
+--- a/sql/opt_range.cc
++++ b/sql/opt_range.cc
@@ -727,7 +727,7 @@
static TRP_RANGE *get_key_scans_params(PARAM *param, SEL_TREE *tree,
bool index_read_must_be_used,
DBUG_RETURN(read_plan);
}
-diff -ruN a/sql/sql_select.cc b/sql/sql_select.cc
---- a/sql/sql_select.cc 2010-11-03 07:01:14.000000000 +0900
-+++ b/sql/sql_select.cc 2010-12-02 20:47:55.813953789 +0900
+--- a/sql/sql_select.cc
++++ b/sql/sql_select.cc
@@ -2619,6 +2619,11 @@
table->reginfo.impossible_range=1;
DBUG_RETURN(0);
DBUG_PRINT("warning",("Couldn't use record count on const keypart"));
}
DBUG_RETURN(HA_POS_ERROR); /* This shouldn't happend */
-diff -ruN a/sql/sys_vars.cc b/sql/sys_vars.cc
---- a/sql/sys_vars.cc 2010-12-02 20:31:56.208023606 +0900
-+++ b/sql/sys_vars.cc 2010-12-02 21:17:44.618120277 +0900
+--- a/sql/sys_vars.cc
++++ b/sql/sys_vars.cc
@@ -2180,6 +2180,12 @@
VALID_RANGE(1, IF_WIN(INT_MAX32/1000, LONG_TIMEOUT)),
DEFAULT(NET_WAIT_TIMEOUT), BLOCK_SIZE(1));
> .percona.spec
> .patch.spec
i=100
-for patch in $(cat $version/series | filter_names); do
+[ -d "$version/patches" ] && dir=$version/patches || dir=$version
+for patch in $(cat $dir/series | filter_names); do
# if patch already existed, use mysql- prefix
if [ -f mysql-$patch ]; then
file=mysql-$patch
else
file=$patch
fi
- cat $version/$patch | filter_files > $file
+ cat $dir/$patch | filter_files > $file
if [ -z "$(awk -vfile=$file -F/ '$2 == file{print}' CVS/Entries)" ]; then
cvs add $file
#!!! notice !!!
# Any small change to this file in the main branch
# should be done or reviewed by the maintainer!
-diff -ruN a/scripts/mysql_install_db.sh b/scripts/mysql_install_db.sh
---- a/scripts/mysql_install_db.sh 2009-08-08 09:20:07.000000000 +0000
-+++ b/scripts/mysql_install_db.sh 2009-08-08 09:29:23.000000000 +0000
-@@ -475,6 +475,9 @@
+--- a/scripts/mysql_install_db.sh
++++ b/scripts/mysql_install_db.sh
+@@ -476,6 +476,9 @@
echo
echo "Please report any problems with the $scriptdir/mysqlbug script!"
echo
#!!! notice !!!
# Any small change to this file in the main branch
# should be done or reviewed by the maintainer!
-diff -ruN a/sql/sql_class.cc b/sql/sql_class.cc
---- a/sql/sql_class.cc 2011-03-09 17:07:26.221709282 +0200
-+++ b/sql/sql_class.cc 2011-03-09 17:07:44.900164285 +0200
-@@ -2017,6 +2017,7 @@
+--- a/sql/sql_class.cc
++++ b/sql/sql_class.cc
+@@ -2288,6 +2288,7 @@
thd->sent_row_count++;
thd->sent_row_count_2++;
if (thd->vio_ok())
DBUG_RETURN(protocol->write());
-diff -ruN a/sql/sql_show.cc b/sql/sql_show.cc
---- a/sql/sql_show.cc 2011-03-09 17:07:26.251706801 +0200
-+++ b/sql/sql_show.cc 2011-03-09 17:07:44.904163954 +0200
+--- a/sql/sql_show.cc
++++ b/sql/sql_show.cc
@@ -1766,7 +1766,8 @@
/****************************************************************************
if (schema_table_store_record(thd, table))
{
mysql_mutex_unlock(&LOCK_thread_count);
-@@ -8082,6 +8108,12 @@
+@@ -8117,6 +8143,12 @@
SKIP_OPEN_TABLE},
{"TIME_MS", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONGLONG,
0, 0, "Time_ms", SKIP_OPEN_TABLE},
#!!! notice !!!
# Any small change to this file in the main branch
# should be done or reviewed by the maintainer!
-diff -ruN /dev/null b/patch_info/query_cache_enhance.patch
---- /dev/null 1970-01-01 00:00:00.000000000 +0000
-+++ b/patch_info/query_cache_enhance.patch 2011-04-09 18:48:53.000000000 +0400
+--- /dev/null
++++ b/patch_info/query_cache_enhance.patch
@@ -0,0 +1,15 @@
+File=query_cache_enhance.patch
+Name= query cache Percona's cumulative patch
+2010-07 - Fix incorrect behavior diff (query_cache_with_comments.patch)
+2010-09 - Merge patches to one
+2010-11 - Ported to 5.5
-diff -ruN a/sql/mysqld.cc b/sql/mysqld.cc
---- a/sql/mysqld.cc 2011-04-09 18:48:50.000000000 +0400
-+++ b/sql/mysqld.cc 2011-04-09 18:48:53.000000000 +0400
-@@ -899,6 +899,7 @@
+--- a/sql/mysqld.cc
++++ b/sql/mysqld.cc
+@@ -904,6 +904,7 @@
#endif
#ifdef HAVE_QUERY_CACHE
ulong query_cache_min_res_unit= QUERY_CACHE_MIN_RESULT_DATA_SIZE;
Query_cache query_cache;
#endif
#ifdef HAVE_SMEM
-diff -ruN a/sql/mysqld.h b/sql/mysqld.h
---- a/sql/mysqld.h 2011-04-09 18:48:50.000000000 +0400
-+++ b/sql/mysqld.h 2011-04-09 18:48:53.000000000 +0400
+--- a/sql/mysqld.h
++++ b/sql/mysqld.h
@@ -91,6 +91,7 @@
extern my_bool opt_log, opt_slow_log;
extern my_bool opt_backup_history_log;
extern ulonglong log_output_options;
extern ulong log_backup_output_options;
extern my_bool opt_log_queries_not_using_indexes;
-diff -ruN /dev/null b/sql/query_strip_comments.h
---- /dev/null 1970-01-01 00:00:00.000000000 +0000
-+++ b/sql/query_strip_comments.h 2011-04-09 18:48:53.000000000 +0400
+--- /dev/null
++++ b/sql/query_strip_comments.h
@@ -0,0 +1,37 @@
+#ifndef _SQL_QUERY_STRIPC_COMMENTS_H_
+#define _SQL_QUERY_STRIPC_COMMENTS_H_
+
+#endif // HAVE_QUERY_CACHE
+#endif // _SQL_QUERY_STRIPC_COMMENTS_H_
-diff -ruN a/sql/sql_cache.cc b/sql/sql_cache.cc
---- a/sql/sql_cache.cc 2011-04-09 18:48:50.000000000 +0400
-+++ b/sql/sql_cache.cc 2011-04-09 18:48:53.000000000 +0400
+--- a/sql/sql_cache.cc
++++ b/sql/sql_cache.cc
@@ -344,6 +344,181 @@
#include "probes_mysql.h"
#include "transaction.h"
#ifdef EMBEDDED_LIBRARY
#include "emb_qcache.h"
#endif
-@@ -454,7 +629,12 @@
+@@ -454,7 +629,14 @@
Query_cache_wait_state wait_state(thd, __func__, __FILE__, __LINE__);
DBUG_ENTER("Query_cache::try_lock");
+ const char* old_proc_info= thd->proc_info;
+ thd_proc_info(thd,"Waiting on query cache mutex");
mysql_mutex_lock(&structure_guard_mutex);
-+ DBUG_EXECUTE_IF("status_wait_query_cache_mutex_sleep", {
-+ sleep(5);
++ DEBUG_SYNC(thd, "status_waiting_on_query_cache_mutex");
++ DBUG_EXECUTE_IF("status_waiting_on_query_cache_mutex_sleep", {
++ sleep(1);
+ });
++ thd->proc_info = old_proc_info;
while (1)
{
if (m_cache_lock_status == Query_cache::UNLOCKED)
-@@ -501,6 +681,7 @@
- }
- }
- mysql_mutex_unlock(&structure_guard_mutex);
-+ thd->proc_info = old_proc_info;
-
- DBUG_RETURN(interrupt);
- }
-@@ -1274,6 +1455,8 @@
+@@ -1274,6 +1456,8 @@
unlock();
DBUG_VOID_RETURN;
}
/* Key is query + database + flag */
if (thd->db_length)
-@@ -1451,6 +1634,9 @@
+@@ -1451,6 +1635,9 @@
Query_cache_block_table *block_table, *block_table_end;
ulong tot_length;
Query_cache_query_flags flags;
DBUG_ENTER("Query_cache::send_result_to_client");
/*
-@@ -1472,21 +1658,103 @@
+@@ -1472,21 +1659,103 @@
{
uint i= 0;
if ((my_toupper(system_charset_info, sql[i]) != 'S' ||
my_toupper(system_charset_info, sql[i + 1]) != 'E' ||
my_toupper(system_charset_info, sql[i + 2]) != 'L') &&
-@@ -1521,6 +1789,12 @@
+@@ -1521,6 +1790,12 @@
goto err_unlock;
Query_cache_block *query_block;
tot_length= query_length + thd->db_length + 1 + QUERY_CACHE_FLAGS_SIZE;
if (thd->db_length)
-@@ -1587,6 +1861,8 @@
+@@ -1587,6 +1862,8 @@
(uchar*) &flags, QUERY_CACHE_FLAGS_SIZE);
query_block = (Query_cache_block *) my_hash_search(&queries, (uchar*) sql,
tot_length);
/* Quick abort on unlocked data */
if (query_block == 0 ||
query_block->query()->result() == 0 ||
-diff -ruN a/sql/sql_class.h b/sql/sql_class.h
---- a/sql/sql_class.h 2011-04-09 18:48:50.000000000 +0400
-+++ b/sql/sql_class.h 2011-04-09 18:48:53.000000000 +0400
+--- a/sql/sql_class.h
++++ b/sql/sql_class.h
@@ -40,6 +40,9 @@
#include "thr_lock.h" /* thr_lock_type, THR_LOCK_DATA,
THR_LOCK_INFO */
/*
MARK_COLUMNS_NONE: Means mark_used_colums is not set and no indicator to
-diff -ruN a/sql/sys_vars.cc b/sql/sys_vars.cc
---- a/sql/sys_vars.cc 2011-04-09 18:48:50.000000000 +0400
-+++ b/sql/sys_vars.cc 2011-04-09 18:48:53.000000000 +0400
+--- a/sql/sys_vars.cc
++++ b/sql/sys_vars.cc
@@ -1786,6 +1786,11 @@
NO_MUTEX_GUARD, NOT_IN_BINLOG, ON_CHECK(0),
ON_UPDATE(fix_query_cache_size));
#!!! notice !!!
# Any small change to this file in the main branch
# should be done or reviewed by the maintainer!
-diff -ruN a/patch_info/remove_fcntl_excessive_calls.info b/patch_info/remove_fcntl_excessive_calls.info
---- a/patch_info/remove_fcntl_excessive_calls.info 1970-01-01 03:00:00.000000000 +0300
-+++ b/patch_info/remove_fcntl_excessive_calls.info 2010-07-22 21:42:08.560424001 +0400
+--- /dev/null
++++ b/patch_info/remove_fcntl_excessive_calls.info
@@ -0,0 +1,6 @@
+File=remove_fcntl_excessive_calls.patch
+Name=remove fcntl excessive calls
+Author=This is a port of the official fix.
+License=GPL
+Comment=
-diff -ruN a/sql/net_serv.cc b/sql/net_serv.cc
---- a/sql/net_serv.cc 2010-06-03 19:50:27.000000000 +0400
-+++ b/sql/net_serv.cc 2010-07-22 21:40:30.680424001 +0400
+--- a/sql/net_serv.cc
++++ b/sql/net_serv.cc
@@ -61,7 +61,7 @@
the client should have a bigger max_allowed_packet.
*/
#!!! notice !!!
# Any small change to this file in the main branch
# should be done or reviewed by the maintainer!
-diff -ruN a/CMakeLists.txt b/CMakeLists.txt
---- a/CMakeLists.txt 2011-03-31 17:36:18.000000000 +0400
-+++ b/CMakeLists.txt 2011-04-09 19:12:12.000000000 +0400
+--- a/CMakeLists.txt
++++ b/CMakeLists.txt
@@ -165,7 +165,12 @@
OPTION (WITH_UNIT_TESTS "Compile MySQL with unit tests" ON)
MARK_AS_ADVANCED(CYBOZU BACKUP_TEST WITHOUT_SERVER DISABLE_SHARED)
OPTION(ENABLE_DEBUG_SYNC "Enable debug sync (debug builds only)" ON)
IF(ENABLE_DEBUG_SYNC)
SET(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -DENABLED_DEBUG_SYNC")
-diff -ruN a/include/mysql_com.h b/include/mysql_com.h
---- a/include/mysql_com.h 2011-03-31 17:36:18.000000000 +0400
-+++ b/include/mysql_com.h 2011-04-10 11:28:51.000000000 +0400
+--- a/include/mysql_com.h
++++ b/include/mysql_com.h
@@ -141,10 +141,11 @@
#define REFRESH_FAST 32768 /* Intern flag */
#define CLIENT_LONG_PASSWORD 1 /* new more secure passwords */
#define CLIENT_FOUND_ROWS 2 /* Found instead of affected rows */
-diff -ruN /dev/null b/patch_info/response-time-distribution.info
---- /dev/null 1970-01-01 00:00:00.000000000 +0000
-+++ b/patch_info/response-time-distribution.info 2011-04-09 19:12:12.000000000 +0400
+--- /dev/null
++++ b/patch_info/response-time-distribution.info
@@ -0,0 +1,9 @@
+File=response-time-distribution.patch
+Name=Response time distribution
+Changelog
+2010-07-02 first version avaliable
+2010-09-15 add column 'total'
-diff -ruN a/sql/CMakeLists.txt b/sql/CMakeLists.txt
---- a/sql/CMakeLists.txt 2011-03-31 17:36:18.000000000 +0400
-+++ b/sql/CMakeLists.txt 2011-04-09 19:12:12.000000000 +0400
+--- a/sql/CMakeLists.txt
++++ b/sql/CMakeLists.txt
@@ -51,7 +51,7 @@
message.h mf_iocache.cc my_decimal.cc ../sql-common/my_time.c
mysqld.cc net_serv.cc keycaches.cc
sql_partition.cc sql_plugin.cc sql_prepare.cc sql_rename.cc
debug_sync.cc debug_sync.h
sql_repl.cc sql_select.cc sql_show.cc sql_state.c sql_string.cc
-diff -ruN a/sql/handler.h b/sql/handler.h
---- a/sql/handler.h 2011-04-09 19:11:54.000000000 +0400
-+++ b/sql/handler.h 2011-04-10 11:28:51.000000000 +0400
-@@ -580,6 +580,7 @@
+--- a/sql/handler.h
++++ b/sql/handler.h
+@@ -581,6 +581,7 @@
SCH_PROFILES,
SCH_REFERENTIAL_CONSTRAINTS,
SCH_PROCEDURES,
SCH_SCHEMATA,
SCH_SCHEMA_PRIVILEGES,
SCH_SESSION_STATUS,
-diff -ruN a/sql/lex.h b/sql/lex.h
---- a/sql/lex.h 2011-03-31 17:36:18.000000000 +0400
-+++ b/sql/lex.h 2011-04-10 11:28:52.000000000 +0400
+--- a/sql/lex.h
++++ b/sql/lex.h
@@ -426,6 +426,7 @@
{ "PURGE", SYM(PURGE)},
{ "QUARTER", SYM(QUARTER_SYM)},
{ "QUICK", SYM(QUICK)},
{ "RANGE", SYM(RANGE_SYM)},
{ "READ", SYM(READ_SYM)},
-diff -ruN a/sql/mysqld.cc b/sql/mysqld.cc
---- a/sql/mysqld.cc 2011-04-09 19:12:11.000000000 +0400
-+++ b/sql/mysqld.cc 2011-04-10 11:28:52.000000000 +0400
+--- a/sql/mysqld.cc
++++ b/sql/mysqld.cc
@@ -69,6 +69,8 @@
#include "debug_sync.h"
#include "sql_callback.h"
#ifdef WITH_PERFSCHEMA_STORAGE_ENGINE
#include "../storage/perfschema/pfs_server.h"
#endif /* WITH_PERFSCHEMA_STORAGE_ENGINE */
-@@ -606,7 +608,7 @@
+@@ -611,7 +613,7 @@
MY_LOCALE *my_default_lc_messages;
MY_LOCALE *my_default_lc_time_names;
SHOW_COMP_OPTION have_geometry, have_rtree_keys;
SHOW_COMP_OPTION have_crypt, have_compress;
SHOW_COMP_OPTION have_profiling;
-@@ -907,6 +909,10 @@
+@@ -912,6 +914,10 @@
my_bool opt_enable_shared_memory;
HANDLE smem_event_connect_request= 0;
#endif
my_bool opt_use_ssl = 0;
char *opt_ssl_ca= NULL, *opt_ssl_capath= NULL, *opt_ssl_cert= NULL,
-@@ -1478,6 +1484,9 @@
+@@ -1483,6 +1489,9 @@
my_free(opt_bin_logname);
bitmap_free(&temp_pool);
free_max_user_conn();
#ifdef HAVE_REPLICATION
end_slave_list();
#endif
-@@ -3960,6 +3969,9 @@
+@@ -4010,6 +4019,9 @@
if (!DEFAULT_ERRMSGS[0][0])
unireg_abort(1);
/* We have to initialize the storage engines before CSV logging */
if (ha_init())
{
-@@ -6848,6 +6860,11 @@
+@@ -6909,6 +6921,11 @@
#else
have_query_cache=SHOW_OPTION_NO;
#endif
#ifdef HAVE_SPATIAL
have_geometry=SHOW_OPTION_YES;
#else
-diff -ruN a/sql/mysqld.h b/sql/mysqld.h
---- a/sql/mysqld.h 2011-04-09 19:12:11.000000000 +0400
-+++ b/sql/mysqld.h 2011-04-10 11:28:52.000000000 +0400
+--- a/sql/mysqld.h
++++ b/sql/mysqld.h
@@ -98,6 +98,10 @@
extern bool opt_disable_networking, opt_skip_show_db;
extern bool opt_skip_name_resolve;
extern my_bool opt_character_set_client_handshake;
extern bool volatile abort_loop;
extern bool in_bootstrap;
-diff -ruN /dev/null b/sql/query_response_time.cc
---- /dev/null 1970-01-01 00:00:00.000000000 +0000
-+++ b/sql/query_response_time.cc 2011-04-10 00:27:11.000000000 +0400
+--- /dev/null
++++ b/sql/query_response_time.cc
@@ -0,0 +1,310 @@
+#include "mysql_version.h"
+#include "my_global.h"
+ return query_response_time::g_collector.fill(thd,tables,cond);
+}
+#endif // HAVE_RESPONSE_TIME_DISTRIBUTION
-diff -ruN /dev/null b/sql/query_response_time.h
---- /dev/null 1970-01-01 00:00:00.000000000 +0000
-+++ b/sql/query_response_time.h 2011-04-09 19:12:12.000000000 +0400
+--- /dev/null
++++ b/sql/query_response_time.h
@@ -0,0 +1,71 @@
+#ifndef QUERY_RESPONSE_TIME_H
+#define QUERY_RESPONSE_TIME_H
+#endif // HAVE_RESPONSE_TIME_DISTRIBUTION
+
+#endif // QUERY_RESPONSE_TIME_H
-diff -ruN a/sql/set_var.h b/sql/set_var.h
---- a/sql/set_var.h 2011-03-31 17:36:18.000000000 +0400
-+++ b/sql/set_var.h 2011-04-09 19:12:12.000000000 +0400
+--- a/sql/set_var.h
++++ b/sql/set_var.h
@@ -293,6 +293,7 @@
extern SHOW_COMP_OPTION have_ssl, have_symlink, have_dlopen;
extern SHOW_COMP_OPTION have_geometry, have_rtree_keys;
extern SHOW_COMP_OPTION have_crypt;
extern SHOW_COMP_OPTION have_compress;
-diff -ruN a/sql/sql_parse.cc b/sql/sql_parse.cc
---- a/sql/sql_parse.cc 2011-04-09 19:12:10.000000000 +0400
-+++ b/sql/sql_parse.cc 2011-04-10 11:28:51.000000000 +0400
+--- a/sql/sql_parse.cc
++++ b/sql/sql_parse.cc
@@ -88,6 +88,7 @@
#include "sp_cache.h"
#include "events.h"
case SCH_COLLATION_CHARACTER_SET_APPLICABILITY:
case SCH_USER_PRIVILEGES:
case SCH_SCHEMA_PRIVILEGES:
-diff -ruN a/sql/sql_reload.cc b/sql/sql_reload.cc
---- a/sql/sql_reload.cc 2011-03-31 17:36:18.000000000 +0400
-+++ b/sql/sql_reload.cc 2011-04-10 11:28:51.000000000 +0400
+--- a/sql/sql_reload.cc
++++ b/sql/sql_reload.cc
@@ -25,7 +25,7 @@
#include "hostname.h" // hostname_cache_refresh
#include "sql_repl.h" // reset_master, reset_slave
if (*write_to_binlog != -1)
*write_to_binlog= tmp_write_to_binlog;
/*
-diff -ruN a/sql/sql_show.cc b/sql/sql_show.cc
---- a/sql/sql_show.cc 2011-04-09 19:12:10.000000000 +0400
-+++ b/sql/sql_show.cc 2011-04-10 11:28:51.000000000 +0400
+--- a/sql/sql_show.cc
++++ b/sql/sql_show.cc
@@ -50,6 +50,7 @@
#include "event_data_objects.h"
#endif
#include "lock.h" // MYSQL_OPEN_IGNORE_FLUSH
#include "debug_sync.h"
#include "datadict.h" // dd_frm_type()
-@@ -7830,6 +7831,14 @@
+@@ -7865,6 +7866,14 @@
*/
ST_SCHEMA_TABLE schema_tables[]=
{
{"CHARACTER_SETS", charsets_fields_info, create_schema_table,
-@@ -7883,6 +7892,13 @@
+@@ -7918,6 +7927,13 @@
1, 9, 0, OPTIMIZE_I_S_TABLE|OPEN_TABLE_ONLY},
{"ROUTINES", proc_fields_info, create_schema_table,
fill_schema_proc, make_proc_old_format, 0, -1, -1, 0, 0},
{"SCHEMATA", schema_fields_info, create_schema_table,
fill_schema_schemata, make_schemata_old_format, 0, 1, -1, 0, 0},
{"SCHEMA_PRIVILEGES", schema_privileges_fields_info, create_schema_table,
-diff -ruN a/sql/sql_yacc.yy b/sql/sql_yacc.yy
---- a/sql/sql_yacc.yy 2011-04-09 19:11:54.000000000 +0400
-+++ b/sql/sql_yacc.yy 2011-04-10 11:28:52.000000000 +0400
-@@ -1193,6 +1193,7 @@
+--- a/sql/sql_yacc.yy
++++ b/sql/sql_yacc.yy
+@@ -1194,6 +1194,7 @@
%token PURGE
%token QUARTER_SYM
%token QUERY_SYM
%token QUICK
%token RANGE_SYM /* SQL-2003-R */
%token READS_SYM /* SQL-2003-R */
-@@ -11076,6 +11077,15 @@
+@@ -11080,6 +11081,15 @@
{
Lex->sql_command = SQLCOM_SHOW_SLAVE_STAT;
}
| CREATE PROCEDURE_SYM sp_name
{
LEX *lex= Lex;
-@@ -11312,6 +11322,12 @@
+@@ -11316,6 +11326,12 @@
{ Lex->type|= REFRESH_STATUS; }
| SLAVE
{ Lex->type|= REFRESH_SLAVE; }
| MASTER_SYM
{ Lex->type|= REFRESH_MASTER; }
| DES_KEY_FILE
-@@ -12597,6 +12613,7 @@
+@@ -12617,6 +12633,7 @@
| PROXY_SYM {}
| QUARTER_SYM {}
| QUERY_SYM {}
| QUICK {}
| READ_ONLY_SYM {}
| REBUILD_SYM {}
-diff -ruN a/sql/sys_vars.cc b/sql/sys_vars.cc
---- a/sql/sys_vars.cc 2011-04-09 19:12:11.000000000 +0400
-+++ b/sql/sys_vars.cc 2011-04-10 11:28:51.000000000 +0400
+--- a/sql/sys_vars.cc
++++ b/sql/sys_vars.cc
@@ -49,6 +49,7 @@
#include "../storage/perfschema/pfs_server.h"
#endif /* WITH_PERFSCHEMA_STORAGE_ENGINE */
static Sys_var_mybool Sys_secure_auth(
"secure_auth",
"Disallow authentication for accounts that have old (pre-4.1) "
+--- a/include/atomic/x86-gcc.h
++++ b/include/atomic/x86-gcc.h
+@@ -108,27 +108,22 @@
+ v=tmp;
+
+ /*
+- On some platforms (e.g. Mac OS X and Solaris) the ebx register
+- is held as a pointer to the global offset table. Thus we're not
+- allowed to use the b-register on those platforms when compiling
+- PIC code, to avoid this we push ebx and pop ebx. The new value
+- is copied directly from memory to avoid problems with a implicit
+- manipulation of the stack pointer by the push.
+-
+ cmpxchg8b works on both 32-bit platforms and 64-bit platforms but
+ the code here is only used on 32-bit platforms, on 64-bit
+ platforms the much simpler make_atomic_cas_body32 will work
+ fine.
+ */
+-#define make_atomic_cas_body64 \
+- asm volatile ("push %%ebx;" \
+- "movl (%%ecx), %%ebx;" \
+- "movl 4(%%ecx), %%ecx;" \
+- LOCK_prefix "; cmpxchg8b %0;" \
+- "setz %2; pop %%ebx" \
+- : "=m" (*a), "+A" (*cmp), "=c" (ret) \
+- : "c" (&set), "m" (*a) \
+- : "memory", "esp")
++#define make_atomic_cas_body64 \
++ asm ("movl %%edi, -4(%%esp);" \
++ "leal %0, %%edi;" \
++ "xchgl %%ebx, %%esi;" \
++ LOCK_prefix "; cmpxchg8b (%%edi);" \
++ "movl %%esi, %%ebx;" \
++ "movl -4(%%esp), %%edi;" \
++ "setz %1;" \
++ : "+m" (*a), "=q" (ret), "+A" (*cmp) \
++ : "S" ((int32)(set & 0xFFFFFFFF)), "c" ((int32)(set >> 32)) \
++ : "flags")
+ #endif
+
+ /*
#!!! notice !!!
# Any small change to this file in the main branch
# should be done or reviewed by the maintainer!
-diff -ruN /dev/null b/patch_info/show_slave_status_nolock.patch
---- /dev/null 1970-01-01 00:00:00.000000000 +0000
-+++ b/patch_info/show_slave_status_nolock.patch 2011-04-10 11:29:06.000000000 +0400
+--- /dev/null
++++ b/patch_info/show_slave_status_nolock.patch
@@ -0,0 +1,6 @@
+File=show_slave_status_nolock.patch
+Name= SHOW SLAVE STATUS NOLOCK
+Author=Percona <info@percona.com>
+License=GPL
+Comment= Implement SHOW SLAVE STATUS without lock (STOP SLAVE lock the same mutex what lock SHOW SLAVE STATUS)
-diff -ruN a/sql/lex.h b/sql/lex.h
---- a/sql/lex.h 2011-04-10 11:29:05.000000000 +0400
-+++ b/sql/lex.h 2011-04-10 11:29:06.000000000 +0400
+--- a/sql/lex.h
++++ b/sql/lex.h
@@ -378,6 +378,7 @@
{ "NONE", SYM(NONE_SYM)},
{ "NOT", SYM(NOT_SYM)},
{ "NULL", SYM(NULL_SYM)},
{ "NUMERIC", SYM(NUMERIC_SYM)},
{ "NVARCHAR", SYM(NVARCHAR_SYM)},
-diff -ruN a/sql/mysqld.cc b/sql/mysqld.cc
---- a/sql/mysqld.cc 2011-04-10 11:29:05.000000000 +0400
-+++ b/sql/mysqld.cc 2011-04-10 11:29:06.000000000 +0400
-@@ -3071,6 +3071,7 @@
+--- a/sql/mysqld.cc
++++ b/sql/mysqld.cc
+@@ -3121,6 +3121,7 @@
{"show_relaylog_events", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_RELAYLOG_EVENTS]), SHOW_LONG_STATUS},
{"show_slave_hosts", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_SLAVE_HOSTS]), SHOW_LONG_STATUS},
{"show_slave_status", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_SLAVE_STAT]), SHOW_LONG_STATUS},
{"show_status", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_STATUS]), SHOW_LONG_STATUS},
{"show_storage_engines", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_STORAGE_ENGINES]), SHOW_LONG_STATUS},
{"show_table_status", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_TABLE_STATUS]), SHOW_LONG_STATUS},
-diff -ruN a/sql/sql_lex.h b/sql/sql_lex.h
---- a/sql/sql_lex.h 2011-04-10 11:29:05.000000000 +0400
-+++ b/sql/sql_lex.h 2011-04-10 11:29:06.000000000 +0400
+--- a/sql/sql_lex.h
++++ b/sql/sql_lex.h
@@ -190,6 +190,8 @@
SQLCOM_SHOW_PROFILE, SQLCOM_SHOW_PROFILES,
SQLCOM_SIGNAL, SQLCOM_RESIGNAL,
/*
When a command is added here, be sure it's also added in mysqld.cc
in "struct show_var_st status_vars[]= {" ...
-diff -ruN a/sql/sql_parse.cc b/sql/sql_parse.cc
---- a/sql/sql_parse.cc 2011-04-10 11:28:51.000000000 +0400
-+++ b/sql/sql_parse.cc 2011-04-10 11:29:06.000000000 +0400
+--- a/sql/sql_parse.cc
++++ b/sql/sql_parse.cc
@@ -335,6 +335,7 @@
sql_command_flags[SQLCOM_SHOW_CREATE]= CF_STATUS_COMMAND;
sql_command_flags[SQLCOM_SHOW_MASTER_STAT]= CF_STATUS_COMMAND;
sql_command_flags[SQLCOM_SHOW_CREATE_PROC]= CF_STATUS_COMMAND;
sql_command_flags[SQLCOM_SHOW_CREATE_FUNC]= CF_STATUS_COMMAND;
sql_command_flags[SQLCOM_SHOW_CREATE_TRIGGER]= CF_STATUS_COMMAND;
-@@ -2293,12 +2294,16 @@
+@@ -2359,12 +2360,16 @@
mysql_mutex_unlock(&LOCK_active_mi);
break;
}
if (active_mi != NULL)
{
res = show_master_info(thd, active_mi);
-@@ -2309,7 +2314,10 @@
+@@ -2375,7 +2380,10 @@
WARN_NO_MASTER_INFO, ER(WARN_NO_MASTER_INFO));
my_ok(thd);
}
break;
}
case SQLCOM_SHOW_MASTER_STAT:
-diff -ruN a/sql/sql_yacc.yy b/sql/sql_yacc.yy
---- a/sql/sql_yacc.yy 2011-04-10 11:29:05.000000000 +0400
-+++ b/sql/sql_yacc.yy 2011-04-10 11:29:06.000000000 +0400
-@@ -1292,6 +1292,7 @@
+--- a/sql/sql_yacc.yy
++++ b/sql/sql_yacc.yy
+@@ -1293,6 +1293,7 @@
%token STARTS_SYM
%token START_SYM /* SQL-2003-R */
%token STATUS_SYM
%token STDDEV_SAMP_SYM /* SQL-2003-N */
%token STD_SYM
%token STOP_SYM
-@@ -11082,6 +11083,10 @@
+@@ -11086,6 +11087,10 @@
{
Lex->sql_command = SQLCOM_SHOW_SLAVE_STAT;
}
#!!! notice !!!
# Any small change to this file in the main branch
# should be done or reviewed by the maintainer!
-diff -ruN a/sql/handler.h b/sql/handler.h
---- a/sql/handler.h 2011-04-09 19:11:53.000000000 +0400
-+++ b/sql/handler.h 2011-04-10 12:16:43.000000000 +0400
-@@ -569,6 +569,7 @@
+--- a/sql/handler.h
++++ b/sql/handler.h
+@@ -570,6 +570,7 @@
SCH_EVENTS,
SCH_FILES,
SCH_GLOBAL_STATUS,
SCH_GLOBAL_VARIABLES,
SCH_KEY_COLUMN_USAGE,
SCH_OPEN_TABLES,
-@@ -590,6 +591,7 @@
+@@ -591,6 +592,7 @@
SCH_TABLE_CONSTRAINTS,
SCH_TABLE_NAMES,
SCH_TABLE_PRIVILEGES,
SCH_TRIGGERS,
SCH_USER_PRIVILEGES,
SCH_VARIABLES,
-diff -ruN a/sql/mysqld.cc b/sql/mysqld.cc
---- a/sql/mysqld.cc 2011-04-09 19:11:52.000000000 +0400
-+++ b/sql/mysqld.cc 2011-04-10 12:16:44.000000000 +0400
-@@ -3051,6 +3051,7 @@
+--- a/sql/mysqld.cc
++++ b/sql/mysqld.cc
+@@ -3101,6 +3101,7 @@
{"show_storage_engines", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_STORAGE_ENGINES]), SHOW_LONG_STATUS},
{"show_table_status", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_TABLE_STATUS]), SHOW_LONG_STATUS},
{"show_tables", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_TABLES]), SHOW_LONG_STATUS},
{"show_triggers", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_TRIGGERS]), SHOW_LONG_STATUS},
{"show_variables", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_VARIABLES]), SHOW_LONG_STATUS},
{"show_warnings", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_WARNS]), SHOW_LONG_STATUS},
-diff -ruN a/sql/sql_lex.h b/sql/sql_lex.h
---- a/sql/sql_lex.h 2011-03-31 17:36:18.000000000 +0400
-+++ b/sql/sql_lex.h 2011-04-10 12:22:19.000000000 +0400
+@@ -7802,6 +7803,7 @@
+ PSI_mutex_key key_LOCK_des_key_file;
+ #endif /* HAVE_OPENSSL */
+
++PSI_mutex_key key_LOCK_temporary_tables;
+ PSI_mutex_key key_BINLOG_LOCK_index, key_BINLOG_LOCK_prep_xids,
+ key_delayed_insert_mutex, key_hash_filo_lock, key_LOCK_active_mi,
+ key_LOCK_connection_count, key_LOCK_crypt, key_LOCK_delayed_create,
+@@ -7855,6 +7857,7 @@
+ { &key_LOCK_system_variables_hash, "LOCK_system_variables_hash", PSI_FLAG_GLOBAL},
+ { &key_LOCK_table_share, "LOCK_table_share", PSI_FLAG_GLOBAL},
+ { &key_LOCK_thd_data, "THD::LOCK_thd_data", 0},
++ { &key_LOCK_temporary_tables, "THD::LOCK_temporary_tables", 0},
+ { &key_LOCK_user_conn, "LOCK_user_conn", PSI_FLAG_GLOBAL},
+ { &key_LOCK_uuid_generator, "LOCK_uuid_generator", PSI_FLAG_GLOBAL},
+ { &key_LOG_LOCK_log, "LOG::LOCK_log", 0},
+--- a/sql/sql_lex.h
++++ b/sql/sql_lex.h
@@ -194,6 +194,7 @@
When a command is added here, be sure it's also added in mysqld.cc
in "struct show_var_st status_vars[]= {" ...
/* This should be the last !!! */
SQLCOM_END
};
-diff -ruN a/sql/sql_parse.cc b/sql/sql_parse.cc
---- a/sql/sql_parse.cc 2011-03-31 17:36:18.000000000 +0400
-+++ b/sql/sql_parse.cc 2011-04-10 12:16:44.000000000 +0400
+--- a/sql/sql_parse.cc
++++ b/sql/sql_parse.cc
@@ -348,6 +348,9 @@
sql_command_flags[SQLCOM_SHOW_TABLES]= (CF_STATUS_COMMAND |
CF_SHOW_TABLE_COMMAND |
case SCH_VIEWS:
case SCH_TRIGGERS:
case SCH_EVENTS:
-@@ -2017,6 +2022,7 @@
+@@ -2083,6 +2088,7 @@
}
case SQLCOM_SHOW_DATABASES:
case SQLCOM_SHOW_TABLES:
case SQLCOM_SHOW_TRIGGERS:
case SQLCOM_SHOW_TABLE_STATUS:
case SQLCOM_SHOW_OPEN_TABLES:
-@@ -4801,6 +4807,8 @@
+@@ -4846,6 +4852,8 @@
case SCH_TABLE_NAMES:
case SCH_TABLES:
case SCH_VIEWS:
case SCH_TRIGGERS:
case SCH_EVENTS:
-diff -ruN a/sql/sql_show.cc b/sql/sql_show.cc
---- a/sql/sql_show.cc 2011-04-09 19:11:52.000000000 +0400
-+++ b/sql/sql_show.cc 2011-04-10 12:16:44.000000000 +0400
-@@ -2693,6 +2693,7 @@
+--- a/sql/sql_show.cc
++++ b/sql/sql_show.cc
+@@ -2692,6 +2692,7 @@
break;
case SQLCOM_SHOW_TABLES:
case SQLCOM_SHOW_TABLE_STATUS:
case SQLCOM_SHOW_TRIGGERS:
case SQLCOM_SHOW_EVENTS:
thd->make_lex_string(&lookup_field_values->db_value,
-@@ -3181,6 +3182,228 @@
+@@ -3279,6 +3280,231 @@
return (uint) OPEN_FULL_TABLE;
}
+#endif
+
+ while ((thd_item=it++)) {
++ mysql_mutex_lock(&thd_item->LOCK_temporary_tables);
+ for (tmp=thd_item->temporary_tables; tmp; tmp=tmp->next) {
+
+#ifndef NO_EMBEDDED_ACCESS_CHECKS
+
+ if (store_temporary_table_record(thd_item, tables->table, tmp, thd->lex->select_lex.db, table_names_only)) {
+ tmp->in_use= t;
++ mysql_mutex_unlock(&thd_item->LOCK_temporary_tables);
+ mysql_mutex_unlock(&LOCK_thread_count);
+ DBUG_RETURN(1);
+ }
+
+ tmp->in_use= t;
+ }
++ mysql_mutex_unlock(&thd_item->LOCK_temporary_tables);
+ }
+
+ mysql_mutex_unlock(&LOCK_thread_count);
/**
Try acquire high priority share metadata lock on a table (with
-@@ -6991,6 +7214,25 @@
+@@ -7023,6 +7249,25 @@
{0, 0, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE}
};
ST_FIELD_INFO columns_fields_info[]=
{
-@@ -7605,6 +7847,9 @@
+@@ -7637,6 +7882,9 @@
hton_fill_schema_table, 0, 0, -1, -1, 0, 0},
{"GLOBAL_STATUS", variables_fields_info, create_schema_table,
fill_status, make_old_format, 0, 0, -1, 0, 0},
{"GLOBAL_VARIABLES", variables_fields_info, create_schema_table,
fill_variables, make_old_format, 0, 0, -1, 0, 0},
{"KEY_COLUMN_USAGE", key_column_usage_fields_info, create_schema_table,
-@@ -7654,6 +7899,9 @@
+@@ -7686,6 +7934,9 @@
get_all_tables, make_table_names_old_format, 0, 1, 2, 1, 0},
{"TABLE_PRIVILEGES", table_privileges_fields_info, create_schema_table,
fill_schema_table_privileges, 0, 0, -1, -1, 0, 0},
{"TRIGGERS", triggers_fields_info, create_schema_table,
get_all_tables, make_old_format, get_schema_triggers_record, 5, 6, 0,
OPEN_TRIGGER_ONLY|OPTIMIZE_I_S_TABLE},
-diff -ruN a/sql/sql_yacc.yy b/sql/sql_yacc.yy
---- a/sql/sql_yacc.yy 2011-03-31 17:36:18.000000000 +0400
-+++ b/sql/sql_yacc.yy 2011-04-10 12:16:43.000000000 +0400
-@@ -10869,6 +10869,15 @@
+--- a/sql/sql_yacc.yy
++++ b/sql/sql_yacc.yy
+@@ -10873,6 +10873,15 @@
if (prepare_schema_table(YYTHD, lex, 0, SCH_TABLE_NAMES))
MYSQL_YYABORT;
}
| opt_full TRIGGERS_SYM opt_db wild_and_where
{
LEX *lex= Lex;
+--- a/sql/mysqld.h
++++ b/sql/mysqld.h
+@@ -233,6 +233,7 @@
+ extern PSI_mutex_key key_LOCK_des_key_file;
+ #endif
+
++extern PSI_mutex_key key_LOCK_temporary_tables;
+ extern PSI_mutex_key key_BINLOG_LOCK_index, key_BINLOG_LOCK_prep_xids,
+ key_delayed_insert_mutex, key_hash_filo_lock, key_LOCK_active_mi,
+ key_LOCK_connection_count, key_LOCK_crypt, key_LOCK_delayed_create,
+--- a/sql/sql_base.cc
++++ b/sql/sql_base.cc
+@@ -1588,12 +1588,16 @@
+ if (!mysql_bin_log.is_open())
+ {
+ TABLE *tmp_next;
++
++ mysql_mutex_lock(&thd->LOCK_temporary_tables);
+ for (table= thd->temporary_tables; table; table= tmp_next)
+ {
+ tmp_next= table->next;
+ close_temporary(table, 1, 1);
+ }
+ thd->temporary_tables= 0;
++ mysql_mutex_unlock(&thd->LOCK_temporary_tables);
++
+ DBUG_RETURN(FALSE);
+ }
+
+@@ -1606,6 +1610,8 @@
+
+ memcpy(buf, stub, stub_len);
+
++ mysql_mutex_lock(&thd->LOCK_temporary_tables);
++
+ /*
+ Insertion sort of temp tables by pseudo_thread_id to build ordered list
+ of sublists of equal pseudo_thread_id
+@@ -1727,6 +1733,8 @@
+ thd->variables.option_bits&= ~OPTION_QUOTE_SHOW_CREATE; /* restore option */
+ thd->temporary_tables=0;
+
++ mysql_mutex_unlock(&thd->LOCK_temporary_tables);
++
+ DBUG_RETURN(error);
+ }
+
+@@ -2104,6 +2112,8 @@
+ table->s->db.str, table->s->table_name.str,
+ (long) table, table->alias));
+
++ mysql_mutex_lock(&thd->LOCK_temporary_tables);
++
+ if (table->prev)
+ {
+ table->prev->next= table->next;
+@@ -2130,6 +2140,9 @@
+ slave_open_temp_tables--;
+ }
+ close_temporary(table, free_share, delete_table);
++
++ mysql_mutex_unlock(&thd->LOCK_temporary_tables);
++
+ DBUG_VOID_RETURN;
+ }
+
+@@ -5854,6 +5867,7 @@
+ if (add_to_temporary_tables_list)
+ {
+ /* growing temp list at the head */
++ mysql_mutex_lock(&thd->LOCK_temporary_tables);
+ tmp_table->next= thd->temporary_tables;
+ if (tmp_table->next)
+ tmp_table->next->prev= tmp_table;
+@@ -5861,6 +5875,7 @@
+ thd->temporary_tables->prev= 0;
+ if (thd->slave_thread)
+ slave_open_temp_tables++;
++ mysql_mutex_unlock(&thd->LOCK_temporary_tables);
+ }
+ tmp_table->pos_in_table_list= 0;
+ DBUG_PRINT("tmptable", ("opened table: '%s'.'%s' 0x%lx", tmp_table->s->db.str,
+--- a/sql/sql_class.cc
++++ b/sql/sql_class.cc
+@@ -837,6 +837,8 @@
+ active_vio = 0;
+ #endif
+ mysql_mutex_init(key_LOCK_thd_data, &LOCK_thd_data, MY_MUTEX_INIT_FAST);
++ mysql_mutex_init(key_LOCK_temporary_tables, &LOCK_temporary_tables,
++ MY_MUTEX_INIT_FAST);
+
+ /* Variables with default values */
+ proc_info="login";
+@@ -1349,6 +1351,7 @@
+ db= NULL;
+ free_root(&transaction.mem_root,MYF(0));
+ mysql_mutex_destroy(&LOCK_thd_data);
++ mysql_mutex_destroy(&LOCK_temporary_tables);
+ #ifndef DBUG_OFF
+ dbug_sentry= THD_SENTRY_GONE;
+ #endif
+--- a/sql/sql_class.h
++++ b/sql/sql_class.h
+@@ -1004,6 +1004,11 @@
+ XXX Why are internal temporary tables added to this list?
+ */
+ TABLE *temporary_tables;
++ /**
++ Protects temporary_tables.
++ */
++ mysql_mutex_t LOCK_temporary_tables;
++
+ TABLE *derived_tables;
+ /*
+ During a MySQL session, one can lock tables in two modes: automatic
---- a/mysql-test/include/wait_for_slave_param.inc 2011-04-12 22:38:45.000000000 +1000
-+++ b/mysql-test/include/wait_for_slave_param.inc 2011-06-21 22:59:13.804854682 +1000
+--- a/mysql-test/include/wait_for_slave_param.inc
++++ b/mysql-test/include/wait_for_slave_param.inc
@@ -79,7 +79,7 @@
# mysqltest doesn't provide any better way to multiply by 10
#!!! notice !!!
# Any small change to this file in the main branch
# should be done or reviewed by the maintainer!
-diff -ruN a/include/mysql/plugin_audit.h.pp b/include/mysql/plugin_audit.h.pp
---- a/include/mysql/plugin_audit.h.pp 2011-04-09 18:48:05.000000000 +0400
-+++ b/include/mysql/plugin_audit.h.pp 2011-04-09 18:48:50.000000000 +0400
-@@ -178,6 +178,16 @@
+--- a/include/mysql/plugin_audit.h.pp
++++ b/include/mysql/plugin_audit.h.pp
+@@ -185,6 +185,16 @@
char *thd_security_context(void* thd, char *buffer, unsigned int length,
unsigned int max_query_len);
void thd_inc_row_count(void* thd);
int mysql_tmpfile(const char *prefix);
int thd_killed(const void* thd);
unsigned long thd_get_thread_id(const void* thd);
-diff -ruN a/include/mysql/plugin_auth.h.pp b/include/mysql/plugin_auth.h.pp
---- a/include/mysql/plugin_auth.h.pp 2011-04-09 18:48:05.000000000 +0400
-+++ b/include/mysql/plugin_auth.h.pp 2011-04-09 18:48:50.000000000 +0400
-@@ -178,6 +178,16 @@
+--- a/include/mysql/plugin_auth.h.pp
++++ b/include/mysql/plugin_auth.h.pp
+@@ -185,6 +185,16 @@
char *thd_security_context(void* thd, char *buffer, unsigned int length,
unsigned int max_query_len);
void thd_inc_row_count(void* thd);
int mysql_tmpfile(const char *prefix);
int thd_killed(const void* thd);
unsigned long thd_get_thread_id(const void* thd);
-diff -ruN a/include/mysql/plugin_ftparser.h.pp b/include/mysql/plugin_ftparser.h.pp
---- a/include/mysql/plugin_ftparser.h.pp 2011-04-09 18:48:05.000000000 +0400
-+++ b/include/mysql/plugin_ftparser.h.pp 2011-04-09 18:48:50.000000000 +0400
-@@ -131,6 +131,16 @@
+--- a/include/mysql/plugin_ftparser.h.pp
++++ b/include/mysql/plugin_ftparser.h.pp
+@@ -138,6 +138,16 @@
char *thd_security_context(void* thd, char *buffer, unsigned int length,
unsigned int max_query_len);
void thd_inc_row_count(void* thd);
int mysql_tmpfile(const char *prefix);
int thd_killed(const void* thd);
unsigned long thd_get_thread_id(const void* thd);
-diff -ruN a/include/mysql/plugin.h b/include/mysql/plugin.h
---- a/include/mysql/plugin.h 2011-04-09 18:48:05.000000000 +0400
-+++ b/include/mysql/plugin.h 2011-04-09 18:48:50.000000000 +0400
+--- a/include/mysql/plugin.h
++++ b/include/mysql/plugin.h
@@ -536,6 +536,17 @@
/* Increments the row counter, see THD::row_count */
void thd_inc_row_count(MYSQL_THD thd);
/**
Create a temporary file.
-diff -ruN /dev/null b/patch_info/slow_extended.info
---- /dev/null 1970-01-01 00:00:00.000000000 +0000
-+++ b/patch_info/slow_extended.info 2011-04-09 18:48:50.000000000 +0400
+--- /dev/null
++++ b/patch_info/slow_extended.info
@@ -0,0 +1,25 @@
+File=slow_extended.patch
+Name=Extended statistics in slow.log (not InnoDB part)
+6) Change variable types (system/command-line)
+2011-01
+Patch profiling_slow.patch was merged
-diff -ruN a/scripts/mysqldumpslow.sh b/scripts/mysqldumpslow.sh
---- a/scripts/mysqldumpslow.sh 2011-04-09 18:48:05.000000000 +0400
-+++ b/scripts/mysqldumpslow.sh 2011-04-09 18:48:50.000000000 +0400
-@@ -101,8 +101,8 @@
+--- a/scripts/mysqldumpslow.sh
++++ b/scripts/mysqldumpslow.sh
+@@ -102,8 +102,8 @@
s/^#? Time: \d{6}\s+\d+:\d+:\d+.*\n//;
my ($user,$host) = s/^#? User\@Host:\s+(\S+)\s+\@\s+(\S+).*\n// ? ($1,$2) : ('','');
$t -= $l unless $opt{l};
# remove fluff that mysqld writes to log when it (re)starts:
-diff -ruN a/sql/event_scheduler.cc b/sql/event_scheduler.cc
---- a/sql/event_scheduler.cc 2011-04-09 18:48:05.000000000 +0400
-+++ b/sql/event_scheduler.cc 2011-04-09 18:48:50.000000000 +0400
+--- a/sql/event_scheduler.cc
++++ b/sql/event_scheduler.cc
@@ -195,6 +195,7 @@
thd->client_capabilities|= CLIENT_MULTI_RESULTS;
mysql_mutex_lock(&LOCK_thread_count);
mysql_mutex_unlock(&LOCK_thread_count);
/*
-diff -ruN a/sql/filesort.cc b/sql/filesort.cc
---- a/sql/filesort.cc 2011-04-09 18:48:05.000000000 +0400
-+++ b/sql/filesort.cc 2011-04-09 18:48:50.000000000 +0400
+--- a/sql/filesort.cc
++++ b/sql/filesort.cc
@@ -195,6 +195,7 @@
{
status_var_increment(thd->status_var.filesort_scan_count);
if (param->not_killable)
{
killed= ¬_killable;
-diff -ruN a/sql/log.cc b/sql/log.cc
---- a/sql/log.cc 2011-04-09 18:48:05.000000000 +0400
-+++ b/sql/log.cc 2011-04-09 18:48:50.000000000 +0400
+--- a/sql/log.cc
++++ b/sql/log.cc
@@ -715,11 +715,13 @@
*/
if (thd->db && strcmp(thd->db, db))
{ // Database changed
if (my_b_printf(&log_file,"use %s;\n",thd->db) == (uint) -1)
-diff -ruN a/sql/log.h b/sql/log.h
---- a/sql/log.h 2011-04-09 18:48:05.000000000 +0400
-+++ b/sql/log.h 2011-04-09 18:48:50.000000000 +0400
+--- a/sql/log.h
++++ b/sql/log.h
@@ -242,7 +242,7 @@
uint user_host_len, int thread_id,
const char *command_type, uint command_type_len,
time_t query_start_arg, const char *user_host,
uint user_host_len, ulonglong query_utime,
ulonglong lock_utime, bool is_command,
-diff -ruN a/sql/mysqld.cc b/sql/mysqld.cc
---- a/sql/mysqld.cc 2011-04-09 18:48:20.000000000 +0400
-+++ b/sql/mysqld.cc 2011-04-09 18:48:50.000000000 +0400
-@@ -416,6 +416,10 @@
+--- a/sql/mysqld.cc
++++ b/sql/mysqld.cc
+@@ -421,6 +421,10 @@
char* opt_secure_file_priv;
my_bool opt_log_slow_admin_statements= 0;
my_bool opt_log_slow_slave_statements= 0;
my_bool lower_case_file_system= 0;
my_bool opt_large_pages= 0;
my_bool opt_super_large_pages= 0;
-@@ -5835,10 +5839,10 @@
+@@ -5896,10 +5900,10 @@
"Log slow OPTIMIZE, ANALYZE, ALTER and other administrative statements to "
"the slow log if it is open.", &opt_log_slow_admin_statements,
&opt_log_slow_admin_statements, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
{"log-slow-queries", OPT_SLOW_QUERY_LOG,
"Log slow queries to a table or log file. Defaults logging to table "
"mysql.slow_log or hostname-slow.log if --log-output=file is used. "
-@@ -7227,6 +7231,10 @@
+@@ -7288,6 +7292,10 @@
C_MODE_END
/**
Get server options from the command line,
and perform related server initializations.
-@@ -7376,6 +7384,8 @@
+@@ -7437,6 +7445,8 @@
global_system_variables.long_query_time= (ulonglong)
(global_system_variables.long_query_time_double * 1e6);
if (opt_short_log_format)
opt_specialflag|= SPECIAL_SHORT_LOG_FORMAT;
-diff -ruN a/sql/mysqld.h b/sql/mysqld.h
---- a/sql/mysqld.h 2011-04-09 18:48:17.000000000 +0400
-+++ b/sql/mysqld.h 2011-04-09 18:48:50.000000000 +0400
+--- a/sql/mysqld.h
++++ b/sql/mysqld.h
@@ -116,6 +116,10 @@
extern char* opt_secure_backup_file_priv;
extern size_t opt_secure_backup_file_priv_len;
extern my_bool sp_automatic_privileges, opt_noacl;
extern my_bool opt_old_style_user_limits, trust_function_creators;
extern uint opt_crash_binlog_innodb;
-diff -ruN a/sql/slave.cc b/sql/slave.cc
---- a/sql/slave.cc 2011-04-09 18:48:05.000000000 +0400
-+++ b/sql/slave.cc 2011-04-09 18:48:50.000000000 +0400
+--- a/sql/slave.cc
++++ b/sql/slave.cc
@@ -2038,6 +2038,7 @@
+ MAX_LOG_EVENT_HEADER; /* note, incr over the global not session var */
thd->slave_thread = 1;
set_slave_thread_options(thd);
thd->client_capabilities = CLIENT_LOCAL_FILES;
mysql_mutex_lock(&LOCK_thread_count);
-diff -ruN a/sql/sp_head.cc b/sql/sp_head.cc
---- a/sql/sp_head.cc 2011-04-09 18:48:05.000000000 +0400
-+++ b/sql/sp_head.cc 2011-04-09 18:48:50.000000000 +0400
-@@ -2151,7 +2151,7 @@
+--- a/sql/sp_head.cc
++++ b/sql/sp_head.cc
+@@ -2152,7 +2152,7 @@
DBUG_PRINT("info",(" %.*s: eval args done", (int) m_name.length,
m_name.str));
}
{
DBUG_PRINT("info", ("Disabling slow log for the execution"));
save_enable_slow_log= true;
-diff -ruN a/sql/sql_cache.cc b/sql/sql_cache.cc
---- a/sql/sql_cache.cc 2011-04-09 18:48:05.000000000 +0400
-+++ b/sql/sql_cache.cc 2011-04-09 18:48:50.000000000 +0400
+--- a/sql/sql_cache.cc
++++ b/sql/sql_cache.cc
@@ -1756,6 +1756,7 @@
response, we can't handle it anyway.
*/
MYSQL_QUERY_CACHE_MISS(thd->query());
DBUG_RETURN(0); // Query was not cached
}
-diff -ruN a/sql/sql_class.cc b/sql/sql_class.cc
---- a/sql/sql_class.cc 2011-04-09 18:48:05.000000000 +0400
-+++ b/sql/sql_class.cc 2011-04-09 18:48:50.000000000 +0400
-@@ -367,6 +367,37 @@
+--- a/sql/sql_class.cc
++++ b/sql/sql_class.cc
+@@ -616,6 +616,37 @@
thd->warning_info->inc_current_row_for_warning();
}
/**
Dumps a text description of a thread, its security context
-@@ -661,6 +692,7 @@
+@@ -912,6 +943,7 @@
*cond_hdl= NULL;
return FALSE;
}
for (Internal_error_handler *error_handler= m_internal_handler;
error_handler;
-@@ -3385,6 +3417,12 @@
+@@ -3656,6 +3688,12 @@
first_successful_insert_id_in_prev_stmt;
backup->first_successful_insert_id_in_cur_stmt=
first_successful_insert_id_in_cur_stmt;
if ((!lex->requires_prelocking() || is_update_query(lex->sql_command)) &&
!is_current_stmt_binlog_format_row())
-@@ -3405,6 +3443,14 @@
+@@ -3676,6 +3714,14 @@
cuted_fields= 0;
transaction.savepoints= 0;
first_successful_insert_id_in_cur_stmt= 0;
}
-@@ -3467,6 +3513,12 @@
+@@ -3738,6 +3784,12 @@
*/
examined_row_count+= backup->examined_row_count;
cuted_fields+= backup->cuted_fields;
DBUG_VOID_RETURN;
}
-diff -ruN a/sql/sql_class.h b/sql/sql_class.h
---- a/sql/sql_class.h 2011-04-09 18:48:19.000000000 +0400
-+++ b/sql/sql_class.h 2011-04-09 18:48:50.000000000 +0400
+--- a/sql/sql_class.h
++++ b/sql/sql_class.h
@@ -60,6 +60,33 @@
enum enum_duplicates { DUP_ERROR, DUP_REPLACE, DUP_UPDATE };
enum enum_delay_key_write { DELAY_KEY_WRITE_NONE, DELAY_KEY_WRITE_ON,
double long_query_time_double;
} SV;
-@@ -1135,6 +1173,14 @@
+@@ -1140,6 +1178,14 @@
uint in_sub_stmt;
bool enable_slow_log;
bool last_insert_id_used;
SAVEPOINT *savepoints;
enum enum_check_fields count_cuted_fields;
};
-@@ -1583,6 +1629,26 @@
+@@ -1588,6 +1634,26 @@
thr_lock_type update_lock_default;
Delayed_insert *di;
/* <> 0 if we are inside of trigger or stored function. */
uint in_sub_stmt;
-diff -ruN a/sql/sql_connect.cc b/sql/sql_connect.cc
---- a/sql/sql_connect.cc 2011-04-09 18:48:05.000000000 +0400
-+++ b/sql/sql_connect.cc 2011-04-09 18:48:50.000000000 +0400
-@@ -764,4 +764,13 @@
+--- a/sql/sql_connect.cc
++++ b/sql/sql_connect.cc
+@@ -721,6 +721,15 @@
+ MYSQL_CONNECTION_START(thd->thread_id, &thd->security_ctx->priv_user[0],
+ (char *) thd->security_ctx->host_or_ip);
+ /*
+ If rate limiting of slow log writes is enabled, decide whether to log this
+ (thd->thread_id % thd->variables.log_slow_rate_limit) == 0)
+ thd->write_to_slow_log= TRUE;
+
- prepare_new_connection_state(thd);
-
- while (!net->error && net->vio != 0 &&
-diff -ruN a/sql/sql_parse.cc b/sql/sql_parse.cc
---- a/sql/sql_parse.cc 2011-04-09 18:48:20.000000000 +0400
-+++ b/sql/sql_parse.cc 2011-04-09 18:48:50.000000000 +0400
+ prepare_new_connection_state(thd);
+ return FALSE;
+ }
+--- a/sql/sql_parse.cc
++++ b/sql/sql_parse.cc
@@ -1430,7 +1430,6 @@
DBUG_RETURN(error);
}
/*
Do not log administrative statements unless the appropriate option is
set.
-@@ -1818,6 +1853,9 @@
+@@ -1879,6 +1914,9 @@
context.resolve_in_table_list_only(select_lex->
table_list.first);
/*
Reset warning count for each query that uses tables
A better approach would be to reset this for any commands
-@@ -5252,6 +5290,21 @@
+@@ -5297,6 +5335,21 @@
thd->rand_used= 0;
thd->sent_row_count= thd->examined_row_count= 0;
thd->reset_current_stmt_binlog_format_row();
thd->binlog_unsafe_warning_flags= 0;
-diff -ruN a/sql/sql_select.cc b/sql/sql_select.cc
---- a/sql/sql_select.cc 2011-04-09 18:48:17.000000000 +0400
-+++ b/sql/sql_select.cc 2011-04-09 18:48:50.000000000 +0400
+--- a/sql/sql_select.cc
++++ b/sql/sql_select.cc
@@ -6902,7 +6902,10 @@
{
join->thd->server_status|=SERVER_QUERY_NO_INDEX_USED;
}
}
if (!table->no_keyread)
-@@ -10247,6 +10253,7 @@
+@@ -10264,6 +10270,7 @@
(ulong) rows_limit,test(group)));
status_var_increment(thd->status_var.created_tmp_tables);
if (use_temp_pool && !(test_flags & TEST_KEEP_TMP_TABLES))
temp_pool_slot = bitmap_lock_set_next(&temp_pool);
-@@ -11145,6 +11152,7 @@
+@@ -11162,6 +11169,7 @@
goto err;
}
status_var_increment(table->in_use->status_var.created_tmp_disk_tables);
share->db_record_offset= 1;
DBUG_RETURN(0);
err:
-@@ -11163,6 +11171,14 @@
+@@ -11180,6 +11188,14 @@
save_proc_info=thd->proc_info;
thd_proc_info(thd, "removing tmp table");
// Release latches since this can take a long time
ha_release_temporary_latches(thd);
-diff -ruN a/sql/sql_show.cc b/sql/sql_show.cc
---- a/sql/sql_show.cc 2011-04-09 18:48:20.000000000 +0400
-+++ b/sql/sql_show.cc 2011-04-09 18:48:50.000000000 +0400
+--- a/sql/sql_show.cc
++++ b/sql/sql_show.cc
@@ -1950,8 +1950,17 @@
table->field[4]->store(command_name[tmp->command].str,
command_name[tmp->command].length, cs);
/* STATE */
if ((val= thread_state_info(tmp)))
{
-diff -ruN a/sql/sys_vars.cc b/sql/sys_vars.cc
---- a/sql/sys_vars.cc 2011-04-09 18:48:19.000000000 +0400
-+++ b/sql/sys_vars.cc 2011-04-09 18:48:50.000000000 +0400
+--- a/sql/sys_vars.cc
++++ b/sql/sys_vars.cc
@@ -2898,6 +2898,117 @@
DEFAULT(FALSE), NO_MUTEX_GUARD, NOT_IN_BINLOG, ON_CHECK(0),
ON_UPDATE(fix_log_state));
/* Synonym of "slow_query_log" for consistency with SHOW VARIABLES output */
static Sys_var_mybool Sys_log_slow(
"log_slow_queries",
-diff -ruN a/sql/sql_profile.cc b/sql/sql_profile.cc
---- a/sql/sql_profile.cc 2011-04-09 18:48:05.000000000 +0400
-+++ b/sql/sql_profile.cc 2011-04-09 18:48:50.000000000 +0400
+--- a/sql/sql_profile.cc
++++ b/sql/sql_profile.cc
@@ -243,7 +243,8 @@
{
time_usecs= (double) my_getsystime() / 10.0; /* 1 sec was 1e7, now is 1e6 */
#else
/* TODO: Add swap info for non-BSD systems */
#endif
-diff -ruN a/sql/sql_profile.h b/sql/sql_profile.h
---- a/sql/sql_profile.h 2011-04-09 18:48:05.000000000 +0400
-+++ b/sql/sql_profile.h 2011-04-09 18:48:50.000000000 +0400
+--- a/sql/sql_profile.h
++++ b/sql/sql_profile.h
@@ -164,11 +164,15 @@
*/
class PROF_MEASUREMENT
#!!! notice !!!
# Any small change to this file in the main branch
# should be done or reviewed by the maintainer!
-diff -ruN a/client/mysqldump.c b/client/mysqldump.c
---- a/client/mysqldump.c 2011-04-09 18:48:18.000000000 +0400
-+++ b/client/mysqldump.c 2011-04-09 18:48:58.000000000 +0400
-@@ -139,6 +139,8 @@
+--- a/client/mysqldump.c
++++ b/client/mysqldump.c
+@@ -141,6 +141,8 @@
static uint opt_protocol= 0;
static char *opt_plugin_dir= 0, *opt_default_auth= 0;
/*
Dynamic_string wrapper functions. In this file use these
wrappers, they will terminate the process if there is
-@@ -1492,6 +1494,17 @@
+@@ -1494,6 +1496,17 @@
/* Don't switch charsets for 4.1 and earlier. (bug#34192). */
server_supports_switching_charsets= FALSE;
}
/*
As we're going to set SQL_MODE, it would be lost on reconnect, so we
cannot reconnect.
-@@ -3173,7 +3186,12 @@
+@@ -3175,7 +3188,12 @@
/* now build the query string */
dynstr_append_checked(&query_string, filename);
dynstr_append_checked(&query_string, "'");
-@@ -3223,7 +3241,12 @@
+@@ -3225,7 +3243,12 @@
check_io(md_result_file);
}
dynstr_append_checked(&query_string, result_table);
if (where)
-diff -ruN /dev/null b/include/flashcache_ioctl.h
---- /dev/null 1970-01-01 00:00:00.000000000 +0000
-+++ b/include/flashcache_ioctl.h 2011-04-09 18:48:58.000000000 +0400
+--- /dev/null
++++ b/include/flashcache_ioctl.h
@@ -0,0 +1,53 @@
+/****************************************************************************
+ * flashcache_ioctl.h
+#define FLASHCACHEDELALLWHITELIST _IOW(FLASHCACHE_IOCTL, FLASHCACHEDELWHITELISTALL_CMD, pid_t)
+
+#endif
-diff -ruN /dev/null b/patch_info/sql_no_fcache.info
---- /dev/null 1970-01-01 00:00:00.000000000 +0000
-+++ b/patch_info/sql_no_fcache.info 2011-04-09 18:48:58.000000000 +0400
+--- /dev/null
++++ b/patch_info/sql_no_fcache.info
@@ -0,0 +1,6 @@
+File=sql_no_fcache.patch
+Name=Support for flashcache including the SQL_NO_FCACHE option that prevents blocks from being cached during a query.
+Author=Facebook
+License=GPL
+Comment=
-diff -ruN a/sql/lex.h b/sql/lex.h
---- a/sql/lex.h 2011-04-09 18:48:55.000000000 +0400
-+++ b/sql/lex.h 2011-04-09 18:48:58.000000000 +0400
+--- a/sql/lex.h
++++ b/sql/lex.h
@@ -516,6 +516,7 @@
{ "SQL_CACHE", SYM(SQL_CACHE_SYM)},
{ "SQL_CALC_FOUND_ROWS", SYM(SQL_CALC_FOUND_ROWS)},
{ "SQL_SMALL_RESULT", SYM(SQL_SMALL_RESULT)},
{ "SQL_THREAD", SYM(SQL_THREAD)},
{ "SQL_TSI_SECOND", SYM(SECOND_SYM)},
-diff -ruN a/sql/mysqld.h b/sql/mysqld.h
---- a/sql/mysqld.h 2011-04-09 18:48:55.000000000 +0400
-+++ b/sql/mysqld.h 2011-04-09 18:48:58.000000000 +0400
+--- a/sql/mysqld.h
++++ b/sql/mysqld.h
@@ -194,6 +194,8 @@
extern char language[FN_REFLEN];
extern "C" MYSQL_PLUGIN_IMPORT ulong server_id;
extern time_t server_start_time, flush_status_time;
extern char *opt_mysql_tmpdir, mysql_charsets_dir[];
extern int mysql_unpacked_real_data_home_len;
-diff -ruN a/sql/mysqld.cc b/sql/mysqld.cc
---- a/sql/mysqld.cc 2011-04-09 18:48:55.000000000 +0400
-+++ b/sql/mysqld.cc 2011-04-09 18:48:58.000000000 +0400
+--- a/sql/mysqld.cc
++++ b/sql/mysqld.cc
@@ -86,6 +86,11 @@
#ifdef HAVE_SYS_PRCTL_H
#include <sys/prctl.h>
#include <thr_alarm.h>
#include <ft_global.h>
-@@ -482,6 +487,11 @@
+@@ -487,6 +492,11 @@
ulong binlog_cache_use= 0, binlog_cache_disk_use= 0;
ulong binlog_stmt_cache_use= 0, binlog_stmt_cache_disk_use= 0;
ulong max_connections, max_connect_errors;
/*
Maximum length of parameter value which can be set through
mysql_send_long_data() call.
-@@ -4202,6 +4212,97 @@
+@@ -4252,6 +4262,97 @@
#define decrement_handler_count()
#endif /* defined(_WIN32) || defined(HAVE_SMEM) */
#ifndef EMBEDDED_LIBRARY
#ifndef DBUG_OFF
-@@ -4460,6 +4561,10 @@
+@@ -4510,6 +4611,10 @@
test_lc_time_sz();
#endif
/*
We have enough space for fiddling with the argv, continue
*/
-@@ -4663,6 +4768,10 @@
+@@ -4713,6 +4818,10 @@
}
#endif
clean_up(1);
mysqld_exit(0);
}
-@@ -6496,6 +6605,7 @@
+@@ -6557,6 +6666,7 @@
{"Delayed_errors", (char*) &delayed_insert_errors, SHOW_LONG},
{"Delayed_insert_threads", (char*) &delayed_insert_threads, SHOW_LONG_NOFLUSH},
{"Delayed_writes", (char*) &delayed_insert_writes, SHOW_LONG},
{"Flush_commands", (char*) &refresh_version, SHOW_LONG_NOFLUSH},
{"Handler_commit", (char*) offsetof(STATUS_VAR, ha_commit_count), SHOW_LONG_STATUS},
{"Handler_delete", (char*) offsetof(STATUS_VAR, ha_delete_count), SHOW_LONG_STATUS},
-diff -ruN a/sql/sql_lex.cc b/sql/sql_lex.cc
---- a/sql/sql_lex.cc 2011-04-09 18:48:04.000000000 +0400
-+++ b/sql/sql_lex.cc 2011-04-09 18:48:58.000000000 +0400
+--- a/sql/sql_lex.cc
++++ b/sql/sql_lex.cc
@@ -384,6 +384,7 @@
lex->describe= 0;
lex->subqueries= FALSE;
lex->derived_tables= 0;
lex->safe_to_cache_query= 1;
lex->leaf_tables_insert= 0;
-diff -ruN a/sql/sql_lex.h b/sql/sql_lex.h
---- a/sql/sql_lex.h 2011-04-09 18:48:20.000000000 +0400
-+++ b/sql/sql_lex.h 2011-04-09 18:48:58.000000000 +0400
-@@ -2292,6 +2292,7 @@
+--- a/sql/sql_lex.h
++++ b/sql/sql_lex.h
+@@ -2298,6 +2298,7 @@
enum enum_yes_no_unknown tx_chain, tx_release;
bool safe_to_cache_query;
bool subqueries, ignore;
st_parsing_options parsing_options;
Alter_info alter_info;
-diff -ruN a/sql/sql_select.cc b/sql/sql_select.cc
---- a/sql/sql_select.cc 2011-04-09 18:48:50.000000000 +0400
-+++ b/sql/sql_select.cc 2011-04-09 18:48:58.000000000 +0400
+--- a/sql/sql_select.cc
++++ b/sql/sql_select.cc
@@ -55,6 +55,12 @@
#define PREV_BITS(type,A) ((type) (((type) 1 << (A)) -1))
MYSQL_SELECT_DONE((int) res, (ulong) thd->limit_found_rows);
DBUG_RETURN(res);
}
-diff -ruN a/sql/sql_yacc.yy b/sql/sql_yacc.yy
---- a/sql/sql_yacc.yy 2011-04-09 18:48:55.000000000 +0400
-+++ b/sql/sql_yacc.yy 2011-04-09 18:48:58.000000000 +0400
-@@ -1283,6 +1283,7 @@
+--- a/sql/sql_yacc.yy
++++ b/sql/sql_yacc.yy
+@@ -1284,6 +1284,7 @@
%token SQL_CACHE_SYM
%token SQL_CALC_FOUND_ROWS
%token SQL_NO_CACHE_SYM
%token SQL_SMALL_RESULT
%token SQL_SYM /* SQL-2003-R */
%token SQL_THREAD
-@@ -7349,6 +7350,10 @@
+@@ -7353,6 +7354,10 @@
Lex->select_lex.sql_cache= SELECT_LEX::SQL_NO_CACHE;
}
}
--- a/scripts/mysqld_multi.sh
+++ b/scripts/mysqld_multi.sh
-@@ -233,10 +233,10 @@ sub report_mysqlds
+@@ -233,10 +233,10 @@
{
my (@groups, $com, $i, @options, $pec);
}
@groups = &find_groups($groupids);
for ($i = 0; defined($groups[$i]); $i++)
-@@ -247,19 +247,19 @@ sub report_mysqlds
+@@ -247,19 +247,19 @@
$pec = $? >> 8;
if ($pec)
{
"$opt_log", 0, 0);
}
}
-@@ -284,11 +284,11 @@ sub start_mysqlds()
+@@ -284,11 +284,11 @@
if (!$opt_no_log)
{
}
@groups = &find_groups($groupids);
for ($i = 0; defined($groups[$i]); $i++)
-@@ -359,7 +359,7 @@ sub start_mysqlds()
+@@ -359,7 +359,7 @@
}
if (!$i && !$opt_no_log)
{
"$opt_log", 0, 0);
}
}
-@@ -374,11 +374,11 @@ sub stop_mysqlds()
+@@ -374,11 +374,11 @@
if (!$opt_no_log)
{
}
@groups = &find_groups($groupids);
for ($i = 0; defined($groups[$i]); $i++)
-@@ -391,7 +391,7 @@ sub stop_mysqlds()
+@@ -391,7 +391,7 @@
}
if (!$i && !$opt_no_log)
{
### END INIT INFO
# If you install MySQL on some other places than @prefix@, then you
-@@ -275,7 +275,7 @@ case "$mode" in
+@@ -275,7 +275,7 @@
# Safeguard (relative paths, core dumps..)
cd $basedir
if test -x $bindir/mysqld_safe
then
# Give extra arguments to mysqld with the my.cnf file. This script
-@@ -305,12 +305,12 @@ case "$mode" in
+@@ -305,12 +305,12 @@
if (kill -0 $mysqld_pid 2>/dev/null)
then
rm "$mysqld_pid_file_path"
fi
-@@ -321,7 +321,7 @@ case "$mode" in
+@@ -321,7 +321,7 @@
fi
exit $return_value
else
fi
;;
-@@ -339,10 +339,10 @@ case "$mode" in
+@@ -339,10 +339,10 @@
'reload'|'force-reload')
if test -s "$mysqld_pid_file_path" ; then
read mysqld_pid < "$mysqld_pid_file_path"
exit 1
fi
;;
-@@ -351,10 +351,10 @@ case "$mode" in
+@@ -351,10 +351,10 @@
if test -s "$mysqld_pid_file_path" ; then
read mysqld_pid < "$mysqld_pid_file_path"
if kill -0 $mysqld_pid 2>/dev/null ; then
exit 1
fi
else
-@@ -362,13 +362,13 @@ case "$mode" in
+@@ -362,13 +362,13 @@
mysqld_pid=`pidof $libexecdir/mysqld`
if test -z $mysqld_pid ; then
if test -f "$lock_file_path" ; then
exit 4
fi
fi
-@@ -376,7 +376,7 @@ case "$mode" in
+@@ -376,7 +376,7 @@
*)
# usage
basename=`basename "$0"`
#!!! notice !!!
# Any small change to this file in the main branch
# should be done or reviewed by the maintainer!
-diff -ruN a/include/mysql/plugin.h b/include/mysql/plugin.h
---- a/include/mysql/plugin.h 2011-04-10 12:23:47.000000000 +0400
-+++ b/include/mysql/plugin.h 2011-04-10 12:24:34.000000000 +0400
+--- a/include/mysql/plugin.h
++++ b/include/mysql/plugin.h
@@ -547,6 +547,9 @@
unsigned long thd_log_slow_verbosity(const MYSQL_THD thd);
int thd_opt_slow_log();
/**
Create a temporary file.
-diff -ruN a/include/mysql_com.h b/include/mysql_com.h
---- a/include/mysql_com.h 2011-04-10 12:23:52.000000000 +0400
-+++ b/include/mysql_com.h 2011-04-10 12:24:34.000000000 +0400
+--- a/include/mysql_com.h
++++ b/include/mysql_com.h
@@ -31,6 +31,7 @@
#define SERVER_VERSION_LENGTH 60
#define CLIENT_LONG_PASSWORD 1 /* new more secure passwords */
#define CLIENT_FOUND_ROWS 2 /* Found instead of affected rows */
-diff -ruN /dev/null b/patch_info/userstats.patch
---- /dev/null 1970-01-01 00:00:00.000000000 +0000
-+++ b/patch_info/userstats.patch 2011-04-10 12:24:34.000000000 +0400
+--- /dev/null
++++ b/patch_info/userstats.patch
@@ -0,0 +1,17 @@
+File=userstats.patch
+Name=SHOW USER/TABLE/INDEX statistics
+Fix porting
+2011-02
+Rename variable USERSTAT_RUNNING => USERSTAT
-diff -ruN a/sql/handler.cc b/sql/handler.cc
---- a/sql/handler.cc 2011-04-10 12:16:42.000000000 +0400
-+++ b/sql/handler.cc 2011-04-10 12:24:34.000000000 +0400
-@@ -1243,6 +1243,8 @@
+--- a/sql/handler.cc
++++ b/sql/handler.cc
+@@ -1244,6 +1244,8 @@
goto end;
}
DBUG_EXECUTE_IF("crash_commit_after", DBUG_SUICIDE(););
RUN_HOOK(transaction, after_commit, (thd, FALSE));
end:
if (rw_trans && mdl_request.ticket)
-@@ -1397,6 +1399,8 @@
+@@ -1398,6 +1400,8 @@
/* Always cleanup. Even if nht==0. There may be savepoints. */
if (is_real_trans)
thd->transaction.cleanup();
if (all)
thd->transaction_rollback_request= FALSE;
-@@ -1800,6 +1804,7 @@
+@@ -1802,6 +1806,7 @@
ha_info->reset(); /* keep it conveniently zero-filled */
}
trans->ha_list= sv->ha_list;
DBUG_RETURN(error);
}
-@@ -2176,6 +2181,8 @@
+@@ -2178,6 +2183,8 @@
dup_ref=ref+ALIGN_SIZE(ref_length);
cached_table_flags= table_flags();
}
DBUG_RETURN(error);
}
-@@ -3626,6 +3633,127 @@
+@@ -3631,6 +3638,127 @@
return;
}
/****************************************************************************
** Some general functions that isn't in the handler class
-diff -ruN a/sql/handler.h b/sql/handler.h
---- a/sql/handler.h 2011-04-10 12:23:52.000000000 +0400
-+++ b/sql/handler.h 2011-04-10 12:24:34.000000000 +0400
-@@ -35,6 +35,10 @@
+--- a/sql/handler.h
++++ b/sql/handler.h
+@@ -36,6 +36,10 @@
#include <ft_global.h>
#include <keycache.h>
// the following is for checking tables
#define HA_ADMIN_ALREADY_DONE 1
-@@ -561,10 +565,12 @@
+@@ -562,10 +566,12 @@
enum enum_schema_tables
{
SCH_CHARSETS= 0,
SCH_ENGINES,
SCH_EVENTS,
SCH_FILES,
-@@ -592,9 +598,12 @@
+@@ -593,9 +599,12 @@
SCH_TABLE_CONSTRAINTS,
SCH_TABLE_NAMES,
SCH_TABLE_PRIVILEGES,
SCH_VARIABLES,
SCH_VIEWS
};
-@@ -1209,6 +1218,9 @@
+@@ -1231,6 +1240,9 @@
bool locked;
bool implicit_emptied; /* Can be !=0 only if HEAP */
const COND *pushed_cond;
/**
next_insert_id is the next value which should be inserted into the
auto_increment column: in a inserting-multi-row statement (like INSERT
-@@ -1260,10 +1272,12 @@
+@@ -1282,10 +1294,12 @@
ref_length(sizeof(my_off_t)),
ft_handler(0), inited(NONE),
locked(FALSE), implicit_emptied(0),
virtual ~handler(void)
{
DBUG_ASSERT(locked == FALSE);
-@@ -1386,6 +1400,8 @@
+@@ -1408,6 +1422,8 @@
{
table= table_arg;
table_share= share;
}
virtual double scan_time()
{ return ulonglong2double(stats.data_file_length) / IO_SIZE + 2; }
-@@ -1753,6 +1769,8 @@
+@@ -1803,6 +1819,8 @@
virtual bool is_crashed() const { return 0; }
virtual bool auto_repair() const { return 0; }
#define CHF_CREATE_FLAG 0
#define CHF_DELETE_FLAG 1
-diff -ruN a/sql/lex.h b/sql/lex.h
---- a/sql/lex.h 2011-04-10 12:23:55.000000000 +0400
-+++ b/sql/lex.h 2011-04-10 12:24:34.000000000 +0400
+--- a/sql/lex.h
++++ b/sql/lex.h
@@ -111,6 +111,7 @@
{ "CIPHER", SYM(CIPHER_SYM)},
{ "CLASS_ORIGIN", SYM(CLASS_ORIGIN_SYM)},
{ "USE_FRM", SYM(USE_FRM)},
{ "USING", SYM(USING)},
{ "UTC_DATE", SYM(UTC_DATE_SYM)},
-diff -ruN a/sql/log.cc b/sql/log.cc
---- a/sql/log.cc 2011-04-10 12:23:47.000000000 +0400
-+++ b/sql/log.cc 2011-04-10 12:24:34.000000000 +0400
+--- a/sql/log.cc
++++ b/sql/log.cc
@@ -1007,6 +1007,13 @@
mysql_slow_log.reopen_file();
}
/*
Log error with all enabled log event handlers
-@@ -5039,6 +5046,8 @@
+@@ -5040,6 +5047,8 @@
thd->first_successful_insert_id_in_prev_stmt_for_binlog);
if (e.write(file))
goto err;
}
if (thd->auto_inc_intervals_in_cur_stmt_for_binlog.nb_elements() > 0)
{
-@@ -5050,12 +5059,16 @@
+@@ -5051,12 +5060,16 @@
minimum());
if (e.write(file))
goto err;
}
if (thd->user_var_events.elements)
{
-@@ -5078,6 +5091,8 @@
+@@ -5079,6 +5092,8 @@
flags);
if (e.write(file))
goto err;
}
}
}
-@@ -5089,6 +5104,8 @@
+@@ -5090,6 +5105,8 @@
if (event_info->write(file) ||
DBUG_EVALUATE_IF("injecting_fault_writing", 1, 0))
goto err;
error= 0;
err:
-@@ -5274,7 +5291,8 @@
+@@ -5275,7 +5292,8 @@
be reset as a READ_CACHE to be able to read the contents from it.
*/
{
Mutex_sentry sentry(lock_log ? &LOCK_log : NULL);
-@@ -5321,6 +5339,7 @@
+@@ -5322,6 +5340,7 @@
/* write the first half of the split header */
if (my_b_write(&log_file, header, carry))
return ER_ERROR_ON_WRITE;
/*
copy fixed second half of header to cache so the correct
-@@ -5389,6 +5408,7 @@
+@@ -5390,6 +5409,7 @@
/* Write data to the binary log file */
if (my_b_write(&log_file, cache->read_pos, length))
return ER_ERROR_ON_WRITE;
cache->read_pos=cache->read_end; // Mark buffer used up
} while ((length= my_b_fill(cache)));
-@@ -5503,20 +5523,23 @@
+@@ -5504,20 +5524,23 @@
Query_log_event qinfo(thd, STRING_WITH_LEN("BEGIN"), TRUE, FALSE, TRUE, 0);
if (qinfo.write(&log_file))
goto err;
if (incident && write_incident(thd, FALSE))
goto err;
-diff -ruN a/sql/log.h b/sql/log.h
---- a/sql/log.h 2011-04-10 12:23:47.000000000 +0400
-+++ b/sql/log.h 2011-04-10 12:24:34.000000000 +0400
+--- a/sql/log.h
++++ b/sql/log.h
@@ -437,7 +437,8 @@
bool write(THD *thd, IO_CACHE *cache, Log_event *commit_event, bool incident);
bool write_incident(THD *thd, bool lock);
void init_pthread_objects();
MYSQL_QUERY_LOG *get_mysql_slow_log() { return &mysql_slow_log; }
MYSQL_QUERY_LOG *get_mysql_log() { return &mysql_log; }
-diff -ruN a/sql/mysqld.cc b/sql/mysqld.cc
---- a/sql/mysqld.cc 2011-04-10 12:23:56.000000000 +0400
-+++ b/sql/mysqld.cc 2011-04-10 12:24:34.000000000 +0400
-@@ -436,6 +436,7 @@
- uint opt_debug_sync_timeout= 0;
+--- a/sql/mysqld.cc
++++ b/sql/mysqld.cc
+@@ -441,6 +441,7 @@
+ MYSQL_PLUGIN_IMPORT uint opt_debug_sync_timeout= 0;
#endif /* defined(ENABLED_DEBUG_SYNC) */
my_bool opt_old_style_user_limits= 0, trust_function_creators= 0;
+my_bool opt_userstat= 0, opt_thread_statistics= 0;
my_bool opt_optimizer_fix= 0;
/*
True if there is at least one per-hour limit for some user, so we should
-@@ -487,6 +488,7 @@
+@@ -492,6 +493,7 @@
ulong binlog_cache_use= 0, binlog_cache_disk_use= 0;
ulong binlog_stmt_cache_use= 0, binlog_stmt_cache_disk_use= 0;
ulong max_connections, max_connect_errors;
/* flashcache */
int cachedev_fd;
-@@ -636,7 +638,9 @@
+@@ -641,7 +643,9 @@
LOCK_crypt,
LOCK_global_system_variables,
LOCK_user_conn, LOCK_slave_list, LOCK_active_mi,
/**
The below lock protects access to two global server variables:
max_prepared_stmt_count and prepared_stmt_count. These variables
-@@ -1499,6 +1503,11 @@
+@@ -1504,6 +1508,11 @@
#ifdef HAVE_RESPONSE_TIME_DISTRIBUTION
query_response_time_free();
#endif // HAVE_RESPONSE_TIME_DISTRIBUTION
#ifdef HAVE_REPLICATION
end_slave_list();
#endif
-@@ -1602,6 +1611,10 @@
+@@ -1607,6 +1616,10 @@
mysql_cond_destroy(&COND_thread_cache);
mysql_cond_destroy(&COND_flush_thread_cache);
mysql_cond_destroy(&COND_manager);
}
#endif /*EMBEDDED_LIBRARY*/
-@@ -3038,6 +3051,7 @@
+@@ -3088,6 +3101,7 @@
{"show_binlog_events", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_BINLOG_EVENTS]), SHOW_LONG_STATUS},
{"show_binlogs", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_BINLOGS]), SHOW_LONG_STATUS},
{"show_charsets", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_CHARSETS]), SHOW_LONG_STATUS},
{"show_collations", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_COLLATIONS]), SHOW_LONG_STATUS},
{"show_contributors", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_CONTRIBUTORS]), SHOW_LONG_STATUS},
{"show_create_db", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_CREATE_DB]), SHOW_LONG_STATUS},
-@@ -3058,6 +3072,7 @@
+@@ -3108,6 +3122,7 @@
#endif
{"show_function_status", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_STATUS_FUNC]), SHOW_LONG_STATUS},
{"show_grants", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_GRANTS]), SHOW_LONG_STATUS},
{"show_keys", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_KEYS]), SHOW_LONG_STATUS},
{"show_master_status", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_MASTER_STAT]), SHOW_LONG_STATUS},
{"show_open_tables", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_OPEN_TABLES]), SHOW_LONG_STATUS},
-@@ -3076,10 +3091,13 @@
+@@ -3126,10 +3141,13 @@
{"show_slave_status_nolock", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_SLAVE_NOLOCK_STAT]), SHOW_LONG_STATUS},
{"show_status", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_STATUS]), SHOW_LONG_STATUS},
{"show_storage_engines", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_STORAGE_ENGINES]), SHOW_LONG_STATUS},
{"show_variables", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_VARIABLES]), SHOW_LONG_STATUS},
{"show_warnings", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_WARNS]), SHOW_LONG_STATUS},
{"slave_start", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SLAVE_START]), SHOW_LONG_STATUS},
-@@ -3617,6 +3635,13 @@
+@@ -3667,6 +3685,13 @@
mysql_mutex_init(key_LOCK_server_started,
&LOCK_server_started, MY_MUTEX_INIT_FAST);
mysql_cond_init(key_COND_server_started, &COND_server_started, NULL);
sp_cache_init();
#ifdef HAVE_EVENT_SCHEDULER
Events::init_mutexes();
-@@ -3986,6 +4011,9 @@
+@@ -4036,6 +4061,9 @@
query_response_time_init();
#endif // HAVE_RESPONSE_TIME_DISTRIBUTION
/* We have to initialize the storage engines before CSV logging */
if (ha_init())
{
sql_print_error("Can't init databases");
-@@ -4122,6 +4150,9 @@
+@@ -4172,6 +4200,9 @@
init_max_user_conn();
init_update_queries();
DBUG_RETURN(0);
}
-@@ -5168,6 +5199,7 @@
+@@ -5226,6 +5257,7 @@
{
sql_print_warning("%s", ER_DEFAULT(ER_CON_COUNT_ERROR));
}
delete thd;
DBUG_VOID_RETURN;
}
-@@ -7882,6 +7914,8 @@
+@@ -7961,6 +7993,8 @@
key_delayed_insert_mutex, key_hash_filo_lock, key_LOCK_active_mi,
key_LOCK_connection_count, key_LOCK_crypt, key_LOCK_delayed_create,
key_LOCK_delayed_insert, key_LOCK_delayed_status, key_LOCK_error_log,
key_LOCK_gdl, key_LOCK_global_system_variables,
key_LOCK_manager,
key_LOCK_prepared_stmt_count,
-@@ -7921,6 +7955,13 @@
+@@ -8000,6 +8034,13 @@
{ &key_LOCK_delayed_insert, "LOCK_delayed_insert", PSI_FLAG_GLOBAL},
{ &key_LOCK_delayed_status, "LOCK_delayed_status", PSI_FLAG_GLOBAL},
{ &key_LOCK_error_log, "LOCK_error_log", PSI_FLAG_GLOBAL},
{ &key_LOCK_gdl, "LOCK_gdl", PSI_FLAG_GLOBAL},
{ &key_LOCK_global_system_variables, "LOCK_global_system_variables", PSI_FLAG_GLOBAL},
{ &key_LOCK_manager, "LOCK_manager", PSI_FLAG_GLOBAL},
-diff -ruN a/sql/mysqld.h b/sql/mysqld.h
---- a/sql/mysqld.h 2011-04-10 12:23:56.000000000 +0400
-+++ b/sql/mysqld.h 2011-04-10 12:24:34.000000000 +0400
+--- a/sql/mysqld.h
++++ b/sql/mysqld.h
@@ -23,6 +23,7 @@
#include "my_atomic.h" /* my_atomic_rwlock_t */
#include "mysql/psi/mysql_file.h" /* MYSQL_FILE */
extern const char *opt_date_time_formats[];
extern handlerton *partition_hton;
extern handlerton *myisam_hton;
-@@ -246,6 +254,8 @@
+@@ -251,6 +259,8 @@
key_delayed_insert_mutex, key_hash_filo_lock, key_LOCK_active_mi,
key_LOCK_connection_count, key_LOCK_crypt, key_LOCK_delayed_create,
key_LOCK_delayed_insert, key_LOCK_delayed_status, key_LOCK_error_log,
key_LOCK_gdl, key_LOCK_global_system_variables,
key_LOCK_logger, key_LOCK_manager,
key_LOCK_prepared_stmt_count,
-@@ -345,7 +355,9 @@
+@@ -350,7 +360,9 @@
LOCK_delayed_status, LOCK_delayed_create, LOCK_crypt, LOCK_timezone,
LOCK_slave_list, LOCK_active_mi, LOCK_manager,
LOCK_global_system_variables, LOCK_user_conn,
extern MYSQL_PLUGIN_IMPORT mysql_mutex_t LOCK_thread_count;
#ifdef HAVE_OPENSSL
extern mysql_mutex_t LOCK_des_key_file;
-@@ -457,6 +469,16 @@
+@@ -462,6 +474,16 @@
return id;
}
/*
TODO: Replace this with an inline function.
-diff -ruN a/sql/sql_base.cc b/sql/sql_base.cc
---- a/sql/sql_base.cc 2011-04-10 12:16:42.000000000 +0400
-+++ b/sql/sql_base.cc 2011-04-10 12:24:34.000000000 +0400
+--- a/sql/sql_base.cc
++++ b/sql/sql_base.cc
@@ -1524,6 +1524,11 @@
table->mdl_ticket= NULL;
*table_ptr=table->next;
mysql_mutex_unlock(&thd->LOCK_thd_data);
-@@ -2149,6 +2154,8 @@
+@@ -2162,6 +2167,8 @@
DBUG_PRINT("tmptable", ("closing table: '%s'.'%s'",
table->s->db.str, table->s->table_name.str));
free_io_cache(table);
closefrm(table, 0);
if (delete_table)
-diff -ruN a/sql/sql_class.cc b/sql/sql_class.cc
---- a/sql/sql_class.cc 2011-04-10 12:23:56.000000000 +0400
-+++ b/sql/sql_class.cc 2011-04-10 12:24:34.000000000 +0400
-@@ -601,6 +601,13 @@
+--- a/sql/sql_class.cc
++++ b/sql/sql_class.cc
+@@ -850,6 +850,13 @@
mysys_var=0;
binlog_evt_union.do_union= FALSE;
enable_slow_log= 0;
#ifndef DBUG_OFF
dbug_sentry=THD_SENTRY_MAGIC;
#endif
-@@ -977,6 +984,7 @@
+@@ -1228,6 +1235,7 @@
variables.option_bits|= OPTION_BIN_LOG;
else
variables.option_bits&= ~OPTION_BIN_LOG;
#if defined(ENABLED_DEBUG_SYNC)
/* Initialize the Debug Sync Facility. See debug_sync.cc. */
-@@ -984,6 +992,94 @@
+@@ -1235,6 +1243,94 @@
#endif /* defined(ENABLED_DEBUG_SYNC) */
}
/*
Init THD for query processing.
-@@ -1718,6 +1814,32 @@
+@@ -1989,6 +2085,32 @@
}
#endif
struct Item_change_record: public ilink
{
-@@ -1894,6 +2016,7 @@
+@@ -2165,6 +2287,7 @@
}
thd->sent_row_count++;
if (thd->vio_ok())
DBUG_RETURN(protocol->write());
-@@ -1986,6 +2109,7 @@
+@@ -2257,6 +2380,7 @@
select_export::~select_export()
{
thd->sent_row_count=row_count;
}
-@@ -3009,6 +3133,7 @@
+@@ -3280,6 +3404,7 @@
if (likely(thd != 0))
{ /* current_thd==0 when close_connection() calls net_send_error() */
thd->status_var.bytes_sent+= length;
}
}
-@@ -3016,6 +3141,7 @@
+@@ -3287,6 +3412,7 @@
void thd_increment_bytes_received(ulong length)
{
current_thd->status_var.bytes_received+= length;
}
-diff -ruN a/sql/sql_class.h b/sql/sql_class.h
---- a/sql/sql_class.h 2011-04-10 12:23:56.000000000 +0400
-+++ b/sql/sql_class.h 2011-04-10 12:24:34.000000000 +0400
-@@ -1625,6 +1625,8 @@
+--- a/sql/sql_class.h
++++ b/sql/sql_class.h
+@@ -1630,6 +1630,8 @@
*/
enum enum_server_command command;
uint32 server_id;
uint32 file_id; // for LOAD DATA INFILE
/* remote (peer) port */
uint16 peer_port;
-@@ -2096,6 +2098,8 @@
+@@ -2101,6 +2103,8 @@
*/
enum_tx_isolation tx_isolation;
enum_check_fields count_cuted_fields;
DYNAMIC_ARRAY user_var_events; /* For user variables replication */
MEM_ROOT *user_var_events_alloc; /* Allocate above array elements here */
-@@ -2190,6 +2194,49 @@
+@@ -2195,6 +2199,49 @@
*/
LOG_INFO* current_linfo;
NET* slave_net; // network connection from slave -> m.
/* Used by the sys_var class to store temporary values */
union
{
-@@ -2270,6 +2317,11 @@
+@@ -2275,6 +2322,11 @@
alloc_root.
*/
void init_for_queries();
void change_user(void);
void cleanup(void);
void cleanup_after_query();
-@@ -2741,6 +2793,15 @@
+@@ -2747,6 +2799,15 @@
}
thd_scheduler scheduler;
public:
inline Internal_error_handler *get_internal_handler()
{ return m_internal_handler; }
-@@ -2929,6 +2990,10 @@
+@@ -2947,6 +3008,10 @@
LEX_STRING invoker_host;
};
/** A short cut for thd->stmt_da->set_ok_status(). */
-diff -ruN a/sql/sql_connect.cc b/sql/sql_connect.cc
---- a/sql/sql_connect.cc 2011-04-10 12:23:47.000000000 +0400
-+++ b/sql/sql_connect.cc 2011-04-10 12:24:34.000000000 +0400
-@@ -55,6 +55,24 @@
+--- a/sql/sql_connect.cc
++++ b/sql/sql_connect.cc
+@@ -56,6 +56,24 @@
#define MIN_HANDSHAKE_SIZE 6
#endif /* HAVE_OPENSSL && !EMBEDDED_LIBRARY */
/*
Get structure for logging connection data for the current user
*/
-@@ -112,6 +130,586 @@
+@@ -113,6 +131,586 @@
}
/*
check if user has already too many connections
-@@ -169,6 +767,7 @@
+@@ -170,6 +768,7 @@
if (error)
{
uc->connections--; // no need for decrease_user_connections() here
/*
The thread may returned back to the pool and assigned to a user
that doesn't have a limit. Ensure the user is not using resources
-@@ -588,11 +1187,18 @@
+@@ -589,11 +1188,18 @@
my_sleep(1000); /* must wait after eof() */
#endif
statistic_increment(aborted_connects,&LOCK_status);
DBUG_RETURN(0);
}
-@@ -622,6 +1228,7 @@
+@@ -623,6 +1229,7 @@
if (thd->killed || (net->error && net->vio != 0))
{
statistic_increment(aborted_threads,&LOCK_status);
}
if (net->error && net->vio != 0)
-@@ -752,12 +1359,16 @@
+@@ -787,10 +1394,14 @@
+ for (;;)
{
- NET *net= &thd->net;
bool rc;
+ bool create_user= TRUE;
- lex_start(thd);
- rc= login_connection(thd);
- MYSQL_AUDIT_NOTIFY_CONNECTION_CONNECT(thd);
+ rc= thd_prepare_connection(thd);
if (rc)
+ {
+ create_user= FALSE;
goto end_thread;
+ }
- MYSQL_CONNECTION_START(thd->thread_id, &thd->security_ctx->priv_user[0],
- (char *) thd->security_ctx->host_or_ip);
-@@ -784,6 +1395,8 @@
+ while (thd_is_connection_alive(thd))
+ {
+@@ -802,6 +1413,8 @@
end_thread:
close_connection(thd);
if (MYSQL_CALLBACK_ELSE(thread_scheduler, end_thread, (thd, 1), 0))
return; // Probably no-threads
-diff -ruN a/sql/sql_delete.cc b/sql/sql_delete.cc
---- a/sql/sql_delete.cc 2011-04-10 12:16:42.000000000 +0400
-+++ b/sql/sql_delete.cc 2011-04-10 12:24:34.000000000 +0400
+--- a/sql/sql_delete.cc
++++ b/sql/sql_delete.cc
@@ -411,6 +411,7 @@
my_ok(thd, deleted);
DBUG_PRINT("info",("%ld records deleted",(long) deleted));
return 0;
}
-diff -ruN a/sql/sql_insert.cc b/sql/sql_insert.cc
---- a/sql/sql_insert.cc 2011-04-10 12:16:42.000000000 +0400
-+++ b/sql/sql_insert.cc 2011-04-10 12:24:34.000000000 +0400
-@@ -1069,13 +1069,14 @@
+--- a/sql/sql_insert.cc
++++ b/sql/sql_insert.cc
+@@ -1070,13 +1070,14 @@
if (error)
goto abort;
}
else
{
-@@ -1091,8 +1092,10 @@
+@@ -1092,8 +1093,10 @@
sprintf(buff, ER(ER_INSERT_INFO), (ulong) info.records,
(ulong) (info.deleted + updated),
(ulong) thd->warning_info->statement_warn_count());
thd->abort_on_warning= 0;
DBUG_RETURN(FALSE);
-@@ -3539,6 +3542,7 @@
+@@ -3540,6 +3543,7 @@
thd->first_successful_insert_id_in_prev_stmt :
(info.copied ? autoinc_value_of_last_inserted_row : 0));
::my_ok(thd, row_count, id, buff);
DBUG_RETURN(0);
}
-diff -ruN a/sql/sql_lex.h b/sql/sql_lex.h
---- a/sql/sql_lex.h 2011-04-10 12:23:55.000000000 +0400
-+++ b/sql/sql_lex.h 2011-04-10 12:25:07.000000000 +0400
+--- a/sql/sql_lex.h
++++ b/sql/sql_lex.h
@@ -197,6 +197,9 @@
in "struct show_var_st status_vars[]= {" ...
*/
/* This should be the last !!! */
SQLCOM_END
};
-diff -ruN a/sql/sql_parse.cc b/sql/sql_parse.cc
---- a/sql/sql_parse.cc 2011-04-10 12:23:55.000000000 +0400
-+++ b/sql/sql_parse.cc 2011-04-10 12:24:34.000000000 +0400
+--- a/sql/sql_parse.cc
++++ b/sql/sql_parse.cc
@@ -116,6 +116,9 @@
static bool execute_sqlcom_select(THD *thd, TABLE_LIST *all_tables);
static void sql_kill(THD *thd, ulong id, bool only_kill_query);
my_error(ER_SPECIFIC_ACCESS_DENIED_ERROR, MYF(0), "SUPER");
DBUG_RETURN(TRUE);
}
-@@ -4757,6 +4778,7 @@
+@@ -4802,6 +4823,7 @@
case ACL_INTERNAL_ACCESS_DENIED:
if (! no_errors)
{
my_error(ER_DBACCESS_DENIED_ERROR, MYF(0),
sctx->priv_user, sctx->priv_host, db);
}
-@@ -4807,6 +4829,7 @@
+@@ -4852,6 +4874,7 @@
DBUG_PRINT("error",("No possible access"));
if (!no_errors)
{
if (thd->password == 2)
my_error(ER_ACCESS_DENIED_NO_PASSWORD_ERROR, MYF(0),
sctx->priv_user,
-@@ -4923,6 +4946,7 @@
+@@ -4968,6 +4991,7 @@
if (!thd->col_access && check_grant_db(thd, dst_db_name))
{
my_error(ER_DBACCESS_DENIED_ERROR, MYF(0),
thd->security_ctx->priv_user,
thd->security_ctx->priv_host,
-@@ -5193,6 +5217,7 @@
+@@ -5238,6 +5262,7 @@
if ((thd->security_ctx->master_access & want_access))
return 0;
get_privilege_desc(command, sizeof(command), want_access);
my_error(ER_SPECIFIC_ACCESS_DENIED_ERROR, MYF(0), command);
return 1;
#else
-@@ -5574,6 +5599,32 @@
+@@ -5619,6 +5644,32 @@
lex_start(thd);
mysql_reset_thd_for_next_command(thd);
if (query_cache_send_result_to_client(thd, rawbuf, length) <= 0)
{
LEX *lex= thd->lex;
-@@ -5642,6 +5693,52 @@
+@@ -5687,6 +5738,52 @@
DBUG_ASSERT(thd->change_list.is_empty());
}
DBUG_VOID_RETURN;
}
-diff -ruN a/sql/sql_prepare.cc b/sql/sql_prepare.cc
---- a/sql/sql_prepare.cc 2011-04-10 12:16:42.000000000 +0400
-+++ b/sql/sql_prepare.cc 2011-04-10 12:24:34.000000000 +0400
+--- a/sql/sql_prepare.cc
++++ b/sql/sql_prepare.cc
@@ -114,6 +114,9 @@
#endif
#include "lock.h" // MYSQL_OPEN_FORCE_SHARED_MDL
if (!(stmt= find_prepared_statement(thd, stmt_id)))
{
char llbuf[22];
- my_error(ER_UNKNOWN_STMT_HANDLER, MYF(0), sizeof(llbuf),
+ my_error(ER_UNKNOWN_STMT_HANDLER, MYF(0), static_cast<int>(sizeof(llbuf)),
llstr(stmt_id, llbuf), "mysqld_stmt_execute");
- DBUG_VOID_RETURN;
+ goto end;
if (!(stmt= find_prepared_statement(thd, stmt_id)))
{
char llbuf[22];
- my_error(ER_UNKNOWN_STMT_HANDLER, MYF(0), sizeof(llbuf),
+ my_error(ER_UNKNOWN_STMT_HANDLER, MYF(0), static_cast<int>(sizeof(llbuf)),
llstr(stmt_id, llbuf), "mysqld_stmt_fetch");
- DBUG_VOID_RETURN;
+ goto end;
if (!(stmt= find_prepared_statement(thd, stmt_id)))
{
char llbuf[22];
- my_error(ER_UNKNOWN_STMT_HANDLER, MYF(0), sizeof(llbuf),
+ my_error(ER_UNKNOWN_STMT_HANDLER, MYF(0), static_cast<int>(sizeof(llbuf)),
llstr(stmt_id, llbuf), "mysqld_stmt_reset");
- DBUG_VOID_RETURN;
+ goto end;
DBUG_VOID_RETURN;
}
-diff -ruN a/sql/sql_reload.cc b/sql/sql_reload.cc
---- a/sql/sql_reload.cc 2011-04-10 12:23:52.000000000 +0400
-+++ b/sql/sql_reload.cc 2011-04-10 12:24:34.000000000 +0400
+--- a/sql/sql_reload.cc
++++ b/sql/sql_reload.cc
@@ -294,14 +294,48 @@
mysql_mutex_unlock(&LOCK_active_mi);
}
if (*write_to_binlog != -1)
*write_to_binlog= tmp_write_to_binlog;
/*
-diff -ruN a/sql/sql_show.cc b/sql/sql_show.cc
---- a/sql/sql_show.cc 2011-04-10 12:23:52.000000000 +0400
-+++ b/sql/sql_show.cc 2011-04-10 12:24:34.000000000 +0400
+--- a/sql/sql_show.cc
++++ b/sql/sql_show.cc
@@ -114,6 +114,43 @@
static COND * make_cond_for_info_schema(COND *cond, TABLE_LIST *table);
/* collect status for all running threads */
-@@ -7654,6 +7970,104 @@
+@@ -7689,6 +8005,104 @@
};
ST_FIELD_INFO processlist_fields_info[]=
{
{"ID", 4, MYSQL_TYPE_LONGLONG, 0, 0, "Id", SKIP_OPEN_TABLE},
-@@ -7843,6 +8257,8 @@
+@@ -7878,6 +8292,8 @@
{
{"CHARACTER_SETS", charsets_fields_info, create_schema_table,
fill_schema_charsets, make_character_sets_old_format, 0, -1, -1, 0, 0},
{"COLLATIONS", collation_fields_info, create_schema_table,
fill_schema_collation, make_old_format, 0, -1, -1, 0, 0},
{"COLLATION_CHARACTER_SET_APPLICABILITY", coll_charset_app_fields_info,
-@@ -7852,6 +8268,8 @@
+@@ -7887,6 +8303,8 @@
OPTIMIZE_I_S_TABLE|OPEN_VIEW_FULL},
{"COLUMN_PRIVILEGES", column_privileges_fields_info, create_schema_table,
fill_schema_column_privileges, 0, 0, -1, -1, 0, 0},
{"ENGINES", engines_fields_info, create_schema_table,
fill_schema_engines, make_old_format, 0, -1, -1, 0, 0},
#ifdef HAVE_EVENT_SCHEDULER
-@@ -7924,14 +8342,20 @@
+@@ -7959,14 +8377,20 @@
get_all_tables, make_table_names_old_format, 0, 1, 2, 1, 0},
{"TABLE_PRIVILEGES", table_privileges_fields_info, create_schema_table,
fill_schema_table_privileges, 0, 0, -1, -1, 0, 0},
{"VARIABLES", variables_fields_info, create_schema_table, fill_variables,
make_old_format, 0, 0, -1, 1, 0},
{"VIEWS", view_fields_info, create_schema_table,
-diff -ruN a/sql/sql_update.cc b/sql/sql_update.cc
---- a/sql/sql_update.cc 2011-04-10 12:16:42.000000000 +0400
-+++ b/sql/sql_update.cc 2011-04-10 12:24:34.000000000 +0400
+--- a/sql/sql_update.cc
++++ b/sql/sql_update.cc
@@ -900,8 +900,10 @@
my_snprintf(buff, sizeof(buff), ER(ER_UPDATE_INFO), (ulong) found,
(ulong) updated,
DBUG_PRINT("info",("%ld records updated", (long) updated));
}
thd->count_cuted_fields= CHECK_FIELD_IGNORE; /* calc cuted fields */
-@@ -2242,7 +2244,9 @@
+@@ -2252,7 +2254,9 @@
thd->first_successful_insert_id_in_prev_stmt : 0;
my_snprintf(buff, sizeof(buff), ER(ER_UPDATE_INFO),
(ulong) found, (ulong) updated, (ulong) thd->cuted_fields);
+ thd->updated_row_count+= row_count;
DBUG_RETURN(FALSE);
}
-diff -ruN a/sql/sql_yacc.yy b/sql/sql_yacc.yy
---- a/sql/sql_yacc.yy 2011-04-10 12:23:55.000000000 +0400
-+++ b/sql/sql_yacc.yy 2011-04-10 12:24:34.000000000 +0400
-@@ -864,6 +864,7 @@
+--- a/sql/sql_yacc.yy
++++ b/sql/sql_yacc.yy
+@@ -865,6 +865,7 @@
%token CIPHER_SYM
%token CLASS_ORIGIN_SYM /* SQL-2003-N */
%token CLIENT_SYM
%token CLOSE_SYM /* SQL-2003-R */
%token COALESCE /* SQL-2003-N */
%token CODE_SYM
-@@ -1017,6 +1018,7 @@
+@@ -1018,6 +1019,7 @@
%token IMPORT
%token INDEXES
%token INDEX_SYM
%token INFILE
%token INITIAL_SIZE_SYM
%token INNER_SYM /* SQL-2003-R */
-@@ -1315,6 +1317,7 @@
+@@ -1316,6 +1318,7 @@
%token TABLESPACE
%token TABLE_REF_PRIORITY
%token TABLE_SYM /* SQL-2003-R */
%token TABLE_CHECKSUM_SYM
%token TABLE_NAME_SYM /* SQL-2003-N */
%token TEMPORARY /* SQL-2003-N */
-@@ -1324,6 +1327,7 @@
+@@ -1325,6 +1328,7 @@
%token TEXT_SYM
%token THAN_SYM
%token THEN_SYM /* SQL-2003-R */
%token TIMESTAMP /* SQL-2003-R */
%token TIMESTAMP_ADD
%token TIMESTAMP_DIFF
-@@ -1361,6 +1365,7 @@
+@@ -1362,6 +1366,7 @@
%token UPGRADE_SYM
%token USAGE /* SQL-2003-N */
%token USER /* SQL-2003-R */
%token USE_FRM
%token USE_SYM
%token USING /* SQL-2003-R */
-@@ -11096,6 +11101,41 @@
+@@ -11100,6 +11105,41 @@
MYSQL_YYABORT;
#endif // HAVE_RESPONSE_TIME_DISTRIBUTION
}
| CREATE PROCEDURE_SYM sp_name
{
LEX *lex= Lex;
-@@ -11338,6 +11378,16 @@
+@@ -11342,6 +11382,16 @@
Lex->type|= REFRESH_QUERY_RESPONSE_TIME;
#endif // HAVE_RESPONSE_TIME_DISTRIBUTION
}
| MASTER_SYM
{ Lex->type|= REFRESH_MASTER; }
| DES_KEY_FILE
-@@ -12460,6 +12510,7 @@
+@@ -12480,6 +12530,7 @@
| CHAIN_SYM {}
| CHANGED {}
| CIPHER_SYM {}
| CLIENT_SYM {}
| CLASS_ORIGIN_SYM {}
| COALESCE {}
-@@ -12528,6 +12579,7 @@
+@@ -12548,6 +12599,7 @@
| HOSTS_SYM {}
| HOUR_SYM {}
| IDENTIFIED_SYM {}
| IGNORE_SERVER_IDS_SYM {}
| INVOKER_SYM {}
| IMPORT {}
-@@ -12679,6 +12731,7 @@
+@@ -12699,6 +12751,7 @@
| SUSPEND_SYM {}
| SWAPS_SYM {}
| SWITCHES_SYM {}
| TABLE_NAME_SYM {}
| TABLES {}
| TABLE_CHECKSUM_SYM {}
-@@ -12704,6 +12757,7 @@
+@@ -12724,6 +12777,7 @@
| UNKNOWN_SYM {}
| UNTIL_SYM {}
| USER {}
| USE_FRM {}
| VARIABLES {}
| VIEW_SYM {}
-diff -ruN a/sql/structs.h b/sql/structs.h
---- a/sql/structs.h 2011-04-10 12:16:42.000000000 +0400
-+++ b/sql/structs.h 2011-04-10 12:24:34.000000000 +0400
+--- a/sql/structs.h
++++ b/sql/structs.h
@@ -25,6 +25,7 @@
#include "my_time.h" /* enum_mysql_timestamp_type */
#include "thr_lock.h" /* thr_lock_type */
/* Bits in form->update */
#define REG_MAKE_DUPP 1 /* Make a copy of record when read */
#define REG_NEW_RECORD 2 /* Write a new record if not found */
-diff -ruN a/sql/sys_vars.cc b/sql/sys_vars.cc
---- a/sql/sys_vars.cc 2011-04-10 12:23:56.000000000 +0400
-+++ b/sql/sys_vars.cc 2011-04-10 12:24:34.000000000 +0400
+--- a/sql/sys_vars.cc
++++ b/sql/sys_vars.cc
@@ -1609,6 +1609,17 @@
NO_MUTEX_GUARD, NOT_IN_BINLOG,
ON_CHECK(check_read_only), ON_UPDATE(fix_read_only));
// Small lower limit to be able to test MRR
static Sys_var_ulong Sys_read_rnd_buff_size(
"read_rnd_buffer_size",
-diff -ruN a/storage/myisam/ha_myisam.cc b/storage/myisam/ha_myisam.cc
---- a/storage/myisam/ha_myisam.cc 2011-04-10 12:16:42.000000000 +0400
-+++ b/storage/myisam/ha_myisam.cc 2011-04-10 12:24:34.000000000 +0400
-@@ -769,6 +769,7 @@
+--- a/storage/myisam/ha_myisam.cc
++++ b/storage/myisam/ha_myisam.cc
+@@ -770,6 +770,7 @@
int ha_myisam::write_row(uchar *buf)
{
ha_statistic_increment(&SSV::ha_write_count);
/* If we have a timestamp column, update it to the current time */
-@@ -781,11 +782,13 @@
+@@ -782,11 +783,13 @@
*/
if (table->next_number_field && buf == table->record[0])
{
}
int ha_myisam::check(THD* thd, HA_CHECK_OPT* check_opt)
-@@ -1536,16 +1539,24 @@
+@@ -1537,16 +1540,24 @@
int ha_myisam::update_row(const uchar *old_data, uchar *new_data)
{
}
int ha_myisam::index_read_map(uchar *buf, const uchar *key,
-@@ -1557,6 +1568,14 @@
+@@ -1558,6 +1569,14 @@
ha_statistic_increment(&SSV::ha_read_key_count);
int error=mi_rkey(file, buf, active_index, key, keypart_map, find_flag);
table->status=error ? STATUS_NOT_FOUND: 0;
MYSQL_INDEX_READ_ROW_DONE(error);
return error;
}
-@@ -1569,6 +1588,14 @@
+@@ -1570,6 +1589,14 @@
ha_statistic_increment(&SSV::ha_read_key_count);
int error=mi_rkey(file, buf, index, key, keypart_map, find_flag);
table->status=error ? STATUS_NOT_FOUND: 0;
MYSQL_INDEX_READ_ROW_DONE(error);
return error;
}
-@@ -1583,6 +1610,14 @@
+@@ -1584,6 +1611,14 @@
int error=mi_rkey(file, buf, active_index, key, keypart_map,
HA_READ_PREFIX_LAST);
table->status=error ? STATUS_NOT_FOUND: 0;
MYSQL_INDEX_READ_ROW_DONE(error);
DBUG_RETURN(error);
}
-@@ -1594,6 +1629,13 @@
+@@ -1595,6 +1630,13 @@
ha_statistic_increment(&SSV::ha_read_next_count);
int error=mi_rnext(file,buf,active_index);
table->status=error ? STATUS_NOT_FOUND: 0;
MYSQL_INDEX_READ_ROW_DONE(error);
return error;
}
-@@ -1605,6 +1647,13 @@
+@@ -1606,6 +1648,13 @@
ha_statistic_increment(&SSV::ha_read_prev_count);
int error=mi_rprev(file,buf, active_index);
table->status=error ? STATUS_NOT_FOUND: 0;
MYSQL_INDEX_READ_ROW_DONE(error);
return error;
}
-@@ -1616,6 +1665,14 @@
+@@ -1617,6 +1666,14 @@
ha_statistic_increment(&SSV::ha_read_first_count);
int error=mi_rfirst(file, buf, active_index);
table->status=error ? STATUS_NOT_FOUND: 0;
MYSQL_INDEX_READ_ROW_DONE(error);
return error;
}
-@@ -1627,6 +1684,14 @@
+@@ -1628,6 +1685,14 @@
ha_statistic_increment(&SSV::ha_read_last_count);
int error=mi_rlast(file, buf, active_index);
table->status=error ? STATUS_NOT_FOUND: 0;
MYSQL_INDEX_READ_ROW_DONE(error);
return error;
}
-@@ -1644,6 +1709,14 @@
+@@ -1645,6 +1710,14 @@
error= mi_rnext_same(file,buf);
} while (error == HA_ERR_RECORD_DELETED);
table->status=error ? STATUS_NOT_FOUND: 0;
MYSQL_INDEX_READ_ROW_DONE(error);
return error;
}
-@@ -1663,6 +1736,8 @@
+@@ -1664,6 +1737,8 @@
ha_statistic_increment(&SSV::ha_read_rnd_next_count);
int error=mi_scan(file, buf);
table->status=error ? STATUS_NOT_FOUND: 0;
MYSQL_READ_ROW_DONE(error);
return error;
}
-@@ -1679,6 +1754,8 @@
+@@ -1680,6 +1755,8 @@
ha_statistic_increment(&SSV::ha_read_rnd_count);
int error=mi_rrnd(file, buf, my_get_ptr(pos,ref_length));
table->status=error ? STATUS_NOT_FOUND: 0;
--- /dev/null
+# MySQL bug#43593 dump/backup/restore/upgrade tools fails
+#
+# The patch is intended to help to those users:
+# - Having indexes on columns with collations
+# utf8_general_ci or ucs2_general_ci
+# - Having German letter SHARP S (SZLIG) in these columns
+# - Upgrading from MySQL from versions 5.0.x or
+# 5.1.23 (and earlier) to version 5.1.24 (and higher).
+#
+# This patch introduces new collations utf8_general50_ci
+# and ucs2_general50_ci which reproduce the "old"
+# sorting order provided by pre-5.1.24 versions of xxx_general_ci.
+#
+# In order to start using new MySQL-5.1.24+ please do the following:
+#
+# - Start new version of mysqld
+# - Convert all affected tables using this query (in case of utf8):
+#
+# ALTER TABLE t1 CONVERT TO CHARACTER SET utf8 COLLATE utf8_general50_ci;
+#
+# Or if you need to apply changes per-column level, use this example:
+#
+# ALTER TABLE t1 MODIFY c1 CHAR(N) CHARACTER SET utf8 COLLATE utf8_general50_ci;
+#
+# (Make sure you're using the old data type and size,
+# NULL/NOT NULL constraints, etc).
+#
+=== modified file 'mysys/charset-def.c'
+--- a/mysys/charset-def.c
++++ b/mysys/charset-def.c
+@@ -22,6 +22,9 @@
+ init_compiled_charsets() that only adds those that he wants
+ */
+
++extern CHARSET_INFO my_charset_ucs2_general50_ci;
++extern CHARSET_INFO my_charset_utf8_general50_ci;
++
+ #ifdef HAVE_UCA_COLLATIONS
+
+ #ifdef HAVE_CHARSET_ucs2
+@@ -204,6 +207,7 @@
+ #ifdef HAVE_CHARSET_ucs2
+ add_compiled_collation(&my_charset_ucs2_general_ci);
+ add_compiled_collation(&my_charset_ucs2_bin);
++ add_compiled_collation(&my_charset_ucs2_general50_ci);
+ #ifdef HAVE_UCA_COLLATIONS
+ add_compiled_collation(&my_charset_ucs2_unicode_ci);
+ add_compiled_collation(&my_charset_ucs2_icelandic_uca_ci);
+@@ -236,6 +240,7 @@
+ #ifdef HAVE_CHARSET_utf8
+ add_compiled_collation(&my_charset_utf8_general_ci);
+ add_compiled_collation(&my_charset_utf8_bin);
++ add_compiled_collation(&my_charset_utf8_general50_ci);
+ #ifdef HAVE_UTF8_GENERAL_CS
+ add_compiled_collation(&my_charset_utf8_general_cs);
+ #endif
+--- a/strings/ctype-ucs2.c
++++ b/strings/ctype-ucs2.c
+@@ -3154,6 +3154,42 @@
+ &my_collation_ucs2_general_ci_handler
+ };
+
++
++extern MY_UNICASE_INFO *my_unicase_general50[256];
++
++CHARSET_INFO my_charset_ucs2_general50_ci=
++{
++ 159,0,0, /* number */
++ MY_CS_COMPILED|MY_CS_STRNXFRM|MY_CS_UNICODE,
++ "ucs2", /* cs name */
++ "ucs2_general50_ci", /* name */
++ "", /* comment */
++ NULL, /* tailoring */
++ ctype_ucs2, /* ctype */
++ to_lower_ucs2, /* to_lower */
++ to_upper_ucs2, /* to_upper */
++ to_upper_ucs2, /* sort_order */
++ NULL, /* contractions */
++ NULL, /* sort_order_big*/
++ NULL, /* tab_to_uni */
++ NULL, /* tab_from_uni */
++ my_unicase_general50, /* caseinfo */
++ NULL, /* state_map */
++ NULL, /* ident_map */
++ 1, /* strxfrm_multiply */
++ 1, /* caseup_multiply */
++ 1, /* casedn_multiply */
++ 2, /* mbminlen */
++ 2, /* mbmaxlen */
++ 0, /* min_sort_char */
++ 0xFFFF, /* max_sort_char */
++ ' ', /* pad char */
++ 0, /* escape_with_backslash_is_dangerous */
++ &my_charset_ucs2_handler,
++ &my_collation_ucs2_general_ci_handler
++};
++
++
+ CHARSET_INFO my_charset_ucs2_bin=
+ {
+ 90,0,0, /* number */
+--- a/strings/ctype-utf8.c
++++ b/strings/ctype-utf8.c
+@@ -193,6 +193,138 @@
+ };
+
+
++static MY_UNICASE_INFO plane00_general50[]={
++ {0x0000,0x0000,0x0000}, {0x0001,0x0001,0x0001},
++ {0x0002,0x0002,0x0002}, {0x0003,0x0003,0x0003},
++ {0x0004,0x0004,0x0004}, {0x0005,0x0005,0x0005},
++ {0x0006,0x0006,0x0006}, {0x0007,0x0007,0x0007},
++ {0x0008,0x0008,0x0008}, {0x0009,0x0009,0x0009},
++ {0x000A,0x000A,0x000A}, {0x000B,0x000B,0x000B},
++ {0x000C,0x000C,0x000C}, {0x000D,0x000D,0x000D},
++ {0x000E,0x000E,0x000E}, {0x000F,0x000F,0x000F},
++ {0x0010,0x0010,0x0010}, {0x0011,0x0011,0x0011},
++ {0x0012,0x0012,0x0012}, {0x0013,0x0013,0x0013},
++ {0x0014,0x0014,0x0014}, {0x0015,0x0015,0x0015},
++ {0x0016,0x0016,0x0016}, {0x0017,0x0017,0x0017},
++ {0x0018,0x0018,0x0018}, {0x0019,0x0019,0x0019},
++ {0x001A,0x001A,0x001A}, {0x001B,0x001B,0x001B},
++ {0x001C,0x001C,0x001C}, {0x001D,0x001D,0x001D},
++ {0x001E,0x001E,0x001E}, {0x001F,0x001F,0x001F},
++ {0x0020,0x0020,0x0020}, {0x0021,0x0021,0x0021},
++ {0x0022,0x0022,0x0022}, {0x0023,0x0023,0x0023},
++ {0x0024,0x0024,0x0024}, {0x0025,0x0025,0x0025},
++ {0x0026,0x0026,0x0026}, {0x0027,0x0027,0x0027},
++ {0x0028,0x0028,0x0028}, {0x0029,0x0029,0x0029},
++ {0x002A,0x002A,0x002A}, {0x002B,0x002B,0x002B},
++ {0x002C,0x002C,0x002C}, {0x002D,0x002D,0x002D},
++ {0x002E,0x002E,0x002E}, {0x002F,0x002F,0x002F},
++ {0x0030,0x0030,0x0030}, {0x0031,0x0031,0x0031},
++ {0x0032,0x0032,0x0032}, {0x0033,0x0033,0x0033},
++ {0x0034,0x0034,0x0034}, {0x0035,0x0035,0x0035},
++ {0x0036,0x0036,0x0036}, {0x0037,0x0037,0x0037},
++ {0x0038,0x0038,0x0038}, {0x0039,0x0039,0x0039},
++ {0x003A,0x003A,0x003A}, {0x003B,0x003B,0x003B},
++ {0x003C,0x003C,0x003C}, {0x003D,0x003D,0x003D},
++ {0x003E,0x003E,0x003E}, {0x003F,0x003F,0x003F},
++ {0x0040,0x0040,0x0040}, {0x0041,0x0061,0x0041},
++ {0x0042,0x0062,0x0042}, {0x0043,0x0063,0x0043},
++ {0x0044,0x0064,0x0044}, {0x0045,0x0065,0x0045},
++ {0x0046,0x0066,0x0046}, {0x0047,0x0067,0x0047},
++ {0x0048,0x0068,0x0048}, {0x0049,0x0069,0x0049},
++ {0x004A,0x006A,0x004A}, {0x004B,0x006B,0x004B},
++ {0x004C,0x006C,0x004C}, {0x004D,0x006D,0x004D},
++ {0x004E,0x006E,0x004E}, {0x004F,0x006F,0x004F},
++ {0x0050,0x0070,0x0050}, {0x0051,0x0071,0x0051},
++ {0x0052,0x0072,0x0052}, {0x0053,0x0073,0x0053},
++ {0x0054,0x0074,0x0054}, {0x0055,0x0075,0x0055},
++ {0x0056,0x0076,0x0056}, {0x0057,0x0077,0x0057},
++ {0x0058,0x0078,0x0058}, {0x0059,0x0079,0x0059},
++ {0x005A,0x007A,0x005A}, {0x005B,0x005B,0x005B},
++ {0x005C,0x005C,0x005C}, {0x005D,0x005D,0x005D},
++ {0x005E,0x005E,0x005E}, {0x005F,0x005F,0x005F},
++ {0x0060,0x0060,0x0060}, {0x0041,0x0061,0x0041},
++ {0x0042,0x0062,0x0042}, {0x0043,0x0063,0x0043},
++ {0x0044,0x0064,0x0044}, {0x0045,0x0065,0x0045},
++ {0x0046,0x0066,0x0046}, {0x0047,0x0067,0x0047},
++ {0x0048,0x0068,0x0048}, {0x0049,0x0069,0x0049},
++ {0x004A,0x006A,0x004A}, {0x004B,0x006B,0x004B},
++ {0x004C,0x006C,0x004C}, {0x004D,0x006D,0x004D},
++ {0x004E,0x006E,0x004E}, {0x004F,0x006F,0x004F},
++ {0x0050,0x0070,0x0050}, {0x0051,0x0071,0x0051},
++ {0x0052,0x0072,0x0052}, {0x0053,0x0073,0x0053},
++ {0x0054,0x0074,0x0054}, {0x0055,0x0075,0x0055},
++ {0x0056,0x0076,0x0056}, {0x0057,0x0077,0x0057},
++ {0x0058,0x0078,0x0058}, {0x0059,0x0079,0x0059},
++ {0x005A,0x007A,0x005A}, {0x007B,0x007B,0x007B},
++ {0x007C,0x007C,0x007C}, {0x007D,0x007D,0x007D},
++ {0x007E,0x007E,0x007E}, {0x007F,0x007F,0x007F},
++ {0x0080,0x0080,0x0080}, {0x0081,0x0081,0x0081},
++ {0x0082,0x0082,0x0082}, {0x0083,0x0083,0x0083},
++ {0x0084,0x0084,0x0084}, {0x0085,0x0085,0x0085},
++ {0x0086,0x0086,0x0086}, {0x0087,0x0087,0x0087},
++ {0x0088,0x0088,0x0088}, {0x0089,0x0089,0x0089},
++ {0x008A,0x008A,0x008A}, {0x008B,0x008B,0x008B},
++ {0x008C,0x008C,0x008C}, {0x008D,0x008D,0x008D},
++ {0x008E,0x008E,0x008E}, {0x008F,0x008F,0x008F},
++ {0x0090,0x0090,0x0090}, {0x0091,0x0091,0x0091},
++ {0x0092,0x0092,0x0092}, {0x0093,0x0093,0x0093},
++ {0x0094,0x0094,0x0094}, {0x0095,0x0095,0x0095},
++ {0x0096,0x0096,0x0096}, {0x0097,0x0097,0x0097},
++ {0x0098,0x0098,0x0098}, {0x0099,0x0099,0x0099},
++ {0x009A,0x009A,0x009A}, {0x009B,0x009B,0x009B},
++ {0x009C,0x009C,0x009C}, {0x009D,0x009D,0x009D},
++ {0x009E,0x009E,0x009E}, {0x009F,0x009F,0x009F},
++ {0x00A0,0x00A0,0x00A0}, {0x00A1,0x00A1,0x00A1},
++ {0x00A2,0x00A2,0x00A2}, {0x00A3,0x00A3,0x00A3},
++ {0x00A4,0x00A4,0x00A4}, {0x00A5,0x00A5,0x00A5},
++ {0x00A6,0x00A6,0x00A6}, {0x00A7,0x00A7,0x00A7},
++ {0x00A8,0x00A8,0x00A8}, {0x00A9,0x00A9,0x00A9},
++ {0x00AA,0x00AA,0x00AA}, {0x00AB,0x00AB,0x00AB},
++ {0x00AC,0x00AC,0x00AC}, {0x00AD,0x00AD,0x00AD},
++ {0x00AE,0x00AE,0x00AE}, {0x00AF,0x00AF,0x00AF},
++ {0x00B0,0x00B0,0x00B0}, {0x00B1,0x00B1,0x00B1},
++ {0x00B2,0x00B2,0x00B2}, {0x00B3,0x00B3,0x00B3},
++ {0x00B4,0x00B4,0x00B4}, {0x039C,0x00B5,0x039C},
++ {0x00B6,0x00B6,0x00B6}, {0x00B7,0x00B7,0x00B7},
++ {0x00B8,0x00B8,0x00B8}, {0x00B9,0x00B9,0x00B9},
++ {0x00BA,0x00BA,0x00BA}, {0x00BB,0x00BB,0x00BB},
++ {0x00BC,0x00BC,0x00BC}, {0x00BD,0x00BD,0x00BD},
++ {0x00BE,0x00BE,0x00BE}, {0x00BF,0x00BF,0x00BF},
++ {0x00C0,0x00E0,0x0041}, {0x00C1,0x00E1,0x0041},
++ {0x00C2,0x00E2,0x0041}, {0x00C3,0x00E3,0x0041},
++ {0x00C4,0x00E4,0x0041}, {0x00C5,0x00E5,0x0041},
++ {0x00C6,0x00E6,0x00C6}, {0x00C7,0x00E7,0x0043},
++ {0x00C8,0x00E8,0x0045}, {0x00C9,0x00E9,0x0045},
++ {0x00CA,0x00EA,0x0045}, {0x00CB,0x00EB,0x0045},
++ {0x00CC,0x00EC,0x0049}, {0x00CD,0x00ED,0x0049},
++ {0x00CE,0x00EE,0x0049}, {0x00CF,0x00EF,0x0049},
++ {0x00D0,0x00F0,0x00D0}, {0x00D1,0x00F1,0x004E},
++ {0x00D2,0x00F2,0x004F}, {0x00D3,0x00F3,0x004F},
++ {0x00D4,0x00F4,0x004F}, {0x00D5,0x00F5,0x004F},
++ {0x00D6,0x00F6,0x004F}, {0x00D7,0x00D7,0x00D7},
++ {0x00D8,0x00F8,0x00D8}, {0x00D9,0x00F9,0x0055},
++ {0x00DA,0x00FA,0x0055}, {0x00DB,0x00FB,0x0055},
++ {0x00DC,0x00FC,0x0055}, {0x00DD,0x00FD,0x0059},
++ {0x00DE,0x00FE,0x00DE}, {0x00DF,0x00DF,0x00DF},
++ {0x00C0,0x00E0,0x0041}, {0x00C1,0x00E1,0x0041},
++ {0x00C2,0x00E2,0x0041}, {0x00C3,0x00E3,0x0041},
++ {0x00C4,0x00E4,0x0041}, {0x00C5,0x00E5,0x0041},
++ {0x00C6,0x00E6,0x00C6}, {0x00C7,0x00E7,0x0043},
++ {0x00C8,0x00E8,0x0045}, {0x00C9,0x00E9,0x0045},
++ {0x00CA,0x00EA,0x0045}, {0x00CB,0x00EB,0x0045},
++ {0x00CC,0x00EC,0x0049}, {0x00CD,0x00ED,0x0049},
++ {0x00CE,0x00EE,0x0049}, {0x00CF,0x00EF,0x0049},
++ {0x00D0,0x00F0,0x00D0}, {0x00D1,0x00F1,0x004E},
++ {0x00D2,0x00F2,0x004F}, {0x00D3,0x00F3,0x004F},
++ {0x00D4,0x00F4,0x004F}, {0x00D5,0x00F5,0x004F},
++ {0x00D6,0x00F6,0x004F}, {0x00F7,0x00F7,0x00F7},
++ {0x00D8,0x00F8,0x00D8}, {0x00D9,0x00F9,0x0055},
++ {0x00DA,0x00FA,0x0055}, {0x00DB,0x00FB,0x0055},
++ {0x00DC,0x00FC,0x0055}, {0x00DD,0x00FD,0x0059},
++ {0x00DE,0x00FE,0x00DE}, {0x0178,0x00FF,0x0059}
++};
++
++
+
+ static MY_UNICASE_INFO plane01[]={
+ {0x0100,0x0101,0x0041}, {0x0100,0x0101,0x0041},
+@@ -1542,6 +1674,48 @@
+
+
+ /*
++ general50: to reproduce old utf8_general_ci behaviour
++ before we fixed Bug#27877.
++*/
++MY_UNICASE_INFO *my_unicase_general50[256]={
++ plane00_general50,
++ plane01, plane02, plane03, plane04, plane05, NULL, NULL,
++ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
++ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
++ NULL, NULL, NULL, NULL, NULL, NULL, plane1E, plane1F,
++ NULL, plane21, NULL, NULL, plane24, NULL, NULL, NULL,
++ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
++ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
++ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
++ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
++ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
++ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
++ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
++ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
++ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
++ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
++ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
++ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
++ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
++ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
++ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
++ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
++ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
++ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
++ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
++ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
++ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
++ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
++ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
++ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
++ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
++ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
++ NULL, NULL, NULL, NULL, NULL, NULL, NULL, planeFF
++
++};
++
++
++/*
+ Turkish lower/upper mapping:
+ 1. LOWER(0x0049 LATIN CAPITAL LETTER I) ->
+ 0x0131 LATIN SMALL LETTER DOTLESS I
+@@ -2814,6 +2988,39 @@
+ };
+
+
++CHARSET_INFO my_charset_utf8_general50_ci=
++{
++ 253,0,0, /* number */
++ MY_CS_COMPILED|MY_CS_STRNXFRM|MY_CS_UNICODE, /* state */
++ "utf8", /* cs name */
++ "utf8_general50_ci", /* name */
++ "", /* comment */
++ NULL, /* tailoring */
++ ctype_utf8, /* ctype */
++ to_lower_utf8, /* to_lower */
++ to_upper_utf8, /* to_upper */
++ to_upper_utf8, /* sort_order */
++ NULL, /* contractions */
++ NULL, /* sort_order_big*/
++ NULL, /* tab_to_uni */
++ NULL, /* tab_from_uni */
++ my_unicase_general50, /* caseinfo */
++ NULL, /* state_map */
++ NULL, /* ident_map */
++ 1, /* strxfrm_multiply */
++ 1, /* caseup_multiply */
++ 1, /* casedn_multiply */
++ 1, /* mbminlen */
++ 3, /* mbmaxlen */
++ 0, /* min_sort_char */
++ 0xFFFF, /* max_sort_char */
++ ' ', /* pad char */
++ 0, /* escape_with_backslash_is_dangerous */
++ &my_charset_utf8_handler,
++ &my_collation_ci_handler
++};
++
++
+ CHARSET_INFO my_charset_utf8_bin=
+ {
+ 83,0,0, /* number */
+--- /dev/null
++++ b/mysql-test/t/percona_ucs2_general50_ci.test
+@@ -0,0 +1,12 @@
++#
++# Test that ucs2_general50_ci provides pre-5.1.24 utf8_general_ci behavior,
++# i.e. SHARP S is only equal to itself.
++#
++
++--source include/have_ucs2.inc
++
++SET NAMES latin1;
++
++SET collation_connection='ucs2_general50_ci';
++
++--source include/ctype_german.inc
+--- /dev/null
++++ b/mysql-test/t/percona_utf8_general50_ci.test
+@@ -0,0 +1,9 @@
++#
++# Test that utf8_general50_ci provides pre-5.1.24 utf8_general_ci behavior,
++# i.e. SHARP S is only equal to itself.
++#
++
++SET NAMES utf8;
++
++SET collation_connection='utf8_general50_ci';
++--source include/ctype_german.inc
+--- /dev/null
++++ b/mysql-test/r/percona_utf8_general50_ci.result
+@@ -0,0 +1,38 @@
++SET NAMES utf8;
++SET collation_connection='utf8_general50_ci';
++drop table if exists t1;
++create table t1 as select repeat(' ', 64) as s1;
++select collation(s1) from t1;
++collation(s1)
++utf8_general50_ci
++delete from t1;
++insert into t1 values ('a'),('ae'),(_latin1 0xE4);
++insert into t1 values ('o'),('oe'),(_latin1 0xF6);
++insert into t1 values ('s'),('ss'),(_latin1 0xDF);
++insert into t1 values ('u'),('ue'),(_latin1 0xFC);
++select s1, hex(s1) from t1 order by s1, binary s1;
++s1 hex(s1)
++a 61
++ä C3A4
++ae 6165
++o 6F
++ö C3B6
++oe 6F65
++s 73
++ss 7373
++u 75
++ü C3BC
++ue 7565
++ß C39F
++select group_concat(s1 order by binary s1) from t1 group by s1;
++group_concat(s1 order by binary s1)
++a,ä
++ae
++o,ö
++oe
++s
++ss
++u,ü
++ue
++ß
++drop table t1;
+--- /dev/null
++++ b/mysql-test/r/percona_ucs2_general50_ci.result
+@@ -0,0 +1,38 @@
++SET NAMES latin1;
++SET collation_connection='ucs2_general50_ci';
++drop table if exists t1;
++create table t1 as select repeat(' ', 64) as s1;
++select collation(s1) from t1;
++collation(s1)
++ucs2_general50_ci
++delete from t1;
++insert into t1 values ('a'),('ae'),(_latin1 0xE4);
++insert into t1 values ('o'),('oe'),(_latin1 0xF6);
++insert into t1 values ('s'),('ss'),(_latin1 0xDF);
++insert into t1 values ('u'),('ue'),(_latin1 0xFC);
++select s1, hex(s1) from t1 order by s1, binary s1;
++s1 hex(s1)
++\0 00
++\0 00
++\0 00
++\0 00
++\0 00
++\0 00
++\0 00
++\0 00
++a 61
++o 6F
++s 73
++u 75
++select group_concat(s1 order by binary s1) from t1 group by s1;
++group_concat(s1 order by binary s1)
++\0a
++\0o
++\0
++\0u
++\0
++a
++o
++s
++u
++drop table t1;
--- /dev/null
+# valgrind suppression for zlib
+# https://bugs.launchpad.net/percona-server/+bug/794837
+--- a/mysql-test/valgrind.supp
++++ b/mysql-test/valgrind.supp
+@@ -876,3 +876,12 @@
+ fun:buf_buddy_free_low
+ fun:buf_buddy_free
+ }
++{
++ zlib longest_match false positive
++ Memcheck:Cond
++ fun:longest_match
++ fun:deflate_slow
++ fun:deflate
++ fun:compress
++ fun:my_compress_alloc
++}