Merge lp:~percona-dev/percona-server/5.5.8 into lp:percona-server/release-5.1.54-12

Proposed by happytony65
Status: Rejected
Rejected by: Oleg Tsarev
Proposed branch: lp:~percona-dev/percona-server/5.5.8
Merge into: lp:percona-server/release-5.1.54-12
Diff against target: 37420 lines (+36564/-0) (has conflicts)
158 files modified
COPYING.innodb-deadlock-count-patch (+30/-0)
COPYING.show_temp_51 (+13/-0)
Makefile (+68/-0)
bug580324.patch (+105/-0)
control_online_alter_index.patch (+90/-0)
error_pad.patch (+267/-0)
innodb_adaptive_hash_index_partitions.patch (+1508/-0)
innodb_admin_command_base.patch (+173/-0)
innodb_buffer_pool_pages_i_s.patch (+803/-0)
innodb_buffer_pool_shm.patch (+1224/-0)
innodb_deadlock_count.patch (+71/-0)
innodb_dict_size_limit.patch (+446/-0)
innodb_expand_import.patch (+561/-0)
innodb_extend_slow.patch (+1034/-0)
innodb_extra_rseg.patch (+273/-0)
innodb_fast_checksum.patch (+301/-0)
innodb_files_extend.patch (+523/-0)
innodb_fix_misc.patch (+206/-0)
innodb_io_patches.patch (+1111/-0)
innodb_lru_dump_restore.patch (+677/-0)
innodb_opt_lru_count.patch (+314/-0)
innodb_overwrite_relay_log_info.patch (+495/-0)
innodb_pass_corrupt_table.patch (+1387/-0)
innodb_recovery_patches.patch (+504/-0)
innodb_separate_doublewrite.patch (+1078/-0)
innodb_show_lock_name.patch (+412/-0)
innodb_show_status.patch (+447/-0)
innodb_show_sys_tables.patch (+1734/-0)
innodb_split_buf_pool_mutex.patch (+3955/-0)
innodb_stats.patch (+2404/-0)
innodb_thread_concurrency_timer_based.patch (+191/-0)
install_tests.sh (+19/-0)
log_connection_error.patch (+53/-0)
log_warnings_silence.patch (+85/-0)
lrusort.py (+38/-0)
microsec_process.patch (+52/-0)
mysql-test.diff (+828/-0)
mysql-test/log_connection_error.patch/percona_log_connection_error-master.opt (+1/-0)
mysql-test/log_connection_error.patch/percona_log_connection_error.result (+15/-0)
mysql-test/log_connection_error.patch/percona_log_connection_error.test (+52/-0)
mysql-test/log_warnings_silence.patch/percona_log_warnings_silence-master.opt (+1/-0)
mysql-test/log_warnings_silence.patch/percona_log_warnings_silence.result (+31/-0)
mysql-test/log_warnings_silence.patch/percona_log_warnings_silence.test (+47/-0)
mysql-test/percona_innodb_buffer_pool_shm-master.opt (+1/-0)
mysql-test/percona_innodb_buffer_pool_shm.result (+6/-0)
mysql-test/percona_innodb_buffer_pool_shm.test (+18/-0)
mysql-test/percona_innodb_deadlock_count.result (+28/-0)
mysql-test/percona_innodb_deadlock_count.test (+49/-0)
mysql-test/percona_innodb_doublewrite_file-master.opt (+1/-0)
mysql-test/percona_innodb_doublewrite_file.result (+4/-0)
mysql-test/percona_innodb_doublewrite_file.test (+2/-0)
mysql-test/percona_innodb_use_sys_stats_table-master.opt (+1/-0)
mysql-test/percona_innodb_use_sys_stats_table.result (+3/-0)
mysql-test/percona_innodb_use_sys_stats_table.test (+2/-0)
mysql-test/percona_server_variables.result (+342/-0)
mysql-test/percona_server_variables.test (+7/-0)
mysql-test/percona_show_temp_tables.result (+58/-0)
mysql-test/percona_show_temp_tables.test (+65/-0)
mysql-test/percona_suppress_log_warning_1592-master.opt (+1/-0)
mysql-test/percona_suppress_log_warning_1592.result (+28/-0)
mysql-test/percona_suppress_log_warning_1592.test (+46/-0)
mysql-test/percona_xtradb_admin_command.result (+6/-0)
mysql-test/percona_xtradb_admin_command.test (+3/-0)
mysql-test/percona_xtradb_bug317074.result (+4/-0)
mysql-test/percona_xtradb_bug317074.test (+47/-0)
mysql-test/profiling_slow.patch/percona_bug643149.result (+16/-0)
mysql-test/profiling_slow.patch/percona_bug643149.test (+47/-0)
mysql-test/query_cache_enhance.patch/percona_query_cache_with_comments.inc (+95/-0)
mysql-test/query_cache_enhance.patch/percona_query_cache_with_comments.inc.backup (+88/-0)
mysql-test/query_cache_enhance.patch/percona_query_cache_with_comments.result (+866/-0)
mysql-test/query_cache_enhance.patch/percona_query_cache_with_comments.test (+5/-0)
mysql-test/query_cache_enhance.patch/percona_query_cache_with_comments_begin.inc (+12/-0)
mysql-test/query_cache_enhance.patch/percona_query_cache_with_comments_clear.inc (+5/-0)
mysql-test/query_cache_enhance.patch/percona_query_cache_with_comments_crash.result (+21/-0)
mysql-test/query_cache_enhance.patch/percona_query_cache_with_comments_crash.test (+22/-0)
mysql-test/query_cache_enhance.patch/percona_query_cache_with_comments_disable.result (+865/-0)
mysql-test/query_cache_enhance.patch/percona_query_cache_with_comments_disable.test (+3/-0)
mysql-test/query_cache_enhance.patch/percona_query_cache_with_comments_end.inc (+3/-0)
mysql-test/query_cache_enhance.patch/percona_query_cache_with_comments_eval.inc (+7/-0)
mysql-test/query_cache_enhance.patch/percona_query_cache_with_comments_prepared_statements.result (+396/-0)
mysql-test/query_cache_enhance.patch/percona_query_cache_with_comments_prepared_statements.test (+208/-0)
mysql-test/query_cache_enhance.patch/percona_query_cache_with_comments_show.inc (+8/-0)
mysql-test/query_cache_enhance.patch/percona_status_wait_query_cache_mutex.result (+27/-0)
mysql-test/query_cache_enhance.patch/percona_status_wait_query_cache_mutex.test (+37/-0)
mysql-test/response-time-distribution.patch/percona_query_response_time-replication.result (+70/-0)
mysql-test/response-time-distribution.patch/percona_query_response_time-replication.test (+56/-0)
mysql-test/response-time-distribution.patch/percona_query_response_time-stored.result (+313/-0)
mysql-test/response-time-distribution.patch/percona_query_response_time-stored.test (+90/-0)
mysql-test/response-time-distribution.patch/percona_query_response_time.result (+567/-0)
mysql-test/response-time-distribution.patch/percona_query_response_time.test (+68/-0)
mysql-test/response-time-distribution.patch/percona_query_response_time_flush.inc (+1/-0)
mysql-test/response-time-distribution.patch/percona_query_response_time_show.inc (+8/-0)
mysql-test/response-time-distribution.patch/percona_query_response_time_sleep.inc (+19/-0)
mysql-test/show_slave_status_nolock.patch/percona_show_slave_status_nolock.result (+26/-0)
mysql-test/show_slave_status_nolock.patch/percona_show_slave_status_nolock.test (+39/-0)
mysql-test/slow_extended.patch/percona_slow_extended-control_global_slow-master.opt (+1/-0)
mysql-test/slow_extended.patch/percona_slow_extended-control_global_slow.result (+11/-0)
mysql-test/slow_extended.patch/percona_slow_extended-control_global_slow.test (+9/-0)
mysql-test/slow_extended.patch/percona_slow_extended-log_slow_filter-master.opt (+1/-0)
mysql-test/slow_extended.patch/percona_slow_extended-log_slow_filter.result (+24/-0)
mysql-test/slow_extended.patch/percona_slow_extended-log_slow_filter.test (+30/-0)
mysql-test/slow_extended.patch/percona_slow_extended-log_slow_sp_statements-cl-master.opt (+1/-0)
mysql-test/slow_extended.patch/percona_slow_extended-log_slow_sp_statements-cl.result (+3/-0)
mysql-test/slow_extended.patch/percona_slow_extended-log_slow_sp_statements-cl.test (+1/-0)
mysql-test/slow_extended.patch/percona_slow_extended-log_slow_timestamp_every-cl-master.opt (+1/-0)
mysql-test/slow_extended.patch/percona_slow_extended-log_slow_timestamp_every-cl.result (+3/-0)
mysql-test/slow_extended.patch/percona_slow_extended-log_slow_timestamp_every-cl.test (+1/-0)
mysql-test/slow_extended.patch/percona_slow_extended-log_slow_verbosity-cl-master.opt (+1/-0)
mysql-test/slow_extended.patch/percona_slow_extended-log_slow_verbosity-cl.result (+9/-0)
mysql-test/slow_extended.patch/percona_slow_extended-log_slow_verbosity-cl.test (+3/-0)
mysql-test/slow_extended.patch/percona_slow_extended-log_slow_verbosity-master.opt (+1/-0)
mysql-test/slow_extended.patch/percona_slow_extended-log_slow_verbosity.result (+8/-0)
mysql-test/slow_extended.patch/percona_slow_extended-log_slow_verbosity.test (+10/-0)
mysql-test/slow_extended.patch/percona_slow_extended-long_query_time-master.opt (+1/-0)
mysql-test/slow_extended.patch/percona_slow_extended-long_query_time.result (+21/-0)
mysql-test/slow_extended.patch/percona_slow_extended-long_query_time.test (+16/-0)
mysql-test/slow_extended.patch/percona_slow_extended-microseconds_in_slow_extended-master.opt (+1/-0)
mysql-test/slow_extended.patch/percona_slow_extended-microseconds_in_slow_extended.result (+10/-0)
mysql-test/slow_extended.patch/percona_slow_extended-microseconds_in_slow_extended.test (+15/-0)
mysql-test/slow_extended.patch/percona_slow_extended-min_examined_row_limit-master.opt (+1/-0)
mysql-test/slow_extended.patch/percona_slow_extended-min_examined_row_limit.result (+24/-0)
mysql-test/slow_extended.patch/percona_slow_extended-min_examined_row_limit.test (+30/-0)
mysql-test/slow_extended.patch/percona_slow_extended-slave_innodb_stats-master.opt (+1/-0)
mysql-test/slow_extended.patch/percona_slow_extended-slave_innodb_stats-slave.opt (+1/-0)
mysql-test/slow_extended.patch/percona_slow_extended-slave_innodb_stats.result (+21/-0)
mysql-test/slow_extended.patch/percona_slow_extended-slave_innodb_stats.test (+44/-0)
mysql-test/slow_extended.patch/percona_slow_extended-slave_statements-and-use_global_long_query_time-master.opt (+1/-0)
mysql-test/slow_extended.patch/percona_slow_extended-slave_statements-and-use_global_long_query_time-slave.opt (+1/-0)
mysql-test/slow_extended.patch/percona_slow_extended-slave_statements-and-use_global_long_query_time.result (+91/-0)
mysql-test/slow_extended.patch/percona_slow_extended-slave_statements-and-use_global_long_query_time.test (+107/-0)
mysql-test/slow_extended.patch/percona_slow_extended-slave_statements-master.opt (+1/-0)
mysql-test/slow_extended.patch/percona_slow_extended-slave_statements-slave.opt (+1/-0)
mysql-test/slow_extended.patch/percona_slow_extended-slave_statements.result (+86/-0)
mysql-test/slow_extended.patch/percona_slow_extended-slave_statements.test (+159/-0)
mysql-test/slow_extended.patch/percona_slow_extended-slow_query_log_microseconds_timestamp-cl-master.opt (+1/-0)
mysql-test/slow_extended.patch/percona_slow_extended-slow_query_log_microseconds_timestamp-cl.result (+3/-0)
mysql-test/slow_extended.patch/percona_slow_extended-slow_query_log_microseconds_timestamp-cl.test (+1/-0)
mysql-test/slow_extended.patch/percona_slow_extended-use_global_long_query_time-master.opt (+1/-0)
mysql-test/slow_extended.patch/percona_slow_extended-use_global_long_query_time.result (+43/-0)
mysql-test/slow_extended.patch/percona_slow_extended-use_global_long_query_time.test (+34/-0)
mysql-test/sql_no_fcache.patch/percona_sql_no_fcache.result (+12/-0)
mysql-test/sql_no_fcache.patch/percona_sql_no_fcache.test (+11/-0)
mysql_dump_ignore_ct.patch (+62/-0)
mysql_syslog.patch (+124/-0)
normalize_patches.sh (+52/-0)
optimizer_fix.patch (+159/-0)
percona_support.patch (+19/-0)
query_cache_enhance.patch (+491/-0)
regenerate_patch.sh (+46/-0)
remove_fcntl_excessive_calls.patch (+82/-0)
response_time_distribution.patch (+774/-0)
series (+43/-0)
show_slave_status_nolock.patch (+114/-0)
show_temp.patch (+393/-0)
slow_extended.patch (+1243/-0)
sql_no_fcache.patch (+401/-0)
uninstall_tests.sh (+24/-0)
userstat.patch (+3343/-0)
Conflict adding file COPYING.innodb-deadlock-count-patch.  Moved existing file to COPYING.innodb-deadlock-count-patch.moved.
Conflict adding file COPYING.show_temp_51.  Moved existing file to COPYING.show_temp_51.moved.
Conflict adding file Makefile.  Moved existing file to Makefile.moved.
Conflict adding file bug580324.patch.  Moved existing file to bug580324.patch.moved.
Conflict adding file control_online_alter_index.patch.  Moved existing file to control_online_alter_index.patch.moved.
Conflict adding file error_pad.patch.  Moved existing file to error_pad.patch.moved.
Conflict adding file innodb_admin_command_base.patch.  Moved existing file to innodb_admin_command_base.patch.moved.
Conflict adding file innodb_buffer_pool_shm.patch.  Moved existing file to innodb_buffer_pool_shm.patch.moved.
Conflict adding file innodb_deadlock_count.patch.  Moved existing file to innodb_deadlock_count.patch.moved.
Conflict adding file innodb_dict_size_limit.patch.  Moved existing file to innodb_dict_size_limit.patch.moved.
Conflict adding file innodb_expand_import.patch.  Moved existing file to innodb_expand_import.patch.moved.
Conflict adding file innodb_extend_slow.patch.  Moved existing file to innodb_extend_slow.patch.moved.
Conflict adding file innodb_extra_rseg.patch.  Moved existing file to innodb_extra_rseg.patch.moved.
Conflict adding file innodb_fast_checksum.patch.  Moved existing file to innodb_fast_checksum.patch.moved.
Conflict adding file innodb_files_extend.patch.  Moved existing file to innodb_files_extend.patch.moved.
Conflict adding file innodb_fix_misc.patch.  Moved existing file to innodb_fix_misc.patch.moved.
Conflict adding file innodb_io_patches.patch.  Moved existing file to innodb_io_patches.patch.moved.
Conflict adding file innodb_lru_dump_restore.patch.  Moved existing file to innodb_lru_dump_restore.patch.moved.
Conflict adding file innodb_opt_lru_count.patch.  Moved existing file to innodb_opt_lru_count.patch.moved.
Conflict adding file innodb_overwrite_relay_log_info.patch.  Moved existing file to innodb_overwrite_relay_log_info.patch.moved.
Conflict adding file innodb_pass_corrupt_table.patch.  Moved existing file to innodb_pass_corrupt_table.patch.moved.
Conflict adding file innodb_recovery_patches.patch.  Moved existing file to innodb_recovery_patches.patch.moved.
Conflict adding file innodb_separate_doublewrite.patch.  Moved existing file to innodb_separate_doublewrite.patch.moved.
Conflict adding file innodb_show_lock_name.patch.  Moved existing file to innodb_show_lock_name.patch.moved.
Conflict adding file innodb_show_status.patch.  Moved existing file to innodb_show_status.patch.moved.
Conflict adding file innodb_show_sys_tables.patch.  Moved existing file to innodb_show_sys_tables.patch.moved.
Conflict adding file innodb_split_buf_pool_mutex.patch.  Moved existing file to innodb_split_buf_pool_mutex.patch.moved.
Conflict adding file innodb_stats.patch.  Moved existing file to innodb_stats.patch.moved.
Conflict adding file innodb_thread_concurrency_timer_based.patch.  Moved existing file to innodb_thread_concurrency_timer_based.patch.moved.
Conflict adding file install_tests.sh.  Moved existing file to install_tests.sh.moved.
Conflict adding file log_connection_error.patch.  Moved existing file to log_connection_error.patch.moved.
Conflict adding file lrusort.py.  Moved existing file to lrusort.py.moved.
Conflict adding file microsec_process.patch.  Moved existing file to microsec_process.patch.moved.
Conflict adding file mysql-test.diff.  Moved existing file to mysql-test.diff.moved.
Conflict adding file mysql-test.  Moved existing file to mysql-test.moved.
Conflict adding file mysql_dump_ignore_ct.patch.  Moved existing file to mysql_dump_ignore_ct.patch.moved.
Conflict adding file normalize_patches.sh.  Moved existing file to normalize_patches.sh.moved.
Conflict adding file optimizer_fix.patch.  Moved existing file to optimizer_fix.patch.moved.
Conflict adding file query_cache_enhance.patch.  Moved existing file to query_cache_enhance.patch.moved.
Conflict adding file regenerate_patch.sh.  Moved existing file to regenerate_patch.sh.moved.
Conflict adding file remove_fcntl_excessive_calls.patch.  Moved existing file to remove_fcntl_excessive_calls.patch.moved.
Conflict adding file series.  Moved existing file to series.moved.
Conflict adding file show_slave_status_nolock.patch.  Moved existing file to show_slave_status_nolock.patch.moved.
Conflict adding file slow_extended.patch.  Moved existing file to slow_extended.patch.moved.
Conflict adding file sql_no_fcache.patch.  Moved existing file to sql_no_fcache.patch.moved.
Conflict adding file userstat.patch.  Moved existing file to userstat.patch.moved.
To merge this branch: bzr merge lp:~percona-dev/percona-server/5.5.8
Reviewer Review Type Date Requested Status
Oleg Tsarev (community) Disapprove
Review via email: mp+45688@code.launchpad.net
To post a comment you must log in.
Revision history for this message
Oleg Tsarev (tsarev) wrote :

What is it?

Revision history for this message
Oleg Tsarev (tsarev) wrote :

lp:percona-server is Percona-Server 5.1
This is dangerous merge.

review: Disapprove

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== added file 'COPYING.innodb-deadlock-count-patch'
2--- COPYING.innodb-deadlock-count-patch 1970-01-01 00:00:00 +0000
3+++ COPYING.innodb-deadlock-count-patch 2011-01-10 13:15:57 +0000
4@@ -0,0 +1,30 @@
5+Portions of this software contain modifications contributed by Eric Bergen.
6+These contributions are used with the following license:
7+
8+Copyright (c) 2010, Eric Bergen. All rights reserved.
9+
10+Redistribution and use in source and binary forms, with or without
11+modification, are permitted provided that the following conditions
12+are met:
13+ * Redistributions of source code must retain the above copyright
14+ notice, this list of conditions and the following disclaimer.
15+ * Redistributions in binary form must reproduce the above
16+ copyright notice, this list of conditions and the following
17+ disclaimer in the documentation and/or other materials
18+ provided with the distribution.
19+ * Neither the name of the Eric Bergen. nor the names of its
20+ contributors may be used to endorse or promote products
21+ derived from this software without specific prior written
22+ permission.
23+
24+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
25+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
26+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
27+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
28+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
29+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
30+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
31+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
32+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
33+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
34+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
35
36=== renamed file 'COPYING.innodb-deadlock-count-patch' => 'COPYING.innodb-deadlock-count-patch.moved'
37=== added file 'COPYING.show_temp_51'
38--- COPYING.show_temp_51 1970-01-01 00:00:00 +0000
39+++ COPYING.show_temp_51 2011-01-10 13:15:57 +0000
40@@ -0,0 +1,13 @@
41+Portions of this software contain modifications contributed by Venu Anuganti.
42+These contributions are used with the following license:
43+
44+Copyright (c) 2010, Venu Anuganti, http://venublog.com/
45+All rights reserved.
46+
47+Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
48+
49+ * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
50+ * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
51+ * Neither the name of the <ORGANIZATION> nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
52+
53+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
54
55=== renamed file 'COPYING.show_temp_51' => 'COPYING.show_temp_51.moved'
56=== added file 'Makefile'
57--- Makefile 1970-01-01 00:00:00 +0000
58+++ Makefile 2011-01-10 13:15:57 +0000
59@@ -0,0 +1,68 @@
60+FETCH_CMD=wget
61+MASTER_SITE=http://www.percona.com/downloads/community
62+MYSQL_VERSION=5.5.8
63+PERCONA_SERVER ?=Percona-Server
64+DEBUG_DIR ?= $(PERCONA_SERVER)-debug
65+RELEASE_DIR ?= $(PERCONA_SERVER)-release
66+SERIES ?=series
67+CMAKE=CC=gcc CXX=gcc CFLAGS="-fPIC -Wall -O3 -g -static-libgcc -fno-omit-frame-pointer -fno-strict-aliasing -DDBUG_OFF" CXXFLAGS="-fno-exceptions -fPIC -Wall -Wno-unused-parameter -fno-implicit-templates -fno-exceptions -fno-rtti -O3 -g -static-libgcc -fno-omit-frame-pointer -fno-strict-aliasing -DDBUG_OFF" cmake
68+CONFIGUR=CFLAGS="-O2 -g -fmessage-length=0 -D_FORTIFY_SOURCE=2" CXXFLAGS="-O2 -g -fmessage-length=0 -D_FORTIFY_SOURCE=2" LIBS=-lrt ./configure --prefix=/usr/local/$(PERCONA_SERVER)-$(MYSQL_VERSION) --with-plugin-innobase --with-plugin-partition
69+
70+
71+all: main install-lic tests misc
72+ @echo ""
73+ @echo "Percona Server source code is ready"
74+ @echo "Now change directory to $(PERCONA_SERVER) define variables as show below"
75+ @echo ""
76+ export CFLAGS="-O2 -g -fmessage-length=0 -D_FORTIFY_SOURCE=2"
77+ export CXXFLAGS="-O2 -g -fmessage-length=0 -D_FORTIFY_SOURCE=2"
78+ export LIBS=-lrt
79+ @echo ""
80+ @echo "and run ./configure --prefix=/usr/local/$(PERCONA_SERVER)-$(MYSQL_VERSION) --with-plugin-innobase --with-plugin-partition && make all install"
81+ @echo ""
82+
83+configure: all
84+ (cd $(PERCONA_SERVER); bash BUILD/autorun.sh; $(CONFIGUR))
85+
86+cmake:
87+ rm -rf $(DEBUG_DIR)
88+ rm -rf $(RELEASE_DIR)
89+ (mkdir -p $(DEBUG_DIR); cd $(DEBUG_DIR); $(CMAKE) -G "Unix Makefiles" -DCMAKE_BUILD_TYPE=Debug -DWITH_DEBUG=Full -DMYSQL_MAINTAINER_MODE=OFF ../$(PERCONA_SERVER))
90+ (mkdir -p $(RELEASE_DIR); cd $(RELEASE_DIR); $(CMAKE) -G "Unix Makefiles" ../$(PERCONA_SERVER))
91+
92+binary:
93+ (cd $(PERCONA_SERVER); ${CMAKE} . -DBUILD_CONFIG=mysql_release \
94+ -DCMAKE_BUILD_TYPE=RelWithDebInfo \
95+ -DCMAKE_INSTALL_PREFIX="/usr/local/$(PERCONA_SERVER)-$(MYSQL_VERSION)" \
96+ -DFEATURE_SET="community" \
97+ -DWITH_EMBEDDED_SERVER=OFF \
98+ -DCOMPILATION_COMMENT="Percona-Server" \
99+ -DMYSQL_SERVER_SUFFIX="${MYSQL_VERSION}" )
100+
101+install-lic:
102+ @echo "Installing license files"
103+ install -m 644 COPYING.* $(PERCONA_SERVER)
104+
105+main: mysql-$(MYSQL_VERSION).tar.gz
106+ @echo "Prepare Percona Server sources"
107+ rm -rf mysql-$(MYSQL_VERSION)
108+ rm -rf $(PERCONA_SERVER);
109+ tar zxf mysql-$(MYSQL_VERSION).tar.gz
110+ mv mysql-$(MYSQL_VERSION) $(PERCONA_SERVER)
111+ (cat `cat $(SERIES)`) | patch -p1 -d $(PERCONA_SERVER)
112+ rm $(PERCONA_SERVER)/sql/sql_yacc.cc $(PERCONA_SERVER)/sql/sql_yacc.h
113+
114+mysql-$(MYSQL_VERSION).tar.gz:
115+ @echo "Downloading MySQL sources from $(MASTER_SITE)"
116+ $(FETCH_CMD) $(MASTER_SITE)/mysql-$(MYSQL_VERSION).tar.gz
117+
118+tests:
119+ ./install_tests.sh
120+
121+misc:
122+ @echo "Installing other files"
123+ install -m 644 lrusort.py $(PERCONA_SERVER)/scripts
124+
125+clean: env
126+ rm -rf mysql-$(MYSQL_VERSION) $(PERCONA_SERVER)
127+ rm -f mysql-$(MYSQL_VERSION).tar.gz
128
129=== renamed file 'Makefile' => 'Makefile.moved'
130=== added file 'bug580324.patch'
131--- bug580324.patch 1970-01-01 00:00:00 +0000
132+++ bug580324.patch 2011-01-10 13:15:57 +0000
133@@ -0,0 +1,105 @@
134+# name : bug580324.patch
135+# introduced : 11 or before
136+# maintainer : Oleg
137+#
138+#!!! notice !!!
139+# Any small change to this file in the main branch
140+# should be done or reviewed by the maintainer!
141+diff -ruN a/sql/sql_base.cc b/sql/sql_base.cc
142+--- a/sql/sql_base.cc 2010-05-27 19:54:18.000000000 +0400
143++++ b/sql/sql_base.cc 2010-05-27 19:55:20.000000000 +0400
144+@@ -233,8 +233,12 @@
145+ uint create_table_def_key(THD *thd, char *key, TABLE_LIST *table_list,
146+ bool tmp_table)
147+ {
148+- uint key_length= (uint) (strmov(strmov(key, table_list->db)+1,
149+- table_list->table_name)-key)+1;
150++ char *db_end= strnmov(key, table_list->db, MAX_DBKEY_LENGTH - 2);
151++ *db_end++= '\0';
152++ char *table_end= strnmov(db_end, table_list->table_name,
153++ key + MAX_DBKEY_LENGTH - 1 - db_end);
154++ *table_end++= '\0';
155++ uint key_length= (uint) (table_end-key);
156+ if (tmp_table)
157+ {
158+ int4store(key + key_length, thd->server_id);
159+diff -ruN a/sql/sql_parse.cc b/sql/sql_parse.cc
160+--- a/sql/sql_parse.cc 2010-05-27 19:54:18.000000000 +0400
161++++ b/sql/sql_parse.cc 2010-05-27 20:03:20.000000000 +0400
162+@@ -1326,10 +1326,12 @@
163+ break;
164+ #else
165+ {
166+- char *fields, *packet_end= packet + packet_length, *arg_end;
167++ char *fields, *packet_end= packet + packet_length, *wildcard;
168+ /* Locked closure of all tables */
169+ TABLE_LIST table_list;
170+- LEX_STRING conv_name;
171++ char db_buff[NAME_LEN+1];
172++ uint32 db_length;
173++ uint dummy_errors;
174+
175+ /* used as fields initializator */
176+ lex_start(thd);
177+@@ -1341,26 +1343,22 @@
178+ /*
179+ We have name + wildcard in packet, separated by endzero
180+ */
181+- arg_end= strend(packet);
182+- uint arg_length= arg_end - packet;
183+-
184+- /* Check given table name length. */
185+- if (arg_length >= packet_length || arg_length > NAME_LEN)
186++ wildcard= strend(packet);
187++ db_length= wildcard - packet;
188++ wildcard++;
189++ uint query_length= (uint) (packet_end - wildcard); // Don't count end \0
190++ if (db_length > NAME_LEN || query_length > NAME_LEN)
191+ {
192+ my_message(ER_UNKNOWN_COM_ERROR, ER(ER_UNKNOWN_COM_ERROR), MYF(0));
193+ break;
194+ }
195+- thd->convert_string(&conv_name, system_charset_info,
196+- packet, arg_length, thd->charset());
197+- if (check_table_name(conv_name.str, conv_name.length, FALSE))
198+- {
199+- /* this is OK due to convert_string() null-terminating the string */
200+- my_error(ER_WRONG_TABLE_NAME, MYF(0), conv_name.str);
201++ db_length= copy_and_convert(db_buff, sizeof(db_buff)-1,
202++ system_charset_info, packet, db_length,
203++ thd->charset(), &dummy_errors);
204++ db_buff[db_length]= '\0';
205++ table_list.alias= table_list.table_name= db_buff;
206++ if (!(fields= (char *) thd->memdup(wildcard, query_length + 1)))
207+ break;
208+- }
209+-
210+- table_list.alias= table_list.table_name= conv_name.str;
211+- packet= arg_end + 1;
212+
213+ if (is_schema_db(table_list.db, table_list.db_length))
214+ {
215+@@ -1369,9 +1367,6 @@
216+ table_list.schema_table= schema_table;
217+ }
218+
219+- uint query_length= (uint) (packet_end - packet); // Don't count end \0
220+- if (!(fields= (char *) thd->memdup(packet, query_length + 1)))
221+- break;
222+ thd->set_query(fields, query_length);
223+ general_log_print(thd, command, "%s %s", table_list.table_name, fields);
224+ if (lower_case_table_names)
225+diff -ruN a/strings/ctype-utf8.c b/strings/ctype-utf8.c
226+--- a/strings/ctype-utf8.c 2010-05-06 19:28:05.000000000 +0400
227++++ b/strings/ctype-utf8.c 2010-05-27 20:04:20.000000000 +0400
228+@@ -4116,6 +4116,10 @@
229+ {
230+ int code;
231+ char hex[]= "0123456789abcdef";
232++
233++ if (s >= e)
234++ return MY_CS_TOOSMALL;
235++
236+ if (wc < 128 && filename_safe_char[wc])
237+ {
238+ *s= (uchar) wc;
239
240=== renamed file 'bug580324.patch' => 'bug580324.patch.moved'
241=== added file 'control_online_alter_index.patch'
242--- control_online_alter_index.patch 1970-01-01 00:00:00 +0000
243+++ control_online_alter_index.patch 2011-01-10 13:15:57 +0000
244@@ -0,0 +1,90 @@
245+# name : control_online_alter_index.patch
246+# introduced : 12
247+# maintainer : Yasufumi
248+#
249+#!!! notice !!!
250+# Any small change to this file in the main branch
251+# should be done or reviewed by the maintainer!
252+diff -ruN a/sql/handler.h b/sql/handler.h
253+--- a/sql/handler.h 2010-11-03 07:01:14.000000000 +0900
254++++ b/sql/handler.h 2010-12-03 13:51:04.727293058 +0900
255+@@ -194,6 +194,19 @@
256+ #define HA_ONLINE_DROP_UNIQUE_INDEX (1L << 9) /*drop uniq. online*/
257+ #define HA_ONLINE_ADD_PK_INDEX (1L << 10)/*add prim. online*/
258+ #define HA_ONLINE_DROP_PK_INDEX (1L << 11)/*drop prim. online*/
259++
260++#define HA_ONLINE_ALTER_INDEX_MASK (HA_ONLINE_ADD_INDEX_NO_WRITES \
261++ | HA_ONLINE_DROP_INDEX_NO_WRITES \
262++ | HA_ONLINE_ADD_UNIQUE_INDEX_NO_WRITES \
263++ | HA_ONLINE_DROP_UNIQUE_INDEX_NO_WRITES \
264++ | HA_ONLINE_ADD_PK_INDEX_NO_WRITES \
265++ | HA_ONLINE_DROP_PK_INDEX_NO_WRITES \
266++ | HA_ONLINE_ADD_INDEX \
267++ | HA_ONLINE_DROP_INDEX \
268++ | HA_ONLINE_ADD_UNIQUE_INDEX \
269++ | HA_ONLINE_DROP_UNIQUE_INDEX \
270++ | HA_ONLINE_ADD_PK_INDEX \
271++ | HA_ONLINE_DROP_PK_INDEX)
272+ /*
273+ HA_PARTITION_FUNCTION_SUPPORTED indicates that the function is
274+ supported at all.
275+diff -ruN a/sql/sql_class.h b/sql/sql_class.h
276+--- a/sql/sql_class.h 2010-12-02 20:31:56.200956501 +0900
277++++ b/sql/sql_class.h 2010-12-03 13:51:04.744953174 +0900
278+@@ -481,6 +481,8 @@
279+ my_bool engine_condition_pushdown;
280+ my_bool keep_files_on_create;
281+
282++ my_bool online_alter_index;
283++
284+ my_bool old_alter_table;
285+ my_bool old_passwords;
286+ my_bool big_tables;
287+diff -ruN a/sql/sql_partition.cc b/sql/sql_partition.cc
288+--- a/sql/sql_partition.cc 2010-11-03 07:01:14.000000000 +0900
289++++ b/sql/sql_partition.cc 2010-12-03 13:59:56.444039002 +0900
290+@@ -4635,7 +4635,12 @@
291+ alter_info->num_parts= curr_part_no - new_part_no;
292+ }
293+ }
294+- if (!(flags= new_table->file->alter_table_flags(alter_info->flags)))
295++ flags= new_table->file->alter_table_flags(alter_info->flags);
296++ if (!thd->variables.online_alter_index)
297++ {
298++ flags&= ~((uint)HA_ONLINE_ALTER_INDEX_MASK);
299++ }
300++ if (!flags)
301+ {
302+ my_error(ER_PARTITION_FUNCTION_FAILURE, MYF(0));
303+ goto err;
304+diff -ruN a/sql/sql_table.cc b/sql/sql_table.cc
305+--- a/sql/sql_table.cc 2010-11-03 07:01:14.000000000 +0900
306++++ b/sql/sql_table.cc 2010-12-03 13:51:04.768955495 +0900
307+@@ -6107,6 +6107,10 @@
308+ uint *idx_end_p;
309+
310+ alter_flags= table->file->alter_table_flags(alter_info->flags);
311++ if (!thd->variables.online_alter_index)
312++ {
313++ alter_flags&= ~((ulong)HA_ONLINE_ALTER_INDEX_MASK);
314++ }
315+ DBUG_PRINT("info", ("alter_flags: %lu", alter_flags));
316+ /* Check dropped indexes. */
317+ for (idx_p= index_drop_buffer, idx_end_p= idx_p + index_drop_count;
318+diff -ruN a/sql/sys_vars.cc b/sql/sys_vars.cc
319+--- a/sql/sys_vars.cc 2010-12-02 21:23:05.569356468 +0900
320++++ b/sql/sys_vars.cc 2010-12-03 14:05:28.857356603 +0900
321+@@ -2124,6 +2124,13 @@
322+ GLOBAL_VAR(opt_optimizer_fix),
323+ NO_CMD_LINE, DEFAULT(TRUE));
324+
325++static Sys_var_mybool Sys_fast_index_creation(
326++ "fast_index_creation",
327++ "If disabled, suppresses online operations for indexes of ALTER TABLE "
328++ "(e.g. fast index creation of InnoDB Plugin) for the session.",
329++ SESSION_VAR(online_alter_index), NO_CMD_LINE,
330++ DEFAULT(TRUE));
331++
332+ /** propagates changes to the relevant flag of @@optimizer_switch */
333+ static bool fix_engine_condition_pushdown(sys_var *self, THD *thd,
334+ enum_var_type type)
335
336=== renamed file 'control_online_alter_index.patch' => 'control_online_alter_index.patch.moved'
337=== added file 'error_pad.patch'
338--- error_pad.patch 1970-01-01 00:00:00 +0000
339+++ error_pad.patch 2011-01-10 13:15:57 +0000
340@@ -0,0 +1,267 @@
341+# name : error_pad.patch
342+# introduced : 12
343+# maintainer : Oleg
344+#
345+#!!! notice !!!
346+# Any small change to this file in the main branch
347+# should be done or reviewed by the maintainer!
348+diff -ruN a/extra/comp_err.c b/extra/comp_err.c
349+--- a/extra/comp_err.c 2010-08-03 17:24:24.000000000 +0000
350++++ b/extra/comp_err.c 2010-09-14 16:49:28.000000000 +0000
351+@@ -30,11 +30,12 @@
352+ #include <assert.h>
353+ #include <my_dir.h>
354+
355+-#define MAX_ROWS 1000
356++#define MAX_ROWS 5000
357+ #define HEADER_LENGTH 32 /* Length of header in errmsg.sys */
358+ #define DEFAULT_CHARSET_DIR "../sql/share/charsets"
359+ #define ER_PREFIX "ER_"
360+ #define WARN_PREFIX "WARN_"
361++#define PADD_PREFIX "PADD_"
362+ static char *OUTFILE= (char*) "errmsg.sys";
363+ static char *HEADERFILE= (char*) "mysqld_error.h";
364+ static char *NAMEFILE= (char*) "mysqld_ername.h";
365+@@ -89,6 +90,7 @@
366+ const char *sql_code1; /* sql state */
367+ const char *sql_code2; /* ODBC state */
368+ struct errors *next_error; /* Pointer to next error */
369++ my_bool is_padding; /* If true - padd this er_name while er_code != d_code*/
370+ DYNAMIC_ARRAY msg; /* All language texts for this error */
371+ };
372+
373+@@ -127,6 +129,7 @@
374+
375+
376+ static struct languages *parse_charset_string(char *str);
377++static struct errors *parse_padd_string(char *ptr, int er_count);
378+ static struct errors *parse_error_string(char *ptr, int er_count);
379+ static struct message *parse_message_string(struct message *new_message,
380+ char *str);
381+@@ -252,6 +255,11 @@
382+
383+ for (tmp_error= error_head; tmp_error; tmp_error= tmp_error->next_error)
384+ {
385++ if (tmp_error->is_padding)
386++ {
387++ er_last= tmp_error->d_code;
388++ continue;
389++ }
390+ /*
391+ generating mysqld_error.h
392+ fprintf() will automatically add \r on windows
393+@@ -344,12 +352,29 @@
394+ "language\n", tmp_error->er_name, tmp_lang->lang_short_name);
395+ goto err;
396+ }
397+- if (copy_rows(to, tmp->text, row_nr, start_pos))
398++ if (tmp_error->is_padding)
399+ {
400+- fprintf(stderr, "Failed to copy rows to %s\n", outfile);
401+- goto err;
402++ uint padd_to= tmp_error->d_code;
403++ char* padd_message= tmp->text;
404++ while ((row_nr+er_offset) < padd_to)
405++ {
406++ if (copy_rows(to, padd_message,row_nr,start_pos))
407++ {
408++ fprintf(stderr, "Failed to copy rows to %s\n", outfile);
409++ goto err;
410++ }
411++ row_nr++;
412++ }
413++ }
414++ else
415++ {
416++ if (copy_rows(to, tmp->text, row_nr, start_pos))
417++ {
418++ fprintf(stderr, "Failed to copy rows to %s\n", outfile);
419++ goto err;
420++ }
421++ row_nr++;
422+ }
423+- row_nr++;
424+ }
425+
426+ /* continue with header of the errmsg.sys file */
427+@@ -500,14 +525,26 @@
428+ DBUG_RETURN(0);
429+ continue;
430+ }
431+- if (is_prefix(str, ER_PREFIX) || is_prefix(str, WARN_PREFIX))
432++ if (is_prefix(str, ER_PREFIX) || is_prefix(str, WARN_PREFIX) || is_prefix(str, PADD_PREFIX))
433+ {
434+- if (!(current_error= parse_error_string(str, rcount)))
435++ if (is_prefix(str, PADD_PREFIX))
436+ {
437+- fprintf(stderr, "Failed to parse the error name string\n");
438+- DBUG_RETURN(0);
439++ if (!(current_error= parse_padd_string(str, rcount)))
440++ {
441++ fprintf(stderr, "Failed to parse the error padd string\n");
442++ DBUG_RETURN(0);
443++ }
444++ rcount= current_error->d_code - er_offset; /* Count number of unique errors */
445++ }
446++ else
447++ {
448++ if (!(current_error= parse_error_string(str, rcount)))
449++ {
450++ fprintf(stderr, "Failed to parse the error name string\n");
451++ DBUG_RETURN(0);
452++ }
453++ rcount++; /* Count number of unique errors */
454+ }
455+- rcount++; /* Count number of unique errors */
456+
457+ /* add error to the list */
458+ *tail_error= current_error;
459+@@ -848,78 +885,122 @@
460+ DBUG_RETURN(new_message);
461+ }
462+
463++static struct errors* create_new_error(my_bool is_padding, char *er_name, int d_code, const char *sql_code1, const char *sql_code2)
464++{
465++ struct errors *new_error;
466++ DBUG_ENTER("create_new_error");
467++ /* create a new element */
468++ new_error= (struct errors *) my_malloc(sizeof(*new_error), MYF(MY_WME));
469++ if (my_init_dynamic_array(&new_error->msg, sizeof(struct message), 0, 0))
470++ DBUG_RETURN(0); /* OOM: Fatal error */
471++ new_error->is_padding= is_padding;
472++ DBUG_PRINT("info", ("is_padding: %s", (is_padding ? "true" : "false")));
473++ new_error->er_name= er_name;
474++ DBUG_PRINT("info", ("er_name: %s", er_name));
475++ new_error->d_code= d_code;
476++ DBUG_PRINT("info", ("d_code: %d", d_code));
477++ new_error->sql_code1= sql_code1;
478++ DBUG_PRINT("info", ("sql_code1: %s", sql_code1));
479++ new_error->sql_code2= sql_code2;
480++ DBUG_PRINT("info", ("sql_code2: %s", sql_code2));
481++ DBUG_RETURN(new_error);
482++}
483+
484+ /*
485+- Parsing the string with error name and codes; returns the pointer to
486++ Parsing the string with padd syntax (name + error to pad); returns the pointer to
487+ the errors struct
488+ */
489+
490+-static struct errors *parse_error_string(char *str, int er_count)
491++static struct errors *parse_padd_string(char* str, int er_count)
492+ {
493+- struct errors *new_error;
494++ char *er_name;
495++ uint d_code;
496++ char *start;
497+ DBUG_ENTER("parse_error_string");
498+ DBUG_PRINT("enter", ("str: %s", str));
499+
500+- /* create a new element */
501+- new_error= (struct errors *) my_malloc(sizeof(*new_error), MYF(MY_WME));
502++ start= str;
503++ str= skip_delimiters(str);
504+
505+- if (my_init_dynamic_array(&new_error->msg, sizeof(struct message), 0, 0))
506++ /* getting the error name */
507++
508++ if (!(er_name= get_word(&str)))
509+ DBUG_RETURN(0); /* OOM: Fatal error */
510+
511+- /* getting the error name */
512+ str= skip_delimiters(str);
513+
514+- if (!(new_error->er_name= get_word(&str)))
515++ if (!(d_code= parse_error_offset(start)))
516++ {
517++ fprintf(stderr, "Failed to parse the error padd string '%s' '%s' (d_code doesn't parse)!\n",er_name,str);
518++ DBUG_RETURN(0);
519++ }
520++ if (d_code < (uint)(er_offset + er_count))
521++ {
522++ fprintf(stderr, "Error to padding less current error number!\n");
523++ DBUG_RETURN(0);
524++ }
525++ DBUG_RETURN(create_new_error(TRUE,er_name,d_code,empty_string,empty_string));
526++}
527++
528++/*
529++ Parsing the string with error name and codes; returns the pointer to
530++ the errors struct
531++*/
532++
533++static struct errors *parse_error_string(char *str, int er_count)
534++{
535++ char *er_name;
536++ int d_code;
537++ const char *sql_code1= empty_string;
538++ const char *sql_code2= empty_string;
539++ DBUG_ENTER("parse_error_string");
540++ DBUG_PRINT("enter", ("str: %s", str));
541++
542++ str= skip_delimiters(str);
543++
544++ /* getting the error name */
545++
546++ if (!(er_name= get_word(&str)))
547+ DBUG_RETURN(0); /* OOM: Fatal error */
548+- DBUG_PRINT("info", ("er_name: %s", new_error->er_name));
549+
550+ str= skip_delimiters(str);
551+
552+ /* getting the code1 */
553+-
554+- new_error->d_code= er_offset + er_count;
555+- DBUG_PRINT("info", ("d_code: %d", new_error->d_code));
556++ d_code= er_offset + er_count;
557+
558+ str= skip_delimiters(str);
559+
560+ /* if we reached EOL => no more codes, but this can happen */
561+ if (!*str)
562+ {
563+- new_error->sql_code1= empty_string;
564+- new_error->sql_code2= empty_string;
565+ DBUG_PRINT("info", ("str: %s", str));
566+- DBUG_RETURN(new_error);
567++ goto complete_create;
568+ }
569+-
570+ /* getting the sql_code 1 */
571+-
572+- if (!(new_error->sql_code1= get_word(&str)))
573++ if (!(sql_code1= get_word(&str)))
574+ DBUG_RETURN(0); /* OOM: Fatal error */
575+- DBUG_PRINT("info", ("sql_code1: %s", new_error->sql_code1));
576+
577+ str= skip_delimiters(str);
578+
579+ /* if we reached EOL => no more codes, but this can happen */
580+ if (!*str)
581+ {
582+- new_error->sql_code2= empty_string;
583+ DBUG_PRINT("info", ("str: %s", str));
584+- DBUG_RETURN(new_error);
585++ goto complete_create;
586+ }
587+-
588+ /* getting the sql_code 2 */
589+- if (!(new_error->sql_code2= get_word(&str)))
590++ if (!(sql_code2= get_word(&str)))
591+ DBUG_RETURN(0); /* OOM: Fatal error */
592+- DBUG_PRINT("info", ("sql_code2: %s", new_error->sql_code2));
593+
594+ str= skip_delimiters(str);
595++
596+ if (*str)
597+ {
598+ fprintf(stderr, "The error line did not end with sql/odbc code!");
599+ DBUG_RETURN(0);
600+ }
601+-
602+- DBUG_RETURN(new_error);
603++complete_create:
604++ DBUG_RETURN(create_new_error(FALSE,er_name,d_code,sql_code1,sql_code2));
605+ }
606+
607+
608
609=== renamed file 'error_pad.patch' => 'error_pad.patch.moved'
610=== added file 'innodb_adaptive_hash_index_partitions.patch'
611--- innodb_adaptive_hash_index_partitions.patch 1970-01-01 00:00:00 +0000
612+++ innodb_adaptive_hash_index_partitions.patch 2011-01-10 13:15:57 +0000
613@@ -0,0 +1,1508 @@
614+# name : innodb_adaptive_hash_index_num.patch
615+# introduced : XtraDB on 5.5 (-13?)
616+# maintainer : Yasufumi
617+#
618+#!!! notice !!!
619+# Any small change to this file in the main branch
620+# should be done or reviewed by the maintainer!
621+diff -ruN a/storage/innobase/btr/btr0btr.c b/storage/innobase/btr/btr0btr.c
622+--- a/storage/innobase/btr/btr0btr.c 2010-12-04 15:52:23.355483176 +0900
623++++ b/storage/innobase/btr/btr0btr.c 2010-12-04 16:12:48.639514256 +0900
624+@@ -954,7 +954,7 @@
625+ }
626+ ut_a(block);
627+
628+- btr_search_drop_page_hash_index(block);
629++ btr_search_drop_page_hash_index(block, NULL);
630+
631+ header = buf_block_get_frame(block) + PAGE_HEADER + PAGE_BTR_SEG_TOP;
632+ #ifdef UNIV_BTR_DEBUG
633+@@ -1023,7 +1023,7 @@
634+
635+ #ifndef UNIV_HOTBACKUP
636+ if (UNIV_LIKELY(!recovery)) {
637+- btr_search_drop_page_hash_index(block);
638++ btr_search_drop_page_hash_index(block, index);
639+ }
640+
641+ block->check_index_page_at_flush = TRUE;
642+@@ -1188,7 +1188,7 @@
643+ ut_a(!page_zip || page_zip_validate(page_zip, page));
644+ #endif /* UNIV_ZIP_DEBUG */
645+
646+- btr_search_drop_page_hash_index(block);
647++ btr_search_drop_page_hash_index(block, index);
648+
649+ /* Recreate the page: note that global data on page (possible
650+ segment headers, next page-field, etc.) is preserved intact */
651+@@ -2497,7 +2497,7 @@
652+ mem_heap_free(heap);
653+ }
654+
655+- btr_search_drop_page_hash_index(block);
656++ btr_search_drop_page_hash_index(block, index);
657+
658+ /* Make the father empty */
659+ btr_page_empty(father_block, father_page_zip, index, page_level, mtr);
660+@@ -2720,7 +2720,7 @@
661+ goto err_exit;
662+ }
663+
664+- btr_search_drop_page_hash_index(block);
665++ btr_search_drop_page_hash_index(block, index);
666+
667+ /* Remove the page from the level list */
668+ btr_level_list_remove(space, zip_size, page, mtr);
669+@@ -2761,7 +2761,7 @@
670+ goto err_exit;
671+ }
672+
673+- btr_search_drop_page_hash_index(block);
674++ btr_search_drop_page_hash_index(block, index);
675+
676+ #ifdef UNIV_BTR_DEBUG
677+ if (UNIV_LIKELY_NULL(merge_page_zip)) {
678+@@ -2875,7 +2875,7 @@
679+ ut_a(btr_page_get_next(page, mtr) == FIL_NULL);
680+
681+ ut_ad(mtr_memo_contains(mtr, block, MTR_MEMO_PAGE_X_FIX));
682+- btr_search_drop_page_hash_index(block);
683++ btr_search_drop_page_hash_index(block, index);
684+
685+ btr_page_get_father(index, block, mtr, &cursor);
686+ father = btr_cur_get_block(&cursor);
687+@@ -2980,7 +2980,7 @@
688+
689+ page = buf_block_get_frame(block);
690+ ut_a(page_is_comp(merge_page) == page_is_comp(page));
691+- btr_search_drop_page_hash_index(block);
692++ btr_search_drop_page_hash_index(block, index);
693+
694+ if (left_page_no == FIL_NULL && !page_is_leaf(page)) {
695+
696+diff -ruN a/storage/innobase/btr/btr0cur.c b/storage/innobase/btr/btr0cur.c
697+--- a/storage/innobase/btr/btr0cur.c 2010-12-04 15:52:23.359513820 +0900
698++++ b/storage/innobase/btr/btr0cur.c 2010-12-04 16:12:48.643551837 +0900
699+@@ -486,7 +486,7 @@
700+ #ifdef UNIV_SEARCH_PERF_STAT
701+ info->n_searches++;
702+ #endif
703+- if (rw_lock_get_writer(&btr_search_latch) == RW_LOCK_NOT_LOCKED
704++ if (rw_lock_get_writer(btr_search_get_latch(cursor->index->id)) == RW_LOCK_NOT_LOCKED
705+ && latch_mode <= BTR_MODIFY_LEAF
706+ && info->last_hash_succ
707+ && !estimate
708+@@ -522,7 +522,7 @@
709+
710+ if (has_search_latch) {
711+ /* Release possible search latch to obey latching order */
712+- rw_lock_s_unlock(&btr_search_latch);
713++ rw_lock_s_unlock(btr_search_get_latch(cursor->index->id));
714+ }
715+
716+ /* Store the position of the tree latch we push to mtr so that we
717+@@ -844,7 +844,7 @@
718+
719+ if (has_search_latch) {
720+
721+- rw_lock_s_lock(&btr_search_latch);
722++ rw_lock_s_lock(btr_search_get_latch(cursor->index->id));
723+ }
724+ }
725+
726+@@ -2059,7 +2059,7 @@
727+ btr_search_update_hash_on_delete(cursor);
728+ }
729+
730+- rw_lock_x_lock(&btr_search_latch);
731++ rw_lock_x_lock(btr_search_get_latch(cursor->index->id));
732+ }
733+
734+ if (!(flags & BTR_KEEP_SYS_FLAG)) {
735+@@ -2073,7 +2073,7 @@
736+ row_upd_rec_in_place(rec, index, offsets, update, page_zip);
737+
738+ if (block->is_hashed) {
739+- rw_lock_x_unlock(&btr_search_latch);
740++ rw_lock_x_unlock(btr_search_get_latch(cursor->index->id));
741+ }
742+
743+ if (page_zip && !dict_index_is_clust(index)
744+@@ -2857,7 +2857,7 @@
745+ block = btr_cur_get_block(cursor);
746+
747+ if (block->is_hashed) {
748+- rw_lock_x_lock(&btr_search_latch);
749++ rw_lock_x_lock(btr_search_get_latch(index->id));
750+ }
751+
752+ page_zip = buf_block_get_page_zip(block);
753+@@ -2872,7 +2872,7 @@
754+ }
755+
756+ if (block->is_hashed) {
757+- rw_lock_x_unlock(&btr_search_latch);
758++ rw_lock_x_unlock(btr_search_get_latch(index->id));
759+ }
760+
761+ btr_cur_del_mark_set_clust_rec_log(flags, rec, index, val, trx,
762+@@ -3003,13 +3003,13 @@
763+ == dict_table_is_comp(cursor->index->table));
764+
765+ if (block->is_hashed) {
766+- rw_lock_x_lock(&btr_search_latch);
767++ rw_lock_x_lock(btr_search_get_latch(cursor->index->id));
768+ }
769+
770+ btr_rec_set_deleted_flag(rec, buf_block_get_page_zip(block), val);
771+
772+ if (block->is_hashed) {
773+- rw_lock_x_unlock(&btr_search_latch);
774++ rw_lock_x_unlock(btr_search_get_latch(cursor->index->id));
775+ }
776+
777+ btr_cur_del_mark_set_sec_rec_log(rec, val, mtr);
778+diff -ruN a/storage/innobase/btr/btr0sea.c b/storage/innobase/btr/btr0sea.c
779+--- a/storage/innobase/btr/btr0sea.c 2010-12-04 15:52:23.387513429 +0900
780++++ b/storage/innobase/btr/btr0sea.c 2010-12-04 16:14:51.721884049 +0900
781+@@ -48,6 +48,8 @@
782+ UNIV_INTERN char btr_search_enabled = TRUE;
783+ UNIV_INTERN ibool btr_search_fully_disabled = FALSE;
784+
785++UNIV_INTERN ulint btr_search_index_num = 1;
786++
787+ /** Mutex protecting btr_search_enabled */
788+ static mutex_t btr_search_enabled_mutex;
789+
790+@@ -79,7 +81,9 @@
791+
792+ /* We will allocate the latch from dynamic memory to get it to the
793+ same DRAM page as other hotspot semaphores */
794+-UNIV_INTERN rw_lock_t* btr_search_latch_temp;
795++//UNIV_INTERN rw_lock_t* btr_search_latch_temp;
796++
797++UNIV_INTERN rw_lock_t** btr_search_latch_part;
798+
799+ /** padding to prevent other memory update hotspots from residing on
800+ the same memory cache line */
801+@@ -131,18 +135,19 @@
802+ will not guarantee success. */
803+ static
804+ void
805+-btr_search_check_free_space_in_heap(void)
806++btr_search_check_free_space_in_heap(
807+ /*=====================================*/
808++ index_id_t key)
809+ {
810+ hash_table_t* table;
811+ mem_heap_t* heap;
812+
813+ #ifdef UNIV_SYNC_DEBUG
814+- ut_ad(!rw_lock_own(&btr_search_latch, RW_LOCK_SHARED));
815+- ut_ad(!rw_lock_own(&btr_search_latch, RW_LOCK_EX));
816++ ut_ad(!rw_lock_own(btr_search_get_latch(key), RW_LOCK_SHARED));
817++ ut_ad(!rw_lock_own(btr_search_get_latch(key), RW_LOCK_EX));
818+ #endif /* UNIV_SYNC_DEBUG */
819+
820+- table = btr_search_sys->hash_index;
821++ table = btr_search_get_hash_index(key);
822+
823+ heap = table->heap;
824+
825+@@ -153,7 +158,7 @@
826+ if (heap->free_block == NULL) {
827+ buf_block_t* block = buf_block_alloc(NULL, 0);
828+
829+- rw_lock_x_lock(&btr_search_latch);
830++ rw_lock_x_lock(btr_search_get_latch(key));
831+
832+ if (heap->free_block == NULL) {
833+ heap->free_block = block;
834+@@ -161,7 +166,7 @@
835+ buf_block_free(block);
836+ }
837+
838+- rw_lock_x_unlock(&btr_search_latch);
839++ rw_lock_x_unlock(btr_search_get_latch(key));
840+ }
841+ }
842+
843+@@ -173,19 +178,30 @@
844+ /*==================*/
845+ ulint hash_size) /*!< in: hash index hash table size */
846+ {
847++ ulint i;
848+ /* We allocate the search latch from dynamic memory:
849+ see above at the global variable definition */
850+
851+- btr_search_latch_temp = mem_alloc(sizeof(rw_lock_t));
852++ //btr_search_latch_temp = mem_alloc(sizeof(rw_lock_t));
853+
854+- rw_lock_create(btr_search_latch_key, &btr_search_latch,
855+- SYNC_SEARCH_SYS);
856++ //rw_lock_create(btr_search_latch_key, &btr_search_latch,
857++ // SYNC_SEARCH_SYS);
858+ mutex_create(btr_search_enabled_mutex_key,
859+ &btr_search_enabled_mutex, SYNC_SEARCH_SYS_CONF);
860+
861+ btr_search_sys = mem_alloc(sizeof(btr_search_sys_t));
862+
863+- btr_search_sys->hash_index = ha_create(hash_size, 0, 0);
864++ /* btr_search_index_num should be <= 32. (bits of trx->has_search_latch) */
865++ btr_search_latch_part = mem_alloc(sizeof(rw_lock_t*) * btr_search_index_num);
866++ btr_search_sys->hash_index = mem_alloc(sizeof(hash_table_t*) * btr_search_index_num);
867++ for (i = 0; i < btr_search_index_num; i++) {
868++ btr_search_latch_part[i] = mem_alloc(sizeof(rw_lock_t));
869++
870++ rw_lock_create(btr_search_latch_key,
871++ btr_search_latch_part[i], SYNC_SEARCH_SYS);
872++
873++ btr_search_sys->hash_index[i] = ha_create(hash_size, 0, 0);
874++ }
875+ }
876+
877+ /*****************************************************************//**
878+@@ -195,11 +211,20 @@
879+ btr_search_sys_free(void)
880+ /*=====================*/
881+ {
882+- rw_lock_free(&btr_search_latch);
883+- mem_free(btr_search_latch_temp);
884+- btr_search_latch_temp = NULL;
885+- mem_heap_free(btr_search_sys->hash_index->heap);
886+- hash_table_free(btr_search_sys->hash_index);
887++ ulint i;
888++
889++ for (i = 0; i < btr_search_index_num; i++) {
890++ mem_heap_free(btr_search_sys->hash_index[i]->heap);
891++ hash_table_free(btr_search_sys->hash_index[i]);
892++
893++ rw_lock_free(btr_search_latch_part[i]);
894++
895++ mem_free(btr_search_latch_part[i]);
896++ }
897++
898++ //rw_lock_free(&btr_search_latch);
899++ //mem_free(btr_search_latch_temp);
900++ //btr_search_latch_temp = NULL;
901+ mem_free(btr_search_sys);
902+ btr_search_sys = NULL;
903+ }
904+@@ -212,7 +237,7 @@
905+ /*====================*/
906+ {
907+ mutex_enter(&btr_search_enabled_mutex);
908+- rw_lock_x_lock(&btr_search_latch);
909++ btr_search_x_lock_all();
910+
911+ /* Disable access to hash index, also tell ha_insert_for_fold()
912+ stop adding new nodes to hash index, but still allow updating
913+@@ -230,7 +255,7 @@
914+ /* btr_search_enabled_mutex should guarantee this. */
915+ ut_ad(!btr_search_enabled);
916+
917+- rw_lock_x_unlock(&btr_search_latch);
918++ btr_search_x_unlock_all();
919+ mutex_exit(&btr_search_enabled_mutex);
920+ }
921+
922+@@ -242,12 +267,12 @@
923+ /*====================*/
924+ {
925+ mutex_enter(&btr_search_enabled_mutex);
926+- rw_lock_x_lock(&btr_search_latch);
927++ btr_search_x_lock_all();
928+
929+ btr_search_enabled = TRUE;
930+ btr_search_fully_disabled = FALSE;
931+
932+- rw_lock_x_unlock(&btr_search_latch);
933++ btr_search_x_unlock_all();
934+ mutex_exit(&btr_search_enabled_mutex);
935+ }
936+
937+@@ -300,20 +325,21 @@
938+ ulint
939+ btr_search_info_get_ref_count(
940+ /*==========================*/
941+- btr_search_t* info) /*!< in: search info. */
942++ btr_search_t* info, /*!< in: search info. */
943++ index_id_t key)
944+ {
945+ ulint ret;
946+
947+ ut_ad(info);
948+
949+ #ifdef UNIV_SYNC_DEBUG
950+- ut_ad(!rw_lock_own(&btr_search_latch, RW_LOCK_SHARED));
951+- ut_ad(!rw_lock_own(&btr_search_latch, RW_LOCK_EX));
952++ ut_ad(!rw_lock_own(btr_search_get_latch(key), RW_LOCK_SHARED));
953++ ut_ad(!rw_lock_own(btr_search_get_latch(key), RW_LOCK_EX));
954+ #endif /* UNIV_SYNC_DEBUG */
955+
956+- rw_lock_s_lock(&btr_search_latch);
957++ rw_lock_s_lock(btr_search_get_latch(key));
958+ ret = info->ref_count;
959+- rw_lock_s_unlock(&btr_search_latch);
960++ rw_lock_s_unlock(btr_search_get_latch(key));
961+
962+ return(ret);
963+ }
964+@@ -334,8 +360,8 @@
965+ int cmp;
966+
967+ #ifdef UNIV_SYNC_DEBUG
968+- ut_ad(!rw_lock_own(&btr_search_latch, RW_LOCK_SHARED));
969+- ut_ad(!rw_lock_own(&btr_search_latch, RW_LOCK_EX));
970++ ut_ad(!rw_lock_own(btr_search_get_latch(cursor->index->id), RW_LOCK_SHARED));
971++ ut_ad(!rw_lock_own(btr_search_get_latch(cursor->index->id), RW_LOCK_EX));
972+ #endif /* UNIV_SYNC_DEBUG */
973+
974+ index = cursor->index;
975+@@ -453,8 +479,8 @@
976+ /*!< in: cursor */
977+ {
978+ #ifdef UNIV_SYNC_DEBUG
979+- ut_ad(!rw_lock_own(&btr_search_latch, RW_LOCK_SHARED));
980+- ut_ad(!rw_lock_own(&btr_search_latch, RW_LOCK_EX));
981++ ut_ad(!rw_lock_own(btr_search_get_latch(cursor->index->id), RW_LOCK_SHARED));
982++ ut_ad(!rw_lock_own(btr_search_get_latch(cursor->index->id), RW_LOCK_EX));
983+ ut_ad(rw_lock_own(&block->lock, RW_LOCK_SHARED)
984+ || rw_lock_own(&block->lock, RW_LOCK_EX));
985+ #endif /* UNIV_SYNC_DEBUG */
986+@@ -538,7 +564,7 @@
987+
988+ ut_ad(cursor->flag == BTR_CUR_HASH_FAIL);
989+ #ifdef UNIV_SYNC_DEBUG
990+- ut_ad(rw_lock_own(&btr_search_latch, RW_LOCK_EX));
991++ ut_ad(rw_lock_own(btr_search_get_latch(cursor->index->id), RW_LOCK_EX));
992+ ut_ad(rw_lock_own(&(block->lock), RW_LOCK_SHARED)
993+ || rw_lock_own(&(block->lock), RW_LOCK_EX));
994+ #endif /* UNIV_SYNC_DEBUG */
995+@@ -578,10 +604,10 @@
996+ mem_heap_free(heap);
997+ }
998+ #ifdef UNIV_SYNC_DEBUG
999+- ut_ad(rw_lock_own(&btr_search_latch, RW_LOCK_EX));
1000++ ut_ad(rw_lock_own(btr_search_get_latch(cursor->index->id), RW_LOCK_EX));
1001+ #endif /* UNIV_SYNC_DEBUG */
1002+
1003+- ha_insert_for_fold(btr_search_sys->hash_index, fold,
1004++ ha_insert_for_fold(btr_search_get_hash_index(cursor->index->id), fold,
1005+ block, rec);
1006+ }
1007+ }
1008+@@ -601,8 +627,8 @@
1009+ ulint* params2;
1010+
1011+ #ifdef UNIV_SYNC_DEBUG
1012+- ut_ad(!rw_lock_own(&btr_search_latch, RW_LOCK_SHARED));
1013+- ut_ad(!rw_lock_own(&btr_search_latch, RW_LOCK_EX));
1014++ ut_ad(!rw_lock_own(btr_search_get_latch(cursor->index->id), RW_LOCK_SHARED));
1015++ ut_ad(!rw_lock_own(btr_search_get_latch(cursor->index->id), RW_LOCK_EX));
1016+ #endif /* UNIV_SYNC_DEBUG */
1017+
1018+ block = btr_cur_get_block(cursor);
1019+@@ -623,7 +649,7 @@
1020+
1021+ if (build_index || (cursor->flag == BTR_CUR_HASH_FAIL)) {
1022+
1023+- btr_search_check_free_space_in_heap();
1024++ btr_search_check_free_space_in_heap(cursor->index->id);
1025+ }
1026+
1027+ if (cursor->flag == BTR_CUR_HASH_FAIL) {
1028+@@ -633,11 +659,11 @@
1029+ btr_search_n_hash_fail++;
1030+ #endif /* UNIV_SEARCH_PERF_STAT */
1031+
1032+- rw_lock_x_lock(&btr_search_latch);
1033++ rw_lock_x_lock(btr_search_get_latch(cursor->index->id));
1034+
1035+ btr_search_update_hash_ref(info, block, cursor);
1036+
1037+- rw_lock_x_unlock(&btr_search_latch);
1038++ rw_lock_x_unlock(btr_search_get_latch(cursor->index->id));
1039+ }
1040+
1041+ if (build_index) {
1042+@@ -881,17 +907,17 @@
1043+ cursor->flag = BTR_CUR_HASH;
1044+
1045+ if (UNIV_LIKELY(!has_search_latch)) {
1046+- rw_lock_s_lock(&btr_search_latch);
1047++ rw_lock_s_lock(btr_search_get_latch(index_id));
1048+
1049+ if (UNIV_UNLIKELY(!btr_search_enabled)) {
1050+ goto failure_unlock;
1051+ }
1052+ }
1053+
1054+- ut_ad(rw_lock_get_writer(&btr_search_latch) != RW_LOCK_EX);
1055+- ut_ad(rw_lock_get_reader_count(&btr_search_latch) > 0);
1056++ ut_ad(rw_lock_get_writer(btr_search_get_latch(index_id)) != RW_LOCK_EX);
1057++ ut_ad(rw_lock_get_reader_count(btr_search_get_latch(index_id)) > 0);
1058+
1059+- rec = ha_search_and_get_data(btr_search_sys->hash_index, fold);
1060++ rec = ha_search_and_get_data(btr_search_get_hash_index(index_id), fold);
1061+
1062+ if (UNIV_UNLIKELY(!rec)) {
1063+ goto failure_unlock;
1064+@@ -909,7 +935,7 @@
1065+ goto failure_unlock;
1066+ }
1067+
1068+- rw_lock_s_unlock(&btr_search_latch);
1069++ rw_lock_s_unlock(btr_search_get_latch(index_id));
1070+
1071+ buf_block_dbg_add_level(block, SYNC_TREE_NODE_FROM_HASH);
1072+ }
1073+@@ -1006,7 +1032,7 @@
1074+ /*-------------------------------------------*/
1075+ failure_unlock:
1076+ if (UNIV_LIKELY(!has_search_latch)) {
1077+- rw_lock_s_unlock(&btr_search_latch);
1078++ rw_lock_s_unlock(btr_search_get_latch(index_id));
1079+ }
1080+ failure:
1081+ cursor->flag = BTR_CUR_HASH_FAIL;
1082+@@ -1029,10 +1055,11 @@
1083+ void
1084+ btr_search_drop_page_hash_index(
1085+ /*============================*/
1086+- buf_block_t* block) /*!< in: block containing index page,
1087++ buf_block_t* block, /*!< in: block containing index page,
1088+ s- or x-latched, or an index page
1089+ for which we know that
1090+ block->buf_fix_count == 0 */
1091++ dict_index_t* index_in)
1092+ {
1093+ hash_table_t* table;
1094+ ulint n_fields;
1095+@@ -1051,22 +1078,60 @@
1096+ ulint* offsets;
1097+
1098+ #ifdef UNIV_SYNC_DEBUG
1099+- ut_ad(!rw_lock_own(&btr_search_latch, RW_LOCK_SHARED));
1100+- ut_ad(!rw_lock_own(&btr_search_latch, RW_LOCK_EX));
1101++ if (index_in) {
1102++ ut_ad(!rw_lock_own(btr_search_get_latch(index_in->id), RW_LOCK_SHARED));
1103++ ut_ad(!rw_lock_own(btr_search_get_latch(index_in->id), RW_LOCK_EX));
1104++ }
1105+ #endif /* UNIV_SYNC_DEBUG */
1106+
1107+ retry:
1108+- rw_lock_s_lock(&btr_search_latch);
1109++ if (index_in) {
1110++ index = index_in;
1111++ rw_lock_s_lock(btr_search_get_latch(index->id));
1112++ } else if (btr_search_index_num > 1) {
1113++ rw_lock_t* btr_search_latch;
1114++
1115++ /* FIXME: This may be optimistic implementation still. */
1116++ btr_search_latch = (rw_lock_t*)(block->btr_search_latch);
1117++ if (UNIV_LIKELY(!btr_search_latch)) {
1118++ if (block->is_hashed) {
1119++ goto retry;
1120++ }
1121++ return;
1122++ }
1123++ rw_lock_s_lock(btr_search_latch);
1124++ if (UNIV_LIKELY(btr_search_latch != block->btr_search_latch)) {
1125++ rw_lock_s_unlock(btr_search_latch);
1126++ goto retry;
1127++ }
1128++ if (UNIV_LIKELY(!block->is_hashed)) {
1129++ rw_lock_s_unlock(btr_search_latch);
1130++ return;
1131++ }
1132++ index = block->index;
1133++ ut_a(btr_search_latch == btr_search_get_latch(index->id));
1134++ } else {
1135++ /* btr_search_index_num == 1 */
1136++ /* btr_search_latch is only one and able to obtain
1137++ before evaluating block->is_hashed. */
1138++ rw_lock_s_lock(btr_search_latch_part[0]);
1139++ if (UNIV_LIKELY(!block->is_hashed)) {
1140++ rw_lock_s_unlock(btr_search_latch_part[0]);
1141++ return;
1142++ }
1143++ index = block->index;
1144++ }
1145++
1146+ page = block->frame;
1147+
1148+ if (UNIV_LIKELY(!block->is_hashed)) {
1149+
1150+- rw_lock_s_unlock(&btr_search_latch);
1151++ rw_lock_s_unlock(btr_search_get_latch(index->id));
1152+
1153+ return;
1154+ }
1155+
1156+- table = btr_search_sys->hash_index;
1157++ table = btr_search_get_hash_index(index->id);
1158+
1159+ #ifdef UNIV_SYNC_DEBUG
1160+ ut_ad(rw_lock_own(&(block->lock), RW_LOCK_SHARED)
1161+@@ -1076,14 +1141,14 @@
1162+
1163+ n_fields = block->curr_n_fields;
1164+ n_bytes = block->curr_n_bytes;
1165+- index = block->index;
1166++ ut_a(index == block->index);
1167+ ut_a(!dict_index_is_ibuf(index));
1168+
1169+ /* NOTE: The fields of block must not be accessed after
1170+ releasing btr_search_latch, as the index page might only
1171+ be s-latched! */
1172+
1173+- rw_lock_s_unlock(&btr_search_latch);
1174++ rw_lock_s_unlock(btr_search_get_latch(index->id));
1175+
1176+ ut_a(n_fields + n_bytes > 0);
1177+
1178+@@ -1133,7 +1198,7 @@
1179+ mem_heap_free(heap);
1180+ }
1181+
1182+- rw_lock_x_lock(&btr_search_latch);
1183++ rw_lock_x_lock(btr_search_get_latch(index->id));
1184+
1185+ if (UNIV_UNLIKELY(!block->is_hashed)) {
1186+ /* Someone else has meanwhile dropped the hash index */
1187+@@ -1149,7 +1214,7 @@
1188+ /* Someone else has meanwhile built a new hash index on the
1189+ page, with different parameters */
1190+
1191+- rw_lock_x_unlock(&btr_search_latch);
1192++ rw_lock_x_unlock(btr_search_get_latch(index->id));
1193+
1194+ mem_free(folds);
1195+ goto retry;
1196+@@ -1165,6 +1230,7 @@
1197+
1198+ block->is_hashed = FALSE;
1199+ block->index = NULL;
1200++ block->btr_search_latch = NULL;
1201+
1202+ cleanup:
1203+ #if defined UNIV_AHI_DEBUG || defined UNIV_DEBUG
1204+@@ -1177,14 +1243,14 @@
1205+ "InnoDB: the hash index to a page of %s,"
1206+ " still %lu hash nodes remain.\n",
1207+ index->name, (ulong) block->n_pointers);
1208+- rw_lock_x_unlock(&btr_search_latch);
1209++ rw_lock_x_unlock(btr_search_get_latch(index->id));
1210+
1211+ btr_search_validate();
1212+ } else {
1213+- rw_lock_x_unlock(&btr_search_latch);
1214++ rw_lock_x_unlock(btr_search_get_latch(index->id));
1215+ }
1216+ #else /* UNIV_AHI_DEBUG || UNIV_DEBUG */
1217+- rw_lock_x_unlock(&btr_search_latch);
1218++ rw_lock_x_unlock(btr_search_get_latch(index->id));
1219+ #endif /* UNIV_AHI_DEBUG || UNIV_DEBUG */
1220+
1221+ mem_free(folds);
1222+@@ -1215,10 +1281,10 @@
1223+ mem_heap_t* heap = NULL;
1224+ ulint* offsets;
1225+
1226+- rw_lock_x_lock(&btr_search_latch);
1227++ rw_lock_x_lock(btr_search_get_latch(index->id));
1228+ //buf_pool_mutex_enter_all();
1229+
1230+- table = btr_search_sys->hash_index;
1231++ table = btr_search_get_hash_index(index->id);
1232+
1233+ for (j = 0; j < srv_buf_pool_instances; j++) {
1234+ buf_pool_t* buf_pool;
1235+@@ -1291,6 +1357,7 @@
1236+
1237+ block->is_hashed = FALSE;
1238+ block->index = NULL;
1239++ block->btr_search_latch = NULL;
1240+
1241+ #if defined UNIV_AHI_DEBUG || defined UNIV_DEBUG
1242+ if (UNIV_UNLIKELY(block->n_pointers)) {
1243+@@ -1313,7 +1380,7 @@
1244+ }
1245+
1246+ //buf_pool_mutex_exit_all();
1247+- rw_lock_x_unlock(&btr_search_latch);
1248++ rw_lock_x_unlock(btr_search_get_latch(index->id));
1249+
1250+ if (UNIV_LIKELY_NULL(heap)) {
1251+ mem_heap_free(heap);
1252+@@ -1360,7 +1427,7 @@
1253+
1254+ buf_block_dbg_add_level(block, SYNC_TREE_NODE_FROM_HASH);
1255+
1256+- btr_search_drop_page_hash_index(block);
1257++ btr_search_drop_page_hash_index(block, NULL);
1258+ }
1259+
1260+ mtr_commit(&mtr);
1261+@@ -1402,26 +1469,26 @@
1262+ ut_ad(index);
1263+ ut_a(!dict_index_is_ibuf(index));
1264+
1265+- table = btr_search_sys->hash_index;
1266++ table = btr_search_get_hash_index(index->id);
1267+ page = buf_block_get_frame(block);
1268+
1269+ #ifdef UNIV_SYNC_DEBUG
1270+- ut_ad(!rw_lock_own(&btr_search_latch, RW_LOCK_EX));
1271++ ut_ad(!rw_lock_own(btr_search_get_latch(index->id), RW_LOCK_EX));
1272+ ut_ad(rw_lock_own(&(block->lock), RW_LOCK_SHARED)
1273+ || rw_lock_own(&(block->lock), RW_LOCK_EX));
1274+ #endif /* UNIV_SYNC_DEBUG */
1275+
1276+- rw_lock_s_lock(&btr_search_latch);
1277++ rw_lock_s_lock(btr_search_get_latch(index->id));
1278+
1279+ if (block->is_hashed && ((block->curr_n_fields != n_fields)
1280+ || (block->curr_n_bytes != n_bytes)
1281+ || (block->curr_left_side != left_side))) {
1282+
1283+- rw_lock_s_unlock(&btr_search_latch);
1284++ rw_lock_s_unlock(btr_search_get_latch(index->id));
1285+
1286+- btr_search_drop_page_hash_index(block);
1287++ btr_search_drop_page_hash_index(block, index);
1288+ } else {
1289+- rw_lock_s_unlock(&btr_search_latch);
1290++ rw_lock_s_unlock(btr_search_get_latch(index->id));
1291+ }
1292+
1293+ n_recs = page_get_n_recs(page);
1294+@@ -1515,9 +1582,9 @@
1295+ fold = next_fold;
1296+ }
1297+
1298+- btr_search_check_free_space_in_heap();
1299++ btr_search_check_free_space_in_heap(index->id);
1300+
1301+- rw_lock_x_lock(&btr_search_latch);
1302++ rw_lock_x_lock(btr_search_get_latch(index->id));
1303+
1304+ if (UNIV_UNLIKELY(btr_search_fully_disabled)) {
1305+ goto exit_func;
1306+@@ -1545,6 +1612,7 @@
1307+ block->curr_n_bytes = n_bytes;
1308+ block->curr_left_side = left_side;
1309+ block->index = index;
1310++ block->btr_search_latch = btr_search_get_latch(index->id);
1311+
1312+ for (i = 0; i < n_cached; i++) {
1313+
1314+@@ -1552,7 +1620,7 @@
1315+ }
1316+
1317+ exit_func:
1318+- rw_lock_x_unlock(&btr_search_latch);
1319++ rw_lock_x_unlock(btr_search_get_latch(index->id));
1320+
1321+ mem_free(folds);
1322+ mem_free(recs);
1323+@@ -1591,13 +1659,13 @@
1324+ ut_a(!(new_block->is_hashed || block->is_hashed)
1325+ || !dict_index_is_ibuf(index));
1326+
1327+- rw_lock_s_lock(&btr_search_latch);
1328++ rw_lock_s_lock(btr_search_get_latch(index->id));
1329+
1330+ if (new_block->is_hashed) {
1331+
1332+- rw_lock_s_unlock(&btr_search_latch);
1333++ rw_lock_s_unlock(btr_search_get_latch(index->id));
1334+
1335+- btr_search_drop_page_hash_index(block);
1336++ btr_search_drop_page_hash_index(block, index);
1337+
1338+ return;
1339+ }
1340+@@ -1612,7 +1680,7 @@
1341+ new_block->n_bytes = block->curr_n_bytes;
1342+ new_block->left_side = left_side;
1343+
1344+- rw_lock_s_unlock(&btr_search_latch);
1345++ rw_lock_s_unlock(btr_search_get_latch(index->id));
1346+
1347+ ut_a(n_fields + n_bytes > 0);
1348+
1349+@@ -1624,7 +1692,7 @@
1350+ return;
1351+ }
1352+
1353+- rw_lock_s_unlock(&btr_search_latch);
1354++ rw_lock_s_unlock(btr_search_get_latch(index->id));
1355+ }
1356+
1357+ /********************************************************************//**
1358+@@ -1663,7 +1731,7 @@
1359+ ut_a(block->curr_n_fields + block->curr_n_bytes > 0);
1360+ ut_a(!dict_index_is_ibuf(cursor->index));
1361+
1362+- table = btr_search_sys->hash_index;
1363++ table = btr_search_get_hash_index(cursor->index->id);
1364+
1365+ index_id = cursor->index->id;
1366+ fold = rec_fold(rec, rec_get_offsets(rec, cursor->index, offsets_,
1367+@@ -1672,11 +1740,11 @@
1368+ if (UNIV_LIKELY_NULL(heap)) {
1369+ mem_heap_free(heap);
1370+ }
1371+- rw_lock_x_lock(&btr_search_latch);
1372++ rw_lock_x_lock(btr_search_get_latch(cursor->index->id));
1373+
1374+ ha_search_and_delete_if_found(table, fold, rec);
1375+
1376+- rw_lock_x_unlock(&btr_search_latch);
1377++ rw_lock_x_unlock(btr_search_get_latch(cursor->index->id));
1378+ }
1379+
1380+ /********************************************************************//**
1381+@@ -1710,21 +1778,21 @@
1382+ ut_a(block->index == cursor->index);
1383+ ut_a(!dict_index_is_ibuf(cursor->index));
1384+
1385+- rw_lock_x_lock(&btr_search_latch);
1386++ rw_lock_x_lock(btr_search_get_latch(cursor->index->id));
1387+
1388+ if ((cursor->flag == BTR_CUR_HASH)
1389+ && (cursor->n_fields == block->curr_n_fields)
1390+ && (cursor->n_bytes == block->curr_n_bytes)
1391+ && !block->curr_left_side) {
1392+
1393+- table = btr_search_sys->hash_index;
1394++ table = btr_search_get_hash_index(cursor->index->id);
1395+
1396+ ha_search_and_update_if_found(table, cursor->fold, rec,
1397+ block, page_rec_get_next(rec));
1398+
1399+- rw_lock_x_unlock(&btr_search_latch);
1400++ rw_lock_x_unlock(btr_search_get_latch(cursor->index->id));
1401+ } else {
1402+- rw_lock_x_unlock(&btr_search_latch);
1403++ rw_lock_x_unlock(btr_search_get_latch(cursor->index->id));
1404+
1405+ btr_search_update_hash_on_insert(cursor);
1406+ }
1407+@@ -1759,9 +1827,9 @@
1408+ ulint* offsets = offsets_;
1409+ rec_offs_init(offsets_);
1410+
1411+- table = btr_search_sys->hash_index;
1412++ table = btr_search_get_hash_index(cursor->index->id);
1413+
1414+- btr_search_check_free_space_in_heap();
1415++ btr_search_check_free_space_in_heap(cursor->index->id);
1416+
1417+ rec = btr_cur_get_rec(cursor);
1418+
1419+@@ -1806,7 +1874,7 @@
1420+ } else {
1421+ if (left_side) {
1422+
1423+- rw_lock_x_lock(&btr_search_latch);
1424++ rw_lock_x_lock(btr_search_get_latch(index_id));
1425+
1426+ locked = TRUE;
1427+
1428+@@ -1820,7 +1888,7 @@
1429+
1430+ if (!locked) {
1431+
1432+- rw_lock_x_lock(&btr_search_latch);
1433++ rw_lock_x_lock(btr_search_get_latch(index_id));
1434+
1435+ locked = TRUE;
1436+ }
1437+@@ -1838,7 +1906,7 @@
1438+ if (!left_side) {
1439+
1440+ if (!locked) {
1441+- rw_lock_x_lock(&btr_search_latch);
1442++ rw_lock_x_lock(btr_search_get_latch(index_id));
1443+
1444+ locked = TRUE;
1445+ }
1446+@@ -1853,7 +1921,7 @@
1447+
1448+ if (!locked) {
1449+
1450+- rw_lock_x_lock(&btr_search_latch);
1451++ rw_lock_x_lock(btr_search_get_latch(index_id));
1452+
1453+ locked = TRUE;
1454+ }
1455+@@ -1876,7 +1944,7 @@
1456+ mem_heap_free(heap);
1457+ }
1458+ if (locked) {
1459+- rw_lock_x_unlock(&btr_search_latch);
1460++ rw_lock_x_unlock(btr_search_get_latch(index_id));
1461+ }
1462+ }
1463+
1464+@@ -1892,7 +1960,7 @@
1465+ ha_node_t* node;
1466+ ulint n_page_dumps = 0;
1467+ ibool ok = TRUE;
1468+- ulint i;
1469++ ulint i,j;
1470+ ulint cell_count;
1471+ mem_heap_t* heap = NULL;
1472+ ulint offsets_[REC_OFFS_NORMAL_SIZE];
1473+@@ -1904,23 +1972,25 @@
1474+
1475+ rec_offs_init(offsets_);
1476+
1477+- rw_lock_x_lock(&btr_search_latch);
1478++ btr_search_x_lock_all();
1479+ buf_pool_page_hash_x_lock_all();
1480+
1481+- cell_count = hash_get_n_cells(btr_search_sys->hash_index);
1482++ for (j = 0; j < btr_search_index_num; j++) {
1483++
1484++ cell_count = hash_get_n_cells(btr_search_sys->hash_index[j]);
1485+
1486+ for (i = 0; i < cell_count; i++) {
1487+ /* We release btr_search_latch every once in a while to
1488+ give other queries a chance to run. */
1489+ if ((i != 0) && ((i % chunk_size) == 0)) {
1490+ buf_pool_page_hash_x_unlock_all();
1491+- rw_lock_x_unlock(&btr_search_latch);
1492++ btr_search_x_unlock_all();
1493+ os_thread_yield();
1494+- rw_lock_x_lock(&btr_search_latch);
1495++ btr_search_x_lock_all();
1496+ buf_pool_page_hash_x_lock_all();
1497+ }
1498+
1499+- node = hash_get_nth_cell(btr_search_sys->hash_index, i)->node;
1500++ node = hash_get_nth_cell(btr_search_sys->hash_index[j], i)->node;
1501+
1502+ for (; node != NULL; node = node->next) {
1503+ const buf_block_t* block
1504+@@ -2029,19 +2099,21 @@
1505+ give other queries a chance to run. */
1506+ if (i != 0) {
1507+ buf_pool_page_hash_x_unlock_all();
1508+- rw_lock_x_unlock(&btr_search_latch);
1509++ btr_search_x_unlock_all();
1510+ os_thread_yield();
1511+- rw_lock_x_lock(&btr_search_latch);
1512++ btr_search_x_lock_all();
1513+ buf_pool_page_hash_x_lock_all();
1514+ }
1515+
1516+- if (!ha_validate(btr_search_sys->hash_index, i, end_index)) {
1517++ if (!ha_validate(btr_search_sys->hash_index[j], i, end_index)) {
1518+ ok = FALSE;
1519+ }
1520+ }
1521+
1522++ } /*for (j = 0; j < btr_search_index_num; j++)*/
1523++
1524+ buf_pool_page_hash_x_unlock_all();
1525+- rw_lock_x_unlock(&btr_search_latch);
1526++ btr_search_x_unlock_all();
1527+ if (UNIV_LIKELY_NULL(heap)) {
1528+ mem_heap_free(heap);
1529+ }
1530+diff -ruN a/storage/innobase/buf/buf0buf.c b/storage/innobase/buf/buf0buf.c
1531+--- a/storage/innobase/buf/buf0buf.c 2010-12-04 15:55:21.351597052 +0900
1532++++ b/storage/innobase/buf/buf0buf.c 2010-12-04 16:12:48.654550708 +0900
1533+@@ -949,6 +949,7 @@
1534+
1535+ block->check_index_page_at_flush = FALSE;
1536+ block->index = NULL;
1537++ block->btr_search_latch = NULL;
1538+
1539+ block->is_hashed = FALSE;
1540+
1541+@@ -1477,7 +1478,7 @@
1542+ /* To follow the latching order, we
1543+ have to release btr_search_latch
1544+ before acquiring block->latch. */
1545+- rw_lock_x_unlock(&btr_search_latch);
1546++ btr_search_x_unlock_all();
1547+ /* When we release the search latch,
1548+ we must rescan all blocks, because
1549+ some may become hashed again. */
1550+@@ -1508,11 +1509,11 @@
1551+ anything. block->is_hashed can only
1552+ be set on uncompressed file pages. */
1553+
1554+- btr_search_drop_page_hash_index(block);
1555++ btr_search_drop_page_hash_index(block, NULL);
1556+
1557+ rw_lock_x_unlock(&block->lock);
1558+
1559+- rw_lock_x_lock(&btr_search_latch);
1560++ btr_search_x_lock_all();
1561+
1562+ ut_ad(!btr_search_enabled);
1563+ }
1564+@@ -1531,7 +1532,11 @@
1565+ ibool released_search_latch;
1566+
1567+ #ifdef UNIV_SYNC_DEBUG
1568+- ut_ad(rw_lock_own(&btr_search_latch, RW_LOCK_EX));
1569++ ulint j;
1570++
1571++ for (j = 0; j < btr_search_index_num; j++) {
1572++ ut_ad(rw_lock_own(btr_search_latch_part[j], RW_LOCK_EX));
1573++ }
1574+ #endif /* UNIV_SYNC_DEBUG */
1575+ ut_ad(!btr_search_enabled);
1576+
1577+@@ -2635,6 +2640,7 @@
1578+ {
1579+ block->check_index_page_at_flush = FALSE;
1580+ block->index = NULL;
1581++ block->btr_search_latch = NULL;
1582+
1583+ block->n_hash_helps = 0;
1584+ block->is_hashed = FALSE;
1585+diff -ruN a/storage/innobase/buf/buf0lru.c b/storage/innobase/buf/buf0lru.c
1586+--- a/storage/innobase/buf/buf0lru.c 2010-12-04 15:35:29.137347521 +0900
1587++++ b/storage/innobase/buf/buf0lru.c 2010-12-04 16:12:48.658550840 +0900
1588+@@ -1775,7 +1775,7 @@
1589+
1590+ UNIV_MEM_VALID(((buf_block_t*) bpage)->frame,
1591+ UNIV_PAGE_SIZE);
1592+- btr_search_drop_page_hash_index((buf_block_t*) bpage);
1593++ btr_search_drop_page_hash_index((buf_block_t*) bpage, NULL);
1594+ UNIV_MEM_INVALID(((buf_block_t*) bpage)->frame,
1595+ UNIV_PAGE_SIZE);
1596+
1597+diff -ruN a/storage/innobase/dict/dict0dict.c b/storage/innobase/dict/dict0dict.c
1598+--- a/storage/innobase/dict/dict0dict.c 2010-12-04 15:52:23.398513916 +0900
1599++++ b/storage/innobase/dict/dict0dict.c 2010-12-04 16:12:48.662550715 +0900
1600+@@ -1802,7 +1802,7 @@
1601+ zero. */
1602+
1603+ for (;;) {
1604+- ulint ref_count = btr_search_info_get_ref_count(info);
1605++ ulint ref_count = btr_search_info_get_ref_count(info, index->id);
1606+ if (ref_count == 0) {
1607+ break;
1608+ }
1609+diff -ruN a/storage/innobase/ha/ha0ha.c b/storage/innobase/ha/ha0ha.c
1610+--- a/storage/innobase/ha/ha0ha.c 2010-11-03 07:01:13.000000000 +0900
1611++++ b/storage/innobase/ha/ha0ha.c 2010-12-04 16:12:48.665593752 +0900
1612+@@ -102,7 +102,8 @@
1613+ ut_ad(table);
1614+ ut_ad(table->magic_n == HASH_TABLE_MAGIC_N);
1615+ #ifdef UNIV_SYNC_DEBUG
1616+- ut_ad(rw_lock_own(&btr_search_latch, RW_LOCK_EXCLUSIVE));
1617++ /* cannot identificate which btr_search_latch[i] for now */
1618++ //ut_ad(rw_lock_own(&btr_search_latch, RW_LOCK_EXCLUSIVE));
1619+ #endif /* UNIV_SYNC_DEBUG */
1620+
1621+ #ifndef UNIV_HOTBACKUP
1622+diff -ruN a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc
1623+--- a/storage/innobase/handler/ha_innodb.cc 2010-12-04 16:12:20.185850734 +0900
1624++++ b/storage/innobase/handler/ha_innodb.cc 2010-12-04 16:12:48.674552412 +0900
1625+@@ -11603,6 +11603,11 @@
1626+ "Disable with --skip-innodb-adaptive-hash-index.",
1627+ NULL, innodb_adaptive_hash_index_update, TRUE);
1628+
1629++static MYSQL_SYSVAR_ULONG(adaptive_hash_index_partitions, btr_search_index_num,
1630++ PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY,
1631++ "Number of InnoDB adaptive hash index partitions (default 1: disable partitioning)",
1632++ NULL, NULL, 1, 1, 32, 0);
1633++
1634+ static MYSQL_SYSVAR_ULONG(replication_delay, srv_replication_delay,
1635+ PLUGIN_VAR_RQCMDARG,
1636+ "Replication thread delay (ms) on the slave server if "
1637+@@ -11956,6 +11961,7 @@
1638+ MYSQL_SYSVAR(use_sys_stats_table),
1639+ MYSQL_SYSVAR(stats_sample_pages),
1640+ MYSQL_SYSVAR(adaptive_hash_index),
1641++ MYSQL_SYSVAR(adaptive_hash_index_partitions),
1642+ MYSQL_SYSVAR(replication_delay),
1643+ MYSQL_SYSVAR(status_file),
1644+ MYSQL_SYSVAR(strict_mode),
1645+diff -ruN a/storage/innobase/include/btr0sea.h b/storage/innobase/include/btr0sea.h
1646+--- a/storage/innobase/include/btr0sea.h 2010-12-03 15:48:03.070987226 +0900
1647++++ b/storage/innobase/include/btr0sea.h 2010-12-04 16:12:48.707551382 +0900
1648+@@ -85,7 +85,8 @@
1649+ ulint
1650+ btr_search_info_get_ref_count(
1651+ /*==========================*/
1652+- btr_search_t* info); /*!< in: search info. */
1653++ btr_search_t* info, /*!< in: search info. */
1654++ index_id_t key);
1655+ /*********************************************************************//**
1656+ Updates the search info. */
1657+ UNIV_INLINE
1658+@@ -136,10 +137,11 @@
1659+ void
1660+ btr_search_drop_page_hash_index(
1661+ /*============================*/
1662+- buf_block_t* block); /*!< in: block containing index page,
1663++ buf_block_t* block, /*!< in: block containing index page,
1664+ s- or x-latched, or an index page
1665+ for which we know that
1666+ block->buf_fix_count == 0 */
1667++ dict_index_t* index_in);
1668+ /************************************************************************
1669+ Drops a page hash index based on index */
1670+ UNIV_INTERN
1671+@@ -199,10 +201,47 @@
1672+ # define btr_search_validate() TRUE
1673+ #endif /* defined UNIV_AHI_DEBUG || defined UNIV_DEBUG */
1674+
1675++/********************************************************************//**
1676++New functions to control split btr_search_index */
1677++UNIV_INLINE
1678++hash_table_t*
1679++btr_search_get_hash_index(
1680++/*======================*/
1681++ index_id_t key);
1682++
1683++UNIV_INLINE
1684++rw_lock_t*
1685++btr_search_get_latch(
1686++/*=================*/
1687++ index_id_t key);
1688++
1689++UNIV_INLINE
1690++void
1691++btr_search_x_lock_all(void);
1692++/*========================*/
1693++
1694++UNIV_INLINE
1695++void
1696++btr_search_x_unlock_all(void);
1697++/*==========================*/
1698++
1699++UNIV_INLINE
1700++void
1701++btr_search_s_lock_all(void);
1702++/*========================*/
1703++
1704++UNIV_INLINE
1705++void
1706++btr_search_s_unlock_all(void);
1707++/*==========================*/
1708++
1709++
1710+ /** Flag: has the search system been enabled?
1711+ Protected by btr_search_latch and btr_search_enabled_mutex. */
1712+ extern char btr_search_enabled;
1713+
1714++extern ulint btr_search_index_num;
1715++
1716+ /** Flag: whether the search system has completed its disabling process,
1717+ It is set to TRUE right after buf_pool_drop_hash_index() in
1718+ btr_search_disable(), indicating hash index entries are cleaned up.
1719+@@ -269,7 +308,7 @@
1720+
1721+ /** The hash index system */
1722+ struct btr_search_sys_struct{
1723+- hash_table_t* hash_index; /*!< the adaptive hash index,
1724++ hash_table_t** hash_index; /*!< the adaptive hash index,
1725+ mapping dtuple_fold values
1726+ to rec_t pointers on index pages */
1727+ };
1728+@@ -290,10 +329,12 @@
1729+
1730+ Bear in mind (3) and (4) when using the hash index.
1731+ */
1732+-extern rw_lock_t* btr_search_latch_temp;
1733++//extern rw_lock_t* btr_search_latch_temp;
1734++
1735++extern rw_lock_t** btr_search_latch_part;
1736+
1737+ /** The latch protecting the adaptive search system */
1738+-#define btr_search_latch (*btr_search_latch_temp)
1739++//#define btr_search_latch (*btr_search_latch_temp)
1740+
1741+ #ifdef UNIV_SEARCH_PERF_STAT
1742+ /** Number of successful adaptive hash index lookups */
1743+diff -ruN a/storage/innobase/include/btr0sea.ic b/storage/innobase/include/btr0sea.ic
1744+--- a/storage/innobase/include/btr0sea.ic 2010-11-03 07:01:13.000000000 +0900
1745++++ b/storage/innobase/include/btr0sea.ic 2010-12-04 16:12:48.709511202 +0900
1746+@@ -62,8 +62,8 @@
1747+ btr_search_t* info;
1748+
1749+ #ifdef UNIV_SYNC_DEBUG
1750+- ut_ad(!rw_lock_own(&btr_search_latch, RW_LOCK_SHARED));
1751+- ut_ad(!rw_lock_own(&btr_search_latch, RW_LOCK_EX));
1752++ ut_ad(!rw_lock_own(btr_search_get_latch(index->id), RW_LOCK_SHARED));
1753++ ut_ad(!rw_lock_own(btr_search_get_latch(index->id), RW_LOCK_EX));
1754+ #endif /* UNIV_SYNC_DEBUG */
1755+
1756+ info = btr_search_get_info(index);
1757+@@ -82,3 +82,72 @@
1758+
1759+ btr_search_info_update_slow(info, cursor);
1760+ }
1761++
1762++/*********************************************************************//**
1763++New functions to control split btr_search_index */
1764++UNIV_INLINE
1765++hash_table_t*
1766++btr_search_get_hash_index(
1767++/*======================*/
1768++ index_id_t key)
1769++{
1770++ return(btr_search_sys->hash_index[key % btr_search_index_num]);
1771++}
1772++
1773++UNIV_INLINE
1774++rw_lock_t*
1775++btr_search_get_latch(
1776++/*=================*/
1777++ index_id_t key)
1778++{
1779++ return(btr_search_latch_part[key % btr_search_index_num]);
1780++}
1781++
1782++UNIV_INLINE
1783++void
1784++btr_search_x_lock_all(void)
1785++/*=======================*/
1786++{
1787++ ulint i;
1788++
1789++ for (i = 0; i < btr_search_index_num; i++) {
1790++ rw_lock_x_lock(btr_search_latch_part[i]);
1791++ }
1792++}
1793++
1794++UNIV_INLINE
1795++void
1796++btr_search_x_unlock_all(void)
1797++/*==========================*/
1798++{
1799++ ulint i;
1800++
1801++ for (i = 0; i < btr_search_index_num; i++) {
1802++ rw_lock_x_unlock(btr_search_latch_part[i]);
1803++ }
1804++}
1805++
1806++UNIV_INLINE
1807++void
1808++btr_search_s_lock_all(void)
1809++/*=======================*/
1810++{
1811++ ulint i;
1812++
1813++ for (i = 0; i < btr_search_index_num; i++) {
1814++ rw_lock_s_lock(btr_search_latch_part[i]);
1815++ }
1816++}
1817++
1818++UNIV_INLINE
1819++void
1820++btr_search_s_unlock_all(void)
1821++/*=========================*/
1822++{
1823++ ulint i;
1824++
1825++ for (i = 0; i < btr_search_index_num; i++) {
1826++ rw_lock_s_unlock(btr_search_latch_part[i]);
1827++ }
1828++}
1829++
1830+diff -ruN a/storage/innobase/include/buf0buf.h b/storage/innobase/include/buf0buf.h
1831+--- a/storage/innobase/include/buf0buf.h 2010-12-15 19:00:07.713604580 +0900
1832++++ b/storage/innobase/include/buf0buf.h 2010-12-15 20:58:03.546839883 +0900
1833+@@ -1473,7 +1473,7 @@
1834+ pointers in the adaptive hash index
1835+ pointing to this frame */
1836+ #endif /* UNIV_AHI_DEBUG || UNIV_DEBUG */
1837+- unsigned is_hashed:1; /*!< TRUE if hash index has
1838++ volatile unsigned is_hashed:1; /*!< TRUE if hash index has
1839+ already been built on this
1840+ page; note that it does not
1841+ guarantee that the index is
1842+@@ -1487,6 +1487,7 @@
1843+ unsigned curr_left_side:1;/*!< TRUE or FALSE in hash indexing */
1844+ dict_index_t* index; /*!< Index for which the adaptive
1845+ hash index has been created. */
1846++ volatile rw_lock_t* btr_search_latch;
1847+ /* @} */
1848+ # ifdef UNIV_SYNC_DEBUG
1849+ /** @name Debug fields */
1850+diff -ruN a/storage/innobase/include/row0upd.ic b/storage/innobase/include/row0upd.ic
1851+--- a/storage/innobase/include/row0upd.ic 2010-11-03 07:01:13.000000000 +0900
1852++++ b/storage/innobase/include/row0upd.ic 2010-12-04 16:12:48.710551113 +0900
1853+@@ -158,7 +158,7 @@
1854+ ut_ad(dict_index_is_clust(index));
1855+ ut_ad(rec_offs_validate(rec, index, offsets));
1856+ #ifdef UNIV_SYNC_DEBUG
1857+- if (!rw_lock_own(&btr_search_latch, RW_LOCK_EX)) {
1858++ if (!rw_lock_own(btr_search_get_latch(index->id), RW_LOCK_EX)) {
1859+ ut_ad(!buf_block_align(rec)->is_hashed);
1860+ }
1861+ #endif /* UNIV_SYNC_DEBUG */
1862+diff -ruN a/storage/innobase/page/page0page.c b/storage/innobase/page/page0page.c
1863+--- a/storage/innobase/page/page0page.c 2010-11-03 07:01:13.000000000 +0900
1864++++ b/storage/innobase/page/page0page.c 2010-12-04 16:12:48.712550963 +0900
1865+@@ -218,7 +218,7 @@
1866+ const ibool is_hashed = block->is_hashed;
1867+
1868+ if (is_hashed) {
1869+- rw_lock_x_lock(&btr_search_latch);
1870++ rw_lock_x_lock(btr_search_get_latch(block->index->id));
1871+ }
1872+
1873+ ut_ad(!mtr || mtr_memo_contains(mtr, block, MTR_MEMO_PAGE_X_FIX));
1874+@@ -244,7 +244,7 @@
1875+
1876+ #ifndef UNIV_HOTBACKUP
1877+ if (is_hashed) {
1878+- rw_lock_x_unlock(&btr_search_latch);
1879++ rw_lock_x_unlock(btr_search_get_latch(block->index->id));
1880+ }
1881+ #endif /* !UNIV_HOTBACKUP */
1882+ }
1883+diff -ruN a/storage/innobase/page/page0zip.c b/storage/innobase/page/page0zip.c
1884+--- a/storage/innobase/page/page0zip.c 2010-12-04 15:57:13.061494433 +0900
1885++++ b/storage/innobase/page/page0zip.c 2010-12-04 16:12:48.716470334 +0900
1886+@@ -4445,7 +4445,7 @@
1887+
1888+ #ifndef UNIV_HOTBACKUP
1889+ temp_block = buf_block_alloc(buf_pool, 0);
1890+- btr_search_drop_page_hash_index(block);
1891++ btr_search_drop_page_hash_index(block, index);
1892+ block->check_index_page_at_flush = TRUE;
1893+ #else /* !UNIV_HOTBACKUP */
1894+ ut_ad(block == back_block1);
1895+diff -ruN a/storage/innobase/row/row0sel.c b/storage/innobase/row/row0sel.c
1896+--- a/storage/innobase/row/row0sel.c 2010-12-04 16:09:53.204513572 +0900
1897++++ b/storage/innobase/row/row0sel.c 2010-12-04 16:12:48.722551273 +0900
1898+@@ -1210,7 +1210,7 @@
1899+ ut_ad(plan->unique_search);
1900+ ut_ad(!plan->must_get_clust);
1901+ #ifdef UNIV_SYNC_DEBUG
1902+- ut_ad(rw_lock_own(&btr_search_latch, RW_LOCK_SHARED));
1903++ ut_ad(rw_lock_own(btr_search_get_latch(index->id), RW_LOCK_SHARED));
1904+ #endif /* UNIV_SYNC_DEBUG */
1905+
1906+ row_sel_open_pcur(plan, TRUE, mtr);
1907+@@ -1381,10 +1381,10 @@
1908+ && !plan->must_get_clust
1909+ && !plan->table->big_rows) {
1910+ if (!search_latch_locked) {
1911+- rw_lock_s_lock(&btr_search_latch);
1912++ rw_lock_s_lock(btr_search_get_latch(index->id));
1913+
1914+ search_latch_locked = TRUE;
1915+- } else if (rw_lock_get_writer(&btr_search_latch) == RW_LOCK_WAIT_EX) {
1916++ } else if (rw_lock_get_writer(btr_search_get_latch(index->id)) == RW_LOCK_WAIT_EX) {
1917+
1918+ /* There is an x-latch request waiting: release the
1919+ s-latch for a moment; as an s-latch here is often
1920+@@ -1393,8 +1393,8 @@
1921+ from acquiring an s-latch for a long time, lowering
1922+ performance significantly in multiprocessors. */
1923+
1924+- rw_lock_s_unlock(&btr_search_latch);
1925+- rw_lock_s_lock(&btr_search_latch);
1926++ rw_lock_s_unlock(btr_search_get_latch(index->id));
1927++ rw_lock_s_lock(btr_search_get_latch(index->id));
1928+ }
1929+
1930+ found_flag = row_sel_try_search_shortcut(node, plan, &mtr);
1931+@@ -1417,7 +1417,7 @@
1932+ }
1933+
1934+ if (search_latch_locked) {
1935+- rw_lock_s_unlock(&btr_search_latch);
1936++ rw_lock_s_unlock(btr_search_get_latch(index->id));
1937+
1938+ search_latch_locked = FALSE;
1939+ }
1940+@@ -1993,7 +1993,7 @@
1941+
1942+ func_exit:
1943+ if (search_latch_locked) {
1944+- rw_lock_s_unlock(&btr_search_latch);
1945++ rw_lock_s_unlock(btr_search_get_latch(index->id));
1946+ }
1947+ if (UNIV_LIKELY_NULL(heap)) {
1948+ mem_heap_free(heap);
1949+@@ -3356,6 +3356,8 @@
1950+ /* if the returned record was locked and we did a semi-consistent
1951+ read (fetch the newest committed version), then this is set to
1952+ TRUE */
1953++ ulint i;
1954++ ulint should_release;
1955+ #ifdef UNIV_SEARCH_DEBUG
1956+ ulint cnt = 0;
1957+ #endif /* UNIV_SEARCH_DEBUG */
1958+@@ -3441,18 +3443,32 @@
1959+ /* PHASE 0: Release a possible s-latch we are holding on the
1960+ adaptive hash index latch if there is someone waiting behind */
1961+
1962+- if (UNIV_UNLIKELY(rw_lock_get_writer(&btr_search_latch) != RW_LOCK_NOT_LOCKED)
1963+- && trx->has_search_latch) {
1964++ should_release = 0;
1965++ for (i = 0; i < btr_search_index_num; i++) {
1966++ if ((trx->has_search_latch & ((ulint)1 << i))
1967++ && rw_lock_get_writer(btr_search_latch_part[i])
1968++ != RW_LOCK_NOT_LOCKED) {
1969++ should_release |= ((ulint)1 << i);
1970++ }
1971++ }
1972++
1973++ if (should_release) {
1974+
1975+ /* There is an x-latch request on the adaptive hash index:
1976+ release the s-latch to reduce starvation and wait for
1977+ BTR_SEA_TIMEOUT rounds before trying to keep it again over
1978+ calls from MySQL */
1979+
1980+- rw_lock_s_unlock(&btr_search_latch);
1981+- trx->has_search_latch = FALSE;
1982++ for (i = 0; i < btr_search_index_num; i++) {
1983++ if (should_release & ((ulint)1 << i)) {
1984++ rw_lock_s_unlock(btr_search_latch_part[i]);
1985++ trx->has_search_latch &= ~((ulint)1 << i);
1986++ }
1987++ }
1988+
1989++ if (!trx->has_search_latch) {
1990+ trx->search_latch_timeout = BTR_SEA_TIMEOUT;
1991++ }
1992+ }
1993+
1994+ /* Reset the new record lock info if srv_locks_unsafe_for_binlog
1995+@@ -3603,9 +3619,11 @@
1996+ hash index semaphore! */
1997+
1998+ #ifndef UNIV_SEARCH_DEBUG
1999+- if (!trx->has_search_latch) {
2000+- rw_lock_s_lock(&btr_search_latch);
2001+- trx->has_search_latch = TRUE;
2002++ if (!(trx->has_search_latch
2003++ & ((ulint)1 << (index->id % btr_search_index_num)))) {
2004++ rw_lock_s_lock(btr_search_get_latch(index->id));
2005++ trx->has_search_latch |=
2006++ (ulint)1 << (index->id % btr_search_index_num);
2007+ }
2008+ #endif
2009+ switch (row_sel_try_search_shortcut_for_mysql(
2010+@@ -3666,7 +3684,11 @@
2011+
2012+ trx->search_latch_timeout--;
2013+
2014+- rw_lock_s_unlock(&btr_search_latch);
2015++ for (i = 0; i < btr_search_index_num; i++) {
2016++ if (trx->has_search_latch & ((ulint)1 << i)) {
2017++ rw_lock_s_unlock(btr_search_latch_part[i]);
2018++ }
2019++ }
2020+ trx->has_search_latch = FALSE;
2021+ }
2022+
2023+@@ -3690,7 +3712,12 @@
2024+ /* PHASE 3: Open or restore index cursor position */
2025+
2026+ if (trx->has_search_latch) {
2027+- rw_lock_s_unlock(&btr_search_latch);
2028++
2029++ for (i = 0; i < btr_search_index_num; i++) {
2030++ if (trx->has_search_latch & ((ulint)1 << i)) {
2031++ rw_lock_s_unlock(btr_search_latch_part[i]);
2032++ }
2033++ }
2034+ trx->has_search_latch = FALSE;
2035+ }
2036+
2037+diff -ruN a/storage/innobase/srv/srv0srv.c b/storage/innobase/srv/srv0srv.c
2038+--- a/storage/innobase/srv/srv0srv.c 2010-12-04 16:12:20.231484679 +0900
2039++++ b/storage/innobase/srv/srv0srv.c 2010-12-04 16:12:48.726551018 +0900
2040+@@ -2005,7 +2005,9 @@
2041+ "-------------------------------------\n", file);
2042+ ibuf_print(file);
2043+
2044+- ha_print_info(file, btr_search_sys->hash_index);
2045++ for (i = 0; i < btr_search_index_num; i++) {
2046++ ha_print_info(file, btr_search_get_hash_index((index_id_t)i));
2047++ }
2048+
2049+ fprintf(file,
2050+ "%.2f hash searches/s, %.2f non-hash searches/s\n",
2051+@@ -2030,14 +2032,15 @@
2052+ ut_total_allocated_memory,
2053+ mem_pool_get_reserved(mem_comm_pool));
2054+ /* Calcurate reserved memories */
2055+- if (btr_search_sys && btr_search_sys->hash_index->heap) {
2056+- btr_search_sys_subtotal = mem_heap_get_size(btr_search_sys->hash_index->heap);
2057++ if (btr_search_sys && btr_search_sys->hash_index[0]->heap) {
2058++ btr_search_sys_subtotal = mem_heap_get_size(btr_search_sys->hash_index[0]->heap);
2059+ } else {
2060+ btr_search_sys_subtotal = 0;
2061+- for (i=0; i < btr_search_sys->hash_index->n_mutexes; i++) {
2062+- btr_search_sys_subtotal += mem_heap_get_size(btr_search_sys->hash_index->heaps[i]);
2063++ for (i=0; i < btr_search_sys->hash_index[0]->n_mutexes; i++) {
2064++ btr_search_sys_subtotal += mem_heap_get_size(btr_search_sys->hash_index[0]->heaps[i]);
2065+ }
2066+ }
2067++ btr_search_sys_subtotal *= btr_search_index_num;
2068+
2069+ lock_sys_subtotal = 0;
2070+ if (trx_sys) {
2071+@@ -2064,10 +2067,10 @@
2072+ " Threads %lu \t(%lu + %lu)\n",
2073+
2074+ (ulong) (btr_search_sys
2075+- ? (btr_search_sys->hash_index->n_cells * sizeof(hash_cell_t)) : 0)
2076++ ? (btr_search_sys->hash_index[0]->n_cells * btr_search_index_num * sizeof(hash_cell_t)) : 0)
2077+ + btr_search_sys_subtotal,
2078+ (ulong) (btr_search_sys
2079+- ? (btr_search_sys->hash_index->n_cells * sizeof(hash_cell_t)) : 0),
2080++ ? (btr_search_sys->hash_index[0]->n_cells * btr_search_index_num * sizeof(hash_cell_t)) : 0),
2081+ (ulong) btr_search_sys_subtotal,
2082+
2083+ (ulong) (buf_pool_from_array(0)->page_hash->n_cells * sizeof(hash_cell_t)),
2084+diff -ruN a/storage/innobase/sync/sync0sync.c b/storage/innobase/sync/sync0sync.c
2085+--- a/storage/innobase/sync/sync0sync.c 2010-12-03 17:36:44.300986571 +0900
2086++++ b/storage/innobase/sync/sync0sync.c 2010-12-04 16:12:48.729513564 +0900
2087+@@ -1183,7 +1183,6 @@
2088+ case SYNC_ANY_LATCH:
2089+ case SYNC_FILE_FORMAT_TAG:
2090+ case SYNC_DOUBLEWRITE:
2091+- case SYNC_SEARCH_SYS:
2092+ case SYNC_SEARCH_SYS_CONF:
2093+ case SYNC_TRX_LOCK_HEAP:
2094+ case SYNC_KERNEL:
2095+@@ -1204,6 +1203,7 @@
2096+ ut_error;
2097+ }
2098+ break;
2099++ case SYNC_SEARCH_SYS:
2100+ case SYNC_BUF_LRU_LIST:
2101+ case SYNC_BUF_FLUSH_LIST:
2102+ case SYNC_BUF_PAGE_HASH:
2103+diff -ruN a/storage/innobase/trx/trx0trx.c b/storage/innobase/trx/trx0trx.c
2104+--- a/storage/innobase/trx/trx0trx.c 2010-12-03 17:49:11.623953784 +0900
2105++++ b/storage/innobase/trx/trx0trx.c 2010-12-04 16:12:48.731513275 +0900
2106+@@ -268,8 +268,14 @@
2107+ /*=================================*/
2108+ trx_t* trx) /*!< in: transaction */
2109+ {
2110++ ulint i;
2111++
2112+ if (trx->has_search_latch) {
2113+- rw_lock_s_unlock(&btr_search_latch);
2114++ for (i = 0; i < btr_search_index_num; i++) {
2115++ if (trx->has_search_latch & ((ulint)1 << i)) {
2116++ rw_lock_s_unlock(btr_search_latch_part[i]);
2117++ }
2118++ }
2119+
2120+ trx->has_search_latch = FALSE;
2121+ }
2122
2123=== added file 'innodb_admin_command_base.patch'
2124--- innodb_admin_command_base.patch 1970-01-01 00:00:00 +0000
2125+++ innodb_admin_command_base.patch 2011-01-10 13:15:57 +0000
2126@@ -0,0 +1,173 @@
2127+# name : innodb_admin_command_base.patch
2128+# introduced : 11 or before
2129+# maintainer : Yasufumi
2130+#
2131+#!!! notice !!!
2132+# Any small change to this file in the main branch
2133+# should be done or reviewed by the maintainer!
2134+diff -ruN a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc
2135+--- a/storage/innobase/handler/ha_innodb.cc 2010-12-03 17:32:15.624039043 +0900
2136++++ b/storage/innobase/handler/ha_innodb.cc 2010-12-03 17:32:35.424957827 +0900
2137+@@ -11769,7 +11769,8 @@
2138+ i_s_innodb_sys_foreign_cols,
2139+ i_s_innodb_sys_stats,
2140+ i_s_innodb_table_stats,
2141+-i_s_innodb_index_stats
2142++i_s_innodb_index_stats,
2143++i_s_innodb_admin_command
2144+ mysql_declare_plugin_end;
2145+
2146+ /** @brief Initialize the default value of innodb_commit_concurrency.
2147+diff -ruN a/storage/innobase/handler/i_s.cc b/storage/innobase/handler/i_s.cc
2148+--- a/storage/innobase/handler/i_s.cc 2010-12-03 17:30:16.299955549 +0900
2149++++ b/storage/innobase/handler/i_s.cc 2010-12-03 17:32:35.425989972 +0900
2150+@@ -4162,3 +4162,139 @@
2151+ STRUCT_FLD(system_vars, NULL),
2152+ STRUCT_FLD(__reserved1, NULL)
2153+ };
2154++
2155++/***********************************************************************
2156++*/
2157++static ST_FIELD_INFO i_s_innodb_admin_command_info[] =
2158++{
2159++ {STRUCT_FLD(field_name, "result_message"),
2160++ STRUCT_FLD(field_length, 1024),
2161++ STRUCT_FLD(field_type, MYSQL_TYPE_STRING),
2162++ STRUCT_FLD(value, 0),
2163++ STRUCT_FLD(field_flags, 0),
2164++ STRUCT_FLD(old_name, ""),
2165++ STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
2166++
2167++ END_OF_ST_FIELD_INFO
2168++};
2169++
2170++#ifndef INNODB_COMPATIBILITY_HOOKS
2171++#error InnoDB needs MySQL to be built with #define INNODB_COMPATIBILITY_HOOKS
2172++#endif
2173++
2174++extern "C" {
2175++char **thd_query(MYSQL_THD thd);
2176++}
2177++
2178++static
2179++int
2180++i_s_innodb_admin_command_fill(
2181++/*==========================*/
2182++ THD* thd,
2183++ TABLE_LIST* tables,
2184++ COND* cond)
2185++{
2186++ TABLE* i_s_table = (TABLE *) tables->table;
2187++ char** query_str;
2188++ char* ptr;
2189++ char quote = '\0';
2190++ const char* command_head = "XTRA_";
2191++
2192++ DBUG_ENTER("i_s_innodb_admin_command_fill");
2193++
2194++ /* deny access to non-superusers */
2195++ if (check_global_access(thd, PROCESS_ACL)) {
2196++ DBUG_RETURN(0);
2197++ }
2198++
2199++ if(thd_sql_command(thd) != SQLCOM_SELECT) {
2200++ field_store_string(i_s_table->field[0],
2201++ "SELECT command is only accepted.");
2202++ goto end_func;
2203++ }
2204++
2205++ query_str = thd_query(thd);
2206++ ptr = *query_str;
2207++
2208++ for (; *ptr; ptr++) {
2209++ if (*ptr == quote) {
2210++ quote = '\0';
2211++ } else if (quote) {
2212++ } else if (*ptr == '`' || *ptr == '"') {
2213++ quote = *ptr;
2214++ } else {
2215++ long i;
2216++ for (i = 0; command_head[i]; i++) {
2217++ if (toupper((int)(unsigned char)(ptr[i]))
2218++ != toupper((int)(unsigned char)
2219++ (command_head[i]))) {
2220++ goto nomatch;
2221++ }
2222++ }
2223++ break;
2224++nomatch:
2225++ ;
2226++ }
2227++ }
2228++
2229++ if (!*ptr) {
2230++ field_store_string(i_s_table->field[0],
2231++ "No XTRA_* command in the SQL statement."
2232++ " Please add /*!XTRA_xxxx*/ to the SQL.");
2233++ goto end_func;
2234++ }
2235++
2236++ if (!strncasecmp("XTRA_HELLO", ptr, 10)) {
2237++ /* This is example command XTRA_HELLO */
2238++
2239++ ut_print_timestamp(stderr);
2240++ fprintf(stderr, " InnoDB: administration command test for XtraDB"
2241++ " 'XTRA_HELLO' was detected.\n");
2242++
2243++ field_store_string(i_s_table->field[0],
2244++ "Hello!");
2245++ goto end_func;
2246++ }
2247++
2248++ field_store_string(i_s_table->field[0],
2249++ "Undefined XTRA_* command.");
2250++ goto end_func;
2251++
2252++end_func:
2253++ if (schema_table_store_record(thd, i_s_table)) {
2254++ DBUG_RETURN(1);
2255++ } else {
2256++ DBUG_RETURN(0);
2257++ }
2258++}
2259++
2260++static
2261++int
2262++i_s_innodb_admin_command_init(
2263++/*==========================*/
2264++ void* p)
2265++{
2266++ DBUG_ENTER("i_s_innodb_admin_command_init");
2267++ ST_SCHEMA_TABLE* schema = (ST_SCHEMA_TABLE*) p;
2268++
2269++ schema->fields_info = i_s_innodb_admin_command_info;
2270++ schema->fill_table = i_s_innodb_admin_command_fill;
2271++
2272++ DBUG_RETURN(0);
2273++}
2274++
2275++UNIV_INTERN struct st_mysql_plugin i_s_innodb_admin_command =
2276++{
2277++ STRUCT_FLD(type, MYSQL_INFORMATION_SCHEMA_PLUGIN),
2278++ STRUCT_FLD(info, &i_s_info),
2279++ STRUCT_FLD(name, "XTRADB_ADMIN_COMMAND"),
2280++ STRUCT_FLD(author, plugin_author),
2281++ STRUCT_FLD(descr, "XtraDB specific command acceptor"),
2282++ STRUCT_FLD(license, PLUGIN_LICENSE_GPL),
2283++ STRUCT_FLD(init, i_s_innodb_admin_command_init),
2284++ STRUCT_FLD(deinit, i_s_common_deinit),
2285++ STRUCT_FLD(version, 0x0100 /* 1.0 */),
2286++ STRUCT_FLD(status_vars, NULL),
2287++ STRUCT_FLD(system_vars, NULL),
2288++ STRUCT_FLD(__reserved1, NULL)
2289++};
2290+diff -ruN a/storage/innobase/handler/i_s.h b/storage/innobase/handler/i_s.h
2291+--- a/storage/innobase/handler/i_s.h 2010-12-03 17:30:16.301987692 +0900
2292++++ b/storage/innobase/handler/i_s.h 2010-12-03 17:32:35.426954555 +0900
2293+@@ -44,5 +44,6 @@
2294+ extern struct st_mysql_plugin i_s_innodb_sys_stats;
2295+ extern struct st_mysql_plugin i_s_innodb_table_stats;
2296+ extern struct st_mysql_plugin i_s_innodb_index_stats;
2297++extern struct st_mysql_plugin i_s_innodb_admin_command;
2298+
2299+ #endif /* i_s_h */
2300
2301=== renamed file 'innodb_admin_command_base.patch' => 'innodb_admin_command_base.patch.moved'
2302=== added file 'innodb_buffer_pool_pages_i_s.patch'
2303--- innodb_buffer_pool_pages_i_s.patch 1970-01-01 00:00:00 +0000
2304+++ innodb_buffer_pool_pages_i_s.patch 2011-01-10 13:15:57 +0000
2305@@ -0,0 +1,803 @@
2306+# name : innodb_buffer_pool_pages_i_s.patch
2307+# introduced : 11 or before
2308+# maintainer : Yasufumi
2309+#
2310+#!!! notice !!!
2311+# Any small change to this file in the main branch
2312+# should be done or reviewed by the maintainer!
2313+diff -ruN a/storage/innobase/buf/buf0buf.c b/storage/innobase/buf/buf0buf.c
2314+--- a/storage/innobase/buf/buf0buf.c 2010-12-04 20:20:44.595483291 +0900
2315++++ b/storage/innobase/buf/buf0buf.c 2010-12-06 19:28:04.055227506 +0900
2316+@@ -4514,6 +4514,36 @@
2317+ mutex_exit(block_mutex);
2318+ }
2319+
2320++/********************************************************************//**
2321++*/
2322++UNIV_INTERN
2323++buf_block_t*
2324++buf_page_from_array(
2325++/*================*/
2326++ buf_pool_t* buf_pool,
2327++ ulint n_block)
2328++{
2329++ ulint n_chunks, offset;
2330++ buf_chunk_t* chunk;
2331++
2332++ ut_a(n_block < buf_pool->curr_size);
2333++
2334++ chunk = buf_pool->chunks;
2335++ offset = n_block;
2336++
2337++ for (n_chunks = buf_pool->n_chunks; n_chunks--; chunk++) {
2338++ if (offset < chunk->size) {
2339++ return(&chunk->blocks[offset]);
2340++ }
2341++
2342++ offset -= chunk->size;
2343++ }
2344++
2345++ ut_error;
2346++
2347++ return(NULL);
2348++}
2349++
2350+ /*********************************************************************//**
2351+ Asserts that all file pages in the buffer are in a replaceable state.
2352+ @return TRUE */
2353+diff -ruN a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc
2354+--- a/storage/innobase/handler/ha_innodb.cc 2010-12-04 20:20:44.614551139 +0900
2355++++ b/storage/innobase/handler/ha_innodb.cc 2010-12-06 19:23:47.622195800 +0900
2356+@@ -12036,6 +12036,9 @@
2357+ i_s_innodb_sys_stats,
2358+ i_s_innodb_table_stats,
2359+ i_s_innodb_index_stats,
2360++i_s_innodb_buffer_pool_pages,
2361++i_s_innodb_buffer_pool_pages_index,
2362++i_s_innodb_buffer_pool_pages_blob,
2363+ i_s_innodb_admin_command
2364+ mysql_declare_plugin_end;
2365+
2366+diff -ruN a/storage/innobase/handler/i_s.cc b/storage/innobase/handler/i_s.cc
2367+--- a/storage/innobase/handler/i_s.cc 2010-12-04 19:46:39.786513783 +0900
2368++++ b/storage/innobase/handler/i_s.cc 2010-12-06 19:28:52.270226921 +0900
2369+@@ -51,6 +51,7 @@
2370+ #include "trx0sys.h" /* for trx_sys */
2371+ #include "dict0dict.h" /* for dict_sys */
2372+ #include "buf0lru.h" /* for XTRA_LRU_[DUMP/RESTORE] */
2373++#include "btr0btr.h" /* for btr_page_get_index_id */
2374+ }
2375+
2376+ static const char plugin_author[] = "Innobase Oy";
2377+@@ -4329,3 +4330,701 @@
2378+ STRUCT_FLD(system_vars, NULL),
2379+ STRUCT_FLD(__reserved1, NULL)
2380+ };
2381++
2382++/***********************************************************************
2383++*/
2384++static ST_FIELD_INFO i_s_innodb_buffer_pool_pages_fields_info[] =
2385++{
2386++ {STRUCT_FLD(field_name, "page_type"),
2387++ STRUCT_FLD(field_length, 64),
2388++ STRUCT_FLD(field_type, MYSQL_TYPE_STRING),
2389++ STRUCT_FLD(value, 0),
2390++ STRUCT_FLD(field_flags, MY_I_S_MAYBE_NULL),
2391++ STRUCT_FLD(old_name, ""),
2392++ STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
2393++
2394++ {STRUCT_FLD(field_name, "space_id"),
2395++ STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS),
2396++ STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG),
2397++ STRUCT_FLD(value, 0),
2398++ STRUCT_FLD(field_flags, MY_I_S_UNSIGNED),
2399++ STRUCT_FLD(old_name, ""),
2400++ STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
2401++
2402++ {STRUCT_FLD(field_name, "page_no"),
2403++ STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS),
2404++ STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG),
2405++ STRUCT_FLD(value, 0),
2406++ STRUCT_FLD(field_flags, MY_I_S_UNSIGNED),
2407++ STRUCT_FLD(old_name, ""),
2408++ STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
2409++
2410++ {STRUCT_FLD(field_name, "lru_position"),
2411++ STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS),
2412++ STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG),
2413++ STRUCT_FLD(value, 0),
2414++ STRUCT_FLD(field_flags, MY_I_S_UNSIGNED),
2415++ STRUCT_FLD(old_name, ""),
2416++ STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
2417++
2418++ {STRUCT_FLD(field_name, "fix_count"),
2419++ STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS),
2420++ STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG),
2421++ STRUCT_FLD(value, 0),
2422++ STRUCT_FLD(field_flags, MY_I_S_UNSIGNED),
2423++ STRUCT_FLD(old_name, ""),
2424++ STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
2425++
2426++ {STRUCT_FLD(field_name, "flush_type"),
2427++ STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS),
2428++ STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG),
2429++ STRUCT_FLD(value, 0),
2430++ STRUCT_FLD(field_flags, MY_I_S_UNSIGNED),
2431++ STRUCT_FLD(old_name, ""),
2432++ STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
2433++
2434++ END_OF_ST_FIELD_INFO
2435++};
2436++
2437++static ST_FIELD_INFO i_s_innodb_buffer_pool_pages_index_fields_info[] =
2438++{
2439++ {STRUCT_FLD(field_name, "index_id"),
2440++ STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS),
2441++ STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG),
2442++ STRUCT_FLD(value, 0),
2443++ STRUCT_FLD(field_flags, MY_I_S_UNSIGNED),
2444++ STRUCT_FLD(old_name, ""),
2445++ STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
2446++
2447++ {STRUCT_FLD(field_name, "space_id"),
2448++ STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS),
2449++ STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG),
2450++ STRUCT_FLD(value, 0),
2451++ STRUCT_FLD(field_flags, MY_I_S_UNSIGNED),
2452++ STRUCT_FLD(old_name, ""),
2453++ STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
2454++
2455++ {STRUCT_FLD(field_name, "page_no"),
2456++ STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS),
2457++ STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG),
2458++ STRUCT_FLD(value, 0),
2459++ STRUCT_FLD(field_flags, MY_I_S_UNSIGNED),
2460++ STRUCT_FLD(old_name, ""),
2461++ STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
2462++
2463++ {STRUCT_FLD(field_name, "n_recs"),
2464++ STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS),
2465++ STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG),
2466++ STRUCT_FLD(value, 0),
2467++ STRUCT_FLD(field_flags, MY_I_S_UNSIGNED),
2468++ STRUCT_FLD(old_name, ""),
2469++ STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
2470++
2471++ {STRUCT_FLD(field_name, "data_size"),
2472++ STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS),
2473++ STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG),
2474++ STRUCT_FLD(value, 0),
2475++ STRUCT_FLD(field_flags, MY_I_S_UNSIGNED),
2476++ STRUCT_FLD(old_name, ""),
2477++ STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
2478++
2479++ {STRUCT_FLD(field_name, "hashed"),
2480++ STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS),
2481++ STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG),
2482++ STRUCT_FLD(value, 0),
2483++ STRUCT_FLD(field_flags, MY_I_S_UNSIGNED),
2484++ STRUCT_FLD(old_name, ""),
2485++ STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
2486++
2487++ {STRUCT_FLD(field_name, "access_time"),
2488++ STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS),
2489++ STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG),
2490++ STRUCT_FLD(value, 0),
2491++ STRUCT_FLD(field_flags, MY_I_S_UNSIGNED),
2492++ STRUCT_FLD(old_name, ""),
2493++ STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
2494++
2495++ {STRUCT_FLD(field_name, "modified"),
2496++ STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS),
2497++ STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG),
2498++ STRUCT_FLD(value, 0),
2499++ STRUCT_FLD(field_flags, MY_I_S_UNSIGNED),
2500++ STRUCT_FLD(old_name, ""),
2501++ STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
2502++
2503++ {STRUCT_FLD(field_name, "dirty"),
2504++ STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS),
2505++ STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG),
2506++ STRUCT_FLD(value, 0),
2507++ STRUCT_FLD(field_flags, MY_I_S_UNSIGNED),
2508++ STRUCT_FLD(old_name, ""),
2509++ STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
2510++
2511++ {STRUCT_FLD(field_name, "old"),
2512++ STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS),
2513++ STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG),
2514++ STRUCT_FLD(value, 0),
2515++ STRUCT_FLD(field_flags, MY_I_S_UNSIGNED),
2516++ STRUCT_FLD(old_name, ""),
2517++ STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
2518++
2519++ {STRUCT_FLD(field_name, "lru_position"),
2520++ STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS),
2521++ STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG),
2522++ STRUCT_FLD(value, 0),
2523++ STRUCT_FLD(field_flags, MY_I_S_UNSIGNED),
2524++ STRUCT_FLD(old_name, ""),
2525++ STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
2526++
2527++ {STRUCT_FLD(field_name, "fix_count"),
2528++ STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS),
2529++ STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG),
2530++ STRUCT_FLD(value, 0),
2531++ STRUCT_FLD(field_flags, MY_I_S_UNSIGNED),
2532++ STRUCT_FLD(old_name, ""),
2533++ STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
2534++
2535++ {STRUCT_FLD(field_name, "flush_type"),
2536++ STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS),
2537++ STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG),
2538++ STRUCT_FLD(value, 0),
2539++ STRUCT_FLD(field_flags, MY_I_S_UNSIGNED),
2540++ STRUCT_FLD(old_name, ""),
2541++ STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
2542++
2543++ END_OF_ST_FIELD_INFO
2544++};
2545++
2546++static ST_FIELD_INFO i_s_innodb_buffer_pool_pages_blob_fields_info[] =
2547++{
2548++ {STRUCT_FLD(field_name, "space_id"),
2549++ STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS),
2550++ STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG),
2551++ STRUCT_FLD(value, 0),
2552++ STRUCT_FLD(field_flags, MY_I_S_UNSIGNED),
2553++ STRUCT_FLD(old_name, ""),
2554++ STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
2555++
2556++ {STRUCT_FLD(field_name, "page_no"),
2557++ STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS),
2558++ STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG),
2559++ STRUCT_FLD(value, 0),
2560++ STRUCT_FLD(field_flags, MY_I_S_UNSIGNED),
2561++ STRUCT_FLD(old_name, ""),
2562++ STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
2563++
2564++ {STRUCT_FLD(field_name, "compressed"),
2565++ STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS),
2566++ STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG),
2567++ STRUCT_FLD(value, 0),
2568++ STRUCT_FLD(field_flags, MY_I_S_UNSIGNED),
2569++ STRUCT_FLD(old_name, ""),
2570++ STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
2571++
2572++ {STRUCT_FLD(field_name, "part_len"),
2573++ STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS),
2574++ STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG),
2575++ STRUCT_FLD(value, 0),
2576++ STRUCT_FLD(field_flags, MY_I_S_UNSIGNED),
2577++ STRUCT_FLD(old_name, ""),
2578++ STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
2579++
2580++ {STRUCT_FLD(field_name, "next_page_no"),
2581++ STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS),
2582++ STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG),
2583++ STRUCT_FLD(value, 0),
2584++ STRUCT_FLD(field_flags, MY_I_S_UNSIGNED),
2585++ STRUCT_FLD(old_name, ""),
2586++ STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
2587++
2588++ {STRUCT_FLD(field_name, "lru_position"),
2589++ STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS),
2590++ STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG),
2591++ STRUCT_FLD(value, 0),
2592++ STRUCT_FLD(field_flags, MY_I_S_UNSIGNED),
2593++ STRUCT_FLD(old_name, ""),
2594++ STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
2595++
2596++ {STRUCT_FLD(field_name, "fix_count"),
2597++ STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS),
2598++ STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG),
2599++ STRUCT_FLD(value, 0),
2600++ STRUCT_FLD(field_flags, MY_I_S_UNSIGNED),
2601++ STRUCT_FLD(old_name, ""),
2602++ STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
2603++
2604++ {STRUCT_FLD(field_name, "flush_type"),
2605++ STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS),
2606++ STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG),
2607++ STRUCT_FLD(value, 0),
2608++ STRUCT_FLD(field_flags, MY_I_S_UNSIGNED),
2609++ STRUCT_FLD(old_name, ""),
2610++ STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
2611++
2612++ END_OF_ST_FIELD_INFO
2613++};
2614++
2615++/***********************************************************************
2616++Fill the dynamic table information_schema.innodb_buffer_pool_pages. */
2617++static
2618++int
2619++i_s_innodb_buffer_pool_pages_fill(
2620++/*================*/
2621++ /* out: 0 on success, 1 on failure */
2622++ THD* thd, /* in: thread */
2623++ TABLE_LIST* tables, /* in/out: tables to fill */
2624++ COND* cond) /* in: condition (ignored) */
2625++{
2626++ TABLE* table = (TABLE *) tables->table;
2627++ int status = 0;
2628++ ulint i;
2629++
2630++ DBUG_ENTER("i_s_innodb_buffer_pool_pages_fill");
2631++
2632++ /* deny access to non-superusers */
2633++ if (check_global_access(thd, PROCESS_ACL)) {
2634++
2635++ DBUG_RETURN(0);
2636++ }
2637++
2638++ RETURN_IF_INNODB_NOT_STARTED(tables->schema_table_name);
2639++
2640++ for (i = 0; i < srv_buf_pool_instances; i++) {
2641++ ulint n_block;
2642++ buf_pool_t* buf_pool;
2643++
2644++ buf_pool = buf_pool_from_array(i);
2645++
2646++ buf_pool_mutex_enter(buf_pool);
2647++
2648++ for (n_block = 0; n_block < buf_pool->curr_size; n_block++) {
2649++ buf_block_t* block = buf_page_from_array(buf_pool, n_block);
2650++ const buf_frame_t* frame = block->frame;
2651++
2652++ char page_type[64];
2653++
2654++ switch(fil_page_get_type(frame))
2655++ {
2656++ case FIL_PAGE_INDEX:
2657++ strcpy(page_type, "index");
2658++ break;
2659++ case FIL_PAGE_UNDO_LOG:
2660++ strcpy(page_type, "undo_log");
2661++ break;
2662++ case FIL_PAGE_INODE:
2663++ strcpy(page_type, "inode");
2664++ break;
2665++ case FIL_PAGE_IBUF_FREE_LIST:
2666++ strcpy(page_type, "ibuf_free_list");
2667++ break;
2668++ case FIL_PAGE_TYPE_ALLOCATED:
2669++ strcpy(page_type, "allocated");
2670++ break;
2671++ case FIL_PAGE_IBUF_BITMAP:
2672++ strcpy(page_type, "bitmap");
2673++ break;
2674++ case FIL_PAGE_TYPE_SYS:
2675++ strcpy(page_type, "sys");
2676++ break;
2677++ case FIL_PAGE_TYPE_TRX_SYS:
2678++ strcpy(page_type, "trx_sys");
2679++ break;
2680++ case FIL_PAGE_TYPE_FSP_HDR:
2681++ strcpy(page_type, "fsp_hdr");
2682++ break;
2683++ case FIL_PAGE_TYPE_XDES:
2684++ strcpy(page_type, "xdes");
2685++ break;
2686++ case FIL_PAGE_TYPE_BLOB:
2687++ strcpy(page_type, "blob");
2688++ break;
2689++ case FIL_PAGE_TYPE_ZBLOB:
2690++ strcpy(page_type, "zblob");
2691++ break;
2692++ case FIL_PAGE_TYPE_ZBLOB2:
2693++ strcpy(page_type, "zblob2");
2694++ break;
2695++ default:
2696++ sprintf(page_type, "unknown (type=%li)", fil_page_get_type(frame));
2697++ }
2698++
2699++ field_store_string(table->field[0], page_type);
2700++ table->field[1]->store(block->page.space);
2701++ table->field[2]->store(block->page.offset);
2702++ table->field[3]->store(0);
2703++ table->field[4]->store(block->page.buf_fix_count);
2704++ table->field[5]->store(block->page.flush_type);
2705++
2706++ if (schema_table_store_record(thd, table)) {
2707++ status = 1;
2708++ break;
2709++ }
2710++
2711++ }
2712++
2713++ buf_pool_mutex_exit(buf_pool);
2714++ }
2715++
2716++ DBUG_RETURN(status);
2717++}
2718++
2719++/***********************************************************************
2720++Fill the dynamic table information_schema.innodb_buffer_pool_pages_index. */
2721++static
2722++int
2723++i_s_innodb_buffer_pool_pages_index_fill(
2724++/*================*/
2725++ /* out: 0 on success, 1 on failure */
2726++ THD* thd, /* in: thread */
2727++ TABLE_LIST* tables, /* in/out: tables to fill */
2728++ COND* cond) /* in: condition (ignored) */
2729++{
2730++ TABLE* table = (TABLE *) tables->table;
2731++ int status = 0;
2732++ ulint i;
2733++ index_id_t index_id;
2734++
2735++ DBUG_ENTER("i_s_innodb_buffer_pool_pages_index_fill");
2736++
2737++ /* deny access to non-superusers */
2738++ if (check_global_access(thd, PROCESS_ACL)) {
2739++
2740++ DBUG_RETURN(0);
2741++ }
2742++
2743++ RETURN_IF_INNODB_NOT_STARTED(tables->schema_table_name);
2744++
2745++ for (i = 0; i < srv_buf_pool_instances; i++) {
2746++ ulint n_block;
2747++ buf_pool_t* buf_pool;
2748++
2749++ buf_pool = buf_pool_from_array(i);
2750++
2751++ buf_pool_mutex_enter(buf_pool);
2752++
2753++ for (n_block = 0; n_block < buf_pool->curr_size; n_block++) {
2754++ buf_block_t* block = buf_page_from_array(buf_pool, n_block);
2755++ const buf_frame_t* frame = block->frame;
2756++
2757++ if (fil_page_get_type(frame) == FIL_PAGE_INDEX) {
2758++ index_id = btr_page_get_index_id(frame);
2759++ table->field[0]->store(index_id);
2760++ table->field[1]->store(block->page.space);
2761++ table->field[2]->store(block->page.offset);
2762++ table->field[3]->store(page_get_n_recs(frame));
2763++ table->field[4]->store(page_get_data_size(frame));
2764++ table->field[5]->store(block->is_hashed);
2765++ table->field[6]->store(block->page.access_time);
2766++ table->field[7]->store(block->page.newest_modification != 0);
2767++ table->field[8]->store(block->page.oldest_modification != 0);
2768++ table->field[9]->store(block->page.old);
2769++ table->field[10]->store(0);
2770++ table->field[11]->store(block->page.buf_fix_count);
2771++ table->field[12]->store(block->page.flush_type);
2772++
2773++ if (schema_table_store_record(thd, table)) {
2774++ status = 1;
2775++ break;
2776++ }
2777++ }
2778++ }
2779++
2780++ buf_pool_mutex_exit(buf_pool);
2781++ }
2782++
2783++ DBUG_RETURN(status);
2784++}
2785++
2786++/***********************************************************************
2787++Fill the dynamic table information_schema.innodb_buffer_pool_pages_index. */
2788++static
2789++int
2790++i_s_innodb_buffer_pool_pages_blob_fill(
2791++/*================*/
2792++ /* out: 0 on success, 1 on failure */
2793++ THD* thd, /* in: thread */
2794++ TABLE_LIST* tables, /* in/out: tables to fill */
2795++ COND* cond) /* in: condition (ignored) */
2796++{
2797++ TABLE* table = (TABLE *) tables->table;
2798++ int status = 0;
2799++ ulint i;
2800++
2801++ ulint part_len;
2802++ ulint next_page_no;
2803++
2804++ DBUG_ENTER("i_s_innodb_buffer_pool_pages_blob_fill");
2805++
2806++ /* deny access to non-superusers */
2807++ if (check_global_access(thd, PROCESS_ACL)) {
2808++
2809++ DBUG_RETURN(0);
2810++ }
2811++
2812++ RETURN_IF_INNODB_NOT_STARTED(tables->schema_table_name);
2813++
2814++ for (i = 0; i < srv_buf_pool_instances; i++) {
2815++ ulint n_block;
2816++ buf_pool_t* buf_pool;
2817++
2818++ buf_pool = buf_pool_from_array(i);
2819++
2820++ buf_pool_mutex_enter(buf_pool);
2821++
2822++ for (n_block = 0; n_block < buf_pool->curr_size; n_block++) {
2823++ buf_block_t* block = buf_page_from_array(buf_pool, n_block);
2824++ page_zip_des_t* block_page_zip = buf_block_get_page_zip(block);
2825++ const buf_frame_t* frame = block->frame;
2826++
2827++ if (fil_page_get_type(frame) == FIL_PAGE_TYPE_BLOB) {
2828++
2829++ if (UNIV_LIKELY_NULL(block_page_zip)) {
2830++ part_len = 0; /* hmm, can't figure it out */
2831++
2832++ next_page_no = mach_read_from_4(
2833++ buf_block_get_frame(block)
2834++ + FIL_PAGE_NEXT);
2835++ } else {
2836++ part_len = mach_read_from_4(
2837++ buf_block_get_frame(block)
2838++ + FIL_PAGE_DATA
2839++ + 0 /*BTR_BLOB_HDR_PART_LEN*/);
2840++
2841++ next_page_no = mach_read_from_4(
2842++ buf_block_get_frame(block)
2843++ + FIL_PAGE_DATA
2844++ + 4 /*BTR_BLOB_HDR_NEXT_PAGE_NO*/);
2845++ }
2846++
2847++ table->field[0]->store(block->page.space);
2848++ table->field[1]->store(block->page.offset);
2849++ table->field[2]->store(block_page_zip != NULL);
2850++ table->field[3]->store(part_len);
2851++
2852++ if(next_page_no == FIL_NULL)
2853++ {
2854++ table->field[4]->store(0);
2855++ } else {
2856++ table->field[4]->store(block->page.offset);
2857++ }
2858++
2859++ table->field[5]->store(0);
2860++ table->field[6]->store(block->page.buf_fix_count);
2861++ table->field[7]->store(block->page.flush_type);
2862++
2863++ if (schema_table_store_record(thd, table)) {
2864++ status = 1;
2865++ break;
2866++ }
2867++
2868++ }
2869++ }
2870++
2871++ buf_pool_mutex_exit(buf_pool);
2872++ }
2873++
2874++ DBUG_RETURN(status);
2875++}
2876++
2877++/***********************************************************************
2878++Bind the dynamic table information_schema.innodb_buffer_pool_pages. */
2879++static
2880++int
2881++i_s_innodb_buffer_pool_pages_init(
2882++/*=========*/
2883++ /* out: 0 on success */
2884++ void* p) /* in/out: table schema object */
2885++{
2886++ DBUG_ENTER("i_s_innodb_buffer_pool_pages_init");
2887++ ST_SCHEMA_TABLE* schema = (ST_SCHEMA_TABLE*) p;
2888++
2889++ schema->fields_info = i_s_innodb_buffer_pool_pages_fields_info;
2890++ schema->fill_table = i_s_innodb_buffer_pool_pages_fill;
2891++
2892++ DBUG_RETURN(0);
2893++}
2894++
2895++/***********************************************************************
2896++Bind the dynamic table information_schema.innodb_buffer_pool_pages. */
2897++static
2898++int
2899++i_s_innodb_buffer_pool_pages_index_init(
2900++/*=========*/
2901++ /* out: 0 on success */
2902++ void* p) /* in/out: table schema object */
2903++{
2904++ DBUG_ENTER("i_s_innodb_buffer_pool_pages_index_init");
2905++ ST_SCHEMA_TABLE* schema = (ST_SCHEMA_TABLE*) p;
2906++
2907++ schema->fields_info = i_s_innodb_buffer_pool_pages_index_fields_info;
2908++ schema->fill_table = i_s_innodb_buffer_pool_pages_index_fill;
2909++
2910++ DBUG_RETURN(0);
2911++}
2912++
2913++/***********************************************************************
2914++Bind the dynamic table information_schema.innodb_buffer_pool_pages. */
2915++static
2916++int
2917++i_s_innodb_buffer_pool_pages_blob_init(
2918++/*=========*/
2919++ /* out: 0 on success */
2920++ void* p) /* in/out: table schema object */
2921++{
2922++ DBUG_ENTER("i_s_innodb_buffer_pool_pages_blob_init");
2923++ ST_SCHEMA_TABLE* schema = (ST_SCHEMA_TABLE*) p;
2924++
2925++ schema->fields_info = i_s_innodb_buffer_pool_pages_blob_fields_info;
2926++ schema->fill_table = i_s_innodb_buffer_pool_pages_blob_fill;
2927++
2928++ DBUG_RETURN(0);
2929++}
2930++
2931++
2932++UNIV_INTERN struct st_mysql_plugin i_s_innodb_buffer_pool_pages =
2933++{
2934++ /* the plugin type (a MYSQL_XXX_PLUGIN value) */
2935++ /* int */
2936++ STRUCT_FLD(type, MYSQL_INFORMATION_SCHEMA_PLUGIN),
2937++
2938++ /* pointer to type-specific plugin descriptor */
2939++ /* void* */
2940++ STRUCT_FLD(info, &i_s_info),
2941++
2942++ /* plugin name */
2943++ /* const char* */
2944++ STRUCT_FLD(name, "INNODB_BUFFER_POOL_PAGES"),
2945++
2946++ /* plugin author (for SHOW PLUGINS) */
2947++ /* const char* */
2948++ STRUCT_FLD(author, plugin_author),
2949++
2950++ /* general descriptive text (for SHOW PLUGINS) */
2951++ /* const char* */
2952++ STRUCT_FLD(descr, "InnoDB buffer pool pages"),
2953++
2954++ /* the plugin license (PLUGIN_LICENSE_XXX) */
2955++ /* int */
2956++ STRUCT_FLD(license, PLUGIN_LICENSE_GPL),
2957++
2958++ /* the function to invoke when plugin is loaded */
2959++ /* int (*)(void*); */
2960++ STRUCT_FLD(init, i_s_innodb_buffer_pool_pages_init),
2961++
2962++ /* the function to invoke when plugin is unloaded */
2963++ /* int (*)(void*); */
2964++ STRUCT_FLD(deinit, i_s_common_deinit),
2965++
2966++ /* plugin version (for SHOW PLUGINS) */
2967++ /* unsigned int */
2968++ STRUCT_FLD(version, 0x0100 /* 1.0 */),
2969++
2970++ /* struct st_mysql_show_var* */
2971++ STRUCT_FLD(status_vars, NULL),
2972++
2973++ /* struct st_mysql_sys_var** */
2974++ STRUCT_FLD(system_vars, NULL),
2975++
2976++ /* reserved for dependency checking */
2977++ /* void* */
2978++ STRUCT_FLD(__reserved1, NULL)
2979++};
2980++
2981++UNIV_INTERN struct st_mysql_plugin i_s_innodb_buffer_pool_pages_index =
2982++{
2983++ /* the plugin type (a MYSQL_XXX_PLUGIN value) */
2984++ /* int */
2985++ STRUCT_FLD(type, MYSQL_INFORMATION_SCHEMA_PLUGIN),
2986++
2987++ /* pointer to type-specific plugin descriptor */
2988++ /* void* */
2989++ STRUCT_FLD(info, &i_s_info),
2990++
2991++ /* plugin name */
2992++ /* const char* */
2993++ STRUCT_FLD(name, "INNODB_BUFFER_POOL_PAGES_INDEX"),
2994++
2995++ /* plugin author (for SHOW PLUGINS) */
2996++ /* const char* */
2997++ STRUCT_FLD(author, plugin_author),
2998++
2999++ /* general descriptive text (for SHOW PLUGINS) */
3000++ /* const char* */
3001++ STRUCT_FLD(descr, "InnoDB buffer pool index pages"),
3002++
3003++ /* the plugin license (PLUGIN_LICENSE_XXX) */
3004++ /* int */
3005++ STRUCT_FLD(license, PLUGIN_LICENSE_GPL),
3006++
3007++ /* the function to invoke when plugin is loaded */
3008++ /* int (*)(void*); */
3009++ STRUCT_FLD(init, i_s_innodb_buffer_pool_pages_index_init),
3010++
3011++ /* the function to invoke when plugin is unloaded */
3012++ /* int (*)(void*); */
3013++ STRUCT_FLD(deinit, i_s_common_deinit),
3014++
3015++ /* plugin version (for SHOW PLUGINS) */
3016++ /* unsigned int */
3017++ STRUCT_FLD(version, 0x0100 /* 1.0 */),
3018++
3019++ /* struct st_mysql_show_var* */
3020++ STRUCT_FLD(status_vars, NULL),
3021++
3022++ /* struct st_mysql_sys_var** */
3023++ STRUCT_FLD(system_vars, NULL),
3024++
3025++ /* reserved for dependency checking */
3026++ /* void* */
3027++ STRUCT_FLD(__reserved1, NULL)
3028++};
3029++
3030++UNIV_INTERN struct st_mysql_plugin i_s_innodb_buffer_pool_pages_blob =
3031++{
3032++ /* the plugin type (a MYSQL_XXX_PLUGIN value) */
3033++ /* int */
3034++ STRUCT_FLD(type, MYSQL_INFORMATION_SCHEMA_PLUGIN),
3035++
3036++ /* pointer to type-specific plugin descriptor */
3037++ /* void* */
3038++ STRUCT_FLD(info, &i_s_info),
3039++
3040++ /* plugin name */
3041++ /* const char* */
3042++ STRUCT_FLD(name, "INNODB_BUFFER_POOL_PAGES_BLOB"),
3043++
3044++ /* plugin author (for SHOW PLUGINS) */
3045++ /* const char* */
3046++ STRUCT_FLD(author, plugin_author),
3047++
3048++ /* general descriptive text (for SHOW PLUGINS) */
3049++ /* const char* */
3050++ STRUCT_FLD(descr, "InnoDB buffer pool blob pages"),
3051++
3052++ /* the plugin license (PLUGIN_LICENSE_XXX) */
3053++ /* int */
3054++ STRUCT_FLD(license, PLUGIN_LICENSE_GPL),
3055++
3056++ /* the function to invoke when plugin is loaded */
3057++ /* int (*)(void*); */
3058++ STRUCT_FLD(init, i_s_innodb_buffer_pool_pages_blob_init),
3059++
3060++ /* the function to invoke when plugin is unloaded */
3061++ /* int (*)(void*); */
3062++ STRUCT_FLD(deinit, i_s_common_deinit),
3063++
3064++ /* plugin version (for SHOW PLUGINS) */
3065++ /* unsigned int */
3066++ STRUCT_FLD(version, 0x0100 /* 1.0 */),
3067++
3068++ /* struct st_mysql_show_var* */
3069++ STRUCT_FLD(status_vars, NULL),
3070++
3071++ /* struct st_mysql_sys_var** */
3072++ STRUCT_FLD(system_vars, NULL),
3073++
3074++ /* reserved for dependency checking */
3075++ /* void* */
3076++ STRUCT_FLD(__reserved1, NULL)
3077++};
3078++
3079+diff -ruN a/storage/innobase/handler/i_s.h b/storage/innobase/handler/i_s.h
3080+--- a/storage/innobase/handler/i_s.h 2010-12-04 19:46:39.657513849 +0900
3081++++ b/storage/innobase/handler/i_s.h 2010-12-06 19:23:47.635192988 +0900
3082+@@ -45,5 +45,8 @@
3083+ extern struct st_mysql_plugin i_s_innodb_table_stats;
3084+ extern struct st_mysql_plugin i_s_innodb_index_stats;
3085+ extern struct st_mysql_plugin i_s_innodb_admin_command;
3086++extern struct st_mysql_plugin i_s_innodb_buffer_pool_pages;
3087++extern struct st_mysql_plugin i_s_innodb_buffer_pool_pages_index;
3088++extern struct st_mysql_plugin i_s_innodb_buffer_pool_pages_blob;
3089+
3090+ #endif /* i_s_h */
3091+diff -ruN a/storage/innobase/include/buf0buf.h b/storage/innobase/include/buf0buf.h
3092+--- a/storage/innobase/include/buf0buf.h 2010-12-04 19:46:40.197471531 +0900
3093++++ b/storage/innobase/include/buf0buf.h 2010-12-06 19:23:47.638195824 +0900
3094+@@ -1072,6 +1072,14 @@
3095+ /*===========*/
3096+ const buf_pool_t* buf_pool) /*!< in: buffer pool */
3097+ __attribute__((nonnull, const));
3098++/********************************************************************//**
3099++*/
3100++UNIV_INTERN
3101++buf_block_t*
3102++buf_page_from_array(
3103++/*================*/
3104++ buf_pool_t* buf_pool,
3105++ ulint n_block);
3106+ /******************************************************************//**
3107+ Returns the buffer pool instance given a page instance
3108+ @return buf_pool */
3109
3110=== added file 'innodb_buffer_pool_shm.patch'
3111--- innodb_buffer_pool_shm.patch 1970-01-01 00:00:00 +0000
3112+++ innodb_buffer_pool_shm.patch 2011-01-10 13:15:57 +0000
3113@@ -0,0 +1,1224 @@
3114+# name : innodb_buffer_pool_shm.patch
3115+# introduced : 12
3116+# maintainer : Yasufumi
3117+#
3118+#!!! notice !!!
3119+# Any small change to this file in the main branch
3120+# should be done or reviewed by the maintainer!
3121+diff -ruN a/storage/innobase/buf/buf0buddy.c b/storage/innobase/buf/buf0buddy.c
3122+--- a/storage/innobase/buf/buf0buddy.c 2010-12-04 19:46:39.372513543 +0900
3123++++ b/storage/innobase/buf/buf0buddy.c 2010-12-07 17:56:28.302087851 +0900
3124+@@ -183,7 +183,7 @@
3125+ void* buf, /*!< in: buffer frame to deallocate */
3126+ ibool have_page_hash_mutex)
3127+ {
3128+- const ulint fold = BUF_POOL_ZIP_FOLD_PTR(buf);
3129++ const ulint fold = BUF_POOL_ZIP_FOLD_PTR(buf_pool, buf);
3130+ buf_page_t* bpage;
3131+ buf_block_t* block;
3132+
3133+@@ -227,7 +227,7 @@
3134+ buf_block_t* block) /*!< in: buffer frame to allocate */
3135+ {
3136+ buf_pool_t* buf_pool = buf_pool_from_block(block);
3137+- const ulint fold = BUF_POOL_ZIP_FOLD(block);
3138++ const ulint fold = BUF_POOL_ZIP_FOLD(buf_pool, block);
3139+ //ut_ad(buf_pool_mutex_own(buf_pool));
3140+ ut_ad(!mutex_own(&buf_pool->zip_mutex));
3141+ ut_ad(buf_block_get_state(block) == BUF_BLOCK_READY_FOR_USE);
3142+diff -ruN a/storage/innobase/buf/buf0buf.c b/storage/innobase/buf/buf0buf.c
3143+--- a/storage/innobase/buf/buf0buf.c 2010-12-06 20:16:21.726195340 +0900
3144++++ b/storage/innobase/buf/buf0buf.c 2010-12-07 20:40:30.824749814 +0900
3145+@@ -53,6 +53,10 @@
3146+ #include "page0zip.h"
3147+ #include "trx0trx.h"
3148+ #include "srv0start.h"
3149++#include "que0que.h"
3150++#include "read0read.h"
3151++#include "row0row.h"
3152++#include "ha_prototypes.h"
3153+
3154+ /* prototypes for new functions added to ha_innodb.cc */
3155+ trx_t* innobase_get_trx();
3156+@@ -342,6 +346,31 @@
3157+ was allocated for the frames */
3158+ buf_block_t* blocks; /*!< array of buffer control blocks */
3159+ };
3160++
3161++/* Buffer pool shared memory segment information */
3162++typedef struct buf_shm_info_struct buf_shm_info_t;
3163++
3164++struct buf_shm_info_struct {
3165++ char head_str[8];
3166++ ulint binary_id;
3167++ ibool is_new; /* during initializing */
3168++ ibool clean; /* clean shutdowned and free */
3169++ ibool reusable; /* reusable */
3170++ ulint buf_pool_size; /* backup value */
3171++ ulint page_size; /* backup value */
3172++ ulint frame_offset; /* offset of the first frame based on chunk->mem */
3173++ ulint zip_hash_offset;
3174++ ulint zip_hash_n;
3175++
3176++ ulint checksum;
3177++
3178++ buf_pool_t buf_pool_backup;
3179++ buf_chunk_t chunk_backup;
3180++
3181++ ib_uint64_t dummy;
3182++};
3183++
3184++#define BUF_SHM_INFO_HEAD "XTRA_SHM"
3185+ #endif /* !UNIV_HOTBACKUP */
3186+
3187+ /********************************************************************//**
3188+@@ -988,6 +1017,58 @@
3189+ #endif /* UNIV_SYNC_DEBUG */
3190+ }
3191+
3192++static
3193++void
3194++buf_block_reuse(
3195++/*============*/
3196++ buf_block_t* block,
3197++ ptrdiff_t frame_offset)
3198++{
3199++ /* block_init */
3200++ block->frame += frame_offset;
3201++
3202++ UNIV_MEM_DESC(block->frame, UNIV_PAGE_SIZE, block);
3203++
3204++ block->index = NULL;
3205++ block->btr_search_latch = NULL;
3206++
3207++#ifdef UNIV_DEBUG
3208++ /* recreate later */
3209++ block->page.in_page_hash = FALSE;
3210++ block->page.in_zip_hash = FALSE;
3211++#endif /* UNIV_DEBUG */
3212++
3213++#if defined UNIV_AHI_DEBUG || defined UNIV_DEBUG
3214++ block->n_pointers = 0;
3215++#endif /* UNIV_AHI_DEBUG || UNIV_DEBUG */
3216++
3217++ if (block->page.zip.data)
3218++ block->page.zip.data += frame_offset;
3219++
3220++ block->is_hashed = FALSE;
3221++
3222++#if defined PFS_SKIP_BUFFER_MUTEX_RWLOCK || defined PFS_GROUP_BUFFER_SYNC
3223++ /* If PFS_SKIP_BUFFER_MUTEX_RWLOCK is defined, skip registration
3224++ of buffer block mutex/rwlock with performance schema. If
3225++ PFS_GROUP_BUFFER_SYNC is defined, skip the registration
3226++ since buffer block mutex/rwlock will be registered later in
3227++ pfs_register_buffer_block() */
3228++
3229++ mutex_create(PFS_NOT_INSTRUMENTED, &block->mutex, SYNC_BUF_BLOCK);
3230++ rw_lock_create(PFS_NOT_INSTRUMENTED, &block->lock, SYNC_LEVEL_VARYING);
3231++#else /* PFS_SKIP_BUFFER_MUTEX_RWLOCK || PFS_GROUP_BUFFER_SYNC */
3232++ mutex_create(buffer_block_mutex_key, &block->mutex, SYNC_BUF_BLOCK);
3233++ rw_lock_create(buf_block_lock_key, &block->lock, SYNC_LEVEL_VARYING);
3234++#endif /* PFS_SKIP_BUFFER_MUTEX_RWLOCK || PFS_GROUP_BUFFER_SYNC */
3235++
3236++ ut_ad(rw_lock_validate(&(block->lock)));
3237++
3238++#ifdef UNIV_SYNC_DEBUG
3239++ rw_lock_create(buf_block_debug_latch_key,
3240++ &block->debug_latch, SYNC_NO_ORDER_CHECK);
3241++#endif /* UNIV_SYNC_DEBUG */
3242++}
3243++
3244+ /********************************************************************//**
3245+ Allocates a chunk of buffer frames.
3246+ @return chunk, or NULL on failure */
3247+@@ -1001,26 +1082,188 @@
3248+ {
3249+ buf_block_t* block;
3250+ byte* frame;
3251++ ulint zip_hash_n = 0;
3252++ ulint zip_hash_mem_size = 0;
3253++ hash_table_t* zip_hash_tmp = NULL;
3254+ ulint i;
3255++ buf_shm_info_t* shm_info = NULL;
3256+
3257+ /* Round down to a multiple of page size,
3258+ although it already should be. */
3259+ mem_size = ut_2pow_round(mem_size, UNIV_PAGE_SIZE);
3260++
3261++ srv_buffer_pool_shm_is_reused = FALSE;
3262++
3263++ if (srv_buffer_pool_shm_key) {
3264++ /* zip_hash size */
3265++ zip_hash_n = (mem_size / UNIV_PAGE_SIZE) * 2;
3266++ zip_hash_mem_size = ut_2pow_round(hash_create_needed(zip_hash_n)
3267++ + (UNIV_PAGE_SIZE - 1), UNIV_PAGE_SIZE);
3268++ }
3269++
3270+ /* Reserve space for the block descriptors. */
3271+ mem_size += ut_2pow_round((mem_size / UNIV_PAGE_SIZE) * (sizeof *block)
3272+ + (UNIV_PAGE_SIZE - 1), UNIV_PAGE_SIZE);
3273++ if (srv_buffer_pool_shm_key) {
3274++ mem_size += ut_2pow_round(sizeof(buf_shm_info_t)
3275++ + (UNIV_PAGE_SIZE - 1), UNIV_PAGE_SIZE);
3276++ mem_size += zip_hash_mem_size;
3277++ }
3278+
3279+ chunk->mem_size = mem_size;
3280++
3281++ if (srv_buffer_pool_shm_key) {
3282++ ulint binary_id;
3283++ ibool is_new;
3284++
3285++ ut_a(buf_pool->n_chunks == 1);
3286++
3287++ fprintf(stderr,
3288++ "InnoDB: Warning: The innodb_buffer_pool_shm_key option has been specified.\n"
3289++ "InnoDB: Do not change the following between restarts of the server while this option is being used:\n"
3290++ "InnoDB: * the mysqld executable between restarts of the server.\n"
3291++ "InnoDB: * the value of innodb_buffer_pool_size.\n"
3292++ "InnoDB: * the value of innodb_page_size.\n"
3293++ "InnoDB: * datafiles created by InnoDB during this session.\n"
3294++ "InnoDB: Otherwise, data corruption in datafiles may result.\n");
3295++
3296++ /* FIXME: This is vague id still */
3297++ binary_id = (ulint) ((byte*)mtr_commit - (byte*)btr_root_get)
3298++ + (ulint) ((byte*)os_get_os_version - (byte*)buf_calc_page_new_checksum)
3299++ + (ulint) ((byte*)page_dir_find_owner_slot - (byte*)dfield_data_is_binary_equal)
3300++ + (ulint) ((byte*)que_graph_publish - (byte*)dict_casedn_str)
3301++ + (ulint) ((byte*)read_view_oldest_copy_or_open_new - (byte*)fil_space_get_version)
3302++ + (ulint) ((byte*)rec_get_n_extern_new - (byte*)fsp_get_size_low)
3303++ + (ulint) ((byte*)row_get_trx_id_offset - (byte*)ha_create_func)
3304++ + (ulint) ((byte*)srv_set_io_thread_op_info - (byte*)thd_is_replication_slave_thread)
3305++ + (ulint) ((byte*)mutex_create_func - (byte*)ibuf_inside)
3306++ + (ulint) ((byte*)trx_set_detailed_error - (byte*)lock_check_trx_id_sanity)
3307++ + (ulint) ((byte*)ut_time - (byte*)mem_heap_strdup);
3308++
3309++ chunk->mem = os_shm_alloc(&chunk->mem_size, srv_buffer_pool_shm_key, &is_new);
3310++
3311++ if (UNIV_UNLIKELY(chunk->mem == NULL)) {
3312++ return(NULL);
3313++ }
3314++init_again:
3315++#ifdef UNIV_SET_MEM_TO_ZERO
3316++ if (is_new) {
3317++ memset(chunk->mem, '\0', chunk->mem_size);
3318++ }
3319++#endif
3320++ /* for ut_fold_binary_32(), these values should be 32-bit aligned */
3321++ ut_a(sizeof(buf_shm_info_t) % 4 == 0);
3322++ ut_a((ulint)chunk->mem % 4 == 0);
3323++ ut_a(chunk->mem_size % 4 == 0);
3324++
3325++ shm_info = chunk->mem;
3326++
3327++ zip_hash_tmp = (hash_table_t*)((byte*)chunk->mem + chunk->mem_size - zip_hash_mem_size);
3328++
3329++ if (is_new) {
3330++ strncpy(shm_info->head_str, BUF_SHM_INFO_HEAD, 8);
3331++ shm_info->binary_id = binary_id;
3332++ shm_info->is_new = TRUE; /* changed to FALSE when the initialization is finished */
3333++ shm_info->clean = FALSE; /* changed to TRUE when free the segment. */
3334++ shm_info->reusable = FALSE; /* changed to TRUE when validation is finished. */
3335++ shm_info->buf_pool_size = srv_buf_pool_size;
3336++ shm_info->page_size = srv_page_size;
3337++ shm_info->zip_hash_offset = chunk->mem_size - zip_hash_mem_size;
3338++ shm_info->zip_hash_n = zip_hash_n;
3339++ } else {
3340++ ulint checksum;
3341++
3342++ if (strncmp(shm_info->head_str, BUF_SHM_INFO_HEAD, 8)) {
3343++ fprintf(stderr,
3344++ "InnoDB: Error: The shared memory segment seems not to be for buffer pool.\n");
3345++ return(NULL);
3346++ }
3347++ if (shm_info->binary_id != binary_id) {
3348++ fprintf(stderr,
3349++ "InnoDB: Error: The shared memory segment seems not to be for this binary.\n");
3350++ return(NULL);
3351++ }
3352++ if (shm_info->is_new) {
3353++ fprintf(stderr,
3354++ "InnoDB: Error: The shared memory was not initialized yet.\n");
3355++ return(NULL);
3356++ }
3357++ if (shm_info->buf_pool_size != srv_buf_pool_size) {
3358++ fprintf(stderr,
3359++ "InnoDB: Error: srv_buf_pool_size is different (shm=%lu current=%lu).\n",
3360++ shm_info->buf_pool_size, srv_buf_pool_size);
3361++ return(NULL);
3362++ }
3363++ if (shm_info->page_size != srv_page_size) {
3364++ fprintf(stderr,
3365++ "InnoDB: Error: srv_page_size is different (shm=%lu current=%lu).\n",
3366++ shm_info->page_size, srv_page_size);
3367++ return(NULL);
3368++ }
3369++ if (!shm_info->reusable) {
3370++ fprintf(stderr,
3371++ "InnoDB: Warning: The shared memory has unrecoverable contents.\n"
3372++ "InnoDB: The shared memory segment is initialized.\n");
3373++ is_new = TRUE;
3374++ goto init_again;
3375++ }
3376++ if (!shm_info->clean) {
3377++ fprintf(stderr,
3378++ "InnoDB: Warning: The shared memory was not shut down cleanly.\n"
3379++ "InnoDB: The shared memory segment is initialized.\n");
3380++ is_new = TRUE;
3381++ goto init_again;
3382++ }
3383++
3384++ ut_a(shm_info->zip_hash_offset == chunk->mem_size - zip_hash_mem_size);
3385++ ut_a(shm_info->zip_hash_n == zip_hash_n);
3386++
3387++ /* check checksum */
3388++ if (srv_buffer_pool_shm_checksum) {
3389++ checksum = ut_fold_binary_32((byte*)chunk->mem + sizeof(buf_shm_info_t),
3390++ chunk->mem_size - sizeof(buf_shm_info_t));
3391++ } else {
3392++ checksum = BUF_NO_CHECKSUM_MAGIC;
3393++ }
3394++
3395++ if (shm_info->checksum != BUF_NO_CHECKSUM_MAGIC
3396++ && shm_info->checksum != checksum) {
3397++ fprintf(stderr,
3398++ "InnoDB: Error: checksum of the shared memory is not match. "
3399++ "(stored=%lu calculated=%lu)\n",
3400++ shm_info->checksum, checksum);
3401++ return(NULL);
3402++ }
3403++
3404++ /* flag to use the segment. */
3405++ shm_info->clean = FALSE; /* changed to TRUE when free the segment. */
3406++ }
3407++
3408++ /* init zip_hash contents */
3409++ if (is_new) {
3410++ hash_create_init(zip_hash_tmp, zip_hash_n);
3411++ } else {
3412++ /* adjust offset is done later */
3413++ hash_create_reuse(zip_hash_tmp);
3414++
3415++ srv_buffer_pool_shm_is_reused = TRUE;
3416++ }
3417++ } else {
3418+ chunk->mem = os_mem_alloc_large(&chunk->mem_size);
3419+
3420+ if (UNIV_UNLIKELY(chunk->mem == NULL)) {
3421+
3422+ return(NULL);
3423+ }
3424++ }
3425+
3426+ /* Allocate the block descriptors from
3427+ the start of the memory block. */
3428++ if (srv_buffer_pool_shm_key) {
3429++ chunk->blocks = (buf_block_t*)((byte*)chunk->mem + sizeof(buf_shm_info_t));
3430++ } else {
3431+ chunk->blocks = chunk->mem;
3432++ }
3433+
3434+ /* Align a pointer to the first frame. Note that when
3435+ os_large_page_size is smaller than UNIV_PAGE_SIZE,
3436+@@ -1028,8 +1271,13 @@
3437+ it is bigger, we may allocate more blocks than requested. */
3438+
3439+ frame = ut_align(chunk->mem, UNIV_PAGE_SIZE);
3440++ if (srv_buffer_pool_shm_key) {
3441++ /* reserve zip_hash space and always -1 for reproductibity */
3442++ chunk->size = (chunk->mem_size - zip_hash_mem_size) / UNIV_PAGE_SIZE - 1;
3443++ } else {
3444+ chunk->size = chunk->mem_size / UNIV_PAGE_SIZE
3445+ - (frame != chunk->mem);
3446++ }
3447+
3448+ /* Subtract the space needed for block descriptors. */
3449+ {
3450+@@ -1043,6 +1291,98 @@
3451+ chunk->size = size;
3452+ }
3453+
3454++ if (shm_info && !(shm_info->is_new)) {
3455++ /* convert the shared memory segment for reuse */
3456++ ptrdiff_t phys_offset;
3457++ ptrdiff_t logi_offset;
3458++ ptrdiff_t blocks_offset;
3459++ void* previous_frame_address;
3460++
3461++ if (chunk->size < shm_info->chunk_backup.size) {
3462++ fprintf(stderr,
3463++ "InnoDB: Error: The buffer pool became smaller because of allocated address.\n"
3464++ "InnoDB: Retrying may avoid this situation.\n");
3465++ shm_info->clean = TRUE; /* release the flag for retrying */
3466++ return(NULL);
3467++ }
3468++
3469++ chunk->size = shm_info->chunk_backup.size;
3470++ phys_offset = frame - ((byte*)chunk->mem + shm_info->frame_offset);
3471++ logi_offset = frame - chunk->blocks[0].frame;
3472++ previous_frame_address = chunk->blocks[0].frame;
3473++ blocks_offset = (byte*)chunk->blocks - (byte*)shm_info->chunk_backup.blocks;
3474++
3475++ if (phys_offset || logi_offset || blocks_offset) {
3476++ fprintf(stderr,
3477++ "InnoDB: Buffer pool in the shared memory segment should be converted.\n"
3478++ "InnoDB: Previous frames in address : %p\n"
3479++ "InnoDB: Previous frames were located : %p\n"
3480++ "InnoDB: Current frames should be located: %p\n"
3481++ "InnoDB: Pysical offset : %ld (%#lx)\n"
3482++ "InnoDB: Logical offset (frames) : %ld (%#lx)\n"
3483++ "InnoDB: Logical offset (blocks) : %ld (%#lx)\n",
3484++ (byte*)chunk->mem + shm_info->frame_offset,
3485++ chunk->blocks[0].frame, frame,
3486++ phys_offset, phys_offset, logi_offset, logi_offset,
3487++ blocks_offset, blocks_offset);
3488++ } else {
3489++ fprintf(stderr,
3490++ "InnoDB: Buffer pool in the shared memory segment can be used as it is.\n");
3491++ }
3492++
3493++ if (phys_offset) {
3494++ fprintf(stderr,
3495++ "InnoDB: Aligning physical offset...");
3496++
3497++ memmove(frame, (byte*)chunk->mem + shm_info->frame_offset,
3498++ chunk->size * UNIV_PAGE_SIZE);
3499++
3500++ fprintf(stderr,
3501++ " Done.\n");
3502++ }
3503++
3504++ /* buf_block_t */
3505++ block = chunk->blocks;
3506++ for (i = chunk->size; i--; ) {
3507++ buf_block_reuse(block, logi_offset);
3508++ block++;
3509++ }
3510++
3511++ if (logi_offset || blocks_offset) {
3512++ fprintf(stderr,
3513++ "InnoDB: Aligning logical offset...");
3514++
3515++
3516++ /* buf_pool_t buf_pool_backup */
3517++ UT_LIST_OFFSET(flush_list, buf_page_t, shm_info->buf_pool_backup.flush_list,
3518++ previous_frame_address, logi_offset, blocks_offset);
3519++ UT_LIST_OFFSET(free, buf_page_t, shm_info->buf_pool_backup.free,
3520++ previous_frame_address, logi_offset, blocks_offset);
3521++ UT_LIST_OFFSET(LRU, buf_page_t, shm_info->buf_pool_backup.LRU,
3522++ previous_frame_address, logi_offset, blocks_offset);
3523++ if (shm_info->buf_pool_backup.LRU_old)
3524++ shm_info->buf_pool_backup.LRU_old =
3525++ (buf_page_t*)((byte*)(shm_info->buf_pool_backup.LRU_old)
3526++ + (((void*)shm_info->buf_pool_backup.LRU_old > previous_frame_address)
3527++ ? logi_offset : blocks_offset));
3528++
3529++ UT_LIST_OFFSET(unzip_LRU, buf_block_t, shm_info->buf_pool_backup.unzip_LRU,
3530++ previous_frame_address, logi_offset, blocks_offset);
3531++
3532++ UT_LIST_OFFSET(zip_list, buf_page_t, shm_info->buf_pool_backup.zip_clean,
3533++ previous_frame_address, logi_offset, blocks_offset);
3534++ for (i = 0; i < BUF_BUDDY_SIZES_MAX; i++) {
3535++ UT_LIST_OFFSET(zip_list, buf_page_t, shm_info->buf_pool_backup.zip_free[i],
3536++ previous_frame_address, logi_offset, blocks_offset);
3537++ }
3538++
3539++ HASH_OFFSET(zip_hash_tmp, buf_page_t, hash,
3540++ previous_frame_address, logi_offset, blocks_offset);
3541++
3542++ fprintf(stderr,
3543++ " Done.\n");
3544++ }
3545++ } else {
3546+ /* Init block structs and assign frames for them. Then we
3547+ assign the frames to the first blocks (we already mapped the
3548+ memory above). */
3549+@@ -1068,6 +1408,11 @@
3550+ block++;
3551+ frame += UNIV_PAGE_SIZE;
3552+ }
3553++ }
3554++
3555++ if (shm_info) {
3556++ shm_info->frame_offset = chunk->blocks[0].frame - (byte*)chunk->mem;
3557++ }
3558+
3559+ #ifdef PFS_GROUP_BUFFER_SYNC
3560+ pfs_register_buffer_block(chunk);
3561+@@ -1249,6 +1594,8 @@
3562+ UNIV_MEM_UNDESC(block);
3563+ }
3564+
3565++ ut_a(!srv_buffer_pool_shm_key);
3566++
3567+ os_mem_free_large(chunk->mem, chunk->mem_size);
3568+ }
3569+
3570+@@ -1289,7 +1636,7 @@
3571+ ulint instance_no) /*!< in: id of the instance */
3572+ {
3573+ ulint i;
3574+- buf_chunk_t* chunk;
3575++ buf_chunk_t* chunk = NULL;
3576+
3577+ /* 1. Initialize general fields
3578+ ------------------------------- */
3579+@@ -1335,7 +1682,10 @@
3580+ buf_pool->curr_pool_size = buf_pool->curr_size * UNIV_PAGE_SIZE;
3581+
3582+ buf_pool->page_hash = hash_create(2 * buf_pool->curr_size);
3583++ /* zip_hash is allocated to shm when srv_buffer_pool_shm_key is enabled */
3584++ if (!srv_buffer_pool_shm_key) {
3585+ buf_pool->zip_hash = hash_create(2 * buf_pool->curr_size);
3586++ }
3587+
3588+ buf_pool->last_printout_time = ut_time();
3589+ }
3590+@@ -1354,6 +1704,86 @@
3591+
3592+ /* All fields are initialized by mem_zalloc(). */
3593+
3594++ if (chunk && srv_buffer_pool_shm_key) {
3595++ buf_shm_info_t* shm_info;
3596++
3597++ ut_a((byte*)chunk->blocks == (byte*)chunk->mem + sizeof(buf_shm_info_t));
3598++ shm_info = chunk->mem;
3599++
3600++ buf_pool->zip_hash = (hash_table_t*)((byte*)chunk->mem + shm_info->zip_hash_offset);
3601++
3602++ if(shm_info->is_new) {
3603++ shm_info->is_new = FALSE; /* initialization was finished */
3604++ } else {
3605++ buf_block_t* block = chunk->blocks;
3606++ buf_page_t* b;
3607++
3608++ /* shm_info->buf_pool_backup should be converted */
3609++ /* at buf_chunk_init(). So copy simply. */
3610++ buf_pool->flush_list = shm_info->buf_pool_backup.flush_list;
3611++ buf_pool->freed_page_clock = shm_info->buf_pool_backup.freed_page_clock;
3612++ buf_pool->free = shm_info->buf_pool_backup.free;
3613++ buf_pool->LRU = shm_info->buf_pool_backup.LRU;
3614++ buf_pool->LRU_old = shm_info->buf_pool_backup.LRU_old;
3615++ buf_pool->LRU_old_len = shm_info->buf_pool_backup.LRU_old_len;
3616++ buf_pool->unzip_LRU = shm_info->buf_pool_backup.unzip_LRU;
3617++ buf_pool->zip_clean = shm_info->buf_pool_backup.zip_clean;
3618++ for (i = 0; i < BUF_BUDDY_SIZES_MAX; i++) {
3619++ buf_pool->zip_free[i] = shm_info->buf_pool_backup.zip_free[i];
3620++ }
3621++
3622++ for (i = 0; i < chunk->size; i++, block++) {
3623++ if (buf_block_get_state(block)
3624++ == BUF_BLOCK_FILE_PAGE) {
3625++ ut_d(block->page.in_page_hash = TRUE);
3626++ HASH_INSERT(buf_page_t, hash, buf_pool->page_hash,
3627++ buf_page_address_fold(
3628++ block->page.space,
3629++ block->page.offset),
3630++ &block->page);
3631++ }
3632++ }
3633++
3634++ for (b = UT_LIST_GET_FIRST(buf_pool->zip_clean); b;
3635++ b = UT_LIST_GET_NEXT(zip_list, b)) {
3636++ ut_ad(!b->in_flush_list);
3637++ ut_ad(b->in_LRU_list);
3638++
3639++ ut_d(b->in_page_hash = TRUE);
3640++ HASH_INSERT(buf_page_t, hash, buf_pool->page_hash,
3641++ buf_page_address_fold(b->space, b->offset), b);
3642++ }
3643++
3644++ for (b = UT_LIST_GET_FIRST(buf_pool->flush_list); b;
3645++ b = UT_LIST_GET_NEXT(flush_list, b)) {
3646++ ut_ad(b->in_flush_list);
3647++ ut_ad(b->in_LRU_list);
3648++
3649++ switch (buf_page_get_state(b)) {
3650++ case BUF_BLOCK_ZIP_DIRTY:
3651++ ut_d(b->in_page_hash = TRUE);
3652++ HASH_INSERT(buf_page_t, hash, buf_pool->page_hash,
3653++ buf_page_address_fold(b->space,
3654++ b->offset), b);
3655++ break;
3656++ case BUF_BLOCK_FILE_PAGE:
3657++ /* uncompressed page */
3658++ break;
3659++ case BUF_BLOCK_ZIP_FREE:
3660++ case BUF_BLOCK_ZIP_PAGE:
3661++ case BUF_BLOCK_NOT_USED:
3662++ case BUF_BLOCK_READY_FOR_USE:
3663++ case BUF_BLOCK_MEMORY:
3664++ case BUF_BLOCK_REMOVE_HASH:
3665++ ut_error;
3666++ break;
3667++ }
3668++ }
3669++
3670++
3671++ }
3672++ }
3673++
3674+ mutex_exit(&buf_pool->LRU_list_mutex);
3675+ rw_lock_x_unlock(&buf_pool->page_hash_latch);
3676+ buf_pool_mutex_exit(buf_pool);
3677+@@ -1373,6 +1803,42 @@
3678+ buf_chunk_t* chunk;
3679+ buf_chunk_t* chunks;
3680+
3681++ if (srv_buffer_pool_shm_key) {
3682++ buf_shm_info_t* shm_info;
3683++
3684++ ut_a(buf_pool->n_chunks == 1);
3685++
3686++ chunk = buf_pool->chunks;
3687++ shm_info = chunk->mem;
3688++ ut_a((byte*)chunk->blocks == (byte*)chunk->mem + sizeof(buf_shm_info_t));
3689++
3690++ /* if opened, close shm. */
3691++ if (!shm_info->clean) {
3692++ /* validation the shared memory segment doesn't have unrecoverable contents. */
3693++ /* Currently, validation became not needed */
3694++ shm_info->reusable = TRUE;
3695++
3696++ memcpy(&(shm_info->buf_pool_backup), buf_pool, sizeof(buf_pool_t));
3697++ memcpy(&(shm_info->chunk_backup), chunk, sizeof(buf_chunk_t));
3698++
3699++ if (srv_fast_shutdown < 2) {
3700++ if (srv_buffer_pool_shm_checksum) {
3701++ shm_info->checksum =
3702++ ut_fold_binary_32(
3703++ (byte*)chunk->mem + sizeof(buf_shm_info_t),
3704++ chunk->mem_size - sizeof(buf_shm_info_t));
3705++ } else {
3706++ shm_info->checksum = BUF_NO_CHECKSUM_MAGIC;
3707++ }
3708++ shm_info->clean = TRUE;
3709++ }
3710++
3711++ fprintf(stderr,
3712++ "InnoDB: The shared memory was closed.\n");
3713++ }
3714++
3715++ os_shm_free(chunk->mem, chunk->mem_size);
3716++ } else {
3717+ chunks = buf_pool->chunks;
3718+ chunk = chunks + buf_pool->n_chunks;
3719+
3720+@@ -1381,10 +1847,13 @@
3721+ would fail at shutdown. */
3722+ os_mem_free_large(chunk->mem, chunk->mem_size);
3723+ }
3724++ }
3725+
3726+ mem_free(buf_pool->chunks);
3727+ hash_table_free(buf_pool->page_hash);
3728++ if (!srv_buffer_pool_shm_key) {
3729+ hash_table_free(buf_pool->zip_hash);
3730++ }
3731+ }
3732+
3733+ /********************************************************************//**
3734+@@ -1668,6 +2137,11 @@
3735+ //buf_pool_mutex_enter(buf_pool);
3736+ mutex_enter(&buf_pool->LRU_list_mutex);
3737+
3738++ if (srv_buffer_pool_shm_key) {
3739++ /* Cannot support shrink */
3740++ goto func_done;
3741++ }
3742++
3743+ shrink_again:
3744+ if (buf_pool->n_chunks <= 1) {
3745+
3746+@@ -1848,7 +2322,7 @@
3747+ zip_hash = hash_create(2 * buf_pool->curr_size);
3748+
3749+ HASH_MIGRATE(buf_pool->zip_hash, zip_hash, buf_page_t, hash,
3750+- BUF_POOL_ZIP_FOLD_BPAGE);
3751++ buf_pool, BUF_POOL_ZIP_FOLD_BPAGE);
3752+
3753+ hash_table_free(buf_pool->zip_hash);
3754+ buf_pool->zip_hash = zip_hash;
3755+@@ -2130,6 +2604,11 @@
3756+ ulint change_size;
3757+ ulint min_change_size = 1048576 * srv_buf_pool_instances;
3758+
3759++ if (srv_buffer_pool_shm_key) {
3760++ /* Cannot support resize */
3761++ return;
3762++ }
3763++
3764+ buf_pool_mutex_enter_all();
3765+
3766+ if (srv_buf_pool_old_size == srv_buf_pool_size) {
3767+diff -ruN a/storage/innobase/ha/hash0hash.c b/storage/innobase/ha/hash0hash.c
3768+--- a/storage/innobase/ha/hash0hash.c 2010-11-03 07:01:13.000000000 +0900
3769++++ b/storage/innobase/ha/hash0hash.c 2010-12-07 16:10:14.937749140 +0900
3770+@@ -133,6 +133,70 @@
3771+ }
3772+
3773+ /*************************************************************//**
3774++*/
3775++UNIV_INTERN
3776++ulint
3777++hash_create_needed(
3778++/*===============*/
3779++ ulint n)
3780++{
3781++ ulint prime;
3782++ ulint offset;
3783++
3784++ prime = ut_find_prime(n);
3785++
3786++ offset = (sizeof(hash_table_t) + 7) / 8;
3787++ offset *= 8;
3788++
3789++ return(offset + sizeof(hash_cell_t) * prime);
3790++}
3791++
3792++UNIV_INTERN
3793++void
3794++hash_create_init(
3795++/*=============*/
3796++ hash_table_t* table,
3797++ ulint n)
3798++{
3799++ ulint prime;
3800++ ulint offset;
3801++
3802++ prime = ut_find_prime(n);
3803++
3804++ offset = (sizeof(hash_table_t) + 7) / 8;
3805++ offset *= 8;
3806++
3807++ table->array = (hash_cell_t*)(((byte*)table) + offset);
3808++ table->n_cells = prime;
3809++# if defined UNIV_AHI_DEBUG || defined UNIV_DEBUG
3810++ table->adaptive = FALSE;
3811++# endif /* UNIV_AHI_DEBUG || UNIV_DEBUG */
3812++ table->n_mutexes = 0;
3813++ table->mutexes = NULL;
3814++ table->heaps = NULL;
3815++ table->heap = NULL;
3816++ ut_d(table->magic_n = HASH_TABLE_MAGIC_N);
3817++
3818++ /* Initialize the cell array */
3819++ hash_table_clear(table);
3820++}
3821++
3822++UNIV_INTERN
3823++void
3824++hash_create_reuse(
3825++/*==============*/
3826++ hash_table_t* table)
3827++{
3828++ ulint offset;
3829++
3830++ offset = (sizeof(hash_table_t) + 7) / 8;
3831++ offset *= 8;
3832++
3833++ table->array = (hash_cell_t*)(((byte*)table) + offset);
3834++ ut_ad(table->magic_n == HASH_TABLE_MAGIC_N);
3835++}
3836++
3837++/*************************************************************//**
3838+ Frees a hash table. */
3839+ UNIV_INTERN
3840+ void
3841+diff -ruN a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc
3842+--- a/storage/innobase/handler/ha_innodb.cc 2010-12-06 20:16:21.733263627 +0900
3843++++ b/storage/innobase/handler/ha_innodb.cc 2010-12-07 17:56:28.316139830 +0900
3844+@@ -194,6 +194,7 @@
3845+ static my_bool innobase_create_status_file = FALSE;
3846+ static my_bool innobase_stats_on_metadata = TRUE;
3847+ static my_bool innobase_use_sys_stats_table = FALSE;
3848++static my_bool innobase_buffer_pool_shm_checksum = TRUE;
3849+
3850+
3851+ static char* internal_innobase_data_file_path = NULL;
3852+@@ -2618,6 +2619,14 @@
3853+ srv_buf_pool_size = (ulint) innobase_buffer_pool_size;
3854+ srv_buf_pool_instances = (ulint) innobase_buffer_pool_instances;
3855+
3856++ if (srv_buffer_pool_shm_key && srv_buf_pool_instances > 1) {
3857++ fprintf(stderr,
3858++ "InnoDB: Warning: innodb_buffer_pool_shm_key cannot be used with several innodb_buffer_pool_instances.\n"
3859++ "InnoDB: innodb_buffer_pool_instances was set to 1.\n");
3860++ srv_buf_pool_instances = 1;
3861++ innobase_buffer_pool_instances = 1;
3862++ }
3863++
3864+ srv_mem_pool_size = (ulint) innobase_additional_mem_pool_size;
3865+
3866+ srv_n_file_io_threads = (ulint) innobase_file_io_threads;
3867+@@ -2634,6 +2643,7 @@
3868+ srv_use_doublewrite_buf = (ibool) innobase_use_doublewrite;
3869+ srv_use_checksums = (ibool) innobase_use_checksums;
3870+ srv_fast_checksum = (ibool) innobase_fast_checksum;
3871++ srv_buffer_pool_shm_checksum = (ibool) innobase_buffer_pool_shm_checksum;
3872+
3873+ #ifdef HAVE_LARGE_PAGES
3874+ if ((os_use_large_pages = (ibool) my_use_large_pages))
3875+@@ -11634,6 +11644,16 @@
3876+ "Number of buffer pool instances, set to higher value on high-end machines to increase scalability",
3877+ NULL, NULL, 1L, 1L, MAX_BUFFER_POOLS, 1L);
3878+
3879++static MYSQL_SYSVAR_UINT(buffer_pool_shm_key, srv_buffer_pool_shm_key,
3880++ PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY,
3881++ "[experimental] The key value of shared memory segment for the buffer pool. 0 (default) disables the feature.",
3882++ NULL, NULL, 0, 0, INT_MAX32, 0);
3883++
3884++static MYSQL_SYSVAR_BOOL(buffer_pool_shm_checksum, innobase_buffer_pool_shm_checksum,
3885++ PLUGIN_VAR_NOCMDARG | PLUGIN_VAR_READONLY,
3886++ "Enable buffer_pool_shm checksum validation (enabled by default).",
3887++ NULL, NULL, TRUE);
3888++
3889+ static MYSQL_SYSVAR_ULONG(commit_concurrency, innobase_commit_concurrency,
3890+ PLUGIN_VAR_RQCMDARG,
3891+ "Helps in performance tuning in heavily concurrent environments.",
3892+@@ -11915,6 +11935,8 @@
3893+ MYSQL_SYSVAR(autoextend_increment),
3894+ MYSQL_SYSVAR(buffer_pool_size),
3895+ MYSQL_SYSVAR(buffer_pool_instances),
3896++ MYSQL_SYSVAR(buffer_pool_shm_key),
3897++ MYSQL_SYSVAR(buffer_pool_shm_checksum),
3898+ MYSQL_SYSVAR(checksums),
3899+ MYSQL_SYSVAR(fast_checksum),
3900+ MYSQL_SYSVAR(commit_concurrency),
3901+diff -ruN a/storage/innobase/include/buf0buf.h b/storage/innobase/include/buf0buf.h
3902+--- a/storage/innobase/include/buf0buf.h 2010-12-06 20:16:21.778264552 +0900
3903++++ b/storage/innobase/include/buf0buf.h 2010-12-07 17:56:28.322749380 +0900
3904+@@ -36,6 +36,7 @@
3905+ #ifndef UNIV_HOTBACKUP
3906+ #include "ut0rbt.h"
3907+ #include "os0proc.h"
3908++#include "srv0srv.h"
3909+
3910+ /** @name Modes for buf_page_get_gen */
3911+ /* @{ */
3912+@@ -1520,9 +1521,12 @@
3913+ /**********************************************************************//**
3914+ Compute the hash fold value for blocks in buf_pool->zip_hash. */
3915+ /* @{ */
3916+-#define BUF_POOL_ZIP_FOLD_PTR(ptr) ((ulint) (ptr) / UNIV_PAGE_SIZE)
3917+-#define BUF_POOL_ZIP_FOLD(b) BUF_POOL_ZIP_FOLD_PTR((b)->frame)
3918+-#define BUF_POOL_ZIP_FOLD_BPAGE(b) BUF_POOL_ZIP_FOLD((buf_block_t*) (b))
3919++/* the fold should be relative when srv_buffer_pool_shm_key is enabled */
3920++#define BUF_POOL_ZIP_FOLD_PTR(bpool, ptr) (!srv_buffer_pool_shm_key\
3921++ ?((ulint) (ptr) / UNIV_PAGE_SIZE)\
3922++ :((ulint) ((byte*)ptr - (byte*)(buf_page_from_array(bpool, 0)->frame)) / UNIV_PAGE_SIZE))
3923++#define BUF_POOL_ZIP_FOLD(bpool, b) BUF_POOL_ZIP_FOLD_PTR(bpool, (b)->frame)
3924++#define BUF_POOL_ZIP_FOLD_BPAGE(bpool, b) BUF_POOL_ZIP_FOLD(bpool, (buf_block_t*) (b))
3925+ /* @} */
3926+
3927+ /** @brief The buffer pool statistics structure. */
3928+diff -ruN a/storage/innobase/include/hash0hash.h b/storage/innobase/include/hash0hash.h
3929+--- a/storage/innobase/include/hash0hash.h 2010-11-03 07:01:13.000000000 +0900
3930++++ b/storage/innobase/include/hash0hash.h 2010-12-07 17:56:28.324726446 +0900
3931+@@ -49,6 +49,28 @@
3932+ hash_create(
3933+ /*========*/
3934+ ulint n); /*!< in: number of array cells */
3935++
3936++/*************************************************************//**
3937++*/
3938++UNIV_INTERN
3939++ulint
3940++hash_create_needed(
3941++/*===============*/
3942++ ulint n);
3943++
3944++UNIV_INTERN
3945++void
3946++hash_create_init(
3947++/*=============*/
3948++ hash_table_t* table,
3949++ ulint n);
3950++
3951++UNIV_INTERN
3952++void
3953++hash_create_reuse(
3954++/*==============*/
3955++ hash_table_t* table);
3956++
3957+ #ifndef UNIV_HOTBACKUP
3958+ /*************************************************************//**
3959+ Creates a mutex array to protect a hash table. */
3960+@@ -306,7 +328,7 @@
3961+ /****************************************************************//**
3962+ Move all hash table entries from OLD_TABLE to NEW_TABLE. */
3963+
3964+-#define HASH_MIGRATE(OLD_TABLE, NEW_TABLE, NODE_TYPE, PTR_NAME, FOLD_FUNC) \
3965++#define HASH_MIGRATE(OLD_TABLE, NEW_TABLE, NODE_TYPE, PTR_NAME, BPOOL, FOLD_FUNC) \
3966+ do {\
3967+ ulint i2222;\
3968+ ulint cell_count2222;\
3969+@@ -318,7 +340,7 @@
3970+ \
3971+ while (node2222) {\
3972+ NODE_TYPE* next2222 = node2222->PTR_NAME;\
3973+- ulint fold2222 = FOLD_FUNC(node2222);\
3974++ ulint fold2222 = FOLD_FUNC(BPOOL, node2222);\
3975+ \
3976+ HASH_INSERT(NODE_TYPE, PTR_NAME, (NEW_TABLE),\
3977+ fold2222, node2222);\
3978+@@ -327,6 +349,33 @@
3979+ }\
3980+ }\
3981+ } while (0)
3982++
3983++/********************************************************************//**
3984++Align nodes with moving location.*/
3985++#define HASH_OFFSET(TABLE, NODE_TYPE, PTR_NAME, FADDR, FOFFSET, BOFFSET) \
3986++do {\
3987++ ulint i2222;\
3988++ ulint cell_count2222;\
3989++\
3990++ cell_count2222 = hash_get_n_cells(TABLE);\
3991++\
3992++ for (i2222 = 0; i2222 < cell_count2222; i2222++) {\
3993++ NODE_TYPE* node2222;\
3994++\
3995++ if ((TABLE)->array[i2222].node) \
3996++ (TABLE)->array[i2222].node = (void*)((byte*)(TABLE)->array[i2222].node \
3997++ + (((TABLE)->array[i2222].node > (void*)FADDR)?FOFFSET:BOFFSET));\
3998++ node2222 = HASH_GET_FIRST((TABLE), i2222);\
3999++\
4000++ while (node2222) {\
4001++ if (node2222->PTR_NAME) \
4002++ node2222->PTR_NAME = (void*)((byte*)(node2222->PTR_NAME) \
4003++ + ((((void*)node2222->PTR_NAME) > (void*)FADDR)?FOFFSET:BOFFSET));\
4004++\
4005++ node2222 = node2222->PTR_NAME;\
4006++ }\
4007++ }\
4008++} while (0)
4009+
4010+ /************************************************************//**
4011+ Gets the mutex index for a fold value in a hash table.
4012+diff -ruN a/storage/innobase/include/os0proc.h b/storage/innobase/include/os0proc.h
4013+--- a/storage/innobase/include/os0proc.h 2010-11-03 07:01:13.000000000 +0900
4014++++ b/storage/innobase/include/os0proc.h 2010-12-07 16:10:14.955718750 +0900
4015+@@ -32,6 +32,11 @@
4016+ #ifdef UNIV_LINUX
4017+ #include <sys/ipc.h>
4018+ #include <sys/shm.h>
4019++#else
4020++# if defined HAVE_SYS_IPC_H && HAVE_SYS_SHM_H
4021++#include <sys/ipc.h>
4022++#include <sys/shm.h>
4023++# endif
4024+ #endif
4025+
4026+ typedef void* os_process_t;
4027+@@ -70,6 +75,29 @@
4028+ ulint size); /*!< in: size returned by
4029+ os_mem_alloc_large() */
4030+
4031++
4032++/****************************************************************//**
4033++Allocates or attaches and reuses shared memory segment.
4034++The content is not cleared automatically.
4035++@return allocated memory */
4036++UNIV_INTERN
4037++void*
4038++os_shm_alloc(
4039++/*=========*/
4040++ ulint* n, /*!< in/out: number of bytes */
4041++ uint key,
4042++ ibool* is_new);
4043++
4044++/****************************************************************//**
4045++Detach shared memory segment. */
4046++UNIV_INTERN
4047++void
4048++os_shm_free(
4049++/*========*/
4050++ void *ptr, /*!< in: pointer returned by
4051++ os_shm_alloc() */
4052++ ulint size); /*!< in: size returned by
4053++ os_shm_alloc() */
4054+ #ifndef UNIV_NONINL
4055+ #include "os0proc.ic"
4056+ #endif
4057+diff -ruN a/storage/innobase/include/srv0srv.h b/storage/innobase/include/srv0srv.h
4058+--- a/storage/innobase/include/srv0srv.h 2010-12-04 20:20:28.016566697 +0900
4059++++ b/storage/innobase/include/srv0srv.h 2010-12-07 16:10:14.956717659 +0900
4060+@@ -170,6 +170,10 @@
4061+ extern ulint srv_mem_pool_size;
4062+ extern ulint srv_lock_table_size;
4063+
4064++extern uint srv_buffer_pool_shm_key;
4065++extern ibool srv_buffer_pool_shm_is_reused;
4066++extern ibool srv_buffer_pool_shm_checksum;
4067++
4068+ extern ibool srv_thread_concurrency_timer_based;
4069+
4070+ extern ulint srv_n_file_io_threads;
4071+diff -ruN a/storage/innobase/include/ut0lst.h b/storage/innobase/include/ut0lst.h
4072+--- a/storage/innobase/include/ut0lst.h 2010-11-03 07:01:13.000000000 +0900
4073++++ b/storage/innobase/include/ut0lst.h 2010-12-07 16:10:14.957785525 +0900
4074+@@ -257,5 +257,48 @@
4075+ ut_a(ut_list_node_313 == NULL); \
4076+ } while (0)
4077+
4078++/********************************************************************//**
4079++Align nodes with moving location.
4080++@param NAME the name of the list
4081++@param TYPE node type
4082++@param BASE base node (not a pointer to it)
4083++@param OFFSET offset moved */
4084++#define UT_LIST_OFFSET(NAME, TYPE, BASE, FADDR, FOFFSET, BOFFSET) \
4085++do { \
4086++ ulint ut_list_i_313; \
4087++ TYPE* ut_list_node_313; \
4088++ \
4089++ if ((BASE).start) \
4090++ (BASE).start = (void*)((byte*)((BASE).start) \
4091++ + (((void*)((BASE).start) > (void*)FADDR)?FOFFSET:BOFFSET));\
4092++ if ((BASE).end) \
4093++ (BASE).end = (void*)((byte*)((BASE).end) \
4094++ + (((void*)((BASE).end) > (void*)FADDR)?FOFFSET:BOFFSET));\
4095++ \
4096++ ut_list_node_313 = (BASE).start; \
4097++ \
4098++ for (ut_list_i_313 = (BASE).count; ut_list_i_313--; ) { \
4099++ ut_a(ut_list_node_313); \
4100++ if ((ut_list_node_313->NAME).prev) \
4101++ (ut_list_node_313->NAME).prev = (void*)((byte*)((ut_list_node_313->NAME).prev)\
4102++ + (((void*)((ut_list_node_313->NAME).prev) > (void*)FADDR)?FOFFSET:BOFFSET));\
4103++ if ((ut_list_node_313->NAME).next) \
4104++ (ut_list_node_313->NAME).next = (void*)((byte*)((ut_list_node_313->NAME).next)\
4105++ + (((void*)((ut_list_node_313->NAME).next)> (void*)FADDR)?FOFFSET:BOFFSET));\
4106++ ut_list_node_313 = (ut_list_node_313->NAME).next; \
4107++ } \
4108++ \
4109++ ut_a(ut_list_node_313 == NULL); \
4110++ \
4111++ ut_list_node_313 = (BASE).end; \
4112++ \
4113++ for (ut_list_i_313 = (BASE).count; ut_list_i_313--; ) { \
4114++ ut_a(ut_list_node_313); \
4115++ ut_list_node_313 = (ut_list_node_313->NAME).prev; \
4116++ } \
4117++ \
4118++ ut_a(ut_list_node_313 == NULL); \
4119++} while (0)
4120++
4121+ #endif
4122+
4123+diff -ruN a/storage/innobase/log/log0recv.c b/storage/innobase/log/log0recv.c
4124+--- a/storage/innobase/log/log0recv.c 2010-12-04 19:46:40.212513377 +0900
4125++++ b/storage/innobase/log/log0recv.c 2010-12-07 16:10:14.959785817 +0900
4126+@@ -2912,6 +2912,7 @@
4127+ /*==========================*/
4128+ {
4129+ ut_a(!recv_needed_recovery);
4130++ ut_a(!srv_buffer_pool_shm_is_reused);
4131+
4132+ recv_needed_recovery = TRUE;
4133+
4134+diff -ruN a/storage/innobase/os/os0proc.c b/storage/innobase/os/os0proc.c
4135+--- a/storage/innobase/os/os0proc.c 2010-11-03 07:01:13.000000000 +0900
4136++++ b/storage/innobase/os/os0proc.c 2010-12-07 16:10:14.960800123 +0900
4137+@@ -229,3 +229,173 @@
4138+ }
4139+ #endif
4140+ }
4141++
4142++/****************************************************************//**
4143++Allocates or attaches and reuses shared memory segment.
4144++The content is not cleared automatically.
4145++@return allocated memory */
4146++UNIV_INTERN
4147++void*
4148++os_shm_alloc(
4149++/*=========*/
4150++ ulint* n, /*!< in/out: number of bytes */
4151++ uint key,
4152++ ibool* is_new)
4153++{
4154++ void* ptr;
4155++#if defined HAVE_SYS_IPC_H && HAVE_SYS_SHM_H
4156++ ulint size;
4157++ int shmid;
4158++
4159++ *is_new = FALSE;
4160++ fprintf(stderr,
4161++ "InnoDB: The shared memory segment containing the buffer pool is: key %#x (%d).\n",
4162++ key, key);
4163++# if defined HAVE_LARGE_PAGES && defined UNIV_LINUX
4164++ if (!os_use_large_pages || !os_large_page_size) {
4165++ goto skip;
4166++ }
4167++
4168++ /* Align block size to os_large_page_size */
4169++ ut_ad(ut_is_2pow(os_large_page_size));
4170++ size = ut_2pow_round(*n + (os_large_page_size - 1),
4171++ os_large_page_size);
4172++
4173++ shmid = shmget((key_t)key, (size_t)size,
4174++ IPC_CREAT | IPC_EXCL | SHM_HUGETLB | SHM_R | SHM_W);
4175++ if (shmid < 0) {
4176++ if (errno == EEXIST) {
4177++ fprintf(stderr,
4178++ "InnoDB: HugeTLB: The shared memory segment exists.\n");
4179++ shmid = shmget((key_t)key, (size_t)size,
4180++ SHM_HUGETLB | SHM_R | SHM_W);
4181++ if (shmid < 0) {
4182++ fprintf(stderr,
4183++ "InnoDB: HugeTLB: Warning: Failed to allocate %lu bytes. (reuse) errno %d\n",
4184++ size, errno);
4185++ goto skip;
4186++ } else {
4187++ fprintf(stderr,
4188++ "InnoDB: HugeTLB: The existent shared memory segment is used.\n");
4189++ }
4190++ } else {
4191++ fprintf(stderr,
4192++ "InnoDB: HugeTLB: Warning: Failed to allocate %lu bytes. (new) errno %d\n",
4193++ size, errno);
4194++ goto skip;
4195++ }
4196++ } else {
4197++ *is_new = TRUE;
4198++ fprintf(stderr,
4199++ "InnoDB: HugeTLB: A new shared memory segment has been created .\n");
4200++ }
4201++
4202++ ptr = shmat(shmid, NULL, 0);
4203++ if (ptr == (void *)-1) {
4204++ fprintf(stderr,
4205++ "InnoDB: HugeTLB: Warning: Failed to attach shared memory segment, errno %d\n",
4206++ errno);
4207++ ptr = NULL;
4208++ }
4209++
4210++ if (ptr) {
4211++ *n = size;
4212++ os_fast_mutex_lock(&ut_list_mutex);
4213++ ut_total_allocated_memory += size;
4214++ os_fast_mutex_unlock(&ut_list_mutex);
4215++ UNIV_MEM_ALLOC(ptr, size);
4216++ return(ptr);
4217++ }
4218++skip:
4219++ *is_new = FALSE;
4220++# endif /* HAVE_LARGE_PAGES && defined UNIV_LINUX */
4221++# ifdef HAVE_GETPAGESIZE
4222++ size = getpagesize();
4223++# else
4224++ size = UNIV_PAGE_SIZE;
4225++# endif
4226++ /* Align block size to system page size */
4227++ ut_ad(ut_is_2pow(size));
4228++ size = *n = ut_2pow_round(*n + (size - 1), size);
4229++
4230++ shmid = shmget((key_t)key, (size_t)size,
4231++ IPC_CREAT | IPC_EXCL | SHM_R | SHM_W);
4232++ if (shmid < 0) {
4233++ if (errno == EEXIST) {
4234++ fprintf(stderr,
4235++ "InnoDB: A shared memory segment containing the buffer pool seems to already exist.\n");
4236++ shmid = shmget((key_t)key, (size_t)size,
4237++ SHM_R | SHM_W);
4238++ if (shmid < 0) {
4239++ fprintf(stderr,
4240++ "InnoDB: Warning: Failed to allocate %lu bytes. (reuse) errno %d\n",
4241++ size, errno);
4242++ ptr = NULL;
4243++ goto end;
4244++ } else {
4245++ fprintf(stderr,
4246++ "InnoDB: The existent shared memory segment is used.\n");
4247++ }
4248++ } else {
4249++ fprintf(stderr,
4250++ "InnoDB: Warning: Failed to allocate %lu bytes. (new) errno %d\n",
4251++ size, errno);
4252++ ptr = NULL;
4253++ goto end;
4254++ }
4255++ } else {
4256++ *is_new = TRUE;
4257++ fprintf(stderr,
4258++ "InnoDB: A new shared memory segment has been created.\n");
4259++ }
4260++
4261++ ptr = shmat(shmid, NULL, 0);
4262++ if (ptr == (void *)-1) {
4263++ fprintf(stderr,
4264++ "InnoDB: Warning: Failed to attach shared memory segment, errno %d\n",
4265++ errno);
4266++ ptr = NULL;
4267++ }
4268++
4269++ if (ptr) {
4270++ *n = size;
4271++ os_fast_mutex_lock(&ut_list_mutex);
4272++ ut_total_allocated_memory += size;
4273++ os_fast_mutex_unlock(&ut_list_mutex);
4274++ UNIV_MEM_ALLOC(ptr, size);
4275++ }
4276++end:
4277++#else /* HAVE_SYS_IPC_H && HAVE_SYS_SHM_H */
4278++ fprintf(stderr, "InnoDB: shared memory segment is not supported.\n");
4279++ ptr = NULL;
4280++#endif /* HAVE_SYS_IPC_H && HAVE_SYS_SHM_H */
4281++ return(ptr);
4282++}
4283++
4284++/****************************************************************//**
4285++Detach shared memory segment. */
4286++UNIV_INTERN
4287++void
4288++os_shm_free(
4289++/*========*/
4290++ void *ptr, /*!< in: pointer returned by
4291++ os_shm_alloc() */
4292++ ulint size) /*!< in: size returned by
4293++ os_shm_alloc() */
4294++{
4295++ os_fast_mutex_lock(&ut_list_mutex);
4296++ ut_a(ut_total_allocated_memory >= size);
4297++ os_fast_mutex_unlock(&ut_list_mutex);
4298++
4299++#if defined HAVE_SYS_IPC_H && HAVE_SYS_SHM_H
4300++ if (!shmdt(ptr)) {
4301++ os_fast_mutex_lock(&ut_list_mutex);
4302++ ut_a(ut_total_allocated_memory >= size);
4303++ ut_total_allocated_memory -= size;
4304++ os_fast_mutex_unlock(&ut_list_mutex);
4305++ UNIV_MEM_FREE(ptr, size);
4306++ }
4307++#else /* HAVE_SYS_IPC_H && HAVE_SYS_SHM_H */
4308++ fprintf(stderr, "InnoDB: shared memory segment is not supported.\n");
4309++#endif /* HAVE_SYS_IPC_H && HAVE_SYS_SHM_H */
4310++}
4311+diff -ruN a/storage/innobase/srv/srv0srv.c b/storage/innobase/srv/srv0srv.c
4312+--- a/storage/innobase/srv/srv0srv.c 2010-12-04 20:20:44.687550693 +0900
4313++++ b/storage/innobase/srv/srv0srv.c 2010-12-07 16:10:14.962785720 +0900
4314+@@ -231,6 +231,11 @@
4315+ UNIV_INTERN ulint srv_mem_pool_size = ULINT_MAX;
4316+ UNIV_INTERN ulint srv_lock_table_size = ULINT_MAX;
4317+
4318++/* key value for shm */
4319++UNIV_INTERN uint srv_buffer_pool_shm_key = 0;
4320++UNIV_INTERN ibool srv_buffer_pool_shm_is_reused = FALSE;
4321++UNIV_INTERN ibool srv_buffer_pool_shm_checksum = TRUE;
4322++
4323+ /* This parameter is deprecated. Use srv_n_io_[read|write]_threads
4324+ instead. */
4325+ UNIV_INTERN ulint srv_n_file_io_threads = ULINT_MAX;
4326+diff -ruN a/storage/innobase/srv/srv0start.c b/storage/innobase/srv/srv0start.c
4327+--- a/storage/innobase/srv/srv0start.c 2010-12-04 20:19:29.806482628 +0900
4328++++ b/storage/innobase/srv/srv0start.c 2010-12-07 16:10:14.964785346 +0900
4329+@@ -1759,6 +1759,8 @@
4330+ Note that this is not as heavy weight as it seems. At
4331+ this point there will be only ONE page in the buf_LRU
4332+ and there must be no page in the buf_flush list. */
4333++ /* buffer_pool_shm should not be reused when recovery was needed. */
4334++ if (!srv_buffer_pool_shm_is_reused)
4335+ buf_pool_invalidate();
4336+
4337+ /* We always try to do a recovery, even if the database had
4338
4339=== renamed file 'innodb_buffer_pool_shm.patch' => 'innodb_buffer_pool_shm.patch.moved'
4340=== added file 'innodb_deadlock_count.patch'
4341--- innodb_deadlock_count.patch 1970-01-01 00:00:00 +0000
4342+++ innodb_deadlock_count.patch 2011-01-10 13:15:57 +0000
4343@@ -0,0 +1,71 @@
4344+# name : innodb_deadlock_count.patch
4345+# introduced : 11 or before
4346+# maintainer : Yasufumi
4347+#
4348+#!!! notice !!!
4349+# Any small change to this file in the main branch
4350+# should be done or reviewed by the maintainer!
4351+diff -ruN a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc
4352+--- a/storage/innobase/handler/ha_innodb.cc 2010-12-04 16:09:53.145500265 +0900
4353++++ b/storage/innobase/handler/ha_innodb.cc 2010-12-04 16:10:24.605515894 +0900
4354+@@ -665,6 +665,8 @@
4355+ (char*) &export_vars.innodb_dblwr_pages_written, SHOW_LONG},
4356+ {"dblwr_writes",
4357+ (char*) &export_vars.innodb_dblwr_writes, SHOW_LONG},
4358++ {"deadlocks",
4359++ (char*) &export_vars.innodb_deadlocks, SHOW_LONG},
4360+ {"dict_tables",
4361+ (char*) &export_vars.innodb_dict_tables, SHOW_LONG},
4362+ {"have_atomic_builtins",
4363+diff -ruN a/storage/innobase/include/lock0lock.h b/storage/innobase/include/lock0lock.h
4364+--- a/storage/innobase/include/lock0lock.h 2010-11-03 07:01:13.000000000 +0900
4365++++ b/storage/innobase/include/lock0lock.h 2010-12-04 16:10:24.605515894 +0900
4366+@@ -43,6 +43,7 @@
4367+ #endif /* UNIV_DEBUG */
4368+ /* Buffer for storing information about the most recent deadlock error */
4369+ extern FILE* lock_latest_err_file;
4370++extern ulint srv_n_lock_deadlock_count;
4371+
4372+ /*********************************************************************//**
4373+ Gets the size of a lock struct.
4374+diff -ruN a/storage/innobase/include/srv0srv.h b/storage/innobase/include/srv0srv.h
4375+--- a/storage/innobase/include/srv0srv.h 2010-12-04 15:55:21.378480843 +0900
4376++++ b/storage/innobase/include/srv0srv.h 2010-12-04 16:10:24.606550983 +0900
4377+@@ -746,6 +746,7 @@
4378+ ulint innodb_buffer_pool_read_ahead_evicted;/*!< srv_read_ahead evicted*/
4379+ ulint innodb_dblwr_pages_written; /*!< srv_dblwr_pages_written */
4380+ ulint innodb_dblwr_writes; /*!< srv_dblwr_writes */
4381++ ulint innodb_deadlocks;
4382+ ibool innodb_have_atomic_builtins; /*!< HAVE_ATOMIC_BUILTINS */
4383+ ulint innodb_log_waits; /*!< srv_log_waits */
4384+ ulint innodb_log_write_requests; /*!< srv_log_write_requests */
4385+diff -ruN a/storage/innobase/lock/lock0lock.c b/storage/innobase/lock/lock0lock.c
4386+--- a/storage/innobase/lock/lock0lock.c 2010-12-03 17:49:11.609953956 +0900
4387++++ b/storage/innobase/lock/lock0lock.c 2010-12-04 16:10:24.608513889 +0900
4388+@@ -3328,6 +3328,7 @@
4389+ break;
4390+
4391+ case LOCK_VICTIM_IS_START:
4392++ srv_n_lock_deadlock_count++;
4393+ fputs("*** WE ROLL BACK TRANSACTION (2)\n",
4394+ lock_latest_err_file);
4395+ break;
4396+diff -ruN a/storage/innobase/srv/srv0srv.c b/storage/innobase/srv/srv0srv.c
4397+--- a/storage/innobase/srv/srv0srv.c 2010-12-04 15:57:13.069513371 +0900
4398++++ b/storage/innobase/srv/srv0srv.c 2010-12-04 16:10:24.610593039 +0900
4399+@@ -462,6 +462,7 @@
4400+ static ulint srv_n_rows_deleted_old = 0;
4401+ static ulint srv_n_rows_read_old = 0;
4402+
4403++UNIV_INTERN ulint srv_n_lock_deadlock_count = 0;
4404+ UNIV_INTERN ulint srv_n_lock_wait_count = 0;
4405+ UNIV_INTERN ulint srv_n_lock_wait_current_count = 0;
4406+ UNIV_INTERN ib_int64_t srv_n_lock_wait_time = 0;
4407+@@ -2237,6 +2238,7 @@
4408+ export_vars.innodb_buffer_pool_pages_data = LRU_len;
4409+ export_vars.innodb_buffer_pool_pages_dirty = flush_list_len;
4410+ export_vars.innodb_buffer_pool_pages_free = free_len;
4411++ export_vars.innodb_deadlocks = srv_n_lock_deadlock_count;
4412+ #ifdef UNIV_DEBUG
4413+ export_vars.innodb_buffer_pool_pages_latched
4414+ = buf_get_latched_pages_number();
4415
4416=== renamed file 'innodb_deadlock_count.patch' => 'innodb_deadlock_count.patch.moved'
4417=== added file 'innodb_dict_size_limit.patch'
4418--- innodb_dict_size_limit.patch 1970-01-01 00:00:00 +0000
4419+++ innodb_dict_size_limit.patch 2011-01-10 13:15:57 +0000
4420@@ -0,0 +1,446 @@
4421+# name : innodb_dict_size_limit.patch
4422+# introduced : 11 or before
4423+# maintainer : Yasufumi
4424+#
4425+#!!! notice !!!
4426+# Any small change to this file in the main branch
4427+# should be done or reviewed by the maintainer!
4428+diff -ruN a/storage/innobase/btr/btr0sea.c b/storage/innobase/btr/btr0sea.c
4429+--- a/storage/innobase/btr/btr0sea.c 2010-11-03 07:01:13.000000000 +0900
4430++++ b/storage/innobase/btr/btr0sea.c 2010-12-03 15:45:47.503988924 +0900
4431+@@ -1185,6 +1185,132 @@
4432+ mem_free(folds);
4433+ }
4434+
4435++/************************************************************************
4436++Drops a page hash index based on index */
4437++UNIV_INTERN
4438++void
4439++btr_search_drop_page_hash_index_on_index(
4440++/*=====================================*/
4441++ dict_index_t* index) /* in: record descriptor */
4442++{
4443++ buf_page_t* bpage;
4444++ hash_table_t* table;
4445++ buf_block_t* block;
4446++ ulint n_fields;
4447++ ulint n_bytes;
4448++ const page_t* page;
4449++ const rec_t* rec;
4450++ ulint fold;
4451++ ulint prev_fold;
4452++ index_id_t index_id;
4453++ ulint n_cached;
4454++ ulint n_recs;
4455++ ulint* folds;
4456++ ulint i, j;
4457++ mem_heap_t* heap = NULL;
4458++ ulint* offsets;
4459++
4460++ rw_lock_x_lock(&btr_search_latch);
4461++ buf_pool_mutex_enter_all();
4462++
4463++ table = btr_search_sys->hash_index;
4464++
4465++ for (j = 0; j < srv_buf_pool_instances; j++) {
4466++ buf_pool_t* buf_pool;
4467++
4468++ buf_pool = buf_pool_from_array(j);
4469++
4470++ bpage = UT_LIST_GET_LAST(buf_pool->LRU);
4471++
4472++ while (bpage != NULL) {
4473++ block = (buf_block_t*) bpage;
4474++ if (block->index == index && block->is_hashed) {
4475++ page = block->frame;
4476++
4477++ /* from btr_search_drop_page_hash_index() */
4478++ n_fields = block->curr_n_fields;
4479++ n_bytes = block->curr_n_bytes;
4480++
4481++ ut_a(n_fields + n_bytes > 0);
4482++
4483++ n_recs = page_get_n_recs(page);
4484++
4485++ /* Calculate and cache fold values into an array for fast deletion
4486++ from the hash index */
4487++
4488++ folds = mem_alloc(n_recs * sizeof(ulint));
4489++
4490++ n_cached = 0;
4491++
4492++ rec = page_get_infimum_rec(page);
4493++ rec = page_rec_get_next_low(rec, page_is_comp(page));
4494++
4495++ index_id = btr_page_get_index_id(page);
4496++
4497++ ut_a(index_id == index->id);
4498++
4499++ prev_fold = 0;
4500++
4501++ offsets = NULL;
4502++
4503++ while (!page_rec_is_supremum(rec)) {
4504++ offsets = rec_get_offsets(rec, index, offsets,
4505++ n_fields + (n_bytes > 0), &heap);
4506++ ut_a(rec_offs_n_fields(offsets) == n_fields + (n_bytes > 0));
4507++ fold = rec_fold(rec, offsets, n_fields, n_bytes, index_id);
4508++
4509++ if (fold == prev_fold && prev_fold != 0) {
4510++
4511++ goto next_rec;
4512++ }
4513++
4514++ /* Remove all hash nodes pointing to this page from the
4515++ hash chain */
4516++
4517++ folds[n_cached] = fold;
4518++ n_cached++;
4519++next_rec:
4520++ rec = page_rec_get_next_low(rec, page_rec_is_comp(rec));
4521++ prev_fold = fold;
4522++ }
4523++
4524++ for (i = 0; i < n_cached; i++) {
4525++
4526++ ha_remove_all_nodes_to_page(table, folds[i], page);
4527++ }
4528++
4529++ ut_a(index->search_info->ref_count > 0);
4530++ index->search_info->ref_count--;
4531++
4532++ block->is_hashed = FALSE;
4533++ block->index = NULL;
4534++
4535++#if defined UNIV_AHI_DEBUG || defined UNIV_DEBUG
4536++ if (UNIV_UNLIKELY(block->n_pointers)) {
4537++ /* Corruption */
4538++ ut_print_timestamp(stderr);
4539++ fprintf(stderr,
4540++" InnoDB: Corruption of adaptive hash index. After dropping\n"
4541++"InnoDB: the hash index to a page of %s, still %lu hash nodes remain.\n",
4542++ index->name, (ulong) block->n_pointers);
4543++ }
4544++#endif /* UNIV_AHI_DEBUG || UNIV_DEBUG */
4545++
4546++ mem_free(folds);
4547++ }
4548++
4549++ bpage = UT_LIST_GET_PREV(LRU, bpage);
4550++ }
4551++ }
4552++
4553++ buf_pool_mutex_exit_all();
4554++ rw_lock_x_unlock(&btr_search_latch);
4555++
4556++ if (UNIV_LIKELY_NULL(heap)) {
4557++ mem_heap_free(heap);
4558++ }
4559++}
4560++
4561+ /********************************************************************//**
4562+ Drops a page hash index when a page is freed from a fseg to the file system.
4563+ Drops possible hash index if the page happens to be in the buffer pool. */
4564+diff -ruN a/storage/innobase/dict/dict0boot.c b/storage/innobase/dict/dict0boot.c
4565+--- a/storage/innobase/dict/dict0boot.c 2010-11-03 07:01:13.000000000 +0900
4566++++ b/storage/innobase/dict/dict0boot.c 2010-12-03 15:45:47.503988924 +0900
4567+@@ -284,6 +284,7 @@
4568+ system tables */
4569+ /*-------------------------*/
4570+ table = dict_mem_table_create("SYS_TABLES", DICT_HDR_SPACE, 8, 0);
4571++ table->n_mysql_handles_opened = 1; /* for pin */
4572+
4573+ dict_mem_table_add_col(table, heap, "NAME", DATA_BINARY, 0, 0);
4574+ dict_mem_table_add_col(table, heap, "ID", DATA_BINARY, 0, 0);
4575+@@ -336,6 +337,7 @@
4576+
4577+ /*-------------------------*/
4578+ table = dict_mem_table_create("SYS_COLUMNS", DICT_HDR_SPACE, 7, 0);
4579++ table->n_mysql_handles_opened = 1; /* for pin */
4580+
4581+ dict_mem_table_add_col(table, heap, "TABLE_ID", DATA_BINARY, 0, 0);
4582+ dict_mem_table_add_col(table, heap, "POS", DATA_INT, 0, 4);
4583+@@ -368,6 +370,7 @@
4584+
4585+ /*-------------------------*/
4586+ table = dict_mem_table_create("SYS_INDEXES", DICT_HDR_SPACE, 7, 0);
4587++ table->n_mysql_handles_opened = 1; /* for pin */
4588+
4589+ dict_mem_table_add_col(table, heap, "TABLE_ID", DATA_BINARY, 0, 0);
4590+ dict_mem_table_add_col(table, heap, "ID", DATA_BINARY, 0, 0);
4591+@@ -413,6 +416,7 @@
4592+
4593+ /*-------------------------*/
4594+ table = dict_mem_table_create("SYS_FIELDS", DICT_HDR_SPACE, 3, 0);
4595++ table->n_mysql_handles_opened = 1; /* for pin */
4596+
4597+ dict_mem_table_add_col(table, heap, "INDEX_ID", DATA_BINARY, 0, 0);
4598+ dict_mem_table_add_col(table, heap, "POS", DATA_INT, 0, 4);
4599+diff -ruN a/storage/innobase/dict/dict0crea.c b/storage/innobase/dict/dict0crea.c
4600+--- a/storage/innobase/dict/dict0crea.c 2010-11-03 07:01:13.000000000 +0900
4601++++ b/storage/innobase/dict/dict0crea.c 2010-12-03 15:45:47.521955810 +0900
4602+@@ -1210,6 +1210,9 @@
4603+ /* Foreign constraint system tables have already been
4604+ created, and they are ok */
4605+
4606++ table1->n_mysql_handles_opened = 1; /* for pin */
4607++ table2->n_mysql_handles_opened = 1; /* for pin */
4608++
4609+ mutex_exit(&(dict_sys->mutex));
4610+
4611+ return(DB_SUCCESS);
4612+@@ -1291,6 +1294,11 @@
4613+
4614+ trx_commit_for_mysql(trx);
4615+
4616++ table1 = dict_table_get_low("SYS_FOREIGN");
4617++ table2 = dict_table_get_low("SYS_FOREIGN_COLS");
4618++ table1->n_mysql_handles_opened = 1; /* for pin */
4619++ table2->n_mysql_handles_opened = 1; /* for pin */
4620++
4621+ row_mysql_unlock_data_dictionary(trx);
4622+
4623+ trx_free_for_mysql(trx);
4624+diff -ruN a/storage/innobase/dict/dict0dict.c b/storage/innobase/dict/dict0dict.c
4625+--- a/storage/innobase/dict/dict0dict.c 2010-11-03 07:01:13.000000000 +0900
4626++++ b/storage/innobase/dict/dict0dict.c 2010-12-03 15:45:47.525953769 +0900
4627+@@ -625,6 +625,8 @@
4628+
4629+ table = dict_table_get_on_id_low(table_id);
4630+
4631++ dict_table_LRU_trim(table);
4632++
4633+ mutex_exit(&(dict_sys->mutex));
4634+
4635+ return(table);
4636+@@ -743,6 +745,8 @@
4637+ table->n_mysql_handles_opened++;
4638+ }
4639+
4640++ dict_table_LRU_trim(table);
4641++
4642+ mutex_exit(&(dict_sys->mutex));
4643+
4644+ if (table != NULL) {
4645+@@ -1256,6 +1260,64 @@
4646+ dict_mem_table_free(table);
4647+ }
4648+
4649++/**************************************************************************
4650++Frees tables from the end of table_LRU if the dictionary cache occupies
4651++too much space. */
4652++UNIV_INTERN
4653++void
4654++dict_table_LRU_trim(
4655++/*================*/
4656++ dict_table_t* self)
4657++{
4658++ dict_table_t* table;
4659++ dict_table_t* prev_table;
4660++ dict_foreign_t* foreign;
4661++ ulint n_removed;
4662++ ulint n_have_parent;
4663++ ulint cached_foreign_tables;
4664++
4665++#ifdef UNIV_SYNC_DEBUG
4666++ ut_ad(mutex_own(&(dict_sys->mutex)));
4667++#endif /* UNIV_SYNC_DEBUG */
4668++
4669++retry:
4670++ n_removed = n_have_parent = 0;
4671++ table = UT_LIST_GET_LAST(dict_sys->table_LRU);
4672++
4673++ while ( srv_dict_size_limit && table
4674++ && ((dict_sys->table_hash->n_cells
4675++ + dict_sys->table_id_hash->n_cells) * sizeof(hash_cell_t)
4676++ + dict_sys->size) > srv_dict_size_limit ) {
4677++ prev_table = UT_LIST_GET_PREV(table_LRU, table);
4678++
4679++ if (table == self || table->n_mysql_handles_opened)
4680++ goto next_loop;
4681++
4682++ cached_foreign_tables = 0;
4683++ foreign = UT_LIST_GET_FIRST(table->foreign_list);
4684++ while (foreign != NULL) {
4685++ if (foreign->referenced_table)
4686++ cached_foreign_tables++;
4687++ foreign = UT_LIST_GET_NEXT(foreign_list, foreign);
4688++ }
4689++
4690++ if (cached_foreign_tables == 0) {
4691++ dict_table_remove_from_cache(table);
4692++ n_removed++;
4693++ } else {
4694++ n_have_parent++;
4695++ }
4696++next_loop:
4697++ table = prev_table;
4698++ }
4699++
4700++ if ( srv_dict_size_limit && n_have_parent && n_removed
4701++ && ((dict_sys->table_hash->n_cells
4702++ + dict_sys->table_id_hash->n_cells) * sizeof(hash_cell_t)
4703++ + dict_sys->size) > srv_dict_size_limit )
4704++ goto retry;
4705++}
4706++
4707+ /****************************************************************//**
4708+ If the given column name is reserved for InnoDB system columns, return
4709+ TRUE.
4710+@@ -1719,6 +1781,11 @@
4711+ ut_ad(index->magic_n == DICT_INDEX_MAGIC_N);
4712+ ut_ad(mutex_own(&(dict_sys->mutex)));
4713+
4714++ /* remove all entry of the index from adaptive hash index,
4715++ because removing from adaptive hash index needs dict_index */
4716++ if (btr_search_enabled && srv_dict_size_limit)
4717++ btr_search_drop_page_hash_index_on_index(index);
4718++
4719+ /* We always create search info whether or not adaptive
4720+ hash index is enabled or not. */
4721+ info = index->search_info;
4722+diff -ruN a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc
4723+--- a/storage/innobase/handler/ha_innodb.cc 2010-12-03 15:43:57.294986852 +0900
4724++++ b/storage/innobase/handler/ha_innodb.cc 2010-12-03 15:45:47.534959966 +0900
4725+@@ -653,6 +653,8 @@
4726+ (char*) &export_vars.innodb_dblwr_pages_written, SHOW_LONG},
4727+ {"dblwr_writes",
4728+ (char*) &export_vars.innodb_dblwr_writes, SHOW_LONG},
4729++ {"dict_tables",
4730++ (char*) &export_vars.innodb_dict_tables, SHOW_LONG},
4731+ {"have_atomic_builtins",
4732+ (char*) &export_vars.innodb_have_atomic_builtins, SHOW_BOOL},
4733+ {"log_waits",
4734+@@ -11537,6 +11539,11 @@
4735+ "Number of extra user rollback segments which are used in a round-robin fashion.",
4736+ NULL, NULL, 127, 0, 127, 0);
4737+
4738++static MYSQL_SYSVAR_ULONG(dict_size_limit, srv_dict_size_limit,
4739++ PLUGIN_VAR_RQCMDARG,
4740++ "Limit the allocated memory for dictionary cache. (0: unlimited)",
4741++ NULL, NULL, 0, 0, LONG_MAX, 0);
4742++
4743+ static struct st_mysql_sys_var* innobase_system_variables[]= {
4744+ MYSQL_SYSVAR(additional_mem_pool_size),
4745+ MYSQL_SYSVAR(autoextend_increment),
4746+@@ -11605,6 +11612,7 @@
4747+ MYSQL_SYSVAR(flush_log_at_trx_commit_session),
4748+ MYSQL_SYSVAR(enable_unsafe_group_commit),
4749+ MYSQL_SYSVAR(extra_rsegments),
4750++ MYSQL_SYSVAR(dict_size_limit),
4751+ MYSQL_SYSVAR(use_sys_malloc),
4752+ MYSQL_SYSVAR(use_native_aio),
4753+ MYSQL_SYSVAR(change_buffering),
4754+diff -ruN a/storage/innobase/ibuf/ibuf0ibuf.c b/storage/innobase/ibuf/ibuf0ibuf.c
4755+--- a/storage/innobase/ibuf/ibuf0ibuf.c 2010-12-03 15:18:48.889024455 +0900
4756++++ b/storage/innobase/ibuf/ibuf0ibuf.c 2010-12-03 15:45:47.553025057 +0900
4757+@@ -578,6 +578,7 @@
4758+
4759+ /* Use old-style record format for the insert buffer. */
4760+ table = dict_mem_table_create(IBUF_TABLE_NAME, IBUF_SPACE_ID, 1, 0);
4761++ table->n_mysql_handles_opened = 1; /* for pin */
4762+
4763+ dict_mem_table_add_col(table, heap, "DUMMY_COLUMN", DATA_BINARY, 0, 0);
4764+
4765+diff -ruN a/storage/innobase/include/btr0sea.h b/storage/innobase/include/btr0sea.h
4766+--- a/storage/innobase/include/btr0sea.h 2010-11-03 07:01:13.000000000 +0900
4767++++ b/storage/innobase/include/btr0sea.h 2010-12-03 15:45:47.555024229 +0900
4768+@@ -140,6 +140,13 @@
4769+ s- or x-latched, or an index page
4770+ for which we know that
4771+ block->buf_fix_count == 0 */
4772++/************************************************************************
4773++Drops a page hash index based on index */
4774++UNIV_INTERN
4775++void
4776++btr_search_drop_page_hash_index_on_index(
4777++/*=====================================*/
4778++ dict_index_t* index); /* in: record descriptor */
4779+ /********************************************************************//**
4780+ Drops a page hash index when a page is freed from a fseg to the file system.
4781+ Drops possible hash index if the page happens to be in the buffer pool. */
4782+diff -ruN a/storage/innobase/include/dict0dict.h b/storage/innobase/include/dict0dict.h
4783+--- a/storage/innobase/include/dict0dict.h 2010-11-03 07:01:13.000000000 +0900
4784++++ b/storage/innobase/include/dict0dict.h 2010-12-03 15:45:47.558024515 +0900
4785+@@ -1158,6 +1158,12 @@
4786+ /*====================================*/
4787+ dict_table_t* table, /*!< in: table */
4788+ const char* name); /*!< in: name of the index to find */
4789++
4790++UNIV_INTERN
4791++void
4792++dict_table_LRU_trim(
4793++/*================*/
4794++ dict_table_t* self);
4795+ /* Buffers for storing detailed information about the latest foreign key
4796+ and unique key errors */
4797+ extern FILE* dict_foreign_err_file;
4798+diff -ruN a/storage/innobase/include/dict0dict.ic b/storage/innobase/include/dict0dict.ic
4799+--- a/storage/innobase/include/dict0dict.ic 2010-11-03 07:01:13.000000000 +0900
4800++++ b/storage/innobase/include/dict0dict.ic 2010-12-03 15:45:47.560024398 +0900
4801+@@ -824,6 +824,13 @@
4802+ HASH_SEARCH(name_hash, dict_sys->table_hash, table_fold,
4803+ dict_table_t*, table, ut_ad(table->cached),
4804+ !strcmp(table->name, table_name));
4805++
4806++ /* make young in table_LRU */
4807++ if (table) {
4808++ UT_LIST_REMOVE(table_LRU, dict_sys->table_LRU, table);
4809++ UT_LIST_ADD_FIRST(table_LRU, dict_sys->table_LRU, table);
4810++ }
4811++
4812+ return(table);
4813+ }
4814+
4815+@@ -877,6 +884,12 @@
4816+ table = dict_load_table_on_id(table_id);
4817+ }
4818+
4819++ /* make young in table_LRU */
4820++ if (table) {
4821++ UT_LIST_REMOVE(table_LRU, dict_sys->table_LRU, table);
4822++ UT_LIST_ADD_FIRST(table_LRU, dict_sys->table_LRU, table);
4823++ }
4824++
4825+ ut_ad(!table || table->cached);
4826+
4827+ /* TODO: should get the type information from MySQL */
4828+diff -ruN a/storage/innobase/include/srv0srv.h b/storage/innobase/include/srv0srv.h
4829+--- a/storage/innobase/include/srv0srv.h 2010-12-03 15:43:57.297067100 +0900
4830++++ b/storage/innobase/include/srv0srv.h 2010-12-03 15:45:47.562024404 +0900
4831+@@ -227,7 +227,7 @@
4832+ extern ulint srv_adaptive_checkpoint;
4833+
4834+ extern ulint srv_extra_rsegments;
4835+-
4836++extern ulint srv_dict_size_limit;
4837+ /*-------------------------------------------*/
4838+
4839+ extern ulint srv_n_rows_inserted;
4840+@@ -697,6 +697,7 @@
4841+ ulint innodb_data_writes; /*!< I/O write requests */
4842+ ulint innodb_data_written; /*!< Data bytes written */
4843+ ulint innodb_data_reads; /*!< I/O read requests */
4844++ ulint innodb_dict_tables;
4845+ ulint innodb_buffer_pool_pages_total; /*!< Buffer pool size */
4846+ ulint innodb_buffer_pool_pages_data; /*!< Data pages */
4847+ ulint innodb_buffer_pool_pages_dirty; /*!< Dirty data pages */
4848+diff -ruN a/storage/innobase/srv/srv0srv.c b/storage/innobase/srv/srv0srv.c
4849+--- a/storage/innobase/srv/srv0srv.c 2010-12-03 15:43:57.301024390 +0900
4850++++ b/storage/innobase/srv/srv0srv.c 2010-12-03 15:45:47.565023830 +0900
4851+@@ -411,6 +411,7 @@
4852+ UNIV_INTERN ulint srv_adaptive_checkpoint = 0; /* 0: none 1: reflex 2: estimate */
4853+
4854+ UNIV_INTERN ulint srv_extra_rsegments = 127; /* extra rseg for users */
4855++UNIV_INTERN ulint srv_dict_size_limit = 0;
4856+ /*-------------------------------------------*/
4857+ UNIV_INTERN ulong srv_n_spin_wait_rounds = 30;
4858+ UNIV_INTERN ulong srv_n_free_tickets_to_enter = 500;
4859+@@ -2179,6 +2180,7 @@
4860+ export_vars.innodb_data_reads = os_n_file_reads;
4861+ export_vars.innodb_data_writes = os_n_file_writes;
4862+ export_vars.innodb_data_written = srv_data_written;
4863++ export_vars.innodb_dict_tables= (dict_sys ? UT_LIST_GET_LEN(dict_sys->table_LRU) : 0);
4864+ export_vars.innodb_buffer_pool_read_requests = stat.n_page_gets;
4865+ export_vars.innodb_buffer_pool_write_requests
4866+ = srv_buf_pool_write_requests;
4867
4868=== renamed file 'innodb_dict_size_limit.patch' => 'innodb_dict_size_limit.patch.moved'
4869=== added file 'innodb_expand_import.patch'
4870--- innodb_expand_import.patch 1970-01-01 00:00:00 +0000
4871+++ innodb_expand_import.patch 2011-01-10 13:15:57 +0000
4872@@ -0,0 +1,561 @@
4873+# name : innodb_expand_import.patch
4874+# introduced : 11 or before
4875+# maintainer : Yasufumi
4876+#
4877+#!!! notice !!!
4878+# Any small change to this file in the main branch
4879+# should be done or reviewed by the maintainer!
4880+diff -ruN a/storage/innobase/fil/fil0fil.c b/storage/innobase/fil/fil0fil.c
4881+--- a/storage/innobase/fil/fil0fil.c 2010-12-03 15:09:51.274957577 +0900
4882++++ b/storage/innobase/fil/fil0fil.c 2010-12-03 15:52:23.553986552 +0900
4883+@@ -40,6 +40,12 @@
4884+ #include "dict0dict.h"
4885+ #include "page0page.h"
4886+ #include "page0zip.h"
4887++#include "trx0trx.h"
4888++#include "trx0sys.h"
4889++#include "pars0pars.h"
4890++#include "row0mysql.h"
4891++#include "row0row.h"
4892++#include "que0que.h"
4893+ #ifndef UNIV_HOTBACKUP
4894+ # include "buf0lru.h"
4895+ # include "ibuf0ibuf.h"
4896+@@ -3050,7 +3056,7 @@
4897+
4898+ file = os_file_create_simple_no_error_handling(
4899+ innodb_file_data_key, filepath, OS_FILE_OPEN,
4900+- OS_FILE_READ_ONLY, &success);
4901++ OS_FILE_READ_WRITE, &success);
4902+ if (!success) {
4903+ /* The following call prints an error message */
4904+ os_file_get_last_error(TRUE);
4905+@@ -3097,6 +3103,466 @@
4906+ space_id = fsp_header_get_space_id(page);
4907+ space_flags = fsp_header_get_flags(page);
4908+
4909++ if (srv_expand_import
4910++ && (space_id != id || space_flags != (flags & ~(~0 << DICT_TF_BITS)))) {
4911++ ibool file_is_corrupt = FALSE;
4912++ byte* buf3;
4913++ byte* descr_page;
4914++ ibool descr_is_corrupt = FALSE;
4915++ index_id_t old_id[31];
4916++ index_id_t new_id[31];
4917++ ulint root_page[31];
4918++ ulint n_index;
4919++ os_file_t info_file = -1;
4920++ char* info_file_path;
4921++ ulint i;
4922++ int len;
4923++ ib_uint64_t current_lsn;
4924++ ulint size_low, size_high, size, free_limit;
4925++ ib_int64_t size_bytes, free_limit_bytes;
4926++ dict_table_t* table;
4927++ dict_index_t* index;
4928++ fil_system_t* system;
4929++ fil_node_t* node = NULL;
4930++ fil_space_t* space;
4931++
4932++ buf3 = ut_malloc(2 * UNIV_PAGE_SIZE);
4933++ descr_page = ut_align(buf3, UNIV_PAGE_SIZE);
4934++
4935++ current_lsn = log_get_lsn();
4936++
4937++ /* check the header page's consistency */
4938++ if (buf_page_is_corrupted(page,
4939++ dict_table_flags_to_zip_size(space_flags))) {
4940++ fprintf(stderr, "InnoDB: page 0 of %s seems corrupt.\n", filepath);
4941++ file_is_corrupt = TRUE;
4942++ descr_is_corrupt = TRUE;
4943++ }
4944++
4945++ /* store as first descr page */
4946++ memcpy(descr_page, page, UNIV_PAGE_SIZE);
4947++
4948++ /* get free limit (page number) of the table space */
4949++/* these should be same to the definition in fsp0fsp.c */
4950++#define FSP_HEADER_OFFSET FIL_PAGE_DATA
4951++#define FSP_FREE_LIMIT 12
4952++ free_limit = mach_read_from_4(FSP_HEADER_OFFSET + FSP_FREE_LIMIT + page);
4953++ free_limit_bytes = (ib_int64_t)free_limit * (ib_int64_t)UNIV_PAGE_SIZE;
4954++
4955++ /* overwrite fsp header */
4956++ fsp_header_init_fields(page, id, flags);
4957++ mach_write_to_4(page + FIL_PAGE_ARCH_LOG_NO_OR_SPACE_ID, id);
4958++ space_id = id;
4959++ space_flags = flags;
4960++ if (mach_read_from_8(page + FIL_PAGE_FILE_FLUSH_LSN) > current_lsn)
4961++ mach_write_to_8(page + FIL_PAGE_FILE_FLUSH_LSN, current_lsn);
4962++ mach_write_to_4(page + FIL_PAGE_SPACE_OR_CHKSUM,
4963++ srv_use_checksums
4964++ ? buf_calc_page_new_checksum(page)
4965++ : BUF_NO_CHECKSUM_MAGIC);
4966++ mach_write_to_4(page + UNIV_PAGE_SIZE - FIL_PAGE_END_LSN_OLD_CHKSUM,
4967++ srv_use_checksums
4968++ ? buf_calc_page_old_checksum(page)
4969++ : BUF_NO_CHECKSUM_MAGIC);
4970++ success = os_file_write(filepath, file, page, 0, 0, UNIV_PAGE_SIZE);
4971++
4972++ /* get file size */
4973++ os_file_get_size(file, &size_low, &size_high);
4974++ size_bytes = (((ib_int64_t)size_high) << 32)
4975++ + (ib_int64_t)size_low;
4976++
4977++ if (size_bytes < free_limit_bytes) {
4978++ free_limit_bytes = size_bytes;
4979++ if (size_bytes >= FSP_EXTENT_SIZE * UNIV_PAGE_SIZE) {
4980++ fprintf(stderr, "InnoDB: free limit of %s is larger than its real size.\n", filepath);
4981++ file_is_corrupt = TRUE;
4982++ }
4983++ }
4984++
4985++ /* get cruster index information */
4986++ table = dict_table_get_low(name);
4987++ index = dict_table_get_first_index(table);
4988++ ut_a(index->page==3);
4989++
4990++ /* read metadata from .exp file */
4991++ n_index = 0;
4992++ memset(old_id, 0, sizeof(old_id));
4993++ memset(new_id, 0, sizeof(new_id));
4994++ memset(root_page, 0, sizeof(root_page));
4995++
4996++ info_file_path = fil_make_ibd_name(name, FALSE);
4997++ len = strlen(info_file_path);
4998++ info_file_path[len - 3] = 'e';
4999++ info_file_path[len - 2] = 'x';
5000++ info_file_path[len - 1] = 'p';
The diff has been truncated for viewing.

Subscribers

People subscribed via source and target branches

to all changes: