Merge MariaDB 5.1.39 release, including XtraDB 8 merge, into MariaDB 5.1 trunk.

This commit is contained in:
unknown 2009-11-14 13:45:36 +01:00
commit 9dfe197da9
324 changed files with 32148 additions and 27768 deletions

View File

@ -15,7 +15,7 @@ AC_CANONICAL_SYSTEM
# MySQL version number.
#
# Note: the following line must be parseable by win/configure.js:GetVersion()
AM_INIT_AUTOMAKE(mysql, 5.1.38-maria-beta)
AM_INIT_AUTOMAKE(mysql, 5.1.39-maria-beta)
AM_CONFIG_HEADER([include/config.h:config.h.in])
PROTOCOL_VERSION=10

View File

@ -122,12 +122,14 @@ insert into t1 (key1a, key1b, key2a, key2b, key3a, key3b)
analyze table t1;
select count(*) from t1;
--replace_column 9 REF
explain select count(*) from t1 where
key1a = 2 and key1b is null and key2a = 2 and key2b is null;
select count(*) from t1 where
key1a = 2 and key1b is null and key2a = 2 and key2b is null;
--replace_column 9 REF
explain select count(*) from t1 where
key1a = 2 and key1b is null and key3a = 2 and key3b is null;

View File

@ -111,7 +111,7 @@ count(*)
explain select count(*) from t1 where
key1a = 2 and key1b is null and key2a = 2 and key2b is null;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 index_merge i1,i2 i1,i2 10,10 NULL 3 Using intersect(i1,i2); Using where; Using index
1 SIMPLE t1 index_merge i1,i2 i1,i2 10,10 NULL REF Using intersect(i1,i2); Using where; Using index
select count(*) from t1 where
key1a = 2 and key1b is null and key2a = 2 and key2b is null;
count(*)
@ -119,7 +119,7 @@ count(*)
explain select count(*) from t1 where
key1a = 2 and key1b is null and key3a = 2 and key3b is null;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 index_merge i1,i3 i1,i3 10,10 NULL 3 Using intersect(i1,i3); Using where; Using index
1 SIMPLE t1 index_merge i1,i3 i1,i3 10,10 NULL REF Using intersect(i1,i3); Using where; Using index
select count(*) from t1 where
key1a = 2 and key1b is null and key3a = 2 and key3b is null;
count(*)

View File

@ -945,7 +945,7 @@ count(*)
explain select count(*) from t1 where
key1a = 2 and key1b is null and key2a = 2 and key2b is null;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 index_merge i1,i2 i1,i2 10,10 NULL 2 Using intersect(i1,i2); Using where; Using index
1 SIMPLE t1 index_merge i1,i2 i1,i2 10,10 NULL REF Using intersect(i1,i2); Using where; Using index
select count(*) from t1 where
key1a = 2 and key1b is null and key2a = 2 and key2b is null;
count(*)
@ -953,7 +953,7 @@ count(*)
explain select count(*) from t1 where
key1a = 2 and key1b is null and key3a = 2 and key3b is null;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 index_merge i1,i3 i1,i3 10,10 NULL 2 Using intersect(i1,i3); Using where; Using index
1 SIMPLE t1 index_merge i1,i3 i1,i3 10,10 NULL REF Using intersect(i1,i3); Using where; Using index
select count(*) from t1 where
key1a = 2 and key1b is null and key3a = 2 and key3b is null;
count(*)

View File

@ -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;

View File

@ -1134,4 +1134,40 @@ t2 CREATE TABLE `t2` (
) ENGINE=InnoDB DEFAULT CHARSET=latin1
DROP TABLE t2;
DROP TABLE t1;
CREATE TABLE t1 (a INT, b CHAR(1)) ENGINE=InnoDB;
INSERT INTO t1 VALUES (3,'a'),(3,'b'),(1,'c'),(0,'d'),(1,'e');
BEGIN;
SELECT * FROM t1;
a b
3 a
3 b
1 c
0 d
1 e
CREATE INDEX t1a ON t1(a);
SELECT * FROM t1;
a b
3 a
3 b
1 c
0 d
1 e
SELECT * FROM t1 FORCE INDEX(t1a) ORDER BY a;
ERROR HY000: Table definition has changed, please retry transaction
SELECT * FROM t1;
a b
3 a
3 b
1 c
0 d
1 e
COMMIT;
SELECT * FROM t1 FORCE INDEX(t1a) ORDER BY a;
a b
0 d
1 c
1 e
3 a
3 b
DROP TABLE t1;
SET GLOBAL innodb_file_format_check=@save_innodb_file_format_check;

View File

@ -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;
SET @old_innodb_thread_concurrency= @@global.innodb_thread_concurrency;
show variables like "innodb_thread_concurrency";
Variable_name Value

View File

@ -1,5 +1,4 @@
set @old_innodb_file_per_table=@@innodb_file_per_table;
set @old_innodb_file_format=@@innodb_file_format;
set @old_innodb_file_format_check=@@innodb_file_format_check;
set @old_innodb_file_per_table=@@innodb_file_per_table;
SET GLOBAL innodb_file_format='Barracuda';
SET GLOBAL innodb_file_per_table=ON;

View File

@ -1,3 +1,4 @@
set @old_innodb_file_format=@@innodb_file_format;
select @@innodb_file_format;
@@innodb_file_format
Antelope
@ -42,3 +43,5 @@ ERROR HY000: Incorrect arguments to SET
select @@innodb_file_format_check;
@@innodb_file_format_check
Barracuda
set global innodb_file_format=@old_innodb_file_format;
set global innodb_file_format_check=Antelope;

View File

@ -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;

View File

@ -515,4 +515,28 @@ SHOW CREATE TABLE t2;
DROP TABLE t2;
DROP TABLE t1;
connect (a,localhost,root,,);
connect (b,localhost,root,,);
connection a;
CREATE TABLE t1 (a INT, b CHAR(1)) ENGINE=InnoDB;
INSERT INTO t1 VALUES (3,'a'),(3,'b'),(1,'c'),(0,'d'),(1,'e');
connection b;
BEGIN;
SELECT * FROM t1;
connection a;
CREATE INDEX t1a ON t1(a);
connection b;
SELECT * FROM t1;
--error ER_TABLE_DEF_CHANGED
SELECT * FROM t1 FORCE INDEX(t1a) ORDER BY a;
SELECT * FROM t1;
COMMIT;
SELECT * FROM t1 FORCE INDEX(t1a) ORDER BY a;
connection default;
disconnect a;
disconnect b;
DROP TABLE t1;
SET GLOBAL innodb_file_format_check=@save_innodb_file_format_check;

View File

@ -1321,7 +1321,7 @@ drop table t1;
# InnoDB aligns the memory for the buffer pool to a page boundary. This may
# cause actual pool size to be one less than requested depending on exact
# alignment of obtained memory.
--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';
@ -1336,6 +1336,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";
@ -1343,6 +1344,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
SET @old_innodb_thread_concurrency= @@global.innodb_thread_concurrency;
@ -2555,6 +2557,8 @@ CONNECTION default;
SET GLOBAL innodb_thread_concurrency = @innodb_thread_concurrency_orig;
-- enable_query_log
#######################################################################
# #
# Please, DO NOT TOUCH this file as well as the innodb.result file. #

View File

@ -4,9 +4,8 @@
#
-- source include/have_innodb.inc
set @old_innodb_file_per_table=@@innodb_file_per_table;
set @old_innodb_file_format=@@innodb_file_format;
set @old_innodb_file_format_check=@@innodb_file_format_check;
set @old_innodb_file_per_table=@@innodb_file_per_table;
SET GLOBAL innodb_file_format='Barracuda';
SET GLOBAL innodb_file_per_table=ON;
@ -1156,7 +1155,5 @@ DROP TABLE IF EXISTS table4;
DROP TABLE IF EXISTS table5;
DROP TABLE IF EXISTS table6;
set global innodb_file_per_table=@old_innodb_file_per_table;
set global innodb_file_format=@old_innodb_file_format;
set global innodb_file_format_check=@old_innodb_file_format_check;
set global innodb_file_per_table=@old_innodb_file_per_table;

View File

@ -15,7 +15,6 @@ SET storage_engine=InnoDB;
-- disable_result_log
set @old_innodb_file_per_table=@@innodb_file_per_table;
set @old_innodb_file_format=@@innodb_file_format;
set @old_innodb_file_format_check=@@innodb_file_format_check;
SET GLOBAL innodb_file_format='Barracuda';
SET GLOBAL innodb_file_per_table=on;
@ -30,5 +29,4 @@ CHECK TABLE table0 EXTENDED;
DROP TABLE table0;
set global innodb_file_per_table=@old_innodb_file_per_table;
set global innodb_file_format=@old_innodb_file_format;
set global innodb_file_format_check=@old_innodb_file_format_check;
set global innodb_file_format_check=Antelope;

View File

@ -1,8 +1,5 @@
-- 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`;
set @old_innodb_file_format=@@innodb_file_format;
select @@innodb_file_format;
select @@innodb_file_format_check;
@ -31,11 +28,5 @@ set global innodb_file_format=on;
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
set global innodb_file_format=@old_innodb_file_format;
set global innodb_file_format_check=Antelope;

View File

@ -22,7 +22,6 @@ pkgplugin_LTLIBRARIES = @plugin_federated_shared_target@
ha_federatedx_la_LDFLAGS = -module -rpath $(pkgplugindir)
ha_federatedx_la_CXXFLAGS= $(AM_CFLAGS) -DMYSQL_DYNAMIC_PLUGIN
ha_federatedx_la_CFLAGS = $(AM_CFLAGS) -DMYSQL_DYNAMIC_PLUGIN
ha_federatedx_la_SOURCES = ha_federatedx.cc
EXTRA_LIBRARIES = libfederatedx.a

View File

@ -390,8 +390,8 @@ int federatedx_db_init(void *p)
DBUG_ENTER("federatedx_db_init");
handlerton *federatedx_hton= (handlerton *)p;
federatedx_hton->state= SHOW_OPTION_YES;
/* This is no longer needed for plugin storage engines */
federatedx_hton->db_type= DB_TYPE_DEFAULT;
/* Needed to work with old .frm files */
federatedx_hton->db_type= DB_TYPE_FEDERATED_DB;
federatedx_hton->savepoint_offset= sizeof(ulong);
federatedx_hton->close_connection= ha_federatedx::disconnect;
federatedx_hton->savepoint_set= ha_federatedx::savepoint_set;

View File

@ -1,5 +1,5 @@
# Copyright (C) 2006 MySQL AB
#
# Copyright (C) 2009 Oracle/Innobase Oy
#
# 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.
@ -11,21 +11,25 @@
#
# 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
IF (CMAKE_SIZEOF_VOID_P MATCHES 8)
SET(WIN64 TRUE)
ENDIF (CMAKE_SIZEOF_VOID_P MATCHES 8)
# Check type sizes
include(CheckTypeSize)
# Currently, the checked results are not used.
CHECK_TYPE_SIZE(int SIZEOF_INT)
CHECK_TYPE_SIZE(long SIZEOF_LONG)
CHECK_TYPE_SIZE(void* SIZEOF_VOID_P)
SET(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -DSAFEMALLOC -DSAFE_MUTEX")
SET(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -DSAFEMALLOC -DSAFE_MUTEX")
INCLUDE("${PROJECT_SOURCE_DIR}/storage/mysql_storage_engine.cmake")
ADD_DEFINITIONS(-D_WIN32 -D_LIB -DMYSQL_SERVER)
# Bug 19424 - InnoDB: Possibly a memory overrun of the buffer being freed (64-bit Visual C)
# Removing Win64 compiler optimizations for all innodb/mem/* files.
IF(CMAKE_GENERATOR MATCHES "Visual Studio" AND CMAKE_SIZEOF_VOID_P MATCHES 8)
SET_SOURCE_FILES_PROPERTIES(${CMAKE_SOURCE_DIR}/storage/xtradb/mem/mem0mem.c
${CMAKE_SOURCE_DIR}/storage/xtradb/mem/mem0pool.c
PROPERTIES COMPILE_FLAGS -Od)
ENDIF(CMAKE_GENERATOR MATCHES "Visual Studio" AND CMAKE_SIZEOF_VOID_P MATCHES 8)
INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/include ${CMAKE_SOURCE_DIR}/zlib
${CMAKE_SOURCE_DIR}/storage/xtradb/include
${CMAKE_SOURCE_DIR}/storage/xtradb/handler
@ -33,39 +37,45 @@ INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/include ${CMAKE_SOURCE_DIR}/zlib
${CMAKE_SOURCE_DIR}/regex
${CMAKE_SOURCE_DIR}/extra/yassl/include)
SET(INNOBASE_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/hash0hash.c ha/ha0storage.c
ibuf/ibuf0ibuf.c
pars/lexyy.c pars/pars0grm.c pars/pars0opt.c pars/pars0pars.c pars/pars0sym.c
lock/lock0lock.c lock/lock0iter.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
que/que0que.c
handler/ha_innodb.cc handler/handler0alter.cc handler/i_s.cc handler/mysql_addons.cc
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/ut0mem.c ut/ut0rnd.c ut/ut0ut.c ut/ut0vec.c ut/ut0list.c ut/ut0wqueue.c)
# Removing compiler optimizations for innodb/mem/* files on 64-bit Windows
# due to 64-bit compiler error, See MySQL Bug #19424, #36366, #34297
IF(MSVC AND $(WIN64))
SET_SOURCE_FILES_PROPERTIES(mem/mem0mem.c mem/mem0pool.c
PROPERTIES COMPILE_FLAGS -Od)
ENDIF(MSVC AND $(WIN64))
SET(INNOBASE_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/hash0hash.c ha/ha0storage.c
ibuf/ibuf0ibuf.c
pars/lexyy.c pars/pars0grm.c pars/pars0opt.c pars/pars0pars.c pars/pars0sym.c
lock/lock0lock.c lock/lock0iter.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
que/que0que.c
handler/ha_innodb.cc handler/handler0alter.cc handler/i_s.cc handler/mysql_addons.cc
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/ut0mem.c ut/ut0rnd.c ut/ut0ut.c ut/ut0vec.c
ut/ut0list.c ut/ut0wqueue.c)
MYSQL_STORAGE_ENGINE(INNOBASE)

View File

@ -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.

View File

@ -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.

View File

@ -1,3 +1,377 @@
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,
include/page0page.ic, include/lock0lock.h, include/dict0dict.h,
include/page0page.h, include/dict0dict.ic, ibuf/ibuf0ibuf.c,
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
could cause failures in secondary index lookups in consistent
reads right after crash recovery.
2009-05-18 The InnoDB Team
* btr/btr0cur.c:
Correctly estimate the space needed on the compressed page when
performing an update by delete-and-insert.
2009-05-14 The InnoDB Team
* handler/ha_innodb.cc, include/srv0srv.h,
mysql-test/innodb_bug42101-nonzero-master.opt,
mysql-test/innodb_bug42101-nonzero.result,
mysql-test/innodb_bug42101-nonzero.test,
mysql-test/innodb_bug42101.result, mysql-test/innodb_bug42101.test,
srv/srv0srv.c:
Fix Bug#42101 Race condition in innodb_commit_concurrency
2009-05-13 The InnoDB Team
* dict/dict0dict.c:
Fix Bug#44320 InnoDB: missing DB_ROLL_PTR in Table Monitor COLUMNS
output
2009-04-23 The InnoDB Team
* 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
ignored in CHECK TABLE.
2009-04-23 The InnoDB Team
* include/trx0types.h:
Define the logical type names trx_id_t, roll_ptr_t, and undo_no_t
and use them in place of dulint everywhere.
2009-04-18 The InnoDB Team
* handler/ha_innodb.cc, include/pars0pars.h:
Fix Bug#29125 Windows Server X64: so many compiler warnings
2009-04-16 The InnoDB Team
* include/univ.i:
Define REFMAN as the base URL of the MySQL Reference Manual and
use the macro in all diagnostic output.
2009-04-16 The InnoDB Team
* CMakeLists.txt, include/os0sync.h, include/sync0sync.h,
include/sync0sync.ic, include/univ.i, srv/srv0start.c,
sync/sync0sync.c:
Use the Windows Interlocked functions for atomic memory
access.
2009-04-15 The InnoDB Team
* mysql-test/innodb.result, mysql-test/innodb.test:
Fix Bug#43309 Test main.innodb can't be run twice
2009-04-14 The InnoDB Team
* CMakeLists.txt, handler/win_delay_loader.cc,
win-plugin/win-plugin.diff:
Remove statically linked libraries from MySQL (zlib and strings).
2009-04-11 The InnoDB Team
* CMakeLists.txt, win-plugin/README, win-plugin/win-plugin.diff:
Rewrite CMakeLists.txt.
2009-04-07 The InnoDB Team
* include/os0sync.h, include/sync0rw.ic, include/sync0sync.h,
include/sync0sync.ic, include/univ.i, plug.in, srv/srv0srv.c,
srv/srv0start.c, sync/sync0arr.c, sync/sync0sync.c:
Enable atomics on Solaris (using the libc functions as defined in
atomic.h) if GCC atomic builtins are not present.
2009-04-07 The InnoDB Team
* btr/btr0btr.c, dict/dict0dict.c, ibuf/ibuf0ibuf.c,
include/data0data.h, include/data0data.ic, include/data0type.h,
include/data0type.ic, include/dict0dict.h, include/dict0dict.ic,
include/rem0rec.ic, mysql-test/innodb.result, mysql-test/innodb.test,
pars/pars0pars.c, rem/rem0rec.c, row/row0upd.c:
Fix Bug#44032 In ROW_FORMAT=REDUNDANT, update UTF-8 CHAR
to/from NULL is not in-place
2009-04-07 The InnoDB Team
* page/page0cur.c:
Fix Bug#43660 SHOW INDEXES/ANALYZE does NOT update cardinality for
indexes of InnoDB table
2009-04-06 The InnoDB Team
* handler/ha_innodb.cc:
Make the parameter innodb_change_buffering settable by the
configuration file or mysqld command line options. Before this
fix, the initial value specified for this parameter was ignored.
2009-04-06 The InnoDB Team
* sync/sync0rw.c:
Avoid a bogus failure in UNIV_SYNC_DEBUG diagnostics.
2009-04-02 The InnoDB Team
* handler/ha_innodb.cc, include/srv0srv.h, srv/srv0srv.c:
Add new parameter innodb_spin_wait_delay to set the maximum delay
between polling for a spin lock.
2009-04-02 The InnoDB Team
* dict/dict0crea.c, handler/ha_innodb.cc, handler/ha_innodb.h,
include/dict0mem.h, include/row0merge.h, include/row0mysql.h,
mysql-test/innodb-index.result, mysql-test/innodb-index.test,
row/row0merge.c, row/row0sel.c:
In consistent reads, refuse to use newly created indexes that may
lack history.
2009-03-25 The InnoDB Team
* buf/buf0buf.c, handler/ha_innodb.cc, include/buf0buf.h:
In SHOW ENGINE INNODB MUTEX do not show the status of block->mutex,
block->lock, block->lock->mutex (if applicable) and all mutexes and
rw-locks for which number of os-waits are zero because this can
be overwhelming particularly when the buffer pool is very large.
2009-03-20 The InnoDB Team
* buf/buf0buf.c, include/log0recv.h, log/log0recv.c:
Remove the compile-time constant parameters of
recv_recover_page(), recv_scan_log_recs(), and recv_sys_init().
2009-03-20 The InnoDB Team
* data/data0type.c, handler/ha_innodb.cc, include/ha_prototypes.h:
Declare innobase_get_at_most_n_mbchars() in ha_prototypes.h.
2009-03-20 The InnoDB Team
* fil/fil0fil.h, fil/fil0fil.c, srv/srv0start.c:
Add the parameter hash_size to fil_init().
2009-03-20 The InnoDB Team
* fil/fil0fil.c:
Refer to fil_system directly, not via local variables.
2009-03-20 The InnoDB Team
* page/page0page.c:
In page_validate(), always report the space id, page number and
the name of the index when corruption is noticed.
2009-03-20 The InnoDB Team
* include/log0log.h, include/log0log.ic, log/log0log.c:
Add in/out comments or const qualifiers to some function
parameters as appropriate.
2009-03-20 The InnoDB Team
* dict/dict0boot.c, dict/dict0dict.c, fsp/fsp0fsp.c,
include/dict0dict.h, include/srv0srv.h, srv/srv0srv.c,
page/page0page.c:
Replace srv_sys->dummy_ind1 and srv_sys->dummy_ind2 with
dict_ind_redundant and dict_ind_compact, which are
initialized by dict_init().
2009-03-11 The InnoDB Team
InnoDB Plugin 1.0.3 released
2009-03-05 The InnoDB Team
* handler/ha_innodb.cc, mysql-test/innodb-autoinc.result,

1419
storage/xtradb/Doxyfile Normal file

File diff suppressed because it is too large Load Diff

View File

@ -24,158 +24,306 @@ INCLUDES= -I$(top_srcdir)/include -I$(top_builddir)/include \
-I$(top_srcdir)/regex \
-I$(top_srcdir)/storage/xtradb/include \
-I$(top_srcdir)/sql \
-I$(srcdir)
-I$(srcdir) @ZLIB_INCLUDES@
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 handler/innodb_patch_info.h \
handler/handler0vars.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/fsp0types.h \
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 \
handler/innodb_patch_info.h \
mem/mem0dbg.c
EXTRA_LIBRARIES= libinnobase.a
noinst_LIBRARIES= @plugin_innobase_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)

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
/******************************************************
/**************************************************//**
@file btr/btr0pcur.c
The index tree persistent cursor
Created 2/23/1996 Heikki Tuuri
@ -32,13 +33,13 @@ Created 2/23/1996 Heikki Tuuri
#include "rem0cmp.h"
#include "trx0trx.h"
/******************************************************************
Allocates memory for a persistent cursor object and initializes the cursor. */
/**************************************************************//**
Allocates memory for a persistent cursor object and initializes the cursor.
@return own: persistent cursor */
UNIV_INTERN
btr_pcur_t*
btr_pcur_create_for_mysql(void)
/*============================*/
/* out, own: persistent cursor */
{
btr_pcur_t* pcur;
@ -50,13 +51,13 @@ btr_pcur_create_for_mysql(void)
return(pcur);
}
/******************************************************************
/**************************************************************//**
Frees the memory for a persistent cursor object. */
UNIV_INTERN
void
btr_pcur_free_for_mysql(
/*====================*/
btr_pcur_t* cursor) /* in, own: persistent cursor */
btr_pcur_t* cursor) /*!< in, own: persistent cursor */
{
if (cursor->old_rec_buf != NULL) {
@ -76,7 +77,7 @@ btr_pcur_free_for_mysql(
mem_free(cursor);
}
/******************************************************************
/**************************************************************//**
The position of the cursor is stored by taking an initial segment of the
record the cursor is positioned on, before, or after, and copying it to the
cursor data structure, or just setting a flag if the cursor id before the
@ -87,8 +88,8 @@ UNIV_INTERN
void
btr_pcur_store_position(
/*====================*/
btr_pcur_t* cursor, /* in: persistent cursor */
mtr_t* mtr) /* in: mtr */
btr_pcur_t* cursor, /*!< in: persistent cursor */
mtr_t* mtr) /*!< in: mtr */
{
page_cur_t* page_cursor;
buf_block_t* block;
@ -157,15 +158,15 @@ btr_pcur_store_position(
cursor->modify_clock = buf_block_get_modify_clock(block);
}
/******************************************************************
/**************************************************************//**
Copies the stored position of a pcur to another pcur. */
UNIV_INTERN
void
btr_pcur_copy_stored_position(
/*==========================*/
btr_pcur_t* pcur_receive, /* in: pcur which will receive the
btr_pcur_t* pcur_receive, /*!< in: pcur which will receive the
position info */
btr_pcur_t* pcur_donate) /* in: pcur from which the info is
btr_pcur_t* pcur_donate) /*!< in: pcur from which the info is
copied */
{
if (pcur_receive->old_rec_buf) {
@ -187,7 +188,7 @@ btr_pcur_copy_stored_position(
pcur_receive->old_n_fields = pcur_donate->old_n_fields;
}
/******************************************************************
/**************************************************************//**
Restores the stored position of a persistent cursor bufferfixing the page and
obtaining the specified latches. If the cursor position was saved when the
(1) cursor was positioned on a user record: this function restores the position
@ -198,19 +199,17 @@ infimum;
(3) cursor was positioned on the page supremum: restores to the first record
GREATER than the user record which was the predecessor of the supremum.
(4) cursor was positioned before the first or after the last in an empty tree:
restores to before first or after the last in the tree. */
restores to before first or after the last in the tree.
@return TRUE if the cursor position was stored when it was on a user
record and it can be restored on a user record whose ordering fields
are identical to the ones of the original user record */
UNIV_INTERN
ibool
btr_pcur_restore_position(
/*======================*/
/* out: TRUE if the cursor position
was stored when it was on a user record
and it can be restored on a user record
whose ordering fields are identical to
the ones of the original user record */
ulint latch_mode, /* in: BTR_SEARCH_LEAF, ... */
btr_pcur_t* cursor, /* in: detached persistent cursor */
mtr_t* mtr) /* in: mtr */
ulint latch_mode, /*!< in: BTR_SEARCH_LEAF, ... */
btr_pcur_t* cursor, /*!< in: detached persistent cursor */
mtr_t* mtr) /*!< in: mtr */
{
dict_index_t* index;
dtuple_t* tuple;
@ -351,7 +350,7 @@ btr_pcur_restore_position(
return(FALSE);
}
/******************************************************************
/**************************************************************//**
If the latch mode of the cursor is BTR_LEAF_SEARCH or BTR_LEAF_MODIFY,
releases the page latch and bufferfix reserved by the cursor.
NOTE! In the case of BTR_LEAF_MODIFY, there should not exist changes
@ -361,8 +360,8 @@ UNIV_INTERN
void
btr_pcur_release_leaf(
/*==================*/
btr_pcur_t* cursor, /* in: persistent cursor */
mtr_t* mtr) /* in: mtr */
btr_pcur_t* cursor, /*!< in: persistent cursor */
mtr_t* mtr) /*!< in: mtr */
{
buf_block_t* block;
@ -378,7 +377,7 @@ btr_pcur_release_leaf(
cursor->pos_state = BTR_PCUR_WAS_POSITIONED;
}
/*************************************************************
/*********************************************************//**
Moves the persistent cursor to the first record on the next page. Releases the
latch on the current page, and bufferunfixes it. Note that there must not be
modifications on the current page, as then the x-latch can be released only in
@ -387,9 +386,9 @@ UNIV_INTERN
void
btr_pcur_move_to_next_page(
/*=======================*/
btr_pcur_t* cursor, /* in: persistent cursor; must be on the
btr_pcur_t* cursor, /*!< in: persistent cursor; must be on the
last record of the current page */
mtr_t* mtr) /* in: mtr */
mtr_t* mtr) /*!< in: mtr */
{
ulint next_page_no;
ulint space;
@ -429,7 +428,7 @@ btr_pcur_move_to_next_page(
page_check_dir(next_page);
}
/*************************************************************
/*********************************************************//**
Moves the persistent cursor backward if it is on the first record of the page.
Commits mtr. Note that to prevent a possible deadlock, the operation
first stores the position of the cursor, commits mtr, acquires the necessary
@ -442,9 +441,9 @@ UNIV_INTERN
void
btr_pcur_move_backward_from_page(
/*=============================*/
btr_pcur_t* cursor, /* in: persistent cursor, must be on the first
btr_pcur_t* cursor, /*!< in: persistent cursor, must be on the first
record of the current page */
mtr_t* mtr) /* in: mtr */
mtr_t* mtr) /*!< in: mtr */
{
ulint prev_page_no;
ulint space;
@ -511,18 +510,17 @@ btr_pcur_move_backward_from_page(
cursor->old_stored = BTR_PCUR_OLD_NOT_STORED;
}
/*************************************************************
/*********************************************************//**
Moves the persistent cursor to the previous record in the tree. If no records
are left, the cursor stays 'before first in tree'. */
are left, the cursor stays 'before first in tree'.
@return TRUE if the cursor was not before first in tree */
UNIV_INTERN
ibool
btr_pcur_move_to_prev(
/*==================*/
/* out: TRUE if the cursor was not before first
in tree */
btr_pcur_t* cursor, /* in: persistent cursor; NOTE that the
btr_pcur_t* cursor, /*!< in: persistent cursor; NOTE that the
function may release the page latch */
mtr_t* mtr) /* in: mtr */
mtr_t* mtr) /*!< in: mtr */
{
ut_ad(cursor->pos_state == BTR_PCUR_IS_POSITIONED);
ut_ad(cursor->latch_mode != BTR_NO_LATCHES);
@ -546,7 +544,7 @@ btr_pcur_move_to_prev(
return(TRUE);
}
/******************************************************************
/**************************************************************//**
If mode is PAGE_CUR_G or PAGE_CUR_GE, opens a persistent cursor on the first
user record satisfying the search condition, in the case PAGE_CUR_L or
PAGE_CUR_LE, on the last user record. If no such user record exists, then
@ -557,14 +555,14 @@ UNIV_INTERN
void
btr_pcur_open_on_user_rec(
/*======================*/
dict_index_t* index, /* in: index */
const dtuple_t* tuple, /* in: tuple on which search done */
ulint mode, /* in: PAGE_CUR_L, ... */
ulint latch_mode, /* in: BTR_SEARCH_LEAF or
dict_index_t* index, /*!< in: index */
const dtuple_t* tuple, /*!< in: tuple on which search done */
ulint mode, /*!< in: PAGE_CUR_L, ... */
ulint latch_mode, /*!< in: BTR_SEARCH_LEAF or
BTR_MODIFY_LEAF */
btr_pcur_t* cursor, /* in: memory buffer for persistent
btr_pcur_t* cursor, /*!< in: memory buffer for persistent
cursor */
mtr_t* mtr) /* in: mtr */
mtr_t* mtr) /*!< in: mtr */
{
btr_pcur_open(index, tuple, mode, latch_mode, cursor, mtr);

View File

@ -23,7 +23,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
/************************************************************************
/********************************************************************//**
@file btr/btr0sea.c
The index tree adaptive search
Created 2/17/1996 Heikki Tuuri
@ -42,26 +43,29 @@ Created 2/17/1996 Heikki Tuuri
#include "btr0btr.h"
#include "ha0ha.h"
/* Flag: has the search system been enabled?
/** Flag: has the search system been enabled?
Protected by btr_search_latch and btr_search_enabled_mutex. */
UNIV_INTERN char btr_search_enabled = TRUE;
/** Mutex protecting btr_search_enabled */
static mutex_t btr_search_enabled_mutex;
/* A dummy variable to fool the compiler */
/** A dummy variable to fool the compiler */
UNIV_INTERN ulint btr_search_this_is_zero = 0;
#ifdef UNIV_SEARCH_PERF_STAT
/** Number of successful adaptive hash index lookups */
UNIV_INTERN ulint btr_search_n_succ = 0;
/** Number of failed adaptive hash index lookups */
UNIV_INTERN ulint btr_search_n_hash_fail = 0;
#endif /* UNIV_SEARCH_PERF_STAT */
/* padding to prevent other memory update
/** padding to prevent other memory update
hotspots from residing on the same memory
cache line as btr_search_latch */
UNIV_INTERN byte btr_sea_pad1[64];
/* The latch protecting the adaptive search system: this latch protects the
/** The latch protecting the adaptive search system: this latch protects the
(1) positions of records on those pages where a hash index has been built.
NOTE: It does not protect values of non-ordering fields within a record from
being updated in-place! We can use fact (1) to perform unique searches to
@ -71,24 +75,23 @@ indexes. */
same DRAM page as other hotspot semaphores */
UNIV_INTERN rw_lock_t* btr_search_latch_temp;
/* padding to prevent other memory update hotspots from residing on
/** padding to prevent other memory update hotspots from residing on
the same memory cache line */
UNIV_INTERN byte btr_sea_pad2[64];
/** The adaptive hash index */
UNIV_INTERN btr_search_sys_t* btr_search_sys;
/* If the number of records on the page divided by this parameter
/** If the number of records on the page divided by this parameter
would have been successfully accessed using a hash index, the index
is then built on the page, assuming the global limit has been reached */
#define BTR_SEARCH_PAGE_BUILD_LIMIT 16
/* The global limit for consecutive potentially successful hash searches,
/** The global limit for consecutive potentially successful hash searches,
before hash index building is started */
#define BTR_SEARCH_BUILD_LIMIT 100
/************************************************************************
/********************************************************************//**
Builds a hash index on a page with the given parameters. If the page already
has a hash index with different parameters, the old hash index is removed.
If index is non-NULL, this function checks if n_fields and n_bytes are
@ -97,15 +100,15 @@ static
void
btr_search_build_page_hash_index(
/*=============================*/
dict_index_t* index, /* in: index for which to build, or NULL if
dict_index_t* index, /*!< in: index for which to build, or NULL if
not known */
buf_block_t* block, /* in: index page, s- or x-latched */
ulint n_fields,/* in: hash this many full fields */
ulint n_bytes,/* in: hash this many bytes from the next
buf_block_t* block, /*!< in: index page, s- or x-latched */
ulint n_fields,/*!< in: hash this many full fields */
ulint n_bytes,/*!< in: hash this many bytes from the next
field */
ibool left_side);/* in: hash for searches from left side? */
ibool left_side);/*!< in: hash for searches from left side? */
/*********************************************************************
/*****************************************************************//**
This function should be called before reserving any btr search mutex, if
the intended operation might add nodes to the search system hash table.
Because of the latching order, once we have reserved the btr search system
@ -151,13 +154,13 @@ btr_search_check_free_space_in_heap(void)
}
}
/*********************************************************************
/*****************************************************************//**
Creates and initializes the adaptive search system at a database start. */
UNIV_INTERN
void
btr_search_sys_create(
/*==================*/
ulint hash_size) /* in: hash index hash table size */
ulint hash_size) /*!< in: hash index hash table size */
{
/* We allocate the search latch from dynamic memory:
see above at the global variable definition */
@ -172,7 +175,7 @@ btr_search_sys_create(
btr_search_sys->hash_index = ha_create(hash_size, 0, 0);
}
/************************************************************************
/********************************************************************//**
Disable the adaptive hash search system and empty the index. */
UNIV_INTERN
void
@ -195,7 +198,7 @@ btr_search_disable(void)
mutex_exit(&btr_search_enabled_mutex);
}
/************************************************************************
/********************************************************************//**
Enable the adaptive hash search system. */
UNIV_INTERN
void
@ -211,14 +214,14 @@ btr_search_enable(void)
mutex_exit(&btr_search_enabled_mutex);
}
/*********************************************************************
Creates and initializes a search info struct. */
/*****************************************************************//**
Creates and initializes a search info struct.
@return own: search info struct */
UNIV_INTERN
btr_search_t*
btr_search_info_create(
/*===================*/
/* out, own: search info struct */
mem_heap_t* heap) /* in: heap where created */
mem_heap_t* heap) /*!< in: heap where created */
{
btr_search_t* info;
@ -252,15 +255,15 @@ btr_search_info_create(
return(info);
}
/*********************************************************************
/*****************************************************************//**
Returns the value of ref_count. The value is protected by
btr_search_latch. */
btr_search_latch.
@return ref_count value. */
UNIV_INTERN
ulint
btr_search_info_get_ref_count(
/*==========================*/
/* out: ref_count value. */
btr_search_t* info) /* in: search info. */
btr_search_t* info) /*!< in: search info. */
{
ulint ret;
@ -278,7 +281,7 @@ btr_search_info_get_ref_count(
return(ret);
}
/*************************************************************************
/*********************************************************************//**
Updates the search info of an index about hash successes. NOTE that info
is NOT protected by any semaphore, to save CPU time! Do not assume its fields
are consistent. */
@ -286,8 +289,8 @@ static
void
btr_search_info_update_hash(
/*========================*/
btr_search_t* info, /* in/out: search info */
btr_cur_t* cursor) /* in: cursor which was just positioned */
btr_search_t* info, /*!< in/out: search info */
btr_cur_t* cursor) /*!< in: cursor which was just positioned */
{
dict_index_t* index;
ulint n_unique;
@ -398,20 +401,19 @@ set_new_recomm:
}
}
/*************************************************************************
/*********************************************************************//**
Updates the block search info on hash successes. NOTE that info and
block->n_hash_helps, n_fields, n_bytes, side are NOT protected by any
semaphore, to save CPU time! Do not assume the fields are consistent. */
semaphore, to save CPU time! Do not assume the fields are consistent.
@return TRUE if building a (new) hash index on the block is recommended */
static
ibool
btr_search_update_block_hash_info(
/*==============================*/
/* out: TRUE if building a (new) hash index on
the block is recommended */
btr_search_t* info, /* in: search info */
buf_block_t* block, /* in: buffer block */
btr_search_t* info, /*!< in: search info */
buf_block_t* block, /*!< in: buffer block */
btr_cur_t* cursor __attribute__((unused)))
/* in: cursor */
/*!< in: cursor */
{
#ifdef UNIV_SYNC_DEBUG
ut_ad(!rw_lock_own(&btr_search_latch, RW_LOCK_SHARED));
@ -477,7 +479,7 @@ btr_search_update_block_hash_info(
return(FALSE);
}
/*************************************************************************
/*********************************************************************//**
Updates a hash node reference when it has been unsuccessfully used in a
search which could have succeeded with the used hash parameters. This can
happen because when building a hash index for a page, we do not check
@ -489,9 +491,9 @@ static
void
btr_search_update_hash_ref(
/*=======================*/
btr_search_t* info, /* in: search info */
buf_block_t* block, /* in: buffer block where cursor positioned */
btr_cur_t* cursor) /* in: cursor */
btr_search_t* info, /*!< in: search info */
buf_block_t* block, /*!< in: buffer block where cursor positioned */
btr_cur_t* cursor) /*!< in: cursor */
{
ulint fold;
rec_t* rec;
@ -547,14 +549,14 @@ btr_search_update_hash_ref(
}
}
/*************************************************************************
/*********************************************************************//**
Updates the search info. */
UNIV_INTERN
void
btr_search_info_update_slow(
/*========================*/
btr_search_t* info, /* in/out: search info */
btr_cur_t* cursor) /* in: cursor which was just positioned */
btr_search_t* info, /*!< in/out: search info */
btr_cur_t* cursor) /*!< in: cursor which was just positioned */
{
buf_block_t* block;
ibool build_index;
@ -624,28 +626,28 @@ btr_search_info_update_slow(
}
}
/**********************************************************************
/******************************************************************//**
Checks if a guessed position for a tree cursor is right. Note that if
mode is PAGE_CUR_LE, which is used in inserts, and the function returns
TRUE, then cursor->up_match and cursor->low_match both have sensible values. */
TRUE, then cursor->up_match and cursor->low_match both have sensible values.
@return TRUE if success */
static
ibool
btr_search_check_guess(
/*===================*/
/* out: TRUE if success */
btr_cur_t* cursor, /* in: guessed cursor position */
btr_cur_t* cursor, /*!< in: guessed cursor position */
ibool can_only_compare_to_cursor_rec,
/* in: if we do not have a latch on the page
/*!< in: if we do not have a latch on the page
of cursor, but only a latch on
btr_search_latch, then ONLY the columns
of the record UNDER the cursor are
protected, not the next or previous record
in the chain: we cannot look at the next or
previous record to check our guess! */
const dtuple_t* tuple, /* in: data tuple */
ulint mode, /* in: PAGE_CUR_L, PAGE_CUR_LE, PAGE_CUR_G,
const dtuple_t* tuple, /*!< in: data tuple */
ulint mode, /*!< in: PAGE_CUR_L, PAGE_CUR_LE, PAGE_CUR_G,
or PAGE_CUR_GE */
mtr_t* mtr) /* in: mtr */
mtr_t* mtr) /*!< in: mtr */
{
rec_t* rec;
ulint n_unique;
@ -770,31 +772,31 @@ exit_func:
return(success);
}
/**********************************************************************
/******************************************************************//**
Tries to guess the right search position based on the hash search info
of the index. Note that if mode is PAGE_CUR_LE, which is used in inserts,
and the function returns TRUE, then cursor->up_match and cursor->low_match
both have sensible values. */
both have sensible values.
@return TRUE if succeeded */
UNIV_INTERN
ibool
btr_search_guess_on_hash(
/*=====================*/
/* out: TRUE if succeeded */
dict_index_t* index, /* in: index */
btr_search_t* info, /* in: index search info */
const dtuple_t* tuple, /* in: logical record */
ulint mode, /* in: PAGE_CUR_L, ... */
ulint latch_mode, /* in: BTR_SEARCH_LEAF, ...;
dict_index_t* index, /*!< in: index */
btr_search_t* info, /*!< in: index search info */
const dtuple_t* tuple, /*!< in: logical record */
ulint mode, /*!< in: PAGE_CUR_L, ... */
ulint latch_mode, /*!< in: BTR_SEARCH_LEAF, ...;
NOTE that only if has_search_latch
is 0, we will have a latch set on
the cursor page, otherwise we assume
the caller uses his search latch
to protect the record! */
btr_cur_t* cursor, /* out: tree cursor */
ulint has_search_latch,/* in: latch mode the caller
btr_cur_t* cursor, /*!< out: tree cursor */
ulint has_search_latch,/*!< in: latch mode the caller
currently has on btr_search_latch:
RW_S_LATCH, RW_X_LATCH, or 0 */
mtr_t* mtr) /* in: mtr */
mtr_t* mtr) /*!< in: mtr */
{
buf_block_t* block;
rec_t* rec;
@ -979,13 +981,13 @@ failure:
return(FALSE);
}
/************************************************************************
/********************************************************************//**
Drops a page hash index. */
UNIV_INTERN
void
btr_search_drop_page_hash_index(
/*============================*/
buf_block_t* block) /* in: block containing index page,
buf_block_t* block) /*!< in: block containing index page,
s- or x-latched, or an index page
for which we know that
block->buf_fix_count == 0 */
@ -1147,16 +1149,136 @@ cleanup:
}
/************************************************************************
Drops a page hash index based on index */
UNIV_INTERN
void
btr_search_drop_page_hash_index_on_index(
/*=====================================*/
dict_index_t* index) /* in: record descriptor */
{
buf_page_t* bpage;
hash_table_t* table;
buf_block_t* block;
ulint n_fields;
ulint n_bytes;
const page_t* page;
const rec_t* rec;
ulint fold;
ulint prev_fold;
dulint index_id;
ulint n_cached;
ulint n_recs;
ulint* folds;
ulint i;
mem_heap_t* heap = NULL;
ulint* offsets;
rw_lock_x_lock(&btr_search_latch);
mutex_enter(&LRU_list_mutex);
table = btr_search_sys->hash_index;
bpage = UT_LIST_GET_LAST(buf_pool->LRU);
while (bpage != NULL) {
block = (buf_block_t*) bpage;
if (block->index == index && block->is_hashed) {
page = block->frame;
/* from btr_search_drop_page_hash_index() */
n_fields = block->curr_n_fields;
n_bytes = block->curr_n_bytes;
ut_a(n_fields + n_bytes > 0);
n_recs = page_get_n_recs(page);
/* Calculate and cache fold values into an array for fast deletion
from the hash index */
folds = mem_alloc(n_recs * sizeof(ulint));
n_cached = 0;
rec = page_get_infimum_rec(page);
rec = page_rec_get_next_low(rec, page_is_comp(page));
index_id = btr_page_get_index_id(page);
ut_a(0 == ut_dulint_cmp(index_id, index->id));
prev_fold = 0;
offsets = NULL;
while (!page_rec_is_supremum(rec)) {
offsets = rec_get_offsets(rec, index, offsets,
n_fields + (n_bytes > 0), &heap);
ut_a(rec_offs_n_fields(offsets) == n_fields + (n_bytes > 0));
fold = rec_fold(rec, offsets, n_fields, n_bytes, index_id);
if (fold == prev_fold && prev_fold != 0) {
goto next_rec;
}
/* Remove all hash nodes pointing to this page from the
hash chain */
folds[n_cached] = fold;
n_cached++;
next_rec:
rec = page_rec_get_next_low(rec, page_rec_is_comp(rec));
prev_fold = fold;
}
for (i = 0; i < n_cached; i++) {
ha_remove_all_nodes_to_page(table, folds[i], page);
}
ut_a(index->search_info->ref_count > 0);
index->search_info->ref_count--;
block->is_hashed = FALSE;
block->index = NULL;
#if defined UNIV_AHI_DEBUG || defined UNIV_DEBUG
if (UNIV_UNLIKELY(block->n_pointers)) {
/* Corruption */
ut_print_timestamp(stderr);
fprintf(stderr,
" InnoDB: Corruption of adaptive hash index. After dropping\n"
"InnoDB: the hash index to a page of %s, still %lu hash nodes remain.\n",
index->name, (ulong) block->n_pointers);
}
#endif /* UNIV_AHI_DEBUG || UNIV_DEBUG */
mem_free(folds);
}
bpage = UT_LIST_GET_PREV(LRU, bpage);
}
mutex_exit(&LRU_list_mutex);
rw_lock_x_unlock(&btr_search_latch);
if (UNIV_LIKELY_NULL(heap)) {
mem_heap_free(heap);
}
}
/********************************************************************//**
Drops a page hash index when a page is freed from a fseg to the file system.
Drops possible hash index if the page happens to be in the buffer pool. */
UNIV_INTERN
void
btr_search_drop_page_hash_when_freed(
/*=================================*/
ulint space, /* in: space id */
ulint zip_size, /* in: compressed page size in bytes
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 */
ulint page_no) /*!< in: page number */
{
buf_block_t* block;
mtr_t mtr;
@ -1192,7 +1314,7 @@ btr_search_drop_page_hash_when_freed(
mtr_commit(&mtr);
}
/************************************************************************
/********************************************************************//**
Builds a hash index on a page with the given parameters. If the page already
has a hash index with different parameters, the old hash index is removed.
If index is non-NULL, this function checks if n_fields and n_bytes are
@ -1201,12 +1323,12 @@ static
void
btr_search_build_page_hash_index(
/*=============================*/
dict_index_t* index, /* in: index for which to build */
buf_block_t* block, /* in: index page, s- or x-latched */
ulint n_fields,/* in: hash this many full fields */
ulint n_bytes,/* in: hash this many bytes from the next
dict_index_t* index, /*!< in: index for which to build */
buf_block_t* block, /*!< in: index page, s- or x-latched */
ulint n_fields,/*!< in: hash this many full fields */
ulint n_bytes,/*!< in: hash this many bytes from the next
field */
ibool left_side)/* in: hash for searches from left side? */
ibool left_side)/*!< in: hash for searches from left side? */
{
hash_table_t* table;
page_t* page;
@ -1387,7 +1509,7 @@ exit_func:
}
}
/************************************************************************
/********************************************************************//**
Moves or deletes hash entries for moved records. If new_page is already hashed,
then the hash index for page, if any, is dropped. If new_page is not hashed,
and page is hashed, then a new hash index is built to new_page with the same
@ -1396,13 +1518,13 @@ UNIV_INTERN
void
btr_search_move_or_delete_hash_entries(
/*===================================*/
buf_block_t* new_block, /* in: records are copied
buf_block_t* new_block, /*!< in: records are copied
to this page */
buf_block_t* block, /* in: index page from which
buf_block_t* block, /*!< in: index page from which
records were copied, and the
copied records will be deleted
from this page */
dict_index_t* index) /* in: record descriptor */
dict_index_t* index) /*!< in: record descriptor */
{
ulint n_fields;
ulint n_bytes;
@ -1453,13 +1575,13 @@ btr_search_move_or_delete_hash_entries(
rw_lock_s_unlock(&btr_search_latch);
}
/************************************************************************
/********************************************************************//**
Updates the page hash index when a single record is deleted from a page. */
UNIV_INTERN
void
btr_search_update_hash_on_delete(
/*=============================*/
btr_cur_t* cursor) /* in: cursor which was positioned on the
btr_cur_t* cursor) /*!< in: cursor which was positioned on the
record to delete using btr_cur_search_...,
the record is not yet deleted */
{
@ -1506,13 +1628,13 @@ btr_search_update_hash_on_delete(
rw_lock_x_unlock(&btr_search_latch);
}
/************************************************************************
/********************************************************************//**
Updates the page hash index when a single record is inserted on a page. */
UNIV_INTERN
void
btr_search_update_hash_node_on_insert(
/*==================================*/
btr_cur_t* cursor) /* in: cursor which was positioned to the
btr_cur_t* cursor) /*!< in: cursor which was positioned to the
place to insert using btr_cur_search_...,
and the new record has been inserted next
to the cursor */
@ -1557,13 +1679,13 @@ btr_search_update_hash_node_on_insert(
}
}
/************************************************************************
/********************************************************************//**
Updates the page hash index when a single record is inserted on a page. */
UNIV_INTERN
void
btr_search_update_hash_on_insert(
/*=============================*/
btr_cur_t* cursor) /* in: cursor which was positioned to the
btr_cur_t* cursor) /*!< in: cursor which was positioned to the
place to insert using btr_cur_search_...,
and the new record has been inserted next
to the cursor */
@ -1707,13 +1829,13 @@ function_exit:
}
}
/************************************************************************
Validates the search system. */
/********************************************************************//**
Validates the search system.
@return TRUE if ok */
UNIV_INTERN
ibool
btr_search_validate(void)
/*=====================*/
/* out: TRUE if ok */
{
ha_node_t* node;
ulint n_page_dumps = 0;

View File

@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
/******************************************************
/**************************************************//**
@file buf/buf0buddy.c
Binary buddy allocator for compressed pages
Created December 2006 by Marko Makela
@ -44,15 +45,15 @@ static ulint buf_buddy_n_frames;
Protected by buf_pool_mutex. */
UNIV_INTERN buf_buddy_stat_t buf_buddy_stat[BUF_BUDDY_SIZES + 1];
/**************************************************************************
Get the offset of the buddy of a compressed page frame. */
/**********************************************************************//**
Get the offset of the buddy of a compressed page frame.
@return the buddy relative of page */
UNIV_INLINE
byte*
buf_buddy_get(
/*==========*/
/* out: the buddy relative of page */
byte* page, /* in: compressed page */
ulint size) /* in: page size in bytes */
byte* page, /*!< in: compressed page */
ulint size) /*!< in: page size in bytes */
{
ut_ad(ut_is_2pow(size));
ut_ad(size >= BUF_BUDDY_LOW);
@ -66,14 +67,14 @@ buf_buddy_get(
}
}
/**************************************************************************
/**********************************************************************//**
Add a block to the head of the appropriate buddy free list. */
UNIV_INLINE
void
buf_buddy_add_to_free(
/*==================*/
buf_page_t* bpage, /* in,own: block to be freed */
ulint i) /* in: index of buf_pool->zip_free[] */
buf_page_t* bpage, /*!< in,own: block to be freed */
ulint i) /*!< in: index of buf_pool->zip_free[] */
{
#ifdef UNIV_DEBUG_VALGRIND
buf_page_t* b = UT_LIST_GET_FIRST(buf_pool->zip_free[i]);
@ -81,6 +82,9 @@ buf_buddy_add_to_free(
if (b) UNIV_MEM_VALID(b, BUF_BUDDY_LOW << i);
#endif /* UNIV_DEBUG_VALGRIND */
//ut_ad(buf_pool_mutex_own());
ut_ad(mutex_own(&zip_free_mutex));
ut_ad(buf_page_get_state(bpage) == BUF_BLOCK_ZIP_FREE);
ut_ad(buf_pool->zip_free[i].start != bpage);
UT_LIST_ADD_FIRST(zip_list, buf_pool->zip_free[i], bpage);
@ -90,14 +94,14 @@ buf_buddy_add_to_free(
#endif /* UNIV_DEBUG_VALGRIND */
}
/**************************************************************************
/**********************************************************************//**
Remove a block from the appropriate buddy free list. */
UNIV_INLINE
void
buf_buddy_remove_from_free(
/*=======================*/
buf_page_t* bpage, /* in: block to be removed */
ulint i) /* in: index of buf_pool->zip_free[] */
buf_page_t* bpage, /*!< in: block to be removed */
ulint i) /*!< in: index of buf_pool->zip_free[] */
{
#ifdef UNIV_DEBUG_VALGRIND
buf_page_t* prev = UT_LIST_GET_PREV(zip_list, bpage);
@ -110,6 +114,8 @@ buf_buddy_remove_from_free(
ut_ad(!next || buf_page_get_state(next) == BUF_BLOCK_ZIP_FREE);
#endif /* UNIV_DEBUG_VALGRIND */
//ut_ad(buf_pool_mutex_own());
ut_ad(mutex_own(&zip_free_mutex));
ut_ad(buf_page_get_state(bpage) == BUF_BLOCK_ZIP_FREE);
UT_LIST_REMOVE(zip_list, buf_pool->zip_free[i], bpage);
@ -119,15 +125,14 @@ buf_buddy_remove_from_free(
#endif /* UNIV_DEBUG_VALGRIND */
}
/**************************************************************************
Try to allocate a block from buf_pool->zip_free[]. */
/**********************************************************************//**
Try to allocate a block from buf_pool->zip_free[].
@return allocated block, or NULL if buf_pool->zip_free[] was empty */
static
void*
buf_buddy_alloc_zip(
/*================*/
/* out: allocated block, or NULL
if buf_pool->zip_free[] was empty */
ulint i) /* in: index of buf_pool->zip_free[] */
ulint i) /*!< in: index of buf_pool->zip_free[] */
{
buf_page_t* bpage;
@ -135,10 +140,12 @@ buf_buddy_alloc_zip(
ut_ad(mutex_own(&zip_free_mutex));
ut_a(i < BUF_BUDDY_SIZES);
#if defined UNIV_DEBUG && !defined UNIV_DEBUG_VALGRIND
#ifndef UNIV_DEBUG_VALGRIND
/* Valgrind would complain about accessing free memory. */
UT_LIST_VALIDATE(zip_list, buf_page_t, buf_pool->zip_free[i]);
#endif /* UNIV_DEBUG && !UNIV_DEBUG_VALGRIND */
ut_d(UT_LIST_VALIDATE(zip_list, buf_page_t, buf_pool->zip_free[i],
ut_ad(buf_page_get_state(ut_list_node_313)
== BUF_BLOCK_ZIP_FREE)));
#endif /* !UNIV_DEBUG_VALGRIND */
bpage = UT_LIST_GET_LAST(buf_pool->zip_free[i]);
if (bpage) {
@ -172,13 +179,13 @@ buf_buddy_alloc_zip(
return(bpage);
}
/**************************************************************************
/**********************************************************************//**
Deallocate a buffer frame of UNIV_PAGE_SIZE. */
static
void
buf_buddy_block_free(
/*=================*/
void* buf, /* in: buffer frame to deallocate */
void* buf, /*!< in: buffer frame to deallocate */
ibool have_page_hash_mutex)
{
const ulint fold = BUF_POOL_ZIP_FOLD_PTR(buf);
@ -216,17 +223,18 @@ buf_buddy_block_free(
ut_d(buf_buddy_n_frames--);
}
/**************************************************************************
/**********************************************************************//**
Allocate a buffer block to the buddy allocator. */
static
void
buf_buddy_block_register(
/*=====================*/
buf_block_t* block) /* in: buffer frame to allocate */
buf_block_t* block) /*!< in: buffer frame to allocate */
{
const ulint fold = BUF_POOL_ZIP_FOLD(block);
//ut_ad(buf_pool_mutex_own());
ut_ad(!mutex_own(&buf_pool_zip_mutex));
ut_ad(buf_block_get_state(block) == BUF_BLOCK_READY_FOR_USE);
buf_block_set_state(block, BUF_BLOCK_MEMORY);
@ -244,16 +252,16 @@ buf_buddy_block_register(
ut_d(buf_buddy_n_frames++);
}
/**************************************************************************
Allocate a block from a bigger object. */
/**********************************************************************//**
Allocate a block from a bigger object.
@return allocated block */
static
void*
buf_buddy_alloc_from(
/*=================*/
/* out: allocated block */
void* buf, /* in: a block that is free to use */
ulint i, /* in: index of buf_pool->zip_free[] */
ulint j) /* in: size of buf as an index
void* buf, /*!< in: a block that is free to use */
ulint i, /*!< in: index of buf_pool->zip_free[] */
ulint j) /*!< in: size of buf as an index
of buf_pool->zip_free[] */
{
ulint offs = BUF_BUDDY_LOW << j;
@ -271,29 +279,31 @@ buf_buddy_alloc_from(
bpage = (buf_page_t*) ((byte*) buf + offs);
ut_d(memset(bpage, j, BUF_BUDDY_LOW << j));
bpage->state = BUF_BLOCK_ZIP_FREE;
#if defined UNIV_DEBUG && !defined UNIV_DEBUG_VALGRIND
#ifndef UNIV_DEBUG_VALGRIND
/* Valgrind would complain about accessing free memory. */
UT_LIST_VALIDATE(zip_list, buf_page_t, buf_pool->zip_free[j]);
#endif /* UNIV_DEBUG && !UNIV_DEBUG_VALGRIND */
ut_d(UT_LIST_VALIDATE(zip_list, buf_page_t, buf_pool->zip_free[i],
ut_ad(buf_page_get_state(
ut_list_node_313)
== BUF_BLOCK_ZIP_FREE)));
#endif /* !UNIV_DEBUG_VALGRIND */
buf_buddy_add_to_free(bpage, j);
}
return(buf);
}
/**************************************************************************
/**********************************************************************//**
Allocate a block. The thread calling this function must hold
buf_pool_mutex and must not hold buf_pool_zip_mutex or any block->mutex.
The buf_pool_mutex may only be released and reacquired if lru != NULL. */
The buf_pool_mutex may only be released and reacquired if lru != NULL.
@return allocated block, possibly NULL if lru==NULL */
UNIV_INTERN
void*
buf_buddy_alloc_low(
/*================*/
/* out: allocated block,
possibly NULL if lru==NULL */
ulint i, /* in: index of buf_pool->zip_free[],
ulint i, /*!< in: index of buf_pool->zip_free[],
or BUF_BUDDY_SIZES */
ibool* lru, /* in: pointer to a variable that will be assigned
ibool* lru, /*!< in: pointer to a variable that will be assigned
TRUE if storage was allocated from the LRU list
and buf_pool_mutex was temporarily released,
or NULL if the LRU list should not be used */
@ -357,15 +367,15 @@ func_exit:
return(block);
}
/**************************************************************************
Try to relocate the control block of a compressed page. */
/**********************************************************************//**
Try to relocate the control block of a compressed page.
@return TRUE if relocated */
static
ibool
buf_buddy_relocate_block(
/*=====================*/
/* out: TRUE if relocated */
buf_page_t* bpage, /* in: block to relocate */
buf_page_t* dpage) /* in: free block to relocate to */
buf_page_t* bpage, /*!< in: block to relocate */
buf_page_t* dpage) /*!< in: free block to relocate to */
{
buf_page_t* b;
@ -425,16 +435,16 @@ buf_buddy_relocate_block(
return(TRUE);
}
/**************************************************************************
Try to relocate a block. */
/**********************************************************************//**
Try to relocate a block.
@return TRUE if relocated */
static
ibool
buf_buddy_relocate(
/*===============*/
/* out: TRUE if relocated */
void* src, /* in: block to relocate */
void* dst, /* in: free block to relocate to */
ulint i, /* in: index of buf_pool->zip_free[] */
void* src, /*!< in: block to relocate */
void* dst, /*!< in: free block to relocate to */
ulint i, /*!< in: index of buf_pool->zip_free[] */
ibool have_page_hash_mutex)
{
buf_page_t* bpage;
@ -461,16 +471,15 @@ buf_buddy_relocate(
actually is a properly initialized buf_page_t object. */
if (size >= PAGE_ZIP_MIN_SIZE) {
mutex_t* mutex;
if (!have_page_hash_mutex)
mutex_exit(&zip_free_mutex);
/* This is a compressed page. */
mutex_t* mutex;
if (!have_page_hash_mutex) {
mutex_exit(&zip_free_mutex);
mutex_enter(&LRU_list_mutex);
rw_lock_x_lock(&page_hash_latch);
}
/* The src block may be split into smaller blocks,
some of which may be free. Thus, the
mach_read_from_4() calls below may attempt to read
@ -521,15 +530,9 @@ buf_buddy_relocate(
contain uninitialized data. */
UNIV_MEM_ASSERT_W(src, size);
mutex = buf_page_get_mutex(bpage);
mutex = buf_page_get_mutex_enter(bpage);
ut_a(mutex);
retry_lock:
mutex_enter(mutex);
if (mutex != buf_page_get_mutex(bpage)) {
mutex_exit(mutex);
mutex = buf_page_get_mutex(bpage);
goto retry_lock;
}
mutex_enter(&zip_free_mutex);
if (buf_page_can_relocate(bpage)) {
@ -594,15 +597,16 @@ success:
return(FALSE);
}
/**************************************************************************
/**********************************************************************//**
Deallocate a block. */
UNIV_INTERN
void
buf_buddy_free_low(
/*===============*/
void* buf, /* in: block to be freed, must not be
void* buf, /*!< in: block to be freed, must not be
pointed to by the buffer pool */
ulint i, /* in: index of buf_pool->zip_free[] */
ulint i, /*!< in: index of buf_pool->zip_free[],
or BUF_BUDDY_SIZES */
ibool have_page_hash_mutex)
{
buf_page_t* bpage;
@ -676,7 +680,9 @@ buddy_free2:
#ifndef UNIV_DEBUG_VALGRIND
buddy_nonfree:
/* Valgrind would complain about accessing free memory. */
ut_d(UT_LIST_VALIDATE(zip_list, buf_page_t, buf_pool->zip_free[i]));
ut_d(UT_LIST_VALIDATE(zip_list, buf_page_t, buf_pool->zip_free[i],
ut_ad(buf_page_get_state(ut_list_node_313)
== BUF_BLOCK_ZIP_FREE)));
#endif /* UNIV_DEBUG_VALGRIND */
/* The buddy is not free. Is there a free block of this size? */
@ -702,21 +708,20 @@ buddy_nonfree:
buddy = (buf_page_t*) buf_buddy_get(((byte*) bpage),
BUF_BUDDY_LOW << i);
#if defined UNIV_DEBUG && !defined UNIV_DEBUG_VALGRIND
{
const buf_page_t* b;
#ifndef UNIV_DEBUG_VALGRIND
/* Valgrind would complain about accessing free memory. */
/* The buddy must not be (completely) free, because
we always recombine adjacent free blocks.
(Parts of the buddy can be free in
buf_pool->zip_free[j] with j < i.)*/
for (b = UT_LIST_GET_FIRST(buf_pool->zip_free[i]);
b; b = UT_LIST_GET_NEXT(zip_list, b)) {
/* The buddy must not be (completely) free, because we
always recombine adjacent free blocks.
ut_a(b != buddy);
}
}
#endif /* UNIV_DEBUG && !UNIV_DEBUG_VALGRIND */
(Parts of the buddy can be free in
buf_pool->zip_free[j] with j < i.) */
ut_d(UT_LIST_VALIDATE(zip_list, buf_page_t, buf_pool->zip_free[i],
ut_ad(buf_page_get_state(
ut_list_node_313)
== BUF_BLOCK_ZIP_FREE
&& ut_list_node_313 != buddy)));
#endif /* !UNIV_DEBUG_VALGRIND */
if (buf_buddy_relocate(buddy, buf, i, have_page_hash_mutex)) {

File diff suppressed because it is too large Load Diff

View File

@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
/******************************************************
/**************************************************//**
@file buf/buf0flu.c
The database buffer buf_pool flush algorithm
Created 11/11/1995 Heikki Tuuri
@ -26,40 +27,73 @@ Created 11/11/1995 Heikki Tuuri
#ifdef UNIV_NONINL
#include "buf0flu.ic"
#include "trx0sys.h"
#endif
#include "buf0buf.h"
#include "srv0srv.h"
#include "page0zip.h"
#ifndef UNIV_HOTBACKUP
#include "ut0byte.h"
#include "ut0lst.h"
#include "page0page.h"
#include "page0zip.h"
#include "fil0fil.h"
#include "buf0buf.h"
#include "buf0lru.h"
#include "buf0rea.h"
#include "ibuf0ibuf.h"
#include "log0log.h"
#include "os0file.h"
#include "trx0sys.h"
#include "srv0srv.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. */
/******************************************************************//**
Validates the flush list.
@return TRUE if ok */
static
ibool
buf_flush_validate_low(void);
/*========================*/
/* out: TRUE if ok */
#endif /* UNIV_DEBUG || UNIV_BUF_DEBUG */
/************************************************************************
/********************************************************************//**
Inserts a modified block into the flush list. */
UNIV_INTERN
void
buf_flush_insert_into_flush_list(
/*=============================*/
buf_block_t* block) /* in/out: block which is modified */
buf_block_t* block) /*!< in/out: block which is modified */
{
//ut_ad(buf_pool_mutex_own());
ut_ad(mutex_own(&block->mutex));
@ -81,7 +115,7 @@ buf_flush_insert_into_flush_list(
#endif /* UNIV_DEBUG || UNIV_BUF_DEBUG */
}
/************************************************************************
/********************************************************************//**
Inserts a modified block into the flush list in the right sorted position.
This function is used by recovery, because there the modifications do not
necessarily come in the order of lsn's. */
@ -89,7 +123,7 @@ UNIV_INTERN
void
buf_flush_insert_sorted_into_flush_list(
/*====================================*/
buf_block_t* block) /* in/out: block which is modified */
buf_block_t* block) /*!< in/out: block which is modified */
{
buf_page_t* prev_b;
buf_page_t* b;
@ -141,15 +175,15 @@ buf_flush_insert_sorted_into_flush_list(
#endif /* UNIV_DEBUG || UNIV_BUF_DEBUG */
}
/************************************************************************
/********************************************************************//**
Returns TRUE if the file page block is immediately suitable for replacement,
i.e., the transition FILE_PAGE => NOT_USED allowed. */
i.e., the transition FILE_PAGE => NOT_USED allowed.
@return TRUE if can replace immediately */
UNIV_INTERN
ibool
buf_flush_ready_for_replace(
/*========================*/
/* out: TRUE if can replace immediately */
buf_page_t* bpage) /* in: buffer control block, must be
buf_page_t* bpage) /*!< in: buffer control block, must be
buf_page_in_file(bpage) and in the LRU list */
{
//ut_ad(buf_pool_mutex_own());
@ -177,16 +211,16 @@ buf_flush_ready_for_replace(
return(FALSE);
}
/************************************************************************
Returns TRUE if the block is modified and ready for flushing. */
/********************************************************************//**
Returns TRUE if the block is modified and ready for flushing.
@return TRUE if can flush immediately */
UNIV_INLINE
ibool
buf_flush_ready_for_flush(
/*======================*/
/* out: TRUE if can flush immediately */
buf_page_t* bpage, /* in: buffer control block, must be
buf_page_t* bpage, /*!< in: buffer control block, must be
buf_page_in_file(bpage) */
enum buf_flush flush_type)/* in: BUF_FLUSH_LRU or BUF_FLUSH_LIST */
enum buf_flush flush_type)/*!< in: BUF_FLUSH_LRU or BUF_FLUSH_LIST */
{
//ut_a(buf_page_in_file(bpage));
//ut_ad(buf_pool_mutex_own()); /*optimistic...*/
@ -214,13 +248,13 @@ buf_flush_ready_for_flush(
return(FALSE);
}
/************************************************************************
/********************************************************************//**
Remove a block from the flush list of modified blocks. */
UNIV_INTERN
void
buf_flush_remove(
/*=============*/
buf_page_t* bpage) /* in: pointer to the block in question */
buf_page_t* bpage) /*!< in: pointer to the block in question */
{
//ut_ad(buf_pool_mutex_own());
ut_ad(mutex_own(buf_page_get_mutex(bpage)));
@ -253,17 +287,18 @@ buf_flush_remove(
bpage->oldest_modification = 0;
ut_d(UT_LIST_VALIDATE(flush_list, buf_page_t, buf_pool->flush_list));
ut_d(UT_LIST_VALIDATE(flush_list, buf_page_t, buf_pool->flush_list,
ut_ad(ut_list_node_313->in_flush_list)));
mutex_exit(&flush_list_mutex);
}
/************************************************************************
/********************************************************************//**
Updates the flush system data structures when a write is completed. */
UNIV_INTERN
void
buf_flush_write_complete(
/*=====================*/
buf_page_t* bpage) /* in: pointer to the block in question */
buf_page_t* bpage) /*!< in: pointer to the block in question */
{
enum buf_flush flush_type;
@ -295,7 +330,7 @@ buf_flush_write_complete(
}
}
/************************************************************************
/********************************************************************//**
Flushes possible buffered writes from the doublewrite memory buffer to disk,
and also wakes up the aio thread if simulated aio is used. It is very
important to call this function after a batch of writes has been posted,
@ -542,7 +577,7 @@ flush:
mutex_exit(&(trx_doublewrite->mutex));
}
/************************************************************************
/********************************************************************//**
Posts a buffer page for writing. If the doublewrite memory buffer is
full, calls buf_flush_buffered_writes and waits for for free space to
appear. */
@ -550,7 +585,7 @@ static
void
buf_flush_post_to_doublewrite_buf(
/*==============================*/
buf_page_t* bpage) /* in: buffer block to write */
buf_page_t* bpage) /*!< in: buffer block to write */
{
ulint zip_size;
try_again:
@ -600,16 +635,17 @@ try_again:
mutex_exit(&(trx_doublewrite->mutex));
}
#endif /* !UNIV_HOTBACKUP */
/************************************************************************
/********************************************************************//**
Initializes a page for writing to the tablespace. */
UNIV_INTERN
void
buf_flush_init_for_writing(
/*=======================*/
byte* page, /* in/out: page */
void* page_zip_, /* in/out: compressed page, or NULL */
ib_uint64_t newest_lsn) /* in: newest modification lsn
byte* page, /*!< in/out: page */
void* page_zip_, /*!< in/out: compressed page, or NULL */
ib_uint64_t newest_lsn) /*!< in: newest modification lsn
to the page */
{
ut_ad(page);
@ -679,7 +715,8 @@ buf_flush_init_for_writing(
: BUF_NO_CHECKSUM_MAGIC);
}
/************************************************************************
#ifndef UNIV_HOTBACKUP
/********************************************************************//**
Does an asynchronous write of a buffer page. NOTE: in simulated aio and
also when the doublewrite buffer is used, we must call
buf_flush_buffered_writes after we have posted a batch of writes! */
@ -687,7 +724,7 @@ static
void
buf_flush_write_block_low(
/*======================*/
buf_page_t* bpage) /* in: buffer block to write */
buf_page_t* bpage) /*!< in: buffer block to write */
{
ulint zip_size = buf_page_get_zip_size(bpage);
page_t* frame = NULL;
@ -769,7 +806,7 @@ buf_flush_write_block_low(
}
}
/************************************************************************
/********************************************************************//**
Writes a flushable page asynchronously from the buffer pool to a file.
NOTE: in simulated aio we must call
os_aio_simulated_wake_handler_threads after we have posted a batch of
@ -780,8 +817,8 @@ static
void
buf_flush_page(
/*===========*/
buf_page_t* bpage, /* in: buffer control block */
enum buf_flush flush_type) /* in: BUF_FLUSH_LRU
buf_page_t* bpage, /*!< in: buffer control block */
enum buf_flush flush_type) /*!< in: BUF_FLUSH_LRU
or BUF_FLUSH_LIST */
{
mutex_t* block_mutex;
@ -892,16 +929,16 @@ buf_flush_page(
buf_flush_write_block_low(bpage);
}
/***************************************************************
Flushes to disk all flushable pages within the flush area. */
/***********************************************************//**
Flushes to disk all flushable pages within the flush area.
@return number of pages flushed */
static
ulint
buf_flush_try_neighbors(
/*====================*/
/* out: number of pages flushed */
ulint space, /* in: space id */
ulint offset, /* in: page offset */
enum buf_flush flush_type, /* in: BUF_FLUSH_LRU or
ulint space, /*!< in: space id */
ulint offset, /*!< in: page offset */
enum buf_flush flush_type, /*!< in: BUF_FLUSH_LRU or
BUF_FLUSH_LIST */
ulint flush_neighbors)
{
@ -955,15 +992,9 @@ buf_flush_try_neighbors(
if (flush_type != BUF_FLUSH_LRU
|| i == offset
|| buf_page_is_old(bpage)) {
mutex_t* block_mutex = buf_page_get_mutex(bpage);
mutex_t* block_mutex = buf_page_get_mutex_enter(bpage);
retry_lock:
mutex_enter(block_mutex);
if (block_mutex != buf_page_get_mutex(bpage)) {
mutex_exit(block_mutex);
block_mutex = buf_page_get_mutex(bpage);
goto retry_lock;
}
ut_a(block_mutex);
if (buf_flush_ready_for_flush(bpage, flush_type)
&& (i == offset || !bpage->buf_fix_count)) {
@ -993,28 +1024,26 @@ retry_lock:
return(count);
}
/***********************************************************************
/*******************************************************************//**
This utility flushes dirty blocks from the end of the LRU list or flush_list.
NOTE 1: in the case of an LRU flush the calling thread may own latches to
pages: to avoid deadlocks, this function must be written so that it cannot
end up waiting for these latches! NOTE 2: in the case of a flush list flush,
the calling thread is not allowed to own any latches on pages! */
the calling thread is not allowed to own any latches on pages!
@return number of blocks for which the write request was queued;
ULINT_UNDEFINED if there was a flush of the same type already running */
UNIV_INTERN
ulint
buf_flush_batch(
/*============*/
/* out: number of blocks for which the
write request was queued;
ULINT_UNDEFINED if there was a flush
of the same type already running */
enum buf_flush flush_type, /* in: BUF_FLUSH_LRU or
enum buf_flush flush_type, /*!< in: BUF_FLUSH_LRU or
BUF_FLUSH_LIST; if BUF_FLUSH_LIST,
then the caller must not own any
latches on pages */
ulint min_n, /* in: wished minimum mumber of blocks
ulint min_n, /*!< in: wished minimum mumber of blocks
flushed (it is not guaranteed that the
actual number is that big, though) */
ib_uint64_t lsn_limit) /* in the case BUF_FLUSH_LIST all
ib_uint64_t lsn_limit) /*!< in the case BUF_FLUSH_LIST all
blocks whose oldest_modification is
smaller than this should be flushed
(if their number does not exceed
@ -1091,24 +1120,16 @@ flush_next:
function a pointer to a block in the list! */
do {
mutex_t*block_mutex = buf_page_get_mutex(bpage);
mutex_t*block_mutex = buf_page_get_mutex_enter(bpage);
ibool ready;
retry_lock_1:
ut_a(buf_page_in_file(bpage));
mutex_enter(block_mutex);
if (block_mutex != buf_page_get_mutex(bpage)) {
mutex_exit(block_mutex);
block_mutex = buf_page_get_mutex(bpage);
goto retry_lock_1;
}
ut_a(block_mutex);
ready = buf_flush_ready_for_flush(bpage, flush_type);
mutex_exit(block_mutex);
if (ready) {
mutex_t* block_mutex;
buf_page_t* bpage_tmp;
space = buf_page_get_space(bpage);
offset = buf_page_get_page_no(bpage);
@ -1122,8 +1143,6 @@ retry_lock_1:
/* Try to flush also all the neighbors */
page_count += buf_flush_try_neighbors(
space, offset, flush_type, srv_flush_neighbor_pages);
block_mutex = buf_page_get_mutex(bpage);
bpage_tmp = buf_page_hash_get(space, offset);
/* fprintf(stderr,
"Flush type %lu, page no %lu, neighb %lu\n",
flush_type, offset,
@ -1189,38 +1208,44 @@ retry_lock_1:
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);
}
/**********************************************************************
/******************************************************************//**
Waits until a flush batch of the given type ends */
UNIV_INTERN
void
buf_flush_wait_batch_end(
/*=====================*/
enum buf_flush type) /* in: BUF_FLUSH_LRU or BUF_FLUSH_LIST */
enum buf_flush type) /*!< in: BUF_FLUSH_LRU or BUF_FLUSH_LIST */
{
ut_ad((type == BUF_FLUSH_LRU) || (type == BUF_FLUSH_LIST));
os_event_wait(buf_pool->no_flush[type]);
}
/**********************************************************************
/******************************************************************//**
Gives a recommendation of how many blocks should be flushed to establish
a big enough margin of replaceable blocks near the end of the LRU list
and in the free list. */
and in the free list.
@return number of blocks which should be flushed from the end of the
LRU list */
static
ulint
buf_flush_LRU_recommendation(void)
/*==============================*/
/* out: number of blocks which should be flushed
from the end of the LRU list */
{
buf_page_t* bpage;
ulint n_replaceable;
ulint distance = 0;
ibool have_LRU_mutex = FALSE;
mutex_t* block_mutex;
if(UT_LIST_GET_LEN(buf_pool->unzip_LRU))
have_LRU_mutex = TRUE;
@ -1238,21 +1263,15 @@ buf_flush_LRU_recommendation(void)
+ BUF_FLUSH_EXTRA_MARGIN)
&& (distance < BUF_LRU_FREE_SEARCH_LEN)) {
if (!bpage->in_LRU_list) {
mutex_t* block_mutex;
if (!bpage->in_LRU_list) {
/* reatart. but it is very optimistic */
bpage = UT_LIST_GET_LAST(buf_pool->LRU);
continue;
}
block_mutex = buf_page_get_mutex_enter(bpage);
block_mutex = buf_page_get_mutex(bpage);
retry_lock:
mutex_enter(block_mutex);
if (block_mutex != buf_page_get_mutex(bpage)) {
mutex_exit(block_mutex);
block_mutex = buf_page_get_mutex(bpage);
goto retry_lock;
}
ut_a(block_mutex);
if (buf_flush_ready_for_replace(bpage)) {
n_replaceable++;
@ -1278,7 +1297,7 @@ retry_lock:
- n_replaceable);
}
/*************************************************************************
/*********************************************************************//**
Flushes pages from the end of the LRU list if there is too small a margin
of replaceable pages there or in the free list. VERY IMPORTANT: this function
is called also by threads which have locks on pages. To avoid deadlocks, we
@ -1306,18 +1325,130 @@ buf_flush_free_margin(
}
}
/*********************************************************************
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. */
/******************************************************************//**
Validates the flush list.
@return TRUE if ok */
static
ibool
buf_flush_validate_low(void)
/*========================*/
/* out: TRUE if ok */
{
buf_page_t* bpage;
UT_LIST_VALIDATE(flush_list, buf_page_t, buf_pool->flush_list);
UT_LIST_VALIDATE(flush_list, buf_page_t, buf_pool->flush_list,
ut_ad(ut_list_node_313->in_flush_list));
bpage = UT_LIST_GET_FIRST(buf_pool->flush_list);
@ -1335,13 +1466,13 @@ buf_flush_validate_low(void)
return(TRUE);
}
/**********************************************************************
Validates the flush list. */
/******************************************************************//**
Validates the flush list.
@return TRUE if ok */
UNIV_INTERN
ibool
buf_flush_validate(void)
/*====================*/
/* out: TRUE if ok */
{
ibool ret;
@ -1356,3 +1487,4 @@ buf_flush_validate(void)
return(ret);
}
#endif /* UNIV_DEBUG || UNIV_BUF_DEBUG */
#endif /* !UNIV_HOTBACKUP */

View File

@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
/******************************************************
/**************************************************//**
@file buf/buf0lru.c
The database buffer replacement algorithm
Created 11/5/1995 Heikki Tuuri
@ -48,7 +49,7 @@ Created 11/5/1995 Heikki Tuuri
#include "log0recv.h"
#include "srv0srv.h"
/* The number of blocks from the LRU_old pointer onward, including the block
/** The number of blocks from the LRU_old pointer onward, including the block
pointed to, must be 3/8 of the whole LRU list length, except that the
tolerance defined below is allowed. Note that the tolerance must be small
enough such that for even the BUF_LRU_OLD_MIN_LEN long LRU list, the
@ -56,21 +57,21 @@ LRU_old pointer is not allowed to point to either end of the LRU list. */
#define BUF_LRU_OLD_TOLERANCE 20
/* The whole LRU list length is divided by this number to determine an
/** The whole LRU list length is divided by this number to determine an
initial segment in buf_LRU_get_recent_limit */
#define BUF_LRU_INITIAL_RATIO 8
/* When dropping the search hash index entries before deleting an ibd
/** When dropping the search hash index entries before deleting an ibd
file, we build a local array of pages belonging to that tablespace
in the buffer pool. Following is the size of that array. */
#define BUF_LRU_DROP_SEARCH_HASH_SIZE 1024
/* If we switch on the InnoDB monitor because there are too few available
/** If we switch on the InnoDB monitor because there are too few available
frames in the buffer pool, we set this to TRUE */
UNIV_INTERN ibool buf_lru_switched_on_innodb_mon = FALSE;
static ibool buf_lru_switched_on_innodb_mon = FALSE;
/**********************************************************************
/******************************************************************//**
These statistics are not 'of' LRU but 'for' LRU. We keep count of I/O
and page_zip_decompress() operations. Based on the statistics,
buf_LRU_evict_from_unzip_LRU() decides if we want to evict from
@ -79,69 +80,71 @@ uncompressed frame (meaning we can evict dirty blocks as well). From
the regular LRU, we will evict the entire block (i.e.: both the
uncompressed and compressed data), which must be clean. */
/* Number of intervals for which we keep the history of these stats.
/* @{ */
/** 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_LRU_stat_update(). */
#define BUF_LRU_STAT_N_INTERVAL 50
/* Co-efficient with which we multiply I/O operations to equate them
/** Co-efficient with which we multiply I/O operations to equate them
with page_zip_decompress() operations. */
#define BUF_LRU_IO_TO_UNZIP_FACTOR 50
/* Sampled values buf_LRU_stat_cur.
/** Sampled values buf_LRU_stat_cur.
Protected by buf_pool_mutex. Updated by buf_LRU_stat_update(). */
static buf_LRU_stat_t buf_LRU_stat_arr[BUF_LRU_STAT_N_INTERVAL];
/* Cursor to buf_LRU_stat_arr[] that is updated in a round-robin fashion. */
/** Cursor to buf_LRU_stat_arr[] that is updated in a round-robin fashion. */
static ulint buf_LRU_stat_arr_ind;
/* Current operation counters. Not protected by any mutex. Cleared
/** Current operation counters. Not protected by any mutex. Cleared
by buf_LRU_stat_update(). */
UNIV_INTERN buf_LRU_stat_t buf_LRU_stat_cur;
/* Running sum of past values of buf_LRU_stat_cur.
/** Running sum of past values of buf_LRU_stat_cur.
Updated by buf_LRU_stat_update(). Protected by buf_pool_mutex. */
UNIV_INTERN buf_LRU_stat_t buf_LRU_stat_sum;
/**********************************************************************
/* @} */
/******************************************************************//**
Takes a block out of the LRU list and page hash table.
If the block is compressed-only (BUF_BLOCK_ZIP_PAGE),
the object will be freed and buf_pool_zip_mutex will be released.
If a compressed page or a compressed-only block descriptor is freed,
other compressed pages or compressed-only block descriptors may be
relocated. */
relocated.
@return the new state of the block (BUF_BLOCK_ZIP_FREE if the state
was BUF_BLOCK_ZIP_PAGE, or BUF_BLOCK_REMOVE_HASH otherwise) */
static
enum buf_page_state
buf_LRU_block_remove_hashed_page(
/*=============================*/
/* out: the new state of the block
(BUF_BLOCK_ZIP_FREE if the state was
BUF_BLOCK_ZIP_PAGE, or BUF_BLOCK_REMOVE_HASH
otherwise) */
buf_page_t* bpage, /* in: block, must contain a file page and
buf_page_t* bpage, /*!< in: block, must contain a file page and
be in a state where it can be freed; there
may or may not be a hash index to the page */
ibool zip); /* in: TRUE if should remove also the
ibool zip); /*!< in: TRUE if should remove also the
compressed page of an uncompressed page */
/**********************************************************************
/******************************************************************//**
Puts a file page whose has no hash index to the free list. */
static
void
buf_LRU_block_free_hashed_page(
/*===========================*/
buf_block_t* block, /* in: block, must contain a file page and
buf_block_t* block, /*!< in: block, must contain a file page and
be in a state where it can be freed */
ibool have_page_hash_mutex);
/**********************************************************************
/******************************************************************//**
Determines if the unzip_LRU list should be used for evicting a victim
instead of the general LRU list. */
instead of the general LRU list.
@return TRUE if should use unzip_LRU */
UNIV_INLINE
ibool
buf_LRU_evict_from_unzip_LRU(
ibool have_LRU_mutex)
/*==============================*/
/* out: TRUE if should use unzip_LRU */
{
ulint io_avg;
ulint unzip_avg;
@ -191,18 +194,18 @@ buf_LRU_evict_from_unzip_LRU(
return(unzip_avg <= io_avg * BUF_LRU_IO_TO_UNZIP_FACTOR);
}
/**********************************************************************
/******************************************************************//**
Attempts to drop page hash index on a batch of pages belonging to a
particular space id. */
static
void
buf_LRU_drop_page_hash_batch(
/*=========================*/
ulint space_id, /* in: space id */
ulint zip_size, /* in: compressed page size in bytes
ulint space_id, /*!< in: space id */
ulint zip_size, /*!< in: compressed page size in bytes
or 0 for uncompressed pages */
const ulint* arr, /* in: array of page_no */
ulint count) /* in: number of entries in array */
const ulint* arr, /*!< in: array of page_no */
ulint count) /*!< in: number of entries in array */
{
ulint i;
@ -215,7 +218,7 @@ buf_LRU_drop_page_hash_batch(
}
}
/**********************************************************************
/******************************************************************//**
When doing a DROP TABLE/DISCARD TABLESPACE we have to drop all page
hash index entries belonging to that table. This function tries to
do that in batch. Note that this is a 'best effort' attempt and does
@ -224,7 +227,7 @@ static
void
buf_LRU_drop_page_hash_for_tablespace(
/*==================================*/
ulint id) /* in: space id */
ulint id) /*!< in: space id */
{
buf_page_t* bpage;
ulint* page_arr;
@ -249,16 +252,10 @@ scan_again:
bpage = UT_LIST_GET_LAST(buf_pool->LRU);
while (bpage != NULL) {
mutex_t* block_mutex = buf_page_get_mutex(bpage);
mutex_t* block_mutex = buf_page_get_mutex_enter(bpage);
buf_page_t* prev_bpage;
retry_lock:
mutex_enter(block_mutex);
if (block_mutex != buf_page_get_mutex(bpage)) {
mutex_exit(block_mutex);
block_mutex = buf_page_get_mutex(bpage);
goto retry_lock;
}
ut_a(block_mutex);
prev_bpage = UT_LIST_GET_PREV(LRU, bpage);
ut_a(buf_page_in_file(bpage));
@ -328,14 +325,14 @@ next_page:
ut_free(page_arr);
}
/**********************************************************************
/******************************************************************//**
Invalidates all pages belonging to a given tablespace when we are deleting
the data file(s) of that tablespace. */
UNIV_INTERN
void
buf_LRU_invalidate_tablespace(
/*==========================*/
ulint id) /* in: space id */
ulint id) /*!< in: space id */
{
buf_page_t* bpage;
ibool all_freed;
@ -358,18 +355,12 @@ scan_again:
bpage = UT_LIST_GET_LAST(buf_pool->LRU);
while (bpage != NULL) {
mutex_t* block_mutex = buf_page_get_mutex(bpage);
mutex_t* block_mutex = buf_page_get_mutex_enter(bpage);
buf_page_t* prev_bpage;
ut_a(buf_page_in_file(bpage));
retry_lock:
mutex_enter(block_mutex);
if (block_mutex != buf_page_get_mutex(bpage)) {
mutex_exit(block_mutex);
block_mutex = buf_page_get_mutex(bpage);
goto retry_lock;
}
ut_a(block_mutex);
prev_bpage = UT_LIST_GET_PREV(LRU, bpage);
if (buf_page_get_space(bpage) == id) {
@ -459,15 +450,15 @@ next_page:
}
}
/**********************************************************************
/******************************************************************//**
Gets the minimum LRU_position field for the blocks in an initial segment
(determined by BUF_LRU_INITIAL_RATIO) of the LRU list. The limit is not
guaranteed to be precise, because the ulint_clock may wrap around. */
guaranteed to be precise, because the ulint_clock may wrap around.
@return the limit; zero if could not determine it */
UNIV_INTERN
ulint
buf_LRU_get_recent_limit(void)
/*==========================*/
/* out: the limit; zero if could not determine it */
{
const buf_page_t* bpage;
ulint len;
@ -489,21 +480,22 @@ 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();
mutex_exit(&LRU_list_mutex);
return(limit);
return(limit > len ? (limit - len) : 0);
}
/************************************************************************
/********************************************************************//**
Insert a compressed block into buf_pool->zip_clean in the LRU order. */
UNIV_INTERN
void
buf_LRU_insert_zip_clean(
/*=====================*/
buf_page_t* bpage) /* in: pointer to the block in question */
buf_page_t* bpage) /*!< in: pointer to the block in question */
{
buf_page_t* b;
@ -531,15 +523,15 @@ buf_LRU_insert_zip_clean(
}
}
/**********************************************************************
/******************************************************************//**
Try to free an uncompressed page of a compressed block from the unzip
LRU list. The compressed page is preserved, and it need not be clean. */
LRU list. The compressed page is preserved, and it need not be clean.
@return TRUE if freed */
UNIV_INLINE
ibool
buf_LRU_free_from_unzip_LRU_list(
/*=============================*/
/* out: TRUE if freed */
ulint n_iterations, /* in: how many times this has been called
ulint n_iterations, /*!< in: how many times this has been called
repeatedly without result: a high value means
that we should search farther; we will search
n_iterations / 5 of the unzip_LRU list,
@ -611,14 +603,14 @@ restart:
return(FALSE);
}
/**********************************************************************
Try to free a clean page from the common LRU list. */
/******************************************************************//**
Try to free a clean page from the common LRU list.
@return TRUE if freed */
UNIV_INLINE
ibool
buf_LRU_free_from_common_LRU_list(
/*==============================*/
/* out: TRUE if freed */
ulint n_iterations, /* in: how many times this has been called
ulint n_iterations, /*!< in: how many times this has been called
repeatedly without result: a high value means
that we should search farther; if
n_iterations < 10, then we search
@ -640,16 +632,9 @@ restart:
enum buf_lru_free_block_status freed;
mutex_t* block_mutex
= buf_page_get_mutex(bpage);
= buf_page_get_mutex_enter(bpage);
retry_lock:
mutex_enter(block_mutex);
if (block_mutex != buf_page_get_mutex(bpage)) {
mutex_exit(block_mutex);
block_mutex = buf_page_get_mutex(bpage);
goto retry_lock;
}
ut_a(block_mutex);
if (!bpage->in_LRU_list
|| !buf_page_in_file(bpage)) {
@ -686,14 +671,14 @@ retry_lock:
return(FALSE);
}
/**********************************************************************
Try to free a replaceable block. */
/******************************************************************//**
Try to free a replaceable block.
@return TRUE if found and freed */
UNIV_INTERN
ibool
buf_LRU_search_and_free_block(
/*==========================*/
/* out: TRUE if found and freed */
ulint n_iterations) /* in: how many times this has been called
ulint n_iterations) /*!< in: how many times this has been called
repeatedly without result: a high value means
that we should search farther; if
n_iterations < 10, then we search
@ -734,7 +719,7 @@ buf_LRU_search_and_free_block(
return(freed);
}
/**********************************************************************
/******************************************************************//**
Tries to remove LRU flushed blocks from the end of the LRU list and put them
to the free list. This is beneficial for the efficiency of the insert buffer
operation, as flushed pages from non-unique non-clustered indexes are here
@ -765,16 +750,15 @@ buf_LRU_try_free_flushed_blocks(void)
mutex_exit(&buf_pool_mutex);
}
/**********************************************************************
/******************************************************************//**
Returns TRUE if less than 25 % of the buffer pool is available. This can be
used in heuristics to prevent huge transactions eating up the whole buffer
pool for their locks. */
pool for their locks.
@return TRUE if less than 25 % of buffer pool left */
UNIV_INTERN
ibool
buf_LRU_buf_pool_running_out(void)
/*==============================*/
/* out: TRUE if less than 25 % of buffer pool
left */
{
ibool ret = FALSE;
@ -795,15 +779,14 @@ buf_LRU_buf_pool_running_out(void)
return(ret);
}
/**********************************************************************
/******************************************************************//**
Returns a free block from the buf_pool. The block is taken off the
free list. If it is empty, returns NULL. */
free list. If it is empty, returns NULL.
@return a free control block, or NULL if the buf_block->free list is empty */
UNIV_INTERN
buf_block_t*
buf_LRU_get_free_only(void)
/*=======================*/
/* out: a free control block, or NULL
if the buf_block->free list is empty */
{
buf_block_t* block;
@ -835,17 +818,16 @@ buf_LRU_get_free_only(void)
return(block);
}
/**********************************************************************
/******************************************************************//**
Returns a free block from the buf_pool. The block is taken off the
free list. If it is empty, blocks are moved from the end of the
LRU list to the free list. */
LRU list to the free list.
@return the free control block, in state BUF_BLOCK_READY_FOR_USE */
UNIV_INTERN
buf_block_t*
buf_LRU_get_free_block(
/*===================*/
/* out: the free control block,
in state BUF_BLOCK_READY_FOR_USE */
ulint zip_size) /* in: compressed page size in bytes,
ulint zip_size) /*!< in: compressed page size in bytes,
or 0 if uncompressed tablespace */
{
buf_block_t* block = NULL;
@ -1031,7 +1013,7 @@ loop:
goto loop;
}
/***********************************************************************
/*******************************************************************//**
Moves the LRU_old pointer so that the length of the old blocks list
is inside the allowed limits. */
UNIV_INLINE
@ -1092,7 +1074,7 @@ buf_LRU_old_adjust_len(void)
}
}
/***********************************************************************
/*******************************************************************//**
Initializes the old blocks pointer in the LRU list. This function should be
called when the LRU list grows to BUF_LRU_OLD_MIN_LEN length. */
static
@ -1124,13 +1106,13 @@ buf_LRU_old_init(void)
buf_LRU_old_adjust_len();
}
/**********************************************************************
/******************************************************************//**
Remove a block from the unzip_LRU list if it belonged to the list. */
static
void
buf_unzip_LRU_remove_block_if_needed(
/*=================================*/
buf_page_t* bpage) /* in/out: control block */
buf_page_t* bpage) /*!< in/out: control block */
{
ut_ad(buf_pool);
ut_ad(bpage);
@ -1148,13 +1130,13 @@ buf_unzip_LRU_remove_block_if_needed(
}
}
/**********************************************************************
/******************************************************************//**
Removes a block from the LRU list. */
UNIV_INLINE
void
buf_LRU_remove_block(
/*=================*/
buf_page_t* bpage) /* in: control block */
buf_page_t* bpage) /*!< in: control block */
{
ut_ad(buf_pool);
ut_ad(bpage);
@ -1210,14 +1192,14 @@ buf_LRU_remove_block(
buf_LRU_old_adjust_len();
}
/**********************************************************************
/******************************************************************//**
Adds a block to the LRU list of decompressed zip pages. */
UNIV_INTERN
void
buf_unzip_LRU_add_block(
/*====================*/
buf_block_t* block, /* in: control block */
ibool old) /* in: TRUE if should be put to the end
buf_block_t* block, /*!< in: control block */
ibool old) /*!< in: TRUE if should be put to the end
of the list, else put to the start */
{
ut_ad(buf_pool);
@ -1237,13 +1219,13 @@ buf_unzip_LRU_add_block(
}
}
/**********************************************************************
/******************************************************************//**
Adds a block to the LRU list end. */
UNIV_INLINE
void
buf_LRU_add_block_to_end_low(
/*=========================*/
buf_page_t* bpage) /* in: control block */
buf_page_t* bpage) /*!< in: control block */
{
buf_page_t* last_bpage;
@ -1296,14 +1278,14 @@ buf_LRU_add_block_to_end_low(
}
}
/**********************************************************************
/******************************************************************//**
Adds a block to the LRU list. */
UNIV_INLINE
void
buf_LRU_add_block_low(
/*==================*/
buf_page_t* bpage, /* in: control block */
ibool old) /* in: TRUE if should be put to the old blocks
buf_page_t* bpage, /*!< in: control block */
ibool old) /*!< in: TRUE if should be put to the old blocks
in the LRU list, else put to the start; if the
LRU list is very short, the block is added to
the start, regardless of this parameter */
@ -1369,14 +1351,14 @@ buf_LRU_add_block_low(
}
}
/**********************************************************************
/******************************************************************//**
Adds a block to the LRU list. */
UNIV_INTERN
void
buf_LRU_add_block(
/*==============*/
buf_page_t* bpage, /* in: control block */
ibool old) /* in: TRUE if should be put to the old
buf_page_t* bpage, /*!< in: control block */
ibool old) /*!< in: TRUE if should be put to the old
blocks in the LRU list, else put to the start;
if the LRU list is very short, the block is
added to the start, regardless of this
@ -1385,31 +1367,31 @@ buf_LRU_add_block(
buf_LRU_add_block_low(bpage, old);
}
/**********************************************************************
/******************************************************************//**
Moves a block to the start of the LRU list. */
UNIV_INTERN
void
buf_LRU_make_block_young(
/*=====================*/
buf_page_t* bpage) /* in: control block */
buf_page_t* bpage) /*!< in: control block */
{
buf_LRU_remove_block(bpage);
buf_LRU_add_block_low(bpage, FALSE);
}
/**********************************************************************
/******************************************************************//**
Moves a block to the end of the LRU list. */
UNIV_INTERN
void
buf_LRU_make_block_old(
/*===================*/
buf_page_t* bpage) /* in: control block */
buf_page_t* bpage) /*!< in: control block */
{
buf_LRU_remove_block(bpage);
buf_LRU_add_block_to_end_low(bpage);
}
/**********************************************************************
/******************************************************************//**
Try to free a block. If bpage is a descriptor of a compressed-only
page, the descriptor object will be freed as well.
@ -1419,19 +1401,18 @@ accessible via bpage.
The caller must hold buf_pool_mutex and buf_page_get_mutex(bpage) and
release these two mutexes after the call. No other
buf_page_get_mutex() may be held when calling this function. */
buf_page_get_mutex() may be held when calling this function.
@return BUF_LRU_FREED if freed, BUF_LRU_CANNOT_RELOCATE or
BUF_LRU_NOT_FREED otherwise. */
UNIV_INTERN
enum buf_lru_free_block_status
buf_LRU_free_block(
/*===============*/
/* out: BUF_LRU_FREED if freed,
BUF_LRU_CANNOT_RELOCATE or
BUF_LRU_NOT_FREED otherwise. */
buf_page_t* bpage, /* in: block to be freed */
ibool zip, /* in: TRUE if should remove also the
buf_page_t* bpage, /*!< in: block to be freed */
ibool zip, /*!< in: TRUE if should remove also the
compressed page of an uncompressed page */
ibool* buf_pool_mutex_released,
/* in: pointer to a variable that will
/*!< in: pointer to a variable that will
be assigned TRUE if buf_pool_mutex
was temporarily released, or NULL */
ibool have_LRU_mutex)
@ -1722,13 +1703,13 @@ not_freed:
return(BUF_LRU_FREED);
}
/**********************************************************************
/******************************************************************//**
Puts a block back to the free list. */
UNIV_INTERN
void
buf_LRU_block_free_non_file_page(
/*=============================*/
buf_block_t* block, /* in: block, must not contain a file page */
buf_block_t* block, /*!< in: block, must not contain a file page */
ibool have_page_hash_mutex)
{
void* data;
@ -1783,26 +1764,24 @@ buf_LRU_block_free_non_file_page(
UNIV_MEM_ASSERT_AND_FREE(block->frame, UNIV_PAGE_SIZE);
}
/**********************************************************************
/******************************************************************//**
Takes a block out of the LRU list and page hash table.
If the block is compressed-only (BUF_BLOCK_ZIP_PAGE),
the object will be freed and buf_pool_zip_mutex will be released.
If a compressed page or a compressed-only block descriptor is freed,
other compressed pages or compressed-only block descriptors may be
relocated. */
relocated.
@return the new state of the block (BUF_BLOCK_ZIP_FREE if the state
was BUF_BLOCK_ZIP_PAGE, or BUF_BLOCK_REMOVE_HASH otherwise) */
static
enum buf_page_state
buf_LRU_block_remove_hashed_page(
/*=============================*/
/* out: the new state of the block
(BUF_BLOCK_ZIP_FREE if the state was
BUF_BLOCK_ZIP_PAGE, or BUF_BLOCK_REMOVE_HASH
otherwise) */
buf_page_t* bpage, /* in: block, must contain a file page and
buf_page_t* bpage, /*!< in: block, must contain a file page and
be in a state where it can be freed; there
may or may not be a hash index to the page */
ibool zip) /* in: TRUE if should remove also the
ibool zip) /*!< in: TRUE if should remove also the
compressed page of an uncompressed page */
{
const buf_page_t* hashed_bpage;
@ -1962,6 +1941,9 @@ buf_LRU_block_remove_hashed_page(
void* data = bpage->zip.data;
bpage->zip.data = NULL;
ut_ad(!bpage->in_free_list);
ut_ad(!bpage->in_flush_list);
ut_ad(!bpage->in_LRU_list);
mutex_exit(&((buf_block_t*) bpage)->mutex);
//buf_pool_mutex_exit_forbid();
buf_buddy_free(data, page_zip_get_size(&bpage->zip), TRUE);
@ -1985,13 +1967,13 @@ buf_LRU_block_remove_hashed_page(
return(BUF_BLOCK_ZIP_FREE);
}
/**********************************************************************
/******************************************************************//**
Puts a file page whose has no hash index to the free list. */
static
void
buf_LRU_block_free_hashed_page(
/*===========================*/
buf_block_t* block, /* in: block, must contain a file page and
buf_block_t* block, /*!< in: block, must contain a file page and
be in a state where it can be freed */
ibool have_page_hash_mutex)
{
@ -2003,7 +1985,7 @@ buf_LRU_block_free_hashed_page(
buf_LRU_block_free_non_file_page(block, have_page_hash_mutex);
}
/************************************************************************
/********************************************************************//**
Update the historical stats that we are collecting for LRU eviction
policy at the end of each interval. */
UNIV_INTERN
@ -2042,8 +2024,9 @@ func_exit:
}
#if defined UNIV_DEBUG || defined UNIV_BUF_DEBUG
/**************************************************************************
Validates the LRU list. */
/**********************************************************************//**
Validates the LRU list.
@return TRUE */
UNIV_INTERN
ibool
buf_LRU_validate(void)
@ -2068,7 +2051,8 @@ buf_LRU_validate(void)
ut_a(old_len <= new_len + BUF_LRU_OLD_TOLERANCE);
}
UT_LIST_VALIDATE(LRU, buf_page_t, buf_pool->LRU);
UT_LIST_VALIDATE(LRU, buf_page_t, buf_pool->LRU,
ut_ad(ut_list_node_313->in_LRU_list));
bpage = UT_LIST_GET_FIRST(buf_pool->LRU);
@ -2119,7 +2103,8 @@ buf_LRU_validate(void)
mutex_exit(&LRU_list_mutex);
mutex_enter(&free_list_mutex);
UT_LIST_VALIDATE(free, buf_page_t, buf_pool->free);
UT_LIST_VALIDATE(free, buf_page_t, buf_pool->free,
ut_ad(ut_list_node_313->in_free_list));
for (bpage = UT_LIST_GET_FIRST(buf_pool->free);
bpage != NULL;
@ -2131,7 +2116,9 @@ buf_LRU_validate(void)
mutex_exit(&free_list_mutex);
mutex_enter(&LRU_list_mutex);
UT_LIST_VALIDATE(unzip_LRU, buf_block_t, buf_pool->unzip_LRU);
UT_LIST_VALIDATE(unzip_LRU, buf_block_t, buf_pool->unzip_LRU,
ut_ad(ut_list_node_313->in_unzip_LRU_list
&& ut_list_node_313->page.in_LRU_list));
for (block = UT_LIST_GET_FIRST(buf_pool->unzip_LRU);
block;
@ -2149,7 +2136,7 @@ buf_LRU_validate(void)
#endif /* UNIV_DEBUG || UNIV_BUF_DEBUG */
#if defined UNIV_DEBUG_PRINT || defined UNIV_DEBUG || defined UNIV_BUF_DEBUG
/**************************************************************************
/**********************************************************************//**
Prints the LRU list. */
UNIV_INTERN
void

View File

@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
/******************************************************
/**************************************************//**
@file buf/buf0rea.c
The database buffer read
Created 11/5/1995 Heikki Tuuri
@ -35,61 +36,53 @@ Created 11/5/1995 Heikki Tuuri
#include "trx0sys.h"
#include "os0file.h"
#include "srv0start.h"
#include "srv0srv.h"
extern ulint srv_read_ahead;
extern ulint srv_read_ahead_rnd;
extern ulint srv_read_ahead_seq;
extern ulint srv_buf_pool_reads;
/* The size in blocks of the area where the random read-ahead algorithm counts
/** The size in blocks of the area where the random read-ahead algorithm counts
the accessed pages when deciding whether to read-ahead */
#define BUF_READ_AHEAD_RANDOM_AREA BUF_READ_AHEAD_AREA
/* There must be at least this many pages in buf_pool in the area to start
/** 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 */
/** 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
/** 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 */
#define BUF_READ_AHEAD_PEND_LIMIT 2
/************************************************************************
/********************************************************************//**
Low-level function which reads a page asynchronously from a file to the
buffer buf_pool if it is not already there, in which case does nothing.
Sets the io_fix flag and sets an exclusive lock on the buffer frame. The
flag is cleared and the x-lock released by an i/o-handler thread. */
flag is cleared and the x-lock released by an i/o-handler thread.
@return 1 if a read request was queued, 0 if the page already resided
in buf_pool, or if the page is in the doublewrite buffer blocks in
which case it is never read into the pool, or if the tablespace does
not exist or is being dropped */
static
ulint
buf_read_page_low(
/*==============*/
/* out: 1 if a read request was queued, 0 if the page
already resided in buf_pool, or if the page is in
the doublewrite buffer blocks in which case it is never
read into the pool, or if the tablespace does not
exist or is being dropped */
ulint* err, /* out: DB_SUCCESS or DB_TABLESPACE_DELETED if we are
ulint* err, /*!< out: DB_SUCCESS or DB_TABLESPACE_DELETED if we are
trying to read from a non-existent tablespace, or a
tablespace which is just now being dropped */
ibool sync, /* in: TRUE if synchronous aio is desired */
ulint mode, /* in: BUF_READ_IBUF_PAGES_ONLY, ...,
ibool sync, /*!< in: TRUE if synchronous aio is desired */
ulint mode, /*!< in: BUF_READ_IBUF_PAGES_ONLY, ...,
ORed to OS_AIO_SIMULATED_WAKE_LATER (see below
at read-ahead functions) */
ulint space, /* in: space id */
ulint zip_size,/* in: compressed page size, or 0 */
ibool unzip, /* in: TRUE=request uncompressed page */
ib_int64_t tablespace_version, /* in: if the space memory object has
ulint space, /*!< in: space id */
ulint zip_size,/*!< in: compressed page size, or 0 */
ibool unzip, /*!< in: TRUE=request uncompressed page */
ib_int64_t tablespace_version, /*!< in: if the space memory object has
this timestamp different from what we are giving here,
treat the tablespace as dropped; this is a timestamp we
use to stop dangling page reads from a tablespace
which we have DISCARDed + IMPORTed back */
ulint offset) /* in: page number */
ulint offset) /*!< in: page number */
{
buf_page_t* bpage;
ulint wake_later;
@ -211,7 +204,7 @@ not_to_recover:
return(1);
}
/************************************************************************
/********************************************************************//**
Applies a random read-ahead in buf_pool if there are at least a threshold
value of accessed pages from the random read-ahead area. Does not read any
page, not even the one at the position (space, offset), if the read-ahead
@ -220,18 +213,17 @@ pages: to avoid deadlocks this function must be written such that it cannot
end up waiting for these latches! NOTE 2: the calling thread must want
access to the page given: this rule is set to prevent unintended read-aheads
performed by ibuf routines, a situation which could result in a deadlock if
the OS does not support asynchronous i/o. */
the OS does not support asynchronous i/o.
@return number of page read requests issued; NOTE that if we read ibuf
pages, it may happen that the page at the given page number does not
get read even if we return a positive value! */
static
ulint
buf_read_ahead_random(
/*==================*/
/* out: number of page read requests issued; NOTE
that if we read ibuf pages, it may happen that
the page at the given page number does not get
read even if we return a value > 0! */
ulint space, /* in: space id */
ulint zip_size,/* in: compressed page size in bytes, or 0 */
ulint offset) /* in: page number of a page which the current thread
ulint space, /*!< in: space id */
ulint zip_size,/*!< in: compressed page size in bytes, or 0 */
ulint offset) /*!< in: page number of a page which the current thread
wants to access */
{
ib_int64_t tablespace_version;
@ -244,6 +236,9 @@ buf_read_ahead_random(
ulint i;
ulint buf_read_ahead_random_area;
// /* We have currently disabled random readahead */
// return(0);
if (!(srv_read_ahead & 1)) {
return(0);
}
@ -378,21 +373,21 @@ read_ahead:
return(count);
}
/************************************************************************
/********************************************************************//**
High-level function which reads a page asynchronously from a file to the
buffer buf_pool if it is not already there. Sets the io_fix flag and sets
an exclusive lock on the buffer frame. The flag is cleared and the x-lock
released by the i/o-handler thread. Does a random read-ahead if it seems
sensible. */
sensible.
@return number of page read requests issued: this can be greater than
1 if read-ahead occurred */
UNIV_INTERN
ulint
buf_read_page(
/*==========*/
/* out: number of page read requests issued: this can
be > 1 if read-ahead occurred */
ulint space, /* in: space id */
ulint zip_size,/* in: compressed page size in bytes, or 0 */
ulint offset) /* in: page number */
ulint space, /*!< in: space id */
ulint zip_size,/*!< in: compressed page size in bytes, or 0 */
ulint offset) /*!< in: page number */
{
ib_int64_t tablespace_version;
ulint count;
@ -429,7 +424,7 @@ buf_read_page(
return(count + count2);
}
/************************************************************************
/********************************************************************//**
Applies linear read-ahead if in the buf_pool the page is a border page of
a linear read-ahead area and all the pages in the area have been accessed.
Does not read any page if the read-ahead mechanism is not activated. Note
@ -451,15 +446,15 @@ function must be written such that it cannot end up waiting for these
latches!
NOTE 3: the calling thread must want access to the page given: this rule is
set to prevent unintended read-aheads performed by ibuf routines, a situation
which could result in a deadlock if the OS does not support asynchronous io. */
which could result in a deadlock if the OS does not support asynchronous io.
@return number of page read requests issued */
UNIV_INTERN
ulint
buf_read_ahead_linear(
/*==================*/
/* out: number of page read requests issued */
ulint space, /* in: space id */
ulint zip_size,/* in: compressed page size in bytes, or 0 */
ulint offset) /* in: page number of a page; NOTE: the current thread
ulint space, /*!< in: space id */
ulint zip_size,/*!< in: compressed page size in bytes, or 0 */
ulint offset) /*!< in: page number of a page; NOTE: the current thread
must want access to this page (see NOTE 3 above) */
{
ib_int64_t tablespace_version;
@ -478,11 +473,12 @@ buf_read_ahead_linear(
ulint i;
const ulint buf_read_ahead_linear_area
= BUF_READ_AHEAD_LINEAR_AREA;
ulint threshold;
if (!(srv_read_ahead & 2)) {
return(0);
}
if (UNIV_UNLIKELY(srv_startup_is_before_trx_rollback_phase)) {
/* No read-ahead to avoid thread deadlocks */
return(0);
@ -545,6 +541,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;
rw_lock_s_lock(&page_hash_latch);
@ -555,28 +556,28 @@ 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 */
if (res != 0 && res != asc_or_desc) {
fail_count++;
}
}
fail_count++;
if (fail_count > threshold) {
/* Too many failures: return */
//buf_pool_mutex_exit();
rw_lock_s_unlock(&page_hash_latch);
return(0);
}
if (bpage && buf_page_is_accessed(bpage)) {
pred_bpage = bpage;
}
}
if (fail_count > buf_read_ahead_linear_area
* LINEAR_AREA_THRESHOLD_COEF) {
/* Too many failures: return */
//buf_pool_mutex_exit();
rw_lock_s_unlock(&page_hash_latch);
return(0);
}
/* If we got this far, we know that enough pages in the area have
been accessed in the right order: linear read-ahead can be sensible */
@ -708,7 +709,7 @@ buf_read_ahead_linear(
return(count);
}
/************************************************************************
/********************************************************************//**
Issues read requests for pages which the ibuf module wants to read in, in
order to contract the insert buffer tree. Technically, this function is like
a read-ahead function. */
@ -716,24 +717,24 @@ UNIV_INTERN
void
buf_read_ibuf_merge_pages(
/*======================*/
ibool sync, /* in: TRUE if the caller
ibool sync, /*!< in: TRUE if the caller
wants this function to wait
for the highest address page
to get read in, before this
function returns */
const ulint* space_ids, /* in: array of space ids */
const ib_int64_t* space_versions,/* in: the spaces must have
const ulint* space_ids, /*!< in: array of space ids */
const ib_int64_t* space_versions,/*!< in: the spaces must have
this version number
(timestamp), otherwise we
discard the read; we use this
to cancel reads if DISCARD +
IMPORT may have changed the
tablespace size */
const ulint* page_nos, /* in: array of page numbers
const ulint* page_nos, /*!< in: array of page numbers
to read, with the highest page
number the last in the
array */
ulint n_stored) /* in: number of elements
ulint n_stored) /*!< in: number of elements
in the arrays */
{
ulint i;
@ -786,25 +787,25 @@ tablespace_deleted:
#endif /* UNIV_DEBUG */
}
/************************************************************************
/********************************************************************//**
Issues read requests for pages which recovery wants to read in. */
UNIV_INTERN
void
buf_read_recv_pages(
/*================*/
ibool sync, /* in: TRUE if the caller
ibool sync, /*!< in: TRUE if the caller
wants this function to wait
for the highest address page
to get read in, before this
function returns */
ulint space, /* in: space id */
ulint zip_size, /* in: compressed page size in
ulint space, /*!< in: space id */
ulint zip_size, /*!< in: compressed page size in
bytes, or 0 */
const ulint* page_nos, /* in: array of page numbers
const ulint* page_nos, /*!< in: array of page numbers
to read, with the highest page
number the last in the
array */
ulint n_stored) /* in: number of page numbers
ulint n_stored) /*!< in: number of page numbers
in the array */
{
ib_int64_t tablespace_version;
@ -813,6 +814,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++) {

View File

@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
/************************************************************************
/********************************************************************//**
@file data/data0data.c
SQL data field and tuple
Created 5/30/1994 Heikki Tuuri
@ -28,6 +29,7 @@ Created 5/30/1994 Heikki Tuuri
#include "data0data.ic"
#endif
#ifndef UNIV_HOTBACKUP
#include "rem0rec.h"
#include "rem0cmp.h"
#include "page0page.h"
@ -36,28 +38,31 @@ Created 5/30/1994 Heikki Tuuri
#include "btr0cur.h"
#include <ctype.h>
#endif /* !UNIV_HOTBACKUP */
#ifdef UNIV_DEBUG
/* data pointers of tuple fields are initialized to point here
for error checking */
/** Dummy variable to catch access to uninitialized fields. In the
debug version, dtuple_create() will make all fields of dtuple_t point
to data_error. */
UNIV_INTERN byte data_error;
# ifndef UNIV_DEBUG_VALGRIND
/* this is used to fool the compiler in dtuple_validate */
/** this is used to fool the compiler in dtuple_validate */
UNIV_INTERN ulint data_dummy;
# endif /* !UNIV_DEBUG_VALGRIND */
#endif /* UNIV_DEBUG */
/*************************************************************************
Tests if dfield data length and content is equal to the given. */
#ifndef UNIV_HOTBACKUP
/*********************************************************************//**
Tests if dfield data length and content is equal to the given.
@return TRUE if equal */
UNIV_INTERN
ibool
dfield_data_is_binary_equal(
/*========================*/
/* out: TRUE if equal */
const dfield_t* field, /* in: field */
ulint len, /* in: data length or UNIV_SQL_NULL */
const byte* data) /* in: data */
const dfield_t* field, /*!< in: field */
ulint len, /*!< in: data length or UNIV_SQL_NULL */
const byte* data) /*!< in: data */
{
if (len != dfield_get_len(field)) {
@ -77,16 +82,16 @@ dfield_data_is_binary_equal(
return(TRUE);
}
/****************************************************************
Compare two data tuples, respecting the collation of character fields. */
/************************************************************//**
Compare two data tuples, respecting the collation of character fields.
@return 1, 0 , -1 if tuple1 is greater, equal, less, respectively,
than tuple2 */
UNIV_INTERN
int
dtuple_coll_cmp(
/*============*/
/* out: 1, 0 , -1 if tuple1 is greater, equal,
less, respectively, than tuple2 */
const dtuple_t* tuple1, /* in: tuple 1 */
const dtuple_t* tuple2) /* in: tuple 2 */
const dtuple_t* tuple1, /*!< in: tuple 1 */
const dtuple_t* tuple2) /*!< in: tuple 2 */
{
ulint n_fields;
ulint i;
@ -119,15 +124,15 @@ dtuple_coll_cmp(
return(0);
}
/*************************************************************************
/*********************************************************************//**
Sets number of fields used in a tuple. Normally this is set in
dtuple_create, but if you want later to set it smaller, you can use this. */
UNIV_INTERN
void
dtuple_set_n_fields(
/*================*/
dtuple_t* tuple, /* in: tuple */
ulint n_fields) /* in: number of fields */
dtuple_t* tuple, /*!< in: tuple */
ulint n_fields) /*!< in: number of fields */
{
ut_ad(tuple);
@ -135,14 +140,14 @@ dtuple_set_n_fields(
tuple->n_fields_cmp = n_fields;
}
/**************************************************************
Checks that a data field is typed. */
/**********************************************************//**
Checks that a data field is typed.
@return TRUE if ok */
static
ibool
dfield_check_typed_no_assert(
/*=========================*/
/* out: TRUE if ok */
const dfield_t* field) /* in: data field */
const dfield_t* field) /*!< in: data field */
{
if (dfield_get_type(field)->mtype > DATA_MYSQL
|| dfield_get_type(field)->mtype < DATA_VARCHAR) {
@ -157,14 +162,14 @@ dfield_check_typed_no_assert(
return(TRUE);
}
/**************************************************************
Checks that a data tuple is typed. */
/**********************************************************//**
Checks that a data tuple is typed.
@return TRUE if ok */
UNIV_INTERN
ibool
dtuple_check_typed_no_assert(
/*=========================*/
/* out: TRUE if ok */
const dtuple_t* tuple) /* in: tuple */
const dtuple_t* tuple) /*!< in: tuple */
{
const dfield_t* field;
ulint i;
@ -192,15 +197,17 @@ dump:
return(TRUE);
}
#endif /* !UNIV_HOTBACKUP */
/**************************************************************
Checks that a data field is typed. Asserts an error if not. */
#ifdef UNIV_DEBUG
/**********************************************************//**
Checks that a data field is typed. Asserts an error if not.
@return TRUE if ok */
UNIV_INTERN
ibool
dfield_check_typed(
/*===============*/
/* out: TRUE if ok */
const dfield_t* field) /* in: data field */
const dfield_t* field) /*!< in: data field */
{
if (dfield_get_type(field)->mtype > DATA_MYSQL
|| dfield_get_type(field)->mtype < DATA_VARCHAR) {
@ -216,14 +223,14 @@ dfield_check_typed(
return(TRUE);
}
/**************************************************************
Checks that a data tuple is typed. Asserts an error if not. */
/**********************************************************//**
Checks that a data tuple is typed. Asserts an error if not.
@return TRUE if ok */
UNIV_INTERN
ibool
dtuple_check_typed(
/*===============*/
/* out: TRUE if ok */
const dtuple_t* tuple) /* in: tuple */
const dtuple_t* tuple) /*!< in: tuple */
{
const dfield_t* field;
ulint i;
@ -238,16 +245,15 @@ dtuple_check_typed(
return(TRUE);
}
#ifdef UNIV_DEBUG
/**************************************************************
/**********************************************************//**
Validates the consistency of a tuple which must be complete, i.e,
all fields must have been set. */
all fields must have been set.
@return TRUE if ok */
UNIV_INTERN
ibool
dtuple_validate(
/*============*/
/* out: TRUE if ok */
const dtuple_t* tuple) /* in: tuple */
const dtuple_t* tuple) /*!< in: tuple */
{
const dfield_t* field;
ulint n_fields;
@ -291,13 +297,14 @@ dtuple_validate(
}
#endif /* UNIV_DEBUG */
/*****************************************************************
#ifndef UNIV_HOTBACKUP
/*************************************************************//**
Pretty prints a dfield value according to its data type. */
UNIV_INTERN
void
dfield_print(
/*=========*/
const dfield_t* dfield) /* in: dfield */
const dfield_t* dfield) /*!< in: dfield */
{
const byte* data;
ulint len;
@ -333,14 +340,14 @@ dfield_print(
}
}
/*****************************************************************
/*************************************************************//**
Pretty prints a dfield value according to its data type. Also the hex string
is printed if a string contains non-printable characters. */
UNIV_INTERN
void
dfield_print_also_hex(
/*==================*/
const dfield_t* dfield) /* in: dfield */
const dfield_t* dfield) /*!< in: dfield */
{
const byte* data;
ulint len;
@ -505,14 +512,14 @@ print_hex:
}
}
/*****************************************************************
/*************************************************************//**
Print a dfield value using ut_print_buf. */
static
void
dfield_print_raw(
/*=============*/
FILE* f, /* in: output stream */
const dfield_t* dfield) /* in: dfield */
FILE* f, /*!< in: output stream */
const dfield_t* dfield) /*!< in: dfield */
{
ulint len = dfield_get_len(dfield);
if (!dfield_is_null(dfield)) {
@ -528,14 +535,14 @@ dfield_print_raw(
}
}
/**************************************************************
/**********************************************************//**
The following function prints the contents of a tuple. */
UNIV_INTERN
void
dtuple_print(
/*=========*/
FILE* f, /* in: output stream */
const dtuple_t* tuple) /* in: tuple */
FILE* f, /*!< in: output stream */
const dtuple_t* tuple) /*!< in: tuple */
{
ulint n_fields;
ulint i;
@ -556,23 +563,21 @@ dtuple_print(
ut_ad(dtuple_validate(tuple));
}
/******************************************************************
/**************************************************************//**
Moves parts of long fields in entry to the big record vector so that
the size of tuple drops below the maximum record size allowed in the
database. Moves data only from those fields which are not necessary
to determine uniquely the insertion place of the tuple in the index. */
to determine uniquely the insertion place of the tuple in the index.
@return own: created big record vector, NULL if we are not able to
shorten the entry enough, i.e., if there are too many fixed-length or
short fields in entry or the index is clustered */
UNIV_INTERN
big_rec_t*
dtuple_convert_big_rec(
/*===================*/
/* out, own: created big record vector,
NULL if we are not able to shorten
the entry enough, i.e., if there are
too many fixed-length or short fields
in entry or the index is clustered */
dict_index_t* index, /* in: index */
dtuple_t* entry, /* in/out: index entry */
ulint* n_ext) /* in/out: number of
dict_index_t* index, /*!< in: index */
dtuple_t* entry, /*!< in/out: index entry */
ulint* n_ext) /*!< in/out: number of
externally stored columns */
{
mem_heap_t* heap;
@ -719,7 +724,7 @@ skip_field:
return(vector);
}
/******************************************************************
/**************************************************************//**
Puts back to entry the data stored in vector. Note that to ensure the
fields in entry can accommodate the data, vector must have been created
from entry with dtuple_convert_big_rec. */
@ -727,9 +732,9 @@ UNIV_INTERN
void
dtuple_convert_back_big_rec(
/*========================*/
dict_index_t* index __attribute__((unused)), /* in: index */
dtuple_t* entry, /* in: entry whose data was put to vector */
big_rec_t* vector) /* in, own: big rec vector; it is
dict_index_t* index __attribute__((unused)), /*!< in: index */
dtuple_t* entry, /*!< in: entry whose data was put to vector */
big_rec_t* vector) /*!< in, own: big rec vector; it is
freed in this function */
{
big_rec_field_t* b = vector->fields;
@ -756,3 +761,4 @@ dtuple_convert_back_big_rec(
mem_heap_free(vector->heap);
}
#endif /* !UNIV_HOTBACKUP */

View File

@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
/******************************************************
/**************************************************//**
@file data/data0type.c
Data types
Created 1/16/1996 Heikki Tuuri
@ -28,26 +29,8 @@ Created 1/16/1996 Heikki Tuuri
#include "data0type.ic"
#endif
/**********************************************************************
This function is used to find the storage length in bytes of the first n
characters for prefix indexes using a multibyte character set. The function
finds charset information and returns length of prefix_len characters in the
index field in bytes.
NOTE: the prototype of this function is copied from ha_innodb.cc! If you change
this function, you MUST change also the prototype here! */
UNIV_INTERN
ulint
innobase_get_at_most_n_mbchars(
/*===========================*/
/* out: number of bytes occupied by the first
n characters */
ulint charset_id, /* in: character set id */
ulint prefix_len, /* in: prefix length in bytes of the index
(this has to be divided by mbmaxlen to get the
number of CHARACTERS n in the prefix) */
ulint data_len, /* in: length of the string in bytes */
const char* str); /* in: character string */
#ifndef UNIV_HOTBACKUP
# include "ha_prototypes.h"
/* At the database startup we store the default-charset collation number of
this MySQL installation to this global variable. If we have < 4.1.2 format
@ -56,29 +39,27 @@ charset-collation code for them. */
UNIV_INTERN ulint data_mysql_default_charset_coll;
/*************************************************************************
/*********************************************************************//**
Determine how many bytes the first n characters of the given string occupy.
If the string is shorter than n characters, returns the number of bytes
the characters in the string occupy. */
the characters in the string occupy.
@return length of the prefix, in bytes */
UNIV_INTERN
ulint
dtype_get_at_most_n_mbchars(
/*========================*/
/* out: length of the prefix,
in bytes */
ulint prtype, /* in: precise type */
ulint mbminlen, /* in: minimum length of a
ulint prtype, /*!< in: precise type */
ulint mbminlen, /*!< in: minimum length of a
multi-byte character */
ulint mbmaxlen, /* in: maximum length of a
ulint mbmaxlen, /*!< in: maximum length of a
multi-byte character */
ulint prefix_len, /* in: length of the requested
ulint prefix_len, /*!< in: length of the requested
prefix, in characters, multiplied by
dtype_get_mbmaxlen(dtype) */
ulint data_len, /* in: length of str (in bytes) */
const char* str) /* in: the string whose prefix
ulint data_len, /*!< in: length of str (in bytes) */
const char* str) /*!< in: the string whose prefix
length is being determined */
{
#ifndef UNIV_HOTBACKUP
ut_a(data_len != UNIV_SQL_NULL);
ut_ad(!mbmaxlen || !(prefix_len % mbmaxlen));
@ -96,23 +77,18 @@ dtype_get_at_most_n_mbchars(
}
return(data_len);
#else /* UNIV_HOTBACKUP */
/* This function depends on MySQL code that is not included in
InnoDB Hot Backup builds. Besides, this function should never
be called in InnoDB Hot Backup. */
ut_error;
#endif /* UNIV_HOTBACKUP */
}
#endif /* UNIV_HOTBACKUP */
/*************************************************************************
/*********************************************************************//**
Checks if a data main type is a string type. Also a BLOB is considered a
string type. */
string type.
@return TRUE if string type */
UNIV_INTERN
ibool
dtype_is_string_type(
/*=================*/
/* out: TRUE if string type */
ulint mtype) /* in: InnoDB main data type code: DATA_CHAR, ... */
ulint mtype) /*!< in: InnoDB main data type code: DATA_CHAR, ... */
{
if (mtype <= DATA_BLOB
|| mtype == DATA_MYSQL
@ -124,17 +100,17 @@ dtype_is_string_type(
return(FALSE);
}
/*************************************************************************
/*********************************************************************//**
Checks if a type is a binary string type. Note that for tables created with
< 4.0.14, we do not know if a DATA_BLOB column is a BLOB or a TEXT column. For
those DATA_BLOB columns this function currently returns FALSE. */
those DATA_BLOB columns this function currently returns FALSE.
@return TRUE if binary string type */
UNIV_INTERN
ibool
dtype_is_binary_string_type(
/*========================*/
/* out: TRUE if binary string type */
ulint mtype, /* in: main data type */
ulint prtype) /* in: precise type */
ulint mtype, /*!< in: main data type */
ulint prtype) /*!< in: precise type */
{
if ((mtype == DATA_FIXBINARY)
|| (mtype == DATA_BINARY)
@ -146,18 +122,18 @@ dtype_is_binary_string_type(
return(FALSE);
}
/*************************************************************************
/*********************************************************************//**
Checks if a type is a non-binary string type. That is, dtype_is_string_type is
TRUE and dtype_is_binary_string_type is FALSE. Note that for tables created
with < 4.0.14, we do not know if a DATA_BLOB column is a BLOB or a TEXT column.
For those DATA_BLOB columns this function currently returns TRUE. */
For those DATA_BLOB columns this function currently returns TRUE.
@return TRUE if non-binary string type */
UNIV_INTERN
ibool
dtype_is_non_binary_string_type(
/*============================*/
/* out: TRUE if non-binary string type */
ulint mtype, /* in: main data type */
ulint prtype) /* in: precise type */
ulint mtype, /*!< in: main data type */
ulint prtype) /*!< in: precise type */
{
if (dtype_is_string_type(mtype) == TRUE
&& dtype_is_binary_string_type(mtype, prtype) == FALSE) {
@ -168,16 +144,17 @@ dtype_is_non_binary_string_type(
return(FALSE);
}
/*************************************************************************
/*********************************************************************//**
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(
/*==============*/
ulint old_prtype, /* in: the MySQL type code and the flags
ulint old_prtype, /*!< in: the MySQL type code and the flags
DATA_BINARY_TYPE etc. */
ulint charset_coll) /* in: MySQL charset-collation code */
ulint charset_coll) /*!< in: MySQL charset-collation code */
{
ut_a(old_prtype < 256 * 256);
ut_a(charset_coll < 256);
@ -185,14 +162,14 @@ dtype_form_prtype(
return(old_prtype + (charset_coll << 16));
}
/*************************************************************************
Validates a data type structure. */
/*********************************************************************//**
Validates a data type structure.
@return TRUE if ok */
UNIV_INTERN
ibool
dtype_validate(
/*===========*/
/* out: TRUE if ok */
const dtype_t* type) /* in: type struct to validate */
const dtype_t* type) /*!< in: type struct to validate */
{
ut_a(type);
ut_a(type->mtype >= DATA_VARCHAR);
@ -202,18 +179,21 @@ dtype_validate(
ut_a((type->prtype & DATA_MYSQL_TYPE_MASK) < DATA_N_SYS_COLS);
}
#ifndef UNIV_HOTBACKUP
ut_a(type->mbminlen <= type->mbmaxlen);
#endif /* !UNIV_HOTBACKUP */
return(TRUE);
}
/*************************************************************************
#ifndef UNIV_HOTBACKUP
/*********************************************************************//**
Prints a data type structure. */
UNIV_INTERN
void
dtype_print(
/*========*/
const dtype_t* type) /* in: type */
const dtype_t* type) /*!< in: type */
{
ulint mtype;
ulint prtype;
@ -298,3 +278,4 @@ dtype_print(
fprintf(stderr, " len %lu", (ulong) len);
}
#endif /* !UNIV_HOTBACKUP */

View File

@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
/******************************************************
/**************************************************//**
@file dict/dict0boot.c
Data dictionary creation and booting
Created 4/18/1996 Heikki Tuuri
@ -39,15 +40,14 @@ Created 4/18/1996 Heikki Tuuri
#include "log0recv.h"
#include "os0file.h"
/**************************************************************************
Gets a pointer to the dictionary header and x-latches its page. */
/**********************************************************************//**
Gets a pointer to the dictionary header and x-latches its page.
@return pointer to the dictionary header, page x-latched */
UNIV_INTERN
dict_hdr_t*
dict_hdr_get(
/*=========*/
/* out: pointer to the dictionary header,
page x-latched */
mtr_t* mtr) /* in: mtr */
mtr_t* mtr) /*!< in: mtr */
{
buf_block_t* block;
dict_hdr_t* header;
@ -61,14 +61,14 @@ dict_hdr_get(
return(header);
}
/**************************************************************************
Returns a new table, index, or tree id. */
/**********************************************************************//**
Returns a new table, index, or tree id.
@return the new id */
UNIV_INTERN
dulint
dict_hdr_get_new_id(
/*================*/
/* out: the new id */
ulint type) /* in: DICT_HDR_ROW_ID, ... */
ulint type) /*!< in: DICT_HDR_ROW_ID, ... */
{
dict_hdr_t* dict_hdr;
dulint id;
@ -90,7 +90,7 @@ dict_hdr_get_new_id(
return(id);
}
/**************************************************************************
/**********************************************************************//**
Writes the current value of the row id counter to the dictionary header file
page. */
UNIV_INTERN
@ -115,15 +115,15 @@ dict_hdr_flush_row_id(void)
mtr_commit(&mtr);
}
/*********************************************************************
/*****************************************************************//**
Creates the file page for the dictionary header. This function is
called only at the database creation. */
called only at the database creation.
@return TRUE if succeed */
static
ibool
dict_hdr_create(
/*============*/
/* out: TRUE if succeed */
mtr_t* mtr) /* in: mtr */
mtr_t* mtr) /*!< in: mtr */
{
buf_block_t* block;
dict_hdr_t* dict_header;
@ -161,7 +161,7 @@ dict_hdr_create(
/*--------------------------*/
root_page_no = btr_create(DICT_CLUSTERED | DICT_UNIQUE,
DICT_HDR_SPACE, 0, DICT_TABLES_ID,
srv_sys->dummy_ind1, mtr);
dict_ind_redundant, mtr);
if (root_page_no == FIL_NULL) {
return(FALSE);
@ -172,7 +172,7 @@ dict_hdr_create(
/*--------------------------*/
root_page_no = btr_create(DICT_UNIQUE, DICT_HDR_SPACE, 0,
DICT_TABLE_IDS_ID,
srv_sys->dummy_ind1, mtr);
dict_ind_redundant, mtr);
if (root_page_no == FIL_NULL) {
return(FALSE);
@ -183,7 +183,7 @@ dict_hdr_create(
/*--------------------------*/
root_page_no = btr_create(DICT_CLUSTERED | DICT_UNIQUE,
DICT_HDR_SPACE, 0, DICT_COLUMNS_ID,
srv_sys->dummy_ind1, mtr);
dict_ind_redundant, mtr);
if (root_page_no == FIL_NULL) {
return(FALSE);
@ -194,7 +194,7 @@ dict_hdr_create(
/*--------------------------*/
root_page_no = btr_create(DICT_CLUSTERED | DICT_UNIQUE,
DICT_HDR_SPACE, 0, DICT_INDEXES_ID,
srv_sys->dummy_ind1, mtr);
dict_ind_redundant, mtr);
if (root_page_no == FIL_NULL) {
return(FALSE);
@ -205,7 +205,7 @@ dict_hdr_create(
/*--------------------------*/
root_page_no = btr_create(DICT_CLUSTERED | DICT_UNIQUE,
DICT_HDR_SPACE, 0, DICT_FIELDS_ID,
srv_sys->dummy_ind1, mtr);
dict_ind_redundant, mtr);
if (root_page_no == FIL_NULL) {
return(FALSE);
@ -218,7 +218,7 @@ dict_hdr_create(
return(TRUE);
}
/*********************************************************************
/*****************************************************************//**
Initializes the data dictionary memory structures when the database is
started. This function is also called when the data dictionary is created. */
UNIV_INTERN
@ -434,7 +434,7 @@ dict_boot(void)
mutex_exit(&(dict_sys->mutex));
}
/*********************************************************************
/*****************************************************************//**
Inserts the basic system table data into themselves in the database
creation. */
static
@ -445,7 +445,7 @@ dict_insert_initial_data(void)
/* Does nothing yet */
}
/*********************************************************************
/*****************************************************************//**
Creates and initializes the data dictionary at the database creation. */
UNIV_INTERN
void

View File

@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
/******************************************************
/**************************************************//**
@file dict/dict0crea.c
Database object creation
Created 1/8/1996 Heikki Tuuri
@ -42,16 +43,16 @@ Created 1/8/1996 Heikki Tuuri
#include "usr0sess.h"
#include "ut0vec.h"
/*********************************************************************
/*****************************************************************//**
Based on a table object, this function builds the entry to be inserted
in the SYS_TABLES system table. */
in the SYS_TABLES system table.
@return the tuple which should be inserted */
static
dtuple_t*
dict_create_sys_tables_tuple(
/*=========================*/
/* out: the tuple which should be inserted */
dict_table_t* table, /* in: table */
mem_heap_t* heap) /* in: memory heap from which the memory for
dict_table_t* table, /*!< in: table */
mem_heap_t* heap) /*!< in: memory heap from which the memory for
the built tuple is allocated */
{
dict_table_t* sys_tables;
@ -134,17 +135,17 @@ dict_create_sys_tables_tuple(
return(entry);
}
/*********************************************************************
/*****************************************************************//**
Based on a table object, this function builds the entry to be inserted
in the SYS_COLUMNS system table. */
in the SYS_COLUMNS system table.
@return the tuple which should be inserted */
static
dtuple_t*
dict_create_sys_columns_tuple(
/*==========================*/
/* out: the tuple which should be inserted */
dict_table_t* table, /* in: table */
ulint i, /* in: column number */
mem_heap_t* heap) /* in: memory heap from which the memory for
dict_table_t* table, /*!< in: table */
ulint i, /*!< in: column number */
mem_heap_t* heap) /*!< in: memory heap from which the memory for
the built tuple is allocated */
{
dict_table_t* sys_columns;
@ -216,15 +217,15 @@ dict_create_sys_columns_tuple(
return(entry);
}
/*******************************************************************
Builds a table definition to insert. */
/***************************************************************//**
Builds a table definition to insert.
@return DB_SUCCESS or error code */
static
ulint
dict_build_table_def_step(
/*======================*/
/* out: DB_SUCCESS or error code */
que_thr_t* thr, /* in: query thread */
tab_node_t* node) /* in: table create node */
que_thr_t* thr, /*!< in: query thread */
tab_node_t* node) /*!< in: table create node */
{
dict_table_t* table;
dtuple_t* row;
@ -295,14 +296,14 @@ dict_build_table_def_step(
return(DB_SUCCESS);
}
/*******************************************************************
Builds a column definition to insert. */
/***************************************************************//**
Builds a column definition to insert.
@return DB_SUCCESS */
static
ulint
dict_build_col_def_step(
/*====================*/
/* out: DB_SUCCESS */
tab_node_t* node) /* in: table create node */
tab_node_t* node) /*!< in: table create node */
{
dtuple_t* row;
@ -313,16 +314,16 @@ dict_build_col_def_step(
return(DB_SUCCESS);
}
/*********************************************************************
/*****************************************************************//**
Based on an index object, this function builds the entry to be inserted
in the SYS_INDEXES system table. */
in the SYS_INDEXES system table.
@return the tuple which should be inserted */
static
dtuple_t*
dict_create_sys_indexes_tuple(
/*==========================*/
/* out: the tuple which should be inserted */
dict_index_t* index, /* in: index */
mem_heap_t* heap) /* in: memory heap from which the memory for
dict_index_t* index, /*!< in: index */
mem_heap_t* heap) /*!< in: memory heap from which the memory for
the built tuple is allocated */
{
dict_table_t* sys_indexes;
@ -403,17 +404,17 @@ dict_create_sys_indexes_tuple(
return(entry);
}
/*********************************************************************
/*****************************************************************//**
Based on an index object, this function builds the entry to be inserted
in the SYS_FIELDS system table. */
in the SYS_FIELDS system table.
@return the tuple which should be inserted */
static
dtuple_t*
dict_create_sys_fields_tuple(
/*=========================*/
/* out: the tuple which should be inserted */
dict_index_t* index, /* in: index */
ulint i, /* in: field number */
mem_heap_t* heap) /* in: memory heap from which the memory for
dict_index_t* index, /*!< in: index */
ulint i, /*!< in: field number */
mem_heap_t* heap) /*!< in: memory heap from which the memory for
the built tuple is allocated */
{
dict_table_t* sys_fields;
@ -479,17 +480,17 @@ dict_create_sys_fields_tuple(
return(entry);
}
/*********************************************************************
/*****************************************************************//**
Creates the tuple with which the index entry is searched for writing the index
tree root page number, if such a tree is created. */
tree root page number, if such a tree is created.
@return the tuple for search */
static
dtuple_t*
dict_create_search_tuple(
/*=====================*/
/* out: the tuple for search */
const dtuple_t* tuple, /* in: the tuple inserted in the SYS_INDEXES
const dtuple_t* tuple, /*!< in: the tuple inserted in the SYS_INDEXES
table */
mem_heap_t* heap) /* in: memory heap from which the memory for
mem_heap_t* heap) /*!< in: memory heap from which the memory for
the built tuple is allocated */
{
dtuple_t* search_tuple;
@ -515,15 +516,15 @@ dict_create_search_tuple(
return(search_tuple);
}
/*******************************************************************
Builds an index definition row to insert. */
/***************************************************************//**
Builds an index definition row to insert.
@return DB_SUCCESS or error code */
static
ulint
dict_build_index_def_step(
/*======================*/
/* out: DB_SUCCESS or error code */
que_thr_t* thr, /* in: query thread */
ind_node_t* node) /* in: index create node */
que_thr_t* thr, /*!< in: query thread */
ind_node_t* node) /*!< in: index create node */
{
dict_table_t* table;
dict_index_t* index;
@ -561,22 +562,20 @@ dict_build_index_def_step(
ins_node_set_new_row(node->ind_def, row);
#ifdef ROW_MERGE_IS_INDEX_USABLE
/* Note that the index was created by this transaction. */
index->trx_id = trx->id;
#endif /* ROW_MERGE_IS_INDEX_USABLE */
index->trx_id = (ib_uint64_t) ut_conv_dulint_to_longlong(trx->id);
return(DB_SUCCESS);
}
/*******************************************************************
Builds a field definition row to insert. */
/***************************************************************//**
Builds a field definition row to insert.
@return DB_SUCCESS */
static
ulint
dict_build_field_def_step(
/*======================*/
/* out: DB_SUCCESS */
ind_node_t* node) /* in: index create node */
ind_node_t* node) /*!< in: index create node */
{
dict_index_t* index;
dtuple_t* row;
@ -590,14 +589,14 @@ dict_build_field_def_step(
return(DB_SUCCESS);
}
/*******************************************************************
Creates an index tree for the index if it is not a member of a cluster. */
/***************************************************************//**
Creates an index tree for the index if it is not a member of a cluster.
@return DB_SUCCESS or DB_OUT_OF_FILE_SPACE */
static
ulint
dict_create_index_tree_step(
/*========================*/
/* out: DB_SUCCESS or DB_OUT_OF_FILE_SPACE */
ind_node_t* node) /* in: index create node */
ind_node_t* node) /*!< in: index create node */
{
dict_index_t* index;
dict_table_t* sys_indexes;
@ -647,15 +646,15 @@ dict_create_index_tree_step(
return(DB_SUCCESS);
}
/***********************************************************************
/*******************************************************************//**
Drops the index tree associated with a row in SYS_INDEXES table. */
UNIV_INTERN
void
dict_drop_index_tree(
/*=================*/
rec_t* rec, /* in/out: record in the clustered index
rec_t* rec, /*!< in/out: record in the clustered index
of SYS_INDEXES table */
mtr_t* mtr) /* in: mtr having the latch on the record page */
mtr_t* mtr) /*!< in: mtr having the latch on the record page */
{
ulint root_page_no;
ulint space;
@ -710,23 +709,22 @@ dict_drop_index_tree(
FIL_NULL, mtr);
}
/***********************************************************************
Truncates the index tree associated with a row in SYS_INDEXES table. */
/*******************************************************************//**
Truncates the index tree associated with a row in SYS_INDEXES table.
@return new root page number, or FIL_NULL on failure */
UNIV_INTERN
ulint
dict_truncate_index_tree(
/*=====================*/
/* out: new root page number, or
FIL_NULL on failure */
dict_table_t* table, /* in: the table the index belongs to */
ulint space, /* in: 0=truncate,
dict_table_t* table, /*!< in: the table the index belongs to */
ulint space, /*!< in: 0=truncate,
nonzero=create the index tree in the
given tablespace */
btr_pcur_t* pcur, /* in/out: persistent cursor pointing to
btr_pcur_t* pcur, /*!< in/out: persistent cursor pointing to
record in the clustered index of
SYS_INDEXES table. The cursor may be
repositioned in this call. */
mtr_t* mtr) /* in: mtr having the latch
mtr_t* mtr) /*!< in: mtr having the latch
on the record page. The mtr may be
committed and restarted in this call. */
{
@ -846,16 +844,16 @@ create:
return(FIL_NULL);
}
/*************************************************************************
Creates a table create graph. */
/*********************************************************************//**
Creates a table create graph.
@return own: table create node */
UNIV_INTERN
tab_node_t*
tab_create_graph_create(
/*====================*/
/* out, own: table create node */
dict_table_t* table, /* in: table to create, built as a memory data
dict_table_t* table, /*!< in: table to create, built as a memory data
structure */
mem_heap_t* heap) /* in: heap where created */
mem_heap_t* heap) /*!< in: heap where created */
{
tab_node_t* node;
@ -882,16 +880,16 @@ tab_create_graph_create(
return(node);
}
/*************************************************************************
Creates an index create graph. */
/*********************************************************************//**
Creates an index create graph.
@return own: index create node */
UNIV_INTERN
ind_node_t*
ind_create_graph_create(
/*====================*/
/* out, own: index create node */
dict_index_t* index, /* in: index to create, built as a memory data
dict_index_t* index, /*!< in: index to create, built as a memory data
structure */
mem_heap_t* heap) /* in: heap where created */
mem_heap_t* heap) /*!< in: heap where created */
{
ind_node_t* node;
@ -919,14 +917,14 @@ ind_create_graph_create(
return(node);
}
/***************************************************************
Creates a table. This is a high-level function used in SQL execution graphs. */
/***********************************************************//**
Creates a table. This is a high-level function used in SQL execution graphs.
@return query thread to run next or NULL */
UNIV_INTERN
que_thr_t*
dict_create_table_step(
/*===================*/
/* out: query thread to run next or NULL */
que_thr_t* thr) /* in: query thread */
que_thr_t* thr) /*!< in: query thread */
{
tab_node_t* node;
ulint err = DB_ERROR;
@ -1025,15 +1023,15 @@ function_exit:
return(thr);
}
/***************************************************************
/***********************************************************//**
Creates an index. This is a high-level function used in SQL execution
graphs. */
graphs.
@return query thread to run next or NULL */
UNIV_INTERN
que_thr_t*
dict_create_index_step(
/*===================*/
/* out: query thread to run next or NULL */
que_thr_t* thr) /* in: query thread */
que_thr_t* thr) /*!< in: query thread */
{
ind_node_t* node;
ulint err = DB_ERROR;
@ -1156,16 +1154,15 @@ function_exit:
return(thr);
}
#ifndef UNIV_HOTBACKUP
/********************************************************************
/****************************************************************//**
Creates the foreign key constraints system tables inside InnoDB
at database creation or database start if they are not found or are
not of the right form. */
not of the right form.
@return DB_SUCCESS or error code */
UNIV_INTERN
ulint
dict_create_or_check_foreign_constraint_tables(void)
/*================================================*/
/* out: DB_SUCCESS or error code */
{
dict_table_t* table1;
dict_table_t* table2;
@ -1286,18 +1283,18 @@ dict_create_or_check_foreign_constraint_tables(void)
return(error);
}
/********************************************************************
Evaluate the given foreign key SQL statement. */
/****************************************************************//**
Evaluate the given foreign key SQL statement.
@return error code or DB_SUCCESS */
static
ulint
dict_foreign_eval_sql(
/*==================*/
/* out: error code or DB_SUCCESS */
pars_info_t* info, /* in: info struct, or NULL */
const char* sql, /* in: SQL string to evaluate */
dict_table_t* table, /* in: table */
dict_foreign_t* foreign,/* in: foreign */
trx_t* trx) /* in: transaction */
pars_info_t* info, /*!< in: info struct, or NULL */
const char* sql, /*!< in: SQL string to evaluate */
dict_table_t* table, /*!< in: table */
dict_foreign_t* foreign,/*!< in: foreign */
trx_t* trx) /*!< in: transaction */
{
ulint error;
FILE* ef = dict_foreign_err_file;
@ -1351,18 +1348,18 @@ dict_foreign_eval_sql(
return(DB_SUCCESS);
}
/************************************************************************
/********************************************************************//**
Add a single foreign key field definition to the data dictionary tables in
the database. */
the database.
@return error code or DB_SUCCESS */
static
ulint
dict_create_add_foreign_field_to_dictionary(
/*========================================*/
/* out: error code or DB_SUCCESS */
ulint field_nr, /* in: foreign field number */
dict_table_t* table, /* in: table */
dict_foreign_t* foreign, /* in: foreign */
trx_t* trx) /* in: transaction */
ulint field_nr, /*!< in: foreign field number */
dict_table_t* table, /*!< in: table */
dict_foreign_t* foreign, /*!< in: foreign */
trx_t* trx) /*!< in: transaction */
{
pars_info_t* info = pars_info_create();
@ -1386,23 +1383,23 @@ dict_create_add_foreign_field_to_dictionary(
table, foreign, trx));
}
/************************************************************************
/********************************************************************//**
Add a single foreign key definition to the data dictionary tables in the
database. We also generate names to constraints that were not named by the
user. A generated constraint has a name of the format
databasename/tablename_ibfk_<number>, where the numbers start from 1, and
are given locally for this table, that is, the number is not global, as in
the old format constraints < 4.0.18 it used to be. */
the old format constraints < 4.0.18 it used to be.
@return error code or DB_SUCCESS */
static
ulint
dict_create_add_foreign_to_dictionary(
/*==================================*/
/* out: error code or DB_SUCCESS */
ulint* id_nr, /* in/out: number to use in id generation;
ulint* id_nr, /*!< in/out: number to use in id generation;
incremented if used */
dict_table_t* table, /* in: table */
dict_foreign_t* foreign,/* in: foreign */
trx_t* trx) /* in: transaction */
dict_table_t* table, /*!< in: table */
dict_foreign_t* foreign,/*!< in: foreign */
trx_t* trx) /*!< in: transaction */
{
ulint error;
ulint i;
@ -1461,14 +1458,14 @@ dict_create_add_foreign_to_dictionary(
return(error);
}
/************************************************************************
Adds foreign key definitions to data dictionary tables in the database. */
/********************************************************************//**
Adds foreign key definitions to data dictionary tables in the database.
@return error code or DB_SUCCESS */
UNIV_INTERN
ulint
dict_create_add_foreigns_to_dictionary(
/*===================================*/
/* out: error code or DB_SUCCESS */
ulint start_id,/* in: if we are actually doing ALTER TABLE
ulint start_id,/*!< in: if we are actually doing ALTER TABLE
ADD CONSTRAINT, we want to generate constraint
numbers which are bigger than in the table so
far; we number the constraints from
@ -1476,8 +1473,8 @@ dict_create_add_foreigns_to_dictionary(
we are creating a new table, or if the table
so far has no constraints for which the name
was generated here */
dict_table_t* table, /* in: table */
trx_t* trx) /* in: transaction */
dict_table_t* table, /*!< in: table */
trx_t* trx) /*!< in: transaction */
{
dict_foreign_t* foreign;
ulint number = start_id + 1;
@ -1508,4 +1505,3 @@ dict_create_add_foreigns_to_dictionary(
return(DB_SUCCESS);
}
#endif /* !UNIV_HOTBACKUP */

File diff suppressed because it is too large Load Diff

View File

@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
/******************************************************
/**************************************************//**
@file dict/dict0load.c
Loads to the memory cache database object definitions
from dictionary tables
@ -24,9 +25,7 @@ Created 4/24/1996 Heikki Tuuri
*******************************************************/
#include "dict0load.h"
#ifndef UNIV_HOTBACKUP
#include "mysql_version.h"
#endif /* !UNIV_HOTBACKUP */
#ifdef UNIV_NONINL
#include "dict0load.ic"
@ -42,17 +41,17 @@ Created 4/24/1996 Heikki Tuuri
#include "srv0start.h"
#include "srv0srv.h"
/********************************************************************
Returns TRUE if index's i'th column's name is 'name' .*/
/****************************************************************//**
Compare the name of an index column.
@return TRUE if the i'th column of index is 'name'. */
static
ibool
name_of_col_is(
/*===========*/
/* out: */
dict_table_t* table, /* in: table */
dict_index_t* index, /* in: index */
ulint i, /* in: */
const char* name) /* in: name to compare to */
const dict_table_t* table, /*!< in: table */
const dict_index_t* index, /*!< in: index */
ulint i, /*!< in: index field offset */
const char* name) /*!< in: name to compare to */
{
ulint tmp = dict_col_get_no(dict_field_get_col(
dict_index_get_nth_field(
@ -61,16 +60,15 @@ name_of_col_is(
return(strcmp(name, dict_table_get_col_name(table, tmp)) == 0);
}
/************************************************************************
Finds the first table name in the given database. */
/********************************************************************//**
Finds the first table name in the given database.
@return own: table name, NULL if does not exist; the caller must free
the memory in the string! */
UNIV_INTERN
char*
dict_get_first_table_name_in_db(
/*============================*/
/* out, own: table name, NULL if
does not exist; the caller must
free the memory in the string! */
const char* name) /* in: database name which ends in '/' */
const char* name) /*!< in: database name which ends in '/' */
{
dict_table_t* sys_tables;
btr_pcur_t pcur;
@ -145,7 +143,7 @@ loop:
goto loop;
}
/************************************************************************
/********************************************************************//**
Prints to the standard output information on all tables found in the data
dictionary system table. */
UNIV_INTERN
@ -238,16 +236,15 @@ loop:
goto loop;
}
/************************************************************************
Determine the flags of a table described in SYS_TABLES. */
/********************************************************************//**
Determine the flags of a table described in SYS_TABLES.
@return compressed page size in kilobytes; or 0 if the tablespace is
uncompressed, ULINT_UNDEFINED on error */
static
ulint
dict_sys_tables_get_flags(
/*======================*/
/* out: compressed page size in kilobytes;
or 0 if the tablespace is uncompressed,
ULINT_UNDEFINED on error */
const rec_t* rec) /* in: a record of SYS_TABLES */
const rec_t* rec) /*!< in: a record of SYS_TABLES */
{
const byte* field;
ulint len;
@ -301,7 +298,7 @@ dict_sys_tables_get_flags(
return(flags);
}
/************************************************************************
/********************************************************************//**
In a crash recovery we already have all the tablespace objects created.
This function compares the space id information in the InnoDB data dictionary
to what we already read with fil_load_single_table_tablespaces().
@ -313,7 +310,7 @@ UNIV_INTERN
void
dict_check_tablespaces_and_store_max_id(
/*====================================*/
ibool in_crash_recovery) /* in: are we doing a crash recovery */
ibool in_crash_recovery) /*!< in: are we doing a crash recovery */
{
dict_table_t* sys_tables;
dict_index_t* sys_index;
@ -423,14 +420,14 @@ loop:
goto loop;
}
/************************************************************************
/********************************************************************//**
Loads definitions for table columns. */
static
void
dict_load_columns(
/*==============*/
dict_table_t* table, /* in: table */
mem_heap_t* heap) /* in: memory heap for temporary storage */
dict_table_t* table, /*!< in: table */
mem_heap_t* heap) /*!< in: memory heap for temporary storage */
{
dict_table_t* sys_columns;
dict_index_t* sys_index;
@ -529,14 +526,14 @@ dict_load_columns(
mtr_commit(&mtr);
}
/************************************************************************
/********************************************************************//**
Loads definitions for index fields. */
static
void
dict_load_fields(
/*=============*/
dict_index_t* index, /* in: index whose fields to load */
mem_heap_t* heap) /* in: memory heap for temporary storage */
dict_index_t* index, /*!< in: index whose fields to load */
mem_heap_t* heap) /*!< in: memory heap for temporary storage */
{
dict_table_t* sys_fields;
dict_index_t* sys_index;
@ -630,19 +627,17 @@ next_rec:
mtr_commit(&mtr);
}
/************************************************************************
/********************************************************************//**
Loads definitions for table indexes. Adds them to the data dictionary
cache. */
cache.
@return DB_SUCCESS if ok, DB_CORRUPTION if corruption of dictionary
table or DB_UNSUPPORTED if table has unknown index type */
static
ulint
dict_load_indexes(
/*==============*/
/* out: DB_SUCCESS if ok, DB_CORRUPTION
if corruption of dictionary table or
DB_UNSUPPORTED if table has unknown index
type */
dict_table_t* table, /* in: table */
mem_heap_t* heap) /* in: memory heap for temporary storage */
dict_table_t* table, /*!< in: table */
mem_heap_t* heap) /*!< in: memory heap for temporary storage */
{
dict_table_t* sys_indexes;
dict_index_t* sys_index;
@ -805,22 +800,20 @@ func_exit:
return(error);
}
/************************************************************************
/********************************************************************//**
Loads a table definition and also all its index definitions, and also
the cluster definition if the table is a member in a cluster. Also loads
all foreign key constraints where the foreign key is in the table or where
a foreign key references columns in this table. Adds all these to the data
dictionary cache. */
dictionary cache.
@return table, NULL if does not exist; if the table is stored in an
.ibd file, but the file does not exist, then we set the
ibd_file_missing flag TRUE in the table object we return */
UNIV_INTERN
dict_table_t*
dict_load_table(
/*============*/
/* out: table, NULL if does not exist;
if the table is stored in an .ibd file,
but the file does not exist,
then we set the ibd_file_missing flag TRUE
in the table object we return */
const char* name) /* in: table name in the
const char* name) /*!< in: table name in the
databasename/tablename format */
{
ibool ibd_file_missing = FALSE;
@ -960,7 +953,7 @@ err_exit:
mem_heap_empty(heap);
err = dict_load_indexes(table, heap);
#ifndef UNIV_HOTBACKUP
/* If the force recovery flag is set, we open the table irrespective
of the error condition, since the user may want to dump data from the
clustered index. However we load the foreign key information only if
@ -971,7 +964,7 @@ err_exit:
dict_table_remove_from_cache(table);
table = NULL;
}
# if 0
#if 0
if (err != DB_SUCCESS && table != NULL) {
mutex_enter(&dict_foreign_err_mutex);
@ -994,21 +987,20 @@ err_exit:
mutex_exit(&dict_foreign_err_mutex);
}
# endif /* 0 */
#endif /* !UNIV_HOTBACKUP */
#endif /* 0 */
mem_heap_free(heap);
return(table);
}
/***************************************************************************
Loads a table object based on the table id. */
/***********************************************************************//**
Loads a table object based on the table id.
@return table; NULL if table does not exist */
UNIV_INTERN
dict_table_t*
dict_load_table_on_id(
/*==================*/
/* out: table; NULL if table does not exist */
dulint table_id) /* in: table id */
dulint table_id) /*!< in: table id */
{
byte id_buf[8];
btr_pcur_t pcur;
@ -1092,7 +1084,7 @@ dict_load_table_on_id(
return(table);
}
/************************************************************************
/********************************************************************//**
This function is called when the database is booted. Loads system table
index definitions except for the clustered index which is added to the
dictionary cache at booting before calling this function. */
@ -1100,7 +1092,7 @@ UNIV_INTERN
void
dict_load_sys_table(
/*================*/
dict_table_t* table) /* in: system table */
dict_table_t* table) /*!< in: system table */
{
mem_heap_t* heap;
@ -1113,16 +1105,15 @@ dict_load_sys_table(
mem_heap_free(heap);
}
#ifndef UNIV_HOTBACKUP
/************************************************************************
/********************************************************************//**
Loads foreign key constraint col names (also for the referenced table). */
static
void
dict_load_foreign_cols(
/*===================*/
const char* id, /* in: foreign constraint id as a
const char* id, /*!< in: foreign constraint id as a
null-terminated string */
dict_foreign_t* foreign)/* in: foreign constraint object */
dict_foreign_t* foreign)/*!< in: foreign constraint object */
{
dict_table_t* sys_foreign_cols;
dict_index_t* sys_index;
@ -1186,17 +1177,17 @@ dict_load_foreign_cols(
mtr_commit(&mtr);
}
/***************************************************************************
Loads a foreign key constraint to the dictionary cache. */
/***********************************************************************//**
Loads a foreign key constraint to the dictionary cache.
@return DB_SUCCESS or error code */
static
ulint
dict_load_foreign(
/*==============*/
/* out: DB_SUCCESS or error code */
const char* id, /* in: foreign constraint id as a
const char* id, /*!< in: foreign constraint id as a
null-terminated string */
ibool check_charsets)
/* in: TRUE=check charset compatibility */
/*!< in: TRUE=check charset compatibility */
{
dict_foreign_t* foreign;
dict_table_t* sys_foreign;
@ -1311,19 +1302,19 @@ dict_load_foreign(
return(dict_foreign_add_to_cache(foreign, check_charsets));
}
/***************************************************************************
/***********************************************************************//**
Loads foreign key constraints where the table is either the foreign key
holder or where the table is referenced by a foreign key. Adds these
constraints to the data dictionary. Note that we know that the dictionary
cache already contains all constraints where the other relevant table is
already in the dictionary cache. */
already in the dictionary cache.
@return DB_SUCCESS or error code */
UNIV_INTERN
ulint
dict_load_foreigns(
/*===============*/
/* out: DB_SUCCESS or error code */
const char* table_name, /* in: table name */
ibool check_charsets) /* in: TRUE=check charset
const char* table_name, /*!< in: table name */
ibool check_charsets) /*!< in: TRUE=check charset
compatibility */
{
btr_pcur_t pcur;
@ -1457,4 +1448,3 @@ load_next_index:
return(DB_SUCCESS);
}
#endif /* !UNIV_HOTBACKUP */

View File

@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
/**********************************************************************
/******************************************************************//**
@file dict/dict0mem.c
Data dictionary memory object creation
Created 1/8/1996 Heikki Tuuri
@ -32,25 +33,27 @@ Created 1/8/1996 Heikki Tuuri
#include "data0type.h"
#include "mach0data.h"
#include "dict0dict.h"
#include "lock0lock.h"
#ifndef UNIV_HOTBACKUP
# include "lock0lock.h"
#endif /* !UNIV_HOTBACKUP */
#define DICT_HEAP_SIZE 100 /* initial memory heap size when
#define DICT_HEAP_SIZE 100 /*!< initial memory heap size when
creating a table or index object */
/**************************************************************************
Creates a table memory object. */
/**********************************************************************//**
Creates a table memory object.
@return own: table object */
UNIV_INTERN
dict_table_t*
dict_mem_table_create(
/*==================*/
/* out, own: table object */
const char* name, /* in: table name */
ulint space, /* in: space where the clustered index of
const char* name, /*!< in: table name */
ulint space, /*!< in: space where the clustered index of
the table is placed; this parameter is
ignored if the table is made a member of
a cluster */
ulint n_cols, /* in: number of columns */
ulint flags) /* in: table flags */
ulint n_cols, /*!< in: number of columns */
ulint flags) /*!< in: table flags */
{
dict_table_t* table;
mem_heap_t* heap;
@ -72,6 +75,7 @@ dict_mem_table_create(
table->cols = mem_heap_alloc(heap, (n_cols + DATA_N_SYS_COLS)
* sizeof(dict_col_t));
#ifndef UNIV_HOTBACKUP
table->autoinc_lock = mem_heap_alloc(heap, lock_get_size());
mutex_create(&table->autoinc_mutex, SYNC_DICT_AUTOINC_MUTEX);
@ -81,41 +85,42 @@ dict_mem_table_create(
/* The number of transactions that are either waiting on the
AUTOINC lock or have been granted the lock. */
table->n_waiting_or_granted_auto_inc_locks = 0;
#endif /* !UNIV_HOTBACKUP */
#ifdef UNIV_DEBUG
table->magic_n = DICT_TABLE_MAGIC_N;
#endif /* UNIV_DEBUG */
ut_d(table->magic_n = DICT_TABLE_MAGIC_N);
return(table);
}
/********************************************************************
/****************************************************************//**
Free a table memory object. */
UNIV_INTERN
void
dict_mem_table_free(
/*================*/
dict_table_t* table) /* in: table */
dict_table_t* table) /*!< in: table */
{
ut_ad(table);
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);
}
/********************************************************************
Append 'name' to 'col_names' (@see dict_table_t::col_names). */
/****************************************************************//**
Append 'name' to 'col_names'. @see dict_table_t::col_names
@return new column names array */
static
const char*
dict_add_col_name(
/*==============*/
/* out: new column names array */
const char* col_names, /* in: existing column names, or
const char* col_names, /*!< in: existing column names, or
NULL */
ulint cols, /* in: number of existing columns */
const char* name, /* in: new column name */
mem_heap_t* heap) /* in: heap */
ulint cols, /*!< in: number of existing columns */
const char* name, /*!< in: new column name */
mem_heap_t* heap) /*!< in: heap */
{
ulint old_len;
ulint new_len;
@ -152,22 +157,24 @@ dict_add_col_name(
return(res);
}
/**************************************************************************
/**********************************************************************//**
Adds a column definition to a table. */
UNIV_INTERN
void
dict_mem_table_add_col(
/*===================*/
dict_table_t* table, /* in: table */
mem_heap_t* heap, /* in: temporary memory heap, or NULL */
const char* name, /* in: column name, or NULL */
ulint mtype, /* in: main datatype */
ulint prtype, /* in: precise type */
ulint len) /* in: precision */
dict_table_t* table, /*!< in: table */
mem_heap_t* heap, /*!< in: temporary memory heap, or NULL */
const char* name, /*!< in: column name, or NULL */
ulint mtype, /*!< in: main datatype */
ulint prtype, /*!< in: precise type */
ulint len) /*!< in: precision */
{
dict_col_t* col;
#ifndef UNIV_HOTBACKUP
ulint mbminlen;
ulint mbmaxlen;
#endif /* !UNIV_HOTBACKUP */
ulint i;
ut_ad(table);
@ -199,27 +206,29 @@ dict_mem_table_add_col(
col->prtype = (unsigned int) prtype;
col->len = (unsigned int) len;
#ifndef UNIV_HOTBACKUP
dtype_get_mblen(mtype, prtype, &mbminlen, &mbmaxlen);
col->mbminlen = (unsigned int) mbminlen;
col->mbmaxlen = (unsigned int) mbmaxlen;
#endif /* !UNIV_HOTBACKUP */
}
/**************************************************************************
Creates an index memory object. */
/**********************************************************************//**
Creates an index memory object.
@return own: index object */
UNIV_INTERN
dict_index_t*
dict_mem_index_create(
/*==================*/
/* out, own: index object */
const char* table_name, /* in: table name */
const char* index_name, /* in: index name */
ulint space, /* in: space where the index tree is
const char* table_name, /*!< in: table name */
const char* index_name, /*!< in: index name */
ulint space, /*!< in: space where the index tree is
placed, ignored if the index is of
the clustered type */
ulint type, /* in: DICT_UNIQUE,
ulint type, /*!< in: DICT_UNIQUE,
DICT_CLUSTERED, ... ORed */
ulint n_fields) /* in: number of fields */
ulint n_fields) /*!< in: number of fields */
{
dict_index_t* index;
mem_heap_t* heap;
@ -232,7 +241,9 @@ dict_mem_index_create(
index->heap = heap;
index->type = type;
#ifndef UNIV_HOTBACKUP
index->space = (unsigned int) space;
#endif /* !UNIV_HOTBACKUP */
index->name = mem_heap_strdup(heap, index_name);
index->table_name = table_name;
index->n_fields = (unsigned int) n_fields;
@ -246,13 +257,13 @@ dict_mem_index_create(
return(index);
}
/**************************************************************************
Creates and initializes a foreign constraint memory object. */
/**********************************************************************//**
Creates and initializes a foreign constraint memory object.
@return own: foreign constraint struct */
UNIV_INTERN
dict_foreign_t*
dict_mem_foreign_create(void)
/*=========================*/
/* out, own: foreign constraint struct */
{
dict_foreign_t* foreign;
mem_heap_t* heap;
@ -266,7 +277,7 @@ dict_mem_foreign_create(void)
return(foreign);
}
/**************************************************************************
/**********************************************************************//**
Adds a field definition to an index. NOTE: does not take a copy
of the column name if the field is a column. The memory occupied
by the column name may be released only after publishing the index. */
@ -274,9 +285,9 @@ UNIV_INTERN
void
dict_mem_index_add_field(
/*=====================*/
dict_index_t* index, /* in: index */
const char* name, /* in: column name */
ulint prefix_len) /* in: 0 or the column prefix length
dict_index_t* index, /*!< in: index */
const char* name, /*!< in: column name */
ulint prefix_len) /*!< in: 0 or the column prefix length
in a MySQL index like
INDEX (textcol(25)) */
{
@ -293,13 +304,13 @@ dict_mem_index_add_field(
field->prefix_len = (unsigned int) prefix_len;
}
/**************************************************************************
/**********************************************************************//**
Frees an index memory object. */
UNIV_INTERN
void
dict_mem_index_free(
/*================*/
dict_index_t* index) /* in: index */
dict_index_t* index) /*!< in: index */
{
ut_ad(index);
ut_ad(index->magic_n == DICT_INDEX_MAGIC_N);

View File

@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
/******************************************************
/**************************************************//**
@file dyn/dyn0dyn.c
The dynamically allocated array
Created 2/5/1996 Heikki Tuuri
@ -27,14 +28,14 @@ Created 2/5/1996 Heikki Tuuri
#include "dyn0dyn.ic"
#endif
/****************************************************************
Adds a new block to a dyn array. */
/************************************************************//**
Adds a new block to a dyn array.
@return created block */
UNIV_INTERN
dyn_block_t*
dyn_array_add_block(
/*================*/
/* out: created block */
dyn_array_t* arr) /* in: dyn array */
dyn_array_t* arr) /*!< in: dyn array */
{
mem_heap_t* heap;
dyn_block_t* block;

View File

@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
/******************************************************
/**************************************************//**
@file eval/eval0eval.c
SQL evaluator: evaluates simple data structures, like expressions, in
a query graph
@ -32,29 +33,29 @@ Created 12/29/1997 Heikki Tuuri
#include "data0data.h"
#include "row0sel.h"
/* The RND function seed */
/** The RND function seed */
static ulint eval_rnd = 128367121;
/* Dummy adress used when we should allocate a buffer of size 0 in
the function below */
/** Dummy adress used when we should allocate a buffer of size 0 in
eval_node_alloc_val_buf */
static byte eval_dummy;
/*********************************************************************
/*****************************************************************//**
Allocate a buffer from global dynamic memory for a value of a que_node.
NOTE that this memory must be explicitly freed when the query graph is
freed. If the node already has an allocated buffer, that buffer is freed
here. NOTE that this is the only function where dynamic memory should be
allocated for a query node val field. */
allocated for a query node val field.
@return pointer to allocated buffer */
UNIV_INTERN
byte*
eval_node_alloc_val_buf(
/*====================*/
/* out: pointer to allocated buffer */
que_node_t* node, /* in: query graph node; sets the val field
que_node_t* node, /*!< in: query graph node; sets the val field
data field to point to the new buffer, and
len field equal to size */
ulint size) /* in: buffer size */
ulint size) /*!< in: buffer size */
{
dfield_t* dfield;
byte* data;
@ -83,7 +84,7 @@ eval_node_alloc_val_buf(
return(data);
}
/*********************************************************************
/*****************************************************************//**
Free the buffer from global dynamic memory for a value of a que_node,
if it has been allocated in the above function. The freeing for pushed
column values is done in sel_col_prefetch_buf_free. */
@ -91,7 +92,7 @@ UNIV_INTERN
void
eval_node_free_val_buf(
/*===================*/
que_node_t* node) /* in: query graph node */
que_node_t* node) /*!< in: query graph node */
{
dfield_t* dfield;
byte* data;
@ -110,14 +111,14 @@ eval_node_free_val_buf(
}
}
/*********************************************************************
Evaluates a comparison node. */
/*****************************************************************//**
Evaluates a comparison node.
@return the result of the comparison */
UNIV_INTERN
ibool
eval_cmp(
/*=====*/
/* out: the result of the comparison */
func_node_t* cmp_node) /* in: comparison node */
func_node_t* cmp_node) /*!< in: comparison node */
{
que_node_t* arg1;
que_node_t* arg2;
@ -169,13 +170,13 @@ eval_cmp(
return(val);
}
/*********************************************************************
/*****************************************************************//**
Evaluates a logical operation node. */
UNIV_INLINE
void
eval_logical(
/*=========*/
func_node_t* logical_node) /* in: logical operation node */
func_node_t* logical_node) /*!< in: logical operation node */
{
que_node_t* arg1;
que_node_t* arg2;
@ -210,13 +211,13 @@ eval_logical(
eval_node_set_ibool_val(logical_node, val);
}
/*********************************************************************
/*****************************************************************//**
Evaluates an arithmetic operation node. */
UNIV_INLINE
void
eval_arith(
/*=======*/
func_node_t* arith_node) /* in: arithmetic operation node */
func_node_t* arith_node) /*!< in: arithmetic operation node */
{
que_node_t* arg1;
que_node_t* arg2;
@ -254,13 +255,13 @@ eval_arith(
eval_node_set_int_val(arith_node, val);
}
/*********************************************************************
/*****************************************************************//**
Evaluates an aggregate operation node. */
UNIV_INLINE
void
eval_aggregate(
/*===========*/
func_node_t* node) /* in: aggregate operation node */
func_node_t* node) /*!< in: aggregate operation node */
{
que_node_t* arg;
lint val;
@ -288,14 +289,14 @@ eval_aggregate(
eval_node_set_int_val(node, val);
}
/*********************************************************************
/*****************************************************************//**
Evaluates a predefined function node where the function is not relevant
in benchmarks. */
static
void
eval_predefined_2(
/*==============*/
func_node_t* func_node) /* in: predefined function node */
func_node_t* func_node) /*!< in: predefined function node */
{
que_node_t* arg;
que_node_t* arg1;
@ -375,13 +376,13 @@ eval_predefined_2(
}
}
/*********************************************************************
/*****************************************************************//**
Evaluates a notfound-function node. */
UNIV_INLINE
void
eval_notfound(
/*==========*/
func_node_t* func_node) /* in: function node */
func_node_t* func_node) /*!< in: function node */
{
que_node_t* arg1;
que_node_t* arg2;
@ -417,13 +418,13 @@ eval_notfound(
eval_node_set_ibool_val(func_node, ibool_val);
}
/*********************************************************************
/*****************************************************************//**
Evaluates a substr-function node. */
UNIV_INLINE
void
eval_substr(
/*========*/
func_node_t* func_node) /* in: function node */
func_node_t* func_node) /*!< in: function node */
{
que_node_t* arg1;
que_node_t* arg2;
@ -450,13 +451,13 @@ eval_substr(
dfield_set_data(dfield, str1 + len1, len2);
}
/*********************************************************************
/*****************************************************************//**
Evaluates a replstr-procedure node. */
static
void
eval_replstr(
/*=========*/
func_node_t* func_node) /* in: function node */
func_node_t* func_node) /*!< in: function node */
{
que_node_t* arg1;
que_node_t* arg2;
@ -490,13 +491,13 @@ eval_replstr(
ut_memcpy(str1 + len1, str2, len2);
}
/*********************************************************************
/*****************************************************************//**
Evaluates an instr-function node. */
static
void
eval_instr(
/*=======*/
func_node_t* func_node) /* in: function node */
func_node_t* func_node) /*!< in: function node */
{
que_node_t* arg1;
que_node_t* arg2;
@ -562,13 +563,13 @@ match_found:
eval_node_set_int_val(func_node, int_val);
}
/*********************************************************************
/*****************************************************************//**
Evaluates a predefined function node. */
UNIV_INLINE
void
eval_binary_to_number(
/*==================*/
func_node_t* func_node) /* in: function node */
func_node_t* func_node) /*!< in: function node */
{
que_node_t* arg1;
dfield_t* dfield;
@ -600,13 +601,13 @@ eval_binary_to_number(
eval_node_copy_and_alloc_val(func_node, str2, 4);
}
/*********************************************************************
/*****************************************************************//**
Evaluates a predefined function node. */
static
void
eval_concat(
/*========*/
func_node_t* func_node) /* in: function node */
func_node_t* func_node) /*!< in: function node */
{
que_node_t* arg;
dfield_t* dfield;
@ -642,7 +643,7 @@ eval_concat(
}
}
/*********************************************************************
/*****************************************************************//**
Evaluates a predefined function node. If the first argument is an integer,
this function looks at the second argument which is the integer length in
bytes, and converts the integer to a VARCHAR.
@ -652,7 +653,7 @@ UNIV_INLINE
void
eval_to_binary(
/*===========*/
func_node_t* func_node) /* in: function node */
func_node_t* func_node) /*!< in: function node */
{
que_node_t* arg1;
que_node_t* arg2;
@ -690,13 +691,13 @@ eval_to_binary(
dfield_set_data(dfield, str1 + (4 - len1), len1);
}
/*********************************************************************
/*****************************************************************//**
Evaluates a predefined function node. */
UNIV_INLINE
void
eval_predefined(
/*============*/
func_node_t* func_node) /* in: function node */
func_node_t* func_node) /*!< in: function node */
{
que_node_t* arg1;
lint int_val;
@ -782,13 +783,13 @@ eval_predefined(
eval_node_set_int_val(func_node, int_val);
}
/*********************************************************************
/*****************************************************************//**
Evaluates a function node. */
UNIV_INTERN
void
eval_func(
/*======*/
func_node_t* func_node) /* in: function node */
func_node_t* func_node) /*!< in: function node */
{
que_node_t* arg;
ulint class;

View File

@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
/******************************************************
/**************************************************//**
@file eval/eval0proc.c
Executes SQL stored procedures and their control structures
Created 1/20/1998 Heikki Tuuri
@ -28,14 +29,14 @@ Created 1/20/1998 Heikki Tuuri
#include "eval0proc.ic"
#endif
/**************************************************************************
Performs an execution step of an if-statement node. */
/**********************************************************************//**
Performs an execution step of an if-statement node.
@return query thread to run next or NULL */
UNIV_INTERN
que_thr_t*
if_step(
/*====*/
/* out: query thread to run next or NULL */
que_thr_t* thr) /* in: query thread */
que_thr_t* thr) /*!< in: query thread */
{
if_node_t* node;
elsif_node_t* elsif_node;
@ -104,14 +105,14 @@ if_step(
return(thr);
}
/**************************************************************************
Performs an execution step of a while-statement node. */
/**********************************************************************//**
Performs an execution step of a while-statement node.
@return query thread to run next or NULL */
UNIV_INTERN
que_thr_t*
while_step(
/*=======*/
/* out: query thread to run next or NULL */
que_thr_t* thr) /* in: query thread */
que_thr_t* thr) /*!< in: query thread */
{
while_node_t* node;
@ -140,14 +141,14 @@ while_step(
return(thr);
}
/**************************************************************************
Performs an execution step of an assignment statement node. */
/**********************************************************************//**
Performs an execution step of an assignment statement node.
@return query thread to run next or NULL */
UNIV_INTERN
que_thr_t*
assign_step(
/*========*/
/* out: query thread to run next or NULL */
que_thr_t* thr) /* in: query thread */
que_thr_t* thr) /*!< in: query thread */
{
assign_node_t* node;
@ -167,14 +168,14 @@ assign_step(
return(thr);
}
/**************************************************************************
Performs an execution step of a for-loop node. */
/**********************************************************************//**
Performs an execution step of a for-loop node.
@return query thread to run next or NULL */
UNIV_INTERN
que_thr_t*
for_step(
/*=====*/
/* out: query thread to run next or NULL */
que_thr_t* thr) /* in: query thread */
que_thr_t* thr) /*!< in: query thread */
{
for_node_t* node;
que_node_t* parent;
@ -229,14 +230,14 @@ for_step(
return(thr);
}
/**************************************************************************
Performs an execution step of an exit statement node. */
/**********************************************************************//**
Performs an execution step of an exit statement node.
@return query thread to run next or NULL */
UNIV_INTERN
que_thr_t*
exit_step(
/*======*/
/* out: query thread to run next or NULL */
que_thr_t* thr) /* in: query thread */
que_thr_t* thr) /*!< in: query thread */
{
exit_node_t* node;
que_node_t* loop_node;
@ -261,14 +262,14 @@ exit_step(
return(thr);
}
/**************************************************************************
Performs an execution step of a return-statement node. */
/**********************************************************************//**
Performs an execution step of a return-statement node.
@return query thread to run next or NULL */
UNIV_INTERN
que_thr_t*
return_step(
/*========*/
/* out: query thread to run next or NULL */
que_thr_t* thr) /* in: query thread */
que_thr_t* thr) /*!< in: query thread */
{
return_node_t* node;
que_node_t* parent;

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
/**********************************************************************
/******************************************************************//**
@file fut/fut0fut.c
File-based utilities
Created 12/13/1995 Heikki Tuuri

View File

@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
/**********************************************************************
/******************************************************************//**
@file fut/fut0lst.c
File-based list utilities
Created 11/28/1995 Heikki Tuuri
@ -31,16 +32,16 @@ Created 11/28/1995 Heikki Tuuri
#include "buf0buf.h"
#include "page0page.h"
/************************************************************************
/********************************************************************//**
Adds a node to an empty list. */
static
void
flst_add_to_empty(
/*==============*/
flst_base_node_t* base, /* in: pointer to base node of
flst_base_node_t* base, /*!< in: pointer to base node of
empty list */
flst_node_t* node, /* in: node to add */
mtr_t* mtr) /* in: mini-transaction handle */
flst_node_t* node, /*!< in: node to add */
mtr_t* mtr) /*!< in: mini-transaction handle */
{
ulint space;
fil_addr_t node_addr;
@ -67,15 +68,15 @@ flst_add_to_empty(
mlog_write_ulint(base + FLST_LEN, len + 1, MLOG_4BYTES, mtr);
}
/************************************************************************
/********************************************************************//**
Adds a node as the last node in a list. */
UNIV_INTERN
void
flst_add_last(
/*==========*/
flst_base_node_t* base, /* in: pointer to base node of list */
flst_node_t* node, /* in: node to add */
mtr_t* mtr) /* in: mini-transaction handle */
flst_base_node_t* base, /*!< in: pointer to base node of list */
flst_node_t* node, /*!< in: node to add */
mtr_t* mtr) /*!< in: mini-transaction handle */
{
ulint space;
fil_addr_t node_addr;
@ -110,15 +111,15 @@ flst_add_last(
}
}
/************************************************************************
/********************************************************************//**
Adds a node as the first node in a list. */
UNIV_INTERN
void
flst_add_first(
/*===========*/
flst_base_node_t* base, /* in: pointer to base node of list */
flst_node_t* node, /* in: node to add */
mtr_t* mtr) /* in: mini-transaction handle */
flst_base_node_t* base, /*!< in: pointer to base node of list */
flst_node_t* node, /*!< in: node to add */
mtr_t* mtr) /*!< in: mini-transaction handle */
{
ulint space;
fil_addr_t node_addr;
@ -153,16 +154,16 @@ flst_add_first(
}
}
/************************************************************************
/********************************************************************//**
Inserts a node after another in a list. */
UNIV_INTERN
void
flst_insert_after(
/*==============*/
flst_base_node_t* base, /* in: pointer to base node of list */
flst_node_t* node1, /* in: node to insert after */
flst_node_t* node2, /* in: node to add */
mtr_t* mtr) /* in: mini-transaction handle */
flst_base_node_t* base, /*!< in: pointer to base node of list */
flst_node_t* node1, /*!< in: node to insert after */
flst_node_t* node2, /*!< in: node to add */
mtr_t* mtr) /*!< in: mini-transaction handle */
{
ulint space;
fil_addr_t node1_addr;
@ -208,16 +209,16 @@ flst_insert_after(
mlog_write_ulint(base + FLST_LEN, len + 1, MLOG_4BYTES, mtr);
}
/************************************************************************
/********************************************************************//**
Inserts a node before another in a list. */
UNIV_INTERN
void
flst_insert_before(
/*===============*/
flst_base_node_t* base, /* in: pointer to base node of list */
flst_node_t* node2, /* in: node to insert */
flst_node_t* node3, /* in: node to insert before */
mtr_t* mtr) /* in: mini-transaction handle */
flst_base_node_t* base, /*!< in: pointer to base node of list */
flst_node_t* node2, /*!< in: node to insert */
flst_node_t* node3, /*!< in: node to insert before */
mtr_t* mtr) /*!< in: mini-transaction handle */
{
ulint space;
flst_node_t* node1;
@ -262,15 +263,15 @@ flst_insert_before(
mlog_write_ulint(base + FLST_LEN, len + 1, MLOG_4BYTES, mtr);
}
/************************************************************************
/********************************************************************//**
Removes a node. */
UNIV_INTERN
void
flst_remove(
/*========*/
flst_base_node_t* base, /* in: pointer to base node of list */
flst_node_t* node2, /* in: node to remove */
mtr_t* mtr) /* in: mini-transaction handle */
flst_base_node_t* base, /*!< in: pointer to base node of list */
flst_node_t* node2, /*!< in: node to remove */
mtr_t* mtr) /*!< in: mini-transaction handle */
{
ulint space;
ulint zip_size;
@ -337,7 +338,7 @@ flst_remove(
mlog_write_ulint(base + FLST_LEN, len - 1, MLOG_4BYTES, mtr);
}
/************************************************************************
/********************************************************************//**
Cuts off the tail of the list, including the node given. The number of
nodes which will be removed must be provided by the caller, as this function
does not measure the length of the tail. */
@ -345,11 +346,11 @@ UNIV_INTERN
void
flst_cut_end(
/*=========*/
flst_base_node_t* base, /* in: pointer to base node of list */
flst_node_t* node2, /* in: first node to remove */
ulint n_nodes,/* in: number of nodes to remove,
flst_base_node_t* base, /*!< in: pointer to base node of list */
flst_node_t* node2, /*!< in: first node to remove */
ulint n_nodes,/*!< in: number of nodes to remove,
must be >= 1 */
mtr_t* mtr) /* in: mini-transaction handle */
mtr_t* mtr) /*!< in: mini-transaction handle */
{
ulint space;
flst_node_t* node1;
@ -394,7 +395,7 @@ flst_cut_end(
mlog_write_ulint(base + FLST_LEN, len - n_nodes, MLOG_4BYTES, mtr);
}
/************************************************************************
/********************************************************************//**
Cuts off the tail of the list, not including the given node. The number of
nodes which will be removed must be provided by the caller, as this function
does not measure the length of the tail. */
@ -402,10 +403,10 @@ UNIV_INTERN
void
flst_truncate_end(
/*==============*/
flst_base_node_t* base, /* in: pointer to base node of list */
flst_node_t* node2, /* in: first node not to remove */
ulint n_nodes,/* in: number of nodes to remove */
mtr_t* mtr) /* in: mini-transaction handle */
flst_base_node_t* base, /*!< in: pointer to base node of list */
flst_node_t* node2, /*!< in: first node not to remove */
ulint n_nodes,/*!< in: number of nodes to remove */
mtr_t* mtr) /*!< in: mini-transaction handle */
{
fil_addr_t node2_addr;
ulint len;
@ -435,15 +436,15 @@ flst_truncate_end(
mlog_write_ulint(base + FLST_LEN, len - n_nodes, MLOG_4BYTES, mtr);
}
/************************************************************************
Validates a file-based list. */
/********************************************************************//**
Validates a file-based list.
@return TRUE if ok */
UNIV_INTERN
ibool
flst_validate(
/*==========*/
/* out: TRUE if ok */
const flst_base_node_t* base, /* in: pointer to base node of list */
mtr_t* mtr1) /* in: mtr */
const flst_base_node_t* base, /*!< in: pointer to base node of list */
mtr_t* mtr1) /*!< in: mtr */
{
ulint space;
ulint zip_size;
@ -502,14 +503,14 @@ flst_validate(
return(TRUE);
}
/************************************************************************
/********************************************************************//**
Prints info of a file-based list. */
UNIV_INTERN
void
flst_print(
/*=======*/
const flst_base_node_t* base, /* in: pointer to base node of list */
mtr_t* mtr) /* in: mtr */
const flst_base_node_t* base, /*!< in: pointer to base node of list */
mtr_t* mtr) /*!< in: mtr */
{
const buf_frame_t* frame;
ulint len;

View File

@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
/************************************************************************
/********************************************************************//**
@file ha/ha0ha.c
The hash table with external chains
Created 8/22/1994 Heikki Tuuri
@ -35,29 +36,34 @@ Created 8/22/1994 Heikki Tuuri
#endif /* UNIV_SYNC_DEBUG */
#include "page0page.h"
/*****************************************************************
Creates a hash table with >= n array cells. The actual number of cells is
chosen to be a prime number slightly bigger than n. */
/*************************************************************//**
Creates a hash table with at least n array cells. The actual number
of cells is chosen to be a prime number slightly bigger than n.
@return own: created table */
UNIV_INTERN
hash_table_t*
ha_create_func(
/*===========*/
/* out, own: created table */
ulint n, /* in: number of array cells */
ulint n, /*!< in: number of array cells */
#ifdef UNIV_SYNC_DEBUG
ulint mutex_level, /* in: level of the mutexes in the latching
ulint mutex_level, /*!< in: level of the mutexes in the latching
order: this is used in the debug version */
#endif /* UNIV_SYNC_DEBUG */
ulint n_mutexes) /* in: number of mutexes to protect the
ulint n_mutexes) /*!< in: number of mutexes to protect the
hash table: must be a power of 2, or 0 */
{
hash_table_t* table;
#ifndef UNIV_HOTBACKUP
ulint i;
#endif /* !UNIV_HOTBACKUP */
ut_ad(ut_is_2pow(n_mutexes));
table = hash_create(n);
#if defined UNIV_AHI_DEBUG || defined UNIV_DEBUG
# ifndef UNIV_HOTBACKUP
table->adaptive = TRUE;
# endif /* !UNIV_HOTBACKUP */
#endif /* UNIV_AHI_DEBUG || UNIV_DEBUG */
/* Creating MEM_HEAP_BTR_SEARCH type heaps can potentially fail,
but in practise it never should in this case, hence the asserts. */
@ -70,6 +76,7 @@ ha_create_func(
return(table);
}
#ifndef UNIV_HOTBACKUP
hash_create_mutexes(table, n_mutexes, mutex_level);
table->heaps = mem_alloc(n_mutexes * sizeof(void*));
@ -78,17 +85,18 @@ ha_create_func(
table->heaps[i] = mem_heap_create_in_btr_search(4096);
ut_a(table->heaps[i]);
}
#endif /* !UNIV_HOTBACKUP */
return(table);
}
/*****************************************************************
/*************************************************************//**
Empties a hash table and frees the memory heaps. */
UNIV_INTERN
void
ha_clear(
/*=====*/
hash_table_t* table) /* in, own: hash table */
hash_table_t* table) /*!< in, own: hash table */
{
ulint i;
ulint n;
@ -97,12 +105,14 @@ ha_clear(
ut_ad(rw_lock_own(&btr_search_latch, RW_LOCK_EXCLUSIVE));
#endif /* UNIV_SYNC_DEBUG */
#ifndef UNIV_HOTBACKUP
/* Free the memory heaps. */
n = table->n_mutexes;
for (i = 0; i < n; i++) {
mem_heap_free(table->heaps[i]);
}
#endif /* !UNIV_HOTBACKUP */
/* Clear the hash table. */
n = hash_get_n_cells(table);
@ -112,25 +122,24 @@ ha_clear(
}
}
/*****************************************************************
/*************************************************************//**
Inserts an entry into a hash table. If an entry with the same fold number
is found, its node is updated to point to the new data, and no new node
is inserted. */
is inserted.
@return TRUE if succeed, FALSE if no more memory could be allocated */
UNIV_INTERN
ibool
ha_insert_for_fold_func(
/*====================*/
/* out: TRUE if succeed, FALSE if no more
memory could be allocated */
hash_table_t* table, /* in: hash table */
ulint fold, /* in: folded value of data; if a node with
hash_table_t* table, /*!< in: hash table */
ulint fold, /*!< in: folded value of data; if a node with
the same fold value already exists, it is
updated to point to the same data, and no new
node is created! */
#if defined UNIV_AHI_DEBUG || defined UNIV_DEBUG
buf_block_t* block, /* in: buffer block containing the data */
buf_block_t* block, /*!< in: buffer block containing the data */
#endif /* UNIV_AHI_DEBUG || UNIV_DEBUG */
void* data) /* in: data, must not be NULL */
void* data) /*!< in: data, must not be NULL */
{
hash_cell_t* cell;
ha_node_t* node;
@ -141,7 +150,7 @@ ha_insert_for_fold_func(
#if defined UNIV_AHI_DEBUG || defined UNIV_DEBUG
ut_a(block->frame == page_align(data));
#endif /* UNIV_AHI_DEBUG || UNIV_DEBUG */
ut_ad(!table->mutexes || mutex_own(hash_get_mutex(table, fold)));
ASSERT_HASH_MUTEX_OWN(table, fold);
hash = hash_calc_hash(fold, table);
@ -152,6 +161,7 @@ ha_insert_for_fold_func(
while (prev_node != NULL) {
if (prev_node->fold == fold) {
#if defined UNIV_AHI_DEBUG || defined UNIV_DEBUG
# ifndef UNIV_HOTBACKUP
if (table->adaptive) {
buf_block_t* prev_block = prev_node->block;
ut_a(prev_block->frame
@ -160,6 +170,7 @@ ha_insert_for_fold_func(
prev_block->n_pointers--;
block->n_pointers++;
}
# endif /* !UNIV_HOTBACKUP */
prev_node->block = block;
#endif /* UNIV_AHI_DEBUG || UNIV_DEBUG */
@ -187,10 +198,13 @@ ha_insert_for_fold_func(
ha_node_set_data(node, block, data);
#if defined UNIV_AHI_DEBUG || defined UNIV_DEBUG
# ifndef UNIV_HOTBACKUP
if (table->adaptive) {
block->n_pointers++;
}
# endif /* !UNIV_HOTBACKUP */
#endif /* UNIV_AHI_DEBUG || UNIV_DEBUG */
node->fold = fold;
node->next = NULL;
@ -214,65 +228,46 @@ ha_insert_for_fold_func(
return(TRUE);
}
/***************************************************************
/***********************************************************//**
Deletes a hash node. */
UNIV_INTERN
void
ha_delete_hash_node(
/*================*/
hash_table_t* table, /* in: hash table */
ha_node_t* del_node) /* in: node to be deleted */
hash_table_t* table, /*!< in: hash table */
ha_node_t* del_node) /*!< in: node to be deleted */
{
#if defined UNIV_AHI_DEBUG || defined UNIV_DEBUG
# ifndef UNIV_HOTBACKUP
if (table->adaptive) {
ut_a(del_node->block->frame = page_align(del_node->data));
ut_a(del_node->block->n_pointers > 0);
del_node->block->n_pointers--;
}
# endif /* !UNIV_HOTBACKUP */
#endif /* UNIV_AHI_DEBUG || UNIV_DEBUG */
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;
ut_ad(!table->mutexes || mutex_own(hash_get_mutex(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. */
UNIV_INTERN
void
ha_search_and_update_if_found_func(
/*===============================*/
hash_table_t* table, /* in: hash table */
ulint fold, /* in: folded value of the searched data */
void* data, /* in: pointer to the data */
hash_table_t* table, /*!< in/out: hash table */
ulint fold, /*!< in: folded value of the searched data */
void* data, /*!< in: pointer to the data */
#if defined UNIV_AHI_DEBUG || defined UNIV_DEBUG
buf_block_t* new_block,/* in: block containing new_data */
buf_block_t* new_block,/*!< in: block containing new_data */
#endif /* UNIV_AHI_DEBUG || UNIV_DEBUG */
void* new_data)/* in: new pointer to the data */
void* new_data)/*!< in: new pointer to the data */
{
ha_node_t* node;
ut_ad(!table->mutexes || mutex_own(hash_get_mutex(table, fold)));
ASSERT_HASH_MUTEX_OWN(table, fold);
#if defined UNIV_AHI_DEBUG || defined UNIV_DEBUG
ut_a(new_block->frame == page_align(new_data));
#endif /* UNIV_AHI_DEBUG || UNIV_DEBUG */
@ -281,11 +276,13 @@ ha_search_and_update_if_found_func(
if (node) {
#if defined UNIV_AHI_DEBUG || defined UNIV_DEBUG
# ifndef UNIV_HOTBACKUP
if (table->adaptive) {
ut_a(node->block->n_pointers > 0);
node->block->n_pointers--;
new_block->n_pointers++;
}
# endif /* !UNIV_HOTBACKUP */
node->block = new_block;
#endif /* UNIV_AHI_DEBUG || UNIV_DEBUG */
@ -293,20 +290,21 @@ ha_search_and_update_if_found_func(
}
}
/*********************************************************************
#ifndef UNIV_HOTBACKUP
/*****************************************************************//**
Removes from the chain determined by fold all nodes whose data pointer
points to the page given. */
UNIV_INTERN
void
ha_remove_all_nodes_to_page(
/*========================*/
hash_table_t* table, /* in: hash table */
ulint fold, /* in: fold value */
const page_t* page) /* in: buffer page */
hash_table_t* table, /*!< in: hash table */
ulint fold, /*!< in: fold value */
const page_t* page) /*!< in: buffer page */
{
ha_node_t* node;
ut_ad(!table->mutexes || mutex_own(hash_get_mutex(table, fold)));
ASSERT_HASH_MUTEX_OWN(table, fold);
node = ha_chain_get_first(table, fold);
@ -339,16 +337,16 @@ ha_remove_all_nodes_to_page(
#endif
}
/*****************************************************************
Validates a given range of the cells in hash table. */
/*************************************************************//**
Validates a given range of the cells in hash table.
@return TRUE if ok */
UNIV_INTERN
ibool
ha_validate(
/*========*/
/* out: TRUE if ok */
hash_table_t* table, /* in: hash table */
ulint start_index, /* in: start index */
ulint end_index) /* in: end index */
hash_table_t* table, /*!< in: hash table */
ulint start_index, /*!< in: start index */
ulint end_index) /*!< in: end index */
{
hash_cell_t* cell;
ha_node_t* node;
@ -384,14 +382,14 @@ ha_validate(
return(ok);
}
/*****************************************************************
/*************************************************************//**
Prints info of a hash table. */
UNIV_INTERN
void
ha_print_info(
/*==========*/
FILE* file, /* in: file where to print */
hash_table_t* table) /* in: hash table */
FILE* file, /*!< in: file where to print */
hash_table_t* table) /*!< in: hash table */
{
#ifdef UNIV_DEBUG
/* Some of the code here is disabled for performance reasons in production
@ -440,3 +438,4 @@ builds, see http://bugs.mysql.com/36941 */
(ulong) n_bufs);
}
}
#endif /* !UNIV_HOTBACKUP */

View File

@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
/******************************************************
/**************************************************//**
@file ha/ha0storage.c
Hash storage.
Provides a data structure that stores chunks of data in
its own storage, avoiding duplicates.
@ -34,16 +35,16 @@ Created September 22, 2007 Vasil Dimov
#include "ha0storage.ic"
#endif
/***********************************************************************
/*******************************************************************//**
Retrieves a data from a storage. If it is present, a pointer to the
stored copy of data is returned, otherwise NULL is returned. */
static
const void*
ha_storage_get(
/*===========*/
ha_storage_t* storage, /* in: hash storage */
const void* data, /* in: data to check for */
ulint data_len) /* in: data length */
ha_storage_t* storage, /*!< in: hash storage */
const void* data, /*!< in: data to check for */
ulint data_len) /*!< in: data length */
{
ha_storage_node_t* node;
ulint fold;
@ -73,7 +74,7 @@ ha_storage_get(
return(node->data);
}
/***********************************************************************
/*******************************************************************//**
Copies data into the storage and returns a pointer to the copy. If the
same data chunk is already present, then pointer to it is returned.
Data chunks are considered to be equal if len1 == len2 and
@ -86,10 +87,10 @@ UNIV_INTERN
const void*
ha_storage_put_memlim(
/*==================*/
ha_storage_t* storage, /* in/out: hash storage */
const void* data, /* in: data to store */
ulint data_len, /* in: data length */
ulint memlim) /* in: memory limit to obey */
ha_storage_t* storage, /*!< in/out: hash storage */
const void* data, /*!< in: data to store */
ulint data_len, /*!< in: data length */
ulint memlim) /*!< in: memory limit to obey */
{
void* raw;
ha_storage_node_t* node;

View File

@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
/******************************************************
/**************************************************//**
@file ha/hash0hash.c
The simple hash table utility
Created 5/20/1997 Heikki Tuuri
@ -29,37 +30,38 @@ Created 5/20/1997 Heikki Tuuri
#include "mem0mem.h"
/****************************************************************
#ifndef UNIV_HOTBACKUP
/************************************************************//**
Reserves the mutex for a fold value in a hash table. */
UNIV_INTERN
void
hash_mutex_enter(
/*=============*/
hash_table_t* table, /* in: hash table */
ulint fold) /* in: fold */
hash_table_t* table, /*!< in: hash table */
ulint fold) /*!< in: fold */
{
mutex_enter(hash_get_mutex(table, fold));
}
/****************************************************************
/************************************************************//**
Releases the mutex for a fold value in a hash table. */
UNIV_INTERN
void
hash_mutex_exit(
/*============*/
hash_table_t* table, /* in: hash table */
ulint fold) /* in: fold */
hash_table_t* table, /*!< in: hash table */
ulint fold) /*!< in: fold */
{
mutex_exit(hash_get_mutex(table, fold));
}
/****************************************************************
/************************************************************//**
Reserves all the mutexes of a hash table, in an ascending order. */
UNIV_INTERN
void
hash_mutex_enter_all(
/*=================*/
hash_table_t* table) /* in: hash table */
hash_table_t* table) /*!< in: hash table */
{
ulint i;
@ -69,13 +71,13 @@ hash_mutex_enter_all(
}
}
/****************************************************************
/************************************************************//**
Releases all the mutexes of a hash table. */
UNIV_INTERN
void
hash_mutex_exit_all(
/*================*/
hash_table_t* table) /* in: hash table */
hash_table_t* table) /*!< in: hash table */
{
ulint i;
@ -84,16 +86,17 @@ hash_mutex_exit_all(
mutex_exit(table->mutexes + i);
}
}
#endif /* !UNIV_HOTBACKUP */
/*****************************************************************
/*************************************************************//**
Creates a hash table with >= n array cells. The actual number of cells is
chosen to be a prime number slightly bigger than n. */
chosen to be a prime number slightly bigger than n.
@return own: created table */
UNIV_INTERN
hash_table_t*
hash_create(
/*========*/
/* out, own: created table */
ulint n) /* in: number of array cells */
ulint n) /*!< in: number of array cells */
{
hash_cell_t* array;
ulint prime;
@ -105,14 +108,16 @@ hash_create(
array = ut_malloc(sizeof(hash_cell_t) * prime);
#if defined UNIV_AHI_DEBUG || defined UNIV_DEBUG
table->adaptive = FALSE;
#endif /* UNIV_AHI_DEBUG || UNIV_DEBUG */
table->array = array;
table->n_cells = prime;
#ifndef UNIV_HOTBACKUP
# if defined UNIV_AHI_DEBUG || defined UNIV_DEBUG
table->adaptive = FALSE;
# endif /* UNIV_AHI_DEBUG || UNIV_DEBUG */
table->n_mutexes = 0;
table->mutexes = NULL;
table->heaps = NULL;
#endif /* !UNIV_HOTBACKUP */
table->heap = NULL;
table->magic_n = HASH_TABLE_MAGIC_N;
@ -122,32 +127,35 @@ hash_create(
return(table);
}
/*****************************************************************
/*************************************************************//**
Frees a hash table. */
UNIV_INTERN
void
hash_table_free(
/*============*/
hash_table_t* table) /* in, own: hash table */
hash_table_t* table) /*!< in, own: hash table */
{
#ifndef UNIV_HOTBACKUP
ut_a(table->mutexes == NULL);
#endif /* !UNIV_HOTBACKUP */
ut_free(table->array);
mem_free(table);
}
/*****************************************************************
#ifndef UNIV_HOTBACKUP
/*************************************************************//**
Creates a mutex array to protect a hash table. */
UNIV_INTERN
void
hash_create_mutexes_func(
/*=====================*/
hash_table_t* table, /* in: hash table */
hash_table_t* table, /*!< in: hash table */
#ifdef UNIV_SYNC_DEBUG
ulint sync_level, /* in: latching order level of the
ulint sync_level, /*!< in: latching order level of the
mutexes: used in the debug version */
#endif /* UNIV_SYNC_DEBUG */
ulint n_mutexes) /* in: number of mutexes, must be a
ulint n_mutexes) /*!< in: number of mutexes, must be a
power of 2 */
{
ulint i;
@ -163,3 +171,4 @@ hash_create_mutexes_func(
table->n_mutexes = n_mutexes;
}
#endif /* !UNIV_HOTBACKUP */

File diff suppressed because it is too large Load Diff

View File

@ -27,35 +27,43 @@ Place, Suite 330, Boston, MA 02111-1307 USA
#pragma interface /* gcc class implementation */
#endif
/** InnoDB table share */
typedef struct st_innobase_share {
THR_LOCK lock;
pthread_mutex_t mutex;
const char* table_name;
uint use_count;
void* table_name_hash;
THR_LOCK lock; /*!< MySQL lock protecting
this structure */
const char* table_name; /*!< InnoDB table name */
uint use_count; /*!< reference count,
incremented in get_share()
and decremented in free_share() */
void* table_name_hash;/*!< hash table chain node */
} INNOBASE_SHARE;
/** InnoDB B-tree index */
struct dict_index_struct;
/** Prebuilt structures in an Innobase table handle used within MySQL */
struct row_prebuilt_struct;
/** InnoDB B-tree index */
typedef struct dict_index_struct dict_index_t;
/** Prebuilt structures in an Innobase table handle used within MySQL */
typedef struct row_prebuilt_struct row_prebuilt_t;
/* The class defining a handle to an Innodb table */
/** The class defining a handle to an Innodb table */
class ha_innobase: public handler
{
row_prebuilt_t* prebuilt; /* prebuilt struct in InnoDB, used
row_prebuilt_t* prebuilt; /*!< prebuilt struct in InnoDB, used
to save CPU time with prebuilt data
structures*/
THD* user_thd; /* the thread handle of the user
THD* user_thd; /*!< the thread handle of the user
currently using the handle; this is
set in external_lock function */
THR_LOCK_DATA lock;
INNOBASE_SHARE *share;
INNOBASE_SHARE* share; /*!< information for MySQL
table locking */
uchar* upd_buff; /* buffer used in updates */
uchar* key_val_buff; /* buffer used in converting
uchar* upd_buff; /*!< buffer used in updates */
uchar* key_val_buff; /*!< buffer used in converting
search key values from MySQL format
to Innodb format */
ulong upd_and_key_val_buff_len;
@ -63,13 +71,13 @@ class ha_innobase: public handler
two buffers */
Table_flags int_table_flags;
uint primary_key;
ulong start_of_scan; /* this is set to 1 when we are
ulong start_of_scan; /*!< this is set to 1 when we are
starting a table scan but have not
yet fetched any row, else 0 */
uint last_match_mode;/* match mode of the latest search:
ROW_SEL_EXACT, ROW_SEL_EXACT_PREFIX,
or undefined */
uint num_write_row; /* number of write_row() calls */
uint num_write_row; /*!< number of write_row() calls */
uint store_key_val_for_row(uint keynr, char* buff, uint buff_len,
const uchar* record);
@ -119,14 +127,6 @@ class ha_innobase: public handler
void try_semi_consistent_read(bool yes);
void unlock_row();
#ifdef ROW_MERGE_IS_INDEX_USABLE
/** Check if an index can be used by this transaction.
* @param keynr key number to check
* @return true if available, false if the index
* does not contain old records that exist
* in the read view of this transaction */
bool is_index_available(uint keynr);
#endif /* ROW_MERGE_IS_INDEX_USABLE */
int index_init(uint index, bool sorted);
int index_end();
int index_read(uchar * buf, const uchar * key,
@ -260,24 +260,25 @@ void thd_mark_transaction_to_rollback(MYSQL_THD thd, bool all);
}
typedef struct trx_struct trx_t;
/************************************************************************
/********************************************************************//**
@file handler/ha_innodb.h
Converts an InnoDB error code to a MySQL error code and also tells to MySQL
about a possible transaction rollback inside InnoDB caused by a lock wait
timeout or a deadlock. */
timeout or a deadlock.
@return MySQL error code */
extern "C"
int
convert_error_code_to_mysql(
/*========================*/
/* out: MySQL error code */
int error, /* in: InnoDB error code */
ulint flags, /* in: InnoDB table flags, or 0 */
MYSQL_THD thd); /* in: user thread handle or NULL */
int error, /*!< in: InnoDB error code */
ulint flags, /*!< in: InnoDB table flags, or 0 */
MYSQL_THD thd); /*!< in: user thread handle or NULL */
/*************************************************************************
Allocates an InnoDB transaction for a MySQL handler object. */
/*********************************************************************//**
Allocates an InnoDB transaction for a MySQL handler object.
@return InnoDB transaction handle */
extern "C"
trx_t*
innobase_trx_allocate(
/*==================*/
/* out: InnoDB transaction handle */
MYSQL_THD thd); /* in: user thread handle */
MYSQL_THD thd); /*!< in: user thread handle */

View File

@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
/******************************************************
/**************************************************//**
@file handler/handler0alter.cc
Smart ALTER TABLE
*******************************************************/
@ -36,17 +37,17 @@ extern "C" {
#include "ha_innodb.h"
#include "handler0vars.h"
/*****************************************************************
/*************************************************************//**
Copies an InnoDB column to a MySQL field. This function is
adapted from row_sel_field_store_in_mysql_format(). */
static
void
innobase_col_to_mysql(
/*==================*/
const dict_col_t* col, /* in: InnoDB column */
const uchar* data, /* in: InnoDB column data */
ulint len, /* in: length of data, in bytes */
Field* field) /* in/out: MySQL field */
const dict_col_t* col, /*!< in: InnoDB column */
const uchar* data, /*!< in: InnoDB column data */
ulint len, /*!< in: length of data, in bytes */
Field* field) /*!< in/out: MySQL field */
{
uchar* ptr;
uchar* dest = field->ptr;
@ -122,16 +123,16 @@ innobase_col_to_mysql(
}
}
/*****************************************************************
/*************************************************************//**
Copies an InnoDB record to table->record[0]. */
extern "C" UNIV_INTERN
void
innobase_rec_to_mysql(
/*==================*/
TABLE* table, /* in/out: MySQL table */
const rec_t* rec, /* in: record */
const dict_index_t* index, /* in: index */
const ulint* offsets) /* in: rec_get_offsets(
TABLE* table, /*!< in/out: MySQL table */
const rec_t* rec, /*!< in: record */
const dict_index_t* index, /*!< in: index */
const ulint* offsets) /*!< in: rec_get_offsets(
rec, index, ...) */
{
uint n_fields = table->s->fields;
@ -172,13 +173,13 @@ null_field:
}
}
/*****************************************************************
/*************************************************************//**
Resets table->record[0]. */
extern "C" UNIV_INTERN
void
innobase_rec_reset(
/*===============*/
TABLE* table) /* in/out: MySQL table */
TABLE* table) /*!< in/out: MySQL table */
{
uint n_fields = table->s->fields;
uint i;
@ -188,13 +189,13 @@ innobase_rec_reset(
}
}
/**********************************************************************
/******************************************************************//**
Removes the filename encoding of a database and table name. */
static
void
innobase_convert_tablename(
/*=======================*/
char* s) /* in: identifier; out: decoded identifier */
char* s) /*!< in: identifier; out: decoded identifier */
{
uint errors;
@ -222,15 +223,15 @@ innobase_convert_tablename(
}
}
/***********************************************************************
This function checks that index keys are sensible. */
/*******************************************************************//**
This function checks that index keys are sensible.
@return 0 or error number */
static
int
innobase_check_index_keys(
/*======================*/
/* out: 0 or error number */
const KEY* key_info, /* in: Indexes to be created */
ulint num_of_keys) /* in: Number of indexes to
const KEY* key_info, /*!< in: Indexes to be created */
ulint num_of_keys) /*!< in: Number of indexes to
be created */
{
ulint key_num;
@ -322,15 +323,15 @@ innobase_check_index_keys(
return(0);
}
/***********************************************************************
/*******************************************************************//**
Create index field definition for key part */
static
void
innobase_create_index_field_def(
/*============================*/
KEY_PART_INFO* key_part, /* in: MySQL key definition */
mem_heap_t* heap, /* in: memory heap */
merge_index_field_t* index_field) /* out: index field
KEY_PART_INFO* key_part, /*!< in: MySQL key definition */
mem_heap_t* heap, /*!< in: memory heap */
merge_index_field_t* index_field) /*!< out: index field
definition for key_part */
{
Field* field;
@ -364,20 +365,20 @@ innobase_create_index_field_def(
DBUG_VOID_RETURN;
}
/***********************************************************************
/*******************************************************************//**
Create index definition for key */
static
void
innobase_create_index_def(
/*======================*/
KEY* key, /* in: key definition */
bool new_primary, /* in: TRUE=generating
KEY* key, /*!< in: key definition */
bool new_primary, /*!< in: TRUE=generating
a new primary key
on the table */
bool key_primary, /* in: TRUE if this key
bool key_primary, /*!< in: TRUE if this key
is a primary key */
merge_index_def_t* index, /* out: index definition */
mem_heap_t* heap) /* in: heap where memory
merge_index_def_t* index, /*!< out: index definition */
mem_heap_t* heap) /*!< in: heap where memory
is allocated */
{
ulint i;
@ -418,14 +419,14 @@ innobase_create_index_def(
DBUG_VOID_RETURN;
}
/***********************************************************************
/*******************************************************************//**
Copy index field definition */
static
void
innobase_copy_index_field_def(
/*==========================*/
const dict_field_t* field, /* in: definition to copy */
merge_index_field_t* index_field) /* out: copied definition */
const dict_field_t* field, /*!< in: definition to copy */
merge_index_field_t* index_field) /*!< out: copied definition */
{
DBUG_ENTER("innobase_copy_index_field_def");
DBUG_ASSERT(field != NULL);
@ -437,15 +438,15 @@ innobase_copy_index_field_def(
DBUG_VOID_RETURN;
}
/***********************************************************************
/*******************************************************************//**
Copy index definition for the index */
static
void
innobase_copy_index_def(
/*====================*/
const dict_index_t* index, /* in: index definition to copy */
merge_index_def_t* new_index,/* out: Index definition */
mem_heap_t* heap) /* in: heap where allocated */
const dict_index_t* index, /*!< in: index definition to copy */
merge_index_def_t* new_index,/*!< out: Index definition */
mem_heap_t* heap) /*!< in: heap where allocated */
{
ulint n_fields;
ulint i;
@ -475,7 +476,7 @@ innobase_copy_index_def(
DBUG_VOID_RETURN;
}
/***********************************************************************
/*******************************************************************//**
Create an index table where indexes are ordered as follows:
IF a new primary key is defined for the table THEN
@ -490,18 +491,18 @@ ELSE
ENDIF
*/
@return key definitions or NULL */
static
merge_index_def_t*
innobase_create_key_def(
/*====================*/
/* out: key definitions or NULL */
trx_t* trx, /* in: trx */
const dict_table_t*table, /* in: table definition */
mem_heap_t* heap, /* in: heap where space for key
trx_t* trx, /*!< in: trx */
const dict_table_t*table, /*!< in: table definition */
mem_heap_t* heap, /*!< in: heap where space for key
definitions are allocated */
KEY* key_info, /* in: Indexes to be created */
ulint& n_keys) /* in/out: Number of indexes to
KEY* key_info, /*!< in: Indexes to be created */
ulint& n_keys) /*!< in/out: Number of indexes to
be created */
{
ulint i = 0;
@ -582,16 +583,16 @@ innobase_create_key_def(
DBUG_RETURN(indexdefs);
}
/***********************************************************************
Create a temporary tablename using query id, thread id, and id */
/*******************************************************************//**
Create a temporary tablename using query id, thread id, and id
@return temporary tablename */
static
char*
innobase_create_temporary_tablename(
/*================================*/
/* out: temporary tablename */
mem_heap_t* heap, /* in: memory heap */
char id, /* in: identifier [0-9a-zA-Z] */
const char* table_name) /* in: table name */
mem_heap_t* heap, /*!< in: memory heap */
char id, /*!< in: identifier [0-9a-zA-Z] */
const char* table_name) /*!< in: table name */
{
char* name;
ulint len;
@ -607,23 +608,23 @@ innobase_create_temporary_tablename(
return(name);
}
/***********************************************************************
Create indexes. */
/*******************************************************************//**
Create indexes.
@return 0 or error number */
UNIV_INTERN
int
ha_innobase::add_index(
/*===================*/
/* out: 0 or error number */
TABLE* table, /* in: Table where indexes are created */
KEY* key_info, /* in: Indexes to be created */
uint num_of_keys) /* in: Number of indexes to be created */
TABLE* table, /*!< in: Table where indexes are created */
KEY* key_info, /*!< in: Indexes to be created */
uint num_of_keys) /*!< in: Number of indexes to be created */
{
dict_index_t** index; /* Index to be created */
dict_table_t* innodb_table; /* InnoDB table in dictionary */
dict_table_t* indexed_table; /* Table where indexes are created */
merge_index_def_t* index_defs; /* Index definitions */
mem_heap_t* heap; /* Heap for index definitions */
trx_t* trx; /* Transaction */
dict_index_t** index; /*!< Index to be created */
dict_table_t* innodb_table; /*!< InnoDB table in dictionary */
dict_table_t* indexed_table; /*!< Table where indexes are created */
merge_index_def_t* index_defs; /*!< Index definitions */
mem_heap_t* heap; /*!< Heap for index definitions */
trx_t* trx; /*!< Transaction */
ulint num_of_idx;
ulint num_created = 0;
ibool dict_locked = FALSE;
@ -646,6 +647,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. */
@ -911,16 +913,16 @@ convert_error:
DBUG_RETURN(error);
}
/***********************************************************************
Prepare to drop some indexes of a table. */
/*******************************************************************//**
Prepare to drop some indexes of a table.
@return 0 or error number */
UNIV_INTERN
int
ha_innobase::prepare_drop_index(
/*============================*/
/* out: 0 or error number */
TABLE* table, /* in: Table where indexes are dropped */
uint* key_num, /* in: Key nums to be dropped */
uint num_of_keys) /* in: Number of keys to be dropped */
TABLE* table, /*!< in: Table where indexes are dropped */
uint* key_num, /*!< in: Key nums to be dropped */
uint num_of_keys) /*!< in: Number of keys to be dropped */
{
trx_t* trx;
int err = 0;
@ -1112,17 +1114,17 @@ func_exit:
DBUG_RETURN(err);
}
/***********************************************************************
Drop the indexes that were passed to a successful prepare_drop_index(). */
/*******************************************************************//**
Drop the indexes that were passed to a successful prepare_drop_index().
@return 0 or error number */
UNIV_INTERN
int
ha_innobase::final_drop_index(
/*==========================*/
/* out: 0 or error number */
TABLE* table) /* in: Table where indexes are dropped */
TABLE* table) /*!< in: Table where indexes are dropped */
{
dict_index_t* index; /* Index to be dropped */
trx_t* trx; /* Transaction */
dict_index_t* index; /*!< Index to be dropped */
trx_t* trx; /*!< Transaction */
int err;
DBUG_ENTER("ha_innobase::final_drop_index");
@ -1135,6 +1137,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. */

View File

@ -16,12 +16,13 @@ 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. */

View File

@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
/******************************************************
/**************************************************//**
@file handler/i_s.cc
InnoDB INFORMATION SCHEMA tables interface to MySQL.
Created July 18, 2007 Vasil Dimov
@ -125,39 +126,39 @@ bool schema_table_store_record(THD *thd, TABLE *table);
void localtime_to_TIME(MYSQL_TIME *to, struct tm *from);
bool check_global_access(THD *thd, ulong want_access);
/***********************************************************************
/*******************************************************************//**
Common function to fill any of the dynamic tables:
INFORMATION_SCHEMA.innodb_trx
INFORMATION_SCHEMA.innodb_locks
INFORMATION_SCHEMA.innodb_lock_waits */
INFORMATION_SCHEMA.innodb_lock_waits
@return 0 on success */
static
int
trx_i_s_common_fill_table(
/*======================*/
/* out: 0 on success */
THD* thd, /* in: thread */
TABLE_LIST* tables, /* in/out: tables to fill */
COND* cond); /* in: condition (not used) */
THD* thd, /*!< in: thread */
TABLE_LIST* tables, /*!< in/out: tables to fill */
COND* cond); /*!< in: condition (not used) */
/***********************************************************************
Unbind a dynamic INFORMATION_SCHEMA table. */
/*******************************************************************//**
Unbind a dynamic INFORMATION_SCHEMA table.
@return 0 on success */
static
int
i_s_common_deinit(
/*==============*/
/* out: 0 on success */
void* p); /* in/out: table schema object */
void* p); /*!< in/out: table schema object */
/***********************************************************************
/*******************************************************************//**
Auxiliary function to store time_t value in MYSQL_TYPE_DATETIME
field. */
field.
@return 0 on success */
static
int
field_store_time_t(
/*===============*/
/* out: 0 on success */
Field* field, /* in/out: target field for storage */
time_t time) /* in: value to store */
Field* field, /*!< in/out: target field for storage */
time_t time) /*!< in: value to store */
{
MYSQL_TIME my_time;
struct tm tm_time;
@ -176,15 +177,15 @@ field_store_time_t(
return(field->store_time(&my_time, MYSQL_TIMESTAMP_DATETIME));
}
/***********************************************************************
Auxiliary function to store char* value in MYSQL_TYPE_STRING field. */
/*******************************************************************//**
Auxiliary function to store char* value in MYSQL_TYPE_STRING field.
@return 0 on success */
static
int
field_store_string(
/*===============*/
/* out: 0 on success */
Field* field, /* in/out: target field for storage */
const char* str) /* in: NUL-terminated utf-8 string,
Field* field, /*!< in/out: target field for storage */
const char* str) /*!< in: NUL-terminated utf-8 string,
or NULL */
{
int ret;
@ -203,16 +204,16 @@ field_store_string(
return(ret);
}
/***********************************************************************
/*******************************************************************//**
Auxiliary function to store ulint value in MYSQL_TYPE_LONGLONG field.
If the value is ULINT_UNDEFINED then the field it set to NULL. */
If the value is ULINT_UNDEFINED then the field it set to NULL.
@return 0 on success */
static
int
field_store_ulint(
/*==============*/
/* out: 0 on success */
Field* field, /* in/out: target field for storage */
ulint n) /* in: value to store */
Field* field, /*!< in/out: target field for storage */
ulint n) /*!< in: value to store */
{
int ret;
@ -806,7 +807,7 @@ i_s_innodb_buffer_pool_pages_index_fill(
field_store_string(table->field[0], NULL);
p = (char *)index->table_name;
}
strcpy(table_name_raw, p);
strcpy(table_name_raw, (const char*)p);
filename_to_tablename(table_name_raw, table_name, sizeof(table_name));
field_store_string(table->field[1], table_name);
field_store_string(table->field[2], index->name);
@ -1214,18 +1215,18 @@ static ST_FIELD_INFO innodb_trx_fields_info[] =
END_OF_ST_FIELD_INFO
};
/***********************************************************************
/*******************************************************************//**
Read data from cache buffer and fill the INFORMATION_SCHEMA.innodb_trx
table with it. */
table with it.
@return 0 on success */
static
int
fill_innodb_trx_from_cache(
/*=======================*/
/* out: 0 on success */
trx_i_s_cache_t* cache, /* in: cache to read from */
THD* thd, /* in: used to call
trx_i_s_cache_t* cache, /*!< in: cache to read from */
THD* thd, /*!< in: used to call
schema_table_store_record() */
TABLE* table) /* in/out: fill this table */
TABLE* table) /*!< in/out: fill this table */
{
Field** fields;
ulint rows_num;
@ -1299,14 +1300,14 @@ fill_innodb_trx_from_cache(
DBUG_RETURN(0);
}
/***********************************************************************
Bind the dynamic table INFORMATION_SCHEMA.innodb_trx */
/*******************************************************************//**
Bind the dynamic table INFORMATION_SCHEMA.innodb_trx
@return 0 on success */
static
int
innodb_trx_init(
/*============*/
/* out: 0 on success */
void* p) /* in/out: table schema object */
void* p) /*!< in/out: table schema object */
{
ST_SCHEMA_TABLE* schema;
@ -1467,17 +1468,17 @@ static ST_FIELD_INFO innodb_locks_fields_info[] =
END_OF_ST_FIELD_INFO
};
/***********************************************************************
/*******************************************************************//**
Read data from cache buffer and fill the INFORMATION_SCHEMA.innodb_locks
table with it. */
table with it.
@return 0 on success */
static
int
fill_innodb_locks_from_cache(
/*=========================*/
/* out: 0 on success */
trx_i_s_cache_t* cache, /* in: cache to read from */
THD* thd, /* in: MySQL client connection */
TABLE* table) /* in/out: fill this table */
trx_i_s_cache_t* cache, /*!< in: cache to read from */
THD* thd, /*!< in: MySQL client connection */
TABLE* table) /*!< in/out: fill this table */
{
Field** fields;
ulint rows_num;
@ -1575,14 +1576,14 @@ fill_innodb_locks_from_cache(
DBUG_RETURN(0);
}
/***********************************************************************
Bind the dynamic table INFORMATION_SCHEMA.innodb_locks */
/*******************************************************************//**
Bind the dynamic table INFORMATION_SCHEMA.innodb_locks
@return 0 on success */
static
int
innodb_locks_init(
/*==============*/
/* out: 0 on success */
void* p) /* in/out: table schema object */
void* p) /*!< in/out: table schema object */
{
ST_SCHEMA_TABLE* schema;
@ -1687,18 +1688,18 @@ static ST_FIELD_INFO innodb_lock_waits_fields_info[] =
END_OF_ST_FIELD_INFO
};
/***********************************************************************
/*******************************************************************//**
Read data from cache buffer and fill the
INFORMATION_SCHEMA.innodb_lock_waits table with it. */
INFORMATION_SCHEMA.innodb_lock_waits table with it.
@return 0 on success */
static
int
fill_innodb_lock_waits_from_cache(
/*==============================*/
/* out: 0 on success */
trx_i_s_cache_t* cache, /* in: cache to read from */
THD* thd, /* in: used to call
trx_i_s_cache_t* cache, /*!< in: cache to read from */
THD* thd, /*!< in: used to call
schema_table_store_record() */
TABLE* table) /* in/out: fill this table */
TABLE* table) /*!< in/out: fill this table */
{
Field** fields;
ulint rows_num;
@ -1758,14 +1759,14 @@ fill_innodb_lock_waits_from_cache(
DBUG_RETURN(0);
}
/***********************************************************************
Bind the dynamic table INFORMATION_SCHEMA.innodb_lock_waits */
/*******************************************************************//**
Bind the dynamic table INFORMATION_SCHEMA.innodb_lock_waits
@return 0 on success */
static
int
innodb_lock_waits_init(
/*===================*/
/* out: 0 on success */
void* p) /* in/out: table schema object */
void* p) /*!< in/out: table schema object */
{
ST_SCHEMA_TABLE* schema;
@ -1828,19 +1829,19 @@ UNIV_INTERN struct st_mysql_plugin i_s_innodb_lock_waits =
STRUCT_FLD(__reserved1, NULL)
};
/***********************************************************************
/*******************************************************************//**
Common function to fill any of the dynamic tables:
INFORMATION_SCHEMA.innodb_trx
INFORMATION_SCHEMA.innodb_locks
INFORMATION_SCHEMA.innodb_lock_waits */
INFORMATION_SCHEMA.innodb_lock_waits
@return 0 on success */
static
int
trx_i_s_common_fill_table(
/*======================*/
/* out: 0 on success */
THD* thd, /* in: thread */
TABLE_LIST* tables, /* in/out: tables to fill */
COND* cond) /* in: condition (not used) */
THD* thd, /*!< in: thread */
TABLE_LIST* tables, /*!< in/out: tables to fill */
COND* cond) /*!< in: condition (not used) */
{
const char* table_name;
int ret;
@ -1989,18 +1990,18 @@ static ST_FIELD_INFO i_s_cmp_fields_info[] =
};
/***********************************************************************
/*******************************************************************//**
Fill the dynamic table information_schema.innodb_cmp or
innodb_cmp_reset. */
innodb_cmp_reset.
@return 0 on success, 1 on failure */
static
int
i_s_cmp_fill_low(
/*=============*/
/* out: 0 on success, 1 on failure */
THD* thd, /* in: thread */
TABLE_LIST* tables, /* in/out: tables to fill */
COND* cond, /* in: condition (ignored) */
ibool reset) /* in: TRUE=reset cumulated counts */
THD* thd, /*!< in: thread */
TABLE_LIST* tables, /*!< in/out: tables to fill */
COND* cond, /*!< in: condition (ignored) */
ibool reset) /*!< in: TRUE=reset cumulated counts */
{
TABLE* table = (TABLE *) tables->table;
int status = 0;
@ -2047,42 +2048,42 @@ i_s_cmp_fill_low(
DBUG_RETURN(status);
}
/***********************************************************************
Fill the dynamic table information_schema.innodb_cmp. */
/*******************************************************************//**
Fill the dynamic table information_schema.innodb_cmp.
@return 0 on success, 1 on failure */
static
int
i_s_cmp_fill(
/*=========*/
/* out: 0 on success, 1 on failure */
THD* thd, /* in: thread */
TABLE_LIST* tables, /* in/out: tables to fill */
COND* cond) /* in: condition (ignored) */
THD* thd, /*!< in: thread */
TABLE_LIST* tables, /*!< in/out: tables to fill */
COND* cond) /*!< in: condition (ignored) */
{
return(i_s_cmp_fill_low(thd, tables, cond, FALSE));
}
/***********************************************************************
Fill the dynamic table information_schema.innodb_cmp_reset. */
/*******************************************************************//**
Fill the dynamic table information_schema.innodb_cmp_reset.
@return 0 on success, 1 on failure */
static
int
i_s_cmp_reset_fill(
/*===============*/
/* out: 0 on success, 1 on failure */
THD* thd, /* in: thread */
TABLE_LIST* tables, /* in/out: tables to fill */
COND* cond) /* in: condition (ignored) */
THD* thd, /*!< in: thread */
TABLE_LIST* tables, /*!< in/out: tables to fill */
COND* cond) /*!< in: condition (ignored) */
{
return(i_s_cmp_fill_low(thd, tables, cond, TRUE));
}
/***********************************************************************
Bind the dynamic table information_schema.innodb_cmp. */
/*******************************************************************//**
Bind the dynamic table information_schema.innodb_cmp.
@return 0 on success */
static
int
i_s_cmp_init(
/*=========*/
/* out: 0 on success */
void* p) /* in/out: table schema object */
void* p) /*!< in/out: table schema object */
{
DBUG_ENTER("i_s_cmp_init");
ST_SCHEMA_TABLE* schema = (ST_SCHEMA_TABLE*) p;
@ -2093,14 +2094,14 @@ i_s_cmp_init(
DBUG_RETURN(0);
}
/***********************************************************************
Bind the dynamic table information_schema.innodb_cmp_reset. */
/*******************************************************************//**
Bind the dynamic table information_schema.innodb_cmp_reset.
@return 0 on success */
static
int
i_s_cmp_reset_init(
/*===============*/
/* out: 0 on success */
void* p) /* in/out: table schema object */
void* p) /*!< in/out: table schema object */
{
DBUG_ENTER("i_s_cmp_reset_init");
ST_SCHEMA_TABLE* schema = (ST_SCHEMA_TABLE*) p;
@ -2257,18 +2258,18 @@ static ST_FIELD_INFO i_s_cmpmem_fields_info[] =
END_OF_ST_FIELD_INFO
};
/***********************************************************************
/*******************************************************************//**
Fill the dynamic table information_schema.innodb_cmpmem or
innodb_cmpmem_reset. */
innodb_cmpmem_reset.
@return 0 on success, 1 on failure */
static
int
i_s_cmpmem_fill_low(
/*================*/
/* out: 0 on success, 1 on failure */
THD* thd, /* in: thread */
TABLE_LIST* tables, /* in/out: tables to fill */
COND* cond, /* in: condition (ignored) */
ibool reset) /* in: TRUE=reset cumulated counts */
THD* thd, /*!< in: thread */
TABLE_LIST* tables, /*!< in/out: tables to fill */
COND* cond, /*!< in: condition (ignored) */
ibool reset) /*!< in: TRUE=reset cumulated counts */
{
TABLE* table = (TABLE *) tables->table;
int status = 0;
@ -2315,42 +2316,42 @@ i_s_cmpmem_fill_low(
DBUG_RETURN(status);
}
/***********************************************************************
Fill the dynamic table information_schema.innodb_cmpmem. */
/*******************************************************************//**
Fill the dynamic table information_schema.innodb_cmpmem.
@return 0 on success, 1 on failure */
static
int
i_s_cmpmem_fill(
/*============*/
/* out: 0 on success, 1 on failure */
THD* thd, /* in: thread */
TABLE_LIST* tables, /* in/out: tables to fill */
COND* cond) /* in: condition (ignored) */
THD* thd, /*!< in: thread */
TABLE_LIST* tables, /*!< in/out: tables to fill */
COND* cond) /*!< in: condition (ignored) */
{
return(i_s_cmpmem_fill_low(thd, tables, cond, FALSE));
}
/***********************************************************************
Fill the dynamic table information_schema.innodb_cmpmem_reset. */
/*******************************************************************//**
Fill the dynamic table information_schema.innodb_cmpmem_reset.
@return 0 on success, 1 on failure */
static
int
i_s_cmpmem_reset_fill(
/*==================*/
/* out: 0 on success, 1 on failure */
THD* thd, /* in: thread */
TABLE_LIST* tables, /* in/out: tables to fill */
COND* cond) /* in: condition (ignored) */
THD* thd, /*!< in: thread */
TABLE_LIST* tables, /*!< in/out: tables to fill */
COND* cond) /*!< in: condition (ignored) */
{
return(i_s_cmpmem_fill_low(thd, tables, cond, TRUE));
}
/***********************************************************************
Bind the dynamic table information_schema.innodb_cmpmem. */
/*******************************************************************//**
Bind the dynamic table information_schema.innodb_cmpmem.
@return 0 on success */
static
int
i_s_cmpmem_init(
/*============*/
/* out: 0 on success */
void* p) /* in/out: table schema object */
void* p) /*!< in/out: table schema object */
{
DBUG_ENTER("i_s_cmpmem_init");
ST_SCHEMA_TABLE* schema = (ST_SCHEMA_TABLE*) p;
@ -2361,14 +2362,14 @@ i_s_cmpmem_init(
DBUG_RETURN(0);
}
/***********************************************************************
Bind the dynamic table information_schema.innodb_cmpmem_reset. */
/*******************************************************************//**
Bind the dynamic table information_schema.innodb_cmpmem_reset.
@return 0 on success */
static
int
i_s_cmpmem_reset_init(
/*==================*/
/* out: 0 on success */
void* p) /* in/out: table schema object */
void* p) /*!< in/out: table schema object */
{
DBUG_ENTER("i_s_cmpmem_reset_init");
ST_SCHEMA_TABLE* schema = (ST_SCHEMA_TABLE*) p;
@ -2478,14 +2479,14 @@ UNIV_INTERN struct st_mysql_plugin i_s_innodb_cmpmem_reset =
STRUCT_FLD(__reserved1, NULL)
};
/***********************************************************************
Unbind a dynamic INFORMATION_SCHEMA table. */
/*******************************************************************//**
Unbind a dynamic INFORMATION_SCHEMA table.
@return 0 on success */
static
int
i_s_common_deinit(
/*==============*/
/* out: 0 on success */
void* p) /* in/out: table schema object */
void* p) /*!< in/out: table schema object */
{
DBUG_ENTER("i_s_common_deinit");

View File

@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
/******************************************************
/**************************************************//**
@file handler/i_s.h
InnoDB INFORMATION SCHEMA tables interface to MySQL.
Created July 18, 2007 Vasil Dimov

View File

@ -31,12 +31,12 @@ struct innodb_enhancement {
{"innodb_expand_undo_slots","expandable maximum number of undo slots","from 1024 (default) to about 4000","http://www.percona.com/docs/wiki/percona-xtradb"},
{"innodb_extra_rseg","allow to create extra rollback segments","When create new db, the new parameter allows to create more rollback segments","http://www.percona.com/docs/wiki/percona-xtradb"},
{"innodb_overwrite_relay_log_info","overwrite relay-log.info when slave recovery","Building as plugin, it is not used.","http://www.percona.com/docs/wiki/percona-xtradb:innodb_overwrite_relay_log_info"},
{"innodb_pause_in_spin","use 'pause' instruction during spin loop for x86 (gcc)","","http://www.percona.com/docs/wiki/percona-xtradb"},
{"innodb_thread_concurrency_timer_based","use InnoDB timer based concurrency throttling (backport from MySQL 5.4.0)","",""},
{"innodb_expand_import","convert .ibd file automatically when import tablespace","the files are generated by xtrabackup export mode.","http://www.percona.com/docs/wiki/percona-xtradb"},
{"innodb_dict_size_limit","Limit dictionary cache size","Variable innodb_dict_size_limit in bytes","http://www.percona.com/docs/wiki/percona-xtradb"},
{"innodb_split_buf_pool_mutex","More fix of buffer_pool mutex","Spliting buf_pool_mutex and optimizing based on innodb_opt_lru_count","http://www.percona.com/docs/wiki/percona-xtradb"},
{"innodb_stats","Additional features about InnoDB statistics/optimizer","","http://www.percona.com/docs/wiki/percona-xtradb"},
{"innodb_recovery_patches","Bugfixes and adjustments about recovery process","","http://www.percona.com/docs/wiki/percona-xtradb"},
{"innodb_purge_thread","Enable to use purge devoted thread","","http://www.percona.com/docs/wiki/percona-xtradb"},
{NULL, NULL, NULL, NULL}
};

View File

@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
/******************************************************
/**************************************************//**
@file handler/mysql_addons.cc
This file contains functions that need to be added to
MySQL code but have not been added yet.

View File

@ -16,7 +16,8 @@ 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.
@ -48,7 +49,7 @@ extern "C" {
# 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. */
@ -72,14 +73,8 @@ uint* wdl_lower_case_table_names;
ulong* wdl_specialflag;
int* wdl_my_umask;
/***********************************************************************
The following is defined in ha_innodb.cc. It is used for copying the
system variables from the builtin innodb plugin to the dynamic plugin.
*/
extern struct st_mysql_plugin* builtin_innobase_plugin_ptr;
/***********************************************************************
The preffered load-address defined in PE (portable executable format).*/
/*******************************************************************//**
The preferred load-address defined in PE (portable executable format). */
#if defined(_M_IA64)
#pragma section(".base", long, read)
extern "C"
@ -90,29 +85,34 @@ 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. */
VAs to RVAs to work on both 32- and 64-bit platforms.
@return absolute virtual address */
template <class X>
X PFromRva(RVA rva) {
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
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,
DWORD dwTimeStamp; /*!< 0 if not bound,
otherwise date/time stamp of DLL
bound to (Old BIND) */
};
@ -120,11 +120,11 @@ struct InternalImgDelayDescr {
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
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
map_hash_chain_t* chain; /*!< a linear chain used for
cleanup. */
};
@ -135,7 +135,7 @@ 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_
@ -144,8 +144,7 @@ in the server:
_db_return_
_db_dump_
The plugin will get those function pointers during the initialization.
*/
The plugin will get those function pointers during the initialization. */
typedef void (__cdecl* pfn_db_enter_)(
const char* _func_,
const char* _file_,
@ -182,19 +181,19 @@ 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. */
initialized, and buffer pools are not ready yet.
@return own: created hash table */
static
hash_table_t*
wdl_hash_create(
/*============*/
/* out, own: created hash table */
ulint n) /* in: number of array cells */
ulint n) /*!< in: number of array cells */
{
hash_cell_t* array;
ulint prime;
@ -227,13 +226,13 @@ wdl_hash_create(
return(table);
}
/*****************************************************************
/*************************************************************//**
Frees a hash table. */
static
void
wdl_hash_table_free(
/*================*/
hash_table_t* table) /* in, own: hash table */
hash_table_t* table) /*!< in, own: hash table */
{
ut_a(table != NULL);
ut_a(table->mutexes == NULL);
@ -242,14 +241,14 @@ wdl_hash_table_free(
free(table);
}
/***********************************************************************
Function for calculating the count of imports given the base of the IAT. */
/*******************************************************************//**
Function for calculating the count of imports given the base of the IAT.
@return number of imports */
static
ulint
wdl_import_count(
/*=============*/
/* out: number of imports */
PCImgThunkData pitd_base) /* in: base of the IAT */
PCImgThunkData pitd_base) /*!< in: base of the IAT */
{
ulint ret = 0;
PCImgThunkData pitd = pitd_base;
@ -262,15 +261,14 @@ wdl_import_count(
return(ret);
}
/***********************************************************************
Read Mapfile to a hashtable for faster access */
/*******************************************************************//**
Read Mapfile to a hashtable for faster access
@return TRUE if the mapfile is loaded successfully. */
static
ibool
wdl_load_mapfile(
/*=============*/
/* out: TRUE if the mapfile is
loaded successfully. */
const char* filename) /* in: name of the mapfile. */
const char* filename) /*!< in: name of the mapfile. */
{
FILE* fp;
const size_t nSize = 256;
@ -358,7 +356,7 @@ wdl_load_mapfile(
chain_header = map_cell;
map_cell->symbol = strdup(func_name);
map_cell->value = (ulint) strtoull(tmp_buf, NULL, 0)
map_cell->value = (ulint) _strtoui64(tmp_buf, NULL, 0)
- load_addr;
map_fold = ut_fold_string(map_cell->symbol);
@ -375,7 +373,7 @@ wdl_load_mapfile(
return(TRUE);
}
/*****************************************************************
/*************************************************************//**
Cleanup.during DLL unload */
static
void
@ -397,13 +395,13 @@ wdl_cleanup(void)
}
}
/***********************************************************************
Load the mapfile mysqld.map. */
/*******************************************************************//**
Load the mapfile mysqld.map.
@return the module handle */
static
HMODULE
wdl_get_mysqld_mapfile(void)
/*========================*/
/* out: the module handle */
{
char file_name[MAX_PATH];
char* ext;
@ -447,17 +445,16 @@ wdl_get_mysqld_mapfile(void)
return(my_hmod);
}
/***********************************************************************
/*******************************************************************//**
Retrieves the address of an exported function. It follows the convention
of GetProcAddress(). */
of GetProcAddress().
@return address of exported function. */
static
FARPROC
wdl_get_procaddr_from_map(
/*======================*/
/* out: address of exported
function. */
HANDLE m_handle, /* in: module handle */
const char* import_proc) /* in: procedure name */
HANDLE m_handle, /*!< in: module handle */
const char* import_proc) /*!< in: procedure name */
{
map_hash_chain_t* hash_chain;
ulint map_fold;
@ -511,17 +508,16 @@ wdl_get_procaddr_from_map(
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. */
Note: It does not follow the Windows call convention FARPROC.
@return address of exported variable. */
static
void*
wdl_get_varaddr_from_map(
/*=====================*/
/* out: address of exported
variable. */
HANDLE m_handle, /* in: module handle */
const char* import_variable) /* in: variable name */
HANDLE m_handle, /*!< in: module handle */
const char* import_variable) /*!< in: variable name */
{
map_hash_chain_t* hash_chain;
ulint map_fold;
@ -575,13 +571,13 @@ wdl_get_varaddr_from_map(
return((void*) ((ulint) m_handle + hash_chain->value));
}
/***********************************************************************
Bind all unresolved external variables from the MySQL executable. */
/*******************************************************************//**
Bind all unresolved external variables from the MySQL executable.
@return TRUE if successful */
static
bool
wdl_get_external_variables(void)
/*============================*/
/* out: TRUE if successful */
{
HMODULE hmod = wdl_get_mysqld_mapfile();
@ -643,12 +639,6 @@ wdl_get_external_variables(void)
"?binlog_format_names@@3PAPBDA",
wdl_binlog_format_names, char*);
/* It is fine if builtin_innobase_plugin is not available. */
builtin_innobase_plugin_ptr = (struct st_mysql_plugin*)
wdl_get_varaddr_from_map(
hmod,
"?builtin_innobase_plugin@@3PAUst_mysql_plugin@@A");
#ifndef DBUG_OFF
GET_PROC_ADDR(_db_enter_);
GET_PROC_ADDR(_db_return_);
@ -680,7 +670,7 @@ wdl_get_external_variables(void)
#undef GET_PROC_ADDR
}
/***********************************************************************
/*******************************************************************//**
The DLL Delayed Loading Helper Function for resolving externals.
The function may fail due to one of the three reasons:
@ -691,16 +681,15 @@ The function may fail due to one of the three reasons:
* 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. */
So, it has to follow Windows call convention.
@return the address of the imported function */
extern "C"
FARPROC WINAPI
__delayLoadHelper2(
/*===============*/
/* out: the address of the imported
function*/
PCImgDelayDescr pidd, /* in: a const pointer to a
PCImgDelayDescr pidd, /*!< in: a const pointer to a
ImgDelayDescr, see delayimp.h. */
FARPROC* iat_entry) /* in/out: A pointer to the slot in
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. */
@ -824,31 +813,30 @@ __delayLoadHelper2(
return(fun);
}
/***********************************************************************
Unload a DLL that was delay loaded. This function is called by run-time. */
/*******************************************************************//**
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(
/*=====================*/
/* out: TRUE is returned if the DLL is found
and the IAT matches the original one. */
LPCSTR module_name) /* in: DLL name */
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. */
convention.
@return S_OK if the DLL matches, otherwise ERROR_MOD_NOT_FOUND is returned. */
extern "C"
HRESULT WINAPI
__HrLoadAllImportsForDll(
/*=====================*/
/* out: S_OK if the DLL matches, otherwise
ERROR_MOD_NOT_FOUND is returned. */
LPCSTR module_name) /* in: DLL name */
LPCSTR module_name) /*!< in: DLL name */
{
PIMAGE_NT_HEADERS img;
PCImgDelayDescr pidd;
@ -908,18 +896,18 @@ __HrLoadAllImportsForDll(
return ret;
}
/******************************************************************
The main function of a DLL */
/**************************************************************//**
The main function of a DLL
@return TRUE if the call succeeds */
BOOL
WINAPI
DllMain(
/*====*/
/* out: TRUE if the call succeeds */
HINSTANCE hinstDLL, /* in: handle to the DLL module */
DWORD fdwReason, /* Reason code that indicates why the
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
LPVOID lpvReserved) /*!< in: additional parameter based on
fdwReason */
{
BOOL success = TRUE;
@ -939,19 +927,19 @@ DllMain(
}
#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 */
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) {
@ -960,16 +948,16 @@ _db_enter_(
}
}
/******************************************************************
/**************************************************************//**
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 */
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) {
@ -977,14 +965,14 @@ _db_return_(
}
}
/******************************************************************
/**************************************************************//**
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 */
uint _line_, /*!< in: current source line number */
const char* keyword) /*!< in: keyword for current macro */
{
if (wdl_db_pargs_ != NULL) {
@ -992,15 +980,15 @@ _db_pargs_(
}
}
/******************************************************************
/**************************************************************//**
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 */
const char* format, /*!< in: the format string */
...) /*!< in: list of arguments */
{
va_list argp;
char buffer[512];
@ -1015,16 +1003,16 @@ _db_doprnt_(
}
}
/******************************************************************
/**************************************************************//**
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
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 */
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) {

File diff suppressed because it is too large Load Diff

View File

@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
/******************************************************
/**************************************************//**
@file include/btr0btr.h
The B-tree
Created 6/2/1994 Heikki Tuuri
@ -33,315 +34,327 @@ Created 6/2/1994 Heikki Tuuri
#include "mtr0mtr.h"
#include "btr0types.h"
/* Maximum record size which can be stored on a page, without using the
#ifndef UNIV_HOTBACKUP
/** Maximum record size which can be stored on a page, without using the
special big record storage structure */
#define BTR_PAGE_MAX_REC_SIZE (UNIV_PAGE_SIZE / 2 - 200)
/* Maximum depth of a B-tree in InnoDB. Note that this isn't a maximum as
such; none of the tree operations avoid producing trees bigger than this. It
is instead a "max depth that other code must work with", useful for e.g.
fixed-size arrays that must store some information about each level in a
tree. In other words: if a B-tree with bigger depth than this is
encountered, it is not acceptable for it to lead to mysterious memory
corruption, but it is acceptable for the program to die with a clear assert
failure. */
/** @brief Maximum depth of a B-tree in InnoDB.
Note that this isn't a maximum as such; none of the tree operations
avoid producing trees bigger than this. It is instead a "max depth
that other code must work with", useful for e.g. fixed-size arrays
that must store some information about each level in a tree. In other
words: if a B-tree with bigger depth than this is encountered, it is
not acceptable for it to lead to mysterious memory corruption, but it
is acceptable for the program to die with a clear assert failure. */
#define BTR_MAX_LEVELS 100
/* Latching modes for btr_cur_search_to_nth_level(). */
#define BTR_SEARCH_LEAF RW_S_LATCH
#define BTR_MODIFY_LEAF RW_X_LATCH
#define BTR_NO_LATCHES RW_NO_LATCH
#define BTR_MODIFY_TREE 33
#define BTR_CONT_MODIFY_TREE 34
#define BTR_SEARCH_PREV 35
#define BTR_MODIFY_PREV 36
/** Latching modes for btr_cur_search_to_nth_level(). */
enum btr_latch_mode {
/** Search a record on a leaf page and S-latch it. */
BTR_SEARCH_LEAF = RW_S_LATCH,
/** (Prepare to) modify a record on a leaf page and X-latch it. */
BTR_MODIFY_LEAF = RW_X_LATCH,
/** Obtain no latches. */
BTR_NO_LATCHES = RW_NO_LATCH,
/** Start modifying the entire B-tree. */
BTR_MODIFY_TREE = 33,
/** Continue modifying the entire B-tree. */
BTR_CONT_MODIFY_TREE = 34,
/** Search the previous record. */
BTR_SEARCH_PREV = 35,
/** Modify the previous record. */
BTR_MODIFY_PREV = 36
};
/* If this is ORed to the latch mode, it means that the search tuple will be
inserted to the index, at the searched position */
/** If this is ORed to btr_latch_mode, it means that the search tuple
will be inserted to the index, at the searched position */
#define BTR_INSERT 512
/* This flag ORed to latch mode says that we do the search in query
/** This flag ORed to btr_latch_mode says that we do the search in query
optimization */
#define BTR_ESTIMATE 1024
/* This flag ORed to latch mode says that we can ignore possible
UNIQUE definition on secondary indexes when we decide if we can use the
insert buffer to speed up inserts */
/** This flag ORed to btr_latch_mode says that we can ignore possible
UNIQUE definition on secondary indexes when we decide if we can use
the insert buffer to speed up inserts */
#define BTR_IGNORE_SEC_UNIQUE 2048
/******************************************************************
Gets the root node of a tree and x-latches it. */
/**************************************************************//**
Gets the root node of a tree and x-latches it.
@return root page, x-latched */
UNIV_INTERN
page_t*
btr_root_get(
/*=========*/
/* out: root page, x-latched */
dict_index_t* index, /* in: index tree */
mtr_t* mtr); /* in: mtr */
/******************************************************************
dict_index_t* index, /*!< in: index tree */
mtr_t* mtr); /*!< in: mtr */
/**************************************************************//**
Gets a buffer page and declares its latching order level. */
UNIV_INLINE
buf_block_t*
btr_block_get(
/*==========*/
ulint space, /* in: space id */
ulint zip_size, /* in: compressed page size in bytes
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 */
ulint mode, /* in: latch mode */
mtr_t* mtr); /* in: mtr */
/******************************************************************
ulint page_no, /*!< in: page number */
ulint mode, /*!< in: latch mode */
mtr_t* mtr); /*!< in: mtr */
/**************************************************************//**
Gets a buffer page and declares its latching order level. */
UNIV_INLINE
page_t*
btr_page_get(
/*=========*/
ulint space, /* in: space id */
ulint zip_size, /* in: compressed page size in bytes
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 */
ulint mode, /* in: latch mode */
mtr_t* mtr); /* in: mtr */
/******************************************************************
Gets the index id field of a page. */
ulint page_no, /*!< in: page number */
ulint mode, /*!< in: latch mode */
mtr_t* mtr); /*!< in: mtr */
#endif /* !UNIV_HOTBACKUP */
/**************************************************************//**
Gets the index id field of a page.
@return index id */
UNIV_INLINE
dulint
btr_page_get_index_id(
/*==================*/
/* out: index id */
const page_t* page); /* in: index page */
/************************************************************
Gets the node level field in an index page. */
const page_t* page); /*!< in: index page */
#ifndef UNIV_HOTBACKUP
/********************************************************//**
Gets the node level field in an index page.
@return level, leaf level == 0 */
UNIV_INLINE
ulint
btr_page_get_level_low(
/*===================*/
/* out: level, leaf level == 0 */
const page_t* page); /* in: index page */
/************************************************************
Gets the node level field in an index page. */
const page_t* page); /*!< in: index page */
/********************************************************//**
Gets the node level field in an index page.
@return level, leaf level == 0 */
UNIV_INLINE
ulint
btr_page_get_level(
/*===============*/
/* out: level, leaf level == 0 */
const page_t* page, /* in: index page */
mtr_t* mtr); /* in: mini-transaction handle */
/************************************************************
Gets the next index page number. */
const page_t* page, /*!< in: index page */
mtr_t* mtr); /*!< in: mini-transaction handle */
/********************************************************//**
Gets the next index page number.
@return next page number */
UNIV_INLINE
ulint
btr_page_get_next(
/*==============*/
/* out: next page number */
const page_t* page, /* in: index page */
mtr_t* mtr); /* in: mini-transaction handle */
/************************************************************
Gets the previous index page number. */
const page_t* page, /*!< in: index page */
mtr_t* mtr); /*!< in: mini-transaction handle */
/********************************************************//**
Gets the previous index page number.
@return prev page number */
UNIV_INLINE
ulint
btr_page_get_prev(
/*==============*/
/* out: prev page number */
const page_t* page, /* in: index page */
mtr_t* mtr); /* in: mini-transaction handle */
/*****************************************************************
const page_t* page, /*!< in: index page */
mtr_t* mtr); /*!< in: mini-transaction handle */
/*************************************************************//**
Gets pointer to the previous user record in the tree. It is assumed
that the caller has appropriate latches on the page and its neighbor. */
that the caller has appropriate latches on the page and its neighbor.
@return previous user record, NULL if there is none */
UNIV_INTERN
rec_t*
btr_get_prev_user_rec(
/*==================*/
/* out: previous user record, NULL if there is none */
rec_t* rec, /* in: record on leaf level */
mtr_t* mtr); /* in: mtr holding a latch on the page, and if
rec_t* rec, /*!< in: record on leaf level */
mtr_t* mtr); /*!< in: mtr holding a latch on the page, and if
needed, also to the previous page */
/*****************************************************************
/*************************************************************//**
Gets pointer to the next user record in the tree. It is assumed
that the caller has appropriate latches on the page and its neighbor. */
that the caller has appropriate latches on the page and its neighbor.
@return next user record, NULL if there is none */
UNIV_INTERN
rec_t*
btr_get_next_user_rec(
/*==================*/
/* out: next user record, NULL if there is none */
rec_t* rec, /* in: record on leaf level */
mtr_t* mtr); /* in: mtr holding a latch on the page, and if
rec_t* rec, /*!< in: record on leaf level */
mtr_t* mtr); /*!< in: mtr holding a latch on the page, and if
needed, also to the next page */
/******************************************************************
/**************************************************************//**
Releases the latch on a leaf page and bufferunfixes it. */
UNIV_INLINE
void
btr_leaf_page_release(
/*==================*/
buf_block_t* block, /* in: buffer block */
ulint latch_mode, /* in: BTR_SEARCH_LEAF or
buf_block_t* block, /*!< in: buffer block */
ulint latch_mode, /*!< in: BTR_SEARCH_LEAF or
BTR_MODIFY_LEAF */
mtr_t* mtr); /* in: mtr */
/******************************************************************
Gets the child node file address in a node pointer. */
mtr_t* mtr); /*!< in: mtr */
/**************************************************************//**
Gets the child node file address in a node pointer.
@return child node address */
UNIV_INLINE
ulint
btr_node_ptr_get_child_page_no(
/*===========================*/
/* out: child node address */
const rec_t* rec, /* in: node pointer record */
const ulint* offsets);/* in: array returned by rec_get_offsets() */
/****************************************************************
Creates the root node for a new index tree. */
const rec_t* rec, /*!< in: node pointer record */
const ulint* offsets);/*!< in: array returned by rec_get_offsets() */
/************************************************************//**
Creates the root node for a new index tree.
@return page number of the created root, FIL_NULL if did not succeed */
UNIV_INTERN
ulint
btr_create(
/*=======*/
/* out: page number of the created root,
FIL_NULL if did not succeed */
ulint type, /* in: type of the index */
ulint space, /* in: space where created */
ulint zip_size,/* in: compressed page size in bytes
ulint type, /*!< in: type of the index */
ulint space, /*!< in: space where created */
ulint zip_size,/*!< in: compressed page size in bytes
or 0 for uncompressed pages */
dulint index_id,/* in: index id */
dict_index_t* index, /* in: index */
mtr_t* mtr); /* in: mini-transaction handle */
/****************************************************************
dulint index_id,/*!< in: index id */
dict_index_t* index, /*!< in: index */
mtr_t* mtr); /*!< in: mini-transaction handle */
/************************************************************//**
Frees a B-tree except the root page, which MUST be freed after this
by calling btr_free_root. */
UNIV_INTERN
void
btr_free_but_not_root(
/*==================*/
ulint space, /* in: space where created */
ulint zip_size, /* in: compressed page size in bytes
ulint space, /*!< in: space where created */
ulint zip_size, /*!< in: compressed page size in bytes
or 0 for uncompressed pages */
ulint root_page_no); /* in: root page number */
/****************************************************************
ulint root_page_no); /*!< in: root page number */
/************************************************************//**
Frees the B-tree root page. Other tree MUST already have been freed. */
UNIV_INTERN
void
btr_free_root(
/*==========*/
ulint space, /* in: space where created */
ulint zip_size, /* in: compressed page size in bytes
ulint space, /*!< in: space where created */
ulint zip_size, /*!< in: compressed page size in bytes
or 0 for uncompressed pages */
ulint root_page_no, /* in: root page number */
mtr_t* mtr); /* in: a mini-transaction which has already
ulint root_page_no, /*!< in: root page number */
mtr_t* mtr); /*!< in: a mini-transaction which has already
been started */
/*****************************************************************
/*************************************************************//**
Makes tree one level higher by splitting the root, and inserts
the tuple. It is assumed that mtr contains an x-latch on the tree.
NOTE that the operation of this function must always succeed,
we cannot reverse it: therefore enough free disk space must be
guaranteed to be available before this function is called. */
guaranteed to be available before this function is called.
@return inserted record */
UNIV_INTERN
rec_t*
btr_root_raise_and_insert(
/*======================*/
/* out: inserted record */
btr_cur_t* cursor, /* in: cursor at which to insert: must be
btr_cur_t* cursor, /*!< in: cursor at which to insert: must be
on the root page; when the function returns,
the cursor is positioned on the predecessor
of the inserted record */
const dtuple_t* tuple, /* in: tuple to insert */
ulint n_ext, /* in: number of externally stored columns */
mtr_t* mtr); /* in: mtr */
/*****************************************************************
const dtuple_t* tuple, /*!< in: tuple to insert */
ulint n_ext, /*!< in: number of externally stored columns */
mtr_t* mtr); /*!< in: mtr */
/*************************************************************//**
Reorganizes an index page.
IMPORTANT: if btr_page_reorganize() is invoked on a compressed leaf
page of a non-clustered index, the caller must update the insert
buffer free bits in the same mini-transaction in such a way that the
modification will be redo-logged. */
modification will be redo-logged.
@return TRUE on success, FALSE on failure */
UNIV_INTERN
ibool
btr_page_reorganize(
/*================*/
/* out: TRUE on success, FALSE on failure */
buf_block_t* block, /* in: page to be reorganized */
dict_index_t* index, /* in: record descriptor */
mtr_t* mtr); /* in: mtr */
/*****************************************************************
buf_block_t* block, /*!< in: page to be reorganized */
dict_index_t* index, /*!< in: record descriptor */
mtr_t* mtr); /*!< in: mtr */
/*************************************************************//**
Decides if the page should be split at the convergence point of
inserts converging to left. */
inserts converging to left.
@return TRUE if split recommended */
UNIV_INTERN
ibool
btr_page_get_split_rec_to_left(
/*===========================*/
/* out: TRUE if split recommended */
btr_cur_t* cursor, /* in: cursor at which to insert */
rec_t** split_rec);/* out: if split recommended,
btr_cur_t* cursor, /*!< in: cursor at which to insert */
rec_t** split_rec);/*!< out: if split recommended,
the first record on upper half page,
or NULL if tuple should be first */
/*****************************************************************
/*************************************************************//**
Decides if the page should be split at the convergence point of
inserts converging to right. */
inserts converging to right.
@return TRUE if split recommended */
UNIV_INTERN
ibool
btr_page_get_split_rec_to_right(
/*============================*/
/* out: TRUE if split recommended */
btr_cur_t* cursor, /* in: cursor at which to insert */
rec_t** split_rec);/* out: if split recommended,
btr_cur_t* cursor, /*!< in: cursor at which to insert */
rec_t** split_rec);/*!< out: if split recommended,
the first record on upper half page,
or NULL if tuple should be first */
/*****************************************************************
/*************************************************************//**
Splits an index page to halves and inserts the tuple. It is assumed
that mtr holds an x-latch to the index tree. NOTE: the tree x-latch
is released within this function! NOTE that the operation of this
function must always succeed, we cannot reverse it: therefore
enough free disk space must be guaranteed to be available before
this function is called. */
that mtr holds an x-latch to the index tree. NOTE: the tree x-latch is
released within this function! NOTE that the operation of this
function must always succeed, we cannot reverse it: therefore enough
free disk space (2 pages) must be guaranteed to be available before
this function is called.
@return inserted record */
UNIV_INTERN
rec_t*
btr_page_split_and_insert(
/*======================*/
/* out: inserted record; NOTE: the tree
x-latch is released! NOTE: 2 free disk
pages must be available! */
btr_cur_t* cursor, /* in: cursor at which to insert; when the
btr_cur_t* cursor, /*!< in: cursor at which to insert; when the
function returns, the cursor is positioned
on the predecessor of the inserted record */
const dtuple_t* tuple, /* in: tuple to insert */
ulint n_ext, /* in: number of externally stored columns */
mtr_t* mtr); /* in: mtr */
/***********************************************************
const dtuple_t* tuple, /*!< in: tuple to insert */
ulint n_ext, /*!< in: number of externally stored columns */
mtr_t* mtr); /*!< in: mtr */
/*******************************************************//**
Inserts a data tuple to a tree on a non-leaf level. It is assumed
that mtr holds an x-latch on the tree. */
UNIV_INTERN
void
btr_insert_on_non_leaf_level(
/*=========================*/
dict_index_t* index, /* in: index */
ulint level, /* in: level, must be > 0 */
dtuple_t* tuple, /* in: the record to be inserted */
mtr_t* mtr); /* in: mtr */
/********************************************************************
dict_index_t* index, /*!< in: index */
ulint level, /*!< in: level, must be > 0 */
dtuple_t* tuple, /*!< in: the record to be inserted */
mtr_t* mtr); /*!< in: mtr */
#endif /* !UNIV_HOTBACKUP */
/****************************************************************//**
Sets a record as the predefined minimum record. */
UNIV_INTERN
void
btr_set_min_rec_mark(
/*=================*/
rec_t* rec, /* in/out: record */
mtr_t* mtr); /* in: mtr */
/*****************************************************************
rec_t* rec, /*!< in/out: record */
mtr_t* mtr); /*!< in: mtr */
#ifndef UNIV_HOTBACKUP
/*************************************************************//**
Deletes on the upper level the node pointer to a page. */
UNIV_INTERN
void
btr_node_ptr_delete(
/*================*/
dict_index_t* index, /* in: index tree */
buf_block_t* block, /* in: page whose node pointer is deleted */
mtr_t* mtr); /* in: mtr */
dict_index_t* index, /*!< in: index tree */
buf_block_t* block, /*!< in: page whose node pointer is deleted */
mtr_t* mtr); /*!< in: mtr */
#ifdef UNIV_DEBUG
/****************************************************************
Checks that the node pointer to a page is appropriate. */
/************************************************************//**
Checks that the node pointer to a page is appropriate.
@return TRUE */
UNIV_INTERN
ibool
btr_check_node_ptr(
/*===============*/
/* out: TRUE */
dict_index_t* index, /* in: index tree */
buf_block_t* block, /* in: index page */
mtr_t* mtr); /* in: mtr */
dict_index_t* index, /*!< in: index tree */
buf_block_t* block, /*!< in: index page */
mtr_t* mtr); /*!< in: mtr */
#endif /* UNIV_DEBUG */
/*****************************************************************
/*************************************************************//**
Tries to merge the page first to the left immediate brother if such a
brother exists, and the node pointers to the current page and to the
brother reside on the same page. If the left brother does not satisfy these
@ -349,18 +362,18 @@ conditions, looks at the right brother. If the page is the only one on that
level lifts the records of the page to the father page, thus reducing the
tree height. It is assumed that mtr holds an x-latch on the tree and on the
page. If cursor is on the leaf level, mtr must also hold x-latches to
the brothers, if they exist. */
the brothers, if they exist.
@return TRUE on success */
UNIV_INTERN
ibool
btr_compress(
/*=========*/
/* out: TRUE on success */
btr_cur_t* cursor, /* in: cursor on the page to merge or lift;
btr_cur_t* cursor, /*!< in: cursor on the page to merge or lift;
the page must not be empty: in record delete
use btr_discard_page if the page would become
empty */
mtr_t* mtr); /* in: mtr */
/*****************************************************************
mtr_t* mtr); /*!< in: mtr */
/*************************************************************//**
Discards a page from a B-tree. This is used to remove the last record from
a B-tree page: the whole page must be removed at the same time. This cannot
be used for the root page, which is allowed to be empty. */
@ -368,70 +381,71 @@ UNIV_INTERN
void
btr_discard_page(
/*=============*/
btr_cur_t* cursor, /* in: cursor on the page to discard: not on
btr_cur_t* cursor, /*!< in: cursor on the page to discard: not on
the root page */
mtr_t* mtr); /* in: mtr */
/********************************************************************
mtr_t* mtr); /*!< in: mtr */
#endif /* !UNIV_HOTBACKUP */
/****************************************************************//**
Parses the redo log record for setting an index record as the predefined
minimum record. */
minimum record.
@return end of log record or NULL */
UNIV_INTERN
byte*
btr_parse_set_min_rec_mark(
/*=======================*/
/* out: end of log record or NULL */
byte* ptr, /* in: buffer */
byte* end_ptr,/* in: buffer end */
ulint comp, /* in: nonzero=compact page format */
page_t* page, /* in: page or NULL */
mtr_t* mtr); /* in: mtr or NULL */
/***************************************************************
Parses a redo log record of reorganizing a page. */
byte* ptr, /*!< in: buffer */
byte* end_ptr,/*!< in: buffer end */
ulint comp, /*!< in: nonzero=compact page format */
page_t* page, /*!< in: page or NULL */
mtr_t* mtr); /*!< in: mtr or NULL */
/***********************************************************//**
Parses a redo log record of reorganizing a page.
@return end of log record or NULL */
UNIV_INTERN
byte*
btr_parse_page_reorganize(
/*======================*/
/* out: end of log record or NULL */
byte* ptr, /* in: buffer */
byte* end_ptr,/* in: buffer end */
dict_index_t* index, /* in: record descriptor */
buf_block_t* block, /* in: page to be reorganized, or NULL */
mtr_t* mtr); /* in: mtr or NULL */
/******************************************************************
Gets the number of pages in a B-tree. */
byte* ptr, /*!< in: buffer */
byte* end_ptr,/*!< in: buffer end */
dict_index_t* index, /*!< in: record descriptor */
buf_block_t* block, /*!< in: page to be reorganized, or NULL */
mtr_t* mtr); /*!< in: mtr or NULL */
#ifndef UNIV_HOTBACKUP
/**************************************************************//**
Gets the number of pages in a B-tree.
@return number of pages */
UNIV_INTERN
ulint
btr_get_size(
/*=========*/
/* out: number of pages */
dict_index_t* index, /* in: index */
ulint flag); /* in: BTR_N_LEAF_PAGES or BTR_TOTAL_SIZE */
/******************************************************************
dict_index_t* index, /*!< in: index */
ulint flag); /*!< in: BTR_N_LEAF_PAGES or BTR_TOTAL_SIZE */
/**************************************************************//**
Allocates a new file page to be used in an index tree. NOTE: we assume
that the caller has made the reservation for free extents! */
that the caller has made the reservation for free extents!
@return new allocated block, x-latched; NULL if out of space */
UNIV_INTERN
buf_block_t*
btr_page_alloc(
/*===========*/
/* out: new allocated block, x-latched;
NULL if out of space */
dict_index_t* index, /* in: index tree */
ulint hint_page_no, /* in: hint of a good page */
byte file_direction, /* in: direction where a possible
dict_index_t* index, /*!< in: index tree */
ulint hint_page_no, /*!< in: hint of a good page */
byte file_direction, /*!< in: direction where a possible
page split is made */
ulint level, /* in: level where the page is placed
ulint level, /*!< in: level where the page is placed
in the tree */
mtr_t* mtr); /* in: mtr */
/******************************************************************
mtr_t* mtr); /*!< in: mtr */
/**************************************************************//**
Frees a file page used in an index tree. NOTE: cannot free field external
storage pages because the page must contain info on its level. */
UNIV_INTERN
void
btr_page_free(
/*==========*/
dict_index_t* index, /* in: index tree */
buf_block_t* block, /* in: block to be freed, x-latched */
mtr_t* mtr); /* in: mtr */
/******************************************************************
dict_index_t* index, /*!< in: index tree */
buf_block_t* block, /*!< in: block to be freed, x-latched */
mtr_t* mtr); /*!< in: mtr */
/**************************************************************//**
Frees a file page used in an index tree. Can be used also to BLOB
external storage pages, because the page level 0 can be given as an
argument. */
@ -439,53 +453,54 @@ UNIV_INTERN
void
btr_page_free_low(
/*==============*/
dict_index_t* index, /* in: index tree */
buf_block_t* block, /* in: block to be freed, x-latched */
ulint level, /* in: page level */
mtr_t* mtr); /* in: mtr */
dict_index_t* index, /*!< in: index tree */
buf_block_t* block, /*!< in: block to be freed, x-latched */
ulint level, /*!< in: page level */
mtr_t* mtr); /*!< in: mtr */
#ifdef UNIV_BTR_PRINT
/*****************************************************************
/*************************************************************//**
Prints size info of a B-tree. */
UNIV_INTERN
void
btr_print_size(
/*===========*/
dict_index_t* index); /* in: index tree */
/******************************************************************
dict_index_t* index); /*!< in: index tree */
/**************************************************************//**
Prints directories and other info of all nodes in the index. */
UNIV_INTERN
void
btr_print_index(
/*============*/
dict_index_t* index, /* in: index */
ulint width); /* in: print this many entries from start
dict_index_t* index, /*!< in: index */
ulint width); /*!< in: print this many entries from start
and end */
#endif /* UNIV_BTR_PRINT */
/****************************************************************
/************************************************************//**
Checks the size and number of fields in a record based on the definition of
the index. */
the index.
@return TRUE if ok */
UNIV_INTERN
ibool
btr_index_rec_validate(
/*===================*/
/* out: TRUE if ok */
const rec_t* rec, /* in: index record */
const dict_index_t* index, /* in: index */
ibool dump_on_error); /* in: TRUE if the function
const rec_t* rec, /*!< in: index record */
const dict_index_t* index, /*!< in: index */
ibool dump_on_error); /*!< in: TRUE if the function
should print hex dump of record
and page on error */
/******************************************************************
Checks the consistency of an index tree. */
/**************************************************************//**
Checks the consistency of an index tree.
@return TRUE if ok */
UNIV_INTERN
ibool
btr_validate_index(
/*===============*/
/* out: TRUE if ok */
dict_index_t* index, /* in: index */
trx_t* trx); /* in: transaction or NULL */
dict_index_t* index, /*!< in: index */
trx_t* trx); /*!< in: transaction or NULL */
#define BTR_N_LEAF_PAGES 1
#define BTR_TOTAL_SIZE 2
#endif /* !UNIV_HOTBACKUP */
#ifndef UNIV_NONINL
#include "btr0btr.ic"

View File

@ -16,31 +16,37 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
/******************************************************
/**************************************************//**
@file include/btr0btr.ic
The B-tree
Created 6/2/1994 Heikki Tuuri
*******************************************************/
#include "mach0data.h"
#ifndef UNIV_HOTBACKUP
#include "mtr0mtr.h"
#include "mtr0log.h"
#include "page0zip.h"
#define BTR_MAX_NODE_LEVEL 50 /* used in debug checking */
#define BTR_MAX_NODE_LEVEL 50 /*!< Maximum B-tree page level
(not really a hard limit).
Used in debug assertions
in btr_page_set_level and
btr_page_get_level_low */
/******************************************************************
/**************************************************************//**
Gets a buffer page and declares its latching order level. */
UNIV_INLINE
buf_block_t*
btr_block_get(
/*==========*/
ulint space, /* in: space id */
ulint zip_size, /* in: compressed page size in bytes
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 */
ulint mode, /* in: latch mode */
mtr_t* mtr) /* in: mtr */
ulint page_no, /*!< in: page number */
ulint mode, /*!< in: latch mode */
mtr_t* mtr) /*!< in: mtr */
{
buf_block_t* block;
@ -54,34 +60,34 @@ btr_block_get(
return(block);
}
/******************************************************************
/**************************************************************//**
Gets a buffer page and declares its latching order level. */
UNIV_INLINE
page_t*
btr_page_get(
/*=========*/
ulint space, /* in: space id */
ulint zip_size, /* in: compressed page size in bytes
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 */
ulint mode, /* in: latch mode */
mtr_t* mtr) /* in: mtr */
ulint page_no, /*!< in: page number */
ulint mode, /*!< in: latch mode */
mtr_t* mtr) /*!< in: mtr */
{
return(buf_block_get_frame(btr_block_get(space, zip_size, page_no,
mode, mtr)));
}
/******************************************************************
/**************************************************************//**
Sets the index id field of a page. */
UNIV_INLINE
void
btr_page_set_index_id(
/*==================*/
page_t* page, /* in: page to be created */
page_zip_des_t* page_zip,/* in: compressed page whose uncompressed
page_t* page, /*!< in: page to be created */
page_zip_des_t* page_zip,/*!< in: compressed page whose uncompressed
part will be updated, or NULL */
dulint id, /* in: index id */
mtr_t* mtr) /* in: mtr */
dulint id, /*!< in: index id */
mtr_t* mtr) /*!< in: mtr */
{
if (UNIV_LIKELY_NULL(page_zip)) {
mach_write_to_8(page + (PAGE_HEADER + PAGE_INDEX_ID), id);
@ -93,27 +99,29 @@ btr_page_set_index_id(
id, mtr);
}
}
#endif /* !UNIV_HOTBACKUP */
/******************************************************************
Gets the index id field of a page. */
/**************************************************************//**
Gets the index id field of a page.
@return index id */
UNIV_INLINE
dulint
btr_page_get_index_id(
/*==================*/
/* out: index id */
const page_t* page) /* in: index page */
const page_t* page) /*!< in: index page */
{
return(mach_read_from_8(page + PAGE_HEADER + PAGE_INDEX_ID));
}
/************************************************************
Gets the node level field in an index page. */
#ifndef UNIV_HOTBACKUP
/********************************************************//**
Gets the node level field in an index page.
@return level, leaf level == 0 */
UNIV_INLINE
ulint
btr_page_get_level_low(
/*===================*/
/* out: level, leaf level == 0 */
const page_t* page) /* in: index page */
const page_t* page) /*!< in: index page */
{
ulint level;
@ -126,33 +134,33 @@ btr_page_get_level_low(
return(level);
}
/************************************************************
Gets the node level field in an index page. */
/********************************************************//**
Gets the node level field in an index page.
@return level, leaf level == 0 */
UNIV_INLINE
ulint
btr_page_get_level(
/*===============*/
/* out: level, leaf level == 0 */
const page_t* page, /* in: index page */
const page_t* page, /*!< in: index page */
mtr_t* mtr __attribute__((unused)))
/* in: mini-transaction handle */
/*!< in: mini-transaction handle */
{
ut_ad(page && mtr);
return(btr_page_get_level_low(page));
}
/************************************************************
/********************************************************//**
Sets the node level field in an index page. */
UNIV_INLINE
void
btr_page_set_level(
/*===============*/
page_t* page, /* in: index page */
page_zip_des_t* page_zip,/* in: compressed page whose uncompressed
page_t* page, /*!< in: index page */
page_zip_des_t* page_zip,/*!< in: compressed page whose uncompressed
part will be updated, or NULL */
ulint level, /* in: level, leaf level == 0 */
mtr_t* mtr) /* in: mini-transaction handle */
ulint level, /*!< in: level, leaf level == 0 */
mtr_t* mtr) /*!< in: mini-transaction handle */
{
ut_ad(page && mtr);
ut_ad(level <= BTR_MAX_NODE_LEVEL);
@ -168,16 +176,16 @@ btr_page_set_level(
}
}
/************************************************************
Gets the next index page number. */
/********************************************************//**
Gets the next index page number.
@return next page number */
UNIV_INLINE
ulint
btr_page_get_next(
/*==============*/
/* out: next page number */
const page_t* page, /* in: index page */
const page_t* page, /*!< in: index page */
mtr_t* mtr __attribute__((unused)))
/* in: mini-transaction handle */
/*!< in: mini-transaction handle */
{
ut_ad(page && mtr);
ut_ad(mtr_memo_contains_page(mtr, page, MTR_MEMO_PAGE_X_FIX)
@ -186,17 +194,17 @@ btr_page_get_next(
return(mach_read_from_4(page + FIL_PAGE_NEXT));
}
/************************************************************
/********************************************************//**
Sets the next index page field. */
UNIV_INLINE
void
btr_page_set_next(
/*==============*/
page_t* page, /* in: index page */
page_zip_des_t* page_zip,/* in: compressed page whose uncompressed
page_t* page, /*!< in: index page */
page_zip_des_t* page_zip,/*!< in: compressed page whose uncompressed
part will be updated, or NULL */
ulint next, /* in: next page number */
mtr_t* mtr) /* in: mini-transaction handle */
ulint next, /*!< in: next page number */
mtr_t* mtr) /*!< in: mini-transaction handle */
{
ut_ad(page && mtr);
@ -208,32 +216,32 @@ btr_page_set_next(
}
}
/************************************************************
Gets the previous index page number. */
/********************************************************//**
Gets the previous index page number.
@return prev page number */
UNIV_INLINE
ulint
btr_page_get_prev(
/*==============*/
/* out: prev page number */
const page_t* page, /* in: index page */
mtr_t* mtr __attribute__((unused))) /* in: mini-transaction handle */
const page_t* page, /*!< in: index page */
mtr_t* mtr __attribute__((unused))) /*!< in: mini-transaction handle */
{
ut_ad(page && mtr);
return(mach_read_from_4(page + FIL_PAGE_PREV));
}
/************************************************************
/********************************************************//**
Sets the previous index page field. */
UNIV_INLINE
void
btr_page_set_prev(
/*==============*/
page_t* page, /* in: index page */
page_zip_des_t* page_zip,/* in: compressed page whose uncompressed
page_t* page, /*!< in: index page */
page_zip_des_t* page_zip,/*!< in: compressed page whose uncompressed
part will be updated, or NULL */
ulint prev, /* in: previous page number */
mtr_t* mtr) /* in: mini-transaction handle */
ulint prev, /*!< in: previous page number */
mtr_t* mtr) /*!< in: mini-transaction handle */
{
ut_ad(page && mtr);
@ -245,15 +253,15 @@ btr_page_set_prev(
}
}
/******************************************************************
Gets the child node file address in a node pointer. */
/**************************************************************//**
Gets the child node file address in a node pointer.
@return child node address */
UNIV_INLINE
ulint
btr_node_ptr_get_child_page_no(
/*===========================*/
/* out: child node address */
const rec_t* rec, /* in: node pointer record */
const ulint* offsets)/* in: array returned by rec_get_offsets() */
const rec_t* rec, /*!< in: node pointer record */
const ulint* offsets)/*!< in: array returned by rec_get_offsets() */
{
const byte* field;
ulint len;
@ -280,16 +288,16 @@ btr_node_ptr_get_child_page_no(
return(page_no);
}
/******************************************************************
/**************************************************************//**
Releases the latches on a leaf page and bufferunfixes it. */
UNIV_INLINE
void
btr_leaf_page_release(
/*==================*/
buf_block_t* block, /* in: buffer block */
ulint latch_mode, /* in: BTR_SEARCH_LEAF or
buf_block_t* block, /*!< in: buffer block */
ulint latch_mode, /*!< in: BTR_SEARCH_LEAF or
BTR_MODIFY_LEAF */
mtr_t* mtr) /* in: mtr */
mtr_t* mtr) /*!< in: mtr */
{
ut_ad(latch_mode == BTR_SEARCH_LEAF || latch_mode == BTR_MODIFY_LEAF);
ut_ad(!mtr_memo_contains(mtr, block, MTR_MEMO_MODIFY));
@ -299,3 +307,4 @@ btr_leaf_page_release(
? MTR_MEMO_PAGE_S_FIX
: MTR_MEMO_PAGE_X_FIX);
}
#endif /* !UNIV_HOTBACKUP */

File diff suppressed because it is too large Load Diff

View File

@ -16,110 +16,110 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
/******************************************************
/**************************************************//**
@file include/btr0cur.ic
The index tree cursor
Created 10/16/1994 Heikki Tuuri
*******************************************************/
#ifndef UNIV_HOTBACKUP
#include "btr0btr.h"
#ifdef UNIV_DEBUG
/*************************************************************
Returns the page cursor component of a tree cursor. */
/*********************************************************//**
Returns the page cursor component of a tree cursor.
@return pointer to page cursor component */
UNIV_INLINE
page_cur_t*
btr_cur_get_page_cur(
/*=================*/
/* out: pointer to page cursor
component */
const btr_cur_t* cursor) /* in: tree cursor */
const btr_cur_t* cursor) /*!< in: tree cursor */
{
return(&((btr_cur_t*) cursor)->page_cur);
}
#endif /* UNIV_DEBUG */
/*************************************************************
Returns the buffer block on which the tree cursor is positioned. */
/*********************************************************//**
Returns the buffer block on which the tree cursor is positioned.
@return pointer to buffer block */
UNIV_INLINE
buf_block_t*
btr_cur_get_block(
/*==============*/
/* out: pointer to buffer block */
btr_cur_t* cursor) /* in: tree cursor */
btr_cur_t* cursor) /*!< in: tree cursor */
{
return(page_cur_get_block(btr_cur_get_page_cur(cursor)));
}
/*************************************************************
Returns the record pointer of a tree cursor. */
/*********************************************************//**
Returns the record pointer of a tree cursor.
@return pointer to record */
UNIV_INLINE
rec_t*
btr_cur_get_rec(
/*============*/
/* out: pointer to record */
btr_cur_t* cursor) /* in: tree cursor */
btr_cur_t* cursor) /*!< in: tree cursor */
{
return(page_cur_get_rec(&(cursor->page_cur)));
}
/*************************************************************
Returns the compressed page on which the tree cursor is positioned. */
/*********************************************************//**
Returns the compressed page on which the tree cursor is positioned.
@return pointer to compressed page, or NULL if the page is not compressed */
UNIV_INLINE
page_zip_des_t*
btr_cur_get_page_zip(
/*=================*/
/* out: pointer to compressed page,
or NULL if the page is not compressed */
btr_cur_t* cursor) /* in: tree cursor */
btr_cur_t* cursor) /*!< in: tree cursor */
{
return(buf_block_get_page_zip(btr_cur_get_block(cursor)));
}
/*************************************************************
/*********************************************************//**
Invalidates a tree cursor by setting record pointer to NULL. */
UNIV_INLINE
void
btr_cur_invalidate(
/*===============*/
btr_cur_t* cursor) /* in: tree cursor */
btr_cur_t* cursor) /*!< in: tree cursor */
{
page_cur_invalidate(&(cursor->page_cur));
}
/*************************************************************
Returns the page of a tree cursor. */
/*********************************************************//**
Returns the page of a tree cursor.
@return pointer to page */
UNIV_INLINE
page_t*
btr_cur_get_page(
/*=============*/
/* out: pointer to page */
btr_cur_t* cursor) /* in: tree cursor */
btr_cur_t* cursor) /*!< in: tree cursor */
{
return(page_align(page_cur_get_rec(&(cursor->page_cur))));
}
/*************************************************************
Returns the index of a cursor. */
/*********************************************************//**
Returns the index of a cursor.
@return index */
UNIV_INLINE
dict_index_t*
btr_cur_get_index(
/*==============*/
/* out: index */
btr_cur_t* cursor) /* in: B-tree cursor */
btr_cur_t* cursor) /*!< in: B-tree cursor */
{
return(cursor->index);
}
/*************************************************************
/*********************************************************//**
Positions a tree cursor at a given record. */
UNIV_INLINE
void
btr_cur_position(
/*=============*/
dict_index_t* index, /* in: index */
rec_t* rec, /* in: record in tree */
buf_block_t* block, /* in: buffer block of rec */
btr_cur_t* cursor) /* out: cursor */
dict_index_t* index, /*!< in: index */
rec_t* rec, /*!< in: record in tree */
buf_block_t* block, /*!< in: buffer block of rec */
btr_cur_t* cursor) /*!< out: cursor */
{
ut_ad(page_align(rec) == block->frame);
@ -128,16 +128,16 @@ btr_cur_position(
cursor->index = index;
}
/*************************************************************************
/*********************************************************************//**
Checks if compressing an index page where a btr cursor is placed makes
sense. */
sense.
@return TRUE if compression is recommended */
UNIV_INLINE
ibool
btr_cur_compress_recommendation(
/*============================*/
/* out: TRUE if compression is recommended */
btr_cur_t* cursor, /* in: btr cursor */
mtr_t* mtr) /* in: mtr */
btr_cur_t* cursor, /*!< in: btr cursor */
mtr_t* mtr) /*!< in: mtr */
{
page_t* page;
@ -162,18 +162,17 @@ btr_cur_compress_recommendation(
return(FALSE);
}
/*************************************************************************
/*********************************************************************//**
Checks if the record on which the cursor is placed can be deleted without
making tree compression necessary (or, recommended). */
making tree compression necessary (or, recommended).
@return TRUE if can be deleted without recommended compression */
UNIV_INLINE
ibool
btr_cur_can_delete_without_compress(
/*================================*/
/* out: TRUE if can be deleted without
recommended compression */
btr_cur_t* cursor, /* in: btr cursor */
ulint rec_size,/* in: rec_get_size(btr_cur_get_rec(cursor))*/
mtr_t* mtr) /* in: mtr */
btr_cur_t* cursor, /*!< in: btr cursor */
ulint rec_size,/*!< in: rec_get_size(btr_cur_get_rec(cursor))*/
mtr_t* mtr) /*!< in: mtr */
{
page_t* page;
@ -198,3 +197,4 @@ btr_cur_can_delete_without_compress(
return(TRUE);
}
#endif /* !UNIV_HOTBACKUP */

View File

@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
/******************************************************
/**************************************************//**
@file include/btr0pcur.h
The index tree persistent cursor
Created 2/23/1996 Heikki Tuuri
@ -45,114 +46,112 @@ of a scroll cursor easier */
#define BTR_PCUR_BEFORE_FIRST_IN_TREE 4 /* in an empty tree */
#define BTR_PCUR_AFTER_LAST_IN_TREE 5 /* in an empty tree */
/******************************************************************
Allocates memory for a persistent cursor object and initializes the cursor. */
/**************************************************************//**
Allocates memory for a persistent cursor object and initializes the cursor.
@return own: persistent cursor */
UNIV_INTERN
btr_pcur_t*
btr_pcur_create_for_mysql(void);
/*============================*/
/* out, own: persistent cursor */
/******************************************************************
/**************************************************************//**
Frees the memory for a persistent cursor object. */
UNIV_INTERN
void
btr_pcur_free_for_mysql(
/*====================*/
btr_pcur_t* cursor); /* in, own: persistent cursor */
/******************************************************************
btr_pcur_t* cursor); /*!< in, own: persistent cursor */
/**************************************************************//**
Copies the stored position of a pcur to another pcur. */
UNIV_INTERN
void
btr_pcur_copy_stored_position(
/*==========================*/
btr_pcur_t* pcur_receive, /* in: pcur which will receive the
btr_pcur_t* pcur_receive, /*!< in: pcur which will receive the
position info */
btr_pcur_t* pcur_donate); /* in: pcur from which the info is
btr_pcur_t* pcur_donate); /*!< in: pcur from which the info is
copied */
/******************************************************************
/**************************************************************//**
Sets the old_rec_buf field to NULL. */
UNIV_INLINE
void
btr_pcur_init(
/*==========*/
btr_pcur_t* pcur); /* in: persistent cursor */
/******************************************************************
btr_pcur_t* pcur); /*!< in: persistent cursor */
/**************************************************************//**
Initializes and opens a persistent cursor to an index tree. It should be
closed with btr_pcur_close. */
UNIV_INLINE
void
btr_pcur_open(
/*==========*/
dict_index_t* index, /* in: index */
const dtuple_t* tuple, /* in: tuple on which search done */
ulint mode, /* in: PAGE_CUR_L, ...;
dict_index_t* index, /*!< in: index */
const dtuple_t* tuple, /*!< in: tuple on which search done */
ulint mode, /*!< in: PAGE_CUR_L, ...;
NOTE that if the search is made using a unique
prefix of a record, mode should be
PAGE_CUR_LE, not PAGE_CUR_GE, as the latter
may end up on the previous page from the
record! */
ulint latch_mode,/* in: BTR_SEARCH_LEAF, ... */
btr_pcur_t* cursor, /* in: memory buffer for persistent cursor */
mtr_t* mtr); /* in: mtr */
/******************************************************************
ulint latch_mode,/*!< in: BTR_SEARCH_LEAF, ... */
btr_pcur_t* cursor, /*!< in: memory buffer for persistent cursor */
mtr_t* mtr); /*!< in: mtr */
/**************************************************************//**
Opens an persistent cursor to an index tree without initializing the
cursor. */
UNIV_INLINE
void
btr_pcur_open_with_no_init(
/*=======================*/
dict_index_t* index, /* in: index */
const dtuple_t* tuple, /* in: tuple on which search done */
ulint mode, /* in: PAGE_CUR_L, ...;
dict_index_t* index, /*!< in: index */
const dtuple_t* tuple, /*!< in: tuple on which search done */
ulint mode, /*!< in: PAGE_CUR_L, ...;
NOTE that if the search is made using a unique
prefix of a record, mode should be
PAGE_CUR_LE, not PAGE_CUR_GE, as the latter
may end up on the previous page of the
record! */
ulint latch_mode,/* in: BTR_SEARCH_LEAF, ...;
ulint latch_mode,/*!< in: BTR_SEARCH_LEAF, ...;
NOTE that if has_search_latch != 0 then
we maybe do not acquire a latch on the cursor
page, but assume that the caller uses his
btr search latch to protect the record! */
btr_pcur_t* cursor, /* in: memory buffer for persistent cursor */
ulint has_search_latch,/* in: latch mode the caller
btr_pcur_t* cursor, /*!< in: memory buffer for persistent cursor */
ulint has_search_latch,/*!< in: latch mode the caller
currently has on btr_search_latch:
RW_S_LATCH, or 0 */
mtr_t* mtr); /* in: mtr */
/*********************************************************************
mtr_t* mtr); /*!< in: mtr */
/*****************************************************************//**
Opens a persistent cursor at either end of an index. */
UNIV_INLINE
void
btr_pcur_open_at_index_side(
/*========================*/
ibool from_left, /* in: TRUE if open to the low end,
ibool from_left, /*!< in: TRUE if open to the low end,
FALSE if to the high end */
dict_index_t* index, /* in: index */
ulint latch_mode, /* in: latch mode */
btr_pcur_t* pcur, /* in: cursor */
ibool do_init, /* in: TRUE if should be initialized */
mtr_t* mtr); /* in: mtr */
/******************************************************************
Gets the up_match value for a pcur after a search. */
dict_index_t* index, /*!< in: index */
ulint latch_mode, /*!< in: latch mode */
btr_pcur_t* pcur, /*!< in: cursor */
ibool do_init, /*!< in: TRUE if should be initialized */
mtr_t* mtr); /*!< in: mtr */
/**************************************************************//**
Gets the up_match value for a pcur after a search.
@return number of matched fields at the cursor or to the right if
search mode was PAGE_CUR_GE, otherwise undefined */
UNIV_INLINE
ulint
btr_pcur_get_up_match(
/*==================*/
/* out: number of matched fields at the cursor
or to the right if search mode was PAGE_CUR_GE,
otherwise undefined */
btr_pcur_t* cursor); /* in: memory buffer for persistent cursor */
/******************************************************************
Gets the low_match value for a pcur after a search. */
btr_pcur_t* cursor); /*!< in: memory buffer for persistent cursor */
/**************************************************************//**
Gets the low_match value for a pcur after a search.
@return number of matched fields at the cursor or to the right if
search mode was PAGE_CUR_LE, otherwise undefined */
UNIV_INLINE
ulint
btr_pcur_get_low_match(
/*===================*/
/* out: number of matched fields at the cursor
or to the right if search mode was PAGE_CUR_LE,
otherwise undefined */
btr_pcur_t* cursor); /* in: memory buffer for persistent cursor */
/******************************************************************
btr_pcur_t* cursor); /*!< in: memory buffer for persistent cursor */
/**************************************************************//**
If mode is PAGE_CUR_G or PAGE_CUR_GE, opens a persistent cursor on the first
user record satisfying the search condition, in the case PAGE_CUR_L or
PAGE_CUR_LE, on the last user record. If no such user record exists, then
@ -163,33 +162,33 @@ UNIV_INTERN
void
btr_pcur_open_on_user_rec(
/*======================*/
dict_index_t* index, /* in: index */
const dtuple_t* tuple, /* in: tuple on which search done */
ulint mode, /* in: PAGE_CUR_L, ... */
ulint latch_mode, /* in: BTR_SEARCH_LEAF or
dict_index_t* index, /*!< in: index */
const dtuple_t* tuple, /*!< in: tuple on which search done */
ulint mode, /*!< in: PAGE_CUR_L, ... */
ulint latch_mode, /*!< in: BTR_SEARCH_LEAF or
BTR_MODIFY_LEAF */
btr_pcur_t* cursor, /* in: memory buffer for persistent
btr_pcur_t* cursor, /*!< in: memory buffer for persistent
cursor */
mtr_t* mtr); /* in: mtr */
/**************************************************************************
mtr_t* mtr); /*!< in: mtr */
/**********************************************************************//**
Positions a cursor at a randomly chosen position within a B-tree. */
UNIV_INLINE
void
btr_pcur_open_at_rnd_pos(
/*=====================*/
dict_index_t* index, /* in: index */
ulint latch_mode, /* in: BTR_SEARCH_LEAF, ... */
btr_pcur_t* cursor, /* in/out: B-tree pcur */
mtr_t* mtr); /* in: mtr */
/******************************************************************
dict_index_t* index, /*!< in: index */
ulint latch_mode, /*!< in: BTR_SEARCH_LEAF, ... */
btr_pcur_t* cursor, /*!< in/out: B-tree pcur */
mtr_t* mtr); /*!< in: mtr */
/**************************************************************//**
Frees the possible old_rec_buf buffer of a persistent cursor and sets the
latch mode of the persistent cursor to BTR_NO_LATCHES. */
UNIV_INLINE
void
btr_pcur_close(
/*===========*/
btr_pcur_t* cursor); /* in: persistent cursor */
/******************************************************************
btr_pcur_t* cursor); /*!< in: persistent cursor */
/**************************************************************//**
The position of the cursor is stored by taking an initial segment of the
record the cursor is positioned on, before, or after, and copying it to the
cursor data structure, or just setting a flag if the cursor id before the
@ -200,9 +199,9 @@ UNIV_INTERN
void
btr_pcur_store_position(
/*====================*/
btr_pcur_t* cursor, /* in: persistent cursor */
mtr_t* mtr); /* in: mtr */
/******************************************************************
btr_pcur_t* cursor, /*!< in: persistent cursor */
mtr_t* mtr); /*!< in: mtr */
/**************************************************************//**
Restores the stored position of a persistent cursor bufferfixing the page and
obtaining the specified latches. If the cursor position was saved when the
(1) cursor was positioned on a user record: this function restores the position
@ -213,20 +212,18 @@ infimum;
(3) cursor was positioned on the page supremum: restores to the first record
GREATER than the user record which was the predecessor of the supremum.
(4) cursor was positioned before the first or after the last in an empty tree:
restores to before first or after the last in the tree. */
restores to before first or after the last in the tree.
@return TRUE if the cursor position was stored when it was on a user
record and it can be restored on a user record whose ordering fields
are identical to the ones of the original user record */
UNIV_INTERN
ibool
btr_pcur_restore_position(
/*======================*/
/* out: TRUE if the cursor position
was stored when it was on a user record
and it can be restored on a user record
whose ordering fields are identical to
the ones of the original user record */
ulint latch_mode, /* in: BTR_SEARCH_LEAF, ... */
btr_pcur_t* cursor, /* in: detached persistent cursor */
mtr_t* mtr); /* in: mtr */
/******************************************************************
ulint latch_mode, /*!< in: BTR_SEARCH_LEAF, ... */
btr_pcur_t* cursor, /*!< in: detached persistent cursor */
mtr_t* mtr); /*!< in: mtr */
/**************************************************************//**
If the latch mode of the cursor is BTR_LEAF_SEARCH or BTR_LEAF_MODIFY,
releases the page latch and bufferfix reserved by the cursor.
NOTE! In the case of BTR_LEAF_MODIFY, there should not exist changes
@ -236,33 +233,33 @@ UNIV_INTERN
void
btr_pcur_release_leaf(
/*==================*/
btr_pcur_t* cursor, /* in: persistent cursor */
mtr_t* mtr); /* in: mtr */
/*************************************************************
Gets the rel_pos field for a cursor whose position has been stored. */
btr_pcur_t* cursor, /*!< in: persistent cursor */
mtr_t* mtr); /*!< in: mtr */
/*********************************************************//**
Gets the rel_pos field for a cursor whose position has been stored.
@return BTR_PCUR_ON, ... */
UNIV_INLINE
ulint
btr_pcur_get_rel_pos(
/*=================*/
/* out: BTR_PCUR_ON, ... */
const btr_pcur_t* cursor);/* in: persistent cursor */
/*************************************************************
const btr_pcur_t* cursor);/*!< in: persistent cursor */
/*********************************************************//**
Sets the mtr field for a pcur. */
UNIV_INLINE
void
btr_pcur_set_mtr(
/*=============*/
btr_pcur_t* cursor, /* in: persistent cursor */
mtr_t* mtr); /* in, own: mtr */
/*************************************************************
Gets the mtr field for a pcur. */
btr_pcur_t* cursor, /*!< in: persistent cursor */
mtr_t* mtr); /*!< in, own: mtr */
/*********************************************************//**
Gets the mtr field for a pcur.
@return mtr */
UNIV_INLINE
mtr_t*
btr_pcur_get_mtr(
/*=============*/
/* out: mtr */
btr_pcur_t* cursor); /* in: persistent cursor */
/******************************************************************
btr_pcur_t* cursor); /*!< in: persistent cursor */
/**************************************************************//**
Commits the pcur mtr and sets the pcur latch mode to BTR_NO_LATCHES,
that is, the cursor becomes detached. If there have been modifications
to the page where pcur is positioned, this can be used instead of
@ -272,68 +269,65 @@ UNIV_INLINE
void
btr_pcur_commit(
/*============*/
btr_pcur_t* pcur); /* in: persistent cursor */
/******************************************************************
btr_pcur_t* pcur); /*!< in: persistent cursor */
/**************************************************************//**
Differs from btr_pcur_commit in that we can specify the mtr to commit. */
UNIV_INLINE
void
btr_pcur_commit_specify_mtr(
/*========================*/
btr_pcur_t* pcur, /* in: persistent cursor */
mtr_t* mtr); /* in: mtr to commit */
/******************************************************************
Tests if a cursor is detached: that is the latch mode is BTR_NO_LATCHES. */
btr_pcur_t* pcur, /*!< in: persistent cursor */
mtr_t* mtr); /*!< in: mtr to commit */
/**************************************************************//**
Tests if a cursor is detached: that is the latch mode is BTR_NO_LATCHES.
@return TRUE if detached */
UNIV_INLINE
ibool
btr_pcur_is_detached(
/*=================*/
/* out: TRUE if detached */
btr_pcur_t* pcur); /* in: persistent cursor */
/*************************************************************
btr_pcur_t* pcur); /*!< in: persistent cursor */
/*********************************************************//**
Moves the persistent cursor to the next record in the tree. If no records are
left, the cursor stays 'after last in tree'. */
left, the cursor stays 'after last in tree'.
@return TRUE if the cursor was not after last in tree */
UNIV_INLINE
ibool
btr_pcur_move_to_next(
/*==================*/
/* out: TRUE if the cursor was not after last
in tree */
btr_pcur_t* cursor, /* in: persistent cursor; NOTE that the
btr_pcur_t* cursor, /*!< in: persistent cursor; NOTE that the
function may release the page latch */
mtr_t* mtr); /* in: mtr */
/*************************************************************
mtr_t* mtr); /*!< in: mtr */
/*********************************************************//**
Moves the persistent cursor to the previous record in the tree. If no records
are left, the cursor stays 'before first in tree'. */
are left, the cursor stays 'before first in tree'.
@return TRUE if the cursor was not before first in tree */
UNIV_INTERN
ibool
btr_pcur_move_to_prev(
/*==================*/
/* out: TRUE if the cursor was not before first
in tree */
btr_pcur_t* cursor, /* in: persistent cursor; NOTE that the
btr_pcur_t* cursor, /*!< in: persistent cursor; NOTE that the
function may release the page latch */
mtr_t* mtr); /* in: mtr */
/*************************************************************
mtr_t* mtr); /*!< in: mtr */
/*********************************************************//**
Moves the persistent cursor to the last record on the same page. */
UNIV_INLINE
void
btr_pcur_move_to_last_on_page(
/*==========================*/
btr_pcur_t* cursor, /* in: persistent cursor */
mtr_t* mtr); /* in: mtr */
/*************************************************************
btr_pcur_t* cursor, /*!< in: persistent cursor */
mtr_t* mtr); /*!< in: mtr */
/*********************************************************//**
Moves the persistent cursor to the next user record in the tree. If no user
records are left, the cursor ends up 'after last in tree'. */
records are left, the cursor ends up 'after last in tree'.
@return TRUE if the cursor moved forward, ending on a user record */
UNIV_INLINE
ibool
btr_pcur_move_to_next_user_rec(
/*===========================*/
/* out: TRUE if the cursor moved forward,
ending on a user record */
btr_pcur_t* cursor, /* in: persistent cursor; NOTE that the
btr_pcur_t* cursor, /*!< in: persistent cursor; NOTE that the
function may release the page latch */
mtr_t* mtr); /* in: mtr */
/*************************************************************
mtr_t* mtr); /*!< in: mtr */
/*********************************************************//**
Moves the persistent cursor to the first record on the next page.
Releases the latch on the current page, and bufferunfixes it.
Note that there must not be modifications on the current page,
@ -342,10 +336,10 @@ UNIV_INTERN
void
btr_pcur_move_to_next_page(
/*=======================*/
btr_pcur_t* cursor, /* in: persistent cursor; must be on the
btr_pcur_t* cursor, /*!< in: persistent cursor; must be on the
last record of the current page */
mtr_t* mtr); /* in: mtr */
/*************************************************************
mtr_t* mtr); /*!< in: mtr */
/*********************************************************//**
Moves the persistent cursor backward if it is on the first record
of the page. Releases the latch on the current page, and bufferunfixes
it. Note that to prevent a possible deadlock, the operation first
@ -359,119 +353,117 @@ UNIV_INTERN
void
btr_pcur_move_backward_from_page(
/*=============================*/
btr_pcur_t* cursor, /* in: persistent cursor, must be on the
btr_pcur_t* cursor, /*!< in: persistent cursor, must be on the
first record of the current page */
mtr_t* mtr); /* in: mtr */
mtr_t* mtr); /*!< in: mtr */
#ifdef UNIV_DEBUG
/*************************************************************
Returns the btr cursor component of a persistent cursor. */
/*********************************************************//**
Returns the btr cursor component of a persistent cursor.
@return pointer to btr cursor component */
UNIV_INLINE
btr_cur_t*
btr_pcur_get_btr_cur(
/*=================*/
/* out: pointer to
btr cursor component */
const btr_pcur_t* cursor); /* in: persistent cursor */
/*************************************************************
Returns the page cursor component of a persistent cursor. */
const btr_pcur_t* cursor); /*!< in: persistent cursor */
/*********************************************************//**
Returns the page cursor component of a persistent cursor.
@return pointer to page cursor component */
UNIV_INLINE
page_cur_t*
btr_pcur_get_page_cur(
/*==================*/
/* out: pointer to
page cursor component */
const btr_pcur_t* cursor); /* in: persistent cursor */
const btr_pcur_t* cursor); /*!< in: persistent cursor */
#else /* UNIV_DEBUG */
# define btr_pcur_get_btr_cur(cursor) (&(cursor)->btr_cur)
# define btr_pcur_get_page_cur(cursor) (&(cursor)->btr_cur.page_cur)
#endif /* UNIV_DEBUG */
/*************************************************************
Returns the page of a persistent cursor. */
/*********************************************************//**
Returns the page of a persistent cursor.
@return pointer to the page */
UNIV_INLINE
page_t*
btr_pcur_get_page(
/*==============*/
/* out: pointer to the page */
btr_pcur_t* cursor);/* in: persistent cursor */
/*************************************************************
Returns the buffer block of a persistent cursor. */
btr_pcur_t* cursor);/*!< in: persistent cursor */
/*********************************************************//**
Returns the buffer block of a persistent cursor.
@return pointer to the block */
UNIV_INLINE
buf_block_t*
btr_pcur_get_block(
/*===============*/
/* out: pointer to the block */
btr_pcur_t* cursor);/* in: persistent cursor */
/*************************************************************
Returns the record of a persistent cursor. */
btr_pcur_t* cursor);/*!< in: persistent cursor */
/*********************************************************//**
Returns the record of a persistent cursor.
@return pointer to the record */
UNIV_INLINE
rec_t*
btr_pcur_get_rec(
/*=============*/
/* out: pointer to the record */
btr_pcur_t* cursor);/* in: persistent cursor */
/*************************************************************
btr_pcur_t* cursor);/*!< in: persistent cursor */
/*********************************************************//**
Checks if the persistent cursor is on a user record. */
UNIV_INLINE
ibool
btr_pcur_is_on_user_rec(
/*====================*/
const btr_pcur_t* cursor);/* in: persistent cursor */
/*************************************************************
const btr_pcur_t* cursor);/*!< in: persistent cursor */
/*********************************************************//**
Checks if the persistent cursor is after the last user record on
a page. */
UNIV_INLINE
ibool
btr_pcur_is_after_last_on_page(
/*===========================*/
const btr_pcur_t* cursor);/* in: persistent cursor */
/*************************************************************
const btr_pcur_t* cursor);/*!< in: persistent cursor */
/*********************************************************//**
Checks if the persistent cursor is before the first user record on
a page. */
UNIV_INLINE
ibool
btr_pcur_is_before_first_on_page(
/*=============================*/
const btr_pcur_t* cursor);/* in: persistent cursor */
/*************************************************************
const btr_pcur_t* cursor);/*!< in: persistent cursor */
/*********************************************************//**
Checks if the persistent cursor is before the first user record in
the index tree. */
UNIV_INLINE
ibool
btr_pcur_is_before_first_in_tree(
/*=============================*/
btr_pcur_t* cursor, /* in: persistent cursor */
mtr_t* mtr); /* in: mtr */
/*************************************************************
btr_pcur_t* cursor, /*!< in: persistent cursor */
mtr_t* mtr); /*!< in: mtr */
/*********************************************************//**
Checks if the persistent cursor is after the last user record in
the index tree. */
UNIV_INLINE
ibool
btr_pcur_is_after_last_in_tree(
/*===========================*/
btr_pcur_t* cursor, /* in: persistent cursor */
mtr_t* mtr); /* in: mtr */
/*************************************************************
btr_pcur_t* cursor, /*!< in: persistent cursor */
mtr_t* mtr); /*!< in: mtr */
/*********************************************************//**
Moves the persistent cursor to the next record on the same page. */
UNIV_INLINE
void
btr_pcur_move_to_next_on_page(
/*==========================*/
btr_pcur_t* cursor);/* in/out: persistent cursor */
/*************************************************************
btr_pcur_t* cursor);/*!< in/out: persistent cursor */
/*********************************************************//**
Moves the persistent cursor to the previous record on the same page. */
UNIV_INLINE
void
btr_pcur_move_to_prev_on_page(
/*==========================*/
btr_pcur_t* cursor);/* in/out: persistent cursor */
btr_pcur_t* cursor);/*!< in/out: persistent cursor */
/* The persistent B-tree cursor structure. This is used mainly for SQL
selects, updates, and deletes. */
struct btr_pcur_struct{
btr_cur_t btr_cur; /* a B-tree cursor */
ulint latch_mode; /* see TODO note below!
btr_cur_t btr_cur; /*!< a B-tree cursor */
ulint latch_mode; /*!< see TODO note below!
BTR_SEARCH_LEAF, BTR_MODIFY_LEAF,
BTR_MODIFY_TREE, or BTR_NO_LATCHES,
depending on the latching state of
@ -482,28 +474,28 @@ struct btr_pcur_struct{
detached; it can be restored to
attached if the old position was
stored in old_rec */
ulint old_stored; /* BTR_PCUR_OLD_STORED
ulint old_stored; /*!< BTR_PCUR_OLD_STORED
or BTR_PCUR_OLD_NOT_STORED */
rec_t* old_rec; /* if cursor position is stored,
rec_t* old_rec; /*!< if cursor position is stored,
contains an initial segment of the
latest record cursor was positioned
either on, before, or after */
ulint old_n_fields; /* number of fields in old_rec */
ulint rel_pos; /* BTR_PCUR_ON, BTR_PCUR_BEFORE, or
ulint old_n_fields; /*!< number of fields in old_rec */
ulint rel_pos; /*!< BTR_PCUR_ON, BTR_PCUR_BEFORE, or
BTR_PCUR_AFTER, depending on whether
cursor was on, before, or after the
old_rec record */
buf_block_t* block_when_stored;/* buffer block when the position was
stored */
ib_uint64_t modify_clock; /* the modify clock value of the
ib_uint64_t modify_clock; /*!< the modify clock value of the
buffer block when the cursor position
was stored */
ulint pos_state; /* see TODO note below!
ulint pos_state; /*!< see TODO note below!
BTR_PCUR_IS_POSITIONED,
BTR_PCUR_WAS_POSITIONED,
BTR_PCUR_NOT_POSITIONED */
ulint search_mode; /* PAGE_CUR_G, ... */
trx_t* trx_if_known; /* the transaction, if we know it;
ulint search_mode; /*!< PAGE_CUR_G, ... */
trx_t* trx_if_known; /*!< the transaction, if we know it;
otherwise this field is not defined;
can ONLY BE USED in error prints in
fatal assertion failures! */
@ -511,12 +503,12 @@ struct btr_pcur_struct{
/* NOTE that the following fields may possess dynamically allocated
memory which should be freed if not needed anymore! */
mtr_t* mtr; /* NULL, or this field may contain
mtr_t* mtr; /*!< NULL, or this field may contain
a mini-transaction which holds the
latch on the cursor page */
byte* old_rec_buf; /* NULL, or a dynamically allocated
byte* old_rec_buf; /*!< NULL, or a dynamically allocated
buffer for old_rec */
ulint buf_size; /* old_rec_buf size if old_rec_buf
ulint buf_size; /*!< old_rec_buf size if old_rec_buf
is not NULL */
};

View File

@ -16,21 +16,22 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
/******************************************************
/**************************************************//**
@file include/btr0pcur.ic
The index tree persistent cursor
Created 2/23/1996 Heikki Tuuri
*******************************************************/
/*************************************************************
Gets the rel_pos field for a cursor whose position has been stored. */
/*********************************************************//**
Gets the rel_pos field for a cursor whose position has been stored.
@return BTR_PCUR_ON, ... */
UNIV_INLINE
ulint
btr_pcur_get_rel_pos(
/*=================*/
/* out: BTR_PCUR_ON, ... */
const btr_pcur_t* cursor) /* in: persistent cursor */
const btr_pcur_t* cursor) /*!< in: persistent cursor */
{
ut_ad(cursor);
ut_ad(cursor->old_rec);
@ -41,28 +42,28 @@ btr_pcur_get_rel_pos(
return(cursor->rel_pos);
}
/*************************************************************
/*********************************************************//**
Sets the mtr field for a pcur. */
UNIV_INLINE
void
btr_pcur_set_mtr(
/*=============*/
btr_pcur_t* cursor, /* in: persistent cursor */
mtr_t* mtr) /* in, own: mtr */
btr_pcur_t* cursor, /*!< in: persistent cursor */
mtr_t* mtr) /*!< in, own: mtr */
{
ut_ad(cursor);
cursor->mtr = mtr;
}
/*************************************************************
Gets the mtr field for a pcur. */
/*********************************************************//**
Gets the mtr field for a pcur.
@return mtr */
UNIV_INLINE
mtr_t*
btr_pcur_get_mtr(
/*=============*/
/* out: mtr */
btr_pcur_t* cursor) /* in: persistent cursor */
btr_pcur_t* cursor) /*!< in: persistent cursor */
{
ut_ad(cursor);
@ -70,69 +71,67 @@ btr_pcur_get_mtr(
}
#ifdef UNIV_DEBUG
/*************************************************************
Returns the btr cursor component of a persistent cursor. */
/*********************************************************//**
Returns the btr cursor component of a persistent cursor.
@return pointer to btr cursor component */
UNIV_INLINE
btr_cur_t*
btr_pcur_get_btr_cur(
/*=================*/
/* out: pointer to
btr cursor component */
const btr_pcur_t* cursor) /* in: persistent cursor */
const btr_pcur_t* cursor) /*!< in: persistent cursor */
{
const btr_cur_t* btr_cur = &cursor->btr_cur;
return((btr_cur_t*) btr_cur);
}
/*************************************************************
Returns the page cursor component of a persistent cursor. */
/*********************************************************//**
Returns the page cursor component of a persistent cursor.
@return pointer to page cursor component */
UNIV_INLINE
page_cur_t*
btr_pcur_get_page_cur(
/*==================*/
/* out: pointer to page cursor
component */
const btr_pcur_t* cursor) /* in: persistent cursor */
const btr_pcur_t* cursor) /*!< in: persistent cursor */
{
return(btr_cur_get_page_cur(btr_pcur_get_btr_cur(cursor)));
}
#endif /* UNIV_DEBUG */
/*************************************************************
Returns the page of a persistent cursor. */
/*********************************************************//**
Returns the page of a persistent cursor.
@return pointer to the page */
UNIV_INLINE
page_t*
btr_pcur_get_page(
/*==============*/
/* out: pointer to the page */
btr_pcur_t* cursor) /* in: persistent cursor */
btr_pcur_t* cursor) /*!< in: persistent cursor */
{
ut_ad(cursor->pos_state == BTR_PCUR_IS_POSITIONED);
return(btr_cur_get_page(btr_pcur_get_btr_cur(cursor)));
}
/*************************************************************
Returns the buffer block of a persistent cursor. */
/*********************************************************//**
Returns the buffer block of a persistent cursor.
@return pointer to the block */
UNIV_INLINE
buf_block_t*
btr_pcur_get_block(
/*===============*/
/* out: pointer to the block */
btr_pcur_t* cursor) /* in: persistent cursor */
btr_pcur_t* cursor) /*!< in: persistent cursor */
{
ut_ad(cursor->pos_state == BTR_PCUR_IS_POSITIONED);
return(btr_cur_get_block(btr_pcur_get_btr_cur(cursor)));
}
/*************************************************************
Returns the record of a persistent cursor. */
/*********************************************************//**
Returns the record of a persistent cursor.
@return pointer to the record */
UNIV_INLINE
rec_t*
btr_pcur_get_rec(
/*=============*/
/* out: pointer to the record */
btr_pcur_t* cursor) /* in: persistent cursor */
btr_pcur_t* cursor) /*!< in: persistent cursor */
{
ut_ad(cursor->pos_state == BTR_PCUR_IS_POSITIONED);
ut_ad(cursor->latch_mode != BTR_NO_LATCHES);
@ -140,16 +139,15 @@ btr_pcur_get_rec(
return(btr_cur_get_rec(btr_pcur_get_btr_cur(cursor)));
}
/******************************************************************
Gets the up_match value for a pcur after a search. */
/**************************************************************//**
Gets the up_match value for a pcur after a search.
@return number of matched fields at the cursor or to the right if
search mode was PAGE_CUR_GE, otherwise undefined */
UNIV_INLINE
ulint
btr_pcur_get_up_match(
/*==================*/
/* out: number of matched fields at the cursor
or to the right if search mode was PAGE_CUR_GE,
otherwise undefined */
btr_pcur_t* cursor) /* in: memory buffer for persistent cursor */
btr_pcur_t* cursor) /*!< in: memory buffer for persistent cursor */
{
btr_cur_t* btr_cursor;
@ -163,16 +161,15 @@ btr_pcur_get_up_match(
return(btr_cursor->up_match);
}
/******************************************************************
Gets the low_match value for a pcur after a search. */
/**************************************************************//**
Gets the low_match value for a pcur after a search.
@return number of matched fields at the cursor or to the right if
search mode was PAGE_CUR_LE, otherwise undefined */
UNIV_INLINE
ulint
btr_pcur_get_low_match(
/*===================*/
/* out: number of matched fields at the cursor
or to the right if search mode was PAGE_CUR_LE,
otherwise undefined */
btr_pcur_t* cursor) /* in: memory buffer for persistent cursor */
btr_pcur_t* cursor) /*!< in: memory buffer for persistent cursor */
{
btr_cur_t* btr_cursor;
@ -185,14 +182,14 @@ btr_pcur_get_low_match(
return(btr_cursor->low_match);
}
/*************************************************************
/*********************************************************//**
Checks if the persistent cursor is after the last user record on
a page. */
UNIV_INLINE
ibool
btr_pcur_is_after_last_on_page(
/*===========================*/
const btr_pcur_t* cursor) /* in: persistent cursor */
const btr_pcur_t* cursor) /*!< in: persistent cursor */
{
ut_ad(cursor->pos_state == BTR_PCUR_IS_POSITIONED);
ut_ad(cursor->latch_mode != BTR_NO_LATCHES);
@ -200,14 +197,14 @@ btr_pcur_is_after_last_on_page(
return(page_cur_is_after_last(btr_pcur_get_page_cur(cursor)));
}
/*************************************************************
/*********************************************************//**
Checks if the persistent cursor is before the first user record on
a page. */
UNIV_INLINE
ibool
btr_pcur_is_before_first_on_page(
/*=============================*/
const btr_pcur_t* cursor) /* in: persistent cursor */
const btr_pcur_t* cursor) /*!< in: persistent cursor */
{
ut_ad(cursor->pos_state == BTR_PCUR_IS_POSITIONED);
ut_ad(cursor->latch_mode != BTR_NO_LATCHES);
@ -215,13 +212,13 @@ btr_pcur_is_before_first_on_page(
return(page_cur_is_before_first(btr_pcur_get_page_cur(cursor)));
}
/*************************************************************
/*********************************************************//**
Checks if the persistent cursor is on a user record. */
UNIV_INLINE
ibool
btr_pcur_is_on_user_rec(
/*====================*/
const btr_pcur_t* cursor) /* in: persistent cursor */
const btr_pcur_t* cursor) /*!< in: persistent cursor */
{
ut_ad(cursor->pos_state == BTR_PCUR_IS_POSITIONED);
ut_ad(cursor->latch_mode != BTR_NO_LATCHES);
@ -235,15 +232,15 @@ btr_pcur_is_on_user_rec(
return(TRUE);
}
/*************************************************************
/*********************************************************//**
Checks if the persistent cursor is before the first user record in
the index tree. */
UNIV_INLINE
ibool
btr_pcur_is_before_first_in_tree(
/*=============================*/
btr_pcur_t* cursor, /* in: persistent cursor */
mtr_t* mtr) /* in: mtr */
btr_pcur_t* cursor, /*!< in: persistent cursor */
mtr_t* mtr) /*!< in: mtr */
{
ut_ad(cursor->pos_state == BTR_PCUR_IS_POSITIONED);
ut_ad(cursor->latch_mode != BTR_NO_LATCHES);
@ -256,15 +253,15 @@ btr_pcur_is_before_first_in_tree(
return(page_cur_is_before_first(btr_pcur_get_page_cur(cursor)));
}
/*************************************************************
/*********************************************************//**
Checks if the persistent cursor is after the last user record in
the index tree. */
UNIV_INLINE
ibool
btr_pcur_is_after_last_in_tree(
/*===========================*/
btr_pcur_t* cursor, /* in: persistent cursor */
mtr_t* mtr) /* in: mtr */
btr_pcur_t* cursor, /*!< in: persistent cursor */
mtr_t* mtr) /*!< in: mtr */
{
ut_ad(cursor->pos_state == BTR_PCUR_IS_POSITIONED);
ut_ad(cursor->latch_mode != BTR_NO_LATCHES);
@ -277,13 +274,13 @@ btr_pcur_is_after_last_in_tree(
return(page_cur_is_after_last(btr_pcur_get_page_cur(cursor)));
}
/*************************************************************
/*********************************************************//**
Moves the persistent cursor to the next record on the same page. */
UNIV_INLINE
void
btr_pcur_move_to_next_on_page(
/*==========================*/
btr_pcur_t* cursor) /* in/out: persistent cursor */
btr_pcur_t* cursor) /*!< in/out: persistent cursor */
{
ut_ad(cursor->pos_state == BTR_PCUR_IS_POSITIONED);
ut_ad(cursor->latch_mode != BTR_NO_LATCHES);
@ -293,13 +290,13 @@ btr_pcur_move_to_next_on_page(
cursor->old_stored = BTR_PCUR_OLD_NOT_STORED;
}
/*************************************************************
/*********************************************************//**
Moves the persistent cursor to the previous record on the same page. */
UNIV_INLINE
void
btr_pcur_move_to_prev_on_page(
/*==========================*/
btr_pcur_t* cursor) /* in/out: persistent cursor */
btr_pcur_t* cursor) /*!< in/out: persistent cursor */
{
ut_ad(cursor->pos_state == BTR_PCUR_IS_POSITIONED);
ut_ad(cursor->latch_mode != BTR_NO_LATCHES);
@ -309,14 +306,14 @@ btr_pcur_move_to_prev_on_page(
cursor->old_stored = BTR_PCUR_OLD_NOT_STORED;
}
/*************************************************************
/*********************************************************//**
Moves the persistent cursor to the last record on the same page. */
UNIV_INLINE
void
btr_pcur_move_to_last_on_page(
/*==========================*/
btr_pcur_t* cursor, /* in: persistent cursor */
mtr_t* mtr) /* in: mtr */
btr_pcur_t* cursor, /*!< in: persistent cursor */
mtr_t* mtr) /*!< in: mtr */
{
UT_NOT_USED(mtr);
ut_ad(cursor->latch_mode != BTR_NO_LATCHES);
@ -327,18 +324,17 @@ btr_pcur_move_to_last_on_page(
cursor->old_stored = BTR_PCUR_OLD_NOT_STORED;
}
/*************************************************************
/*********************************************************//**
Moves the persistent cursor to the next user record in the tree. If no user
records are left, the cursor ends up 'after last in tree'. */
records are left, the cursor ends up 'after last in tree'.
@return TRUE if the cursor moved forward, ending on a user record */
UNIV_INLINE
ibool
btr_pcur_move_to_next_user_rec(
/*===========================*/
/* out: TRUE if the cursor moved forward,
ending on a user record */
btr_pcur_t* cursor, /* in: persistent cursor; NOTE that the
btr_pcur_t* cursor, /*!< in: persistent cursor; NOTE that the
function may release the page latch */
mtr_t* mtr) /* in: mtr */
mtr_t* mtr) /*!< in: mtr */
{
ut_ad(cursor->pos_state == BTR_PCUR_IS_POSITIONED);
ut_ad(cursor->latch_mode != BTR_NO_LATCHES);
@ -364,18 +360,17 @@ loop:
goto loop;
}
/*************************************************************
/*********************************************************//**
Moves the persistent cursor to the next record in the tree. If no records are
left, the cursor stays 'after last in tree'. */
left, the cursor stays 'after last in tree'.
@return TRUE if the cursor was not after last in tree */
UNIV_INLINE
ibool
btr_pcur_move_to_next(
/*==================*/
/* out: TRUE if the cursor was not after last
in tree */
btr_pcur_t* cursor, /* in: persistent cursor; NOTE that the
btr_pcur_t* cursor, /*!< in: persistent cursor; NOTE that the
function may release the page latch */
mtr_t* mtr) /* in: mtr */
mtr_t* mtr) /*!< in: mtr */
{
ut_ad(cursor->pos_state == BTR_PCUR_IS_POSITIONED);
ut_ad(cursor->latch_mode != BTR_NO_LATCHES);
@ -399,7 +394,7 @@ btr_pcur_move_to_next(
return(TRUE);
}
/******************************************************************
/**************************************************************//**
Commits the pcur mtr and sets the pcur latch mode to BTR_NO_LATCHES,
that is, the cursor becomes detached. If there have been modifications
to the page where pcur is positioned, this can be used instead of
@ -409,7 +404,7 @@ UNIV_INLINE
void
btr_pcur_commit(
/*============*/
btr_pcur_t* pcur) /* in: persistent cursor */
btr_pcur_t* pcur) /*!< in: persistent cursor */
{
ut_a(pcur->pos_state == BTR_PCUR_IS_POSITIONED);
@ -420,14 +415,14 @@ btr_pcur_commit(
pcur->pos_state = BTR_PCUR_WAS_POSITIONED;
}
/******************************************************************
/**************************************************************//**
Differs from btr_pcur_commit in that we can specify the mtr to commit. */
UNIV_INLINE
void
btr_pcur_commit_specify_mtr(
/*========================*/
btr_pcur_t* pcur, /* in: persistent cursor */
mtr_t* mtr) /* in: mtr to commit */
btr_pcur_t* pcur, /*!< in: persistent cursor */
mtr_t* mtr) /*!< in: mtr to commit */
{
ut_a(pcur->pos_state == BTR_PCUR_IS_POSITIONED);
@ -438,13 +433,13 @@ btr_pcur_commit_specify_mtr(
pcur->pos_state = BTR_PCUR_WAS_POSITIONED;
}
/******************************************************************
/**************************************************************//**
Sets the pcur latch mode to BTR_NO_LATCHES. */
UNIV_INLINE
void
btr_pcur_detach(
/*============*/
btr_pcur_t* pcur) /* in: persistent cursor */
btr_pcur_t* pcur) /*!< in: persistent cursor */
{
ut_a(pcur->pos_state == BTR_PCUR_IS_POSITIONED);
@ -453,14 +448,14 @@ btr_pcur_detach(
pcur->pos_state = BTR_PCUR_WAS_POSITIONED;
}
/******************************************************************
Tests if a cursor is detached: that is the latch mode is BTR_NO_LATCHES. */
/**************************************************************//**
Tests if a cursor is detached: that is the latch mode is BTR_NO_LATCHES.
@return TRUE if detached */
UNIV_INLINE
ibool
btr_pcur_is_detached(
/*=================*/
/* out: TRUE if detached */
btr_pcur_t* pcur) /* in: persistent cursor */
btr_pcur_t* pcur) /*!< in: persistent cursor */
{
if (pcur->latch_mode == BTR_NO_LATCHES) {
@ -470,37 +465,37 @@ btr_pcur_is_detached(
return(FALSE);
}
/******************************************************************
/**************************************************************//**
Sets the old_rec_buf field to NULL. */
UNIV_INLINE
void
btr_pcur_init(
/*==========*/
btr_pcur_t* pcur) /* in: persistent cursor */
btr_pcur_t* pcur) /*!< in: persistent cursor */
{
pcur->old_stored = BTR_PCUR_OLD_NOT_STORED;
pcur->old_rec_buf = NULL;
pcur->old_rec = NULL;
}
/******************************************************************
/**************************************************************//**
Initializes and opens a persistent cursor to an index tree. It should be
closed with btr_pcur_close. */
UNIV_INLINE
void
btr_pcur_open(
/*==========*/
dict_index_t* index, /* in: index */
const dtuple_t* tuple, /* in: tuple on which search done */
ulint mode, /* in: PAGE_CUR_L, ...;
dict_index_t* index, /*!< in: index */
const dtuple_t* tuple, /*!< in: tuple on which search done */
ulint mode, /*!< in: PAGE_CUR_L, ...;
NOTE that if the search is made using a unique
prefix of a record, mode should be
PAGE_CUR_LE, not PAGE_CUR_GE, as the latter
may end up on the previous page from the
record! */
ulint latch_mode,/* in: BTR_SEARCH_LEAF, ... */
btr_pcur_t* cursor, /* in: memory buffer for persistent cursor */
mtr_t* mtr) /* in: mtr */
ulint latch_mode,/*!< in: BTR_SEARCH_LEAF, ... */
btr_pcur_t* cursor, /*!< in: memory buffer for persistent cursor */
mtr_t* mtr) /*!< in: mtr */
{
btr_cur_t* btr_cursor;
@ -522,31 +517,31 @@ btr_pcur_open(
cursor->trx_if_known = NULL;
}
/******************************************************************
/**************************************************************//**
Opens an persistent cursor to an index tree without initializing the
cursor. */
UNIV_INLINE
void
btr_pcur_open_with_no_init(
/*=======================*/
dict_index_t* index, /* in: index */
const dtuple_t* tuple, /* in: tuple on which search done */
ulint mode, /* in: PAGE_CUR_L, ...;
dict_index_t* index, /*!< in: index */
const dtuple_t* tuple, /*!< in: tuple on which search done */
ulint mode, /*!< in: PAGE_CUR_L, ...;
NOTE that if the search is made using a unique
prefix of a record, mode should be
PAGE_CUR_LE, not PAGE_CUR_GE, as the latter
may end up on the previous page of the
record! */
ulint latch_mode,/* in: BTR_SEARCH_LEAF, ...;
ulint latch_mode,/*!< in: BTR_SEARCH_LEAF, ...;
NOTE that if has_search_latch != 0 then
we maybe do not acquire a latch on the cursor
page, but assume that the caller uses his
btr search latch to protect the record! */
btr_pcur_t* cursor, /* in: memory buffer for persistent cursor */
ulint has_search_latch,/* in: latch mode the caller
btr_pcur_t* cursor, /*!< in: memory buffer for persistent cursor */
ulint has_search_latch,/*!< in: latch mode the caller
currently has on btr_search_latch:
RW_S_LATCH, or 0 */
mtr_t* mtr) /* in: mtr */
mtr_t* mtr) /*!< in: mtr */
{
btr_cur_t* btr_cursor;
@ -566,19 +561,19 @@ btr_pcur_open_with_no_init(
cursor->trx_if_known = NULL;
}
/*********************************************************************
/*****************************************************************//**
Opens a persistent cursor at either end of an index. */
UNIV_INLINE
void
btr_pcur_open_at_index_side(
/*========================*/
ibool from_left, /* in: TRUE if open to the low end,
ibool from_left, /*!< in: TRUE if open to the low end,
FALSE if to the high end */
dict_index_t* index, /* in: index */
ulint latch_mode, /* in: latch mode */
btr_pcur_t* pcur, /* in: cursor */
ibool do_init, /* in: TRUE if should be initialized */
mtr_t* mtr) /* in: mtr */
dict_index_t* index, /*!< in: index */
ulint latch_mode, /*!< in: latch mode */
btr_pcur_t* pcur, /*!< in: cursor */
ibool do_init, /*!< in: TRUE if should be initialized */
mtr_t* mtr) /*!< in: mtr */
{
pcur->latch_mode = latch_mode;
@ -601,16 +596,16 @@ btr_pcur_open_at_index_side(
pcur->trx_if_known = NULL;
}
/**************************************************************************
/**********************************************************************//**
Positions a cursor at a randomly chosen position within a B-tree. */
UNIV_INLINE
void
btr_pcur_open_at_rnd_pos(
/*=====================*/
dict_index_t* index, /* in: index */
ulint latch_mode, /* in: BTR_SEARCH_LEAF, ... */
btr_pcur_t* cursor, /* in/out: B-tree pcur */
mtr_t* mtr) /* in: mtr */
dict_index_t* index, /*!< in: index */
ulint latch_mode, /*!< in: BTR_SEARCH_LEAF, ... */
btr_pcur_t* cursor, /*!< in/out: B-tree pcur */
mtr_t* mtr) /*!< in: mtr */
{
/* Initialize the cursor */
@ -627,14 +622,14 @@ btr_pcur_open_at_rnd_pos(
cursor->trx_if_known = NULL;
}
/******************************************************************
/**************************************************************//**
Frees the possible memory heap of a persistent cursor and sets the latch
mode of the persistent cursor to BTR_NO_LATCHES. */
UNIV_INLINE
void
btr_pcur_close(
/*===========*/
btr_pcur_t* cursor) /* in: persistent cursor */
btr_pcur_t* cursor) /*!< in: persistent cursor */
{
if (cursor->old_rec_buf != NULL) {

View File

@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
/************************************************************************
/********************************************************************//**
@file include/btr0sea.h
The index tree adaptive search
Created 2/17/1996 Heikki Tuuri
@ -33,81 +34,81 @@ Created 2/17/1996 Heikki Tuuri
#include "mtr0mtr.h"
#include "ha0ha.h"
/*********************************************************************
/*****************************************************************//**
Creates and initializes the adaptive search system at a database start. */
UNIV_INTERN
void
btr_search_sys_create(
/*==================*/
ulint hash_size); /* in: hash index hash table size */
ulint hash_size); /*!< in: hash index hash table size */
/************************************************************************
/********************************************************************//**
Disable the adaptive hash search system and empty the index. */
UNIV_INTERN
void
btr_search_disable(void);
/*====================*/
/************************************************************************
/********************************************************************//**
Enable the adaptive hash search system. */
UNIV_INTERN
void
btr_search_enable(void);
/*====================*/
/************************************************************************
Returns search info for an index. */
/********************************************************************//**
Returns search info for an index.
@return search info; search mutex reserved */
UNIV_INLINE
btr_search_t*
btr_search_get_info(
/*================*/
/* out: search info; search mutex reserved */
dict_index_t* index); /* in: index */
/*********************************************************************
Creates and initializes a search info struct. */
dict_index_t* index); /*!< in: index */
/*****************************************************************//**
Creates and initializes a search info struct.
@return own: search info struct */
UNIV_INTERN
btr_search_t*
btr_search_info_create(
/*===================*/
/* out, own: search info struct */
mem_heap_t* heap); /* in: heap where created */
/*********************************************************************
mem_heap_t* heap); /*!< in: heap where created */
/*****************************************************************//**
Returns the value of ref_count. The value is protected by
btr_search_latch. */
btr_search_latch.
@return ref_count value. */
UNIV_INTERN
ulint
btr_search_info_get_ref_count(
/*==========================*/
/* out: ref_count value. */
btr_search_t* info); /* in: search info. */
/*************************************************************************
btr_search_t* info); /*!< in: search info. */
/*********************************************************************//**
Updates the search info. */
UNIV_INLINE
void
btr_search_info_update(
/*===================*/
dict_index_t* index, /* in: index of the cursor */
btr_cur_t* cursor);/* in: cursor which was just positioned */
/**********************************************************************
dict_index_t* index, /*!< in: index of the cursor */
btr_cur_t* cursor);/*!< in: cursor which was just positioned */
/******************************************************************//**
Tries to guess the right search position based on the hash search info
of the index. Note that if mode is PAGE_CUR_LE, which is used in inserts,
and the function returns TRUE, then cursor->up_match and cursor->low_match
both have sensible values. */
both have sensible values.
@return TRUE if succeeded */
UNIV_INTERN
ibool
btr_search_guess_on_hash(
/*=====================*/
/* out: TRUE if succeeded */
dict_index_t* index, /* in: index */
btr_search_t* info, /* in: index search info */
const dtuple_t* tuple, /* in: logical record */
ulint mode, /* in: PAGE_CUR_L, ... */
ulint latch_mode, /* in: BTR_SEARCH_LEAF, ... */
btr_cur_t* cursor, /* out: tree cursor */
ulint has_search_latch,/* in: latch mode the caller
dict_index_t* index, /*!< in: index */
btr_search_t* info, /*!< in: index search info */
const dtuple_t* tuple, /*!< in: logical record */
ulint mode, /*!< in: PAGE_CUR_L, ... */
ulint latch_mode, /*!< in: BTR_SEARCH_LEAF, ... */
btr_cur_t* cursor, /*!< out: tree cursor */
ulint has_search_latch,/*!< in: latch mode the caller
currently has on btr_search_latch:
RW_S_LATCH, RW_X_LATCH, or 0 */
mtr_t* mtr); /* in: mtr */
/************************************************************************
mtr_t* mtr); /*!< in: mtr */
/********************************************************************//**
Moves or deletes hash entries for moved records. If new_page is already hashed,
then the hash index for page, if any, is dropped. If new_page is not hashed,
and page is hashed, then a new hash index is built to new_page with the same
@ -116,139 +117,153 @@ UNIV_INTERN
void
btr_search_move_or_delete_hash_entries(
/*===================================*/
buf_block_t* new_block, /* in: records are copied
buf_block_t* new_block, /*!< in: records are copied
to this page */
buf_block_t* block, /* in: index page from which
buf_block_t* block, /*!< in: index page from which
records were copied, and the
copied records will be deleted
from this page */
dict_index_t* index); /* in: record descriptor */
/************************************************************************
dict_index_t* index); /*!< in: record descriptor */
/********************************************************************//**
Drops a page hash index. */
UNIV_INTERN
void
btr_search_drop_page_hash_index(
/*============================*/
buf_block_t* block); /* in: block containing index page,
buf_block_t* block); /*!< in: block containing index page,
s- or x-latched, or an index page
for which we know that
block->buf_fix_count == 0 */
/************************************************************************
Drops a page hash index based on index */
UNIV_INTERN
void
btr_search_drop_page_hash_index_on_index(
/*=====================================*/
dict_index_t* index); /* in: record descriptor */
/********************************************************************//**
Drops a page hash index when a page is freed from a fseg to the file system.
Drops possible hash index if the page happens to be in the buffer pool. */
UNIV_INTERN
void
btr_search_drop_page_hash_when_freed(
/*=================================*/
ulint space, /* in: space id */
ulint zip_size, /* in: compressed page size in bytes
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 */
/************************************************************************
ulint page_no); /*!< in: page number */
/********************************************************************//**
Updates the page hash index when a single record is inserted on a page. */
UNIV_INTERN
void
btr_search_update_hash_node_on_insert(
/*==================================*/
btr_cur_t* cursor);/* in: cursor which was positioned to the
btr_cur_t* cursor);/*!< in: cursor which was positioned to the
place to insert using btr_cur_search_...,
and the new record has been inserted next
to the cursor */
/************************************************************************
/********************************************************************//**
Updates the page hash index when a single record is inserted on a page. */
UNIV_INTERN
void
btr_search_update_hash_on_insert(
/*=============================*/
btr_cur_t* cursor);/* in: cursor which was positioned to the
btr_cur_t* cursor);/*!< in: cursor which was positioned to the
place to insert using btr_cur_search_...,
and the new record has been inserted next
to the cursor */
/************************************************************************
/********************************************************************//**
Updates the page hash index when a single record is deleted from a page. */
UNIV_INTERN
void
btr_search_update_hash_on_delete(
/*=============================*/
btr_cur_t* cursor);/* in: cursor which was positioned on the
btr_cur_t* cursor);/*!< in: cursor which was positioned on the
record to delete using btr_cur_search_...,
the record is not yet deleted */
/************************************************************************
Validates the search system. */
/********************************************************************//**
Validates the search system.
@return TRUE if ok */
UNIV_INTERN
ibool
btr_search_validate(void);
/*======================*/
/* out: TRUE if ok */
/* Flag: has the search system been enabled?
/** Flag: has the search system been enabled?
Protected by btr_search_latch and btr_search_enabled_mutex. */
extern char btr_search_enabled;
/* The search info struct in an index */
/** The search info struct in an index */
struct btr_search_struct{
ulint ref_count; /* Number of blocks in this index tree
ulint ref_count; /*!< Number of blocks in this index tree
that have search index built
i.e. block->index points to this index.
Protected by btr_search_latch except
when during initialization in
btr_search_info_create(). */
/* The following fields are not protected by any latch.
/* @{ The following fields are not protected by any latch.
Unfortunately, this means that they must be aligned to
the machine word, i.e., they cannot be turned into bit-fields. */
buf_block_t* root_guess;/* the root page frame when it was last time
buf_block_t* root_guess;/*!< the root page frame when it was last time
fetched, or NULL */
ulint hash_analysis; /* when this exceeds BTR_SEARCH_HASH_ANALYSIS,
the hash analysis starts; this is reset if no
ulint hash_analysis; /*!< when this exceeds
BTR_SEARCH_HASH_ANALYSIS, the hash
analysis starts; this is reset if no
success noticed */
ibool last_hash_succ; /* TRUE if the last search would have
ibool last_hash_succ; /*!< TRUE if the last search would have
succeeded, or did succeed, using the hash
index; NOTE that the value here is not exact:
it is not calculated for every search, and the
calculation itself is not always accurate! */
ulint n_hash_potential;
/* number of consecutive searches
/*!< number of consecutive searches
which would have succeeded, or did succeed,
using the hash index;
the range is 0 .. BTR_SEARCH_BUILD_LIMIT + 5 */
/*----------------------*/
ulint n_fields; /* recommended prefix length for hash search:
/* @} */
/*---------------------- @{ */
ulint n_fields; /*!< recommended prefix length for hash search:
number of full fields */
ulint n_bytes; /* recommended prefix: number of bytes in
an incomplete field;
see also BTR_PAGE_MAX_REC_SIZE */
ibool left_side; /* TRUE or FALSE, depending on whether
ulint n_bytes; /*!< recommended prefix: number of bytes in
an incomplete field
@see BTR_PAGE_MAX_REC_SIZE */
ibool left_side; /*!< TRUE or FALSE, depending on whether
the leftmost record of several records with
the same prefix should be indexed in the
hash index */
/*----------------------*/
/*---------------------- @} */
#ifdef UNIV_SEARCH_PERF_STAT
ulint n_hash_succ; /* number of successful hash searches thus
ulint n_hash_succ; /*!< number of successful hash searches thus
far */
ulint n_hash_fail; /* number of failed hash searches */
ulint n_patt_succ; /* number of successful pattern searches thus
ulint n_hash_fail; /*!< number of failed hash searches */
ulint n_patt_succ; /*!< number of successful pattern searches thus
far */
ulint n_searches; /* number of searches */
ulint n_searches; /*!< number of searches */
#endif /* UNIV_SEARCH_PERF_STAT */
#ifdef UNIV_DEBUG
ulint magic_n; /* magic number */
ulint magic_n; /*!< magic number @see BTR_SEARCH_MAGIC_N */
/** value of btr_search_struct::magic_n, used in assertions */
# define BTR_SEARCH_MAGIC_N 1112765
#endif /* UNIV_DEBUG */
};
/* The hash index system */
/** The hash index system */
typedef struct btr_search_sys_struct btr_search_sys_t;
/** The hash index system */
struct btr_search_sys_struct{
hash_table_t* hash_index;
hash_table_t* hash_index; /*!< the adaptive hash index,
mapping dtuple_fold values
to rec_t pointers on index pages */
};
/** The adaptive hash index */
extern btr_search_sys_t* btr_search_sys;
/* The latch protecting the adaptive search system: this latch protects the
/** @brief The latch protecting the adaptive search system
This latch protects the
(1) hash index;
(2) columns of a record to which we have a pointer in the hash index;
@ -259,36 +274,34 @@ but does NOT protect:
Bear in mind (3) and (4) when using the hash index.
*/
extern rw_lock_t* btr_search_latch_temp;
/** The latch protecting the adaptive search system */
#define btr_search_latch (*btr_search_latch_temp)
#ifdef UNIV_SEARCH_PERF_STAT
/** Number of successful adaptive hash index lookups */
extern ulint btr_search_n_succ;
/** Number of failed adaptive hash index lookups */
extern ulint btr_search_n_hash_fail;
#endif /* UNIV_SEARCH_PERF_STAT */
/* After change in n_fields or n_bytes in info, this many rounds are waited
/** After change in n_fields or n_bytes in info, this many rounds are waited
before starting the hash analysis again: this is to save CPU time when there
is no hope in building a hash index. */
#define BTR_SEARCH_HASH_ANALYSIS 17
/* Limit of consecutive searches for trying a search shortcut on the search
/** Limit of consecutive searches for trying a search shortcut on the search
pattern */
#define BTR_SEARCH_ON_PATTERN_LIMIT 3
/* Limit of consecutive searches for trying a search shortcut using the hash
index */
/** Limit of consecutive searches for trying a search shortcut using
the hash index */
#define BTR_SEARCH_ON_HASH_LIMIT 3
/* We do this many searches before trying to keep the search latch over calls
from MySQL. If we notice someone waiting for the latch, we again set this
much timeout. This is to reduce contention. */
/** We do this many searches before trying to keep the search latch
over calls from MySQL. If we notice someone waiting for the latch, we
again set this much timeout. This is to reduce contention. */
#define BTR_SEA_TIMEOUT 10000
#ifndef UNIV_NONINL

View File

@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
/************************************************************************
/********************************************************************//**
@file include/btr0sea.ic
The index tree adaptive search
Created 2/17/1996 Heikki Tuuri
@ -26,37 +27,37 @@ Created 2/17/1996 Heikki Tuuri
#include "btr0cur.h"
#include "buf0buf.h"
/*************************************************************************
/*********************************************************************//**
Updates the search info. */
UNIV_INTERN
void
btr_search_info_update_slow(
/*========================*/
btr_search_t* info, /* in/out: search info */
btr_cur_t* cursor);/* in: cursor which was just positioned */
btr_search_t* info, /*!< in/out: search info */
btr_cur_t* cursor);/*!< in: cursor which was just positioned */
/************************************************************************
Returns search info for an index. */
/********************************************************************//**
Returns search info for an index.
@return search info; search mutex reserved */
UNIV_INLINE
btr_search_t*
btr_search_get_info(
/*================*/
/* out: search info; search mutex reserved */
dict_index_t* index) /* in: index */
dict_index_t* index) /*!< in: index */
{
ut_ad(index);
return(index->search_info);
}
/*************************************************************************
/*********************************************************************//**
Updates the search info. */
UNIV_INLINE
void
btr_search_info_update(
/*===================*/
dict_index_t* index, /* in: index of the cursor */
btr_cur_t* cursor) /* in: cursor which was just positioned */
dict_index_t* index, /*!< in: index of the cursor */
btr_cur_t* cursor) /*!< in: cursor which was just positioned */
{
btr_search_t* info;

View File

@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
/************************************************************************
/********************************************************************//**
@file include/btr0types.h
The index tree general types
Created 2/17/1996 Heikki Tuuri
@ -30,16 +31,19 @@ Created 2/17/1996 Heikki Tuuri
#include "rem0types.h"
#include "page0types.h"
/** Persistent cursor */
typedef struct btr_pcur_struct btr_pcur_t;
/** B-tree cursor */
typedef struct btr_cur_struct btr_cur_t;
/** B-tree search information for the adaptive hash index */
typedef struct btr_search_struct btr_search_t;
/* The size of a reference to data stored on a different page.
/** The size of a reference to data stored on a different page.
The reference is stored at the end of the prefix of the field
in the index record. */
#define BTR_EXTERN_FIELD_REF_SIZE 20
/* A BLOB field reference full of zero, for use in assertions and tests.
/** A BLOB field reference full of zero, for use in assertions and tests.
Initially, BLOB field references are set to zero, in
dtuple_convert_big_rec(). */
extern const byte field_ref_zero[BTR_EXTERN_FIELD_REF_SIZE];

View File

@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
/******************************************************
/**************************************************//**
@file include/buf0buddy.h
Binary buddy allocator for compressed pages
Created December 2006 by Marko Makela
@ -33,7 +34,7 @@ Created December 2006 by Marko Makela
#include "univ.i"
#include "buf0types.h"
/**************************************************************************
/**********************************************************************//**
Allocate a block. The thread calling this function must hold
buf_pool_mutex and must not hold buf_pool_zip_mutex or any
block->mutex. The buf_pool_mutex may only be released and reacquired
@ -41,30 +42,29 @@ if lru != NULL. This function should only be used for allocating
compressed page frames or control blocks (buf_page_t). Allocated
control blocks must be properly initialized immediately after
buf_buddy_alloc() has returned the memory, before releasing
buf_pool_mutex. */
buf_pool_mutex.
@return allocated block, possibly NULL if lru == NULL */
UNIV_INLINE
void*
buf_buddy_alloc(
/*============*/
/* out: allocated block,
possibly NULL if lru == NULL */
ulint size, /* in: block size, up to UNIV_PAGE_SIZE */
ibool* lru, /* in: pointer to a variable that will be assigned
ulint size, /*!< in: block size, up to UNIV_PAGE_SIZE */
ibool* lru, /*!< in: pointer to a variable that will be assigned
TRUE if storage was allocated from the LRU list
and buf_pool_mutex was temporarily released,
or NULL if the LRU list should not be used */
ibool have_page_hash_mutex)
__attribute__((malloc));
/**************************************************************************
/**********************************************************************//**
Release a block. */
UNIV_INLINE
void
buf_buddy_free(
/*===========*/
void* buf, /* in: block to be freed, must not be
void* buf, /*!< in: block to be freed, must not be
pointed to by the buffer pool */
ulint size, /* in: block size, up to UNIV_PAGE_SIZE */
ulint size, /*!< in: block size, up to UNIV_PAGE_SIZE */
ibool have_page_hash_mutex)
__attribute__((nonnull));
@ -78,6 +78,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.

View File

@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
/******************************************************
/**************************************************//**
@file include/buf0buddy.ic
Binary buddy allocator for compressed pages
Created December 2006 by Marko Makela
@ -32,47 +33,45 @@ Created December 2006 by Marko Makela
#include "ut0ut.h"
#include "sync0sync.h"
/**************************************************************************
/**********************************************************************//**
Allocate a block. The thread calling this function must hold
buf_pool_mutex and must not hold buf_pool_zip_mutex or any block->mutex.
The buf_pool_mutex may only be released and reacquired if lru != NULL. */
The buf_pool_mutex may only be released and reacquired if lru != NULL.
@return allocated block, possibly NULL if lru==NULL */
UNIV_INTERN
void*
buf_buddy_alloc_low(
/*================*/
/* out: allocated block,
possibly NULL if lru==NULL */
ulint i, /* in: index of buf_pool->zip_free[],
ulint i, /*!< in: index of buf_pool->zip_free[],
or BUF_BUDDY_SIZES */
ibool* lru, /* in: pointer to a variable that will be assigned
ibool* lru, /*!< in: pointer to a variable that will be assigned
TRUE if storage was allocated from the LRU list
and buf_pool_mutex was temporarily released,
or NULL if the LRU list should not be used */
ibool have_page_hash_mutex)
__attribute__((malloc));
/**************************************************************************
/**********************************************************************//**
Deallocate a block. */
UNIV_INTERN
void
buf_buddy_free_low(
/*===============*/
void* buf, /* in: block to be freed, must not be
void* buf, /*!< in: block to be freed, must not be
pointed to by the buffer pool */
ulint i, /* in: index of buf_pool->zip_free[],
ulint i, /*!< in: index of buf_pool->zip_free[],
or BUF_BUDDY_SIZES */
ibool have_page_hash_mutex)
__attribute__((nonnull));
/**************************************************************************
Get the index of buf_pool->zip_free[] for a given block size. */
/**********************************************************************//**
Get the index of buf_pool->zip_free[] for a given block size.
@return index of buf_pool->zip_free[], or BUF_BUDDY_SIZES */
UNIV_INLINE
ulint
buf_buddy_get_slot(
/*===============*/
/* out: index of buf_pool->zip_free[],
or BUF_BUDDY_SIZES */
ulint size) /* in: block size */
ulint size) /*!< in: block size */
{
ulint i;
ulint s;
@ -84,7 +83,7 @@ buf_buddy_get_slot(
return(i);
}
/**************************************************************************
/**********************************************************************//**
Allocate a block. The thread calling this function must hold
buf_pool_mutex and must not hold buf_pool_zip_mutex or any
block->mutex. The buf_pool_mutex may only be released and reacquired
@ -92,15 +91,14 @@ if lru != NULL. This function should only be used for allocating
compressed page frames or control blocks (buf_page_t). Allocated
control blocks must be properly initialized immediately after
buf_buddy_alloc() has returned the memory, before releasing
buf_pool_mutex. */
buf_pool_mutex.
@return allocated block, possibly NULL if lru == NULL */
UNIV_INLINE
void*
buf_buddy_alloc(
/*============*/
/* out: allocated block,
possibly NULL if lru == NULL */
ulint size, /* in: block size, up to UNIV_PAGE_SIZE */
ibool* lru, /* in: pointer to a variable that will be assigned
ulint size, /*!< in: block size, up to UNIV_PAGE_SIZE */
ibool* lru, /*!< in: pointer to a variable that will be assigned
TRUE if storage was allocated from the LRU list
and buf_pool_mutex was temporarily released,
or NULL if the LRU list should not be used */
@ -111,15 +109,15 @@ buf_buddy_alloc(
return(buf_buddy_alloc_low(buf_buddy_get_slot(size), lru, have_page_hash_mutex));
}
/**************************************************************************
/**********************************************************************//**
Deallocate a block. */
UNIV_INLINE
void
buf_buddy_free(
/*===========*/
void* buf, /* in: block to be freed, must not be
void* buf, /*!< in: block to be freed, must not be
pointed to by the buffer pool */
ulint size, /* in: block size, up to UNIV_PAGE_SIZE */
ulint size, /*!< in: block size, up to UNIV_PAGE_SIZE */
ibool have_page_hash_mutex)
{
//ut_ad(buf_pool_mutex_own());

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
/******************************************************
/**************************************************//**
@file include/buf0flu.h
The database buffer pool flush algorithm
Created 11/5/1995 Heikki Tuuri
@ -26,25 +27,26 @@ Created 11/5/1995 Heikki Tuuri
#define buf0flu_h
#include "univ.i"
#include "buf0types.h"
#include "ut0byte.h"
#ifndef UNIV_HOTBACKUP
#include "mtr0types.h"
#include "buf0types.h"
/************************************************************************
/********************************************************************//**
Remove a block from the flush list of modified blocks. */
UNIV_INTERN
void
buf_flush_remove(
/*=============*/
buf_page_t* bpage); /* in: pointer to the block in question */
/************************************************************************
buf_page_t* bpage); /*!< in: pointer to the block in question */
/********************************************************************//**
Updates the flush system data structures when a write is completed. */
UNIV_INTERN
void
buf_flush_write_complete(
/*=====================*/
buf_page_t* bpage); /* in: pointer to the block in question */
/*************************************************************************
buf_page_t* bpage); /*!< in: pointer to the block in question */
/*********************************************************************//**
Flushes pages from the end of the LRU list if there is too small
a margin of replaceable pages there. */
UNIV_INTERN
@ -52,50 +54,50 @@ void
buf_flush_free_margin(
/*=======================*/
ibool wait);
/************************************************************************
#endif /* !UNIV_HOTBACKUP */
/********************************************************************//**
Initializes a page for writing to the tablespace. */
UNIV_INTERN
void
buf_flush_init_for_writing(
/*=======================*/
byte* page, /* in/out: page */
void* page_zip_, /* in/out: compressed page, or NULL */
ib_uint64_t newest_lsn); /* in: newest modification lsn
byte* page, /*!< in/out: page */
void* page_zip_, /*!< in/out: compressed page, or NULL */
ib_uint64_t newest_lsn); /*!< in: newest modification lsn
to the page */
/***********************************************************************
#ifndef UNIV_HOTBACKUP
/*******************************************************************//**
This utility flushes dirty blocks from the end of the LRU list or flush_list.
NOTE 1: in the case of an LRU flush the calling thread may own latches to
pages: to avoid deadlocks, this function must be written so that it cannot
end up waiting for these latches! NOTE 2: in the case of a flush list flush,
the calling thread is not allowed to own any latches on pages! */
the calling thread is not allowed to own any latches on pages!
@return number of blocks for which the write request was queued;
ULINT_UNDEFINED if there was a flush of the same type already running */
UNIV_INTERN
ulint
buf_flush_batch(
/*============*/
/* out: number of blocks for which the
write request was queued;
ULINT_UNDEFINED if there was a flush
of the same type already running */
enum buf_flush flush_type, /* in: BUF_FLUSH_LRU or
enum buf_flush flush_type, /*!< in: BUF_FLUSH_LRU or
BUF_FLUSH_LIST; if BUF_FLUSH_LIST,
then the caller must not own any
latches on pages */
ulint min_n, /* in: wished minimum mumber of blocks
ulint min_n, /*!< in: wished minimum mumber of blocks
flushed (it is not guaranteed that the
actual number is that big, though) */
ib_uint64_t lsn_limit); /* in the case BUF_FLUSH_LIST all
ib_uint64_t lsn_limit); /*!< in the case BUF_FLUSH_LIST all
blocks whose oldest_modification is
smaller than this should be flushed
(if their number does not exceed
min_n), otherwise ignored */
/**********************************************************************
/******************************************************************//**
Waits until a flush batch of the given type ends */
UNIV_INTERN
void
buf_flush_wait_batch_end(
/*=====================*/
enum buf_flush type); /* in: BUF_FLUSH_LRU or BUF_FLUSH_LIST */
/************************************************************************
enum buf_flush type); /*!< in: BUF_FLUSH_LRU or BUF_FLUSH_LIST */
/********************************************************************//**
This function should be called at a mini-transaction commit, if a page was
modified in it. Puts the block to the list of modified blocks, if it not
already in it. */
@ -103,46 +105,85 @@ UNIV_INLINE
void
buf_flush_note_modification(
/*========================*/
buf_block_t* block, /* in: block which is modified */
mtr_t* mtr); /* in: mtr */
/************************************************************************
buf_block_t* block, /*!< in: block which is modified */
mtr_t* mtr); /*!< in: mtr */
/********************************************************************//**
This function should be called when recovery has modified a buffer page. */
UNIV_INLINE
void
buf_flush_recv_note_modification(
/*=============================*/
buf_block_t* block, /* in: block which is modified */
ib_uint64_t start_lsn, /* in: start lsn of the first mtr in a
buf_block_t* block, /*!< in: block which is modified */
ib_uint64_t start_lsn, /*!< in: start lsn of the first mtr in a
set of mtr's */
ib_uint64_t end_lsn); /* in: end lsn of the last mtr in the
ib_uint64_t end_lsn); /*!< in: end lsn of the last mtr in the
set of mtr's */
/************************************************************************
/********************************************************************//**
Returns TRUE if the file page block is immediately suitable for replacement,
i.e., transition FILE_PAGE => NOT_USED allowed. */
i.e., transition FILE_PAGE => NOT_USED allowed.
@return TRUE if can replace immediately */
UNIV_INTERN
ibool
buf_flush_ready_for_replace(
/*========================*/
/* out: TRUE if can replace immediately */
buf_page_t* bpage); /* in: buffer control block, must be
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. */
/******************************************************************//**
Validates the flush list.
@return TRUE if ok */
UNIV_INTERN
ibool
buf_flush_validate(void);
/*====================*/
/* out: TRUE if ok */
#endif /* UNIV_DEBUG || UNIV_BUF_DEBUG */
/* When buf_flush_free_margin is called, it tries to make this many blocks
/** When buf_flush_free_margin is called, it tries to make this many blocks
available to replacement in the free list and at the end of the LRU list (to
make sure that a read-ahead batch can be read efficiently in a single
sweep). */
#define BUF_FLUSH_FREE_BLOCK_MARGIN (5 + BUF_READ_AHEAD_AREA)
/** Extra margin to apply above BUF_FLUSH_FREE_BLOCK_MARGIN */
#define BUF_FLUSH_EXTRA_MARGIN (BUF_FLUSH_FREE_BLOCK_MARGIN / 4 + 100)
#endif /* !UNIV_HOTBACKUP */
#ifndef UNIV_NONINL
#include "buf0flu.ic"

View File

@ -16,23 +16,25 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
/******************************************************
/**************************************************//**
@file include/buf0flu.ic
The database buffer pool flush algorithm
Created 11/5/1995 Heikki Tuuri
*******************************************************/
#ifndef UNIV_HOTBACKUP
#include "buf0buf.h"
#include "mtr0mtr.h"
/************************************************************************
/********************************************************************//**
Inserts a modified block into the flush list. */
UNIV_INTERN
void
buf_flush_insert_into_flush_list(
/*=============================*/
buf_block_t* block); /* in/out: block which is modified */
/************************************************************************
buf_block_t* block); /*!< in/out: block which is modified */
/********************************************************************//**
Inserts a modified block into the flush list in the right sorted position.
This function is used by recovery, because there the modifications do not
necessarily come in the order of lsn's. */
@ -40,9 +42,9 @@ UNIV_INTERN
void
buf_flush_insert_sorted_into_flush_list(
/*====================================*/
buf_block_t* block); /* in/out: block which is modified */
buf_block_t* block); /*!< in/out: block which is modified */
/************************************************************************
/********************************************************************//**
This function should be called at a mini-transaction commit, if a page was
modified in it. Puts the block to the list of modified blocks, if it is not
already in it. */
@ -50,8 +52,8 @@ UNIV_INLINE
void
buf_flush_note_modification(
/*========================*/
buf_block_t* block, /* in: block which is modified */
mtr_t* mtr) /* in: mtr */
buf_block_t* block, /*!< in: block which is modified */
mtr_t* mtr) /*!< in: mtr */
{
ibool use_LRU_mutex = FALSE;
@ -97,16 +99,16 @@ buf_flush_note_modification(
mutex_exit(&LRU_list_mutex);
}
/************************************************************************
/********************************************************************//**
This function should be called when recovery has modified a buffer page. */
UNIV_INLINE
void
buf_flush_recv_note_modification(
/*=============================*/
buf_block_t* block, /* in: block which is modified */
ib_uint64_t start_lsn, /* in: start lsn of the first mtr in a
buf_block_t* block, /*!< in: block which is modified */
ib_uint64_t start_lsn, /*!< in: start lsn of the first mtr in a
set of mtr's */
ib_uint64_t end_lsn) /* in: end lsn of the last mtr in the
ib_uint64_t end_lsn) /*!< in: end lsn of the last mtr in the
set of mtr's */
{
ibool use_LRU_mutex = FALSE;
@ -150,3 +152,4 @@ buf_flush_recv_note_modification(
mutex_exit(&LRU_list_mutex);
mutex_exit(&(block->mutex));
}
#endif /* !UNIV_HOTBACKUP */

View File

@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
/******************************************************
/**************************************************//**
@file include/buf0lru.h
The database buffer pool LRU replacement algorithm
Created 11/5/1995 Heikki Tuuri
@ -41,7 +42,7 @@ enum buf_lru_free_block_status {
BUF_LRU_NOT_FREED
};
/**********************************************************************
/******************************************************************//**
Tries to remove LRU flushed blocks from the end of the LRU list and put them
to the free list. This is beneficial for the efficiency of the insert buffer
operation, as flushed pages from non-unique non-clustered indexes are here
@ -53,28 +54,27 @@ UNIV_INTERN
void
buf_LRU_try_free_flushed_blocks(void);
/*==================================*/
/**********************************************************************
/******************************************************************//**
Returns TRUE if less than 25 % of the buffer pool is available. This can be
used in heuristics to prevent huge transactions eating up the whole buffer
pool for their locks. */
pool for their locks.
@return TRUE if less than 25 % of buffer pool left */
UNIV_INTERN
ibool
buf_LRU_buf_pool_running_out(void);
/*==============================*/
/* out: TRUE if less than 25 % of buffer pool
left */
/*#######################################################################
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)
/**********************************************************************
/******************************************************************//**
Invalidates all pages belonging to a given tablespace when we are deleting
the data file(s) of that tablespace. A PROBLEM: if readahead is being started,
what guarantees that it will not try to read in pages after this operation has
@ -83,25 +83,25 @@ UNIV_INTERN
void
buf_LRU_invalidate_tablespace(
/*==========================*/
ulint id); /* in: space id */
/**********************************************************************
ulint id); /*!< in: space id */
/******************************************************************//**
Gets the minimum LRU_position field for the blocks in an initial segment
(determined by BUF_LRU_INITIAL_RATIO) of the LRU list. The limit is not
guaranteed to be precise, because the ulint_clock may wrap around. */
guaranteed to be precise, because the ulint_clock may wrap around.
@return the limit; zero if could not determine it */
UNIV_INTERN
ulint
buf_LRU_get_recent_limit(void);
/*==========================*/
/* out: the limit; zero if could not determine it */
/************************************************************************
/********************************************************************//**
Insert a compressed block into buf_pool->zip_clean in the LRU order. */
UNIV_INTERN
void
buf_LRU_insert_zip_clean(
/*=====================*/
buf_page_t* bpage); /* in: pointer to the block in question */
buf_page_t* bpage); /*!< in: pointer to the block in question */
/**********************************************************************
/******************************************************************//**
Try to free a block. If bpage is a descriptor of a compressed-only
page, the descriptor object will be freed as well.
@ -111,30 +111,29 @@ accessible via bpage.
The caller must hold buf_pool_mutex and buf_page_get_mutex(bpage) and
release these two mutexes after the call. No other
buf_page_get_mutex() may be held when calling this function. */
buf_page_get_mutex() may be held when calling this function.
@return BUF_LRU_FREED if freed, BUF_LRU_CANNOT_RELOCATE or
BUF_LRU_NOT_FREED otherwise. */
UNIV_INTERN
enum buf_lru_free_block_status
buf_LRU_free_block(
/*===============*/
/* out: BUF_LRU_FREED if freed,
BUF_LRU_CANNOT_RELOCATE or
BUF_LRU_NOT_FREED otherwise. */
buf_page_t* bpage, /* in: block to be freed */
ibool zip, /* in: TRUE if should remove also the
buf_page_t* bpage, /*!< in: block to be freed */
ibool zip, /*!< in: TRUE if should remove also the
compressed page of an uncompressed page */
ibool* buf_pool_mutex_released,
/* in: pointer to a variable that will
/*!< in: pointer to a variable that will
be assigned TRUE if buf_pool_mutex
was temporarily released, or NULL */
ibool have_LRU_mutex);
/**********************************************************************
Try to free a replaceable block. */
/******************************************************************//**
Try to free a replaceable block.
@return TRUE if found and freed */
UNIV_INTERN
ibool
buf_LRU_search_and_free_block(
/*==========================*/
/* out: TRUE if found and freed */
ulint n_iterations); /* in: how many times this has been called
ulint n_iterations); /*!< in: how many times this has been called
repeatedly without result: a high value means
that we should search farther; if
n_iterations < 10, then we search
@ -142,71 +141,69 @@ buf_LRU_search_and_free_block(
pages from the end of the LRU list; if
n_iterations < 5, then we will also search
n_iterations / 5 of the unzip_LRU list. */
/**********************************************************************
/******************************************************************//**
Returns a free block from the buf_pool. The block is taken off the
free list. If it is empty, returns NULL. */
free list. If it is empty, returns NULL.
@return a free control block, or NULL if the buf_block->free list is empty */
UNIV_INTERN
buf_block_t*
buf_LRU_get_free_only(void);
/*=======================*/
/* out: a free control block, or NULL
if the buf_block->free list is empty */
/**********************************************************************
/******************************************************************//**
Returns a free block from the buf_pool. The block is taken off the
free list. If it is empty, blocks are moved from the end of the
LRU list to the free list. */
LRU list to the free list.
@return the free control block, in state BUF_BLOCK_READY_FOR_USE */
UNIV_INTERN
buf_block_t*
buf_LRU_get_free_block(
/*===================*/
/* out: the free control block,
in state BUF_BLOCK_READY_FOR_USE */
ulint zip_size); /* in: compressed page size in bytes,
ulint zip_size); /*!< in: compressed page size in bytes,
or 0 if uncompressed tablespace */
/**********************************************************************
/******************************************************************//**
Puts a block back to the free list. */
UNIV_INTERN
void
buf_LRU_block_free_non_file_page(
/*=============================*/
buf_block_t* block, /* in: block, must not contain a file page */
buf_block_t* block, /*!< in: block, must not contain a file page */
ibool have_page_hash_mutex);
/**********************************************************************
/******************************************************************//**
Adds a block to the LRU list. */
UNIV_INTERN
void
buf_LRU_add_block(
/*==============*/
buf_page_t* bpage, /* in: control block */
ibool old); /* in: TRUE if should be put to the old
buf_page_t* bpage, /*!< in: control block */
ibool old); /*!< in: TRUE if should be put to the old
blocks in the LRU list, else put to the
start; if the LRU list is very short, added to
the start regardless of this parameter */
/**********************************************************************
/******************************************************************//**
Adds a block to the LRU list of decompressed zip pages. */
UNIV_INTERN
void
buf_unzip_LRU_add_block(
/*====================*/
buf_block_t* block, /* in: control block */
ibool old); /* in: TRUE if should be put to the end
buf_block_t* block, /*!< in: control block */
ibool old); /*!< in: TRUE if should be put to the end
of the list, else put to the start */
/**********************************************************************
/******************************************************************//**
Moves a block to the start of the LRU list. */
UNIV_INTERN
void
buf_LRU_make_block_young(
/*=====================*/
buf_page_t* bpage); /* in: control block */
/**********************************************************************
buf_page_t* bpage); /*!< in: control block */
/******************************************************************//**
Moves a block to the end of the LRU list. */
UNIV_INTERN
void
buf_LRU_make_block_old(
/*===================*/
buf_page_t* bpage); /* in: control block */
/************************************************************************
buf_page_t* bpage); /*!< in: control block */
/********************************************************************//**
Update the historical stats that we are collecting for LRU eviction
policy at the end of each interval. */
UNIV_INTERN
@ -215,15 +212,16 @@ buf_LRU_stat_update(void);
/*=====================*/
#if defined UNIV_DEBUG || defined UNIV_BUF_DEBUG
/**************************************************************************
Validates the LRU list. */
/**********************************************************************//**
Validates the LRU list.
@return TRUE */
UNIV_INTERN
ibool
buf_LRU_validate(void);
/*==================*/
#endif /* UNIV_DEBUG || UNIV_BUF_DEBUG */
#if defined UNIV_DEBUG_PRINT || defined UNIV_DEBUG || defined UNIV_BUF_DEBUG
/**************************************************************************
/**********************************************************************//**
Prints the LRU list. */
UNIV_INTERN
void
@ -231,18 +229,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.
@ -253,10 +251,10 @@ extern buf_LRU_stat_t buf_LRU_stat_cur;
Updated by buf_LRU_stat_update(). Protected by buf_pool_mutex. */
extern buf_LRU_stat_t buf_LRU_stat_sum;
/************************************************************************
/********************************************************************//**
Increments the I/O counter in buf_LRU_stat_cur. */
#define buf_LRU_stat_inc_io() buf_LRU_stat_cur.io++
/************************************************************************
/********************************************************************//**
Increments the page_zip_decompress() counter in buf_LRU_stat_cur. */
#define buf_LRU_stat_inc_unzip() buf_LRU_stat_cur.unzip++

View File

@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
/******************************************************
/**************************************************//**
@file include/buf0lru.ic
The database buffer replacement algorithm
Created 11/5/1995 Heikki Tuuri

View File

@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
/******************************************************
/**************************************************//**
@file include/buf0rea.h
The database buffer read
Created 11/5/1995 Heikki Tuuri
@ -28,22 +29,22 @@ Created 11/5/1995 Heikki Tuuri
#include "univ.i"
#include "buf0types.h"
/************************************************************************
/********************************************************************//**
High-level function which reads a page asynchronously from a file to the
buffer buf_pool if it is not already there. Sets the io_fix flag and sets
an exclusive lock on the buffer frame. The flag is cleared and the x-lock
released by the i/o-handler thread. Does a random read-ahead if it seems
sensible. */
sensible.
@return number of page read requests issued: this can be greater than
1 if read-ahead occurred */
UNIV_INTERN
ulint
buf_read_page(
/*==========*/
/* out: number of page read requests issued: this can
be > 1 if read-ahead occurred */
ulint space, /* in: space id */
ulint zip_size,/* in: compressed page size in bytes, or 0 */
ulint offset);/* in: page number */
/************************************************************************
ulint space, /*!< in: space id */
ulint zip_size,/*!< in: compressed page size in bytes, or 0 */
ulint offset);/*!< in: page number */
/********************************************************************//**
Applies linear read-ahead if in the buf_pool the page is a border page of
a linear read-ahead area and all the pages in the area have been accessed.
Does not read any page if the read-ahead mechanism is not activated. Note
@ -65,17 +66,17 @@ function must be written such that it cannot end up waiting for these
latches!
NOTE 3: the calling thread must want access to the page given: this rule is
set to prevent unintended read-aheads performed by ibuf routines, a situation
which could result in a deadlock if the OS does not support asynchronous io. */
which could result in a deadlock if the OS does not support asynchronous io.
@return number of page read requests issued */
UNIV_INTERN
ulint
buf_read_ahead_linear(
/*==================*/
/* out: number of page read requests issued */
ulint space, /* in: space id */
ulint zip_size,/* in: compressed page size in bytes, or 0 */
ulint offset);/* in: page number of a page; NOTE: the current thread
ulint space, /*!< in: space id */
ulint zip_size,/*!< in: compressed page size in bytes, or 0 */
ulint offset);/*!< in: page number of a page; NOTE: the current thread
must want access to this page (see NOTE 3 above) */
/************************************************************************
/********************************************************************//**
Issues read requests for pages which the ibuf module wants to read in, in
order to contract the insert buffer tree. Technically, this function is like
a read-ahead function. */
@ -83,54 +84,56 @@ UNIV_INTERN
void
buf_read_ibuf_merge_pages(
/*======================*/
ibool sync, /* in: TRUE if the caller
ibool sync, /*!< in: TRUE if the caller
wants this function to wait
for the highest address page
to get read in, before this
function returns */
const ulint* space_ids, /* in: array of space ids */
const ib_int64_t* space_versions,/* in: the spaces must have
const ulint* space_ids, /*!< in: array of space ids */
const ib_int64_t* space_versions,/*!< in: the spaces must have
this version number
(timestamp), otherwise we
discard the read; we use this
to cancel reads if DISCARD +
IMPORT may have changed the
tablespace size */
const ulint* page_nos, /* in: array of page numbers
const ulint* page_nos, /*!< in: array of page numbers
to read, with the highest page
number the last in the
array */
ulint n_stored); /* in: number of elements
ulint n_stored); /*!< in: number of elements
in the arrays */
/************************************************************************
/********************************************************************//**
Issues read requests for pages which recovery wants to read in. */
UNIV_INTERN
void
buf_read_recv_pages(
/*================*/
ibool sync, /* in: TRUE if the caller
ibool sync, /*!< in: TRUE if the caller
wants this function to wait
for the highest address page
to get read in, before this
function returns */
ulint space, /* in: space id */
ulint zip_size, /* in: compressed page size in
ulint space, /*!< in: space id */
ulint zip_size, /*!< in: compressed page size in
bytes, or 0 */
const ulint* page_nos, /* in: array of page numbers
const ulint* page_nos, /*!< in: array of page numbers
to read, with the highest page
number the last in the
array */
ulint n_stored); /* in: number of page numbers
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

View File

@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
/******************************************************
/**************************************************//**
@file include/buf0types.h
The database buffer pool global types for the directory
Created 11/17/1995 Heikki Tuuri
@ -25,46 +26,55 @@ Created 11/17/1995 Heikki Tuuri
#ifndef buf0types_h
#define buf0types_h
/** Buffer page (uncompressed or compressed) */
typedef struct buf_page_struct buf_page_t;
/** Buffer block for which an uncompressed page exists */
typedef struct buf_block_struct buf_block_t;
/** Buffer pool chunk comprising buf_block_t */
typedef struct buf_chunk_struct buf_chunk_t;
/** Buffer pool comprising buf_chunk_t */
typedef struct buf_pool_struct buf_pool_t;
/* The 'type' used of a buffer frame */
/** A buffer frame. @see page_t */
typedef byte buf_frame_t;
/* Flags for flush types */
/** Flags for flush types */
enum buf_flush {
BUF_FLUSH_LRU = 0,
BUF_FLUSH_SINGLE_PAGE,
BUF_FLUSH_LIST,
BUF_FLUSH_N_TYPES /* index of last element + 1 */
BUF_FLUSH_LRU = 0, /*!< flush via the LRU list */
BUF_FLUSH_SINGLE_PAGE, /*!< flush a single page */
BUF_FLUSH_LIST, /*!< flush via the flush list
of dirty blocks */
BUF_FLUSH_N_TYPES /*!< index of last element + 1 */
};
/* Flags for io_fix types */
/** Flags for io_fix types */
enum buf_io_fix {
BUF_IO_NONE = 0, /**< no pending I/O */
BUF_IO_READ, /**< read pending */
BUF_IO_WRITE /**< write pending */
};
/* Parameters of binary buddy system for compressed pages (buf0buddy.h) */
/** Parameters of binary buddy system for compressed pages (buf0buddy.h) */
/* @{ */
#if UNIV_WORD_SIZE <= 4 /* 32-bit system */
/** Base-2 logarithm of the smallest buddy block size */
# define BUF_BUDDY_LOW_SHIFT 6
#else /* 64-bit system */
/** Base-2 logarithm of the smallest buddy block size */
# define BUF_BUDDY_LOW_SHIFT 7
#endif
#define BUF_BUDDY_LOW (1 << BUF_BUDDY_LOW_SHIFT)
/* minimum block size in the binary
/*!< minimum block size in the binary
buddy system; must be at least
sizeof(buf_page_t) */
#define BUF_BUDDY_SIZES (UNIV_PAGE_SIZE_SHIFT - BUF_BUDDY_LOW_SHIFT)
/* number of buddy sizes */
/*!< number of buddy sizes */
/* twice the maximum block size of the buddy system;
/** twice the maximum block size of the buddy system;
the underlying memory is aligned by this amount:
this must be equal to UNIV_PAGE_SIZE */
#define BUF_BUDDY_HIGH (BUF_BUDDY_LOW << BUF_BUDDY_SIZES)
/* @} */
#endif

View File

@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
/************************************************************************
/********************************************************************//**
@file include/data0data.h
SQL data field and tuple
Created 5/30/1994 Heikki Tuuri
@ -32,376 +33,375 @@ Created 5/30/1994 Heikki Tuuri
#include "mem0mem.h"
#include "dict0types.h"
/** Storage for overflow data in a big record, that is, a clustered
index record which needs external storage of data fields */
typedef struct big_rec_struct big_rec_t;
#ifdef UNIV_DEBUG
/*************************************************************************
Gets pointer to the type struct of SQL data field. */
/*********************************************************************//**
Gets pointer to the type struct of SQL data field.
@return pointer to the type struct */
UNIV_INLINE
dtype_t*
dfield_get_type(
/*============*/
/* out: pointer to the type struct */
const dfield_t* field); /* in: SQL data field */
/*************************************************************************
Gets pointer to the data in a field. */
const dfield_t* field); /*!< in: SQL data field */
/*********************************************************************//**
Gets pointer to the data in a field.
@return pointer to data */
UNIV_INLINE
void*
dfield_get_data(
/*============*/
/* out: pointer to data */
const dfield_t* field); /* in: field */
const dfield_t* field); /*!< in: field */
#else /* UNIV_DEBUG */
# define dfield_get_type(field) (&(field)->type)
# define dfield_get_data(field) ((field)->data)
#endif /* UNIV_DEBUG */
/*************************************************************************
/*********************************************************************//**
Sets the type struct of SQL data field. */
UNIV_INLINE
void
dfield_set_type(
/*============*/
dfield_t* field, /* in: SQL data field */
dtype_t* type); /* in: pointer to data type struct */
/*************************************************************************
Gets length of field data. */
dfield_t* field, /*!< in: SQL data field */
dtype_t* type); /*!< in: pointer to data type struct */
/*********************************************************************//**
Gets length of field data.
@return length of data; UNIV_SQL_NULL if SQL null data */
UNIV_INLINE
ulint
dfield_get_len(
/*===========*/
/* out: length of data; UNIV_SQL_NULL if
SQL null data */
const dfield_t* field); /* in: field */
/*************************************************************************
const dfield_t* field); /*!< in: field */
/*********************************************************************//**
Sets length in a field. */
UNIV_INLINE
void
dfield_set_len(
/*===========*/
dfield_t* field, /* in: field */
ulint len); /* in: length or UNIV_SQL_NULL */
/*************************************************************************
Determines if a field is SQL NULL */
dfield_t* field, /*!< in: field */
ulint len); /*!< in: length or UNIV_SQL_NULL */
/*********************************************************************//**
Determines if a field is SQL NULL
@return nonzero if SQL null data */
UNIV_INLINE
ulint
dfield_is_null(
/*===========*/
/* out: nonzero if SQL null data */
const dfield_t* field); /* in: field */
/*************************************************************************
Determines if a field is externally stored */
const dfield_t* field); /*!< in: field */
/*********************************************************************//**
Determines if a field is externally stored
@return nonzero if externally stored */
UNIV_INLINE
ulint
dfield_is_ext(
/*==========*/
/* out: nonzero if externally stored */
const dfield_t* field); /* in: field */
/*************************************************************************
const dfield_t* field); /*!< in: field */
/*********************************************************************//**
Sets the "external storage" flag */
UNIV_INLINE
void
dfield_set_ext(
/*===========*/
dfield_t* field); /* in/out: field */
/*************************************************************************
dfield_t* field); /*!< in/out: field */
/*********************************************************************//**
Sets pointer to the data and length in a field. */
UNIV_INLINE
void
dfield_set_data(
/*============*/
dfield_t* field, /* in: field */
const void* data, /* in: data */
ulint len); /* in: length or UNIV_SQL_NULL */
/*************************************************************************
dfield_t* field, /*!< in: field */
const void* data, /*!< in: data */
ulint len); /*!< in: length or UNIV_SQL_NULL */
/*********************************************************************//**
Sets a data field to SQL NULL. */
UNIV_INLINE
void
dfield_set_null(
/*============*/
dfield_t* field); /* in/out: field */
/**************************************************************************
dfield_t* field); /*!< in/out: field */
/**********************************************************************//**
Writes an SQL null field full of zeros. */
UNIV_INLINE
void
data_write_sql_null(
/*================*/
byte* data, /* in: pointer to a buffer of size len */
ulint len); /* in: SQL null size in bytes */
/*************************************************************************
byte* data, /*!< in: pointer to a buffer of size len */
ulint len); /*!< in: SQL null size in bytes */
/*********************************************************************//**
Copies the data and len fields. */
UNIV_INLINE
void
dfield_copy_data(
/*=============*/
dfield_t* field1, /* out: field to copy to */
const dfield_t* field2);/* in: field to copy from */
/*************************************************************************
dfield_t* field1, /*!< out: field to copy to */
const dfield_t* field2);/*!< in: field to copy from */
/*********************************************************************//**
Copies a data field to another. */
UNIV_INLINE
void
dfield_copy(
/*========*/
dfield_t* field1, /* out: field to copy to */
const dfield_t* field2);/* in: field to copy from */
/*************************************************************************
dfield_t* field1, /*!< out: field to copy to */
const dfield_t* field2);/*!< in: field to copy from */
/*********************************************************************//**
Copies the data pointed to by a data field. */
UNIV_INLINE
void
dfield_dup(
/*=======*/
dfield_t* field, /* in/out: data field */
mem_heap_t* heap); /* in: memory heap where allocated */
/*************************************************************************
Tests if data length and content is equal for two dfields. */
dfield_t* field, /*!< in/out: data field */
mem_heap_t* heap); /*!< in: memory heap where allocated */
/*********************************************************************//**
Tests if data length and content is equal for two dfields.
@return TRUE if equal */
UNIV_INLINE
ibool
dfield_datas_are_binary_equal(
/*==========================*/
/* out: TRUE if equal */
const dfield_t* field1, /* in: field */
const dfield_t* field2);/* in: field */
/*************************************************************************
Tests if dfield data length and content is equal to the given. */
const dfield_t* field1, /*!< in: field */
const dfield_t* field2);/*!< in: field */
/*********************************************************************//**
Tests if dfield data length and content is equal to the given.
@return TRUE if equal */
UNIV_INTERN
ibool
dfield_data_is_binary_equal(
/*========================*/
/* out: TRUE if equal */
const dfield_t* field, /* in: field */
ulint len, /* in: data length or UNIV_SQL_NULL */
const byte* data); /* in: data */
/*************************************************************************
Gets number of fields in a data tuple. */
const dfield_t* field, /*!< in: field */
ulint len, /*!< in: data length or UNIV_SQL_NULL */
const byte* data); /*!< in: data */
/*********************************************************************//**
Gets number of fields in a data tuple.
@return number of fields */
UNIV_INLINE
ulint
dtuple_get_n_fields(
/*================*/
/* out: number of fields */
const dtuple_t* tuple); /* in: tuple */
const dtuple_t* tuple); /*!< in: tuple */
#ifdef UNIV_DEBUG
/*************************************************************************
Gets nth field of a tuple. */
/*********************************************************************//**
Gets nth field of a tuple.
@return nth field */
UNIV_INLINE
dfield_t*
dtuple_get_nth_field(
/*=================*/
/* out: nth field */
const dtuple_t* tuple, /* in: tuple */
ulint n); /* in: index of field */
const dtuple_t* tuple, /*!< in: tuple */
ulint n); /*!< in: index of field */
#else /* UNIV_DEBUG */
# define dtuple_get_nth_field(tuple, n) ((tuple)->fields + (n))
#endif /* UNIV_DEBUG */
/*************************************************************************
Gets info bits in a data tuple. */
/*********************************************************************//**
Gets info bits in a data tuple.
@return info bits */
UNIV_INLINE
ulint
dtuple_get_info_bits(
/*=================*/
/* out: info bits */
const dtuple_t* tuple); /* in: tuple */
/*************************************************************************
const dtuple_t* tuple); /*!< in: tuple */
/*********************************************************************//**
Sets info bits in a data tuple. */
UNIV_INLINE
void
dtuple_set_info_bits(
/*=================*/
dtuple_t* tuple, /* in: tuple */
ulint info_bits); /* in: info bits */
/*************************************************************************
Gets number of fields used in record comparisons. */
dtuple_t* tuple, /*!< in: tuple */
ulint info_bits); /*!< in: info bits */
/*********************************************************************//**
Gets number of fields used in record comparisons.
@return number of fields used in comparisons in rem0cmp.* */
UNIV_INLINE
ulint
dtuple_get_n_fields_cmp(
/*====================*/
/* out: number of fields used in comparisons
in rem0cmp.* */
const dtuple_t* tuple); /* in: tuple */
/*************************************************************************
const dtuple_t* tuple); /*!< in: tuple */
/*********************************************************************//**
Gets number of fields used in record comparisons. */
UNIV_INLINE
void
dtuple_set_n_fields_cmp(
/*====================*/
dtuple_t* tuple, /* in: tuple */
ulint n_fields_cmp); /* in: number of fields used in
dtuple_t* tuple, /*!< in: tuple */
ulint n_fields_cmp); /*!< in: number of fields used in
comparisons in rem0cmp.* */
/**************************************************************
/**********************************************************//**
Creates a data tuple to a memory heap. The default value for number
of fields used in record comparisons for this tuple is n_fields. */
of fields used in record comparisons for this tuple is n_fields.
@return own: created tuple */
UNIV_INLINE
dtuple_t*
dtuple_create(
/*==========*/
/* out, own: created tuple */
mem_heap_t* heap, /* in: memory heap where the tuple
mem_heap_t* heap, /*!< in: memory heap where the tuple
is created */
ulint n_fields); /* in: number of fields */
ulint n_fields); /*!< in: number of fields */
/**************************************************************
/**********************************************************//**
Wrap data fields in a tuple. The default value for number
of fields used in record comparisons for this tuple is n_fields. */
of fields used in record comparisons for this tuple is n_fields.
@return data tuple */
UNIV_INLINE
const dtuple_t*
dtuple_from_fields(
/*===============*/
/* out: data tuple */
dtuple_t* tuple, /* in: storage for data tuple */
const dfield_t* fields, /* in: fields */
ulint n_fields); /* in: number of fields */
dtuple_t* tuple, /*!< in: storage for data tuple */
const dfield_t* fields, /*!< in: fields */
ulint n_fields); /*!< in: number of fields */
/*************************************************************************
/*********************************************************************//**
Sets number of fields used in a tuple. Normally this is set in
dtuple_create, but if you want later to set it smaller, you can use this. */
UNIV_INTERN
void
dtuple_set_n_fields(
/*================*/
dtuple_t* tuple, /* in: tuple */
ulint n_fields); /* in: number of fields */
/*************************************************************************
dtuple_t* tuple, /*!< in: tuple */
ulint n_fields); /*!< in: number of fields */
/*********************************************************************//**
Copies a data tuple to another. This is a shallow copy; if a deep copy
is desired, dfield_dup() will have to be invoked on each field. */
is desired, dfield_dup() will have to be invoked on each field.
@return own: copy of tuple */
UNIV_INLINE
dtuple_t*
dtuple_copy(
/*========*/
/* out, own: copy of tuple */
const dtuple_t* tuple, /* in: tuple to copy from */
mem_heap_t* heap); /* in: memory heap
const dtuple_t* tuple, /*!< in: tuple to copy from */
mem_heap_t* heap); /*!< in: memory heap
where the tuple is created */
/**************************************************************
/**********************************************************//**
The following function returns the sum of data lengths of a tuple. The space
occupied by the field structs or the tuple struct is not counted. */
occupied by the field structs or the tuple struct is not counted.
@return sum of data lens */
UNIV_INLINE
ulint
dtuple_get_data_size(
/*=================*/
/* out: sum of data lens */
const dtuple_t* tuple); /* in: typed data tuple */
/*************************************************************************
Computes the number of externally stored fields in a data tuple. */
const dtuple_t* tuple, /*!< in: typed data tuple */
ulint comp); /*!< in: nonzero=ROW_FORMAT=COMPACT */
/*********************************************************************//**
Computes the number of externally stored fields in a data tuple.
@return number of fields */
UNIV_INLINE
ulint
dtuple_get_n_ext(
/*=============*/
/* out: number of fields */
const dtuple_t* tuple); /* in: tuple */
/****************************************************************
Compare two data tuples, respecting the collation of character fields. */
const dtuple_t* tuple); /*!< in: tuple */
/************************************************************//**
Compare two data tuples, respecting the collation of character fields.
@return 1, 0 , -1 if tuple1 is greater, equal, less, respectively,
than tuple2 */
UNIV_INTERN
int
dtuple_coll_cmp(
/*============*/
/* out: 1, 0 , -1 if tuple1 is greater, equal,
less, respectively, than tuple2 */
const dtuple_t* tuple1, /* in: tuple 1 */
const dtuple_t* tuple2);/* in: tuple 2 */
/****************************************************************
Folds a prefix given as the number of fields of a tuple. */
const dtuple_t* tuple1, /*!< in: tuple 1 */
const dtuple_t* tuple2);/*!< in: tuple 2 */
/************************************************************//**
Folds a prefix given as the number of fields of a tuple.
@return the folded value */
UNIV_INLINE
ulint
dtuple_fold(
/*========*/
/* out: the folded value */
const dtuple_t* tuple, /* in: the tuple */
ulint n_fields,/* in: number of complete fields to fold */
ulint n_bytes,/* in: number of bytes to fold in an
const dtuple_t* tuple, /*!< in: the tuple */
ulint n_fields,/*!< in: number of complete fields to fold */
ulint n_bytes,/*!< in: number of bytes to fold in an
incomplete last field */
dulint tree_id)/* in: index tree id */
dulint tree_id)/*!< in: index tree id */
__attribute__((pure));
/***********************************************************************
/*******************************************************************//**
Sets types of fields binary in a tuple. */
UNIV_INLINE
void
dtuple_set_types_binary(
/*====================*/
dtuple_t* tuple, /* in: data tuple */
ulint n); /* in: number of fields to set */
/**************************************************************************
Checks if a dtuple contains an SQL null value. */
dtuple_t* tuple, /*!< in: data tuple */
ulint n); /*!< in: number of fields to set */
/**********************************************************************//**
Checks if a dtuple contains an SQL null value.
@return TRUE if some field is SQL null */
UNIV_INLINE
ibool
dtuple_contains_null(
/*=================*/
/* out: TRUE if some field is SQL null */
const dtuple_t* tuple); /* in: dtuple */
/**************************************************************
Checks that a data field is typed. Asserts an error if not. */
const dtuple_t* tuple); /*!< in: dtuple */
/**********************************************************//**
Checks that a data field is typed. Asserts an error if not.
@return TRUE if ok */
UNIV_INTERN
ibool
dfield_check_typed(
/*===============*/
/* out: TRUE if ok */
const dfield_t* field); /* in: data field */
/**************************************************************
Checks that a data tuple is typed. Asserts an error if not. */
const dfield_t* field); /*!< in: data field */
/**********************************************************//**
Checks that a data tuple is typed. Asserts an error if not.
@return TRUE if ok */
UNIV_INTERN
ibool
dtuple_check_typed(
/*===============*/
/* out: TRUE if ok */
const dtuple_t* tuple); /* in: tuple */
/**************************************************************
Checks that a data tuple is typed. */
const dtuple_t* tuple); /*!< in: tuple */
/**********************************************************//**
Checks that a data tuple is typed.
@return TRUE if ok */
UNIV_INTERN
ibool
dtuple_check_typed_no_assert(
/*=========================*/
/* out: TRUE if ok */
const dtuple_t* tuple); /* in: tuple */
const dtuple_t* tuple); /*!< in: tuple */
#ifdef UNIV_DEBUG
/**************************************************************
/**********************************************************//**
Validates the consistency of a tuple which must be complete, i.e,
all fields must have been set. */
all fields must have been set.
@return TRUE if ok */
UNIV_INTERN
ibool
dtuple_validate(
/*============*/
/* out: TRUE if ok */
const dtuple_t* tuple); /* in: tuple */
const dtuple_t* tuple); /*!< in: tuple */
#endif /* UNIV_DEBUG */
/*****************************************************************
/*************************************************************//**
Pretty prints a dfield value according to its data type. */
UNIV_INTERN
void
dfield_print(
/*=========*/
const dfield_t* dfield);/* in: dfield */
/*****************************************************************
const dfield_t* dfield);/*!< in: dfield */
/*************************************************************//**
Pretty prints a dfield value according to its data type. Also the hex string
is printed if a string contains non-printable characters. */
UNIV_INTERN
void
dfield_print_also_hex(
/*==================*/
const dfield_t* dfield); /* in: dfield */
/**************************************************************
const dfield_t* dfield); /*!< in: dfield */
/**********************************************************//**
The following function prints the contents of a tuple. */
UNIV_INTERN
void
dtuple_print(
/*=========*/
FILE* f, /* in: output stream */
const dtuple_t* tuple); /* in: tuple */
/******************************************************************
FILE* f, /*!< in: output stream */
const dtuple_t* tuple); /*!< in: tuple */
/**************************************************************//**
Moves parts of long fields in entry to the big record vector so that
the size of tuple drops below the maximum record size allowed in the
database. Moves data only from those fields which are not necessary
to determine uniquely the insertion place of the tuple in the index. */
to determine uniquely the insertion place of the tuple in the index.
@return own: created big record vector, NULL if we are not able to
shorten the entry enough, i.e., if there are too many fixed-length or
short fields in entry or the index is clustered */
UNIV_INTERN
big_rec_t*
dtuple_convert_big_rec(
/*===================*/
/* out, own: created big record vector,
NULL if we are not able to shorten
the entry enough, i.e., if there are
too many fixed-length or short fields
in entry or the index is clustered */
dict_index_t* index, /* in: index */
dtuple_t* entry, /* in/out: index entry */
ulint* n_ext); /* in/out: number of
dict_index_t* index, /*!< in: index */
dtuple_t* entry, /*!< in/out: index entry */
ulint* n_ext); /*!< in/out: number of
externally stored columns */
/******************************************************************
/**************************************************************//**
Puts back to entry the data stored in vector. Note that to ensure the
fields in entry can accommodate the data, vector must have been created
from entry with dtuple_convert_big_rec. */
@ -409,68 +409,71 @@ UNIV_INTERN
void
dtuple_convert_back_big_rec(
/*========================*/
dict_index_t* index, /* in: index */
dtuple_t* entry, /* in: entry whose data was put to vector */
big_rec_t* vector);/* in, own: big rec vector; it is
dict_index_t* index, /*!< in: index */
dtuple_t* entry, /*!< in: entry whose data was put to vector */
big_rec_t* vector);/*!< in, own: big rec vector; it is
freed in this function */
/******************************************************************
/**************************************************************//**
Frees the memory in a big rec vector. */
UNIV_INLINE
void
dtuple_big_rec_free(
/*================*/
big_rec_t* vector); /* in, own: big rec vector; it is
big_rec_t* vector); /*!< in, own: big rec vector; it is
freed in this function */
/*######################################################################*/
/* Structure for an SQL data field */
/** Structure for an SQL data field */
struct dfield_struct{
void* data; /* pointer to data */
unsigned ext:1; /* TRUE=externally stored, FALSE=local */
unsigned len:32; /* data length; UNIV_SQL_NULL if SQL null */
dtype_t type; /* type of data */
void* data; /*!< pointer to data */
unsigned ext:1; /*!< TRUE=externally stored, FALSE=local */
unsigned len:32; /*!< data length; UNIV_SQL_NULL if SQL null */
dtype_t type; /*!< type of data */
};
/** Structure for an SQL data tuple of fields (logical record) */
struct dtuple_struct {
ulint info_bits; /* info bits of an index record:
ulint info_bits; /*!< info bits of an index record:
the default is 0; this field is used
if an index record is built from
a data tuple */
ulint n_fields; /* number of fields in dtuple */
ulint n_fields_cmp; /* number of fields which should
ulint n_fields; /*!< number of fields in dtuple */
ulint n_fields_cmp; /*!< number of fields which should
be used in comparison services
of rem0cmp.*; the index search
is performed by comparing only these
fields, others are ignored; the
default value in dtuple creation is
the same value as n_fields */
dfield_t* fields; /* fields */
dfield_t* fields; /*!< fields */
UT_LIST_NODE_T(dtuple_t) tuple_list;
/* data tuples can be linked into a
/*!< data tuples can be linked into a
list using this field */
#ifdef UNIV_DEBUG
ulint magic_n;
ulint magic_n; /*!< magic number, used in
debug assertions */
/** Value of dtuple_struct::magic_n */
# define DATA_TUPLE_MAGIC_N 65478679
#endif /* UNIV_DEBUG */
};
/* A slot for a field in a big rec vector */
/** A slot for a field in a big rec vector */
typedef struct big_rec_field_struct big_rec_field_t;
/** A slot for a field in a big rec vector */
struct big_rec_field_struct {
ulint field_no; /* field number in record */
ulint len; /* stored data len */
const void* data; /* stored data */
ulint field_no; /*!< field number in record */
ulint len; /*!< stored data length, in bytes */
const void* data; /*!< stored data */
};
/* Storage format for overflow data in a big record, that is, a record
which needs external storage of data fields */
/** Storage format for overflow data in a big record, that is, a
clustered index record which needs external storage of data fields */
struct big_rec_struct {
mem_heap_t* heap; /* memory heap from which allocated */
ulint n_fields; /* number of stored fields */
big_rec_field_t* fields; /* stored fields */
mem_heap_t* heap; /*!< memory heap from which
allocated */
ulint n_fields; /*!< number of stored fields */
big_rec_field_t*fields; /*!< stored fields */
};
#ifndef UNIV_NONINL

View File

@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
/************************************************************************
/********************************************************************//**
@file include/data0data.ic
SQL data field and tuple
Created 5/30/1994 Heikki Tuuri
@ -26,16 +27,19 @@ Created 5/30/1994 Heikki Tuuri
#include "ut0rnd.h"
#ifdef UNIV_DEBUG
/** Dummy variable to catch access to uninitialized fields. In the
debug version, dtuple_create() will make all fields of dtuple_t point
to data_error. */
extern byte data_error;
/*************************************************************************
Gets pointer to the type struct of SQL data field. */
/*********************************************************************//**
Gets pointer to the type struct of SQL data field.
@return pointer to the type struct */
UNIV_INLINE
dtype_t*
dfield_get_type(
/*============*/
/* out: pointer to the type struct */
const dfield_t* field) /* in: SQL data field */
const dfield_t* field) /*!< in: SQL data field */
{
ut_ad(field);
@ -43,14 +47,14 @@ dfield_get_type(
}
#endif /* UNIV_DEBUG */
/*************************************************************************
/*********************************************************************//**
Sets the type struct of SQL data field. */
UNIV_INLINE
void
dfield_set_type(
/*============*/
dfield_t* field, /* in: SQL data field */
dtype_t* type) /* in: pointer to data type struct */
dfield_t* field, /*!< in: SQL data field */
dtype_t* type) /*!< in: pointer to data type struct */
{
ut_ad(field && type);
@ -58,14 +62,14 @@ dfield_set_type(
}
#ifdef UNIV_DEBUG
/*************************************************************************
Gets pointer to the data in a field. */
/*********************************************************************//**
Gets pointer to the data in a field.
@return pointer to data */
UNIV_INLINE
void*
dfield_get_data(
/*============*/
/* out: pointer to data */
const dfield_t* field) /* in: field */
const dfield_t* field) /*!< in: field */
{
ut_ad(field);
ut_ad((field->len == UNIV_SQL_NULL)
@ -75,15 +79,14 @@ dfield_get_data(
}
#endif /* UNIV_DEBUG */
/*************************************************************************
Gets length of field data. */
/*********************************************************************//**
Gets length of field data.
@return length of data; UNIV_SQL_NULL if SQL null data */
UNIV_INLINE
ulint
dfield_get_len(
/*===========*/
/* out: length of data; UNIV_SQL_NULL if
SQL null data */
const dfield_t* field) /* in: field */
const dfield_t* field) /*!< in: field */
{
ut_ad(field);
ut_ad((field->len == UNIV_SQL_NULL)
@ -92,14 +95,14 @@ dfield_get_len(
return(field->len);
}
/*************************************************************************
/*********************************************************************//**
Sets length in a field. */
UNIV_INLINE
void
dfield_set_len(
/*===========*/
dfield_t* field, /* in: field */
ulint len) /* in: length or UNIV_SQL_NULL */
dfield_t* field, /*!< in: field */
ulint len) /*!< in: length or UNIV_SQL_NULL */
{
ut_ad(field);
#ifdef UNIV_VALGRIND_DEBUG
@ -110,56 +113,56 @@ dfield_set_len(
field->len = len;
}
/*************************************************************************
Determines if a field is SQL NULL */
/*********************************************************************//**
Determines if a field is SQL NULL
@return nonzero if SQL null data */
UNIV_INLINE
ulint
dfield_is_null(
/*===========*/
/* out: nonzero if SQL null data */
const dfield_t* field) /* in: field */
const dfield_t* field) /*!< in: field */
{
ut_ad(field);
return(field->len == UNIV_SQL_NULL);
}
/*************************************************************************
Determines if a field is externally stored */
/*********************************************************************//**
Determines if a field is externally stored
@return nonzero if externally stored */
UNIV_INLINE
ulint
dfield_is_ext(
/*==========*/
/* out: nonzero if externally stored */
const dfield_t* field) /* in: field */
const dfield_t* field) /*!< in: field */
{
ut_ad(field);
return(UNIV_UNLIKELY(field->ext));
}
/*************************************************************************
/*********************************************************************//**
Sets the "external storage" flag */
UNIV_INLINE
void
dfield_set_ext(
/*===========*/
dfield_t* field) /* in/out: field */
dfield_t* field) /*!< in/out: field */
{
ut_ad(field);
field->ext = 1;
}
/*************************************************************************
/*********************************************************************//**
Sets pointer to the data and length in a field. */
UNIV_INLINE
void
dfield_set_data(
/*============*/
dfield_t* field, /* in: field */
const void* data, /* in: data */
ulint len) /* in: length or UNIV_SQL_NULL */
dfield_t* field, /*!< in: field */
const void* data, /*!< in: data */
ulint len) /*!< in: length or UNIV_SQL_NULL */
{
ut_ad(field);
@ -171,25 +174,25 @@ dfield_set_data(
field->len = len;
}
/*************************************************************************
/*********************************************************************//**
Sets a data field to SQL NULL. */
UNIV_INLINE
void
dfield_set_null(
/*============*/
dfield_t* field) /* in/out: field */
dfield_t* field) /*!< in/out: field */
{
dfield_set_data(field, NULL, UNIV_SQL_NULL);
}
/*************************************************************************
/*********************************************************************//**
Copies the data and len fields. */
UNIV_INLINE
void
dfield_copy_data(
/*=============*/
dfield_t* field1, /* out: field to copy to */
const dfield_t* field2) /* in: field to copy from */
dfield_t* field1, /*!< out: field to copy to */
const dfield_t* field2) /*!< in: field to copy from */
{
ut_ad(field1 && field2);
@ -198,26 +201,26 @@ dfield_copy_data(
field1->ext = field2->ext;
}
/*************************************************************************
/*********************************************************************//**
Copies a data field to another. */
UNIV_INLINE
void
dfield_copy(
/*========*/
dfield_t* field1, /* out: field to copy to */
const dfield_t* field2) /* in: field to copy from */
dfield_t* field1, /*!< out: field to copy to */
const dfield_t* field2) /*!< in: field to copy from */
{
*field1 = *field2;
}
/*************************************************************************
/*********************************************************************//**
Copies the data pointed to by a data field. */
UNIV_INLINE
void
dfield_dup(
/*=======*/
dfield_t* field, /* in/out: data field */
mem_heap_t* heap) /* in: memory heap where allocated */
dfield_t* field, /*!< in/out: data field */
mem_heap_t* heap) /*!< in: memory heap where allocated */
{
if (!dfield_is_null(field)) {
UNIV_MEM_ASSERT_RW(field->data, field->len);
@ -225,15 +228,15 @@ dfield_dup(
}
}
/*************************************************************************
Tests if data length and content is equal for two dfields. */
/*********************************************************************//**
Tests if data length and content is equal for two dfields.
@return TRUE if equal */
UNIV_INLINE
ibool
dfield_datas_are_binary_equal(
/*==========================*/
/* out: TRUE if equal */
const dfield_t* field1, /* in: field */
const dfield_t* field2) /* in: field */
const dfield_t* field1, /*!< in: field */
const dfield_t* field2) /*!< in: field */
{
ulint len;
@ -244,57 +247,56 @@ dfield_datas_are_binary_equal(
|| !memcmp(field1->data, field2->data, len)));
}
/*************************************************************************
Gets info bits in a data tuple. */
/*********************************************************************//**
Gets info bits in a data tuple.
@return info bits */
UNIV_INLINE
ulint
dtuple_get_info_bits(
/*=================*/
/* out: info bits */
const dtuple_t* tuple) /* in: tuple */
const dtuple_t* tuple) /*!< in: tuple */
{
ut_ad(tuple);
return(tuple->info_bits);
}
/*************************************************************************
/*********************************************************************//**
Sets info bits in a data tuple. */
UNIV_INLINE
void
dtuple_set_info_bits(
/*=================*/
dtuple_t* tuple, /* in: tuple */
ulint info_bits) /* in: info bits */
dtuple_t* tuple, /*!< in: tuple */
ulint info_bits) /*!< in: info bits */
{
ut_ad(tuple);
tuple->info_bits = info_bits;
}
/*************************************************************************
Gets number of fields used in record comparisons. */
/*********************************************************************//**
Gets number of fields used in record comparisons.
@return number of fields used in comparisons in rem0cmp.* */
UNIV_INLINE
ulint
dtuple_get_n_fields_cmp(
/*====================*/
/* out: number of fields used in comparisons
in rem0cmp.* */
const dtuple_t* tuple) /* in: tuple */
const dtuple_t* tuple) /*!< in: tuple */
{
ut_ad(tuple);
return(tuple->n_fields_cmp);
}
/*************************************************************************
/*********************************************************************//**
Sets number of fields used in record comparisons. */
UNIV_INLINE
void
dtuple_set_n_fields_cmp(
/*====================*/
dtuple_t* tuple, /* in: tuple */
ulint n_fields_cmp) /* in: number of fields used in
dtuple_t* tuple, /*!< in: tuple */
ulint n_fields_cmp) /*!< in: number of fields used in
comparisons in rem0cmp.* */
{
ut_ad(tuple);
@ -303,14 +305,14 @@ dtuple_set_n_fields_cmp(
tuple->n_fields_cmp = n_fields_cmp;
}
/*************************************************************************
Gets number of fields in a data tuple. */
/*********************************************************************//**
Gets number of fields in a data tuple.
@return number of fields */
UNIV_INLINE
ulint
dtuple_get_n_fields(
/*================*/
/* out: number of fields */
const dtuple_t* tuple) /* in: tuple */
const dtuple_t* tuple) /*!< in: tuple */
{
ut_ad(tuple);
@ -318,15 +320,15 @@ dtuple_get_n_fields(
}
#ifdef UNIV_DEBUG
/*************************************************************************
Gets nth field of a tuple. */
/*********************************************************************//**
Gets nth field of a tuple.
@return nth field */
UNIV_INLINE
dfield_t*
dtuple_get_nth_field(
/*=================*/
/* out: nth field */
const dtuple_t* tuple, /* in: tuple */
ulint n) /* in: index of field */
const dtuple_t* tuple, /*!< in: tuple */
ulint n) /*!< in: index of field */
{
ut_ad(tuple);
ut_ad(n < tuple->n_fields);
@ -335,17 +337,17 @@ dtuple_get_nth_field(
}
#endif /* UNIV_DEBUG */
/**************************************************************
/**********************************************************//**
Creates a data tuple to a memory heap. The default value for number
of fields used in record comparisons for this tuple is n_fields. */
of fields used in record comparisons for this tuple is n_fields.
@return own: created tuple */
UNIV_INLINE
dtuple_t*
dtuple_create(
/*==========*/
/* out, own: created tuple */
mem_heap_t* heap, /* in: memory heap where the tuple
mem_heap_t* heap, /*!< in: memory heap where the tuple
is created */
ulint n_fields) /* in: number of fields */
ulint n_fields) /*!< in: number of fields */
{
dtuple_t* tuple;
@ -380,17 +382,17 @@ dtuple_create(
return(tuple);
}
/**************************************************************
/**********************************************************//**
Wrap data fields in a tuple. The default value for number
of fields used in record comparisons for this tuple is n_fields. */
of fields used in record comparisons for this tuple is n_fields.
@return data tuple */
UNIV_INLINE
const dtuple_t*
dtuple_from_fields(
/*===============*/
/* out: data tuple */
dtuple_t* tuple, /* in: storage for data tuple */
const dfield_t* fields, /* in: fields */
ulint n_fields) /* in: number of fields */
dtuple_t* tuple, /*!< in: storage for data tuple */
const dfield_t* fields, /*!< in: fields */
ulint n_fields) /*!< in: number of fields */
{
tuple->info_bits = 0;
tuple->n_fields = tuple->n_fields_cmp = n_fields;
@ -400,16 +402,16 @@ dtuple_from_fields(
return(tuple);
}
/*************************************************************************
/*********************************************************************//**
Copies a data tuple to another. This is a shallow copy; if a deep copy
is desired, dfield_dup() will have to be invoked on each field. */
is desired, dfield_dup() will have to be invoked on each field.
@return own: copy of tuple */
UNIV_INLINE
dtuple_t*
dtuple_copy(
/*========*/
/* out, own: copy of tuple */
const dtuple_t* tuple, /* in: tuple to copy from */
mem_heap_t* heap) /* in: memory heap
const dtuple_t* tuple, /*!< in: tuple to copy from */
mem_heap_t* heap) /*!< in: memory heap
where the tuple is created */
{
ulint n_fields = dtuple_get_n_fields(tuple);
@ -424,16 +426,17 @@ dtuple_copy(
return(new_tuple);
}
/**************************************************************
/**********************************************************//**
The following function returns the sum of data lengths of a tuple. The space
occupied by the field structs or the tuple struct is not counted. Neither
is possible space in externally stored parts of the field. */
is possible space in externally stored parts of the field.
@return sum of data lengths */
UNIV_INLINE
ulint
dtuple_get_data_size(
/*=================*/
/* out: sum of data lengths */
const dtuple_t* tuple) /* in: typed data tuple */
const dtuple_t* tuple, /*!< in: typed data tuple */
ulint comp) /*!< in: nonzero=ROW_FORMAT=COMPACT */
{
const dfield_t* field;
ulint n_fields;
@ -452,7 +455,8 @@ dtuple_get_data_size(
len = dfield_get_len(field);
if (len == UNIV_SQL_NULL) {
len = dtype_get_sql_null_size(dfield_get_type(field));
len = dtype_get_sql_null_size(dfield_get_type(field),
comp);
}
sum += len;
@ -461,14 +465,14 @@ dtuple_get_data_size(
return(sum);
}
/*************************************************************************
Computes the number of externally stored fields in a data tuple. */
/*********************************************************************//**
Computes the number of externally stored fields in a data tuple.
@return number of externally stored fields */
UNIV_INLINE
ulint
dtuple_get_n_ext(
/*=============*/
/* out: number of externally stored fields */
const dtuple_t* tuple) /* in: tuple */
const dtuple_t* tuple) /*!< in: tuple */
{
ulint n_ext = 0;
ulint n_fields = tuple->n_fields;
@ -485,14 +489,14 @@ dtuple_get_n_ext(
return(n_ext);
}
/***********************************************************************
/*******************************************************************//**
Sets types of fields binary in a tuple. */
UNIV_INLINE
void
dtuple_set_types_binary(
/*====================*/
dtuple_t* tuple, /* in: data tuple */
ulint n) /* in: number of fields to set */
dtuple_t* tuple, /*!< in: data tuple */
ulint n) /*!< in: number of fields to set */
{
dtype_t* dfield_type;
ulint i;
@ -503,18 +507,18 @@ dtuple_set_types_binary(
}
}
/****************************************************************
Folds a prefix given as the number of fields of a tuple. */
/************************************************************//**
Folds a prefix given as the number of fields of a tuple.
@return the folded value */
UNIV_INLINE
ulint
dtuple_fold(
/*========*/
/* out: the folded value */
const dtuple_t* tuple, /* in: the tuple */
ulint n_fields,/* in: number of complete fields to fold */
ulint n_bytes,/* in: number of bytes to fold in an
const dtuple_t* tuple, /*!< in: the tuple */
ulint n_fields,/*!< in: number of complete fields to fold */
ulint n_bytes,/*!< in: number of bytes to fold in an
incomplete last field */
dulint tree_id)/* in: index tree id */
dulint tree_id)/*!< in: index tree id */
{
const dfield_t* field;
ulint i;
@ -559,26 +563,26 @@ dtuple_fold(
return(fold);
}
/**************************************************************************
/**********************************************************************//**
Writes an SQL null field full of zeros. */
UNIV_INLINE
void
data_write_sql_null(
/*================*/
byte* data, /* in: pointer to a buffer of size len */
ulint len) /* in: SQL null size in bytes */
byte* data, /*!< in: pointer to a buffer of size len */
ulint len) /*!< in: SQL null size in bytes */
{
memset(data, 0, len);
}
/**************************************************************************
Checks if a dtuple contains an SQL null value. */
/**********************************************************************//**
Checks if a dtuple contains an SQL null value.
@return TRUE if some field is SQL null */
UNIV_INLINE
ibool
dtuple_contains_null(
/*=================*/
/* out: TRUE if some field is SQL null */
const dtuple_t* tuple) /* in: dtuple */
const dtuple_t* tuple) /*!< in: dtuple */
{
ulint n;
ulint i;
@ -595,13 +599,13 @@ dtuple_contains_null(
return(FALSE);
}
/******************************************************************
/**************************************************************//**
Frees the memory in a big rec vector. */
UNIV_INLINE
void
dtuple_big_rec_free(
/*================*/
big_rec_t* vector) /* in, own: big rec vector; it is
big_rec_t* vector) /*!< in, own: big rec vector; it is
freed in this function */
{
mem_heap_free(vector->heap);

View File

@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
/******************************************************
/**************************************************//**
@file include/data0type.h
Data types
Created 1/16/1996 Heikki Tuuri
@ -167,228 +168,240 @@ SQL null*/
store the charset-collation number; one byte is left unused, though */
#define DATA_NEW_ORDER_NULL_TYPE_BUF_SIZE 6
/*************************************************************************
Gets the MySQL type code from a dtype. */
#ifndef UNIV_HOTBACKUP
/*********************************************************************//**
Gets the MySQL type code from a dtype.
@return MySQL type code; this is NOT an InnoDB type code! */
UNIV_INLINE
ulint
dtype_get_mysql_type(
/*=================*/
/* out: MySQL type code; this is NOT an InnoDB
type code! */
const dtype_t* type); /* in: type struct */
/*************************************************************************
const dtype_t* type); /*!< in: type struct */
/*********************************************************************//**
Determine how many bytes the first n characters of the given string occupy.
If the string is shorter than n characters, returns the number of bytes
the characters in the string occupy. */
the characters in the string occupy.
@return length of the prefix, in bytes */
UNIV_INTERN
ulint
dtype_get_at_most_n_mbchars(
/*========================*/
/* out: length of the prefix,
in bytes */
ulint prtype, /* in: precise type */
ulint mbminlen, /* in: minimum length of a
ulint prtype, /*!< in: precise type */
ulint mbminlen, /*!< in: minimum length of a
multi-byte character */
ulint mbmaxlen, /* in: maximum length of a
ulint mbmaxlen, /*!< in: maximum length of a
multi-byte character */
ulint prefix_len, /* in: length of the requested
ulint prefix_len, /*!< in: length of the requested
prefix, in characters, multiplied by
dtype_get_mbmaxlen(dtype) */
ulint data_len, /* in: length of str (in bytes) */
const char* str); /* in: the string whose prefix
ulint data_len, /*!< in: length of str (in bytes) */
const char* str); /*!< in: the string whose prefix
length is being determined */
/*************************************************************************
#endif /* !UNIV_HOTBACKUP */
/*********************************************************************//**
Checks if a data main type is a string type. Also a BLOB is considered a
string type. */
string type.
@return TRUE if string type */
UNIV_INTERN
ibool
dtype_is_string_type(
/*=================*/
/* out: TRUE if string type */
ulint mtype); /* in: InnoDB main data type code: DATA_CHAR, ... */
/*************************************************************************
ulint mtype); /*!< in: InnoDB main data type code: DATA_CHAR, ... */
/*********************************************************************//**
Checks if a type is a binary string type. Note that for tables created with
< 4.0.14, we do not know if a DATA_BLOB column is a BLOB or a TEXT column. For
those DATA_BLOB columns this function currently returns FALSE. */
those DATA_BLOB columns this function currently returns FALSE.
@return TRUE if binary string type */
UNIV_INTERN
ibool
dtype_is_binary_string_type(
/*========================*/
/* out: TRUE if binary string type */
ulint mtype, /* in: main data type */
ulint prtype);/* in: precise type */
/*************************************************************************
ulint mtype, /*!< in: main data type */
ulint prtype);/*!< in: precise type */
/*********************************************************************//**
Checks if a type is a non-binary string type. That is, dtype_is_string_type is
TRUE and dtype_is_binary_string_type is FALSE. Note that for tables created
with < 4.0.14, we do not know if a DATA_BLOB column is a BLOB or a TEXT column.
For those DATA_BLOB columns this function currently returns TRUE. */
For those DATA_BLOB columns this function currently returns TRUE.
@return TRUE if non-binary string type */
UNIV_INTERN
ibool
dtype_is_non_binary_string_type(
/*============================*/
/* out: TRUE if non-binary string type */
ulint mtype, /* in: main data type */
ulint prtype);/* in: precise type */
/*************************************************************************
ulint mtype, /*!< in: main data type */
ulint prtype);/*!< in: precise type */
/*********************************************************************//**
Sets a data type structure. */
UNIV_INLINE
void
dtype_set(
/*======*/
dtype_t* type, /* in: type struct to init */
ulint mtype, /* in: main data type */
ulint prtype, /* in: precise type */
ulint len); /* in: precision of type */
/*************************************************************************
dtype_t* type, /*!< in: type struct to init */
ulint mtype, /*!< in: main data type */
ulint prtype, /*!< in: precise type */
ulint len); /*!< in: precision of type */
/*********************************************************************//**
Copies a data type structure. */
UNIV_INLINE
void
dtype_copy(
/*=======*/
dtype_t* type1, /* in: type struct to copy to */
const dtype_t* type2); /* in: type struct to copy from */
/*************************************************************************
Gets the SQL main data type. */
dtype_t* type1, /*!< in: type struct to copy to */
const dtype_t* type2); /*!< in: type struct to copy from */
/*********************************************************************//**
Gets the SQL main data type.
@return SQL main data type */
UNIV_INLINE
ulint
dtype_get_mtype(
/*============*/
const dtype_t* type);
/*************************************************************************
Gets the precise data type. */
const dtype_t* type); /*!< in: data type */
/*********************************************************************//**
Gets the precise data type.
@return precise data type */
UNIV_INLINE
ulint
dtype_get_prtype(
/*=============*/
const dtype_t* type);
/*************************************************************************
const dtype_t* type); /*!< in: data type */
#ifndef UNIV_HOTBACKUP
/*********************************************************************//**
Compute the mbminlen and mbmaxlen members of a data type structure. */
UNIV_INLINE
void
dtype_get_mblen(
/*============*/
ulint mtype, /* in: main type */
ulint prtype, /* in: precise type (and collation) */
ulint* mbminlen, /* out: minimum length of a
ulint mtype, /*!< in: main type */
ulint prtype, /*!< in: precise type (and collation) */
ulint* mbminlen, /*!< out: minimum length of a
multi-byte character */
ulint* mbmaxlen); /* out: maximum length of a
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(
/*===================*/
ulint prtype);/* in: precise data type */
/*************************************************************************
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(
/*==============*/
ulint old_prtype, /* in: the MySQL type code and the flags
ulint old_prtype, /*!< in: the MySQL type code and the flags
DATA_BINARY_TYPE etc. */
ulint charset_coll); /* in: MySQL charset-collation code */
/*************************************************************************
ulint charset_coll); /*!< in: MySQL charset-collation code */
/*********************************************************************//**
Determines if a MySQL string type is a subset of UTF-8. This function
may return false negatives, in case further character-set collation
codes are introduced in MySQL later. */
codes are introduced in MySQL later.
@return TRUE if a subset of UTF-8 */
UNIV_INLINE
ibool
dtype_is_utf8(
/*==========*/
/* out: TRUE if a subset of UTF-8 */
ulint prtype);/* in: precise data type */
/*************************************************************************
Gets the type length. */
ulint prtype);/*!< in: precise data type */
#endif /* !UNIV_HOTBACKUP */
/*********************************************************************//**
Gets the type length.
@return fixed length of the type, in bytes, or 0 if variable-length */
UNIV_INLINE
ulint
dtype_get_len(
/*==========*/
const dtype_t* type);
/*************************************************************************
Gets the minimum length of a character, in bytes. */
const dtype_t* type); /*!< in: data type */
#ifndef UNIV_HOTBACKUP
/*********************************************************************//**
Gets the minimum length of a character, in bytes.
@return minimum length of a char, in bytes, or 0 if this is not a
character type */
UNIV_INLINE
ulint
dtype_get_mbminlen(
/*===============*/
/* out: minimum length of a char, in bytes,
or 0 if this is not a character type */
const dtype_t* type); /* in: type */
/*************************************************************************
Gets the maximum length of a character, in bytes. */
const dtype_t* type); /*!< in: type */
/*********************************************************************//**
Gets the maximum length of a character, in bytes.
@return maximum length of a char, in bytes, or 0 if this is not a
character type */
UNIV_INLINE
ulint
dtype_get_mbmaxlen(
/*===============*/
/* out: maximum length of a char, in bytes,
or 0 if this is not a character type */
const dtype_t* type); /* in: type */
/*************************************************************************
Gets the padding character code for the type. */
const dtype_t* type); /*!< in: type */
/*********************************************************************//**
Gets the padding character code for the type.
@return padding character code, or ULINT_UNDEFINED if no padding specified */
UNIV_INLINE
ulint
dtype_get_pad_char(
/*===============*/
/* out: padding character code, or
ULINT_UNDEFINED if no padding specified */
ulint mtype, /* in: main type */
ulint prtype); /* in: precise type */
/***************************************************************************
Returns the size of a fixed size data type, 0 if not a fixed size type. */
ulint mtype, /*!< in: main type */
ulint prtype); /*!< in: precise type */
#endif /* !UNIV_HOTBACKUP */
/***********************************************************************//**
Returns the size of a fixed size data type, 0 if not a fixed size type.
@return fixed size, or 0 */
UNIV_INLINE
ulint
dtype_get_fixed_size_low(
/*=====================*/
/* out: fixed size, or 0 */
ulint mtype, /* in: main type */
ulint prtype, /* in: precise type */
ulint len, /* in: length */
ulint mbminlen, /* in: minimum length of a multibyte char */
ulint mbmaxlen); /* in: maximum length of a multibyte char */
/***************************************************************************
Returns the minimum size of a data type. */
ulint mtype, /*!< in: main type */
ulint prtype, /*!< in: precise type */
ulint len, /*!< in: length */
ulint mbminlen, /*!< in: minimum length of a multibyte char */
ulint mbmaxlen, /*!< in: maximum length of a multibyte char */
ulint comp); /*!< in: nonzero=ROW_FORMAT=COMPACT */
#ifndef UNIV_HOTBACKUP
/***********************************************************************//**
Returns the minimum size of a data type.
@return minimum size */
UNIV_INLINE
ulint
dtype_get_min_size_low(
/*===================*/
/* out: minimum size */
ulint mtype, /* in: main type */
ulint prtype, /* in: precise type */
ulint len, /* in: length */
ulint mbminlen, /* in: minimum length of a multibyte char */
ulint mbmaxlen); /* in: maximum length of a multibyte char */
/***************************************************************************
ulint mtype, /*!< in: main type */
ulint prtype, /*!< in: precise type */
ulint len, /*!< in: length */
ulint mbminlen, /*!< in: minimum length of a multibyte char */
ulint mbmaxlen); /*!< in: maximum length of a multibyte char */
/***********************************************************************//**
Returns the maximum size of a data type. Note: types in system tables may be
incomplete and return incorrect information. */
incomplete and return incorrect information.
@return maximum size */
UNIV_INLINE
ulint
dtype_get_max_size_low(
/*===================*/
/* out: maximum size */
ulint mtype, /* in: main type */
ulint len); /* in: length */
/***************************************************************************
ulint mtype, /*!< in: main type */
ulint len); /*!< in: length */
#endif /* !UNIV_HOTBACKUP */
/***********************************************************************//**
Returns the ROW_FORMAT=REDUNDANT stored SQL NULL size of a type.
For fixed length types it is the fixed length of the type, otherwise 0. */
For fixed length types it is the fixed length of the type, otherwise 0.
@return SQL null storage size in ROW_FORMAT=REDUNDANT */
UNIV_INLINE
ulint
dtype_get_sql_null_size(
/*====================*/
/* out: SQL null storage size
in ROW_FORMAT=REDUNDANT */
const dtype_t* type); /* in: type */
/**************************************************************************
const dtype_t* type, /*!< in: type */
ulint comp); /*!< in: nonzero=ROW_FORMAT=COMPACT */
#ifndef UNIV_HOTBACKUP
/**********************************************************************//**
Reads to a type the stored information which determines its alphabetical
ordering and the storage size of an SQL NULL value. */
UNIV_INLINE
void
dtype_read_for_order_and_null_size(
/*===============================*/
dtype_t* type, /* in: type struct */
const byte* buf); /* in: buffer for the stored order info */
/**************************************************************************
dtype_t* type, /*!< in: type struct */
const byte* buf); /*!< in: buffer for the stored order info */
/**********************************************************************//**
Stores for a type the information which determines its alphabetical ordering
and the storage size of an SQL NULL value. This is the >= 4.1.x storage
format. */
@ -396,13 +409,13 @@ UNIV_INLINE
void
dtype_new_store_for_order_and_null_size(
/*====================================*/
byte* buf, /* in: buffer for
byte* buf, /*!< in: buffer for
DATA_NEW_ORDER_NULL_TYPE_BUF_SIZE
bytes where we store the info */
const dtype_t* type, /* in: type struct */
ulint prefix_len);/* in: prefix length to
const dtype_t* type, /*!< in: type struct */
ulint prefix_len);/*!< in: prefix length to
replace type->len, or 0 */
/**************************************************************************
/**********************************************************************//**
Reads to a type the stored information which determines its alphabetical
ordering and the storage size of an SQL NULL value. This is the 4.1.x storage
format. */
@ -410,24 +423,25 @@ UNIV_INLINE
void
dtype_new_read_for_order_and_null_size(
/*===================================*/
dtype_t* type, /* in: type struct */
const byte* buf); /* in: buffer for stored type order info */
dtype_t* type, /*!< in: type struct */
const byte* buf); /*!< in: buffer for stored type order info */
#endif /* !UNIV_HOTBACKUP */
/*************************************************************************
Validates a data type structure. */
/*********************************************************************//**
Validates a data type structure.
@return TRUE if ok */
UNIV_INTERN
ibool
dtype_validate(
/*===========*/
/* out: TRUE if ok */
const dtype_t* type); /* in: type struct to validate */
/*************************************************************************
const dtype_t* type); /*!< in: type struct to validate */
/*********************************************************************//**
Prints a data type structure. */
UNIV_INTERN
void
dtype_print(
/*========*/
const dtype_t* type); /* in: type */
const dtype_t* type); /*!< in: type */
/* Structure for an SQL data type.
If you add fields to this structure, be sure to initialize them everywhere.
@ -438,8 +452,8 @@ dtype_new_read_for_order_and_null_size()
sym_tab_add_null_lit() */
struct dtype_struct{
unsigned mtype:8; /* main data type */
unsigned prtype:24; /* precise type; MySQL data
unsigned mtype:8; /*!< main data type */
unsigned prtype:24; /*!< precise type; MySQL data
type, charset code, flags to
indicate nullability,
signedness, whether this is a
@ -449,7 +463,7 @@ struct dtype_struct{
/* the remaining fields do not affect alphabetical ordering: */
unsigned len:16; /* length; for MySQL data this
unsigned len:16; /*!< length; for MySQL data this
is field->pack_length(),
except that for a >= 5.0.3
type true VARCHAR this is the
@ -457,11 +471,12 @@ struct dtype_struct{
string data (in addition to
the string, MySQL uses 1 or 2
bytes to store the string length) */
unsigned mbminlen:2; /* minimum length of a
#ifndef UNIV_HOTBACKUP
unsigned mbminlen:2; /*!< minimum length of a
character, in bytes */
unsigned mbmaxlen:3; /* maximum length of a
unsigned mbmaxlen:3; /*!< maximum length of a
character, in bytes */
#endif /* !UNIV_HOTBACKUP */
};
#ifndef UNIV_NONINL

View File

@ -16,36 +16,39 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
/******************************************************
/**************************************************//**
@file include/data0type.ic
Data types
Created 1/16/1996 Heikki Tuuri
*******************************************************/
#include "mach0data.h"
#include "ha_prototypes.h"
#ifndef UNIV_HOTBACKUP
# 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(
/*===================*/
ulint prtype) /* in: precise data type */
ulint prtype) /*!< in: precise data type */
{
return((prtype >> 16) & 0xFFUL);
}
/*************************************************************************
/*********************************************************************//**
Determines if a MySQL string type is a subset of UTF-8. This function
may return false negatives, in case further character-set collation
codes are introduced in MySQL later. */
codes are introduced in MySQL later.
@return TRUE if a subset of UTF-8 */
UNIV_INLINE
ibool
dtype_is_utf8(
/*==========*/
/* out: TRUE if a subset of UTF-8 */
ulint prtype) /* in: precise data type */
ulint prtype) /*!< in: precise data type */
{
/* These codes have been copied from strings/ctype-extra.c
and strings/ctype-utf8.c. */
@ -61,55 +64,49 @@ dtype_is_utf8(
return(FALSE);
}
/*************************************************************************
Gets the MySQL type code from a dtype. */
/*********************************************************************//**
Gets the MySQL type code from a dtype.
@return MySQL type code; this is NOT an InnoDB type code! */
UNIV_INLINE
ulint
dtype_get_mysql_type(
/*=================*/
/* out: MySQL type code; this is NOT an InnoDB
type code! */
const dtype_t* type) /* in: type struct */
const dtype_t* type) /*!< in: type struct */
{
return(type->prtype & 0xFFUL);
}
/*************************************************************************
/*********************************************************************//**
Compute the mbminlen and mbmaxlen members of a data type structure. */
UNIV_INLINE
void
dtype_get_mblen(
/*============*/
ulint mtype, /* in: main type */
ulint prtype, /* in: precise type (and collation) */
ulint* mbminlen, /* out: minimum length of a
ulint mtype, /*!< in: main type */
ulint prtype, /*!< in: precise type (and collation) */
ulint* mbminlen, /*!< out: minimum length of a
multi-byte character */
ulint* mbmaxlen) /* out: maximum length of a
ulint* mbmaxlen) /*!< out: maximum length of a
multi-byte character */
{
if (dtype_is_string_type(mtype)) {
#ifndef UNIV_HOTBACKUP
innobase_get_cset_width(dtype_get_charset_coll(prtype),
mbminlen, mbmaxlen);
ut_ad(*mbminlen <= *mbmaxlen);
ut_ad(*mbminlen <= 2); /* mbminlen in dtype_t is 0..3 */
ut_ad(*mbmaxlen < 1 << 3); /* mbmaxlen in dtype_t is 0..7 */
#else /* !UNIV_HOTBACKUP */
ut_a(mtype <= DATA_BINARY);
*mbminlen = *mbmaxlen = 1;
#endif /* !UNIV_HOTBACKUP */
} else {
*mbminlen = *mbmaxlen = 0;
}
}
/*************************************************************************
/*********************************************************************//**
Compute the mbminlen and mbmaxlen members of a data type structure. */
UNIV_INLINE
void
dtype_set_mblen(
/*============*/
dtype_t* type) /* in/out: type */
dtype_t* type) /*!< in/out: type */
{
ulint mbminlen;
ulint mbmaxlen;
@ -120,17 +117,20 @@ dtype_set_mblen(
ut_ad(dtype_validate(type));
}
#else /* !UNIV_HOTBACKUP */
# define dtype_set_mblen(type) (void) 0
#endif /* !UNIV_HOTBACKUP */
/*************************************************************************
/*********************************************************************//**
Sets a data type structure. */
UNIV_INLINE
void
dtype_set(
/*======*/
dtype_t* type, /* in: type struct to init */
ulint mtype, /* in: main data type */
ulint prtype, /* in: precise type */
ulint len) /* in: precision of type */
dtype_t* type, /*!< in: type struct to init */
ulint mtype, /*!< in: main data type */
ulint prtype, /*!< in: precise type */
ulint len) /*!< in: precision of type */
{
ut_ad(type);
ut_ad(mtype <= DATA_MTYPE_MAX);
@ -142,96 +142,99 @@ dtype_set(
dtype_set_mblen(type);
}
/*************************************************************************
/*********************************************************************//**
Copies a data type structure. */
UNIV_INLINE
void
dtype_copy(
/*=======*/
dtype_t* type1, /* in: type struct to copy to */
const dtype_t* type2) /* in: type struct to copy from */
dtype_t* type1, /*!< in: type struct to copy to */
const dtype_t* type2) /*!< in: type struct to copy from */
{
*type1 = *type2;
ut_ad(dtype_validate(type1));
}
/*************************************************************************
Gets the SQL main data type. */
/*********************************************************************//**
Gets the SQL main data type.
@return SQL main data type */
UNIV_INLINE
ulint
dtype_get_mtype(
/*============*/
const dtype_t* type)
const dtype_t* type) /*!< in: data type */
{
ut_ad(type);
return(type->mtype);
}
/*************************************************************************
Gets the precise data type. */
/*********************************************************************//**
Gets the precise data type.
@return precise data type */
UNIV_INLINE
ulint
dtype_get_prtype(
/*=============*/
const dtype_t* type)
const dtype_t* type) /*!< in: data type */
{
ut_ad(type);
return(type->prtype);
}
/*************************************************************************
Gets the type length. */
/*********************************************************************//**
Gets the type length.
@return fixed length of the type, in bytes, or 0 if variable-length */
UNIV_INLINE
ulint
dtype_get_len(
/*==========*/
const dtype_t* type)
const dtype_t* type) /*!< in: data type */
{
ut_ad(type);
return(type->len);
}
/*************************************************************************
Gets the minimum length of a character, in bytes. */
#ifndef UNIV_HOTBACKUP
/*********************************************************************//**
Gets the minimum length of a character, in bytes.
@return minimum length of a char, in bytes, or 0 if this is not a
character type */
UNIV_INLINE
ulint
dtype_get_mbminlen(
/*===============*/
/* out: minimum length of a char, in bytes,
or 0 if this is not a character type */
const dtype_t* type) /* in: type */
const dtype_t* type) /*!< in: type */
{
ut_ad(type);
return(type->mbminlen);
}
/*************************************************************************
Gets the maximum length of a character, in bytes. */
/*********************************************************************//**
Gets the maximum length of a character, in bytes.
@return maximum length of a char, in bytes, or 0 if this is not a
character type */
UNIV_INLINE
ulint
dtype_get_mbmaxlen(
/*===============*/
/* out: maximum length of a char, in bytes,
or 0 if this is not a character type */
const dtype_t* type) /* in: type */
const dtype_t* type) /*!< in: type */
{
ut_ad(type);
return(type->mbmaxlen);
}
/*************************************************************************
Gets the padding character code for a type. */
/*********************************************************************//**
Gets the padding character code for a type.
@return padding character code, or ULINT_UNDEFINED if no padding specified */
UNIV_INLINE
ulint
dtype_get_pad_char(
/*===============*/
/* out: padding character code, or
ULINT_UNDEFINED if no padding specified */
ulint mtype, /* in: main type */
ulint prtype) /* in: precise type */
ulint mtype, /*!< in: main type */
ulint prtype) /*!< in: precise type */
{
switch (mtype) {
case DATA_FIXBINARY:
@ -262,7 +265,7 @@ dtype_get_pad_char(
}
}
/**************************************************************************
/**********************************************************************//**
Stores for a type the information which determines its alphabetical ordering
and the storage size of an SQL NULL value. This is the >= 4.1.x storage
format. */
@ -270,11 +273,11 @@ UNIV_INLINE
void
dtype_new_store_for_order_and_null_size(
/*====================================*/
byte* buf, /* in: buffer for
byte* buf, /*!< in: buffer for
DATA_NEW_ORDER_NULL_TYPE_BUF_SIZE
bytes where we store the info */
const dtype_t* type, /* in: type struct */
ulint prefix_len)/* in: prefix length to
const dtype_t* type, /*!< in: type struct */
ulint prefix_len)/*!< in: prefix length to
replace type->len, or 0 */
{
#if 6 != DATA_NEW_ORDER_NULL_TYPE_BUF_SIZE
@ -307,7 +310,7 @@ dtype_new_store_for_order_and_null_size(
}
}
/**************************************************************************
/**********************************************************************//**
Reads to a type the stored information which determines its alphabetical
ordering and the storage size of an SQL NULL value. This is the < 4.1.x
storage format. */
@ -315,8 +318,8 @@ UNIV_INLINE
void
dtype_read_for_order_and_null_size(
/*===============================*/
dtype_t* type, /* in: type struct */
const byte* buf) /* in: buffer for stored type order info */
dtype_t* type, /*!< in: type struct */
const byte* buf) /*!< in: buffer for stored type order info */
{
#if 4 != DATA_ORDER_NULL_TYPE_BUF_SIZE
# error "4 != DATA_ORDER_NULL_TYPE_BUF_SIZE"
@ -336,7 +339,7 @@ dtype_read_for_order_and_null_size(
dtype_set_mblen(type);
}
/**************************************************************************
/**********************************************************************//**
Reads to a type the stored information which determines its alphabetical
ordering and the storage size of an SQL NULL value. This is the >= 4.1.x
storage format. */
@ -344,8 +347,8 @@ UNIV_INLINE
void
dtype_new_read_for_order_and_null_size(
/*===================================*/
dtype_t* type, /* in: type struct */
const byte* buf) /* in: buffer for stored type order info */
dtype_t* type, /*!< in: type struct */
const byte* buf) /*!< in: buffer for stored type order info */
{
ulint charset_coll;
@ -385,19 +388,21 @@ dtype_new_read_for_order_and_null_size(
}
dtype_set_mblen(type);
}
#endif /* !UNIV_HOTBACKUP */
/***************************************************************************
Returns the size of a fixed size data type, 0 if not a fixed size type. */
/***********************************************************************//**
Returns the size of a fixed size data type, 0 if not a fixed size type.
@return fixed size, or 0 */
UNIV_INLINE
ulint
dtype_get_fixed_size_low(
/*=====================*/
/* out: fixed size, or 0 */
ulint mtype, /* in: main type */
ulint prtype, /* in: precise type */
ulint len, /* in: length */
ulint mbminlen, /* in: minimum length of a multibyte char */
ulint mbmaxlen) /* in: maximum length of a multibyte char */
ulint mtype, /*!< in: main type */
ulint prtype, /*!< in: precise type */
ulint len, /*!< in: length */
ulint mbminlen, /*!< in: minimum length of a multibyte char */
ulint mbmaxlen, /*!< in: maximum length of a multibyte char */
ulint comp) /*!< in: nonzero=ROW_FORMAT=COMPACT */
{
switch (mtype) {
case DATA_SYS:
@ -424,14 +429,12 @@ dtype_get_fixed_size_low(
case DATA_DOUBLE:
return(len);
case DATA_MYSQL:
#ifndef UNIV_HOTBACKUP
if (prtype & DATA_BINARY_TYPE) {
return(len);
} else if (!comp) {
return(len);
} else {
#ifdef UNIV_HOTBACKUP
if (mbminlen == mbmaxlen) {
return(len);
}
#else /* UNIV_HOTBACKUP */
/* We play it safe here and ask MySQL for
mbminlen and mbmaxlen. Although
mbminlen and mbmaxlen are
@ -463,8 +466,10 @@ dtype_get_fixed_size_low(
if (mbminlen == mbmaxlen) {
return(len);
}
#endif /* !UNIV_HOTBACKUP */
}
#else /* !UNIV_HOTBACKUP */
return(len);
#endif /* !UNIV_HOTBACKUP */
/* fall through for variable-length charsets */
case DATA_VARCHAR:
case DATA_BINARY:
@ -479,18 +484,19 @@ dtype_get_fixed_size_low(
return(0);
}
/***************************************************************************
Returns the minimum size of a data type. */
#ifndef UNIV_HOTBACKUP
/***********************************************************************//**
Returns the minimum size of a data type.
@return minimum size */
UNIV_INLINE
ulint
dtype_get_min_size_low(
/*===================*/
/* out: minimum size */
ulint mtype, /* in: main type */
ulint prtype, /* in: precise type */
ulint len, /* in: length */
ulint mbminlen, /* in: minimum length of a multibyte char */
ulint mbmaxlen) /* in: maximum length of a multibyte char */
ulint mtype, /*!< in: main type */
ulint prtype, /*!< in: precise type */
ulint len, /*!< in: length */
ulint mbminlen, /*!< in: minimum length of a multibyte char */
ulint mbmaxlen) /*!< in: maximum length of a multibyte char */
{
switch (mtype) {
case DATA_SYS:
@ -538,16 +544,16 @@ dtype_get_min_size_low(
return(0);
}
/***************************************************************************
/***********************************************************************//**
Returns the maximum size of a data type. Note: types in system tables may be
incomplete and return incorrect information. */
incomplete and return incorrect information.
@return maximum size */
UNIV_INLINE
ulint
dtype_get_max_size_low(
/*===================*/
/* out: maximum size */
ulint mtype, /* in: main type */
ulint len) /* in: length */
ulint mtype, /*!< in: main type */
ulint len) /*!< in: length */
{
switch (mtype) {
case DATA_SYS:
@ -570,18 +576,24 @@ dtype_get_max_size_low(
return(ULINT_MAX);
}
#endif /* !UNIV_HOTBACKUP */
/***************************************************************************
/***********************************************************************//**
Returns the ROW_FORMAT=REDUNDANT stored SQL NULL size of a type.
For fixed length types it is the fixed length of the type, otherwise 0. */
For fixed length types it is the fixed length of the type, otherwise 0.
@return SQL null storage size in ROW_FORMAT=REDUNDANT */
UNIV_INLINE
ulint
dtype_get_sql_null_size(
/*====================*/
/* out: SQL null storage size
in ROW_FORMAT=REDUNDANT */
const dtype_t* type) /* in: type */
const dtype_t* type, /*!< in: type */
ulint comp) /*!< in: nonzero=ROW_FORMAT=COMPACT */
{
#ifndef UNIV_HOTBACKUP
return(dtype_get_fixed_size_low(type->mtype, type->prtype, type->len,
type->mbminlen, type->mbmaxlen));
type->mbminlen, type->mbmaxlen, comp));
#else /* !UNIV_HOTBACKUP */
return(dtype_get_fixed_size_low(type->mtype, type->prtype, type->len,
0, 0, 0));
#endif /* !UNIV_HOTBACKUP */
}

View File

@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
/************************************************************************
/********************************************************************//**
@file include/data0types.h
Some type definitions
Created 9/21/2000 Heikki Tuuri

View File

@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
/******************************************************
/**************************************************//**
@file include/db0err.h
Global error codes for the database
Created 5/24/1996 Heikki Tuuri

View File

@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
/******************************************************
/**************************************************//**
@file include/dict0boot.h
Data dictionary creation and booting
Created 4/18/1996 Heikki Tuuri
@ -36,54 +37,53 @@ Created 4/18/1996 Heikki Tuuri
typedef byte dict_hdr_t;
/**************************************************************************
Gets a pointer to the dictionary header and x-latches its page. */
/**********************************************************************//**
Gets a pointer to the dictionary header and x-latches its page.
@return pointer to the dictionary header, page x-latched */
UNIV_INTERN
dict_hdr_t*
dict_hdr_get(
/*=========*/
/* out: pointer to the dictionary header,
page x-latched */
mtr_t* mtr); /* in: mtr */
/**************************************************************************
Returns a new row, table, index, or tree id. */
mtr_t* mtr); /*!< in: mtr */
/**********************************************************************//**
Returns a new row, table, index, or tree id.
@return the new id */
UNIV_INTERN
dulint
dict_hdr_get_new_id(
/*================*/
/* out: the new id */
ulint type); /* in: DICT_HDR_ROW_ID, ... */
/**************************************************************************
Returns a new row id. */
ulint type); /*!< in: DICT_HDR_ROW_ID, ... */
/**********************************************************************//**
Returns a new row id.
@return the new id */
UNIV_INLINE
dulint
dict_sys_get_new_row_id(void);
/*=========================*/
/* out: the new id */
/**************************************************************************
Reads a row id from a record or other 6-byte stored form. */
/**********************************************************************//**
Reads a row id from a record or other 6-byte stored form.
@return row id */
UNIV_INLINE
dulint
dict_sys_read_row_id(
/*=================*/
/* out: row id */
byte* field); /* in: record field */
/**************************************************************************
byte* field); /*!< in: record field */
/**********************************************************************//**
Writes a row id to a record or other 6-byte stored form. */
UNIV_INLINE
void
dict_sys_write_row_id(
/*==================*/
byte* field, /* in: record field */
dulint row_id);/* in: row id */
/*********************************************************************
byte* field, /*!< in: record field */
dulint row_id);/*!< in: row id */
/*****************************************************************//**
Initializes the data dictionary memory structures when the database is
started. This function is also called when the data dictionary is created. */
UNIV_INTERN
void
dict_boot(void);
/*===========*/
/*********************************************************************
/*****************************************************************//**
Creates and initializes the data dictionary at the database creation. */
UNIV_INTERN
void

View File

@ -16,13 +16,14 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
/******************************************************
/**************************************************//**
@file include/dict0boot.ic
Data dictionary creation and booting
Created 4/18/1996 Heikki Tuuri
*******************************************************/
/**************************************************************************
/**********************************************************************//**
Writes the current value of the row id counter to the dictionary header file
page. */
UNIV_INTERN
@ -31,13 +32,13 @@ dict_hdr_flush_row_id(void);
/*=======================*/
/**************************************************************************
Returns a new row id. */
/**********************************************************************//**
Returns a new row id.
@return the new id */
UNIV_INLINE
dulint
dict_sys_get_new_row_id(void)
/*=========================*/
/* out: the new id */
{
dulint id;
@ -57,14 +58,14 @@ dict_sys_get_new_row_id(void)
return(id);
}
/**************************************************************************
Reads a row id from a record or other 6-byte stored form. */
/**********************************************************************//**
Reads a row id from a record or other 6-byte stored form.
@return row id */
UNIV_INLINE
dulint
dict_sys_read_row_id(
/*=================*/
/* out: row id */
byte* field) /* in: record field */
byte* field) /*!< in: record field */
{
#if DATA_ROW_ID_LEN != 6
# error "DATA_ROW_ID_LEN != 6"
@ -73,14 +74,14 @@ dict_sys_read_row_id(
return(mach_read_from_6(field));
}
/**************************************************************************
/**********************************************************************//**
Writes a row id to a record or other 6-byte stored form. */
UNIV_INLINE
void
dict_sys_write_row_id(
/*==================*/
byte* field, /* in: record field */
dulint row_id) /* in: row id */
byte* field, /*!< in: record field */
dulint row_id) /*!< in: row id */
{
#if DATA_ROW_ID_LEN != 6
# error "DATA_ROW_ID_LEN != 6"

View File

@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
/******************************************************
/**************************************************//**
@file include/dict0crea.h
Database object creation
Created 1/8/1996 Heikki Tuuri
@ -32,94 +33,92 @@ Created 1/8/1996 Heikki Tuuri
#include "row0types.h"
#include "mtr0mtr.h"
/*************************************************************************
Creates a table create graph. */
/*********************************************************************//**
Creates a table create graph.
@return own: table create node */
UNIV_INTERN
tab_node_t*
tab_create_graph_create(
/*====================*/
/* out, own: table create node */
dict_table_t* table, /* in: table to create, built as a memory data
dict_table_t* table, /*!< in: table to create, built as a memory data
structure */
mem_heap_t* heap); /* in: heap where created */
/*************************************************************************
Creates an index create graph. */
mem_heap_t* heap); /*!< in: heap where created */
/*********************************************************************//**
Creates an index create graph.
@return own: index create node */
UNIV_INTERN
ind_node_t*
ind_create_graph_create(
/*====================*/
/* out, own: index create node */
dict_index_t* index, /* in: index to create, built as a memory data
dict_index_t* index, /*!< in: index to create, built as a memory data
structure */
mem_heap_t* heap); /* in: heap where created */
/***************************************************************
Creates a table. This is a high-level function used in SQL execution graphs. */
mem_heap_t* heap); /*!< in: heap where created */
/***********************************************************//**
Creates a table. This is a high-level function used in SQL execution graphs.
@return query thread to run next or NULL */
UNIV_INTERN
que_thr_t*
dict_create_table_step(
/*===================*/
/* out: query thread to run next or NULL */
que_thr_t* thr); /* in: query thread */
/***************************************************************
que_thr_t* thr); /*!< in: query thread */
/***********************************************************//**
Creates an index. This is a high-level function used in SQL execution
graphs. */
graphs.
@return query thread to run next or NULL */
UNIV_INTERN
que_thr_t*
dict_create_index_step(
/*===================*/
/* out: query thread to run next or NULL */
que_thr_t* thr); /* in: query thread */
/***********************************************************************
Truncates the index tree associated with a row in SYS_INDEXES table. */
que_thr_t* thr); /*!< in: query thread */
/*******************************************************************//**
Truncates the index tree associated with a row in SYS_INDEXES table.
@return new root page number, or FIL_NULL on failure */
UNIV_INTERN
ulint
dict_truncate_index_tree(
/*=====================*/
/* out: new root page number, or
FIL_NULL on failure */
dict_table_t* table, /* in: the table the index belongs to */
ulint space, /* in: 0=truncate,
dict_table_t* table, /*!< in: the table the index belongs to */
ulint space, /*!< in: 0=truncate,
nonzero=create the index tree in the
given tablespace */
btr_pcur_t* pcur, /* in/out: persistent cursor pointing to
btr_pcur_t* pcur, /*!< in/out: persistent cursor pointing to
record in the clustered index of
SYS_INDEXES table. The cursor may be
repositioned in this call. */
mtr_t* mtr); /* in: mtr having the latch
mtr_t* mtr); /*!< in: mtr having the latch
on the record page. The mtr may be
committed and restarted in this call. */
/***********************************************************************
/*******************************************************************//**
Drops the index tree associated with a row in SYS_INDEXES table. */
UNIV_INTERN
void
dict_drop_index_tree(
/*=================*/
rec_t* rec, /* in/out: record in the clustered index
rec_t* rec, /*!< in/out: record in the clustered index
of SYS_INDEXES table */
mtr_t* mtr); /* in: mtr having the latch on the record page */
#ifndef UNIV_HOTBACKUP
/********************************************************************
mtr_t* mtr); /*!< in: mtr having the latch on the record page */
/****************************************************************//**
Creates the foreign key constraints system tables inside InnoDB
at database creation or database start if they are not found or are
not of the right form. */
not of the right form.
@return DB_SUCCESS or error code */
UNIV_INTERN
ulint
dict_create_or_check_foreign_constraint_tables(void);
/*================================================*/
/* out: DB_SUCCESS or error code */
/************************************************************************
/********************************************************************//**
Adds foreign key definitions to data dictionary tables in the database. We
look at table->foreign_list, and also generate names to constraints that were
not named by the user. A generated constraint has a name of the format
databasename/tablename_ibfk_<number>, where the numbers start from 1, and are
given locally for this table, that is, the number is not global, as in the
old format constraints < 4.0.18 it used to be. */
old format constraints < 4.0.18 it used to be.
@return error code or DB_SUCCESS */
UNIV_INTERN
ulint
dict_create_add_foreigns_to_dictionary(
/*===================================*/
/* out: error code or DB_SUCCESS */
ulint start_id,/* in: if we are actually doing ALTER TABLE
ulint start_id,/*!< in: if we are actually doing ALTER TABLE
ADD CONSTRAINT, we want to generate constraint
numbers which are bigger than in the table so
far; we number the constraints from
@ -127,15 +126,14 @@ dict_create_add_foreigns_to_dictionary(
we are creating a new table, or if the table
so far has no constraints for which the name
was generated here */
dict_table_t* table, /* in: table */
trx_t* trx); /* in: transaction */
#endif /* !UNIV_HOTBACKUP */
dict_table_t* table, /*!< in: table */
trx_t* trx); /*!< in: transaction */
/* Table create node structure */
struct tab_node_struct{
que_common_t common; /* node type: QUE_NODE_TABLE_CREATE */
dict_table_t* table; /* table to create, built as a memory data
que_common_t common; /*!< node type: QUE_NODE_TABLE_CREATE */
dict_table_t* table; /*!< table to create, built as a memory data
structure with dict_mem_... functions */
ins_node_t* tab_def; /* child node which does the insert of
the table definition; the row to be inserted
@ -148,9 +146,9 @@ struct tab_node_struct{
a successful table creation */
/*----------------------*/
/* Local storage for this graph node */
ulint state; /* node execution state */
ulint col_no; /* next column definition to insert */
mem_heap_t* heap; /* memory heap used as auxiliary storage */
ulint state; /*!< node execution state */
ulint col_no; /*!< next column definition to insert */
mem_heap_t* heap; /*!< memory heap used as auxiliary storage */
};
/* Table create node states */
@ -163,8 +161,8 @@ struct tab_node_struct{
/* Index create node struct */
struct ind_node_struct{
que_common_t common; /* node type: QUE_NODE_INDEX_CREATE */
dict_index_t* index; /* index to create, built as a memory data
que_common_t common; /*!< node type: QUE_NODE_INDEX_CREATE */
dict_index_t* index; /*!< index to create, built as a memory data
structure with dict_mem_... functions */
ins_node_t* ind_def; /* child node which does the insert of
the index definition; the row to be inserted
@ -177,12 +175,12 @@ struct ind_node_struct{
a successful index creation */
/*----------------------*/
/* Local storage for this graph node */
ulint state; /* node execution state */
ulint state; /*!< node execution state */
ulint page_no;/* root page number of the index */
dict_table_t* table; /* table which owns the index */
dict_table_t* table; /*!< table which owns the index */
dtuple_t* ind_row;/* index definition row built */
ulint field_no;/* next field definition to insert */
mem_heap_t* heap; /* memory heap used as auxiliary storage */
mem_heap_t* heap; /*!< memory heap used as auxiliary storage */
};
/* Index create node states */

View File

@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
/******************************************************
/**************************************************//**
@file include/dict0crea.ic
Database object creation
Created 1/8/1996 Heikki Tuuri

File diff suppressed because it is too large Load Diff

View File

@ -16,24 +16,26 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
/**********************************************************************
/******************************************************************//**
@file include/dict0dict.ic
Data dictionary system
Created 1/8/1996 Heikki Tuuri
***********************************************************************/
#include "data0type.h"
#ifndef UNIV_HOTBACKUP
#include "dict0load.h"
#include "rem0types.h"
#include "data0type.h"
/*************************************************************************
/*********************************************************************//**
Gets the column data type. */
UNIV_INLINE
void
dict_col_copy_type(
/*===============*/
const dict_col_t* col, /* in: column */
dtype_t* type) /* out: data type */
const dict_col_t* col, /*!< in: column */
dtype_t* type) /*!< out: data type */
{
ut_ad(col && type);
@ -43,17 +45,18 @@ dict_col_copy_type(
type->mbminlen = col->mbminlen;
type->mbmaxlen = col->mbmaxlen;
}
#endif /* !UNIV_HOTBACKUP */
#ifdef UNIV_DEBUG
/*************************************************************************
Assert that a column and a data type match. */
/*********************************************************************//**
Assert that a column and a data type match.
@return TRUE */
UNIV_INLINE
ibool
dict_col_type_assert_equal(
/*=======================*/
/* out: TRUE */
const dict_col_t* col, /* in: column */
const dtype_t* type) /* in: data type */
const dict_col_t* col, /*!< in: column */
const dtype_t* type) /*!< in: data type */
{
ut_ad(col);
ut_ad(type);
@ -61,83 +64,89 @@ dict_col_type_assert_equal(
ut_ad(col->mtype == type->mtype);
ut_ad(col->prtype == type->prtype);
ut_ad(col->len == type->len);
# ifndef UNIV_HOTBACKUP
ut_ad(col->mbminlen == type->mbminlen);
ut_ad(col->mbmaxlen == type->mbmaxlen);
# endif /* !UNIV_HOTBACKUP */
return(TRUE);
}
#endif /* UNIV_DEBUG */
/***************************************************************************
Returns the minimum size of the column. */
#ifndef UNIV_HOTBACKUP
/***********************************************************************//**
Returns the minimum size of the column.
@return minimum size */
UNIV_INLINE
ulint
dict_col_get_min_size(
/*==================*/
/* out: minimum size */
const dict_col_t* col) /* in: column */
const dict_col_t* col) /*!< in: column */
{
return(dtype_get_min_size_low(col->mtype, col->prtype, col->len,
col->mbminlen, col->mbmaxlen));
}
/***************************************************************************
Returns the maximum size of the column. */
/***********************************************************************//**
Returns the maximum size of the column.
@return maximum size */
UNIV_INLINE
ulint
dict_col_get_max_size(
/*==================*/
/* out: maximum size */
const dict_col_t* col) /* in: column */
const dict_col_t* col) /*!< in: column */
{
return(dtype_get_max_size_low(col->mtype, col->len));
}
/***************************************************************************
Returns the size of a fixed size column, 0 if not a fixed size column. */
#endif /* !UNIV_HOTBACKUP */
/***********************************************************************//**
Returns the size of a fixed size column, 0 if not a fixed size column.
@return fixed size, or 0 */
UNIV_INLINE
ulint
dict_col_get_fixed_size(
/*====================*/
/* out: fixed size, or 0 */
const dict_col_t* col) /* in: column */
const dict_col_t* col, /*!< in: column */
ulint comp) /*!< in: nonzero=ROW_FORMAT=COMPACT */
{
return(dtype_get_fixed_size_low(col->mtype, col->prtype, col->len,
col->mbminlen, col->mbmaxlen));
col->mbminlen, col->mbmaxlen, comp));
}
/***************************************************************************
/***********************************************************************//**
Returns the ROW_FORMAT=REDUNDANT stored SQL NULL size of a column.
For fixed length types it is the fixed length of the type, otherwise 0. */
For fixed length types it is the fixed length of the type, otherwise 0.
@return SQL null storage size in ROW_FORMAT=REDUNDANT */
UNIV_INLINE
ulint
dict_col_get_sql_null_size(
/*=======================*/
/* out: SQL null storage size
in ROW_FORMAT=REDUNDANT */
const dict_col_t* col) /* in: column */
const dict_col_t* col, /*!< in: column */
ulint comp) /*!< in: nonzero=ROW_FORMAT=COMPACT */
{
return(dict_col_get_fixed_size(col));
return(dict_col_get_fixed_size(col, comp));
}
/*************************************************************************
Gets the column number. */
/*********************************************************************//**
Gets the column number.
@return col->ind, table column position (starting from 0) */
UNIV_INLINE
ulint
dict_col_get_no(
/*============*/
const dict_col_t* col)
const dict_col_t* col) /*!< in: column */
{
ut_ad(col);
return(col->ind);
}
/*************************************************************************
/*********************************************************************//**
Gets the column position in the clustered index. */
UNIV_INLINE
ulint
dict_col_get_clust_pos(
/*===================*/
const dict_col_t* col, /* in: table column */
const dict_index_t* clust_index) /* in: clustered index */
const dict_col_t* col, /*!< in: table column */
const dict_index_t* clust_index) /*!< in: clustered index */
{
ulint i;
@ -156,15 +165,16 @@ dict_col_get_clust_pos(
return(ULINT_UNDEFINED);
}
#ifndef UNIV_HOTBACKUP
#ifdef UNIV_DEBUG
/************************************************************************
Gets the first index on the table (the clustered index). */
/********************************************************************//**
Gets the first index on the table (the clustered index).
@return index, NULL if none exists */
UNIV_INLINE
dict_index_t*
dict_table_get_first_index(
/*=======================*/
/* out: index, NULL if none exists */
const dict_table_t* table) /* in: table */
const dict_table_t* table) /*!< in: table */
{
ut_ad(table);
ut_ad(table->magic_n == DICT_TABLE_MAGIC_N);
@ -172,14 +182,14 @@ dict_table_get_first_index(
return(UT_LIST_GET_FIRST(((dict_table_t*) table)->indexes));
}
/************************************************************************
Gets the next index on the table. */
/********************************************************************//**
Gets the next index on the table.
@return index, NULL if none left */
UNIV_INLINE
dict_index_t*
dict_table_get_next_index(
/*======================*/
/* out: index, NULL if none left */
const dict_index_t* index) /* in: index */
const dict_index_t* index) /*!< in: index */
{
ut_ad(index);
ut_ad(index->magic_n == DICT_INDEX_MAGIC_N);
@ -187,31 +197,30 @@ dict_table_get_next_index(
return(UT_LIST_GET_NEXT(indexes, (dict_index_t*) index));
}
#endif /* UNIV_DEBUG */
#endif /* !UNIV_HOTBACKUP */
/************************************************************************
Check whether the index is the clustered index. */
/********************************************************************//**
Check whether the index is the clustered index.
@return nonzero for clustered index, zero for other indexes */
UNIV_INLINE
ulint
dict_index_is_clust(
/*================*/
/* out: nonzero for clustered index,
zero for other indexes */
const dict_index_t* index) /* in: index */
const dict_index_t* index) /*!< in: index */
{
ut_ad(index);
ut_ad(index->magic_n == DICT_INDEX_MAGIC_N);
return(UNIV_UNLIKELY(index->type & DICT_CLUSTERED));
}
/************************************************************************
Check whether the index is unique. */
/********************************************************************//**
Check whether the index is unique.
@return nonzero for unique index, zero for other indexes */
UNIV_INLINE
ulint
dict_index_is_unique(
/*=================*/
/* out: nonzero for unique index,
zero for other indexes */
const dict_index_t* index) /* in: index */
const dict_index_t* index) /*!< in: index */
{
ut_ad(index);
ut_ad(index->magic_n == DICT_INDEX_MAGIC_N);
@ -219,15 +228,14 @@ dict_index_is_unique(
return(UNIV_UNLIKELY(index->type & DICT_UNIQUE));
}
/************************************************************************
Check whether the index is the insert buffer tree. */
/********************************************************************//**
Check whether the index is the insert buffer tree.
@return nonzero for insert buffer, zero for other indexes */
UNIV_INLINE
ulint
dict_index_is_ibuf(
/*===============*/
/* out: nonzero for insert buffer,
zero for other indexes */
const dict_index_t* index) /* in: index */
const dict_index_t* index) /*!< in: index */
{
ut_ad(index);
ut_ad(index->magic_n == DICT_INDEX_MAGIC_N);
@ -235,17 +243,34 @@ dict_index_is_ibuf(
return(UNIV_UNLIKELY(index->type & DICT_IBUF));
}
/************************************************************************
/********************************************************************//**
Check whether the index is a secondary index or the insert buffer tree.
@return nonzero for insert buffer, zero for other indexes */
UNIV_INLINE
ulint
dict_index_is_sec_or_ibuf(
/*======================*/
const dict_index_t* index) /*!< in: index */
{
ulint type;
ut_ad(index);
ut_ad(index->magic_n == DICT_INDEX_MAGIC_N);
type = index->type;
return(UNIV_LIKELY(!(type & DICT_CLUSTERED) || (type & DICT_IBUF)));
}
/********************************************************************//**
Gets the number of user-defined columns in a table in the dictionary
cache. */
cache.
@return number of user-defined (e.g., not ROW_ID) columns of a table */
UNIV_INLINE
ulint
dict_table_get_n_user_cols(
/*=======================*/
/* out: number of user-defined
(e.g., not ROW_ID)
columns of a table */
const dict_table_t* table) /* in: table */
const dict_table_t* table) /*!< in: table */
{
ut_ad(table);
ut_ad(table->magic_n == DICT_TABLE_MAGIC_N);
@ -253,15 +278,14 @@ dict_table_get_n_user_cols(
return(table->n_cols - DATA_N_SYS_COLS);
}
/************************************************************************
Gets the number of system columns in a table in the dictionary cache. */
/********************************************************************//**
Gets the number of system columns in a table in the dictionary cache.
@return number of system (e.g., ROW_ID) columns of a table */
UNIV_INLINE
ulint
dict_table_get_n_sys_cols(
/*======================*/
/* out: number of system (e.g.,
ROW_ID) columns of a table */
const dict_table_t* table __attribute__((unused))) /* in: table */
const dict_table_t* table __attribute__((unused))) /*!< in: table */
{
ut_ad(table);
ut_ad(table->magic_n == DICT_TABLE_MAGIC_N);
@ -270,15 +294,15 @@ dict_table_get_n_sys_cols(
return(DATA_N_SYS_COLS);
}
/************************************************************************
/********************************************************************//**
Gets the number of all columns (also system) in a table in the dictionary
cache. */
cache.
@return number of columns of a table */
UNIV_INLINE
ulint
dict_table_get_n_cols(
/*==================*/
/* out: number of columns of a table */
const dict_table_t* table) /* in: table */
const dict_table_t* table) /*!< in: table */
{
ut_ad(table);
ut_ad(table->magic_n == DICT_TABLE_MAGIC_N);
@ -287,15 +311,15 @@ dict_table_get_n_cols(
}
#ifdef UNIV_DEBUG
/************************************************************************
Gets the nth column of a table. */
/********************************************************************//**
Gets the nth column of a table.
@return pointer to column object */
UNIV_INLINE
dict_col_t*
dict_table_get_nth_col(
/*===================*/
/* out: pointer to column object */
const dict_table_t* table, /* in: table */
ulint pos) /* in: position of column */
const dict_table_t* table, /*!< in: table */
ulint pos) /*!< in: position of column */
{
ut_ad(table);
ut_ad(pos < table->n_def);
@ -304,15 +328,15 @@ dict_table_get_nth_col(
return((dict_col_t*) (table->cols) + pos);
}
/************************************************************************
Gets the given system column of a table. */
/********************************************************************//**
Gets the given system column of a table.
@return pointer to column object */
UNIV_INLINE
dict_col_t*
dict_table_get_sys_col(
/*===================*/
/* out: pointer to column object */
const dict_table_t* table, /* in: table */
ulint sys) /* in: DATA_ROW_ID, ... */
const dict_table_t* table, /*!< in: table */
ulint sys) /*!< in: DATA_ROW_ID, ... */
{
dict_col_t* col;
@ -329,15 +353,15 @@ dict_table_get_sys_col(
}
#endif /* UNIV_DEBUG */
/************************************************************************
Gets the given system column number of a table. */
/********************************************************************//**
Gets the given system column number of a table.
@return column number */
UNIV_INLINE
ulint
dict_table_get_sys_col_no(
/*======================*/
/* out: column number */
const dict_table_t* table, /* in: table */
ulint sys) /* in: DATA_ROW_ID, ... */
const dict_table_t* table, /*!< in: table */
ulint sys) /*!< in: DATA_ROW_ID, ... */
{
ut_ad(table);
ut_ad(sys < DATA_N_SYS_COLS);
@ -346,15 +370,14 @@ dict_table_get_sys_col_no(
return(table->n_cols - DATA_N_SYS_COLS + sys);
}
/************************************************************************
Check whether the table uses the compact page format. */
/********************************************************************//**
Check whether the table uses the compact page format.
@return TRUE if table uses the compact page format */
UNIV_INLINE
ibool
dict_table_is_comp(
/*===============*/
/* out: TRUE if table uses the
compact page format */
const dict_table_t* table) /* in: table */
const dict_table_t* table) /*!< in: table */
{
ut_ad(table);
@ -365,28 +388,28 @@ dict_table_is_comp(
return(UNIV_LIKELY(table->flags & DICT_TF_COMPACT));
}
/************************************************************************
Determine the file format of a table. */
/********************************************************************//**
Determine the file format of a table.
@return file format version */
UNIV_INLINE
ulint
dict_table_get_format(
/*==================*/
/* out: file format version */
const dict_table_t* table) /* in: table */
const dict_table_t* table) /*!< in: table */
{
ut_ad(table);
return((table->flags & DICT_TF_FORMAT_MASK) >> DICT_TF_FORMAT_SHIFT);
}
/************************************************************************
/********************************************************************//**
Determine the file format of a table. */
UNIV_INLINE
void
dict_table_set_format(
/*==================*/
dict_table_t* table, /* in/out: table */
ulint format) /* in: file format version */
dict_table_t* table, /*!< in/out: table */
ulint format) /*!< in: file format version */
{
ut_ad(table);
@ -394,15 +417,14 @@ dict_table_set_format(
| (format << DICT_TF_FORMAT_SHIFT);
}
/************************************************************************
Extract the compressed page size from table flags. */
/********************************************************************//**
Extract the compressed page size from table flags.
@return compressed page size, or 0 if not compressed */
UNIV_INLINE
ulint
dict_table_flags_to_zip_size(
/*=========================*/
/* out: compressed page size,
or 0 if not compressed */
ulint flags) /* in: flags */
ulint flags) /*!< in: flags */
{
ulint zip_size = flags & DICT_TF_ZSSIZE_MASK;
@ -416,30 +438,29 @@ dict_table_flags_to_zip_size(
return(zip_size);
}
/************************************************************************
Check whether the table uses the compressed compact page format. */
/********************************************************************//**
Check whether the table uses the compressed compact page format.
@return compressed page size, or 0 if not compressed */
UNIV_INLINE
ulint
dict_table_zip_size(
/*================*/
/* out: compressed page size,
or 0 if not compressed */
const dict_table_t* table) /* in: table */
const dict_table_t* table) /*!< in: table */
{
ut_ad(table);
return(dict_table_flags_to_zip_size(table->flags));
}
/************************************************************************
/********************************************************************//**
Gets the number of fields in the internal representation of an index,
including fields added by the dictionary system. */
including fields added by the dictionary system.
@return number of fields */
UNIV_INLINE
ulint
dict_index_get_n_fields(
/*====================*/
/* out: number of fields */
const dict_index_t* index) /* in: an internal
const dict_index_t* index) /*!< in: an internal
representation of index (in
the dictionary cache) */
{
@ -449,17 +470,17 @@ dict_index_get_n_fields(
return(index->n_fields);
}
/************************************************************************
/********************************************************************//**
Gets the number of fields in the internal representation of an index
that uniquely determine the position of an index entry in the index, if
we do not take multiversioning into account: in the B-tree use the value
returned by dict_index_get_n_unique_in_tree. */
returned by dict_index_get_n_unique_in_tree.
@return number of fields */
UNIV_INLINE
ulint
dict_index_get_n_unique(
/*====================*/
/* out: number of fields */
const dict_index_t* index) /* in: an internal representation
const dict_index_t* index) /*!< in: an internal representation
of index (in the dictionary cache) */
{
ut_ad(index);
@ -469,16 +490,16 @@ dict_index_get_n_unique(
return(index->n_uniq);
}
/************************************************************************
/********************************************************************//**
Gets the number of fields in the internal representation of an index
which uniquely determine the position of an index entry in the index, if
we also take multiversioning into account. */
we also take multiversioning into account.
@return number of fields */
UNIV_INLINE
ulint
dict_index_get_n_unique_in_tree(
/*============================*/
/* out: number of fields */
const dict_index_t* index) /* in: an internal representation
const dict_index_t* index) /*!< in: an internal representation
of index (in the dictionary cache) */
{
ut_ad(index);
@ -493,32 +514,32 @@ dict_index_get_n_unique_in_tree(
return(dict_index_get_n_fields(index));
}
/************************************************************************
/********************************************************************//**
Gets the number of user-defined ordering fields in the index. In the internal
representation of clustered indexes we add the row id to the ordering fields
to make a clustered index unique, but this function returns the number of
fields the user defined in the index as ordering fields. */
fields the user defined in the index as ordering fields.
@return number of fields */
UNIV_INLINE
ulint
dict_index_get_n_ordering_defined_by_user(
/*======================================*/
/* out: number of fields */
const dict_index_t* index) /* in: an internal representation
const dict_index_t* index) /*!< in: an internal representation
of index (in the dictionary cache) */
{
return(index->n_user_defined_cols);
}
#ifdef UNIV_DEBUG
/************************************************************************
Gets the nth field of an index. */
/********************************************************************//**
Gets the nth field of an index.
@return pointer to field object */
UNIV_INLINE
dict_field_t*
dict_index_get_nth_field(
/*=====================*/
/* out: pointer to field object */
const dict_index_t* index, /* in: index */
ulint pos) /* in: position of field */
const dict_index_t* index, /*!< in: index */
ulint pos) /*!< in: position of field */
{
ut_ad(index);
ut_ad(pos < index->n_def);
@ -528,16 +549,15 @@ dict_index_get_nth_field(
}
#endif /* UNIV_DEBUG */
/************************************************************************
Returns the position of a system column in an index. */
/********************************************************************//**
Returns the position of a system column in an index.
@return position, ULINT_UNDEFINED if not contained */
UNIV_INLINE
ulint
dict_index_get_sys_col_pos(
/*=======================*/
/* out: position,
ULINT_UNDEFINED if not contained */
const dict_index_t* index, /* in: index */
ulint type) /* in: DATA_ROW_ID, ... */
const dict_index_t* index, /*!< in: index */
ulint type) /*!< in: DATA_ROW_ID, ... */
{
ut_ad(index);
ut_ad(index->magic_n == DICT_INDEX_MAGIC_N);
@ -554,53 +574,55 @@ dict_index_get_sys_col_pos(
index, dict_table_get_sys_col_no(index->table, type)));
}
/*************************************************************************
Gets the field column. */
/*********************************************************************//**
Gets the field column.
@return field->col, pointer to the table column */
UNIV_INLINE
const dict_col_t*
dict_field_get_col(
/*===============*/
const dict_field_t* field)
const dict_field_t* field) /*!< in: index field */
{
ut_ad(field);
return(field->col);
}
/************************************************************************
Gets pointer to the nth column in an index. */
/********************************************************************//**
Gets pointer to the nth column in an index.
@return column */
UNIV_INLINE
const dict_col_t*
dict_index_get_nth_col(
/*===================*/
/* out: column */
const dict_index_t* index, /* in: index */
ulint pos) /* in: position of the field */
const dict_index_t* index, /*!< in: index */
ulint pos) /*!< in: position of the field */
{
return(dict_field_get_col(dict_index_get_nth_field(index, pos)));
}
/************************************************************************
Gets the column number the nth field in an index. */
/********************************************************************//**
Gets the column number the nth field in an index.
@return column number */
UNIV_INLINE
ulint
dict_index_get_nth_col_no(
/*======================*/
/* out: column number */
const dict_index_t* index, /* in: index */
ulint pos) /* in: position of the field */
const dict_index_t* index, /*!< in: index */
ulint pos) /*!< in: position of the field */
{
return(dict_col_get_no(dict_index_get_nth_col(index, pos)));
}
/************************************************************************
Returns the minimum data size of an index record. */
#ifndef UNIV_HOTBACKUP
/********************************************************************//**
Returns the minimum data size of an index record.
@return minimum data size in bytes */
UNIV_INLINE
ulint
dict_index_get_min_size(
/*====================*/
/* out: minimum data size in bytes */
const dict_index_t* index) /* in: index */
const dict_index_t* index) /*!< in: index */
{
ulint n = dict_index_get_n_fields(index);
ulint size = 0;
@ -613,14 +635,14 @@ dict_index_get_min_size(
return(size);
}
/*************************************************************************
Gets the space id of the root of the index tree. */
/*********************************************************************//**
Gets the space id of the root of the index tree.
@return space id */
UNIV_INLINE
ulint
dict_index_get_space(
/*=================*/
/* out: space id */
const dict_index_t* index) /* in: index */
const dict_index_t* index) /*!< in: index */
{
ut_ad(index);
ut_ad(index->magic_n == DICT_INDEX_MAGIC_N);
@ -628,14 +650,14 @@ dict_index_get_space(
return(index->space);
}
/*************************************************************************
/*********************************************************************//**
Sets the space id of the root of the index tree. */
UNIV_INLINE
void
dict_index_set_space(
/*=================*/
dict_index_t* index, /* in/out: index */
ulint space) /* in: space id */
dict_index_t* index, /*!< in/out: index */
ulint space) /*!< in: space id */
{
ut_ad(index);
ut_ad(index->magic_n == DICT_INDEX_MAGIC_N);
@ -643,14 +665,14 @@ dict_index_set_space(
index->space = space;
}
/*************************************************************************
Gets the page number of the root of the index tree. */
/*********************************************************************//**
Gets the page number of the root of the index tree.
@return page number */
UNIV_INLINE
ulint
dict_index_get_page(
/*================*/
/* out: page number */
const dict_index_t* index) /* in: index */
const dict_index_t* index) /*!< in: index */
{
ut_ad(index);
ut_ad(index->magic_n == DICT_INDEX_MAGIC_N);
@ -658,14 +680,14 @@ dict_index_get_page(
return(index->page);
}
/*************************************************************************
/*********************************************************************//**
Sets the page number of the root of index tree. */
UNIV_INLINE
void
dict_index_set_page(
/*================*/
dict_index_t* index, /* in/out: index */
ulint page) /* in: page number */
dict_index_t* index, /*!< in/out: index */
ulint page) /*!< in: page number */
{
ut_ad(index);
ut_ad(index->magic_n == DICT_INDEX_MAGIC_N);
@ -673,14 +695,14 @@ dict_index_set_page(
index->page = page;
}
/*************************************************************************
Gets the read-write lock of the index tree. */
/*********************************************************************//**
Gets the read-write lock of the index tree.
@return read-write lock */
UNIV_INLINE
rw_lock_t*
dict_index_get_lock(
/*================*/
/* out: read-write lock */
dict_index_t* index) /* in: index */
dict_index_t* index) /*!< in: index */
{
ut_ad(index);
ut_ad(index->magic_n == DICT_INDEX_MAGIC_N);
@ -688,28 +710,27 @@ dict_index_get_lock(
return(&(index->lock));
}
/************************************************************************
/********************************************************************//**
Returns free space reserved for future updates of records. This is
relevant only in the case of many consecutive inserts, as updates
which make the records bigger might fragment the index. */
which make the records bigger might fragment the index.
@return number of free bytes on page, reserved for updates */
UNIV_INLINE
ulint
dict_index_get_space_reserve(void)
/*==============================*/
/* out: number of free bytes on page,
reserved for updates */
{
return(UNIV_PAGE_SIZE / 16);
}
/**************************************************************************
Checks if a table is in the dictionary cache. */
/**********************************************************************//**
Checks if a table is in the dictionary cache.
@return table, NULL if not found */
UNIV_INLINE
dict_table_t*
dict_table_check_if_in_cache_low(
/*=============================*/
/* out: table, NULL if not found */
const char* table_name) /* in: table name */
const char* table_name) /*!< in: table name */
{
dict_table_t* table;
ulint table_fold;
@ -733,15 +754,15 @@ dict_table_check_if_in_cache_low(
return(table);
}
/**************************************************************************
/**********************************************************************//**
Gets a table; loads it to the dictionary cache if necessary. A low-level
function. */
function.
@return table, NULL if not found */
UNIV_INLINE
dict_table_t*
dict_table_get_low(
/*===============*/
/* out: table, NULL if not found */
const char* table_name) /* in: table name */
const char* table_name) /*!< in: table name */
{
dict_table_t* table;
@ -759,14 +780,14 @@ dict_table_get_low(
return(table);
}
/**************************************************************************
Returns a table object based on table id. */
/**********************************************************************//**
Returns a table object based on table id.
@return table, NULL if does not exist */
UNIV_INLINE
dict_table_t*
dict_table_get_on_id_low(
/*=====================*/
/* out: table, NULL if does not exist */
dulint table_id) /* in: table id */
dulint table_id) /*!< in: table id */
{
dict_table_t* table;
ulint fold;
@ -795,4 +816,4 @@ dict_table_get_on_id_low(
return(table);
}
#endif /* !UNIV_HOTBACKUP */

View File

@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
/******************************************************
/**************************************************//**
@file include/dict0load.h
Loads to the memory cache database object definitions
from dictionary tables
@ -31,7 +32,7 @@ Created 4/24/1996 Heikki Tuuri
#include "ut0byte.h"
#include "mem0mem.h"
/************************************************************************
/********************************************************************//**
In a crash recovery we already have all the tablespace objects created.
This function compares the space id information in the InnoDB data dictionary
to what we already read with fil_load_single_table_tablespaces().
@ -43,42 +44,39 @@ UNIV_INTERN
void
dict_check_tablespaces_and_store_max_id(
/*====================================*/
ibool in_crash_recovery); /* in: are we doing a crash recovery */
/************************************************************************
Finds the first table name in the given database. */
ibool in_crash_recovery); /*!< in: are we doing a crash recovery */
/********************************************************************//**
Finds the first table name in the given database.
@return own: table name, NULL if does not exist; the caller must free
the memory in the string! */
UNIV_INTERN
char*
dict_get_first_table_name_in_db(
/*============================*/
/* out, own: table name, NULL if
does not exist; the caller must free
the memory in the string! */
const char* name); /* in: database name which ends to '/' */
/************************************************************************
const char* name); /*!< in: database name which ends to '/' */
/********************************************************************//**
Loads a table definition and also all its index definitions, and also
the cluster definition if the table is a member in a cluster. Also loads
all foreign key constraints where the foreign key is in the table or where
a foreign key references columns in this table. */
a foreign key references columns in this table.
@return table, NULL if does not exist; if the table is stored in an
.ibd file, but the file does not exist, then we set the
ibd_file_missing flag TRUE in the table object we return */
UNIV_INTERN
dict_table_t*
dict_load_table(
/*============*/
/* out: table, NULL if does not exist;
if the table is stored in an .ibd file,
but the file does not exist,
then we set the ibd_file_missing flag TRUE
in the table object we return */
const char* name); /* in: table name in the
const char* name); /*!< in: table name in the
databasename/tablename format */
/***************************************************************************
Loads a table object based on the table id. */
/***********************************************************************//**
Loads a table object based on the table id.
@return table; NULL if table does not exist */
UNIV_INTERN
dict_table_t*
dict_load_table_on_id(
/*==================*/
/* out: table; NULL if table does not exist */
dulint table_id); /* in: table id */
/************************************************************************
dulint table_id); /*!< in: table id */
/********************************************************************//**
This function is called when the database is booted.
Loads system table index definitions except for the clustered index which
is added to the dictionary cache at booting before calling this function. */
@ -86,24 +84,22 @@ UNIV_INTERN
void
dict_load_sys_table(
/*================*/
dict_table_t* table); /* in: system table */
#ifndef UNIV_HOTBACKUP
/***************************************************************************
dict_table_t* table); /*!< in: system table */
/***********************************************************************//**
Loads foreign key constraints where the table is either the foreign key
holder or where the table is referenced by a foreign key. Adds these
constraints to the data dictionary. Note that we know that the dictionary
cache already contains all constraints where the other relevant table is
already in the dictionary cache. */
already in the dictionary cache.
@return DB_SUCCESS or error code */
UNIV_INTERN
ulint
dict_load_foreigns(
/*===============*/
/* out: DB_SUCCESS or error code */
const char* table_name, /* in: table name */
ibool check_charsets);/* in: TRUE=check charsets
const char* table_name, /*!< in: table name */
ibool check_charsets);/*!< in: TRUE=check charsets
compatibility */
#endif /* !UNIV_HOTBACKUP */
/************************************************************************
/********************************************************************//**
Prints to the standard output information on all tables found in the data
dictionary system table. */
UNIV_INTERN

View File

@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
/******************************************************
/**************************************************//**
@file include/dict0load.ic
Loads to the memory cache database object definitions
from dictionary tables

View File

@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
/******************************************************
/**************************************************//**
@file include/dict0mem.h
Data dictionary memory object creation
Created 1/8/1996 Heikki Tuuri
@ -31,107 +32,118 @@ Created 1/8/1996 Heikki Tuuri
#include "mem0mem.h"
#include "rem0types.h"
#include "btr0types.h"
#ifndef UNIV_HOTBACKUP
# include "lock0types.h"
# include "que0types.h"
# include "sync0rw.h"
#endif /* !UNIV_HOTBACKUP */
#include "ut0mem.h"
#include "ut0lst.h"
#include "ut0rnd.h"
#include "ut0byte.h"
#include "sync0rw.h"
#include "lock0types.h"
#include "hash0hash.h"
#include "que0types.h"
#include "trx0types.h"
/* Type flags of an index: OR'ing of the flags is allowed to define a
/** Type flags of an index: OR'ing of the flags is allowed to define a
combination of types */
#define DICT_CLUSTERED 1 /* clustered index */
#define DICT_UNIQUE 2 /* unique index */
#define DICT_UNIVERSAL 4 /* index which can contain records from any
/* @{ */
#define DICT_CLUSTERED 1 /*!< clustered index */
#define DICT_UNIQUE 2 /*!< unique index */
#define DICT_UNIVERSAL 4 /*!< index which can contain records from any
other index */
#define DICT_IBUF 8 /* insert buffer tree */
#define DICT_IBUF 8 /*!< insert buffer tree */
/* @} */
/* Types for a table object */
#define DICT_TABLE_ORDINARY 1
/** Types for a table object */
#define DICT_TABLE_ORDINARY 1 /*!< ordinary table */
#if 0 /* not implemented */
#define DICT_TABLE_CLUSTER_MEMBER 2
#define DICT_TABLE_CLUSTER 3 /* this means that the table is
really a cluster definition */
#endif
/* Table flags. All unused bits must be 0. */
/** Table flags. All unused bits must be 0. */
/* @{ */
#define DICT_TF_COMPACT 1 /* Compact page format.
This must be set for
new file formats
(later than
DICT_TF_FORMAT_51). */
/* compressed page size (0=uncompressed, up to 15 compressed sizes) */
/** Compressed page size (0=uncompressed, up to 15 compressed sizes) */
/* @{ */
#define DICT_TF_ZSSIZE_SHIFT 1
#define DICT_TF_ZSSIZE_MASK (15 << DICT_TF_ZSSIZE_SHIFT)
#define DICT_TF_ZSSIZE_MAX (UNIV_PAGE_SIZE_SHIFT - PAGE_ZIP_MIN_SIZE_SHIFT + 1)
/* @} */
/** File format */
/* @{ */
#define DICT_TF_FORMAT_SHIFT 5 /* file format */
#define DICT_TF_FORMAT_MASK (127 << DICT_TF_FORMAT_SHIFT)
#define DICT_TF_FORMAT_51 0 /* InnoDB/MySQL up to 5.1 */
#define DICT_TF_FORMAT_ZIP 1 /* InnoDB plugin for 5.1:
#define DICT_TF_FORMAT_51 0 /*!< InnoDB/MySQL up to 5.1 */
#define DICT_TF_FORMAT_ZIP 1 /*!< InnoDB plugin for 5.1:
compressed tables,
new BLOB treatment */
/** Maximum supported file format */
#define DICT_TF_FORMAT_MAX DICT_TF_FORMAT_ZIP
#define DICT_TF_BITS 6 /* number of flag bits */
#define DICT_TF_BITS 6 /*!< number of flag bits */
#if (1 << (DICT_TF_BITS - DICT_TF_FORMAT_SHIFT)) <= DICT_TF_FORMAT_MAX
# error "DICT_TF_BITS is insufficient for DICT_TF_FORMAT_MAX"
#endif
/* @} */
/* @} */
/**************************************************************************
Creates a table memory object. */
/**********************************************************************//**
Creates a table memory object.
@return own: table object */
UNIV_INTERN
dict_table_t*
dict_mem_table_create(
/*==================*/
/* out, own: table object */
const char* name, /* in: table name */
ulint space, /* in: space where the clustered index
const char* name, /*!< in: table name */
ulint space, /*!< in: space where the clustered index
of the table is placed; this parameter
is ignored if the table is made
a member of a cluster */
ulint n_cols, /* in: number of columns */
ulint flags); /* in: table flags */
/********************************************************************
ulint n_cols, /*!< in: number of columns */
ulint flags); /*!< in: table flags */
/****************************************************************//**
Free a table memory object. */
UNIV_INTERN
void
dict_mem_table_free(
/*================*/
dict_table_t* table); /* in: table */
/**************************************************************************
dict_table_t* table); /*!< in: table */
/**********************************************************************//**
Adds a column definition to a table. */
UNIV_INTERN
void
dict_mem_table_add_col(
/*===================*/
dict_table_t* table, /* in: table */
mem_heap_t* heap, /* in: temporary memory heap, or NULL */
const char* name, /* in: column name, or NULL */
ulint mtype, /* in: main datatype */
ulint prtype, /* in: precise type */
ulint len); /* in: precision */
/**************************************************************************
Creates an index memory object. */
dict_table_t* table, /*!< in: table */
mem_heap_t* heap, /*!< in: temporary memory heap, or NULL */
const char* name, /*!< in: column name, or NULL */
ulint mtype, /*!< in: main datatype */
ulint prtype, /*!< in: precise type */
ulint len); /*!< in: precision */
/**********************************************************************//**
Creates an index memory object.
@return own: index object */
UNIV_INTERN
dict_index_t*
dict_mem_index_create(
/*==================*/
/* out, own: index object */
const char* table_name, /* in: table name */
const char* index_name, /* in: index name */
ulint space, /* in: space where the index tree is
const char* table_name, /*!< in: table name */
const char* index_name, /*!< in: index name */
ulint space, /*!< in: space where the index tree is
placed, ignored if the index is of
the clustered type */
ulint type, /* in: DICT_UNIQUE,
ulint type, /*!< in: DICT_UNIQUE,
DICT_CLUSTERED, ... ORed */
ulint n_fields); /* in: number of fields */
/**************************************************************************
ulint n_fields); /*!< in: number of fields */
/**********************************************************************//**
Adds a field definition to an index. NOTE: does not take a copy
of the column name if the field is a column. The memory occupied
by the column name may be released only after publishing the index. */
@ -139,33 +151,34 @@ UNIV_INTERN
void
dict_mem_index_add_field(
/*=====================*/
dict_index_t* index, /* in: index */
const char* name, /* in: column name */
ulint prefix_len); /* in: 0 or the column prefix length
dict_index_t* index, /*!< in: index */
const char* name, /*!< in: column name */
ulint prefix_len); /*!< in: 0 or the column prefix length
in a MySQL index like
INDEX (textcol(25)) */
/**************************************************************************
/**********************************************************************//**
Frees an index memory object. */
UNIV_INTERN
void
dict_mem_index_free(
/*================*/
dict_index_t* index); /* in: index */
/**************************************************************************
Creates and initializes a foreign constraint memory object. */
dict_index_t* index); /*!< in: index */
/**********************************************************************//**
Creates and initializes a foreign constraint memory object.
@return own: foreign constraint struct */
UNIV_INTERN
dict_foreign_t*
dict_mem_foreign_create(void);
/*=========================*/
/* out, own: foreign constraint struct */
/* Data structure for a column in a table */
/** Data structure for a column in a table */
struct dict_col_struct{
/*----------------------*/
/* The following are copied from dtype_t,
/** The following are copied from dtype_t,
so that all bit-fields can be packed tightly. */
unsigned mtype:8; /* main data type */
unsigned prtype:24; /* precise type; MySQL data
/* @{ */
unsigned mtype:8; /*!< main data type */
unsigned prtype:24; /*!< precise type; MySQL data
type, charset code, flags to
indicate nullability,
signedness, whether this is a
@ -175,7 +188,7 @@ struct dict_col_struct{
/* the remaining fields do not affect alphabetical ordering: */
unsigned len:16; /* length; for MySQL data this
unsigned len:16; /*!< length; for MySQL data this
is field->pack_length(),
except that for a >= 5.0.3
type true VARCHAR this is the
@ -184,258 +197,276 @@ struct dict_col_struct{
the string, MySQL uses 1 or 2
bytes to store the string length) */
unsigned mbminlen:2; /* minimum length of a
unsigned mbminlen:2; /*!< minimum length of a
character, in bytes */
unsigned mbmaxlen:3; /* maximum length of a
unsigned mbmaxlen:3; /*!< maximum length of a
character, in bytes */
/*----------------------*/
/* End of definitions copied from dtype_t */
/* @} */
unsigned ind:10; /* table column position
unsigned ind:10; /*!< table column position
(starting from 0) */
unsigned ord_part:1; /* nonzero if this column
unsigned ord_part:1; /*!< nonzero if this column
appears in the ordering fields
of an index */
};
/* DICT_MAX_INDEX_COL_LEN is measured in bytes and is the maximum
indexed column length (or indexed prefix length). It is set to 3*256,
so that one can create a column prefix index on 256 characters of a
TEXT or VARCHAR column also in the UTF-8 charset. In that charset,
a character may take at most 3 bytes.
This constant MUST NOT BE CHANGED, or the compatibility of InnoDB data
files would be at risk! */
/** @brief DICT_MAX_INDEX_COL_LEN is measured in bytes and is the maximum
indexed column length (or indexed prefix length).
It is set to 3*256, so that one can create a column prefix index on
256 characters of a TEXT or VARCHAR column also in the UTF-8
charset. In that charset, a character may take at most 3 bytes. This
constant MUST NOT BE CHANGED, or the compatibility of InnoDB data
files would be at risk! */
#define DICT_MAX_INDEX_COL_LEN REC_MAX_INDEX_COL_LEN
/* Data structure for a field in an index */
/** Data structure for a field in an index */
struct dict_field_struct{
dict_col_t* col; /* pointer to the table column */
const char* name; /* name of the column */
unsigned prefix_len:10; /* 0 or the length of the column
dict_col_t* col; /*!< pointer to the table column */
const char* name; /*!< name of the column */
unsigned prefix_len:10; /*!< 0 or the length of the column
prefix in bytes in a MySQL index of
type, e.g., INDEX (textcol(25));
must be smaller than
DICT_MAX_INDEX_COL_LEN; NOTE that
in the UTF-8 charset, MySQL sets this
to 3 * the prefix len in UTF-8 chars */
unsigned fixed_len:10; /* 0 or the fixed length of the
unsigned fixed_len:10; /*!< 0 or the fixed length of the
column if smaller than
DICT_MAX_INDEX_COL_LEN */
};
/* Data structure for an index. Most fields will be
/** Data structure for an index. Most fields will be
initialized to 0, NULL or FALSE in dict_mem_index_create(). */
struct dict_index_struct{
dulint id; /* id of the index */
mem_heap_t* heap; /* memory heap */
const char* name; /* index name */
const char* table_name; /* table name */
dict_table_t* table; /* back pointer to table */
dulint id; /*!< id of the index */
mem_heap_t* heap; /*!< memory heap */
const char* name; /*!< index name */
const char* table_name;/*!< table name */
dict_table_t* table; /*!< back pointer to table */
#ifndef UNIV_HOTBACKUP
unsigned space:32;
/* space where the index tree is placed */
unsigned page:32;/* index tree root page number */
unsigned type:4; /* index type (DICT_CLUSTERED, DICT_UNIQUE,
/*!< space where the index tree is placed */
unsigned page:32;/*!< index tree root page number */
#endif /* !UNIV_HOTBACKUP */
unsigned type:4; /*!< index type (DICT_CLUSTERED, DICT_UNIQUE,
DICT_UNIVERSAL, DICT_IBUF) */
unsigned trx_id_offset:10;/* position of the trx id column
unsigned trx_id_offset:10;/*!< position of the trx id column
in a clustered index record, if the fields
before it are known to be of a fixed size,
0 otherwise */
unsigned n_user_defined_cols:10;
/* number of columns the user defined to
/*!< number of columns the user defined to
be in the index: in the internal
representation we add more columns */
unsigned n_uniq:10;/* number of fields from the beginning
unsigned n_uniq:10;/*!< number of fields from the beginning
which are enough to determine an index
entry uniquely */
unsigned n_def:10;/* number of fields defined so far */
unsigned n_fields:10;/* number of fields in the index */
unsigned n_nullable:10;/* number of nullable fields */
unsigned cached:1;/* TRUE if the index object is in the
unsigned n_def:10;/*!< number of fields defined so far */
unsigned n_fields:10;/*!< number of fields in the index */
unsigned n_nullable:10;/*!< number of nullable fields */
unsigned cached:1;/*!< TRUE if the index object is in the
dictionary cache */
unsigned to_be_dropped:1;
/* TRUE if this index is marked to be
/*!< TRUE if this index is marked to be
dropped in ha_innobase::prepare_drop_index(),
otherwise FALSE */
dict_field_t* fields; /* array of field descriptions */
dict_field_t* fields; /*!< array of field descriptions */
#ifndef UNIV_HOTBACKUP
UT_LIST_NODE_T(dict_index_t)
indexes;/* list of indexes of the table */
btr_search_t* search_info; /* info used in optimistic searches */
indexes;/*!< list of indexes of the table */
btr_search_t* search_info; /*!< info used in optimistic searches */
/*----------------------*/
/** Statistics for query optimization */
/* @{ */
ib_int64_t* stat_n_diff_key_vals;
/* approximate number of different key values
for this index, for each n-column prefix
where n <= dict_get_n_unique(index); we
periodically calculate new estimates */
/*!< approximate number of different
key values for this index, for each
n-column prefix where n <=
dict_get_n_unique(index); we
periodically calculate new
estimates */
ulint stat_index_size;
/* approximate index size in database pages */
/*!< approximate index size in
database pages */
ulint stat_n_leaf_pages;
/* approximate number of leaf pages in the
/*!< approximate number of leaf pages in the
index tree */
rw_lock_t lock; /* read-write lock protecting the upper levels
of the index tree */
#ifdef ROW_MERGE_IS_INDEX_USABLE
dulint trx_id; /* id of the transaction that created this
index, or ut_dulint_zero if the index existed
/* @} */
rw_lock_t lock; /*!< read-write lock protecting the
upper levels of the index tree */
ib_uint64_t trx_id; /*!< id of the transaction that created this
index, or 0 if the index existed
when InnoDB was started up */
#endif /* ROW_MERGE_IS_INDEX_USABLE */
#endif /* !UNIV_HOTBACKUP */
#ifdef UNIV_DEBUG
ulint magic_n;/* magic number */
ulint magic_n;/*!< magic number */
/** Value of dict_index_struct::magic_n */
# define DICT_INDEX_MAGIC_N 76789786
#endif
};
/* Data structure for a foreign key constraint; an example:
/** Data structure for a foreign key constraint; an example:
FOREIGN KEY (A, B) REFERENCES TABLE2 (C, D). Most fields will be
initialized to 0, NULL or FALSE in dict_mem_foreign_create(). */
struct dict_foreign_struct{
mem_heap_t* heap; /* this object is allocated from
mem_heap_t* heap; /*!< this object is allocated from
this memory heap */
char* id; /* id of the constraint as a
char* id; /*!< id of the constraint as a
null-terminated string */
unsigned n_fields:10; /* number of indexes' first fields
unsigned n_fields:10; /*!< number of indexes' first fields
for which the the foreign key
constraint is defined: we allow the
indexes to contain more fields than
mentioned in the constraint, as long
as the first fields are as mentioned */
unsigned type:6; /* 0 or DICT_FOREIGN_ON_DELETE_CASCADE
unsigned type:6; /*!< 0 or DICT_FOREIGN_ON_DELETE_CASCADE
or DICT_FOREIGN_ON_DELETE_SET_NULL */
char* foreign_table_name;/* foreign table name */
dict_table_t* foreign_table; /* table where the foreign key is */
const char** foreign_col_names;/* names of the columns in the
char* foreign_table_name;/*!< foreign table name */
dict_table_t* foreign_table; /*!< table where the foreign key is */
const char** foreign_col_names;/*!< names of the columns in the
foreign key */
char* referenced_table_name;/* referenced table name */
dict_table_t* referenced_table;/* table where the referenced key
char* referenced_table_name;/*!< referenced table name */
dict_table_t* referenced_table;/*!< table where the referenced key
is */
const char** referenced_col_names;/* names of the referenced
const char** referenced_col_names;/*!< names of the referenced
columns in the referenced table */
dict_index_t* foreign_index; /* foreign index; we require that
dict_index_t* foreign_index; /*!< foreign index; we require that
both tables contain explicitly defined
indexes for the constraint: InnoDB
does not generate new indexes
implicitly */
dict_index_t* referenced_index;/* referenced index */
dict_index_t* referenced_index;/*!< referenced index */
UT_LIST_NODE_T(dict_foreign_t)
foreign_list; /* list node for foreign keys of the
foreign_list; /*!< list node for foreign keys of the
table */
UT_LIST_NODE_T(dict_foreign_t)
referenced_list;/* list node for referenced keys of the
table */
referenced_list;/*!< list node for referenced
keys of the table */
};
/* The flags for ON_UPDATE and ON_DELETE can be ORed; the default is that
/** The flags for ON_UPDATE and ON_DELETE can be ORed; the default is that
a foreign key constraint is enforced, therefore RESTRICT just means no flag */
#define DICT_FOREIGN_ON_DELETE_CASCADE 1
#define DICT_FOREIGN_ON_DELETE_SET_NULL 2
#define DICT_FOREIGN_ON_UPDATE_CASCADE 4
#define DICT_FOREIGN_ON_UPDATE_SET_NULL 8
#define DICT_FOREIGN_ON_DELETE_NO_ACTION 16
#define DICT_FOREIGN_ON_UPDATE_NO_ACTION 32
/* @{ */
#define DICT_FOREIGN_ON_DELETE_CASCADE 1 /*!< ON DELETE CASCADE */
#define DICT_FOREIGN_ON_DELETE_SET_NULL 2 /*!< ON UPDATE SET NULL */
#define DICT_FOREIGN_ON_UPDATE_CASCADE 4 /*!< ON DELETE CASCADE */
#define DICT_FOREIGN_ON_UPDATE_SET_NULL 8 /*!< ON UPDATE SET NULL */
#define DICT_FOREIGN_ON_DELETE_NO_ACTION 16 /*!< ON DELETE NO ACTION */
#define DICT_FOREIGN_ON_UPDATE_NO_ACTION 32 /*!< ON UPDATE NO ACTION */
/* @} */
/* Data structure for a database table. Most fields will be
/** Data structure for a database table. Most fields will be
initialized to 0, NULL or FALSE in dict_mem_table_create(). */
struct dict_table_struct{
dulint id; /* id of the table */
mem_heap_t* heap; /* memory heap */
const char* name; /* table name */
const char* dir_path_of_temp_table;/* NULL or the directory path
dulint id; /*!< id of the table */
mem_heap_t* heap; /*!< memory heap */
const char* name; /*!< table name */
const char* dir_path_of_temp_table;/*!< NULL or the directory path
where a TEMPORARY table that was explicitly
created by a user should be placed if
innodb_file_per_table is defined in my.cnf;
in Unix this is usually /tmp/..., in Windows
\temp\... */
temp\... */
unsigned space:32;
/* space where the clustered index of the
/*!< space where the clustered index of the
table is placed */
unsigned flags:DICT_TF_BITS;/* DICT_TF_COMPACT, ... */
unsigned flags:DICT_TF_BITS;/*!< DICT_TF_COMPACT, ... */
unsigned ibd_file_missing:1;
/* TRUE if this is in a single-table
/*!< TRUE if this is in a single-table
tablespace and the .ibd file is missing; then
we must return in ha_innodb.cc an error if the
user tries to query such an orphaned table */
unsigned tablespace_discarded:1;
/* this flag is set TRUE when the user
/*!< this flag is set TRUE when the user
calls DISCARD TABLESPACE on this
table, and reset to FALSE in IMPORT
TABLESPACE */
unsigned cached:1;/* TRUE if the table object has been added
unsigned cached:1;/*!< TRUE if the table object has been added
to the dictionary cache */
unsigned n_def:10;/* number of columns defined so far */
unsigned n_cols:10;/* number of columns */
dict_col_t* cols; /* array of column descriptions */
unsigned n_def:10;/*!< number of columns defined so far */
unsigned n_cols:10;/*!< number of columns */
dict_col_t* cols; /*!< array of column descriptions */
const char* col_names;
/* Column names packed in a character string
/*!< Column names packed in a character string
"name1\0name2\0...nameN\0". Until
the string contains n_cols, it will be
allocated from a temporary heap. The final
string will be allocated from table->heap. */
hash_node_t name_hash; /* hash chain node */
hash_node_t id_hash; /* hash chain node */
#ifndef UNIV_HOTBACKUP
hash_node_t name_hash; /*!< hash chain node */
hash_node_t id_hash; /*!< hash chain node */
UT_LIST_BASE_NODE_T(dict_index_t)
indexes; /* list of indexes of the table */
indexes; /*!< list of indexes of the table */
UT_LIST_BASE_NODE_T(dict_foreign_t)
foreign_list;/* list of foreign key constraints
foreign_list;/*!< list of foreign key constraints
in the table; these refer to columns
in other tables */
UT_LIST_BASE_NODE_T(dict_foreign_t)
referenced_list;/* list of foreign key constraints
referenced_list;/*!< list of foreign key constraints
which refer to this table */
UT_LIST_NODE_T(dict_table_t)
table_LRU; /* node of the LRU list of tables */
table_LRU; /*!< node of the LRU list of tables */
ulint n_mysql_handles_opened;
/* count of how many handles MySQL has opened
/*!< count of how many handles MySQL has opened
to this table; dropping of the table is
NOT allowed until this count gets to zero;
MySQL does NOT itself check the number of
open handles at drop */
ulint n_foreign_key_checks_running;
/* count of how many foreign key check
/*!< count of how many foreign key check
operations are currently being performed
on the table: we cannot drop the table while
there are foreign key checks running on
it! */
dulint query_cache_inv_trx_id;
/* transactions whose trx id < than this
number are not allowed to store to the MySQL
query cache or retrieve from it; when a trx
with undo logs commits, it sets this to the
value of the trx id counter for the tables it
had an IX lock on */
trx_id_t query_cache_inv_trx_id;
/*!< transactions whose trx id is
smaller than this number are not
allowed to store to the MySQL query
cache or retrieve from it; when a trx
with undo logs commits, it sets this
to the value of the trx id counter for
the tables it had an IX lock on */
UT_LIST_BASE_NODE_T(lock_t)
locks; /* list of locks on the table */
locks; /*!< list of locks on the table */
#ifdef UNIV_DEBUG
/*----------------------*/
ibool does_not_fit_in_memory;
/* this field is used to specify in simulations
tables which are so big that disk should be
accessed: disk access is simulated by
putting the thread to sleep for a while;
NOTE that this flag is not stored to the data
dictionary on disk, and the database will
forget about value TRUE if it has to reload
the table definition from disk */
/*!< this field is used to specify in
simulations tables which are so big
that disk should be accessed: disk
access is simulated by putting the
thread to sleep for a while; NOTE that
this flag is not stored to the data
dictionary on disk, and the database
will forget about value TRUE if it has
to reload the table definition from
disk */
#endif /* UNIV_DEBUG */
/*----------------------*/
unsigned big_rows:1;
/* flag: TRUE if the maximum length of
/*!< flag: TRUE if the maximum length of
a single row exceeds BIG_ROW_SIZE;
initialized in dict_table_add_to_cache() */
unsigned stat_initialized:1; /* TRUE if statistics have
/** Statistics for query optimization */
/* @{ */
unsigned stat_initialized:1; /*!< TRUE if statistics have
been calculated the first time
after database startup or table creation */
ib_int64_t stat_n_rows;
/* approximate number of rows in the table;
/*!< approximate number of rows in the table;
we periodically calculate new estimates */
ulint stat_clustered_index_size;
/* approximate clustered index size in
/*!< approximate clustered index size in
database pages */
ulint stat_sum_of_other_index_sizes;
/* other indexes in database pages */
/*!< other indexes in database pages */
ulint stat_modified_counter;
/* when a row is inserted, updated, or deleted,
/*!< when a row is inserted, updated,
or deleted,
we add 1 to this number; we calculate new
estimates for the stat_... values for the
table and the indexes at an interval of 2 GB
@ -446,8 +477,9 @@ struct dict_table_struct{
calculation; this counter is not protected by
any latch, because this is only used for
heuristics */
/* @} */
/*----------------------*/
/* The following fields are used by the
/**!< The following fields are used by the
AUTOINC code. The actual collection of
tables locked during AUTOINC read/write is
kept in trx_t. In order to quickly determine
@ -461,8 +493,9 @@ struct dict_table_struct{
corresponding lock instance is created on
the trx lock heap rather than use the
pre-allocated instance in autoinc_lock below.*/
/* @{ */
lock_t* autoinc_lock;
/* a buffer for an AUTOINC lock
/*!< a buffer for an AUTOINC lock
for this table: we allocate the memory here
so that individual transactions can get it
and release it without a need to allocate
@ -470,12 +503,12 @@ struct dict_table_struct{
otherwise the lock heap would grow rapidly
if we do a large insert from a select */
mutex_t autoinc_mutex;
/* mutex protecting the autoincrement
/*!< mutex protecting the autoincrement
counter */
ib_uint64_t autoinc;/* autoinc counter value to give to the
ib_uint64_t autoinc;/*!< autoinc counter value to give to the
next inserted row */
ulong n_waiting_or_granted_auto_inc_locks;
/* This counter is used to track the number
/*!< This counter is used to track the number
of granted and pending autoinc locks on this
table. This value is set after acquiring the
kernel mutex but we peek the contents to
@ -484,12 +517,15 @@ struct dict_table_struct{
only one transaction can be granted the
lock but there can be multiple waiters. */
const trx_t* autoinc_trx;
/* The transaction that currently holds the
/*!< The transaction that currently holds the
the AUTOINC lock on this table. */
/* @} */
/*----------------------*/
#endif /* !UNIV_HOTBACKUP */
#ifdef UNIV_DEBUG
ulint magic_n;/* magic number */
ulint magic_n;/*!< magic number */
/** Value of dict_table_struct::magic_n */
# define DICT_TABLE_MAGIC_N 76333786
#endif /* UNIV_DEBUG */
};

View File

@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
/**********************************************************************
/******************************************************************//**
@file include/dict0mem.ic
Data dictionary memory object creation
Created 1/8/1996 Heikki Tuuri

View File

@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
/******************************************************
/**************************************************//**
@file include/dict0types.h
Data dictionary global types
Created 1/8/1996 Heikki Tuuri
@ -25,8 +26,6 @@ Created 1/8/1996 Heikki Tuuri
#ifndef dict0types_h
#define dict0types_h
#include "ut0list.h"
typedef struct dict_sys_struct dict_sys_t;
typedef struct dict_col_struct dict_col_t;
typedef struct dict_field_struct dict_field_t;
@ -42,4 +41,8 @@ typedef dict_table_t dict_cluster_t;
typedef struct ind_node_struct ind_node_t;
typedef struct tab_node_struct tab_node_t;
/* Space id and page no where the dictionary header resides */
#define DICT_HDR_SPACE 0 /* the SYSTEM tablespace */
#define DICT_HDR_PAGE_NO FSP_DICT_HDR_PAGE_NO
#endif

View File

@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
/******************************************************
/**************************************************//**
@file include/dyn0dyn.h
The dynamically allocated array
Created 2/5/1996 Heikki Tuuri
@ -29,148 +30,153 @@ Created 2/5/1996 Heikki Tuuri
#include "ut0lst.h"
#include "mem0mem.h"
/** A block in a dynamically allocated array */
typedef struct dyn_block_struct dyn_block_t;
/** Dynamically allocated array */
typedef dyn_block_t dyn_array_t;
/* This is the initial 'payload' size of a dynamic array;
/** This is the initial 'payload' size of a dynamic array;
this must be > MLOG_BUF_MARGIN + 30! */
#define DYN_ARRAY_DATA_SIZE 512
/*************************************************************************
Initializes a dynamic array. */
/*********************************************************************//**
Initializes a dynamic array.
@return initialized dyn array */
UNIV_INLINE
dyn_array_t*
dyn_array_create(
/*=============*/
/* out: initialized dyn array */
dyn_array_t* arr); /* in: pointer to a memory buffer of
dyn_array_t* arr); /*!< in: pointer to a memory buffer of
size sizeof(dyn_array_t) */
/****************************************************************
/************************************************************//**
Frees a dynamic array. */
UNIV_INLINE
void
dyn_array_free(
/*===========*/
dyn_array_t* arr); /* in: dyn array */
/*************************************************************************
dyn_array_t* arr); /*!< in: dyn array */
/*********************************************************************//**
Makes room on top of a dyn array and returns a pointer to a buffer in it.
After copying the elements, the caller must close the buffer using
dyn_array_close. */
dyn_array_close.
@return pointer to the buffer */
UNIV_INLINE
byte*
dyn_array_open(
/*===========*/
/* out: pointer to the buffer */
dyn_array_t* arr, /* in: dynamic array */
ulint size); /* in: size in bytes of the buffer; MUST be
dyn_array_t* arr, /*!< in: dynamic array */
ulint size); /*!< in: size in bytes of the buffer; MUST be
smaller than DYN_ARRAY_DATA_SIZE! */
/*************************************************************************
/*********************************************************************//**
Closes the buffer returned by dyn_array_open. */
UNIV_INLINE
void
dyn_array_close(
/*============*/
dyn_array_t* arr, /* in: dynamic array */
byte* ptr); /* in: buffer space from ptr up was not used */
/*************************************************************************
dyn_array_t* arr, /*!< in: dynamic array */
byte* ptr); /*!< in: buffer space from ptr up was not used */
/*********************************************************************//**
Makes room on top of a dyn array and returns a pointer to
the added element. The caller must copy the element to
the pointer returned. */
the pointer returned.
@return pointer to the element */
UNIV_INLINE
void*
dyn_array_push(
/*===========*/
/* out: pointer to the element */
dyn_array_t* arr, /* in: dynamic array */
ulint size); /* in: size in bytes of the element */
/****************************************************************
Returns pointer to an element in dyn array. */
dyn_array_t* arr, /*!< in: dynamic array */
ulint size); /*!< in: size in bytes of the element */
/************************************************************//**
Returns pointer to an element in dyn array.
@return pointer to element */
UNIV_INLINE
void*
dyn_array_get_element(
/*==================*/
/* out: pointer to element */
dyn_array_t* arr, /* in: dyn array */
ulint pos); /* in: position of element as bytes
dyn_array_t* arr, /*!< in: dyn array */
ulint pos); /*!< in: position of element as bytes
from array start */
/****************************************************************
Returns the size of stored data in a dyn array. */
/************************************************************//**
Returns the size of stored data in a dyn array.
@return data size in bytes */
UNIV_INLINE
ulint
dyn_array_get_data_size(
/*====================*/
/* out: data size in bytes */
dyn_array_t* arr); /* in: dyn array */
/****************************************************************
dyn_array_t* arr); /*!< in: dyn array */
/************************************************************//**
Gets the first block in a dyn array. */
UNIV_INLINE
dyn_block_t*
dyn_array_get_first_block(
/*======================*/
dyn_array_t* arr); /* in: dyn array */
/****************************************************************
dyn_array_t* arr); /*!< in: dyn array */
/************************************************************//**
Gets the last block in a dyn array. */
UNIV_INLINE
dyn_block_t*
dyn_array_get_last_block(
/*=====================*/
dyn_array_t* arr); /* in: dyn array */
/************************************************************************
Gets the next block in a dyn array. */
dyn_array_t* arr); /*!< in: dyn array */
/********************************************************************//**
Gets the next block in a dyn array.
@return pointer to next, NULL if end of list */
UNIV_INLINE
dyn_block_t*
dyn_array_get_next_block(
/*=====================*/
/* out: pointer to next, NULL if end of list */
dyn_array_t* arr, /* in: dyn array */
dyn_block_t* block); /* in: dyn array block */
/************************************************************************
Gets the number of used bytes in a dyn array block. */
dyn_array_t* arr, /*!< in: dyn array */
dyn_block_t* block); /*!< in: dyn array block */
/********************************************************************//**
Gets the number of used bytes in a dyn array block.
@return number of bytes used */
UNIV_INLINE
ulint
dyn_block_get_used(
/*===============*/
/* out: number of bytes used */
dyn_block_t* block); /* in: dyn array block */
/************************************************************************
Gets pointer to the start of data in a dyn array block. */
dyn_block_t* block); /*!< in: dyn array block */
/********************************************************************//**
Gets pointer to the start of data in a dyn array block.
@return pointer to data */
UNIV_INLINE
byte*
dyn_block_get_data(
/*===============*/
/* out: pointer to data */
dyn_block_t* block); /* in: dyn array block */
/************************************************************
dyn_block_t* block); /*!< in: dyn array block */
/********************************************************//**
Pushes n bytes to a dyn array. */
UNIV_INLINE
void
dyn_push_string(
/*============*/
dyn_array_t* arr, /* in: dyn array */
const byte* str, /* in: string to write */
ulint len); /* in: string length */
dyn_array_t* arr, /*!< in: dyn array */
const byte* str, /*!< in: string to write */
ulint len); /*!< in: string length */
/*#################################################################*/
/* NOTE! Do not use the fields of the struct directly: the definition
/** @brief A block in a dynamically allocated array.
NOTE! Do not access the fields of the struct directly: the definition
appears here only for the compiler to know its size! */
struct dyn_block_struct{
mem_heap_t* heap; /* in the first block this is != NULL
mem_heap_t* heap; /*!< in the first block this is != NULL
if dynamic allocation has been needed */
ulint used; /* number of data bytes used in this block */
ulint used; /*!< number of data bytes used in this block;
DYN_BLOCK_FULL_FLAG is set when the block
becomes full */
byte data[DYN_ARRAY_DATA_SIZE];
/* storage for array elements */
/*!< storage for array elements */
UT_LIST_BASE_NODE_T(dyn_block_t) base;
/* linear list of dyn blocks: this node is
/*!< linear list of dyn blocks: this node is
used only in the first block */
UT_LIST_NODE_T(dyn_block_t) list;
/* linear list node: used in all blocks */
/*!< linear list node: used in all blocks */
#ifdef UNIV_DEBUG
ulint buf_end;/* only in the debug version: if dyn array is
opened, this is the buffer end offset, else
this is 0 */
ulint magic_n;
ulint buf_end;/*!< only in the debug version: if dyn
array is opened, this is the buffer
end offset, else this is 0 */
ulint magic_n;/*!< magic number (DYN_BLOCK_MAGIC_N) */
#endif
};

View File

@ -16,43 +16,46 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
/******************************************************
/**************************************************//**
@file include/dyn0dyn.ic
The dynamically allocated array
Created 2/5/1996 Heikki Tuuri
*******************************************************/
/** Value of dyn_block_struct::magic_n */
#define DYN_BLOCK_MAGIC_N 375767
/** Flag for dyn_block_struct::used that indicates a full block */
#define DYN_BLOCK_FULL_FLAG 0x1000000UL
/****************************************************************
Adds a new block to a dyn array. */
/************************************************************//**
Adds a new block to a dyn array.
@return created block */
UNIV_INTERN
dyn_block_t*
dyn_array_add_block(
/*================*/
/* out: created block */
dyn_array_t* arr); /* in: dyn array */
dyn_array_t* arr); /*!< in: dyn array */
/****************************************************************
/************************************************************//**
Gets the first block in a dyn array. */
UNIV_INLINE
dyn_block_t*
dyn_array_get_first_block(
/*======================*/
dyn_array_t* arr) /* in: dyn array */
dyn_array_t* arr) /*!< in: dyn array */
{
return(arr);
}
/****************************************************************
/************************************************************//**
Gets the last block in a dyn array. */
UNIV_INLINE
dyn_block_t*
dyn_array_get_last_block(
/*=====================*/
dyn_array_t* arr) /* in: dyn array */
dyn_array_t* arr) /*!< in: dyn array */
{
if (arr->heap == NULL) {
@ -62,15 +65,15 @@ dyn_array_get_last_block(
return(UT_LIST_GET_LAST(arr->base));
}
/************************************************************************
Gets the next block in a dyn array. */
/********************************************************************//**
Gets the next block in a dyn array.
@return pointer to next, NULL if end of list */
UNIV_INLINE
dyn_block_t*
dyn_array_get_next_block(
/*=====================*/
/* out: pointer to next, NULL if end of list */
dyn_array_t* arr, /* in: dyn array */
dyn_block_t* block) /* in: dyn array block */
dyn_array_t* arr, /*!< in: dyn array */
dyn_block_t* block) /*!< in: dyn array block */
{
ut_ad(arr && block);
@ -83,42 +86,42 @@ dyn_array_get_next_block(
return(UT_LIST_GET_NEXT(list, block));
}
/************************************************************************
Gets the number of used bytes in a dyn array block. */
/********************************************************************//**
Gets the number of used bytes in a dyn array block.
@return number of bytes used */
UNIV_INLINE
ulint
dyn_block_get_used(
/*===============*/
/* out: number of bytes used */
dyn_block_t* block) /* in: dyn array block */
dyn_block_t* block) /*!< in: dyn array block */
{
ut_ad(block);
return((block->used) & ~DYN_BLOCK_FULL_FLAG);
}
/************************************************************************
Gets pointer to the start of data in a dyn array block. */
/********************************************************************//**
Gets pointer to the start of data in a dyn array block.
@return pointer to data */
UNIV_INLINE
byte*
dyn_block_get_data(
/*===============*/
/* out: pointer to data */
dyn_block_t* block) /* in: dyn array block */
dyn_block_t* block) /*!< in: dyn array block */
{
ut_ad(block);
return(block->data);
}
/*************************************************************************
Initializes a dynamic array. */
/*********************************************************************//**
Initializes a dynamic array.
@return initialized dyn array */
UNIV_INLINE
dyn_array_t*
dyn_array_create(
/*=============*/
/* out: initialized dyn array */
dyn_array_t* arr) /* in: pointer to a memory buffer of
dyn_array_t* arr) /*!< in: pointer to a memory buffer of
size sizeof(dyn_array_t) */
{
ut_ad(arr);
@ -136,13 +139,13 @@ dyn_array_create(
return(arr);
}
/****************************************************************
/************************************************************//**
Frees a dynamic array. */
UNIV_INLINE
void
dyn_array_free(
/*===========*/
dyn_array_t* arr) /* in: dyn array */
dyn_array_t* arr) /*!< in: dyn array */
{
if (arr->heap != NULL) {
mem_heap_free(arr->heap);
@ -153,16 +156,16 @@ dyn_array_free(
#endif
}
/*************************************************************************
/*********************************************************************//**
Makes room on top of a dyn array and returns a pointer to the added element.
The caller must copy the element to the pointer returned. */
The caller must copy the element to the pointer returned.
@return pointer to the element */
UNIV_INLINE
void*
dyn_array_push(
/*===========*/
/* out: pointer to the element */
dyn_array_t* arr, /* in: dynamic array */
ulint size) /* in: size in bytes of the element */
dyn_array_t* arr, /*!< in: dynamic array */
ulint size) /*!< in: size in bytes of the element */
{
dyn_block_t* block;
ulint used;
@ -193,17 +196,17 @@ dyn_array_push(
return((block->data) + used);
}
/*************************************************************************
/*********************************************************************//**
Makes room on top of a dyn array and returns a pointer to a buffer in it.
After copying the elements, the caller must close the buffer using
dyn_array_close. */
dyn_array_close.
@return pointer to the buffer */
UNIV_INLINE
byte*
dyn_array_open(
/*===========*/
/* out: pointer to the buffer */
dyn_array_t* arr, /* in: dynamic array */
ulint size) /* in: size in bytes of the buffer; MUST be
dyn_array_t* arr, /*!< in: dynamic array */
ulint size) /*!< in: size in bytes of the buffer; MUST be
smaller than DYN_ARRAY_DATA_SIZE! */
{
dyn_block_t* block;
@ -239,14 +242,14 @@ dyn_array_open(
return((block->data) + used);
}
/*************************************************************************
/*********************************************************************//**
Closes the buffer returned by dyn_array_open. */
UNIV_INLINE
void
dyn_array_close(
/*============*/
dyn_array_t* arr, /* in: dynamic array */
byte* ptr) /* in: buffer space from ptr up was not used */
dyn_array_t* arr, /*!< in: dynamic array */
byte* ptr) /*!< in: buffer space from ptr up was not used */
{
dyn_block_t* block;
@ -266,15 +269,15 @@ dyn_array_close(
#endif
}
/****************************************************************
Returns pointer to an element in dyn array. */
/************************************************************//**
Returns pointer to an element in dyn array.
@return pointer to element */
UNIV_INLINE
void*
dyn_array_get_element(
/*==================*/
/* out: pointer to element */
dyn_array_t* arr, /* in: dyn array */
ulint pos) /* in: position of element as bytes
dyn_array_t* arr, /*!< in: dyn array */
ulint pos) /*!< in: position of element as bytes
from array start */
{
dyn_block_t* block;
@ -304,14 +307,14 @@ dyn_array_get_element(
return(block->data + pos);
}
/****************************************************************
Returns the size of stored data in a dyn array. */
/************************************************************//**
Returns the size of stored data in a dyn array.
@return data size in bytes */
UNIV_INLINE
ulint
dyn_array_get_data_size(
/*====================*/
/* out: data size in bytes */
dyn_array_t* arr) /* in: dyn array */
dyn_array_t* arr) /*!< in: dyn array */
{
dyn_block_t* block;
ulint sum = 0;
@ -335,15 +338,15 @@ dyn_array_get_data_size(
return(sum);
}
/************************************************************
/********************************************************//**
Pushes n bytes to a dyn array. */
UNIV_INLINE
void
dyn_push_string(
/*============*/
dyn_array_t* arr, /* in: dyn array */
const byte* str, /* in: string to write */
ulint len) /* in: string length */
dyn_array_t* arr, /*!< in: dyn array */
const byte* str, /*!< in: string to write */
ulint len) /*!< in: string length */
{
ulint n_copied;

View File

@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
/******************************************************
/**************************************************//**
@file include/eval0eval.h
SQL evaluator: evaluates simple data structures, like expressions, in
a query graph
@ -31,7 +32,7 @@ Created 12/29/1997 Heikki Tuuri
#include "pars0sym.h"
#include "pars0pars.h"
/*********************************************************************
/*****************************************************************//**
Free the buffer from global dynamic memory for a value of a que_node,
if it has been allocated in the above function. The freeing for pushed
column values is done in sel_col_prefetch_buf_free. */
@ -39,71 +40,71 @@ UNIV_INTERN
void
eval_node_free_val_buf(
/*===================*/
que_node_t* node); /* in: query graph node */
/*********************************************************************
que_node_t* node); /*!< in: query graph node */
/*****************************************************************//**
Evaluates a symbol table symbol. */
UNIV_INLINE
void
eval_sym(
/*=====*/
sym_node_t* sym_node); /* in: symbol table node */
/*********************************************************************
sym_node_t* sym_node); /*!< in: symbol table node */
/*****************************************************************//**
Evaluates an expression. */
UNIV_INLINE
void
eval_exp(
/*=====*/
que_node_t* exp_node); /* in: expression */
/*********************************************************************
que_node_t* exp_node); /*!< in: expression */
/*****************************************************************//**
Sets an integer value as the value of an expression node. */
UNIV_INLINE
void
eval_node_set_int_val(
/*==================*/
que_node_t* node, /* in: expression node */
lint val); /* in: value to set */
/*********************************************************************
Gets an integer value from an expression node. */
que_node_t* node, /*!< in: expression node */
lint val); /*!< in: value to set */
/*****************************************************************//**
Gets an integer value from an expression node.
@return integer value */
UNIV_INLINE
lint
eval_node_get_int_val(
/*==================*/
/* out: integer value */
que_node_t* node); /* in: expression node */
/*********************************************************************
que_node_t* node); /*!< in: expression node */
/*****************************************************************//**
Copies a binary string value as the value of a query graph node. Allocates a
new buffer if necessary. */
UNIV_INLINE
void
eval_node_copy_and_alloc_val(
/*=========================*/
que_node_t* node, /* in: query graph node */
const byte* str, /* in: binary string */
ulint len); /* in: string length or UNIV_SQL_NULL */
/*********************************************************************
que_node_t* node, /*!< in: query graph node */
const byte* str, /*!< in: binary string */
ulint len); /*!< in: string length or UNIV_SQL_NULL */
/*****************************************************************//**
Copies a query node value to another node. */
UNIV_INLINE
void
eval_node_copy_val(
/*===============*/
que_node_t* node1, /* in: node to copy to */
que_node_t* node2); /* in: node to copy from */
/*********************************************************************
Gets a iboolean value from a query node. */
que_node_t* node1, /*!< in: node to copy to */
que_node_t* node2); /*!< in: node to copy from */
/*****************************************************************//**
Gets a iboolean value from a query node.
@return iboolean value */
UNIV_INLINE
ibool
eval_node_get_ibool_val(
/*====================*/
/* out: iboolean value */
que_node_t* node); /* in: query graph node */
/*********************************************************************
Evaluates a comparison node. */
que_node_t* node); /*!< in: query graph node */
/*****************************************************************//**
Evaluates a comparison node.
@return the result of the comparison */
UNIV_INTERN
ibool
eval_cmp(
/*=====*/
/* out: the result of the comparison */
func_node_t* cmp_node); /* in: comparison node */
func_node_t* cmp_node); /*!< in: comparison node */
#ifndef UNIV_NONINL

Some files were not shown because too many files have changed in this diff Show More