summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSergey Vojtovich <svoj@sun.com>2009-07-30 17:42:56 +0500
committerSergey Vojtovich <svoj@sun.com>2009-07-30 17:42:56 +0500
commitbae6276d458cdbf68df5d472ed63d4d7e3b09e66 (patch)
tree4d4fd1ed09a36796ae4f3f23fc3daa5f4bf7947f
parent058cd6256557165d4b8a059c071eaea91d39d2b7 (diff)
downloadmariadb-git-bae6276d458cdbf68df5d472ed63d4d7e3b09e66.tar.gz
Update to innoplug-1.0.4.
-rw-r--r--mysql-test/lib/mtr_cases.pm5
-rw-r--r--mysql-test/suite/innodb/r/innodb_file_format.result44
-rw-r--r--mysql-test/suite/innodb/t/innodb_file_format.test41
-rw-r--r--storage/innodb_plugin/CMakeLists.txt2
-rw-r--r--storage/innodb_plugin/COPYING.Percona30
-rw-r--r--storage/innodb_plugin/COPYING.Sun_Microsystems31
-rw-r--r--storage/innodb_plugin/ChangeLog191
-rw-r--r--storage/innodb_plugin/Doxyfile1419
-rw-r--r--storage/innodb_plugin/Makefile.am433
-rw-r--r--storage/innodb_plugin/btr/btr0cur.c1
-rw-r--r--storage/innodb_plugin/buf/buf0buf.c27
-rw-r--r--storage/innodb_plugin/buf/buf0flu.c151
-rw-r--r--storage/innodb_plugin/buf/buf0lru.c5
-rw-r--r--storage/innodb_plugin/buf/buf0rea.c50
-rw-r--r--storage/innodb_plugin/data/data0type.c3
-rw-r--r--storage/innodb_plugin/dict/dict0dict.c7
-rw-r--r--storage/innodb_plugin/dict/dict0mem.c2
-rw-r--r--storage/innodb_plugin/fil/fil0fil.c6
-rw-r--r--storage/innodb_plugin/fsp/fsp0fsp.c47
-rw-r--r--storage/innodb_plugin/ha/ha0ha.c24
-rw-r--r--storage/innodb_plugin/handler/ha_innodb.cc383
-rw-r--r--storage/innodb_plugin/handler/handler0alter.cc2
-rw-r--r--storage/innodb_plugin/handler/handler0vars.h69
-rw-r--r--storage/innodb_plugin/handler/win_delay_loader.cc1024
-rw-r--r--storage/innodb_plugin/ibuf/ibuf0ibuf.c7
-rw-r--r--storage/innodb_plugin/include/buf0buddy.h1
-rw-r--r--storage/innodb_plugin/include/buf0buf.h107
-rw-r--r--storage/innodb_plugin/include/buf0buf.ic23
-rw-r--r--storage/innodb_plugin/include/buf0flu.h38
-rw-r--r--storage/innodb_plugin/include/buf0lru.h10
-rw-r--r--storage/innodb_plugin/include/buf0rea.h8
-rw-r--r--storage/innodb_plugin/include/data0type.h6
-rw-r--r--storage/innodb_plugin/include/data0type.ic3
-rw-r--r--storage/innodb_plugin/include/fsp0fsp.h85
-rw-r--r--storage/innodb_plugin/include/fsp0types.h110
-rw-r--r--storage/innodb_plugin/include/ha0ha.h10
-rw-r--r--storage/innodb_plugin/include/lock0lock.h16
-rw-r--r--storage/innodb_plugin/include/log0log.h42
-rw-r--r--storage/innodb_plugin/include/log0log.ic12
-rw-r--r--storage/innodb_plugin/include/mem0mem.h13
-rw-r--r--storage/innodb_plugin/include/mtr0log.h4
-rw-r--r--storage/innodb_plugin/include/mtr0log.ic26
-rw-r--r--storage/innodb_plugin/include/mtr0mtr.h163
-rw-r--r--storage/innodb_plugin/include/os0file.h54
-rw-r--r--storage/innodb_plugin/include/os0proc.h9
-rw-r--r--storage/innodb_plugin/include/os0sync.h12
-rw-r--r--storage/innodb_plugin/include/os0thread.h2
-rw-r--r--storage/innodb_plugin/include/page0zip.h8
-rw-r--r--storage/innodb_plugin/include/page0zip.ic10
-rw-r--r--storage/innodb_plugin/include/que0que.h10
-rw-r--r--storage/innodb_plugin/include/row0row.h15
-rw-r--r--storage/innodb_plugin/include/srv0que.h30
-rw-r--r--storage/innodb_plugin/include/srv0srv.h66
-rw-r--r--storage/innodb_plugin/include/sync0sync.h2
-rw-r--r--storage/innodb_plugin/include/trx0rseg.ic1
-rw-r--r--storage/innodb_plugin/include/trx0sys.h41
-rw-r--r--storage/innodb_plugin/include/trx0sys.ic1
-rw-r--r--storage/innodb_plugin/include/trx0trx.h10
-rw-r--r--storage/innodb_plugin/include/trx0types.h8
-rw-r--r--storage/innodb_plugin/include/univ.i46
-rw-r--r--storage/innodb_plugin/include/ut0auxconf.h2
-rw-r--r--storage/innodb_plugin/include/ut0ut.h29
-rw-r--r--storage/innodb_plugin/lock/lock0lock.c63
-rw-r--r--storage/innodb_plugin/log/log0log.c47
-rw-r--r--storage/innodb_plugin/mem/mem0mem.c21
-rw-r--r--storage/innodb_plugin/mtr/mtr0log.c4
-rw-r--r--storage/innodb_plugin/mysql-test/innodb-autoinc.result22
-rw-r--r--storage/innodb_plugin/mysql-test/innodb-autoinc.test20
-rw-r--r--storage/innodb_plugin/mysql-test/innodb.result6
-rw-r--r--storage/innodb_plugin/mysql-test/innodb.test4
-rw-r--r--storage/innodb_plugin/mysql-test/innodb_bug21704.result55
-rw-r--r--storage/innodb_plugin/mysql-test/innodb_bug21704.test96
-rw-r--r--storage/innodb_plugin/mysql-test/innodb_bug40565.result9
-rw-r--r--storage/innodb_plugin/mysql-test/innodb_bug40565.test10
-rw-r--r--storage/innodb_plugin/mysql-test/innodb_bug42101-nonzero.result6
-rw-r--r--storage/innodb_plugin/mysql-test/innodb_bug42101-nonzero.test2
-rw-r--r--storage/innodb_plugin/mysql-test/innodb_bug42101.result4
-rw-r--r--storage/innodb_plugin/mysql-test/innodb_bug42101.test2
-rw-r--r--storage/innodb_plugin/mysql-test/innodb_bug45357.result7
-rw-r--r--storage/innodb_plugin/mysql-test/innodb_bug45357.test10
-rw-r--r--storage/innodb_plugin/mysql-test/innodb_file_format.result44
-rw-r--r--storage/innodb_plugin/mysql-test/innodb_file_format.test28
-rw-r--r--storage/innodb_plugin/os/os0file.c89
-rw-r--r--storage/innodb_plugin/os/os0proc.c34
-rw-r--r--storage/innodb_plugin/os/os0sync.c41
-rw-r--r--storage/innodb_plugin/page/page0page.c2
-rw-r--r--storage/innodb_plugin/page/page0zip.c7
-rw-r--r--storage/innodb_plugin/plug.in26
-rw-r--r--storage/innodb_plugin/que/que0que.c31
-rw-r--r--storage/innodb_plugin/row/row0merge.c9
-rw-r--r--storage/innodb_plugin/row/row0mysql.c9
-rw-r--r--storage/innodb_plugin/row/row0row.c61
-rw-r--r--storage/innodb_plugin/row/row0sel.c3
-rw-r--r--storage/innodb_plugin/srv/srv0que.c77
-rw-r--r--storage/innodb_plugin/srv/srv0srv.c275
-rw-r--r--storage/innodb_plugin/srv/srv0start.c77
-rw-r--r--storage/innodb_plugin/sync/sync0sync.c9
-rw-r--r--storage/innodb_plugin/trx/trx0purge.c1
-rw-r--r--storage/innodb_plugin/trx/trx0sys.c217
-rw-r--r--storage/innodb_plugin/trx/trx0trx.c6
-rw-r--r--storage/innodb_plugin/trx/trx0undo.c1
-rw-r--r--storage/innodb_plugin/ut/ut0auxconf_pause.c32
-rw-r--r--storage/innodb_plugin/ut/ut0mem.c2
-rw-r--r--storage/innodb_plugin/ut/ut0ut.c8
104 files changed, 5341 insertions, 1173 deletions
diff --git a/mysql-test/lib/mtr_cases.pm b/mysql-test/lib/mtr_cases.pm
index 1018ba31724..c9c0f1796e5 100644
--- a/mysql-test/lib/mtr_cases.pm
+++ b/mysql-test/lib/mtr_cases.pm
@@ -494,17 +494,12 @@ sub collect_one_suite($)
next if ($test->{'skip'} || !$test->{'innodb_test'});
# Exceptions
next if ($test->{'name'} eq 'main.innodb'); # Failed with wrong errno (fk)
- next if ($test->{'name'} eq 'main.innodb_mysql'); # Diff in show (fk)
- next if ($test->{'name'} eq 'main.index_merge_innodb'); # Explain diff
# innodb_file_per_table is rw with innodb_plugin
next if ($test->{'name'} eq 'sys_vars.innodb_file_per_table_basic');
# innodb_lock_wait_timeout is rw with innodb_plugin
next if ($test->{'name'} eq 'sys_vars.innodb_lock_wait_timeout_basic');
# Diff around innodb_thread_concurrency variable
next if ($test->{'name'} eq 'sys_vars.innodb_thread_concurrency_basic');
- next if ($test->{'name'} eq 'main.innodb_bug42101-nonzero');
- next if ($test->{'name'} eq 'main.innodb_bug21704');
- next if ($test->{'name'} eq 'main.innodb_bug45357');
# Copy test options
my $new_test= My::Test->new();
while (my ($key, $value) = each(%$test))
diff --git a/mysql-test/suite/innodb/r/innodb_file_format.result b/mysql-test/suite/innodb/r/innodb_file_format.result
new file mode 100644
index 00000000000..9cfac5f001c
--- /dev/null
+++ b/mysql-test/suite/innodb/r/innodb_file_format.result
@@ -0,0 +1,44 @@
+select @@innodb_file_format;
+@@innodb_file_format
+Antelope
+select @@innodb_file_format_check;
+@@innodb_file_format_check
+Antelope
+set global innodb_file_format=antelope;
+set global innodb_file_format=barracuda;
+set global innodb_file_format=cheetah;
+ERROR HY000: Incorrect arguments to SET
+select @@innodb_file_format;
+@@innodb_file_format
+Barracuda
+set global innodb_file_format=default;
+select @@innodb_file_format;
+@@innodb_file_format
+Antelope
+set global innodb_file_format=on;
+ERROR HY000: Incorrect arguments to SET
+set global innodb_file_format=off;
+ERROR HY000: Incorrect arguments to SET
+select @@innodb_file_format;
+@@innodb_file_format
+Antelope
+set global innodb_file_format_check=antelope;
+set global innodb_file_format_check=barracuda;
+set global innodb_file_format_check=cheetah;
+ERROR HY000: Incorrect arguments to SET
+select @@innodb_file_format_check;
+@@innodb_file_format_check
+Barracuda
+set global innodb_file_format_check=default;
+Warnings:
+Warning 1210 Ignoring SET innodb_file_format=on
+select @@innodb_file_format_check;
+@@innodb_file_format_check
+Barracuda
+set global innodb_file_format=on;
+ERROR HY000: Incorrect arguments to SET
+set global innodb_file_format=off;
+ERROR HY000: Incorrect arguments to SET
+select @@innodb_file_format_check;
+@@innodb_file_format_check
+Barracuda
diff --git a/mysql-test/suite/innodb/t/innodb_file_format.test b/mysql-test/suite/innodb/t/innodb_file_format.test
new file mode 100644
index 00000000000..293e87a413e
--- /dev/null
+++ b/mysql-test/suite/innodb/t/innodb_file_format.test
@@ -0,0 +1,41 @@
+-- source include/have_innodb.inc
+-- source suite/innodb/include/have_innodb_plugin.inc
+
+let $format=`select @@innodb_file_format`;
+let $innodb_file_format_check_orig=`select @@innodb_file_format_check`;
+
+select @@innodb_file_format;
+select @@innodb_file_format_check;
+set global innodb_file_format=antelope;
+set global innodb_file_format=barracuda;
+--error ER_WRONG_ARGUMENTS
+set global innodb_file_format=cheetah;
+select @@innodb_file_format;
+set global innodb_file_format=default;
+select @@innodb_file_format;
+--error ER_WRONG_ARGUMENTS
+set global innodb_file_format=on;
+--error ER_WRONG_ARGUMENTS
+set global innodb_file_format=off;
+select @@innodb_file_format;
+set global innodb_file_format_check=antelope;
+set global innodb_file_format_check=barracuda;
+--error ER_WRONG_ARGUMENTS
+set global innodb_file_format_check=cheetah;
+select @@innodb_file_format_check;
+set global innodb_file_format_check=default;
+select @@innodb_file_format_check;
+--error ER_WRONG_ARGUMENTS
+set global innodb_file_format=on;
+--error ER_WRONG_ARGUMENTS
+set global innodb_file_format=off;
+select @@innodb_file_format_check;
+
+#
+# restore environment to the state it was before this test execution
+#
+
+-- disable_query_log
+eval set global innodb_file_format=$format;
+eval set global innodb_file_format_check=$innodb_file_format_check_orig;
+-- enable_query_log
diff --git a/storage/innodb_plugin/CMakeLists.txt b/storage/innodb_plugin/CMakeLists.txt
index 6da3785990a..7762ece9bcd 100644
--- a/storage/innodb_plugin/CMakeLists.txt
+++ b/storage/innodb_plugin/CMakeLists.txt
@@ -74,5 +74,5 @@ SET(INNODB_PLUGIN_SOURCES btr/btr0btr.c btr/btr0cur.c btr/btr0pcur.c btr/btr0sea
usr/usr0sess.c
ut/ut0byte.c ut/ut0dbg.c ut/ut0mem.c ut/ut0rnd.c ut/ut0ut.c ut/ut0vec.c
ut/ut0list.c ut/ut0wqueue.c)
-ADD_DEFINITIONS(-DHAVE_WINDOWS_ATOMICS -DINNODB_RW_LOCKS_USE_ATOMICS)
+ADD_DEFINITIONS(-DHAVE_WINDOWS_ATOMICS -DINNODB_RW_LOCKS_USE_ATOMICS -DIB_HAVE_PAUSE_INSTRUCTION)
MYSQL_STORAGE_ENGINE(INNODB_PLUGIN) \ No newline at end of file
diff --git a/storage/innodb_plugin/COPYING.Percona b/storage/innodb_plugin/COPYING.Percona
new file mode 100644
index 00000000000..8c786811719
--- /dev/null
+++ b/storage/innodb_plugin/COPYING.Percona
@@ -0,0 +1,30 @@
+Portions of this software contain modifications contributed by Percona, Inc.
+These contributions are used with the following license:
+
+Copyright (c) 2008, 2009, Percona Inc. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+ * Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ * 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.
+ * Neither the name of the Percona Inc. nor the names of its
+ contributors may be used to endorse or promote products
+ derived from this software without specific prior written
+ permission.
+
+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
+OWNER 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.
diff --git a/storage/innodb_plugin/COPYING.Sun_Microsystems b/storage/innodb_plugin/COPYING.Sun_Microsystems
new file mode 100644
index 00000000000..5a77ef3ab73
--- /dev/null
+++ b/storage/innodb_plugin/COPYING.Sun_Microsystems
@@ -0,0 +1,31 @@
+Portions of this software contain modifications contributed by
+Sun Microsystems, Inc. These contributions are used with the following
+license:
+
+Copyright (c) 2009, Sun Microsystems, Inc.
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+ * Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ * 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.
+ * Neither the name of Sun Microsystems, Inc. nor the names of its
+ contributors may be used to endorse or promote products derived
+ from this software without specific prior written permission.
+
+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
+OWNER 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.
diff --git a/storage/innodb_plugin/ChangeLog b/storage/innodb_plugin/ChangeLog
index 2531eb6e51d..2b04c06f0e8 100644
--- a/storage/innodb_plugin/ChangeLog
+++ b/storage/innodb_plugin/ChangeLog
@@ -1,3 +1,190 @@
+2009-07-20 The InnoDB Team
+
+ * buf/buf0rea.c, handler/ha_innodb.cc, include/srv0srv.h,
+ srv/srv0srv.c:
+ Change the read ahead parameter name to innodb_read_ahead_threshold.
+ Change the meaning of this parameter to signify the number of pages
+ that must be sequentially accessed for InnoDB to trigger a readahead
+ request.
+
+2009-07-20 The InnoDB Team
+
+ * handler/ha_innodb.cc:
+ Fix Bug#39802 On Windows, 32-bit time_t should be enforced
+
+2009-07-16 The InnoDB Team
+
+ * include/univ.i:
+ Support inlining of functions and prefetch with Sun Studio.
+ These changes are based on contribution from Sun Microsystems Inc.
+ under a BSD license.
+
+2009-07-14 The InnoDB Team
+
+ * fil/fil0fil.c:
+ Fix Bug#45814 URL reference in InnoDB server errors needs adjusting to
+ match documentation
+
+2009-07-14 The InnoDB Team
+
+ * handler/ha_innodb.cc, mysql-test/innodb_bug21704.result,
+ mysql-test/innodb_bug21704.test:
+ Fix Bug#21704 Renaming column does not update FK definition
+
+2009-07-10 The InnoDB Team
+
+ * handler/ha_innodb.cc, srv/srv0srv.c:
+ Change the defaults for
+ innodb_sync_spin_loops: 20 -> 30
+ innodb_spin_wait_delay: 5 -> 6
+
+2009-07-08 The InnoDB Team
+
+ * buf/buf0flu.c, handler/ha_innodb.cc, include/buf0flu.h,
+ include/log0log.h, include/log0log.ic, include/srv0srv.h,
+ srv/srv0srv.c:
+ Implement the adaptive flushing of dirty pages, which uses
+ a heuristics based flushing rate of dirty pages to avoid IO
+ bursts at checkpoint. Expose new configure knob
+ innodb_adaptive_flushing to control whether the new flushing
+ algorithm should be used.
+
+2009-07-07 The InnoDB Team
+
+ * handler/ha_innodb.cc, include/srv0srv.h, log/log0log.c,
+ srv/srv0srv.c:
+ Implement IO capacity tuning. Expose new configure knob
+ innodb_io_capacity to control the master threads IO rate. The
+ ibuf merge is also changed from synchronous to asynchronous.
+ These changes are based on contribution from Google Inc.
+ under a BSD license.
+
+2009-07-02 The InnoDB Team
+
+ * include/ut0ut.h, plug.in, ut/ut0ut.c:
+ Use the PAUSE instruction inside the spinloop if it is available,
+ Thanks to Mikael Ronstrom <mikael@mysql.com>.
+
+2009-06-29 The InnoDB Team
+
+ * handler/ha_innodb.cc, mysql-test/innodb_file_format.test,
+ mysql-test/innodb_file_format.result:
+ Do not crash on SET GLOBAL innodb_file_format=DEFAULT
+ or SET GLOBAL innodb_file_format_check=DEFAULT.
+
+2009-06-29 The InnoDB Team
+
+ * buf/buf0buf.c, buf/buf0rea.c, lock/lock0lock.c:
+ Tolerate missing tablespaces during crash recovery and when
+ printing information on locks.
+
+2009-06-29 The InnoDB Team
+
+ * buf/buf0buf.c:
+ Fix a race condition when reading buf_fix_count.
+ Currently, it is not being protected by the buffer pool mutex,
+ but by the block mutex.
+
+2009-06-29 The InnoDB Team
+
+ * handler/handler0alter.cc:
+ Start the user transaction prebuilt->trx if it was not started
+ before adding or dropping an index. Without this fix, the
+ table could be locked outside an active transaction.
+
+2009-06-25 The InnoDB Team
+
+ * handler/ha_innodb.cc, mysql-test/innodb_bug42101.test,
+ mysql-test/innodb_bug42101.result,
+ mysql-test/innodb_bug42101-nonzero.test,
+ mysql-test/innodb_bug42101-nonzero.result:
+ Fix Bug#45749 Race condition in SET GLOBAL
+ innodb_commit_concurrency=DEFAULT
+
+2009-06-25 The InnoDB Team
+
+ * dict/dict0dict.c:
+ When an index column cannot be found in the table during index
+ creation, display additional diagnostic before an assertion failure.
+ This does NOT fix Bug #44571 InnoDB Plugin crashes on ADD INDEX,
+ but it helps understand the reason of the crash.
+
+2009-06-17 The InnoDB Team
+
+ * row/row0merge.c:
+ Fix Bug#45426 UNIV_DEBUG build cause assertion error at CREATE INDEX
+
+2009-06-17 The InnoDB Team
+
+ * mysql-test/innodb_bug45357.result, mysql-test/innodb_bug45357.test,
+ row/row0mysql.c:
+ Fix Bug#45357 5.1.35 crashes with Failing assertion: index->type &
+ DICT_CLUSTERED
+
+2009-06-17 The InnoDB Team
+
+ * handler/ha_innodb.cc, mysql-test/innodb-autoinc.result,
+ mysql-test/innodb-autoinc.test:
+ Fix Bug#44030 Error: (1500) Couldn't read the MAX(ID) autoinc value
+ from the index (PRIMARY)
+
+2009-06-11 The InnoDB Team
+
+ * handler/ha_innodb.cc, mysql-test/innodb.result, srv/srv0srv.c:
+ Change the following defaults:
+ max_dirty_pages_pct: from 90 to 75, max allowed from 100 to 99
+ additional_mem_pool_size: from 1 to 8 MB
+ buffer_pool_size: from 8 to 128 MB
+ log_buffer_size: from 1 to 8 MB
+ read_io_threads/write_io_threads: from 1 to 4
+
+2009-06-09 The InnoDB Team
+
+ * handler/ha_innodb.cc, include/trx0trx.h, trx/trx0trx.c:
+ Enable Group Commit functionality that was broken in 5.0 when
+ distributed transactions were introduced.
+
+2009-06-05 The InnoDB Team
+
+ * handler/ha_innodb.cc, include/os0file.h, include/srv0srv.h,
+ os/os0file.c, srv/srv0srv.c, srv/srv0start.c:
+ Enable functionality to have multiple background IO helper threads.
+ Expose new configure knobs innodb_read_io_threads and
+ innodb_write_io_threads and deprecate innodb_file_io_threads (this
+ parameter was relevant only on windows). Internally this allows
+ multiple segments for read and write IO request arrays where one
+ thread works on one segment.
+
+2009-06-05 The InnoDB Team
+
+ * buf/buf0lru.c, buf/buf0rea.c, handler/ha_innodb.cc,
+ include/srv0srv.h, srv/srv0srv.c:
+ Fix a bug in linear read ahead:
+ 1) Take into account access pattern when deciding whether or not to
+ do linear read ahead.
+ 2) Expose a knob innodb_read_ahead_factor = [0-64] default (8),
+ dynamic, global to control linear read ahead behavior. This is the
+ value of the number of pages that InnoDB will tolerate within a
+ 64 page extent even if they are accessed out of order or have
+ not been accessed at all. This number (which varies from 0 to 64)
+ is indicative of the slack that we have when deciding about linear
+ readahead.
+ 3) Disable random read ahead. Keep the code for now.
+
+2009-06-03 The InnoDB Team
+
+ * dict/dict0dict.c, mysql-test/t/innodb_mysql.test,
+ mysql-test/r/innodb_mysql.result:
+ Fix Bug#39793 Foreign keys not constructed when column
+ has a '#' in a comment or default value
+
+2009-05-27 The InnoDB Team
+
+ * Doxyfile:
+ Allow the extraction of documentation from the code base with the
+ Doxygen tool. Convert and add many (but not yet all) comments to
+ Doxygen format.
+
2009-05-19 The InnoDB Team
* btr/btr0btr.c, btr/btr0cur.c, lock/lock0lock.c,
@@ -6,7 +193,7 @@
page/page0zip.c, page/page0page.c:
Write updates of PAGE_MAX_TRX_ID to the redo log and add debug
assertions for checking that PAGE_MAX_TRX_ID is valid on leaf
- pages of secondary indexes and the insert buffer B-tree. This bug
+ pages of secondary indexes and the insert buffer B-tree. This bug
could cause failures in secondary index lookups in consistent
reads right after crash recovery.
@@ -36,7 +223,7 @@
* row/row0mysql.c:
When scanning indexes, report in the error log any error codes
- returned by the search function. These error codes will still be
+ returned by the search function. These error codes will still be
ignored in CHECK TABLE.
2009-04-23 The InnoDB Team
diff --git a/storage/innodb_plugin/Doxyfile b/storage/innodb_plugin/Doxyfile
new file mode 100644
index 00000000000..62aa7dd8abc
--- /dev/null
+++ b/storage/innodb_plugin/Doxyfile
@@ -0,0 +1,1419 @@
+# Doxyfile 1.5.6
+
+# Usage: SVNVERSION=-r$(svnversion) doxygen
+
+# This file describes the settings to be used by the documentation system
+# doxygen (www.doxygen.org) for a project
+#
+# All text after a hash (#) is considered a comment and will be ignored
+# The format is:
+# TAG = value [value, ...]
+# For lists items can also be appended using:
+# TAG += value [value, ...]
+# Values that contain spaces should be placed between quotes (" ")
+
+#---------------------------------------------------------------------------
+# Project related configuration options
+#---------------------------------------------------------------------------
+
+# This tag specifies the encoding used for all characters in the config file
+# that follow. The default is UTF-8 which is also the encoding used for all
+# text before the first occurrence of this tag. Doxygen uses libiconv (or the
+# iconv built into libc) for the transcoding. See
+# http://www.gnu.org/software/libiconv for the list of possible encodings.
+
+DOXYFILE_ENCODING = UTF-8
+
+# The PROJECT_NAME tag is a single word (or a sequence of words surrounded
+# by quotes) that should identify the project.
+
+PROJECT_NAME = "InnoDB Plugin"
+
+# The PROJECT_NUMBER tag can be used to enter a project or revision number.
+# This could be handy for archiving the generated documentation or
+# if some version control system is used.
+
+PROJECT_NUMBER = 1.0$(SVNVERSION)
+
+# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute)
+# base path where the generated documentation will be put.
+# If a relative path is entered, it will be relative to the location
+# where doxygen was started. If left blank the current directory will be used.
+
+OUTPUT_DIRECTORY = dox
+
+# If the CREATE_SUBDIRS tag is set to YES, then doxygen will create
+# 4096 sub-directories (in 2 levels) under the output directory of each output
+# format and will distribute the generated files over these directories.
+# Enabling this option can be useful when feeding doxygen a huge amount of
+# source files, where putting all generated files in the same directory would
+# otherwise cause performance problems for the file system.
+
+CREATE_SUBDIRS = NO
+
+# The OUTPUT_LANGUAGE tag is used to specify the language in which all
+# documentation generated by doxygen is written. Doxygen will use this
+# information to generate all constant output in the proper language.
+# The default language is English, other supported languages are:
+# Afrikaans, Arabic, Brazilian, Catalan, Chinese, Chinese-Traditional,
+# Croatian, Czech, Danish, Dutch, Farsi, Finnish, French, German, Greek,
+# Hungarian, Italian, Japanese, Japanese-en (Japanese with English messages),
+# Korean, Korean-en, Lithuanian, Norwegian, Macedonian, Persian, Polish,
+# Portuguese, Romanian, Russian, Serbian, Slovak, Slovene, Spanish, Swedish,
+# and Ukrainian.
+
+OUTPUT_LANGUAGE = English
+
+# If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will
+# include brief member descriptions after the members that are listed in
+# the file and class documentation (similar to JavaDoc).
+# Set to NO to disable this.
+
+BRIEF_MEMBER_DESC = YES
+
+# If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend
+# the brief description of a member or function before the detailed description.
+# Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the
+# brief descriptions will be completely suppressed.
+
+REPEAT_BRIEF = YES
+
+# This tag implements a quasi-intelligent brief description abbreviator
+# that is used to form the text in various listings. Each string
+# in this list, if found as the leading text of the brief description, will be
+# stripped from the text and the result after processing the whole list, is
+# used as the annotated text. Otherwise, the brief description is used as-is.
+# If left blank, the following values are used ("$name" is automatically
+# replaced with the name of the entity): "The $name class" "The $name widget"
+# "The $name file" "is" "provides" "specifies" "contains"
+# "represents" "a" "an" "the"
+
+ABBREVIATE_BRIEF =
+
+# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then
+# Doxygen will generate a detailed section even if there is only a brief
+# description.
+
+ALWAYS_DETAILED_SEC = NO
+
+# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all
+# inherited members of a class in the documentation of that class as if those
+# members were ordinary class members. Constructors, destructors and assignment
+# operators of the base classes will not be shown.
+
+INLINE_INHERITED_MEMB = NO
+
+# If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full
+# path before files name in the file list and in the header files. If set
+# to NO the shortest path that makes the file name unique will be used.
+
+FULL_PATH_NAMES = YES
+
+# If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag
+# can be used to strip a user-defined part of the path. Stripping is
+# only done if one of the specified strings matches the left-hand part of
+# the path. The tag can be used to show relative paths in the file list.
+# If left blank the directory from which doxygen is run is used as the
+# path to strip.
+
+STRIP_FROM_PATH =
+
+# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of
+# the path mentioned in the documentation of a class, which tells
+# the reader which header file to include in order to use a class.
+# If left blank only the name of the header file containing the class
+# definition is used. Otherwise one should specify the include paths that
+# are normally passed to the compiler using the -I flag.
+
+STRIP_FROM_INC_PATH =
+
+# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter
+# (but less readable) file names. This can be useful is your file systems
+# doesn't support long names like on DOS, Mac, or CD-ROM.
+
+SHORT_NAMES = NO
+
+# If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen
+# will interpret the first line (until the first dot) of a JavaDoc-style
+# comment as the brief description. If set to NO, the JavaDoc
+# comments will behave just like regular Qt-style comments
+# (thus requiring an explicit @brief command for a brief description.)
+
+JAVADOC_AUTOBRIEF = NO
+
+# If the QT_AUTOBRIEF tag is set to YES then Doxygen will
+# interpret the first line (until the first dot) of a Qt-style
+# comment as the brief description. If set to NO, the comments
+# will behave just like regular Qt-style comments (thus requiring
+# an explicit \brief command for a brief description.)
+
+QT_AUTOBRIEF = NO
+
+# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen
+# treat a multi-line C++ special comment block (i.e. a block of //! or ///
+# comments) as a brief description. This used to be the default behaviour.
+# The new default is to treat a multi-line C++ comment block as a detailed
+# description. Set this tag to YES if you prefer the old behaviour instead.
+
+MULTILINE_CPP_IS_BRIEF = NO
+
+# If the DETAILS_AT_TOP tag is set to YES then Doxygen
+# will output the detailed description near the top, like JavaDoc.
+# If set to NO, the detailed description appears after the member
+# documentation.
+
+DETAILS_AT_TOP = NO
+
+# If the INHERIT_DOCS tag is set to YES (the default) then an undocumented
+# member inherits the documentation from any documented member that it
+# re-implements.
+
+INHERIT_DOCS = YES
+
+# If the SEPARATE_MEMBER_PAGES tag is set to YES, then doxygen will produce
+# a new page for each member. If set to NO, the documentation of a member will
+# be part of the file/class/namespace that contains it.
+
+SEPARATE_MEMBER_PAGES = NO
+
+# The TAB_SIZE tag can be used to set the number of spaces in a tab.
+# Doxygen uses this value to replace tabs by spaces in code fragments.
+
+TAB_SIZE = 8
+
+# This tag can be used to specify a number of aliases that acts
+# as commands in the documentation. An alias has the form "name=value".
+# For example adding "sideeffect=\par Side Effects:\n" will allow you to
+# put the command \sideeffect (or @sideeffect) in the documentation, which
+# will result in a user-defined paragraph with heading "Side Effects:".
+# You can put \n's in the value part of an alias to insert newlines.
+
+ALIASES =
+
+# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C
+# sources only. Doxygen will then generate output that is more tailored for C.
+# For instance, some of the names that are used will be different. The list
+# of all members will be omitted, etc.
+
+OPTIMIZE_OUTPUT_FOR_C = YES
+
+# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java
+# sources only. Doxygen will then generate output that is more tailored for
+# Java. For instance, namespaces will be presented as packages, qualified
+# scopes will look different, etc.
+
+OPTIMIZE_OUTPUT_JAVA = NO
+
+# Set the OPTIMIZE_FOR_FORTRAN tag to YES if your project consists of Fortran
+# sources only. Doxygen will then generate output that is more tailored for
+# Fortran.
+
+OPTIMIZE_FOR_FORTRAN = NO
+
+# Set the OPTIMIZE_OUTPUT_VHDL tag to YES if your project consists of VHDL
+# sources. Doxygen will then generate output that is tailored for
+# VHDL.
+
+OPTIMIZE_OUTPUT_VHDL = NO
+
+# If you use STL classes (i.e. std::string, std::vector, etc.) but do not want
+# to include (a tag file for) the STL sources as input, then you should
+# set this tag to YES in order to let doxygen match functions declarations and
+# definitions whose arguments contain STL classes (e.g. func(std::string); v.s.
+# func(std::string) {}). This also make the inheritance and collaboration
+# diagrams that involve STL classes more complete and accurate.
+
+BUILTIN_STL_SUPPORT = NO
+
+# If you use Microsoft's C++/CLI language, you should set this option to YES to
+# enable parsing support.
+
+CPP_CLI_SUPPORT = NO
+
+# Set the SIP_SUPPORT tag to YES if your project consists of sip sources only.
+# Doxygen will parse them like normal C++ but will assume all classes use public
+# instead of private inheritance when no explicit protection keyword is present.
+
+SIP_SUPPORT = NO
+
+# For Microsoft's IDL there are propget and propput attributes to indicate getter
+# and setter methods for a property. Setting this option to YES (the default)
+# will make doxygen to replace the get and set methods by a property in the
+# documentation. This will only work if the methods are indeed getting or
+# setting a simple type. If this is not the case, or you want to show the
+# methods anyway, you should set this option to NO.
+
+IDL_PROPERTY_SUPPORT = YES
+
+# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC
+# tag is set to YES, then doxygen will reuse the documentation of the first
+# member in the group (if any) for the other members of the group. By default
+# all members of a group must be documented explicitly.
+
+DISTRIBUTE_GROUP_DOC = NO
+
+# Set the SUBGROUPING tag to YES (the default) to allow class member groups of
+# the same type (for instance a group of public functions) to be put as a
+# subgroup of that type (e.g. under the Public Functions section). Set it to
+# NO to prevent subgrouping. Alternatively, this can be done per class using
+# the \nosubgrouping command.
+
+SUBGROUPING = YES
+
+# When TYPEDEF_HIDES_STRUCT is enabled, a typedef of a struct, union, or enum
+# is documented as struct, union, or enum with the name of the typedef. So
+# typedef struct TypeS {} TypeT, will appear in the documentation as a struct
+# with name TypeT. When disabled the typedef will appear as a member of a file,
+# namespace, or class. And the struct will be named TypeS. This can typically
+# be useful for C code in case the coding convention dictates that all compound
+# types are typedef'ed and only the typedef is referenced, never the tag name.
+
+TYPEDEF_HIDES_STRUCT = NO
+
+#---------------------------------------------------------------------------
+# Build related configuration options
+#---------------------------------------------------------------------------
+
+# If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in
+# documentation are documented, even if no documentation was available.
+# Private class members and static file members will be hidden unless
+# the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES
+
+EXTRACT_ALL = NO
+
+# If the EXTRACT_PRIVATE tag is set to YES all private members of a class
+# will be included in the documentation.
+
+EXTRACT_PRIVATE = YES
+
+# If the EXTRACT_STATIC tag is set to YES all static members of a file
+# will be included in the documentation.
+
+EXTRACT_STATIC = YES
+
+# If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs)
+# defined locally in source files will be included in the documentation.
+# If set to NO only classes defined in header files are included.
+
+EXTRACT_LOCAL_CLASSES = YES
+
+# This flag is only useful for Objective-C code. When set to YES local
+# methods, which are defined in the implementation section but not in
+# the interface are included in the documentation.
+# If set to NO (the default) only methods in the interface are included.
+
+EXTRACT_LOCAL_METHODS = NO
+
+# If this flag is set to YES, the members of anonymous namespaces will be
+# extracted and appear in the documentation as a namespace called
+# 'anonymous_namespace{file}', where file will be replaced with the base
+# name of the file that contains the anonymous namespace. By default
+# anonymous namespace are hidden.
+
+EXTRACT_ANON_NSPACES = NO
+
+# If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all
+# undocumented members of documented classes, files or namespaces.
+# If set to NO (the default) these members will be included in the
+# various overviews, but no documentation section is generated.
+# This option has no effect if EXTRACT_ALL is enabled.
+
+HIDE_UNDOC_MEMBERS = NO
+
+# If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all
+# undocumented classes that are normally visible in the class hierarchy.
+# If set to NO (the default) these classes will be included in the various
+# overviews. This option has no effect if EXTRACT_ALL is enabled.
+
+HIDE_UNDOC_CLASSES = NO
+
+# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all
+# friend (class|struct|union) declarations.
+# If set to NO (the default) these declarations will be included in the
+# documentation.
+
+HIDE_FRIEND_COMPOUNDS = NO
+
+# If the HIDE_IN_BODY_DOCS tag is set to YES, Doxygen will hide any
+# documentation blocks found inside the body of a function.
+# If set to NO (the default) these blocks will be appended to the
+# function's detailed documentation block.
+
+HIDE_IN_BODY_DOCS = NO
+
+# The INTERNAL_DOCS tag determines if documentation
+# that is typed after a \internal command is included. If the tag is set
+# to NO (the default) then the documentation will be excluded.
+# Set it to YES to include the internal documentation.
+
+INTERNAL_DOCS = NO
+
+# If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate
+# file names in lower-case letters. If set to YES upper-case letters are also
+# allowed. This is useful if you have classes or files whose names only differ
+# in case and if your file system supports case sensitive file names. Windows
+# and Mac users are advised to set this option to NO.
+
+CASE_SENSE_NAMES = YES
+
+# If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen
+# will show members with their full class and namespace scopes in the
+# documentation. If set to YES the scope will be hidden.
+
+HIDE_SCOPE_NAMES = NO
+
+# If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen
+# will put a list of the files that are included by a file in the documentation
+# of that file.
+
+SHOW_INCLUDE_FILES = YES
+
+# If the INLINE_INFO tag is set to YES (the default) then a tag [inline]
+# is inserted in the documentation for inline members.
+
+INLINE_INFO = YES
+
+# If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen
+# will sort the (detailed) documentation of file and class members
+# alphabetically by member name. If set to NO the members will appear in
+# declaration order.
+
+SORT_MEMBER_DOCS = YES
+
+# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the
+# brief documentation of file, namespace and class members alphabetically
+# by member name. If set to NO (the default) the members will appear in
+# declaration order.
+
+SORT_BRIEF_DOCS = NO
+
+# If the SORT_GROUP_NAMES tag is set to YES then doxygen will sort the
+# hierarchy of group names into alphabetical order. If set to NO (the default)
+# the group names will appear in their defined order.
+
+SORT_GROUP_NAMES = NO
+
+# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be
+# sorted by fully-qualified names, including namespaces. If set to
+# NO (the default), the class list will be sorted only by class name,
+# not including the namespace part.
+# Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES.
+# Note: This option applies only to the class list, not to the
+# alphabetical list.
+
+SORT_BY_SCOPE_NAME = NO
+
+# The GENERATE_TODOLIST tag can be used to enable (YES) or
+# disable (NO) the todo list. This list is created by putting \todo
+# commands in the documentation.
+
+GENERATE_TODOLIST = YES
+
+# The GENERATE_TESTLIST tag can be used to enable (YES) or
+# disable (NO) the test list. This list is created by putting \test
+# commands in the documentation.
+
+GENERATE_TESTLIST = YES
+
+# The GENERATE_BUGLIST tag can be used to enable (YES) or
+# disable (NO) the bug list. This list is created by putting \bug
+# commands in the documentation.
+
+GENERATE_BUGLIST = YES
+
+# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or
+# disable (NO) the deprecated list. This list is created by putting
+# \deprecated commands in the documentation.
+
+GENERATE_DEPRECATEDLIST= YES
+
+# The ENABLED_SECTIONS tag can be used to enable conditional
+# documentation sections, marked by \if sectionname ... \endif.
+
+ENABLED_SECTIONS =
+
+# The MAX_INITIALIZER_LINES tag determines the maximum number of lines
+# the initial value of a variable or define consists of for it to appear in
+# the documentation. If the initializer consists of more lines than specified
+# here it will be hidden. Use a value of 0 to hide initializers completely.
+# The appearance of the initializer of individual variables and defines in the
+# documentation can be controlled using \showinitializer or \hideinitializer
+# command in the documentation regardless of this setting.
+
+MAX_INITIALIZER_LINES = 30
+
+# Set the SHOW_USED_FILES tag to NO to disable the list of files generated
+# at the bottom of the documentation of classes and structs. If set to YES the
+# list will mention the files that were used to generate the documentation.
+
+SHOW_USED_FILES = YES
+
+# If the sources in your project are distributed over multiple directories
+# then setting the SHOW_DIRECTORIES tag to YES will show the directory hierarchy
+# in the documentation. The default is NO.
+
+SHOW_DIRECTORIES = NO
+
+# Set the SHOW_FILES tag to NO to disable the generation of the Files page.
+# This will remove the Files entry from the Quick Index and from the
+# Folder Tree View (if specified). The default is YES.
+
+SHOW_FILES = YES
+
+# Set the SHOW_NAMESPACES tag to NO to disable the generation of the
+# Namespaces page. This will remove the Namespaces entry from the Quick Index
+# and from the Folder Tree View (if specified). The default is YES.
+
+SHOW_NAMESPACES = YES
+
+# The FILE_VERSION_FILTER tag can be used to specify a program or script that
+# doxygen should invoke to get the current version for each file (typically from
+# the version control system). Doxygen will invoke the program by executing (via
+# popen()) the command <command> <input-file>, where <command> is the value of
+# the FILE_VERSION_FILTER tag, and <input-file> is the name of an input file
+# provided by doxygen. Whatever the program writes to standard output
+# is used as the file version. See the manual for examples.
+
+FILE_VERSION_FILTER =
+
+#---------------------------------------------------------------------------
+# configuration options related to warning and progress messages
+#---------------------------------------------------------------------------
+
+# The QUIET tag can be used to turn on/off the messages that are generated
+# by doxygen. Possible values are YES and NO. If left blank NO is used.
+
+QUIET = YES
+
+# The WARNINGS tag can be used to turn on/off the warning messages that are
+# generated by doxygen. Possible values are YES and NO. If left blank
+# NO is used.
+
+WARNINGS = YES
+
+# If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings
+# for undocumented members. If EXTRACT_ALL is set to YES then this flag will
+# automatically be disabled.
+
+WARN_IF_UNDOCUMENTED = YES
+
+# If WARN_IF_DOC_ERROR is set to YES, doxygen will generate warnings for
+# potential errors in the documentation, such as not documenting some
+# parameters in a documented function, or documenting parameters that
+# don't exist or using markup commands wrongly.
+
+WARN_IF_DOC_ERROR = YES
+
+# This WARN_NO_PARAMDOC option can be abled to get warnings for
+# functions that are documented, but have no documentation for their parameters
+# or return value. If set to NO (the default) doxygen will only warn about
+# wrong or incomplete parameter documentation, but not about the absence of
+# documentation.
+
+WARN_NO_PARAMDOC = NO
+
+# The WARN_FORMAT tag determines the format of the warning messages that
+# doxygen can produce. The string should contain the $file, $line, and $text
+# tags, which will be replaced by the file and line number from which the
+# warning originated and the warning text. Optionally the format may contain
+# $version, which will be replaced by the version of the file (if it could
+# be obtained via FILE_VERSION_FILTER)
+
+WARN_FORMAT = "$file:$line: $text"
+
+# The WARN_LOGFILE tag can be used to specify a file to which warning
+# and error messages should be written. If left blank the output is written
+# to stderr.
+
+WARN_LOGFILE =
+
+#---------------------------------------------------------------------------
+# configuration options related to the input files
+#---------------------------------------------------------------------------
+
+# The INPUT tag can be used to specify the files and/or directories that contain
+# documented source files. You may enter file names like "myfile.cpp" or
+# directories like "/usr/src/myproject". Separate the files or directories
+# with spaces.
+
+INPUT = . include/univ.i
+
+# This tag can be used to specify the character encoding of the source files
+# that doxygen parses. Internally doxygen uses the UTF-8 encoding, which is
+# also the default input encoding. Doxygen uses libiconv (or the iconv built
+# into libc) for the transcoding. See http://www.gnu.org/software/libiconv for
+# the list of possible encodings.
+
+INPUT_ENCODING = UTF-8
+
+# If the value of the INPUT tag contains directories, you can use the
+# FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp
+# and *.h) to filter out the source-files in the directories. If left
+# blank the following patterns are tested:
+# *.c *.cc *.cxx *.cpp *.c++ *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh *.hxx
+# *.hpp *.h++ *.idl *.odl *.cs *.php *.php3 *.inc *.m *.mm *.py *.f90
+
+FILE_PATTERNS = *.c *.ic *.h
+
+# The RECURSIVE tag can be used to turn specify whether or not subdirectories
+# should be searched for input files as well. Possible values are YES and NO.
+# If left blank NO is used.
+
+RECURSIVE = YES
+
+# The EXCLUDE tag can be used to specify files and/or directories that should
+# excluded from the INPUT source files. This way you can easily exclude a
+# subdirectory from a directory tree whose root is specified with the INPUT tag.
+
+EXCLUDE = ut0auxconf_*
+
+# The EXCLUDE_SYMLINKS tag can be used select whether or not files or
+# directories that are symbolic links (a Unix filesystem feature) are excluded
+# from the input.
+
+EXCLUDE_SYMLINKS = NO
+
+# If the value of the INPUT tag contains directories, you can use the
+# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude
+# certain files from those directories. Note that the wildcards are matched
+# against the file with absolute path, so to exclude all test directories
+# for example use the pattern */test/*
+
+EXCLUDE_PATTERNS =
+
+# The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names
+# (namespaces, classes, functions, etc.) that should be excluded from the
+# output. The symbol name can be a fully qualified name, a word, or if the
+# wildcard * is used, a substring. Examples: ANamespace, AClass,
+# AClass::ANamespace, ANamespace::*Test
+
+EXCLUDE_SYMBOLS =
+
+# The EXAMPLE_PATH tag can be used to specify one or more files or
+# directories that contain example code fragments that are included (see
+# the \include command).
+
+EXAMPLE_PATH =
+
+# If the value of the EXAMPLE_PATH tag contains directories, you can use the
+# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp
+# and *.h) to filter out the source-files in the directories. If left
+# blank all files are included.
+
+EXAMPLE_PATTERNS =
+
+# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be
+# searched for input files to be used with the \include or \dontinclude
+# commands irrespective of the value of the RECURSIVE tag.
+# Possible values are YES and NO. If left blank NO is used.
+
+EXAMPLE_RECURSIVE = NO
+
+# The IMAGE_PATH tag can be used to specify one or more files or
+# directories that contain image that are included in the documentation (see
+# the \image command).
+
+IMAGE_PATH =
+
+# The INPUT_FILTER tag can be used to specify a program that doxygen should
+# invoke to filter for each input file. Doxygen will invoke the filter program
+# by executing (via popen()) the command <filter> <input-file>, where <filter>
+# is the value of the INPUT_FILTER tag, and <input-file> is the name of an
+# input file. Doxygen will then use the output that the filter program writes
+# to standard output. If FILTER_PATTERNS is specified, this tag will be
+# ignored.
+
+INPUT_FILTER =
+
+# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern
+# basis. Doxygen will compare the file name with each pattern and apply the
+# filter if there is a match. The filters are a list of the form:
+# pattern=filter (like *.cpp=my_cpp_filter). See INPUT_FILTER for further
+# info on how filters are used. If FILTER_PATTERNS is empty, INPUT_FILTER
+# is applied to all files.
+
+FILTER_PATTERNS =
+
+# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using
+# INPUT_FILTER) will be used to filter the input files when producing source
+# files to browse (i.e. when SOURCE_BROWSER is set to YES).
+
+FILTER_SOURCE_FILES = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to source browsing
+#---------------------------------------------------------------------------
+
+# If the SOURCE_BROWSER tag is set to YES then a list of source files will
+# be generated. Documented entities will be cross-referenced with these sources.
+# Note: To get rid of all source code in the generated output, make sure also
+# VERBATIM_HEADERS is set to NO.
+
+SOURCE_BROWSER = NO
+
+# Setting the INLINE_SOURCES tag to YES will include the body
+# of functions and classes directly in the documentation.
+
+INLINE_SOURCES = NO
+
+# Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct
+# doxygen to hide any special comment blocks from generated source code
+# fragments. Normal C and C++ comments will always remain visible.
+
+STRIP_CODE_COMMENTS = YES
+
+# If the REFERENCED_BY_RELATION tag is set to YES
+# then for each documented function all documented
+# functions referencing it will be listed.
+
+REFERENCED_BY_RELATION = NO
+
+# If the REFERENCES_RELATION tag is set to YES
+# then for each documented function all documented entities
+# called/used by that function will be listed.
+
+REFERENCES_RELATION = NO
+
+# If the REFERENCES_LINK_SOURCE tag is set to YES (the default)
+# and SOURCE_BROWSER tag is set to YES, then the hyperlinks from
+# functions in REFERENCES_RELATION and REFERENCED_BY_RELATION lists will
+# link to the source code. Otherwise they will link to the documentstion.
+
+REFERENCES_LINK_SOURCE = YES
+
+# If the USE_HTAGS tag is set to YES then the references to source code
+# will point to the HTML generated by the htags(1) tool instead of doxygen
+# built-in source browser. The htags tool is part of GNU's global source
+# tagging system (see http://www.gnu.org/software/global/global.html). You
+# will need version 4.8.6 or higher.
+
+USE_HTAGS = NO
+
+# If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen
+# will generate a verbatim copy of the header file for each class for
+# which an include is specified. Set to NO to disable this.
+
+VERBATIM_HEADERS = YES
+
+#---------------------------------------------------------------------------
+# configuration options related to the alphabetical class index
+#---------------------------------------------------------------------------
+
+# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index
+# of all compounds will be generated. Enable this if the project
+# contains a lot of classes, structs, unions or interfaces.
+
+ALPHABETICAL_INDEX = NO
+
+# If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then
+# the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns
+# in which this list will be split (can be a number in the range [1..20])
+
+COLS_IN_ALPHA_INDEX = 5
+
+# In case all classes in a project start with a common prefix, all
+# classes will be put under the same header in the alphabetical index.
+# The IGNORE_PREFIX tag can be used to specify one or more prefixes that
+# should be ignored while generating the index headers.
+
+IGNORE_PREFIX =
+
+#---------------------------------------------------------------------------
+# configuration options related to the HTML output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_HTML tag is set to YES (the default) Doxygen will
+# generate HTML output.
+
+GENERATE_HTML = YES
+
+# The HTML_OUTPUT tag is used to specify where the HTML docs will be put.
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be
+# put in front of it. If left blank `html' will be used as the default path.
+
+HTML_OUTPUT = html
+
+# The HTML_FILE_EXTENSION tag can be used to specify the file extension for
+# each generated HTML page (for example: .htm,.php,.asp). If it is left blank
+# doxygen will generate files with .html extension.
+
+HTML_FILE_EXTENSION = .html
+
+# The HTML_HEADER tag can be used to specify a personal HTML header for
+# each generated HTML page. If it is left blank doxygen will generate a
+# standard header.
+
+HTML_HEADER =
+
+# The HTML_FOOTER tag can be used to specify a personal HTML footer for
+# each generated HTML page. If it is left blank doxygen will generate a
+# standard footer.
+
+HTML_FOOTER =
+
+# The HTML_STYLESHEET tag can be used to specify a user-defined cascading
+# style sheet that is used by each HTML page. It can be used to
+# fine-tune the look of the HTML output. If the tag is left blank doxygen
+# will generate a default style sheet. Note that doxygen will try to copy
+# the style sheet file to the HTML output directory, so don't put your own
+# stylesheet in the HTML output directory as well, or it will be erased!
+
+HTML_STYLESHEET =
+
+# If the HTML_ALIGN_MEMBERS tag is set to YES, the members of classes,
+# files or namespaces will be aligned in HTML using tables. If set to
+# NO a bullet list will be used.
+
+HTML_ALIGN_MEMBERS = YES
+
+# If the GENERATE_HTMLHELP tag is set to YES, additional index files
+# will be generated that can be used as input for tools like the
+# Microsoft HTML help workshop to generate a compiled HTML help file (.chm)
+# of the generated HTML documentation.
+
+GENERATE_HTMLHELP = NO
+
+# If the GENERATE_DOCSET tag is set to YES, additional index files
+# will be generated that can be used as input for Apple's Xcode 3
+# integrated development environment, introduced with OSX 10.5 (Leopard).
+# To create a documentation set, doxygen will generate a Makefile in the
+# HTML output directory. Running make will produce the docset in that
+# directory and running "make install" will install the docset in
+# ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find
+# it at startup.
+
+GENERATE_DOCSET = NO
+
+# When GENERATE_DOCSET tag is set to YES, this tag determines the name of the
+# feed. A documentation feed provides an umbrella under which multiple
+# documentation sets from a single provider (such as a company or product suite)
+# can be grouped.
+
+DOCSET_FEEDNAME = "Doxygen generated docs"
+
+# When GENERATE_DOCSET tag is set to YES, this tag specifies a string that
+# should uniquely identify the documentation set bundle. This should be a
+# reverse domain-name style string, e.g. com.mycompany.MyDocSet. Doxygen
+# will append .docset to the name.
+
+DOCSET_BUNDLE_ID = org.doxygen.Project
+
+# If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML
+# documentation will contain sections that can be hidden and shown after the
+# page has loaded. For this to work a browser that supports
+# JavaScript and DHTML is required (for instance Mozilla 1.0+, Firefox
+# Netscape 6.0+, Internet explorer 5.0+, Konqueror, or Safari).
+
+HTML_DYNAMIC_SECTIONS = NO
+
+# If the GENERATE_HTMLHELP tag is set to YES, the CHM_FILE tag can
+# be used to specify the file name of the resulting .chm file. You
+# can add a path in front of the file if the result should not be
+# written to the html output directory.
+
+CHM_FILE =
+
+# If the GENERATE_HTMLHELP tag is set to YES, the HHC_LOCATION tag can
+# be used to specify the location (absolute path including file name) of
+# the HTML help compiler (hhc.exe). If non-empty doxygen will try to run
+# the HTML help compiler on the generated index.hhp.
+
+HHC_LOCATION =
+
+# If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag
+# controls if a separate .chi index file is generated (YES) or that
+# it should be included in the master .chm file (NO).
+
+GENERATE_CHI = NO
+
+# If the GENERATE_HTMLHELP tag is set to YES, the CHM_INDEX_ENCODING
+# is used to encode HtmlHelp index (hhk), content (hhc) and project file
+# content.
+
+CHM_INDEX_ENCODING =
+
+# If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag
+# controls whether a binary table of contents is generated (YES) or a
+# normal table of contents (NO) in the .chm file.
+
+BINARY_TOC = NO
+
+# The TOC_EXPAND flag can be set to YES to add extra items for group members
+# to the contents of the HTML help documentation and to the tree view.
+
+TOC_EXPAND = NO
+
+# The DISABLE_INDEX tag can be used to turn on/off the condensed index at
+# top of each HTML page. The value NO (the default) enables the index and
+# the value YES disables it.
+
+DISABLE_INDEX = NO
+
+# This tag can be used to set the number of enum values (range [1..20])
+# that doxygen will group on one line in the generated HTML documentation.
+
+ENUM_VALUES_PER_LINE = 4
+
+# The GENERATE_TREEVIEW tag is used to specify whether a tree-like index
+# structure should be generated to display hierarchical information.
+# If the tag value is set to FRAME, a side panel will be generated
+# containing a tree-like index structure (just like the one that
+# is generated for HTML Help). For this to work a browser that supports
+# JavaScript, DHTML, CSS and frames is required (for instance Mozilla 1.0+,
+# Netscape 6.0+, Internet explorer 5.0+, or Konqueror). Windows users are
+# probably better off using the HTML help feature. Other possible values
+# for this tag are: HIERARCHIES, which will generate the Groups, Directories,
+# and Class Hiererachy pages using a tree view instead of an ordered list;
+# ALL, which combines the behavior of FRAME and HIERARCHIES; and NONE, which
+# disables this behavior completely. For backwards compatibility with previous
+# releases of Doxygen, the values YES and NO are equivalent to FRAME and NONE
+# respectively.
+
+GENERATE_TREEVIEW = NONE
+
+# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be
+# used to set the initial width (in pixels) of the frame in which the tree
+# is shown.
+
+TREEVIEW_WIDTH = 250
+
+# Use this tag to change the font size of Latex formulas included
+# as images in the HTML documentation. The default is 10. Note that
+# when you change the font size after a successful doxygen run you need
+# to manually remove any form_*.png images from the HTML output directory
+# to force them to be regenerated.
+
+FORMULA_FONTSIZE = 10
+
+#---------------------------------------------------------------------------
+# configuration options related to the LaTeX output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_LATEX tag is set to YES (the default) Doxygen will
+# generate Latex output.
+
+GENERATE_LATEX = NO
+
+# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put.
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be
+# put in front of it. If left blank `latex' will be used as the default path.
+
+LATEX_OUTPUT = latex
+
+# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be
+# invoked. If left blank `latex' will be used as the default command name.
+
+LATEX_CMD_NAME = latex
+
+# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to
+# generate index for LaTeX. If left blank `makeindex' will be used as the
+# default command name.
+
+MAKEINDEX_CMD_NAME = makeindex
+
+# If the COMPACT_LATEX tag is set to YES Doxygen generates more compact
+# LaTeX documents. This may be useful for small projects and may help to
+# save some trees in general.
+
+COMPACT_LATEX = NO
+
+# The PAPER_TYPE tag can be used to set the paper type that is used
+# by the printer. Possible values are: a4, a4wide, letter, legal and
+# executive. If left blank a4wide will be used.
+
+PAPER_TYPE = a4wide
+
+# The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX
+# packages that should be included in the LaTeX output.
+
+EXTRA_PACKAGES =
+
+# The LATEX_HEADER tag can be used to specify a personal LaTeX header for
+# the generated latex document. The header should contain everything until
+# the first chapter. If it is left blank doxygen will generate a
+# standard header. Notice: only use this tag if you know what you are doing!
+
+LATEX_HEADER =
+
+# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated
+# is prepared for conversion to pdf (using ps2pdf). The pdf file will
+# contain links (just like the HTML output) instead of page references
+# This makes the output suitable for online browsing using a pdf viewer.
+
+PDF_HYPERLINKS = YES
+
+# If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of
+# plain latex in the generated Makefile. Set this option to YES to get a
+# higher quality PDF documentation.
+
+USE_PDFLATEX = YES
+
+# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode.
+# command to the generated LaTeX files. This will instruct LaTeX to keep
+# running if errors occur, instead of asking the user for help.
+# This option is also used when generating formulas in HTML.
+
+LATEX_BATCHMODE = NO
+
+# If LATEX_HIDE_INDICES is set to YES then doxygen will not
+# include the index chapters (such as File Index, Compound Index, etc.)
+# in the output.
+
+LATEX_HIDE_INDICES = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to the RTF output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output
+# The RTF output is optimized for Word 97 and may not look very pretty with
+# other RTF readers or editors.
+
+GENERATE_RTF = NO
+
+# The RTF_OUTPUT tag is used to specify where the RTF docs will be put.
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be
+# put in front of it. If left blank `rtf' will be used as the default path.
+
+RTF_OUTPUT = rtf
+
+# If the COMPACT_RTF tag is set to YES Doxygen generates more compact
+# RTF documents. This may be useful for small projects and may help to
+# save some trees in general.
+
+COMPACT_RTF = NO
+
+# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated
+# will contain hyperlink fields. The RTF file will
+# contain links (just like the HTML output) instead of page references.
+# This makes the output suitable for online browsing using WORD or other
+# programs which support those fields.
+# Note: wordpad (write) and others do not support links.
+
+RTF_HYPERLINKS = NO
+
+# Load stylesheet definitions from file. Syntax is similar to doxygen's
+# config file, i.e. a series of assignments. You only have to provide
+# replacements, missing definitions are set to their default value.
+
+RTF_STYLESHEET_FILE =
+
+# Set optional variables used in the generation of an rtf document.
+# Syntax is similar to doxygen's config file.
+
+RTF_EXTENSIONS_FILE =
+
+#---------------------------------------------------------------------------
+# configuration options related to the man page output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_MAN tag is set to YES (the default) Doxygen will
+# generate man pages
+
+GENERATE_MAN = NO
+
+# The MAN_OUTPUT tag is used to specify where the man pages will be put.
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be
+# put in front of it. If left blank `man' will be used as the default path.
+
+MAN_OUTPUT = man
+
+# The MAN_EXTENSION tag determines the extension that is added to
+# the generated man pages (default is the subroutine's section .3)
+
+MAN_EXTENSION = .3
+
+# If the MAN_LINKS tag is set to YES and Doxygen generates man output,
+# then it will generate one additional man file for each entity
+# documented in the real man page(s). These additional files
+# only source the real man page, but without them the man command
+# would be unable to find the correct page. The default is NO.
+
+MAN_LINKS = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to the XML output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_XML tag is set to YES Doxygen will
+# generate an XML file that captures the structure of
+# the code including all documentation.
+
+GENERATE_XML = NO
+
+# The XML_OUTPUT tag is used to specify where the XML pages will be put.
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be
+# put in front of it. If left blank `xml' will be used as the default path.
+
+XML_OUTPUT = xml
+
+# The XML_SCHEMA tag can be used to specify an XML schema,
+# which can be used by a validating XML parser to check the
+# syntax of the XML files.
+
+XML_SCHEMA =
+
+# The XML_DTD tag can be used to specify an XML DTD,
+# which can be used by a validating XML parser to check the
+# syntax of the XML files.
+
+XML_DTD =
+
+# If the XML_PROGRAMLISTING tag is set to YES Doxygen will
+# dump the program listings (including syntax highlighting
+# and cross-referencing information) to the XML output. Note that
+# enabling this will significantly increase the size of the XML output.
+
+XML_PROGRAMLISTING = YES
+
+#---------------------------------------------------------------------------
+# configuration options for the AutoGen Definitions output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_AUTOGEN_DEF tag is set to YES Doxygen will
+# generate an AutoGen Definitions (see autogen.sf.net) file
+# that captures the structure of the code including all
+# documentation. Note that this feature is still experimental
+# and incomplete at the moment.
+
+GENERATE_AUTOGEN_DEF = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to the Perl module output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_PERLMOD tag is set to YES Doxygen will
+# generate a Perl module file that captures the structure of
+# the code including all documentation. Note that this
+# feature is still experimental and incomplete at the
+# moment.
+
+GENERATE_PERLMOD = NO
+
+# If the PERLMOD_LATEX tag is set to YES Doxygen will generate
+# the necessary Makefile rules, Perl scripts and LaTeX code to be able
+# to generate PDF and DVI output from the Perl module output.
+
+PERLMOD_LATEX = NO
+
+# If the PERLMOD_PRETTY tag is set to YES the Perl module output will be
+# nicely formatted so it can be parsed by a human reader. This is useful
+# if you want to understand what is going on. On the other hand, if this
+# tag is set to NO the size of the Perl module output will be much smaller
+# and Perl will parse it just the same.
+
+PERLMOD_PRETTY = YES
+
+# The names of the make variables in the generated doxyrules.make file
+# are prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX.
+# This is useful so different doxyrules.make files included by the same
+# Makefile don't overwrite each other's variables.
+
+PERLMOD_MAKEVAR_PREFIX =
+
+#---------------------------------------------------------------------------
+# Configuration options related to the preprocessor
+#---------------------------------------------------------------------------
+
+# If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will
+# evaluate all C-preprocessor directives found in the sources and include
+# files.
+
+ENABLE_PREPROCESSING = YES
+
+# If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro
+# names in the source code. If set to NO (the default) only conditional
+# compilation will be performed. Macro expansion can be done in a controlled
+# way by setting EXPAND_ONLY_PREDEF to YES.
+
+MACRO_EXPANSION = YES
+
+# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES
+# then the macro expansion is limited to the macros specified with the
+# PREDEFINED and EXPAND_AS_DEFINED tags.
+
+EXPAND_ONLY_PREDEF = YES
+
+# If the SEARCH_INCLUDES tag is set to YES (the default) the includes files
+# in the INCLUDE_PATH (see below) will be search if a #include is found.
+
+SEARCH_INCLUDES = YES
+
+# The INCLUDE_PATH tag can be used to specify one or more directories that
+# contain include files that are not input files but should be processed by
+# the preprocessor.
+
+INCLUDE_PATH =
+
+# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard
+# patterns (like *.h and *.hpp) to filter out the header-files in the
+# directories. If left blank, the patterns specified with FILE_PATTERNS will
+# be used.
+
+INCLUDE_FILE_PATTERNS =
+
+# The PREDEFINED tag can be used to specify one or more macro names that
+# are defined before the preprocessor is started (similar to the -D option of
+# gcc). The argument of the tag is a list of macros of the form: name
+# or name=definition (no spaces). If the definition and the = are
+# omitted =1 is assumed. To prevent a macro definition from being
+# undefined via #undef or recursively expanded use the := operator
+# instead of the = operator.
+
+PREDEFINED = DOXYGEN UNIV_DEBUG UNIV_SYNC_DEBUG __attribute__()=
+
+# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then
+# this tag can be used to specify a list of macro names that should be expanded.
+# The macro definition that is found in the sources will be used.
+# Use the PREDEFINED tag if you want to use a different macro definition.
+
+EXPAND_AS_DEFINED = UT_LIST_BASE_NODE_T UT_LIST_NODE_T
+
+# If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then
+# doxygen's preprocessor will remove all function-like macros that are alone
+# on a line, have an all uppercase name, and do not end with a semicolon. Such
+# function macros are typically used for boiler-plate code, and will confuse
+# the parser if not removed.
+
+SKIP_FUNCTION_MACROS = YES
+
+#---------------------------------------------------------------------------
+# Configuration::additions related to external references
+#---------------------------------------------------------------------------
+
+# The TAGFILES option can be used to specify one or more tagfiles.
+# Optionally an initial location of the external documentation
+# can be added for each tagfile. The format of a tag file without
+# this location is as follows:
+# TAGFILES = file1 file2 ...
+# Adding location for the tag files is done as follows:
+# TAGFILES = file1=loc1 "file2 = loc2" ...
+# where "loc1" and "loc2" can be relative or absolute paths or
+# URLs. If a location is present for each tag, the installdox tool
+# does not have to be run to correct the links.
+# Note that each tag file must have a unique name
+# (where the name does NOT include the path)
+# If a tag file is not located in the directory in which doxygen
+# is run, you must also specify the path to the tagfile here.
+
+TAGFILES =
+
+# When a file name is specified after GENERATE_TAGFILE, doxygen will create
+# a tag file that is based on the input files it reads.
+
+GENERATE_TAGFILE =
+
+# If the ALLEXTERNALS tag is set to YES all external classes will be listed
+# in the class index. If set to NO only the inherited external classes
+# will be listed.
+
+ALLEXTERNALS = NO
+
+# If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed
+# in the modules index. If set to NO, only the current project's groups will
+# be listed.
+
+EXTERNAL_GROUPS = NO
+
+# The PERL_PATH should be the absolute path and name of the perl script
+# interpreter (i.e. the result of `which perl').
+
+PERL_PATH = /usr/bin/perl
+
+#---------------------------------------------------------------------------
+# Configuration options related to the dot tool
+#---------------------------------------------------------------------------
+
+# If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will
+# generate a inheritance diagram (in HTML, RTF and LaTeX) for classes with base
+# or super classes. Setting the tag to NO turns the diagrams off. Note that
+# this option is superseded by the HAVE_DOT option below. This is only a
+# fallback. It is recommended to install and use dot, since it yields more
+# powerful graphs.
+
+CLASS_DIAGRAMS = YES
+
+# You can define message sequence charts within doxygen comments using the \msc
+# command. Doxygen will then run the mscgen tool (see
+# http://www.mcternan.me.uk/mscgen/) to produce the chart and insert it in the
+# documentation. The MSCGEN_PATH tag allows you to specify the directory where
+# the mscgen tool resides. If left empty the tool is assumed to be found in the
+# default search path.
+
+MSCGEN_PATH =
+
+# If set to YES, the inheritance and collaboration graphs will hide
+# inheritance and usage relations if the target is undocumented
+# or is not a class.
+
+HIDE_UNDOC_RELATIONS = YES
+
+# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is
+# available from the path. This tool is part of Graphviz, a graph visualization
+# toolkit from AT&T and Lucent Bell Labs. The other options in this section
+# have no effect if this option is set to NO (the default)
+
+HAVE_DOT = YES
+
+# By default doxygen will write a font called FreeSans.ttf to the output
+# directory and reference it in all dot files that doxygen generates. This
+# font does not include all possible unicode characters however, so when you need
+# these (or just want a differently looking font) you can specify the font name
+# using DOT_FONTNAME. You need need to make sure dot is able to find the font,
+# which can be done by putting it in a standard location or by setting the
+# DOTFONTPATH environment variable or by setting DOT_FONTPATH to the directory
+# containing the font.
+
+DOT_FONTNAME = FreeSans
+
+# By default doxygen will tell dot to use the output directory to look for the
+# FreeSans.ttf font (which doxygen will put there itself). If you specify a
+# different font using DOT_FONTNAME you can set the path where dot
+# can find it using this tag.
+
+DOT_FONTPATH =
+
+# If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen
+# will generate a graph for each documented class showing the direct and
+# indirect inheritance relations. Setting this tag to YES will force the
+# the CLASS_DIAGRAMS tag to NO.
+
+CLASS_GRAPH = YES
+
+# If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen
+# will generate a graph for each documented class showing the direct and
+# indirect implementation dependencies (inheritance, containment, and
+# class references variables) of the class with other documented classes.
+
+COLLABORATION_GRAPH = YES
+
+# If the GROUP_GRAPHS and HAVE_DOT tags are set to YES then doxygen
+# will generate a graph for groups, showing the direct groups dependencies
+
+GROUP_GRAPHS = NO
+
+# If the UML_LOOK tag is set to YES doxygen will generate inheritance and
+# collaboration diagrams in a style similar to the OMG's Unified Modeling
+# Language.
+
+UML_LOOK = NO
+
+# If set to YES, the inheritance and collaboration graphs will show the
+# relations between templates and their instances.
+
+TEMPLATE_RELATIONS = NO
+
+# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT
+# tags are set to YES then doxygen will generate a graph for each documented
+# file showing the direct and indirect include dependencies of the file with
+# other documented files.
+
+INCLUDE_GRAPH = YES
+
+# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and
+# HAVE_DOT tags are set to YES then doxygen will generate a graph for each
+# documented header file showing the documented files that directly or
+# indirectly include this file.
+
+INCLUDED_BY_GRAPH = YES
+
+# If the CALL_GRAPH and HAVE_DOT options are set to YES then
+# doxygen will generate a call dependency graph for every global function
+# or class method. Note that enabling this option will significantly increase
+# the time of a run. So in most cases it will be better to enable call graphs
+# for selected functions only using the \callgraph command.
+
+CALL_GRAPH = NO
+
+# If the CALLER_GRAPH and HAVE_DOT tags are set to YES then
+# doxygen will generate a caller dependency graph for every global function
+# or class method. Note that enabling this option will significantly increase
+# the time of a run. So in most cases it will be better to enable caller
+# graphs for selected functions only using the \callergraph command.
+
+CALLER_GRAPH = NO
+
+# If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen
+# will graphical hierarchy of all classes instead of a textual one.
+
+GRAPHICAL_HIERARCHY = YES
+
+# If the DIRECTORY_GRAPH, SHOW_DIRECTORIES and HAVE_DOT tags are set to YES
+# then doxygen will show the dependencies a directory has on other directories
+# in a graphical way. The dependency relations are determined by the #include
+# relations between the files in the directories.
+
+DIRECTORY_GRAPH = YES
+
+# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images
+# generated by dot. Possible values are png, jpg, or gif
+# If left blank png will be used.
+
+DOT_IMAGE_FORMAT = png
+
+# The tag DOT_PATH can be used to specify the path where the dot tool can be
+# found. If left blank, it is assumed the dot tool can be found in the path.
+
+DOT_PATH =
+
+# The DOTFILE_DIRS tag can be used to specify one or more directories that
+# contain dot files that are included in the documentation (see the
+# \dotfile command).
+
+DOTFILE_DIRS =
+
+# The DOT_GRAPH_MAX_NODES tag can be used to set the maximum number of
+# nodes that will be shown in the graph. If the number of nodes in a graph
+# becomes larger than this value, doxygen will truncate the graph, which is
+# visualized by representing a node as a red box. Note that doxygen if the
+# number of direct children of the root node in a graph is already larger than
+# DOT_GRAPH_MAX_NODES then the graph will not be shown at all. Also note
+# that the size of a graph can be further restricted by MAX_DOT_GRAPH_DEPTH.
+
+DOT_GRAPH_MAX_NODES = 50
+
+# The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the
+# graphs generated by dot. A depth value of 3 means that only nodes reachable
+# from the root by following a path via at most 3 edges will be shown. Nodes
+# that lay further from the root node will be omitted. Note that setting this
+# option to 1 or 2 may greatly reduce the computation time needed for large
+# code bases. Also note that the size of a graph can be further restricted by
+# DOT_GRAPH_MAX_NODES. Using a depth of 0 means no depth restriction.
+
+MAX_DOT_GRAPH_DEPTH = 3
+
+# Set the DOT_TRANSPARENT tag to YES to generate images with a transparent
+# background. This is enabled by default, which results in a transparent
+# background. Warning: Depending on the platform used, enabling this option
+# may lead to badly anti-aliased labels on the edges of a graph (i.e. they
+# become hard to read).
+
+DOT_TRANSPARENT = YES
+
+# Set the DOT_MULTI_TARGETS tag to YES allow dot to generate multiple output
+# files in one run (i.e. multiple -o and -T options on the command line). This
+# makes dot run faster, but since only newer versions of dot (>1.8.10)
+# support this, this feature is disabled by default.
+
+DOT_MULTI_TARGETS = NO
+
+# If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will
+# generate a legend page explaining the meaning of the various boxes and
+# arrows in the dot generated graphs.
+
+GENERATE_LEGEND = YES
+
+# If the DOT_CLEANUP tag is set to YES (the default) Doxygen will
+# remove the intermediate dot files that are used to generate
+# the various graphs.
+
+DOT_CLEANUP = YES
+
+#---------------------------------------------------------------------------
+# Configuration::additions related to the search engine
+#---------------------------------------------------------------------------
+
+# The SEARCHENGINE tag specifies whether or not a search engine should be
+# used. If set to NO the values of all tags below this one will be ignored.
+
+SEARCHENGINE = NO
diff --git a/storage/innodb_plugin/Makefile.am b/storage/innodb_plugin/Makefile.am
index 4792b72cba0..87c9720c1b7 100644
--- a/storage/innodb_plugin/Makefile.am
+++ b/storage/innodb_plugin/Makefile.am
@@ -29,152 +29,299 @@ INCLUDES= -I$(top_srcdir)/include -I$(top_builddir)/include \
DEFS= @DEFS@
-noinst_HEADERS= include/btr0btr.h include/btr0btr.ic \
- include/btr0cur.h include/btr0cur.ic \
- include/btr0pcur.h include/btr0pcur.ic \
- include/btr0sea.h include/btr0sea.ic \
- include/btr0types.h include/buf0buddy.h \
- include/buf0buddy.ic include/buf0buf.h \
- include/buf0buf.ic include/buf0flu.h \
- include/buf0flu.ic include/buf0lru.h \
- include/buf0lru.ic include/buf0rea.h \
- include/buf0types.h include/data0data.h \
- include/data0data.ic include/data0type.h \
- include/data0type.ic include/data0types.h \
- include/db0err.h include/dict0boot.h \
- include/dict0boot.ic include/dict0crea.h \
- include/dict0crea.ic include/dict0dict.h \
- include/dict0dict.ic include/dict0load.h \
- include/dict0load.ic include/dict0mem.h \
- include/dict0mem.ic include/dict0types.h \
- include/dyn0dyn.h include/dyn0dyn.ic \
- include/eval0eval.h include/eval0eval.ic \
- include/eval0proc.h include/eval0proc.ic \
- include/fil0fil.h include/fsp0fsp.h \
- include/fsp0fsp.ic include/fut0fut.h \
- include/fut0fut.ic include/fut0lst.h \
- include/fut0lst.ic include/ha0ha.h \
- include/ha0ha.ic \
- include/ha0storage.h \
- include/ha0storage.ic \
- include/hash0hash.h \
- include/hash0hash.ic include/ibuf0ibuf.h \
- include/ibuf0ibuf.ic include/ibuf0types.h \
- include/lock0iter.h \
- include/lock0lock.h include/lock0lock.ic \
- include/lock0priv.h include/lock0priv.ic \
- include/lock0types.h include/log0log.h \
- include/log0log.ic include/log0recv.h \
- include/log0recv.ic include/mach0data.h \
- include/mach0data.ic include/mem0dbg.h \
- include/mem0dbg.ic mem/mem0dbg.c \
- include/mem0mem.h include/mem0mem.ic \
- include/mem0pool.h include/mem0pool.ic \
- include/mtr0log.h include/mtr0log.ic \
- include/mtr0mtr.h include/mtr0mtr.ic \
- include/mtr0types.h \
- include/mysql_addons.h \
- include/os0file.h \
- include/os0proc.h include/os0proc.ic \
- include/os0sync.h include/os0sync.ic \
- include/os0thread.h include/os0thread.ic \
- include/page0cur.h include/page0cur.ic \
- include/page0page.h include/page0page.ic \
- include/page0zip.h include/page0zip.ic \
- include/page0types.h include/pars0grm.h \
- include/pars0opt.h include/pars0opt.ic \
- include/pars0pars.h include/pars0pars.ic \
- include/pars0sym.h include/pars0sym.ic \
- include/pars0types.h include/que0que.h \
- include/que0que.ic include/que0types.h \
- include/read0read.h include/read0read.ic \
- include/read0types.h include/rem0cmp.h \
- include/rem0cmp.ic include/rem0rec.h \
- include/rem0rec.ic include/rem0types.h \
- include/row0ext.h include/row0ext.ic \
- include/row0ins.h include/row0ins.ic \
- include/row0merge.h \
- include/row0mysql.h include/row0mysql.ic \
- include/row0purge.h include/row0purge.ic \
- include/row0row.h include/row0row.ic \
- include/row0sel.h include/row0sel.ic \
- include/row0types.h include/row0uins.h \
- include/row0uins.ic include/row0umod.h \
- include/row0umod.ic include/row0undo.h \
- include/row0undo.ic include/row0upd.h \
- include/row0upd.ic include/row0vers.h \
- include/row0vers.ic include/srv0que.h \
- include/srv0srv.h include/srv0srv.ic \
- include/srv0start.h include/sync0arr.h \
- include/sync0arr.ic include/sync0rw.h \
- include/sync0rw.ic include/sync0sync.h \
- include/sync0sync.ic include/sync0types.h \
- include/thr0loc.h include/thr0loc.ic \
- include/trx0i_s.h \
- include/trx0purge.h include/trx0purge.ic \
- include/trx0rec.h include/trx0rec.ic \
- include/trx0roll.h include/trx0roll.ic \
- include/trx0rseg.h include/trx0rseg.ic \
- include/trx0sys.h include/trx0sys.ic \
- include/trx0trx.h include/trx0trx.ic \
- include/trx0types.h include/trx0undo.h \
- include/trx0undo.ic include/trx0xa.h \
- include/univ.i include/usr0sess.h \
- include/usr0sess.ic include/usr0types.h \
- include/ut0byte.h include/ut0byte.ic \
- include/ut0dbg.h include/ut0lst.h \
- include/ut0mem.h include/ut0mem.ic \
- include/ut0rnd.h include/ut0rnd.ic \
- include/ut0sort.h include/ut0ut.h \
- include/ut0ut.ic include/ut0vec.h \
- include/ut0vec.ic include/ut0list.h \
- include/ut0list.ic include/ut0wqueue.h \
- include/ha_prototypes.h handler/ha_innodb.h \
- include/handler0alter.h \
- handler/i_s.h include/ut0auxconf.h
+noinst_HEADERS= \
+ handler/ha_innodb.h \
+ handler/handler0vars.h \
+ handler/i_s.h \
+ include/btr0btr.h \
+ include/btr0btr.ic \
+ include/btr0cur.h \
+ include/btr0cur.ic \
+ include/btr0pcur.h \
+ include/btr0pcur.ic \
+ include/btr0sea.h \
+ include/btr0sea.ic \
+ include/btr0types.h \
+ include/buf0buddy.h \
+ include/buf0buddy.ic \
+ include/buf0buf.h \
+ include/buf0buf.ic \
+ include/buf0flu.h \
+ include/buf0flu.ic \
+ include/buf0lru.h \
+ include/buf0lru.ic \
+ include/buf0rea.h \
+ include/buf0types.h \
+ include/data0data.h \
+ include/data0data.ic \
+ include/data0type.h \
+ include/data0type.ic \
+ include/data0types.h \
+ include/db0err.h \
+ include/dict0boot.h \
+ include/dict0boot.ic \
+ include/dict0crea.h \
+ include/dict0crea.ic \
+ include/dict0dict.h \
+ include/dict0dict.ic \
+ include/dict0load.h \
+ include/dict0load.ic \
+ include/dict0mem.h \
+ include/dict0mem.ic \
+ include/dict0types.h \
+ include/dyn0dyn.h \
+ include/dyn0dyn.ic \
+ include/eval0eval.h \
+ include/eval0eval.ic \
+ include/eval0proc.h \
+ include/eval0proc.ic \
+ include/fil0fil.h \
+ include/fsp0fsp.h \
+ include/fsp0fsp.ic \
+ include/fut0fut.h \
+ include/fut0fut.ic \
+ include/fut0lst.h \
+ include/fut0lst.ic \
+ include/ha0ha.h \
+ include/ha0ha.ic \
+ include/ha0storage.h \
+ include/ha0storage.ic \
+ include/ha_prototypes.h \
+ include/handler0alter.h \
+ include/hash0hash.h \
+ include/hash0hash.ic \
+ include/ibuf0ibuf.h \
+ include/ibuf0ibuf.ic \
+ include/ibuf0types.h \
+ include/lock0iter.h \
+ include/lock0lock.h \
+ include/lock0lock.ic \
+ include/lock0priv.h \
+ include/lock0priv.ic \
+ include/lock0types.h \
+ include/log0log.h \
+ include/log0log.ic \
+ include/log0recv.h \
+ include/log0recv.ic \
+ include/mach0data.h \
+ include/mach0data.ic \
+ include/mem0dbg.h \
+ include/mem0dbg.ic \
+ include/mem0mem.h \
+ include/mem0mem.ic \
+ include/mem0pool.h \
+ include/mem0pool.ic \
+ include/mtr0log.h \
+ include/mtr0log.ic \
+ include/mtr0mtr.h \
+ include/mtr0mtr.ic \
+ include/mtr0types.h \
+ include/mysql_addons.h \
+ include/os0file.h \
+ include/os0proc.h \
+ include/os0proc.ic \
+ include/os0sync.h \
+ include/os0sync.ic \
+ include/os0thread.h \
+ include/os0thread.ic \
+ include/page0cur.h \
+ include/page0cur.ic \
+ include/page0page.h \
+ include/page0page.ic \
+ include/page0types.h \
+ include/page0zip.h \
+ include/page0zip.ic \
+ include/pars0grm.h \
+ include/pars0opt.h \
+ include/pars0opt.ic \
+ include/pars0pars.h \
+ include/pars0pars.ic \
+ include/pars0sym.h \
+ include/pars0sym.ic \
+ include/pars0types.h \
+ include/que0que.h \
+ include/que0que.ic \
+ include/que0types.h \
+ include/read0read.h \
+ include/read0read.ic \
+ include/read0types.h \
+ include/rem0cmp.h \
+ include/rem0cmp.ic \
+ include/rem0rec.h \
+ include/rem0rec.ic \
+ include/rem0types.h \
+ include/row0ext.h \
+ include/row0ext.ic \
+ include/row0ins.h \
+ include/row0ins.ic \
+ include/row0merge.h \
+ include/row0mysql.h \
+ include/row0mysql.ic \
+ include/row0purge.h \
+ include/row0purge.ic \
+ include/row0row.h \
+ include/row0row.ic \
+ include/row0sel.h \
+ include/row0sel.ic \
+ include/row0types.h \
+ include/row0uins.h \
+ include/row0uins.ic \
+ include/row0umod.h \
+ include/row0umod.ic \
+ include/row0undo.h \
+ include/row0undo.ic \
+ include/row0upd.h \
+ include/row0upd.ic \
+ include/row0vers.h \
+ include/row0vers.ic \
+ include/srv0que.h \
+ include/srv0srv.h \
+ include/srv0srv.ic \
+ include/srv0start.h \
+ include/sync0arr.h \
+ include/sync0arr.ic \
+ include/sync0rw.h \
+ include/sync0rw.ic \
+ include/sync0sync.h \
+ include/sync0sync.ic \
+ include/sync0types.h \
+ include/thr0loc.h \
+ include/thr0loc.ic \
+ include/trx0i_s.h \
+ include/trx0purge.h \
+ include/trx0purge.ic \
+ include/trx0rec.h \
+ include/trx0rec.ic \
+ include/trx0roll.h \
+ include/trx0roll.ic \
+ include/trx0rseg.h \
+ include/trx0rseg.ic \
+ include/trx0sys.h \
+ include/trx0sys.ic \
+ include/trx0trx.h \
+ include/trx0trx.ic \
+ include/trx0types.h \
+ include/trx0undo.h \
+ include/trx0undo.ic \
+ include/trx0xa.h \
+ include/univ.i \
+ include/usr0sess.h \
+ include/usr0sess.ic \
+ include/usr0types.h \
+ include/ut0auxconf.h \
+ include/ut0byte.h \
+ include/ut0byte.ic \
+ include/ut0dbg.h \
+ include/ut0list.h \
+ include/ut0list.ic \
+ include/ut0lst.h \
+ include/ut0mem.h \
+ include/ut0mem.ic \
+ include/ut0rnd.h \
+ include/ut0rnd.ic \
+ include/ut0sort.h \
+ include/ut0ut.h \
+ include/ut0ut.ic \
+ include/ut0vec.h \
+ include/ut0vec.ic \
+ include/ut0wqueue.h \
+ mem/mem0dbg.c
EXTRA_LIBRARIES= libinnobase.a
noinst_LIBRARIES= @plugin_innodb_plugin_static_target@
-libinnobase_a_SOURCES= btr/btr0btr.c btr/btr0cur.c btr/btr0pcur.c \
- btr/btr0sea.c buf/buf0buddy.c \
- buf/buf0buf.c buf/buf0flu.c \
- buf/buf0lru.c buf/buf0rea.c data/data0data.c \
- data/data0type.c dict/dict0boot.c \
- dict/dict0crea.c dict/dict0dict.c \
- dict/dict0load.c dict/dict0mem.c dyn/dyn0dyn.c \
- eval/eval0eval.c eval/eval0proc.c \
- fil/fil0fil.c fsp/fsp0fsp.c fut/fut0fut.c \
- fut/fut0lst.c ha/ha0ha.c \
- ha/ha0storage.c \
- ha/hash0hash.c \
- ibuf/ibuf0ibuf.c lock/lock0iter.c \
- lock/lock0lock.c \
- log/log0log.c log/log0recv.c mach/mach0data.c \
- mem/mem0mem.c mem/mem0pool.c mtr/mtr0log.c \
- mtr/mtr0mtr.c os/os0file.c os/os0proc.c \
- os/os0sync.c os/os0thread.c page/page0cur.c \
- page/page0page.c page/page0zip.c \
- pars/lexyy.c pars/pars0grm.c \
- pars/pars0opt.c pars/pars0pars.c \
- pars/pars0sym.c que/que0que.c read/read0read.c \
- rem/rem0cmp.c rem/rem0rec.c row/row0ext.c \
- row/row0ins.c row/row0merge.c \
- row/row0mysql.c row/row0purge.c row/row0row.c \
- row/row0sel.c row/row0uins.c row/row0umod.c \
- row/row0undo.c row/row0upd.c row/row0vers.c \
- srv/srv0que.c srv/srv0srv.c srv/srv0start.c \
- sync/sync0arr.c sync/sync0rw.c \
- sync/sync0sync.c thr/thr0loc.c \
- trx/trx0i_s.c \
- trx/trx0purge.c \
- trx/trx0rec.c trx/trx0roll.c trx/trx0rseg.c \
- trx/trx0sys.c trx/trx0trx.c trx/trx0undo.c \
- usr/usr0sess.c ut/ut0byte.c ut/ut0dbg.c \
- ut/ut0list.c ut/ut0mem.c ut/ut0rnd.c \
- ut/ut0ut.c ut/ut0vec.c ut/ut0wqueue.c \
- handler/ha_innodb.cc handler/handler0alter.cc \
- handler/i_s.cc \
- handler/mysql_addons.cc
+libinnobase_a_SOURCES= \
+ btr/btr0btr.c \
+ btr/btr0cur.c \
+ btr/btr0pcur.c \
+ btr/btr0sea.c \
+ buf/buf0buddy.c \
+ buf/buf0buf.c \
+ buf/buf0flu.c \
+ buf/buf0lru.c \
+ buf/buf0rea.c \
+ data/data0data.c \
+ data/data0type.c \
+ dict/dict0boot.c \
+ dict/dict0crea.c \
+ dict/dict0dict.c \
+ dict/dict0load.c \
+ dict/dict0mem.c \
+ dyn/dyn0dyn.c \
+ eval/eval0eval.c \
+ eval/eval0proc.c \
+ fil/fil0fil.c \
+ fsp/fsp0fsp.c \
+ fut/fut0fut.c \
+ fut/fut0lst.c \
+ ha/ha0ha.c \
+ ha/ha0storage.c \
+ ha/hash0hash.c \
+ handler/ha_innodb.cc \
+ handler/handler0alter.cc \
+ handler/i_s.cc \
+ handler/mysql_addons.cc \
+ ibuf/ibuf0ibuf.c \
+ lock/lock0iter.c \
+ lock/lock0lock.c \
+ log/log0log.c \
+ log/log0recv.c \
+ mach/mach0data.c \
+ mem/mem0mem.c \
+ mem/mem0pool.c \
+ mtr/mtr0log.c \
+ mtr/mtr0mtr.c \
+ os/os0file.c \
+ os/os0proc.c \
+ os/os0sync.c \
+ os/os0thread.c \
+ page/page0cur.c \
+ page/page0page.c \
+ page/page0zip.c \
+ pars/lexyy.c \
+ pars/pars0grm.c \
+ pars/pars0opt.c \
+ pars/pars0pars.c \
+ pars/pars0sym.c \
+ que/que0que.c \
+ read/read0read.c \
+ rem/rem0cmp.c \
+ rem/rem0rec.c \
+ row/row0ext.c \
+ row/row0ins.c \
+ row/row0merge.c \
+ row/row0mysql.c \
+ row/row0purge.c \
+ row/row0row.c \
+ row/row0sel.c \
+ row/row0uins.c \
+ row/row0umod.c \
+ row/row0undo.c \
+ row/row0upd.c \
+ row/row0vers.c \
+ srv/srv0que.c \
+ srv/srv0srv.c \
+ srv/srv0start.c \
+ sync/sync0arr.c \
+ sync/sync0rw.c \
+ sync/sync0sync.c \
+ thr/thr0loc.c \
+ trx/trx0i_s.c \
+ trx/trx0purge.c \
+ trx/trx0rec.c \
+ trx/trx0roll.c \
+ trx/trx0rseg.c \
+ trx/trx0sys.c \
+ trx/trx0trx.c \
+ trx/trx0undo.c \
+ usr/usr0sess.c \
+ ut/ut0byte.c \
+ ut/ut0dbg.c \
+ ut/ut0list.c \
+ ut/ut0mem.c \
+ ut/ut0rnd.c \
+ ut/ut0ut.c \
+ ut/ut0vec.c \
+ ut/ut0wqueue.c
libinnobase_a_CXXFLAGS= $(AM_CFLAGS)
libinnobase_a_CFLAGS= $(AM_CFLAGS)
diff --git a/storage/innodb_plugin/btr/btr0cur.c b/storage/innodb_plugin/btr/btr0cur.c
index d522b3445b6..46dfb5d1a46 100644
--- a/storage/innodb_plugin/btr/btr0cur.c
+++ b/storage/innodb_plugin/btr/btr0cur.c
@@ -49,6 +49,7 @@ Created 10/16/1994 Heikki Tuuri
#include "row0upd.h"
#ifndef UNIV_HOTBACKUP
+#include "mtr0log.h"
#include "page0page.h"
#include "page0zip.h"
#include "rem0rec.h"
diff --git a/storage/innodb_plugin/buf/buf0buf.c b/storage/innodb_plugin/buf/buf0buf.c
index af7c16f1bf5..0008fcb1271 100644
--- a/storage/innodb_plugin/buf/buf0buf.c
+++ b/storage/innodb_plugin/buf/buf0buf.c
@@ -1672,26 +1672,28 @@ lookup:
if (UNIV_UNLIKELY(!bpage->zip.data)) {
/* There is no compressed page. */
+err_exit:
buf_pool_mutex_exit();
return(NULL);
}
- block_mutex = buf_page_get_mutex(bpage);
- mutex_enter(block_mutex);
-
switch (buf_page_get_state(bpage)) {
case BUF_BLOCK_NOT_USED:
case BUF_BLOCK_READY_FOR_USE:
case BUF_BLOCK_MEMORY:
case BUF_BLOCK_REMOVE_HASH:
case BUF_BLOCK_ZIP_FREE:
- ut_error;
break;
case BUF_BLOCK_ZIP_PAGE:
case BUF_BLOCK_ZIP_DIRTY:
+ block_mutex = &buf_pool_zip_mutex;
+ mutex_enter(block_mutex);
bpage->buf_fix_count++;
- break;
+ goto got_block;
case BUF_BLOCK_FILE_PAGE:
+ block_mutex = &((buf_block_t*) bpage)->mutex;
+ mutex_enter(block_mutex);
+
/* Discard the uncompressed page frame if possible. */
if (buf_LRU_free_block(bpage, FALSE, NULL)
== BUF_LRU_FREED) {
@@ -1702,9 +1704,13 @@ lookup:
buf_block_buf_fix_inc((buf_block_t*) bpage,
__FILE__, __LINE__);
- break;
+ goto got_block;
}
+ ut_error;
+ goto err_exit;
+
+got_block:
must_read = buf_page_get_io_fix(bpage) == BUF_IO_READ;
buf_pool_mutex_exit();
@@ -2006,6 +2012,7 @@ buf_page_get_gen(
ut_ad((mode == BUF_GET) || (mode == BUF_GET_IF_IN_POOL)
|| (mode == BUF_GET_NO_LATCH));
ut_ad(zip_size == fil_space_get_zip_size(space));
+ ut_ad(ut_is_2pow(zip_size));
#ifndef UNIV_LOG_DEBUG
ut_ad(!ibuf_inside() || ibuf_page(space, zip_size, offset, NULL));
#endif
@@ -2079,12 +2086,15 @@ loop2:
case BUF_BLOCK_ZIP_PAGE:
case BUF_BLOCK_ZIP_DIRTY:
bpage = &block->page;
+ /* Protect bpage->buf_fix_count. */
+ mutex_enter(&buf_pool_zip_mutex);
if (bpage->buf_fix_count
|| buf_page_get_io_fix(bpage) != BUF_IO_NONE) {
/* This condition often occurs when the buffer
is not buffer-fixed, but I/O-fixed by
buf_page_init_for_read(). */
+ mutex_exit(&buf_pool_zip_mutex);
wait_until_unfixed:
/* The block is buffer-fixed or I/O-fixed.
Try again later. */
@@ -2096,6 +2106,7 @@ wait_until_unfixed:
/* Allocate an uncompressed page. */
buf_pool_mutex_exit();
+ mutex_exit(&buf_pool_zip_mutex);
block = buf_LRU_get_free_block(0);
ut_a(block);
@@ -2182,10 +2193,10 @@ wait_until_unfixed:
block->page.buf_fix_count = 1;
buf_block_set_io_fix(block, BUF_IO_READ);
- buf_pool->n_pend_unzip++;
rw_lock_x_lock(&block->lock);
mutex_exit(&block->mutex);
mutex_exit(&buf_pool_zip_mutex);
+ buf_pool->n_pend_unzip++;
buf_buddy_free(bpage, sizeof *bpage);
@@ -2203,10 +2214,10 @@ wait_until_unfixed:
/* Unfix and unlatch the block. */
buf_pool_mutex_enter();
mutex_enter(&block->mutex);
- buf_pool->n_pend_unzip--;
block->page.buf_fix_count--;
buf_block_set_io_fix(block, BUF_IO_NONE);
mutex_exit(&block->mutex);
+ buf_pool->n_pend_unzip--;
rw_lock_x_unlock(&block->lock);
if (UNIV_UNLIKELY(!success)) {
diff --git a/storage/innodb_plugin/buf/buf0flu.c b/storage/innodb_plugin/buf/buf0flu.c
index c8bf05bde51..74dd0c07ca6 100644
--- a/storage/innodb_plugin/buf/buf0flu.c
+++ b/storage/innodb_plugin/buf/buf0flu.c
@@ -44,6 +44,39 @@ Created 11/11/1995 Heikki Tuuri
#include "os0file.h"
#include "trx0sys.h"
+/**********************************************************************
+These statistics are generated for heuristics used in estimating the
+rate at which we should flush the dirty blocks to avoid bursty IO
+activity. Note that the rate of flushing not only depends on how many
+dirty pages we have in the buffer pool but it is also a fucntion of
+how much redo the workload is generating and at what rate. */
+/* @{ */
+
+/** Number of intervals for which we keep the history of these stats.
+Each interval is 1 second, defined by the rate at which
+srv_error_monitor_thread() calls buf_flush_stat_update(). */
+#define BUF_FLUSH_STAT_N_INTERVAL 20
+
+/** Sampled values buf_flush_stat_cur.
+Not protected by any mutex. Updated by buf_flush_stat_update(). */
+static buf_flush_stat_t buf_flush_stat_arr[BUF_FLUSH_STAT_N_INTERVAL];
+
+/** Cursor to buf_flush_stat_arr[]. Updated in a round-robin fashion. */
+static ulint buf_flush_stat_arr_ind;
+
+/** Values at start of the current interval. Reset by
+buf_flush_stat_update(). */
+static buf_flush_stat_t buf_flush_stat_cur;
+
+/** Running sum of past values of buf_flush_stat_cur.
+Updated by buf_flush_stat_update(). Not protected by any mutex. */
+static buf_flush_stat_t buf_flush_stat_sum;
+
+/** Number of pages flushed through non flush_list flushes. */
+static ulint buf_lru_flush_page_count = 0;
+
+/* @} */
+
#if defined UNIV_DEBUG || defined UNIV_BUF_DEBUG
/******************************************************************//**
Validates the flush list.
@@ -1102,6 +1135,13 @@ flush_next:
srv_buf_pool_flushed += page_count;
+ /* We keep track of all flushes happening as part of LRU
+ flush. When estimating the desired rate at which flush_list
+ should be flushed we factor in this value. */
+ if (flush_type == BUF_FLUSH_LRU) {
+ buf_lru_flush_page_count += page_count;
+ }
+
return(page_count);
}
@@ -1197,6 +1237,117 @@ buf_flush_free_margin(void)
}
}
+/*********************************************************************
+Update the historical stats that we are collecting for flush rate
+heuristics at the end of each interval.
+Flush rate heuristic depends on (a) rate of redo log generation and
+(b) the rate at which LRU flush is happening. */
+UNIV_INTERN
+void
+buf_flush_stat_update(void)
+/*=======================*/
+{
+ buf_flush_stat_t* item;
+ ib_uint64_t lsn_diff;
+ ib_uint64_t lsn;
+ ulint n_flushed;
+
+ lsn = log_get_lsn();
+ if (buf_flush_stat_cur.redo == 0) {
+ /* First time around. Just update the current LSN
+ and return. */
+ buf_flush_stat_cur.redo = lsn;
+ return;
+ }
+
+ item = &buf_flush_stat_arr[buf_flush_stat_arr_ind];
+
+ /* values for this interval */
+ lsn_diff = lsn - buf_flush_stat_cur.redo;
+ n_flushed = buf_lru_flush_page_count
+ - buf_flush_stat_cur.n_flushed;
+
+ /* add the current value and subtract the obsolete entry. */
+ buf_flush_stat_sum.redo += lsn_diff - item->redo;
+ buf_flush_stat_sum.n_flushed += n_flushed - item->n_flushed;
+
+ /* put current entry in the array. */
+ item->redo = lsn_diff;
+ item->n_flushed = n_flushed;
+
+ /* update the index */
+ buf_flush_stat_arr_ind++;
+ buf_flush_stat_arr_ind %= BUF_FLUSH_STAT_N_INTERVAL;
+
+ /* reset the current entry. */
+ buf_flush_stat_cur.redo = lsn;
+ buf_flush_stat_cur.n_flushed = buf_lru_flush_page_count;
+}
+
+/*********************************************************************
+Determines the fraction of dirty pages that need to be flushed based
+on the speed at which we generate redo log. Note that if redo log
+is generated at a significant rate without corresponding increase
+in the number of dirty pages (for example, an in-memory workload)
+it can cause IO bursts of flushing. This function implements heuristics
+to avoid this burstiness.
+@return number of dirty pages to be flushed / second */
+UNIV_INTERN
+ulint
+buf_flush_get_desired_flush_rate(void)
+/*==================================*/
+{
+ ulint redo_avg;
+ ulint lru_flush_avg;
+ ulint n_dirty;
+ ulint n_flush_req;
+ lint rate;
+ ib_uint64_t lsn = log_get_lsn();
+ ulint log_capacity = log_get_capacity();
+
+ /* log_capacity should never be zero after the initialization
+ of log subsystem. */
+ ut_ad(log_capacity != 0);
+
+ /* Get total number of dirty pages. It is OK to access
+ flush_list without holding any mtex as we are using this
+ only for heuristics. */
+ n_dirty = UT_LIST_GET_LEN(buf_pool->flush_list);
+
+ /* An overflow can happen if we generate more than 2^32 bytes
+ of redo in this interval i.e.: 4G of redo in 1 second. We can
+ safely consider this as infinity because if we ever come close
+ to 4G we'll start a synchronous flush of dirty pages. */
+ /* redo_avg below is average at which redo is generated in
+ past BUF_FLUSH_STAT_N_INTERVAL + redo generated in the current
+ interval. */
+ redo_avg = (ulint) (buf_flush_stat_sum.redo
+ / BUF_FLUSH_STAT_N_INTERVAL
+ + (lsn - buf_flush_stat_cur.redo));
+
+ /* An overflow can happen possibly if we flush more than 2^32
+ pages in BUF_FLUSH_STAT_N_INTERVAL. This is a very very
+ unlikely scenario. Even when this happens it means that our
+ flush rate will be off the mark. It won't affect correctness
+ of any subsystem. */
+ /* lru_flush_avg below is rate at which pages are flushed as
+ part of LRU flush in past BUF_FLUSH_STAT_N_INTERVAL + the
+ number of pages flushed in the current interval. */
+ lru_flush_avg = buf_flush_stat_sum.n_flushed
+ / BUF_FLUSH_STAT_N_INTERVAL
+ + (buf_lru_flush_page_count
+ - buf_flush_stat_cur.n_flushed);
+
+ n_flush_req = (n_dirty * redo_avg) / log_capacity;
+
+ /* The number of pages that we want to flush from the flush
+ list is the difference between the required rate and the
+ number of pages that we are historically flushing from the
+ LRU list */
+ rate = n_flush_req - lru_flush_avg;
+ return(rate > 0 ? (ulint) rate : 0);
+}
+
#if defined UNIV_DEBUG || defined UNIV_BUF_DEBUG
/******************************************************************//**
Validates the flush list.
diff --git a/storage/innodb_plugin/buf/buf0lru.c b/storage/innodb_plugin/buf/buf0lru.c
index 00094092375..be53a5f5d9d 100644
--- a/storage/innodb_plugin/buf/buf0lru.c
+++ b/storage/innodb_plugin/buf/buf0lru.c
@@ -456,11 +456,12 @@ buf_LRU_get_recent_limit(void)
bpage = UT_LIST_GET_FIRST(buf_pool->LRU);
- limit = buf_page_get_LRU_position(bpage) - len / BUF_LRU_INITIAL_RATIO;
+ limit = buf_page_get_LRU_position(bpage);
+ len /= BUF_LRU_INITIAL_RATIO;
buf_pool_mutex_exit();
- return(limit);
+ return(limit > len ? (limit - len) : 0);
}
/********************************************************************//**
diff --git a/storage/innodb_plugin/buf/buf0rea.c b/storage/innodb_plugin/buf/buf0rea.c
index f21bbf2e63e..319d6b2a522 100644
--- a/storage/innodb_plugin/buf/buf0rea.c
+++ b/storage/innodb_plugin/buf/buf0rea.c
@@ -44,14 +44,11 @@ the accessed pages when deciding whether to read-ahead */
/** There must be at least this many pages in buf_pool in the area to start
a random read-ahead */
-#define BUF_READ_AHEAD_RANDOM_THRESHOLD (5 + buf_read_ahead_random_area / 8)
+#define BUF_READ_AHEAD_RANDOM_THRESHOLD (1 + BUF_READ_AHEAD_RANDOM_AREA / 2)
/** The linear read-ahead area size */
#define BUF_READ_AHEAD_LINEAR_AREA BUF_READ_AHEAD_AREA
-/** The linear read-ahead threshold */
-#define LINEAR_AREA_THRESHOLD_COEF 5 / 8
-
/** If there are buf_pool->curr_size per the number below pending reads, then
read-ahead is not done: this is to prevent flooding the buffer pool with
i/o-fixed buffer blocks */
@@ -199,6 +196,9 @@ buf_read_ahead_random(
ulint i;
ulint buf_read_ahead_random_area;
+ /* We have currently disabled random readahead */
+ return(0);
+
if (srv_startup_is_before_trx_rollback_phase) {
/* No read-ahead to avoid thread deadlocks */
return(0);
@@ -423,6 +423,7 @@ buf_read_ahead_linear(
ulint i;
const ulint buf_read_ahead_linear_area
= BUF_READ_AHEAD_LINEAR_AREA;
+ ulint threshold;
if (UNIV_UNLIKELY(srv_startup_is_before_trx_rollback_phase)) {
/* No read-ahead to avoid thread deadlocks */
@@ -482,6 +483,11 @@ buf_read_ahead_linear(
asc_or_desc = -1;
}
+ /* How many out of order accessed pages can we ignore
+ when working out the access pattern for linear readahead */
+ threshold = ut_min((64 - srv_read_ahead_threshold),
+ BUF_READ_AHEAD_AREA);
+
fail_count = 0;
for (i = low; i < high; i++) {
@@ -491,25 +497,25 @@ buf_read_ahead_linear(
/* Not accessed */
fail_count++;
- } else if (pred_bpage
- && (ut_ulint_cmp(
+ } else if (pred_bpage) {
+ int res = (ut_ulint_cmp(
buf_page_get_LRU_position(bpage),
- buf_page_get_LRU_position(pred_bpage))
- != asc_or_desc)) {
+ buf_page_get_LRU_position(pred_bpage)));
/* Accesses not in the right order */
-
- fail_count++;
- pred_bpage = bpage;
+ if (res != 0 && res != asc_or_desc) {
+ fail_count++;
+ }
}
- }
-
- if (fail_count > buf_read_ahead_linear_area
- * LINEAR_AREA_THRESHOLD_COEF) {
- /* Too many failures: return */
- buf_pool_mutex_exit();
+ if (fail_count > threshold) {
+ /* Too many failures: return */
+ buf_pool_mutex_exit();
+ return(0);
+ }
- return(0);
+ if (bpage && buf_page_is_accessed(bpage)) {
+ pred_bpage = bpage;
+ }
}
/* If we got this far, we know that enough pages in the area have
@@ -746,6 +752,14 @@ buf_read_recv_pages(
ulint i;
zip_size = fil_space_get_zip_size(space);
+
+ if (UNIV_UNLIKELY(zip_size == ULINT_UNDEFINED)) {
+ /* It is a single table tablespace and the .ibd file is
+ missing: do nothing */
+
+ return;
+ }
+
tablespace_version = fil_space_get_version(space);
for (i = 0; i < n_stored; i++) {
diff --git a/storage/innodb_plugin/data/data0type.c b/storage/innodb_plugin/data/data0type.c
index 3caa082a1a4..8429775e7d8 100644
--- a/storage/innodb_plugin/data/data0type.c
+++ b/storage/innodb_plugin/data/data0type.c
@@ -146,7 +146,8 @@ dtype_is_non_binary_string_type(
/*********************************************************************//**
Forms a precise type from the < 4.1.2 format precise type plus the
-charset-collation code. */
+charset-collation code.
+@return precise type, including the charset-collation code */
UNIV_INTERN
ulint
dtype_form_prtype(
diff --git a/storage/innodb_plugin/dict/dict0dict.c b/storage/innodb_plugin/dict/dict0dict.c
index 1d8ddabd26f..d1f0e0ffc19 100644
--- a/storage/innodb_plugin/dict/dict0dict.c
+++ b/storage/innodb_plugin/dict/dict0dict.c
@@ -1693,6 +1693,11 @@ dict_index_find_cols(
}
/* It is an error not to find a matching column. */
+ fputs("InnoDB: Error: no matching column for ", stderr);
+ ut_print_name(stderr, NULL, FALSE, field->name);
+ fputs(" in ", stderr);
+ dict_index_name_print(stderr, NULL, index);
+ fputs("!\n", stderr);
ut_error;
found:
@@ -2974,7 +2979,7 @@ scan_more:
} else if (quote) {
/* Within quotes: do not look for
starting quotes or comments. */
- } else if (*sptr == '"' || *sptr == '`') {
+ } else if (*sptr == '"' || *sptr == '`' || *sptr == '\'') {
/* Starting quote: remember the quote character. */
quote = *sptr;
} else if (*sptr == '#'
diff --git a/storage/innodb_plugin/dict/dict0mem.c b/storage/innodb_plugin/dict/dict0mem.c
index 1f7dd38e6f5..6458cbab92d 100644
--- a/storage/innodb_plugin/dict/dict0mem.c
+++ b/storage/innodb_plugin/dict/dict0mem.c
@@ -103,7 +103,9 @@ dict_mem_table_free(
ut_ad(table->magic_n == DICT_TABLE_MAGIC_N);
ut_d(table->cached = FALSE);
+#ifndef UNIV_HOTBACKUP
mutex_free(&(table->autoinc_mutex));
+#endif /* UNIV_HOTBACKUP */
mem_heap_free(table->heap);
}
diff --git a/storage/innodb_plugin/fil/fil0fil.c b/storage/innodb_plugin/fil/fil0fil.c
index b0799ee54e2..96e60b0128f 100644
--- a/storage/innodb_plugin/fil/fil0fil.c
+++ b/storage/innodb_plugin/fil/fil0fil.c
@@ -2954,7 +2954,7 @@ fil_open_single_table_tablespace(
" a temporary table #sql...,\n"
"InnoDB: and MySQL removed the .ibd file for this.\n"
"InnoDB: Please refer to\n"
- "InnoDB: " REFMAN "innodb-troubleshooting.html\n"
+ "InnoDB: " REFMAN "innodb-troubleshooting-datadict.html\n"
"InnoDB: for how to resolve the issue.\n", stderr);
mem_free(filepath);
@@ -2996,7 +2996,7 @@ fil_open_single_table_tablespace(
"InnoDB: commands DISCARD TABLESPACE and"
" IMPORT TABLESPACE?\n"
"InnoDB: Please refer to\n"
- "InnoDB: " REFMAN "innodb-troubleshooting.html\n"
+ "InnoDB: " REFMAN "innodb-troubleshooting-datadict.html\n"
"InnoDB: for how to resolve the issue.\n",
(ulong) space_id, (ulong) space_flags,
(ulong) id, (ulong) flags);
@@ -3677,7 +3677,7 @@ fil_space_for_table_exists_in_mem(
}
error_exit:
fputs("InnoDB: Please refer to\n"
- "InnoDB: " REFMAN "innodb-troubleshooting.html\n"
+ "InnoDB: " REFMAN "innodb-troubleshooting-datadict.html\n"
"InnoDB: for how to resolve the issue.\n", stderr);
mem_free(path);
diff --git a/storage/innodb_plugin/fsp/fsp0fsp.c b/storage/innodb_plugin/fsp/fsp0fsp.c
index 27d16dd89ed..ce14723ba18 100644
--- a/storage/innodb_plugin/fsp/fsp0fsp.c
+++ b/storage/innodb_plugin/fsp/fsp0fsp.c
@@ -264,7 +264,8 @@ ulint
fseg_n_reserved_pages_low(
/*======================*/
fseg_inode_t* header, /*!< in: segment inode */
- ulint* used, /*!< out: number of pages used (<= reserved) */
+ ulint* used, /*!< out: number of pages used (not
+ more than reserved) */
mtr_t* mtr); /*!< in: mtr handle */
/********************************************************************//**
Marks a page used. The page must reside within the extents of the given
@@ -2337,7 +2338,8 @@ ulint
fseg_n_reserved_pages_low(
/*======================*/
fseg_inode_t* inode, /*!< in: segment inode */
- ulint* used, /*!< out: number of pages used (<= reserved) */
+ ulint* used, /*!< out: number of pages used (not
+ more than reserved) */
mtr_t* mtr) /*!< in: mtr handle */
{
ulint ret;
@@ -3564,45 +3566,6 @@ fseg_free_step_not_header(
return(FALSE);
}
-/*******************************************************************//**
-Frees a segment. The freeing is performed in several mini-transactions,
-so that there is no danger of bufferfixing too many buffer pages. */
-UNIV_INTERN
-void
-fseg_free(
-/*======*/
- ulint space, /*!< in: space id */
- ulint zip_size,/*!< in: compressed page size in bytes
- or 0 for uncompressed pages */
- ulint page_no,/*!< in: page number where the segment header is
- placed */
- ulint offset) /*!< in: byte offset of the segment header on that
- page */
-{
- mtr_t mtr;
- ibool finished;
- fseg_header_t* header;
- fil_addr_t addr;
-
- addr.page = page_no;
- addr.boffset = offset;
-
- for (;;) {
- mtr_start(&mtr);
-
- header = fut_get_ptr(space, zip_size, addr, RW_X_LATCH, &mtr);
-
- finished = fseg_free_step(header, &mtr);
-
- mtr_commit(&mtr);
-
- if (finished) {
-
- return;
- }
- }
-}
-
/**********************************************************************//**
Returns the first extent descriptor for a segment. We think of the extent
lists of the segment catenated in the order FSEG_FULL -> FSEG_NOT_FULL
@@ -3758,6 +3721,7 @@ fseg_validate_low(
return(TRUE);
}
+#ifdef UNIV_DEBUG
/*******************************************************************//**
Validates a segment.
@return TRUE if ok */
@@ -3785,6 +3749,7 @@ fseg_validate(
return(ret);
}
+#endif /* UNIV_DEBUG */
/*******************************************************************//**
Writes info of a segment. */
diff --git a/storage/innodb_plugin/ha/ha0ha.c b/storage/innodb_plugin/ha/ha0ha.c
index da860c619ae..cb5e541b55d 100644
--- a/storage/innodb_plugin/ha/ha0ha.c
+++ b/storage/innodb_plugin/ha/ha0ha.c
@@ -57,7 +57,7 @@ ha_create_func(
ulint i;
#endif /* !UNIV_HOTBACKUP */
- ut_ad(ut_is_2pow(n));
+ ut_ad(ut_is_2pow(n_mutexes));
table = hash_create(n);
#if defined UNIV_AHI_DEBUG || defined UNIV_DEBUG
@@ -250,28 +250,6 @@ ha_delete_hash_node(
HASH_DELETE_AND_COMPACT(ha_node_t, next, table, del_node);
}
-/*************************************************************//**
-Deletes an entry from a hash table. */
-UNIV_INTERN
-void
-ha_delete(
-/*======*/
- hash_table_t* table, /*!< in: hash table */
- ulint fold, /*!< in: folded value of data */
- void* data) /*!< in: data, must not be NULL and must exist
- in the hash table */
-{
- ha_node_t* node;
-
- ASSERT_HASH_MUTEX_OWN(table, fold);
-
- node = ha_search_with_data(table, fold, data);
-
- ut_a(node);
-
- ha_delete_hash_node(table, node);
-}
-
/*********************************************************//**
Looks for an element when we know the pointer to the data, and updates
the pointer to data, if found. */
diff --git a/storage/innodb_plugin/handler/ha_innodb.cc b/storage/innodb_plugin/handler/ha_innodb.cc
index 1f033b4141a..90999254f6b 100644
--- a/storage/innodb_plugin/handler/ha_innodb.cc
+++ b/storage/innodb_plugin/handler/ha_innodb.cc
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 2000, 2009, MySQL AB & Innobase Oy. All Rights Reserved.
-Copyright (c) 2008, Google Inc.
+Copyright (c) 2008, 2009 Google Inc.
Portions of this file contain modifications contributed and copyrighted by
Google, Inc. Those modifications are gratefully acknowledged and are described
@@ -22,6 +22,32 @@ this program; if not, write to the Free Software Foundation, Inc., 59 Temple
Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
+/***********************************************************************
+
+Copyright (c) 1995, 2009, Innobase Oy. All Rights Reserved.
+Copyright (c) 2009, Percona Inc.
+
+Portions of this file contain modifications contributed and copyrighted
+by Percona Inc.. Those modifications are
+gratefully acknowledged and are described briefly in the InnoDB
+documentation. The contributions by Percona Inc. are incorporated with
+their permission, and subject to the conditions contained in the file
+COPYING.Percona.
+
+This program is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; version 2 of the License.
+
+This program is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
+Public License for more details.
+
+You should have received a copy of the GNU General Public License along
+with this program; if not, write to the Free Software Foundation, Inc.,
+59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+***********************************************************************/
/* TODO list for the InnoDB handler in 5.0:
- Remove the flag trx->active_trans and look at trx->conc_state
@@ -41,6 +67,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
#include <mysys_err.h>
#include <mysql/plugin.h>
+/** @file ha_innodb.cc */
+
/* Include necessary InnoDB headers */
extern "C" {
#include "univ.i"
@@ -119,6 +147,8 @@ static long innobase_mirrored_log_groups, innobase_log_files_in_group,
innobase_force_recovery, innobase_open_files,
innobase_autoinc_lock_mode;
static ulong innobase_commit_concurrency = 0;
+static ulong innobase_read_io_threads;
+static ulong innobase_write_io_threads;
static long long innobase_buffer_pool_size, innobase_log_file_size;
@@ -193,8 +223,21 @@ static handler *innobase_create_handler(handlerton *hton,
TABLE_SHARE *table,
MEM_ROOT *mem_root);
+/** @brief Initialize the default value of innodb_commit_concurrency.
+
+Once InnoDB is running, the innodb_commit_concurrency must not change
+from zero to nonzero. (Bug #42101)
+
+The initial default value is 0, and without this extra initialization,
+SET GLOBAL innodb_commit_concurrency=DEFAULT would set the parameter
+to 0, even if it was initially set to nonzero at the command line
+or configuration file. */
+static
+void
+innobase_commit_concurrency_init_default(void);
+/*==========================================*/
+
/************************************************************//**
-@file handler/ha_innodb.cc
Validate the file format name and return its corresponding id.
@return valid file format id */
static
@@ -980,7 +1023,6 @@ innobase_get_charset(
}
#if defined (__WIN__) && defined (MYSQL_DYNAMIC_PLUGIN)
-extern MYSQL_PLUGIN_IMPORT MY_TMPDIR mysql_tmpdir_list;
/*******************************************************************//**
Map an OS error to an errno value. The OS error number is stored in
_doserrno and the mapped value is stored in errno) */
@@ -2124,6 +2166,8 @@ innobase_change_buffering_inited_ok:
srv_mem_pool_size = (ulint) innobase_additional_mem_pool_size;
srv_n_file_io_threads = (ulint) innobase_file_io_threads;
+ srv_n_read_io_threads = (ulint) innobase_read_io_threads;
+ srv_n_write_io_threads = (ulint) innobase_write_io_threads;
srv_force_recovery = (ulint) innobase_force_recovery;
@@ -2161,6 +2205,8 @@ innobase_change_buffering_inited_ok:
ut_a(0 == strcmp(my_charset_latin1.name, "latin1_swedish_ci"));
srv_latin1_ordering = my_charset_latin1.sort_order;
+ innobase_commit_concurrency_init_default();
+
/* Since we in this module access directly the fields of a trx
struct, and due to different headers and flags it might happen that
mutex_t has a different size in this module and in InnoDB
@@ -2415,7 +2461,12 @@ retry:
trx->mysql_log_file_name = mysql_bin_log_file_name();
trx->mysql_log_offset = (ib_int64_t) mysql_bin_log_file_pos();
+ /* Don't do write + flush right now. For group commit
+ to work we want to do the flush after releasing the
+ prepare_commit_mutex. */
+ trx->flush_log_later = TRUE;
innobase_commit_low(trx);
+ trx->flush_log_later = FALSE;
if (innobase_commit_concurrency > 0) {
pthread_mutex_lock(&commit_cond_m);
@@ -2429,6 +2480,8 @@ retry:
pthread_mutex_unlock(&prepare_commit_mutex);
}
+ /* Now do a write + flush of logs. */
+ trx_commit_complete_for_mysql(trx);
trx->active_trans = 0;
} else {
@@ -2930,8 +2983,7 @@ ha_innobase::innobase_initialize_autoinc()
dict_index_t* index;
ulonglong auto_inc;
const char* col_name;
- ulint error = DB_SUCCESS;
- dict_table_t* innodb_table = prebuilt->table;
+ ulint error;
col_name = table->found_next_number_field->field_name;
index = innobase_get_index(table->s->next_number_index);
@@ -2939,22 +2991,40 @@ ha_innobase::innobase_initialize_autoinc()
/* Execute SELECT MAX(col_name) FROM TABLE; */
error = row_search_max_autoinc(index, col_name, &auto_inc);
- if (error == DB_SUCCESS) {
+ switch (error) {
+ case DB_SUCCESS:
- /* At the this stage we dont' know the increment
+ /* At the this stage we don't know the increment
or the offset, so use default inrement of 1. */
++auto_inc;
+ break;
- dict_table_autoinc_initialize(innodb_table, auto_inc);
-
- } else {
+ case DB_RECORD_NOT_FOUND:
ut_print_timestamp(stderr);
- fprintf(stderr, " InnoDB: Error: (%lu) Couldn't read "
- "the MAX(%s) autoinc value from the "
- "index (%s).\n", error, col_name, index->name);
+ fprintf(stderr, " InnoDB: MySQL and InnoDB data "
+ "dictionaries are out of sync.\n"
+ "InnoDB: Unable to find the AUTOINC column %s in the "
+ "InnoDB table %s.\n"
+ "InnoDB: We set the next AUTOINC column value to the "
+ "maximum possible value,\n"
+ "InnoDB: in effect disabling the AUTOINC next value "
+ "generation.\n"
+ "InnoDB: You can either set the next AUTOINC value "
+ "explicitly using ALTER TABLE\n"
+ "InnoDB: or fix the data dictionary by recreating "
+ "the table.\n",
+ col_name, index->table->name);
+
+ auto_inc = 0xFFFFFFFFFFFFFFFFULL;
+ break;
+
+ default:
+ return(error);
}
- return(error);
+ dict_table_autoinc_initialize(prebuilt->table, auto_inc);
+
+ return(DB_SUCCESS);
}
/*****************************************************************//**
@@ -3172,7 +3242,6 @@ retry:
if (dict_table_autoinc_read(prebuilt->table) == 0) {
error = innobase_initialize_autoinc();
- /* Should always succeed! */
ut_a(error == DB_SUCCESS);
}
@@ -6190,7 +6259,7 @@ ha_innobase::create(
/* Our function row_get_mysql_key_number_for_index assumes
the primary key is always number 0, if it exists */
- DBUG_ASSERT(primary_key_no == -1 || primary_key_no == 0);
+ ut_a(primary_key_no == -1 || primary_key_no == 0);
/* Create the keys */
@@ -6923,7 +6992,7 @@ ha_innobase::info(
nor the CHECK TABLE time, nor the UPDATE or INSERT time. */
if (os_file_get_status(path,&stat_info)) {
- stats.create_time = stat_info.ctime;
+ stats.create_time = (ulong) stat_info.ctime;
}
}
@@ -8900,33 +8969,6 @@ innobase_xa_prepare(
DBUG_ASSERT(hton == innodb_hton_ptr);
- if (thd_sql_command(thd) != SQLCOM_XA_PREPARE &&
- (all || !thd_test_options(thd, OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN)))
- {
-
- /* For ibbackup to work the order of transactions in binlog
- and InnoDB must be the same. Consider the situation
-
- thread1> prepare; write to binlog; ...
- <context switch>
- thread2> prepare; write to binlog; commit
- thread1> ... commit
-
- To ensure this will not happen we're taking the mutex on
- prepare, and releasing it on commit.
-
- Note: only do it for normal commits, done via ha_commit_trans.
- If 2pc protocol is executed by external transaction
- coordinator, it will be just a regular MySQL client
- executing XA PREPARE and XA COMMIT commands.
- In this case we cannot know how many minutes or hours
- will be between XA PREPARE and XA COMMIT, and we don't want
- to block for undefined period of time.
- */
- pthread_mutex_lock(&prepare_commit_mutex);
- trx->active_trans = 2;
- }
-
/* we use support_xa value as it was seen at transaction start
time, not the current session variable value. Any possible changes
to the session variable take effect only in the next transaction */
@@ -8979,6 +9021,33 @@ innobase_xa_prepare(
srv_active_wake_master_thread();
+ if (thd_sql_command(thd) != SQLCOM_XA_PREPARE &&
+ (all || !thd_test_options(thd, OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN)))
+ {
+
+ /* For ibbackup to work the order of transactions in binlog
+ and InnoDB must be the same. Consider the situation
+
+ thread1> prepare; write to binlog; ...
+ <context switch>
+ thread2> prepare; write to binlog; commit
+ thread1> ... commit
+
+ To ensure this will not happen we're taking the mutex on
+ prepare, and releasing it on commit.
+
+ Note: only do it for normal commits, done via ha_commit_trans.
+ If 2pc protocol is executed by external transaction
+ coordinator, it will be just a regular MySQL client
+ executing XA PREPARE and XA COMMIT commands.
+ In this case we cannot know how many minutes or hours
+ will be between XA PREPARE and XA COMMIT, and we don't want
+ to block for undefined period of time.
+ */
+ pthread_mutex_lock(&prepare_commit_mutex);
+ trx->active_trans = 2;
+ }
+
return(error);
}
@@ -9110,6 +9179,97 @@ innobase_set_cursor_view(
}
+/***********************************************************************
+Check whether any of the given columns is being renamed in the table. */
+static
+bool
+column_is_being_renamed(
+/*====================*/
+ /* out: true if any of col_names is
+ being renamed in table */
+ TABLE* table, /* in: MySQL table */
+ uint n_cols, /* in: number of columns */
+ const char** col_names) /* in: names of the columns */
+{
+ uint j;
+ uint k;
+ Field* field;
+ const char* col_name;
+
+ for (j = 0; j < n_cols; j++) {
+ col_name = col_names[j];
+ for (k = 0; k < table->s->fields; k++) {
+ field = table->field[k];
+ if ((field->flags & FIELD_IS_RENAMED)
+ && innobase_strcasecmp(field->field_name,
+ col_name) == 0) {
+ return(true);
+ }
+ }
+ }
+
+ return(false);
+}
+
+/***********************************************************************
+Check whether a column in table "table" is being renamed and if this column
+is part of a foreign key, either part of another table, referencing this
+table or part of this table, referencing another table. */
+static
+bool
+foreign_key_column_is_being_renamed(
+/*================================*/
+ /* out: true if a column that
+ participates in a foreign key definition
+ is being renamed */
+ row_prebuilt_t* prebuilt, /* in: InnoDB prebuilt struct */
+ TABLE* table) /* in: MySQL table */
+{
+ dict_foreign_t* foreign;
+
+ /* check whether there are foreign keys at all */
+ if (UT_LIST_GET_LEN(prebuilt->table->foreign_list) == 0
+ && UT_LIST_GET_LEN(prebuilt->table->referenced_list) == 0) {
+ /* no foreign keys involved with prebuilt->table */
+
+ return(false);
+ }
+
+ row_mysql_lock_data_dictionary(prebuilt->trx);
+
+ /* Check whether any column in the foreign key constraints which refer
+ to this table is being renamed. */
+ for (foreign = UT_LIST_GET_FIRST(prebuilt->table->referenced_list);
+ foreign != NULL;
+ foreign = UT_LIST_GET_NEXT(referenced_list, foreign)) {
+
+ if (column_is_being_renamed(table, foreign->n_fields,
+ foreign->referenced_col_names)) {
+
+ row_mysql_unlock_data_dictionary(prebuilt->trx);
+ return(true);
+ }
+ }
+
+ /* Check whether any column in the foreign key constraints in the
+ table is being renamed. */
+ for (foreign = UT_LIST_GET_FIRST(prebuilt->table->foreign_list);
+ foreign != NULL;
+ foreign = UT_LIST_GET_NEXT(foreign_list, foreign)) {
+
+ if (column_is_being_renamed(table, foreign->n_fields,
+ foreign->foreign_col_names)) {
+
+ row_mysql_unlock_data_dictionary(prebuilt->trx);
+ return(true);
+ }
+ }
+
+ row_mysql_unlock_data_dictionary(prebuilt->trx);
+
+ return(false);
+}
+
UNIV_INTERN
bool
ha_innobase::check_if_incompatible_data(
@@ -9128,9 +9288,17 @@ ha_innobase::check_if_incompatible_data(
return(COMPATIBLE_DATA_NO);
}
+ /* Check if a column participating in a foreign key is being renamed.
+ There is no mechanism for updating InnoDB foreign key definitions. */
+ if (foreign_key_column_is_being_renamed(prebuilt, table)) {
+
+ return COMPATIBLE_DATA_NO;
+ }
+
/* Check that row format didn't change */
- if ((info->used_fields & HA_CREATE_USED_ROW_FORMAT) &&
- get_row_type() != info->row_type) {
+ if ((info->used_fields & HA_CREATE_USED_ROW_FORMAT)
+ && info->row_type != ROW_TYPE_DEFAULT
+ && info->row_type != get_row_type()) {
return(COMPATIBLE_DATA_NO);
}
@@ -9270,11 +9438,12 @@ innodb_file_format_name_validate(
if (format_id <= DICT_TF_FORMAT_MAX) {
- *(uint*) save = format_id;
+ *static_cast<const char**>(save) = file_format_input;
return(0);
}
}
+ *static_cast<const char**>(save) = NULL;
return(1);
}
@@ -9293,13 +9462,24 @@ innodb_file_format_name_update(
const void* save) /*!< in: immediate result
from check function */
{
+ const char* format_name;
+
ut_a(var_ptr != NULL);
ut_a(save != NULL);
- ut_a((*(const uint*) save) <= DICT_TF_FORMAT_MAX);
- srv_file_format = *(const uint*) save;
+ format_name = *static_cast<const char*const*>(save);
+
+ if (format_name) {
+ uint format_id;
+
+ format_id = innobase_file_format_name_lookup(format_name);
- *(const char**) var_ptr
+ if (format_id <= DICT_TF_FORMAT_MAX) {
+ srv_file_format = format_id;
+ }
+ }
+
+ *static_cast<const char**>(var_ptr)
= trx_sys_file_format_id_to_name(srv_file_format);
}
@@ -9340,14 +9520,7 @@ innodb_file_format_check_validate(
} else if (innobase_file_format_check_validate(
file_format_input)) {
- uint format_id;
-
- format_id = innobase_file_format_name_lookup(
- file_format_input);
-
- ut_a(format_id <= DICT_TF_FORMAT_MAX);
-
- *(uint*) save = format_id;
+ *static_cast<const char**>(save) = file_format_input;
return(0);
@@ -9361,6 +9534,7 @@ innodb_file_format_check_validate(
}
}
+ *static_cast<const char**>(save) = NULL;
return(1);
}
@@ -9379,19 +9553,39 @@ innodb_file_format_check_update(
const void* save) /*!< in: immediate result
from check function */
{
- uint format_id;
+ const char* format_name_in;
+ const char** format_name_out;
+ uint format_id;
ut_a(save != NULL);
ut_a(var_ptr != NULL);
- format_id = *(const uint*) save;
+ format_name_in = *static_cast<const char*const*>(save);
+
+ if (!format_name_in) {
+
+ return;
+ }
+
+ format_id = innobase_file_format_name_lookup(format_name_in);
+
+ if (format_id > DICT_TF_FORMAT_MAX) {
+ /* DEFAULT is "on", which is invalid at runtime. */
+ push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
+ ER_WRONG_ARGUMENTS,
+ "Ignoring SET innodb_file_format=%s",
+ format_name_in);
+ return;
+ }
+
+ format_name_out = static_cast<const char**>(var_ptr);
/* Update the max format id in the system tablespace. */
- if (trx_sys_file_format_max_set(format_id, (const char**) var_ptr)) {
+ if (trx_sys_file_format_max_set(format_id, format_name_out)) {
ut_print_timestamp(stderr);
fprintf(stderr,
" [Info] InnoDB: the file format in the system "
- "tablespace is now set to %s.\n", *(char**) var_ptr);
+ "tablespace is now set to %s.\n", *format_name_out);
}
}
@@ -9516,6 +9710,11 @@ static MYSQL_SYSVAR_BOOL(doublewrite, innobase_use_doublewrite,
"Disable with --skip-innodb-doublewrite.",
NULL, NULL, TRUE);
+static MYSQL_SYSVAR_ULONG(io_capacity, srv_io_capacity,
+ PLUGIN_VAR_RQCMDARG,
+ "Number of IOPs the server can do. Tunes the background IO rate",
+ NULL, NULL, 200, 100, ~0L, 0);
+
static MYSQL_SYSVAR_ULONG(fast_shutdown, innobase_fast_shutdown,
PLUGIN_VAR_OPCMDARG,
"Speeds up the shutdown process of the InnoDB storage engine. Possible "
@@ -9579,7 +9778,12 @@ static MYSQL_SYSVAR_STR(log_group_home_dir, innobase_log_group_home_dir,
static MYSQL_SYSVAR_ULONG(max_dirty_pages_pct, srv_max_buf_pool_modified_pct,
PLUGIN_VAR_RQCMDARG,
"Percentage of dirty pages allowed in bufferpool.",
- NULL, NULL, 90, 0, 100, 0);
+ NULL, NULL, 75, 0, 99, 0);
+
+static MYSQL_SYSVAR_BOOL(adaptive_flushing, srv_adaptive_flushing,
+ PLUGIN_VAR_NOCMDARG,
+ "Attempt flushing dirty pages to avoid IO bursts at checkpoints.",
+ NULL, NULL, TRUE);
static MYSQL_SYSVAR_ULONG(max_purge_lag, srv_max_purge_lag,
PLUGIN_VAR_RQCMDARG,
@@ -9621,7 +9825,7 @@ static MYSQL_SYSVAR_ULONG(replication_delay, srv_replication_delay,
static MYSQL_SYSVAR_LONG(additional_mem_pool_size, innobase_additional_mem_pool_size,
PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY,
"Size of a memory pool InnoDB uses to store data dictionary information and other internal data structures.",
- NULL, NULL, 1*1024*1024L, 512*1024L, LONG_MAX, 1024);
+ NULL, NULL, 8*1024*1024L, 512*1024L, LONG_MAX, 1024);
static MYSQL_SYSVAR_ULONG(autoextend_increment, srv_auto_extend_increment,
PLUGIN_VAR_RQCMDARG,
@@ -9631,7 +9835,7 @@ static MYSQL_SYSVAR_ULONG(autoextend_increment, srv_auto_extend_increment,
static MYSQL_SYSVAR_LONGLONG(buffer_pool_size, innobase_buffer_pool_size,
PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY,
"The size of the memory buffer InnoDB uses to cache data and indexes of its tables.",
- NULL, NULL, 8*1024*1024L, 5*1024*1024L, LONGLONG_MAX, 1024*1024L);
+ NULL, NULL, 128*1024*1024L, 5*1024*1024L, LONGLONG_MAX, 1024*1024L);
static MYSQL_SYSVAR_ULONG(commit_concurrency, innobase_commit_concurrency,
PLUGIN_VAR_RQCMDARG,
@@ -9648,6 +9852,16 @@ static MYSQL_SYSVAR_LONG(file_io_threads, innobase_file_io_threads,
"Number of file I/O threads in InnoDB.",
NULL, NULL, 4, 4, 64, 0);
+static MYSQL_SYSVAR_ULONG(read_io_threads, innobase_read_io_threads,
+ PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY,
+ "Number of background read I/O threads in InnoDB.",
+ NULL, NULL, 4, 1, 64, 0);
+
+static MYSQL_SYSVAR_ULONG(write_io_threads, innobase_write_io_threads,
+ PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY,
+ "Number of background write I/O threads in InnoDB.",
+ NULL, NULL, 4, 1, 64, 0);
+
static MYSQL_SYSVAR_LONG(force_recovery, innobase_force_recovery,
PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY,
"Helps to save your data in case the disk image of the database becomes corrupt.",
@@ -9656,7 +9870,7 @@ static MYSQL_SYSVAR_LONG(force_recovery, innobase_force_recovery,
static MYSQL_SYSVAR_LONG(log_buffer_size, innobase_log_buffer_size,
PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY,
"The size of the buffer which InnoDB uses to write log to the log files on disk.",
- NULL, NULL, 1024*1024L, 256*1024L, LONG_MAX, 1024);
+ NULL, NULL, 8*1024*1024L, 256*1024L, LONG_MAX, 1024);
static MYSQL_SYSVAR_LONGLONG(log_file_size, innobase_log_file_size,
PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY,
@@ -9680,13 +9894,13 @@ static MYSQL_SYSVAR_LONG(open_files, innobase_open_files,
static MYSQL_SYSVAR_ULONG(sync_spin_loops, srv_n_spin_wait_rounds,
PLUGIN_VAR_RQCMDARG,
- "Count of spin-loop rounds in InnoDB mutexes",
- NULL, NULL, 20L, 0L, ~0L, 0);
+ "Count of spin-loop rounds in InnoDB mutexes (30 by default)",
+ NULL, NULL, 30L, 0L, ~0L, 0);
static MYSQL_SYSVAR_ULONG(spin_wait_delay, srv_spin_wait_delay,
PLUGIN_VAR_OPCMDARG,
- "Maximum delay between polling for a spin lock (5 by default)",
- NULL, NULL, 5L, 0L, ~0L, 0);
+ "Maximum delay between polling for a spin lock (6 by default)",
+ NULL, NULL, 6L, 0L, ~0L, 0);
static MYSQL_SYSVAR_ULONG(thread_concurrency, srv_thread_concurrency,
PLUGIN_VAR_RQCMDARG,
@@ -9731,6 +9945,12 @@ static MYSQL_SYSVAR_STR(change_buffering, innobase_change_buffering,
innodb_change_buffering_validate,
innodb_change_buffering_update, NULL);
+static MYSQL_SYSVAR_ULONG(read_ahead_threshold, srv_read_ahead_threshold,
+ PLUGIN_VAR_RQCMDARG,
+ "Number of pages that must be accessed sequentially for InnoDB to"
+ "trigger a readahead.",
+ NULL, NULL, 56, 0, 64, 0);
+
static struct st_mysql_sys_var* innobase_system_variables[]= {
MYSQL_SYSVAR(additional_mem_pool_size),
MYSQL_SYSVAR(autoextend_increment),
@@ -9743,6 +9963,8 @@ static struct st_mysql_sys_var* innobase_system_variables[]= {
MYSQL_SYSVAR(doublewrite),
MYSQL_SYSVAR(fast_shutdown),
MYSQL_SYSVAR(file_io_threads),
+ MYSQL_SYSVAR(read_io_threads),
+ MYSQL_SYSVAR(write_io_threads),
MYSQL_SYSVAR(file_per_table),
MYSQL_SYSVAR(file_format),
MYSQL_SYSVAR(file_format_check),
@@ -9760,6 +9982,7 @@ static struct st_mysql_sys_var* innobase_system_variables[]= {
MYSQL_SYSVAR(log_files_in_group),
MYSQL_SYSVAR(log_group_home_dir),
MYSQL_SYSVAR(max_dirty_pages_pct),
+ MYSQL_SYSVAR(adaptive_flushing),
MYSQL_SYSVAR(max_purge_lag),
MYSQL_SYSVAR(mirrored_log_groups),
MYSQL_SYSVAR(open_files),
@@ -9780,6 +10003,8 @@ static struct st_mysql_sys_var* innobase_system_variables[]= {
MYSQL_SYSVAR(version),
MYSQL_SYSVAR(use_sys_malloc),
MYSQL_SYSVAR(change_buffering),
+ MYSQL_SYSVAR(read_ahead_threshold),
+ MYSQL_SYSVAR(io_capacity),
NULL
};
@@ -9807,6 +10032,24 @@ i_s_innodb_cmpmem,
i_s_innodb_cmpmem_reset
mysql_declare_plugin_end;
+/** @brief Initialize the default value of innodb_commit_concurrency.
+
+Once InnoDB is running, the innodb_commit_concurrency must not change
+from zero to nonzero. (Bug #42101)
+
+The initial default value is 0, and without this extra initialization,
+SET GLOBAL innodb_commit_concurrency=DEFAULT would set the parameter
+to 0, even if it was initially set to nonzero at the command line
+or configuration file. */
+static
+void
+innobase_commit_concurrency_init_default(void)
+/*==========================================*/
+{
+ MYSQL_SYSVAR_NAME(commit_concurrency).def_val
+ = innobase_commit_concurrency;
+}
+
#ifdef UNIV_COMPILE_TEST_FUNCS
typedef struct innobase_convert_name_test_struct {
diff --git a/storage/innodb_plugin/handler/handler0alter.cc b/storage/innodb_plugin/handler/handler0alter.cc
index 3bac42b7e9e..d1f64a1985c 100644
--- a/storage/innodb_plugin/handler/handler0alter.cc
+++ b/storage/innodb_plugin/handler/handler0alter.cc
@@ -646,6 +646,7 @@ ha_innobase::add_index(
/* In case MySQL calls this in the middle of a SELECT query, release
possible adaptive hash latch to avoid deadlocks of threads. */
trx_search_latch_release_if_reserved(prebuilt->trx);
+ trx_start_if_not_started(prebuilt->trx);
/* Create a background transaction for the operations on
the data dictionary tables. */
@@ -1135,6 +1136,7 @@ ha_innobase::final_drop_index(
update_thd();
trx_search_latch_release_if_reserved(prebuilt->trx);
+ trx_start_if_not_started(prebuilt->trx);
/* Create a background transaction for the operations on
the data dictionary tables. */
diff --git a/storage/innodb_plugin/handler/handler0vars.h b/storage/innodb_plugin/handler/handler0vars.h
new file mode 100644
index 00000000000..e0f8f75e34d
--- /dev/null
+++ b/storage/innodb_plugin/handler/handler0vars.h
@@ -0,0 +1,69 @@
+/*****************************************************************************
+
+Copyright (c) 2008, 2009, Innobase Oy. All Rights Reserved.
+
+This program is free software; you can redistribute it and/or modify it under
+the terms of the GNU General Public License as published by the Free Software
+Foundation; version 2 of the License.
+
+This program is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License along with
+this program; if not, write to the Free Software Foundation, Inc., 59 Temple
+Place, Suite 330, Boston, MA 02111-1307 USA
+
+*****************************************************************************/
+
+/*******************************************************************//**
+@file handler/handler0vars.h
+This file contains accessor functions for dynamic plugin on Windows.
+***********************************************************************/
+
+#if defined __WIN__ && defined MYSQL_DYNAMIC_PLUGIN
+/*******************************************************************//**
+This is a list of externals that can not be resolved by delay loading.
+They have to be resolved indirectly via their addresses in the .map file.
+All of them are external variables. */
+extern CHARSET_INFO* wdl_my_charset_bin;
+extern CHARSET_INFO* wdl_my_charset_latin1;
+extern CHARSET_INFO* wdl_my_charset_filename;
+extern CHARSET_INFO** wdl_system_charset_info;
+extern CHARSET_INFO** wdl_default_charset_info;
+extern CHARSET_INFO** wdl_all_charsets;
+extern system_variables* wdl_global_system_variables;
+extern char* wdl_mysql_real_data_home;
+extern char** wdl_mysql_data_home;
+extern char** wdl_tx_isolation_names;
+extern char** wdl_binlog_format_names;
+extern char* wdl_reg_ext;
+extern pthread_mutex_t* wdl_LOCK_thread_count;
+extern key_map* wdl_key_map_full;
+extern MY_TMPDIR* wdl_mysql_tmpdir_list;
+extern bool* wdl_mysqld_embedded;
+extern uint* wdl_lower_case_table_names;
+extern ulong* wdl_specialflag;
+extern int* wdl_my_umask;
+
+#define my_charset_bin (*wdl_my_charset_bin)
+#define my_charset_latin1 (*wdl_my_charset_latin1)
+#define my_charset_filename (*wdl_my_charset_filename)
+#define system_charset_info (*wdl_system_charset_info)
+#define default_charset_info (*wdl_default_charset_info)
+#define all_charsets (wdl_all_charsets)
+#define global_system_variables (*wdl_global_system_variables)
+#define mysql_real_data_home (wdl_mysql_real_data_home)
+#define mysql_data_home (*wdl_mysql_data_home)
+#define tx_isolation_names (wdl_tx_isolation_names)
+#define binlog_format_names (wdl_binlog_format_names)
+#define reg_ext (wdl_reg_ext)
+#define LOCK_thread_count (*wdl_LOCK_thread_count)
+#define key_map_full (*wdl_key_map_full)
+#define mysql_tmpdir_list (*wdl_mysql_tmpdir_list)
+#define mysqld_embedded (*wdl_mysqld_embedded)
+#define lower_case_table_names (*wdl_lower_case_table_names)
+#define specialflag (*wdl_specialflag)
+#define my_umask (*wdl_my_umask)
+
+#endif
diff --git a/storage/innodb_plugin/handler/win_delay_loader.cc b/storage/innodb_plugin/handler/win_delay_loader.cc
new file mode 100644
index 00000000000..9b92f6a9cf2
--- /dev/null
+++ b/storage/innodb_plugin/handler/win_delay_loader.cc
@@ -0,0 +1,1024 @@
+/*****************************************************************************
+
+Copyright (c) 2008, 2009, Innobase Oy. All Rights Reserved.
+
+This program is free software; you can redistribute it and/or modify it under
+the terms of the GNU General Public License as published by the Free Software
+Foundation; version 2 of the License.
+
+This program is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License along with
+this program; if not, write to the Free Software Foundation, Inc., 59 Temple
+Place, Suite 330, Boston, MA 02111-1307 USA
+
+*****************************************************************************/
+
+/*******************************************************************//**
+@file handler/win_delay_loader.cc
+This file contains functions that implement the delay loader on Windows.
+
+This is a customized version of delay loader with limited functionalities.
+It does not support:
+
+* (manual) unloading
+* multiple delay loaded DLLs
+* multiple loading of the same DLL
+
+This delay loader is used only by the InnoDB plugin. Other components (DLLs)
+can still use the default delay loader, provided by MSVC.
+
+Several acronyms used by Microsoft:
+ * IAT: import address table
+ * INT: import name table
+ * RVA: Relative Virtual Address
+
+See http://msdn.microsoft.com/en-us/magazine/bb985992.aspx for details of
+PE format.
+***********************************************************************/
+#if defined (__WIN__) && defined (MYSQL_DYNAMIC_PLUGIN)
+# define WIN32_LEAN_AND_MEAN
+# include <windows.h>
+# include <delayimp.h>
+# include <mysql_priv.h>
+
+extern "C" {
+# include "univ.i"
+# include "hash0hash.h"
+}
+
+/*******************************************************************//**
+This following contains a list of externals that can not be resolved by
+delay loading. They have to be resolved indirectly via their addresses
+in the .map file. All of them are external variables. */
+CHARSET_INFO* wdl_my_charset_bin;
+CHARSET_INFO* wdl_my_charset_latin1;
+CHARSET_INFO* wdl_my_charset_filename;
+CHARSET_INFO** wdl_system_charset_info;
+CHARSET_INFO** wdl_default_charset_info;
+CHARSET_INFO** wdl_all_charsets;
+system_variables* wdl_global_system_variables;
+char* wdl_mysql_real_data_home;
+char** wdl_mysql_data_home;
+char** wdl_tx_isolation_names;
+char** wdl_binlog_format_names;
+char* wdl_reg_ext;
+pthread_mutex_t* wdl_LOCK_thread_count;
+key_map* wdl_key_map_full;
+MY_TMPDIR* wdl_mysql_tmpdir_list;
+bool* wdl_mysqld_embedded;
+uint* wdl_lower_case_table_names;
+ulong* wdl_specialflag;
+int* wdl_my_umask;
+
+/*******************************************************************//**
+The preferred load-address defined in PE (portable executable format). */
+#if defined(_M_IA64)
+#pragma section(".base", long, read)
+extern "C"
+__declspec(allocate(".base"))
+const IMAGE_DOS_HEADER __ImageBase;
+#else
+extern "C"
+const IMAGE_DOS_HEADER __ImageBase;
+#endif
+
+/*******************************************************************//**
+A template function for converting a relative address (RVA) to an
+absolute address (VA). This is due to the pointers in the delay
+descriptor (ImgDelayDescr in delayimp.h) have been changed from
+VAs to RVAs to work on both 32- and 64-bit platforms.
+@return absolute virtual address */
+template <class X>
+X PFromRva(
+/*=======*/
+ RVA rva) /*!< in: relative virtual address */
+{
+ return X(PBYTE(&__ImageBase) + rva);
+}
+
+/*******************************************************************//**
+Convert to the old format for convenience. The structure as well as its
+element names follow the definition of ImgDelayDescr in delayimp.h. */
+struct InternalImgDelayDescr
+{
+ DWORD grAttrs; /*!< attributes */
+ LPCSTR szName; /*!< pointer to dll name */
+ HMODULE* phmod; /*!< address of module handle */
+ PImgThunkData pIAT; /*!< address of the IAT */
+ PCImgThunkData pINT; /*!< address of the INT */
+ PCImgThunkData pBoundIAT; /*!< address of the optional bound IAT */
+ PCImgThunkData pUnloadIAT; /*!< address of optional copy of
+ original IAT */
+ DWORD dwTimeStamp; /*!< 0 if not bound,
+ otherwise date/time stamp of DLL
+ bound to (Old BIND) */
+};
+
+typedef struct map_hash_chain_struct map_hash_chain_t;
+
+struct map_hash_chain_struct {
+ char* symbol; /*!< pointer to a symbol */
+ ulint value; /*!< address of the symbol */
+ map_hash_chain_t* next; /*!< pointer to the next cell
+ in the same folder. */
+ map_hash_chain_t* chain; /*!< a linear chain used for
+ cleanup. */
+};
+
+static HMODULE my_hmod = 0;
+static struct hash_table_struct* m_htbl = NULL ;
+static map_hash_chain_t* chain_header = NULL;
+static ibool wdl_init = FALSE;
+const ulint MAP_HASH_CELLS_NUM = 10000;
+
+#ifndef DBUG_OFF
+/*******************************************************************//**
+In the dynamic plugin, it is required to call the following dbug functions
+in the server:
+ _db_pargs_
+ _db_doprnt_
+ _db_enter_
+ _db_return_
+ _db_dump_
+
+The plugin will get those function pointers during the initialization. */
+typedef void (__cdecl* pfn_db_enter_)(
+ const char* _func_,
+ const char* _file_,
+ uint _line_,
+ const char** _sfunc_,
+ const char** _sfile_,
+ uint* _slevel_,
+ char***);
+
+typedef void (__cdecl* pfn_db_return_)(
+ uint _line_,
+ const char** _sfunc_,
+ const char** _sfile_,
+ uint* _slevel_);
+
+typedef void (__cdecl* pfn_db_pargs_)(
+ uint _line_,
+ const char* keyword);
+
+typedef void (__cdecl* pfn_db_doprnt_)(
+ const char* format,
+ ...);
+
+typedef void (__cdecl* pfn_db_dump_)(
+ uint _line_,
+ const char* keyword,
+ const unsigned char* memory,
+ size_t length);
+
+static pfn_db_enter_ wdl_db_enter_;
+static pfn_db_return_ wdl_db_return_;
+static pfn_db_pargs_ wdl_db_pargs_;
+static pfn_db_doprnt_ wdl_db_doprnt_;
+static pfn_db_dump_ wdl_db_dump_;
+#endif /* !DBUG_OFF */
+
+/*************************************************************//**
+Creates a hash table with >= n array cells. The actual number of cells is
+chosen to be a prime number slightly bigger than n.
+
+This is the same function as hash_create in hash0hash.c, except the
+memory allocation. This function is invoked before the engine is
+initialized, and buffer pools are not ready yet.
+@return own: created hash table */
+static
+hash_table_t*
+wdl_hash_create(
+/*============*/
+ ulint n) /*!< in: number of array cells */
+{
+ hash_cell_t* array;
+ ulint prime;
+ hash_table_t* table;
+
+ prime = ut_find_prime(n);
+
+ table = (hash_table_t*) malloc(sizeof(hash_table_t));
+ if (table == NULL) {
+ return(NULL);
+ }
+
+ array = (hash_cell_t*) malloc(sizeof(hash_cell_t) * prime);
+ if (array == NULL) {
+ free(table);
+ return(NULL);
+ }
+
+ table->array = array;
+ table->n_cells = prime;
+ table->n_mutexes = 0;
+ table->mutexes = NULL;
+ table->heaps = NULL;
+ table->heap = NULL;
+ table->magic_n = HASH_TABLE_MAGIC_N;
+
+ /* Initialize the cell array */
+ hash_table_clear(table);
+
+ return(table);
+}
+
+/*************************************************************//**
+Frees a hash table. */
+static
+void
+wdl_hash_table_free(
+/*================*/
+ hash_table_t* table) /*!< in, own: hash table */
+{
+ ut_a(table != NULL);
+ ut_a(table->mutexes == NULL);
+
+ free(table->array);
+ free(table);
+}
+
+/*******************************************************************//**
+Function for calculating the count of imports given the base of the IAT.
+@return number of imports */
+static
+ulint
+wdl_import_count(
+/*=============*/
+ PCImgThunkData pitd_base) /*!< in: base of the IAT */
+{
+ ulint ret = 0;
+ PCImgThunkData pitd = pitd_base;
+
+ while (pitd->u1.Function) {
+ pitd++;
+ ret++;
+ }
+
+ return(ret);
+}
+
+/*******************************************************************//**
+Read Mapfile to a hashtable for faster access
+@return TRUE if the mapfile is loaded successfully. */
+static
+ibool
+wdl_load_mapfile(
+/*=============*/
+ const char* filename) /*!< in: name of the mapfile. */
+{
+ FILE* fp;
+ const size_t nSize = 256;
+ char tmp_buf[nSize];
+ char* func_name;
+ char* func_addr;
+ ulint load_addr = 0;
+ ibool valid_load_addr = FALSE;
+#ifdef _WIN64
+ const char* tmp_string = " Preferred load address is %16llx";
+#else
+ const char* tmp_string = " Preferred load address is %08x";
+#endif
+
+ fp = fopen(filename, "r");
+ if (fp == NULL) {
+
+ return(FALSE);
+ }
+
+ /* Check whether to create the hashtable */
+ if (m_htbl == NULL) {
+
+ m_htbl = wdl_hash_create(MAP_HASH_CELLS_NUM);
+
+ if (m_htbl == NULL) {
+
+ fclose(fp);
+ return(FALSE);
+ }
+ }
+
+ /* Search start of symbol list and get the preferred load address */
+ while (fgets(tmp_buf, sizeof(tmp_buf), fp)) {
+
+ if (sscanf(tmp_buf, tmp_string, &load_addr) == 1) {
+
+ valid_load_addr = TRUE;
+ }
+
+ if (strstr(tmp_buf, "Rva+Base") != NULL) {
+
+ break;
+ }
+ }
+
+ if (valid_load_addr == FALSE) {
+
+ /* No "Preferred load address", the map file is wrong. */
+ fclose(fp);
+ return(FALSE);
+ }
+
+ /* Read symbol list */
+ while (fgets(tmp_buf, sizeof(tmp_buf), fp))
+ {
+ map_hash_chain_t* map_cell;
+ ulint map_fold;
+
+ if (*tmp_buf == 0) {
+
+ continue;
+ }
+
+ func_name = strtok(tmp_buf, " ");
+ func_name = strtok(NULL, " ");
+ func_addr = strtok(NULL, " ");
+
+ if (func_name && func_addr) {
+
+ ut_snprintf(tmp_buf, nSize, "0x%s", func_addr);
+ if (*func_name == '_') {
+
+ func_name++;
+ }
+
+ map_cell = (map_hash_chain_t*)
+ malloc(sizeof(map_hash_chain_t));
+ if (map_cell == NULL) {
+ return(FALSE);
+ }
+
+ /* Chain all cells together */
+ map_cell->chain = chain_header;
+ chain_header = map_cell;
+
+ map_cell->symbol = strdup(func_name);
+ map_cell->value = (ulint) _strtoui64(tmp_buf, NULL, 0)
+ - load_addr;
+ map_fold = ut_fold_string(map_cell->symbol);
+
+ HASH_INSERT(map_hash_chain_t,
+ next,
+ m_htbl,
+ map_fold,
+ map_cell);
+ }
+ }
+
+ fclose(fp);
+
+ return(TRUE);
+}
+
+/*************************************************************//**
+Cleanup.during DLL unload */
+static
+void
+wdl_cleanup(void)
+/*=============*/
+{
+ while (chain_header != NULL) {
+ map_hash_chain_t* tmp;
+
+ tmp = chain_header->chain;
+ free(chain_header->symbol);
+ free(chain_header);
+ chain_header = tmp;
+ }
+
+ if (m_htbl != NULL) {
+
+ wdl_hash_table_free(m_htbl);
+ }
+}
+
+/*******************************************************************//**
+Load the mapfile mysqld.map.
+@return the module handle */
+static
+HMODULE
+wdl_get_mysqld_mapfile(void)
+/*========================*/
+{
+ char file_name[MAX_PATH];
+ char* ext;
+ ulint err;
+
+ if (my_hmod == 0) {
+
+ size_t nSize = MAX_PATH - strlen(".map") -1;
+
+ /* First find out the name of current executable */
+ my_hmod = GetModuleHandle(NULL);
+ if (my_hmod == 0) {
+
+ return(my_hmod);
+ }
+
+ err = GetModuleFileName(my_hmod, file_name, nSize);
+ if (err == 0) {
+
+ my_hmod = 0;
+ return(my_hmod);
+ }
+
+ ext = strrchr(file_name, '.');
+ if (ext != NULL) {
+
+ *ext = 0;
+ strcat(file_name, ".map");
+
+ err = wdl_load_mapfile(file_name);
+ if (err == 0) {
+
+ my_hmod = 0;
+ }
+ } else {
+
+ my_hmod = 0;
+ }
+ }
+
+ return(my_hmod);
+}
+
+/*******************************************************************//**
+Retrieves the address of an exported function. It follows the convention
+of GetProcAddress().
+@return address of exported function. */
+static
+FARPROC
+wdl_get_procaddr_from_map(
+/*======================*/
+ HANDLE m_handle, /*!< in: module handle */
+ const char* import_proc) /*!< in: procedure name */
+{
+ map_hash_chain_t* hash_chain;
+ ulint map_fold;
+
+ map_fold = ut_fold_string(import_proc);
+ HASH_SEARCH(
+ next,
+ m_htbl,
+ map_fold,
+ map_hash_chain_t*,
+ hash_chain,
+ ,
+ (ut_strcmp(hash_chain->symbol, import_proc) == 0));
+
+ if (hash_chain == NULL) {
+
+#ifdef _WIN64
+ /* On Win64, the leading '_' may not be taken out. In this
+ case, search again without the leading '_'. */
+ if (*import_proc == '_') {
+
+ import_proc++;
+ }
+
+ map_fold = ut_fold_string(import_proc);
+ HASH_SEARCH(
+ next,
+ m_htbl,
+ map_fold,
+ map_hash_chain_t*,
+ hash_chain,
+ ,
+ (ut_strcmp(hash_chain->symbol, import_proc) == 0));
+
+ if (hash_chain == NULL) {
+#endif
+ if (wdl_init == TRUE) {
+
+ sql_print_error(
+ "InnoDB: the procedure pointer of %s"
+ " is not found.",
+ import_proc);
+ }
+
+ return(0);
+#ifdef _WIN64
+ }
+#endif
+ }
+
+ return((FARPROC) ((ulint) m_handle + hash_chain->value));
+}
+
+/*******************************************************************//**
+Retrieves the address of an exported variable.
+Note: It does not follow the Windows call convention FARPROC.
+@return address of exported variable. */
+static
+void*
+wdl_get_varaddr_from_map(
+/*=====================*/
+ HANDLE m_handle, /*!< in: module handle */
+ const char* import_variable) /*!< in: variable name */
+{
+ map_hash_chain_t* hash_chain;
+ ulint map_fold;
+
+ map_fold = ut_fold_string(import_variable);
+ HASH_SEARCH(
+ next,
+ m_htbl,
+ map_fold,
+ map_hash_chain_t*,
+ hash_chain,
+ ,
+ (ut_strcmp(hash_chain->symbol, import_variable) == 0));
+
+ if (hash_chain == NULL) {
+
+#ifdef _WIN64
+ /* On Win64, the leading '_' may not be taken out. In this
+ case, search again without the leading '_'. */
+ if (*import_variable == '_') {
+
+ import_variable++;
+ }
+
+ map_fold = ut_fold_string(import_variable);
+ HASH_SEARCH(
+ next,
+ m_htbl,
+ map_fold,
+ map_hash_chain_t*,
+ hash_chain,
+ ,
+ (ut_strcmp(hash_chain->symbol, import_variable) == 0));
+
+ if (hash_chain == NULL) {
+#endif
+ if (wdl_init == TRUE) {
+
+ sql_print_error(
+ "InnoDB: the variable address of %s"
+ " is not found.",
+ import_variable);
+ }
+
+ return(0);
+#ifdef _WIN64
+ }
+#endif
+ }
+
+ return((void*) ((ulint) m_handle + hash_chain->value));
+}
+
+/*******************************************************************//**
+Bind all unresolved external variables from the MySQL executable.
+@return TRUE if successful */
+static
+bool
+wdl_get_external_variables(void)
+/*============================*/
+{
+ HMODULE hmod = wdl_get_mysqld_mapfile();
+
+ if (hmod == 0) {
+
+ return(FALSE);
+ }
+
+#define GET_SYM(sym, var, type) \
+ var = (type*) wdl_get_varaddr_from_map(hmod, sym); \
+ if (var == NULL) return(FALSE)
+#ifdef _WIN64
+#define GET_SYM2(sym1, sym2, var, type) \
+ var = (type*) wdl_get_varaddr_from_map(hmod, sym1); \
+ if (var == NULL) return(FALSE)
+#else
+#define GET_SYM2(sym1, sym2, var, type) \
+ var = (type*) wdl_get_varaddr_from_map(hmod, sym2); \
+ if (var == NULL) return(FALSE)
+#endif // (_WIN64)
+#define GET_C_SYM(sym, type) GET_SYM(#sym, wdl_##sym, type)
+#define GET_PROC_ADDR(sym) \
+ wdl##sym = (pfn##sym) wdl_get_procaddr_from_map(hmod, #sym)
+
+ GET_C_SYM(my_charset_bin, CHARSET_INFO);
+ GET_C_SYM(my_charset_latin1, CHARSET_INFO);
+ GET_C_SYM(my_charset_filename, CHARSET_INFO);
+ GET_C_SYM(default_charset_info, CHARSET_INFO*);
+ GET_C_SYM(all_charsets, CHARSET_INFO*);
+ GET_C_SYM(my_umask, int);
+
+ GET_SYM("?global_system_variables@@3Usystem_variables@@A",
+ wdl_global_system_variables, struct system_variables);
+ GET_SYM("?mysql_real_data_home@@3PADA",
+ wdl_mysql_real_data_home, char);
+ GET_SYM("?reg_ext@@3PADA", wdl_reg_ext, char);
+ GET_SYM("?LOCK_thread_count@@3U_RTL_CRITICAL_SECTION@@A",
+ wdl_LOCK_thread_count, pthread_mutex_t);
+ GET_SYM("?key_map_full@@3V?$Bitmap@$0EA@@@A",
+ wdl_key_map_full, key_map);
+ GET_SYM("?mysql_tmpdir_list@@3Ust_my_tmpdir@@A",
+ wdl_mysql_tmpdir_list, MY_TMPDIR);
+ GET_SYM("?mysqld_embedded@@3_NA",
+ wdl_mysqld_embedded, bool);
+ GET_SYM("?lower_case_table_names@@3IA",
+ wdl_lower_case_table_names, uint);
+ GET_SYM("?specialflag@@3KA", wdl_specialflag, ulong);
+
+ GET_SYM2("?system_charset_info@@3PEAUcharset_info_st@@EA",
+ "?system_charset_info@@3PAUcharset_info_st@@A",
+ wdl_system_charset_info, CHARSET_INFO*);
+ GET_SYM2("?mysql_data_home@@3PEADEA",
+ "?mysql_data_home@@3PADA",
+ wdl_mysql_data_home, char*);
+ GET_SYM2("?tx_isolation_names@@3PAPEBDA",
+ "?tx_isolation_names@@3PAPBDA",
+ wdl_tx_isolation_names, char*);
+ GET_SYM2("?binlog_format_names@@3PAPEBDA",
+ "?binlog_format_names@@3PAPBDA",
+ wdl_binlog_format_names, char*);
+
+#ifndef DBUG_OFF
+ GET_PROC_ADDR(_db_enter_);
+ GET_PROC_ADDR(_db_return_);
+ GET_PROC_ADDR(_db_pargs_);
+ GET_PROC_ADDR(_db_doprnt_);
+ GET_PROC_ADDR(_db_dump_);
+
+ /* If any of the dbug functions is not available, just make them
+ all invalid. This is the case when working with a non-debug
+ version of the server. */
+ if (wdl_db_enter_ == NULL || wdl_db_return_ == NULL
+ || wdl_db_pargs_ == NULL || wdl_db_doprnt_ == NULL
+ || wdl_db_dump_ == NULL) {
+
+ wdl_db_enter_ = NULL;
+ wdl_db_return_ = NULL;
+ wdl_db_pargs_ = NULL;
+ wdl_db_doprnt_ = NULL;
+ wdl_db_dump_ = NULL;
+ }
+#endif /* !DBUG_OFF */
+
+ wdl_init = TRUE;
+ return(TRUE);
+
+#undef GET_SYM
+#undef GET_SYM2
+#undef GET_C_SYM
+#undef GET_PROC_ADDR
+}
+
+/*******************************************************************//**
+The DLL Delayed Loading Helper Function for resolving externals.
+
+The function may fail due to one of the three reasons:
+
+* Invalid parameter, which happens if the attributes in pidd aren't
+ specified correctly.
+* Failed to load the map file mysqld.map.
+* Failed to find an external name in the map file mysqld.map.
+
+Note: this function is called by run-time as well as __HrLoadAllImportsForDll.
+So, it has to follow Windows call convention.
+@return the address of the imported function */
+extern "C"
+FARPROC WINAPI
+__delayLoadHelper2(
+/*===============*/
+ PCImgDelayDescr pidd, /*!< in: a const pointer to a
+ ImgDelayDescr, see delayimp.h. */
+ FARPROC* iat_entry) /*!< in/out: A pointer to the slot in
+ the delay load import address table
+ to be updated with the address of the
+ imported function. */
+{
+ ulint iIAT, iINT;
+ HMODULE hmod;
+ PCImgThunkData pitd;
+ FARPROC fun = NULL;
+
+ /* Set up data used for the hook procs */
+ InternalImgDelayDescr idd = {
+ pidd->grAttrs,
+ PFromRva<LPCSTR>(pidd->rvaDLLName),
+ PFromRva<HMODULE*>(pidd->rvaHmod),
+ PFromRva<PImgThunkData>(pidd->rvaIAT),
+ PFromRva<PCImgThunkData>(pidd->rvaINT),
+ PFromRva<PCImgThunkData>(pidd->rvaBoundIAT),
+ PFromRva<PCImgThunkData>(pidd->rvaUnloadIAT),
+ pidd->dwTimeStamp
+ };
+
+ DelayLoadInfo dli = {
+ sizeof(DelayLoadInfo),
+ pidd,
+ iat_entry,
+ idd.szName,
+ {0},
+ 0,
+ 0,
+ 0
+ };
+
+ /* Check the Delay Load Attributes, log an error of invalid
+ parameter, which happens if the attributes in pidd are not
+ specified correctly. */
+ if ((idd.grAttrs & dlattrRva) == 0) {
+
+ sql_print_error("InnoDB: invalid parameter for delay loader.");
+ return(0);
+ }
+
+ hmod = *idd.phmod;
+
+ /* Calculate the index for the IAT entry in the import address table.
+ The INT entries are ordered the same as the IAT entries so the
+ calculation can be done on the IAT side. */
+ iIAT = (PCImgThunkData) iat_entry - idd.pIAT;
+ iINT = iIAT;
+
+ pitd = &(idd.pINT[iINT]);
+
+ dli.dlp.fImportByName = !IMAGE_SNAP_BY_ORDINAL(pitd->u1.Ordinal);
+
+ if (dli.dlp.fImportByName) {
+
+ dli.dlp.szProcName = (LPCSTR) (PFromRva<PIMAGE_IMPORT_BY_NAME>
+ ((RVA) ((UINT_PTR) pitd->u1.AddressOfData))->Name);
+ } else {
+
+ dli.dlp.dwOrdinal = (ulint) IMAGE_ORDINAL(pitd->u1.Ordinal);
+ }
+
+ /* Now, load the mapfile, if it has not been done yet */
+ if (hmod == 0) {
+
+ hmod = wdl_get_mysqld_mapfile();
+ }
+
+ if (hmod == 0) {
+ /* LoadLibrary failed. */
+ PDelayLoadInfo rgpdli[1] = {&dli};
+
+ dli.dwLastError = ::GetLastError();
+
+ sql_print_error(
+ "InnoDB: failed to load mysqld.map with error %d.",
+ dli.dwLastError);
+
+ return(0);
+ }
+
+ /* Store the library handle. */
+ idd.phmod = &hmod;
+
+ /* Go for the procedure now. */
+ dli.hmodCur = hmod;
+
+ if (pidd->rvaBoundIAT && pidd->dwTimeStamp) {
+
+ /* Bound imports exist, check the timestamp from the target
+ image */
+ PIMAGE_NT_HEADERS pinh;
+
+ pinh = (PIMAGE_NT_HEADERS) ((byte*) hmod
+ + ((PIMAGE_DOS_HEADER) hmod)->e_lfanew);
+
+ if (pinh->Signature == IMAGE_NT_SIGNATURE
+ && pinh->FileHeader.TimeDateStamp == idd.dwTimeStamp
+ && (DWORD) hmod == pinh->OptionalHeader.ImageBase) {
+
+ /* We have a decent address in the bound IAT. */
+ fun = (FARPROC) (UINT_PTR)
+ idd.pBoundIAT[iIAT].u1.Function;
+
+ if (fun) {
+
+ *iat_entry = fun;
+ return(fun);
+ }
+ }
+ }
+
+ fun = wdl_get_procaddr_from_map(hmod, dli.dlp.szProcName);
+
+ if (fun == 0) {
+
+ return(0);
+ }
+
+ *iat_entry = fun;
+ return(fun);
+}
+
+/*******************************************************************//**
+Unload a DLL that was delay loaded. This function is called by run-time.
+@return TRUE is returned if the DLL is found and the IAT matches the
+original one. */
+extern "C"
+BOOL WINAPI
+__FUnloadDelayLoadedDLL2(
+/*=====================*/
+ LPCSTR module_name) /*!< in: DLL name */
+{
+ return(TRUE);
+}
+
+/**************************************************************//**
+Load all imports from a DLL that was specified with the /delayload linker
+option.
+Note: this function is called by run-time. So, it has to follow Windows call
+convention.
+@return S_OK if the DLL matches, otherwise ERROR_MOD_NOT_FOUND is returned. */
+extern "C"
+HRESULT WINAPI
+__HrLoadAllImportsForDll(
+/*=====================*/
+ LPCSTR module_name) /*!< in: DLL name */
+{
+ PIMAGE_NT_HEADERS img;
+ PCImgDelayDescr pidd;
+ IMAGE_DATA_DIRECTORY* image_data;
+ LPCSTR current_module;
+ HRESULT ret = ERROR_MOD_NOT_FOUND;
+ HMODULE hmod = (HMODULE) &__ImageBase;
+
+ img = (PIMAGE_NT_HEADERS) ((byte*) hmod
+ + ((PIMAGE_DOS_HEADER) hmod)->e_lfanew);
+ image_data =
+ &img->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_DELAY_IMPORT];
+
+ /* Scan the delay load IAT/INT for the DLL */
+ if (image_data->Size) {
+
+ pidd = PFromRva<PCImgDelayDescr>(image_data->VirtualAddress);
+
+ /* Check all of the listed DLLs we want to load. */
+ while (pidd->rvaDLLName) {
+
+ current_module = PFromRva<LPCSTR>(pidd->rvaDLLName);
+
+ if (stricmp(module_name, current_module) == 0) {
+
+ /* Found it, break out with pidd and
+ current_module set appropriately */
+ break;
+ }
+
+ /* To the next delay import descriptor */
+ pidd++;
+ }
+
+ if (pidd->rvaDLLName) {
+
+ /* Found a matching DLL, now process it. */
+ FARPROC* iat_entry;
+ size_t count;
+
+ iat_entry = PFromRva<FARPROC*>(pidd->rvaIAT);
+ count = wdl_import_count((PCImgThunkData) iat_entry);
+
+ /* now load all the imports from the DLL */
+ while (count > 0) {
+
+ /* No need to check the return value */
+ __delayLoadHelper2(pidd, iat_entry);
+ iat_entry++;
+ count--;
+ }
+
+ ret = S_OK;
+ }
+ }
+
+ return ret;
+}
+
+/**************************************************************//**
+The main function of a DLL
+@return TRUE if the call succeeds */
+BOOL
+WINAPI
+DllMain(
+/*====*/
+ HINSTANCE hinstDLL, /*!< in: handle to the DLL module */
+ DWORD fdwReason, /*!< Reason code that indicates why the
+ DLL entry-point function is being
+ called.*/
+ LPVOID lpvReserved) /*!< in: additional parameter based on
+ fdwReason */
+{
+ BOOL success = TRUE;
+
+ switch (fdwReason) {
+
+ case DLL_PROCESS_ATTACH:
+ success = wdl_get_external_variables();
+ break;
+
+ case DLL_PROCESS_DETACH:
+ wdl_cleanup();
+ break;
+ }
+
+ return(success);
+}
+
+#ifndef DBUG_OFF
+/**************************************************************//**
+Process entry point to user function. It makes the call to _db_enter_
+in mysqld.exe. The DBUG functions are defined in my_dbug.h. */
+extern "C" UNIV_INTERN
+void
+_db_enter_(
+ const char* _func_, /*!< in: current function name */
+ const char* _file_, /*!< in: current file name */
+ uint _line_, /*!< in: current source line number */
+ const char** _sfunc_, /*!< out: previous _func_ */
+ const char** _sfile_, /*!< out: previous _file_ */
+ uint* _slevel_, /*!< out: previous nesting level */
+ char*** _sframep_) /*!< out: previous frame pointer */
+{
+ if (wdl_db_enter_ != NULL) {
+
+ wdl_db_enter_(_func_, _file_, _line_, _sfunc_, _sfile_,
+ _slevel_, _sframep_);
+ }
+}
+
+/**************************************************************//**
+Process exit from user function. It makes the call to _db_return_()
+in the server. */
+extern "C" UNIV_INTERN
+void
+_db_return_(
+ uint _line_, /*!< in: current source line number */
+ const char** _sfunc_, /*!< out: previous _func_ */
+ const char** _sfile_, /*!< out: previous _file_ */
+ uint* _slevel_) /*!< out: previous level */
+{
+ if (wdl_db_return_ != NULL) {
+
+ wdl_db_return_(_line_, _sfunc_, _sfile_, _slevel_);
+ }
+}
+
+/**************************************************************//**
+Log arguments for subsequent use. It makes the call to _db_pargs_()
+in the server. */
+extern "C" UNIV_INTERN
+void
+_db_pargs_(
+ uint _line_, /*!< in: current source line number */
+ const char* keyword) /*!< in: keyword for current macro */
+{
+ if (wdl_db_pargs_ != NULL) {
+
+ wdl_db_pargs_(_line_, keyword);
+ }
+}
+
+/**************************************************************//**
+Handle print of debug lines. It saves the text into a buffer first,
+then makes the call to _db_doprnt_() in the server. The text is
+truncated to the size of buffer. */
+extern "C" UNIV_INTERN
+void
+_db_doprnt_(
+ const char* format, /*!< in: the format string */
+ ...) /*!< in: list of arguments */
+{
+ va_list argp;
+ char buffer[512];
+
+ if (wdl_db_doprnt_ != NULL) {
+
+ va_start(argp, format);
+ /* it is ok to ignore the trunction. */
+ _vsnprintf(buffer, sizeof(buffer), format, argp);
+ wdl_db_doprnt_(buffer);
+ va_end(argp);
+ }
+}
+
+/**************************************************************//**
+Dump a string in hex. It makes the call to _db_dump_() in the server. */
+extern "C" UNIV_INTERN
+void
+_db_dump_(
+ uint _line_, /*!< in: current source line
+ number */
+ const char* keyword, /*!< in: keyword list */
+ const unsigned char* memory, /*!< in: memory to dump */
+ size_t length) /*!< in: bytes to dump */
+{
+ if (wdl_db_dump_ != NULL) {
+
+ wdl_db_dump_(_line_, keyword, memory, length);
+ }
+}
+
+#endif /* !DBUG_OFF */
+#endif /* defined (__WIN__) && defined (MYSQL_DYNAMIC_PLUGIN) */
diff --git a/storage/innodb_plugin/ibuf/ibuf0ibuf.c b/storage/innodb_plugin/ibuf/ibuf0ibuf.c
index d3f38760470..37c68391477 100644
--- a/storage/innodb_plugin/ibuf/ibuf0ibuf.c
+++ b/storage/innodb_plugin/ibuf/ibuf0ibuf.c
@@ -209,7 +209,7 @@ ibuf_count_check(
}
#endif
-/** Offsets in bits for the bits describing a single page in the bitmap */
+/** @name Offsets to the per-page bits in the insert buffer bitmap */
/* @{ */
#define IBUF_BITMAP_FREE 0 /*!< Bits indicating the
amount of free space */
@@ -1159,13 +1159,12 @@ ibuf_dummy_index_add_col(
dict_table_get_nth_col(index->table, i), len);
}
/********************************************************************//**
-Deallocates a dummy index for inserting a record to a non-clustered index.
-*/
+Deallocates a dummy index for inserting a record to a non-clustered index. */
static
void
ibuf_dummy_index_free(
/*==================*/
- dict_index_t* index) /*!< in: dummy index */
+ dict_index_t* index) /*!< in, own: dummy index */
{
dict_table_t* table = index->table;
diff --git a/storage/innodb_plugin/include/buf0buddy.h b/storage/innodb_plugin/include/buf0buddy.h
index 7eb5a388af9..7648950d5d1 100644
--- a/storage/innodb_plugin/include/buf0buddy.h
+++ b/storage/innodb_plugin/include/buf0buddy.h
@@ -76,6 +76,7 @@ struct buf_buddy_stat_struct {
ib_uint64_t relocated_usec;
};
+/** Statistics of buddy blocks of a given size. */
typedef struct buf_buddy_stat_struct buf_buddy_stat_t;
/** Statistics of the buddy system, indexed by block size.
diff --git a/storage/innodb_plugin/include/buf0buf.h b/storage/innodb_plugin/include/buf0buf.h
index 6d15350866c..65ad42c895a 100644
--- a/storage/innodb_plugin/include/buf0buf.h
+++ b/storage/innodb_plugin/include/buf0buf.h
@@ -36,7 +36,7 @@ Created 11/5/1995 Heikki Tuuri
#ifndef UNIV_HOTBACKUP
#include "os0proc.h"
-/** Modes for buf_page_get_gen */
+/** @name Modes for buf_page_get_gen */
/* @{ */
#define BUF_GET 10 /*!< get always */
#define BUF_GET_IF_IN_POOL 11 /*!< get if in pool */
@@ -47,7 +47,7 @@ Created 11/5/1995 Heikki Tuuri
not to set a latch, and it
should be used with care */
/* @} */
-/** Modes for buf_page_get_known_nowait */
+/** @name Modes for buf_page_get_known_nowait */
/* @{ */
#define BUF_MAKE_YOUNG 51 /*!< Move the block to the
start of the LRU list if there
@@ -242,7 +242,7 @@ buf_page_get_known_nowait(
Given a tablespace id and page number tries to get that page. If the
page is not in the buffer pool it is not loaded and NULL is returned.
Suitable for using when holding the kernel mutex. */
-
+UNIV_INTERN
const buf_block_t*
buf_page_try_get_func(
/*==================*/
@@ -252,6 +252,12 @@ buf_page_try_get_func(
ulint line, /*!< in: line where called */
mtr_t* mtr); /*!< in: mini-transaction */
+/** Tries to get a page. If the page is not in the buffer pool it is
+not loaded. Suitable for using when holding the kernel mutex.
+@param space_id in: tablespace id
+@param page_no in: page number
+@param mtr in: mini-transaction
+@return the page if in buffer pool, NULL if not */
#define buf_page_try_get(space_id, page_no, mtr) \
buf_page_try_get_func(space_id, page_no, __FILE__, __LINE__, mtr);
@@ -928,10 +934,16 @@ buf_pointer_is_block_field(
/*=======================*/
const void* ptr); /*!< in: pointer not
dereferenced */
-#define buf_pool_is_block_mutex(m) \
- buf_pointer_is_block_field((void *)(m))
-#define buf_pool_is_block_lock(l) \
- buf_pointer_is_block_field((void *)(l))
+/** Find out if a pointer corresponds to a buf_block_t::mutex.
+@param m in: mutex candidate
+@return TRUE if m is a buf_block_t::mutex */
+#define buf_pool_is_block_mutex(m) \
+ buf_pointer_is_block_field((const void*)(m))
+/** Find out if a pointer corresponds to a buf_block_t::lock.
+@param l in: rw-lock candidate
+@return TRUE if l is a buf_block_t::lock */
+#define buf_pool_is_block_lock(l) \
+ buf_pointer_is_block_field((const void*)(l))
#if defined UNIV_DEBUG || defined UNIV_ZIP_DEBUG
/*********************************************************************//**
@@ -945,15 +957,6 @@ buf_frame_get_page_zip(
const byte* ptr); /*!< in: pointer to the page */
#endif /* UNIV_DEBUG || UNIV_ZIP_DEBUG */
/********************************************************************//**
-This function is used to get info if there is an io operation
-going on on a buffer page.
-@return TRUE if io going on */
-UNIV_INLINE
-ibool
-buf_page_io_query(
-/*==============*/
- buf_page_t* bpage); /*!< in: pool block, must be bufferfixed */
-/********************************************************************//**
Function which inits a page for read to the buffer buf_pool. If the page is
(1) already in buf_pool, or
(2) if we specify to read only ibuf pages and the page is not an ibuf page, or
@@ -1036,10 +1039,12 @@ buf_get_free_list_len(void);
for compressed and uncompressed frames */
struct buf_page_struct{
- /** None of the following bit-fields must be modified without
- holding buf_page_get_mutex() [block->mutex or buf_pool_zip_mutex],
- since they can be stored in the same machine word. Some of them are
- additionally protected by buf_pool_mutex. */
+ /** @name General fields
+ None of these bit-fields must be modified without holding
+ buf_page_get_mutex() [buf_block_struct::mutex or
+ buf_pool_zip_mutex], since they can be stored in the same
+ machine word. Some of these fields are additionally protected
+ by buf_pool_mutex. */
/* @{ */
unsigned space:32; /*!< tablespace id; also protected
@@ -1084,8 +1089,8 @@ struct buf_page_struct{
ibool in_zip_hash; /*!< TRUE if in buf_pool->zip_hash */
#endif /* UNIV_DEBUG */
- /** @defgroup buf_page_flush Page flushing fields; protected
- by buf_pool_mutex */
+ /** @name Page flushing fields
+ All these are protected by buf_pool_mutex. */
/* @{ */
UT_LIST_NODE_T(buf_page_t) list;
@@ -1094,11 +1099,11 @@ struct buf_page_struct{
buf_pool_mutex, in one of the
following lists in buf_pool:
- BUF_BLOCK_NOT_USED: free
- BUF_BLOCK_FILE_PAGE: flush_list
- BUF_BLOCK_ZIP_DIRTY: flush_list
- BUF_BLOCK_ZIP_PAGE: zip_clean
- BUF_BLOCK_ZIP_FREE: zip_free[] */
+ - BUF_BLOCK_NOT_USED: free
+ - BUF_BLOCK_FILE_PAGE: flush_list
+ - BUF_BLOCK_ZIP_DIRTY: flush_list
+ - BUF_BLOCK_ZIP_PAGE: zip_clean
+ - BUF_BLOCK_ZIP_FREE: zip_free[] */
#ifdef UNIV_DEBUG
ibool in_flush_list; /*!< TRUE if in buf_pool->flush_list;
when buf_pool_mutex is free, the
@@ -1124,10 +1129,9 @@ struct buf_page_struct{
on disk; zero if all
modifications are on disk */
/* @} */
- /** @defgroup buf_LRU LRU replacement algorithm */
- /** @ingroup buf_LRU
- protected by buf_pool_mutex only (not buf_pool_zip_mutex or
- buf_block_struct::mutex) */
+ /** @name LRU replacement algorithm fields
+ These fields are protected by buf_pool_mutex only (not
+ buf_pool_zip_mutex or buf_block_struct::mutex). */
/* @{ */
UT_LIST_NODE_T(buf_page_t) LRU;
@@ -1158,11 +1162,11 @@ struct buf_page_struct{
purposes without holding any
mutex or latch */
/* @} */
-#ifdef UNIV_DEBUG_FILE_ACCESSES
+# ifdef UNIV_DEBUG_FILE_ACCESSES
ibool file_page_was_freed;
/*!< this is set to TRUE when fsp
frees a page in buffer pool */
-#endif /* UNIV_DEBUG_FILE_ACCESSES */
+# endif /* UNIV_DEBUG_FILE_ACCESSES */
#endif /* !UNIV_HOTBACKUP */
};
@@ -1170,7 +1174,7 @@ struct buf_page_struct{
struct buf_block_struct{
- /** @defgroup buf_block_general General fields */
+ /** @name General fields */
/* @{ */
buf_page_t page; /*!< page information; this must
@@ -1211,7 +1215,7 @@ struct buf_block_struct{
but this flag is not set because
we do not keep track of all pages */
/* @} */
- /** @defgroup buf_block_search Optimistic search field */
+ /** @name Optimistic search field */
/* @{ */
ib_uint64_t modify_clock; /*!< this clock is incremented every
@@ -1226,9 +1230,8 @@ struct buf_block_struct{
bufferfixed, or (2) the thread has an
x-latch on the block */
/* @} */
- /** @defgroup buf_block_hash Hash search fields */
- /** @ingroup buf_block_hash
- NOTE that the first 4 fields are NOT protected by any semaphore! */
+ /** @name Hash search fields (unprotected)
+ NOTE that these fields are NOT protected by any semaphore! */
/* @{ */
ulint n_hash_helps; /*!< counter which controls building
@@ -1243,11 +1246,11 @@ struct buf_block_struct{
indexed in the hash index */
/* @} */
- /** @ingroup buf_block_hash
+ /** @name Hash search fields
These 6 fields may only be modified when we have
an x-latch on btr_search_latch AND
- a) we are holding an s-latch or x-latch on buf_block_struct::lock or
- b) we know that buf_block_struct::buf_fix_count == 0.
+ - we are holding an s-latch or x-latch on buf_block_struct::lock or
+ - we know that buf_block_struct::buf_fix_count == 0.
An exception to this is when we init or create a page
in the buffer pool in buf0buf.c. */
@@ -1274,15 +1277,15 @@ struct buf_block_struct{
dict_index_t* index; /*!< Index for which the adaptive
hash index has been created. */
/* @} */
- /** Debug fields */
+# ifdef UNIV_SYNC_DEBUG
+ /** @name Debug fields */
/* @{ */
-#ifdef UNIV_SYNC_DEBUG
rw_lock_t debug_latch; /*!< in the debug version, each thread
which bufferfixes the block acquires
an s-latch here; so we can use the
debug utilities in sync0rw */
-#endif
/* @} */
+# endif
#endif /* !UNIV_HOTBACKUP */
};
@@ -1300,6 +1303,7 @@ Compute the hash fold value for blocks in buf_pool->zip_hash. */
#define BUF_POOL_ZIP_FOLD_PTR(ptr) ((ulint) (ptr) / UNIV_PAGE_SIZE)
#define BUF_POOL_ZIP_FOLD(b) BUF_POOL_ZIP_FOLD_PTR((b)->frame)
#define BUF_POOL_ZIP_FOLD_BPAGE(b) BUF_POOL_ZIP_FOLD((buf_block_t*) (b))
+/* @} */
/** @brief The buffer pool structure.
@@ -1308,7 +1312,7 @@ directory (buf) to see it. Do not use from outside! */
struct buf_pool_struct{
- /** @defgroup buf_pool_general General fields */
+ /** @name General fields */
/* @{ */
ulint n_chunks; /*!< number of buffer pool chunks */
@@ -1346,7 +1350,7 @@ struct buf_pool_struct{
ulint n_pages_created_old;/*!< number of pages created in
the pool with no read */
/* @} */
- /** @defgroup buf_pool_flush Page flushing algorithm fields */
+ /** @name Page flushing algorithm fields */
/* @{ */
UT_LIST_BASE_NODE_T(buf_page_t) flush_list;
@@ -1381,7 +1385,7 @@ struct buf_pool_struct{
allocated */
/* @} */
- /** @defgroup buf_LRU LRU replacement algorithm */
+ /** @name LRU replacement algorithm fields */
/* @{ */
UT_LIST_BASE_NODE_T(buf_page_t) free;
@@ -1408,7 +1412,10 @@ struct buf_pool_struct{
unzip_LRU list */
/* @} */
- /** @defgroup buf_buddy Buddy allocator of compressed pages */
+ /** @name Buddy allocator fields
+ The buddy allocator is used for allocating compressed page
+ frames and buf_page_t descriptors of blocks that exist
+ in the buffer pool only in compressed form. */
/* @{ */
UT_LIST_BASE_NODE_T(buf_page_t) zip_clean;
/*!< unmodified compressed pages */
@@ -1430,8 +1437,8 @@ extern mutex_t buf_pool_mutex;
(of type buf_page_t, not buf_block_t) */
extern mutex_t buf_pool_zip_mutex;
-/** Accessors for buf_pool_mutex. Use these instead of accessing
-buf_pool_mutex directly. */
+/** @name Accessors for buf_pool_mutex.
+Use these instead of accessing buf_pool_mutex directly. */
/* @{ */
/** Test if buf_pool_mutex is owned. */
diff --git a/storage/innodb_plugin/include/buf0buf.ic b/storage/innodb_plugin/include/buf0buf.ic
index 5a914fc0e98..17064342116 100644
--- a/storage/innodb_plugin/include/buf0buf.ic
+++ b/storage/innodb_plugin/include/buf0buf.ic
@@ -780,29 +780,6 @@ buf_page_address_fold(
}
/********************************************************************//**
-This function is used to get info if there is an io operation
-going on on a buffer page.
-@return TRUE if io going on */
-UNIV_INLINE
-ibool
-buf_page_io_query(
-/*==============*/
- buf_page_t* bpage) /*!< in: buf_pool block, must be bufferfixed */
-{
- ibool io_fixed;
-
- buf_pool_mutex_enter();
-
- ut_ad(buf_page_in_file(bpage));
- ut_ad(bpage->buf_fix_count > 0);
-
- io_fixed = buf_page_get_io_fix(bpage) != BUF_IO_NONE;
- buf_pool_mutex_exit();
-
- return(io_fixed);
-}
-
-/********************************************************************//**
Gets the youngest modification log sequence number for a frame.
Returns zero if not file page or no modification occurred yet.
@return newest modification to page */
diff --git a/storage/innodb_plugin/include/buf0flu.h b/storage/innodb_plugin/include/buf0flu.h
index 5f922959dcb..6c751852f54 100644
--- a/storage/innodb_plugin/include/buf0flu.h
+++ b/storage/innodb_plugin/include/buf0flu.h
@@ -127,6 +127,44 @@ buf_flush_ready_for_replace(
/*========================*/
buf_page_t* bpage); /*!< in: buffer control block, must be
buf_page_in_file(bpage) and in the LRU list */
+
+/** @brief Statistics for selecting flush rate based on redo log
+generation speed.
+
+These statistics are generated for heuristics used in estimating the
+rate at which we should flush the dirty blocks to avoid bursty IO
+activity. Note that the rate of flushing not only depends on how many
+dirty pages we have in the buffer pool but it is also a fucntion of
+how much redo the workload is generating and at what rate. */
+
+struct buf_flush_stat_struct
+{
+ ib_uint64_t redo; /**< amount of redo generated. */
+ ulint n_flushed; /**< number of pages flushed. */
+};
+
+/** Statistics for selecting flush rate of dirty pages. */
+typedef struct buf_flush_stat_struct buf_flush_stat_t;
+/*********************************************************************
+Update the historical stats that we are collecting for flush rate
+heuristics at the end of each interval. */
+UNIV_INTERN
+void
+buf_flush_stat_update(void);
+/*=======================*/
+/*********************************************************************
+Determines the fraction of dirty pages that need to be flushed based
+on the speed at which we generate redo log. Note that if redo log
+is generated at significant rate without a corresponding increase
+in the number of dirty pages (for example, an in-memory workload)
+it can cause IO bursts of flushing. This function implements heuristics
+to avoid this burstiness.
+@return number of dirty pages to be flushed / second */
+UNIV_INTERN
+ulint
+buf_flush_get_desired_flush_rate(void);
+/*==================================*/
+
#if defined UNIV_DEBUG || defined UNIV_BUF_DEBUG
/******************************************************************//**
Validates the flush list.
diff --git a/storage/innodb_plugin/include/buf0lru.h b/storage/innodb_plugin/include/buf0lru.h
index 32c61660d0f..463aca0982c 100644
--- a/storage/innodb_plugin/include/buf0lru.h
+++ b/storage/innodb_plugin/include/buf0lru.h
@@ -68,10 +68,10 @@ buf_LRU_buf_pool_running_out(void);
These are low-level functions
#########################################################################*/
-/* Minimum LRU list length for which the LRU_old pointer is defined */
-
+/** Minimum LRU list length for which the LRU_old pointer is defined */
#define BUF_LRU_OLD_MIN_LEN 80
+/** Maximum LRU list search length in buf_flush_LRU_recommendation() */
#define BUF_LRU_FREE_SEARCH_LEN (5 + 2 * BUF_READ_AHEAD_AREA)
/******************************************************************//**
@@ -227,18 +227,18 @@ buf_LRU_print(void);
/*===============*/
#endif /* UNIV_DEBUG_PRINT || UNIV_DEBUG || UNIV_BUF_DEBUG */
-/******************************************************************//**
+/** @brief Statistics for selecting the LRU list for eviction.
+
These statistics are not 'of' LRU but 'for' LRU. We keep count of I/O
and page_zip_decompress() operations. Based on the statistics we decide
if we want to evict from buf_pool->unzip_LRU or buf_pool->LRU. */
-
-/** Statistics for selecting the LRU list for eviction. */
struct buf_LRU_stat_struct
{
ulint io; /**< Counter of buffer pool I/O operations. */
ulint unzip; /**< Counter of page_zip_decompress operations. */
};
+/** Statistics for selecting the LRU list for eviction. */
typedef struct buf_LRU_stat_struct buf_LRU_stat_t;
/** Current operation counters. Not protected by any mutex.
diff --git a/storage/innodb_plugin/include/buf0rea.h b/storage/innodb_plugin/include/buf0rea.h
index 781f99f2fa3..b4d25e6fde0 100644
--- a/storage/innodb_plugin/include/buf0rea.h
+++ b/storage/innodb_plugin/include/buf0rea.h
@@ -124,14 +124,16 @@ buf_read_recv_pages(
ulint n_stored); /*!< in: number of page numbers
in the array */
-/* The size in pages of the area which the read-ahead algorithms read if
+/** The size in pages of the area which the read-ahead algorithms read if
invoked */
-
#define BUF_READ_AHEAD_AREA \
ut_min(64, ut_2_power_up(buf_pool->curr_size / 32))
-/* Modes used in read-ahead */
+/** @name Modes used in read-ahead @{ */
+/** read only pages belonging to the insert buffer tree */
#define BUF_READ_IBUF_PAGES_ONLY 131
+/** read any page */
#define BUF_READ_ANY_PAGE 132
+/* @} */
#endif
diff --git a/storage/innodb_plugin/include/data0type.h b/storage/innodb_plugin/include/data0type.h
index d101b9a186a..a73bed3a9f5 100644
--- a/storage/innodb_plugin/include/data0type.h
+++ b/storage/innodb_plugin/include/data0type.h
@@ -278,7 +278,8 @@ dtype_get_mblen(
ulint* mbmaxlen); /*!< out: maximum length of a
multi-byte character */
/*********************************************************************//**
-Gets the MySQL charset-collation code for MySQL string types. */
+Gets the MySQL charset-collation code for MySQL string types.
+@return MySQL charset-collation code */
UNIV_INLINE
ulint
dtype_get_charset_coll(
@@ -286,7 +287,8 @@ dtype_get_charset_coll(
ulint prtype);/*!< in: precise data type */
/*********************************************************************//**
Forms a precise type from the < 4.1.2 format precise type plus the
-charset-collation code. */
+charset-collation code.
+@return precise type, including the charset-collation code */
UNIV_INTERN
ulint
dtype_form_prtype(
diff --git a/storage/innodb_plugin/include/data0type.ic b/storage/innodb_plugin/include/data0type.ic
index f53ad25b6d2..240b4288f39 100644
--- a/storage/innodb_plugin/include/data0type.ic
+++ b/storage/innodb_plugin/include/data0type.ic
@@ -28,7 +28,8 @@ Created 1/16/1996 Heikki Tuuri
# include "ha_prototypes.h"
/*********************************************************************//**
-Gets the MySQL charset-collation code for MySQL string types. */
+Gets the MySQL charset-collation code for MySQL string types.
+@return MySQL charset-collation code */
UNIV_INLINE
ulint
dtype_get_charset_coll(
diff --git a/storage/innodb_plugin/include/fsp0fsp.h b/storage/innodb_plugin/include/fsp0fsp.h
index d6c61b1338f..5f7dc58eedc 100644
--- a/storage/innodb_plugin/include/fsp0fsp.h
+++ b/storage/innodb_plugin/include/fsp0fsp.h
@@ -32,37 +32,7 @@ Created 12/18/1995 Heikki Tuuri
#include "fut0lst.h"
#include "ut0byte.h"
#include "page0types.h"
-
-/** If records are inserted in order, there are the following
-flags to tell this (their type is made byte for the compiler
-to warn if direction and hint parameters are switched in
-fseg_alloc_free_page): */
-/* @{ */
-#define FSP_UP ((byte)111) /*!< alphabetically upwards */
-#define FSP_DOWN ((byte)112) /*!< alphabetically downwards */
-#define FSP_NO_DIR ((byte)113) /*!< no order */
-/* @} */
-
-/** File space extent size (one megabyte) in pages */
-#define FSP_EXTENT_SIZE (1 << (20 - UNIV_PAGE_SIZE_SHIFT))
-
-/** On a page of any file segment, data may be put starting from this
-offset */
-#define FSEG_PAGE_DATA FIL_PAGE_DATA
-
-/** File segment header which points to the inode describing the file
-segment */
-/* @{ */
-/** Data type for file segment header */
-typedef byte fseg_header_t;
-
-#define FSEG_HDR_SPACE 0 /*!< space id of the inode */
-#define FSEG_HDR_PAGE_NO 4 /*!< page number of the inode */
-#define FSEG_HDR_OFFSET 8 /*!< byte offset of the inode */
-
-#define FSEG_HEADER_SIZE 10 /*!< Length of the file system
- header, in bytes */
-/* @} */
+#include "fsp0types.h"
/**********************************************************************//**
Initializes the file space system. */
@@ -299,20 +269,6 @@ fseg_free_page(
ulint space, /*!< in: space id */
ulint page, /*!< in: page offset */
mtr_t* mtr); /*!< in: mtr handle */
-/*******************************************************************//**
-Frees a segment. The freeing is performed in several mini-transactions,
-so that there is no danger of bufferfixing too many buffer pages. */
-UNIV_INTERN
-void
-fseg_free(
-/*======*/
- ulint space, /*!< in: space id */
- ulint zip_size,/*!< in: compressed page size in bytes
- or 0 for uncompressed pages */
- ulint page_no,/*!< in: page number where the segment header is
- placed */
- ulint offset);/*!< in: byte offset of the segment header on that
- page */
/**********************************************************************//**
Frees part of a segment. This function can be used to free a segment
by repeatedly calling this function in different mini-transactions.
@@ -374,6 +330,7 @@ void
fsp_print(
/*======*/
ulint space); /*!< in: space id */
+#ifdef UNIV_DEBUG
/*******************************************************************//**
Validates a segment.
@return TRUE if ok */
@@ -382,7 +339,8 @@ ibool
fseg_validate(
/*==========*/
fseg_header_t* header, /*!< in: segment header */
- mtr_t* mtr2); /*!< in: mtr */
+ mtr_t* mtr); /*!< in: mtr */
+#endif /* UNIV_DEBUG */
#ifdef UNIV_BTR_PRINT
/*******************************************************************//**
Writes info of a segment. */
@@ -394,41 +352,6 @@ fseg_print(
mtr_t* mtr); /*!< in: mtr */
#endif /* UNIV_BTR_PRINT */
-/* Flags for fsp_reserve_free_extents */
-#define FSP_NORMAL 1000000
-#define FSP_UNDO 2000000
-#define FSP_CLEANING 3000000
-
-/* Number of pages described in a single descriptor page: currently each page
-description takes less than 1 byte; a descriptor page is repeated every
-this many file pages */
-/* #define XDES_DESCRIBED_PER_PAGE UNIV_PAGE_SIZE */
-/* This has been replaced with either UNIV_PAGE_SIZE or page_zip->size. */
-
-/* The space low address page map */
-/*--------------------------------------*/
- /* The following two pages are repeated
- every XDES_DESCRIBED_PER_PAGE pages in
- every tablespace. */
-#define FSP_XDES_OFFSET 0 /* extent descriptor */
-#define FSP_IBUF_BITMAP_OFFSET 1 /* insert buffer bitmap */
- /* The ibuf bitmap pages are the ones whose
- page number is the number above plus a
- multiple of XDES_DESCRIBED_PER_PAGE */
-
-#define FSP_FIRST_INODE_PAGE_NO 2 /* in every tablespace */
- /* The following pages exist
- in the system tablespace (space 0). */
-#define FSP_IBUF_HEADER_PAGE_NO 3 /* in tablespace 0 */
-#define FSP_IBUF_TREE_ROOT_PAGE_NO 4 /* in tablespace 0 */
- /* The ibuf tree root page number in
- tablespace 0; its fseg inode is on the page
- number FSP_FIRST_INODE_PAGE_NO */
-#define FSP_TRX_SYS_PAGE_NO 5 /* in tablespace 0 */
-#define FSP_FIRST_RSEG_PAGE_NO 6 /* in tablespace 0 */
-#define FSP_DICT_HDR_PAGE_NO 7 /* in tablespace 0 */
-/*--------------------------------------*/
-
#ifndef UNIV_NONINL
#include "fsp0fsp.ic"
#endif
diff --git a/storage/innodb_plugin/include/fsp0types.h b/storage/innodb_plugin/include/fsp0types.h
new file mode 100644
index 00000000000..496081c2346
--- /dev/null
+++ b/storage/innodb_plugin/include/fsp0types.h
@@ -0,0 +1,110 @@
+/*****************************************************************************
+
+Copyright (c) 1995, 2009, Innobase Oy. All Rights Reserved.
+
+This program is free software; you can redistribute it and/or modify it under
+the terms of the GNU General Public License as published by the Free Software
+Foundation; version 2 of the License.
+
+This program is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License along with
+this program; if not, write to the Free Software Foundation, Inc., 59 Temple
+Place, Suite 330, Boston, MA 02111-1307 USA
+
+*****************************************************************************/
+
+/******************************************************
+@file include/fsp0types.h
+File space management types
+
+Created May 26, 2009 Vasil Dimov
+*******************************************************/
+
+#ifndef fsp0types_h
+#define fsp0types_h
+
+#include "univ.i"
+
+#include "fil0fil.h" /* for FIL_PAGE_DATA */
+
+/** @name Flags for inserting records in order
+If records are inserted in order, there are the following
+flags to tell this (their type is made byte for the compiler
+to warn if direction and hint parameters are switched in
+fseg_alloc_free_page) */
+/* @{ */
+#define FSP_UP ((byte)111) /*!< alphabetically upwards */
+#define FSP_DOWN ((byte)112) /*!< alphabetically downwards */
+#define FSP_NO_DIR ((byte)113) /*!< no order */
+/* @} */
+
+/** File space extent size (one megabyte) in pages */
+#define FSP_EXTENT_SIZE (1 << (20 - UNIV_PAGE_SIZE_SHIFT))
+
+/** On a page of any file segment, data may be put starting from this
+offset */
+#define FSEG_PAGE_DATA FIL_PAGE_DATA
+
+/** @name File segment header
+The file segment header points to the inode describing the file segment. */
+/* @{ */
+/** Data type for file segment header */
+typedef byte fseg_header_t;
+
+#define FSEG_HDR_SPACE 0 /*!< space id of the inode */
+#define FSEG_HDR_PAGE_NO 4 /*!< page number of the inode */
+#define FSEG_HDR_OFFSET 8 /*!< byte offset of the inode */
+
+#define FSEG_HEADER_SIZE 10 /*!< Length of the file system
+ header, in bytes */
+/* @} */
+
+/** Flags for fsp_reserve_free_extents @{ */
+#define FSP_NORMAL 1000000
+#define FSP_UNDO 2000000
+#define FSP_CLEANING 3000000
+/* @} */
+
+/* Number of pages described in a single descriptor page: currently each page
+description takes less than 1 byte; a descriptor page is repeated every
+this many file pages */
+/* #define XDES_DESCRIBED_PER_PAGE UNIV_PAGE_SIZE */
+/* This has been replaced with either UNIV_PAGE_SIZE or page_zip->size. */
+
+/** @name The space low address page map
+The pages at FSP_XDES_OFFSET and FSP_IBUF_BITMAP_OFFSET are repeated
+every XDES_DESCRIBED_PER_PAGE pages in every tablespace. */
+/* @{ */
+/*--------------------------------------*/
+#define FSP_XDES_OFFSET 0 /* !< extent descriptor */
+#define FSP_IBUF_BITMAP_OFFSET 1 /* !< insert buffer bitmap */
+ /* The ibuf bitmap pages are the ones whose
+ page number is the number above plus a
+ multiple of XDES_DESCRIBED_PER_PAGE */
+
+#define FSP_FIRST_INODE_PAGE_NO 2 /*!< in every tablespace */
+ /* The following pages exist
+ in the system tablespace (space 0). */
+#define FSP_IBUF_HEADER_PAGE_NO 3 /*!< insert buffer
+ header page, in
+ tablespace 0 */
+#define FSP_IBUF_TREE_ROOT_PAGE_NO 4 /*!< insert buffer
+ B-tree root page in
+ tablespace 0 */
+ /* The ibuf tree root page number in
+ tablespace 0; its fseg inode is on the page
+ number FSP_FIRST_INODE_PAGE_NO */
+#define FSP_TRX_SYS_PAGE_NO 5 /*!< transaction
+ system header, in
+ tablespace 0 */
+#define FSP_FIRST_RSEG_PAGE_NO 6 /*!< first rollback segment
+ page, in tablespace 0 */
+#define FSP_DICT_HDR_PAGE_NO 7 /*!< data dictionary header
+ page, in tablespace 0 */
+/*--------------------------------------*/
+/* @} */
+
+#endif /* fsp0types_h */
diff --git a/storage/innodb_plugin/include/ha0ha.h b/storage/innodb_plugin/include/ha0ha.h
index f4ec01dd88a..1ffbd3440aa 100644
--- a/storage/innodb_plugin/include/ha0ha.h
+++ b/storage/innodb_plugin/include/ha0ha.h
@@ -164,16 +164,6 @@ is inserted.
# define ha_insert_for_fold(t,f,b,d) ha_insert_for_fold_func(t,f,d)
#endif /* UNIV_AHI_DEBUG || UNIV_DEBUG */
-/*************************************************************//**
-Deletes an entry from a hash table. */
-UNIV_INTERN
-void
-ha_delete(
-/*======*/
- hash_table_t* table, /*!< in: hash table */
- ulint fold, /*!< in: folded value of data */
- void* data); /*!< in: data, must not be NULL and must exist
- in the hash table */
/*********************************************************//**
Looks for an element when we know the pointer to the data and deletes
it from the hash table if found.
diff --git a/storage/innodb_plugin/include/lock0lock.h b/storage/innodb_plugin/include/lock0lock.h
index 727e30d49dd..fa5db831d4f 100644
--- a/storage/innodb_plugin/include/lock0lock.h
+++ b/storage/innodb_plugin/include/lock0lock.h
@@ -461,14 +461,6 @@ lock_table(
dict_table_t* table, /*!< in: database table in dictionary cache */
enum lock_mode mode, /*!< in: lock mode */
que_thr_t* thr); /*!< in: query thread */
-/*********************************************************************//**
-Checks if there are any locks set on the table.
-@return TRUE if there are lock(s) */
-UNIV_INTERN
-ibool
-lock_is_on_table(
-/*=============*/
- dict_table_t* table); /*!< in: database table in dictionary cache */
/*************************************************************//**
Removes a granted record lock of a transaction from the queue and grants
locks to other transactions waiting in the queue if they now are entitled
@@ -483,14 +475,6 @@ lock_rec_unlock(
const rec_t* rec, /*!< in: record */
enum lock_mode lock_mode);/*!< in: LOCK_S or LOCK_X */
/*********************************************************************//**
-Releases a table lock.
-Releases possible other transactions waiting for this lock. */
-UNIV_INTERN
-void
-lock_table_unlock(
-/*==============*/
- lock_t* lock); /*!< in: lock */
-/*********************************************************************//**
Releases transaction locks, and releases possible other transactions waiting
because of these locks. */
UNIV_INTERN
diff --git a/storage/innodb_plugin/include/log0log.h b/storage/innodb_plugin/include/log0log.h
index b6e01539d61..059f548a085 100644
--- a/storage/innodb_plugin/include/log0log.h
+++ b/storage/innodb_plugin/include/log0log.h
@@ -15,6 +15,30 @@ this program; if not, write to the Free Software Foundation, Inc., 59 Temple
Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
+/*****************************************************************************
+
+Copyright (c) 1995, 2009, Innobase Oy. All Rights Reserved.
+Copyright (c) 2009, Google Inc.
+
+Portions of this file contain modifications contributed and copyrighted by
+Google, Inc. Those modifications are gratefully acknowledged and are described
+briefly in the InnoDB documentation. The contributions by Google are
+incorporated with their permission, and subject to the conditions contained in
+the file COPYING.Google.
+
+This program is free software; you can redistribute it and/or modify it under
+the terms of the GNU General Public License as published by the Free Software
+Foundation; version 2 of the License.
+
+This program is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License along with
+this program; if not, write to the Free Software Foundation, Inc., 59 Temple
+Place, Suite 330, Boston, MA 02111-1307 USA
+
+*****************************************************************************/
/**************************************************//**
@file include/log0log.h
@@ -145,6 +169,14 @@ UNIV_INLINE
ib_uint64_t
log_get_lsn(void);
/*=============*/
+/****************************************************************
+Gets the log group capacity. It is OK to read the value without
+holding log_sys->mutex because it is constant.
+@return log group capacity */
+UNIV_INLINE
+ulint
+log_get_capacity(void);
+/*==================*/
/******************************************************//**
Initializes the log. */
UNIV_INTERN
@@ -199,6 +231,16 @@ void
log_buffer_flush_to_disk(void);
/*==========================*/
/****************************************************************//**
+This functions writes the log buffer to the log file and if 'flush'
+is set it forces a flush of the log file as well. This is meant to be
+called from background master thread only as it does not wait for
+the write (+ possible flush) to finish. */
+UNIV_INTERN
+void
+log_buffer_sync_in_background(
+/*==========================*/
+ ibool flush); /*<! in: flush the logs to disk */
+/****************************************************************//**
Advances the smallest lsn for which there are unflushed dirty blocks in the
buffer pool and also may make a new checkpoint. NOTE: this function may only
be called if the calling thread owns no synchronization objects!
diff --git a/storage/innodb_plugin/include/log0log.ic b/storage/innodb_plugin/include/log0log.ic
index fc0769cd963..d071985982a 100644
--- a/storage/innodb_plugin/include/log0log.ic
+++ b/storage/innodb_plugin/include/log0log.ic
@@ -385,6 +385,18 @@ log_get_lsn(void)
return(lsn);
}
+/****************************************************************
+Gets the log group capacity. It is OK to read the value without
+holding log_sys->mutex because it is constant.
+@return log group capacity */
+UNIV_INLINE
+ulint
+log_get_capacity(void)
+/*==================*/
+{
+ return(log_sys->log_group_capacity);
+}
+
/***********************************************************************//**
Checks if there is need for a log buffer flush or a new checkpoint, and does
this if yes. Any database operation should call this when it has modified
diff --git a/storage/innodb_plugin/include/mem0mem.h b/storage/innodb_plugin/include/mem0mem.h
index f52e1093363..a092b024219 100644
--- a/storage/innodb_plugin/include/mem0mem.h
+++ b/storage/innodb_plugin/include/mem0mem.h
@@ -312,19 +312,6 @@ mem_heap_dup(
const void* data, /*!< in: data to be copied */
ulint len); /*!< in: length of data, in bytes */
-/**********************************************************************//**
-Concatenate two memory blocks and return the result, using a memory heap.
-@return own: the result */
-UNIV_INTERN
-void*
-mem_heap_cat(
-/*=========*/
- mem_heap_t* heap, /*!< in: memory heap where result is allocated */
- const void* b1, /*!< in: block 1 */
- ulint len1, /*!< in: length of b1, in bytes */
- const void* b2, /*!< in: block 2 */
- ulint len2); /*!< in: length of b2, in bytes */
-
/****************************************************************//**
A simple (s)printf replacement that dynamically allocates the space for the
formatted string from the given heap. This supports a very limited set of
diff --git a/storage/innodb_plugin/include/mtr0log.h b/storage/innodb_plugin/include/mtr0log.h
index 0ed89d0a0a0..6322af2a569 100644
--- a/storage/innodb_plugin/include/mtr0log.h
+++ b/storage/innodb_plugin/include/mtr0log.h
@@ -168,7 +168,7 @@ mlog_write_initial_log_record_fast(
mtr_t* mtr); /*!< in: mtr */
#else /* !UNIV_HOTBACKUP */
# define mlog_write_initial_log_record(ptr,type,mtr) ((void) 0)
-# define mlog_write_initial_log_record_fast(ptr,type,log_ptr,mtr) ((void) 0)
+# define mlog_write_initial_log_record_fast(ptr,type,log_ptr,mtr) ((byte *) 0)
#endif /* !UNIV_HOTBACKUP */
/********************************************************//**
Parses an initial log record written by mlog_write_initial_log_record.
@@ -218,7 +218,7 @@ byte*
mlog_open_and_write_index(
/*======================*/
mtr_t* mtr, /*!< in: mtr */
- byte* rec, /*!< in: index record or page */
+ const byte* rec, /*!< in: index record or page */
dict_index_t* index, /*!< in: record descriptor */
byte type, /*!< in: log item type */
ulint size); /*!< in: requested buffer size in bytes
diff --git a/storage/innodb_plugin/include/mtr0log.ic b/storage/innodb_plugin/include/mtr0log.ic
index 646b329fa1b..5c24c38b337 100644
--- a/storage/innodb_plugin/include/mtr0log.ic
+++ b/storage/innodb_plugin/include/mtr0log.ic
@@ -23,10 +23,11 @@ Mini-transaction logging routines
Created 12/7/1995 Heikki Tuuri
*******************************************************/
-#ifndef UNIV_HOTBACKUP
#include "mach0data.h"
#include "ut0lst.h"
#include "buf0buf.h"
+#include "fsp0types.h"
+#include "trx0sys.h"
/********************************************************//**
Opens a buffer to mlog. It must be closed with mlog_close.
@@ -71,6 +72,7 @@ mlog_close(
dyn_array_close(mlog, ptr);
}
+#ifndef UNIV_HOTBACKUP
/********************************************************//**
Catenates 1 - 4 bytes to the mtr log. The value is not compressed. */
UNIV_INLINE
@@ -195,6 +197,28 @@ mlog_write_initial_log_record_fast(
space = mach_read_from_4(page + FIL_PAGE_ARCH_LOG_NO_OR_SPACE_ID);
offset = mach_read_from_4(page + FIL_PAGE_OFFSET);
+ /* check whether the page is in the doublewrite buffer;
+ the doublewrite buffer is located in pages
+ FSP_EXTENT_SIZE, ..., 3 * FSP_EXTENT_SIZE - 1 in the
+ system tablespace */
+ if (space == TRX_SYS_SPACE
+ && offset >= FSP_EXTENT_SIZE && offset < 3 * FSP_EXTENT_SIZE) {
+ if (trx_doublewrite_buf_is_being_created) {
+ /* Do nothing: we only come to this branch in an
+ InnoDB database creation. We do not redo log
+ anything for the doublewrite buffer pages. */
+ return(log_ptr);
+ } else {
+ fprintf(stderr,
+ "Error: trying to redo log a record of type "
+ "%d on page %lu of space %lu in the "
+ "doublewrite buffer, continuing anyway.\n"
+ "Please post a bug report to "
+ "bugs.mysql.com.\n",
+ type, offset, space);
+ }
+ }
+
mach_write_to_1(log_ptr, type);
log_ptr++;
log_ptr += mach_write_compressed(log_ptr, space);
diff --git a/storage/innodb_plugin/include/mtr0mtr.h b/storage/innodb_plugin/include/mtr0mtr.h
index 1e9b78c3356..69a2c03f4cb 100644
--- a/storage/innodb_plugin/include/mtr0mtr.h
+++ b/storage/innodb_plugin/include/mtr0mtr.h
@@ -54,118 +54,137 @@ first 3 values must be RW_S_LATCH, RW_X_LATCH, RW_NO_LATCH */
#define MTR_MEMO_S_LOCK 55
#define MTR_MEMO_X_LOCK 56
-/* Log item types: we have made them to be of the type 'byte'
-for the compiler to warn if val and type parameters are switched
-in a call to mlog_write_ulint. NOTE! For 1 - 8 bytes, the
-flag value must give the length also! */
-#define MLOG_SINGLE_REC_FLAG 128 /* if the mtr contains only
+/** @name Log item types
+The log items are declared 'byte' so that the compiler can warn if val
+and type parameters are switched in a call to mlog_write_ulint. NOTE!
+For 1 - 8 bytes, the flag value must give the length also! @{ */
+#define MLOG_SINGLE_REC_FLAG 128 /*!< if the mtr contains only
one log record for one page,
i.e., write_initial_log_record
has been called only once,
this flag is ORed to the type
of that first log record */
-#define MLOG_1BYTE (1) /* one byte is written */
-#define MLOG_2BYTES (2) /* 2 bytes ... */
-#define MLOG_4BYTES (4) /* 4 bytes ... */
-#define MLOG_8BYTES (8) /* 8 bytes ... */
-#define MLOG_REC_INSERT ((byte)9) /* record insert */
-#define MLOG_REC_CLUST_DELETE_MARK ((byte)10) /* mark clustered index record
+#define MLOG_1BYTE (1) /*!< one byte is written */
+#define MLOG_2BYTES (2) /*!< 2 bytes ... */
+#define MLOG_4BYTES (4) /*!< 4 bytes ... */
+#define MLOG_8BYTES (8) /*!< 8 bytes ... */
+#define MLOG_REC_INSERT ((byte)9) /*!< record insert */
+#define MLOG_REC_CLUST_DELETE_MARK ((byte)10) /*!< mark clustered index record
deleted */
-#define MLOG_REC_SEC_DELETE_MARK ((byte)11) /* mark secondary index record
+#define MLOG_REC_SEC_DELETE_MARK ((byte)11) /*!< mark secondary index record
deleted */
-#define MLOG_REC_UPDATE_IN_PLACE ((byte)13) /* update of a record,
+#define MLOG_REC_UPDATE_IN_PLACE ((byte)13) /*!< update of a record,
preserves record field sizes */
-#define MLOG_REC_DELETE ((byte)14) /* delete a record from a
+#define MLOG_REC_DELETE ((byte)14) /*!< delete a record from a
page */
-#define MLOG_LIST_END_DELETE ((byte)15) /* delete record list end on
+#define MLOG_LIST_END_DELETE ((byte)15) /*!< delete record list end on
index page */
-#define MLOG_LIST_START_DELETE ((byte)16) /* delete record list start on
+#define MLOG_LIST_START_DELETE ((byte)16) /*!< delete record list start on
index page */
-#define MLOG_LIST_END_COPY_CREATED ((byte)17) /* copy record list end to a
+#define MLOG_LIST_END_COPY_CREATED ((byte)17) /*!< copy record list end to a
new created index page */
-#define MLOG_PAGE_REORGANIZE ((byte)18) /* reorganize an index page */
-#define MLOG_PAGE_CREATE ((byte)19) /* create an index page */
-#define MLOG_UNDO_INSERT ((byte)20) /* insert entry in an undo
+#define MLOG_PAGE_REORGANIZE ((byte)18) /*!< reorganize an
+ index page in
+ ROW_FORMAT=REDUNDANT */
+#define MLOG_PAGE_CREATE ((byte)19) /*!< create an index page */
+#define MLOG_UNDO_INSERT ((byte)20) /*!< insert entry in an undo
log */
-#define MLOG_UNDO_ERASE_END ((byte)21) /* erase an undo log
+#define MLOG_UNDO_ERASE_END ((byte)21) /*!< erase an undo log
page end */
-#define MLOG_UNDO_INIT ((byte)22) /* initialize a page in an
+#define MLOG_UNDO_INIT ((byte)22) /*!< initialize a page in an
undo log */
-#define MLOG_UNDO_HDR_DISCARD ((byte)23) /* discard an update undo log
+#define MLOG_UNDO_HDR_DISCARD ((byte)23) /*!< discard an update undo log
header */
-#define MLOG_UNDO_HDR_REUSE ((byte)24) /* reuse an insert undo log
+#define MLOG_UNDO_HDR_REUSE ((byte)24) /*!< reuse an insert undo log
header */
-#define MLOG_UNDO_HDR_CREATE ((byte)25) /* create an undo log header */
-#define MLOG_REC_MIN_MARK ((byte)26) /* mark an index record as the
- predefined minimum record */
-#define MLOG_IBUF_BITMAP_INIT ((byte)27) /* initialize an ibuf bitmap
- page */
+#define MLOG_UNDO_HDR_CREATE ((byte)25) /*!< create an undo
+ log header */
+#define MLOG_REC_MIN_MARK ((byte)26) /*!< mark an index
+ record as the
+ predefined minimum
+ record */
+#define MLOG_IBUF_BITMAP_INIT ((byte)27) /*!< initialize an
+ ibuf bitmap page */
/*#define MLOG_FULL_PAGE ((byte)28) full contents of a page */
-#define MLOG_INIT_FILE_PAGE ((byte)29) /* this means that a file page
- is taken into use and the prior
- contents of the page should be
- ignored: in recovery we must
- not trust the lsn values stored
- to the file page */
-#define MLOG_WRITE_STRING ((byte)30) /* write a string to a page */
-#define MLOG_MULTI_REC_END ((byte)31) /* if a single mtr writes
+#define MLOG_INIT_FILE_PAGE ((byte)29) /*!< this means that a
+ file page is taken
+ into use and the prior
+ contents of the page
+ should be ignored: in
+ recovery we must not
+ trust the lsn values
+ stored to the file
+ page */
+#define MLOG_WRITE_STRING ((byte)30) /*!< write a string to
+ a page */
+#define MLOG_MULTI_REC_END ((byte)31) /*!< if a single mtr writes
log records for several pages,
this log record ends the
sequence of these records */
-#define MLOG_DUMMY_RECORD ((byte)32) /* dummy log record used to
+#define MLOG_DUMMY_RECORD ((byte)32) /*!< dummy log record used to
pad a log block full */
-#define MLOG_FILE_CREATE ((byte)33) /* log record about an .ibd
+#define MLOG_FILE_CREATE ((byte)33) /*!< log record about an .ibd
file creation */
-#define MLOG_FILE_RENAME ((byte)34) /* log record about an .ibd
+#define MLOG_FILE_RENAME ((byte)34) /*!< log record about an .ibd
file rename */
-#define MLOG_FILE_DELETE ((byte)35) /* log record about an .ibd
+#define MLOG_FILE_DELETE ((byte)35) /*!< log record about an .ibd
file deletion */
-#define MLOG_COMP_REC_MIN_MARK ((byte)36) /* mark a compact index record
- as the predefined minimum
+#define MLOG_COMP_REC_MIN_MARK ((byte)36) /*!< mark a compact
+ index record as the
+ predefined minimum
record */
-#define MLOG_COMP_PAGE_CREATE ((byte)37) /* create a compact
+#define MLOG_COMP_PAGE_CREATE ((byte)37) /*!< create a compact
index page */
-#define MLOG_COMP_REC_INSERT ((byte)38) /* compact record insert */
+#define MLOG_COMP_REC_INSERT ((byte)38) /*!< compact record insert */
#define MLOG_COMP_REC_CLUST_DELETE_MARK ((byte)39)
- /* mark compact clustered index
- record deleted */
-#define MLOG_COMP_REC_SEC_DELETE_MARK ((byte)40)/* mark compact secondary index
- record deleted; this log
- record type is redundant, as
- MLOG_REC_SEC_DELETE_MARK is
- independent of the record
- format. */
-#define MLOG_COMP_REC_UPDATE_IN_PLACE ((byte)41)/* update of a compact record,
- preserves record field sizes */
-#define MLOG_COMP_REC_DELETE ((byte)42) /* delete a compact record
+ /*!< mark compact
+ clustered index record
+ deleted */
+#define MLOG_COMP_REC_SEC_DELETE_MARK ((byte)40)/*!< mark compact
+ secondary index record
+ deleted; this log
+ record type is
+ redundant, as
+ MLOG_REC_SEC_DELETE_MARK
+ is independent of the
+ record format. */
+#define MLOG_COMP_REC_UPDATE_IN_PLACE ((byte)41)/*!< update of a
+ compact record,
+ preserves record field
+ sizes */
+#define MLOG_COMP_REC_DELETE ((byte)42) /*!< delete a compact record
from a page */
-#define MLOG_COMP_LIST_END_DELETE ((byte)43) /* delete compact record list
+#define MLOG_COMP_LIST_END_DELETE ((byte)43) /*!< delete compact record list
end on index page */
-#define MLOG_COMP_LIST_START_DELETE ((byte)44) /* delete compact record list
+#define MLOG_COMP_LIST_START_DELETE ((byte)44) /*!< delete compact record list
start on index page */
#define MLOG_COMP_LIST_END_COPY_CREATED ((byte)45)
- /* copy compact record list end
- to a new created index page */
-#define MLOG_COMP_PAGE_REORGANIZE ((byte)46) /* reorganize an index page */
-#define MLOG_FILE_CREATE2 ((byte)47) /* log record about creating
+ /*!< copy compact
+ record list end to a
+ new created index
+ page */
+#define MLOG_COMP_PAGE_REORGANIZE ((byte)46) /*!< reorganize an index page */
+#define MLOG_FILE_CREATE2 ((byte)47) /*!< log record about creating
an .ibd file, with format */
-#define MLOG_ZIP_WRITE_NODE_PTR ((byte)48) /* write the node pointer of
+#define MLOG_ZIP_WRITE_NODE_PTR ((byte)48) /*!< write the node pointer of
a record on a compressed
non-leaf B-tree page */
-#define MLOG_ZIP_WRITE_BLOB_PTR ((byte)49) /* write the BLOB pointer
+#define MLOG_ZIP_WRITE_BLOB_PTR ((byte)49) /*!< write the BLOB pointer
of an externally stored column
on a compressed page */
-#define MLOG_ZIP_WRITE_HEADER ((byte)50) /* write to compressed page
+#define MLOG_ZIP_WRITE_HEADER ((byte)50) /*!< write to compressed page
header */
-#define MLOG_ZIP_PAGE_COMPRESS ((byte)51) /* compress an index page */
-#define MLOG_BIGGEST_TYPE ((byte)51) /* biggest value (used in
- asserts) */
+#define MLOG_ZIP_PAGE_COMPRESS ((byte)51) /*!< compress an index page */
+#define MLOG_BIGGEST_TYPE ((byte)51) /*!< biggest value (used in
+ assertions) */
+/* @} */
-/* Flags for MLOG_FILE operations (stored in the page number
-parameter, called log_flags in the functions). The page number
-parameter was initially written as 0. */
-#define MLOG_FILE_FLAG_TEMP 1 /* identifies TEMPORARY TABLE in
+/** @name Flags for MLOG_FILE operations
+(stored in the page number parameter, called log_flags in the
+functions). The page number parameter was originally written as 0. @{ */
+#define MLOG_FILE_FLAG_TEMP 1 /*!< identifies TEMPORARY TABLE in
MLOG_FILE_CREATE, MLOG_FILE_CREATE2 */
+/* @} */
/***************************************************************//**
Starts a mini-transaction and creates a mini-transaction handle
diff --git a/storage/innodb_plugin/include/os0file.h b/storage/innodb_plugin/include/os0file.h
index cc4120d1a6b..d8d2f0e5d9e 100644
--- a/storage/innodb_plugin/include/os0file.h
+++ b/storage/innodb_plugin/include/os0file.h
@@ -15,6 +15,32 @@ this program; if not, write to the Free Software Foundation, Inc., 59 Temple
Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
+/***********************************************************************
+
+Copyright (c) 1995, 2009, Innobase Oy. All Rights Reserved.
+Copyright (c) 2009, Percona Inc.
+
+Portions of this file contain modifications contributed and copyrighted
+by Percona Inc.. Those modifications are
+gratefully acknowledged and are described briefly in the InnoDB
+documentation. The contributions by Percona Inc. are incorporated with
+their permission, and subject to the conditions contained in the file
+COPYING.Percona.
+
+This program is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; version 2 of the License.
+
+This program is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
+Public License for more details.
+
+You should have received a copy of the GNU General Public License along
+with this program; if not, write to the Free Software Foundation, Inc.,
+59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+***********************************************************************/
/**************************************************//**
@file include/os0file.h
@@ -398,6 +424,7 @@ ibool
os_file_close(
/*==========*/
os_file_t file); /*!< in, own: handle to a file */
+#ifdef UNIV_HOTBACKUP
/***********************************************************************//**
Closes a file handle.
@return TRUE if success */
@@ -406,6 +433,7 @@ ibool
os_file_close_no_error_handling(
/*============================*/
os_file_t file); /*!< in, own: handle to a file */
+#endif /* UNIV_HOTBACKUP */
/***********************************************************************//**
Gets a file size.
@return TRUE if success */
@@ -574,23 +602,23 @@ ibool
os_file_create_subdirs_if_needed(
/*=============================*/
const char* path); /*!< in: path name */
-/************************************************************************//**
-Initializes the asynchronous io system. Creates separate aio array for
-non-ibuf read and write, a third aio array for the ibuf i/o, with just one
-segment, two aio arrays for log reads and writes with one segment, and a
-synchronous aio array of the specified size. The combined number of segments
-in the three first aio arrays is the parameter n_segments given to the
-function. The caller must create an i/o handler thread for each segment in
-the four first arrays, but not for the sync aio array. */
+/***********************************************************************
+Initializes the asynchronous io system. Creates one array each for ibuf
+and log i/o. Also creates one array each for read and write where each
+array is divided logically into n_read_segs and n_write_segs
+respectively. The caller must create an i/o handler thread for each
+segment in these arrays. This function also creates the sync array.
+No i/o handler thread needs to be created for that */
UNIV_INTERN
void
os_aio_init(
/*========*/
- ulint n, /*!< in: maximum number of pending aio operations
- allowed; n must be divisible by n_segments */
- ulint n_segments, /*!< in: combined number of segments in the four
- first aio arrays; must be >= 4 */
- ulint n_slots_sync); /*!< in: number of slots in the sync aio array */
+ ulint n_per_seg, /*<! in: maximum number of pending aio
+ operations allowed per segment */
+ ulint n_read_segs, /*<! in: number of reader threads */
+ ulint n_write_segs, /*<! in: number of writer threads */
+ ulint n_slots_sync); /*<! in: number of slots in the sync aio
+ array */
/*******************************************************************//**
Requests an asynchronous i/o operation.
@return TRUE if request was queued successfully, FALSE if fail */
diff --git a/storage/innodb_plugin/include/os0proc.h b/storage/innodb_plugin/include/os0proc.h
index 7a4c45cd38c..fd46bd7db87 100644
--- a/storage/innodb_plugin/include/os0proc.h
+++ b/storage/innodb_plugin/include/os0proc.h
@@ -69,15 +69,6 @@ os_mem_free_large(
os_mem_alloc_large() */
ulint size); /*!< in: size returned by
os_mem_alloc_large() */
-/****************************************************************//**
-Sets the priority boost for threads released from waiting within the current
-process. */
-UNIV_INTERN
-void
-os_process_set_priority_boost(
-/*==========================*/
- ibool do_boost); /*!< in: TRUE if priority boost should be done,
- FALSE if not */
#ifndef UNIV_NONINL
#include "os0proc.ic"
diff --git a/storage/innodb_plugin/include/os0sync.h b/storage/innodb_plugin/include/os0sync.h
index dc8d20f4680..0e0b32e7036 100644
--- a/storage/innodb_plugin/include/os0sync.h
+++ b/storage/innodb_plugin/include/os0sync.h
@@ -128,18 +128,6 @@ os_event_create(
/*============*/
const char* name); /*!< in: the name of the event, if NULL
the event is created without a name */
-#ifdef __WIN__
-/*********************************************************//**
-Creates an auto-reset event semaphore, i.e., an event which is automatically
-reset when a single thread is released. Works only in Windows.
-@return the event handle */
-UNIV_INTERN
-os_event_t
-os_event_create_auto(
-/*=================*/
- const char* name); /*!< in: the name of the event, if NULL
- the event is created without a name */
-#endif
/**********************************************************//**
Sets an event semaphore to the signaled state: lets waiting threads
proceed. */
diff --git a/storage/innodb_plugin/include/os0thread.h b/storage/innodb_plugin/include/os0thread.h
index def5853b189..6583de0005f 100644
--- a/storage/innodb_plugin/include/os0thread.h
+++ b/storage/innodb_plugin/include/os0thread.h
@@ -44,7 +44,7 @@ can wait inside InnoDB */
#ifdef __WIN__
typedef void* os_thread_t;
-typedef unsigned long os_thread_id_t; /*!< In Windows the thread id
+typedef unsigned long os_thread_id_t; /*!< In Windows the thread id
is an unsigned long int */
#else
typedef pthread_t os_thread_t;
diff --git a/storage/innodb_plugin/include/page0zip.h b/storage/innodb_plugin/include/page0zip.h
index c860136905f..9aaa066306b 100644
--- a/storage/innodb_plugin/include/page0zip.h
+++ b/storage/innodb_plugin/include/page0zip.h
@@ -444,9 +444,17 @@ page_zip_calc_checksum(
__attribute__((nonnull));
#ifndef UNIV_HOTBACKUP
+/** Check if a pointer to an uncompressed page matches a compressed page.
+@param ptr pointer to an uncompressed page frame
+@param page_zip compressed page descriptor
+@return TRUE if ptr and page_zip refer to the same block */
# define PAGE_ZIP_MATCH(ptr, page_zip) \
(buf_frame_get_page_zip(ptr) == (page_zip))
#else /* !UNIV_HOTBACKUP */
+/** Check if a pointer to an uncompressed page matches a compressed page.
+@param ptr pointer to an uncompressed page frame
+@param page_zip compressed page descriptor
+@return TRUE if ptr and page_zip refer to the same block */
# define PAGE_ZIP_MATCH(ptr, page_zip) \
(page_align(ptr) + UNIV_PAGE_SIZE == (page_zip)->data)
#endif /* !UNIV_HOTBACKUP */
diff --git a/storage/innodb_plugin/include/page0zip.ic b/storage/innodb_plugin/include/page0zip.ic
index cb819030572..75cc7a9fcc4 100644
--- a/storage/innodb_plugin/include/page0zip.ic
+++ b/storage/innodb_plugin/include/page0zip.ic
@@ -98,15 +98,15 @@ In summary, the compressed page looks like this:
- deleted records (free list) in link order
*/
-/* Start offset of the area that will be compressed */
+/** Start offset of the area that will be compressed */
#define PAGE_ZIP_START PAGE_NEW_SUPREMUM_END
-/* Size of an compressed page directory entry */
+/** Size of an compressed page directory entry */
#define PAGE_ZIP_DIR_SLOT_SIZE 2
-/* Mask of record offsets */
+/** Mask of record offsets */
#define PAGE_ZIP_DIR_SLOT_MASK 0x3fff
-/* 'owned' flag */
+/** 'owned' flag */
#define PAGE_ZIP_DIR_SLOT_OWNED 0x4000
-/* 'deleted' flag */
+/** 'deleted' flag */
#define PAGE_ZIP_DIR_SLOT_DEL 0x8000
/**********************************************************************//**
diff --git a/storage/innodb_plugin/include/que0que.h b/storage/innodb_plugin/include/que0que.h
index 871f42f6d87..420f34550e2 100644
--- a/storage/innodb_plugin/include/que0que.h
+++ b/storage/innodb_plugin/include/que0que.h
@@ -93,16 +93,6 @@ que_thr_create(
que_fork_t* parent, /*!< in: parent node, i.e., a fork node */
mem_heap_t* heap); /*!< in: memory heap where created */
/**********************************************************************//**
-Checks if the query graph is in a state where it should be freed, and
-frees it in that case. If the session is in a state where it should be
-closed, also this is done.
-@return TRUE if freed */
-UNIV_INTERN
-ibool
-que_graph_try_free(
-/*===============*/
- que_t* graph); /*!< in: query graph */
-/**********************************************************************//**
Frees a query graph, but not the heap where it was created. Does not free
explicit cursor declarations, they are freed in que_graph_free. */
UNIV_INTERN
diff --git a/storage/innodb_plugin/include/row0row.h b/storage/innodb_plugin/include/row0row.h
index 9942b960721..723b7b53395 100644
--- a/storage/innodb_plugin/include/row0row.h
+++ b/storage/innodb_plugin/include/row0row.h
@@ -215,21 +215,6 @@ row_build_row_ref_in_tuple(
or NULL */
trx_t* trx); /*!< in: transaction */
/*******************************************************************//**
-From a row build a row reference with which we can search the clustered
-index record. */
-UNIV_INTERN
-void
-row_build_row_ref_from_row(
-/*=======================*/
- dtuple_t* ref, /*!< in/out: row reference built;
- see the NOTE below!
- ref must have the right number
- of fields! */
- const dict_table_t* table, /*!< in: table */
- const dtuple_t* row); /*!< in: row
- NOTE: the data fields in ref will point
- directly into data of this row */
-/*******************************************************************//**
Builds from a secondary index record a row reference with which we can
search the clustered index record. */
UNIV_INLINE
diff --git a/storage/innodb_plugin/include/srv0que.h b/storage/innodb_plugin/include/srv0que.h
index 413fff19143..82ee7739ef7 100644
--- a/storage/innodb_plugin/include/srv0que.h
+++ b/storage/innodb_plugin/include/srv0que.h
@@ -30,34 +30,8 @@ Created 6/5/1996 Heikki Tuuri
#include "que0types.h"
/**********************************************************************//**
-Checks if there is work to do in the server task queue. If there is, the
-thread starts processing a task. Before leaving, it again checks the task
-queue and picks a new task if any exists. This is called by a SRV_WORKER
-thread. */
-UNIV_INTERN
-void
-srv_que_task_queue_check(void);
-/*==========================*/
-/**********************************************************************//**
-Performs round-robin on the server tasks. This is called by a SRV_WORKER
-thread every second or so.
-@return the new (may be == thr) query thread to run */
-UNIV_INTERN
-que_thr_t*
-srv_que_round_robin(
-/*================*/
- que_thr_t* thr); /*!< in: query thread */
-/**********************************************************************//**
-Enqueues a task to server task queue and releases a worker thread, if
-there exists one suspended. */
-UNIV_INTERN
-void
-srv_que_task_enqueue(
-/*=================*/
- que_thr_t* thr); /*!< in: query thread */
-/**********************************************************************//**
-Enqueues a task to server task queue and releases a worker thread, if
-there exists one suspended. */
+Enqueues a task to server task queue and releases a worker thread, if there
+is a suspended one. */
UNIV_INTERN
void
srv_que_task_enqueue_low(
diff --git a/storage/innodb_plugin/include/srv0srv.h b/storage/innodb_plugin/include/srv0srv.h
index d4995e6d724..499bccfe2b8 100644
--- a/storage/innodb_plugin/include/srv0srv.h
+++ b/storage/innodb_plugin/include/srv0srv.h
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 1995, 2009, Innobase Oy. All Rights Reserved.
-Copyright (c) 2008, Google Inc.
+Copyright (c) 2008, 2009, Google Inc.
Portions of this file contain modifications contributed and copyrighted by
Google, Inc. Those modifications are gratefully acknowledged and are described
@@ -22,6 +22,32 @@ this program; if not, write to the Free Software Foundation, Inc., 59 Temple
Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
+/***********************************************************************
+
+Copyright (c) 1995, 2009, Innobase Oy. All Rights Reserved.
+Copyright (c) 2009, Percona Inc.
+
+Portions of this file contain modifications contributed and copyrighted
+by Percona Inc.. Those modifications are
+gratefully acknowledged and are described briefly in the InnoDB
+documentation. The contributions by Percona Inc. are incorporated with
+their permission, and subject to the conditions contained in the file
+COPYING.Percona.
+
+This program is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; version 2 of the License.
+
+This program is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
+Public License for more details.
+
+You should have received a copy of the GNU General Public License along
+with this program; if not, write to the Free Software Foundation, Inc.,
+59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+***********************************************************************/
/**************************************************//**
@file include/srv0srv.h
@@ -42,7 +68,7 @@ Created 10/10/1995 Heikki Tuuri
extern const char* srv_main_thread_op_info;
-/* Prefix used by MySQL to indicate pre-5.1 table name encoding */
+/** Prefix used by MySQL to indicate pre-5.1 table name encoding */
extern const char srv_mysql50_table_name_prefix[9];
/* When this event is set the lock timeout and InnoDB monitor
@@ -81,14 +107,20 @@ extern char* srv_data_home;
extern char* srv_arch_dir;
#endif /* UNIV_LOG_ARCHIVE */
-/* store to its own file each table created by an user; data
+/** store to its own file each table created by an user; data
dictionary tables are in the system tablespace 0 */
+#ifndef UNIV_HOTBACKUP
extern my_bool srv_file_per_table;
-/* The file format to use on new *.ibd files. */
+#else
+extern ibool srv_file_per_table;
+#endif /* UNIV_HOTBACKUP */
+/** The file format to use on new *.ibd files. */
extern ulint srv_file_format;
-/* Whether to check file format during startup.*/
+/** Whether to check file format during startup. A value of
+DICT_TF_FORMAT_MAX + 1 means no checking ie. FALSE. The default is to
+set it to the highest format we support. */
extern ulint srv_check_file_format_at_startup;
-/* Place locks to records only i.e. do not use next-key locking except
+/** Place locks to records only i.e. do not use next-key locking except
on duplicate key checking and foreign key checking */
extern ibool srv_locks_unsafe_for_binlog;
#endif /* !UNIV_HOTBACKUP */
@@ -111,11 +143,17 @@ extern ulint srv_n_log_files;
extern ulint srv_log_file_size;
extern ulint srv_log_buffer_size;
extern ulong srv_flush_log_at_trx_commit;
+extern char srv_adaptive_flushing;
+
/* The sort order table of the MySQL latin1_swedish_ci character set
collation */
extern const byte* srv_latin1_ordering;
+#ifndef UNIV_HOTBACKUP
extern my_bool srv_use_sys_malloc;
+#else
+extern ibool srv_use_sys_malloc;
+#endif /* UNIV_HOTBACKUP */
extern ulint srv_buf_pool_size; /*!< requested size in bytes */
extern ulint srv_buf_pool_old_size; /*!< previously requested size */
extern ulint srv_buf_pool_curr_size; /*!< current size in bytes */
@@ -123,6 +161,16 @@ extern ulint srv_mem_pool_size;
extern ulint srv_lock_table_size;
extern ulint srv_n_file_io_threads;
+extern ulong srv_read_ahead_threshold;
+extern ulint srv_n_read_io_threads;
+extern ulint srv_n_write_io_threads;
+
+/* Number of IO operations per second the server can do */
+extern ulong srv_io_capacity;
+/* Returns the number of IO operations that is X percent of the
+capacity. PCT_IO(5) -> returns the number of IO operations that
+is 5% of the max where max is srv_io_capacity. */
+#define PCT_IO(p) ((ulong) (srv_io_capacity * ((double) p / 100.0)))
#ifdef UNIV_LOG_ARCHIVE
extern ibool srv_log_archive_on;
@@ -215,7 +263,7 @@ extern mutex_t* kernel_mutex_temp;/* mutex protecting the server, trx structs,
same DRAM page as other hotspot semaphores */
#define kernel_mutex (*kernel_mutex_temp)
-#define SRV_MAX_N_IO_THREADS 100
+#define SRV_MAX_N_IO_THREADS 130
/* Array of English strings describing the current state of an
i/o handler thread */
@@ -533,10 +581,10 @@ void
srv_export_innodb_status(void);
/*==========================*/
-/* Thread slot in the thread table */
+/** Thread slot in the thread table */
typedef struct srv_slot_struct srv_slot_t;
-/* Thread table is an array of slots */
+/** Thread table is an array of slots */
typedef srv_slot_t srv_table_t;
/** Status variables to be passed to MySQL */
diff --git a/storage/innodb_plugin/include/sync0sync.h b/storage/innodb_plugin/include/sync0sync.h
index 3310a6331bb..df990823cc4 100644
--- a/storage/innodb_plugin/include/sync0sync.h
+++ b/storage/innodb_plugin/include/sync0sync.h
@@ -41,7 +41,9 @@ Created 9/5/1995 Heikki Tuuri
#include "os0sync.h"
#include "sync0arr.h"
+#if defined(UNIV_DEBUG) && !defined(UNIV_HOTBACKUP)
extern my_bool timed_mutexes;
+#endif /* UNIV_DEBUG && !UNIV_HOTBACKUP */
#ifdef HAVE_WINDOWS_ATOMICS
typedef LONG lock_word_t; /*!< On Windows, InterlockedExchange operates
diff --git a/storage/innodb_plugin/include/trx0rseg.ic b/storage/innodb_plugin/include/trx0rseg.ic
index f028f62434d..daffa92fc7d 100644
--- a/storage/innodb_plugin/include/trx0rseg.ic
+++ b/storage/innodb_plugin/include/trx0rseg.ic
@@ -24,6 +24,7 @@ Created 3/26/1996 Heikki Tuuri
*******************************************************/
#include "srv0srv.h"
+#include "mtr0log.h"
/******************************************************************//**
Gets a rollback segment header.
diff --git a/storage/innodb_plugin/include/trx0sys.h b/storage/innodb_plugin/include/trx0sys.h
index 6b2c1cb29b6..812e8cfa0ba 100644
--- a/storage/innodb_plugin/include/trx0sys.h
+++ b/storage/innodb_plugin/include/trx0sys.h
@@ -29,13 +29,11 @@ Created 3/26/1996 Heikki Tuuri
#include "univ.i"
#include "trx0types.h"
-#include "fsp0fsp.h"
+#include "fsp0types.h"
#include "fil0fil.h"
-#include "fut0lst.h"
#include "buf0buf.h"
#ifndef UNIV_HOTBACKUP
#include "mtr0mtr.h"
-#include "mtr0log.h"
#include "ut0byte.h"
#include "mem0mem.h"
#include "sync0sync.h"
@@ -72,6 +70,8 @@ extern trx_doublewrite_t* trx_doublewrite;
/** The following is set to TRUE when we are upgrading from pre-4.1
format data files to the multiple tablespaces format data files */
extern ibool trx_doublewrite_must_reset_space_ids;
+/** Set to TRUE when the doublewrite buffer is being created */
+extern ibool trx_doublewrite_buf_is_being_created;
/** The following is TRUE when we are using the database in the
post-4.1 format, i.e., we have successfully upgraded, or have created
a new database installation */
@@ -388,12 +388,47 @@ trx_sys_print_mysql_binlog_offset_from_page(
const byte* page); /*!< in: buffer containing the trx
system header page, i.e., page number
TRX_SYS_PAGE_NO in the tablespace */
+/*****************************************************************//**
+Reads the file format id from the first system table space file.
+Even if the call succeeds and returns TRUE, the returned format id
+may be ULINT_UNDEFINED signalling that the format id was not present
+in the data file.
+@return TRUE if call succeeds */
+UNIV_INTERN
+ibool
+trx_sys_read_file_format_id(
+/*========================*/
+ const char *pathname, /*!< in: pathname of the first system
+ table space file */
+ ulint *format_id); /*!< out: file format of the system table
+ space */
+/*****************************************************************//**
+Reads the file format id from the given per-table data file.
+@return TRUE if call succeeds */
+UNIV_INTERN
+ibool
+trx_sys_read_pertable_file_format_id(
+/*=================================*/
+ const char *pathname, /*!< in: pathname of a per-table
+ datafile */
+ ulint *format_id); /*!< out: file format of the per-table
+ data file */
+/*****************************************************************//**
+Get the name representation of the file format from its id.
+@return pointer to the name */
+UNIV_INTERN
+const char*
+trx_sys_file_format_id_to_name(
+/*===========================*/
+ const ulint id); /*!< in: id of the file format */
+
#endif /* !UNIV_HOTBACKUP */
/* The automatically created system rollback segment has this id */
#define TRX_SYS_SYSTEM_RSEG_ID 0
/* Space id and page no where the trx system file copy resides */
#define TRX_SYS_SPACE 0 /* the SYSTEM tablespace */
+#include "fsp0fsp.h"
#define TRX_SYS_PAGE_NO FSP_TRX_SYS_PAGE_NO
/* The offset of the transaction system header on the page */
diff --git a/storage/innodb_plugin/include/trx0sys.ic b/storage/innodb_plugin/include/trx0sys.ic
index f7196ab4dcd..1c7c732751b 100644
--- a/storage/innodb_plugin/include/trx0sys.ic
+++ b/storage/innodb_plugin/include/trx0sys.ic
@@ -27,6 +27,7 @@ Created 3/26/1996 Heikki Tuuri
#include "data0type.h"
#ifndef UNIV_HOTBACKUP
# include "srv0srv.h"
+# include "mtr0log.h"
/* The typedef for rseg slot in the file copy */
typedef byte trx_sysf_rseg_t;
diff --git a/storage/innodb_plugin/include/trx0trx.h b/storage/innodb_plugin/include/trx0trx.h
index 82f88a1bfe3..681feeaec94 100644
--- a/storage/innodb_plugin/include/trx0trx.h
+++ b/storage/innodb_plugin/include/trx0trx.h
@@ -497,10 +497,12 @@ struct trx_struct{
FALSE, one can save CPU time and about
150 bytes in the undo log size as then
we skip XA steps */
- unsigned flush_log_later:1;/* when we commit the transaction
- in MySQL's binlog write, we will
- flush the log to disk later in
- a separate call */
+ unsigned flush_log_later:1;/* In 2PC, we hold the
+ prepare_commit mutex across
+ both phases. In that case, we
+ defer flush of the logs to disk
+ until after we release the
+ mutex. */
unsigned must_flush_log_later:1;/* this flag is set to TRUE in
trx_commit_off_kernel() if
flush_log_later was TRUE, and there
diff --git a/storage/innodb_plugin/include/trx0types.h b/storage/innodb_plugin/include/trx0types.h
index bc75bb06c8c..08cc9622d02 100644
--- a/storage/innodb_plugin/include/trx0types.h
+++ b/storage/innodb_plugin/include/trx0types.h
@@ -28,14 +28,14 @@ Created 3/26/1996 Heikki Tuuri
#include "ut0byte.h"
-/* prepare trx_t::id for being printed via printf(3) */
+/** prepare trx_t::id for being printed via printf(3) */
#define TRX_ID_PREP_PRINTF(id) (ullint) ut_conv_dulint_to_longlong(id)
-/* printf(3) format used for printing TRX_ID_PRINTF_PREP() */
+/** printf(3) format used for printing TRX_ID_PRINTF_PREP() */
#define TRX_ID_FMT "%llX"
-/* maximum length that a formatted trx_t::id could take, not including
-the terminating '\0'. */
+/** maximum length that a formatted trx_t::id could take, not including
+the terminating NUL character. */
#define TRX_ID_MAX_LEN 17
/** Memory objects */
diff --git a/storage/innodb_plugin/include/univ.i b/storage/innodb_plugin/include/univ.i
index 4b8277d93ee..6bce6dd765e 100644
--- a/storage/innodb_plugin/include/univ.i
+++ b/storage/innodb_plugin/include/univ.i
@@ -2,6 +2,7 @@
Copyright (c) 1994, 2009, Innobase Oy. All Rights Reserved.
Copyright (c) 2008, Google Inc.
+Copyright (c) 2009, Sun Microsystems, Inc.
Portions of this file contain modifications contributed and copyrighted by
Google, Inc. Those modifications are gratefully acknowledged and are described
@@ -9,6 +10,12 @@ briefly in the InnoDB documentation. The contributions by Google are
incorporated with their permission, and subject to the conditions contained in
the file COPYING.Google.
+Portions of this file contain modifications contributed and copyrighted by
+Sun Microsystems, Inc. Those modifications are gratefully acknowledged and
+are described briefly in the InnoDB documentation. The contributions by
+Sun Microsystems are incorporated with their permission, and subject to the
+conditions contained in the file COPYING.Sun_Microsystems.
+
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
Foundation; version 2 of the License.
@@ -33,6 +40,10 @@ Created 1/20/1994 Heikki Tuuri
#ifndef univ_i
#define univ_i
+#ifdef UNIV_HOTBACKUP
+#include "hb_univ.i"
+#endif /* UNIV_HOTBACKUP */
+
#define INNODB_VERSION_MAJOR 1
#define INNODB_VERSION_MINOR 0
#define INNODB_VERSION_BUGFIX 4
@@ -89,8 +100,10 @@ the virtual method table (vtable) in GCC 3. */
in compiling more Posix-compatible. These headers also define __WIN__
if we are compiling on Windows. */
+#ifndef UNIV_HOTBACKUP
# include <my_global.h>
# include <my_pthread.h>
+#endif /* UNIV_HOTBACKUP */
/* Include <sys/stat.h> to get S_I... macros defined for os0file.c */
# include <sys/stat.h>
@@ -103,7 +116,9 @@ if we are compiling on Windows. */
/* Include the header file generated by GNU autoconf */
# ifndef __WIN__
-# include "config.h"
+#ifndef UNIV_HOTBACKUP
+# include "config.h"
+#endif /* UNIV_HOTBACKUP */
# endif
# ifdef HAVE_SCHED_H
@@ -136,9 +151,9 @@ from Makefile.in->ut0auxconf.h */
#endif /* HAVE_ATOMIC_BUILTINS */
/* We only try to do explicit inlining of functions with gcc and
-Microsoft Visual C++ */
+Sun Studio */
-# if !defined(__GNUC__)
+# if !defined(__GNUC__) && !(defined(__SUNPRO_C) || defined(__SUNPRO_CC))
# undef UNIV_MUST_NOT_INLINE /* Remove compiler warning */
# define UNIV_MUST_NOT_INLINE
# endif
@@ -236,10 +251,8 @@ by one. */
/* Linkage specifier for non-static InnoDB symbols (variables and functions)
that are only referenced from within InnoDB, not from MySQL */
-#if defined(__GNUC__) && (__GNUC__ >= 4)
+#if defined(__GNUC__) && (__GNUC__ >= 4) && !defined(UNIV_HOTBACKUP)
# define UNIV_INTERN __attribute__((visibility ("hidden")))
-#elif defined(__SUNPRO_C) && (__SUNPRO_C >= 0x550)
-# define UNIV_INTERN __hidden
#else
# define UNIV_INTERN
#endif
@@ -248,9 +261,11 @@ that are only referenced from within InnoDB, not from MySQL */
/* Definition for inline version */
#ifdef __WIN__
-#define UNIV_INLINE __inline
+# define UNIV_INLINE __inline
+#elif defined(__SUNPRO_CC) || defined(__SUNPRO_C)
+# define UNIV_INLINE static inline
#else
-#define UNIV_INLINE static __inline__
+# define UNIV_INLINE static __inline__
#endif
#else
@@ -327,13 +342,15 @@ typedef long int lint;
#ifdef __WIN__
typedef __int64 ib_int64_t;
typedef unsigned __int64 ib_uint64_t;
-#else
+#elif !defined(UNIV_HOTBACKUP)
/* Note: longlong and ulonglong come from MySQL headers. */
typedef longlong ib_int64_t;
typedef ulonglong ib_uint64_t;
#endif
+#ifndef UNIV_HOTBACKUP
typedef unsigned long long int ullint;
+#endif /* UNIV_HOTBACKUP */
#ifndef __WIN__
#if SIZEOF_LONG != SIZEOF_VOIDP
@@ -391,6 +408,17 @@ it is read. */
/* Minimize cache-miss latency by moving data at addr into a cache before
it is read or written. */
# define UNIV_PREFETCH_RW(addr) __builtin_prefetch(addr, 1, 3)
+#elif defined(__SUNPRO_C) || defined(__SUNPRO_CC)
+# include <sun_prefetch.h>
+#if __SUNPRO_C >= 0x550
+# undef UNIV_INTERN
+# define UNIV_INTERN __hidden
+#endif /* __SUNPRO_C >= 0x550 */
+/* Use sun_prefetch when compile with Sun Studio */
+# define UNIV_EXPECT(expr,value) (expr)
+# define UNIV_LIKELY_NULL(expr) (expr)
+# define UNIV_PREFETCH_R(addr) sun_prefetch_read_many(addr)
+# define UNIV_PREFETCH_RW(addr) sun_prefetch_write_many(addr)
#else
/* Dummy versions of the macros */
# define UNIV_EXPECT(expr,value) (expr)
diff --git a/storage/innodb_plugin/include/ut0auxconf.h b/storage/innodb_plugin/include/ut0auxconf.h
index 6362b7ca412..88fb26f1863 100644
--- a/storage/innodb_plugin/include/ut0auxconf.h
+++ b/storage/innodb_plugin/include/ut0auxconf.h
@@ -2,7 +2,7 @@
This file is included in univ.i and will cause compilation failure
if not present.
A custom check has been added in the generated
-storage/innobase/Makefile.in that is shipped with with the InnoDB Plugin
+storage/innobase/Makefile.in that is shipped with the InnoDB Plugin
source archive. This check tries to compile a test program and if
successful then adds "#define HAVE_ATOMIC_PTHREAD_T" to this file.
This is a hack that has been developed in order to check for pthread_t
diff --git a/storage/innodb_plugin/include/ut0ut.h b/storage/innodb_plugin/include/ut0ut.h
index 6b3af2c279d..80094321041 100644
--- a/storage/innodb_plugin/include/ut0ut.h
+++ b/storage/innodb_plugin/include/ut0ut.h
@@ -1,6 +1,13 @@
/*****************************************************************************
Copyright (c) 1994, 2009, Innobase Oy. All Rights Reserved.
+Copyright (c) 2009, Sun Microsystems, Inc.
+
+Portions of this file contain modifications contributed and copyrighted by
+Sun Microsystems, Inc. Those modifications are gratefully acknowledged and
+are described briefly in the InnoDB documentation. The contributions by
+Sun Microsystems are incorporated with their permission, and subject to the
+conditions contained in the file COPYING.Sun_Microsystems.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
@@ -40,6 +47,28 @@ Created 1/20/1994 Heikki Tuuri
/** Time stamp */
typedef time_t ib_time_t;
+#if defined(IB_HAVE_PAUSE_INSTRUCTION)
+# ifdef WIN32
+ /* In the Win32 API, the x86 PAUSE instruction is executed by calling
+ the YieldProcessor macro defined in WinNT.h. It is a CPU architecture-
+ independent way by using YieldProcessor.*/
+# define UT_RELAX_CPU() YieldProcessor()
+# else
+ /* According to the gcc info page, asm volatile means that the
+ instruction has important side-effects and must not be removed.
+ Also asm volatile may trigger a memory barrier (spilling all registers
+ to memory). */
+# define UT_RELAX_CPU() __asm__ __volatile__ ("pause")
+# endif
+#elif defined(HAVE_ATOMIC_BUILTINS)
+# define UT_RELAX_CPU() do { \
+ volatile lint volatile_var; \
+ os_compare_and_swap_lint(&volatile_var, 0, 1); \
+ } while (0)
+#else
+# define UT_RELAX_CPU() ((void)0) /* avoid warning for an empty statement */
+#endif
+
/*********************************************************************//**
Delays execution for at most max_wait_us microseconds or returns earlier
if cond becomes true.
diff --git a/storage/innodb_plugin/lock/lock0lock.c b/storage/innodb_plugin/lock/lock0lock.c
index de5ba2b8404..fcd8d268331 100644
--- a/storage/innodb_plugin/lock/lock0lock.c
+++ b/storage/innodb_plugin/lock/lock0lock.c
@@ -3768,32 +3768,6 @@ lock_table(
}
/*********************************************************************//**
-Checks if there are any locks set on the table.
-@return TRUE if there are lock(s) */
-UNIV_INTERN
-ibool
-lock_is_on_table(
-/*=============*/
- dict_table_t* table) /*!< in: database table in dictionary cache */
-{
- ibool ret;
-
- ut_ad(table);
-
- lock_mutex_enter_kernel();
-
- if (UT_LIST_GET_LAST(table->locks)) {
- ret = TRUE;
- } else {
- ret = FALSE;
- }
-
- lock_mutex_exit_kernel();
-
- return(ret);
-}
-
-/*********************************************************************//**
Checks if a waiting table lock request still has to wait in a queue.
@return TRUE if still has to wait */
static
@@ -3937,22 +3911,6 @@ lock_rec_unlock(
}
/*********************************************************************//**
-Releases a table lock.
-Releases possible other transactions waiting for this lock. */
-UNIV_INTERN
-void
-lock_table_unlock(
-/*==============*/
- lock_t* lock) /*!< in: lock */
-{
- mutex_enter(&kernel_mutex);
-
- lock_table_dequeue(lock);
-
- mutex_exit(&kernel_mutex);
-}
-
-/*********************************************************************//**
Releases transaction locks, and releases possible other transactions waiting
because of these locks. */
UNIV_INTERN
@@ -4499,6 +4457,20 @@ loop:
ulint zip_size= fil_space_get_zip_size(space);
ulint page_no = lock->un_member.rec_lock.page_no;
+ if (UNIV_UNLIKELY(zip_size == ULINT_UNDEFINED)) {
+
+ /* It is a single table tablespace and
+ the .ibd file is missing (TRUNCATE
+ TABLE probably stole the locks): just
+ print the lock without attempting to
+ load the page in the buffer pool. */
+
+ fprintf(file, "RECORD LOCKS on"
+ " non-existing space %lu\n",
+ (ulong) space);
+ goto print_rec;
+ }
+
lock_mutex_exit_kernel();
innobase_mysql_end_print_arbitrary_thd();
@@ -4517,6 +4489,7 @@ loop:
goto loop;
}
+print_rec:
lock_rec_print(file, lock);
} else {
ut_ad(lock_get_type_low(lock) & LOCK_TABLE);
@@ -4721,6 +4694,7 @@ lock_rec_validate_page(
ulint nth_lock = 0;
ulint nth_bit = 0;
ulint i;
+ ulint zip_size;
mtr_t mtr;
mem_heap_t* heap = NULL;
ulint offsets_[REC_OFFS_NORMAL_SIZE];
@@ -4731,8 +4705,9 @@ lock_rec_validate_page(
mtr_start(&mtr);
- block = buf_page_get(space, fil_space_get_zip_size(space),
- page_no, RW_X_LATCH, &mtr);
+ zip_size = fil_space_get_zip_size(space);
+ ut_ad(zip_size != ULINT_UNDEFINED);
+ block = buf_page_get(space, zip_size, page_no, RW_X_LATCH, &mtr);
buf_block_dbg_add_level(block, SYNC_NO_ORDER_CHECK);
page = block->frame;
diff --git a/storage/innodb_plugin/log/log0log.c b/storage/innodb_plugin/log/log0log.c
index 3ad294affb7..24c828cdf5f 100644
--- a/storage/innodb_plugin/log/log0log.c
+++ b/storage/innodb_plugin/log/log0log.c
@@ -15,6 +15,30 @@ this program; if not, write to the Free Software Foundation, Inc., 59 Temple
Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
+/*****************************************************************************
+
+Copyright (c) 1995, 2009, Innobase Oy. All Rights Reserved.
+Copyright (c) 2009, Google Inc.
+
+Portions of this file contain modifications contributed and copyrighted by
+Google, Inc. Those modifications are gratefully acknowledged and are described
+briefly in the InnoDB documentation. The contributions by Google are
+incorporated with their permission, and subject to the conditions contained in
+the file COPYING.Google.
+
+This program is free software; you can redistribute it and/or modify it under
+the terms of the GNU General Public License as published by the Free Software
+Foundation; version 2 of the License.
+
+This program is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License along with
+this program; if not, write to the Free Software Foundation, Inc., 59 Temple
+Place, Suite 330, Boston, MA 02111-1307 USA
+
+*****************************************************************************/
/**************************************************//**
@file log/log0log.c
@@ -1533,6 +1557,29 @@ log_buffer_flush_to_disk(void)
}
/****************************************************************//**
+This functions writes the log buffer to the log file and if 'flush'
+is set it forces a flush of the log file as well. This is meant to be
+called from background master thread only as it does not wait for
+the write (+ possible flush) to finish. */
+UNIV_INTERN
+void
+log_buffer_sync_in_background(
+/*==========================*/
+ ibool flush) /*!< in: flush the logs to disk */
+{
+ ib_uint64_t lsn;
+
+ mutex_enter(&(log_sys->mutex));
+
+ lsn = log_sys->lsn;
+
+ mutex_exit(&(log_sys->mutex));
+
+ log_write_up_to(lsn, LOG_NO_WAIT, flush);
+}
+
+/********************************************************************
+
Tries to establish a big enough margin of free space in the log buffer, such
that a new log entry can be catenated without an immediate need for a flush. */
static
diff --git a/storage/innodb_plugin/mem/mem0mem.c b/storage/innodb_plugin/mem/mem0mem.c
index e60e6809d15..e0dc8716f13 100644
--- a/storage/innodb_plugin/mem/mem0mem.c
+++ b/storage/innodb_plugin/mem/mem0mem.c
@@ -126,27 +126,6 @@ mem_heap_dup(
}
/**********************************************************************//**
-Concatenate two memory blocks and return the result, using a memory heap.
-@return own: the result */
-UNIV_INTERN
-void*
-mem_heap_cat(
-/*=========*/
- mem_heap_t* heap, /*!< in: memory heap where result is allocated */
- const void* b1, /*!< in: block 1 */
- ulint len1, /*!< in: length of b1, in bytes */
- const void* b2, /*!< in: block 2 */
- ulint len2) /*!< in: length of b2, in bytes */
-{
- void* res = mem_heap_alloc(heap, len1 + len2);
-
- memcpy(res, b1, len1);
- memcpy((char*)res + len1, b2, len2);
-
- return(res);
-}
-
-/**********************************************************************//**
Concatenate two strings and return the result, using a memory heap.
@return own: the result */
UNIV_INTERN
diff --git a/storage/innodb_plugin/mtr/mtr0log.c b/storage/innodb_plugin/mtr/mtr0log.c
index a2f39434a90..3f3dab36b76 100644
--- a/storage/innodb_plugin/mtr/mtr0log.c
+++ b/storage/innodb_plugin/mtr/mtr0log.c
@@ -239,7 +239,6 @@ mlog_parse_nbytes(
return(ptr);
}
-#ifndef UNIV_HOTBACKUP
/********************************************************//**
Writes 1 - 4 bytes to a file page buffered in the buffer pool.
Writes the corresponding log record to the mini-transaction log. */
@@ -322,6 +321,7 @@ mlog_write_dulint(
mlog_close(mtr, log_ptr);
}
+#ifndef UNIV_HOTBACKUP
/********************************************************//**
Writes a string to a file page buffered in the buffer pool. Writes the
corresponding log record to the mini-transaction log. */
@@ -440,7 +440,7 @@ byte*
mlog_open_and_write_index(
/*======================*/
mtr_t* mtr, /*!< in: mtr */
- byte* rec, /*!< in: index record or page */
+ const byte* rec, /*!< in: index record or page */
dict_index_t* index, /*!< in: record descriptor */
byte type, /*!< in: log item type */
ulint size) /*!< in: requested buffer size in bytes
diff --git a/storage/innodb_plugin/mysql-test/innodb-autoinc.result b/storage/innodb_plugin/mysql-test/innodb-autoinc.result
index ade4db35ce6..d2e8eb19e0c 100644
--- a/storage/innodb_plugin/mysql-test/innodb-autoinc.result
+++ b/storage/innodb_plugin/mysql-test/innodb-autoinc.result
@@ -867,3 +867,25 @@ INSERT INTO t2 SELECT NULL FROM t1;
Got one of the listed errors
DROP TABLE t1;
DROP TABLE t2;
+CREATE TABLE t1 (c1 INT PRIMARY KEY AUTO_INCREMENT) ENGINE=InnoDB;
+INSERT INTO t1 VALUES (null);
+INSERT INTO t1 VALUES (null);
+ALTER TABLE t1 CHANGE c1 d1 INT NOT NULL AUTO_INCREMENT;
+SELECT * FROM t1;
+d1
+1
+3
+SELECT * FROM t1;
+d1
+1
+3
+INSERT INTO t1 VALUES(null);
+Got one of the listed errors
+ALTER TABLE t1 AUTO_INCREMENT = 3;
+INSERT INTO t1 VALUES(null);
+SELECT * FROM t1;
+d1
+1
+3
+4
+DROP TABLE t1;
diff --git a/storage/innodb_plugin/mysql-test/innodb-autoinc.test b/storage/innodb_plugin/mysql-test/innodb-autoinc.test
index d76b29a7dc8..61c42f45733 100644
--- a/storage/innodb_plugin/mysql-test/innodb-autoinc.test
+++ b/storage/innodb_plugin/mysql-test/innodb-autoinc.test
@@ -478,3 +478,23 @@ INSERT INTO t2 SELECT c1 FROM t1;
INSERT INTO t2 SELECT NULL FROM t1;
DROP TABLE t1;
DROP TABLE t2;
+#
+# 44030: Error: (1500) Couldn't read the MAX(ID) autoinc value from
+# the index (PRIMARY)
+# This test requires a restart of the server
+CREATE TABLE t1 (c1 INT PRIMARY KEY AUTO_INCREMENT) ENGINE=InnoDB;
+INSERT INTO t1 VALUES (null);
+INSERT INTO t1 VALUES (null);
+ALTER TABLE t1 CHANGE c1 d1 INT NOT NULL AUTO_INCREMENT;
+SELECT * FROM t1;
+# Restart the server
+-- source include/restart_mysqld.inc
+# The MySQL and InnoDB data dictionaries should now be out of sync.
+# The select should print message to the error log
+SELECT * FROM t1;
+-- error ER_AUTOINC_READ_FAILED,1467
+INSERT INTO t1 VALUES(null);
+ALTER TABLE t1 AUTO_INCREMENT = 3;
+INSERT INTO t1 VALUES(null);
+SELECT * FROM t1;
+DROP TABLE t1;
diff --git a/storage/innodb_plugin/mysql-test/innodb.result b/storage/innodb_plugin/mysql-test/innodb.result
index e3c52fd7b6b..bdae7633fd1 100644
--- a/storage/innodb_plugin/mysql-test/innodb.result
+++ b/storage/innodb_plugin/mysql-test/innodb.result
@@ -1738,7 +1738,7 @@ count(*)
drop table t1;
SELECT variable_value FROM information_schema.global_status WHERE LOWER(variable_name) = 'innodb_buffer_pool_pages_total';
variable_value
-511
+8191
SELECT variable_value FROM information_schema.global_status WHERE LOWER(variable_name) = 'innodb_page_size';
variable_value
16384
@@ -1766,9 +1766,10 @@ variable_value - @innodb_row_lock_time_max_orig
SELECT variable_value - @innodb_row_lock_time_avg_orig FROM information_schema.global_status WHERE LOWER(variable_name) = 'innodb_row_lock_time_avg';
variable_value - @innodb_row_lock_time_avg_orig
0
+SET @innodb_sync_spin_loops_orig = @@innodb_sync_spin_loops;
show variables like "innodb_sync_spin_loops";
Variable_name Value
-innodb_sync_spin_loops 20
+innodb_sync_spin_loops 30
set global innodb_sync_spin_loops=1000;
show variables like "innodb_sync_spin_loops";
Variable_name Value
@@ -1781,6 +1782,7 @@ set global innodb_sync_spin_loops=20;
show variables like "innodb_sync_spin_loops";
Variable_name Value
innodb_sync_spin_loops 20
+set global innodb_sync_spin_loops=@innodb_sync_spin_loops_orig;
show variables like "innodb_thread_concurrency";
Variable_name Value
innodb_thread_concurrency 0
diff --git a/storage/innodb_plugin/mysql-test/innodb.test b/storage/innodb_plugin/mysql-test/innodb.test
index 0d8e164de34..f46a3a70b56 100644
--- a/storage/innodb_plugin/mysql-test/innodb.test
+++ b/storage/innodb_plugin/mysql-test/innodb.test
@@ -1317,7 +1317,7 @@ drop table t1;
# Test for testable InnoDB status variables. This test
# uses previous ones(pages_created, rows_deleted, ...).
---replace_result 512 511
+--replace_result 8192 8191
SELECT variable_value FROM information_schema.global_status WHERE LOWER(variable_name) = 'innodb_buffer_pool_pages_total';
SELECT variable_value FROM information_schema.global_status WHERE LOWER(variable_name) = 'innodb_page_size';
SELECT variable_value - @innodb_rows_deleted_orig FROM information_schema.global_status WHERE LOWER(variable_name) = 'innodb_rows_deleted';
@@ -1332,6 +1332,7 @@ SELECT variable_value - @innodb_row_lock_time_max_orig FROM information_schema.g
SELECT variable_value - @innodb_row_lock_time_avg_orig FROM information_schema.global_status WHERE LOWER(variable_name) = 'innodb_row_lock_time_avg';
# Test for innodb_sync_spin_loops variable
+SET @innodb_sync_spin_loops_orig = @@innodb_sync_spin_loops;
show variables like "innodb_sync_spin_loops";
set global innodb_sync_spin_loops=1000;
show variables like "innodb_sync_spin_loops";
@@ -1339,6 +1340,7 @@ set global innodb_sync_spin_loops=0;
show variables like "innodb_sync_spin_loops";
set global innodb_sync_spin_loops=20;
show variables like "innodb_sync_spin_loops";
+set global innodb_sync_spin_loops=@innodb_sync_spin_loops_orig;
# Test for innodb_thread_concurrency variable
show variables like "innodb_thread_concurrency";
diff --git a/storage/innodb_plugin/mysql-test/innodb_bug21704.result b/storage/innodb_plugin/mysql-test/innodb_bug21704.result
new file mode 100644
index 00000000000..b8e0b15d50d
--- /dev/null
+++ b/storage/innodb_plugin/mysql-test/innodb_bug21704.result
@@ -0,0 +1,55 @@
+#
+# Bug#21704: Renaming column does not update FK definition.
+#
+
+# Test that it's not possible to rename columns participating in a
+# foreign key (either in the referencing or referenced table).
+
+DROP TABLE IF EXISTS t1;
+DROP TABLE IF EXISTS t2;
+DROP TABLE IF EXISTS t3;
+CREATE TABLE t1 (a INT PRIMARY KEY, b INT) ROW_FORMAT=COMPACT ENGINE=INNODB;
+CREATE TABLE t2 (a INT PRIMARY KEY, b INT,
+CONSTRAINT fk1 FOREIGN KEY (a) REFERENCES t1(a))
+ROW_FORMAT=COMPACT ENGINE=INNODB;
+CREATE TABLE t3 (a INT PRIMARY KEY, b INT, KEY(b), C INT,
+CONSTRAINT fk2 FOREIGN KEY (b) REFERENCES t3 (a))
+ROW_FORMAT=COMPACT ENGINE=INNODB;
+INSERT INTO t1 VALUES (1,1),(2,2),(3,3);
+INSERT INTO t2 VALUES (1,1),(2,2),(3,3);
+INSERT INTO t3 VALUES (1,1,1),(2,2,2),(3,3,3);
+
+# Test renaming the column in the referenced table.
+
+ALTER TABLE t1 CHANGE a c INT;
+ERROR HY000: Error on rename of '#sql-temporary' to './test/t1' (errno: 150)
+# Ensure that online column rename works.
+ALTER TABLE t1 CHANGE b c INT;
+affected rows: 0
+info: Records: 0 Duplicates: 0 Warnings: 0
+
+# Test renaming the column in the referencing table
+
+ALTER TABLE t2 CHANGE a c INT;
+ERROR HY000: Error on rename of '#sql-temporary' to './test/t2' (errno: 150)
+# Ensure that online column rename works.
+ALTER TABLE t2 CHANGE b c INT;
+affected rows: 0
+info: Records: 0 Duplicates: 0 Warnings: 0
+
+# Test with self-referential constraints
+
+ALTER TABLE t3 CHANGE a d INT;
+ERROR HY000: Error on rename of '#sql-temporary' to './test/t3' (errno: 150)
+ALTER TABLE t3 CHANGE b d INT;
+ERROR HY000: Error on rename of '#sql-temporary' to './test/t3' (errno: 150)
+# Ensure that online column rename works.
+ALTER TABLE t3 CHANGE c d INT;
+affected rows: 0
+info: Records: 0 Duplicates: 0 Warnings: 0
+
+# Cleanup.
+
+DROP TABLE t3;
+DROP TABLE t2;
+DROP TABLE t1;
diff --git a/storage/innodb_plugin/mysql-test/innodb_bug21704.test b/storage/innodb_plugin/mysql-test/innodb_bug21704.test
new file mode 100644
index 00000000000..c649b61034c
--- /dev/null
+++ b/storage/innodb_plugin/mysql-test/innodb_bug21704.test
@@ -0,0 +1,96 @@
+-- source include/have_innodb.inc
+
+--echo #
+--echo # Bug#21704: Renaming column does not update FK definition.
+--echo #
+
+--echo
+--echo # Test that it's not possible to rename columns participating in a
+--echo # foreign key (either in the referencing or referenced table).
+--echo
+
+--disable_warnings
+DROP TABLE IF EXISTS t1;
+DROP TABLE IF EXISTS t2;
+DROP TABLE IF EXISTS t3;
+--enable_warnings
+
+CREATE TABLE t1 (a INT PRIMARY KEY, b INT) ROW_FORMAT=COMPACT ENGINE=INNODB;
+
+CREATE TABLE t2 (a INT PRIMARY KEY, b INT,
+ CONSTRAINT fk1 FOREIGN KEY (a) REFERENCES t1(a))
+ROW_FORMAT=COMPACT ENGINE=INNODB;
+
+CREATE TABLE t3 (a INT PRIMARY KEY, b INT, KEY(b), C INT,
+ CONSTRAINT fk2 FOREIGN KEY (b) REFERENCES t3 (a))
+ROW_FORMAT=COMPACT ENGINE=INNODB;
+
+INSERT INTO t1 VALUES (1,1),(2,2),(3,3);
+INSERT INTO t2 VALUES (1,1),(2,2),(3,3);
+INSERT INTO t3 VALUES (1,1,1),(2,2,2),(3,3,3);
+
+--echo
+--echo # Test renaming the column in the referenced table.
+--echo
+
+# mysqltest first does replace_regex, then replace_result
+--replace_regex /'[^']*test\/#sql-[0-9a-f_]*'/'#sql-temporary'/
+# Embedded server doesn't chdir to data directory
+--replace_result $MYSQLTEST_VARDIR . mysqld.1/data/ ''
+--error ER_ERROR_ON_RENAME
+ALTER TABLE t1 CHANGE a c INT;
+
+--echo # Ensure that online column rename works.
+
+--enable_info
+ALTER TABLE t1 CHANGE b c INT;
+--disable_info
+
+--echo
+--echo # Test renaming the column in the referencing table
+--echo
+
+# mysqltest first does replace_regex, then replace_result
+--replace_regex /'[^']*test\/#sql-[0-9a-f_]*'/'#sql-temporary'/
+# Embedded server doesn't chdir to data directory
+--replace_result $MYSQLTEST_VARDIR . mysqld.1/data/ ''
+--error ER_ERROR_ON_RENAME
+ALTER TABLE t2 CHANGE a c INT;
+
+--echo # Ensure that online column rename works.
+
+--enable_info
+ALTER TABLE t2 CHANGE b c INT;
+--disable_info
+
+--echo
+--echo # Test with self-referential constraints
+--echo
+
+# mysqltest first does replace_regex, then replace_result
+--replace_regex /'[^']*test\/#sql-[0-9a-f_]*'/'#sql-temporary'/
+# Embedded server doesn't chdir to data directory
+--replace_result $MYSQLTEST_VARDIR . mysqld.1/data/ ''
+--error ER_ERROR_ON_RENAME
+ALTER TABLE t3 CHANGE a d INT;
+
+# mysqltest first does replace_regex, then replace_result
+--replace_regex /'[^']*test\/#sql-[0-9a-f_]*'/'#sql-temporary'/
+# Embedded server doesn't chdir to data directory
+--replace_result $MYSQLTEST_VARDIR . mysqld.1/data/ ''
+--error ER_ERROR_ON_RENAME
+ALTER TABLE t3 CHANGE b d INT;
+
+--echo # Ensure that online column rename works.
+
+--enable_info
+ALTER TABLE t3 CHANGE c d INT;
+--disable_info
+
+--echo
+--echo # Cleanup.
+--echo
+
+DROP TABLE t3;
+DROP TABLE t2;
+DROP TABLE t1;
diff --git a/storage/innodb_plugin/mysql-test/innodb_bug40565.result b/storage/innodb_plugin/mysql-test/innodb_bug40565.result
new file mode 100644
index 00000000000..21e923d9336
--- /dev/null
+++ b/storage/innodb_plugin/mysql-test/innodb_bug40565.result
@@ -0,0 +1,9 @@
+create table bug40565(value decimal(4,2)) engine=innodb;
+insert into bug40565 values (1), (null);
+update bug40565 set value=NULL;
+affected rows: 1
+info: Rows matched: 2 Changed: 1 Warnings: 0
+update bug40565 set value=NULL;
+affected rows: 0
+info: Rows matched: 2 Changed: 0 Warnings: 0
+drop table bug40565;
diff --git a/storage/innodb_plugin/mysql-test/innodb_bug40565.test b/storage/innodb_plugin/mysql-test/innodb_bug40565.test
new file mode 100644
index 00000000000..d7aa0fd514a
--- /dev/null
+++ b/storage/innodb_plugin/mysql-test/innodb_bug40565.test
@@ -0,0 +1,10 @@
+# Bug #40565 Update Query Results in "1 Row Affected" But Should Be "Zero Rows"
+-- source include/have_innodb.inc
+
+create table bug40565(value decimal(4,2)) engine=innodb;
+insert into bug40565 values (1), (null);
+--enable_info
+update bug40565 set value=NULL;
+update bug40565 set value=NULL;
+--disable_info
+drop table bug40565;
diff --git a/storage/innodb_plugin/mysql-test/innodb_bug42101-nonzero.result b/storage/innodb_plugin/mysql-test/innodb_bug42101-nonzero.result
index 8a14296381c..277dfffdd35 100644
--- a/storage/innodb_plugin/mysql-test/innodb_bug42101-nonzero.result
+++ b/storage/innodb_plugin/mysql-test/innodb_bug42101-nonzero.result
@@ -11,11 +11,15 @@ set global innodb_commit_concurrency=42;
select @@innodb_commit_concurrency;
@@innodb_commit_concurrency
42
+set global innodb_commit_concurrency=DEFAULT;
+select @@innodb_commit_concurrency;
+@@innodb_commit_concurrency
+1
set global innodb_commit_concurrency=0;
ERROR HY000: Incorrect arguments to SET
select @@innodb_commit_concurrency;
@@innodb_commit_concurrency
-42
+1
set global innodb_commit_concurrency=1;
select @@innodb_commit_concurrency;
@@innodb_commit_concurrency
diff --git a/storage/innodb_plugin/mysql-test/innodb_bug42101-nonzero.test b/storage/innodb_plugin/mysql-test/innodb_bug42101-nonzero.test
index c691a234c51..685fdf20489 100644
--- a/storage/innodb_plugin/mysql-test/innodb_bug42101-nonzero.test
+++ b/storage/innodb_plugin/mysql-test/innodb_bug42101-nonzero.test
@@ -12,6 +12,8 @@ set global innodb_commit_concurrency=1;
select @@innodb_commit_concurrency;
set global innodb_commit_concurrency=42;
select @@innodb_commit_concurrency;
+set global innodb_commit_concurrency=DEFAULT;
+select @@innodb_commit_concurrency;
--error ER_WRONG_ARGUMENTS
set global innodb_commit_concurrency=0;
select @@innodb_commit_concurrency;
diff --git a/storage/innodb_plugin/mysql-test/innodb_bug42101.result b/storage/innodb_plugin/mysql-test/innodb_bug42101.result
index 9a9c8e0ce9b..805097ffe9d 100644
--- a/storage/innodb_plugin/mysql-test/innodb_bug42101.result
+++ b/storage/innodb_plugin/mysql-test/innodb_bug42101.result
@@ -16,3 +16,7 @@ set global innodb_commit_concurrency=0;
select @@innodb_commit_concurrency;
@@innodb_commit_concurrency
0
+set global innodb_commit_concurrency=DEFAULT;
+select @@innodb_commit_concurrency;
+@@innodb_commit_concurrency
+0
diff --git a/storage/innodb_plugin/mysql-test/innodb_bug42101.test b/storage/innodb_plugin/mysql-test/innodb_bug42101.test
index 13d531ecde7..b6536490d48 100644
--- a/storage/innodb_plugin/mysql-test/innodb_bug42101.test
+++ b/storage/innodb_plugin/mysql-test/innodb_bug42101.test
@@ -15,3 +15,5 @@ set global innodb_commit_concurrency=42;
select @@innodb_commit_concurrency;
set global innodb_commit_concurrency=0;
select @@innodb_commit_concurrency;
+set global innodb_commit_concurrency=DEFAULT;
+select @@innodb_commit_concurrency;
diff --git a/storage/innodb_plugin/mysql-test/innodb_bug45357.result b/storage/innodb_plugin/mysql-test/innodb_bug45357.result
new file mode 100644
index 00000000000..7adeff2062f
--- /dev/null
+++ b/storage/innodb_plugin/mysql-test/innodb_bug45357.result
@@ -0,0 +1,7 @@
+set session transaction isolation level read committed;
+create table bug45357(a int, b int,key(b))engine=innodb;
+insert into bug45357 values (25170,6122);
+update bug45357 set a=1 where b=30131;
+delete from bug45357 where b < 20996;
+delete from bug45357 where b < 7001;
+drop table bug45357;
diff --git a/storage/innodb_plugin/mysql-test/innodb_bug45357.test b/storage/innodb_plugin/mysql-test/innodb_bug45357.test
new file mode 100644
index 00000000000..81727f352dd
--- /dev/null
+++ b/storage/innodb_plugin/mysql-test/innodb_bug45357.test
@@ -0,0 +1,10 @@
+-- source include/have_innodb.inc
+
+set session transaction isolation level read committed;
+
+create table bug45357(a int, b int,key(b))engine=innodb;
+insert into bug45357 values (25170,6122);
+update bug45357 set a=1 where b=30131;
+delete from bug45357 where b < 20996;
+delete from bug45357 where b < 7001;
+drop table bug45357;
diff --git a/storage/innodb_plugin/mysql-test/innodb_file_format.result b/storage/innodb_plugin/mysql-test/innodb_file_format.result
new file mode 100644
index 00000000000..9cfac5f001c
--- /dev/null
+++ b/storage/innodb_plugin/mysql-test/innodb_file_format.result
@@ -0,0 +1,44 @@
+select @@innodb_file_format;
+@@innodb_file_format
+Antelope
+select @@innodb_file_format_check;
+@@innodb_file_format_check
+Antelope
+set global innodb_file_format=antelope;
+set global innodb_file_format=barracuda;
+set global innodb_file_format=cheetah;
+ERROR HY000: Incorrect arguments to SET
+select @@innodb_file_format;
+@@innodb_file_format
+Barracuda
+set global innodb_file_format=default;
+select @@innodb_file_format;
+@@innodb_file_format
+Antelope
+set global innodb_file_format=on;
+ERROR HY000: Incorrect arguments to SET
+set global innodb_file_format=off;
+ERROR HY000: Incorrect arguments to SET
+select @@innodb_file_format;
+@@innodb_file_format
+Antelope
+set global innodb_file_format_check=antelope;
+set global innodb_file_format_check=barracuda;
+set global innodb_file_format_check=cheetah;
+ERROR HY000: Incorrect arguments to SET
+select @@innodb_file_format_check;
+@@innodb_file_format_check
+Barracuda
+set global innodb_file_format_check=default;
+Warnings:
+Warning 1210 Ignoring SET innodb_file_format=on
+select @@innodb_file_format_check;
+@@innodb_file_format_check
+Barracuda
+set global innodb_file_format=on;
+ERROR HY000: Incorrect arguments to SET
+set global innodb_file_format=off;
+ERROR HY000: Incorrect arguments to SET
+select @@innodb_file_format_check;
+@@innodb_file_format_check
+Barracuda
diff --git a/storage/innodb_plugin/mysql-test/innodb_file_format.test b/storage/innodb_plugin/mysql-test/innodb_file_format.test
new file mode 100644
index 00000000000..62ce4157183
--- /dev/null
+++ b/storage/innodb_plugin/mysql-test/innodb_file_format.test
@@ -0,0 +1,28 @@
+-- source include/have_innodb.inc
+
+select @@innodb_file_format;
+select @@innodb_file_format_check;
+set global innodb_file_format=antelope;
+set global innodb_file_format=barracuda;
+--error ER_WRONG_ARGUMENTS
+set global innodb_file_format=cheetah;
+select @@innodb_file_format;
+set global innodb_file_format=default;
+select @@innodb_file_format;
+--error ER_WRONG_ARGUMENTS
+set global innodb_file_format=on;
+--error ER_WRONG_ARGUMENTS
+set global innodb_file_format=off;
+select @@innodb_file_format;
+set global innodb_file_format_check=antelope;
+set global innodb_file_format_check=barracuda;
+--error ER_WRONG_ARGUMENTS
+set global innodb_file_format_check=cheetah;
+select @@innodb_file_format_check;
+set global innodb_file_format_check=default;
+select @@innodb_file_format_check;
+--error ER_WRONG_ARGUMENTS
+set global innodb_file_format=on;
+--error ER_WRONG_ARGUMENTS
+set global innodb_file_format=off;
+select @@innodb_file_format_check;
diff --git a/storage/innodb_plugin/os/os0file.c b/storage/innodb_plugin/os/os0file.c
index 7ee9af4824d..d3bd6465f5f 100644
--- a/storage/innodb_plugin/os/os0file.c
+++ b/storage/innodb_plugin/os/os0file.c
@@ -15,6 +15,32 @@ this program; if not, write to the Free Software Foundation, Inc., 59 Temple
Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
+/***********************************************************************
+
+Copyright (c) 1995, 2009, Innobase Oy. All Rights Reserved.
+Copyright (c) 2009, Percona Inc.
+
+Portions of this file contain modifications contributed and copyrighted
+by Percona Inc.. Those modifications are
+gratefully acknowledged and are described briefly in the InnoDB
+documentation. The contributions by Percona Inc. are incorporated with
+their permission, and subject to the conditions contained in the file
+COPYING.Percona.
+
+This program is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; version 2 of the License.
+
+This program is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
+Public License for more details.
+
+You should have received a copy of the GNU General Public License along
+with this program; if not, write to the Free Software Foundation, Inc.,
+59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+***********************************************************************/
/**************************************************//**
@file os/os0file.c
@@ -1618,6 +1644,7 @@ os_file_close(
#endif
}
+#ifdef UNIV_HOTBACKUP
/***********************************************************************//**
Closes a file handle.
@return TRUE if success */
@@ -1652,6 +1679,7 @@ os_file_close_no_error_handling(
return(TRUE);
#endif
}
+#endif /* UNIV_HOTBACKUP */
/***********************************************************************//**
Gets a file size.
@@ -2923,31 +2951,27 @@ os_aio_array_create(
return(array);
}
-/************************************************************************//**
-Initializes the asynchronous io system. Calls also os_io_init_simple.
-Creates a separate aio array for
-non-ibuf read and write, a third aio array for the ibuf i/o, with just one
-segment, two aio arrays for log reads and writes with one segment, and a
-synchronous aio array of the specified size. The combined number of segments
-in the three first aio arrays is the parameter n_segments given to the
-function. The caller must create an i/o handler thread for each segment in
-the four first arrays, but not for the sync aio array. */
+/***********************************************************************
+Initializes the asynchronous io system. Creates one array each for ibuf
+and log i/o. Also creates one array each for read and write where each
+array is divided logically into n_read_segs and n_write_segs
+respectively. The caller must create an i/o handler thread for each
+segment in these arrays. This function also creates the sync array.
+No i/o handler thread needs to be created for that */
UNIV_INTERN
void
os_aio_init(
/*========*/
- ulint n, /*!< in: maximum number of pending aio operations
- allowed; n must be divisible by n_segments */
- ulint n_segments, /*!< in: combined number of segments in the four
- first aio arrays; must be >= 4 */
- ulint n_slots_sync) /*!< in: number of slots in the sync aio array */
+ ulint n_per_seg, /*<! in: maximum number of pending aio
+ operations allowed per segment */
+ ulint n_read_segs, /*<! in: number of reader threads */
+ ulint n_write_segs, /*<! in: number of writer threads */
+ ulint n_slots_sync) /*<! in: number of slots in the sync aio
+ array */
{
- ulint n_read_segs;
- ulint n_write_segs;
- ulint n_per_seg;
ulint i;
+ ulint n_segments = 2 + n_read_segs + n_write_segs;
- ut_ad(n % n_segments == 0);
ut_ad(n_segments >= 4);
os_io_init_simple();
@@ -2956,9 +2980,6 @@ os_aio_init(
srv_set_io_thread_op_info(i, "not started yet");
}
- n_per_seg = n / n_segments;
- n_write_segs = (n_segments - 2) / 2;
- n_read_segs = n_segments - 2 - n_write_segs;
/* fprintf(stderr, "Array n per seg %lu\n", n_per_seg); */
@@ -3157,6 +3178,18 @@ os_aio_array_reserve_slot(
OVERLAPPED* control;
#endif
ulint i;
+ ulint slots_per_seg;
+ ulint local_seg;
+
+ /* No need of a mutex. Only reading constant fields */
+ slots_per_seg = array->n_slots / array->n_segments;
+
+ /* We attempt to keep adjacent blocks in the same local
+ segment. This can help in merging IO requests when we are
+ doing simulated AIO */
+ local_seg = (offset >> (UNIV_PAGE_SIZE_SHIFT + 6))
+ % array->n_segments;
+
loop:
os_mutex_enter(array->mutex);
@@ -3175,14 +3208,26 @@ loop:
goto loop;
}
+ /* First try to find a slot in the preferred local segment */
+ for (i = local_seg * slots_per_seg; i < array->n_slots; i++) {
+ slot = os_aio_array_get_nth_slot(array, i);
+
+ if (slot->reserved == FALSE) {
+ goto found;
+ }
+ }
+
+ /* Fall back to a full scan. We are guaranteed to find a slot */
for (i = 0;; i++) {
slot = os_aio_array_get_nth_slot(array, i);
if (slot->reserved == FALSE) {
- break;
+ goto found;
}
}
+found:
+ ut_a(slot->reserved == FALSE);
array->n_reserved++;
if (array->n_reserved == 1) {
diff --git a/storage/innodb_plugin/os/os0proc.c b/storage/innodb_plugin/os/os0proc.c
index e0d21378ad9..a0ea9a1b258 100644
--- a/storage/innodb_plugin/os/os0proc.c
+++ b/storage/innodb_plugin/os/os0proc.c
@@ -228,37 +228,3 @@ os_mem_free_large(
}
#endif
}
-
-/****************************************************************//**
-Sets the priority boost for threads released from waiting within the current
-process. */
-UNIV_INTERN
-void
-os_process_set_priority_boost(
-/*==========================*/
- ibool do_boost) /*!< in: TRUE if priority boost should be done,
- FALSE if not */
-{
-#ifdef __WIN__
- ibool no_boost;
-
- if (do_boost) {
- no_boost = FALSE;
- } else {
- no_boost = TRUE;
- }
-
-#if TRUE != 1
-# error "TRUE != 1"
-#endif
-
- /* Does not do anything currently!
- SetProcessPriorityBoost(GetCurrentProcess(), no_boost);
- */
- fputs("Warning: process priority boost setting"
- " currently not functional!\n",
- stderr);
-#else
- UT_NOT_USED(do_boost);
-#endif
-}
diff --git a/storage/innodb_plugin/os/os0sync.c b/storage/innodb_plugin/os/os0sync.c
index 729ca383269..4ec340b72b5 100644
--- a/storage/innodb_plugin/os/os0sync.c
+++ b/storage/innodb_plugin/os/os0sync.c
@@ -196,47 +196,6 @@ os_event_create(
return(event);
}
-#ifdef __WIN__
-/*********************************************************//**
-Creates an auto-reset event semaphore, i.e., an event which is automatically
-reset when a single thread is released. Works only in Windows.
-@return the event handle */
-UNIV_INTERN
-os_event_t
-os_event_create_auto(
-/*=================*/
- const char* name) /*!< in: the name of the event, if NULL
- the event is created without a name */
-{
- os_event_t event;
-
- event = ut_malloc(sizeof(struct os_event_struct));
-
- event->handle = CreateEvent(NULL, /* No security attributes */
- FALSE, /* Auto-reset */
- FALSE, /* Initial state nonsignaled */
- (LPCTSTR) name);
-
- if (!event->handle) {
- fprintf(stderr,
- "InnoDB: Could not create a Windows auto"
- " event semaphore; Windows error %lu\n",
- (ulong) GetLastError());
- }
-
- /* Put to the list of events */
- os_mutex_enter(os_sync_mutex);
-
- UT_LIST_ADD_FIRST(os_event_list, os_event_list, event);
-
- os_event_count++;
-
- os_mutex_exit(os_sync_mutex);
-
- return(event);
-}
-#endif
-
/**********************************************************//**
Sets an event semaphore to the signaled state: lets waiting threads
proceed. */
diff --git a/storage/innodb_plugin/page/page0page.c b/storage/innodb_plugin/page/page0page.c
index 12d0bbe8969..f056ef77bdc 100644
--- a/storage/innodb_plugin/page/page0page.c
+++ b/storage/innodb_plugin/page/page0page.c
@@ -233,9 +233,11 @@ page_set_max_trx_id(
page_zip_write_header(page_zip,
page + (PAGE_HEADER + PAGE_MAX_TRX_ID),
8, mtr);
+#ifndef UNIV_HOTBACKUP
} else if (mtr) {
mlog_write_dulint(page + (PAGE_HEADER + PAGE_MAX_TRX_ID),
trx_id, mtr);
+#endif /* !UNIV_HOTBACKUP */
} else {
mach_write_to_8(page + (PAGE_HEADER + PAGE_MAX_TRX_ID), trx_id);
}
diff --git a/storage/innodb_plugin/page/page0zip.c b/storage/innodb_plugin/page/page0zip.c
index 5af77c7b1b9..92ba0ec768a 100644
--- a/storage/innodb_plugin/page/page0zip.c
+++ b/storage/innodb_plugin/page/page0zip.c
@@ -3021,9 +3021,12 @@ page_zip_hexdump_func(
}
}
+/** Dump a block of memory on the standard error stream.
+@param buf in: data
+@param size in: length of the data, in bytes */
#define page_zip_hexdump(buf, size) page_zip_hexdump_func(#buf, buf, size)
-/* Flag: make page_zip_validate() compare page headers only */
+/** Flag: make page_zip_validate() compare page headers only */
UNIV_INTERN ibool page_zip_validate_header_only = FALSE;
/**********************************************************************//**
@@ -3864,7 +3867,7 @@ page_zip_write_trx_id_and_roll_ptr(
}
#ifdef UNIV_ZIP_DEBUG
-/* Set this variable in a debugger to disable page_zip_clear_rec().
+/** Set this variable in a debugger to disable page_zip_clear_rec().
The only observable effect should be the compression ratio due to
deleted records not being zeroed out. In rare cases, there can be
page_zip_validate() failures on the node_ptr, trx_id and roll_ptr
diff --git a/storage/innodb_plugin/plug.in b/storage/innodb_plugin/plug.in
index da0eee90f57..6daa6c5daed 100644
--- a/storage/innodb_plugin/plug.in
+++ b/storage/innodb_plugin/plug.in
@@ -125,6 +125,32 @@ MYSQL_PLUGIN_ACTIONS(innodb_plugin, [
])
])
])
+ # Check for x86 PAUSE instruction
+ AC_MSG_CHECKING(for x86 PAUSE instruction)
+ # We have to actually try running the test program, because of a bug
+ # in Solaris on x86_64, where it wrongly reports that PAUSE is not
+ # supported when trying to run an application. See
+ # http://bugs.opensolaris.org/bugdatabase/printableBug.do?bug_id=6478684
+ # We use ib_ prefix to avoid collisoins if this code is added to
+ # mysql's configure.in.
+ AC_TRY_RUN(
+ [
+ int main() {
+ __asm__ __volatile__ ("pause");
+ return(0);
+ }
+ ],
+ [
+ AC_DEFINE([IB_HAVE_PAUSE_INSTRUCTION], [1], [Does x86 PAUSE instruction exist])
+ AC_MSG_RESULT(yes)
+ ],
+ [
+ AC_MSG_RESULT(no)
+ ],
+ [
+ AC_MSG_RESULT(no)
+ ]
+ )
])
# vim: set ft=config:
diff --git a/storage/innodb_plugin/que/que0que.c b/storage/innodb_plugin/que/que0que.c
index 8f0673f7b69..54b1e7535fa 100644
--- a/storage/innodb_plugin/que/que0que.c
+++ b/storage/innodb_plugin/que/que0que.c
@@ -696,37 +696,6 @@ que_graph_free(
mem_heap_free(graph->heap);
}
-/**********************************************************************//**
-Checks if the query graph is in a state where it should be freed, and
-frees it in that case. If the session is in a state where it should be
-closed, also this is done.
-@return TRUE if freed */
-UNIV_INTERN
-ibool
-que_graph_try_free(
-/*===============*/
- que_t* graph) /*!< in: query graph */
-{
- sess_t* sess;
-
- ut_ad(mutex_own(&kernel_mutex));
-
- sess = (graph->trx)->sess;
-
- if ((graph->state == QUE_FORK_BEING_FREED)
- && (graph->n_active_thrs == 0)) {
-
- UT_LIST_REMOVE(graphs, sess->graphs, graph);
- que_graph_free(graph);
-
- sess_try_close(sess);
-
- return(TRUE);
- }
-
- return(FALSE);
-}
-
/****************************************************************//**
Performs an execution step on a thr node.
@return query thread to run next, or NULL if none */
diff --git a/storage/innodb_plugin/row/row0merge.c b/storage/innodb_plugin/row/row0merge.c
index 2feeba91bf5..05a45dc647c 100644
--- a/storage/innodb_plugin/row/row0merge.c
+++ b/storage/innodb_plugin/row/row0merge.c
@@ -849,7 +849,14 @@ err_exit:
avail_size = block[1] - b;
memcpy(*buf, b, avail_size);
*mrec = *buf + extra_size;
- rec_offs_make_valid(*mrec, index, offsets);
+#ifdef UNIV_DEBUG
+ /* We cannot invoke rec_offs_make_valid() here, because there
+ are no REC_N_NEW_EXTRA_BYTES between extra_size and data_size.
+ Similarly, rec_offs_validate() would fail, because it invokes
+ rec_get_status(). */
+ offsets[2] = (ulint) *mrec;
+ offsets[3] = (ulint) index;
+#endif /* UNIV_DEBUG */
if (!row_merge_read(fd, ++(*foffs), block)) {
diff --git a/storage/innodb_plugin/row/row0mysql.c b/storage/innodb_plugin/row/row0mysql.c
index b915de20c33..b345bb59624 100644
--- a/storage/innodb_plugin/row/row0mysql.c
+++ b/storage/innodb_plugin/row/row0mysql.c
@@ -1498,9 +1498,14 @@ row_unlock_for_mysql(
index = btr_pcur_get_btr_cur(clust_pcur)->index;
}
+ if (UNIV_UNLIKELY(!dict_index_is_clust(index))) {
+ /* This is not a clustered index record. We
+ do not know how to unlock the record. */
+ goto no_unlock;
+ }
+
/* If the record has been modified by this
transaction, do not unlock it. */
- ut_a(dict_index_is_clust(index));
if (index->trx_id_offset) {
rec_trx_id = trx_read_trx_id(rec
@@ -1540,7 +1545,7 @@ row_unlock_for_mysql(
prebuilt->select_lock_type);
}
}
-
+no_unlock:
mtr_commit(&mtr);
}
diff --git a/storage/innodb_plugin/row/row0row.c b/storage/innodb_plugin/row/row0row.c
index c453252b3b3..128ac3ba3e8 100644
--- a/storage/innodb_plugin/row/row0row.c
+++ b/storage/innodb_plugin/row/row0row.c
@@ -643,67 +643,6 @@ notfound:
}
}
-/*******************************************************************//**
-From a row build a row reference with which we can search the clustered
-index record. */
-UNIV_INTERN
-void
-row_build_row_ref_from_row(
-/*=======================*/
- dtuple_t* ref, /*!< in/out: row reference built;
- see the NOTE below!
- ref must have the right number
- of fields! */
- const dict_table_t* table, /*!< in: table */
- const dtuple_t* row) /*!< in: row
- NOTE: the data fields in ref will point
- directly into data of this row */
-{
- const dict_index_t* clust_index;
- ulint ref_len;
- ulint i;
-
- ut_ad(ref && table && row);
-
- clust_index = dict_table_get_first_index(table);
-
- ref_len = dict_index_get_n_unique(clust_index);
-
- ut_ad(ref_len == dtuple_get_n_fields(ref));
-
- for (i = 0; i < ref_len; i++) {
- const dict_col_t* col;
- const dict_field_t* field;
- dfield_t* dfield;
- const dfield_t* dfield2;
-
- dfield = dtuple_get_nth_field(ref, i);
-
- field = dict_index_get_nth_field(clust_index, i);
-
- col = dict_field_get_col(field);
-
- dfield2 = dtuple_get_nth_field(row, dict_col_get_no(col));
-
- dfield_copy(dfield, dfield2);
- ut_ad(!dfield_is_ext(dfield));
-
- if (field->prefix_len > 0 && !dfield_is_null(dfield)) {
-
- ulint len = dfield_get_len(dfield);
-
- len = dtype_get_at_most_n_mbchars(
- col->prtype, col->mbminlen, col->mbmaxlen,
- field->prefix_len,
- len, dfield_get_data(dfield));
-
- dfield_set_len(dfield, len);
- }
- }
-
- ut_ad(dtuple_check_typed(ref));
-}
-
/***************************************************************//**
Searches the clustered index record for a row, if we have the row reference.
@return TRUE if found */
diff --git a/storage/innodb_plugin/row/row0sel.c b/storage/innodb_plugin/row/row0sel.c
index ea6945813ed..3ef9726588e 100644
--- a/storage/innodb_plugin/row/row0sel.c
+++ b/storage/innodb_plugin/row/row0sel.c
@@ -2782,7 +2782,8 @@ row_sel_store_mysql_rec(
mysql_rec[templ->mysql_null_byte_offset]
|= (byte) templ->mysql_null_bit_mask;
memcpy(mysql_rec + templ->mysql_col_offset,
- prebuilt->default_rec + templ->mysql_col_offset,
+ (const byte*) prebuilt->default_rec
+ + templ->mysql_col_offset,
templ->mysql_col_len);
}
}
diff --git a/storage/innodb_plugin/srv/srv0que.c b/storage/innodb_plugin/srv/srv0que.c
index e2a7b2331e4..fc50a86a55c 100644
--- a/storage/innodb_plugin/srv/srv0que.c
+++ b/storage/innodb_plugin/srv/srv0que.c
@@ -32,63 +32,6 @@ Created 6/5/1996 Heikki Tuuri
#include "que0que.h"
/**********************************************************************//**
-Checks if there is work to do in the server task queue. If there is, the
-thread starts processing a task. Before leaving, it again checks the task
-queue and picks a new task if any exists. This is called by a SRV_WORKER
-thread. */
-UNIV_INTERN
-void
-srv_que_task_queue_check(void)
-/*==========================*/
-{
- que_thr_t* thr;
-
- for (;;) {
- mutex_enter(&kernel_mutex);
-
- thr = UT_LIST_GET_FIRST(srv_sys->tasks);
-
- if (thr == NULL) {
- mutex_exit(&kernel_mutex);
-
- return;
- }
-
- UT_LIST_REMOVE(queue, srv_sys->tasks, thr);
-
- mutex_exit(&kernel_mutex);
-
- que_run_threads(thr);
- }
-}
-
-/**********************************************************************//**
-Performs round-robin on the server tasks. This is called by a SRV_WORKER
-thread every second or so.
-@return the new (may be == thr) query thread to run */
-UNIV_INTERN
-que_thr_t*
-srv_que_round_robin(
-/*================*/
- que_thr_t* thr) /*!< in: query thread */
-{
- que_thr_t* new_thr;
-
- ut_ad(thr);
- ut_ad(thr->state == QUE_THR_RUNNING);
-
- mutex_enter(&kernel_mutex);
-
- UT_LIST_ADD_LAST(queue, srv_sys->tasks, thr);
-
- new_thr = UT_LIST_GET_FIRST(srv_sys->tasks);
-
- mutex_exit(&kernel_mutex);
-
- return(new_thr);
-}
-
-/**********************************************************************//**
Enqueues a task to server task queue and releases a worker thread, if there
is a suspended one. */
UNIV_INTERN
@@ -104,23 +47,3 @@ srv_que_task_enqueue_low(
srv_release_threads(SRV_WORKER, 1);
}
-
-/**********************************************************************//**
-Enqueues a task to server task queue and releases a worker thread, if there
-is a suspended one. */
-UNIV_INTERN
-void
-srv_que_task_enqueue(
-/*=================*/
- que_thr_t* thr) /*!< in: query thread */
-{
- ut_ad(thr);
-
- ut_a(0); /* Under MySQL this is never called */
-
- mutex_enter(&kernel_mutex);
-
- srv_que_task_enqueue_low(thr);
-
- mutex_exit(&kernel_mutex);
-}
diff --git a/storage/innodb_plugin/srv/srv0srv.c b/storage/innodb_plugin/srv/srv0srv.c
index 3a70562bc00..79fa08e7cdf 100644
--- a/storage/innodb_plugin/srv/srv0srv.c
+++ b/storage/innodb_plugin/srv/srv0srv.c
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 1995, 2009, Innobase Oy. All Rights Reserved.
-Copyright (c) 2008, Google Inc.
+Copyright (c) 2008, 2009 Google Inc.
Portions of this file contain modifications contributed and copyrighted by
Google, Inc. Those modifications are gratefully acknowledged and are described
@@ -22,6 +22,32 @@ this program; if not, write to the Free Software Foundation, Inc., 59 Temple
Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
+/***********************************************************************
+
+Copyright (c) 1995, 2009, Innobase Oy. All Rights Reserved.
+Copyright (c) 2009, Percona Inc.
+
+Portions of this file contain modifications contributed and copyrighted
+by Percona Inc.. Those modifications are
+gratefully acknowledged and are described briefly in the InnoDB
+documentation. The contributions by Percona Inc. are incorporated with
+their permission, and subject to the conditions contained in the file
+COPYING.Percona.
+
+This program is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; version 2 of the License.
+
+This program is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
+Public License for more details.
+
+You should have received a copy of the GNU General Public License along
+with this program; if not, write to the Free Software Foundation, Inc.,
+59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+***********************************************************************/
/**************************************************//**
@file srv/srv0srv.c
@@ -97,7 +123,7 @@ UNIV_INTERN ibool srv_error_monitor_active = FALSE;
UNIV_INTERN const char* srv_main_thread_op_info = "";
-/* Prefix used by MySQL to indicate pre-5.1 table name encoding */
+/** Prefix used by MySQL to indicate pre-5.1 table name encoding */
UNIV_INTERN const char srv_mysql50_table_name_prefix[9] = "#mysql50#";
/* Server parameters which are read from the initfile */
@@ -110,12 +136,12 @@ UNIV_INTERN char* srv_data_home = NULL;
UNIV_INTERN char* srv_arch_dir = NULL;
#endif /* UNIV_LOG_ARCHIVE */
-/* store to its own file each table created by an user; data
+/** store to its own file each table created by an user; data
dictionary tables are in the system tablespace 0 */
UNIV_INTERN my_bool srv_file_per_table;
-/* The file format to use on new *.ibd files. */
+/** The file format to use on new *.ibd files. */
UNIV_INTERN ulint srv_file_format = 0;
-/* Whether to check file format during startup a value of
+/** Whether to check file format during startup. A value of
DICT_TF_FORMAT_MAX + 1 means no checking ie. FALSE. The default is to
set it to the highest format we support. */
UNIV_INTERN ulint srv_check_file_format_at_startup = DICT_TF_FORMAT_MAX;
@@ -123,7 +149,7 @@ UNIV_INTERN ulint srv_check_file_format_at_startup = DICT_TF_FORMAT_MAX;
#if DICT_TF_FORMAT_51
# error "DICT_TF_FORMAT_51 must be 0!"
#endif
-/* Place locks to records only i.e. do not use next-key locking except
+/** Place locks to records only i.e. do not use next-key locking except
on duplicate key checking and foreign key checking */
UNIV_INTERN ibool srv_locks_unsafe_for_binlog = FALSE;
@@ -157,6 +183,10 @@ UNIV_INTERN ulint srv_log_file_size = ULINT_MAX;
UNIV_INTERN ulint srv_log_buffer_size = ULINT_MAX;
UNIV_INTERN ulong srv_flush_log_at_trx_commit = 1;
+/* Try to flush dirty pages so as to avoid IO bursts at
+the checkpoints. */
+UNIV_INTERN char srv_adaptive_flushing = TRUE;
+
/* The sort order table of the MySQL latin1_swedish_ci character set
collation */
UNIV_INTERN const byte* srv_latin1_ordering;
@@ -173,7 +203,16 @@ UNIV_INTERN ulint srv_buf_pool_curr_size = 0;
UNIV_INTERN ulint srv_mem_pool_size = ULINT_MAX;
UNIV_INTERN ulint srv_lock_table_size = ULINT_MAX;
+/* This parameter is deprecated. Use srv_n_io_[read|write]_threads
+instead. */
UNIV_INTERN ulint srv_n_file_io_threads = ULINT_MAX;
+UNIV_INTERN ulint srv_n_read_io_threads = ULINT_MAX;
+UNIV_INTERN ulint srv_n_write_io_threads = ULINT_MAX;
+
+/* User settable value of the number of pages that must be present
+in the buffer cache and accessed sequentially for InnoDB to trigger a
+readahead request. */
+UNIV_INTERN ulong srv_read_ahead_threshold = 56;
#ifdef UNIV_LOG_ARCHIVE
UNIV_INTERN ibool srv_log_archive_on = FALSE;
@@ -197,12 +236,15 @@ UNIV_INTERN ulint srv_win_file_flush_method = SRV_WIN_IO_UNBUFFERED;
UNIV_INTERN ulint srv_max_n_open_files = 300;
+/* Number of IO operations per second the server can do */
+UNIV_INTERN ulong srv_io_capacity = 200;
+
/* The InnoDB main thread tries to keep the ratio of modified pages
in the buffer pool to all database pages in the buffer pool smaller than
the following number. But it is not guaranteed that the value stays below
that during a time of heavy update/insert activity. */
-UNIV_INTERN ulong srv_max_buf_pool_modified_pct = 90;
+UNIV_INTERN ulong srv_max_buf_pool_modified_pct = 75;
/* variable counts amount of data read in total (in bytes) */
UNIV_INTERN ulint srv_data_read = 0;
@@ -338,10 +380,10 @@ UNIV_INTERN int srv_query_thread_priority = 0;
UNIV_INTERN ulong srv_replication_delay = 0;
/*-------------------------------------------*/
-UNIV_INTERN ulong srv_n_spin_wait_rounds = 20;
+UNIV_INTERN ulong srv_n_spin_wait_rounds = 30;
UNIV_INTERN ulong srv_n_free_tickets_to_enter = 500;
UNIV_INTERN ulong srv_thread_sleep_delay = 10000;
-UNIV_INTERN ulong srv_spin_wait_delay = 5;
+UNIV_INTERN ulong srv_spin_wait_delay = 6;
UNIV_INTERN ibool srv_priority_boost = TRUE;
#ifdef UNIV_DEBUG
@@ -408,6 +450,36 @@ UNIV_INTERN FILE* srv_misc_tmpfile;
UNIV_INTERN ulint srv_main_thread_process_no = 0;
UNIV_INTERN ulint srv_main_thread_id = 0;
+/* The following count work done by srv_master_thread. */
+
+/* Iterations by the 'once per second' loop. */
+static ulint srv_main_1_second_loops = 0;
+/* Calls to sleep by the 'once per second' loop. */
+static ulint srv_main_sleeps = 0;
+/* Iterations by the 'once per 10 seconds' loop. */
+static ulint srv_main_10_second_loops = 0;
+/* Iterations of the loop bounded by the 'background_loop' label. */
+static ulint srv_main_background_loops = 0;
+/* Iterations of the loop bounded by the 'flush_loop' label. */
+static ulint srv_main_flush_loops = 0;
+/* Log writes involving flush. */
+static ulint srv_log_writes_and_flush = 0;
+/* Log writes not including flush. */
+static ulint srv_log_buffer_writes = 0;
+
+/* This is only ever touched by the master thread. It records the
+time when the last flush of log file has happened. The master
+thread ensures that we flush the log files at least once per
+second. */
+static time_t srv_last_log_flush_time;
+
+/* The master thread performs various tasks based on the current
+state of IO activity and the level of IO utilization is past
+intervals. Following macros define thresholds for these conditions. */
+#define SRV_PEND_IO_THRESHOLD (PCT_IO(3))
+#define SRV_RECENT_IO_ACTIVITY (PCT_IO(5))
+#define SRV_PAST_IO_ACTIVITY (PCT_IO(200))
+
/*
IMPLEMENTATION OF THE SERVER MAIN PROGRAM
=========================================
@@ -629,6 +701,24 @@ are indexed by the type of the thread. */
UNIV_INTERN ulint srv_n_threads_active[SRV_MASTER + 1];
UNIV_INTERN ulint srv_n_threads[SRV_MASTER + 1];
+/***********************************************************************
+Prints counters for work done by srv_master_thread. */
+static
+void
+srv_print_master_thread_info(
+/*=========================*/
+ FILE *file) /* in: output stream */
+{
+ fprintf(file, "srv_master_thread loops: %lu 1_second, %lu sleeps, "
+ "%lu 10_second, %lu background, %lu flush\n",
+ srv_main_1_second_loops, srv_main_sleeps,
+ srv_main_10_second_loops, srv_main_background_loops,
+ srv_main_flush_loops);
+ fprintf(file, "srv_master_thread log flush and writes: %lu "
+ " log writes only: %lu\n",
+ srv_log_writes_and_flush, srv_log_buffer_writes);
+}
+
/*********************************************************************//**
Sets the info describing an i/o thread current state. */
UNIV_INTERN
@@ -1624,6 +1714,11 @@ srv_printf_innodb_monitor(
(ulong)time_elapsed);
fputs("----------\n"
+ "BACKGROUND THREAD\n"
+ "----------\n", file);
+ srv_print_master_thread_info(file);
+
+ fputs("----------\n"
"SEMAPHORES\n"
"----------\n", file);
sync_print(file);
@@ -2082,13 +2177,16 @@ loop:
}
/* Update the statistics collected for deciding LRU
- eviction policy. */
+ eviction policy. */
buf_LRU_stat_update();
+ /* Update the statistics collected for flush rate policy. */
+ buf_flush_stat_update();
+
/* In case mutex_exit is not a memory barrier, it is
theoretically possible some threads are left waiting though
the semaphore is already released. Wake up those threads: */
-
+
sync_arr_wake_threads_if_sema_free();
if (sync_array_print_long_waits()) {
@@ -2169,6 +2267,32 @@ srv_wake_master_thread(void)
mutex_exit(&kernel_mutex);
}
+/**********************************************************************
+The master thread is tasked to ensure that flush of log file happens
+once every second in the background. This is to ensure that not more
+than one second of trxs are lost in case of crash when
+innodb_flush_logs_at_trx_commit != 1 */
+static
+void
+srv_sync_log_buffer_in_background(void)
+/*===================================*/
+{
+ time_t current_time = time(NULL);
+
+ srv_main_thread_op_info = "flushing log";
+ if (difftime(current_time, srv_last_log_flush_time) >= 1) {
+ log_buffer_sync_in_background(TRUE);
+ srv_last_log_flush_time = current_time;
+ srv_log_writes_and_flush++;
+ } else {
+ /* Actually we don't need to write logs here.
+ We are just being extra safe here by forcing
+ the log buffer to log file. */
+ log_buffer_sync_in_background(FALSE);
+ srv_log_buffer_writes++;
+ }
+}
+
/*********************************************************************//**
The master thread controlling the server.
@return a dummy parameter */
@@ -2181,8 +2305,6 @@ srv_master_thread(
os_thread_create */
{
os_event_t event;
- time_t last_flush_time;
- time_t current_time;
ulint old_activity_count;
ulint n_pages_purged = 0;
ulint n_bytes_merged;
@@ -2235,16 +2357,19 @@ loop:
/* ---- We run the following loop approximately once per second
when there is database activity */
+ srv_last_log_flush_time = time(NULL);
skip_sleep = FALSE;
for (i = 0; i < 10; i++) {
n_ios_old = log_sys->n_log_ios + buf_pool->n_pages_read
+ buf_pool->n_pages_written;
srv_main_thread_op_info = "sleeping";
+ srv_main_1_second_loops++;
if (!skip_sleep) {
os_thread_sleep(1000000);
+ srv_main_sleeps++;
}
skip_sleep = FALSE;
@@ -2264,33 +2389,27 @@ loop:
goto background_loop;
}
- /* We flush the log once in a second even if no commit
- is issued or the we have specified in my.cnf no flush
- at transaction commit */
-
- srv_main_thread_op_info = "flushing log";
- log_buffer_flush_to_disk();
+ /* Flush logs if needed */
+ srv_sync_log_buffer_in_background();
srv_main_thread_op_info = "making checkpoint";
log_free_check();
- /* If there were less than 5 i/os during the
- one second sleep, we assume that there is free
- disk i/o capacity available, and it makes sense to
- do an insert buffer merge. */
+ /* If i/os during one second sleep were less than 5% of
+ capacity, we assume that there is free disk i/o capacity
+ available, and it makes sense to do an insert buffer merge. */
n_pend_ios = buf_get_n_pending_ios()
+ log_sys->n_pending_writes;
n_ios = log_sys->n_log_ios + buf_pool->n_pages_read
+ buf_pool->n_pages_written;
- if (n_pend_ios < 3 && (n_ios - n_ios_old < 5)) {
+ if (n_pend_ios < SRV_PEND_IO_THRESHOLD
+ && (n_ios - n_ios_old < SRV_RECENT_IO_ACTIVITY)) {
srv_main_thread_op_info = "doing insert buffer merge";
- ibuf_contract_for_n_pages(
- TRUE, srv_insert_buffer_batch_size / 4);
-
- srv_main_thread_op_info = "flushing log";
+ ibuf_contract_for_n_pages(FALSE, PCT_IO(5));
- log_buffer_flush_to_disk();
+ /* Flush logs if needed */
+ srv_sync_log_buffer_in_background();
}
if (UNIV_UNLIKELY(buf_get_modified_ratio_pct()
@@ -2299,7 +2418,8 @@ loop:
/* Try to keep the number of modified pages in the
buffer pool under the limit wished by the user */
- n_pages_flushed = buf_flush_batch(BUF_FLUSH_LIST, 100,
+ n_pages_flushed = buf_flush_batch(BUF_FLUSH_LIST,
+ PCT_IO(100),
IB_ULONGLONG_MAX);
/* If we had to do the flush, it may have taken
@@ -2308,6 +2428,22 @@ loop:
iteration of this loop. */
skip_sleep = TRUE;
+ } else if (srv_adaptive_flushing) {
+
+ /* Try to keep the rate of flushing of dirty
+ pages such that redo log generation does not
+ produce bursts of IO at checkpoint time. */
+ ulint n_flush = buf_flush_get_desired_flush_rate();
+
+ if (n_flush) {
+ n_flush = ut_min(PCT_IO(100), n_flush);
+ n_pages_flushed =
+ buf_flush_batch(
+ BUF_FLUSH_LIST,
+ n_flush,
+ IB_ULONGLONG_MAX);
+ skip_sleep = TRUE;
+ }
}
if (srv_activity_count == old_activity_count) {
@@ -2327,36 +2463,42 @@ loop:
seconds */
mem_validate_all_blocks();
#endif
- /* If there were less than 200 i/os during the 10 second period,
- we assume that there is free disk i/o capacity available, and it
- makes sense to flush 100 pages. */
+ /* If i/os during the 10 second period were less than 200% of
+ capacity, we assume that there is free disk i/o capacity
+ available, and it makes sense to flush srv_io_capacity pages.
+
+ Note that this is done regardless of the fraction of dirty
+ pages relative to the max requested by the user. The one second
+ loop above requests writes for that case. The writes done here
+ are not required, and may be disabled. */
n_pend_ios = buf_get_n_pending_ios() + log_sys->n_pending_writes;
n_ios = log_sys->n_log_ios + buf_pool->n_pages_read
+ buf_pool->n_pages_written;
- if (n_pend_ios < 3 && (n_ios - n_ios_very_old < 200)) {
+
+ srv_main_10_second_loops++;
+ if (n_pend_ios < SRV_PEND_IO_THRESHOLD
+ && (n_ios - n_ios_very_old < SRV_PAST_IO_ACTIVITY)) {
srv_main_thread_op_info = "flushing buffer pool pages";
- buf_flush_batch(BUF_FLUSH_LIST, 100, IB_ULONGLONG_MAX);
+ buf_flush_batch(BUF_FLUSH_LIST, PCT_IO(100),
+ IB_ULONGLONG_MAX);
- srv_main_thread_op_info = "flushing log";
- log_buffer_flush_to_disk();
+ /* Flush logs if needed */
+ srv_sync_log_buffer_in_background();
}
/* We run a batch of insert buffer merge every 10 seconds,
even if the server were active */
srv_main_thread_op_info = "doing insert buffer merge";
- ibuf_contract_for_n_pages(TRUE, srv_insert_buffer_batch_size / 4);
+ ibuf_contract_for_n_pages(FALSE, PCT_IO(5));
- srv_main_thread_op_info = "flushing log";
- log_buffer_flush_to_disk();
+ /* Flush logs if needed */
+ srv_sync_log_buffer_in_background();
/* We run a full purge every 10 seconds, even if the server
were active */
-
- last_flush_time = time(NULL);
-
do {
if (srv_fast_shutdown && srv_shutdown_state > 0) {
@@ -2367,14 +2509,9 @@ loop:
srv_main_thread_op_info = "purging";
n_pages_purged = trx_purge();
- current_time = time(NULL);
-
- if (difftime(current_time, last_flush_time) > 1) {
- srv_main_thread_op_info = "flushing log";
+ /* Flush logs if needed */
+ srv_sync_log_buffer_in_background();
- log_buffer_flush_to_disk();
- last_flush_time = current_time;
- }
} while (n_pages_purged);
srv_main_thread_op_info = "flushing buffer pool pages";
@@ -2387,14 +2524,16 @@ loop:
(> 70 %), we assume we can afford reserving the disk(s) for
the time it requires to flush 100 pages */
- n_pages_flushed = buf_flush_batch(BUF_FLUSH_LIST, 100,
+ n_pages_flushed = buf_flush_batch(BUF_FLUSH_LIST,
+ PCT_IO(100),
IB_ULONGLONG_MAX);
} else {
/* Otherwise, we only flush a small number of pages so that
we do not unnecessarily use much disk i/o capacity from
other work */
- n_pages_flushed = buf_flush_batch(BUF_FLUSH_LIST, 10,
+ n_pages_flushed = buf_flush_batch(BUF_FLUSH_LIST,
+ PCT_IO(10),
IB_ULONGLONG_MAX);
}
@@ -2428,7 +2567,7 @@ background_loop:
/* The server has been quiet for a while: start running background
operations */
-
+ srv_main_background_loops++;
srv_main_thread_op_info = "doing background drop tables";
n_tables_to_drop = row_drop_tables_for_mysql_in_background();
@@ -2445,9 +2584,6 @@ background_loop:
srv_main_thread_op_info = "purging";
/* Run a full purge */
-
- last_flush_time = time(NULL);
-
do {
if (srv_fast_shutdown && srv_shutdown_state > 0) {
@@ -2457,14 +2593,9 @@ background_loop:
srv_main_thread_op_info = "purging";
n_pages_purged = trx_purge();
- current_time = time(NULL);
-
- if (difftime(current_time, last_flush_time) > 1) {
- srv_main_thread_op_info = "flushing log";
+ /* Flush logs if needed */
+ srv_sync_log_buffer_in_background();
- log_buffer_flush_to_disk();
- last_flush_time = current_time;
- }
} while (n_pages_purged);
srv_main_thread_op_info = "reserving kernel mutex";
@@ -2481,8 +2612,12 @@ background_loop:
if (srv_fast_shutdown && srv_shutdown_state > 0) {
n_bytes_merged = 0;
} else {
- n_bytes_merged = ibuf_contract_for_n_pages(
- TRUE, srv_insert_buffer_batch_size);
+ /* This should do an amount of IO similar to the number of
+ dirty pages that will be flushed in the call to
+ buf_flush_batch below. Otherwise, the system favors
+ clean pages over cleanup throughput. */
+ n_bytes_merged = ibuf_contract_for_n_pages(FALSE,
+ PCT_IO(100));
}
srv_main_thread_op_info = "reserving kernel mutex";
@@ -2496,9 +2631,10 @@ background_loop:
flush_loop:
srv_main_thread_op_info = "flushing buffer pool pages";
-
+ srv_main_flush_loops++;
if (srv_fast_shutdown < 2) {
- n_pages_flushed = buf_flush_batch(BUF_FLUSH_LIST, 100,
+ n_pages_flushed = buf_flush_batch(BUF_FLUSH_LIST,
+ PCT_IO(100),
IB_ULONGLONG_MAX);
} else {
/* In the fastest shutdown we do not flush the buffer pool
@@ -2519,9 +2655,8 @@ flush_loop:
srv_main_thread_op_info = "waiting for buffer pool flush to end";
buf_flush_wait_batch_end(BUF_FLUSH_LIST);
- srv_main_thread_op_info = "flushing log";
-
- log_buffer_flush_to_disk();
+ /* Flush logs if needed */
+ srv_sync_log_buffer_in_background();
srv_main_thread_op_info = "making checkpoint";
diff --git a/storage/innodb_plugin/srv/srv0start.c b/storage/innodb_plugin/srv/srv0start.c
index c329d9cad86..a942fd439a3 100644
--- a/storage/innodb_plugin/srv/srv0start.c
+++ b/storage/innodb_plugin/srv/srv0start.c
@@ -22,6 +22,32 @@ this program; if not, write to the Free Software Foundation, Inc., 59 Temple
Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
+/***********************************************************************
+
+Copyright (c) 1995, 2009, Innobase Oy. All Rights Reserved.
+Copyright (c) 2009, Percona Inc.
+
+Portions of this file contain modifications contributed and copyrighted
+by Percona Inc.. Those modifications are
+gratefully acknowledged and are described briefly in the InnoDB
+documentation. The contributions by Percona Inc. are incorporated with
+their permission, and subject to the conditions contained in the file
+COPYING.Percona.
+
+This program is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; version 2 of the License.
+
+This program is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
+Public License for more details.
+
+You should have received a copy of the GNU General Public License along
+with this program; if not, write to the Free Software Foundation, Inc.,
+59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+***********************************************************************/
/********************************************************************//**
@file srv/srv0start.c
@@ -1007,6 +1033,7 @@ innobase_start_or_create_for_mysql(void)
ulint tablespace_size_in_header;
ulint err;
ulint i;
+ ulint io_limit;
my_bool srv_file_per_table_original_value
= srv_file_per_table;
mtr_t mtr;
@@ -1135,19 +1162,21 @@ innobase_start_or_create_for_mysql(void)
os_aio_use_native_aio = FALSE;
#ifdef __WIN__
- if (os_get_os_version() == OS_WIN95
- || os_get_os_version() == OS_WIN31
- || os_get_os_version() == OS_WINNT) {
-
+ switch (os_get_os_version()) {
+ case OS_WIN95:
+ case OS_WIN31:
+ case OS_WINNT:
/* On Win 95, 98, ME, Win32 subsystem for Windows 3.1,
and NT use simulated aio. In NT Windows provides async i/o,
but when run in conjunction with InnoDB Hot Backup, it seemed
to corrupt the data files. */
os_aio_use_native_aio = FALSE;
- } else {
+ break;
+ default:
/* On Win 2000 and XP use async i/o */
os_aio_use_native_aio = TRUE;
+ break;
}
#endif
if (srv_file_flush_method_str == NULL) {
@@ -1265,27 +1294,35 @@ innobase_start_or_create_for_mysql(void)
return(DB_ERROR);
}
- /* Restrict the maximum number of file i/o threads */
- if (srv_n_file_io_threads > SRV_MAX_N_IO_THREADS) {
-
- srv_n_file_io_threads = SRV_MAX_N_IO_THREADS;
+ /* If user has set the value of innodb_file_io_threads then
+ we'll emit a message telling the user that this parameter
+ is now deprecated. */
+ if (srv_n_file_io_threads != 4) {
+ fprintf(stderr, "InnoDB: Warning:"
+ " innodb_file_io_threads is deprecated."
+ " Please use innodb_read_io_threads and"
+ " innodb_write_io_threads instead\n");
}
- if (!os_aio_use_native_aio) {
- /* In simulated aio we currently have use only for 4 threads */
- srv_n_file_io_threads = 4;
+ /* Now overwrite the value on srv_n_file_io_threads */
+ srv_n_file_io_threads = 2 + srv_n_read_io_threads
+ + srv_n_write_io_threads;
+
+ ut_a(srv_n_file_io_threads <= SRV_MAX_N_IO_THREADS);
- os_aio_init(8 * SRV_N_PENDING_IOS_PER_THREAD
- * srv_n_file_io_threads,
- srv_n_file_io_threads,
- SRV_MAX_N_PENDING_SYNC_IOS);
+ /* TODO: Investigate if SRV_N_PENDING_IOS_PER_THREAD (32) limit
+ still applies to windows. */
+ if (!os_aio_use_native_aio) {
+ io_limit = 8 * SRV_N_PENDING_IOS_PER_THREAD;
} else {
- os_aio_init(SRV_N_PENDING_IOS_PER_THREAD
- * srv_n_file_io_threads,
- srv_n_file_io_threads,
- SRV_MAX_N_PENDING_SYNC_IOS);
+ io_limit = SRV_N_PENDING_IOS_PER_THREAD;
}
+ os_aio_init(io_limit,
+ srv_n_read_io_threads,
+ srv_n_write_io_threads,
+ SRV_MAX_N_PENDING_SYNC_IOS);
+
fil_init(srv_file_per_table ? 50000 : 5000,
srv_max_n_open_files);
diff --git a/storage/innodb_plugin/sync/sync0sync.c b/storage/innodb_plugin/sync/sync0sync.c
index 39a3c7d98d5..84ed08e14e7 100644
--- a/storage/innodb_plugin/sync/sync0sync.c
+++ b/storage/innodb_plugin/sync/sync0sync.c
@@ -484,11 +484,13 @@ spin_loop:
if (i == SYNC_SPIN_ROUNDS) {
#ifdef UNIV_DEBUG
mutex->count_os_yield++;
- if (timed_mutexes == 1 && timer_started==0) {
+#ifndef UNIV_HOTBACKUP
+ if (timed_mutexes && timer_started == 0) {
ut_usectime(&sec, &ms);
lstart_time= (ib_int64_t)sec * 1000000 + ms;
timer_started = 1;
}
+#endif /* UNIV_HOTBACKUP */
#endif /* UNIV_DEBUG */
os_thread_yield();
}
@@ -583,12 +585,13 @@ spin_loop:
mutex->count_os_wait++;
#ifdef UNIV_DEBUG
/* !!!!! Sometimes os_wait can be called without os_thread_yield */
-
- if (timed_mutexes == 1 && timer_started==0) {
+#ifndef UNIV_HOTBACKUP
+ if (timed_mutexes == 1 && timer_started == 0) {
ut_usectime(&sec, &ms);
lstart_time= (ib_int64_t)sec * 1000000 + ms;
timer_started = 1;
}
+#endif /* UNIV_HOTBACKUP */
#endif /* UNIV_DEBUG */
sync_array_wait_event(sync_primary_wait_array, index);
diff --git a/storage/innodb_plugin/trx/trx0purge.c b/storage/innodb_plugin/trx/trx0purge.c
index b936d4d5d74..cd79fd1c315 100644
--- a/storage/innodb_plugin/trx/trx0purge.c
+++ b/storage/innodb_plugin/trx/trx0purge.c
@@ -31,6 +31,7 @@ Created 3/26/1996 Heikki Tuuri
#include "fsp0fsp.h"
#include "mach0data.h"
+#include "mtr0log.h"
#include "trx0rseg.h"
#include "trx0trx.h"
#include "trx0roll.h"
diff --git a/storage/innodb_plugin/trx/trx0sys.c b/storage/innodb_plugin/trx/trx0sys.c
index 502dba4553d..ef10119587d 100644
--- a/storage/innodb_plugin/trx/trx0sys.c
+++ b/storage/innodb_plugin/trx/trx0sys.c
@@ -31,7 +31,8 @@ Created 3/26/1996 Heikki Tuuri
#ifndef UNIV_HOTBACKUP
#include "fsp0fsp.h"
-#include "mtr0mtr.h"
+#include "mtr0log.h"
+#include "mtr0log.h"
#include "trx0trx.h"
#include "trx0rseg.h"
#include "trx0undo.h"
@@ -60,6 +61,8 @@ UNIV_INTERN trx_doublewrite_t* trx_doublewrite = NULL;
/** The following is set to TRUE when we are upgrading from pre-4.1
format data files to the multiple tablespaces format data files */
UNIV_INTERN ibool trx_doublewrite_must_reset_space_ids = FALSE;
+/** Set to TRUE when the doublewrite buffer is being created */
+UNIV_INTERN ibool trx_doublewrite_buf_is_being_created = FALSE;
/** The following is TRUE when we are using the database in the
post-4.1 format, i.e., we have successfully upgraded, or have created
@@ -86,6 +89,7 @@ UNIV_INTERN char trx_sys_mysql_bin_log_name[TRX_SYS_MYSQL_LOG_NAME_LEN];
/** Binlog file position, or -1 if unknown */
UNIV_INTERN ib_int64_t trx_sys_mysql_bin_log_pos = -1;
/* @} */
+#endif /* !UNIV_HOTBACKUP */
/** List of animal names representing file format. */
static const char* file_format_name_map[] = {
@@ -121,6 +125,7 @@ static const char* file_format_name_map[] = {
static const ulint FILE_FORMAT_NAME_N
= sizeof(file_format_name_map) / sizeof(file_format_name_map[0]);
+#ifndef UNIV_HOTBACKUP
/** This is used to track the maximum file format id known to InnoDB. It's
updated via SET GLOBAL innodb_file_format_check = 'x' or when we open
or create a table. */
@@ -251,6 +256,7 @@ trx_sys_create_doublewrite_buf(void)
start_again:
mtr_start(&mtr);
+ trx_doublewrite_buf_is_being_created = TRUE;
block = buf_page_get(TRX_SYS_SPACE, 0, TRX_SYS_PAGE_NO,
RW_X_LATCH, &mtr);
@@ -266,6 +272,7 @@ start_again:
trx_doublewrite_init(doublewrite);
mtr_commit(&mtr);
+ trx_doublewrite_buf_is_being_created = FALSE;
} else {
fprintf(stderr,
"InnoDB: Doublewrite buffer not found:"
@@ -341,15 +348,8 @@ start_again:
buf_block_dbg_add_level(new_block,
SYNC_NO_ORDER_CHECK);
- /* Make a dummy change to the page to ensure it will
- be written to disk in a flush */
-
- mlog_write_ulint(buf_block_get_frame(new_block)
- + FIL_PAGE_TYPE,
- FIL_PAGE_TYPE_ALLOCATED,
- MLOG_2BYTES, &mtr);
-
if (i == FSP_EXTENT_SIZE / 2) {
+ ut_a(page_no == FSP_EXTENT_SIZE);
mlog_write_ulint(doublewrite
+ TRX_SYS_DOUBLEWRITE_BLOCK1,
page_no, MLOG_4BYTES, &mtr);
@@ -359,6 +359,7 @@ start_again:
page_no, MLOG_4BYTES, &mtr);
} else if (i == FSP_EXTENT_SIZE / 2
+ TRX_SYS_DOUBLEWRITE_BLOCK_SIZE) {
+ ut_a(page_no == 2 * FSP_EXTENT_SIZE);
mlog_write_ulint(doublewrite
+ TRX_SYS_DOUBLEWRITE_BLOCK2,
page_no, MLOG_4BYTES, &mtr);
@@ -1333,4 +1334,202 @@ trx_sys_print_mysql_binlog_offset_from_page(
+ TRX_SYS_MYSQL_LOG_NAME);
}
}
+
+
+/* THESE ARE COPIED FROM NON-HOTBACKUP PART OF THE INNODB SOURCE TREE
+ (This code duplicaton should be fixed at some point!)
+*/
+
+#define TRX_SYS_SPACE 0 /* the SYSTEM tablespace */
+/* The offset of the file format tag on the trx system header page */
+#define TRX_SYS_FILE_FORMAT_TAG (UNIV_PAGE_SIZE - 16)
+/* We use these random constants to reduce the probability of reading
+garbage (from previous versions) that maps to an actual format id. We
+use these as bit masks at the time of reading and writing from/to disk. */
+#define TRX_SYS_FILE_FORMAT_TAG_MAGIC_N_LOW 3645922177UL
+#define TRX_SYS_FILE_FORMAT_TAG_MAGIC_N_HIGH 2745987765UL
+
+/* END OF COPIED DEFINITIONS */
+
+
+/*****************************************************************//**
+Reads the file format id from the first system table space file.
+Even if the call succeeds and returns TRUE, the returned format id
+may be ULINT_UNDEFINED signalling that the format id was not present
+in the data file.
+@return TRUE if call succeeds */
+UNIV_INTERN
+ibool
+trx_sys_read_file_format_id(
+/*========================*/
+ const char *pathname, /*!< in: pathname of the first system
+ table space file */
+ ulint *format_id) /*!< out: file format of the system table
+ space */
+{
+ os_file_t file;
+ ibool success;
+ byte buf[UNIV_PAGE_SIZE * 2];
+ page_t* page = ut_align(buf, UNIV_PAGE_SIZE);
+ const byte* ptr;
+ dulint file_format_id;
+
+ *format_id = ULINT_UNDEFINED;
+
+ file = os_file_create_simple_no_error_handling(
+ pathname,
+ OS_FILE_OPEN,
+ OS_FILE_READ_ONLY,
+ &success
+ );
+ if (!success) {
+ /* The following call prints an error message */
+ os_file_get_last_error(TRUE);
+
+ ut_print_timestamp(stderr);
+
+ fprintf(stderr,
+" ibbackup: Error: trying to read system tablespace file format,\n"
+" ibbackup: but could not open the tablespace file %s!\n",
+ pathname
+ );
+ return(FALSE);
+ }
+
+ /* Read the page on which file format is stored */
+
+ success = os_file_read_no_error_handling(
+ file, page, TRX_SYS_PAGE_NO * UNIV_PAGE_SIZE, 0, UNIV_PAGE_SIZE
+ );
+ if (!success) {
+ /* The following call prints an error message */
+ os_file_get_last_error(TRUE);
+
+ ut_print_timestamp(stderr);
+
+ fprintf(stderr,
+" ibbackup: Error: trying to read system table space file format,\n"
+" ibbackup: but failed to read the tablespace file %s!\n",
+ pathname
+ );
+ os_file_close(file);
+ return(FALSE);
+ }
+ os_file_close(file);
+
+ /* get the file format from the page */
+ ptr = page + TRX_SYS_FILE_FORMAT_TAG;
+ file_format_id = mach_read_from_8(ptr);
+
+ *format_id = file_format_id.low - TRX_SYS_FILE_FORMAT_TAG_MAGIC_N_LOW;
+
+ if (file_format_id.high != TRX_SYS_FILE_FORMAT_TAG_MAGIC_N_HIGH
+ || *format_id >= FILE_FORMAT_NAME_N) {
+
+ /* Either it has never been tagged, or garbage in it. */
+ *format_id = ULINT_UNDEFINED;
+ return(TRUE);
+ }
+
+ return(TRUE);
+}
+
+
+/*****************************************************************//**
+Reads the file format id from the given per-table data file.
+@return TRUE if call succeeds */
+UNIV_INTERN
+ibool
+trx_sys_read_pertable_file_format_id(
+/*=================================*/
+ const char *pathname, /*!< in: pathname of a per-table
+ datafile */
+ ulint *format_id) /*!< out: file format of the per-table
+ data file */
+{
+ os_file_t file;
+ ibool success;
+ byte buf[UNIV_PAGE_SIZE * 2];
+ page_t* page = ut_align(buf, UNIV_PAGE_SIZE);
+ const byte* ptr;
+ ib_uint32_t flags;
+
+ *format_id = ULINT_UNDEFINED;
+
+ file = os_file_create_simple_no_error_handling(
+ pathname,
+ OS_FILE_OPEN,
+ OS_FILE_READ_ONLY,
+ &success
+ );
+ if (!success) {
+ /* The following call prints an error message */
+ os_file_get_last_error(TRUE);
+
+ ut_print_timestamp(stderr);
+
+ fprintf(stderr,
+" ibbackup: Error: trying to read per-table tablespace format,\n"
+" ibbackup: but could not open the tablespace file %s!\n",
+ pathname
+ );
+ return(FALSE);
+ }
+
+ /* Read the first page of the per-table datafile */
+
+ success = os_file_read_no_error_handling(
+ file, page, 0, 0, UNIV_PAGE_SIZE
+ );
+ if (!success) {
+ /* The following call prints an error message */
+ os_file_get_last_error(TRUE);
+
+ ut_print_timestamp(stderr);
+
+ fprintf(stderr,
+" ibbackup: Error: trying to per-table data file format,\n"
+" ibbackup: but failed to read the tablespace file %s!\n",
+ pathname
+ );
+ os_file_close(file);
+ return(FALSE);
+ }
+ os_file_close(file);
+
+ /* get the file format from the page */
+ ptr = page + 54;
+ flags = mach_read_from_4(ptr);
+ if (flags == 0) {
+ /* file format is Antelope */
+ *format_id = 0;
+ return (TRUE);
+ } else if (flags & 1) {
+ /* tablespace flags are ok */
+ *format_id = (flags / 32) % 128;
+ return (TRUE);
+ } else {
+ /* bad tablespace flags */
+ return(FALSE);
+ }
+}
+
+
+/*****************************************************************//**
+Get the name representation of the file format from its id.
+@return pointer to the name */
+UNIV_INTERN
+const char*
+trx_sys_file_format_id_to_name(
+/*===========================*/
+ const ulint id) /*!< in: id of the file format */
+{
+ if (!(id < FILE_FORMAT_NAME_N)) {
+ /* unknown id */
+ return ("Unknown");
+ }
+
+ return(file_format_name_map[id]);
+}
+
#endif /* !UNIV_HOTBACKUP */
diff --git a/storage/innodb_plugin/trx/trx0trx.c b/storage/innodb_plugin/trx/trx0trx.c
index 4516ac004bb..4d4885062a6 100644
--- a/storage/innodb_plugin/trx/trx0trx.c
+++ b/storage/innodb_plugin/trx/trx0trx.c
@@ -891,11 +891,11 @@ trx_commit_off_kernel(
there are > 2 users in the database. Then at least 2 users can
gather behind one doing the physical log write to disk.
- If we are calling trx_commit() under MySQL's binlog mutex, we
+ If we are calling trx_commit() under prepare_commit_mutex, we
will delay possible log write and flush to a separate function
trx_commit_complete_for_mysql(), which is only called when the
- thread has released the binlog mutex. This is to make the
- group commit algorithm to work. Otherwise, the MySQL binlog
+ thread has released the mutex. This is to make the
+ group commit algorithm to work. Otherwise, the prepare_commit
mutex would serialize all commits and prevent a group of
transactions from gathering. */
diff --git a/storage/innodb_plugin/trx/trx0undo.c b/storage/innodb_plugin/trx/trx0undo.c
index b04a4070aea..9af96f14526 100644
--- a/storage/innodb_plugin/trx/trx0undo.c
+++ b/storage/innodb_plugin/trx/trx0undo.c
@@ -32,6 +32,7 @@ Created 3/26/1996 Heikki Tuuri
#include "fsp0fsp.h"
#ifndef UNIV_HOTBACKUP
#include "mach0data.h"
+#include "mtr0log.h"
#include "trx0rseg.h"
#include "trx0trx.h"
#include "srv0srv.h"
diff --git a/storage/innodb_plugin/ut/ut0auxconf_pause.c b/storage/innodb_plugin/ut/ut0auxconf_pause.c
new file mode 100644
index 00000000000..54d63bdd9bc
--- /dev/null
+++ b/storage/innodb_plugin/ut/ut0auxconf_pause.c
@@ -0,0 +1,32 @@
+/*****************************************************************************
+
+Copyright (c) 2009, Innobase Oy. All Rights Reserved.
+
+This program is free software; you can redistribute it and/or modify it under
+the terms of the GNU General Public License as published by the Free Software
+Foundation; version 2 of the License.
+
+This program is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License along with
+this program; if not, write to the Free Software Foundation, Inc., 59 Temple
+Place, Suite 330, Boston, MA 02111-1307 USA
+
+*****************************************************************************/
+
+/*****************************************************************************
+If this program compiles and can be run and returns 0, then the pause
+instruction is available.
+
+Created Jul 21, 2009 Vasil Dimov
+*****************************************************************************/
+
+int
+main(int argc, char** argv)
+{
+ __asm__ __volatile__ ("pause");
+
+ return(0);
+}
diff --git a/storage/innodb_plugin/ut/ut0mem.c b/storage/innodb_plugin/ut/ut0mem.c
index 7ed43d32fe0..edb63c95700 100644
--- a/storage/innodb_plugin/ut/ut0mem.c
+++ b/storage/innodb_plugin/ut/ut0mem.c
@@ -333,7 +333,7 @@ man realloc in Linux, 2004:
realloc() changes the size of the memory block pointed to
by ptr to size bytes. The contents will be unchanged to
- the minimum of the old and new sizes; newly allocated mem­
+ the minimum of the old and new sizes; newly allocated mem-
ory will be uninitialized. If ptr is NULL, the call is
equivalent to malloc(size); if size is equal to zero, the
call is equivalent to free(ptr). Unless ptr is NULL, it
diff --git a/storage/innodb_plugin/ut/ut0ut.c b/storage/innodb_plugin/ut/ut0ut.c
index c0ea362bee3..e4cc226fbad 100644
--- a/storage/innodb_plugin/ut/ut0ut.c
+++ b/storage/innodb_plugin/ut/ut0ut.c
@@ -1,6 +1,13 @@
/*****************************************************************************
Copyright (c) 1994, 2009, Innobase Oy. All Rights Reserved.
+Copyright (c) 2009, Sun Microsystems, Inc.
+
+Portions of this file contain modifications contributed and copyrighted by
+Sun Microsystems, Inc. Those modifications are gratefully acknowledged and
+are described briefly in the InnoDB documentation. The contributions by
+Sun Microsystems are incorporated with their permission, and subject to the
+conditions contained in the file COPYING.Sun_Microsystems.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
@@ -391,6 +398,7 @@ ut_delay(
for (i = 0; i < delay * 50; i++) {
j += i;
+ UT_RELAX_CPU();
}
if (ut_always_false) {