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