Commit a0e12ec2 authored by Satya B's avatar Satya B

Merging Innodb plugin 1.0.5 revisions from 5.1-main from revisions 3149 to 3163

also merged missing Innodb plugin revisions r5636,r5635 manually
parent 42ea72db
drop table if exists t1;
set session transaction isolation level read committed;
create table t1(a int not null) engine=innodb DEFAULT CHARSET=latin1;
create table t2 like t1;
insert into t2 values (1),(2),(3),(4),(5),(6),(7);
set autocommit=0;
begin;
replace into t1 select * from t2;
set session transaction isolation level read committed;
set autocommit=0;
delete from t2 where a=5;
commit;
delete from t2;
commit;
commit;
begin;
insert into t1 select * from t2;
set session transaction isolation level read committed;
set autocommit=0;
delete from t2 where a=5;
commit;
delete from t2;
commit;
commit;
select * from t1;
a
1
2
3
4
5
6
7
drop table t1;
drop table t2;
......@@ -6,4 +6,5 @@ SELECT f4, f8 FROM bug34300;
f4 f8
xxx zzz
DROP TABLE bug34300;
SET @@global.max_allowed_packet=1048576;
SET @@global.max_allowed_packet=default;
create table bug44369 (DB_ROW_ID int) engine=innodb;
ERROR HY000: Can't create table 'test.bug44369' (errno: -1)
create table bug44369 (db_row_id int) engine=innodb;
ERROR HY000: Can't create table 'test.bug44369' (errno: -1)
show errors;
Level Code Message
Error 1005 Error creating table 'test/bug44369' with column name 'db_row_id'. 'db_row_id' is a reserved name. Please try to re-create the table with a different column name.
Error 1005 Can't create table 'test.bug44369' (errno: -1)
create table bug44369 (db_TRX_Id int) engine=innodb;
ERROR HY000: Can't create table 'test.bug44369' (errno: -1)
show errors;
Level Code Message
Error 1005 Error creating table 'test/bug44369' with column name 'db_TRX_Id'. 'db_TRX_Id' is a reserved name. Please try to re-create the table with a different column name.
Error 1005 Can't create table 'test.bug44369' (errno: -1)
CREATE TABLE bug44571 (foo INT) ENGINE=InnoDB;
ALTER TABLE bug44571 CHANGE foo bar INT;
ALTER TABLE bug44571 ADD INDEX bug44571b (foo);
ERROR 42000: Key column 'foo' doesn't exist in table
ALTER TABLE bug44571 ADD INDEX bug44571b (bar);
ERROR HY000: Incorrect key file for table 'bug44571'; try to repair it
CREATE INDEX bug44571b ON bug44571 (bar);
ERROR HY000: Incorrect key file for table 'bug44571'; try to repair it
DROP TABLE bug44571;
create table bug46000(`id` int,key `GEN_CLUST_INDEX`(`id`))engine=innodb;
ERROR HY000: Can't create table 'test.bug46000' (errno: -1)
create table bug46000(`id` int, key `GEN_clust_INDEX`(`id`))engine=innodb;
ERROR HY000: Can't create table 'test.bug46000' (errno: -1)
show errors;
Level Code Message
Error 1005 Cannot Create Index with name 'GEN_CLUST_INDEX'. The name is reserved for the system default primary index.
Error 1005 Can't create table 'test.bug46000' (errno: -1)
create table bug46000(id int) engine=innodb;
create index GEN_CLUST_INDEX on bug46000(id);
ERROR HY000: Can't create table '#sql-temporary' (errno: -1)
show errors;
Level Code Message
Error 1005 Cannot Create Index with name 'GEN_CLUST_INDEX'. The name is reserved for the system default primary index.
Error 1005 Can't create table '#sql-temporary' (errno: -1)
create index idx on bug46000(id);
drop table bug46000;
......@@ -105,12 +105,6 @@ drop table t1;
--error ER_TOO_BIG_ROWSIZE
CREATE TABLE t1(c TEXT, PRIMARY KEY (c(440)))
ENGINE=InnoDB ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=1 CHARSET=ASCII;
# 439 throws error with certain system zlib (ubuntu "intrepid")
# but not with zlib bundled with MySQL, because zlib's compressBound()
# are different (and used by InnoDB's page_zip_empty_size()); see
# http://www.linux-archive.org/archlinux-development/119356-zlib-1-2-3-3-1-a.html
# "Fix compressBound(), was low for some pathological cases [Fearnley]".
# 438 works with both zlib-s.
CREATE TABLE t1(c TEXT, PRIMARY KEY (c(438)))
ENGINE=InnoDB ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=1 CHARSET=ASCII;
INSERT INTO t1 VALUES(REPEAT('A',512)),(REPEAT('B',512));
......
......@@ -14,3 +14,4 @@ innodb_bug39438 : Bug#42383 2009-01-28 lsoares "This fails in embedded
query_cache_28249 : Bug#43861 2009-03-25 main.query_cache_28249 fails sporadically
partition_innodb_builtin : Bug#32430 2009-09-25 mattiasj Waiting for push of Innodb changes
partition_innodb_plugin : Bug#32430 2009-09-25 mattiasj Waiting for push of Innodb changes
innodb_bug46000 : Bug#47860 2009-10-16 satyab Test fails for innodb plugin 1.0.5
-- source include/not_embedded.inc
-- source include/have_innodb.inc
--disable_warnings
drop table if exists t1;
--enable_warnings
# REPLACE INTO ... SELECT and INSERT INTO ... SELECT should do
# a consistent read of the source table.
connect (a,localhost,root,,);
connect (b,localhost,root,,);
connection a;
set session transaction isolation level read committed;
create table t1(a int not null) engine=innodb DEFAULT CHARSET=latin1;
create table t2 like t1;
insert into t2 values (1),(2),(3),(4),(5),(6),(7);
set autocommit=0;
# REPLACE INTO ... SELECT case
begin;
# this should not result in any locks on t2.
replace into t1 select * from t2;
connection b;
set session transaction isolation level read committed;
set autocommit=0;
# should not cuase a lock wait.
delete from t2 where a=5;
commit;
delete from t2;
commit;
connection a;
commit;
# INSERT INTO ... SELECT case
begin;
# this should not result in any locks on t2.
insert into t1 select * from t2;
connection b;
set session transaction isolation level read committed;
set autocommit=0;
# should not cuase a lock wait.
delete from t2 where a=5;
commit;
delete from t2;
commit;
connection a;
commit;
select * from t1;
drop table t1;
drop table t2;
connection default;
disconnect a;
disconnect b;
......@@ -9,6 +9,7 @@
-- disable_result_log
# set packet size and reconnect
let $max_packet=`select @@global.max_allowed_packet`;
SET @@global.max_allowed_packet=16777216;
--connect (newconn, localhost, root,,)
......@@ -32,6 +33,7 @@ SELECT f4, f8 FROM bug34300;
DROP TABLE bug34300;
EVAL SET @@global.max_allowed_packet=$max_packet;
disconnect newconn;
connection default;
SET @@global.max_allowed_packet=default;
# This is the test for bug 44369. We should
# block table creation with columns match
# some innodb internal reserved key words,
# both case sensitively and insensitely.
--source include/have_innodb.inc
# This create table operation should fail.
--error ER_CANT_CREATE_TABLE
create table bug44369 (DB_ROW_ID int) engine=innodb;
# This create should fail as well
--error ER_CANT_CREATE_TABLE
create table bug44369 (db_row_id int) engine=innodb;
show errors;
--error ER_CANT_CREATE_TABLE
create table bug44369 (db_TRX_Id int) engine=innodb;
show errors;
#
# Bug#44571 InnoDB Plugin crashes on ADD INDEX
# http://bugs.mysql.com/44571
#
-- source include/have_innodb.inc
CREATE TABLE bug44571 (foo INT) ENGINE=InnoDB;
ALTER TABLE bug44571 CHANGE foo bar INT;
-- error ER_KEY_COLUMN_DOES_NOT_EXITS
ALTER TABLE bug44571 ADD INDEX bug44571b (foo);
# The following will fail, because the CHANGE foo bar was
# not communicated to InnoDB.
--error ER_NOT_KEYFILE
ALTER TABLE bug44571 ADD INDEX bug44571b (bar);
--error ER_NOT_KEYFILE
CREATE INDEX bug44571b ON bug44571 (bar);
DROP TABLE bug44571;
# This is the test for bug 46000. We shall
# block any index creation with the name of
# "GEN_CLUST_INDEX", which is the reserved
# name for innodb default primary index.
--source include/have_innodb.inc
# This 'create table' operation should fail because of
# using the reserve name as its index name.
--error ER_CANT_CREATE_TABLE
create table bug46000(`id` int,key `GEN_CLUST_INDEX`(`id`))engine=innodb;
# Mixed upper/lower case of the reserved key words
--error ER_CANT_CREATE_TABLE
create table bug46000(`id` int, key `GEN_clust_INDEX`(`id`))engine=innodb;
show errors;
create table bug46000(id int) engine=innodb;
# This 'create index' operation should fail.
--replace_regex /'[^']*test.#sql-[0-9a-f_]*'/'#sql-temporary'/
--error ER_CANT_CREATE_TABLE
create index GEN_CLUST_INDEX on bug46000(id);
--replace_regex /'[^']*test.#sql-[0-9a-f_]*'/'#sql-temporary'/
show errors;
# This 'create index' operation should succeed, no
# temp table left from last failed create index
# operation.
create index idx on bug46000(id);
drop table bug46000;
......@@ -21,7 +21,16 @@
# those trees.
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")
# Starting at 5.1.38, MySQL CMake files are simplified. But the plugin
# CMakeLists.txt still needs to work with previous versions of MySQL.
IF (MYSQL_VERSION_ID GREATER "50137")
INCLUDE("${PROJECT_SOURCE_DIR}/storage/mysql_storage_engine.cmake")
ENDIF (MYSQL_VERSION_ID GREATER "50137")
IF (CMAKE_SIZEOF_VOID_P MATCHES 8)
SET(WIN64 TRUE)
ENDIF (CMAKE_SIZEOF_VOID_P MATCHES 8)
# Include directories under innobase
INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/storage/innobase/include
......@@ -36,10 +45,10 @@ INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/include
# 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 CMAKE_SIZEOF_VOID_P MATCHES 8)
IF (MSVC AND $(WIN64))
SET_SOURCE_FILES_PROPERTIES(mem/mem0mem.c mem/mem0pool.c
PROPERTIES COMPILE_FLAGS -Od)
ENDIF(MSVC AND CMAKE_SIZEOF_VOID_P MATCHES 8)
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
......@@ -74,5 +83,5 @@ SET(INNOBASE_SOURCES btr/btr0btr.c btr/btr0cur.c btr/btr0pcur.c btr/btr0sea.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)
ADD_DEFINITIONS(-DHAVE_WINDOWS_ATOMICS -DINNODB_RW_LOCKS_USE_ATOMICS -DIB_HAVE_PAUSE_INSTRUCTION)
MYSQL_STORAGE_ENGINE(INNOBASE)
\ No newline at end of file
ADD_DEFINITIONS(-DHAVE_WINDOWS_ATOMICS -DIB_HAVE_PAUSE_INSTRUCTION)
MYSQL_STORAGE_ENGINE(INNOBASE)
2009-10-01 The InnoDB Team
* fsp/fsp0fsp.c, row/row0merge.c:
Clean up after a crash during DROP INDEX. When InnoDB crashes
while dropping an index, ensure that the index will be completely
dropped during crash recovery. The MySQL .frm file may still
contain the dropped index, but there is little that we can do
about it.
2009-09-28 The InnoDB Team
* handler/ha_innodb.cc:
When a secondary index exists in the MySQL .frm file but not in
the InnoDB data dictionary, return an error instead of letting an
assertion fail in index_read.
2009-09-28 The InnoDB Team
* btr/btr0btr.c, buf/buf0buf.c, include/page0page.h,
include/page0zip.h, page/page0cur.c, page/page0page.c,
page/page0zip.c:
Do not write to PAGE_INDEX_ID when restoring an uncompressed page
after a compression failure. The field should only be written
when creating a B-tree page. This fix addresses a race condition
in a debug assertion.
2009-09-28 The InnoDB Team
* fil/fil0fil.c:
Try to prevent the reuse of tablespace identifiers after InnoDB
has crashed during table creation. Also, refuse to start if files
with duplicate tablespace identifiers are encountered.
2009-09-25 The InnoDB Team
* include/os0file.h, os/os0file.c:
Fix Bug#47055 unconditional exit(1) on ERROR_WORKING_SET_QUOTA
1453 (0x5AD) for InnoDB backend
2009-09-19 The InnoDB Team
* handler/ha_innodb.cc, mysql-test/innodb-consistent-master.opt,
mysql-test/innodb-consistent.result,
mysql-test/innodb-consistent.test:
Fix Bug#37232 Innodb might get too many read locks for DML with
repeatable-read
2009-09-19 The InnoDB Team
* fsp/fsp0fsp.c:
Fix Bug#31183 Tablespace full problems not reported in error log,
error message unclear
2009-09-17 The InnoDB Team
* mysql-test/innodb-zip.result, mysql-test/innodb-zip.test:
Make the test pass with zlib 1.2.3.3. Apparently, the definition
of compressBound() has changed between zlib versions, and the
maximum record size of a table with 1K compressed page size has
been reduced by one byte. This is an arbitrary test. In practical
applications, for good write performance, the compressed page size
should be chosen to be bigger than the absolute minimum.
2009-09-16 The InnoDB Team
* handler/ha_innodb.cc:
Fix Bug#46256 drop table with unknown collation crashes innodb
2009-09-16 The InnoDB Team
* dict/dict0dict.c, handler/ha_innodb.cc,
mysql-test/innodb_bug44369.result, mysql-test/innodb_bug44369.test,
row/row0mysql.c:
Fix Bug#44369 InnoDB: Does not uniformly disallow disallowed column
names
2009-09-16 The InnoDB Team
* handler/ha_innodb.cc, include/db0err.h,
mysql-test/innodb_bug46000.result, mysql-test/innodb_bug46000.test:
Fix Bug#46000 using index called GEN_CLUST_INDEX crashes server
2009-09-02 The InnoDB Team
* include/lock0lock.h, include/row0mysql.h, lock/lock0lock.c,
row/row0mysql.c:
Fix a regression introduced by the fix for MySQL bug#26316. We check
whether a transaction holds any AUTOINC locks before we acquire
the kernel mutex and release those locks.
2009-08-27 The InnoDB Team
* dict/dict0dict.c, include/dict0dict.h,
mysql-test/innodb_bug44571.result, mysql-test/innodb_bug44571.test:
Fix Bug#44571 InnoDB Plugin crashes on ADD INDEX
2009-08-27 The InnoDB Team
* row/row0merge.c:
Fix a bug in the merge sort that can corrupt indexes in fast index
creation. Add some consistency checks. Check that the number of
records remains constant in every merge sort pass.
2009-08-27 The InnoDB Team
* buf/buf0buf.c, buf/buf0lru.c, buf/buf0rea.c, handler/ha_innodb.cc,
include/buf0buf.h, include/buf0buf.ic, include/buf0lru.h,
include/ut0ut.h, ut/ut0ut.c:
Make it possible to tune the buffer pool LRU eviction policy to be
more resistant against index scans. Introduce the settable global
variables innodb_old_blocks_pct and innodb_old_blocks_time for
controlling the buffer pool eviction policy. The parameter
innodb_old_blocks_pct (5..95) controls the desired amount of "old"
blocks in the LRU list. The default is 37, corresponding to the
old fixed ratio of 3/8. Each time a block is accessed, it will be
moved to the "new" blocks if its first access was at least
innodb_old_blocks_time milliseconds ago (default 0, meaning every
block). The idea is that in index scans, blocks will be accessed
a few times within innodb_old_blocks_time, and they will remain in
the "old" section of the LRU list. Thus, when innodb_old_blocks_time
is nonzero, blocks retrieved for one-time index scans will be more
likely candidates for eviction than blocks that are accessed in
random patterns.
2009-08-26 The InnoDB Team
* handler/ha_innodb.cc, os/os0file.c:
Fix Bug#42885 buf_read_ahead_random, buf_read_ahead_linear counters,
thread wakeups
2009-08-20 The InnoDB Team
* lock/lock0lock.c:
Fix Bug#46650 Innodb assertion autoinc_lock == lock in
lock_table_remove_low on INSERT SELECT
2009-08-13 The InnoDB Team
* handler/handler0alter.cc:
Fix Bug#46657 InnoDB plugin: invalid read in index_merge_innodb test
(Valgrind)
2009-08-11 The InnoDB Team
InnoDB Plugin 1.0.4 released
2009-07-20 The InnoDB Team
* buf/buf0rea.c, handler/ha_innodb.cc, include/srv0srv.h,
......
......@@ -31,7 +31,6 @@ DEFS= @DEFS@
noinst_HEADERS= \
handler/ha_innodb.h \
handler/handler0vars.h \
handler/i_s.h \
include/btr0btr.h \
include/btr0btr.ic \
......
This is the source of the InnoDB Plugin 1.0.4 for MySQL 5.1
===========================================================
Instructions for compiling the plugin:
--------------------------------------
1. Get the latest MySQL 5.1 sources from
http://dev.mysql.com/downloads/mysql/5.1.html#source
2. Replace the contents of the mysql-5.1.N/storage/innobase/ directory
with the contents of this directory.
3. Optional (only necessary if you are going to run tests from the
mysql-test suite): cd into the innobase directory and run ./setup.sh
4. Compile MySQL as usual.
5. Enjoy!
See the online documentation for more detailed instructions:
http://www.innodb.com/doc/innodb_plugin-1.0/innodb-plugin-installation.html
For more information about InnoDB visit
http://www.innodb.com
Please report any problems or issues with the plugin in the InnoDB Forums
http://forums.innodb.com/ or in the MySQL Bugs database http://bugs.mysql.com
Thank you for using the InnoDB plugin!
......@@ -797,7 +797,7 @@ btr_create(
buf_block_dbg_add_level(block, SYNC_TREE_NODE_NEW);
}
/* Create a new index page on the the allocated segment page */
/* Create a new index page on the allocated segment page */
page_zip = buf_block_get_page_zip(block);
if (UNIV_LIKELY_NULL(page_zip)) {
......@@ -1011,7 +1011,26 @@ btr_page_reorganize_low(
(!page_zip_compress(page_zip, page, index, NULL))) {
/* Restore the old page and exit. */
buf_frame_copy(page, temp_page);
#if defined UNIV_DEBUG || defined UNIV_ZIP_DEBUG
/* Check that the bytes that we skip are identical. */
ut_a(!memcmp(page, temp_page, PAGE_HEADER));
ut_a(!memcmp(PAGE_HEADER + PAGE_N_RECS + page,
PAGE_HEADER + PAGE_N_RECS + temp_page,
PAGE_DATA - (PAGE_HEADER + PAGE_N_RECS)));
ut_a(!memcmp(UNIV_PAGE_SIZE - FIL_PAGE_DATA_END + page,
UNIV_PAGE_SIZE - FIL_PAGE_DATA_END + temp_page,
FIL_PAGE_DATA_END));
#endif /* UNIV_DEBUG || UNIV_ZIP_DEBUG */
memcpy(PAGE_HEADER + page, PAGE_HEADER + temp_page,
PAGE_N_RECS - PAGE_N_DIR_SLOTS);
memcpy(PAGE_DATA + page, PAGE_DATA + temp_page,
UNIV_PAGE_SIZE - PAGE_DATA - FIL_PAGE_DATA_END);
#if defined UNIV_DEBUG || defined UNIV_ZIP_DEBUG
ut_a(!memcmp(page, temp_page, UNIV_PAGE_SIZE));
#endif /* UNIV_DEBUG || UNIV_ZIP_DEBUG */
goto func_exit;
}
......@@ -1902,7 +1921,7 @@ btr_page_split_and_insert(
n_uniq, &heap);
/* If the new record is less than the existing record
the the split in the middle will copy the existing
the split in the middle will copy the existing
record to the new node. */
if (cmp_dtuple_rec(tuple, first_rec, offsets) < 0) {
split_rec = page_get_middle_rec(page);
......
......@@ -957,7 +957,7 @@ btr_search_guess_on_hash(
/* Increment the page get statistics though we did not really
fix the page: for user info only */
buf_pool->n_page_gets++;
buf_pool->stat.n_page_gets++;
return(TRUE);
......
This diff is collapsed.
This diff is collapsed.
......@@ -38,14 +38,6 @@ Created 11/5/1995 Heikki Tuuri
#include "srv0start.h"
#include "srv0srv.h"
/** 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
a random read-ahead */
#define BUF_READ_AHEAD_RANDOM_THRESHOLD (1 + BUF_READ_AHEAD_RANDOM_AREA / 2)
/** The linear read-ahead area size */
#define BUF_READ_AHEAD_LINEAR_AREA BUF_READ_AHEAD_AREA
......@@ -62,7 +54,8 @@ 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 */
not exist or is being dropped
@return 1 if read request is issued. 0 if it is not */
static
ulint
buf_read_page_low(
......@@ -164,175 +157,14 @@ buf_read_page_low(
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
mechanism is not activated. NOTE 1: the calling thread may own latches on
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.
@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(
/*==================*/
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;
ulint recent_blocks = 0;
ulint count;
ulint LRU_recent_limit;
ulint ibuf_mode;
ulint low, high;
ulint err;
ulint i;
ulint buf_read_ahead_random_area;
/* We have currently disabled random readahead */
return(0);
if (srv_startup_is_before_trx_rollback_phase) {
/* No read-ahead to avoid thread deadlocks */
return(0);
}
if (ibuf_bitmap_page(zip_size, offset)
|| trx_sys_hdr_page(space, offset)) {
/* If it is an ibuf bitmap page or trx sys hdr, we do
no read-ahead, as that could break the ibuf page access
order */
return(0);
}
/* Remember the tablespace version before we ask te tablespace size
below: if DISCARD + IMPORT changes the actual .ibd file meanwhile, we
do not try to read outside the bounds of the tablespace! */
tablespace_version = fil_space_get_version(space);
buf_read_ahead_random_area = BUF_READ_AHEAD_RANDOM_AREA;
low = (offset / buf_read_ahead_random_area)
* buf_read_ahead_random_area;
high = (offset / buf_read_ahead_random_area + 1)
* buf_read_ahead_random_area;
if (high > fil_space_get_size(space)) {
high = fil_space_get_size(space);
}
/* Get the minimum LRU_position field value for an initial segment
of the LRU list, to determine which blocks have recently been added
to the start of the list. */
LRU_recent_limit = buf_LRU_get_recent_limit();
buf_pool_mutex_enter();
if (buf_pool->n_pend_reads
> buf_pool->curr_size / BUF_READ_AHEAD_PEND_LIMIT) {
buf_pool_mutex_exit();
return(0);
}
/* Count how many blocks in the area have been recently accessed,
that is, reside near the start of the LRU list. */
for (i = low; i < high; i++) {
const buf_page_t* bpage = buf_page_hash_get(space, i);
if (bpage
&& buf_page_is_accessed(bpage)
&& (buf_page_get_LRU_position(bpage) > LRU_recent_limit)) {
recent_blocks++;
if (recent_blocks >= BUF_READ_AHEAD_RANDOM_THRESHOLD) {
buf_pool_mutex_exit();
goto read_ahead;
}
}
}
buf_pool_mutex_exit();
/* Do nothing */
return(0);
read_ahead:
/* Read all the suitable blocks within the area */
if (ibuf_inside()) {
ibuf_mode = BUF_READ_IBUF_PAGES_ONLY;
} else {
ibuf_mode = BUF_READ_ANY_PAGE;
}
count = 0;
for (i = low; i < high; i++) {
/* It is only sensible to do read-ahead in the non-sync aio
mode: hence FALSE as the first parameter */
if (!ibuf_bitmap_page(zip_size, i)) {
count += buf_read_page_low(
&err, FALSE,
ibuf_mode | OS_AIO_SIMULATED_WAKE_LATER,
space, zip_size, FALSE,
tablespace_version, i);
if (err == DB_TABLESPACE_DELETED) {
ut_print_timestamp(stderr);
fprintf(stderr,
" InnoDB: Warning: in random"
" readahead trying to access\n"
"InnoDB: tablespace %lu page %lu,\n"
"InnoDB: but the tablespace does not"
" exist or is just being dropped.\n",
(ulong) space, (ulong) i);
}
}
}
/* In simulated aio we wake the aio handler threads only after
queuing all aio requests, in native aio the following call does
nothing: */
os_aio_simulated_wake_handler_threads();
#ifdef UNIV_DEBUG
if (buf_debug_prints && (count > 0)) {
fprintf(stderr,
"Random read-ahead space %lu offset %lu pages %lu\n",
(ulong) space, (ulong) offset,
(ulong) count);
}
#endif /* UNIV_DEBUG */
++srv_read_ahead_rnd;
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.
@return number of page read requests issued: this can be greater than
1 if read-ahead occurred */
released by the i/o-handler thread.
@return TRUE if page has been read in, FALSE in case of failure */
UNIV_INTERN
ulint
ibool
buf_read_page(
/*==========*/
ulint space, /*!< in: space id */
......@@ -341,20 +173,17 @@ buf_read_page(
{
ib_int64_t tablespace_version;
ulint count;
ulint count2;
ulint err;
tablespace_version = fil_space_get_version(space);
count = buf_read_ahead_random(space, zip_size, offset);
/* We do the i/o in the synchronous aio mode to save thread
switches: hence TRUE */
count2 = buf_read_page_low(&err, TRUE, BUF_READ_ANY_PAGE, space,
zip_size, FALSE,
tablespace_version, offset);
srv_buf_pool_reads+= count2;
count = buf_read_page_low(&err, TRUE, BUF_READ_ANY_PAGE, space,
zip_size, FALSE,
tablespace_version, offset);
srv_buf_pool_reads += count;
if (err == DB_TABLESPACE_DELETED) {
ut_print_timestamp(stderr);
fprintf(stderr,
......@@ -371,14 +200,14 @@ buf_read_page(
/* Increment number of I/O operations used for LRU policy. */
buf_LRU_stat_inc_io();
return(count + count2);
return(count > 0);
}
/********************************************************************//**
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
that the the algorithm looks at the 'natural' adjacent successor and
that the algorithm looks at the 'natural' adjacent successor and
predecessor of the page, which on the leaf level of a B-tree are the next
and previous page in the chain of leaves. To know these, the page specified
in (space, offset) must already be present in the buf_pool. Thus, the
......@@ -498,9 +327,17 @@ buf_read_ahead_linear(
fail_count++;
} else if (pred_bpage) {
int res = (ut_ulint_cmp(
buf_page_get_LRU_position(bpage),
buf_page_get_LRU_position(pred_bpage)));
/* Note that buf_page_is_accessed() returns
the time of the first access. If some blocks
of the extent existed in the buffer pool at
the time of a linear access pattern, the first
access times may be nonmonotonic, even though
the latest access times were linear. The
threshold (srv_read_ahead_factor) should help
a little against this. */
int res = ut_ulint_cmp(
buf_page_is_accessed(bpage),
buf_page_is_accessed(pred_bpage));
/* Accesses not in the right order */
if (res != 0 && res != asc_or_desc) {
fail_count++;
......@@ -643,7 +480,7 @@ buf_read_ahead_linear(
LRU policy decision. */
buf_LRU_stat_inc_io();
++srv_read_ahead_seq;
buf_pool->stat.n_ra_pages_read += count;
return(count);
}
......
......@@ -1379,7 +1379,7 @@ dict_create_add_foreign_field_to_dictionary(
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
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.
@return error code or DB_SUCCESS */
......
......@@ -82,9 +82,10 @@ static char dict_ibfk[] = "_ibfk_";
/*******************************************************************//**
Tries to find column names for the index and sets the col field of the
index. */
index.
@return TRUE if the column names were found */
static
void
ibool
dict_index_find_cols(
/*=================*/
dict_table_t* table, /*!< in: table */
......@@ -1169,7 +1170,7 @@ dict_col_name_is_reserved(
ulint i;
for (i = 0; i < UT_ARR_SIZE(reserved_names); i++) {
if (strcmp(name, reserved_names[i]) == 0) {
if (innobase_strcasecmp(name, reserved_names[i]) == 0) {
return(TRUE);
}
......@@ -1431,7 +1432,7 @@ dict_index_too_big_for_tree(
/**********************************************************************//**
Adds an index to the dictionary cache.
@return DB_SUCCESS or DB_TOO_BIG_RECORD */
@return DB_SUCCESS, DB_TOO_BIG_RECORD, or DB_CORRUPTION */
UNIV_INTERN
ulint
dict_index_add_to_cache(
......@@ -1457,7 +1458,10 @@ dict_index_add_to_cache(
ut_a(!dict_index_is_clust(index)
|| UT_LIST_GET_LEN(table->indexes) == 0);
dict_index_find_cols(table, index);
if (!dict_index_find_cols(table, index)) {
return(DB_CORRUPTION);
}
/* Build the cache internal representation of the index,
containing also the added system fields */
......@@ -1665,9 +1669,10 @@ dict_index_remove_from_cache(
/*******************************************************************//**
Tries to find column names for the index and sets the col field of the
index. */
index.
@return TRUE if the column names were found */
static
void
ibool
dict_index_find_cols(
/*=================*/
dict_table_t* table, /*!< in: table */
......@@ -1692,17 +1697,21 @@ dict_index_find_cols(
}
}
#ifdef UNIV_DEBUG
/* It is an error not to find a matching column. */
fputs("InnoDB: Error: no matching column for ", stderr);
ut_print_name(stderr, NULL, FALSE, field->name);
fputs(" in ", stderr);
dict_index_name_print(stderr, NULL, index);
fputs("!\n", stderr);
ut_error;
#endif /* UNIV_DEBUG */
return(FALSE);
found:
;
}
return(TRUE);
}
#endif /* !UNIV_HOTBACKUP */
......
......@@ -594,6 +594,11 @@ fil_node_create(
UT_LIST_ADD_LAST(chain, space->chain, node);
if (id < SRV_LOG_SPACE_FIRST_ID && fil_system->max_assigned_id < id) {
fil_system->max_assigned_id = id;
}
mutex_exit(&fil_system->mutex);
}
......@@ -613,12 +618,10 @@ fil_node_open_file(
ulint size_high;
ibool ret;
ibool success;
#ifndef UNIV_HOTBACKUP
byte* buf2;
byte* page;
ulint space_id;
ulint flags;
#endif /* !UNIV_HOTBACKUP */
ut_ad(mutex_own(&(system->mutex)));
ut_a(node->n_pending == 0);
......@@ -654,9 +657,11 @@ fil_node_open_file(
size_bytes = (((ib_int64_t)size_high) << 32)
+ (ib_int64_t)size_low;
#ifdef UNIV_HOTBACKUP
node->size = (ulint) (size_bytes / UNIV_PAGE_SIZE);
/* TODO: adjust to zip_size, like below? */
#else
if (space->id == 0) {
node->size = (ulint) (size_bytes / UNIV_PAGE_SIZE);
goto add_size;
}
#endif /* UNIV_HOTBACKUP */
ut_a(space->purpose != FIL_LOG);
ut_a(space->id != 0);
......@@ -735,7 +740,10 @@ fil_node_open_file(
(size_bytes
/ dict_table_flags_to_zip_size(flags));
}
#endif
#ifdef UNIV_HOTBACKUP
add_size:
#endif /* UNIV_HOTBACKUP */
space->size += node->size;
}
......@@ -955,7 +963,7 @@ fil_mutex_enter_and_prepare_for_io(
" while the maximum\n"
"InnoDB: allowed value would be %lu.\n"
"InnoDB: You may need to raise the value of"
" innodb_max_files_open in\n"
" innodb_open_files in\n"
"InnoDB: my.cnf.\n",
(ulong) fil_system->n_open,
(ulong) fil_system->max_n_open);
......@@ -1535,7 +1543,7 @@ fil_open_log_and_system_tablespace_files(void)
fprintf(stderr,
"InnoDB: Warning: you must"
" raise the value of"
" innodb_max_open_files in\n"
" innodb_open_files in\n"
"InnoDB: my.cnf! Remember that"
" InnoDB keeps all log files"
" and all system\n"
......@@ -2923,7 +2931,6 @@ fil_open_single_table_tablespace(
byte* page;
ulint space_id;
ulint space_flags;
ibool ret = TRUE;
filepath = fil_make_ibd_name(name, FALSE);
......@@ -3001,7 +3008,7 @@ fil_open_single_table_tablespace(
(ulong) space_id, (ulong) space_flags,
(ulong) id, (ulong) flags);
ret = FALSE;
success = FALSE;
goto func_exit;
}
......@@ -3021,7 +3028,7 @@ fil_open_single_table_tablespace(
os_file_close(file);
mem_free(filepath);
return(ret);
return(success);
}
#endif /* !UNIV_HOTBACKUP */
......@@ -3299,7 +3306,17 @@ fil_load_single_table_tablespace(
if (!success) {
goto func_exit;
if (srv_force_recovery > 0) {
fprintf(stderr,
"InnoDB: innodb_force_recovery"
" was set to %lu. Continuing crash recovery\n"
"InnoDB: even though the tablespace creation"
" of this table failed.\n",
srv_force_recovery);
goto func_exit;
}
exit(1);
}
/* We do not use the size information we have about the file, because
......
......@@ -232,6 +232,9 @@ the extent are free and which contain old tuple version to clean. */
#define XDES_ARR_OFFSET (FSP_HEADER_OFFSET + FSP_HEADER_SIZE)
#ifndef UNIV_HOTBACKUP
/* Flag to indicate if we have printed the tablespace full error. */
static ibool fsp_tbs_full_error_printed = FALSE;
/**********************************************************************//**
Returns an extent to the free list of a space. */
static
......@@ -1099,7 +1102,7 @@ fsp_header_inc_size(
/**********************************************************************//**
Gets the current free limit of the system tablespace. The free limit
means the place of the first page which has never been put to the the
means the place of the first page which has never been put to the
free list for allocation. The space above that address is initialized
to zero. Sets also the global variable log_fsp_current_free_limit.
@return free limit in megabytes */
......@@ -1218,6 +1221,19 @@ fsp_try_extend_data_file(
if (space == 0 && !srv_auto_extend_last_data_file) {
/* We print the error message only once to avoid
spamming the error log. Note that we don't need
to reset the flag to FALSE as dealing with this
error requires server restart. */
if (fsp_tbs_full_error_printed == FALSE) {
fprintf(stderr,
"InnoDB: Error: Data file(s) ran"
" out of space.\n"
"Please add another data file or"
" use \'autoextend\' for the last"
" data file.\n");
fsp_tbs_full_error_printed = TRUE;
}
return(FALSE);
}
......@@ -1832,6 +1848,8 @@ fsp_seg_inode_page_find_used(
if (!ut_dulint_is_zero(mach_read_from_8(inode + FSEG_ID))) {
/* This is used */
ut_ad(mach_read_from_4(inode + FSEG_MAGIC_N)
== FSEG_MAGIC_N_VALUE);
return(i);
}
}
......@@ -1863,6 +1881,9 @@ fsp_seg_inode_page_find_free(
return(i);
}
ut_ad(mach_read_from_4(inode + FSEG_MAGIC_N)
== FSEG_MAGIC_N_VALUE);
}
return(ULINT_UNDEFINED);
......@@ -1981,6 +2002,8 @@ fsp_alloc_seg_inode(
page + FSEG_INODE_PAGE_NODE, mtr);
}
ut_ad(ut_dulint_is_zero(mach_read_from_8(inode + FSEG_ID))
|| mach_read_from_4(inode + FSEG_MAGIC_N) == FSEG_MAGIC_N_VALUE);
return(inode);
}
......@@ -2018,7 +2041,7 @@ fsp_free_seg_inode(
}
mlog_write_dulint(inode + FSEG_ID, ut_dulint_zero, mtr);
mlog_write_ulint(inode + FSEG_MAGIC_N, 0, MLOG_4BYTES, mtr);
mlog_write_ulint(inode + FSEG_MAGIC_N, 0xfa051ce3, MLOG_4BYTES, mtr);
if (ULINT_UNDEFINED
== fsp_seg_inode_page_find_used(page, zip_size, mtr)) {
......@@ -2034,11 +2057,11 @@ fsp_free_seg_inode(
/**********************************************************************//**
Returns the file segment inode, page x-latched.
@return segment inode, page x-latched */
@return segment inode, page x-latched; NULL if the inode is free */
static
fseg_inode_t*
fseg_inode_get(
/*===========*/
fseg_inode_try_get(
/*===============*/
fseg_header_t* header, /*!< in: segment header */
ulint space, /*!< in: space id */
ulint zip_size,/*!< in: compressed page size in bytes
......@@ -2054,11 +2077,37 @@ fseg_inode_get(
inode = fut_get_ptr(space, zip_size, inode_addr, RW_X_LATCH, mtr);
ut_ad(mach_read_from_4(inode + FSEG_MAGIC_N) == FSEG_MAGIC_N_VALUE);
if (UNIV_UNLIKELY
(ut_dulint_is_zero(mach_read_from_8(inode + FSEG_ID)))) {
inode = NULL;
} else {
ut_ad(mach_read_from_4(inode + FSEG_MAGIC_N)
== FSEG_MAGIC_N_VALUE);
}
return(inode);
}
/**********************************************************************//**
Returns the file segment inode, page x-latched.
@return segment inode, page x-latched */
static
fseg_inode_t*
fseg_inode_get(
/*===========*/
fseg_header_t* header, /*!< in: segment header */
ulint space, /*!< in: space id */
ulint zip_size,/*!< in: compressed page size in bytes
or 0 for uncompressed pages */
mtr_t* mtr) /*!< in: mtr handle */
{
fseg_inode_t* inode
= fseg_inode_try_get(header, space, zip_size, mtr);
ut_a(inode);
return(inode);
}
/**********************************************************************//**
Gets the page number from the nth fragment page slot.
@return page number, FIL_NULL if not in use */
......@@ -2073,6 +2122,7 @@ fseg_get_nth_frag_page_no(
ut_ad(inode && mtr);
ut_ad(n < FSEG_FRAG_ARR_N_SLOTS);
ut_ad(mtr_memo_contains_page(mtr, inode, MTR_MEMO_PAGE_X_FIX));
ut_ad(mach_read_from_4(inode + FSEG_MAGIC_N) == FSEG_MAGIC_N_VALUE);
return(mach_read_from_4(inode + FSEG_FRAG_ARR
+ n * FSEG_FRAG_SLOT_SIZE));
}
......@@ -2091,6 +2141,7 @@ fseg_set_nth_frag_page_no(
ut_ad(inode && mtr);
ut_ad(n < FSEG_FRAG_ARR_N_SLOTS);
ut_ad(mtr_memo_contains_page(mtr, inode, MTR_MEMO_PAGE_X_FIX));
ut_ad(mach_read_from_4(inode + FSEG_MAGIC_N) == FSEG_MAGIC_N_VALUE);
mlog_write_ulint(inode + FSEG_FRAG_ARR + n * FSEG_FRAG_SLOT_SIZE,
page_no, MLOG_4BYTES, mtr);
......@@ -2451,6 +2502,8 @@ fseg_fill_free_list(
xdes_set_state(descr, XDES_FSEG, mtr);
seg_id = mtr_read_dulint(inode + FSEG_ID, mtr);
ut_ad(mach_read_from_4(inode + FSEG_MAGIC_N)
== FSEG_MAGIC_N_VALUE);
mlog_write_dulint(descr + XDES_ID, seg_id, mtr);
flst_add_last(inode + FSEG_FREE, descr + XDES_FLST_NODE, mtr);
......@@ -2479,6 +2532,7 @@ fseg_alloc_free_extent(
fil_addr_t first;
ut_ad(!((page_offset(inode) - FSEG_ARR_OFFSET) % FSEG_INODE_SIZE));
ut_ad(mach_read_from_4(inode + FSEG_MAGIC_N) == FSEG_MAGIC_N_VALUE);
if (flst_get_len(inode + FSEG_FREE, mtr) > 0) {
/* Segment free list is not empty, allocate from it */
......@@ -3136,6 +3190,8 @@ fseg_mark_page_used(
ut_ad(seg_inode && mtr);
ut_ad(!((page_offset(seg_inode) - FSEG_ARR_OFFSET) % FSEG_INODE_SIZE));
ut_ad(mach_read_from_4(seg_inode + FSEG_MAGIC_N)
== FSEG_MAGIC_N_VALUE);
descr = xdes_get_descriptor(space, zip_size, page, mtr);
......@@ -3373,6 +3429,8 @@ fseg_free_extent(
ut_a(xdes_get_state(descr, mtr) == XDES_FSEG);
ut_a(0 == ut_dulint_cmp(mtr_read_dulint(descr + XDES_ID, mtr),
mtr_read_dulint(seg_inode + FSEG_ID, mtr)));
ut_ad(mach_read_from_4(seg_inode + FSEG_MAGIC_N)
== FSEG_MAGIC_N_VALUE);
first_page_in_extent = page - (page % FSP_EXTENT_SIZE);
......@@ -3463,7 +3521,13 @@ fseg_free_step(
ut_a(descr);
ut_a(xdes_get_bit(descr, XDES_FREE_BIT,
header_page % FSP_EXTENT_SIZE, mtr) == FALSE);
inode = fseg_inode_get(header, space, zip_size, mtr);
inode = fseg_inode_try_get(header, space, zip_size, mtr);
if (UNIV_UNLIKELY(inode == NULL)) {
fprintf(stderr, "double free of inode from %u:%u\n",
(unsigned) space, (unsigned) header_page);
return(TRUE);
}
descr = fseg_get_first_extent(inode, space, zip_size, mtr);
......@@ -3587,6 +3651,7 @@ fseg_get_first_extent(
ut_ad(inode && mtr);
ut_ad(space == page_get_space_id(page_align(inode)));
ut_ad(mach_read_from_4(inode + FSEG_MAGIC_N) == FSEG_MAGIC_N_VALUE);
first = fil_addr_null;
......@@ -3801,6 +3866,7 @@ fseg_print_low(
(ulong) reserved, (ulong) used, (ulong) n_full,
(ulong) n_frag, (ulong) n_free, (ulong) n_not_full,
(ulong) n_used);
ut_ad(mach_read_from_4(inode + FSEG_MAGIC_N) == FSEG_MAGIC_N_VALUE);
}
#ifdef UNIV_BTR_PRINT
......
This diff is collapsed.
......@@ -663,7 +663,7 @@ ha_innobase::add_index(
if (UNIV_UNLIKELY(error)) {
err_exit:
mem_heap_free(heap);
trx_general_rollback_for_mysql(trx, FALSE, NULL);
trx_general_rollback_for_mysql(trx, NULL);
trx_free_for_mysql(trx);
trx_commit_for_mysql(prebuilt->trx);
DBUG_RETURN(error);
......@@ -801,7 +801,7 @@ ha_innobase::add_index(
alter table t drop index b, add index (b);
The fix will have to parse the SQL and note that the index
being added has the same name as the the one being dropped and
being added has the same name as the one being dropped and
ignore that in the dup index check.*/
//dict_table_check_for_dup_indexes(prebuilt->table);
#endif
......
/*****************************************************************************
Copyright (c) 2008, 2009, Innobase Oy. All Rights Reserved.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
Foundation; version 2 of the License.
This program is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with
this program; if not, write to the Free Software Foundation, Inc., 59 Temple
Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
/*******************************************************************//**
@file handler/handler0vars.h
This file contains accessor functions for dynamic plugin on Windows.
***********************************************************************/
#if defined __WIN__ && defined MYSQL_DYNAMIC_PLUGIN
/*******************************************************************//**
This is a list of externals that can not be resolved by delay loading.
They have to be resolved indirectly via their addresses in the .map file.
All of them are external variables. */
extern CHARSET_INFO* wdl_my_charset_bin;
extern CHARSET_INFO* wdl_my_charset_latin1;
extern CHARSET_INFO* wdl_my_charset_filename;
extern CHARSET_INFO** wdl_system_charset_info;
extern CHARSET_INFO** wdl_default_charset_info;
extern CHARSET_INFO** wdl_all_charsets;
extern system_variables* wdl_global_system_variables;
extern char* wdl_mysql_real_data_home;
extern char** wdl_mysql_data_home;
extern char** wdl_tx_isolation_names;
extern char** wdl_binlog_format_names;
extern char* wdl_reg_ext;
extern pthread_mutex_t* wdl_LOCK_thread_count;
extern key_map* wdl_key_map_full;
extern MY_TMPDIR* wdl_mysql_tmpdir_list;
extern bool* wdl_mysqld_embedded;
extern uint* wdl_lower_case_table_names;
extern ulong* wdl_specialflag;
extern int* wdl_my_umask;
#define my_charset_bin (*wdl_my_charset_bin)
#define my_charset_latin1 (*wdl_my_charset_latin1)
#define my_charset_filename (*wdl_my_charset_filename)
#define system_charset_info (*wdl_system_charset_info)
#define default_charset_info (*wdl_default_charset_info)
#define all_charsets (wdl_all_charsets)
#define global_system_variables (*wdl_global_system_variables)
#define mysql_real_data_home (wdl_mysql_real_data_home)
#define mysql_data_home (*wdl_mysql_data_home)
#define tx_isolation_names (wdl_tx_isolation_names)
#define binlog_format_names (wdl_binlog_format_names)
#define reg_ext (wdl_reg_ext)
#define LOCK_thread_count (*wdl_LOCK_thread_count)
#define key_map_full (*wdl_key_map_full)
#define mysql_tmpdir_list (*wdl_mysql_tmpdir_list)
#define mysqld_embedded (*wdl_mysqld_embedded)
#define lower_case_table_names (*wdl_lower_case_table_names)
#define specialflag (*wdl_specialflag)
#define my_umask (*wdl_my_umask)
#endif
This diff is collapsed.
......@@ -346,7 +346,7 @@ buf_page_release(
mtr_t* mtr); /*!< in: mtr */
/********************************************************************//**
Moves a page to the start of the buffer pool LRU list. This high-level
function can be used to prevent an important page from from slipping out of
function can be used to prevent an important page from slipping out of
the buffer pool. */
UNIV_INTERN
void
......@@ -707,15 +707,6 @@ buf_page_belongs_to_unzip_LRU(
/*==========================*/
const buf_page_t* bpage) /*!< in: pointer to control block */
__attribute__((pure));
/*********************************************************************//**
Determine the approximate LRU list position of a block.
@return LRU list position */
UNIV_INLINE
ulint
buf_page_get_LRU_position(
/*======================*/
const buf_page_t* bpage) /*!< in: control block */
__attribute__((pure));
/*********************************************************************//**
Gets the mutex of a block.
......@@ -816,14 +807,14 @@ buf_page_set_old(
buf_page_t* bpage, /*!< in/out: control block */
ibool old); /*!< in: old */
/*********************************************************************//**
Determine if a block has been accessed in the buffer pool.
@return TRUE if accessed */
Determine the time of first access of a block in the buffer pool.
@return ut_time_ms() at the time of first access, 0 if not accessed */
UNIV_INLINE
ibool
unsigned
buf_page_is_accessed(
/*=================*/
const buf_page_t* bpage) /*!< in: control block */
__attribute__((pure));
__attribute__((nonnull, pure));
/*********************************************************************//**
Flag a block accessed. */
UNIV_INLINE
......@@ -831,7 +822,8 @@ void
buf_page_set_accessed(
/*==================*/
buf_page_t* bpage, /*!< in/out: control block */
ibool accessed); /*!< in: accessed */
ulint time_ms) /*!< in: ut_time_ms() */
__attribute__((nonnull));
/*********************************************************************//**
Gets the buf_block_t handle of a buffered file block if an uncompressed
page frame exists, or NULL.
......@@ -1017,14 +1009,6 @@ buf_block_hash_get(
/*===============*/
ulint space, /*!< in: space id */
ulint offset);/*!< in: offset of the page within space */
/*******************************************************************//**
Increments the pool clock by one and returns its new value. Remember that
in the 32 bit version the clock wraps around at 4 billion!
@return new clock value */
UNIV_INLINE
ulint
buf_pool_clock_tic(void);
/*====================*/
/*********************************************************************//**
Gets the current length of the free list of buffer blocks.
@return length of the free list */
......@@ -1064,16 +1048,10 @@ struct buf_page_struct{
flushed to disk, this tells the
flush_type.
@see enum buf_flush */
unsigned accessed:1; /*!< TRUE if the page has been accessed
while in the buffer pool: read-ahead
may read in pages which have not been
accessed yet; a thread is allowed to
read this for heuristic purposes
without holding any mutex or latch */
unsigned io_fix:2; /*!< type of pending I/O operation;
also protected by buf_pool_mutex
@see enum buf_io_fix */
unsigned buf_fix_count:24;/*!< count of how manyfold this block
unsigned buf_fix_count:25;/*!< count of how manyfold this block
is currently bufferfixed */
/* @} */
#endif /* !UNIV_HOTBACKUP */
......@@ -1103,7 +1081,16 @@ struct buf_page_struct{
- BUF_BLOCK_FILE_PAGE: flush_list
- BUF_BLOCK_ZIP_DIRTY: flush_list
- BUF_BLOCK_ZIP_PAGE: zip_clean
- BUF_BLOCK_ZIP_FREE: zip_free[] */
- BUF_BLOCK_ZIP_FREE: zip_free[]
The contents of the list node
is undefined if !in_flush_list
&& state == BUF_BLOCK_FILE_PAGE,
or if state is one of
BUF_BLOCK_MEMORY,
BUF_BLOCK_REMOVE_HASH or
BUF_BLOCK_READY_IN_USE. */
#ifdef UNIV_DEBUG
ibool in_flush_list; /*!< TRUE if in buf_pool->flush_list;
when buf_pool_mutex is free, the
......@@ -1143,17 +1130,7 @@ struct buf_page_struct{
#endif /* UNIV_DEBUG */
unsigned old:1; /*!< TRUE if the block is in the old
blocks in the LRU list */
unsigned LRU_position:31;/*!< value which monotonically
decreases (or may stay
constant if old==TRUE) toward
the end of the LRU list, if
buf_pool->ulint_clock has not
wrapped around: NOTE that this
value can only be used in
heuristic algorithms, because
of the possibility of a
wrap-around! */
unsigned freed_page_clock:32;/*!< the value of
unsigned freed_page_clock:31;/*!< the value of
buf_pool->freed_page_clock
when this block was the last
time put to the head of the
......@@ -1161,6 +1138,9 @@ struct buf_page_struct{
to read this for heuristic
purposes without holding any
mutex or latch */
unsigned access_time:32; /*!< time of first access, or
0 if the block was never accessed
in the buffer pool */
/* @} */
# ifdef UNIV_DEBUG_FILE_ACCESSES
ibool file_page_was_freed;
......@@ -1305,6 +1285,31 @@ Compute the hash fold value for blocks in buf_pool->zip_hash. */
#define BUF_POOL_ZIP_FOLD_BPAGE(b) BUF_POOL_ZIP_FOLD((buf_block_t*) (b))
/* @} */
/** @brief The buffer pool statistics structure. */
struct buf_pool_stat_struct{
ulint n_page_gets; /*!< number of page gets performed;
also successful searches through
the adaptive hash index are
counted as page gets; this field
is NOT protected by the buffer
pool mutex */
ulint n_pages_read; /*!< number read operations */
ulint n_pages_written;/*!< number write operations */
ulint n_pages_created;/*!< number of pages created
in the pool with no read */
ulint n_ra_pages_read;/*!< number of pages read in
as part of read ahead */
ulint n_ra_pages_evicted;/*!< number of read ahead
pages that are evicted without
being accessed */
ulint n_pages_made_young; /*!< number of pages made young, in
calls to buf_LRU_make_block_young() */
ulint n_pages_not_made_young; /*!< number of pages not made
young because the first access
was not long enough ago, in
buf_page_peek_if_too_old() */
};
/** @brief The buffer pool structure.
NOTE! The definition appears here only for other modules of this
......@@ -1329,28 +1334,16 @@ struct buf_pool_struct{
ulint n_pend_reads; /*!< number of pending read operations */
ulint n_pend_unzip; /*!< number of pending decompressions */
time_t last_printout_time; /*!< when buf_print was last time
time_t last_printout_time;
/*!< when buf_print_io was last time
called */
ulint n_pages_read; /*!< number read operations */
ulint n_pages_written;/*!< number write operations */
ulint n_pages_created;/*!< number of pages created
in the pool with no read */
ulint n_page_gets; /*!< number of page gets performed;
also successful searches through
the adaptive hash index are
counted as page gets; this field
is NOT protected by the buffer
pool mutex */
ulint n_page_gets_old;/*!< n_page_gets when buf_print was
last time called: used to calculate
hit rate */
ulint n_pages_read_old;/*!< n_pages_read when buf_print was
last time called */
ulint n_pages_written_old;/*!< number write operations */
ulint n_pages_created_old;/*!< number of pages created in
the pool with no read */
buf_pool_stat_t stat; /*!< current statistics */
buf_pool_stat_t old_stat; /*!< old statistics */
/* @} */
/** @name Page flushing algorithm fields */
/* @{ */
UT_LIST_BASE_NODE_T(buf_page_t) flush_list;
......@@ -1366,10 +1359,6 @@ struct buf_pool_struct{
/*!< this is in the set state
when there is no flush batch
of the given type running */
ulint ulint_clock; /*!< a sequence number used to count
time. NOTE! This counter wraps
around at 4 billion (if ulint ==
32 bits)! */
ulint freed_page_clock;/*!< a sequence number used
to count the number of buffer
blocks removed from the end of
......@@ -1393,9 +1382,11 @@ struct buf_pool_struct{
block list */
UT_LIST_BASE_NODE_T(buf_page_t) LRU;
/*!< base node of the LRU list */
buf_page_t* LRU_old; /*!< pointer to the about 3/8 oldest
blocks in the LRU list; NULL if LRU
length less than BUF_LRU_OLD_MIN_LEN;
buf_page_t* LRU_old; /*!< pointer to the about
buf_LRU_old_ratio/BUF_LRU_OLD_RATIO_DIV
oldest blocks in the LRU list;
NULL if LRU length less than
BUF_LRU_OLD_MIN_LEN;
NOTE: when LRU_old != NULL, its length
should always equal LRU_old_len */
ulint LRU_old_len; /*!< length of the LRU list from
......
......@@ -72,9 +72,30 @@ buf_page_peek_if_too_old(
/*=====================*/
const buf_page_t* bpage) /*!< in: block to make younger */
{
return(buf_pool->freed_page_clock
>= buf_page_get_freed_page_clock(bpage)
+ 1 + (buf_pool->curr_size / 4));
if (UNIV_UNLIKELY(buf_pool->freed_page_clock == 0)) {
/* If eviction has not started yet, do not update the
statistics or move blocks in the LRU list. This is
either the warm-up phase or an in-memory workload. */
return(FALSE);
} else if (buf_LRU_old_threshold_ms && bpage->old) {
unsigned access_time = buf_page_is_accessed(bpage);
if (access_time > 0
&& (ut_time_ms() - access_time)
>= buf_LRU_old_threshold_ms) {
return(TRUE);
}
buf_pool->stat.n_pages_not_made_young++;
return(FALSE);
} else {
/* FIXME: bpage->freed_page_clock is 31 bits */
return((buf_pool->freed_page_clock & ((1UL << 31) - 1))
> ((ulint) bpage->freed_page_clock
+ (buf_pool->curr_size
* (BUF_LRU_OLD_RATIO_DIV - buf_LRU_old_ratio)
/ (BUF_LRU_OLD_RATIO_DIV * 4))));
}
}
/*********************************************************************//**
......@@ -118,22 +139,6 @@ buf_pool_get_oldest_modification(void)
return(lsn);
}
/*******************************************************************//**
Increments the buf_pool clock by one and returns its new value. Remember
that in the 32 bit version the clock wraps around at 4 billion!
@return new clock value */
UNIV_INLINE
ulint
buf_pool_clock_tic(void)
/*====================*/
{
ut_ad(buf_pool_mutex_own());
buf_pool->ulint_clock++;
return(buf_pool->ulint_clock);
}
#endif /* !UNIV_HOTBACKUP */
/*********************************************************************//**
......@@ -279,21 +284,6 @@ buf_page_belongs_to_unzip_LRU(
&& buf_page_get_state(bpage) == BUF_BLOCK_FILE_PAGE);
}
/*********************************************************************//**
Determine the approximate LRU list position of a block.
@return LRU list position */
UNIV_INLINE
ulint
buf_page_get_LRU_position(
/*======================*/
const buf_page_t* bpage) /*!< in: control block */
{
ut_ad(buf_page_in_file(bpage));
ut_ad(buf_pool_mutex_own());
return(bpage->LRU_position);
}
/*********************************************************************//**
Gets the mutex of a block.
@return pointer to mutex protecting bpage */
......@@ -487,17 +477,17 @@ buf_page_set_old(
}
/*********************************************************************//**
Determine if a block has been accessed in the buffer pool.
@return TRUE if accessed */
Determine the time of first access of a block in the buffer pool.
@return ut_time_ms() at the time of first access, 0 if not accessed */
UNIV_INLINE
ibool
unsigned
buf_page_is_accessed(
/*=================*/
const buf_page_t* bpage) /*!< in: control block */
{
ut_ad(buf_page_in_file(bpage));
return(bpage->accessed);
return(bpage->access_time);
}
/*********************************************************************//**
......@@ -507,12 +497,15 @@ void
buf_page_set_accessed(
/*==================*/
buf_page_t* bpage, /*!< in/out: control block */
ibool accessed) /*!< in: accessed */
ulint time_ms) /*!< in: ut_time_ms() */
{
ut_a(buf_page_in_file(bpage));
ut_ad(mutex_own(buf_page_get_mutex(bpage)));
ut_ad(buf_pool_mutex_own());
bpage->accessed = accessed;
if (!bpage->access_time) {
/* Make this the time of the first access. */
bpage->access_time = time_ms;
}
}
/*********************************************************************//**
......
......@@ -69,7 +69,7 @@ These are low-level functions
#########################################################################*/
/** Minimum LRU list length for which the LRU_old pointer is defined */
#define BUF_LRU_OLD_MIN_LEN 80
#define BUF_LRU_OLD_MIN_LEN 512 /* 8 megabytes of 16k pages */
/** Maximum LRU list search length in buf_flush_LRU_recommendation() */
#define BUF_LRU_FREE_SEARCH_LEN (5 + 2 * BUF_READ_AHEAD_AREA)
......@@ -84,15 +84,6 @@ void
buf_LRU_invalidate_tablespace(
/*==========================*/
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.
@return the limit; zero if could not determine it */
UNIV_INTERN
ulint
buf_LRU_get_recent_limit(void);
/*==========================*/
/********************************************************************//**
Insert a compressed block into buf_pool->zip_clean in the LRU order. */
UNIV_INTERN
......@@ -201,6 +192,18 @@ void
buf_LRU_make_block_old(
/*===================*/
buf_page_t* bpage); /*!< in: control block */
/**********************************************************************//**
Updates buf_LRU_old_ratio.
@return updated old_pct */
UNIV_INTERN
uint
buf_LRU_old_ratio_update(
/*=====================*/
uint old_pct,/*!< in: Reserve this percentage of
the buffer pool for "old" blocks. */
ibool adjust);/*!< in: TRUE=adjust the LRU list;
FALSE=just assign buf_LRU_old_ratio
during the initialization of InnoDB */
/********************************************************************//**
Update the historical stats that we are collecting for LRU eviction
policy at the end of each interval. */
......@@ -227,6 +230,35 @@ buf_LRU_print(void);
/*===============*/
#endif /* UNIV_DEBUG_PRINT || UNIV_DEBUG || UNIV_BUF_DEBUG */
/** @name Heuristics for detecting index scan @{ */
/** Reserve this much/BUF_LRU_OLD_RATIO_DIV of the buffer pool for
"old" blocks. Protected by buf_pool_mutex. */
extern uint buf_LRU_old_ratio;
/** The denominator of buf_LRU_old_ratio. */
#define BUF_LRU_OLD_RATIO_DIV 1024
/** Maximum value of buf_LRU_old_ratio.
@see buf_LRU_old_adjust_len
@see buf_LRU_old_ratio_update */
#define BUF_LRU_OLD_RATIO_MAX BUF_LRU_OLD_RATIO_DIV
/** Minimum value of buf_LRU_old_ratio.
@see buf_LRU_old_adjust_len
@see buf_LRU_old_ratio_update
The minimum must exceed
(BUF_LRU_OLD_TOLERANCE + 5) * BUF_LRU_OLD_RATIO_DIV / BUF_LRU_OLD_MIN_LEN. */
#define BUF_LRU_OLD_RATIO_MIN 51
#if BUF_LRU_OLD_RATIO_MIN >= BUF_LRU_OLD_RATIO_MAX
# error "BUF_LRU_OLD_RATIO_MIN >= BUF_LRU_OLD_RATIO_MAX"
#endif
#if BUF_LRU_OLD_RATIO_MAX > BUF_LRU_OLD_RATIO_DIV
# error "BUF_LRU_OLD_RATIO_MAX > BUF_LRU_OLD_RATIO_DIV"
#endif
/** Move blocks to "new" LRU list only if the first access was at
least this many milliseconds ago. Not protected by any mutex or latch. */
extern uint buf_LRU_old_threshold_ms;
/* @} */
/** @brief Statistics for selecting the LRU list for eviction.
These statistics are not 'of' LRU but 'for' LRU. We keep count of I/O
......
......@@ -33,12 +33,10 @@ Created 11/5/1995 Heikki Tuuri
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.
@return number of page read requests issued: this can be greater than
1 if read-ahead occurred */
released by the i/o-handler thread.
@return TRUE if page has been read in, FALSE in case of failure */
UNIV_INTERN
ulint
ibool
buf_read_page(
/*==========*/
ulint space, /*!< in: space id */
......@@ -48,7 +46,7 @@ buf_read_page(
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
that the the algorithm looks at the 'natural' adjacent successor and
that the algorithm looks at the 'natural' adjacent successor and
predecessor of the page, which on the leaf level of a B-tree are the next
and previous page in the chain of leaves. To know these, the page specified
in (space, offset) must already be present in the buf_pool. Thus, the
......
......@@ -34,6 +34,8 @@ typedef struct buf_block_struct 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;
/** Buffer pool statistics struct */
typedef struct buf_pool_stat_struct buf_pool_stat_t;
/** A buffer frame. @see page_t */
typedef byte buf_frame_t;
......
......@@ -110,7 +110,7 @@ dict_create_or_check_foreign_constraint_tables(void);
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
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.
@return error code or DB_SUCCESS */
......
......@@ -712,7 +712,7 @@ dict_index_find_on_id_low(
dulint id); /*!< in: index id */
/**********************************************************************//**
Adds an index to the dictionary cache.
@return DB_SUCCESS or error code */
@return DB_SUCCESS, DB_TOO_BIG_RECORD, or DB_CORRUPTION */
UNIV_INTERN
ulint
dict_index_add_to_cache(
......
......@@ -317,7 +317,7 @@ struct dict_foreign_struct{
char* id; /*!< id of the constraint as a
null-terminated string */
unsigned n_fields:10; /*!< number of indexes' first fields
for which the the foreign key
for which the foreign key
constraint is defined: we allow the
indexes to contain more fields than
mentioned in the constraint, as long
......
......@@ -42,7 +42,7 @@ fsp_init(void);
/*==========*/
/**********************************************************************//**
Gets the current free limit of the system tablespace. The free limit
means the place of the first page which has never been put to the the
means the place of the first page which has never been put to the
free list for allocation. The space above that address is initialized
to zero. Sets also the global variable log_fsp_current_free_limit.
@return free limit in megabytes */
......
......@@ -630,6 +630,14 @@ lock_number_of_rows_locked(
/*=======================*/
trx_t* trx); /*!< in: transaction */
/*******************************************************************//**
Check if a transaction holds any autoinc locks.
@return TRUE if the transaction holds any AUTOINC locks. */
UNIV_INTERN
ibool
lock_trx_holds_autoinc_locks(
/*=========================*/
const trx_t* trx); /*!< in: transaction */
/*******************************************************************//**
Release all the transaction's autoinc locks. */
UNIV_INTERN
void
......
......@@ -118,10 +118,9 @@ UNIV_INLINE
ib_uint64_t
log_reserve_and_write_fast(
/*=======================*/
byte* str, /*!< in: string */
const void* str, /*!< in: string */
ulint len, /*!< in: string length */
ib_uint64_t* start_lsn,/*!< out: start lsn of the log record */
ibool* success);/*!< out: TRUE if success */
ib_uint64_t* start_lsn);/*!< out: start lsn of the log record */
/***********************************************************************//**
Releases the log mutex. */
UNIV_INLINE
......@@ -283,7 +282,7 @@ log_make_checkpoint_at(
later lsn, if IB_ULONGLONG_MAX, makes
a checkpoint at the latest lsn */
ibool write_always); /*!< in: the function normally checks if
the the new checkpoint would have a
the new checkpoint would have a
greater lsn than the previous one: if
not, then no physical write is done;
by setting this parameter TRUE, a
......
......@@ -27,6 +27,7 @@ Created 12/9/1995 Heikki Tuuri
#include "mach0data.h"
#include "mtr0mtr.h"
#ifdef UNIV_LOG_DEBUG
/******************************************************//**
Checks by parsing that the catenated log segment for a single mtr is
consistent. */
......@@ -34,11 +35,12 @@ UNIV_INTERN
ibool
log_check_log_recs(
/*===============*/
byte* buf, /*!< in: pointer to the start of
const byte* buf, /*!< in: pointer to the start of
the log segment in the
log_sys->buf log buffer */
ulint len, /*!< in: segment length in bytes */
ib_uint64_t buf_start_lsn); /*!< in: buffer start lsn */
#endif /* UNIV_LOG_DEBUG */
/************************************************************//**
Gets a log block flush bit.
......@@ -305,55 +307,76 @@ UNIV_INLINE
ib_uint64_t
log_reserve_and_write_fast(
/*=======================*/
byte* str, /*!< in: string */
const void* str, /*!< in: string */
ulint len, /*!< in: string length */
ib_uint64_t* start_lsn,/*!< out: start lsn of the log record */
ibool* success)/*!< out: TRUE if success */
ib_uint64_t* start_lsn)/*!< out: start lsn of the log record */
{
log_t* log = log_sys;
ulint data_len;
ib_uint64_t lsn;
#ifdef UNIV_LOG_LSN_DEBUG
/* length of the LSN pseudo-record */
ulint lsn_len = 1
+ mach_get_compressed_size(log_sys->lsn >> 32)
+ mach_get_compressed_size(log_sys->lsn & 0xFFFFFFFFUL);
#endif /* UNIV_LOG_LSN_DEBUG */
*success = TRUE;
mutex_enter(&log_sys->mutex);
mutex_enter(&(log->mutex));
data_len = len + log->buf_free % OS_FILE_LOG_BLOCK_SIZE;
data_len = len
#ifdef UNIV_LOG_LSN_DEBUG
+ lsn_len
#endif /* UNIV_LOG_LSN_DEBUG */
+ log_sys->buf_free % OS_FILE_LOG_BLOCK_SIZE;
if (data_len >= OS_FILE_LOG_BLOCK_SIZE - LOG_BLOCK_TRL_SIZE) {
/* The string does not fit within the current log block
or the log block would become full */
*success = FALSE;
mutex_exit(&(log->mutex));
mutex_exit(&log_sys->mutex);
return(0);
}
*start_lsn = log->lsn;
ut_memcpy(log->buf + log->buf_free, str, len);
*start_lsn = log_sys->lsn;
#ifdef UNIV_LOG_LSN_DEBUG
{
/* Write the LSN pseudo-record. */
byte* b = &log_sys->buf[log_sys->buf_free];
*b++ = MLOG_LSN | (MLOG_SINGLE_REC_FLAG & *(const byte*) str);
/* Write the LSN in two parts,
as a pseudo page number and space id. */
b += mach_write_compressed(b, log_sys->lsn >> 32);
b += mach_write_compressed(b, log_sys->lsn & 0xFFFFFFFFUL);
ut_a(b - lsn_len == &log_sys->buf[log_sys->buf_free]);
memcpy(b, str, len);
len += lsn_len;
}
#else /* UNIV_LOG_LSN_DEBUG */
memcpy(log_sys->buf + log_sys->buf_free, str, len);
#endif /* UNIV_LOG_LSN_DEBUG */
log_block_set_data_len((byte*) ut_align_down(log->buf + log->buf_free,
log_block_set_data_len((byte*) ut_align_down(log_sys->buf
+ log_sys->buf_free,
OS_FILE_LOG_BLOCK_SIZE),
data_len);
#ifdef UNIV_LOG_DEBUG
log->old_buf_free = log->buf_free;
log->old_lsn = log->lsn;
log_sys->old_buf_free = log_sys->buf_free;
log_sys->old_lsn = log_sys->lsn;
#endif
log->buf_free += len;
log_sys->buf_free += len;
ut_ad(log->buf_free <= log->buf_size);
ut_ad(log_sys->buf_free <= log_sys->buf_size);
lsn = log->lsn += len;
log_sys->lsn += len;
#ifdef UNIV_LOG_DEBUG
log_check_log_recs(log->buf + log->old_buf_free,
log->buf_free - log->old_buf_free, log->old_lsn);
log_check_log_recs(log_sys->buf + log_sys->old_buf_free,
log_sys->buf_free - log_sys->old_buf_free,
log_sys->old_lsn);
#endif
return(lsn);
return(log_sys->lsn);
}
/***********************************************************************//**
......
......@@ -433,6 +433,11 @@ are allowed yet: the variable name is misleading. */
extern ibool recv_no_ibuf_operations;
/** TRUE when recv_init_crash_recovery() has been called. */
extern ibool recv_needed_recovery;
#ifdef UNIV_DEBUG
/** TRUE if writing to the redo log (mtr_commit) is forbidden.
Protected by log_sys->mutex. */
extern ibool recv_no_log_write;
#endif /* UNIV_DEBUG */
/** TRUE if buf_page_is_corrupted() should check if the log sequence
number (FIL_PAGE_LSN) is in the future. Initially FALSE, and set by
......
......@@ -106,6 +106,9 @@ For 1 - 8 bytes, the flag value must give the length also! @{ */
#define MLOG_IBUF_BITMAP_INIT ((byte)27) /*!< initialize an
ibuf bitmap page */
/*#define MLOG_FULL_PAGE ((byte)28) full contents of a page */
#ifdef UNIV_LOG_LSN_DEBUG
# define MLOG_LSN ((byte)28) /* current LSN */
#endif
#define MLOG_INIT_FILE_PAGE ((byte)29) /*!< this means that a
file page is taken
into use and the prior
......@@ -118,7 +121,7 @@ For 1 - 8 bytes, the flag value must give the length also! @{ */
#define MLOG_WRITE_STRING ((byte)30) /*!< write a string to
a page */
#define MLOG_MULTI_REC_END ((byte)31) /*!< if a single mtr writes
log records for several pages,
several log records,
this log record ends the
sequence of these records */
#define MLOG_DUMMY_RECORD ((byte)32) /*!< dummy log record used to
......
......@@ -157,6 +157,7 @@ log. */
to become available again */
#define OS_FILE_SHARING_VIOLATION 76
#define OS_FILE_ERROR_NOT_SPECIFIED 77
#define OS_FILE_INSUFFICIENT_RESOURCE 78
/* @} */
/** Types for aio operations @{ */
......
......@@ -285,44 +285,74 @@ os_fast_mutex_free(
/**********************************************************//**
Atomic compare-and-swap and increment for InnoDB. */
#ifdef HAVE_GCC_ATOMIC_BUILTINS
#if defined(HAVE_IB_GCC_ATOMIC_BUILTINS)
#define HAVE_ATOMIC_BUILTINS
/**********************************************************//**
Returns true if swapped, ptr is pointer to target, old_val is value to
compare to, new_val is the value to swap in. */
# define os_compare_and_swap(ptr, old_val, new_val) \
__sync_bool_compare_and_swap(ptr, old_val, new_val)
# define os_compare_and_swap_ulint(ptr, old_val, new_val) \
os_compare_and_swap(ptr, old_val, new_val)
# define os_compare_and_swap_lint(ptr, old_val, new_val) \
os_compare_and_swap(ptr, old_val, new_val)
# define os_compare_and_swap_thread_id(ptr, old_val, new_val) \
# ifdef HAVE_IB_ATOMIC_PTHREAD_T_GCC
# define os_compare_and_swap_thread_id(ptr, old_val, new_val) \
os_compare_and_swap(ptr, old_val, new_val)
# define INNODB_RW_LOCKS_USE_ATOMICS
# define IB_ATOMICS_STARTUP_MSG \
"Mutexes and rw_locks use GCC atomic builtins"
# else /* HAVE_IB_ATOMIC_PTHREAD_T_GCC */
# define IB_ATOMICS_STARTUP_MSG \
"Mutexes use GCC atomic builtins, rw_locks do not"
# endif /* HAVE_IB_ATOMIC_PTHREAD_T_GCC */
/**********************************************************//**
Returns the resulting value, ptr is pointer to target, amount is the
amount of increment. */
# define os_atomic_increment(ptr, amount) \
__sync_add_and_fetch(ptr, amount)
# define os_atomic_increment_lint(ptr, amount) \
os_atomic_increment(ptr, amount)
# define os_atomic_increment_ulint(ptr, amount) \
os_atomic_increment(ptr, amount)
/**********************************************************//**
Returns the old value of *ptr, atomically sets *ptr to new_val */
# define os_atomic_test_and_set_byte(ptr, new_val) \
__sync_lock_test_and_set(ptr, new_val)
#elif defined(HAVE_IB_SOLARIS_ATOMICS)
#define HAVE_ATOMIC_BUILTINS
/* If not compiling with GCC or GCC doesn't support the atomic
intrinsics and running on Solaris >= 10 use Solaris atomics */
#elif defined(HAVE_SOLARIS_ATOMICS)
#include <atomic.h>
/**********************************************************//**
Returns true if swapped, ptr is pointer to target, old_val is value to
compare to, new_val is the value to swap in. */
# define os_compare_and_swap_ulint(ptr, old_val, new_val) \
(atomic_cas_ulong(ptr, old_val, new_val) == old_val)
# define os_compare_and_swap_lint(ptr, old_val, new_val) \
((lint)atomic_cas_ulong((ulong_t*) ptr, old_val, new_val) == old_val)
# ifdef INNODB_RW_LOCKS_USE_ATOMICS
# if SIZEOF_PTHREAD_T == 4
# ifdef HAVE_IB_ATOMIC_PTHREAD_T_SOLARIS
# if SIZEOF_PTHREAD_T == 4
# define os_compare_and_swap_thread_id(ptr, old_val, new_val) \
((pthread_t)atomic_cas_32(ptr, old_val, new_val) == old_val)
# elif SIZEOF_PTHREAD_T == 8
......@@ -331,21 +361,35 @@ compare to, new_val is the value to swap in. */
# else
# error "SIZEOF_PTHREAD_T != 4 or 8"
# endif /* SIZEOF_PTHREAD_T CHECK */
# endif /* INNODB_RW_LOCKS_USE_ATOMICS */
# define INNODB_RW_LOCKS_USE_ATOMICS
# define IB_ATOMICS_STARTUP_MSG \
"Mutexes and rw_locks use Solaris atomic functions"
# else /* HAVE_IB_ATOMIC_PTHREAD_T_SOLARIS */
# define IB_ATOMICS_STARTUP_MSG \
"Mutexes use Solaris atomic functions, rw_locks do not"
# endif /* HAVE_IB_ATOMIC_PTHREAD_T_SOLARIS */
/**********************************************************//**
Returns the resulting value, ptr is pointer to target, amount is the
amount of increment. */
# define os_atomic_increment_lint(ptr, amount) \
atomic_add_long_nv((ulong_t*) ptr, amount)
# define os_atomic_increment_ulint(ptr, amount) \
atomic_add_long_nv(ptr, amount)
/**********************************************************//**
Returns the old value of *ptr, atomically sets *ptr to new_val */
# define os_atomic_test_and_set_byte(ptr, new_val) \
atomic_swap_uchar(ptr, new_val)
/* On Windows, use Windows atomics / interlocked */
#elif defined(HAVE_WINDOWS_ATOMICS)
#define HAVE_ATOMIC_BUILTINS
/* On Windows, use Windows atomics / interlocked */
# ifdef _WIN64
# define win_cmp_and_xchg InterlockedCompareExchange64
# define win_xchg_and_add InterlockedExchangeAdd64
......@@ -353,31 +397,46 @@ Returns the old value of *ptr, atomically sets *ptr to new_val */
# define win_cmp_and_xchg InterlockedCompareExchange
# define win_xchg_and_add InterlockedExchangeAdd
# endif
/**********************************************************//**
Returns true if swapped, ptr is pointer to target, old_val is value to
compare to, new_val is the value to swap in. */
# define os_compare_and_swap_ulint(ptr, old_val, new_val) \
(win_cmp_and_xchg(ptr, new_val, old_val) == old_val)
# define os_compare_and_swap_lint(ptr, old_val, new_val) \
(win_cmp_and_xchg(ptr, new_val, old_val) == old_val)
# ifdef INNODB_RW_LOCKS_USE_ATOMICS
# define os_compare_and_swap_thread_id(ptr, old_val, new_val) \
/* windows thread objects can always be passed to windows atomic functions */
# define os_compare_and_swap_thread_id(ptr, old_val, new_val) \
(InterlockedCompareExchange(ptr, new_val, old_val) == old_val)
# endif /* INNODB_RW_LOCKS_USE_ATOMICS */
# define INNODB_RW_LOCKS_USE_ATOMICS
# define IB_ATOMICS_STARTUP_MSG \
"Mutexes and rw_locks use Windows interlocked functions"
/**********************************************************//**
Returns the resulting value, ptr is pointer to target, amount is the
amount of increment. */
# define os_atomic_increment_lint(ptr, amount) \
(win_xchg_and_add(ptr, amount) + amount)
# define os_atomic_increment_ulint(ptr, amount) \
((ulint) (win_xchg_and_add(ptr, amount) + amount))
/**********************************************************//**
Returns the old value of *ptr, atomically sets *ptr to new_val.
InterlockedExchange() operates on LONG, and the LONG will be
clobbered */
# define os_atomic_test_and_set_byte(ptr, new_val) \
((byte) InterlockedExchange(ptr, new_val))
#endif /* HAVE_GCC_ATOMIC_BUILTINS */
#else
# define IB_ATOMICS_STARTUP_MSG \
"Mutexes and rw_locks use InnoDB's own implementation"
#endif
#ifndef UNIV_NONINL
#include "os0sync.ic"
......
......@@ -76,8 +76,11 @@ typedef byte page_header_t;
header which are set in a page create */
/*----*/
#define PAGE_LEVEL 26 /* level of the node in an index tree; the
leaf level is the level 0 */
#define PAGE_INDEX_ID 28 /* index id where the page belongs */
leaf level is the level 0. This field should
not be written to after page creation. */
#define PAGE_INDEX_ID 28 /* index id where the page belongs.
This field should not be written to after
page creation. */
#define PAGE_BTR_SEG_LEAF 36 /* file segment header for the leaf pages in
a B-tree: defined only on the root page of a
B-tree, but not in the root of an ibuf tree */
......
......@@ -127,8 +127,12 @@ page_zip_decompress(
/*================*/
page_zip_des_t* page_zip,/*!< in: data, ssize;
out: m_start, m_end, m_nonempty, n_blobs */
page_t* page) /*!< out: uncompressed page, may be trashed */
__attribute__((nonnull));
page_t* page, /*!< out: uncompressed page, may be trashed */
ibool all) /*!< in: TRUE=decompress the whole page;
FALSE=verify but do not copy some
page header fields that should not change
after page creation */
__attribute__((nonnull(1,2)));
#ifdef UNIV_DEBUG
/**********************************************************************//**
......@@ -385,8 +389,8 @@ IMPORTANT: if page_zip_reorganize() is invoked on a 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.
@return TRUE on success, FALSE on failure; page and page_zip will be
left intact on failure. */
@return TRUE on success, FALSE on failure; page_zip will be left
intact on failure, but page will be overwritten. */
UNIV_INTERN
ibool
page_zip_reorganize(
......
......@@ -89,7 +89,7 @@ cmp_dfield_dfield(
/*************************************************************//**
This function is used to compare a data tuple to a physical record.
Only dtuple->n_fields_cmp first fields are taken into account for
the the data tuple! If we denote by n = n_fields_cmp, then rec must
the data tuple! If we denote by n = n_fields_cmp, then rec must
have either m >= n fields, or it must differ from dtuple in some of
the m fields rec has. If rec has an externally stored field we do not
compare it but return with value 0 if such a comparison should be
......
......@@ -65,7 +65,7 @@ most significant bytes and bits are written below less significant.
- offset_of_this_record) mod 64Ki,
where mod is the modulo as a non-negative
number;
we can calculate the the offset of the next
we can calculate the offset of the next
record with the formula:
relative_offset + offset_of_this_record
mod UNIV_PAGE_SIZE
......
......@@ -45,7 +45,7 @@ row_ins_check_foreign_constraint(
/*=============================*/
ibool check_ref,/*!< in: TRUE If we want to check that
the referenced table is ok, FALSE if we
want to to check the foreign key table */
want to check the foreign key table */
dict_foreign_t* foreign,/*!< in: foreign constraint; NOTE that the
tables mentioned in it must be in the
dictionary cache if they exist at all */
......
......@@ -177,7 +177,9 @@ row_update_prebuilt_trx(
in MySQL handle */
trx_t* trx); /*!< in: transaction handle */
/*********************************************************************//**
Unlocks AUTO_INC type locks that were possibly reserved by a trx. */
Unlocks AUTO_INC type locks that were possibly reserved by a trx. This
function should be called at the the end of an SQL statement, by the
connection thread that owns the transaction (trx->mysql_thd). */
UNIV_INTERN
void
row_unlock_table_autoinc_for_mysql(
......
......@@ -315,10 +315,6 @@ extern ulint srv_buf_pool_flushed;
/** Number of buffer pool reads that led to the
reading of a disk page */
extern ulint srv_buf_pool_reads;
/** Number of sequential read-aheads */
extern ulint srv_read_ahead_seq;
/** Number of random read-aheads */
extern ulint srv_read_ahead_rnd;
/** Status variables to be passed to MySQL */
typedef struct export_var_struct export_struc;
......@@ -605,13 +601,13 @@ struct export_var_struct{
#ifdef UNIV_DEBUG
ulint innodb_buffer_pool_pages_latched; /*!< Latched pages */
#endif /* UNIV_DEBUG */
ulint innodb_buffer_pool_read_requests; /*!< buf_pool->n_page_gets */
ulint innodb_buffer_pool_read_requests; /*!< buf_pool->stat.n_page_gets */
ulint innodb_buffer_pool_reads; /*!< srv_buf_pool_reads */
ulint innodb_buffer_pool_wait_free; /*!< srv_buf_pool_wait_free */
ulint innodb_buffer_pool_pages_flushed; /*!< srv_buf_pool_flushed */
ulint innodb_buffer_pool_write_requests;/*!< srv_buf_pool_write_requests */
ulint innodb_buffer_pool_read_ahead_seq;/*!< srv_read_ahead_seq */
ulint innodb_buffer_pool_read_ahead_rnd;/*!< srv_read_ahead_rnd */
ulint innodb_buffer_pool_read_ahead; /*!< srv_read_ahead */
ulint innodb_buffer_pool_read_ahead_evicted;/*!< srv_read_ahead evicted*/
ulint innodb_dblwr_pages_written; /*!< srv_dblwr_pages_written */
ulint innodb_dblwr_writes; /*!< srv_dblwr_writes */
ibool innodb_have_atomic_builtins; /*!< HAVE_ATOMIC_BUILTINS */
......@@ -623,9 +619,9 @@ struct export_var_struct{
ulint innodb_os_log_pending_writes; /*!< srv_os_log_pending_writes */
ulint innodb_os_log_pending_fsyncs; /*!< fil_n_pending_log_flushes */
ulint innodb_page_size; /*!< UNIV_PAGE_SIZE */
ulint innodb_pages_created; /*!< buf_pool->n_pages_created */
ulint innodb_pages_read; /*!< buf_pool->n_pages_read */
ulint innodb_pages_written; /*!< buf_pool->n_pages_written */
ulint innodb_pages_created; /*!< buf_pool->stat.n_pages_created */
ulint innodb_pages_read; /*!< buf_pool->stat.n_pages_read */
ulint innodb_pages_written; /*!< buf_pool->stat.n_pages_written */
ulint innodb_row_lock_waits; /*!< srv_n_lock_wait_count */
ulint innodb_row_lock_current_waits; /*!< srv_n_lock_wait_current_count */
ib_int64_t innodb_row_lock_time; /*!< srv_n_lock_wait_time
......
......@@ -44,8 +44,8 @@ UNIV_INLINE
trx_undo_rec_t*
trx_undo_rec_copy(
/*==============*/
trx_undo_rec_t* undo_rec, /*!< in: undo log record */
mem_heap_t* heap); /*!< in: heap where copied */
const trx_undo_rec_t* undo_rec, /*!< in: undo log record */
mem_heap_t* heap); /*!< in: heap where copied */
/**********************************************************************//**
Reads the undo log record type.
@return record type */
......
......@@ -100,8 +100,8 @@ UNIV_INLINE
trx_undo_rec_t*
trx_undo_rec_copy(
/*==============*/
trx_undo_rec_t* undo_rec, /*!< in: undo log record */
mem_heap_t* heap) /*!< in: heap where copied */
const trx_undo_rec_t* undo_rec, /*!< in: undo log record */
mem_heap_t* heap) /*!< in: heap where copied */
{
ulint len;
......
......@@ -133,6 +133,17 @@ trx_rollback(
Rollback or clean up any incomplete transactions which were
encountered in crash recovery. If the transaction already was
committed, then we clean up a possible insert undo log. If the
transaction was not yet committed, then we roll it back. */
UNIV_INTERN
void
trx_rollback_or_clean_recovered(
/*============================*/
ibool all); /*!< in: FALSE=roll back dictionary transactions;
TRUE=roll back all non-PREPARED transactions */
/*******************************************************************//**
Rollback or clean up any incomplete transactions which were
encountered in crash recovery. If the transaction already was
committed, then we clean up a possible insert undo log. If the
transaction was not yet committed, then we roll it back.
Note: this is done in a background thread.
@return a dummy parameter */
......@@ -208,9 +219,9 @@ int
trx_general_rollback_for_mysql(
/*===========================*/
trx_t* trx, /*!< in: transaction handle */
ibool partial,/*!< in: TRUE if partial rollback requested */
trx_savept_t* savept);/*!< in: pointer to savepoint undo number, if
partial rollback requested */
partial rollback requested, or NULL for
complete rollback */
/*******************************************************************//**
Rolls back a transaction back to a named savepoint. Modifications after the
savepoint are undone but InnoDB does NOT release the corresponding locks
......
......@@ -34,11 +34,11 @@ typedef byte trx_sysf_rseg_t;
/* Rollback segment specification slot offsets */
/*-------------------------------------------------------------*/
#define TRX_SYS_RSEG_SPACE 0 /* space where the the segment
#define TRX_SYS_RSEG_SPACE 0 /* space where the segment
header is placed; starting with
MySQL/InnoDB 5.1.7, this is
UNIV_UNDEFINED if the slot is unused */
#define TRX_SYS_RSEG_PAGE_NO 4 /* page number where the the segment
#define TRX_SYS_RSEG_PAGE_NO 4 /* page number where the segment
header is placed; this is FIL_NULL
if the slot is unused */
/*-------------------------------------------------------------*/
......
......@@ -179,7 +179,7 @@ trx_commit_off_kernel(
/****************************************************************//**
Cleans up a transaction at database startup. The cleanup is needed if
the transaction already got to the middle of a commit when the database
crashed, andf we cannot roll it back. */
crashed, and we cannot roll it back. */
UNIV_INTERN
void
trx_cleanup_at_db_startup(
......@@ -360,7 +360,7 @@ enum trx_dict_op {
operation modes in crash recovery. */
TRX_DICT_OP_TABLE = 1,
/** The transaction is creating or dropping an index in an
existing table. In crash recovery, the the data dictionary
existing table. In crash recovery, the data dictionary
must be locked, but the table must not be dropped. */
TRX_DICT_OP_INDEX = 2
};
......
......@@ -46,11 +46,11 @@ Created 1/20/1994 Heikki Tuuri
#define INNODB_VERSION_MAJOR 1
#define INNODB_VERSION_MINOR 0
#define INNODB_VERSION_BUGFIX 4
#define INNODB_VERSION_BUGFIX 5
/* The following is the InnoDB version as shown in
SELECT plugin_version FROM information_schema.plugins;
calculated in in make_version_string() in sql/sql_show.cc like this:
calculated in make_version_string() in sql/sql_show.cc like this:
"version >> 8" . "version & 0xff"
because the version is shown with only one dot, we skip the last
component, i.e. we show M.N.P as M.N */
......@@ -78,17 +78,25 @@ the virtual method table (vtable) in GCC 3. */
# define ha_innobase ha_innodb
#endif /* MYSQL_DYNAMIC_PLUGIN */
/* if any of the following macros is defined at this point this means
that the code from the "right" plug.in was executed and we do not
need to include ut0auxconf.h which would either define the same macros
or will be empty */
#if !defined(HAVE_IB_GCC_ATOMIC_BUILTINS) \
&& !defined(HAVE_IB_ATOMIC_PTHREAD_T_GCC) \
&& !defined(HAVE_IB_SOLARIS_ATOMICS) \
&& !defined(HAVE_IB_ATOMIC_PTHREAD_T_SOLARIS) \
&& !defined(SIZEOF_PTHREAD_T) \
&& !defined(HAVE_IB_PAUSE_INSTRUCTION)
# include "ut0auxconf.h"
#endif
#if (defined(WIN32) || defined(_WIN32) || defined(WIN64) || defined(_WIN64)) && !defined(MYSQL_SERVER) && !defined(__WIN__)
# undef __WIN__
# define __WIN__
# include <windows.h>
# if defined(HAVE_WINDOWS_ATOMICS)
/* If atomics are defined we use them in InnoDB mutex implementation */
# define HAVE_ATOMIC_BUILTINS
# endif /* HAVE_WINDOWS_ATOMICS */
# ifdef _NT_
# define __NT__
# endif
......@@ -111,45 +119,17 @@ if we are compiling on Windows. */
# include <sys/mman.h> /* mmap() for os0proc.c */
# endif
# undef PACKAGE
# undef VERSION
/* Include the header file generated by GNU autoconf */
# ifndef __WIN__
#ifndef UNIV_HOTBACKUP
# include "config.h"
#endif /* UNIV_HOTBACKUP */
# ifndef UNIV_HOTBACKUP
# include "config.h"
# endif /* UNIV_HOTBACKUP */
# endif
# ifdef HAVE_SCHED_H
# include <sched.h>
# endif
# if defined(HAVE_GCC_ATOMIC_BUILTINS) || defined(HAVE_SOLARIS_ATOMICS) \
|| defined(HAVE_WINDOWS_ATOMICS)
/* If atomics are defined we use them in InnoDB mutex implementation */
# define HAVE_ATOMIC_BUILTINS
# endif /* (HAVE_GCC_ATOMIC_BUILTINS) || (HAVE_SOLARIS_ATOMICS)
|| (HAVE_WINDOWS_ATOMICS) */
/* For InnoDB rw_locks to work with atomics we need the thread_id
to be no more than machine word wide. The following enables using
atomics for InnoDB rw_locks where these conditions are met. */
#ifdef HAVE_ATOMIC_BUILTINS
/* if HAVE_ATOMIC_PTHREAD_T is defined at this point that means that
the code from plug.in has defined it and we do not need to include
ut0auxconf.h which would either define HAVE_ATOMIC_PTHREAD_T or will
be empty */
# ifndef HAVE_ATOMIC_PTHREAD_T
# include "ut0auxconf.h"
# endif /* HAVE_ATOMIC_PTHREAD_T */
/* now HAVE_ATOMIC_PTHREAD_T is eventually defined either by plug.in or
from Makefile.in->ut0auxconf.h */
# ifdef HAVE_ATOMIC_PTHREAD_T
# define INNODB_RW_LOCKS_USE_ATOMICS
# endif /* HAVE_ATOMIC_PTHREAD_T */
#endif /* HAVE_ATOMIC_BUILTINS */
/* We only try to do explicit inlining of functions with gcc and
Sun Studio */
......@@ -196,12 +176,18 @@ command. Not tested on Windows. */
debugging without UNIV_DEBUG */
#define UNIV_DEBUG /* Enable ut_ad() assertions
and disable UNIV_INLINE */
#define UNIV_DEBUG_LOCK_VALIDATE /* Enable
ut_ad(lock_rec_validate_page())
assertions. */
#define UNIV_DEBUG_FILE_ACCESSES /* Debug .ibd file access
(field file_page_was_freed
in buf_page_t) */
#define UNIV_LRU_DEBUG /* debug the buffer pool LRU */
#define UNIV_HASH_DEBUG /* debug HASH_ macros */
#define UNIV_LIST_DEBUG /* debug UT_LIST_ macros */
#define UNIV_LOG_LSN_DEBUG /* write LSN to the redo log;
this will break redo log file compatibility, but it may be useful when
debugging redo log application problems. */
#define UNIV_MEM_DEBUG /* detect memory leaks etc */
#define UNIV_IBUF_DEBUG /* debug the insert buffer */
#define UNIV_IBUF_COUNT_DEBUG /* debug the insert buffer;
......@@ -409,7 +395,8 @@ it is read. */
it is read or written. */
# define UNIV_PREFETCH_RW(addr) __builtin_prefetch(addr, 1, 3)
/* Sun Studio includes sun_prefetch.h as of version 5.9 */
#elif (defined(__SUNPRO_C) && __SUNPRO_C >= 0x590) || (defined(__SUNPRO_CC) && __SUNPRO_CC >= 0x590)
#elif (defined(__SUNPRO_C) && __SUNPRO_C >= 0x590) \
|| (defined(__SUNPRO_CC) && __SUNPRO_CC >= 0x590)
# include <sun_prefetch.h>
#if __SUNPRO_C >= 0x550
# undef UNIV_INTERN
......
/* Do not remove this file even though it is empty.
This file is included in univ.i and will cause compilation failure
if not present.
A custom check has been added in the generated
A custom checks have been added in the generated
storage/innobase/Makefile.in that is shipped with the InnoDB Plugin
source archive. This check tries to compile a test program and if
successful then adds "#define HAVE_ATOMIC_PTHREAD_T" to this file.
This is a hack that has been developed in order to check for pthread_t
atomicity without the need to regenerate the ./configure script that is
source archive. These checks eventually define some macros and put
them in this file.
This is a hack that has been developed in order to deploy new compile
time checks without the need to regenerate the ./configure script that is
distributed in the MySQL 5.1 official source archives.
If by any chance Makefile.in and ./configure are regenerated and thus
the hack from Makefile.in wiped away then the "real" check from plug.in
the hack from Makefile.in wiped away then the "real" checks from plug.in
will take over.
*/
......@@ -219,8 +219,8 @@ UNIV_INLINE
void*
ut_align(
/*=====*/
void* ptr, /*!< in: pointer */
ulint align_no); /*!< in: align by this number */
const void* ptr, /*!< in: pointer */
ulint align_no); /*!< in: align by this number */
/*********************************************************//**
The following function rounds down a pointer to the nearest
aligned address.
......
......@@ -319,8 +319,8 @@ UNIV_INLINE
void*
ut_align(
/*=====*/
void* ptr, /*!< in: pointer */
ulint align_no) /*!< in: align by this number */
const void* ptr, /*!< in: pointer */
ulint align_no) /*!< in: align by this number */
{
ut_ad(align_no > 0);
ut_ad(((align_no - 1) & align_no) == 0);
......
......@@ -34,6 +34,11 @@ Created 1/20/1994 Heikki Tuuri
#define ut0ut_h
#include "univ.i"
#ifndef UNIV_HOTBACKUP
# include "os0sync.h" /* for HAVE_ATOMIC_BUILTINS */
#endif /* UNIV_HOTBACKUP */
#include <time.h>
#ifndef MYSQL_SERVER
#include <ctype.h>
......@@ -47,7 +52,8 @@ Created 1/20/1994 Heikki Tuuri
/** Time stamp */
typedef time_t ib_time_t;
#if defined(IB_HAVE_PAUSE_INSTRUCTION)
#ifndef UNIV_HOTBACKUP
#if defined(HAVE_IB_PAUSE_INSTRUCTION)
# ifdef WIN32
/* In the Win32 API, the x86 PAUSE instruction is executed by calling
the YieldProcessor macro defined in WinNT.h. It is a CPU architecture-
......@@ -84,6 +90,7 @@ do { \
os_thread_sleep(2000 /* 2 ms */); \
} \
} while (0)
#endif /* !UNIV_HOTBACKUP */
/********************************************************//**
Gets the high 32 bits in a ulint. That is makes a shift >> 32,
......@@ -216,6 +223,7 @@ UNIV_INTERN
ib_time_t
ut_time(void);
/*=========*/
#ifndef UNIV_HOTBACKUP
/**********************************************************//**
Returns system time.
Upon successful completion, the value 0 is returned; otherwise the
......@@ -239,6 +247,16 @@ ullint
ut_time_us(
/*=======*/
ullint* tloc); /*!< out: us since epoch, if non-NULL */
/**********************************************************//**
Returns the number of milliseconds since some epoch. The
value may wrap around. It should only be used for heuristic
purposes.
@return ms since epoch */
UNIV_INTERN
ulint
ut_time_ms(void);
/*============*/
#endif /* !UNIV_HOTBACKUP */
/**********************************************************//**
Returns the difference of two times in seconds.
......
......@@ -214,7 +214,7 @@ a waiting s-lock request on the next record? If this s-lock was placed
by a read cursor moving in the ascending order in the index, we cannot
do the insert immediately, because when we finally commit our transaction,
the read cursor should see also the new inserted record. So we should
move the read cursor backward from the the next record for it to pass over
move the read cursor backward from the next record for it to pass over
the new inserted record. This move backward may be too cumbersome to
implement. If we in this situation just enqueue a second x-lock request
for our transaction on the next record, then the deadlock mechanism
......@@ -360,10 +360,9 @@ ibool
lock_rec_validate_page(
/*===================*/
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 */
/* Define the following in order to enable lock_rec_validate_page() checks. */
# undef UNIV_DEBUG_LOCK_VALIDATE
#endif /* UNIV_DEBUG */
/* The lock system */
......@@ -2622,6 +2621,7 @@ lock_move_reorganize_page(
#ifdef UNIV_DEBUG_LOCK_VALIDATE
ut_ad(lock_rec_validate_page(buf_block_get_space(block),
buf_block_get_zip_size(block),
buf_block_get_page_no(block)));
#endif
}
......@@ -2711,8 +2711,10 @@ lock_move_rec_list_end(
#ifdef UNIV_DEBUG_LOCK_VALIDATE
ut_ad(lock_rec_validate_page(buf_block_get_space(block),
buf_block_get_zip_size(block),
buf_block_get_page_no(block)));
ut_ad(lock_rec_validate_page(buf_block_get_space(new_block),
buf_block_get_zip_size(block),
buf_block_get_page_no(new_block)));
#endif
}
......@@ -2822,6 +2824,7 @@ lock_move_rec_list_start(
#ifdef UNIV_DEBUG_LOCK_VALIDATE
ut_ad(lock_rec_validate_page(buf_block_get_space(block),
buf_block_get_zip_size(block),
buf_block_get_page_no(block)));
#endif
}
......@@ -4630,6 +4633,10 @@ lock_rec_queue_validate(
next function call: we have to release lock table mutex
to obey the latching order */
/* If this thread is holding the file space latch
(fil_space_t::latch), the following check WILL break
latching order and may cause a deadlock of threads. */
impl_trx = lock_sec_rec_some_has_impl_off_kernel(
rec, index, offsets);
......@@ -4687,6 +4694,8 @@ ibool
lock_rec_validate_page(
/*===================*/
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 */
{
dict_index_t* index;
......@@ -4697,7 +4706,6 @@ lock_rec_validate_page(
ulint nth_lock = 0;
ulint nth_bit = 0;
ulint i;
ulint zip_size;
mtr_t mtr;
mem_heap_t* heap = NULL;
ulint offsets_[REC_OFFS_NORMAL_SIZE];
......@@ -4708,7 +4716,6 @@ lock_rec_validate_page(
mtr_start(&mtr);
zip_size = fil_space_get_zip_size(space);
ut_ad(zip_size != ULINT_UNDEFINED);
block = buf_page_get(space, zip_size, page_no, RW_X_LATCH, &mtr);
buf_block_dbg_add_level(block, SYNC_NO_ORDER_CHECK);
......@@ -4753,6 +4760,11 @@ lock_rec_validate_page(
lock_mutex_exit_kernel();
/* If this thread is holding the file space
latch (fil_space_t::latch), the following
check WILL break the latching order and may
cause a deadlock of threads. */
lock_rec_queue_validate(block, rec, index, offsets);
lock_mutex_enter_kernel();
......@@ -4843,7 +4855,9 @@ lock_validate(void)
lock_mutex_exit_kernel();
lock_rec_validate_page(space, page_no);
lock_rec_validate_page(space,
fil_space_get_zip_size(space),
page_no);
lock_mutex_enter_kernel();
......@@ -5366,6 +5380,20 @@ lock_release_autoinc_last_lock(
lock_table_dequeue(lock);
}
/*******************************************************************//**
Check if a transaction holds any autoinc locks.
@return TRUE if the transaction holds any AUTOINC locks. */
UNIV_INTERN
ibool
lock_trx_holds_autoinc_locks(
/*=========================*/
const trx_t* trx) /*!< in: transaction */
{
ut_a(trx->autoinc_locks != NULL);
return(!ib_vector_is_empty(trx->autoinc_locks));
}
/*******************************************************************//**
Release all the transaction's autoinc locks. */
UNIV_INTERN
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
......@@ -11,6 +11,7 @@
-- disable_result_log
-- enable_warnings
let $sample_pages=`select @@innodb_stats_sample_pages`;
SET GLOBAL innodb_stats_sample_pages=0;
# check that the value has been adjusted to 1
......@@ -61,3 +62,4 @@ SET GLOBAL innodb_stats_sample_pages=16;
ANALYZE TABLE innodb_analyze;
DROP TABLE innodb_analyze;
EVAL SET GLOBAL innodb_stats_sample_pages=$sample_pages;
This diff is collapsed.
This diff is collapsed.
......@@ -141,7 +141,7 @@ drop table t1;
CREATE TABLE t1(c TEXT, PRIMARY KEY (c(440)))
ENGINE=InnoDB ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=1 CHARSET=ASCII;
ERROR 42000: Row size too large. The maximum row size for the used table type, not counting BLOBs, is 8126. You have to change some columns to TEXT or BLOBs
CREATE TABLE t1(c TEXT, PRIMARY KEY (c(439)))
CREATE TABLE t1(c TEXT, PRIMARY KEY (c(438)))
ENGINE=InnoDB ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=1 CHARSET=ASCII;
INSERT INTO t1 VALUES(REPEAT('A',512)),(REPEAT('B',512));
DROP TABLE t1;
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
......@@ -42,3 +42,4 @@ ERROR HY000: Incorrect arguments to SET
select @@innodb_file_format_check;
@@innodb_file_format_check
Barracuda
set global innodb_file_format_check=antelope;
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment