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
=== added file 'COPYING.innodb-deadlock-count-patch'
--- COPYING.innodb-deadlock-count-patch 1970-01-01 00:00:00 +0000
+++ COPYING.innodb-deadlock-count-patch 2011-01-10 13:15:57 +0000
@@ -0,0 +1,30 @@
1Portions of this software contain modifications contributed by Eric Bergen.
2These contributions are used with the following license:
3
4Copyright (c) 2010, Eric Bergen. All rights reserved.
5
6Redistribution and use in source and binary forms, with or without
7modification, are permitted provided that the following conditions
8are met:
9 * Redistributions of source code must retain the above copyright
10 notice, this list of conditions and the following disclaimer.
11 * Redistributions in binary form must reproduce the above
12 copyright notice, this list of conditions and the following
13 disclaimer in the documentation and/or other materials
14 provided with the distribution.
15 * Neither the name of the Eric Bergen. nor the names of its
16 contributors may be used to endorse or promote products
17 derived from this software without specific prior written
18 permission.
19
20THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
23A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
24OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
25SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
26LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
031
=== renamed file 'COPYING.innodb-deadlock-count-patch' => 'COPYING.innodb-deadlock-count-patch.moved'
=== added file 'COPYING.show_temp_51'
--- COPYING.show_temp_51 1970-01-01 00:00:00 +0000
+++ COPYING.show_temp_51 2011-01-10 13:15:57 +0000
@@ -0,0 +1,13 @@
1Portions of this software contain modifications contributed by Venu Anuganti.
2These contributions are used with the following license:
3
4Copyright (c) 2010, Venu Anuganti, http://venublog.com/
5All rights reserved.
6
7Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
8
9 * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
10 * 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.
11 * 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.
12
13THIS 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.
014
=== renamed file 'COPYING.show_temp_51' => 'COPYING.show_temp_51.moved'
=== added file 'Makefile'
--- Makefile 1970-01-01 00:00:00 +0000
+++ Makefile 2011-01-10 13:15:57 +0000
@@ -0,0 +1,68 @@
1FETCH_CMD=wget
2MASTER_SITE=http://www.percona.com/downloads/community
3MYSQL_VERSION=5.5.8
4PERCONA_SERVER ?=Percona-Server
5DEBUG_DIR ?= $(PERCONA_SERVER)-debug
6RELEASE_DIR ?= $(PERCONA_SERVER)-release
7SERIES ?=series
8CMAKE=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
9CONFIGUR=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
10
11
12all: main install-lic tests misc
13 @echo ""
14 @echo "Percona Server source code is ready"
15 @echo "Now change directory to $(PERCONA_SERVER) define variables as show below"
16 @echo ""
17 export CFLAGS="-O2 -g -fmessage-length=0 -D_FORTIFY_SOURCE=2"
18 export CXXFLAGS="-O2 -g -fmessage-length=0 -D_FORTIFY_SOURCE=2"
19 export LIBS=-lrt
20 @echo ""
21 @echo "and run ./configure --prefix=/usr/local/$(PERCONA_SERVER)-$(MYSQL_VERSION) --with-plugin-innobase --with-plugin-partition && make all install"
22 @echo ""
23
24configure: all
25 (cd $(PERCONA_SERVER); bash BUILD/autorun.sh; $(CONFIGUR))
26
27cmake:
28 rm -rf $(DEBUG_DIR)
29 rm -rf $(RELEASE_DIR)
30 (mkdir -p $(DEBUG_DIR); cd $(DEBUG_DIR); $(CMAKE) -G "Unix Makefiles" -DCMAKE_BUILD_TYPE=Debug -DWITH_DEBUG=Full -DMYSQL_MAINTAINER_MODE=OFF ../$(PERCONA_SERVER))
31 (mkdir -p $(RELEASE_DIR); cd $(RELEASE_DIR); $(CMAKE) -G "Unix Makefiles" ../$(PERCONA_SERVER))
32
33binary:
34 (cd $(PERCONA_SERVER); ${CMAKE} . -DBUILD_CONFIG=mysql_release \
35 -DCMAKE_BUILD_TYPE=RelWithDebInfo \
36 -DCMAKE_INSTALL_PREFIX="/usr/local/$(PERCONA_SERVER)-$(MYSQL_VERSION)" \
37 -DFEATURE_SET="community" \
38 -DWITH_EMBEDDED_SERVER=OFF \
39 -DCOMPILATION_COMMENT="Percona-Server" \
40 -DMYSQL_SERVER_SUFFIX="${MYSQL_VERSION}" )
41
42install-lic:
43 @echo "Installing license files"
44 install -m 644 COPYING.* $(PERCONA_SERVER)
45
46main: mysql-$(MYSQL_VERSION).tar.gz
47 @echo "Prepare Percona Server sources"
48 rm -rf mysql-$(MYSQL_VERSION)
49 rm -rf $(PERCONA_SERVER);
50 tar zxf mysql-$(MYSQL_VERSION).tar.gz
51 mv mysql-$(MYSQL_VERSION) $(PERCONA_SERVER)
52 (cat `cat $(SERIES)`) | patch -p1 -d $(PERCONA_SERVER)
53 rm $(PERCONA_SERVER)/sql/sql_yacc.cc $(PERCONA_SERVER)/sql/sql_yacc.h
54
55mysql-$(MYSQL_VERSION).tar.gz:
56 @echo "Downloading MySQL sources from $(MASTER_SITE)"
57 $(FETCH_CMD) $(MASTER_SITE)/mysql-$(MYSQL_VERSION).tar.gz
58
59tests:
60 ./install_tests.sh
61
62misc:
63 @echo "Installing other files"
64 install -m 644 lrusort.py $(PERCONA_SERVER)/scripts
65
66clean: env
67 rm -rf mysql-$(MYSQL_VERSION) $(PERCONA_SERVER)
68 rm -f mysql-$(MYSQL_VERSION).tar.gz
069
=== renamed file 'Makefile' => 'Makefile.moved'
=== added file 'bug580324.patch'
--- bug580324.patch 1970-01-01 00:00:00 +0000
+++ bug580324.patch 2011-01-10 13:15:57 +0000
@@ -0,0 +1,105 @@
1# name : bug580324.patch
2# introduced : 11 or before
3# maintainer : Oleg
4#
5#!!! notice !!!
6# Any small change to this file in the main branch
7# should be done or reviewed by the maintainer!
8diff -ruN a/sql/sql_base.cc b/sql/sql_base.cc
9--- a/sql/sql_base.cc 2010-05-27 19:54:18.000000000 +0400
10+++ b/sql/sql_base.cc 2010-05-27 19:55:20.000000000 +0400
11@@ -233,8 +233,12 @@
12 uint create_table_def_key(THD *thd, char *key, TABLE_LIST *table_list,
13 bool tmp_table)
14 {
15- uint key_length= (uint) (strmov(strmov(key, table_list->db)+1,
16- table_list->table_name)-key)+1;
17+ char *db_end= strnmov(key, table_list->db, MAX_DBKEY_LENGTH - 2);
18+ *db_end++= '\0';
19+ char *table_end= strnmov(db_end, table_list->table_name,
20+ key + MAX_DBKEY_LENGTH - 1 - db_end);
21+ *table_end++= '\0';
22+ uint key_length= (uint) (table_end-key);
23 if (tmp_table)
24 {
25 int4store(key + key_length, thd->server_id);
26diff -ruN a/sql/sql_parse.cc b/sql/sql_parse.cc
27--- a/sql/sql_parse.cc 2010-05-27 19:54:18.000000000 +0400
28+++ b/sql/sql_parse.cc 2010-05-27 20:03:20.000000000 +0400
29@@ -1326,10 +1326,12 @@
30 break;
31 #else
32 {
33- char *fields, *packet_end= packet + packet_length, *arg_end;
34+ char *fields, *packet_end= packet + packet_length, *wildcard;
35 /* Locked closure of all tables */
36 TABLE_LIST table_list;
37- LEX_STRING conv_name;
38+ char db_buff[NAME_LEN+1];
39+ uint32 db_length;
40+ uint dummy_errors;
41
42 /* used as fields initializator */
43 lex_start(thd);
44@@ -1341,26 +1343,22 @@
45 /*
46 We have name + wildcard in packet, separated by endzero
47 */
48- arg_end= strend(packet);
49- uint arg_length= arg_end - packet;
50-
51- /* Check given table name length. */
52- if (arg_length >= packet_length || arg_length > NAME_LEN)
53+ wildcard= strend(packet);
54+ db_length= wildcard - packet;
55+ wildcard++;
56+ uint query_length= (uint) (packet_end - wildcard); // Don't count end \0
57+ if (db_length > NAME_LEN || query_length > NAME_LEN)
58 {
59 my_message(ER_UNKNOWN_COM_ERROR, ER(ER_UNKNOWN_COM_ERROR), MYF(0));
60 break;
61 }
62- thd->convert_string(&conv_name, system_charset_info,
63- packet, arg_length, thd->charset());
64- if (check_table_name(conv_name.str, conv_name.length, FALSE))
65- {
66- /* this is OK due to convert_string() null-terminating the string */
67- my_error(ER_WRONG_TABLE_NAME, MYF(0), conv_name.str);
68+ db_length= copy_and_convert(db_buff, sizeof(db_buff)-1,
69+ system_charset_info, packet, db_length,
70+ thd->charset(), &dummy_errors);
71+ db_buff[db_length]= '\0';
72+ table_list.alias= table_list.table_name= db_buff;
73+ if (!(fields= (char *) thd->memdup(wildcard, query_length + 1)))
74 break;
75- }
76-
77- table_list.alias= table_list.table_name= conv_name.str;
78- packet= arg_end + 1;
79
80 if (is_schema_db(table_list.db, table_list.db_length))
81 {
82@@ -1369,9 +1367,6 @@
83 table_list.schema_table= schema_table;
84 }
85
86- uint query_length= (uint) (packet_end - packet); // Don't count end \0
87- if (!(fields= (char *) thd->memdup(packet, query_length + 1)))
88- break;
89 thd->set_query(fields, query_length);
90 general_log_print(thd, command, "%s %s", table_list.table_name, fields);
91 if (lower_case_table_names)
92diff -ruN a/strings/ctype-utf8.c b/strings/ctype-utf8.c
93--- a/strings/ctype-utf8.c 2010-05-06 19:28:05.000000000 +0400
94+++ b/strings/ctype-utf8.c 2010-05-27 20:04:20.000000000 +0400
95@@ -4116,6 +4116,10 @@
96 {
97 int code;
98 char hex[]= "0123456789abcdef";
99+
100+ if (s >= e)
101+ return MY_CS_TOOSMALL;
102+
103 if (wc < 128 && filename_safe_char[wc])
104 {
105 *s= (uchar) wc;
0106
=== renamed file 'bug580324.patch' => 'bug580324.patch.moved'
=== added file 'control_online_alter_index.patch'
--- control_online_alter_index.patch 1970-01-01 00:00:00 +0000
+++ control_online_alter_index.patch 2011-01-10 13:15:57 +0000
@@ -0,0 +1,90 @@
1# name : control_online_alter_index.patch
2# introduced : 12
3# maintainer : Yasufumi
4#
5#!!! notice !!!
6# Any small change to this file in the main branch
7# should be done or reviewed by the maintainer!
8diff -ruN a/sql/handler.h b/sql/handler.h
9--- a/sql/handler.h 2010-11-03 07:01:14.000000000 +0900
10+++ b/sql/handler.h 2010-12-03 13:51:04.727293058 +0900
11@@ -194,6 +194,19 @@
12 #define HA_ONLINE_DROP_UNIQUE_INDEX (1L << 9) /*drop uniq. online*/
13 #define HA_ONLINE_ADD_PK_INDEX (1L << 10)/*add prim. online*/
14 #define HA_ONLINE_DROP_PK_INDEX (1L << 11)/*drop prim. online*/
15+
16+#define HA_ONLINE_ALTER_INDEX_MASK (HA_ONLINE_ADD_INDEX_NO_WRITES \
17+ | HA_ONLINE_DROP_INDEX_NO_WRITES \
18+ | HA_ONLINE_ADD_UNIQUE_INDEX_NO_WRITES \
19+ | HA_ONLINE_DROP_UNIQUE_INDEX_NO_WRITES \
20+ | HA_ONLINE_ADD_PK_INDEX_NO_WRITES \
21+ | HA_ONLINE_DROP_PK_INDEX_NO_WRITES \
22+ | HA_ONLINE_ADD_INDEX \
23+ | HA_ONLINE_DROP_INDEX \
24+ | HA_ONLINE_ADD_UNIQUE_INDEX \
25+ | HA_ONLINE_DROP_UNIQUE_INDEX \
26+ | HA_ONLINE_ADD_PK_INDEX \
27+ | HA_ONLINE_DROP_PK_INDEX)
28 /*
29 HA_PARTITION_FUNCTION_SUPPORTED indicates that the function is
30 supported at all.
31diff -ruN a/sql/sql_class.h b/sql/sql_class.h
32--- a/sql/sql_class.h 2010-12-02 20:31:56.200956501 +0900
33+++ b/sql/sql_class.h 2010-12-03 13:51:04.744953174 +0900
34@@ -481,6 +481,8 @@
35 my_bool engine_condition_pushdown;
36 my_bool keep_files_on_create;
37
38+ my_bool online_alter_index;
39+
40 my_bool old_alter_table;
41 my_bool old_passwords;
42 my_bool big_tables;
43diff -ruN a/sql/sql_partition.cc b/sql/sql_partition.cc
44--- a/sql/sql_partition.cc 2010-11-03 07:01:14.000000000 +0900
45+++ b/sql/sql_partition.cc 2010-12-03 13:59:56.444039002 +0900
46@@ -4635,7 +4635,12 @@
47 alter_info->num_parts= curr_part_no - new_part_no;
48 }
49 }
50- if (!(flags= new_table->file->alter_table_flags(alter_info->flags)))
51+ flags= new_table->file->alter_table_flags(alter_info->flags);
52+ if (!thd->variables.online_alter_index)
53+ {
54+ flags&= ~((uint)HA_ONLINE_ALTER_INDEX_MASK);
55+ }
56+ if (!flags)
57 {
58 my_error(ER_PARTITION_FUNCTION_FAILURE, MYF(0));
59 goto err;
60diff -ruN a/sql/sql_table.cc b/sql/sql_table.cc
61--- a/sql/sql_table.cc 2010-11-03 07:01:14.000000000 +0900
62+++ b/sql/sql_table.cc 2010-12-03 13:51:04.768955495 +0900
63@@ -6107,6 +6107,10 @@
64 uint *idx_end_p;
65
66 alter_flags= table->file->alter_table_flags(alter_info->flags);
67+ if (!thd->variables.online_alter_index)
68+ {
69+ alter_flags&= ~((ulong)HA_ONLINE_ALTER_INDEX_MASK);
70+ }
71 DBUG_PRINT("info", ("alter_flags: %lu", alter_flags));
72 /* Check dropped indexes. */
73 for (idx_p= index_drop_buffer, idx_end_p= idx_p + index_drop_count;
74diff -ruN a/sql/sys_vars.cc b/sql/sys_vars.cc
75--- a/sql/sys_vars.cc 2010-12-02 21:23:05.569356468 +0900
76+++ b/sql/sys_vars.cc 2010-12-03 14:05:28.857356603 +0900
77@@ -2124,6 +2124,13 @@
78 GLOBAL_VAR(opt_optimizer_fix),
79 NO_CMD_LINE, DEFAULT(TRUE));
80
81+static Sys_var_mybool Sys_fast_index_creation(
82+ "fast_index_creation",
83+ "If disabled, suppresses online operations for indexes of ALTER TABLE "
84+ "(e.g. fast index creation of InnoDB Plugin) for the session.",
85+ SESSION_VAR(online_alter_index), NO_CMD_LINE,
86+ DEFAULT(TRUE));
87+
88 /** propagates changes to the relevant flag of @@optimizer_switch */
89 static bool fix_engine_condition_pushdown(sys_var *self, THD *thd,
90 enum_var_type type)
091
=== renamed file 'control_online_alter_index.patch' => 'control_online_alter_index.patch.moved'
=== added file 'error_pad.patch'
--- error_pad.patch 1970-01-01 00:00:00 +0000
+++ error_pad.patch 2011-01-10 13:15:57 +0000
@@ -0,0 +1,267 @@
1# name : error_pad.patch
2# introduced : 12
3# maintainer : Oleg
4#
5#!!! notice !!!
6# Any small change to this file in the main branch
7# should be done or reviewed by the maintainer!
8diff -ruN a/extra/comp_err.c b/extra/comp_err.c
9--- a/extra/comp_err.c 2010-08-03 17:24:24.000000000 +0000
10+++ b/extra/comp_err.c 2010-09-14 16:49:28.000000000 +0000
11@@ -30,11 +30,12 @@
12 #include <assert.h>
13 #include <my_dir.h>
14
15-#define MAX_ROWS 1000
16+#define MAX_ROWS 5000
17 #define HEADER_LENGTH 32 /* Length of header in errmsg.sys */
18 #define DEFAULT_CHARSET_DIR "../sql/share/charsets"
19 #define ER_PREFIX "ER_"
20 #define WARN_PREFIX "WARN_"
21+#define PADD_PREFIX "PADD_"
22 static char *OUTFILE= (char*) "errmsg.sys";
23 static char *HEADERFILE= (char*) "mysqld_error.h";
24 static char *NAMEFILE= (char*) "mysqld_ername.h";
25@@ -89,6 +90,7 @@
26 const char *sql_code1; /* sql state */
27 const char *sql_code2; /* ODBC state */
28 struct errors *next_error; /* Pointer to next error */
29+ my_bool is_padding; /* If true - padd this er_name while er_code != d_code*/
30 DYNAMIC_ARRAY msg; /* All language texts for this error */
31 };
32
33@@ -127,6 +129,7 @@
34
35
36 static struct languages *parse_charset_string(char *str);
37+static struct errors *parse_padd_string(char *ptr, int er_count);
38 static struct errors *parse_error_string(char *ptr, int er_count);
39 static struct message *parse_message_string(struct message *new_message,
40 char *str);
41@@ -252,6 +255,11 @@
42
43 for (tmp_error= error_head; tmp_error; tmp_error= tmp_error->next_error)
44 {
45+ if (tmp_error->is_padding)
46+ {
47+ er_last= tmp_error->d_code;
48+ continue;
49+ }
50 /*
51 generating mysqld_error.h
52 fprintf() will automatically add \r on windows
53@@ -344,12 +352,29 @@
54 "language\n", tmp_error->er_name, tmp_lang->lang_short_name);
55 goto err;
56 }
57- if (copy_rows(to, tmp->text, row_nr, start_pos))
58+ if (tmp_error->is_padding)
59 {
60- fprintf(stderr, "Failed to copy rows to %s\n", outfile);
61- goto err;
62+ uint padd_to= tmp_error->d_code;
63+ char* padd_message= tmp->text;
64+ while ((row_nr+er_offset) < padd_to)
65+ {
66+ if (copy_rows(to, padd_message,row_nr,start_pos))
67+ {
68+ fprintf(stderr, "Failed to copy rows to %s\n", outfile);
69+ goto err;
70+ }
71+ row_nr++;
72+ }
73+ }
74+ else
75+ {
76+ if (copy_rows(to, tmp->text, row_nr, start_pos))
77+ {
78+ fprintf(stderr, "Failed to copy rows to %s\n", outfile);
79+ goto err;
80+ }
81+ row_nr++;
82 }
83- row_nr++;
84 }
85
86 /* continue with header of the errmsg.sys file */
87@@ -500,14 +525,26 @@
88 DBUG_RETURN(0);
89 continue;
90 }
91- if (is_prefix(str, ER_PREFIX) || is_prefix(str, WARN_PREFIX))
92+ if (is_prefix(str, ER_PREFIX) || is_prefix(str, WARN_PREFIX) || is_prefix(str, PADD_PREFIX))
93 {
94- if (!(current_error= parse_error_string(str, rcount)))
95+ if (is_prefix(str, PADD_PREFIX))
96 {
97- fprintf(stderr, "Failed to parse the error name string\n");
98- DBUG_RETURN(0);
99+ if (!(current_error= parse_padd_string(str, rcount)))
100+ {
101+ fprintf(stderr, "Failed to parse the error padd string\n");
102+ DBUG_RETURN(0);
103+ }
104+ rcount= current_error->d_code - er_offset; /* Count number of unique errors */
105+ }
106+ else
107+ {
108+ if (!(current_error= parse_error_string(str, rcount)))
109+ {
110+ fprintf(stderr, "Failed to parse the error name string\n");
111+ DBUG_RETURN(0);
112+ }
113+ rcount++; /* Count number of unique errors */
114 }
115- rcount++; /* Count number of unique errors */
116
117 /* add error to the list */
118 *tail_error= current_error;
119@@ -848,78 +885,122 @@
120 DBUG_RETURN(new_message);
121 }
122
123+static struct errors* create_new_error(my_bool is_padding, char *er_name, int d_code, const char *sql_code1, const char *sql_code2)
124+{
125+ struct errors *new_error;
126+ DBUG_ENTER("create_new_error");
127+ /* create a new element */
128+ new_error= (struct errors *) my_malloc(sizeof(*new_error), MYF(MY_WME));
129+ if (my_init_dynamic_array(&new_error->msg, sizeof(struct message), 0, 0))
130+ DBUG_RETURN(0); /* OOM: Fatal error */
131+ new_error->is_padding= is_padding;
132+ DBUG_PRINT("info", ("is_padding: %s", (is_padding ? "true" : "false")));
133+ new_error->er_name= er_name;
134+ DBUG_PRINT("info", ("er_name: %s", er_name));
135+ new_error->d_code= d_code;
136+ DBUG_PRINT("info", ("d_code: %d", d_code));
137+ new_error->sql_code1= sql_code1;
138+ DBUG_PRINT("info", ("sql_code1: %s", sql_code1));
139+ new_error->sql_code2= sql_code2;
140+ DBUG_PRINT("info", ("sql_code2: %s", sql_code2));
141+ DBUG_RETURN(new_error);
142+}
143
144 /*
145- Parsing the string with error name and codes; returns the pointer to
146+ Parsing the string with padd syntax (name + error to pad); returns the pointer to
147 the errors struct
148 */
149
150-static struct errors *parse_error_string(char *str, int er_count)
151+static struct errors *parse_padd_string(char* str, int er_count)
152 {
153- struct errors *new_error;
154+ char *er_name;
155+ uint d_code;
156+ char *start;
157 DBUG_ENTER("parse_error_string");
158 DBUG_PRINT("enter", ("str: %s", str));
159
160- /* create a new element */
161- new_error= (struct errors *) my_malloc(sizeof(*new_error), MYF(MY_WME));
162+ start= str;
163+ str= skip_delimiters(str);
164
165- if (my_init_dynamic_array(&new_error->msg, sizeof(struct message), 0, 0))
166+ /* getting the error name */
167+
168+ if (!(er_name= get_word(&str)))
169 DBUG_RETURN(0); /* OOM: Fatal error */
170
171- /* getting the error name */
172 str= skip_delimiters(str);
173
174- if (!(new_error->er_name= get_word(&str)))
175+ if (!(d_code= parse_error_offset(start)))
176+ {
177+ fprintf(stderr, "Failed to parse the error padd string '%s' '%s' (d_code doesn't parse)!\n",er_name,str);
178+ DBUG_RETURN(0);
179+ }
180+ if (d_code < (uint)(er_offset + er_count))
181+ {
182+ fprintf(stderr, "Error to padding less current error number!\n");
183+ DBUG_RETURN(0);
184+ }
185+ DBUG_RETURN(create_new_error(TRUE,er_name,d_code,empty_string,empty_string));
186+}
187+
188+/*
189+ Parsing the string with error name and codes; returns the pointer to
190+ the errors struct
191+*/
192+
193+static struct errors *parse_error_string(char *str, int er_count)
194+{
195+ char *er_name;
196+ int d_code;
197+ const char *sql_code1= empty_string;
198+ const char *sql_code2= empty_string;
199+ DBUG_ENTER("parse_error_string");
200+ DBUG_PRINT("enter", ("str: %s", str));
201+
202+ str= skip_delimiters(str);
203+
204+ /* getting the error name */
205+
206+ if (!(er_name= get_word(&str)))
207 DBUG_RETURN(0); /* OOM: Fatal error */
208- DBUG_PRINT("info", ("er_name: %s", new_error->er_name));
209
210 str= skip_delimiters(str);
211
212 /* getting the code1 */
213-
214- new_error->d_code= er_offset + er_count;
215- DBUG_PRINT("info", ("d_code: %d", new_error->d_code));
216+ d_code= er_offset + er_count;
217
218 str= skip_delimiters(str);
219
220 /* if we reached EOL => no more codes, but this can happen */
221 if (!*str)
222 {
223- new_error->sql_code1= empty_string;
224- new_error->sql_code2= empty_string;
225 DBUG_PRINT("info", ("str: %s", str));
226- DBUG_RETURN(new_error);
227+ goto complete_create;
228 }
229-
230 /* getting the sql_code 1 */
231-
232- if (!(new_error->sql_code1= get_word(&str)))
233+ if (!(sql_code1= get_word(&str)))
234 DBUG_RETURN(0); /* OOM: Fatal error */
235- DBUG_PRINT("info", ("sql_code1: %s", new_error->sql_code1));
236
237 str= skip_delimiters(str);
238
239 /* if we reached EOL => no more codes, but this can happen */
240 if (!*str)
241 {
242- new_error->sql_code2= empty_string;
243 DBUG_PRINT("info", ("str: %s", str));
244- DBUG_RETURN(new_error);
245+ goto complete_create;
246 }
247-
248 /* getting the sql_code 2 */
249- if (!(new_error->sql_code2= get_word(&str)))
250+ if (!(sql_code2= get_word(&str)))
251 DBUG_RETURN(0); /* OOM: Fatal error */
252- DBUG_PRINT("info", ("sql_code2: %s", new_error->sql_code2));
253
254 str= skip_delimiters(str);
255+
256 if (*str)
257 {
258 fprintf(stderr, "The error line did not end with sql/odbc code!");
259 DBUG_RETURN(0);
260 }
261-
262- DBUG_RETURN(new_error);
263+complete_create:
264+ DBUG_RETURN(create_new_error(FALSE,er_name,d_code,sql_code1,sql_code2));
265 }
266
267
0268
=== renamed file 'error_pad.patch' => 'error_pad.patch.moved'
=== added file 'innodb_adaptive_hash_index_partitions.patch'
--- innodb_adaptive_hash_index_partitions.patch 1970-01-01 00:00:00 +0000
+++ innodb_adaptive_hash_index_partitions.patch 2011-01-10 13:15:57 +0000
@@ -0,0 +1,1508 @@
1# name : innodb_adaptive_hash_index_num.patch
2# introduced : XtraDB on 5.5 (-13?)
3# maintainer : Yasufumi
4#
5#!!! notice !!!
6# Any small change to this file in the main branch
7# should be done or reviewed by the maintainer!
8diff -ruN a/storage/innobase/btr/btr0btr.c b/storage/innobase/btr/btr0btr.c
9--- a/storage/innobase/btr/btr0btr.c 2010-12-04 15:52:23.355483176 +0900
10+++ b/storage/innobase/btr/btr0btr.c 2010-12-04 16:12:48.639514256 +0900
11@@ -954,7 +954,7 @@
12 }
13 ut_a(block);
14
15- btr_search_drop_page_hash_index(block);
16+ btr_search_drop_page_hash_index(block, NULL);
17
18 header = buf_block_get_frame(block) + PAGE_HEADER + PAGE_BTR_SEG_TOP;
19 #ifdef UNIV_BTR_DEBUG
20@@ -1023,7 +1023,7 @@
21
22 #ifndef UNIV_HOTBACKUP
23 if (UNIV_LIKELY(!recovery)) {
24- btr_search_drop_page_hash_index(block);
25+ btr_search_drop_page_hash_index(block, index);
26 }
27
28 block->check_index_page_at_flush = TRUE;
29@@ -1188,7 +1188,7 @@
30 ut_a(!page_zip || page_zip_validate(page_zip, page));
31 #endif /* UNIV_ZIP_DEBUG */
32
33- btr_search_drop_page_hash_index(block);
34+ btr_search_drop_page_hash_index(block, index);
35
36 /* Recreate the page: note that global data on page (possible
37 segment headers, next page-field, etc.) is preserved intact */
38@@ -2497,7 +2497,7 @@
39 mem_heap_free(heap);
40 }
41
42- btr_search_drop_page_hash_index(block);
43+ btr_search_drop_page_hash_index(block, index);
44
45 /* Make the father empty */
46 btr_page_empty(father_block, father_page_zip, index, page_level, mtr);
47@@ -2720,7 +2720,7 @@
48 goto err_exit;
49 }
50
51- btr_search_drop_page_hash_index(block);
52+ btr_search_drop_page_hash_index(block, index);
53
54 /* Remove the page from the level list */
55 btr_level_list_remove(space, zip_size, page, mtr);
56@@ -2761,7 +2761,7 @@
57 goto err_exit;
58 }
59
60- btr_search_drop_page_hash_index(block);
61+ btr_search_drop_page_hash_index(block, index);
62
63 #ifdef UNIV_BTR_DEBUG
64 if (UNIV_LIKELY_NULL(merge_page_zip)) {
65@@ -2875,7 +2875,7 @@
66 ut_a(btr_page_get_next(page, mtr) == FIL_NULL);
67
68 ut_ad(mtr_memo_contains(mtr, block, MTR_MEMO_PAGE_X_FIX));
69- btr_search_drop_page_hash_index(block);
70+ btr_search_drop_page_hash_index(block, index);
71
72 btr_page_get_father(index, block, mtr, &cursor);
73 father = btr_cur_get_block(&cursor);
74@@ -2980,7 +2980,7 @@
75
76 page = buf_block_get_frame(block);
77 ut_a(page_is_comp(merge_page) == page_is_comp(page));
78- btr_search_drop_page_hash_index(block);
79+ btr_search_drop_page_hash_index(block, index);
80
81 if (left_page_no == FIL_NULL && !page_is_leaf(page)) {
82
83diff -ruN a/storage/innobase/btr/btr0cur.c b/storage/innobase/btr/btr0cur.c
84--- a/storage/innobase/btr/btr0cur.c 2010-12-04 15:52:23.359513820 +0900
85+++ b/storage/innobase/btr/btr0cur.c 2010-12-04 16:12:48.643551837 +0900
86@@ -486,7 +486,7 @@
87 #ifdef UNIV_SEARCH_PERF_STAT
88 info->n_searches++;
89 #endif
90- if (rw_lock_get_writer(&btr_search_latch) == RW_LOCK_NOT_LOCKED
91+ if (rw_lock_get_writer(btr_search_get_latch(cursor->index->id)) == RW_LOCK_NOT_LOCKED
92 && latch_mode <= BTR_MODIFY_LEAF
93 && info->last_hash_succ
94 && !estimate
95@@ -522,7 +522,7 @@
96
97 if (has_search_latch) {
98 /* Release possible search latch to obey latching order */
99- rw_lock_s_unlock(&btr_search_latch);
100+ rw_lock_s_unlock(btr_search_get_latch(cursor->index->id));
101 }
102
103 /* Store the position of the tree latch we push to mtr so that we
104@@ -844,7 +844,7 @@
105
106 if (has_search_latch) {
107
108- rw_lock_s_lock(&btr_search_latch);
109+ rw_lock_s_lock(btr_search_get_latch(cursor->index->id));
110 }
111 }
112
113@@ -2059,7 +2059,7 @@
114 btr_search_update_hash_on_delete(cursor);
115 }
116
117- rw_lock_x_lock(&btr_search_latch);
118+ rw_lock_x_lock(btr_search_get_latch(cursor->index->id));
119 }
120
121 if (!(flags & BTR_KEEP_SYS_FLAG)) {
122@@ -2073,7 +2073,7 @@
123 row_upd_rec_in_place(rec, index, offsets, update, page_zip);
124
125 if (block->is_hashed) {
126- rw_lock_x_unlock(&btr_search_latch);
127+ rw_lock_x_unlock(btr_search_get_latch(cursor->index->id));
128 }
129
130 if (page_zip && !dict_index_is_clust(index)
131@@ -2857,7 +2857,7 @@
132 block = btr_cur_get_block(cursor);
133
134 if (block->is_hashed) {
135- rw_lock_x_lock(&btr_search_latch);
136+ rw_lock_x_lock(btr_search_get_latch(index->id));
137 }
138
139 page_zip = buf_block_get_page_zip(block);
140@@ -2872,7 +2872,7 @@
141 }
142
143 if (block->is_hashed) {
144- rw_lock_x_unlock(&btr_search_latch);
145+ rw_lock_x_unlock(btr_search_get_latch(index->id));
146 }
147
148 btr_cur_del_mark_set_clust_rec_log(flags, rec, index, val, trx,
149@@ -3003,13 +3003,13 @@
150 == dict_table_is_comp(cursor->index->table));
151
152 if (block->is_hashed) {
153- rw_lock_x_lock(&btr_search_latch);
154+ rw_lock_x_lock(btr_search_get_latch(cursor->index->id));
155 }
156
157 btr_rec_set_deleted_flag(rec, buf_block_get_page_zip(block), val);
158
159 if (block->is_hashed) {
160- rw_lock_x_unlock(&btr_search_latch);
161+ rw_lock_x_unlock(btr_search_get_latch(cursor->index->id));
162 }
163
164 btr_cur_del_mark_set_sec_rec_log(rec, val, mtr);
165diff -ruN a/storage/innobase/btr/btr0sea.c b/storage/innobase/btr/btr0sea.c
166--- a/storage/innobase/btr/btr0sea.c 2010-12-04 15:52:23.387513429 +0900
167+++ b/storage/innobase/btr/btr0sea.c 2010-12-04 16:14:51.721884049 +0900
168@@ -48,6 +48,8 @@
169 UNIV_INTERN char btr_search_enabled = TRUE;
170 UNIV_INTERN ibool btr_search_fully_disabled = FALSE;
171
172+UNIV_INTERN ulint btr_search_index_num = 1;
173+
174 /** Mutex protecting btr_search_enabled */
175 static mutex_t btr_search_enabled_mutex;
176
177@@ -79,7 +81,9 @@
178
179 /* We will allocate the latch from dynamic memory to get it to the
180 same DRAM page as other hotspot semaphores */
181-UNIV_INTERN rw_lock_t* btr_search_latch_temp;
182+//UNIV_INTERN rw_lock_t* btr_search_latch_temp;
183+
184+UNIV_INTERN rw_lock_t** btr_search_latch_part;
185
186 /** padding to prevent other memory update hotspots from residing on
187 the same memory cache line */
188@@ -131,18 +135,19 @@
189 will not guarantee success. */
190 static
191 void
192-btr_search_check_free_space_in_heap(void)
193+btr_search_check_free_space_in_heap(
194 /*=====================================*/
195+ index_id_t key)
196 {
197 hash_table_t* table;
198 mem_heap_t* heap;
199
200 #ifdef UNIV_SYNC_DEBUG
201- ut_ad(!rw_lock_own(&btr_search_latch, RW_LOCK_SHARED));
202- ut_ad(!rw_lock_own(&btr_search_latch, RW_LOCK_EX));
203+ ut_ad(!rw_lock_own(btr_search_get_latch(key), RW_LOCK_SHARED));
204+ ut_ad(!rw_lock_own(btr_search_get_latch(key), RW_LOCK_EX));
205 #endif /* UNIV_SYNC_DEBUG */
206
207- table = btr_search_sys->hash_index;
208+ table = btr_search_get_hash_index(key);
209
210 heap = table->heap;
211
212@@ -153,7 +158,7 @@
213 if (heap->free_block == NULL) {
214 buf_block_t* block = buf_block_alloc(NULL, 0);
215
216- rw_lock_x_lock(&btr_search_latch);
217+ rw_lock_x_lock(btr_search_get_latch(key));
218
219 if (heap->free_block == NULL) {
220 heap->free_block = block;
221@@ -161,7 +166,7 @@
222 buf_block_free(block);
223 }
224
225- rw_lock_x_unlock(&btr_search_latch);
226+ rw_lock_x_unlock(btr_search_get_latch(key));
227 }
228 }
229
230@@ -173,19 +178,30 @@
231 /*==================*/
232 ulint hash_size) /*!< in: hash index hash table size */
233 {
234+ ulint i;
235 /* We allocate the search latch from dynamic memory:
236 see above at the global variable definition */
237
238- btr_search_latch_temp = mem_alloc(sizeof(rw_lock_t));
239+ //btr_search_latch_temp = mem_alloc(sizeof(rw_lock_t));
240
241- rw_lock_create(btr_search_latch_key, &btr_search_latch,
242- SYNC_SEARCH_SYS);
243+ //rw_lock_create(btr_search_latch_key, &btr_search_latch,
244+ // SYNC_SEARCH_SYS);
245 mutex_create(btr_search_enabled_mutex_key,
246 &btr_search_enabled_mutex, SYNC_SEARCH_SYS_CONF);
247
248 btr_search_sys = mem_alloc(sizeof(btr_search_sys_t));
249
250- btr_search_sys->hash_index = ha_create(hash_size, 0, 0);
251+ /* btr_search_index_num should be <= 32. (bits of trx->has_search_latch) */
252+ btr_search_latch_part = mem_alloc(sizeof(rw_lock_t*) * btr_search_index_num);
253+ btr_search_sys->hash_index = mem_alloc(sizeof(hash_table_t*) * btr_search_index_num);
254+ for (i = 0; i < btr_search_index_num; i++) {
255+ btr_search_latch_part[i] = mem_alloc(sizeof(rw_lock_t));
256+
257+ rw_lock_create(btr_search_latch_key,
258+ btr_search_latch_part[i], SYNC_SEARCH_SYS);
259+
260+ btr_search_sys->hash_index[i] = ha_create(hash_size, 0, 0);
261+ }
262 }
263
264 /*****************************************************************//**
265@@ -195,11 +211,20 @@
266 btr_search_sys_free(void)
267 /*=====================*/
268 {
269- rw_lock_free(&btr_search_latch);
270- mem_free(btr_search_latch_temp);
271- btr_search_latch_temp = NULL;
272- mem_heap_free(btr_search_sys->hash_index->heap);
273- hash_table_free(btr_search_sys->hash_index);
274+ ulint i;
275+
276+ for (i = 0; i < btr_search_index_num; i++) {
277+ mem_heap_free(btr_search_sys->hash_index[i]->heap);
278+ hash_table_free(btr_search_sys->hash_index[i]);
279+
280+ rw_lock_free(btr_search_latch_part[i]);
281+
282+ mem_free(btr_search_latch_part[i]);
283+ }
284+
285+ //rw_lock_free(&btr_search_latch);
286+ //mem_free(btr_search_latch_temp);
287+ //btr_search_latch_temp = NULL;
288 mem_free(btr_search_sys);
289 btr_search_sys = NULL;
290 }
291@@ -212,7 +237,7 @@
292 /*====================*/
293 {
294 mutex_enter(&btr_search_enabled_mutex);
295- rw_lock_x_lock(&btr_search_latch);
296+ btr_search_x_lock_all();
297
298 /* Disable access to hash index, also tell ha_insert_for_fold()
299 stop adding new nodes to hash index, but still allow updating
300@@ -230,7 +255,7 @@
301 /* btr_search_enabled_mutex should guarantee this. */
302 ut_ad(!btr_search_enabled);
303
304- rw_lock_x_unlock(&btr_search_latch);
305+ btr_search_x_unlock_all();
306 mutex_exit(&btr_search_enabled_mutex);
307 }
308
309@@ -242,12 +267,12 @@
310 /*====================*/
311 {
312 mutex_enter(&btr_search_enabled_mutex);
313- rw_lock_x_lock(&btr_search_latch);
314+ btr_search_x_lock_all();
315
316 btr_search_enabled = TRUE;
317 btr_search_fully_disabled = FALSE;
318
319- rw_lock_x_unlock(&btr_search_latch);
320+ btr_search_x_unlock_all();
321 mutex_exit(&btr_search_enabled_mutex);
322 }
323
324@@ -300,20 +325,21 @@
325 ulint
326 btr_search_info_get_ref_count(
327 /*==========================*/
328- btr_search_t* info) /*!< in: search info. */
329+ btr_search_t* info, /*!< in: search info. */
330+ index_id_t key)
331 {
332 ulint ret;
333
334 ut_ad(info);
335
336 #ifdef UNIV_SYNC_DEBUG
337- ut_ad(!rw_lock_own(&btr_search_latch, RW_LOCK_SHARED));
338- ut_ad(!rw_lock_own(&btr_search_latch, RW_LOCK_EX));
339+ ut_ad(!rw_lock_own(btr_search_get_latch(key), RW_LOCK_SHARED));
340+ ut_ad(!rw_lock_own(btr_search_get_latch(key), RW_LOCK_EX));
341 #endif /* UNIV_SYNC_DEBUG */
342
343- rw_lock_s_lock(&btr_search_latch);
344+ rw_lock_s_lock(btr_search_get_latch(key));
345 ret = info->ref_count;
346- rw_lock_s_unlock(&btr_search_latch);
347+ rw_lock_s_unlock(btr_search_get_latch(key));
348
349 return(ret);
350 }
351@@ -334,8 +360,8 @@
352 int cmp;
353
354 #ifdef UNIV_SYNC_DEBUG
355- ut_ad(!rw_lock_own(&btr_search_latch, RW_LOCK_SHARED));
356- ut_ad(!rw_lock_own(&btr_search_latch, RW_LOCK_EX));
357+ ut_ad(!rw_lock_own(btr_search_get_latch(cursor->index->id), RW_LOCK_SHARED));
358+ ut_ad(!rw_lock_own(btr_search_get_latch(cursor->index->id), RW_LOCK_EX));
359 #endif /* UNIV_SYNC_DEBUG */
360
361 index = cursor->index;
362@@ -453,8 +479,8 @@
363 /*!< in: cursor */
364 {
365 #ifdef UNIV_SYNC_DEBUG
366- ut_ad(!rw_lock_own(&btr_search_latch, RW_LOCK_SHARED));
367- ut_ad(!rw_lock_own(&btr_search_latch, RW_LOCK_EX));
368+ ut_ad(!rw_lock_own(btr_search_get_latch(cursor->index->id), RW_LOCK_SHARED));
369+ ut_ad(!rw_lock_own(btr_search_get_latch(cursor->index->id), RW_LOCK_EX));
370 ut_ad(rw_lock_own(&block->lock, RW_LOCK_SHARED)
371 || rw_lock_own(&block->lock, RW_LOCK_EX));
372 #endif /* UNIV_SYNC_DEBUG */
373@@ -538,7 +564,7 @@
374
375 ut_ad(cursor->flag == BTR_CUR_HASH_FAIL);
376 #ifdef UNIV_SYNC_DEBUG
377- ut_ad(rw_lock_own(&btr_search_latch, RW_LOCK_EX));
378+ ut_ad(rw_lock_own(btr_search_get_latch(cursor->index->id), RW_LOCK_EX));
379 ut_ad(rw_lock_own(&(block->lock), RW_LOCK_SHARED)
380 || rw_lock_own(&(block->lock), RW_LOCK_EX));
381 #endif /* UNIV_SYNC_DEBUG */
382@@ -578,10 +604,10 @@
383 mem_heap_free(heap);
384 }
385 #ifdef UNIV_SYNC_DEBUG
386- ut_ad(rw_lock_own(&btr_search_latch, RW_LOCK_EX));
387+ ut_ad(rw_lock_own(btr_search_get_latch(cursor->index->id), RW_LOCK_EX));
388 #endif /* UNIV_SYNC_DEBUG */
389
390- ha_insert_for_fold(btr_search_sys->hash_index, fold,
391+ ha_insert_for_fold(btr_search_get_hash_index(cursor->index->id), fold,
392 block, rec);
393 }
394 }
395@@ -601,8 +627,8 @@
396 ulint* params2;
397
398 #ifdef UNIV_SYNC_DEBUG
399- ut_ad(!rw_lock_own(&btr_search_latch, RW_LOCK_SHARED));
400- ut_ad(!rw_lock_own(&btr_search_latch, RW_LOCK_EX));
401+ ut_ad(!rw_lock_own(btr_search_get_latch(cursor->index->id), RW_LOCK_SHARED));
402+ ut_ad(!rw_lock_own(btr_search_get_latch(cursor->index->id), RW_LOCK_EX));
403 #endif /* UNIV_SYNC_DEBUG */
404
405 block = btr_cur_get_block(cursor);
406@@ -623,7 +649,7 @@
407
408 if (build_index || (cursor->flag == BTR_CUR_HASH_FAIL)) {
409
410- btr_search_check_free_space_in_heap();
411+ btr_search_check_free_space_in_heap(cursor->index->id);
412 }
413
414 if (cursor->flag == BTR_CUR_HASH_FAIL) {
415@@ -633,11 +659,11 @@
416 btr_search_n_hash_fail++;
417 #endif /* UNIV_SEARCH_PERF_STAT */
418
419- rw_lock_x_lock(&btr_search_latch);
420+ rw_lock_x_lock(btr_search_get_latch(cursor->index->id));
421
422 btr_search_update_hash_ref(info, block, cursor);
423
424- rw_lock_x_unlock(&btr_search_latch);
425+ rw_lock_x_unlock(btr_search_get_latch(cursor->index->id));
426 }
427
428 if (build_index) {
429@@ -881,17 +907,17 @@
430 cursor->flag = BTR_CUR_HASH;
431
432 if (UNIV_LIKELY(!has_search_latch)) {
433- rw_lock_s_lock(&btr_search_latch);
434+ rw_lock_s_lock(btr_search_get_latch(index_id));
435
436 if (UNIV_UNLIKELY(!btr_search_enabled)) {
437 goto failure_unlock;
438 }
439 }
440
441- ut_ad(rw_lock_get_writer(&btr_search_latch) != RW_LOCK_EX);
442- ut_ad(rw_lock_get_reader_count(&btr_search_latch) > 0);
443+ ut_ad(rw_lock_get_writer(btr_search_get_latch(index_id)) != RW_LOCK_EX);
444+ ut_ad(rw_lock_get_reader_count(btr_search_get_latch(index_id)) > 0);
445
446- rec = ha_search_and_get_data(btr_search_sys->hash_index, fold);
447+ rec = ha_search_and_get_data(btr_search_get_hash_index(index_id), fold);
448
449 if (UNIV_UNLIKELY(!rec)) {
450 goto failure_unlock;
451@@ -909,7 +935,7 @@
452 goto failure_unlock;
453 }
454
455- rw_lock_s_unlock(&btr_search_latch);
456+ rw_lock_s_unlock(btr_search_get_latch(index_id));
457
458 buf_block_dbg_add_level(block, SYNC_TREE_NODE_FROM_HASH);
459 }
460@@ -1006,7 +1032,7 @@
461 /*-------------------------------------------*/
462 failure_unlock:
463 if (UNIV_LIKELY(!has_search_latch)) {
464- rw_lock_s_unlock(&btr_search_latch);
465+ rw_lock_s_unlock(btr_search_get_latch(index_id));
466 }
467 failure:
468 cursor->flag = BTR_CUR_HASH_FAIL;
469@@ -1029,10 +1055,11 @@
470 void
471 btr_search_drop_page_hash_index(
472 /*============================*/
473- buf_block_t* block) /*!< in: block containing index page,
474+ buf_block_t* block, /*!< in: block containing index page,
475 s- or x-latched, or an index page
476 for which we know that
477 block->buf_fix_count == 0 */
478+ dict_index_t* index_in)
479 {
480 hash_table_t* table;
481 ulint n_fields;
482@@ -1051,22 +1078,60 @@
483 ulint* offsets;
484
485 #ifdef UNIV_SYNC_DEBUG
486- ut_ad(!rw_lock_own(&btr_search_latch, RW_LOCK_SHARED));
487- ut_ad(!rw_lock_own(&btr_search_latch, RW_LOCK_EX));
488+ if (index_in) {
489+ ut_ad(!rw_lock_own(btr_search_get_latch(index_in->id), RW_LOCK_SHARED));
490+ ut_ad(!rw_lock_own(btr_search_get_latch(index_in->id), RW_LOCK_EX));
491+ }
492 #endif /* UNIV_SYNC_DEBUG */
493
494 retry:
495- rw_lock_s_lock(&btr_search_latch);
496+ if (index_in) {
497+ index = index_in;
498+ rw_lock_s_lock(btr_search_get_latch(index->id));
499+ } else if (btr_search_index_num > 1) {
500+ rw_lock_t* btr_search_latch;
501+
502+ /* FIXME: This may be optimistic implementation still. */
503+ btr_search_latch = (rw_lock_t*)(block->btr_search_latch);
504+ if (UNIV_LIKELY(!btr_search_latch)) {
505+ if (block->is_hashed) {
506+ goto retry;
507+ }
508+ return;
509+ }
510+ rw_lock_s_lock(btr_search_latch);
511+ if (UNIV_LIKELY(btr_search_latch != block->btr_search_latch)) {
512+ rw_lock_s_unlock(btr_search_latch);
513+ goto retry;
514+ }
515+ if (UNIV_LIKELY(!block->is_hashed)) {
516+ rw_lock_s_unlock(btr_search_latch);
517+ return;
518+ }
519+ index = block->index;
520+ ut_a(btr_search_latch == btr_search_get_latch(index->id));
521+ } else {
522+ /* btr_search_index_num == 1 */
523+ /* btr_search_latch is only one and able to obtain
524+ before evaluating block->is_hashed. */
525+ rw_lock_s_lock(btr_search_latch_part[0]);
526+ if (UNIV_LIKELY(!block->is_hashed)) {
527+ rw_lock_s_unlock(btr_search_latch_part[0]);
528+ return;
529+ }
530+ index = block->index;
531+ }
532+
533 page = block->frame;
534
535 if (UNIV_LIKELY(!block->is_hashed)) {
536
537- rw_lock_s_unlock(&btr_search_latch);
538+ rw_lock_s_unlock(btr_search_get_latch(index->id));
539
540 return;
541 }
542
543- table = btr_search_sys->hash_index;
544+ table = btr_search_get_hash_index(index->id);
545
546 #ifdef UNIV_SYNC_DEBUG
547 ut_ad(rw_lock_own(&(block->lock), RW_LOCK_SHARED)
548@@ -1076,14 +1141,14 @@
549
550 n_fields = block->curr_n_fields;
551 n_bytes = block->curr_n_bytes;
552- index = block->index;
553+ ut_a(index == block->index);
554 ut_a(!dict_index_is_ibuf(index));
555
556 /* NOTE: The fields of block must not be accessed after
557 releasing btr_search_latch, as the index page might only
558 be s-latched! */
559
560- rw_lock_s_unlock(&btr_search_latch);
561+ rw_lock_s_unlock(btr_search_get_latch(index->id));
562
563 ut_a(n_fields + n_bytes > 0);
564
565@@ -1133,7 +1198,7 @@
566 mem_heap_free(heap);
567 }
568
569- rw_lock_x_lock(&btr_search_latch);
570+ rw_lock_x_lock(btr_search_get_latch(index->id));
571
572 if (UNIV_UNLIKELY(!block->is_hashed)) {
573 /* Someone else has meanwhile dropped the hash index */
574@@ -1149,7 +1214,7 @@
575 /* Someone else has meanwhile built a new hash index on the
576 page, with different parameters */
577
578- rw_lock_x_unlock(&btr_search_latch);
579+ rw_lock_x_unlock(btr_search_get_latch(index->id));
580
581 mem_free(folds);
582 goto retry;
583@@ -1165,6 +1230,7 @@
584
585 block->is_hashed = FALSE;
586 block->index = NULL;
587+ block->btr_search_latch = NULL;
588
589 cleanup:
590 #if defined UNIV_AHI_DEBUG || defined UNIV_DEBUG
591@@ -1177,14 +1243,14 @@
592 "InnoDB: the hash index to a page of %s,"
593 " still %lu hash nodes remain.\n",
594 index->name, (ulong) block->n_pointers);
595- rw_lock_x_unlock(&btr_search_latch);
596+ rw_lock_x_unlock(btr_search_get_latch(index->id));
597
598 btr_search_validate();
599 } else {
600- rw_lock_x_unlock(&btr_search_latch);
601+ rw_lock_x_unlock(btr_search_get_latch(index->id));
602 }
603 #else /* UNIV_AHI_DEBUG || UNIV_DEBUG */
604- rw_lock_x_unlock(&btr_search_latch);
605+ rw_lock_x_unlock(btr_search_get_latch(index->id));
606 #endif /* UNIV_AHI_DEBUG || UNIV_DEBUG */
607
608 mem_free(folds);
609@@ -1215,10 +1281,10 @@
610 mem_heap_t* heap = NULL;
611 ulint* offsets;
612
613- rw_lock_x_lock(&btr_search_latch);
614+ rw_lock_x_lock(btr_search_get_latch(index->id));
615 //buf_pool_mutex_enter_all();
616
617- table = btr_search_sys->hash_index;
618+ table = btr_search_get_hash_index(index->id);
619
620 for (j = 0; j < srv_buf_pool_instances; j++) {
621 buf_pool_t* buf_pool;
622@@ -1291,6 +1357,7 @@
623
624 block->is_hashed = FALSE;
625 block->index = NULL;
626+ block->btr_search_latch = NULL;
627
628 #if defined UNIV_AHI_DEBUG || defined UNIV_DEBUG
629 if (UNIV_UNLIKELY(block->n_pointers)) {
630@@ -1313,7 +1380,7 @@
631 }
632
633 //buf_pool_mutex_exit_all();
634- rw_lock_x_unlock(&btr_search_latch);
635+ rw_lock_x_unlock(btr_search_get_latch(index->id));
636
637 if (UNIV_LIKELY_NULL(heap)) {
638 mem_heap_free(heap);
639@@ -1360,7 +1427,7 @@
640
641 buf_block_dbg_add_level(block, SYNC_TREE_NODE_FROM_HASH);
642
643- btr_search_drop_page_hash_index(block);
644+ btr_search_drop_page_hash_index(block, NULL);
645 }
646
647 mtr_commit(&mtr);
648@@ -1402,26 +1469,26 @@
649 ut_ad(index);
650 ut_a(!dict_index_is_ibuf(index));
651
652- table = btr_search_sys->hash_index;
653+ table = btr_search_get_hash_index(index->id);
654 page = buf_block_get_frame(block);
655
656 #ifdef UNIV_SYNC_DEBUG
657- ut_ad(!rw_lock_own(&btr_search_latch, RW_LOCK_EX));
658+ ut_ad(!rw_lock_own(btr_search_get_latch(index->id), RW_LOCK_EX));
659 ut_ad(rw_lock_own(&(block->lock), RW_LOCK_SHARED)
660 || rw_lock_own(&(block->lock), RW_LOCK_EX));
661 #endif /* UNIV_SYNC_DEBUG */
662
663- rw_lock_s_lock(&btr_search_latch);
664+ rw_lock_s_lock(btr_search_get_latch(index->id));
665
666 if (block->is_hashed && ((block->curr_n_fields != n_fields)
667 || (block->curr_n_bytes != n_bytes)
668 || (block->curr_left_side != left_side))) {
669
670- rw_lock_s_unlock(&btr_search_latch);
671+ rw_lock_s_unlock(btr_search_get_latch(index->id));
672
673- btr_search_drop_page_hash_index(block);
674+ btr_search_drop_page_hash_index(block, index);
675 } else {
676- rw_lock_s_unlock(&btr_search_latch);
677+ rw_lock_s_unlock(btr_search_get_latch(index->id));
678 }
679
680 n_recs = page_get_n_recs(page);
681@@ -1515,9 +1582,9 @@
682 fold = next_fold;
683 }
684
685- btr_search_check_free_space_in_heap();
686+ btr_search_check_free_space_in_heap(index->id);
687
688- rw_lock_x_lock(&btr_search_latch);
689+ rw_lock_x_lock(btr_search_get_latch(index->id));
690
691 if (UNIV_UNLIKELY(btr_search_fully_disabled)) {
692 goto exit_func;
693@@ -1545,6 +1612,7 @@
694 block->curr_n_bytes = n_bytes;
695 block->curr_left_side = left_side;
696 block->index = index;
697+ block->btr_search_latch = btr_search_get_latch(index->id);
698
699 for (i = 0; i < n_cached; i++) {
700
701@@ -1552,7 +1620,7 @@
702 }
703
704 exit_func:
705- rw_lock_x_unlock(&btr_search_latch);
706+ rw_lock_x_unlock(btr_search_get_latch(index->id));
707
708 mem_free(folds);
709 mem_free(recs);
710@@ -1591,13 +1659,13 @@
711 ut_a(!(new_block->is_hashed || block->is_hashed)
712 || !dict_index_is_ibuf(index));
713
714- rw_lock_s_lock(&btr_search_latch);
715+ rw_lock_s_lock(btr_search_get_latch(index->id));
716
717 if (new_block->is_hashed) {
718
719- rw_lock_s_unlock(&btr_search_latch);
720+ rw_lock_s_unlock(btr_search_get_latch(index->id));
721
722- btr_search_drop_page_hash_index(block);
723+ btr_search_drop_page_hash_index(block, index);
724
725 return;
726 }
727@@ -1612,7 +1680,7 @@
728 new_block->n_bytes = block->curr_n_bytes;
729 new_block->left_side = left_side;
730
731- rw_lock_s_unlock(&btr_search_latch);
732+ rw_lock_s_unlock(btr_search_get_latch(index->id));
733
734 ut_a(n_fields + n_bytes > 0);
735
736@@ -1624,7 +1692,7 @@
737 return;
738 }
739
740- rw_lock_s_unlock(&btr_search_latch);
741+ rw_lock_s_unlock(btr_search_get_latch(index->id));
742 }
743
744 /********************************************************************//**
745@@ -1663,7 +1731,7 @@
746 ut_a(block->curr_n_fields + block->curr_n_bytes > 0);
747 ut_a(!dict_index_is_ibuf(cursor->index));
748
749- table = btr_search_sys->hash_index;
750+ table = btr_search_get_hash_index(cursor->index->id);
751
752 index_id = cursor->index->id;
753 fold = rec_fold(rec, rec_get_offsets(rec, cursor->index, offsets_,
754@@ -1672,11 +1740,11 @@
755 if (UNIV_LIKELY_NULL(heap)) {
756 mem_heap_free(heap);
757 }
758- rw_lock_x_lock(&btr_search_latch);
759+ rw_lock_x_lock(btr_search_get_latch(cursor->index->id));
760
761 ha_search_and_delete_if_found(table, fold, rec);
762
763- rw_lock_x_unlock(&btr_search_latch);
764+ rw_lock_x_unlock(btr_search_get_latch(cursor->index->id));
765 }
766
767 /********************************************************************//**
768@@ -1710,21 +1778,21 @@
769 ut_a(block->index == cursor->index);
770 ut_a(!dict_index_is_ibuf(cursor->index));
771
772- rw_lock_x_lock(&btr_search_latch);
773+ rw_lock_x_lock(btr_search_get_latch(cursor->index->id));
774
775 if ((cursor->flag == BTR_CUR_HASH)
776 && (cursor->n_fields == block->curr_n_fields)
777 && (cursor->n_bytes == block->curr_n_bytes)
778 && !block->curr_left_side) {
779
780- table = btr_search_sys->hash_index;
781+ table = btr_search_get_hash_index(cursor->index->id);
782
783 ha_search_and_update_if_found(table, cursor->fold, rec,
784 block, page_rec_get_next(rec));
785
786- rw_lock_x_unlock(&btr_search_latch);
787+ rw_lock_x_unlock(btr_search_get_latch(cursor->index->id));
788 } else {
789- rw_lock_x_unlock(&btr_search_latch);
790+ rw_lock_x_unlock(btr_search_get_latch(cursor->index->id));
791
792 btr_search_update_hash_on_insert(cursor);
793 }
794@@ -1759,9 +1827,9 @@
795 ulint* offsets = offsets_;
796 rec_offs_init(offsets_);
797
798- table = btr_search_sys->hash_index;
799+ table = btr_search_get_hash_index(cursor->index->id);
800
801- btr_search_check_free_space_in_heap();
802+ btr_search_check_free_space_in_heap(cursor->index->id);
803
804 rec = btr_cur_get_rec(cursor);
805
806@@ -1806,7 +1874,7 @@
807 } else {
808 if (left_side) {
809
810- rw_lock_x_lock(&btr_search_latch);
811+ rw_lock_x_lock(btr_search_get_latch(index_id));
812
813 locked = TRUE;
814
815@@ -1820,7 +1888,7 @@
816
817 if (!locked) {
818
819- rw_lock_x_lock(&btr_search_latch);
820+ rw_lock_x_lock(btr_search_get_latch(index_id));
821
822 locked = TRUE;
823 }
824@@ -1838,7 +1906,7 @@
825 if (!left_side) {
826
827 if (!locked) {
828- rw_lock_x_lock(&btr_search_latch);
829+ rw_lock_x_lock(btr_search_get_latch(index_id));
830
831 locked = TRUE;
832 }
833@@ -1853,7 +1921,7 @@
834
835 if (!locked) {
836
837- rw_lock_x_lock(&btr_search_latch);
838+ rw_lock_x_lock(btr_search_get_latch(index_id));
839
840 locked = TRUE;
841 }
842@@ -1876,7 +1944,7 @@
843 mem_heap_free(heap);
844 }
845 if (locked) {
846- rw_lock_x_unlock(&btr_search_latch);
847+ rw_lock_x_unlock(btr_search_get_latch(index_id));
848 }
849 }
850
851@@ -1892,7 +1960,7 @@
852 ha_node_t* node;
853 ulint n_page_dumps = 0;
854 ibool ok = TRUE;
855- ulint i;
856+ ulint i,j;
857 ulint cell_count;
858 mem_heap_t* heap = NULL;
859 ulint offsets_[REC_OFFS_NORMAL_SIZE];
860@@ -1904,23 +1972,25 @@
861
862 rec_offs_init(offsets_);
863
864- rw_lock_x_lock(&btr_search_latch);
865+ btr_search_x_lock_all();
866 buf_pool_page_hash_x_lock_all();
867
868- cell_count = hash_get_n_cells(btr_search_sys->hash_index);
869+ for (j = 0; j < btr_search_index_num; j++) {
870+
871+ cell_count = hash_get_n_cells(btr_search_sys->hash_index[j]);
872
873 for (i = 0; i < cell_count; i++) {
874 /* We release btr_search_latch every once in a while to
875 give other queries a chance to run. */
876 if ((i != 0) && ((i % chunk_size) == 0)) {
877 buf_pool_page_hash_x_unlock_all();
878- rw_lock_x_unlock(&btr_search_latch);
879+ btr_search_x_unlock_all();
880 os_thread_yield();
881- rw_lock_x_lock(&btr_search_latch);
882+ btr_search_x_lock_all();
883 buf_pool_page_hash_x_lock_all();
884 }
885
886- node = hash_get_nth_cell(btr_search_sys->hash_index, i)->node;
887+ node = hash_get_nth_cell(btr_search_sys->hash_index[j], i)->node;
888
889 for (; node != NULL; node = node->next) {
890 const buf_block_t* block
891@@ -2029,19 +2099,21 @@
892 give other queries a chance to run. */
893 if (i != 0) {
894 buf_pool_page_hash_x_unlock_all();
895- rw_lock_x_unlock(&btr_search_latch);
896+ btr_search_x_unlock_all();
897 os_thread_yield();
898- rw_lock_x_lock(&btr_search_latch);
899+ btr_search_x_lock_all();
900 buf_pool_page_hash_x_lock_all();
901 }
902
903- if (!ha_validate(btr_search_sys->hash_index, i, end_index)) {
904+ if (!ha_validate(btr_search_sys->hash_index[j], i, end_index)) {
905 ok = FALSE;
906 }
907 }
908
909+ } /*for (j = 0; j < btr_search_index_num; j++)*/
910+
911 buf_pool_page_hash_x_unlock_all();
912- rw_lock_x_unlock(&btr_search_latch);
913+ btr_search_x_unlock_all();
914 if (UNIV_LIKELY_NULL(heap)) {
915 mem_heap_free(heap);
916 }
917diff -ruN a/storage/innobase/buf/buf0buf.c b/storage/innobase/buf/buf0buf.c
918--- a/storage/innobase/buf/buf0buf.c 2010-12-04 15:55:21.351597052 +0900
919+++ b/storage/innobase/buf/buf0buf.c 2010-12-04 16:12:48.654550708 +0900
920@@ -949,6 +949,7 @@
921
922 block->check_index_page_at_flush = FALSE;
923 block->index = NULL;
924+ block->btr_search_latch = NULL;
925
926 block->is_hashed = FALSE;
927
928@@ -1477,7 +1478,7 @@
929 /* To follow the latching order, we
930 have to release btr_search_latch
931 before acquiring block->latch. */
932- rw_lock_x_unlock(&btr_search_latch);
933+ btr_search_x_unlock_all();
934 /* When we release the search latch,
935 we must rescan all blocks, because
936 some may become hashed again. */
937@@ -1508,11 +1509,11 @@
938 anything. block->is_hashed can only
939 be set on uncompressed file pages. */
940
941- btr_search_drop_page_hash_index(block);
942+ btr_search_drop_page_hash_index(block, NULL);
943
944 rw_lock_x_unlock(&block->lock);
945
946- rw_lock_x_lock(&btr_search_latch);
947+ btr_search_x_lock_all();
948
949 ut_ad(!btr_search_enabled);
950 }
951@@ -1531,7 +1532,11 @@
952 ibool released_search_latch;
953
954 #ifdef UNIV_SYNC_DEBUG
955- ut_ad(rw_lock_own(&btr_search_latch, RW_LOCK_EX));
956+ ulint j;
957+
958+ for (j = 0; j < btr_search_index_num; j++) {
959+ ut_ad(rw_lock_own(btr_search_latch_part[j], RW_LOCK_EX));
960+ }
961 #endif /* UNIV_SYNC_DEBUG */
962 ut_ad(!btr_search_enabled);
963
964@@ -2635,6 +2640,7 @@
965 {
966 block->check_index_page_at_flush = FALSE;
967 block->index = NULL;
968+ block->btr_search_latch = NULL;
969
970 block->n_hash_helps = 0;
971 block->is_hashed = FALSE;
972diff -ruN a/storage/innobase/buf/buf0lru.c b/storage/innobase/buf/buf0lru.c
973--- a/storage/innobase/buf/buf0lru.c 2010-12-04 15:35:29.137347521 +0900
974+++ b/storage/innobase/buf/buf0lru.c 2010-12-04 16:12:48.658550840 +0900
975@@ -1775,7 +1775,7 @@
976
977 UNIV_MEM_VALID(((buf_block_t*) bpage)->frame,
978 UNIV_PAGE_SIZE);
979- btr_search_drop_page_hash_index((buf_block_t*) bpage);
980+ btr_search_drop_page_hash_index((buf_block_t*) bpage, NULL);
981 UNIV_MEM_INVALID(((buf_block_t*) bpage)->frame,
982 UNIV_PAGE_SIZE);
983
984diff -ruN a/storage/innobase/dict/dict0dict.c b/storage/innobase/dict/dict0dict.c
985--- a/storage/innobase/dict/dict0dict.c 2010-12-04 15:52:23.398513916 +0900
986+++ b/storage/innobase/dict/dict0dict.c 2010-12-04 16:12:48.662550715 +0900
987@@ -1802,7 +1802,7 @@
988 zero. */
989
990 for (;;) {
991- ulint ref_count = btr_search_info_get_ref_count(info);
992+ ulint ref_count = btr_search_info_get_ref_count(info, index->id);
993 if (ref_count == 0) {
994 break;
995 }
996diff -ruN a/storage/innobase/ha/ha0ha.c b/storage/innobase/ha/ha0ha.c
997--- a/storage/innobase/ha/ha0ha.c 2010-11-03 07:01:13.000000000 +0900
998+++ b/storage/innobase/ha/ha0ha.c 2010-12-04 16:12:48.665593752 +0900
999@@ -102,7 +102,8 @@
1000 ut_ad(table);
1001 ut_ad(table->magic_n == HASH_TABLE_MAGIC_N);
1002 #ifdef UNIV_SYNC_DEBUG
1003- ut_ad(rw_lock_own(&btr_search_latch, RW_LOCK_EXCLUSIVE));
1004+ /* cannot identificate which btr_search_latch[i] for now */
1005+ //ut_ad(rw_lock_own(&btr_search_latch, RW_LOCK_EXCLUSIVE));
1006 #endif /* UNIV_SYNC_DEBUG */
1007
1008 #ifndef UNIV_HOTBACKUP
1009diff -ruN a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc
1010--- a/storage/innobase/handler/ha_innodb.cc 2010-12-04 16:12:20.185850734 +0900
1011+++ b/storage/innobase/handler/ha_innodb.cc 2010-12-04 16:12:48.674552412 +0900
1012@@ -11603,6 +11603,11 @@
1013 "Disable with --skip-innodb-adaptive-hash-index.",
1014 NULL, innodb_adaptive_hash_index_update, TRUE);
1015
1016+static MYSQL_SYSVAR_ULONG(adaptive_hash_index_partitions, btr_search_index_num,
1017+ PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY,
1018+ "Number of InnoDB adaptive hash index partitions (default 1: disable partitioning)",
1019+ NULL, NULL, 1, 1, 32, 0);
1020+
1021 static MYSQL_SYSVAR_ULONG(replication_delay, srv_replication_delay,
1022 PLUGIN_VAR_RQCMDARG,
1023 "Replication thread delay (ms) on the slave server if "
1024@@ -11956,6 +11961,7 @@
1025 MYSQL_SYSVAR(use_sys_stats_table),
1026 MYSQL_SYSVAR(stats_sample_pages),
1027 MYSQL_SYSVAR(adaptive_hash_index),
1028+ MYSQL_SYSVAR(adaptive_hash_index_partitions),
1029 MYSQL_SYSVAR(replication_delay),
1030 MYSQL_SYSVAR(status_file),
1031 MYSQL_SYSVAR(strict_mode),
1032diff -ruN a/storage/innobase/include/btr0sea.h b/storage/innobase/include/btr0sea.h
1033--- a/storage/innobase/include/btr0sea.h 2010-12-03 15:48:03.070987226 +0900
1034+++ b/storage/innobase/include/btr0sea.h 2010-12-04 16:12:48.707551382 +0900
1035@@ -85,7 +85,8 @@
1036 ulint
1037 btr_search_info_get_ref_count(
1038 /*==========================*/
1039- btr_search_t* info); /*!< in: search info. */
1040+ btr_search_t* info, /*!< in: search info. */
1041+ index_id_t key);
1042 /*********************************************************************//**
1043 Updates the search info. */
1044 UNIV_INLINE
1045@@ -136,10 +137,11 @@
1046 void
1047 btr_search_drop_page_hash_index(
1048 /*============================*/
1049- buf_block_t* block); /*!< in: block containing index page,
1050+ buf_block_t* block, /*!< in: block containing index page,
1051 s- or x-latched, or an index page
1052 for which we know that
1053 block->buf_fix_count == 0 */
1054+ dict_index_t* index_in);
1055 /************************************************************************
1056 Drops a page hash index based on index */
1057 UNIV_INTERN
1058@@ -199,10 +201,47 @@
1059 # define btr_search_validate() TRUE
1060 #endif /* defined UNIV_AHI_DEBUG || defined UNIV_DEBUG */
1061
1062+/********************************************************************//**
1063+New functions to control split btr_search_index */
1064+UNIV_INLINE
1065+hash_table_t*
1066+btr_search_get_hash_index(
1067+/*======================*/
1068+ index_id_t key);
1069+
1070+UNIV_INLINE
1071+rw_lock_t*
1072+btr_search_get_latch(
1073+/*=================*/
1074+ index_id_t key);
1075+
1076+UNIV_INLINE
1077+void
1078+btr_search_x_lock_all(void);
1079+/*========================*/
1080+
1081+UNIV_INLINE
1082+void
1083+btr_search_x_unlock_all(void);
1084+/*==========================*/
1085+
1086+UNIV_INLINE
1087+void
1088+btr_search_s_lock_all(void);
1089+/*========================*/
1090+
1091+UNIV_INLINE
1092+void
1093+btr_search_s_unlock_all(void);
1094+/*==========================*/
1095+
1096+
1097 /** Flag: has the search system been enabled?
1098 Protected by btr_search_latch and btr_search_enabled_mutex. */
1099 extern char btr_search_enabled;
1100
1101+extern ulint btr_search_index_num;
1102+
1103 /** Flag: whether the search system has completed its disabling process,
1104 It is set to TRUE right after buf_pool_drop_hash_index() in
1105 btr_search_disable(), indicating hash index entries are cleaned up.
1106@@ -269,7 +308,7 @@
1107
1108 /** The hash index system */
1109 struct btr_search_sys_struct{
1110- hash_table_t* hash_index; /*!< the adaptive hash index,
1111+ hash_table_t** hash_index; /*!< the adaptive hash index,
1112 mapping dtuple_fold values
1113 to rec_t pointers on index pages */
1114 };
1115@@ -290,10 +329,12 @@
1116
1117 Bear in mind (3) and (4) when using the hash index.
1118 */
1119-extern rw_lock_t* btr_search_latch_temp;
1120+//extern rw_lock_t* btr_search_latch_temp;
1121+
1122+extern rw_lock_t** btr_search_latch_part;
1123
1124 /** The latch protecting the adaptive search system */
1125-#define btr_search_latch (*btr_search_latch_temp)
1126+//#define btr_search_latch (*btr_search_latch_temp)
1127
1128 #ifdef UNIV_SEARCH_PERF_STAT
1129 /** Number of successful adaptive hash index lookups */
1130diff -ruN a/storage/innobase/include/btr0sea.ic b/storage/innobase/include/btr0sea.ic
1131--- a/storage/innobase/include/btr0sea.ic 2010-11-03 07:01:13.000000000 +0900
1132+++ b/storage/innobase/include/btr0sea.ic 2010-12-04 16:12:48.709511202 +0900
1133@@ -62,8 +62,8 @@
1134 btr_search_t* info;
1135
1136 #ifdef UNIV_SYNC_DEBUG
1137- ut_ad(!rw_lock_own(&btr_search_latch, RW_LOCK_SHARED));
1138- ut_ad(!rw_lock_own(&btr_search_latch, RW_LOCK_EX));
1139+ ut_ad(!rw_lock_own(btr_search_get_latch(index->id), RW_LOCK_SHARED));
1140+ ut_ad(!rw_lock_own(btr_search_get_latch(index->id), RW_LOCK_EX));
1141 #endif /* UNIV_SYNC_DEBUG */
1142
1143 info = btr_search_get_info(index);
1144@@ -82,3 +82,72 @@
1145
1146 btr_search_info_update_slow(info, cursor);
1147 }
1148+
1149+/*********************************************************************//**
1150+New functions to control split btr_search_index */
1151+UNIV_INLINE
1152+hash_table_t*
1153+btr_search_get_hash_index(
1154+/*======================*/
1155+ index_id_t key)
1156+{
1157+ return(btr_search_sys->hash_index[key % btr_search_index_num]);
1158+}
1159+
1160+UNIV_INLINE
1161+rw_lock_t*
1162+btr_search_get_latch(
1163+/*=================*/
1164+ index_id_t key)
1165+{
1166+ return(btr_search_latch_part[key % btr_search_index_num]);
1167+}
1168+
1169+UNIV_INLINE
1170+void
1171+btr_search_x_lock_all(void)
1172+/*=======================*/
1173+{
1174+ ulint i;
1175+
1176+ for (i = 0; i < btr_search_index_num; i++) {
1177+ rw_lock_x_lock(btr_search_latch_part[i]);
1178+ }
1179+}
1180+
1181+UNIV_INLINE
1182+void
1183+btr_search_x_unlock_all(void)
1184+/*==========================*/
1185+{
1186+ ulint i;
1187+
1188+ for (i = 0; i < btr_search_index_num; i++) {
1189+ rw_lock_x_unlock(btr_search_latch_part[i]);
1190+ }
1191+}
1192+
1193+UNIV_INLINE
1194+void
1195+btr_search_s_lock_all(void)
1196+/*=======================*/
1197+{
1198+ ulint i;
1199+
1200+ for (i = 0; i < btr_search_index_num; i++) {
1201+ rw_lock_s_lock(btr_search_latch_part[i]);
1202+ }
1203+}
1204+
1205+UNIV_INLINE
1206+void
1207+btr_search_s_unlock_all(void)
1208+/*=========================*/
1209+{
1210+ ulint i;
1211+
1212+ for (i = 0; i < btr_search_index_num; i++) {
1213+ rw_lock_s_unlock(btr_search_latch_part[i]);
1214+ }
1215+}
1216+
1217diff -ruN a/storage/innobase/include/buf0buf.h b/storage/innobase/include/buf0buf.h
1218--- a/storage/innobase/include/buf0buf.h 2010-12-15 19:00:07.713604580 +0900
1219+++ b/storage/innobase/include/buf0buf.h 2010-12-15 20:58:03.546839883 +0900
1220@@ -1473,7 +1473,7 @@
1221 pointers in the adaptive hash index
1222 pointing to this frame */
1223 #endif /* UNIV_AHI_DEBUG || UNIV_DEBUG */
1224- unsigned is_hashed:1; /*!< TRUE if hash index has
1225+ volatile unsigned is_hashed:1; /*!< TRUE if hash index has
1226 already been built on this
1227 page; note that it does not
1228 guarantee that the index is
1229@@ -1487,6 +1487,7 @@
1230 unsigned curr_left_side:1;/*!< TRUE or FALSE in hash indexing */
1231 dict_index_t* index; /*!< Index for which the adaptive
1232 hash index has been created. */
1233+ volatile rw_lock_t* btr_search_latch;
1234 /* @} */
1235 # ifdef UNIV_SYNC_DEBUG
1236 /** @name Debug fields */
1237diff -ruN a/storage/innobase/include/row0upd.ic b/storage/innobase/include/row0upd.ic
1238--- a/storage/innobase/include/row0upd.ic 2010-11-03 07:01:13.000000000 +0900
1239+++ b/storage/innobase/include/row0upd.ic 2010-12-04 16:12:48.710551113 +0900
1240@@ -158,7 +158,7 @@
1241 ut_ad(dict_index_is_clust(index));
1242 ut_ad(rec_offs_validate(rec, index, offsets));
1243 #ifdef UNIV_SYNC_DEBUG
1244- if (!rw_lock_own(&btr_search_latch, RW_LOCK_EX)) {
1245+ if (!rw_lock_own(btr_search_get_latch(index->id), RW_LOCK_EX)) {
1246 ut_ad(!buf_block_align(rec)->is_hashed);
1247 }
1248 #endif /* UNIV_SYNC_DEBUG */
1249diff -ruN a/storage/innobase/page/page0page.c b/storage/innobase/page/page0page.c
1250--- a/storage/innobase/page/page0page.c 2010-11-03 07:01:13.000000000 +0900
1251+++ b/storage/innobase/page/page0page.c 2010-12-04 16:12:48.712550963 +0900
1252@@ -218,7 +218,7 @@
1253 const ibool is_hashed = block->is_hashed;
1254
1255 if (is_hashed) {
1256- rw_lock_x_lock(&btr_search_latch);
1257+ rw_lock_x_lock(btr_search_get_latch(block->index->id));
1258 }
1259
1260 ut_ad(!mtr || mtr_memo_contains(mtr, block, MTR_MEMO_PAGE_X_FIX));
1261@@ -244,7 +244,7 @@
1262
1263 #ifndef UNIV_HOTBACKUP
1264 if (is_hashed) {
1265- rw_lock_x_unlock(&btr_search_latch);
1266+ rw_lock_x_unlock(btr_search_get_latch(block->index->id));
1267 }
1268 #endif /* !UNIV_HOTBACKUP */
1269 }
1270diff -ruN a/storage/innobase/page/page0zip.c b/storage/innobase/page/page0zip.c
1271--- a/storage/innobase/page/page0zip.c 2010-12-04 15:57:13.061494433 +0900
1272+++ b/storage/innobase/page/page0zip.c 2010-12-04 16:12:48.716470334 +0900
1273@@ -4445,7 +4445,7 @@
1274
1275 #ifndef UNIV_HOTBACKUP
1276 temp_block = buf_block_alloc(buf_pool, 0);
1277- btr_search_drop_page_hash_index(block);
1278+ btr_search_drop_page_hash_index(block, index);
1279 block->check_index_page_at_flush = TRUE;
1280 #else /* !UNIV_HOTBACKUP */
1281 ut_ad(block == back_block1);
1282diff -ruN a/storage/innobase/row/row0sel.c b/storage/innobase/row/row0sel.c
1283--- a/storage/innobase/row/row0sel.c 2010-12-04 16:09:53.204513572 +0900
1284+++ b/storage/innobase/row/row0sel.c 2010-12-04 16:12:48.722551273 +0900
1285@@ -1210,7 +1210,7 @@
1286 ut_ad(plan->unique_search);
1287 ut_ad(!plan->must_get_clust);
1288 #ifdef UNIV_SYNC_DEBUG
1289- ut_ad(rw_lock_own(&btr_search_latch, RW_LOCK_SHARED));
1290+ ut_ad(rw_lock_own(btr_search_get_latch(index->id), RW_LOCK_SHARED));
1291 #endif /* UNIV_SYNC_DEBUG */
1292
1293 row_sel_open_pcur(plan, TRUE, mtr);
1294@@ -1381,10 +1381,10 @@
1295 && !plan->must_get_clust
1296 && !plan->table->big_rows) {
1297 if (!search_latch_locked) {
1298- rw_lock_s_lock(&btr_search_latch);
1299+ rw_lock_s_lock(btr_search_get_latch(index->id));
1300
1301 search_latch_locked = TRUE;
1302- } else if (rw_lock_get_writer(&btr_search_latch) == RW_LOCK_WAIT_EX) {
1303+ } else if (rw_lock_get_writer(btr_search_get_latch(index->id)) == RW_LOCK_WAIT_EX) {
1304
1305 /* There is an x-latch request waiting: release the
1306 s-latch for a moment; as an s-latch here is often
1307@@ -1393,8 +1393,8 @@
1308 from acquiring an s-latch for a long time, lowering
1309 performance significantly in multiprocessors. */
1310
1311- rw_lock_s_unlock(&btr_search_latch);
1312- rw_lock_s_lock(&btr_search_latch);
1313+ rw_lock_s_unlock(btr_search_get_latch(index->id));
1314+ rw_lock_s_lock(btr_search_get_latch(index->id));
1315 }
1316
1317 found_flag = row_sel_try_search_shortcut(node, plan, &mtr);
1318@@ -1417,7 +1417,7 @@
1319 }
1320
1321 if (search_latch_locked) {
1322- rw_lock_s_unlock(&btr_search_latch);
1323+ rw_lock_s_unlock(btr_search_get_latch(index->id));
1324
1325 search_latch_locked = FALSE;
1326 }
1327@@ -1993,7 +1993,7 @@
1328
1329 func_exit:
1330 if (search_latch_locked) {
1331- rw_lock_s_unlock(&btr_search_latch);
1332+ rw_lock_s_unlock(btr_search_get_latch(index->id));
1333 }
1334 if (UNIV_LIKELY_NULL(heap)) {
1335 mem_heap_free(heap);
1336@@ -3356,6 +3356,8 @@
1337 /* if the returned record was locked and we did a semi-consistent
1338 read (fetch the newest committed version), then this is set to
1339 TRUE */
1340+ ulint i;
1341+ ulint should_release;
1342 #ifdef UNIV_SEARCH_DEBUG
1343 ulint cnt = 0;
1344 #endif /* UNIV_SEARCH_DEBUG */
1345@@ -3441,18 +3443,32 @@
1346 /* PHASE 0: Release a possible s-latch we are holding on the
1347 adaptive hash index latch if there is someone waiting behind */
1348
1349- if (UNIV_UNLIKELY(rw_lock_get_writer(&btr_search_latch) != RW_LOCK_NOT_LOCKED)
1350- && trx->has_search_latch) {
1351+ should_release = 0;
1352+ for (i = 0; i < btr_search_index_num; i++) {
1353+ if ((trx->has_search_latch & ((ulint)1 << i))
1354+ && rw_lock_get_writer(btr_search_latch_part[i])
1355+ != RW_LOCK_NOT_LOCKED) {
1356+ should_release |= ((ulint)1 << i);
1357+ }
1358+ }
1359+
1360+ if (should_release) {
1361
1362 /* There is an x-latch request on the adaptive hash index:
1363 release the s-latch to reduce starvation and wait for
1364 BTR_SEA_TIMEOUT rounds before trying to keep it again over
1365 calls from MySQL */
1366
1367- rw_lock_s_unlock(&btr_search_latch);
1368- trx->has_search_latch = FALSE;
1369+ for (i = 0; i < btr_search_index_num; i++) {
1370+ if (should_release & ((ulint)1 << i)) {
1371+ rw_lock_s_unlock(btr_search_latch_part[i]);
1372+ trx->has_search_latch &= ~((ulint)1 << i);
1373+ }
1374+ }
1375
1376+ if (!trx->has_search_latch) {
1377 trx->search_latch_timeout = BTR_SEA_TIMEOUT;
1378+ }
1379 }
1380
1381 /* Reset the new record lock info if srv_locks_unsafe_for_binlog
1382@@ -3603,9 +3619,11 @@
1383 hash index semaphore! */
1384
1385 #ifndef UNIV_SEARCH_DEBUG
1386- if (!trx->has_search_latch) {
1387- rw_lock_s_lock(&btr_search_latch);
1388- trx->has_search_latch = TRUE;
1389+ if (!(trx->has_search_latch
1390+ & ((ulint)1 << (index->id % btr_search_index_num)))) {
1391+ rw_lock_s_lock(btr_search_get_latch(index->id));
1392+ trx->has_search_latch |=
1393+ (ulint)1 << (index->id % btr_search_index_num);
1394 }
1395 #endif
1396 switch (row_sel_try_search_shortcut_for_mysql(
1397@@ -3666,7 +3684,11 @@
1398
1399 trx->search_latch_timeout--;
1400
1401- rw_lock_s_unlock(&btr_search_latch);
1402+ for (i = 0; i < btr_search_index_num; i++) {
1403+ if (trx->has_search_latch & ((ulint)1 << i)) {
1404+ rw_lock_s_unlock(btr_search_latch_part[i]);
1405+ }
1406+ }
1407 trx->has_search_latch = FALSE;
1408 }
1409
1410@@ -3690,7 +3712,12 @@
1411 /* PHASE 3: Open or restore index cursor position */
1412
1413 if (trx->has_search_latch) {
1414- rw_lock_s_unlock(&btr_search_latch);
1415+
1416+ for (i = 0; i < btr_search_index_num; i++) {
1417+ if (trx->has_search_latch & ((ulint)1 << i)) {
1418+ rw_lock_s_unlock(btr_search_latch_part[i]);
1419+ }
1420+ }
1421 trx->has_search_latch = FALSE;
1422 }
1423
1424diff -ruN a/storage/innobase/srv/srv0srv.c b/storage/innobase/srv/srv0srv.c
1425--- a/storage/innobase/srv/srv0srv.c 2010-12-04 16:12:20.231484679 +0900
1426+++ b/storage/innobase/srv/srv0srv.c 2010-12-04 16:12:48.726551018 +0900
1427@@ -2005,7 +2005,9 @@
1428 "-------------------------------------\n", file);
1429 ibuf_print(file);
1430
1431- ha_print_info(file, btr_search_sys->hash_index);
1432+ for (i = 0; i < btr_search_index_num; i++) {
1433+ ha_print_info(file, btr_search_get_hash_index((index_id_t)i));
1434+ }
1435
1436 fprintf(file,
1437 "%.2f hash searches/s, %.2f non-hash searches/s\n",
1438@@ -2030,14 +2032,15 @@
1439 ut_total_allocated_memory,
1440 mem_pool_get_reserved(mem_comm_pool));
1441 /* Calcurate reserved memories */
1442- if (btr_search_sys && btr_search_sys->hash_index->heap) {
1443- btr_search_sys_subtotal = mem_heap_get_size(btr_search_sys->hash_index->heap);
1444+ if (btr_search_sys && btr_search_sys->hash_index[0]->heap) {
1445+ btr_search_sys_subtotal = mem_heap_get_size(btr_search_sys->hash_index[0]->heap);
1446 } else {
1447 btr_search_sys_subtotal = 0;
1448- for (i=0; i < btr_search_sys->hash_index->n_mutexes; i++) {
1449- btr_search_sys_subtotal += mem_heap_get_size(btr_search_sys->hash_index->heaps[i]);
1450+ for (i=0; i < btr_search_sys->hash_index[0]->n_mutexes; i++) {
1451+ btr_search_sys_subtotal += mem_heap_get_size(btr_search_sys->hash_index[0]->heaps[i]);
1452 }
1453 }
1454+ btr_search_sys_subtotal *= btr_search_index_num;
1455
1456 lock_sys_subtotal = 0;
1457 if (trx_sys) {
1458@@ -2064,10 +2067,10 @@
1459 " Threads %lu \t(%lu + %lu)\n",
1460
1461 (ulong) (btr_search_sys
1462- ? (btr_search_sys->hash_index->n_cells * sizeof(hash_cell_t)) : 0)
1463+ ? (btr_search_sys->hash_index[0]->n_cells * btr_search_index_num * sizeof(hash_cell_t)) : 0)
1464 + btr_search_sys_subtotal,
1465 (ulong) (btr_search_sys
1466- ? (btr_search_sys->hash_index->n_cells * sizeof(hash_cell_t)) : 0),
1467+ ? (btr_search_sys->hash_index[0]->n_cells * btr_search_index_num * sizeof(hash_cell_t)) : 0),
1468 (ulong) btr_search_sys_subtotal,
1469
1470 (ulong) (buf_pool_from_array(0)->page_hash->n_cells * sizeof(hash_cell_t)),
1471diff -ruN a/storage/innobase/sync/sync0sync.c b/storage/innobase/sync/sync0sync.c
1472--- a/storage/innobase/sync/sync0sync.c 2010-12-03 17:36:44.300986571 +0900
1473+++ b/storage/innobase/sync/sync0sync.c 2010-12-04 16:12:48.729513564 +0900
1474@@ -1183,7 +1183,6 @@
1475 case SYNC_ANY_LATCH:
1476 case SYNC_FILE_FORMAT_TAG:
1477 case SYNC_DOUBLEWRITE:
1478- case SYNC_SEARCH_SYS:
1479 case SYNC_SEARCH_SYS_CONF:
1480 case SYNC_TRX_LOCK_HEAP:
1481 case SYNC_KERNEL:
1482@@ -1204,6 +1203,7 @@
1483 ut_error;
1484 }
1485 break;
1486+ case SYNC_SEARCH_SYS:
1487 case SYNC_BUF_LRU_LIST:
1488 case SYNC_BUF_FLUSH_LIST:
1489 case SYNC_BUF_PAGE_HASH:
1490diff -ruN a/storage/innobase/trx/trx0trx.c b/storage/innobase/trx/trx0trx.c
1491--- a/storage/innobase/trx/trx0trx.c 2010-12-03 17:49:11.623953784 +0900
1492+++ b/storage/innobase/trx/trx0trx.c 2010-12-04 16:12:48.731513275 +0900
1493@@ -268,8 +268,14 @@
1494 /*=================================*/
1495 trx_t* trx) /*!< in: transaction */
1496 {
1497+ ulint i;
1498+
1499 if (trx->has_search_latch) {
1500- rw_lock_s_unlock(&btr_search_latch);
1501+ for (i = 0; i < btr_search_index_num; i++) {
1502+ if (trx->has_search_latch & ((ulint)1 << i)) {
1503+ rw_lock_s_unlock(btr_search_latch_part[i]);
1504+ }
1505+ }
1506
1507 trx->has_search_latch = FALSE;
1508 }
01509
=== added file 'innodb_admin_command_base.patch'
--- innodb_admin_command_base.patch 1970-01-01 00:00:00 +0000
+++ innodb_admin_command_base.patch 2011-01-10 13:15:57 +0000
@@ -0,0 +1,173 @@
1# name : innodb_admin_command_base.patch
2# introduced : 11 or before
3# maintainer : Yasufumi
4#
5#!!! notice !!!
6# Any small change to this file in the main branch
7# should be done or reviewed by the maintainer!
8diff -ruN a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc
9--- a/storage/innobase/handler/ha_innodb.cc 2010-12-03 17:32:15.624039043 +0900
10+++ b/storage/innobase/handler/ha_innodb.cc 2010-12-03 17:32:35.424957827 +0900
11@@ -11769,7 +11769,8 @@
12 i_s_innodb_sys_foreign_cols,
13 i_s_innodb_sys_stats,
14 i_s_innodb_table_stats,
15-i_s_innodb_index_stats
16+i_s_innodb_index_stats,
17+i_s_innodb_admin_command
18 mysql_declare_plugin_end;
19
20 /** @brief Initialize the default value of innodb_commit_concurrency.
21diff -ruN a/storage/innobase/handler/i_s.cc b/storage/innobase/handler/i_s.cc
22--- a/storage/innobase/handler/i_s.cc 2010-12-03 17:30:16.299955549 +0900
23+++ b/storage/innobase/handler/i_s.cc 2010-12-03 17:32:35.425989972 +0900
24@@ -4162,3 +4162,139 @@
25 STRUCT_FLD(system_vars, NULL),
26 STRUCT_FLD(__reserved1, NULL)
27 };
28+
29+/***********************************************************************
30+*/
31+static ST_FIELD_INFO i_s_innodb_admin_command_info[] =
32+{
33+ {STRUCT_FLD(field_name, "result_message"),
34+ STRUCT_FLD(field_length, 1024),
35+ STRUCT_FLD(field_type, MYSQL_TYPE_STRING),
36+ STRUCT_FLD(value, 0),
37+ STRUCT_FLD(field_flags, 0),
38+ STRUCT_FLD(old_name, ""),
39+ STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
40+
41+ END_OF_ST_FIELD_INFO
42+};
43+
44+#ifndef INNODB_COMPATIBILITY_HOOKS
45+#error InnoDB needs MySQL to be built with #define INNODB_COMPATIBILITY_HOOKS
46+#endif
47+
48+extern "C" {
49+char **thd_query(MYSQL_THD thd);
50+}
51+
52+static
53+int
54+i_s_innodb_admin_command_fill(
55+/*==========================*/
56+ THD* thd,
57+ TABLE_LIST* tables,
58+ COND* cond)
59+{
60+ TABLE* i_s_table = (TABLE *) tables->table;
61+ char** query_str;
62+ char* ptr;
63+ char quote = '\0';
64+ const char* command_head = "XTRA_";
65+
66+ DBUG_ENTER("i_s_innodb_admin_command_fill");
67+
68+ /* deny access to non-superusers */
69+ if (check_global_access(thd, PROCESS_ACL)) {
70+ DBUG_RETURN(0);
71+ }
72+
73+ if(thd_sql_command(thd) != SQLCOM_SELECT) {
74+ field_store_string(i_s_table->field[0],
75+ "SELECT command is only accepted.");
76+ goto end_func;
77+ }
78+
79+ query_str = thd_query(thd);
80+ ptr = *query_str;
81+
82+ for (; *ptr; ptr++) {
83+ if (*ptr == quote) {
84+ quote = '\0';
85+ } else if (quote) {
86+ } else if (*ptr == '`' || *ptr == '"') {
87+ quote = *ptr;
88+ } else {
89+ long i;
90+ for (i = 0; command_head[i]; i++) {
91+ if (toupper((int)(unsigned char)(ptr[i]))
92+ != toupper((int)(unsigned char)
93+ (command_head[i]))) {
94+ goto nomatch;
95+ }
96+ }
97+ break;
98+nomatch:
99+ ;
100+ }
101+ }
102+
103+ if (!*ptr) {
104+ field_store_string(i_s_table->field[0],
105+ "No XTRA_* command in the SQL statement."
106+ " Please add /*!XTRA_xxxx*/ to the SQL.");
107+ goto end_func;
108+ }
109+
110+ if (!strncasecmp("XTRA_HELLO", ptr, 10)) {
111+ /* This is example command XTRA_HELLO */
112+
113+ ut_print_timestamp(stderr);
114+ fprintf(stderr, " InnoDB: administration command test for XtraDB"
115+ " 'XTRA_HELLO' was detected.\n");
116+
117+ field_store_string(i_s_table->field[0],
118+ "Hello!");
119+ goto end_func;
120+ }
121+
122+ field_store_string(i_s_table->field[0],
123+ "Undefined XTRA_* command.");
124+ goto end_func;
125+
126+end_func:
127+ if (schema_table_store_record(thd, i_s_table)) {
128+ DBUG_RETURN(1);
129+ } else {
130+ DBUG_RETURN(0);
131+ }
132+}
133+
134+static
135+int
136+i_s_innodb_admin_command_init(
137+/*==========================*/
138+ void* p)
139+{
140+ DBUG_ENTER("i_s_innodb_admin_command_init");
141+ ST_SCHEMA_TABLE* schema = (ST_SCHEMA_TABLE*) p;
142+
143+ schema->fields_info = i_s_innodb_admin_command_info;
144+ schema->fill_table = i_s_innodb_admin_command_fill;
145+
146+ DBUG_RETURN(0);
147+}
148+
149+UNIV_INTERN struct st_mysql_plugin i_s_innodb_admin_command =
150+{
151+ STRUCT_FLD(type, MYSQL_INFORMATION_SCHEMA_PLUGIN),
152+ STRUCT_FLD(info, &i_s_info),
153+ STRUCT_FLD(name, "XTRADB_ADMIN_COMMAND"),
154+ STRUCT_FLD(author, plugin_author),
155+ STRUCT_FLD(descr, "XtraDB specific command acceptor"),
156+ STRUCT_FLD(license, PLUGIN_LICENSE_GPL),
157+ STRUCT_FLD(init, i_s_innodb_admin_command_init),
158+ STRUCT_FLD(deinit, i_s_common_deinit),
159+ STRUCT_FLD(version, 0x0100 /* 1.0 */),
160+ STRUCT_FLD(status_vars, NULL),
161+ STRUCT_FLD(system_vars, NULL),
162+ STRUCT_FLD(__reserved1, NULL)
163+};
164diff -ruN a/storage/innobase/handler/i_s.h b/storage/innobase/handler/i_s.h
165--- a/storage/innobase/handler/i_s.h 2010-12-03 17:30:16.301987692 +0900
166+++ b/storage/innobase/handler/i_s.h 2010-12-03 17:32:35.426954555 +0900
167@@ -44,5 +44,6 @@
168 extern struct st_mysql_plugin i_s_innodb_sys_stats;
169 extern struct st_mysql_plugin i_s_innodb_table_stats;
170 extern struct st_mysql_plugin i_s_innodb_index_stats;
171+extern struct st_mysql_plugin i_s_innodb_admin_command;
172
173 #endif /* i_s_h */
0174
=== renamed file 'innodb_admin_command_base.patch' => 'innodb_admin_command_base.patch.moved'
=== added file 'innodb_buffer_pool_pages_i_s.patch'
--- innodb_buffer_pool_pages_i_s.patch 1970-01-01 00:00:00 +0000
+++ innodb_buffer_pool_pages_i_s.patch 2011-01-10 13:15:57 +0000
@@ -0,0 +1,803 @@
1# name : innodb_buffer_pool_pages_i_s.patch
2# introduced : 11 or before
3# maintainer : Yasufumi
4#
5#!!! notice !!!
6# Any small change to this file in the main branch
7# should be done or reviewed by the maintainer!
8diff -ruN a/storage/innobase/buf/buf0buf.c b/storage/innobase/buf/buf0buf.c
9--- a/storage/innobase/buf/buf0buf.c 2010-12-04 20:20:44.595483291 +0900
10+++ b/storage/innobase/buf/buf0buf.c 2010-12-06 19:28:04.055227506 +0900
11@@ -4514,6 +4514,36 @@
12 mutex_exit(block_mutex);
13 }
14
15+/********************************************************************//**
16+*/
17+UNIV_INTERN
18+buf_block_t*
19+buf_page_from_array(
20+/*================*/
21+ buf_pool_t* buf_pool,
22+ ulint n_block)
23+{
24+ ulint n_chunks, offset;
25+ buf_chunk_t* chunk;
26+
27+ ut_a(n_block < buf_pool->curr_size);
28+
29+ chunk = buf_pool->chunks;
30+ offset = n_block;
31+
32+ for (n_chunks = buf_pool->n_chunks; n_chunks--; chunk++) {
33+ if (offset < chunk->size) {
34+ return(&chunk->blocks[offset]);
35+ }
36+
37+ offset -= chunk->size;
38+ }
39+
40+ ut_error;
41+
42+ return(NULL);
43+}
44+
45 /*********************************************************************//**
46 Asserts that all file pages in the buffer are in a replaceable state.
47 @return TRUE */
48diff -ruN a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc
49--- a/storage/innobase/handler/ha_innodb.cc 2010-12-04 20:20:44.614551139 +0900
50+++ b/storage/innobase/handler/ha_innodb.cc 2010-12-06 19:23:47.622195800 +0900
51@@ -12036,6 +12036,9 @@
52 i_s_innodb_sys_stats,
53 i_s_innodb_table_stats,
54 i_s_innodb_index_stats,
55+i_s_innodb_buffer_pool_pages,
56+i_s_innodb_buffer_pool_pages_index,
57+i_s_innodb_buffer_pool_pages_blob,
58 i_s_innodb_admin_command
59 mysql_declare_plugin_end;
60
61diff -ruN a/storage/innobase/handler/i_s.cc b/storage/innobase/handler/i_s.cc
62--- a/storage/innobase/handler/i_s.cc 2010-12-04 19:46:39.786513783 +0900
63+++ b/storage/innobase/handler/i_s.cc 2010-12-06 19:28:52.270226921 +0900
64@@ -51,6 +51,7 @@
65 #include "trx0sys.h" /* for trx_sys */
66 #include "dict0dict.h" /* for dict_sys */
67 #include "buf0lru.h" /* for XTRA_LRU_[DUMP/RESTORE] */
68+#include "btr0btr.h" /* for btr_page_get_index_id */
69 }
70
71 static const char plugin_author[] = "Innobase Oy";
72@@ -4329,3 +4330,701 @@
73 STRUCT_FLD(system_vars, NULL),
74 STRUCT_FLD(__reserved1, NULL)
75 };
76+
77+/***********************************************************************
78+*/
79+static ST_FIELD_INFO i_s_innodb_buffer_pool_pages_fields_info[] =
80+{
81+ {STRUCT_FLD(field_name, "page_type"),
82+ STRUCT_FLD(field_length, 64),
83+ STRUCT_FLD(field_type, MYSQL_TYPE_STRING),
84+ STRUCT_FLD(value, 0),
85+ STRUCT_FLD(field_flags, MY_I_S_MAYBE_NULL),
86+ STRUCT_FLD(old_name, ""),
87+ STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
88+
89+ {STRUCT_FLD(field_name, "space_id"),
90+ STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS),
91+ STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG),
92+ STRUCT_FLD(value, 0),
93+ STRUCT_FLD(field_flags, MY_I_S_UNSIGNED),
94+ STRUCT_FLD(old_name, ""),
95+ STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
96+
97+ {STRUCT_FLD(field_name, "page_no"),
98+ STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS),
99+ STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG),
100+ STRUCT_FLD(value, 0),
101+ STRUCT_FLD(field_flags, MY_I_S_UNSIGNED),
102+ STRUCT_FLD(old_name, ""),
103+ STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
104+
105+ {STRUCT_FLD(field_name, "lru_position"),
106+ STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS),
107+ STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG),
108+ STRUCT_FLD(value, 0),
109+ STRUCT_FLD(field_flags, MY_I_S_UNSIGNED),
110+ STRUCT_FLD(old_name, ""),
111+ STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
112+
113+ {STRUCT_FLD(field_name, "fix_count"),
114+ STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS),
115+ STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG),
116+ STRUCT_FLD(value, 0),
117+ STRUCT_FLD(field_flags, MY_I_S_UNSIGNED),
118+ STRUCT_FLD(old_name, ""),
119+ STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
120+
121+ {STRUCT_FLD(field_name, "flush_type"),
122+ STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS),
123+ STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG),
124+ STRUCT_FLD(value, 0),
125+ STRUCT_FLD(field_flags, MY_I_S_UNSIGNED),
126+ STRUCT_FLD(old_name, ""),
127+ STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
128+
129+ END_OF_ST_FIELD_INFO
130+};
131+
132+static ST_FIELD_INFO i_s_innodb_buffer_pool_pages_index_fields_info[] =
133+{
134+ {STRUCT_FLD(field_name, "index_id"),
135+ STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS),
136+ STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG),
137+ STRUCT_FLD(value, 0),
138+ STRUCT_FLD(field_flags, MY_I_S_UNSIGNED),
139+ STRUCT_FLD(old_name, ""),
140+ STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
141+
142+ {STRUCT_FLD(field_name, "space_id"),
143+ STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS),
144+ STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG),
145+ STRUCT_FLD(value, 0),
146+ STRUCT_FLD(field_flags, MY_I_S_UNSIGNED),
147+ STRUCT_FLD(old_name, ""),
148+ STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
149+
150+ {STRUCT_FLD(field_name, "page_no"),
151+ STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS),
152+ STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG),
153+ STRUCT_FLD(value, 0),
154+ STRUCT_FLD(field_flags, MY_I_S_UNSIGNED),
155+ STRUCT_FLD(old_name, ""),
156+ STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
157+
158+ {STRUCT_FLD(field_name, "n_recs"),
159+ STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS),
160+ STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG),
161+ STRUCT_FLD(value, 0),
162+ STRUCT_FLD(field_flags, MY_I_S_UNSIGNED),
163+ STRUCT_FLD(old_name, ""),
164+ STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
165+
166+ {STRUCT_FLD(field_name, "data_size"),
167+ STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS),
168+ STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG),
169+ STRUCT_FLD(value, 0),
170+ STRUCT_FLD(field_flags, MY_I_S_UNSIGNED),
171+ STRUCT_FLD(old_name, ""),
172+ STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
173+
174+ {STRUCT_FLD(field_name, "hashed"),
175+ STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS),
176+ STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG),
177+ STRUCT_FLD(value, 0),
178+ STRUCT_FLD(field_flags, MY_I_S_UNSIGNED),
179+ STRUCT_FLD(old_name, ""),
180+ STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
181+
182+ {STRUCT_FLD(field_name, "access_time"),
183+ STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS),
184+ STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG),
185+ STRUCT_FLD(value, 0),
186+ STRUCT_FLD(field_flags, MY_I_S_UNSIGNED),
187+ STRUCT_FLD(old_name, ""),
188+ STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
189+
190+ {STRUCT_FLD(field_name, "modified"),
191+ STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS),
192+ STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG),
193+ STRUCT_FLD(value, 0),
194+ STRUCT_FLD(field_flags, MY_I_S_UNSIGNED),
195+ STRUCT_FLD(old_name, ""),
196+ STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
197+
198+ {STRUCT_FLD(field_name, "dirty"),
199+ STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS),
200+ STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG),
201+ STRUCT_FLD(value, 0),
202+ STRUCT_FLD(field_flags, MY_I_S_UNSIGNED),
203+ STRUCT_FLD(old_name, ""),
204+ STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
205+
206+ {STRUCT_FLD(field_name, "old"),
207+ STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS),
208+ STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG),
209+ STRUCT_FLD(value, 0),
210+ STRUCT_FLD(field_flags, MY_I_S_UNSIGNED),
211+ STRUCT_FLD(old_name, ""),
212+ STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
213+
214+ {STRUCT_FLD(field_name, "lru_position"),
215+ STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS),
216+ STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG),
217+ STRUCT_FLD(value, 0),
218+ STRUCT_FLD(field_flags, MY_I_S_UNSIGNED),
219+ STRUCT_FLD(old_name, ""),
220+ STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
221+
222+ {STRUCT_FLD(field_name, "fix_count"),
223+ STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS),
224+ STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG),
225+ STRUCT_FLD(value, 0),
226+ STRUCT_FLD(field_flags, MY_I_S_UNSIGNED),
227+ STRUCT_FLD(old_name, ""),
228+ STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
229+
230+ {STRUCT_FLD(field_name, "flush_type"),
231+ STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS),
232+ STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG),
233+ STRUCT_FLD(value, 0),
234+ STRUCT_FLD(field_flags, MY_I_S_UNSIGNED),
235+ STRUCT_FLD(old_name, ""),
236+ STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
237+
238+ END_OF_ST_FIELD_INFO
239+};
240+
241+static ST_FIELD_INFO i_s_innodb_buffer_pool_pages_blob_fields_info[] =
242+{
243+ {STRUCT_FLD(field_name, "space_id"),
244+ STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS),
245+ STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG),
246+ STRUCT_FLD(value, 0),
247+ STRUCT_FLD(field_flags, MY_I_S_UNSIGNED),
248+ STRUCT_FLD(old_name, ""),
249+ STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
250+
251+ {STRUCT_FLD(field_name, "page_no"),
252+ STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS),
253+ STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG),
254+ STRUCT_FLD(value, 0),
255+ STRUCT_FLD(field_flags, MY_I_S_UNSIGNED),
256+ STRUCT_FLD(old_name, ""),
257+ STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
258+
259+ {STRUCT_FLD(field_name, "compressed"),
260+ STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS),
261+ STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG),
262+ STRUCT_FLD(value, 0),
263+ STRUCT_FLD(field_flags, MY_I_S_UNSIGNED),
264+ STRUCT_FLD(old_name, ""),
265+ STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
266+
267+ {STRUCT_FLD(field_name, "part_len"),
268+ STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS),
269+ STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG),
270+ STRUCT_FLD(value, 0),
271+ STRUCT_FLD(field_flags, MY_I_S_UNSIGNED),
272+ STRUCT_FLD(old_name, ""),
273+ STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
274+
275+ {STRUCT_FLD(field_name, "next_page_no"),
276+ STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS),
277+ STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG),
278+ STRUCT_FLD(value, 0),
279+ STRUCT_FLD(field_flags, MY_I_S_UNSIGNED),
280+ STRUCT_FLD(old_name, ""),
281+ STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
282+
283+ {STRUCT_FLD(field_name, "lru_position"),
284+ STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS),
285+ STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG),
286+ STRUCT_FLD(value, 0),
287+ STRUCT_FLD(field_flags, MY_I_S_UNSIGNED),
288+ STRUCT_FLD(old_name, ""),
289+ STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
290+
291+ {STRUCT_FLD(field_name, "fix_count"),
292+ STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS),
293+ STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG),
294+ STRUCT_FLD(value, 0),
295+ STRUCT_FLD(field_flags, MY_I_S_UNSIGNED),
296+ STRUCT_FLD(old_name, ""),
297+ STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
298+
299+ {STRUCT_FLD(field_name, "flush_type"),
300+ STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS),
301+ STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG),
302+ STRUCT_FLD(value, 0),
303+ STRUCT_FLD(field_flags, MY_I_S_UNSIGNED),
304+ STRUCT_FLD(old_name, ""),
305+ STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
306+
307+ END_OF_ST_FIELD_INFO
308+};
309+
310+/***********************************************************************
311+Fill the dynamic table information_schema.innodb_buffer_pool_pages. */
312+static
313+int
314+i_s_innodb_buffer_pool_pages_fill(
315+/*================*/
316+ /* out: 0 on success, 1 on failure */
317+ THD* thd, /* in: thread */
318+ TABLE_LIST* tables, /* in/out: tables to fill */
319+ COND* cond) /* in: condition (ignored) */
320+{
321+ TABLE* table = (TABLE *) tables->table;
322+ int status = 0;
323+ ulint i;
324+
325+ DBUG_ENTER("i_s_innodb_buffer_pool_pages_fill");
326+
327+ /* deny access to non-superusers */
328+ if (check_global_access(thd, PROCESS_ACL)) {
329+
330+ DBUG_RETURN(0);
331+ }
332+
333+ RETURN_IF_INNODB_NOT_STARTED(tables->schema_table_name);
334+
335+ for (i = 0; i < srv_buf_pool_instances; i++) {
336+ ulint n_block;
337+ buf_pool_t* buf_pool;
338+
339+ buf_pool = buf_pool_from_array(i);
340+
341+ buf_pool_mutex_enter(buf_pool);
342+
343+ for (n_block = 0; n_block < buf_pool->curr_size; n_block++) {
344+ buf_block_t* block = buf_page_from_array(buf_pool, n_block);
345+ const buf_frame_t* frame = block->frame;
346+
347+ char page_type[64];
348+
349+ switch(fil_page_get_type(frame))
350+ {
351+ case FIL_PAGE_INDEX:
352+ strcpy(page_type, "index");
353+ break;
354+ case FIL_PAGE_UNDO_LOG:
355+ strcpy(page_type, "undo_log");
356+ break;
357+ case FIL_PAGE_INODE:
358+ strcpy(page_type, "inode");
359+ break;
360+ case FIL_PAGE_IBUF_FREE_LIST:
361+ strcpy(page_type, "ibuf_free_list");
362+ break;
363+ case FIL_PAGE_TYPE_ALLOCATED:
364+ strcpy(page_type, "allocated");
365+ break;
366+ case FIL_PAGE_IBUF_BITMAP:
367+ strcpy(page_type, "bitmap");
368+ break;
369+ case FIL_PAGE_TYPE_SYS:
370+ strcpy(page_type, "sys");
371+ break;
372+ case FIL_PAGE_TYPE_TRX_SYS:
373+ strcpy(page_type, "trx_sys");
374+ break;
375+ case FIL_PAGE_TYPE_FSP_HDR:
376+ strcpy(page_type, "fsp_hdr");
377+ break;
378+ case FIL_PAGE_TYPE_XDES:
379+ strcpy(page_type, "xdes");
380+ break;
381+ case FIL_PAGE_TYPE_BLOB:
382+ strcpy(page_type, "blob");
383+ break;
384+ case FIL_PAGE_TYPE_ZBLOB:
385+ strcpy(page_type, "zblob");
386+ break;
387+ case FIL_PAGE_TYPE_ZBLOB2:
388+ strcpy(page_type, "zblob2");
389+ break;
390+ default:
391+ sprintf(page_type, "unknown (type=%li)", fil_page_get_type(frame));
392+ }
393+
394+ field_store_string(table->field[0], page_type);
395+ table->field[1]->store(block->page.space);
396+ table->field[2]->store(block->page.offset);
397+ table->field[3]->store(0);
398+ table->field[4]->store(block->page.buf_fix_count);
399+ table->field[5]->store(block->page.flush_type);
400+
401+ if (schema_table_store_record(thd, table)) {
402+ status = 1;
403+ break;
404+ }
405+
406+ }
407+
408+ buf_pool_mutex_exit(buf_pool);
409+ }
410+
411+ DBUG_RETURN(status);
412+}
413+
414+/***********************************************************************
415+Fill the dynamic table information_schema.innodb_buffer_pool_pages_index. */
416+static
417+int
418+i_s_innodb_buffer_pool_pages_index_fill(
419+/*================*/
420+ /* out: 0 on success, 1 on failure */
421+ THD* thd, /* in: thread */
422+ TABLE_LIST* tables, /* in/out: tables to fill */
423+ COND* cond) /* in: condition (ignored) */
424+{
425+ TABLE* table = (TABLE *) tables->table;
426+ int status = 0;
427+ ulint i;
428+ index_id_t index_id;
429+
430+ DBUG_ENTER("i_s_innodb_buffer_pool_pages_index_fill");
431+
432+ /* deny access to non-superusers */
433+ if (check_global_access(thd, PROCESS_ACL)) {
434+
435+ DBUG_RETURN(0);
436+ }
437+
438+ RETURN_IF_INNODB_NOT_STARTED(tables->schema_table_name);
439+
440+ for (i = 0; i < srv_buf_pool_instances; i++) {
441+ ulint n_block;
442+ buf_pool_t* buf_pool;
443+
444+ buf_pool = buf_pool_from_array(i);
445+
446+ buf_pool_mutex_enter(buf_pool);
447+
448+ for (n_block = 0; n_block < buf_pool->curr_size; n_block++) {
449+ buf_block_t* block = buf_page_from_array(buf_pool, n_block);
450+ const buf_frame_t* frame = block->frame;
451+
452+ if (fil_page_get_type(frame) == FIL_PAGE_INDEX) {
453+ index_id = btr_page_get_index_id(frame);
454+ table->field[0]->store(index_id);
455+ table->field[1]->store(block->page.space);
456+ table->field[2]->store(block->page.offset);
457+ table->field[3]->store(page_get_n_recs(frame));
458+ table->field[4]->store(page_get_data_size(frame));
459+ table->field[5]->store(block->is_hashed);
460+ table->field[6]->store(block->page.access_time);
461+ table->field[7]->store(block->page.newest_modification != 0);
462+ table->field[8]->store(block->page.oldest_modification != 0);
463+ table->field[9]->store(block->page.old);
464+ table->field[10]->store(0);
465+ table->field[11]->store(block->page.buf_fix_count);
466+ table->field[12]->store(block->page.flush_type);
467+
468+ if (schema_table_store_record(thd, table)) {
469+ status = 1;
470+ break;
471+ }
472+ }
473+ }
474+
475+ buf_pool_mutex_exit(buf_pool);
476+ }
477+
478+ DBUG_RETURN(status);
479+}
480+
481+/***********************************************************************
482+Fill the dynamic table information_schema.innodb_buffer_pool_pages_index. */
483+static
484+int
485+i_s_innodb_buffer_pool_pages_blob_fill(
486+/*================*/
487+ /* out: 0 on success, 1 on failure */
488+ THD* thd, /* in: thread */
489+ TABLE_LIST* tables, /* in/out: tables to fill */
490+ COND* cond) /* in: condition (ignored) */
491+{
492+ TABLE* table = (TABLE *) tables->table;
493+ int status = 0;
494+ ulint i;
495+
496+ ulint part_len;
497+ ulint next_page_no;
498+
499+ DBUG_ENTER("i_s_innodb_buffer_pool_pages_blob_fill");
500+
501+ /* deny access to non-superusers */
502+ if (check_global_access(thd, PROCESS_ACL)) {
503+
504+ DBUG_RETURN(0);
505+ }
506+
507+ RETURN_IF_INNODB_NOT_STARTED(tables->schema_table_name);
508+
509+ for (i = 0; i < srv_buf_pool_instances; i++) {
510+ ulint n_block;
511+ buf_pool_t* buf_pool;
512+
513+ buf_pool = buf_pool_from_array(i);
514+
515+ buf_pool_mutex_enter(buf_pool);
516+
517+ for (n_block = 0; n_block < buf_pool->curr_size; n_block++) {
518+ buf_block_t* block = buf_page_from_array(buf_pool, n_block);
519+ page_zip_des_t* block_page_zip = buf_block_get_page_zip(block);
520+ const buf_frame_t* frame = block->frame;
521+
522+ if (fil_page_get_type(frame) == FIL_PAGE_TYPE_BLOB) {
523+
524+ if (UNIV_LIKELY_NULL(block_page_zip)) {
525+ part_len = 0; /* hmm, can't figure it out */
526+
527+ next_page_no = mach_read_from_4(
528+ buf_block_get_frame(block)
529+ + FIL_PAGE_NEXT);
530+ } else {
531+ part_len = mach_read_from_4(
532+ buf_block_get_frame(block)
533+ + FIL_PAGE_DATA
534+ + 0 /*BTR_BLOB_HDR_PART_LEN*/);
535+
536+ next_page_no = mach_read_from_4(
537+ buf_block_get_frame(block)
538+ + FIL_PAGE_DATA
539+ + 4 /*BTR_BLOB_HDR_NEXT_PAGE_NO*/);
540+ }
541+
542+ table->field[0]->store(block->page.space);
543+ table->field[1]->store(block->page.offset);
544+ table->field[2]->store(block_page_zip != NULL);
545+ table->field[3]->store(part_len);
546+
547+ if(next_page_no == FIL_NULL)
548+ {
549+ table->field[4]->store(0);
550+ } else {
551+ table->field[4]->store(block->page.offset);
552+ }
553+
554+ table->field[5]->store(0);
555+ table->field[6]->store(block->page.buf_fix_count);
556+ table->field[7]->store(block->page.flush_type);
557+
558+ if (schema_table_store_record(thd, table)) {
559+ status = 1;
560+ break;
561+ }
562+
563+ }
564+ }
565+
566+ buf_pool_mutex_exit(buf_pool);
567+ }
568+
569+ DBUG_RETURN(status);
570+}
571+
572+/***********************************************************************
573+Bind the dynamic table information_schema.innodb_buffer_pool_pages. */
574+static
575+int
576+i_s_innodb_buffer_pool_pages_init(
577+/*=========*/
578+ /* out: 0 on success */
579+ void* p) /* in/out: table schema object */
580+{
581+ DBUG_ENTER("i_s_innodb_buffer_pool_pages_init");
582+ ST_SCHEMA_TABLE* schema = (ST_SCHEMA_TABLE*) p;
583+
584+ schema->fields_info = i_s_innodb_buffer_pool_pages_fields_info;
585+ schema->fill_table = i_s_innodb_buffer_pool_pages_fill;
586+
587+ DBUG_RETURN(0);
588+}
589+
590+/***********************************************************************
591+Bind the dynamic table information_schema.innodb_buffer_pool_pages. */
592+static
593+int
594+i_s_innodb_buffer_pool_pages_index_init(
595+/*=========*/
596+ /* out: 0 on success */
597+ void* p) /* in/out: table schema object */
598+{
599+ DBUG_ENTER("i_s_innodb_buffer_pool_pages_index_init");
600+ ST_SCHEMA_TABLE* schema = (ST_SCHEMA_TABLE*) p;
601+
602+ schema->fields_info = i_s_innodb_buffer_pool_pages_index_fields_info;
603+ schema->fill_table = i_s_innodb_buffer_pool_pages_index_fill;
604+
605+ DBUG_RETURN(0);
606+}
607+
608+/***********************************************************************
609+Bind the dynamic table information_schema.innodb_buffer_pool_pages. */
610+static
611+int
612+i_s_innodb_buffer_pool_pages_blob_init(
613+/*=========*/
614+ /* out: 0 on success */
615+ void* p) /* in/out: table schema object */
616+{
617+ DBUG_ENTER("i_s_innodb_buffer_pool_pages_blob_init");
618+ ST_SCHEMA_TABLE* schema = (ST_SCHEMA_TABLE*) p;
619+
620+ schema->fields_info = i_s_innodb_buffer_pool_pages_blob_fields_info;
621+ schema->fill_table = i_s_innodb_buffer_pool_pages_blob_fill;
622+
623+ DBUG_RETURN(0);
624+}
625+
626+
627+UNIV_INTERN struct st_mysql_plugin i_s_innodb_buffer_pool_pages =
628+{
629+ /* the plugin type (a MYSQL_XXX_PLUGIN value) */
630+ /* int */
631+ STRUCT_FLD(type, MYSQL_INFORMATION_SCHEMA_PLUGIN),
632+
633+ /* pointer to type-specific plugin descriptor */
634+ /* void* */
635+ STRUCT_FLD(info, &i_s_info),
636+
637+ /* plugin name */
638+ /* const char* */
639+ STRUCT_FLD(name, "INNODB_BUFFER_POOL_PAGES"),
640+
641+ /* plugin author (for SHOW PLUGINS) */
642+ /* const char* */
643+ STRUCT_FLD(author, plugin_author),
644+
645+ /* general descriptive text (for SHOW PLUGINS) */
646+ /* const char* */
647+ STRUCT_FLD(descr, "InnoDB buffer pool pages"),
648+
649+ /* the plugin license (PLUGIN_LICENSE_XXX) */
650+ /* int */
651+ STRUCT_FLD(license, PLUGIN_LICENSE_GPL),
652+
653+ /* the function to invoke when plugin is loaded */
654+ /* int (*)(void*); */
655+ STRUCT_FLD(init, i_s_innodb_buffer_pool_pages_init),
656+
657+ /* the function to invoke when plugin is unloaded */
658+ /* int (*)(void*); */
659+ STRUCT_FLD(deinit, i_s_common_deinit),
660+
661+ /* plugin version (for SHOW PLUGINS) */
662+ /* unsigned int */
663+ STRUCT_FLD(version, 0x0100 /* 1.0 */),
664+
665+ /* struct st_mysql_show_var* */
666+ STRUCT_FLD(status_vars, NULL),
667+
668+ /* struct st_mysql_sys_var** */
669+ STRUCT_FLD(system_vars, NULL),
670+
671+ /* reserved for dependency checking */
672+ /* void* */
673+ STRUCT_FLD(__reserved1, NULL)
674+};
675+
676+UNIV_INTERN struct st_mysql_plugin i_s_innodb_buffer_pool_pages_index =
677+{
678+ /* the plugin type (a MYSQL_XXX_PLUGIN value) */
679+ /* int */
680+ STRUCT_FLD(type, MYSQL_INFORMATION_SCHEMA_PLUGIN),
681+
682+ /* pointer to type-specific plugin descriptor */
683+ /* void* */
684+ STRUCT_FLD(info, &i_s_info),
685+
686+ /* plugin name */
687+ /* const char* */
688+ STRUCT_FLD(name, "INNODB_BUFFER_POOL_PAGES_INDEX"),
689+
690+ /* plugin author (for SHOW PLUGINS) */
691+ /* const char* */
692+ STRUCT_FLD(author, plugin_author),
693+
694+ /* general descriptive text (for SHOW PLUGINS) */
695+ /* const char* */
696+ STRUCT_FLD(descr, "InnoDB buffer pool index pages"),
697+
698+ /* the plugin license (PLUGIN_LICENSE_XXX) */
699+ /* int */
700+ STRUCT_FLD(license, PLUGIN_LICENSE_GPL),
701+
702+ /* the function to invoke when plugin is loaded */
703+ /* int (*)(void*); */
704+ STRUCT_FLD(init, i_s_innodb_buffer_pool_pages_index_init),
705+
706+ /* the function to invoke when plugin is unloaded */
707+ /* int (*)(void*); */
708+ STRUCT_FLD(deinit, i_s_common_deinit),
709+
710+ /* plugin version (for SHOW PLUGINS) */
711+ /* unsigned int */
712+ STRUCT_FLD(version, 0x0100 /* 1.0 */),
713+
714+ /* struct st_mysql_show_var* */
715+ STRUCT_FLD(status_vars, NULL),
716+
717+ /* struct st_mysql_sys_var** */
718+ STRUCT_FLD(system_vars, NULL),
719+
720+ /* reserved for dependency checking */
721+ /* void* */
722+ STRUCT_FLD(__reserved1, NULL)
723+};
724+
725+UNIV_INTERN struct st_mysql_plugin i_s_innodb_buffer_pool_pages_blob =
726+{
727+ /* the plugin type (a MYSQL_XXX_PLUGIN value) */
728+ /* int */
729+ STRUCT_FLD(type, MYSQL_INFORMATION_SCHEMA_PLUGIN),
730+
731+ /* pointer to type-specific plugin descriptor */
732+ /* void* */
733+ STRUCT_FLD(info, &i_s_info),
734+
735+ /* plugin name */
736+ /* const char* */
737+ STRUCT_FLD(name, "INNODB_BUFFER_POOL_PAGES_BLOB"),
738+
739+ /* plugin author (for SHOW PLUGINS) */
740+ /* const char* */
741+ STRUCT_FLD(author, plugin_author),
742+
743+ /* general descriptive text (for SHOW PLUGINS) */
744+ /* const char* */
745+ STRUCT_FLD(descr, "InnoDB buffer pool blob pages"),
746+
747+ /* the plugin license (PLUGIN_LICENSE_XXX) */
748+ /* int */
749+ STRUCT_FLD(license, PLUGIN_LICENSE_GPL),
750+
751+ /* the function to invoke when plugin is loaded */
752+ /* int (*)(void*); */
753+ STRUCT_FLD(init, i_s_innodb_buffer_pool_pages_blob_init),
754+
755+ /* the function to invoke when plugin is unloaded */
756+ /* int (*)(void*); */
757+ STRUCT_FLD(deinit, i_s_common_deinit),
758+
759+ /* plugin version (for SHOW PLUGINS) */
760+ /* unsigned int */
761+ STRUCT_FLD(version, 0x0100 /* 1.0 */),
762+
763+ /* struct st_mysql_show_var* */
764+ STRUCT_FLD(status_vars, NULL),
765+
766+ /* struct st_mysql_sys_var** */
767+ STRUCT_FLD(system_vars, NULL),
768+
769+ /* reserved for dependency checking */
770+ /* void* */
771+ STRUCT_FLD(__reserved1, NULL)
772+};
773+
774diff -ruN a/storage/innobase/handler/i_s.h b/storage/innobase/handler/i_s.h
775--- a/storage/innobase/handler/i_s.h 2010-12-04 19:46:39.657513849 +0900
776+++ b/storage/innobase/handler/i_s.h 2010-12-06 19:23:47.635192988 +0900
777@@ -45,5 +45,8 @@
778 extern struct st_mysql_plugin i_s_innodb_table_stats;
779 extern struct st_mysql_plugin i_s_innodb_index_stats;
780 extern struct st_mysql_plugin i_s_innodb_admin_command;
781+extern struct st_mysql_plugin i_s_innodb_buffer_pool_pages;
782+extern struct st_mysql_plugin i_s_innodb_buffer_pool_pages_index;
783+extern struct st_mysql_plugin i_s_innodb_buffer_pool_pages_blob;
784
785 #endif /* i_s_h */
786diff -ruN a/storage/innobase/include/buf0buf.h b/storage/innobase/include/buf0buf.h
787--- a/storage/innobase/include/buf0buf.h 2010-12-04 19:46:40.197471531 +0900
788+++ b/storage/innobase/include/buf0buf.h 2010-12-06 19:23:47.638195824 +0900
789@@ -1072,6 +1072,14 @@
790 /*===========*/
791 const buf_pool_t* buf_pool) /*!< in: buffer pool */
792 __attribute__((nonnull, const));
793+/********************************************************************//**
794+*/
795+UNIV_INTERN
796+buf_block_t*
797+buf_page_from_array(
798+/*================*/
799+ buf_pool_t* buf_pool,
800+ ulint n_block);
801 /******************************************************************//**
802 Returns the buffer pool instance given a page instance
803 @return buf_pool */
0804
=== added file 'innodb_buffer_pool_shm.patch'
--- innodb_buffer_pool_shm.patch 1970-01-01 00:00:00 +0000
+++ innodb_buffer_pool_shm.patch 2011-01-10 13:15:57 +0000
@@ -0,0 +1,1224 @@
1# name : innodb_buffer_pool_shm.patch
2# introduced : 12
3# maintainer : Yasufumi
4#
5#!!! notice !!!
6# Any small change to this file in the main branch
7# should be done or reviewed by the maintainer!
8diff -ruN a/storage/innobase/buf/buf0buddy.c b/storage/innobase/buf/buf0buddy.c
9--- a/storage/innobase/buf/buf0buddy.c 2010-12-04 19:46:39.372513543 +0900
10+++ b/storage/innobase/buf/buf0buddy.c 2010-12-07 17:56:28.302087851 +0900
11@@ -183,7 +183,7 @@
12 void* buf, /*!< in: buffer frame to deallocate */
13 ibool have_page_hash_mutex)
14 {
15- const ulint fold = BUF_POOL_ZIP_FOLD_PTR(buf);
16+ const ulint fold = BUF_POOL_ZIP_FOLD_PTR(buf_pool, buf);
17 buf_page_t* bpage;
18 buf_block_t* block;
19
20@@ -227,7 +227,7 @@
21 buf_block_t* block) /*!< in: buffer frame to allocate */
22 {
23 buf_pool_t* buf_pool = buf_pool_from_block(block);
24- const ulint fold = BUF_POOL_ZIP_FOLD(block);
25+ const ulint fold = BUF_POOL_ZIP_FOLD(buf_pool, block);
26 //ut_ad(buf_pool_mutex_own(buf_pool));
27 ut_ad(!mutex_own(&buf_pool->zip_mutex));
28 ut_ad(buf_block_get_state(block) == BUF_BLOCK_READY_FOR_USE);
29diff -ruN a/storage/innobase/buf/buf0buf.c b/storage/innobase/buf/buf0buf.c
30--- a/storage/innobase/buf/buf0buf.c 2010-12-06 20:16:21.726195340 +0900
31+++ b/storage/innobase/buf/buf0buf.c 2010-12-07 20:40:30.824749814 +0900
32@@ -53,6 +53,10 @@
33 #include "page0zip.h"
34 #include "trx0trx.h"
35 #include "srv0start.h"
36+#include "que0que.h"
37+#include "read0read.h"
38+#include "row0row.h"
39+#include "ha_prototypes.h"
40
41 /* prototypes for new functions added to ha_innodb.cc */
42 trx_t* innobase_get_trx();
43@@ -342,6 +346,31 @@
44 was allocated for the frames */
45 buf_block_t* blocks; /*!< array of buffer control blocks */
46 };
47+
48+/* Buffer pool shared memory segment information */
49+typedef struct buf_shm_info_struct buf_shm_info_t;
50+
51+struct buf_shm_info_struct {
52+ char head_str[8];
53+ ulint binary_id;
54+ ibool is_new; /* during initializing */
55+ ibool clean; /* clean shutdowned and free */
56+ ibool reusable; /* reusable */
57+ ulint buf_pool_size; /* backup value */
58+ ulint page_size; /* backup value */
59+ ulint frame_offset; /* offset of the first frame based on chunk->mem */
60+ ulint zip_hash_offset;
61+ ulint zip_hash_n;
62+
63+ ulint checksum;
64+
65+ buf_pool_t buf_pool_backup;
66+ buf_chunk_t chunk_backup;
67+
68+ ib_uint64_t dummy;
69+};
70+
71+#define BUF_SHM_INFO_HEAD "XTRA_SHM"
72 #endif /* !UNIV_HOTBACKUP */
73
74 /********************************************************************//**
75@@ -988,6 +1017,58 @@
76 #endif /* UNIV_SYNC_DEBUG */
77 }
78
79+static
80+void
81+buf_block_reuse(
82+/*============*/
83+ buf_block_t* block,
84+ ptrdiff_t frame_offset)
85+{
86+ /* block_init */
87+ block->frame += frame_offset;
88+
89+ UNIV_MEM_DESC(block->frame, UNIV_PAGE_SIZE, block);
90+
91+ block->index = NULL;
92+ block->btr_search_latch = NULL;
93+
94+#ifdef UNIV_DEBUG
95+ /* recreate later */
96+ block->page.in_page_hash = FALSE;
97+ block->page.in_zip_hash = FALSE;
98+#endif /* UNIV_DEBUG */
99+
100+#if defined UNIV_AHI_DEBUG || defined UNIV_DEBUG
101+ block->n_pointers = 0;
102+#endif /* UNIV_AHI_DEBUG || UNIV_DEBUG */
103+
104+ if (block->page.zip.data)
105+ block->page.zip.data += frame_offset;
106+
107+ block->is_hashed = FALSE;
108+
109+#if defined PFS_SKIP_BUFFER_MUTEX_RWLOCK || defined PFS_GROUP_BUFFER_SYNC
110+ /* If PFS_SKIP_BUFFER_MUTEX_RWLOCK is defined, skip registration
111+ of buffer block mutex/rwlock with performance schema. If
112+ PFS_GROUP_BUFFER_SYNC is defined, skip the registration
113+ since buffer block mutex/rwlock will be registered later in
114+ pfs_register_buffer_block() */
115+
116+ mutex_create(PFS_NOT_INSTRUMENTED, &block->mutex, SYNC_BUF_BLOCK);
117+ rw_lock_create(PFS_NOT_INSTRUMENTED, &block->lock, SYNC_LEVEL_VARYING);
118+#else /* PFS_SKIP_BUFFER_MUTEX_RWLOCK || PFS_GROUP_BUFFER_SYNC */
119+ mutex_create(buffer_block_mutex_key, &block->mutex, SYNC_BUF_BLOCK);
120+ rw_lock_create(buf_block_lock_key, &block->lock, SYNC_LEVEL_VARYING);
121+#endif /* PFS_SKIP_BUFFER_MUTEX_RWLOCK || PFS_GROUP_BUFFER_SYNC */
122+
123+ ut_ad(rw_lock_validate(&(block->lock)));
124+
125+#ifdef UNIV_SYNC_DEBUG
126+ rw_lock_create(buf_block_debug_latch_key,
127+ &block->debug_latch, SYNC_NO_ORDER_CHECK);
128+#endif /* UNIV_SYNC_DEBUG */
129+}
130+
131 /********************************************************************//**
132 Allocates a chunk of buffer frames.
133 @return chunk, or NULL on failure */
134@@ -1001,26 +1082,188 @@
135 {
136 buf_block_t* block;
137 byte* frame;
138+ ulint zip_hash_n = 0;
139+ ulint zip_hash_mem_size = 0;
140+ hash_table_t* zip_hash_tmp = NULL;
141 ulint i;
142+ buf_shm_info_t* shm_info = NULL;
143
144 /* Round down to a multiple of page size,
145 although it already should be. */
146 mem_size = ut_2pow_round(mem_size, UNIV_PAGE_SIZE);
147+
148+ srv_buffer_pool_shm_is_reused = FALSE;
149+
150+ if (srv_buffer_pool_shm_key) {
151+ /* zip_hash size */
152+ zip_hash_n = (mem_size / UNIV_PAGE_SIZE) * 2;
153+ zip_hash_mem_size = ut_2pow_round(hash_create_needed(zip_hash_n)
154+ + (UNIV_PAGE_SIZE - 1), UNIV_PAGE_SIZE);
155+ }
156+
157 /* Reserve space for the block descriptors. */
158 mem_size += ut_2pow_round((mem_size / UNIV_PAGE_SIZE) * (sizeof *block)
159 + (UNIV_PAGE_SIZE - 1), UNIV_PAGE_SIZE);
160+ if (srv_buffer_pool_shm_key) {
161+ mem_size += ut_2pow_round(sizeof(buf_shm_info_t)
162+ + (UNIV_PAGE_SIZE - 1), UNIV_PAGE_SIZE);
163+ mem_size += zip_hash_mem_size;
164+ }
165
166 chunk->mem_size = mem_size;
167+
168+ if (srv_buffer_pool_shm_key) {
169+ ulint binary_id;
170+ ibool is_new;
171+
172+ ut_a(buf_pool->n_chunks == 1);
173+
174+ fprintf(stderr,
175+ "InnoDB: Warning: The innodb_buffer_pool_shm_key option has been specified.\n"
176+ "InnoDB: Do not change the following between restarts of the server while this option is being used:\n"
177+ "InnoDB: * the mysqld executable between restarts of the server.\n"
178+ "InnoDB: * the value of innodb_buffer_pool_size.\n"
179+ "InnoDB: * the value of innodb_page_size.\n"
180+ "InnoDB: * datafiles created by InnoDB during this session.\n"
181+ "InnoDB: Otherwise, data corruption in datafiles may result.\n");
182+
183+ /* FIXME: This is vague id still */
184+ binary_id = (ulint) ((byte*)mtr_commit - (byte*)btr_root_get)
185+ + (ulint) ((byte*)os_get_os_version - (byte*)buf_calc_page_new_checksum)
186+ + (ulint) ((byte*)page_dir_find_owner_slot - (byte*)dfield_data_is_binary_equal)
187+ + (ulint) ((byte*)que_graph_publish - (byte*)dict_casedn_str)
188+ + (ulint) ((byte*)read_view_oldest_copy_or_open_new - (byte*)fil_space_get_version)
189+ + (ulint) ((byte*)rec_get_n_extern_new - (byte*)fsp_get_size_low)
190+ + (ulint) ((byte*)row_get_trx_id_offset - (byte*)ha_create_func)
191+ + (ulint) ((byte*)srv_set_io_thread_op_info - (byte*)thd_is_replication_slave_thread)
192+ + (ulint) ((byte*)mutex_create_func - (byte*)ibuf_inside)
193+ + (ulint) ((byte*)trx_set_detailed_error - (byte*)lock_check_trx_id_sanity)
194+ + (ulint) ((byte*)ut_time - (byte*)mem_heap_strdup);
195+
196+ chunk->mem = os_shm_alloc(&chunk->mem_size, srv_buffer_pool_shm_key, &is_new);
197+
198+ if (UNIV_UNLIKELY(chunk->mem == NULL)) {
199+ return(NULL);
200+ }
201+init_again:
202+#ifdef UNIV_SET_MEM_TO_ZERO
203+ if (is_new) {
204+ memset(chunk->mem, '\0', chunk->mem_size);
205+ }
206+#endif
207+ /* for ut_fold_binary_32(), these values should be 32-bit aligned */
208+ ut_a(sizeof(buf_shm_info_t) % 4 == 0);
209+ ut_a((ulint)chunk->mem % 4 == 0);
210+ ut_a(chunk->mem_size % 4 == 0);
211+
212+ shm_info = chunk->mem;
213+
214+ zip_hash_tmp = (hash_table_t*)((byte*)chunk->mem + chunk->mem_size - zip_hash_mem_size);
215+
216+ if (is_new) {
217+ strncpy(shm_info->head_str, BUF_SHM_INFO_HEAD, 8);
218+ shm_info->binary_id = binary_id;
219+ shm_info->is_new = TRUE; /* changed to FALSE when the initialization is finished */
220+ shm_info->clean = FALSE; /* changed to TRUE when free the segment. */
221+ shm_info->reusable = FALSE; /* changed to TRUE when validation is finished. */
222+ shm_info->buf_pool_size = srv_buf_pool_size;
223+ shm_info->page_size = srv_page_size;
224+ shm_info->zip_hash_offset = chunk->mem_size - zip_hash_mem_size;
225+ shm_info->zip_hash_n = zip_hash_n;
226+ } else {
227+ ulint checksum;
228+
229+ if (strncmp(shm_info->head_str, BUF_SHM_INFO_HEAD, 8)) {
230+ fprintf(stderr,
231+ "InnoDB: Error: The shared memory segment seems not to be for buffer pool.\n");
232+ return(NULL);
233+ }
234+ if (shm_info->binary_id != binary_id) {
235+ fprintf(stderr,
236+ "InnoDB: Error: The shared memory segment seems not to be for this binary.\n");
237+ return(NULL);
238+ }
239+ if (shm_info->is_new) {
240+ fprintf(stderr,
241+ "InnoDB: Error: The shared memory was not initialized yet.\n");
242+ return(NULL);
243+ }
244+ if (shm_info->buf_pool_size != srv_buf_pool_size) {
245+ fprintf(stderr,
246+ "InnoDB: Error: srv_buf_pool_size is different (shm=%lu current=%lu).\n",
247+ shm_info->buf_pool_size, srv_buf_pool_size);
248+ return(NULL);
249+ }
250+ if (shm_info->page_size != srv_page_size) {
251+ fprintf(stderr,
252+ "InnoDB: Error: srv_page_size is different (shm=%lu current=%lu).\n",
253+ shm_info->page_size, srv_page_size);
254+ return(NULL);
255+ }
256+ if (!shm_info->reusable) {
257+ fprintf(stderr,
258+ "InnoDB: Warning: The shared memory has unrecoverable contents.\n"
259+ "InnoDB: The shared memory segment is initialized.\n");
260+ is_new = TRUE;
261+ goto init_again;
262+ }
263+ if (!shm_info->clean) {
264+ fprintf(stderr,
265+ "InnoDB: Warning: The shared memory was not shut down cleanly.\n"
266+ "InnoDB: The shared memory segment is initialized.\n");
267+ is_new = TRUE;
268+ goto init_again;
269+ }
270+
271+ ut_a(shm_info->zip_hash_offset == chunk->mem_size - zip_hash_mem_size);
272+ ut_a(shm_info->zip_hash_n == zip_hash_n);
273+
274+ /* check checksum */
275+ if (srv_buffer_pool_shm_checksum) {
276+ checksum = ut_fold_binary_32((byte*)chunk->mem + sizeof(buf_shm_info_t),
277+ chunk->mem_size - sizeof(buf_shm_info_t));
278+ } else {
279+ checksum = BUF_NO_CHECKSUM_MAGIC;
280+ }
281+
282+ if (shm_info->checksum != BUF_NO_CHECKSUM_MAGIC
283+ && shm_info->checksum != checksum) {
284+ fprintf(stderr,
285+ "InnoDB: Error: checksum of the shared memory is not match. "
286+ "(stored=%lu calculated=%lu)\n",
287+ shm_info->checksum, checksum);
288+ return(NULL);
289+ }
290+
291+ /* flag to use the segment. */
292+ shm_info->clean = FALSE; /* changed to TRUE when free the segment. */
293+ }
294+
295+ /* init zip_hash contents */
296+ if (is_new) {
297+ hash_create_init(zip_hash_tmp, zip_hash_n);
298+ } else {
299+ /* adjust offset is done later */
300+ hash_create_reuse(zip_hash_tmp);
301+
302+ srv_buffer_pool_shm_is_reused = TRUE;
303+ }
304+ } else {
305 chunk->mem = os_mem_alloc_large(&chunk->mem_size);
306
307 if (UNIV_UNLIKELY(chunk->mem == NULL)) {
308
309 return(NULL);
310 }
311+ }
312
313 /* Allocate the block descriptors from
314 the start of the memory block. */
315+ if (srv_buffer_pool_shm_key) {
316+ chunk->blocks = (buf_block_t*)((byte*)chunk->mem + sizeof(buf_shm_info_t));
317+ } else {
318 chunk->blocks = chunk->mem;
319+ }
320
321 /* Align a pointer to the first frame. Note that when
322 os_large_page_size is smaller than UNIV_PAGE_SIZE,
323@@ -1028,8 +1271,13 @@
324 it is bigger, we may allocate more blocks than requested. */
325
326 frame = ut_align(chunk->mem, UNIV_PAGE_SIZE);
327+ if (srv_buffer_pool_shm_key) {
328+ /* reserve zip_hash space and always -1 for reproductibity */
329+ chunk->size = (chunk->mem_size - zip_hash_mem_size) / UNIV_PAGE_SIZE - 1;
330+ } else {
331 chunk->size = chunk->mem_size / UNIV_PAGE_SIZE
332 - (frame != chunk->mem);
333+ }
334
335 /* Subtract the space needed for block descriptors. */
336 {
337@@ -1043,6 +1291,98 @@
338 chunk->size = size;
339 }
340
341+ if (shm_info && !(shm_info->is_new)) {
342+ /* convert the shared memory segment for reuse */
343+ ptrdiff_t phys_offset;
344+ ptrdiff_t logi_offset;
345+ ptrdiff_t blocks_offset;
346+ void* previous_frame_address;
347+
348+ if (chunk->size < shm_info->chunk_backup.size) {
349+ fprintf(stderr,
350+ "InnoDB: Error: The buffer pool became smaller because of allocated address.\n"
351+ "InnoDB: Retrying may avoid this situation.\n");
352+ shm_info->clean = TRUE; /* release the flag for retrying */
353+ return(NULL);
354+ }
355+
356+ chunk->size = shm_info->chunk_backup.size;
357+ phys_offset = frame - ((byte*)chunk->mem + shm_info->frame_offset);
358+ logi_offset = frame - chunk->blocks[0].frame;
359+ previous_frame_address = chunk->blocks[0].frame;
360+ blocks_offset = (byte*)chunk->blocks - (byte*)shm_info->chunk_backup.blocks;
361+
362+ if (phys_offset || logi_offset || blocks_offset) {
363+ fprintf(stderr,
364+ "InnoDB: Buffer pool in the shared memory segment should be converted.\n"
365+ "InnoDB: Previous frames in address : %p\n"
366+ "InnoDB: Previous frames were located : %p\n"
367+ "InnoDB: Current frames should be located: %p\n"
368+ "InnoDB: Pysical offset : %ld (%#lx)\n"
369+ "InnoDB: Logical offset (frames) : %ld (%#lx)\n"
370+ "InnoDB: Logical offset (blocks) : %ld (%#lx)\n",
371+ (byte*)chunk->mem + shm_info->frame_offset,
372+ chunk->blocks[0].frame, frame,
373+ phys_offset, phys_offset, logi_offset, logi_offset,
374+ blocks_offset, blocks_offset);
375+ } else {
376+ fprintf(stderr,
377+ "InnoDB: Buffer pool in the shared memory segment can be used as it is.\n");
378+ }
379+
380+ if (phys_offset) {
381+ fprintf(stderr,
382+ "InnoDB: Aligning physical offset...");
383+
384+ memmove(frame, (byte*)chunk->mem + shm_info->frame_offset,
385+ chunk->size * UNIV_PAGE_SIZE);
386+
387+ fprintf(stderr,
388+ " Done.\n");
389+ }
390+
391+ /* buf_block_t */
392+ block = chunk->blocks;
393+ for (i = chunk->size; i--; ) {
394+ buf_block_reuse(block, logi_offset);
395+ block++;
396+ }
397+
398+ if (logi_offset || blocks_offset) {
399+ fprintf(stderr,
400+ "InnoDB: Aligning logical offset...");
401+
402+
403+ /* buf_pool_t buf_pool_backup */
404+ UT_LIST_OFFSET(flush_list, buf_page_t, shm_info->buf_pool_backup.flush_list,
405+ previous_frame_address, logi_offset, blocks_offset);
406+ UT_LIST_OFFSET(free, buf_page_t, shm_info->buf_pool_backup.free,
407+ previous_frame_address, logi_offset, blocks_offset);
408+ UT_LIST_OFFSET(LRU, buf_page_t, shm_info->buf_pool_backup.LRU,
409+ previous_frame_address, logi_offset, blocks_offset);
410+ if (shm_info->buf_pool_backup.LRU_old)
411+ shm_info->buf_pool_backup.LRU_old =
412+ (buf_page_t*)((byte*)(shm_info->buf_pool_backup.LRU_old)
413+ + (((void*)shm_info->buf_pool_backup.LRU_old > previous_frame_address)
414+ ? logi_offset : blocks_offset));
415+
416+ UT_LIST_OFFSET(unzip_LRU, buf_block_t, shm_info->buf_pool_backup.unzip_LRU,
417+ previous_frame_address, logi_offset, blocks_offset);
418+
419+ UT_LIST_OFFSET(zip_list, buf_page_t, shm_info->buf_pool_backup.zip_clean,
420+ previous_frame_address, logi_offset, blocks_offset);
421+ for (i = 0; i < BUF_BUDDY_SIZES_MAX; i++) {
422+ UT_LIST_OFFSET(zip_list, buf_page_t, shm_info->buf_pool_backup.zip_free[i],
423+ previous_frame_address, logi_offset, blocks_offset);
424+ }
425+
426+ HASH_OFFSET(zip_hash_tmp, buf_page_t, hash,
427+ previous_frame_address, logi_offset, blocks_offset);
428+
429+ fprintf(stderr,
430+ " Done.\n");
431+ }
432+ } else {
433 /* Init block structs and assign frames for them. Then we
434 assign the frames to the first blocks (we already mapped the
435 memory above). */
436@@ -1068,6 +1408,11 @@
437 block++;
438 frame += UNIV_PAGE_SIZE;
439 }
440+ }
441+
442+ if (shm_info) {
443+ shm_info->frame_offset = chunk->blocks[0].frame - (byte*)chunk->mem;
444+ }
445
446 #ifdef PFS_GROUP_BUFFER_SYNC
447 pfs_register_buffer_block(chunk);
448@@ -1249,6 +1594,8 @@
449 UNIV_MEM_UNDESC(block);
450 }
451
452+ ut_a(!srv_buffer_pool_shm_key);
453+
454 os_mem_free_large(chunk->mem, chunk->mem_size);
455 }
456
457@@ -1289,7 +1636,7 @@
458 ulint instance_no) /*!< in: id of the instance */
459 {
460 ulint i;
461- buf_chunk_t* chunk;
462+ buf_chunk_t* chunk = NULL;
463
464 /* 1. Initialize general fields
465 ------------------------------- */
466@@ -1335,7 +1682,10 @@
467 buf_pool->curr_pool_size = buf_pool->curr_size * UNIV_PAGE_SIZE;
468
469 buf_pool->page_hash = hash_create(2 * buf_pool->curr_size);
470+ /* zip_hash is allocated to shm when srv_buffer_pool_shm_key is enabled */
471+ if (!srv_buffer_pool_shm_key) {
472 buf_pool->zip_hash = hash_create(2 * buf_pool->curr_size);
473+ }
474
475 buf_pool->last_printout_time = ut_time();
476 }
477@@ -1354,6 +1704,86 @@
478
479 /* All fields are initialized by mem_zalloc(). */
480
481+ if (chunk && srv_buffer_pool_shm_key) {
482+ buf_shm_info_t* shm_info;
483+
484+ ut_a((byte*)chunk->blocks == (byte*)chunk->mem + sizeof(buf_shm_info_t));
485+ shm_info = chunk->mem;
486+
487+ buf_pool->zip_hash = (hash_table_t*)((byte*)chunk->mem + shm_info->zip_hash_offset);
488+
489+ if(shm_info->is_new) {
490+ shm_info->is_new = FALSE; /* initialization was finished */
491+ } else {
492+ buf_block_t* block = chunk->blocks;
493+ buf_page_t* b;
494+
495+ /* shm_info->buf_pool_backup should be converted */
496+ /* at buf_chunk_init(). So copy simply. */
497+ buf_pool->flush_list = shm_info->buf_pool_backup.flush_list;
498+ buf_pool->freed_page_clock = shm_info->buf_pool_backup.freed_page_clock;
499+ buf_pool->free = shm_info->buf_pool_backup.free;
500+ buf_pool->LRU = shm_info->buf_pool_backup.LRU;
501+ buf_pool->LRU_old = shm_info->buf_pool_backup.LRU_old;
502+ buf_pool->LRU_old_len = shm_info->buf_pool_backup.LRU_old_len;
503+ buf_pool->unzip_LRU = shm_info->buf_pool_backup.unzip_LRU;
504+ buf_pool->zip_clean = shm_info->buf_pool_backup.zip_clean;
505+ for (i = 0; i < BUF_BUDDY_SIZES_MAX; i++) {
506+ buf_pool->zip_free[i] = shm_info->buf_pool_backup.zip_free[i];
507+ }
508+
509+ for (i = 0; i < chunk->size; i++, block++) {
510+ if (buf_block_get_state(block)
511+ == BUF_BLOCK_FILE_PAGE) {
512+ ut_d(block->page.in_page_hash = TRUE);
513+ HASH_INSERT(buf_page_t, hash, buf_pool->page_hash,
514+ buf_page_address_fold(
515+ block->page.space,
516+ block->page.offset),
517+ &block->page);
518+ }
519+ }
520+
521+ for (b = UT_LIST_GET_FIRST(buf_pool->zip_clean); b;
522+ b = UT_LIST_GET_NEXT(zip_list, b)) {
523+ ut_ad(!b->in_flush_list);
524+ ut_ad(b->in_LRU_list);
525+
526+ ut_d(b->in_page_hash = TRUE);
527+ HASH_INSERT(buf_page_t, hash, buf_pool->page_hash,
528+ buf_page_address_fold(b->space, b->offset), b);
529+ }
530+
531+ for (b = UT_LIST_GET_FIRST(buf_pool->flush_list); b;
532+ b = UT_LIST_GET_NEXT(flush_list, b)) {
533+ ut_ad(b->in_flush_list);
534+ ut_ad(b->in_LRU_list);
535+
536+ switch (buf_page_get_state(b)) {
537+ case BUF_BLOCK_ZIP_DIRTY:
538+ ut_d(b->in_page_hash = TRUE);
539+ HASH_INSERT(buf_page_t, hash, buf_pool->page_hash,
540+ buf_page_address_fold(b->space,
541+ b->offset), b);
542+ break;
543+ case BUF_BLOCK_FILE_PAGE:
544+ /* uncompressed page */
545+ break;
546+ case BUF_BLOCK_ZIP_FREE:
547+ case BUF_BLOCK_ZIP_PAGE:
548+ case BUF_BLOCK_NOT_USED:
549+ case BUF_BLOCK_READY_FOR_USE:
550+ case BUF_BLOCK_MEMORY:
551+ case BUF_BLOCK_REMOVE_HASH:
552+ ut_error;
553+ break;
554+ }
555+ }
556+
557+
558+ }
559+ }
560+
561 mutex_exit(&buf_pool->LRU_list_mutex);
562 rw_lock_x_unlock(&buf_pool->page_hash_latch);
563 buf_pool_mutex_exit(buf_pool);
564@@ -1373,6 +1803,42 @@
565 buf_chunk_t* chunk;
566 buf_chunk_t* chunks;
567
568+ if (srv_buffer_pool_shm_key) {
569+ buf_shm_info_t* shm_info;
570+
571+ ut_a(buf_pool->n_chunks == 1);
572+
573+ chunk = buf_pool->chunks;
574+ shm_info = chunk->mem;
575+ ut_a((byte*)chunk->blocks == (byte*)chunk->mem + sizeof(buf_shm_info_t));
576+
577+ /* if opened, close shm. */
578+ if (!shm_info->clean) {
579+ /* validation the shared memory segment doesn't have unrecoverable contents. */
580+ /* Currently, validation became not needed */
581+ shm_info->reusable = TRUE;
582+
583+ memcpy(&(shm_info->buf_pool_backup), buf_pool, sizeof(buf_pool_t));
584+ memcpy(&(shm_info->chunk_backup), chunk, sizeof(buf_chunk_t));
585+
586+ if (srv_fast_shutdown < 2) {
587+ if (srv_buffer_pool_shm_checksum) {
588+ shm_info->checksum =
589+ ut_fold_binary_32(
590+ (byte*)chunk->mem + sizeof(buf_shm_info_t),
591+ chunk->mem_size - sizeof(buf_shm_info_t));
592+ } else {
593+ shm_info->checksum = BUF_NO_CHECKSUM_MAGIC;
594+ }
595+ shm_info->clean = TRUE;
596+ }
597+
598+ fprintf(stderr,
599+ "InnoDB: The shared memory was closed.\n");
600+ }
601+
602+ os_shm_free(chunk->mem, chunk->mem_size);
603+ } else {
604 chunks = buf_pool->chunks;
605 chunk = chunks + buf_pool->n_chunks;
606
607@@ -1381,10 +1847,13 @@
608 would fail at shutdown. */
609 os_mem_free_large(chunk->mem, chunk->mem_size);
610 }
611+ }
612
613 mem_free(buf_pool->chunks);
614 hash_table_free(buf_pool->page_hash);
615+ if (!srv_buffer_pool_shm_key) {
616 hash_table_free(buf_pool->zip_hash);
617+ }
618 }
619
620 /********************************************************************//**
621@@ -1668,6 +2137,11 @@
622 //buf_pool_mutex_enter(buf_pool);
623 mutex_enter(&buf_pool->LRU_list_mutex);
624
625+ if (srv_buffer_pool_shm_key) {
626+ /* Cannot support shrink */
627+ goto func_done;
628+ }
629+
630 shrink_again:
631 if (buf_pool->n_chunks <= 1) {
632
633@@ -1848,7 +2322,7 @@
634 zip_hash = hash_create(2 * buf_pool->curr_size);
635
636 HASH_MIGRATE(buf_pool->zip_hash, zip_hash, buf_page_t, hash,
637- BUF_POOL_ZIP_FOLD_BPAGE);
638+ buf_pool, BUF_POOL_ZIP_FOLD_BPAGE);
639
640 hash_table_free(buf_pool->zip_hash);
641 buf_pool->zip_hash = zip_hash;
642@@ -2130,6 +2604,11 @@
643 ulint change_size;
644 ulint min_change_size = 1048576 * srv_buf_pool_instances;
645
646+ if (srv_buffer_pool_shm_key) {
647+ /* Cannot support resize */
648+ return;
649+ }
650+
651 buf_pool_mutex_enter_all();
652
653 if (srv_buf_pool_old_size == srv_buf_pool_size) {
654diff -ruN a/storage/innobase/ha/hash0hash.c b/storage/innobase/ha/hash0hash.c
655--- a/storage/innobase/ha/hash0hash.c 2010-11-03 07:01:13.000000000 +0900
656+++ b/storage/innobase/ha/hash0hash.c 2010-12-07 16:10:14.937749140 +0900
657@@ -133,6 +133,70 @@
658 }
659
660 /*************************************************************//**
661+*/
662+UNIV_INTERN
663+ulint
664+hash_create_needed(
665+/*===============*/
666+ ulint n)
667+{
668+ ulint prime;
669+ ulint offset;
670+
671+ prime = ut_find_prime(n);
672+
673+ offset = (sizeof(hash_table_t) + 7) / 8;
674+ offset *= 8;
675+
676+ return(offset + sizeof(hash_cell_t) * prime);
677+}
678+
679+UNIV_INTERN
680+void
681+hash_create_init(
682+/*=============*/
683+ hash_table_t* table,
684+ ulint n)
685+{
686+ ulint prime;
687+ ulint offset;
688+
689+ prime = ut_find_prime(n);
690+
691+ offset = (sizeof(hash_table_t) + 7) / 8;
692+ offset *= 8;
693+
694+ table->array = (hash_cell_t*)(((byte*)table) + offset);
695+ table->n_cells = prime;
696+# if defined UNIV_AHI_DEBUG || defined UNIV_DEBUG
697+ table->adaptive = FALSE;
698+# endif /* UNIV_AHI_DEBUG || UNIV_DEBUG */
699+ table->n_mutexes = 0;
700+ table->mutexes = NULL;
701+ table->heaps = NULL;
702+ table->heap = NULL;
703+ ut_d(table->magic_n = HASH_TABLE_MAGIC_N);
704+
705+ /* Initialize the cell array */
706+ hash_table_clear(table);
707+}
708+
709+UNIV_INTERN
710+void
711+hash_create_reuse(
712+/*==============*/
713+ hash_table_t* table)
714+{
715+ ulint offset;
716+
717+ offset = (sizeof(hash_table_t) + 7) / 8;
718+ offset *= 8;
719+
720+ table->array = (hash_cell_t*)(((byte*)table) + offset);
721+ ut_ad(table->magic_n == HASH_TABLE_MAGIC_N);
722+}
723+
724+/*************************************************************//**
725 Frees a hash table. */
726 UNIV_INTERN
727 void
728diff -ruN a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc
729--- a/storage/innobase/handler/ha_innodb.cc 2010-12-06 20:16:21.733263627 +0900
730+++ b/storage/innobase/handler/ha_innodb.cc 2010-12-07 17:56:28.316139830 +0900
731@@ -194,6 +194,7 @@
732 static my_bool innobase_create_status_file = FALSE;
733 static my_bool innobase_stats_on_metadata = TRUE;
734 static my_bool innobase_use_sys_stats_table = FALSE;
735+static my_bool innobase_buffer_pool_shm_checksum = TRUE;
736
737
738 static char* internal_innobase_data_file_path = NULL;
739@@ -2618,6 +2619,14 @@
740 srv_buf_pool_size = (ulint) innobase_buffer_pool_size;
741 srv_buf_pool_instances = (ulint) innobase_buffer_pool_instances;
742
743+ if (srv_buffer_pool_shm_key && srv_buf_pool_instances > 1) {
744+ fprintf(stderr,
745+ "InnoDB: Warning: innodb_buffer_pool_shm_key cannot be used with several innodb_buffer_pool_instances.\n"
746+ "InnoDB: innodb_buffer_pool_instances was set to 1.\n");
747+ srv_buf_pool_instances = 1;
748+ innobase_buffer_pool_instances = 1;
749+ }
750+
751 srv_mem_pool_size = (ulint) innobase_additional_mem_pool_size;
752
753 srv_n_file_io_threads = (ulint) innobase_file_io_threads;
754@@ -2634,6 +2643,7 @@
755 srv_use_doublewrite_buf = (ibool) innobase_use_doublewrite;
756 srv_use_checksums = (ibool) innobase_use_checksums;
757 srv_fast_checksum = (ibool) innobase_fast_checksum;
758+ srv_buffer_pool_shm_checksum = (ibool) innobase_buffer_pool_shm_checksum;
759
760 #ifdef HAVE_LARGE_PAGES
761 if ((os_use_large_pages = (ibool) my_use_large_pages))
762@@ -11634,6 +11644,16 @@
763 "Number of buffer pool instances, set to higher value on high-end machines to increase scalability",
764 NULL, NULL, 1L, 1L, MAX_BUFFER_POOLS, 1L);
765
766+static MYSQL_SYSVAR_UINT(buffer_pool_shm_key, srv_buffer_pool_shm_key,
767+ PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY,
768+ "[experimental] The key value of shared memory segment for the buffer pool. 0 (default) disables the feature.",
769+ NULL, NULL, 0, 0, INT_MAX32, 0);
770+
771+static MYSQL_SYSVAR_BOOL(buffer_pool_shm_checksum, innobase_buffer_pool_shm_checksum,
772+ PLUGIN_VAR_NOCMDARG | PLUGIN_VAR_READONLY,
773+ "Enable buffer_pool_shm checksum validation (enabled by default).",
774+ NULL, NULL, TRUE);
775+
776 static MYSQL_SYSVAR_ULONG(commit_concurrency, innobase_commit_concurrency,
777 PLUGIN_VAR_RQCMDARG,
778 "Helps in performance tuning in heavily concurrent environments.",
779@@ -11915,6 +11935,8 @@
780 MYSQL_SYSVAR(autoextend_increment),
781 MYSQL_SYSVAR(buffer_pool_size),
782 MYSQL_SYSVAR(buffer_pool_instances),
783+ MYSQL_SYSVAR(buffer_pool_shm_key),
784+ MYSQL_SYSVAR(buffer_pool_shm_checksum),
785 MYSQL_SYSVAR(checksums),
786 MYSQL_SYSVAR(fast_checksum),
787 MYSQL_SYSVAR(commit_concurrency),
788diff -ruN a/storage/innobase/include/buf0buf.h b/storage/innobase/include/buf0buf.h
789--- a/storage/innobase/include/buf0buf.h 2010-12-06 20:16:21.778264552 +0900
790+++ b/storage/innobase/include/buf0buf.h 2010-12-07 17:56:28.322749380 +0900
791@@ -36,6 +36,7 @@
792 #ifndef UNIV_HOTBACKUP
793 #include "ut0rbt.h"
794 #include "os0proc.h"
795+#include "srv0srv.h"
796
797 /** @name Modes for buf_page_get_gen */
798 /* @{ */
799@@ -1520,9 +1521,12 @@
800 /**********************************************************************//**
801 Compute the hash fold value for blocks in buf_pool->zip_hash. */
802 /* @{ */
803-#define BUF_POOL_ZIP_FOLD_PTR(ptr) ((ulint) (ptr) / UNIV_PAGE_SIZE)
804-#define BUF_POOL_ZIP_FOLD(b) BUF_POOL_ZIP_FOLD_PTR((b)->frame)
805-#define BUF_POOL_ZIP_FOLD_BPAGE(b) BUF_POOL_ZIP_FOLD((buf_block_t*) (b))
806+/* the fold should be relative when srv_buffer_pool_shm_key is enabled */
807+#define BUF_POOL_ZIP_FOLD_PTR(bpool, ptr) (!srv_buffer_pool_shm_key\
808+ ?((ulint) (ptr) / UNIV_PAGE_SIZE)\
809+ :((ulint) ((byte*)ptr - (byte*)(buf_page_from_array(bpool, 0)->frame)) / UNIV_PAGE_SIZE))
810+#define BUF_POOL_ZIP_FOLD(bpool, b) BUF_POOL_ZIP_FOLD_PTR(bpool, (b)->frame)
811+#define BUF_POOL_ZIP_FOLD_BPAGE(bpool, b) BUF_POOL_ZIP_FOLD(bpool, (buf_block_t*) (b))
812 /* @} */
813
814 /** @brief The buffer pool statistics structure. */
815diff -ruN a/storage/innobase/include/hash0hash.h b/storage/innobase/include/hash0hash.h
816--- a/storage/innobase/include/hash0hash.h 2010-11-03 07:01:13.000000000 +0900
817+++ b/storage/innobase/include/hash0hash.h 2010-12-07 17:56:28.324726446 +0900
818@@ -49,6 +49,28 @@
819 hash_create(
820 /*========*/
821 ulint n); /*!< in: number of array cells */
822+
823+/*************************************************************//**
824+*/
825+UNIV_INTERN
826+ulint
827+hash_create_needed(
828+/*===============*/
829+ ulint n);
830+
831+UNIV_INTERN
832+void
833+hash_create_init(
834+/*=============*/
835+ hash_table_t* table,
836+ ulint n);
837+
838+UNIV_INTERN
839+void
840+hash_create_reuse(
841+/*==============*/
842+ hash_table_t* table);
843+
844 #ifndef UNIV_HOTBACKUP
845 /*************************************************************//**
846 Creates a mutex array to protect a hash table. */
847@@ -306,7 +328,7 @@
848 /****************************************************************//**
849 Move all hash table entries from OLD_TABLE to NEW_TABLE. */
850
851-#define HASH_MIGRATE(OLD_TABLE, NEW_TABLE, NODE_TYPE, PTR_NAME, FOLD_FUNC) \
852+#define HASH_MIGRATE(OLD_TABLE, NEW_TABLE, NODE_TYPE, PTR_NAME, BPOOL, FOLD_FUNC) \
853 do {\
854 ulint i2222;\
855 ulint cell_count2222;\
856@@ -318,7 +340,7 @@
857 \
858 while (node2222) {\
859 NODE_TYPE* next2222 = node2222->PTR_NAME;\
860- ulint fold2222 = FOLD_FUNC(node2222);\
861+ ulint fold2222 = FOLD_FUNC(BPOOL, node2222);\
862 \
863 HASH_INSERT(NODE_TYPE, PTR_NAME, (NEW_TABLE),\
864 fold2222, node2222);\
865@@ -327,6 +349,33 @@
866 }\
867 }\
868 } while (0)
869+
870+/********************************************************************//**
871+Align nodes with moving location.*/
872+#define HASH_OFFSET(TABLE, NODE_TYPE, PTR_NAME, FADDR, FOFFSET, BOFFSET) \
873+do {\
874+ ulint i2222;\
875+ ulint cell_count2222;\
876+\
877+ cell_count2222 = hash_get_n_cells(TABLE);\
878+\
879+ for (i2222 = 0; i2222 < cell_count2222; i2222++) {\
880+ NODE_TYPE* node2222;\
881+\
882+ if ((TABLE)->array[i2222].node) \
883+ (TABLE)->array[i2222].node = (void*)((byte*)(TABLE)->array[i2222].node \
884+ + (((TABLE)->array[i2222].node > (void*)FADDR)?FOFFSET:BOFFSET));\
885+ node2222 = HASH_GET_FIRST((TABLE), i2222);\
886+\
887+ while (node2222) {\
888+ if (node2222->PTR_NAME) \
889+ node2222->PTR_NAME = (void*)((byte*)(node2222->PTR_NAME) \
890+ + ((((void*)node2222->PTR_NAME) > (void*)FADDR)?FOFFSET:BOFFSET));\
891+\
892+ node2222 = node2222->PTR_NAME;\
893+ }\
894+ }\
895+} while (0)
896
897 /************************************************************//**
898 Gets the mutex index for a fold value in a hash table.
899diff -ruN a/storage/innobase/include/os0proc.h b/storage/innobase/include/os0proc.h
900--- a/storage/innobase/include/os0proc.h 2010-11-03 07:01:13.000000000 +0900
901+++ b/storage/innobase/include/os0proc.h 2010-12-07 16:10:14.955718750 +0900
902@@ -32,6 +32,11 @@
903 #ifdef UNIV_LINUX
904 #include <sys/ipc.h>
905 #include <sys/shm.h>
906+#else
907+# if defined HAVE_SYS_IPC_H && HAVE_SYS_SHM_H
908+#include <sys/ipc.h>
909+#include <sys/shm.h>
910+# endif
911 #endif
912
913 typedef void* os_process_t;
914@@ -70,6 +75,29 @@
915 ulint size); /*!< in: size returned by
916 os_mem_alloc_large() */
917
918+
919+/****************************************************************//**
920+Allocates or attaches and reuses shared memory segment.
921+The content is not cleared automatically.
922+@return allocated memory */
923+UNIV_INTERN
924+void*
925+os_shm_alloc(
926+/*=========*/
927+ ulint* n, /*!< in/out: number of bytes */
928+ uint key,
929+ ibool* is_new);
930+
931+/****************************************************************//**
932+Detach shared memory segment. */
933+UNIV_INTERN
934+void
935+os_shm_free(
936+/*========*/
937+ void *ptr, /*!< in: pointer returned by
938+ os_shm_alloc() */
939+ ulint size); /*!< in: size returned by
940+ os_shm_alloc() */
941 #ifndef UNIV_NONINL
942 #include "os0proc.ic"
943 #endif
944diff -ruN a/storage/innobase/include/srv0srv.h b/storage/innobase/include/srv0srv.h
945--- a/storage/innobase/include/srv0srv.h 2010-12-04 20:20:28.016566697 +0900
946+++ b/storage/innobase/include/srv0srv.h 2010-12-07 16:10:14.956717659 +0900
947@@ -170,6 +170,10 @@
948 extern ulint srv_mem_pool_size;
949 extern ulint srv_lock_table_size;
950
951+extern uint srv_buffer_pool_shm_key;
952+extern ibool srv_buffer_pool_shm_is_reused;
953+extern ibool srv_buffer_pool_shm_checksum;
954+
955 extern ibool srv_thread_concurrency_timer_based;
956
957 extern ulint srv_n_file_io_threads;
958diff -ruN a/storage/innobase/include/ut0lst.h b/storage/innobase/include/ut0lst.h
959--- a/storage/innobase/include/ut0lst.h 2010-11-03 07:01:13.000000000 +0900
960+++ b/storage/innobase/include/ut0lst.h 2010-12-07 16:10:14.957785525 +0900
961@@ -257,5 +257,48 @@
962 ut_a(ut_list_node_313 == NULL); \
963 } while (0)
964
965+/********************************************************************//**
966+Align nodes with moving location.
967+@param NAME the name of the list
968+@param TYPE node type
969+@param BASE base node (not a pointer to it)
970+@param OFFSET offset moved */
971+#define UT_LIST_OFFSET(NAME, TYPE, BASE, FADDR, FOFFSET, BOFFSET) \
972+do { \
973+ ulint ut_list_i_313; \
974+ TYPE* ut_list_node_313; \
975+ \
976+ if ((BASE).start) \
977+ (BASE).start = (void*)((byte*)((BASE).start) \
978+ + (((void*)((BASE).start) > (void*)FADDR)?FOFFSET:BOFFSET));\
979+ if ((BASE).end) \
980+ (BASE).end = (void*)((byte*)((BASE).end) \
981+ + (((void*)((BASE).end) > (void*)FADDR)?FOFFSET:BOFFSET));\
982+ \
983+ ut_list_node_313 = (BASE).start; \
984+ \
985+ for (ut_list_i_313 = (BASE).count; ut_list_i_313--; ) { \
986+ ut_a(ut_list_node_313); \
987+ if ((ut_list_node_313->NAME).prev) \
988+ (ut_list_node_313->NAME).prev = (void*)((byte*)((ut_list_node_313->NAME).prev)\
989+ + (((void*)((ut_list_node_313->NAME).prev) > (void*)FADDR)?FOFFSET:BOFFSET));\
990+ if ((ut_list_node_313->NAME).next) \
991+ (ut_list_node_313->NAME).next = (void*)((byte*)((ut_list_node_313->NAME).next)\
992+ + (((void*)((ut_list_node_313->NAME).next)> (void*)FADDR)?FOFFSET:BOFFSET));\
993+ ut_list_node_313 = (ut_list_node_313->NAME).next; \
994+ } \
995+ \
996+ ut_a(ut_list_node_313 == NULL); \
997+ \
998+ ut_list_node_313 = (BASE).end; \
999+ \
1000+ for (ut_list_i_313 = (BASE).count; ut_list_i_313--; ) { \
1001+ ut_a(ut_list_node_313); \
1002+ ut_list_node_313 = (ut_list_node_313->NAME).prev; \
1003+ } \
1004+ \
1005+ ut_a(ut_list_node_313 == NULL); \
1006+} while (0)
1007+
1008 #endif
1009
1010diff -ruN a/storage/innobase/log/log0recv.c b/storage/innobase/log/log0recv.c
1011--- a/storage/innobase/log/log0recv.c 2010-12-04 19:46:40.212513377 +0900
1012+++ b/storage/innobase/log/log0recv.c 2010-12-07 16:10:14.959785817 +0900
1013@@ -2912,6 +2912,7 @@
1014 /*==========================*/
1015 {
1016 ut_a(!recv_needed_recovery);
1017+ ut_a(!srv_buffer_pool_shm_is_reused);
1018
1019 recv_needed_recovery = TRUE;
1020
1021diff -ruN a/storage/innobase/os/os0proc.c b/storage/innobase/os/os0proc.c
1022--- a/storage/innobase/os/os0proc.c 2010-11-03 07:01:13.000000000 +0900
1023+++ b/storage/innobase/os/os0proc.c 2010-12-07 16:10:14.960800123 +0900
1024@@ -229,3 +229,173 @@
1025 }
1026 #endif
1027 }
1028+
1029+/****************************************************************//**
1030+Allocates or attaches and reuses shared memory segment.
1031+The content is not cleared automatically.
1032+@return allocated memory */
1033+UNIV_INTERN
1034+void*
1035+os_shm_alloc(
1036+/*=========*/
1037+ ulint* n, /*!< in/out: number of bytes */
1038+ uint key,
1039+ ibool* is_new)
1040+{
1041+ void* ptr;
1042+#if defined HAVE_SYS_IPC_H && HAVE_SYS_SHM_H
1043+ ulint size;
1044+ int shmid;
1045+
1046+ *is_new = FALSE;
1047+ fprintf(stderr,
1048+ "InnoDB: The shared memory segment containing the buffer pool is: key %#x (%d).\n",
1049+ key, key);
1050+# if defined HAVE_LARGE_PAGES && defined UNIV_LINUX
1051+ if (!os_use_large_pages || !os_large_page_size) {
1052+ goto skip;
1053+ }
1054+
1055+ /* Align block size to os_large_page_size */
1056+ ut_ad(ut_is_2pow(os_large_page_size));
1057+ size = ut_2pow_round(*n + (os_large_page_size - 1),
1058+ os_large_page_size);
1059+
1060+ shmid = shmget((key_t)key, (size_t)size,
1061+ IPC_CREAT | IPC_EXCL | SHM_HUGETLB | SHM_R | SHM_W);
1062+ if (shmid < 0) {
1063+ if (errno == EEXIST) {
1064+ fprintf(stderr,
1065+ "InnoDB: HugeTLB: The shared memory segment exists.\n");
1066+ shmid = shmget((key_t)key, (size_t)size,
1067+ SHM_HUGETLB | SHM_R | SHM_W);
1068+ if (shmid < 0) {
1069+ fprintf(stderr,
1070+ "InnoDB: HugeTLB: Warning: Failed to allocate %lu bytes. (reuse) errno %d\n",
1071+ size, errno);
1072+ goto skip;
1073+ } else {
1074+ fprintf(stderr,
1075+ "InnoDB: HugeTLB: The existent shared memory segment is used.\n");
1076+ }
1077+ } else {
1078+ fprintf(stderr,
1079+ "InnoDB: HugeTLB: Warning: Failed to allocate %lu bytes. (new) errno %d\n",
1080+ size, errno);
1081+ goto skip;
1082+ }
1083+ } else {
1084+ *is_new = TRUE;
1085+ fprintf(stderr,
1086+ "InnoDB: HugeTLB: A new shared memory segment has been created .\n");
1087+ }
1088+
1089+ ptr = shmat(shmid, NULL, 0);
1090+ if (ptr == (void *)-1) {
1091+ fprintf(stderr,
1092+ "InnoDB: HugeTLB: Warning: Failed to attach shared memory segment, errno %d\n",
1093+ errno);
1094+ ptr = NULL;
1095+ }
1096+
1097+ if (ptr) {
1098+ *n = size;
1099+ os_fast_mutex_lock(&ut_list_mutex);
1100+ ut_total_allocated_memory += size;
1101+ os_fast_mutex_unlock(&ut_list_mutex);
1102+ UNIV_MEM_ALLOC(ptr, size);
1103+ return(ptr);
1104+ }
1105+skip:
1106+ *is_new = FALSE;
1107+# endif /* HAVE_LARGE_PAGES && defined UNIV_LINUX */
1108+# ifdef HAVE_GETPAGESIZE
1109+ size = getpagesize();
1110+# else
1111+ size = UNIV_PAGE_SIZE;
1112+# endif
1113+ /* Align block size to system page size */
1114+ ut_ad(ut_is_2pow(size));
1115+ size = *n = ut_2pow_round(*n + (size - 1), size);
1116+
1117+ shmid = shmget((key_t)key, (size_t)size,
1118+ IPC_CREAT | IPC_EXCL | SHM_R | SHM_W);
1119+ if (shmid < 0) {
1120+ if (errno == EEXIST) {
1121+ fprintf(stderr,
1122+ "InnoDB: A shared memory segment containing the buffer pool seems to already exist.\n");
1123+ shmid = shmget((key_t)key, (size_t)size,
1124+ SHM_R | SHM_W);
1125+ if (shmid < 0) {
1126+ fprintf(stderr,
1127+ "InnoDB: Warning: Failed to allocate %lu bytes. (reuse) errno %d\n",
1128+ size, errno);
1129+ ptr = NULL;
1130+ goto end;
1131+ } else {
1132+ fprintf(stderr,
1133+ "InnoDB: The existent shared memory segment is used.\n");
1134+ }
1135+ } else {
1136+ fprintf(stderr,
1137+ "InnoDB: Warning: Failed to allocate %lu bytes. (new) errno %d\n",
1138+ size, errno);
1139+ ptr = NULL;
1140+ goto end;
1141+ }
1142+ } else {
1143+ *is_new = TRUE;
1144+ fprintf(stderr,
1145+ "InnoDB: A new shared memory segment has been created.\n");
1146+ }
1147+
1148+ ptr = shmat(shmid, NULL, 0);
1149+ if (ptr == (void *)-1) {
1150+ fprintf(stderr,
1151+ "InnoDB: Warning: Failed to attach shared memory segment, errno %d\n",
1152+ errno);
1153+ ptr = NULL;
1154+ }
1155+
1156+ if (ptr) {
1157+ *n = size;
1158+ os_fast_mutex_lock(&ut_list_mutex);
1159+ ut_total_allocated_memory += size;
1160+ os_fast_mutex_unlock(&ut_list_mutex);
1161+ UNIV_MEM_ALLOC(ptr, size);
1162+ }
1163+end:
1164+#else /* HAVE_SYS_IPC_H && HAVE_SYS_SHM_H */
1165+ fprintf(stderr, "InnoDB: shared memory segment is not supported.\n");
1166+ ptr = NULL;
1167+#endif /* HAVE_SYS_IPC_H && HAVE_SYS_SHM_H */
1168+ return(ptr);
1169+}
1170+
1171+/****************************************************************//**
1172+Detach shared memory segment. */
1173+UNIV_INTERN
1174+void
1175+os_shm_free(
1176+/*========*/
1177+ void *ptr, /*!< in: pointer returned by
1178+ os_shm_alloc() */
1179+ ulint size) /*!< in: size returned by
1180+ os_shm_alloc() */
1181+{
1182+ os_fast_mutex_lock(&ut_list_mutex);
1183+ ut_a(ut_total_allocated_memory >= size);
1184+ os_fast_mutex_unlock(&ut_list_mutex);
1185+
1186+#if defined HAVE_SYS_IPC_H && HAVE_SYS_SHM_H
1187+ if (!shmdt(ptr)) {
1188+ os_fast_mutex_lock(&ut_list_mutex);
1189+ ut_a(ut_total_allocated_memory >= size);
1190+ ut_total_allocated_memory -= size;
1191+ os_fast_mutex_unlock(&ut_list_mutex);
1192+ UNIV_MEM_FREE(ptr, size);
1193+ }
1194+#else /* HAVE_SYS_IPC_H && HAVE_SYS_SHM_H */
1195+ fprintf(stderr, "InnoDB: shared memory segment is not supported.\n");
1196+#endif /* HAVE_SYS_IPC_H && HAVE_SYS_SHM_H */
1197+}
1198diff -ruN a/storage/innobase/srv/srv0srv.c b/storage/innobase/srv/srv0srv.c
1199--- a/storage/innobase/srv/srv0srv.c 2010-12-04 20:20:44.687550693 +0900
1200+++ b/storage/innobase/srv/srv0srv.c 2010-12-07 16:10:14.962785720 +0900
1201@@ -231,6 +231,11 @@
1202 UNIV_INTERN ulint srv_mem_pool_size = ULINT_MAX;
1203 UNIV_INTERN ulint srv_lock_table_size = ULINT_MAX;
1204
1205+/* key value for shm */
1206+UNIV_INTERN uint srv_buffer_pool_shm_key = 0;
1207+UNIV_INTERN ibool srv_buffer_pool_shm_is_reused = FALSE;
1208+UNIV_INTERN ibool srv_buffer_pool_shm_checksum = TRUE;
1209+
1210 /* This parameter is deprecated. Use srv_n_io_[read|write]_threads
1211 instead. */
1212 UNIV_INTERN ulint srv_n_file_io_threads = ULINT_MAX;
1213diff -ruN a/storage/innobase/srv/srv0start.c b/storage/innobase/srv/srv0start.c
1214--- a/storage/innobase/srv/srv0start.c 2010-12-04 20:19:29.806482628 +0900
1215+++ b/storage/innobase/srv/srv0start.c 2010-12-07 16:10:14.964785346 +0900
1216@@ -1759,6 +1759,8 @@
1217 Note that this is not as heavy weight as it seems. At
1218 this point there will be only ONE page in the buf_LRU
1219 and there must be no page in the buf_flush list. */
1220+ /* buffer_pool_shm should not be reused when recovery was needed. */
1221+ if (!srv_buffer_pool_shm_is_reused)
1222 buf_pool_invalidate();
1223
1224 /* We always try to do a recovery, even if the database had
01225
=== renamed file 'innodb_buffer_pool_shm.patch' => 'innodb_buffer_pool_shm.patch.moved'
=== added file 'innodb_deadlock_count.patch'
--- innodb_deadlock_count.patch 1970-01-01 00:00:00 +0000
+++ innodb_deadlock_count.patch 2011-01-10 13:15:57 +0000
@@ -0,0 +1,71 @@
1# name : innodb_deadlock_count.patch
2# introduced : 11 or before
3# maintainer : Yasufumi
4#
5#!!! notice !!!
6# Any small change to this file in the main branch
7# should be done or reviewed by the maintainer!
8diff -ruN a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc
9--- a/storage/innobase/handler/ha_innodb.cc 2010-12-04 16:09:53.145500265 +0900
10+++ b/storage/innobase/handler/ha_innodb.cc 2010-12-04 16:10:24.605515894 +0900
11@@ -665,6 +665,8 @@
12 (char*) &export_vars.innodb_dblwr_pages_written, SHOW_LONG},
13 {"dblwr_writes",
14 (char*) &export_vars.innodb_dblwr_writes, SHOW_LONG},
15+ {"deadlocks",
16+ (char*) &export_vars.innodb_deadlocks, SHOW_LONG},
17 {"dict_tables",
18 (char*) &export_vars.innodb_dict_tables, SHOW_LONG},
19 {"have_atomic_builtins",
20diff -ruN a/storage/innobase/include/lock0lock.h b/storage/innobase/include/lock0lock.h
21--- a/storage/innobase/include/lock0lock.h 2010-11-03 07:01:13.000000000 +0900
22+++ b/storage/innobase/include/lock0lock.h 2010-12-04 16:10:24.605515894 +0900
23@@ -43,6 +43,7 @@
24 #endif /* UNIV_DEBUG */
25 /* Buffer for storing information about the most recent deadlock error */
26 extern FILE* lock_latest_err_file;
27+extern ulint srv_n_lock_deadlock_count;
28
29 /*********************************************************************//**
30 Gets the size of a lock struct.
31diff -ruN a/storage/innobase/include/srv0srv.h b/storage/innobase/include/srv0srv.h
32--- a/storage/innobase/include/srv0srv.h 2010-12-04 15:55:21.378480843 +0900
33+++ b/storage/innobase/include/srv0srv.h 2010-12-04 16:10:24.606550983 +0900
34@@ -746,6 +746,7 @@
35 ulint innodb_buffer_pool_read_ahead_evicted;/*!< srv_read_ahead evicted*/
36 ulint innodb_dblwr_pages_written; /*!< srv_dblwr_pages_written */
37 ulint innodb_dblwr_writes; /*!< srv_dblwr_writes */
38+ ulint innodb_deadlocks;
39 ibool innodb_have_atomic_builtins; /*!< HAVE_ATOMIC_BUILTINS */
40 ulint innodb_log_waits; /*!< srv_log_waits */
41 ulint innodb_log_write_requests; /*!< srv_log_write_requests */
42diff -ruN a/storage/innobase/lock/lock0lock.c b/storage/innobase/lock/lock0lock.c
43--- a/storage/innobase/lock/lock0lock.c 2010-12-03 17:49:11.609953956 +0900
44+++ b/storage/innobase/lock/lock0lock.c 2010-12-04 16:10:24.608513889 +0900
45@@ -3328,6 +3328,7 @@
46 break;
47
48 case LOCK_VICTIM_IS_START:
49+ srv_n_lock_deadlock_count++;
50 fputs("*** WE ROLL BACK TRANSACTION (2)\n",
51 lock_latest_err_file);
52 break;
53diff -ruN a/storage/innobase/srv/srv0srv.c b/storage/innobase/srv/srv0srv.c
54--- a/storage/innobase/srv/srv0srv.c 2010-12-04 15:57:13.069513371 +0900
55+++ b/storage/innobase/srv/srv0srv.c 2010-12-04 16:10:24.610593039 +0900
56@@ -462,6 +462,7 @@
57 static ulint srv_n_rows_deleted_old = 0;
58 static ulint srv_n_rows_read_old = 0;
59
60+UNIV_INTERN ulint srv_n_lock_deadlock_count = 0;
61 UNIV_INTERN ulint srv_n_lock_wait_count = 0;
62 UNIV_INTERN ulint srv_n_lock_wait_current_count = 0;
63 UNIV_INTERN ib_int64_t srv_n_lock_wait_time = 0;
64@@ -2237,6 +2238,7 @@
65 export_vars.innodb_buffer_pool_pages_data = LRU_len;
66 export_vars.innodb_buffer_pool_pages_dirty = flush_list_len;
67 export_vars.innodb_buffer_pool_pages_free = free_len;
68+ export_vars.innodb_deadlocks = srv_n_lock_deadlock_count;
69 #ifdef UNIV_DEBUG
70 export_vars.innodb_buffer_pool_pages_latched
71 = buf_get_latched_pages_number();
072
=== renamed file 'innodb_deadlock_count.patch' => 'innodb_deadlock_count.patch.moved'
=== added file 'innodb_dict_size_limit.patch'
--- innodb_dict_size_limit.patch 1970-01-01 00:00:00 +0000
+++ innodb_dict_size_limit.patch 2011-01-10 13:15:57 +0000
@@ -0,0 +1,446 @@
1# name : innodb_dict_size_limit.patch
2# introduced : 11 or before
3# maintainer : Yasufumi
4#
5#!!! notice !!!
6# Any small change to this file in the main branch
7# should be done or reviewed by the maintainer!
8diff -ruN a/storage/innobase/btr/btr0sea.c b/storage/innobase/btr/btr0sea.c
9--- a/storage/innobase/btr/btr0sea.c 2010-11-03 07:01:13.000000000 +0900
10+++ b/storage/innobase/btr/btr0sea.c 2010-12-03 15:45:47.503988924 +0900
11@@ -1185,6 +1185,132 @@
12 mem_free(folds);
13 }
14
15+/************************************************************************
16+Drops a page hash index based on index */
17+UNIV_INTERN
18+void
19+btr_search_drop_page_hash_index_on_index(
20+/*=====================================*/
21+ dict_index_t* index) /* in: record descriptor */
22+{
23+ buf_page_t* bpage;
24+ hash_table_t* table;
25+ buf_block_t* block;
26+ ulint n_fields;
27+ ulint n_bytes;
28+ const page_t* page;
29+ const rec_t* rec;
30+ ulint fold;
31+ ulint prev_fold;
32+ index_id_t index_id;
33+ ulint n_cached;
34+ ulint n_recs;
35+ ulint* folds;
36+ ulint i, j;
37+ mem_heap_t* heap = NULL;
38+ ulint* offsets;
39+
40+ rw_lock_x_lock(&btr_search_latch);
41+ buf_pool_mutex_enter_all();
42+
43+ table = btr_search_sys->hash_index;
44+
45+ for (j = 0; j < srv_buf_pool_instances; j++) {
46+ buf_pool_t* buf_pool;
47+
48+ buf_pool = buf_pool_from_array(j);
49+
50+ bpage = UT_LIST_GET_LAST(buf_pool->LRU);
51+
52+ while (bpage != NULL) {
53+ block = (buf_block_t*) bpage;
54+ if (block->index == index && block->is_hashed) {
55+ page = block->frame;
56+
57+ /* from btr_search_drop_page_hash_index() */
58+ n_fields = block->curr_n_fields;
59+ n_bytes = block->curr_n_bytes;
60+
61+ ut_a(n_fields + n_bytes > 0);
62+
63+ n_recs = page_get_n_recs(page);
64+
65+ /* Calculate and cache fold values into an array for fast deletion
66+ from the hash index */
67+
68+ folds = mem_alloc(n_recs * sizeof(ulint));
69+
70+ n_cached = 0;
71+
72+ rec = page_get_infimum_rec(page);
73+ rec = page_rec_get_next_low(rec, page_is_comp(page));
74+
75+ index_id = btr_page_get_index_id(page);
76+
77+ ut_a(index_id == index->id);
78+
79+ prev_fold = 0;
80+
81+ offsets = NULL;
82+
83+ while (!page_rec_is_supremum(rec)) {
84+ offsets = rec_get_offsets(rec, index, offsets,
85+ n_fields + (n_bytes > 0), &heap);
86+ ut_a(rec_offs_n_fields(offsets) == n_fields + (n_bytes > 0));
87+ fold = rec_fold(rec, offsets, n_fields, n_bytes, index_id);
88+
89+ if (fold == prev_fold && prev_fold != 0) {
90+
91+ goto next_rec;
92+ }
93+
94+ /* Remove all hash nodes pointing to this page from the
95+ hash chain */
96+
97+ folds[n_cached] = fold;
98+ n_cached++;
99+next_rec:
100+ rec = page_rec_get_next_low(rec, page_rec_is_comp(rec));
101+ prev_fold = fold;
102+ }
103+
104+ for (i = 0; i < n_cached; i++) {
105+
106+ ha_remove_all_nodes_to_page(table, folds[i], page);
107+ }
108+
109+ ut_a(index->search_info->ref_count > 0);
110+ index->search_info->ref_count--;
111+
112+ block->is_hashed = FALSE;
113+ block->index = NULL;
114+
115+#if defined UNIV_AHI_DEBUG || defined UNIV_DEBUG
116+ if (UNIV_UNLIKELY(block->n_pointers)) {
117+ /* Corruption */
118+ ut_print_timestamp(stderr);
119+ fprintf(stderr,
120+" InnoDB: Corruption of adaptive hash index. After dropping\n"
121+"InnoDB: the hash index to a page of %s, still %lu hash nodes remain.\n",
122+ index->name, (ulong) block->n_pointers);
123+ }
124+#endif /* UNIV_AHI_DEBUG || UNIV_DEBUG */
125+
126+ mem_free(folds);
127+ }
128+
129+ bpage = UT_LIST_GET_PREV(LRU, bpage);
130+ }
131+ }
132+
133+ buf_pool_mutex_exit_all();
134+ rw_lock_x_unlock(&btr_search_latch);
135+
136+ if (UNIV_LIKELY_NULL(heap)) {
137+ mem_heap_free(heap);
138+ }
139+}
140+
141 /********************************************************************//**
142 Drops a page hash index when a page is freed from a fseg to the file system.
143 Drops possible hash index if the page happens to be in the buffer pool. */
144diff -ruN a/storage/innobase/dict/dict0boot.c b/storage/innobase/dict/dict0boot.c
145--- a/storage/innobase/dict/dict0boot.c 2010-11-03 07:01:13.000000000 +0900
146+++ b/storage/innobase/dict/dict0boot.c 2010-12-03 15:45:47.503988924 +0900
147@@ -284,6 +284,7 @@
148 system tables */
149 /*-------------------------*/
150 table = dict_mem_table_create("SYS_TABLES", DICT_HDR_SPACE, 8, 0);
151+ table->n_mysql_handles_opened = 1; /* for pin */
152
153 dict_mem_table_add_col(table, heap, "NAME", DATA_BINARY, 0, 0);
154 dict_mem_table_add_col(table, heap, "ID", DATA_BINARY, 0, 0);
155@@ -336,6 +337,7 @@
156
157 /*-------------------------*/
158 table = dict_mem_table_create("SYS_COLUMNS", DICT_HDR_SPACE, 7, 0);
159+ table->n_mysql_handles_opened = 1; /* for pin */
160
161 dict_mem_table_add_col(table, heap, "TABLE_ID", DATA_BINARY, 0, 0);
162 dict_mem_table_add_col(table, heap, "POS", DATA_INT, 0, 4);
163@@ -368,6 +370,7 @@
164
165 /*-------------------------*/
166 table = dict_mem_table_create("SYS_INDEXES", DICT_HDR_SPACE, 7, 0);
167+ table->n_mysql_handles_opened = 1; /* for pin */
168
169 dict_mem_table_add_col(table, heap, "TABLE_ID", DATA_BINARY, 0, 0);
170 dict_mem_table_add_col(table, heap, "ID", DATA_BINARY, 0, 0);
171@@ -413,6 +416,7 @@
172
173 /*-------------------------*/
174 table = dict_mem_table_create("SYS_FIELDS", DICT_HDR_SPACE, 3, 0);
175+ table->n_mysql_handles_opened = 1; /* for pin */
176
177 dict_mem_table_add_col(table, heap, "INDEX_ID", DATA_BINARY, 0, 0);
178 dict_mem_table_add_col(table, heap, "POS", DATA_INT, 0, 4);
179diff -ruN a/storage/innobase/dict/dict0crea.c b/storage/innobase/dict/dict0crea.c
180--- a/storage/innobase/dict/dict0crea.c 2010-11-03 07:01:13.000000000 +0900
181+++ b/storage/innobase/dict/dict0crea.c 2010-12-03 15:45:47.521955810 +0900
182@@ -1210,6 +1210,9 @@
183 /* Foreign constraint system tables have already been
184 created, and they are ok */
185
186+ table1->n_mysql_handles_opened = 1; /* for pin */
187+ table2->n_mysql_handles_opened = 1; /* for pin */
188+
189 mutex_exit(&(dict_sys->mutex));
190
191 return(DB_SUCCESS);
192@@ -1291,6 +1294,11 @@
193
194 trx_commit_for_mysql(trx);
195
196+ table1 = dict_table_get_low("SYS_FOREIGN");
197+ table2 = dict_table_get_low("SYS_FOREIGN_COLS");
198+ table1->n_mysql_handles_opened = 1; /* for pin */
199+ table2->n_mysql_handles_opened = 1; /* for pin */
200+
201 row_mysql_unlock_data_dictionary(trx);
202
203 trx_free_for_mysql(trx);
204diff -ruN a/storage/innobase/dict/dict0dict.c b/storage/innobase/dict/dict0dict.c
205--- a/storage/innobase/dict/dict0dict.c 2010-11-03 07:01:13.000000000 +0900
206+++ b/storage/innobase/dict/dict0dict.c 2010-12-03 15:45:47.525953769 +0900
207@@ -625,6 +625,8 @@
208
209 table = dict_table_get_on_id_low(table_id);
210
211+ dict_table_LRU_trim(table);
212+
213 mutex_exit(&(dict_sys->mutex));
214
215 return(table);
216@@ -743,6 +745,8 @@
217 table->n_mysql_handles_opened++;
218 }
219
220+ dict_table_LRU_trim(table);
221+
222 mutex_exit(&(dict_sys->mutex));
223
224 if (table != NULL) {
225@@ -1256,6 +1260,64 @@
226 dict_mem_table_free(table);
227 }
228
229+/**************************************************************************
230+Frees tables from the end of table_LRU if the dictionary cache occupies
231+too much space. */
232+UNIV_INTERN
233+void
234+dict_table_LRU_trim(
235+/*================*/
236+ dict_table_t* self)
237+{
238+ dict_table_t* table;
239+ dict_table_t* prev_table;
240+ dict_foreign_t* foreign;
241+ ulint n_removed;
242+ ulint n_have_parent;
243+ ulint cached_foreign_tables;
244+
245+#ifdef UNIV_SYNC_DEBUG
246+ ut_ad(mutex_own(&(dict_sys->mutex)));
247+#endif /* UNIV_SYNC_DEBUG */
248+
249+retry:
250+ n_removed = n_have_parent = 0;
251+ table = UT_LIST_GET_LAST(dict_sys->table_LRU);
252+
253+ while ( srv_dict_size_limit && table
254+ && ((dict_sys->table_hash->n_cells
255+ + dict_sys->table_id_hash->n_cells) * sizeof(hash_cell_t)
256+ + dict_sys->size) > srv_dict_size_limit ) {
257+ prev_table = UT_LIST_GET_PREV(table_LRU, table);
258+
259+ if (table == self || table->n_mysql_handles_opened)
260+ goto next_loop;
261+
262+ cached_foreign_tables = 0;
263+ foreign = UT_LIST_GET_FIRST(table->foreign_list);
264+ while (foreign != NULL) {
265+ if (foreign->referenced_table)
266+ cached_foreign_tables++;
267+ foreign = UT_LIST_GET_NEXT(foreign_list, foreign);
268+ }
269+
270+ if (cached_foreign_tables == 0) {
271+ dict_table_remove_from_cache(table);
272+ n_removed++;
273+ } else {
274+ n_have_parent++;
275+ }
276+next_loop:
277+ table = prev_table;
278+ }
279+
280+ if ( srv_dict_size_limit && n_have_parent && n_removed
281+ && ((dict_sys->table_hash->n_cells
282+ + dict_sys->table_id_hash->n_cells) * sizeof(hash_cell_t)
283+ + dict_sys->size) > srv_dict_size_limit )
284+ goto retry;
285+}
286+
287 /****************************************************************//**
288 If the given column name is reserved for InnoDB system columns, return
289 TRUE.
290@@ -1719,6 +1781,11 @@
291 ut_ad(index->magic_n == DICT_INDEX_MAGIC_N);
292 ut_ad(mutex_own(&(dict_sys->mutex)));
293
294+ /* remove all entry of the index from adaptive hash index,
295+ because removing from adaptive hash index needs dict_index */
296+ if (btr_search_enabled && srv_dict_size_limit)
297+ btr_search_drop_page_hash_index_on_index(index);
298+
299 /* We always create search info whether or not adaptive
300 hash index is enabled or not. */
301 info = index->search_info;
302diff -ruN a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc
303--- a/storage/innobase/handler/ha_innodb.cc 2010-12-03 15:43:57.294986852 +0900
304+++ b/storage/innobase/handler/ha_innodb.cc 2010-12-03 15:45:47.534959966 +0900
305@@ -653,6 +653,8 @@
306 (char*) &export_vars.innodb_dblwr_pages_written, SHOW_LONG},
307 {"dblwr_writes",
308 (char*) &export_vars.innodb_dblwr_writes, SHOW_LONG},
309+ {"dict_tables",
310+ (char*) &export_vars.innodb_dict_tables, SHOW_LONG},
311 {"have_atomic_builtins",
312 (char*) &export_vars.innodb_have_atomic_builtins, SHOW_BOOL},
313 {"log_waits",
314@@ -11537,6 +11539,11 @@
315 "Number of extra user rollback segments which are used in a round-robin fashion.",
316 NULL, NULL, 127, 0, 127, 0);
317
318+static MYSQL_SYSVAR_ULONG(dict_size_limit, srv_dict_size_limit,
319+ PLUGIN_VAR_RQCMDARG,
320+ "Limit the allocated memory for dictionary cache. (0: unlimited)",
321+ NULL, NULL, 0, 0, LONG_MAX, 0);
322+
323 static struct st_mysql_sys_var* innobase_system_variables[]= {
324 MYSQL_SYSVAR(additional_mem_pool_size),
325 MYSQL_SYSVAR(autoextend_increment),
326@@ -11605,6 +11612,7 @@
327 MYSQL_SYSVAR(flush_log_at_trx_commit_session),
328 MYSQL_SYSVAR(enable_unsafe_group_commit),
329 MYSQL_SYSVAR(extra_rsegments),
330+ MYSQL_SYSVAR(dict_size_limit),
331 MYSQL_SYSVAR(use_sys_malloc),
332 MYSQL_SYSVAR(use_native_aio),
333 MYSQL_SYSVAR(change_buffering),
334diff -ruN a/storage/innobase/ibuf/ibuf0ibuf.c b/storage/innobase/ibuf/ibuf0ibuf.c
335--- a/storage/innobase/ibuf/ibuf0ibuf.c 2010-12-03 15:18:48.889024455 +0900
336+++ b/storage/innobase/ibuf/ibuf0ibuf.c 2010-12-03 15:45:47.553025057 +0900
337@@ -578,6 +578,7 @@
338
339 /* Use old-style record format for the insert buffer. */
340 table = dict_mem_table_create(IBUF_TABLE_NAME, IBUF_SPACE_ID, 1, 0);
341+ table->n_mysql_handles_opened = 1; /* for pin */
342
343 dict_mem_table_add_col(table, heap, "DUMMY_COLUMN", DATA_BINARY, 0, 0);
344
345diff -ruN a/storage/innobase/include/btr0sea.h b/storage/innobase/include/btr0sea.h
346--- a/storage/innobase/include/btr0sea.h 2010-11-03 07:01:13.000000000 +0900
347+++ b/storage/innobase/include/btr0sea.h 2010-12-03 15:45:47.555024229 +0900
348@@ -140,6 +140,13 @@
349 s- or x-latched, or an index page
350 for which we know that
351 block->buf_fix_count == 0 */
352+/************************************************************************
353+Drops a page hash index based on index */
354+UNIV_INTERN
355+void
356+btr_search_drop_page_hash_index_on_index(
357+/*=====================================*/
358+ dict_index_t* index); /* in: record descriptor */
359 /********************************************************************//**
360 Drops a page hash index when a page is freed from a fseg to the file system.
361 Drops possible hash index if the page happens to be in the buffer pool. */
362diff -ruN a/storage/innobase/include/dict0dict.h b/storage/innobase/include/dict0dict.h
363--- a/storage/innobase/include/dict0dict.h 2010-11-03 07:01:13.000000000 +0900
364+++ b/storage/innobase/include/dict0dict.h 2010-12-03 15:45:47.558024515 +0900
365@@ -1158,6 +1158,12 @@
366 /*====================================*/
367 dict_table_t* table, /*!< in: table */
368 const char* name); /*!< in: name of the index to find */
369+
370+UNIV_INTERN
371+void
372+dict_table_LRU_trim(
373+/*================*/
374+ dict_table_t* self);
375 /* Buffers for storing detailed information about the latest foreign key
376 and unique key errors */
377 extern FILE* dict_foreign_err_file;
378diff -ruN a/storage/innobase/include/dict0dict.ic b/storage/innobase/include/dict0dict.ic
379--- a/storage/innobase/include/dict0dict.ic 2010-11-03 07:01:13.000000000 +0900
380+++ b/storage/innobase/include/dict0dict.ic 2010-12-03 15:45:47.560024398 +0900
381@@ -824,6 +824,13 @@
382 HASH_SEARCH(name_hash, dict_sys->table_hash, table_fold,
383 dict_table_t*, table, ut_ad(table->cached),
384 !strcmp(table->name, table_name));
385+
386+ /* make young in table_LRU */
387+ if (table) {
388+ UT_LIST_REMOVE(table_LRU, dict_sys->table_LRU, table);
389+ UT_LIST_ADD_FIRST(table_LRU, dict_sys->table_LRU, table);
390+ }
391+
392 return(table);
393 }
394
395@@ -877,6 +884,12 @@
396 table = dict_load_table_on_id(table_id);
397 }
398
399+ /* make young in table_LRU */
400+ if (table) {
401+ UT_LIST_REMOVE(table_LRU, dict_sys->table_LRU, table);
402+ UT_LIST_ADD_FIRST(table_LRU, dict_sys->table_LRU, table);
403+ }
404+
405 ut_ad(!table || table->cached);
406
407 /* TODO: should get the type information from MySQL */
408diff -ruN a/storage/innobase/include/srv0srv.h b/storage/innobase/include/srv0srv.h
409--- a/storage/innobase/include/srv0srv.h 2010-12-03 15:43:57.297067100 +0900
410+++ b/storage/innobase/include/srv0srv.h 2010-12-03 15:45:47.562024404 +0900
411@@ -227,7 +227,7 @@
412 extern ulint srv_adaptive_checkpoint;
413
414 extern ulint srv_extra_rsegments;
415-
416+extern ulint srv_dict_size_limit;
417 /*-------------------------------------------*/
418
419 extern ulint srv_n_rows_inserted;
420@@ -697,6 +697,7 @@
421 ulint innodb_data_writes; /*!< I/O write requests */
422 ulint innodb_data_written; /*!< Data bytes written */
423 ulint innodb_data_reads; /*!< I/O read requests */
424+ ulint innodb_dict_tables;
425 ulint innodb_buffer_pool_pages_total; /*!< Buffer pool size */
426 ulint innodb_buffer_pool_pages_data; /*!< Data pages */
427 ulint innodb_buffer_pool_pages_dirty; /*!< Dirty data pages */
428diff -ruN a/storage/innobase/srv/srv0srv.c b/storage/innobase/srv/srv0srv.c
429--- a/storage/innobase/srv/srv0srv.c 2010-12-03 15:43:57.301024390 +0900
430+++ b/storage/innobase/srv/srv0srv.c 2010-12-03 15:45:47.565023830 +0900
431@@ -411,6 +411,7 @@
432 UNIV_INTERN ulint srv_adaptive_checkpoint = 0; /* 0: none 1: reflex 2: estimate */
433
434 UNIV_INTERN ulint srv_extra_rsegments = 127; /* extra rseg for users */
435+UNIV_INTERN ulint srv_dict_size_limit = 0;
436 /*-------------------------------------------*/
437 UNIV_INTERN ulong srv_n_spin_wait_rounds = 30;
438 UNIV_INTERN ulong srv_n_free_tickets_to_enter = 500;
439@@ -2179,6 +2180,7 @@
440 export_vars.innodb_data_reads = os_n_file_reads;
441 export_vars.innodb_data_writes = os_n_file_writes;
442 export_vars.innodb_data_written = srv_data_written;
443+ export_vars.innodb_dict_tables= (dict_sys ? UT_LIST_GET_LEN(dict_sys->table_LRU) : 0);
444 export_vars.innodb_buffer_pool_read_requests = stat.n_page_gets;
445 export_vars.innodb_buffer_pool_write_requests
446 = srv_buf_pool_write_requests;
0447
=== renamed file 'innodb_dict_size_limit.patch' => 'innodb_dict_size_limit.patch.moved'
=== added file 'innodb_expand_import.patch'
--- innodb_expand_import.patch 1970-01-01 00:00:00 +0000
+++ innodb_expand_import.patch 2011-01-10 13:15:57 +0000
@@ -0,0 +1,561 @@
1# name : innodb_expand_import.patch
2# introduced : 11 or before
3# maintainer : Yasufumi
4#
5#!!! notice !!!
6# Any small change to this file in the main branch
7# should be done or reviewed by the maintainer!
8diff -ruN a/storage/innobase/fil/fil0fil.c b/storage/innobase/fil/fil0fil.c
9--- a/storage/innobase/fil/fil0fil.c 2010-12-03 15:09:51.274957577 +0900
10+++ b/storage/innobase/fil/fil0fil.c 2010-12-03 15:52:23.553986552 +0900
11@@ -40,6 +40,12 @@
12 #include "dict0dict.h"
13 #include "page0page.h"
14 #include "page0zip.h"
15+#include "trx0trx.h"
16+#include "trx0sys.h"
17+#include "pars0pars.h"
18+#include "row0mysql.h"
19+#include "row0row.h"
20+#include "que0que.h"
21 #ifndef UNIV_HOTBACKUP
22 # include "buf0lru.h"
23 # include "ibuf0ibuf.h"
24@@ -3050,7 +3056,7 @@
25
26 file = os_file_create_simple_no_error_handling(
27 innodb_file_data_key, filepath, OS_FILE_OPEN,
28- OS_FILE_READ_ONLY, &success);
29+ OS_FILE_READ_WRITE, &success);
30 if (!success) {
31 /* The following call prints an error message */
32 os_file_get_last_error(TRUE);
33@@ -3097,6 +3103,466 @@
34 space_id = fsp_header_get_space_id(page);
35 space_flags = fsp_header_get_flags(page);
36
37+ if (srv_expand_import
38+ && (space_id != id || space_flags != (flags & ~(~0 << DICT_TF_BITS)))) {
39+ ibool file_is_corrupt = FALSE;
40+ byte* buf3;
41+ byte* descr_page;
42+ ibool descr_is_corrupt = FALSE;
43+ index_id_t old_id[31];
44+ index_id_t new_id[31];
45+ ulint root_page[31];
46+ ulint n_index;
47+ os_file_t info_file = -1;
48+ char* info_file_path;
49+ ulint i;
50+ int len;
51+ ib_uint64_t current_lsn;
52+ ulint size_low, size_high, size, free_limit;
53+ ib_int64_t size_bytes, free_limit_bytes;
54+ dict_table_t* table;
55+ dict_index_t* index;
56+ fil_system_t* system;
57+ fil_node_t* node = NULL;
58+ fil_space_t* space;
59+
60+ buf3 = ut_malloc(2 * UNIV_PAGE_SIZE);
61+ descr_page = ut_align(buf3, UNIV_PAGE_SIZE);
62+
63+ current_lsn = log_get_lsn();
64+
65+ /* check the header page's consistency */
66+ if (buf_page_is_corrupted(page,
67+ dict_table_flags_to_zip_size(space_flags))) {
68+ fprintf(stderr, "InnoDB: page 0 of %s seems corrupt.\n", filepath);
69+ file_is_corrupt = TRUE;
70+ descr_is_corrupt = TRUE;
71+ }
72+
73+ /* store as first descr page */
74+ memcpy(descr_page, page, UNIV_PAGE_SIZE);
75+
76+ /* get free limit (page number) of the table space */
77+/* these should be same to the definition in fsp0fsp.c */
78+#define FSP_HEADER_OFFSET FIL_PAGE_DATA
79+#define FSP_FREE_LIMIT 12
80+ free_limit = mach_read_from_4(FSP_HEADER_OFFSET + FSP_FREE_LIMIT + page);
81+ free_limit_bytes = (ib_int64_t)free_limit * (ib_int64_t)UNIV_PAGE_SIZE;
82+
83+ /* overwrite fsp header */
84+ fsp_header_init_fields(page, id, flags);
85+ mach_write_to_4(page + FIL_PAGE_ARCH_LOG_NO_OR_SPACE_ID, id);
86+ space_id = id;
87+ space_flags = flags;
88+ if (mach_read_from_8(page + FIL_PAGE_FILE_FLUSH_LSN) > current_lsn)
89+ mach_write_to_8(page + FIL_PAGE_FILE_FLUSH_LSN, current_lsn);
90+ mach_write_to_4(page + FIL_PAGE_SPACE_OR_CHKSUM,
91+ srv_use_checksums
92+ ? buf_calc_page_new_checksum(page)
93+ : BUF_NO_CHECKSUM_MAGIC);
94+ mach_write_to_4(page + UNIV_PAGE_SIZE - FIL_PAGE_END_LSN_OLD_CHKSUM,
95+ srv_use_checksums
96+ ? buf_calc_page_old_checksum(page)
97+ : BUF_NO_CHECKSUM_MAGIC);
98+ success = os_file_write(filepath, file, page, 0, 0, UNIV_PAGE_SIZE);
99+
100+ /* get file size */
101+ os_file_get_size(file, &size_low, &size_high);
102+ size_bytes = (((ib_int64_t)size_high) << 32)
103+ + (ib_int64_t)size_low;
104+
105+ if (size_bytes < free_limit_bytes) {
106+ free_limit_bytes = size_bytes;
107+ if (size_bytes >= FSP_EXTENT_SIZE * UNIV_PAGE_SIZE) {
108+ fprintf(stderr, "InnoDB: free limit of %s is larger than its real size.\n", filepath);
109+ file_is_corrupt = TRUE;
110+ }
111+ }
112+
113+ /* get cruster index information */
114+ table = dict_table_get_low(name);
115+ index = dict_table_get_first_index(table);
116+ ut_a(index->page==3);
117+
118+ /* read metadata from .exp file */
119+ n_index = 0;
120+ memset(old_id, 0, sizeof(old_id));
121+ memset(new_id, 0, sizeof(new_id));
122+ memset(root_page, 0, sizeof(root_page));
123+
124+ info_file_path = fil_make_ibd_name(name, FALSE);
125+ len = strlen(info_file_path);
126+ info_file_path[len - 3] = 'e';
127+ info_file_path[len - 2] = 'x';
128+ info_file_path[len - 1] = 'p';
The diff has been truncated for viewing.

Subscribers

People subscribed via source and target branches

to all changes: