Below is the list of changes that have just been committed into a local
5.1 repository of alexi. When alexi does a push these changes will
be propagated to the main repository and, within 24 hours after the
push, to the public repository.
For information on how to access the public repository
see http://dev.mysql.com/doc/mysql/en/installing-source-tree.html
ChangeSet
1.2214 06/03/03 22:34:24 aivanov@stripped +39 -0
Applying innodb-5.1-ss160 snapshot
Intermediate, not to be pushed
mysql-test/t/innodb_unsafe_binlog.test
1.1 06/03/03 22:34:17 aivanov@stripped +55 -0
Applying innodb-5.1-ss160 snapshot
Intermediate, not to be pushed
mysql-test/t/innodb_unsafe_binlog-master.opt
1.1 06/03/03 22:34:17 aivanov@stripped +1 -0
Applying innodb-5.1-ss160 snapshot
Intermediate, not to be pushed
mysql-test/r/innodb_unsafe_binlog.result
1.1 06/03/03 22:34:17 aivanov@stripped +35 -0
Applying innodb-5.1-ss160 snapshot
Intermediate, not to be pushed
storage/innobase/trx/trx0trx.c
1.63 06/03/03 22:34:17 aivanov@stripped +2 -1
Applying innodb-5.1-ss160 snapshot
Intermediate, not to be pushed
storage/innobase/sync/sync0sync.c
1.38 06/03/03 22:34:17 aivanov@stripped +1 -1
Applying innodb-5.1-ss160 snapshot
Intermediate, not to be pushed
storage/innobase/sync/sync0arr.c
1.22 06/03/03 22:34:17 aivanov@stripped +188 -97
Applying innodb-5.1-ss160 snapshot
Intermediate, not to be pushed
mysql-test/t/innodb_unsafe_binlog.test
1.0 06/03/03 22:34:17 aivanov@stripped +0 -0
BitKeeper file /home/alexi/innodb/mysql-5.1-xx160/mysql-test/t/innodb_unsafe_binlog.test
mysql-test/t/innodb_unsafe_binlog-master.opt
1.0 06/03/03 22:34:17 aivanov@stripped +0 -0
BitKeeper file /home/alexi/innodb/mysql-5.1-xx160/mysql-test/t/innodb_unsafe_binlog-master.opt
mysql-test/r/innodb_unsafe_binlog.result
1.0 06/03/03 22:34:17 aivanov@stripped +0 -0
BitKeeper file /home/alexi/innodb/mysql-5.1-xx160/mysql-test/r/innodb_unsafe_binlog.result
storage/innobase/srv/srv0start.c
1.91 06/03/03 22:34:16 aivanov@stripped +40 -1
Applying innodb-5.1-ss160 snapshot
Intermediate, not to be pushed
storage/innobase/srv/srv0srv.c
1.97 06/03/03 22:34:16 aivanov@stripped +18 -5
Applying innodb-5.1-ss160 snapshot
Intermediate, not to be pushed
storage/innobase/row/row0sel.c
1.101 06/03/03 22:34:16 aivanov@stripped +4 -3
Applying innodb-5.1-ss160 snapshot
Intermediate, not to be pushed
storage/innobase/row/row0mysql.c
1.122 06/03/03 22:34:16 aivanov@stripped +28 -41
Applying innodb-5.1-ss160 snapshot
Intermediate, not to be pushed
storage/innobase/row/row0ins.c
1.77 06/03/03 22:34:16 aivanov@stripped +22 -27
Applying innodb-5.1-ss160 snapshot
Intermediate, not to be pushed
storage/innobase/rem/rem0cmp.c
1.32 06/03/03 22:34:16 aivanov@stripped +6 -5
Applying innodb-5.1-ss160 snapshot
Intermediate, not to be pushed
storage/innobase/os/os0thread.c
1.33 06/03/03 22:34:16 aivanov@stripped +0 -9
Applying innodb-5.1-ss160 snapshot
Intermediate, not to be pushed
storage/innobase/os/os0sync.c
1.29 06/03/03 22:34:16 aivanov@stripped +15 -15
Applying innodb-5.1-ss160 snapshot
Intermediate, not to be pushed
storage/innobase/os/os0file.c
1.114 06/03/03 22:34:16 aivanov@stripped +72 -40
Applying innodb-5.1-ss160 snapshot
Intermediate, not to be pushed
storage/innobase/lock/lock0lock.c
1.66 06/03/03 22:34:16 aivanov@stripped +11 -8
Applying innodb-5.1-ss160 snapshot
Intermediate, not to be pushed
storage/innobase/include/univ.i
1.47 06/03/03 22:34:16 aivanov@stripped +9 -0
Applying innodb-5.1-ss160 snapshot
Intermediate, not to be pushed
storage/innobase/include/sync0arr.h
1.9 06/03/03 22:34:16 aivanov@stripped +5 -5
Applying innodb-5.1-ss160 snapshot
Intermediate, not to be pushed
storage/innobase/include/srv0srv.h
1.60 06/03/03 22:34:16 aivanov@stripped +13 -2
Applying innodb-5.1-ss160 snapshot
Intermediate, not to be pushed
storage/innobase/include/row0mysql.h
1.47 06/03/03 22:34:16 aivanov@stripped +0 -1
Applying innodb-5.1-ss160 snapshot
Intermediate, not to be pushed
storage/innobase/include/rem0cmp.h
1.12 06/03/03 22:34:15 aivanov@stripped +2 -1
Applying innodb-5.1-ss160 snapshot
Intermediate, not to be pushed
storage/innobase/include/os0file.h
1.45 06/03/03 22:34:15 aivanov@stripped +4 -3
Applying innodb-5.1-ss160 snapshot
Intermediate, not to be pushed
storage/innobase/include/dict0load.h
1.12 06/03/03 22:34:15 aivanov@stripped +2 -1
Applying innodb-5.1-ss160 snapshot
Intermediate, not to be pushed
storage/innobase/include/dict0dict.h
1.41 06/03/03 22:34:15 aivanov@stripped +2 -1
Applying innodb-5.1-ss160 snapshot
Intermediate, not to be pushed
storage/innobase/include/db0err.h
1.13 06/03/03 22:34:15 aivanov@stripped +0 -4
Applying innodb-5.1-ss160 snapshot
Intermediate, not to be pushed
storage/innobase/include/data0type.ic
1.29 06/03/03 22:34:15 aivanov@stripped +24 -15
Applying innodb-5.1-ss160 snapshot
Intermediate, not to be pushed
storage/innobase/include/data0type.h
1.24 06/03/03 22:34:15 aivanov@stripped +2 -1
Applying innodb-5.1-ss160 snapshot
Intermediate, not to be pushed
storage/innobase/include/buf0buf.h
1.34 06/03/03 22:34:15 aivanov@stripped +9 -3
Applying innodb-5.1-ss160 snapshot
Intermediate, not to be pushed
storage/innobase/include/btr0sea.ic
1.5 06/03/03 22:34:15 aivanov@stripped +1 -1
Applying innodb-5.1-ss160 snapshot
Intermediate, not to be pushed
storage/innobase/fil/fil0fil.c
1.62 06/03/03 22:34:15 aivanov@stripped +81 -2
Applying innodb-5.1-ss160 snapshot
Intermediate, not to be pushed
storage/innobase/dict/dict0load.c
1.45 06/03/03 22:34:15 aivanov@stripped +20 -9
Applying innodb-5.1-ss160 snapshot
Intermediate, not to be pushed
storage/innobase/dict/dict0dict.c
1.76 06/03/03 22:34:15 aivanov@stripped +15 -22
Applying innodb-5.1-ss160 snapshot
Intermediate, not to be pushed
storage/innobase/btr/btr0sea.c
1.39 06/03/03 22:34:15 aivanov@stripped +51 -24
Applying innodb-5.1-ss160 snapshot
Intermediate, not to be pushed
sql/ha_innodb.h
1.118 06/03/03 22:34:15 aivanov@stripped +2 -13
Applying innodb-5.1-ss160 snapshot
Intermediate, not to be pushed
sql/ha_innodb.cc
1.259 06/03/03 22:34:15 aivanov@stripped +188 -159
Applying innodb-5.1-ss160 snapshot
Intermediate, not to be pushed
mysql-test/t/innodb_cache.test
1.13 06/03/03 22:34:15 aivanov@stripped +0 -4
Applying innodb-5.1-ss160 snapshot
Intermediate, not to be pushed
mysql-test/t/innodb.test
1.131 06/03/03 22:34:14 aivanov@stripped +382 -20
Applying innodb-5.1-ss160 snapshot
Intermediate, not to be pushed
mysql-test/r/innodb_cache.result
1.14 06/03/03 22:34:14 aivanov@stripped +1 -1
Applying innodb-5.1-ss160 snapshot
Intermediate, not to be pushed
mysql-test/r/innodb.result
1.164 06/03/03 22:34:14 aivanov@stripped +481 -44
Applying innodb-5.1-ss160 snapshot
Intermediate, not to be pushed
# This is a BitKeeper patch. What follows are the unified diffs for the
# set of deltas contained in the patch. The rest of the patch, the part
# that BitKeeper cares about, is below these diffs.
# User: aivanov
# Host: mysqld.creware.com
# Root: /home/alexi/innodb/mysql-5.1-xx160
--- New file ---
+++ mysql-test/r/innodb_unsafe_binlog.result 06/03/03 22:34:17
drop table if exists t1,t2;
create table t1 (id int not null, f_id int not null, f int not null,
primary key(f_id, id)) engine=innodb;
create table t2 (id int not null,s_id int not null,s varchar(200),
primary key(id)) engine=innodb;
INSERT INTO t1 VALUES (8, 1, 3);
INSERT INTO t1 VALUES (1, 2, 1);
INSERT INTO t2 VALUES (1, 0, '');
INSERT INTO t2 VALUES (8, 1, '');
commit;
DELETE ml.* FROM t1 AS ml LEFT JOIN t2 AS mm ON (mm.id=ml.id)
WHERE mm.id IS NULL;
select ml.* from t1 as ml left join t2 as mm on (mm.id=ml.id)
where mm.id is null lock in share mode;
id f_id f
drop table t1,t2;
create table t1(a int not null, b int, primary key(a)) engine=innodb;
insert into t1 values(1,1),(2,2),(3,1),(4,2),(5,1),(6,2);
commit;
set autocommit = 0;
select * from t1 lock in share mode;
a b
1 1
2 2
3 1
4 2
5 1
6 2
update t1 set b = 5 where b = 1;
set autocommit = 0;
select * from t1 where a = 2 and b = 2 for update;
ERROR HY000: Lock wait timeout exceeded; try restarting transaction
commit;
commit;
drop table t1;
--- New file ---
+++ mysql-test/t/innodb_unsafe_binlog-master.opt 06/03/03 22:34:17
--innodb_locks_unsafe_for_binlog=true
--- New file ---
+++ mysql-test/t/innodb_unsafe_binlog.test 06/03/03 22:34:17
-- source include/have_innodb.inc
#
# Note that these tests uses a innodb_locks_unsafe_for_binlog option.
#
#
# Test cases for a bug #15650
#
--disable_warnings
drop table if exists t1,t2;
--enable_warnings
create table t1 (id int not null, f_id int not null, f int not null,
primary key(f_id, id)) engine=innodb;
create table t2 (id int not null,s_id int not null,s varchar(200),
primary key(id)) engine=innodb;
INSERT INTO t1 VALUES (8, 1, 3);
INSERT INTO t1 VALUES (1, 2, 1);
INSERT INTO t2 VALUES (1, 0, '');
INSERT INTO t2 VALUES (8, 1, '');
commit;
DELETE ml.* FROM t1 AS ml LEFT JOIN t2 AS mm ON (mm.id=ml.id)
WHERE mm.id IS NULL;
select ml.* from t1 as ml left join t2 as mm on (mm.id=ml.id)
where mm.id is null lock in share mode;
drop table t1,t2;
#
# Test case for unlock row bug where unlock releases all locks granted for
# a row. Only the latest lock should be released.
#
connect (a,localhost,root,,);
connect (b,localhost,root,,);
connection a;
create table t1(a int not null, b int, primary key(a)) engine=innodb;
insert into t1 values(1,1),(2,2),(3,1),(4,2),(5,1),(6,2);
commit;
set autocommit = 0;
select * from t1 lock in share mode;
update t1 set b = 5 where b = 1;
connection b;
set autocommit = 0;
#
# S-lock to records (2,2),(4,2), and (6,2) should not be released in a update
#
--error 1205
select * from t1 where a = 2 and b = 2 for update;
connection a;
commit;
connection b;
commit;
drop table t1;
disconnect a;
disconnect b;
--- 1.38/storage/innobase/btr/btr0sea.c 2006-02-08 13:58:49 +03:00
+++ 1.39/storage/innobase/btr/btr0sea.c 2006-03-03 22:34:15 +03:00
@@ -191,7 +191,7 @@
void
btr_search_info_update_hash(
/*========================*/
- btr_search_t* info, /* in: search info */
+ btr_search_t* info, /* in/out: search info */
btr_cur_t* cursor) /* in: cursor which was just positioned */
{
dict_index_t* index;
@@ -452,7 +452,7 @@
void
btr_search_info_update_slow(
/*========================*/
- btr_search_t* info, /* in: search info */
+ btr_search_t* info, /* in/out: search info */
btr_cur_t* cursor) /* in: cursor which was just positioned */
{
buf_block_t* block;
@@ -889,7 +889,8 @@
void
btr_search_drop_page_hash_index(
/*============================*/
- page_t* page) /* in: index page, s- or x-latched */
+ page_t* page) /* in: index page, s- or x-latched, or an index page
+ for which we know that block->buf_fix_count == 0 */
{
hash_table_t* table;
buf_block_t* block;
@@ -904,18 +905,19 @@
ulint* folds;
ulint i;
mem_heap_t* heap;
+ dict_index_t* index;
ulint* offsets;
#ifdef UNIV_SYNC_DEBUG
ut_ad(!rw_lock_own(&btr_search_latch, RW_LOCK_SHARED));
ut_ad(!rw_lock_own(&btr_search_latch, RW_LOCK_EX));
#endif /* UNIV_SYNC_DEBUG */
-
+retry:
rw_lock_s_lock(&btr_search_latch);
block = buf_block_align(page);
- if (!block->is_hashed) {
+ if (UNIV_LIKELY(!block->is_hashed)) {
rw_lock_s_unlock(&btr_search_latch);
@@ -932,11 +934,16 @@
n_fields = block->curr_n_fields;
n_bytes = block->curr_n_bytes;
+ index = block->index;
- ut_a(n_fields + n_bytes > 0);
+ /* NOTE: The fields of block must not be accessed after
+ releasing btr_search_latch, as the index page might only
+ be s-latched! */
rw_lock_s_unlock(&btr_search_latch);
+ ut_a(n_fields + n_bytes > 0);
+
n_recs = page_get_n_recs(page);
/* Calculate and cache fold values into an array for fast deletion
@@ -949,33 +956,21 @@
rec = page_get_infimum_rec(page);
rec = page_rec_get_next(rec);
- if (!page_rec_is_supremum(rec)) {
- ut_a(n_fields <= rec_get_n_fields(rec, block->index));
-
- if (n_bytes > 0) {
- ut_a(n_fields < rec_get_n_fields(rec, block->index));
- }
- }
-
tree_id = btr_page_get_index_id(page);
+ ut_a(0 == ut_dulint_cmp(tree_id, index->id));
+
prev_fold = 0;
heap = NULL;
offsets = NULL;
- if (block->index == NULL) {
-
- mem_analyze_corruption((byte*)block);
-
- ut_a(block->index != NULL);
- }
-
while (!page_rec_is_supremum(rec)) {
/* FIXME: in a mixed tree, not all records may have enough
ordering fields: */
- offsets = rec_get_offsets(rec, block->index,
- offsets, n_fields + (n_bytes > 0), &heap);
+ offsets = rec_get_offsets(rec, index, offsets,
+ n_fields + (n_bytes > 0), &heap);
+ ut_a(rec_offs_n_fields(offsets) == n_fields + (n_bytes > 0));
fold = rec_fold(rec, offsets, n_fields, n_bytes, tree_id);
if (fold == prev_fold && prev_fold != 0) {
@@ -999,6 +994,26 @@
rw_lock_x_lock(&btr_search_latch);
+ if (UNIV_UNLIKELY(!block->is_hashed)) {
+ /* Someone else has meanwhile dropped the hash index */
+
+ goto cleanup;
+ }
+
+ ut_a(block->index == index);
+
+ if (UNIV_UNLIKELY(block->curr_n_fields != n_fields)
+ || UNIV_UNLIKELY(block->curr_n_bytes != n_bytes)) {
+
+ /* Someone else has meanwhile built a new hash index on the
+ page, with different parameters */
+
+ rw_lock_x_unlock(&btr_search_latch);
+
+ mem_free(folds);
+ goto retry;
+ }
+
for (i = 0; i < n_cached; i++) {
ha_remove_all_nodes_to_page(table, folds[i], page);
@@ -1006,8 +1021,20 @@
block->is_hashed = FALSE;
block->index = NULL;
+cleanup:
+ if (UNIV_UNLIKELY(block->n_pointers)) {
+ /* Corruption */
+ ut_print_timestamp(stderr);
+ fprintf(stderr,
+" InnoDB: Corruption of adaptive hash index. After dropping\n"
+"InnoDB: the hash index to a page of %s, still %lu hash nodes remain.\n",
+ index->name, (ulong) block->n_pointers);
+ rw_lock_x_unlock(&btr_search_latch);
- rw_lock_x_unlock(&btr_search_latch);
+ btr_search_validate();
+ } else {
+ rw_lock_x_unlock(&btr_search_latch);
+ }
mem_free(folds);
}
--- 1.75/storage/innobase/dict/dict0dict.c 2006-02-08 13:58:49 +03:00
+++ 1.76/storage/innobase/dict/dict0dict.c 2006-03-03 22:34:15 +03:00
@@ -2104,8 +2104,11 @@
dict_table_t* table, /* in: table */
const char** columns,/* in: array of column names */
ulint n_cols, /* in: number of columns */
- dict_index_t* types_idx)/* in: NULL or an index to whose types the
- column types must match */
+ dict_index_t* types_idx, /* in: NULL or an index to whose types the
+ column types must match */
+ ibool check_charsets) /* in: whether to check charsets.
+ only has an effect if types_idx !=
+ NULL. */
{
#ifndef UNIV_HOTBACKUP
dict_index_t* index;
@@ -2135,7 +2138,8 @@
if (types_idx && !cmp_types_are_equal(
dict_index_get_nth_type(index, i),
- dict_index_get_nth_type(types_idx, i))) {
+ dict_index_get_nth_type(types_idx, i),
+ check_charsets)) {
break;
}
@@ -2212,7 +2216,8 @@
/*======================*/
/* out: DB_SUCCESS or error code */
dict_foreign_t* foreign, /* in, own: foreign key constraint */
- ibool check_types) /* in: TRUE=check type compatibility */
+ ibool check_charsets) /* in: TRUE=check charset
+ compatibility */
{
dict_table_t* for_table;
dict_table_t* ref_table;
@@ -2248,16 +2253,10 @@
}
if (for_in_cache->referenced_table == NULL && ref_table) {
- dict_index_t* types_idx;
- if (check_types) {
- types_idx = for_in_cache->foreign_index;
- } else {
- types_idx = NULL;
- }
index = dict_foreign_find_index(ref_table,
(const char**) for_in_cache->referenced_col_names,
for_in_cache->n_fields,
- types_idx);
+ for_in_cache->foreign_index, check_charsets);
if (index == NULL) {
dict_foreign_error_report(ef, for_in_cache,
@@ -2281,16 +2280,10 @@
}
if (for_in_cache->foreign_table == NULL && for_table) {
- dict_index_t* types_idx;
- if (check_types) {
- types_idx = for_in_cache->referenced_index;
- } else {
- types_idx = NULL;
- }
index = dict_foreign_find_index(for_table,
(const char**) for_in_cache->foreign_col_names,
for_in_cache->n_fields,
- types_idx);
+ for_in_cache->referenced_index, check_charsets);
if (index == NULL) {
dict_foreign_error_report(ef, for_in_cache,
@@ -2810,7 +2803,8 @@
if (ut_strlen(foreign->id) > ((sizeof dict_ibfk) - 1) + len
&& 0 == ut_memcmp(foreign->id, table->name, len)
&& 0 == ut_memcmp(foreign->id + len,
- dict_ibfk, (sizeof dict_ibfk) - 1)) {
+ dict_ibfk, (sizeof dict_ibfk) - 1)
+ && foreign->id[len + ((sizeof dict_ibfk) - 1)] != '0') {
/* It is of the >= 4.0.18 format */
id = strtoul(foreign->id + len + ((sizeof dict_ibfk) - 1),
@@ -3097,7 +3091,7 @@
/* Try to find an index which contains the columns
as the first fields and in the right order */
- index = dict_foreign_find_index(table, column_names, i, NULL);
+ index = dict_foreign_find_index(table, column_names, i, NULL, TRUE);
if (!index) {
mutex_enter(&dict_foreign_err_mutex);
@@ -3362,8 +3356,7 @@
if (referenced_table) {
index = dict_foreign_find_index(referenced_table,
- column_names, i,
- foreign->foreign_index);
+ column_names, i, foreign->foreign_index, TRUE);
if (!index) {
dict_foreign_free(foreign);
mutex_enter(&dict_foreign_err_mutex);
--- 1.44/storage/innobase/dict/dict0load.c 2006-02-08 13:58:50 +03:00
+++ 1.45/storage/innobase/dict/dict0load.c 2006-03-03 22:34:15 +03:00
@@ -385,13 +385,23 @@
field = rec_get_nth_field_old(rec, 6, &len);
prtype = mach_read_from_4(field);
- if (dtype_is_non_binary_string_type(mtype, prtype)
- && dtype_get_charset_coll(prtype) == 0) {
- /* This is a non-binary string type, and the table
- was created with < 4.1.2. Use the default charset. */
+ if (dtype_get_charset_coll(prtype) == 0
+ && dtype_is_string_type(mtype)) {
+ /* The table was created with < 4.1.2. */
+
+ if (dtype_is_binary_string_type(mtype, prtype)) {
+ /* Use the binary collation for
+ string columns of binary type. */
+
+ prtype = dtype_form_prtype(prtype,
+ DATA_MYSQL_BINARY_CHARSET_COLL);
+ } else {
+ /* Use the default charset for
+ other than binary columns. */
- prtype = dtype_form_prtype(prtype,
+ prtype = dtype_form_prtype(prtype,
data_mysql_default_charset_coll);
+ }
}
field = rec_get_nth_field_old(rec, 7, &len);
@@ -1091,7 +1101,7 @@
/* out: DB_SUCCESS or error code */
const char* id, /* in: foreign constraint id as a
null-terminated string */
- ibool check_types)/* in: TRUE=check type compatibility */
+ ibool check_charsets)/* in: TRUE=check charset compatibility */
{
dict_foreign_t* foreign;
dict_table_t* sys_foreign;
@@ -1204,7 +1214,7 @@
a new foreign key constraint but loading one from the data
dictionary. */
- return(dict_foreign_add_to_cache(foreign, check_types));
+ return(dict_foreign_add_to_cache(foreign, check_charsets));
}
/***************************************************************************
@@ -1219,7 +1229,8 @@
/*===============*/
/* out: DB_SUCCESS or error code */
const char* table_name, /* in: table name */
- ibool check_types) /* in: TRUE=check type compatibility */
+ ibool check_charsets) /* in: TRUE=check charset
+ compatibility */
{
btr_pcur_t pcur;
mem_heap_t* heap;
@@ -1319,7 +1330,7 @@
/* Load the foreign constraint definition to the dictionary cache */
- err = dict_load_foreign(id, check_types);
+ err = dict_load_foreign(id, check_charsets);
if (err != DB_SUCCESS) {
btr_pcur_close(&pcur);
--- 1.61/storage/innobase/fil/fil0fil.c 2006-02-08 13:58:50 +03:00
+++ 1.62/storage/innobase/fil/fil0fil.c 2006-03-03 22:34:15 +03:00
@@ -181,6 +181,11 @@
hash_node_t name_hash;/* hash chain the name_hash table */
rw_lock_t latch; /* latch protecting the file space storage
allocation */
+ UT_LIST_NODE_T(fil_space_t) unflushed_spaces;
+ /* list of spaces with at least one unflushed
+ file we have written to */
+ ibool is_in_unflushed_spaces; /* TRUE if this space is
+ currently in the list above */
UT_LIST_NODE_T(fil_space_t) space_list;
/* list of all spaces */
ibuf_data_t* ibuf_data;
@@ -213,6 +218,12 @@
not put to this list: they are opened
after the startup, and kept open until
shutdown */
+ UT_LIST_BASE_NODE_T(fil_space_t) unflushed_spaces;
+ /* base node for the list of those
+ tablespaces whose files contain
+ unflushed writes; those spaces have
+ at least one file node where
+ modification_counter > flush_counter */
ulint n_open; /* number of files currently open */
ulint max_n_open; /* n_open is not allowed to exceed
this */
@@ -389,6 +400,36 @@
return(space->ibuf_data);
}
+/**************************************************************************
+Checks if all the file nodes in a space are flushed. The caller must hold
+the fil_system mutex. */
+static
+ibool
+fil_space_is_flushed(
+/*=================*/
+ /* out: TRUE if all are flushed */
+ fil_space_t* space) /* in: space */
+{
+ fil_node_t* node;
+
+#ifdef UNIV_SYNC_DEBUG
+ ut_ad(mutex_own(&(fil_system->mutex)));
+#endif /* UNIV_SYNC_DEBUG */
+
+ node = UT_LIST_GET_FIRST(space->chain);
+
+ while (node) {
+ if (node->modification_counter > node->flush_counter) {
+
+ return(FALSE);
+ }
+
+ node = UT_LIST_GET_NEXT(chain, node);
+ }
+
+ return(TRUE);
+}
+
/***********************************************************************
Appends a new file to the chain of files of a space. File must be closed. */
@@ -841,6 +882,16 @@
node->modification_counter = node->flush_counter;
+ if (space->is_in_unflushed_spaces
+ && fil_space_is_flushed(space)) {
+
+ space->is_in_unflushed_spaces = FALSE;
+
+ UT_LIST_REMOVE(unflushed_spaces,
+ system->unflushed_spaces,
+ space);
+ }
+
fil_node_close_file(node, system);
}
@@ -1004,6 +1055,8 @@
HASH_INSERT(fil_space_t, name_hash, system->name_hash,
ut_fold_string(name), space);
+ space->is_in_unflushed_spaces = FALSE;
+
UT_LIST_ADD_LAST(space_list, system->space_list, space);
mutex_exit(&(system->mutex));
@@ -1099,6 +1152,13 @@
HASH_DELETE(fil_space_t, name_hash, system->name_hash,
ut_fold_string(space->name), space);
+ if (space->is_in_unflushed_spaces) {
+ space->is_in_unflushed_spaces = FALSE;
+
+ UT_LIST_REMOVE(unflushed_spaces, system->unflushed_spaces,
+ space);
+ }
+
UT_LIST_REMOVE(space_list, system->space_list, space);
ut_a(space->magic_n == FIL_SPACE_MAGIC_N);
@@ -1250,6 +1310,7 @@
system->tablespace_version = 0;
+ UT_LIST_INIT(system->unflushed_spaces);
UT_LIST_INIT(system->space_list);
return(system);
@@ -3742,6 +3803,14 @@
if (type == OS_FILE_WRITE) {
system->modification_counter++;
node->modification_counter = system->modification_counter;
+
+ if (!node->space->is_in_unflushed_spaces) {
+
+ node->space->is_in_unflushed_spaces = TRUE;
+ UT_LIST_ADD_FIRST(unflushed_spaces,
+ system->unflushed_spaces,
+ node->space);
+ }
}
if (node->n_pending == 0 && node->space->purpose == FIL_TABLESPACE
@@ -4162,6 +4231,16 @@
skip_flush:
if (node->flush_counter < old_mod_counter) {
node->flush_counter = old_mod_counter;
+
+ if (space->is_in_unflushed_spaces
+ && fil_space_is_flushed(space)) {
+
+ space->is_in_unflushed_spaces = FALSE;
+
+ UT_LIST_REMOVE(unflushed_spaces,
+ system->unflushed_spaces,
+ space);
+ }
}
if (space->purpose == FIL_TABLESPACE) {
@@ -4193,7 +4272,7 @@
mutex_enter(&(system->mutex));
- space = UT_LIST_GET_FIRST(system->space_list);
+ space = UT_LIST_GET_FIRST(system->unflushed_spaces);
while (space) {
if (space->purpose == purpose && !space->is_being_deleted) {
@@ -4209,7 +4288,7 @@
space->n_pending_flushes--;
}
- space = UT_LIST_GET_NEXT(space_list, space);
+ space = UT_LIST_GET_NEXT(unflushed_spaces, space);
}
mutex_exit(&(system->mutex));
--- 1.4/storage/innobase/include/btr0sea.ic 2006-02-08 00:09:57 +03:00
+++ 1.5/storage/innobase/include/btr0sea.ic 2006-03-03 22:34:15 +03:00
@@ -16,7 +16,7 @@
void
btr_search_info_update_slow(
/*========================*/
- btr_search_t* info, /* in: search info */
+ btr_search_t* info, /* in/out: search info */
btr_cur_t* cursor);/* in: cursor which was just positioned */
/************************************************************************
--- 1.33/storage/innobase/include/buf0buf.h 2005-12-13 23:56:11 +03:00
+++ 1.34/storage/innobase/include/buf0buf.h 2006-03-03 22:34:15 +03:00
@@ -745,8 +745,6 @@
buffer pool which are index pages,
but this flag is not set because
we do not keep track of all pages */
- dict_index_t* index; /* index for which the adaptive
- hash index has been created */
/* 2. Page flushing fields */
UT_LIST_NODE_T(buf_block_t) flush_list;
@@ -833,7 +831,13 @@
records with the same prefix should be
indexed in the hash index */
- /* The following 4 fields are protected by btr_search_latch: */
+ /* These 6 fields may only be modified when we have
+ an x-latch on btr_search_latch AND
+ a) we are holding an s-latch or x-latch on block->lock or
+ b) we know that block->buf_fix_count == 0.
+
+ An exception to this is when we init or create a page
+ in the buffer pool in buf0buf.c. */
ibool is_hashed; /* TRUE if hash index has already been
built on this page; note that it does
@@ -850,6 +854,8 @@
ulint curr_side; /* BTR_SEARCH_LEFT_SIDE or
BTR_SEARCH_RIGHT_SIDE in hash
indexing */
+ dict_index_t* index; /* Index for which the adaptive
+ hash index has been created. */
/* 6. Debug fields */
#ifdef UNIV_SYNC_DEBUG
rw_lock_t debug_latch; /* in the debug version, each thread
--- 1.23/storage/innobase/include/data0type.h 2006-02-02 01:04:01 +03:00
+++ 1.24/storage/innobase/include/data0type.h 2006-03-03 22:34:15 +03:00
@@ -13,6 +13,7 @@
extern ulint data_mysql_default_charset_coll;
#define DATA_MYSQL_LATIN1_SWEDISH_CHARSET_COLL 8
+#define DATA_MYSQL_BINARY_CHARSET_COLL 63
/* SQL data type struct */
typedef struct dtype_struct dtype_t;
@@ -311,7 +312,7 @@
/*===============*/
/* out: padding character code, or
ULINT_UNDEFINED if no padding specified */
- dtype_t* type); /* in: type */
+ const dtype_t* type); /* in: type */
/***************************************************************************
Returns the size of a fixed size data type, 0 if not a fixed size type. */
UNIV_INLINE
--- 1.28/storage/innobase/include/data0type.ic 2006-02-02 01:04:01 +03:00
+++ 1.29/storage/innobase/include/data0type.ic 2006-03-03 22:34:15 +03:00
@@ -188,26 +188,35 @@
/*===============*/
/* out: padding character code, or
ULINT_UNDEFINED if no padding specified */
- dtype_t* type) /* in: type */
+ const dtype_t* type) /* in: type */
{
- if (type->mtype == DATA_CHAR
- || type->mtype == DATA_VARCHAR
- || type->mtype == DATA_BINARY
- || type->mtype == DATA_FIXBINARY
- || type->mtype == DATA_MYSQL
- || type->mtype == DATA_VARMYSQL
- || (type->mtype == DATA_BLOB
- && (type->prtype & DATA_BINARY_TYPE) == 0)) {
-
+ switch (type->mtype) {
+ case DATA_FIXBINARY:
+ case DATA_BINARY:
+ if (UNIV_UNLIKELY(dtype_get_charset_coll(type->prtype)
+ == DATA_MYSQL_BINARY_CHARSET_COLL)) {
+ /* Starting from 5.0.18, do not pad
+ VARBINARY or BINARY columns. */
+ return(ULINT_UNDEFINED);
+ }
+ /* Fall through */
+ case DATA_CHAR:
+ case DATA_VARCHAR:
+ case DATA_MYSQL:
+ case DATA_VARMYSQL:
/* Space is the padding character for all char and binary
strings, and starting from 5.0.3, also for TEXT strings. */
- return((ulint)' ');
+ return(0x20);
+ case DATA_BLOB:
+ if ((type->prtype & DATA_BINARY_TYPE) == 0) {
+ return(0x20);
+ }
+ /* Fall through */
+ default:
+ /* No padding specified */
+ return(ULINT_UNDEFINED);
}
-
- /* No padding specified */
-
- return(ULINT_UNDEFINED);
}
/**************************************************************************
--- 1.12/storage/innobase/include/db0err.h 2006-02-09 20:43:04 +03:00
+++ 1.13/storage/innobase/include/db0err.h 2006-03-03 22:34:15 +03:00
@@ -57,10 +57,6 @@
buffer pool (for big transactions,
InnoDB stores the lock structs in the
buffer pool) */
-#define DB_FOREIGN_DUPLICATE_KEY 46 /* foreign key constraints
- activated by the operation would
- lead to a duplicate key in some
- table */
/* The following are partial failure codes */
#define DB_FAIL 1000
--- 1.40/storage/innobase/include/dict0dict.h 2005-12-14 02:26:58 +03:00
+++ 1.41/storage/innobase/include/dict0dict.h 2006-03-03 22:34:15 +03:00
@@ -197,7 +197,8 @@
/*======================*/
/* out: DB_SUCCESS or error code */
dict_foreign_t* foreign, /* in, own: foreign key constraint */
- ibool check_types); /* in: TRUE=check type compatibility */
+ ibool check_charsets);/* in: TRUE=check charset
+ compatibility */
/*************************************************************************
Checks if a table is referenced by foreign keys. */
--- 1.11/storage/innobase/include/dict0load.h 2005-12-14 02:26:58 +03:00
+++ 1.12/storage/innobase/include/dict0load.h 2006-03-03 22:34:15 +03:00
@@ -82,7 +82,8 @@
/*===============*/
/* out: DB_SUCCESS or error code */
const char* table_name, /* in: table name */
- ibool check_types); /* in: TRUE=check type compatibility */
+ ibool check_charsets);/* in: TRUE=check charsets
+ compatibility */
/************************************************************************
Prints to the standard output information on all tables found in the data
dictionary system table. */
--- 1.44/storage/innobase/include/os0file.h 2006-02-02 01:04:01 +03:00
+++ 1.45/storage/innobase/include/os0file.h 2006-03-03 22:34:15 +03:00
@@ -91,9 +91,10 @@
#define OS_FILE_NOT_FOUND 71
#define OS_FILE_DISK_FULL 72
#define OS_FILE_ALREADY_EXISTS 73
-#define OS_FILE_AIO_RESOURCES_RESERVED 74 /* wait for OS aio resources
+#define OS_FILE_PATH_ERROR 74
+#define OS_FILE_AIO_RESOURCES_RESERVED 75 /* wait for OS aio resources
to become available again */
-#define OS_FILE_ERROR_NOT_SPECIFIED 75
+#define OS_FILE_ERROR_NOT_SPECIFIED 76
/* Types for aio operations */
#define OS_FILE_READ 10
@@ -187,7 +188,7 @@
FILE*
os_file_create_tmpfile(void);
/*========================*/
- /* out: temporary file handle (never NULL) */
+ /* out: temporary file handle, or NULL on error */
/***************************************************************************
The os_file_opendir() function opens a directory stream corresponding to the
directory named by the dirname argument. The directory stream is positioned
--- 1.11/storage/innobase/include/rem0cmp.h 2005-12-14 02:26:59 +03:00
+++ 1.12/storage/innobase/include/rem0cmp.h 2006-03-03 22:34:15 +03:00
@@ -24,7 +24,8 @@
/* out: TRUE if the types are considered
equal in comparisons */
dtype_t* type1, /* in: type 1 */
- dtype_t* type2); /* in: type 2 */
+ dtype_t* type2, /* in: type 2 */
+ ibool check_charsets); /* in: whether to check charsets */
/*****************************************************************
This function is used to compare two data fields for which we know the
data type. */
--- 1.46/storage/innobase/include/row0mysql.h 2006-02-02 01:04:01 +03:00
+++ 1.47/storage/innobase/include/row0mysql.h 2006-03-03 22:34:16 +03:00
@@ -687,7 +687,6 @@
#define ROW_READ_TRY_SEMI_CONSISTENT 1
#define ROW_READ_DID_SEMI_CONSISTENT 2
-
#ifndef UNIV_NONINL
#include "row0mysql.ic"
#endif
--- 1.59/storage/innobase/include/srv0srv.h 2006-02-02 17:20:20 +03:00
+++ 1.60/storage/innobase/include/srv0srv.h 2006-03-03 22:34:16 +03:00
@@ -34,6 +34,18 @@
extern mutex_t srv_monitor_file_mutex;
/* Temporary file for innodb monitor output */
extern FILE* srv_monitor_file;
+/* Mutex for locking srv_dict_tmpfile.
+This mutex has a very high rank; threads reserving it should not
+be holding any InnoDB latches. */
+extern mutex_t srv_dict_tmpfile_mutex;
+/* Temporary file for output from the data dictionary */
+extern FILE* srv_dict_tmpfile;
+/* Mutex for locking srv_misc_tmpfile.
+This mutex has a very low rank; threads reserving it should not
+acquire any further latches or sleep before releasing this one. */
+extern mutex_t srv_misc_tmpfile_mutex;
+/* Temporary file for miscellanous diagnostic output */
+extern FILE* srv_misc_tmpfile;
/* Server parameters which are read from the initfile */
@@ -65,7 +77,7 @@
extern ulint srv_n_log_files;
extern ulint srv_log_file_size;
extern ulint srv_log_buffer_size;
-extern ulint srv_flush_log_at_trx_commit;
+extern ulong srv_flush_log_at_trx_commit;
extern byte srv_latin1_ordering[256];/* The sort order table of the latin1
character set */
@@ -183,7 +195,6 @@
#define kernel_mutex (*kernel_mutex_temp)
#define SRV_MAX_N_IO_THREADS 100
-#define SRV_CONCURRENCY_THRESHOLD 20
/* Array of English strings describing the current state of an
i/o handler thread */
--- 1.8/storage/innobase/include/sync0arr.h 2005-04-08 03:37:33 +04:00
+++ 1.9/storage/innobase/include/sync0arr.h 2006-03-03 22:34:16 +03:00
@@ -66,14 +66,14 @@
sync_array_t* arr, /* in: wait array */
ulint index); /* in: index of the reserved cell */
/**********************************************************************
-Frees the cell. NOTE! sync_array_wait_event frees the cell
-automatically! */
+Frees the cell safely by reserving the sync array mutex and decrementing
+n_reserved if necessary. Should only be called from mutex_spin_wait. */
void
-sync_array_free_cell(
-/*=================*/
+sync_array_free_cell_protected(
+/*===========================*/
sync_array_t* arr, /* in: wait array */
- ulint index); /* in: index of the cell in array */
+ ulint index); /* in: index of the cell in array */
/**************************************************************************
Looks for the cells in the wait array which refer
to the wait object specified,
--- 1.46/storage/innobase/include/univ.i 2006-02-12 22:33:14 +03:00
+++ 1.47/storage/innobase/include/univ.i 2006-03-03 22:34:16 +03:00
@@ -126,8 +126,14 @@
#ifdef __WIN__
#define UNIV_INLINE __inline
#else
+/* config.h contains the right def for 'inline' for the current compiler */
+#if (__GNUC__ == 2)
+#define UNIV_INLINE extern inline
+#else
+/* extern inline doesn't work with gcc 3.0.2 */
#define UNIV_INLINE static inline
#endif
+#endif
#else
/* If we want to compile a noninlined version we use the following macro
@@ -264,6 +270,9 @@
#define UNIV_LIKELY(cond) UNIV_EXPECT(cond, TRUE)
/* Tell the compiler that cond is unlikely to hold */
#define UNIV_UNLIKELY(cond) UNIV_EXPECT(cond, FALSE)
+
+/* Compile-time constant of the given array's size. */
+#define UT_ARR_SIZE(a) (sizeof(a) / sizeof((a)[0]))
#include <stdio.h>
#include "ut0dbg.h"
--- 1.65/storage/innobase/lock/lock0lock.c 2006-02-02 01:04:01 +03:00
+++ 1.66/storage/innobase/lock/lock0lock.c 2006-03-03 22:34:16 +03:00
@@ -3761,8 +3761,9 @@
rec_t* rec, /* in: record */
ulint lock_mode) /* in: LOCK_S or LOCK_X */
{
- lock_t* lock;
- ulint heap_no;
+ lock_t* lock;
+ lock_t* release_lock = NULL;
+ ulint heap_no;
ut_ad(trx && rec);
@@ -3772,21 +3773,23 @@
lock = lock_rec_get_first(rec);
- /* Remove the record lock */
+ /* Find the last lock with the same lock_mode and transaction
+ from the record. */
while (lock != NULL) {
if (lock->trx == trx && lock_get_mode(lock) == lock_mode) {
+ release_lock = lock;
ut_a(!lock_get_wait(lock));
-
- lock_rec_reset_nth_bit(lock, heap_no);
-
- break;
}
lock = lock_rec_get_next(rec, lock);
}
- if (UNIV_UNLIKELY(lock == NULL)) {
+ /* If a record lock is found, release the record lock */
+
+ if (UNIV_LIKELY(release_lock != NULL)) {
+ lock_rec_reset_nth_bit(release_lock, heap_no);
+ } else {
mutex_exit(&kernel_mutex);
ut_print_timestamp(stderr);
fprintf(stderr,
--- 1.113/storage/innobase/os/os0file.c 2006-02-02 01:04:02 +03:00
+++ 1.114/storage/innobase/os/os0file.c 2006-03-03 22:34:16 +03:00
@@ -160,15 +160,12 @@
ibool os_has_said_disk_full = FALSE;
-/* The mutex protecting the following counts of pending pread and pwrite
-operations */
+/* The mutex protecting the following counts of pending I/O operations */
static os_mutex_t os_file_count_mutex;
ulint os_file_n_pending_preads = 0;
ulint os_file_n_pending_pwrites = 0;
-
-/* These are not protected by any mutex */
-ulint os_n_pending_writes = 0;
-ulint os_n_pending_reads = 0;
+ulint os_n_pending_writes = 0;
+ulint os_n_pending_reads = 0;
/***************************************************************************
Gets the operating system version. Currently works only on Windows. */
@@ -314,6 +311,8 @@
return(OS_FILE_NOT_FOUND);
} else if (err == EEXIST) {
return(OS_FILE_ALREADY_EXISTS);
+ } else if (err == EXDEV || err == ENOTDIR || err == EISDIR) {
+ return(OS_FILE_PATH_ERROR);
} else {
return(100 + err);
}
@@ -363,7 +362,8 @@
return(TRUE);
- } else if (err == OS_FILE_ALREADY_EXISTS) {
+ } else if (err == OS_FILE_ALREADY_EXISTS
+ || err == OS_FILE_PATH_ERROR) {
return(FALSE);
} else {
@@ -467,7 +467,8 @@
return(TRUE);
- } else if (err == OS_FILE_ALREADY_EXISTS) {
+ } else if (err == OS_FILE_ALREADY_EXISTS
+ || err == OS_FILE_PATH_ERROR) {
return(FALSE);
} else {
@@ -1905,12 +1906,14 @@
#if defined(HAVE_PREAD) && !defined(HAVE_BROKEN_PREAD)
os_mutex_enter(os_file_count_mutex);
os_file_n_pending_preads++;
+ os_n_pending_reads++;
os_mutex_exit(os_file_count_mutex);
n_bytes = pread(file, buf, (ssize_t)n, offs);
os_mutex_enter(os_file_count_mutex);
os_file_n_pending_preads--;
+ os_n_pending_reads--;
os_mutex_exit(os_file_count_mutex);
return(n_bytes);
@@ -1920,6 +1923,10 @@
ssize_t ret;
ulint i;
+ os_mutex_enter(os_file_count_mutex);
+ os_n_pending_reads++;
+ os_mutex_exit(os_file_count_mutex);
+
/* Protect the seek / read operation with a mutex */
i = ((ulint) file) % OS_FILE_N_SEEK_MUTEXES;
@@ -1928,15 +1935,17 @@
ret_offset = lseek(file, offs, SEEK_SET);
if (ret_offset < 0) {
- os_mutex_exit(os_file_seek_mutexes[i]);
-
- return(-1);
+ ret = -1;
+ } else {
+ ret = read(file, buf, (ssize_t)n);
}
-
- ret = read(file, buf, (ssize_t)n);
os_mutex_exit(os_file_seek_mutexes[i]);
+ os_mutex_enter(os_file_count_mutex);
+ os_n_pending_reads--;
+ os_mutex_exit(os_file_count_mutex);
+
return(ret);
}
#endif
@@ -1981,12 +1990,14 @@
#if defined(HAVE_PWRITE) && !defined(HAVE_BROKEN_PREAD)
os_mutex_enter(os_file_count_mutex);
os_file_n_pending_pwrites++;
+ os_n_pending_writes++;
os_mutex_exit(os_file_count_mutex);
ret = pwrite(file, buf, (ssize_t)n, offs);
os_mutex_enter(os_file_count_mutex);
os_file_n_pending_pwrites--;
+ os_n_pending_writes--;
os_mutex_exit(os_file_count_mutex);
# ifdef UNIV_DO_FLUSH
@@ -2008,6 +2019,10 @@
off_t ret_offset;
ulint i;
+ os_mutex_enter(os_file_count_mutex);
+ os_n_pending_writes++;
+ os_mutex_exit(os_file_count_mutex);
+
/* Protect the seek / write operation with a mutex */
i = ((ulint) file) % OS_FILE_N_SEEK_MUTEXES;
@@ -2016,9 +2031,9 @@
ret_offset = lseek(file, offs, SEEK_SET);
if (ret_offset < 0) {
- os_mutex_exit(os_file_seek_mutexes[i]);
+ ret = -1;
- return(-1);
+ goto func_exit;
}
ret = write(file, buf, (ssize_t)n);
@@ -2036,8 +2051,13 @@
}
# endif /* UNIV_DO_FLUSH */
+func_exit:
os_mutex_exit(os_file_seek_mutexes[i]);
+ os_mutex_enter(os_file_count_mutex);
+ os_n_pending_writes--;
+ os_mutex_exit(os_file_count_mutex);
+
return(ret);
}
#endif
@@ -2082,9 +2102,13 @@
low = (DWORD) offset;
high = (DWORD) offset_high;
+ os_mutex_enter(os_file_count_mutex);
+ os_n_pending_reads++;
+ os_mutex_exit(os_file_count_mutex);
+
/* Protect the seek / read operation with a mutex */
i = ((ulint) file) % OS_FILE_N_SEEK_MUTEXES;
-
+
os_mutex_enter(os_file_seek_mutexes[i]);
ret2 = SetFilePointer(file, low, &high, FILE_BEGIN);
@@ -2093,17 +2117,21 @@
os_mutex_exit(os_file_seek_mutexes[i]);
+ os_mutex_enter(os_file_count_mutex);
+ os_n_pending_reads--;
+ os_mutex_exit(os_file_count_mutex);
+
goto error_handling;
}
- os_n_pending_reads++;
-
ret = ReadFile(file, buf, (DWORD) n, &len, NULL);
- os_n_pending_reads--;
-
os_mutex_exit(os_file_seek_mutexes[i]);
+ os_mutex_enter(os_file_count_mutex);
+ os_n_pending_reads--;
+ os_mutex_exit(os_file_count_mutex);
+
if (ret && len == n) {
return(TRUE);
}
@@ -2114,12 +2142,8 @@
os_bytes_read_since_printout += n;
try_again:
- os_n_pending_reads++;
-
ret = os_file_pread(file, buf, n, offset, offset_high);
- os_n_pending_reads--;
-
if ((ulint)ret == n) {
return(TRUE);
@@ -2193,6 +2217,10 @@
low = (DWORD) offset;
high = (DWORD) offset_high;
+ os_mutex_enter(os_file_count_mutex);
+ os_n_pending_reads++;
+ os_mutex_exit(os_file_count_mutex);
+
/* Protect the seek / read operation with a mutex */
i = ((ulint) file) % OS_FILE_N_SEEK_MUTEXES;
@@ -2204,17 +2232,21 @@
os_mutex_exit(os_file_seek_mutexes[i]);
+ os_mutex_enter(os_file_count_mutex);
+ os_n_pending_reads--;
+ os_mutex_exit(os_file_count_mutex);
+
goto error_handling;
}
- os_n_pending_reads++;
-
ret = ReadFile(file, buf, (DWORD) n, &len, NULL);
- os_n_pending_reads--;
-
os_mutex_exit(os_file_seek_mutexes[i]);
+ os_mutex_enter(os_file_count_mutex);
+ os_n_pending_reads--;
+ os_mutex_exit(os_file_count_mutex);
+
if (ret && len == n) {
return(TRUE);
}
@@ -2225,12 +2257,8 @@
os_bytes_read_since_printout += n;
try_again:
- os_n_pending_reads++;
-
ret = os_file_pread(file, buf, n, offset, offset_high);
- os_n_pending_reads--;
-
if ((ulint)ret == n) {
return(TRUE);
@@ -2310,6 +2338,10 @@
low = (DWORD) offset;
high = (DWORD) offset_high;
+ os_mutex_enter(os_file_count_mutex);
+ os_n_pending_writes++;
+ os_mutex_exit(os_file_count_mutex);
+
/* Protect the seek / write operation with a mutex */
i = ((ulint) file) % OS_FILE_N_SEEK_MUTEXES;
@@ -2321,6 +2353,10 @@
os_mutex_exit(os_file_seek_mutexes[i]);
+ os_mutex_enter(os_file_count_mutex);
+ os_n_pending_writes--;
+ os_mutex_exit(os_file_count_mutex);
+
ut_print_timestamp(stderr);
fprintf(stderr,
@@ -2335,12 +2371,8 @@
return(FALSE);
}
- os_n_pending_writes++;
-
ret = WriteFile(file, buf, (DWORD) n, &len, NULL);
- os_n_pending_writes--;
-
/* Always do fsync to reduce the probability that when the OS crashes,
a database page is only partially physically written to disk. */
@@ -2352,6 +2384,10 @@
os_mutex_exit(os_file_seek_mutexes[i]);
+ os_mutex_enter(os_file_count_mutex);
+ os_n_pending_writes--;
+ os_mutex_exit(os_file_count_mutex);
+
if (ret && len == n) {
return(TRUE);
@@ -2402,11 +2438,7 @@
#else
ssize_t ret;
- os_n_pending_writes++;
-
ret = os_file_pwrite(file, buf, n, offset, offset_high);
-
- os_n_pending_writes--;
if ((ulint)ret == n) {
--- 1.28/storage/innobase/os/os0sync.c 2006-02-08 13:58:50 +03:00
+++ 1.29/storage/innobase/os/os0sync.c 2006-03-03 22:34:16 +03:00
@@ -317,28 +317,28 @@
os_fast_mutex_lock(&(event->os_mutex));
old_signal_count = event->signal_count;
-loop:
- if (event->is_set == TRUE
- || event->signal_count != old_signal_count) {
- os_fast_mutex_unlock(&(event->os_mutex));
+ for (;;) {
+ if (event->is_set == TRUE
+ || event->signal_count != old_signal_count) {
- if (srv_shutdown_state == SRV_SHUTDOWN_EXIT_THREADS) {
+ os_fast_mutex_unlock(&(event->os_mutex));
- os_thread_exit(NULL);
- }
- /* Ok, we may return */
+ if (srv_shutdown_state == SRV_SHUTDOWN_EXIT_THREADS) {
- return;
- }
+ os_thread_exit(NULL);
+ }
+ /* Ok, we may return */
- pthread_cond_wait(&(event->cond_var), &(event->os_mutex));
+ return;
+ }
- /* Solaris manual said that spurious wakeups may occur: we have to
- check if the event really has been signaled after we came here to
- wait */
+ pthread_cond_wait(&(event->cond_var), &(event->os_mutex));
- goto loop;
+ /* Solaris manual said that spurious wakeups may occur: we
+ have to check if the event really has been signaled after
+ we came here to wait */
+ }
#endif
}
--- 1.32/storage/innobase/os/os0thread.c 2006-02-12 22:33:15 +03:00
+++ 1.33/storage/innobase/os/os0thread.c 2006-03-03 22:34:16 +03:00
@@ -157,15 +157,6 @@
exit(1);
}
#endif
-#ifdef __NETWARE__
- ret = pthread_attr_setstacksize(&attr,
- (size_t)NW_THD_STACKSIZE);
- if (ret) {
- fprintf(stderr,
- "InnoDB: Error: pthread_attr_setstacksize returned %d\n", ret);
- exit(1);
- }
-#endif
os_mutex_enter(os_sync_mutex);
os_thread_count++;
os_mutex_exit(os_sync_mutex);
--- 1.31/storage/innobase/rem/rem0cmp.c 2005-12-14 02:26:59 +03:00
+++ 1.32/storage/innobase/rem/rem0cmp.c 2006-03-03 22:34:16 +03:00
@@ -99,7 +99,8 @@
/* out: TRUE if the types are considered
equal in comparisons */
dtype_t* type1, /* in: type 1 */
- dtype_t* type2) /* in: type 2 */
+ dtype_t* type2, /* in: type 2 */
+ ibool check_charsets) /* in: whether to check charsets */
{
if (dtype_is_non_binary_string_type(type1->mtype, type1->prtype)
&& dtype_is_non_binary_string_type(type2->mtype, type2->prtype)) {
@@ -107,12 +108,12 @@
/* Both are non-binary string types: they can be compared if
and only if the charset-collation is the same */
- if (dtype_get_charset_coll(type1->prtype)
- == dtype_get_charset_coll(type2->prtype)) {
+ if (check_charsets) {
+ return(dtype_get_charset_coll(type1->prtype)
+ == dtype_get_charset_coll(type2->prtype));
+ } else {
return(TRUE);
}
-
- return(FALSE);
}
if (dtype_is_binary_string_type(type1->mtype, type1->prtype)
--- 1.76/storage/innobase/row/row0ins.c 2006-02-09 20:43:04 +03:00
+++ 1.77/storage/innobase/row/row0ins.c 2006-03-03 22:34:16 +03:00
@@ -549,6 +549,15 @@
default:
ut_error;
case 1:
+ if (UNIV_UNLIKELY(
+ dtype_get_charset_coll(
+ dtype_get_prtype(type))
+ == DATA_MYSQL_BINARY_CHARSET_COLL)) {
+ /* Do not pad BINARY
+ columns. */
+ return(ULINT_UNDEFINED);
+ }
+
/* space=0x20 */
memset(pad_start, 0x20,
pad_end - pad_start);
@@ -588,20 +597,21 @@
trx_t* trx, /* in: transaction */
dict_foreign_t* foreign) /* in: foreign key constraint */
{
-
- FILE* tf = os_file_create_tmpfile();
-
- if (tf) {
- ut_print_name(tf, trx, foreign->foreign_table_name);
- dict_print_info_on_foreign_key_in_create_format(tf, trx,
- foreign, FALSE);
+ mutex_enter(&srv_misc_tmpfile_mutex);
+ rewind(srv_misc_tmpfile);
- trx_set_detailed_error_from_file(trx, tf);
-
- fclose(tf);
+ if (os_file_set_eof(srv_misc_tmpfile)) {
+ ut_print_name(srv_misc_tmpfile, trx,
+ foreign->foreign_table_name);
+ dict_print_info_on_foreign_key_in_create_format(
+ srv_misc_tmpfile,
+ trx, foreign, FALSE);
+ trx_set_detailed_error_from_file(trx, srv_misc_tmpfile);
} else {
- trx_set_detailed_error(trx, "temp file creation failed");
+ trx_set_detailed_error(trx, "temp file operation failed");
}
+
+ mutex_exit(&srv_misc_tmpfile_mutex);
}
/*************************************************************************
@@ -709,7 +719,7 @@
}
if (rec) {
- rec_print(ef, rec, foreign->foreign_index);
+ rec_print(ef, rec, foreign->referenced_index);
}
putc('\n', ef);
@@ -1376,21 +1386,6 @@
thr, foreign, &pcur, entry,
&mtr);
if (err != DB_SUCCESS) {
- /* Since reporting a plain
- "duplicate key" error
- message to the user in
- cases where a long CASCADE
- operation would lead to a
- duplicate key in some
- other table is very
- confusing, map duplicate
- key errors resulting from
- FK constraints to a
- separate error code. */
-
- if (err == DB_DUPLICATE_KEY) {
- err = DB_FOREIGN_DUPLICATE_KEY;
- }
break;
}
--- 1.121/storage/innobase/row/row0mysql.c 2006-02-09 20:43:04 +03:00
+++ 1.122/storage/innobase/row/row0mysql.c 2006-03-03 22:34:16 +03:00
@@ -473,9 +473,8 @@
ut_a(err != DB_SUCCESS);
trx->error_state = DB_SUCCESS;
-
- if ((err == DB_DUPLICATE_KEY)
- || (err == DB_FOREIGN_DUPLICATE_KEY)) {
+
+ if (err == DB_DUPLICATE_KEY) {
if (savept) {
/* Roll back the latest, possibly incomplete
insertion or update */
@@ -2127,7 +2126,7 @@
if (err == DB_SUCCESS) {
/* Check that also referencing constraints are ok */
- err = dict_load_foreigns(name, trx->check_foreigns);
+ err = dict_load_foreigns(name, TRUE);
}
if (err != DB_SUCCESS) {
@@ -3586,7 +3585,8 @@
mem_heap_t* heap = NULL;
const char** constraints_to_drop = NULL;
ulint n_constraints_to_drop = 0;
- ibool recovering_temp_table = FALSE;
+ ibool recovering_temp_table = FALSE;
+ ibool old_is_tmp, new_is_tmp;
ulint len;
ulint i;
ibool success;
@@ -3626,6 +3626,9 @@
trx->op_info = "renaming table";
trx_start_if_not_started(trx);
+ old_is_tmp = row_is_mysql_tmp_table_name(old_name);
+ new_is_tmp = row_is_mysql_tmp_table_name(new_name);
+
if (row_mysql_is_recovered_tmp_table(new_name)) {
recovering_temp_table = TRUE;
@@ -3672,7 +3675,7 @@
len = (sizeof str1) + (sizeof str2) + (sizeof str3) + (sizeof str5) - 4
+ ut_strlenq(new_name, '\'') + ut_strlenq(old_name, '\'');
- if (row_is_mysql_tmp_table_name(new_name)) {
+ if (new_is_tmp) {
db_name_len = dict_get_db_name_len(old_name) + 1;
/* MySQL is doing an ALTER TABLE command and it renames the
@@ -3825,7 +3828,7 @@
the table is stored in a single-table tablespace */
success = dict_table_rename_in_cache(table, new_name,
- !row_is_mysql_tmp_table_name(new_name));
+ !new_is_tmp);
if (!success) {
trx->error_state = DB_SUCCESS;
trx_general_rollback_for_mysql(trx, FALSE, NULL);
@@ -3842,19 +3845,16 @@
goto funct_exit;
}
- err = dict_load_foreigns(new_name, trx->check_foreigns);
-
- if (row_is_mysql_tmp_table_name(old_name)) {
+ /* We only want to switch off some of the type checking in
+ an ALTER, not in a RENAME. */
+
+ err = dict_load_foreigns(new_name,
+ old_is_tmp ? trx->check_foreigns : TRUE);
- /* MySQL is doing an ALTER TABLE command and it
- renames the created temporary table to the name
- of the original table. In the ALTER TABLE we maybe
- created some FOREIGN KEY constraints for the temporary
- table. But we want to load also the foreign key
- constraint definitions for the original table name. */
+ if (err != DB_SUCCESS) {
+ ut_print_timestamp(stderr);
- if (err != DB_SUCCESS) {
- ut_print_timestamp(stderr);
+ if (old_is_tmp) {
fputs(" InnoDB: Error: in ALTER TABLE ",
stderr);
ut_print_name(stderr, trx, new_name);
@@ -3862,36 +3862,23 @@
"InnoDB: has or is referenced in foreign key constraints\n"
"InnoDB: which are not compatible with the new table definition.\n",
stderr);
-
- ut_a(dict_table_rename_in_cache(table,
- old_name, FALSE));
- trx->error_state = DB_SUCCESS;
- trx_general_rollback_for_mysql(trx, FALSE,
- NULL);
- trx->error_state = DB_SUCCESS;
- }
- } else {
- if (err != DB_SUCCESS) {
-
- ut_print_timestamp(stderr);
-
+ } else {
fputs(
" InnoDB: Error: in RENAME TABLE table ",
stderr);
ut_print_name(stderr, trx, new_name);
fputs("\n"
- "InnoDB: is referenced in foreign key constraints\n"
- "InnoDB: which are not compatible with the new table definition.\n",
+ "InnoDB: is referenced in foreign key constraints\n"
+ "InnoDB: which are not compatible with the new table definition.\n",
stderr);
-
- ut_a(dict_table_rename_in_cache(table,
- old_name, FALSE));
-
- trx->error_state = DB_SUCCESS;
- trx_general_rollback_for_mysql(trx, FALSE,
- NULL);
- trx->error_state = DB_SUCCESS;
}
+
+ ut_a(dict_table_rename_in_cache(table,
+ old_name, FALSE));
+ trx->error_state = DB_SUCCESS;
+ trx_general_rollback_for_mysql(trx, FALSE,
+ NULL);
+ trx->error_state = DB_SUCCESS;
}
}
funct_exit:
--- 1.100/storage/innobase/row/row0sel.c 2006-02-02 01:04:02 +03:00
+++ 1.101/storage/innobase/row/row0sel.c 2006-03-03 22:34:16 +03:00
@@ -4085,9 +4085,9 @@
/* We have an optimization to save CPU time: if this is a consistent
read on a unique condition on the clustered index, then we do not
store the pcur position, because any fetch next or prev will anyway
- return 'end of file'. An exception is the MySQL HANDLER command
- where the user can move the cursor with PREV or NEXT even after
- a unique search. */
+ return 'end of file'. Exceptions are locking reads and the MySQL
+ HANDLER command where the user can move the cursor with PREV or NEXT
+ even after a unique search. */
if (!unique_search_from_clust_index
|| prebuilt->select_lock_type != LOCK_NONE
@@ -4176,6 +4176,7 @@
did_semi_consistent_read = FALSE;
/*-------------------------------------------------------------*/
+
btr_pcur_store_position(pcur, &mtr);
mtr_commit(&mtr);
--- 1.96/storage/innobase/srv/srv0srv.c 2006-02-02 17:20:29 +03:00
+++ 1.97/storage/innobase/srv/srv0srv.c 2006-03-03 22:34:16 +03:00
@@ -113,7 +113,7 @@
ulint srv_n_log_files = ULINT_MAX;
ulint srv_log_file_size = ULINT_MAX; /* size in database pages */
ulint srv_log_buffer_size = ULINT_MAX; /* size in database pages */
-ulint srv_flush_log_at_trx_commit = 1;
+ulong srv_flush_log_at_trx_commit = 1;
byte srv_latin1_ordering[256] /* The sort order table of the latin1
character set. The following table is
@@ -258,9 +258,10 @@
we could get a deadlock. MySQL creates a thread for each user session, and
semaphore contention and convoy problems can occur withput this restriction.
Value 10 should be good if there are less than 4 processors + 4 disks in the
-computer. Bigger computers need bigger values. */
+computer. Bigger computers need bigger values. Value 0 will disable the
+concurrency check. */
-ulong srv_thread_concurrency = SRV_CONCURRENCY_THRESHOLD;
+ulong srv_thread_concurrency = 0;
ulong srv_commit_concurrency = 0;
os_fast_mutex_t srv_conc_mutex; /* this mutex protects srv_conc data
@@ -397,6 +398,18 @@
mutex_t srv_monitor_file_mutex;
/* Temporary file for innodb monitor output */
FILE* srv_monitor_file;
+/* Mutex for locking srv_dict_tmpfile.
+This mutex has a very high rank; threads reserving it should not
+be holding any InnoDB latches. */
+mutex_t srv_dict_tmpfile_mutex;
+/* Temporary file for output from the data dictionary */
+FILE* srv_dict_tmpfile;
+/* Mutex for locking srv_misc_tmpfile.
+This mutex has a very low rank; threads reserving it should not
+acquire any further latches or sleep before releasing this one. */
+mutex_t srv_misc_tmpfile_mutex;
+/* Temporary file for miscellanous diagnostic output */
+FILE* srv_misc_tmpfile;
ulint srv_main_thread_process_no = 0;
ulint srv_main_thread_id = 0;
@@ -1129,7 +1142,7 @@
trx_t* trx) /* in: transaction object associated with the
thread */
{
- if (srv_thread_concurrency >= SRV_CONCURRENCY_THRESHOLD) {
+ if (UNIV_LIKELY(!srv_thread_concurrency)) {
return;
}
@@ -1155,7 +1168,7 @@
{
srv_conc_slot_t* slot = NULL;
- if (srv_thread_concurrency >= SRV_CONCURRENCY_THRESHOLD) {
+ if (UNIV_LIKELY(!srv_thread_concurrency)) {
return;
}
--- 1.90/storage/innobase/srv/srv0start.c 2006-02-08 13:58:50 +03:00
+++ 1.91/storage/innobase/srv/srv0start.c 2006-03-03 22:34:16 +03:00
@@ -233,6 +233,13 @@
}
}
+ if (i == 0) {
+ /* If innodb_data_file_path was defined it must contain
+ at least one data file definition */
+
+ return(FALSE);
+ }
+
*data_file_names = (char**)ut_malloc(i * sizeof(void*));
*data_file_sizes = (ulint*)ut_malloc(i * sizeof(ulint));
*data_file_is_raw_partition = (ulint*)ut_malloc(i * sizeof(ulint));
@@ -379,6 +386,13 @@
}
}
+ if (i != 1) {
+ /* If innodb_log_group_home_dir was defined it must
+ contain exactly one path definition under current MySQL */
+
+ return(FALSE);
+ }
+
*log_group_home_dirs = (char**) ut_malloc(i * sizeof(void*));
/* Then store the actual values to our array */
@@ -1180,6 +1194,20 @@
}
}
+ mutex_create(&srv_dict_tmpfile_mutex);
+ mutex_set_level(&srv_dict_tmpfile_mutex, SYNC_DICT_OPERATION);
+ srv_dict_tmpfile = os_file_create_tmpfile();
+ if (!srv_dict_tmpfile) {
+ return(DB_ERROR);
+ }
+
+ mutex_create(&srv_misc_tmpfile_mutex);
+ mutex_set_level(&srv_misc_tmpfile_mutex, SYNC_ANY_LATCH);
+ srv_misc_tmpfile = os_file_create_tmpfile();
+ if (!srv_misc_tmpfile) {
+ return(DB_ERROR);
+ }
+
/* Restrict the maximum number of file i/o threads */
if (srv_n_file_io_threads > SRV_MAX_N_IO_THREADS) {
@@ -1822,8 +1850,19 @@
mem_free(srv_monitor_file_name);
}
}
-
+ if (srv_dict_tmpfile) {
+ fclose(srv_dict_tmpfile);
+ srv_dict_tmpfile = 0;
+ }
+
+ if (srv_misc_tmpfile) {
+ fclose(srv_misc_tmpfile);
+ srv_misc_tmpfile = 0;
+ }
+
mutex_free(&srv_monitor_file_mutex);
+ mutex_free(&srv_dict_tmpfile_mutex);
+ mutex_free(&srv_misc_tmpfile_mutex);
/* 3. Free all InnoDB's own mutexes and the os_fast_mutexes inside
them */
--- 1.21/storage/innobase/sync/sync0arr.c 2005-04-08 03:37:36 +04:00
+++ 1.22/storage/innobase/sync/sync0arr.c 2006-03-03 22:34:17 +03:00
@@ -46,9 +46,18 @@
until a resource is released. The suspending is implemented
using an operating system event semaphore. */
struct sync_cell_struct {
+ /* State of the cell. SC_WAKING_UP means
+ sync_array_struct->n_reserved has been decremented, but the thread
+ in this cell has not waken up yet. When it does, it will set the
+ state to SC_FREE. Note that this is done without the protection of
+ any mutex. */
+ enum { SC_FREE, SC_RESERVED, SC_WAKING_UP } state;
+
void* wait_object; /* pointer to the object the
- thread is waiting for; if NULL
- the cell is free for use */
+ thread is waiting for; this is not
+ reseted to NULL when a cell is
+ freed. */
+
mutex_t* old_wait_mutex; /* the latest wait mutex in cell */
rw_lock_t* old_wait_rw_lock;/* the latest wait rw-lock in cell */
ulint request_type; /* lock type requested on the
@@ -69,11 +78,6 @@
the wait cell */
};
-/* NOTE: It is allowed for a thread to wait
-for an event allocated for the array without owning the
-protecting mutex (depending on the case: OS or database mutex), but
-all changes (set or reset) to the state of the event must be made
-while owning the mutex. */
struct sync_array_struct {
ulint n_reserved; /* number of currently reserved
cells in the wait array */
@@ -217,7 +221,8 @@
for (i = 0; i < n_cells; i++) {
cell = sync_array_get_nth_cell(arr, i);
- cell->wait_object = NULL;
+ cell->state = SC_FREE;
+ cell->wait_object = NULL;
/* Create an operating system event semaphore with no name */
cell->event = os_event_create(NULL);
@@ -282,7 +287,7 @@
for (i = 0; i < arr->n_cells; i++) {
cell = sync_array_get_nth_cell(arr, i);
- if (cell->wait_object != NULL) {
+ if (cell->state == SC_RESERVED) {
count++;
}
}
@@ -292,30 +297,6 @@
sync_array_exit(arr);
}
-/***********************************************************************
-Puts the cell event in set state. */
-static
-void
-sync_cell_event_set(
-/*================*/
- sync_cell_t* cell) /* in: array cell */
-{
- os_event_set(cell->event);
- cell->event_set = TRUE;
-}
-
-/***********************************************************************
-Puts the cell event in reset state. */
-static
-void
-sync_cell_event_reset(
-/*==================*/
- sync_cell_t* cell) /* in: array cell */
-{
- os_event_reset(cell->event);
- cell->event_set = FALSE;
-}
-
/**********************************************************************
Reserves a wait array cell for waiting for an object.
The event of the cell is reset to nonsignalled state. */
@@ -344,13 +325,18 @@
for (i = 0; i < arr->n_cells; i++) {
cell = sync_array_get_nth_cell(arr, i);
- if (cell->wait_object == NULL) {
+ if (cell->state == SC_FREE) {
- /* Make sure the event is reset */
- if (cell->event_set) {
- sync_cell_event_reset(cell);
- }
+ /* We do not check cell->event_set because it is
+ set outside the protection of the sync array mutex
+ and we had a bug regarding it, and since resetting
+ an event when it is not needed does no harm it is
+ safer always to do it. */
+
+ cell->event_set = FALSE;
+ os_event_reset(cell->event);
+ cell->state = SC_RESERVED;
cell->reservation_time = time(NULL);
cell->thread = os_thread_get_curr_id();
@@ -384,6 +370,68 @@
}
/**********************************************************************
+Frees the cell. Note that we don't have any mutex reserved when calling
+this. */
+static
+void
+sync_array_free_cell(
+/*=================*/
+ sync_array_t* arr, /* in: wait array */
+ ulint index) /* in: index of the cell in array */
+{
+ sync_cell_t* cell;
+
+ cell = sync_array_get_nth_cell(arr, index);
+
+ ut_a(cell->state == SC_WAKING_UP);
+ ut_a(cell->wait_object != NULL);
+
+ cell->state = SC_FREE;
+}
+
+/**********************************************************************
+Frees the cell safely by reserving the sync array mutex and decrementing
+n_reserved if necessary. Should only be called from mutex_spin_wait. */
+
+void
+sync_array_free_cell_protected(
+/*===========================*/
+ sync_array_t* arr, /* in: wait array */
+ ulint index) /* in: index of the cell in array */
+{
+ sync_cell_t* cell;
+
+ sync_array_enter(arr);
+
+ cell = sync_array_get_nth_cell(arr, index);
+
+ ut_a(cell->state != SC_FREE);
+ ut_a(cell->wait_object != NULL);
+
+ /* We only need to decrement n_reserved if it has not already been
+ done by sync_array_signal_object. */
+ if (cell->state == SC_RESERVED) {
+ ut_a(arr->n_reserved > 0);
+ arr->n_reserved--;
+ } else if (cell->state == SC_WAKING_UP) {
+ /* This is tricky; if we don't wait for the event to be
+ signaled, signal_object can set the state of a cell to
+ SC_WAKING_UP, mutex_spin_wait can call this and set the
+ state to SC_FREE, and then signal_object gets around to
+ calling os_set_event for the cell but since it's already
+ been freed things break horribly. */
+
+ sync_array_exit(arr);
+ os_event_wait(cell->event);
+ sync_array_enter(arr);
+ }
+
+ cell->state = SC_FREE;
+
+ sync_array_exit(arr);
+}
+
+/**********************************************************************
This function should be called when a thread starts to wait on
a wait array cell. In the debug version this function checks
if the wait for a semaphore will result in a deadlock, in which
@@ -400,10 +448,9 @@
ut_a(arr);
- sync_array_enter(arr);
-
cell = sync_array_get_nth_cell(arr, index);
+ ut_a((cell->state == SC_RESERVED) || (cell->state == SC_WAKING_UP));
ut_a(cell->wait_object);
ut_a(!cell->waiting);
ut_ad(os_thread_get_curr_id() == cell->thread);
@@ -418,6 +465,7 @@
recursively sync_array routines, leading to trouble.
rw_lock_debug_mutex freezes the debug lists. */
+ sync_array_enter(arr);
rw_lock_debug_mutex_enter();
if (TRUE == sync_array_detect_deadlock(arr, cell, cell, 0)) {
@@ -427,16 +475,16 @@
}
rw_lock_debug_mutex_exit();
+ sync_array_exit(arr);
#endif
- sync_array_exit(arr);
-
os_event_wait(event);
sync_array_free_cell(arr, index);
}
/**********************************************************************
-Reports info of a wait array cell. */
+Reports info of a wait array cell. Note: sync_array_print_long_waits()
+calls this without mutex protection. */
static
void
sync_array_cell_print(
@@ -455,8 +503,17 @@
(ulong) os_thread_pf(cell->thread), cell->file,
(ulong) cell->line,
difftime(time(NULL), cell->reservation_time));
+ fprintf(file, "Wait array cell state %lu\n", (ulong)cell->state);
+
+ /* If the memory area pointed to by old_wait_mutex /
+ old_wait_rw_lock has been freed, this can crash. */
+
+ if (cell->state != SC_RESERVED) {
+ /* If cell has this state, then even if we are holding the sync
+ array mutex, the wait object may get freed meanwhile. Do not
+ print the wait object then. */
- if (type == SYNC_MUTEX) {
+ } else if (type == SYNC_MUTEX) {
/* We use old_wait_mutex in case the cell has already
been freed meanwhile */
mutex = cell->old_wait_mutex;
@@ -507,10 +564,6 @@
ut_error;
}
- if (!cell->waiting) {
- fputs("wait has ended\n", file);
- }
-
if (cell->event_set) {
fputs("wait is ending\n", file);
}
@@ -535,7 +588,7 @@
cell = sync_array_get_nth_cell(arr, i);
- if (cell->wait_object != NULL
+ if ((cell->state == SC_RESERVED)
&& os_thread_eq(cell->thread, thread)) {
return(cell); /* Found */
@@ -617,6 +670,7 @@
rw_lock_debug_t*debug;
ut_a(arr && start && cell);
+ ut_ad(cell->state == SC_RESERVED);
ut_ad(cell->wait_object);
ut_ad(os_thread_get_curr_id() == start->thread);
ut_ad(depth < 100);
@@ -649,7 +703,8 @@
if (ret) {
fprintf(stderr,
"Mutex %p owned by thread %lu file %s line %lu\n",
- mutex, (ulong) os_thread_pf(mutex->thread_id),
+ mutex,
+ (ulong) os_thread_pf(mutex->thread_id),
mutex->file_name, (ulong) mutex->line);
sync_array_cell_print(stderr, cell);
@@ -784,32 +839,6 @@
return(FALSE);
}
-/**********************************************************************
-Frees the cell. NOTE! sync_array_wait_event frees the cell
-automatically! */
-
-void
-sync_array_free_cell(
-/*=================*/
- sync_array_t* arr, /* in: wait array */
- ulint index) /* in: index of the cell in array */
-{
- sync_cell_t* cell;
-
- sync_array_enter(arr);
-
- cell = sync_array_get_nth_cell(arr, index);
-
- ut_a(cell->wait_object != NULL);
-
- cell->wait_object = NULL;
-
- ut_a(arr->n_reserved > 0);
- arr->n_reserved--;
-
- sync_array_exit(arr);
-}
-
/**************************************************************************
Looks for the cells in the wait array which refer to the wait object
specified, and sets their corresponding events to the signaled state. In this
@@ -825,6 +854,21 @@
sync_cell_t* cell;
ulint count;
ulint i;
+ ulint res_count;
+
+ /* We store the addresses of cells we need to signal and signal
+ them only after we have released the sync array's mutex (for
+ performance reasons). cell_count is the number of such cells, and
+ cell_ptr points to the first one. If there are less than
+ UT_ARR_SIZE(cells) of them, cell_ptr == &cells[0], otherwise
+ cell_ptr points to malloc'd memory that we must free. */
+
+ sync_cell_t* cells[100];
+ sync_cell_t** cell_ptr = &cells[0];
+ ulint cell_count = 0;
+ ulint cell_max_count = UT_ARR_SIZE(cells);
+
+ ut_a(100 == cell_max_count);
sync_array_enter(arr);
@@ -833,16 +877,44 @@
i = 0;
count = 0;
- while (count < arr->n_reserved) {
+ /* We need to store this to a local variable because it is modified
+ inside the loop */
+ res_count = arr->n_reserved;
+
+ while (count < res_count) {
cell = sync_array_get_nth_cell(arr, i);
- if (cell->wait_object != NULL) {
+ if (cell->state == SC_RESERVED) {
count++;
if (cell->wait_object == object) {
+ cell->state = SC_WAKING_UP;
- sync_cell_event_set(cell);
+ ut_a(arr->n_reserved > 0);
+ arr->n_reserved--;
+
+ if (cell_count == cell_max_count) {
+ sync_cell_t** old_cell_ptr = cell_ptr;
+ size_t old_size = cell_max_count *
+ sizeof(sync_cell_t*);
+ cell_max_count *= 2;
+
+ size_t new_size = cell_max_count *
+ sizeof(sync_cell_t*);
+
+ cell_ptr = malloc(new_size);
+ ut_a(cell_ptr);
+ memcpy(cell_ptr, old_cell_ptr,
+ old_size);
+
+ if (old_cell_ptr != &cells[0]) {
+ free(old_cell_ptr);
+ }
+ }
+
+ cell_ptr[cell_count] = cell;
+ cell_count++;
}
}
@@ -850,12 +922,27 @@
}
sync_array_exit(arr);
+
+ for (i = 0; i < cell_count; i++) {
+ cell = cell_ptr[i];
+
+ cell->event_set = TRUE;
+ os_event_set(cell->event);
+ }
+
+ if (cell_ptr != &cells[0]) {
+ free(cell_ptr);
+ }
}
/**************************************************************************
If the wakeup algorithm does not work perfectly at semaphore relases,
this function will do the waking (see the comment in mutex_exit). This
-function should be called about every 1 second in the server. */
+function should be called about every 1 second in the server.
+
+Note that there's a race condition between this thread and mutex_exit
+changing the lock_word and calling signal_object, so sometimes this finds
+threads to wake up even when nothing has gone wrong. */
void
sync_arr_wake_threads_if_sema_free(void)
@@ -865,23 +952,33 @@
sync_cell_t* cell;
ulint count;
ulint i;
-
+ ulint res_count;
+
sync_array_enter(arr);
i = 0;
count = 0;
- while (count < arr->n_reserved) {
+ /* We need to store this to a local variable because it is modified
+ inside the loop */
+
+ res_count = arr->n_reserved;
+
+ while (count < res_count) {
cell = sync_array_get_nth_cell(arr, i);
- if (cell->wait_object != NULL) {
+ if (cell->state == SC_RESERVED) {
count++;
if (sync_arr_cell_can_wake_up(cell)) {
+ cell->state = SC_WAKING_UP;
+ cell->event_set = TRUE;
+ os_event_set(cell->event);
- sync_cell_event_set(cell);
+ ut_a(arr->n_reserved > 0);
+ arr->n_reserved--;
}
}
@@ -911,7 +1008,7 @@
cell = sync_array_get_nth_cell(sync_primary_wait_array, i);
- if (cell->wait_object != NULL
+ if ((cell->state != SC_FREE)
&& difftime(time(NULL), cell->reservation_time) > 240) {
fputs("InnoDB: Warning: a long semaphore wait:\n",
stderr);
@@ -919,7 +1016,7 @@
noticed = TRUE;
}
- if (cell->wait_object != NULL
+ if ((cell->state != SC_FREE)
&& difftime(time(NULL), cell->reservation_time)
> fatal_timeout) {
fatal = TRUE;
@@ -965,25 +1062,19 @@
mutex */
{
sync_cell_t* cell;
- ulint count;
ulint i;
fprintf(file,
- "OS WAIT ARRAY INFO: reservation count %ld, signal count %ld\n",
- (long) arr->res_count, (long) arr->sg_count);
- i = 0;
- count = 0;
-
- while (count < arr->n_reserved) {
+ "OS WAIT ARRAY INFO: reservation count %ld, signal count %ld\n",
+ (long) arr->res_count,
+ (long) arr->sg_count);
+ for (i = 0; i < arr->n_cells; i++) {
cell = sync_array_get_nth_cell(arr, i);
- if (cell->wait_object != NULL) {
- count++;
+ if (cell->state != SC_FREE) {
sync_array_cell_print(file, cell);
}
-
- i++;
}
}
--- 1.37/storage/innobase/sync/sync0sync.c 2005-07-22 04:56:23 +04:00
+++ 1.38/storage/innobase/sync/sync0sync.c 2006-03-03 22:34:17 +03:00
@@ -482,7 +482,7 @@
{
/* Succeeded! Free the reserved wait cell */
- sync_array_free_cell(sync_primary_wait_array, index);
+ sync_array_free_cell_protected(sync_primary_wait_array, index);
#ifdef UNIV_SYNC_DEBUG
mutex_set_debug_info(mutex, file_name, line);
--- 1.62/storage/innobase/trx/trx0trx.c 2006-02-02 01:04:02 +03:00
+++ 1.63/storage/innobase/trx/trx0trx.c 2006-03-03 22:34:17 +03:00
@@ -794,7 +794,8 @@
in trx sys header if MySQL binlogging is on or the database
server is a MySQL replication slave */
- if (trx->mysql_log_file_name) {
+ if (trx->mysql_log_file_name
+ && trx->mysql_log_file_name[0] != '\0') {
trx_sys_update_mysql_binlog_offset(
trx->mysql_log_file_name,
trx->mysql_log_offset,
--- 1.163/mysql-test/r/innodb.result 2006-02-25 21:35:06 +03:00
+++ 1.164/mysql-test/r/innodb.result 2006-03-03 22:34:14 +03:00
@@ -234,7 +234,7 @@
commit;
insert into t1 values (5);
insert into t1 values (4);
-ERROR 23000: Duplicate entry '4' for key 'PRIMARY'
+ERROR 23000: Duplicate entry '4' for key 1
commit;
select n, "after commit" from t1;
n after commit
@@ -243,7 +243,7 @@
set autocommit=1;
insert into t1 values (6);
insert into t1 values (4);
-ERROR 23000: Duplicate entry '4' for key 'PRIMARY'
+ERROR 23000: Duplicate entry '4' for key 1
select n from t1;
n
4
@@ -318,7 +318,7 @@
CREATE TABLE t1 (id char(8) not null primary key, val int not null) engine=innodb;
insert into t1 values ('pippo', 12);
insert into t1 values ('pippo', 12);
-ERROR 23000: Duplicate entry 'pippo' for key 'PRIMARY'
+ERROR 23000: Duplicate entry 'pippo' for key 1
delete from t1;
delete from t1 where id = 'pippo';
select * from t1;
@@ -482,9 +482,9 @@
insert into t1 (ggid,passwd) values ('test1','xxx');
insert into t1 (ggid,passwd) values ('test2','yyy');
insert into t1 (ggid,passwd) values ('test2','this will fail');
-ERROR 23000: Duplicate entry 'test2' for key 'ggid'
+ERROR 23000: Duplicate entry 'test2' for key 2
insert into t1 (ggid,id) values ('this will fail',1);
-ERROR 23000: Duplicate entry '1' for key 'PRIMARY'
+ERROR 23000: Duplicate entry '1' for key 1
select * from t1 where ggid='test1';
id ggid email passwd
1 test1 xxx
@@ -497,7 +497,7 @@
replace into t1 (ggid,id) values ('this will work',1);
replace into t1 (ggid,passwd) values ('test2','this will work');
update t1 set id=100,ggid='test2' where id=1;
-ERROR 23000: Duplicate entry 'test2' for key 'ggid'
+ERROR 23000: Duplicate entry 'test2' for key 2
select * from t1;
id ggid email passwd
1 this will work
@@ -816,7 +816,7 @@
insert into t1 values (0,0,0,'ABCDEFGHIJ'),(2,2,2,'BCDEFGHIJK'),(1,1,1,'CDEFGHIJKL');
LOCK TABLES t1 WRITE;
insert into t1 values (99,1,2,'D'),(1,1,2,'D');
-ERROR 23000: Duplicate entry '1-1' for key 'PRIMARY'
+ERROR 23000: Duplicate entry '1-1' for key 1
select id from t1;
id
0
@@ -834,7 +834,7 @@
LOCK TABLES t1 WRITE;
begin;
insert into t1 values (99,1,2,'D'),(1,1,2,'D');
-ERROR 23000: Duplicate entry '1-1' for key 'PRIMARY'
+ERROR 23000: Duplicate entry '1-1' for key 1
select id from t1;
id
0
@@ -1457,16 +1457,16 @@
checksum table t1, t2, t3, t4;
Table Checksum
test.t1 2948697075
-test.t2 2948697075
-test.t3 2948697075
+test.t2 3835700799
+test.t3 3835700799
test.t4 NULL
Warnings:
Error 1146 Table 'test.t4' doesn't exist
checksum table t1, t2, t3, t4 extended;
Table Checksum
-test.t1 2948697075
-test.t2 2948697075
-test.t3 2948697075
+test.t1 3092701434
+test.t2 3835700799
+test.t3 3835700799
test.t4 NULL
Warnings:
Error 1146 Table 'test.t4' doesn't exist
@@ -1589,7 +1589,7 @@
t2 CREATE TABLE `t2` (
`id` int(11) NOT NULL auto_increment,
`id2` int(11) NOT NULL,
- PRIMARY KEY (`id`),
+ PRIMARY KEY (`id`),
KEY `id` (`id`,`id2`),
CONSTRAINT `t1_id_fk` FOREIGN KEY (`id`) REFERENCES `t1` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1
@@ -1622,7 +1622,7 @@
t2 CREATE TABLE `t2` (
`a` int(11) NOT NULL auto_increment,
`b` int(11) default NULL,
- PRIMARY KEY (`a`),
+ PRIMARY KEY (`a`),
UNIQUE KEY `b_2` (`b`),
KEY `b` (`b`),
CONSTRAINT `t2_ibfk_1` FOREIGN KEY (`b`) REFERENCES `t1` (`id`)
@@ -1634,7 +1634,7 @@
t2 CREATE TABLE `t2` (
`a` int(11) NOT NULL auto_increment,
`b` int(11) default NULL,
- PRIMARY KEY (`a`),
+ PRIMARY KEY (`a`),
UNIQUE KEY `b` (`b`),
CONSTRAINT `t2_ibfk_1` FOREIGN KEY (`b`) REFERENCES `t1` (`id`),
CONSTRAINT `t2_ibfk_2` FOREIGN KEY (`b`) REFERENCES `t1` (`id`)
@@ -1783,15 +1783,15 @@
innodb_sync_spin_loops 20
show variables like "innodb_thread_concurrency";
Variable_name Value
-innodb_thread_concurrency 20
-set global innodb_thread_concurrency=1000;
+innodb_thread_concurrency 0
+set global innodb_thread_concurrency=1001;
show variables like "innodb_thread_concurrency";
Variable_name Value
innodb_thread_concurrency 1000
set global innodb_thread_concurrency=0;
show variables like "innodb_thread_concurrency";
Variable_name Value
-innodb_thread_concurrency 1
+innodb_thread_concurrency 0
set global innodb_thread_concurrency=16;
show variables like "innodb_thread_concurrency";
Variable_name Value
@@ -1964,7 +1964,7 @@
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 ref v v 13 const # Using where; Using index
alter table t1 add unique(v);
-ERROR 23000: Duplicate entry '{ ' for key 'v_2'
+ERROR 23000: Duplicate entry '{ ' for key 1
alter table t1 add key(v);
select concat('*',v,'*',c,'*',t,'*') as qq from t1 where v='a';
qq
@@ -2324,16 +2324,16 @@
create table t1 (a char(10), unique (a));
insert into t1 values ('a ');
insert into t1 values ('a ');
-ERROR 23000: Duplicate entry 'a' for key 'a'
+ERROR 23000: Duplicate entry 'a' for key 1
alter table t1 modify a varchar(10);
insert into t1 values ('a '),('a '),('a '),('a ');
-ERROR 23000: Duplicate entry 'a ' for key 'a'
+ERROR 23000: Duplicate entry 'a ' for key 1
insert into t1 values ('a ');
-ERROR 23000: Duplicate entry 'a ' for key 'a'
+ERROR 23000: Duplicate entry 'a ' for key 1
insert into t1 values ('a ');
-ERROR 23000: Duplicate entry 'a ' for key 'a'
+ERROR 23000: Duplicate entry 'a ' for key 1
insert into t1 values ('a ');
-ERROR 23000: Duplicate entry 'a ' for key 'a'
+ERROR 23000: Duplicate entry 'a ' for key 1
update t1 set a='a ' where a like 'a%';
select concat(a,'.') from t1;
concat(a,'.')
@@ -2456,7 +2456,7 @@
replace into t1 (val) values ('1'),('2');
replace into t1 (val) values ('1'),('2');
insert into t1 (val) values ('1'),('2');
-ERROR 23000: Duplicate entry '1' for key 'val'
+ERROR 23000: Duplicate entry '1' for key 2
select * from t1;
rowid val
3 1
@@ -2466,7 +2466,7 @@
insert into t1 (val) values (1);
update t1 set a=2 where a=1;
insert into t1 (val) values (1);
-ERROR 23000: Duplicate entry '2' for key 'PRIMARY'
+ERROR 23000: Duplicate entry '2' for key 1
select * from t1;
a val
2 1
@@ -2635,6 +2635,25 @@
Table Checksum
test.t1 2050879373
drop table t1;
+create table t1 (col1 integer primary key, col2 integer) engine=innodb;
+insert t1 values (1,100);
+create function f1 () returns integer begin
+declare var1 int;
+select col2 into var1 from t1 where col1=1 for update;
+return var1;
+end|
+start transaction;
+select f1();
+f1()
+100
+ update t1 set col2=0 where col1=1;
+select * from t1;
+col1 col2
+1 100
+rollback;
+rollback;
+drop table t1;
+drop function f1;
create table t1 (
a int, b char(10), c char(10), filler char(10), primary key(a, b(2)), unique key (a, c(2))
) character set utf8 engine = innodb;
@@ -2661,6 +2680,32 @@
insert into t2 values (4,_ucs2 0x05630563,_ucs2 0x05630563,'eleven');
insert into t2 values (4,_ucs2 0x0563001fc0563,_ucs2 0x0563001fc0563,'point');
insert into t2 values (4,_ucs2 0x05612020,_ucs2 0x05612020,'taken');
+update t1 set filler = 'boo' where a = 1;
+update t2 set filler ='email' where a = 4;
+select a,hex(b),hex(c),filler from t1 order by filler;
+a hex(b) hex(c) filler
+1 61626364656667 61626364656667 boo
+4 D0B1 D0B1 eight
+4 5B 5B five
+4 E880BD E880BD four
+4 E880BDD0B1E880BD E880BDD0B1E880BD seven
+4 E880BDE880BD E880BDE880BD six
+3 71727374757677 71727374757677 three
+2 696A6B696C6D6E 696A6B696C6D6E two
+select a,hex(b),hex(c),filler from t2 order by filler;
+a hex(b) hex(c) filler
+4 05630563 05630563 email
+4 0563 0563 email
+4 05612020 05612020 email
+4 01FC 01FC email
+4 0120 0120 email
+4 00640065 00640065 email
+4 00E400E50068 00E400E50068 email
+4 0000E400 0000E400 email
+4 0000563001FC0563 0000563001FC0563 email
+1 0061006200630064006500660067 0061006200630064006500660067 one
+3 0071007200730074007500760077 0071007200730074007500760077 three
+2 0069006A006B0069006C006D006E 0069006A006B0069006C006D006E two
drop table t1;
drop table t2;
create table t1 (
@@ -2689,6 +2734,32 @@
insert into t2 values (4,_ucs2 0x05630563,_ucs2 0x05630563,'eleven');
insert into t2 values (4,_ucs2 0x0563001fc0563,_ucs2 0x0563001fc0563,'point');
insert into t2 values (4,_ucs2 0x05612020,_ucs2 0x05612020,'taken');
+update t1 set filler = 'boo' where a = 1;
+update t2 set filler ='email' where a = 4;
+select a,hex(b),hex(c),filler from t1 order by filler;
+a hex(b) hex(c) filler
+1 61626364656667 61626364656667 boo
+4 D0B1 D0B1 eight
+4 5B 5B five
+4 E880BD E880BD four
+4 E880BDD0B1E880BD E880BDD0B1E880BD seven
+4 E880BDE880BD E880BDE880BD six
+3 71727374757677 71727374757677 three
+2 696A6B696C6D6E 696A6B696C6D6E two
+select a,hex(b),hex(c),filler from t2 order by filler;
+a hex(b) hex(c) filler
+4 05630563 05630563 email
+4 0563 0563 email
+4 05612020 05612020 email
+4 01FC 01FC email
+4 0120 0120 email
+4 00640065 00640065 email
+4 00E400E50068 00E400E50068 email
+4 0000E400 0000E400 email
+4 0000563001FC0563 0000563001FC0563 email
+1 0061006200630064006500660067 0061006200630064006500660067 one
+3 0071007200730074007500760077 0071007200730074007500760077 three
+2 0069006A006B0069006C006D006E 0069006A006B0069006C006D006E two
drop table t1;
drop table t2;
create table t1 (
@@ -2717,6 +2788,32 @@
insert into t2 values (4,_ucs2 0x05630563,_ucs2 0x05630563,'eleven');
insert into t2 values (4,_ucs2 0x0563001fc0563,_ucs2 0x0563001fc0563,'point');
insert into t2 values (4,_ucs2 0x05612020,_ucs2 0x05612020,'taken');
+update t1 set filler = 'boo' where a = 1;
+update t2 set filler ='email' where a = 4;
+select a,hex(b),hex(c),filler from t1 order by filler;
+a hex(b) hex(c) filler
+1 61626364656667 61626364656667 boo
+4 D0B1 D0B1 eight
+4 5B 5B five
+4 E880BD E880BD four
+4 E880BDD0B1E880BD E880BDD0B1E880BD seven
+4 E880BDE880BD E880BDE880BD six
+3 71727374757677 71727374757677 three
+2 696A6B696C6D6E 696A6B696C6D6E two
+select a,hex(b),hex(c),filler from t2 order by filler;
+a hex(b) hex(c) filler
+4 0120 0120 email
+4 01FC 01FC email
+4 0563 0563 email
+4 0000563001FC0563 0000563001FC0563 email
+4 0000E400 0000E400 email
+4 00640065 00640065 email
+4 00E400E50068 00E400E50068 email
+4 05612020 05612020 email
+4 05630563 05630563 email
+1 0061006200630064006500660067 0061006200630064006500660067 one
+3 0071007200730074007500760077 0071007200730074007500760077 three
+2 0069006A006B0069006C006D006E 0069006A006B0069006C006D006E two
drop table t1;
drop table t2;
create table t1 (
@@ -2741,9 +2838,92 @@
insert into t2 values (4,_ucs2 0x0120,_ucs2 0x0120,'eight');
insert into t2 values (4,_ucs2 0x0563,_ucs2 0x0563,'ten');
insert into t2 values (4,_ucs2 0x05612020,_ucs2 0x05612020,'taken');
+update t1 set filler = 'boo' where a = 1;
+update t2 set filler ='email' where a = 4;
+select a,hex(b),hex(c),filler from t1 order by filler;
+a hex(b) hex(c) filler
+1 61626364656667 61626364656667 boo
+4 D0B1 D0B1 eight
+4 5B 5B five
+4 E880BD E880BD four
+3 71727374757677 71727374757677 three
+2 696A6B696C6D6E 696A6B696C6D6E two
+select a,hex(b),hex(c),filler from t2 order by filler;
+a hex(b) hex(c) filler
+4 0000E400 0000E400 email
+4 00640065 00640065 email
+4 00E400E50068 00E400E50068 email
+4 0120 0120 email
+4 01FC 01FC email
+4 05612020 05612020 email
+4 0563 0563 email
+1 61626364656667 61626364656667 one
+3 71727374757677 71727374757677 three
+2 696A6B696C6D6E 696A6B696C6D6E two
drop table t1;
drop table t2;
commit;
+set foreign_key_checks=0;
+create table t2 (a int primary key, b int, foreign key (b) references t1(a)) engine = innodb;
+create table t1(a char(10) primary key, b varchar(20)) engine = innodb;
+ERROR HY000: Can't create table 'test.t1' (errno: 150)
+set foreign_key_checks=1;
+drop table t2;
+set foreign_key_checks=0;
+create table t1(a varchar(10) primary key) engine = innodb DEFAULT CHARSET=latin1;
+create table t2 (a varchar(10), foreign key (a) references t1(a)) engine = innodb DEFAULT CHARSET=utf8;
+ERROR HY000: Can't create table 'test.t2' (errno: 150)
+set foreign_key_checks=1;
+drop table t1;
+set foreign_key_checks=0;
+create table t2 (a varchar(10), foreign key (a) references t1(a)) engine = innodb;
+create table t1(a varchar(10) primary key) engine = innodb;
+alter table t1 modify column a int;
+Got one of the listed errors
+set foreign_key_checks=1;
+drop table t2,t1;
+set foreign_key_checks=0;
+create table t2 (a varchar(10), foreign key (a) references t1(a)) engine = innodb DEFAULT CHARSET=latin1;
+create table t1(a varchar(10) primary key) engine = innodb DEFAULT CHARSET=latin1;
+alter table t1 convert to character set utf8;
+set foreign_key_checks=1;
+drop table t2,t1;
+set foreign_key_checks=0;
+create table t2 (a varchar(10), foreign key (a) references t1(a)) engine = innodb DEFAULT CHARSET=latin1;
+create table t3(a varchar(10) primary key) engine = innodb DEFAULT CHARSET=utf8;
+rename table t3 to t1;
+ERROR HY000: Error on rename of './test/t3' to './test/t1' (errno: 150)
+set foreign_key_checks=1;
+drop table t2,t3;
+create table t1(a int primary key) row_format=redundant engine=innodb;
+create table t2(a int primary key,constraint foreign key(a)references t1(a)) row_format=compact engine=innodb;
+create table t3(a int primary key) row_format=compact engine=innodb;
+create table t4(a int primary key,constraint foreign key(a)references t3(a)) row_format=redundant engine=innodb;
+insert into t1 values(1);
+insert into t3 values(1);
+insert into t2 values(2);
+ERROR 23000: Cannot add or update a child row: a foreign key constraint fails (`test/t2`, CONSTRAINT `t2_ibfk_1` FOREIGN KEY (`a`) REFERENCES `t1` (`a`))
+insert into t4 values(2);
+ERROR 23000: Cannot add or update a child row: a foreign key constraint fails (`test/t4`, CONSTRAINT `t4_ibfk_1` FOREIGN KEY (`a`) REFERENCES `t3` (`a`))
+insert into t2 values(1);
+insert into t4 values(1);
+update t1 set a=2;
+ERROR 23000: Cannot delete or update a parent row: a foreign key constraint fails (`test/t2`, CONSTRAINT `t2_ibfk_1` FOREIGN KEY (`a`) REFERENCES `t1` (`a`))
+update t2 set a=2;
+ERROR 23000: Cannot add or update a child row: a foreign key constraint fails (`test/t2`, CONSTRAINT `t2_ibfk_1` FOREIGN KEY (`a`) REFERENCES `t1` (`a`))
+update t3 set a=2;
+ERROR 23000: Cannot delete or update a parent row: a foreign key constraint fails (`test/t4`, CONSTRAINT `t4_ibfk_1` FOREIGN KEY (`a`) REFERENCES `t3` (`a`))
+update t4 set a=2;
+ERROR 23000: Cannot add or update a child row: a foreign key constraint fails (`test/t4`, CONSTRAINT `t4_ibfk_1` FOREIGN KEY (`a`) REFERENCES `t3` (`a`))
+truncate t1;
+ERROR 23000: Cannot delete or update a parent row: a foreign key constraint fails (`test/t2`, CONSTRAINT `t2_ibfk_1` FOREIGN KEY (`a`) REFERENCES `t1` (`a`))
+truncate t3;
+ERROR 23000: Cannot delete or update a parent row: a foreign key constraint fails (`test/t4`, CONSTRAINT `t4_ibfk_1` FOREIGN KEY (`a`) REFERENCES `t3` (`a`))
+truncate t2;
+truncate t4;
+truncate t1;
+truncate t3;
+drop table t4,t3,t2,t1;
create table t1 (a varchar(255) character set utf8,
b varchar(255) character set utf8,
c varchar(255) character set utf8,
@@ -2757,22 +2937,279 @@
e varchar(255) character set utf8,
key (a,b,c,d,e)) engine=innodb;
ERROR 42000: Specified key was too long; max key length is 3072 bytes
-End of 5.0 tests
+create table t1 (s1 varbinary(2),primary key (s1)) engine=innodb;
+create table t2 (s1 binary(2),primary key (s1)) engine=innodb;
+create table t3 (s1 varchar(2) binary,primary key (s1)) engine=innodb;
+create table t4 (s1 char(2) binary,primary key (s1)) engine=innodb;
+insert into t1 values (0x41),(0x4120),(0x4100);
+insert into t2 values (0x41),(0x4120),(0x4100);
+ERROR 23000: Duplicate entry 'A' for key 1
+insert into t2 values (0x41),(0x4120);
+insert into t3 values (0x41),(0x4120),(0x4100);
+ERROR 23000: Duplicate entry 'A ' for key 1
+insert into t3 values (0x41),(0x4100);
+insert into t4 values (0x41),(0x4120),(0x4100);
+ERROR 23000: Duplicate entry 'A' for key 1
+insert into t4 values (0x41),(0x4100);
+select hex(s1) from t1;
+hex(s1)
+41
+4100
+4120
+select hex(s1) from t2;
+hex(s1)
+4100
+4120
+select hex(s1) from t3;
+hex(s1)
+4100
+41
+select hex(s1) from t4;
+hex(s1)
+4100
+41
+drop table t1,t2,t3,t4;
+create table t1 (a int primary key,s1 varbinary(3) not null unique) engine=innodb;
+create table t2 (s1 binary(2) not null, constraint c foreign key(s1) references t1(s1) on update cascade) engine=innodb;
+insert into t1 values(1,0x4100),(2,0x41),(3,0x4120),(4,0x42);
+insert into t2 values(0x42);
+ERROR 23000: Cannot add or update a child row: a foreign key constraint fails (`test/t2`, CONSTRAINT `c` FOREIGN KEY (`s1`) REFERENCES `t1` (`s1`) ON UPDATE CASCADE)
+insert into t2 values(0x41);
+select hex(s1) from t2;
+hex(s1)
+4100
+update t1 set s1=0x123456 where a=2;
+select hex(s1) from t2;
+hex(s1)
+4100
+update t1 set s1=0x12 where a=1;
+ERROR 23000: Cannot delete or update a parent row: a foreign key constraint fails (`test/t2`, CONSTRAINT `c` FOREIGN KEY (`s1`) REFERENCES `t1` (`s1`) ON UPDATE CASCADE)
+update t1 set s1=0x12345678 where a=1;
+ERROR 23000: Cannot delete or update a parent row: a foreign key constraint fails (`test/t2`, CONSTRAINT `c` FOREIGN KEY (`s1`) REFERENCES `t1` (`s1`) ON UPDATE CASCADE)
+update t1 set s1=0x123457 where a=1;
+ERROR 23000: Cannot delete or update a parent row: a foreign key constraint fails (`test/t2`, CONSTRAINT `c` FOREIGN KEY (`s1`) REFERENCES `t1` (`s1`) ON UPDATE CASCADE)
+update t1 set s1=0x1220 where a=1;
+select hex(s1) from t2;
+hex(s1)
+1220
+update t1 set s1=0x1200 where a=1;
+select hex(s1) from t2;
+hex(s1)
+1200
+update t1 set s1=0x4200 where a=1;
+select hex(s1) from t2;
+hex(s1)
+4200
+delete from t1 where a=1;
+ERROR 23000: Cannot delete or update a parent row: a foreign key constraint fails (`test/t2`, CONSTRAINT `c` FOREIGN KEY (`s1`) REFERENCES `t1` (`s1`) ON UPDATE CASCADE)
+delete from t1 where a=2;
+update t2 set s1=0x4120;
+delete from t1;
+ERROR 23000: Cannot delete or update a parent row: a foreign key constraint fails (`test/t2`, CONSTRAINT `c` FOREIGN KEY (`s1`) REFERENCES `t1` (`s1`) ON UPDATE CASCADE)
+delete from t1 where a!=3;
+select a,hex(s1) from t1;
+a hex(s1)
+3 4120
+select hex(s1) from t2;
+hex(s1)
+4120
+drop table t2,t1;
+create table t1 (a int primary key,s1 varchar(2) binary not null unique) engine=innodb;
+create table t2 (s1 char(2) binary not null, constraint c foreign key(s1) references t1(s1) on update cascade) engine=innodb;
+insert into t1 values(1,0x4100),(2,0x41);
+insert into t2 values(0x41);
+select hex(s1) from t2;
+hex(s1)
+41
+update t1 set s1=0x1234 where a=1;
+select hex(s1) from t2;
+hex(s1)
+41
+update t1 set s1=0x12 where a=2;
+select hex(s1) from t2;
+hex(s1)
+12
+delete from t1 where a=1;
+delete from t1 where a=2;
+ERROR 23000: Cannot delete or update a parent row: a foreign key constraint fails (`test/t2`, CONSTRAINT `c` FOREIGN KEY (`s1`) REFERENCES `t1` (`s1`) ON UPDATE CASCADE)
+select a,hex(s1) from t1;
+a hex(s1)
+2 12
+select hex(s1) from t2;
+hex(s1)
+12
+drop table t2,t1;
CREATE TABLE t1 (
-field1 varchar(8) NOT NULL DEFAULT '',
-field2 varchar(8) NOT NULL DEFAULT '',
-PRIMARY KEY (field1, field2)
-) ENGINE=InnoDB;
+ind enum('0','1','2') NOT NULL default '0',
+string1 varchar(250) NOT NULL,
+PRIMARY KEY (ind)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE t2 (
-field1 varchar(8) NOT NULL DEFAULT '' PRIMARY KEY,
-FOREIGN KEY (field1) REFERENCES t1 (field1)
-ON DELETE CASCADE ON UPDATE CASCADE
-) ENGINE=InnoDB;
-INSERT INTO t1 VALUES ('old', 'somevalu');
-INSERT INTO t1 VALUES ('other', 'anyvalue');
-INSERT INTO t2 VALUES ('old');
-INSERT INTO t2 VALUES ('other');
-UPDATE t1 SET field1 = 'other' WHERE field2 = 'somevalu';
-ERROR 23000: Upholding foreign key constraints for table 't1', entry 'other-somevalu', key 1 would lead to a duplicate entry
-DROP TABLE t2;
-DROP TABLE t1;
+ind enum('0','1','2') NOT NULL default '0',
+string1 varchar(250) NOT NULL,
+PRIMARY KEY (ind)
+) ENGINE=InnoDB DEFAULT CHARSET=ucs2;
+INSERT INTO t1 VALUES ('1', ''),('2', '');
+INSERT INTO t2 VALUES ('1', ''),('2', '');
+SELECT hex(ind),hex(string1) FROM t1 ORDER BY string1;
+hex(ind) hex(string1)
+31
+32
+SELECT hex(ind),hex(string1) FROM t2 ORDER BY string1;
+hex(ind) hex(string1)
+0031
+0032
+drop table t1,t2;
+CREATE TABLE t1 (
+ind set('0','1','2') NOT NULL default '0',
+string1 varchar(250) NOT NULL,
+PRIMARY KEY (ind)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8;
+CREATE TABLE t2 (
+ind set('0','1','2') NOT NULL default '0',
+string1 varchar(250) NOT NULL,
+PRIMARY KEY (ind)
+) ENGINE=InnoDB DEFAULT CHARSET=ucs2;
+INSERT INTO t1 VALUES ('1', ''),('2', '');
+INSERT INTO t2 VALUES ('1', ''),('2', '');
+SELECT hex(ind),hex(string1) FROM t1 ORDER BY string1;
+hex(ind) hex(string1)
+31
+32
+SELECT hex(ind),hex(string1) FROM t2 ORDER BY string1;
+hex(ind) hex(string1)
+0031
+0032
+drop table t1,t2;
+CREATE TABLE t1 (
+ind bit not null,
+string1 varchar(250) NOT NULL,
+PRIMARY KEY (ind)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8;
+CREATE TABLE t2 (
+ind bit not null,
+string1 varchar(250) NOT NULL,
+PRIMARY KEY (ind)
+) ENGINE=InnoDB DEFAULT CHARSET=ucs2;
+insert into t1 values(0,''),(1,'');
+insert into t2 values(0,''),(1,'');
+select hex(ind),hex(string1) from t1 order by string1;
+hex(ind) hex(string1)
+0
+1
+select hex(ind),hex(string1) from t2 order by string1;
+hex(ind) hex(string1)
+0
+1
+drop table t1,t2;
+create table t2 (
+a int, b char(10), filler char(10), primary key(a, b(2))
+) character set utf8 engine = innodb;
+insert into t2 values (1,'abcdefg','one');
+insert into t2 values (2,'ijkilmn','two');
+insert into t2 values (3, 'qrstuvw','three');
+update t2 set a=5, filler='booo' where a=1;
+drop table t2;
+create table t2 (
+a int, b char(10), filler char(10), primary key(a, b(2))
+) character set ucs2 engine = innodb;
+insert into t2 values (1,'abcdefg','one');
+insert into t2 values (2,'ijkilmn','two');
+insert into t2 values (3, 'qrstuvw','three');
+update t2 set a=5, filler='booo' where a=1;
+drop table t2;
+create table t1(a int not null, b char(110),primary key(a,b(100))) engine=innodb default charset=utf8;
+insert into t1 values(1,'abcdefg'),(2,'defghijk');
+insert into t1 values(6,_utf8 0xD0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1);
+insert into t1 values(7,_utf8 0xD0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B2);
+select a,hex(b) from t1 order by b;
+a hex(b)
+1 61626364656667
+2 6465666768696A6B
+6 D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1
+7 D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B2
+update t1 set b = 'three' where a = 6;
+drop table t1;
+create table t1(a int not null, b text(110),primary key(a,b(100))) engine=innodb default charset=utf8;
+insert into t1 values(1,'abcdefg'),(2,'defghijk');
+insert into t1 values(6,_utf8 0xD0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1);
+insert into t1 values(7,_utf8 0xD0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B2);
+select a,hex(b) from t1 order by b;
+a hex(b)
+1 61626364656667
+2 6465666768696A6B
+6 D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1
+7 D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B2
+update t1 set b = 'three' where a = 6;
+drop table t1;
+CREATE TABLE t1(a INT, PRIMARY KEY(a)) ENGINE=InnoDB;
+CREATE TABLE t2(a INT) ENGINE=InnoDB;
+ALTER TABLE t2 ADD FOREIGN KEY (a) REFERENCES t1(a);
+ALTER TABLE t2 DROP FOREIGN KEY t2_ibfk_1;
+ALTER TABLE t2 ADD CONSTRAINT t2_ibfk_0 FOREIGN KEY (a) REFERENCES t1(a);
+ALTER TABLE t2 DROP FOREIGN KEY t2_ibfk_0;
+SHOW CREATE TABLE t2;
+Table Create Table
+t2 CREATE TABLE `t2` (
+ `a` int(11) default NULL,
+ KEY `t2_ibfk_0` (`a`)
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+DROP TABLE t2,t1;
+create table t1(a int not null, b int, c int, d int, primary key(a)) engine=innodb;
+insert into t1(a) values (1),(2),(3);
+commit;
+set autocommit = 0;
+update t1 set b = 5 where a = 2;
+create trigger t1t before insert on t1 for each row begin set NEW.b = NEW.a * 10 + 5, NEW.c = NEW.a / 10; end |
+set autocommit = 0;
+insert into t1(a) values (10),(20),(30),(40),(50),(60),(70),(80),(90),(100),
+(11),(21),(31),(41),(51),(61),(71),(81),(91),(101),
+(12),(22),(32),(42),(52),(62),(72),(82),(92),(102),
+(13),(23),(33),(43),(53),(63),(73),(83),(93),(103),
+(14),(24),(34),(44),(54),(64),(74),(84),(94),(104);
+commit;
+commit;
+drop trigger t1t;
+drop table t1;
+create table t1(a int not null, b int, c int, d int, primary key(a)) engine=innodb;
+create table t2(a int not null, b int, c int, d int, primary key(a)) engine=innodb;
+create table t3(a int not null, b int, c int, d int, primary key(a)) engine=innodb;
+create table t4(a int not null, b int, c int, d int, primary key(a)) engine=innodb;
+create table t5(a int not null, b int, c int, d int, primary key(a)) engine=innodb;
+insert into t1(a) values (1),(2),(3);
+insert into t2(a) values (1),(2),(3);
+insert into t3(a) values (1),(2),(3);
+insert into t4(a) values (1),(2),(3);
+insert into t3(a) values (5),(7),(8);
+insert into t4(a) values (5),(7),(8);
+insert into t5(a) values (1),(2),(3),(4),(5),(6),(7),(8),(9),(10),(11),(12);
+create trigger t1t before insert on t1 for each row begin
+INSERT INTO t2 SET a = NEW.a;
+end |
+create trigger t2t before insert on t2 for each row begin
+DELETE FROM t3 WHERE a = NEW.a;
+end |
+create trigger t3t before delete on t3 for each row begin
+UPDATE t4 SET b = b + 1 WHERE a = OLD.a;
+end |
+create trigger t4t before update on t4 for each row begin
+UPDATE t5 SET b = b + 1 where a = NEW.a;
+end |
+commit;
+set autocommit = 0;
+update t1 set b = b + 5 where a = 1;
+update t2 set b = b + 5 where a = 1;
+update t3 set b = b + 5 where a = 1;
+update t4 set b = b + 5 where a = 1;
+insert into t5(a) values(20);
+set autocommit = 0;
+insert into t1(a) values(7);
+insert into t2(a) values(8);
+delete from t2 where a = 3;
+update t4 set b = b + 1 where a = 3;
+commit;
+drop trigger t1t;
+drop trigger t2t;
+drop trigger t3t;
+drop trigger t4t;
+drop table t1, t2, t3, t4, t5;
--- 1.130/mysql-test/t/innodb.test 2006-02-25 22:54:29 +03:00
+++ 1.131/mysql-test/t/innodb.test 2006-03-03 22:34:14 +03:00
@@ -1273,7 +1273,7 @@
# Test for innodb_thread_concurrency variable
show variables like "innodb_thread_concurrency";
-set global innodb_thread_concurrency=1000;
+set global innodb_thread_concurrency=1001;
show variables like "innodb_thread_concurrency";
set global innodb_thread_concurrency=0;
show variables like "innodb_thread_concurrency";
@@ -1576,7 +1576,33 @@
checksum table t1;
drop table t1;
+#
+# BUG#11238 - in prelocking mode SELECT .. FOR UPDATE is changed to
+# non-blocking SELECT
+#
+create table t1 (col1 integer primary key, col2 integer) engine=innodb;
+insert t1 values (1,100);
+delimiter |;
+create function f1 () returns integer begin
+declare var1 int;
+select col2 into var1 from t1 where col1=1 for update;
+return var1;
+end|
+delimiter ;|
+start transaction;
+select f1();
+connection b;
+send update t1 set col2=0 where col1=1;
+connection default;
+select * from t1;
+connection a;
+rollback;
+connection b;
+reap;
+rollback;
connection default;
+drop table t1;
+drop function f1;
disconnect a;
disconnect b;
@@ -1610,6 +1636,10 @@
insert into t2 values (4,_ucs2 0x05630563,_ucs2 0x05630563,'eleven');
insert into t2 values (4,_ucs2 0x0563001fc0563,_ucs2 0x0563001fc0563,'point');
insert into t2 values (4,_ucs2 0x05612020,_ucs2 0x05612020,'taken');
+update t1 set filler = 'boo' where a = 1;
+update t2 set filler ='email' where a = 4;
+select a,hex(b),hex(c),filler from t1 order by filler;
+select a,hex(b),hex(c),filler from t2 order by filler;
drop table t1;
drop table t2;
@@ -1639,6 +1669,10 @@
insert into t2 values (4,_ucs2 0x05630563,_ucs2 0x05630563,'eleven');
insert into t2 values (4,_ucs2 0x0563001fc0563,_ucs2 0x0563001fc0563,'point');
insert into t2 values (4,_ucs2 0x05612020,_ucs2 0x05612020,'taken');
+update t1 set filler = 'boo' where a = 1;
+update t2 set filler ='email' where a = 4;
+select a,hex(b),hex(c),filler from t1 order by filler;
+select a,hex(b),hex(c),filler from t2 order by filler;
drop table t1;
drop table t2;
@@ -1668,6 +1702,10 @@
insert into t2 values (4,_ucs2 0x05630563,_ucs2 0x05630563,'eleven');
insert into t2 values (4,_ucs2 0x0563001fc0563,_ucs2 0x0563001fc0563,'point');
insert into t2 values (4,_ucs2 0x05612020,_ucs2 0x05612020,'taken');
+update t1 set filler = 'boo' where a = 1;
+update t2 set filler ='email' where a = 4;
+select a,hex(b),hex(c),filler from t1 order by filler;
+select a,hex(b),hex(c),filler from t2 order by filler;
drop table t1;
drop table t2;
@@ -1693,10 +1731,99 @@
insert into t2 values (4,_ucs2 0x0120,_ucs2 0x0120,'eight');
insert into t2 values (4,_ucs2 0x0563,_ucs2 0x0563,'ten');
insert into t2 values (4,_ucs2 0x05612020,_ucs2 0x05612020,'taken');
+update t1 set filler = 'boo' where a = 1;
+update t2 set filler ='email' where a = 4;
+select a,hex(b),hex(c),filler from t1 order by filler;
+select a,hex(b),hex(c),filler from t2 order by filler;
drop table t1;
drop table t2;
commit;
+# tests for bugs #9802 and #13778
+
+# test that FKs between invalid types are not accepted
+
+set foreign_key_checks=0;
+create table t2 (a int primary key, b int, foreign key (b) references t1(a)) engine = innodb;
+-- error 1005
+create table t1(a char(10) primary key, b varchar(20)) engine = innodb;
+set foreign_key_checks=1;
+drop table t2;
+
+# test that FKs between different charsets are not accepted in CREATE even
+# when f_k_c is 0
+
+set foreign_key_checks=0;
+create table t1(a varchar(10) primary key) engine = innodb DEFAULT CHARSET=latin1;
+-- error 1005
+create table t2 (a varchar(10), foreign key (a) references t1(a)) engine = innodb DEFAULT CHARSET=utf8;
+set foreign_key_checks=1;
+drop table t1;
+
+# test that invalid datatype conversions with ALTER are not allowed
+
+set foreign_key_checks=0;
+create table t2 (a varchar(10), foreign key (a) references t1(a)) engine = innodb;
+create table t1(a varchar(10) primary key) engine = innodb;
+-- error 1025,1025
+alter table t1 modify column a int;
+set foreign_key_checks=1;
+drop table t2,t1;
+
+# test that charset conversions with ALTER are allowed when f_k_c is 0
+
+set foreign_key_checks=0;
+create table t2 (a varchar(10), foreign key (a) references t1(a)) engine = innodb DEFAULT CHARSET=latin1;
+create table t1(a varchar(10) primary key) engine = innodb DEFAULT CHARSET=latin1;
+alter table t1 convert to character set utf8;
+set foreign_key_checks=1;
+drop table t2,t1;
+
+# test that RENAME does not allow invalid charsets when f_k_c is 0
+
+set foreign_key_checks=0;
+create table t2 (a varchar(10), foreign key (a) references t1(a)) engine = innodb DEFAULT CHARSET=latin1;
+create table t3(a varchar(10) primary key) engine = innodb DEFAULT CHARSET=utf8;
+-- error 1025
+rename table t3 to t1;
+set foreign_key_checks=1;
+drop table t2,t3;
+
+# test that foreign key errors are reported correctly (Bug #15550)
+
+create table t1(a int primary key) row_format=redundant engine=innodb;
+create table t2(a int primary key,constraint foreign key(a)references t1(a)) row_format=compact engine=innodb;
+create table t3(a int primary key) row_format=compact engine=innodb;
+create table t4(a int primary key,constraint foreign key(a)references t3(a)) row_format=redundant engine=innodb;
+
+insert into t1 values(1);
+insert into t3 values(1);
+-- error 1452
+insert into t2 values(2);
+-- error 1452
+insert into t4 values(2);
+insert into t2 values(1);
+insert into t4 values(1);
+-- error 1451
+update t1 set a=2;
+-- error 1452
+update t2 set a=2;
+-- error 1451
+update t3 set a=2;
+-- error 1452
+update t4 set a=2;
+-- error 1451
+truncate t1;
+-- error 1451
+truncate t3;
+truncate t2;
+truncate t4;
+truncate t1;
+truncate t3;
+
+drop table t4,t3,t2,t1;
+
+
#
# Test that we can create a large (>1K) key
#
@@ -1714,33 +1841,268 @@
e varchar(255) character set utf8,
key (a,b,c,d,e)) engine=innodb;
---echo End of 5.0 tests
+# test the padding of BINARY types and collations (Bug #14189)
+
+create table t1 (s1 varbinary(2),primary key (s1)) engine=innodb;
+create table t2 (s1 binary(2),primary key (s1)) engine=innodb;
+create table t3 (s1 varchar(2) binary,primary key (s1)) engine=innodb;
+create table t4 (s1 char(2) binary,primary key (s1)) engine=innodb;
+
+insert into t1 values (0x41),(0x4120),(0x4100);
+-- error 1062
+insert into t2 values (0x41),(0x4120),(0x4100);
+insert into t2 values (0x41),(0x4120);
+-- error 1062
+insert into t3 values (0x41),(0x4120),(0x4100);
+insert into t3 values (0x41),(0x4100);
+-- error 1062
+insert into t4 values (0x41),(0x4120),(0x4100);
+insert into t4 values (0x41),(0x4100);
+select hex(s1) from t1;
+select hex(s1) from t2;
+select hex(s1) from t3;
+select hex(s1) from t4;
+drop table t1,t2,t3,t4;
+
+create table t1 (a int primary key,s1 varbinary(3) not null unique) engine=innodb;
+create table t2 (s1 binary(2) not null, constraint c foreign key(s1) references t1(s1) on update cascade) engine=innodb;
+
+insert into t1 values(1,0x4100),(2,0x41),(3,0x4120),(4,0x42);
+-- error 1452
+insert into t2 values(0x42);
+insert into t2 values(0x41);
+select hex(s1) from t2;
+update t1 set s1=0x123456 where a=2;
+select hex(s1) from t2;
+-- error 1451
+update t1 set s1=0x12 where a=1;
+-- error 1451
+update t1 set s1=0x12345678 where a=1;
+-- error 1451
+update t1 set s1=0x123457 where a=1;
+update t1 set s1=0x1220 where a=1;
+select hex(s1) from t2;
+update t1 set s1=0x1200 where a=1;
+select hex(s1) from t2;
+update t1 set s1=0x4200 where a=1;
+select hex(s1) from t2;
+-- error 1451
+delete from t1 where a=1;
+delete from t1 where a=2;
+update t2 set s1=0x4120;
+-- error 1451
+delete from t1;
+delete from t1 where a!=3;
+select a,hex(s1) from t1;
+select hex(s1) from t2;
+
+drop table t2,t1;
+
+create table t1 (a int primary key,s1 varchar(2) binary not null unique) engine=innodb;
+create table t2 (s1 char(2) binary not null, constraint c foreign key(s1) references t1(s1) on update cascade) engine=innodb;
+
+insert into t1 values(1,0x4100),(2,0x41);
+insert into t2 values(0x41);
+select hex(s1) from t2;
+update t1 set s1=0x1234 where a=1;
+select hex(s1) from t2;
+update t1 set s1=0x12 where a=2;
+select hex(s1) from t2;
+delete from t1 where a=1;
+-- error 1451
+delete from t1 where a=2;
+select a,hex(s1) from t1;
+select hex(s1) from t2;
+
+drop table t2,t1;
#
-# Test that cascading updates leading to duplicate keys give the correct
-# error message (bug #9680)
+# Test cases for bug #15308 Problem of Order with Enum Column in Primary Key
#
+CREATE TABLE t1 (
+ ind enum('0','1','2') NOT NULL default '0',
+ string1 varchar(250) NOT NULL,
+ PRIMARY KEY (ind)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8;
+CREATE TABLE t2 (
+ ind enum('0','1','2') NOT NULL default '0',
+ string1 varchar(250) NOT NULL,
+ PRIMARY KEY (ind)
+) ENGINE=InnoDB DEFAULT CHARSET=ucs2;
+
+INSERT INTO t1 VALUES ('1', ''),('2', '');
+INSERT INTO t2 VALUES ('1', ''),('2', '');
+SELECT hex(ind),hex(string1) FROM t1 ORDER BY string1;
+SELECT hex(ind),hex(string1) FROM t2 ORDER BY string1;
+drop table t1,t2;
CREATE TABLE t1 (
- field1 varchar(8) NOT NULL DEFAULT '',
- field2 varchar(8) NOT NULL DEFAULT '',
- PRIMARY KEY (field1, field2)
-) ENGINE=InnoDB;
+ ind set('0','1','2') NOT NULL default '0',
+ string1 varchar(250) NOT NULL,
+ PRIMARY KEY (ind)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8;
+CREATE TABLE t2 (
+ ind set('0','1','2') NOT NULL default '0',
+ string1 varchar(250) NOT NULL,
+ PRIMARY KEY (ind)
+) ENGINE=InnoDB DEFAULT CHARSET=ucs2;
+
+INSERT INTO t1 VALUES ('1', ''),('2', '');
+INSERT INTO t2 VALUES ('1', ''),('2', '');
+SELECT hex(ind),hex(string1) FROM t1 ORDER BY string1;
+SELECT hex(ind),hex(string1) FROM t2 ORDER BY string1;
+drop table t1,t2;
+CREATE TABLE t1 (
+ ind bit not null,
+ string1 varchar(250) NOT NULL,
+ PRIMARY KEY (ind)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE t2 (
- field1 varchar(8) NOT NULL DEFAULT '' PRIMARY KEY,
- FOREIGN KEY (field1) REFERENCES t1 (field1)
- ON DELETE CASCADE ON UPDATE CASCADE
-) ENGINE=InnoDB;
+ ind bit not null,
+ string1 varchar(250) NOT NULL,
+ PRIMARY KEY (ind)
+) ENGINE=InnoDB DEFAULT CHARSET=ucs2;
+insert into t1 values(0,''),(1,'');
+insert into t2 values(0,''),(1,'');
+select hex(ind),hex(string1) from t1 order by string1;
+select hex(ind),hex(string1) from t2 order by string1;
+drop table t1,t2;
+
+# tests for bug #14056 Column prefix index on UTF-8 primary key column causes 'Can't find record..'
+
+create table t2 (
+ a int, b char(10), filler char(10), primary key(a, b(2))
+) character set utf8 engine = innodb;
+
+insert into t2 values (1,'abcdefg','one');
+insert into t2 values (2,'ijkilmn','two');
+insert into t2 values (3, 'qrstuvw','three');
+update t2 set a=5, filler='booo' where a=1;
+drop table t2;
+create table t2 (
+ a int, b char(10), filler char(10), primary key(a, b(2))
+) character set ucs2 engine = innodb;
-INSERT INTO t1 VALUES ('old', 'somevalu');
-INSERT INTO t1 VALUES ('other', 'anyvalue');
+insert into t2 values (1,'abcdefg','one');
+insert into t2 values (2,'ijkilmn','two');
+insert into t2 values (3, 'qrstuvw','three');
+update t2 set a=5, filler='booo' where a=1;
+drop table t2;
-INSERT INTO t2 VALUES ('old');
-INSERT INTO t2 VALUES ('other');
+create table t1(a int not null, b char(110),primary key(a,b(100))) engine=innodb default charset=utf8;
+insert into t1 values(1,'abcdefg'),(2,'defghijk');
+insert into t1 values(6,_utf8 0xD0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1);
+insert into t1 values(7,_utf8 0xD0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B2);
+select a,hex(b) from t1 order by b;
+update t1 set b = 'three' where a = 6;
+drop table t1;
+create table t1(a int not null, b text(110),primary key(a,b(100))) engine=innodb default charset=utf8;
+insert into t1 values(1,'abcdefg'),(2,'defghijk');
+insert into t1 values(6,_utf8 0xD0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1);
+insert into t1 values(7,_utf8 0xD0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B2);
+select a,hex(b) from t1 order by b;
+update t1 set b = 'three' where a = 6;
+drop table t1;
+
+# Ensure that <tablename>_ibfk_0 is not mistreated as a
+# generated foreign key identifier. (Bug #16387)
+
+CREATE TABLE t1(a INT, PRIMARY KEY(a)) ENGINE=InnoDB;
+CREATE TABLE t2(a INT) ENGINE=InnoDB;
+ALTER TABLE t2 ADD FOREIGN KEY (a) REFERENCES t1(a);
+ALTER TABLE t2 DROP FOREIGN KEY t2_ibfk_1;
+ALTER TABLE t2 ADD CONSTRAINT t2_ibfk_0 FOREIGN KEY (a) REFERENCES t1(a);
+ALTER TABLE t2 DROP FOREIGN KEY t2_ibfk_0;
+SHOW CREATE TABLE t2;
+DROP TABLE t2,t1;
---error ER_FOREIGN_DUPLICATE_KEY
-UPDATE t1 SET field1 = 'other' WHERE field2 = 'somevalu';
+#
+# Test case for bug #16229: MySQL/InnoDB uses full explicit table locks in trigger processing
+#
-DROP TABLE t2;
-DROP TABLE t1;
+connect (a,localhost,root,,);
+connect (b,localhost,root,,);
+connection a;
+create table t1(a int not null, b int, c int, d int, primary key(a)) engine=innodb;
+insert into t1(a) values (1),(2),(3);
+commit;
+connection b;
+set autocommit = 0;
+update t1 set b = 5 where a = 2;
+connection a;
+delimiter |;
+create trigger t1t before insert on t1 for each row begin set NEW.b = NEW.a * 10 + 5, NEW.c = NEW.a / 10; end |
+delimiter ;|
+set autocommit = 0;
+connection a;
+insert into t1(a) values (10),(20),(30),(40),(50),(60),(70),(80),(90),(100),
+(11),(21),(31),(41),(51),(61),(71),(81),(91),(101),
+(12),(22),(32),(42),(52),(62),(72),(82),(92),(102),
+(13),(23),(33),(43),(53),(63),(73),(83),(93),(103),
+(14),(24),(34),(44),(54),(64),(74),(84),(94),(104);
+connection b;
+commit;
+connection a;
+commit;
+drop trigger t1t;
+drop table t1;
+disconnect a;
+disconnect b;
+#
+# Another trigger test
+#
+connect (a,localhost,root,,);
+connect (b,localhost,root,,);
+connection a;
+create table t1(a int not null, b int, c int, d int, primary key(a)) engine=innodb;
+create table t2(a int not null, b int, c int, d int, primary key(a)) engine=innodb;
+create table t3(a int not null, b int, c int, d int, primary key(a)) engine=innodb;
+create table t4(a int not null, b int, c int, d int, primary key(a)) engine=innodb;
+create table t5(a int not null, b int, c int, d int, primary key(a)) engine=innodb;
+insert into t1(a) values (1),(2),(3);
+insert into t2(a) values (1),(2),(3);
+insert into t3(a) values (1),(2),(3);
+insert into t4(a) values (1),(2),(3);
+insert into t3(a) values (5),(7),(8);
+insert into t4(a) values (5),(7),(8);
+insert into t5(a) values (1),(2),(3),(4),(5),(6),(7),(8),(9),(10),(11),(12);
+
+delimiter |;
+create trigger t1t before insert on t1 for each row begin
+ INSERT INTO t2 SET a = NEW.a;
+end |
+
+create trigger t2t before insert on t2 for each row begin
+ DELETE FROM t3 WHERE a = NEW.a;
+end |
+
+create trigger t3t before delete on t3 for each row begin
+ UPDATE t4 SET b = b + 1 WHERE a = OLD.a;
+end |
+
+create trigger t4t before update on t4 for each row begin
+ UPDATE t5 SET b = b + 1 where a = NEW.a;
+end |
+delimiter ;|
+commit;
+set autocommit = 0;
+update t1 set b = b + 5 where a = 1;
+update t2 set b = b + 5 where a = 1;
+update t3 set b = b + 5 where a = 1;
+update t4 set b = b + 5 where a = 1;
+insert into t5(a) values(20);
+connection b;
+set autocommit = 0;
+insert into t1(a) values(7);
+insert into t2(a) values(8);
+delete from t2 where a = 3;
+update t4 set b = b + 1 where a = 3;
+commit;
+drop trigger t1t;
+drop trigger t2t;
+drop trigger t3t;
+drop trigger t4t;
+drop table t1, t2, t3, t4, t5;
+disconnect a;
+disconnect b;
--- 1.258/sql/ha_innodb.cc 2006-02-26 00:20:52 +03:00
+++ 1.259/sql/ha_innodb.cc 2006-03-03 22:34:15 +03:00
@@ -137,8 +137,6 @@
#define HA_INNOBASE_ROWS_IN_TABLE 10000 /* to get optimization right */
#define HA_INNOBASE_RANGE_COUNT 100
-uint innobase_init_flags = 0;
-ulong innobase_cache_size = 0;
ulong innobase_large_page_size = 0;
/* The default values for the following, type long or longlong, start-up
@@ -166,7 +164,6 @@
/* Below we have boolean-valued start-up parameters, and their default
values */
-uint innobase_flush_log_at_trx_commit = 1;
ulong innobase_fast_shutdown = 1;
my_bool innobase_log_archive = FALSE;/* unused */
my_bool innobase_use_doublewrite = TRUE;
@@ -187,8 +184,6 @@
#define INNOBASE_WAKE_INTERVAL 32
ulong innobase_active_counter = 0;
-char* innobase_home = NULL;
-
static HASH innobase_open_tables;
#ifdef __NETWARE__ /* some special cleanup for NetWare */
@@ -235,13 +230,7 @@
innobase_start_trx_and_assign_read_view, /* Start Consistent Snapshot */
innobase_flush_logs, /* Flush logs */
innobase_show_status, /* Show status */
- NULL, /* Partition flags */
- NULL, /* Alter table flags */
- NULL, /* alter_tablespace */
- NULL, /* Fill FILES table */
- HTON_NO_FLAGS,
- NULL, /* binlog_func */
- NULL /* binlog_log_query */
+ HTON_NO_FLAGS
};
@@ -359,7 +348,7 @@
/*=========================*/
trx_t* trx) /* in: transaction handle */
{
- if (UNIV_LIKELY(srv_thread_concurrency >= SRV_CONCURRENCY_THRESHOLD)) {
+ if (UNIV_LIKELY(!srv_thread_concurrency)) {
return;
}
@@ -376,7 +365,7 @@
/*========================*/
trx_t* trx) /* in: transaction handle */
{
- if (UNIV_LIKELY(srv_thread_concurrency >= SRV_CONCURRENCY_THRESHOLD)) {
+ if (UNIV_LIKELY(!srv_thread_concurrency)) {
return;
}
@@ -468,10 +457,6 @@
return(HA_ERR_FOUND_DUPP_KEY);
- } else if (error == (int) DB_FOREIGN_DUPLICATE_KEY) {
-
- return(HA_ERR_FOREIGN_DUPLICATE_KEY);
-
} else if (error == (int) DB_RECORD_NOT_FOUND) {
return(HA_ERR_NO_ACTIVE_RECORD);
@@ -841,7 +826,6 @@
HA_PRIMARY_KEY_IN_READ_INDEX |
HA_CAN_GEOMETRY |
HA_TABLE_SCAN_ON_INDEX),
- last_dup_key((uint) -1),
start_of_scan(0),
num_write_row(0)
{}
@@ -1010,6 +994,11 @@
sql_print_error("The calling thread is holding the adaptive "
"search, latch though calling "
"innobase_query_caching_of_table_permitted.");
+
+ mutex_enter_noninline(&kernel_mutex);
+ trx_print(stderr, trx, 1024);
+ mutex_exit_noninline(&kernel_mutex);
+ ut_error;
}
innobase_release_stat_resources(trx);
@@ -1367,7 +1356,6 @@
srv_log_archive_on = (ulint) innobase_log_archive;
#endif /* UNIV_LOG_ARCHIVE */
srv_log_buffer_size = (ulint) innobase_log_buffer_size;
- srv_flush_log_at_trx_commit = (ulint) innobase_flush_log_at_trx_commit;
/* We set srv_pool_size here in units of 1 kB. InnoDB internally
changes the value so that it becomes the number of database pages. */
@@ -1417,6 +1405,7 @@
ut_a(DATA_MYSQL_LATIN1_SWEDISH_CHARSET_COLL ==
my_charset_latin1.number);
+ ut_a(DATA_MYSQL_BINARY_CHARSET_COLL == my_charset_bin.number);
/* Store the latin1_swedish_ci character ordering table to InnoDB. For
non-latin1_swedish_ci charsets we use the MySQL comparison functions,
@@ -1841,7 +1830,7 @@
trx->active_trans = 0;
- if (srv_flush_log_at_trx_commit == 0) {
+ if (UNIV_UNLIKELY(srv_flush_log_at_trx_commit == 0)) {
return(0);
}
@@ -2878,8 +2867,6 @@
char* buff_start = buff;
enum_field_types mysql_type;
Field* field;
- ulint blob_len;
- byte* blob_data;
ibool is_null;
DBUG_ENTER("store_key_val_for_row");
@@ -2934,14 +2921,18 @@
ulint len;
byte* data;
ulint key_len;
+ ulint true_len;
CHARSET_INFO* cs;
int error=0;
+ key_len = key_part->length;
+
if (is_null) {
- buff += key_part->length + 2;
+ buff += key_len + 2;
continue;
}
+ cs = field->charset();
lenlen = (ulint)
(((Field_varstring*)field)->length_bytes);
@@ -2951,32 +2942,33 @@
+ (ulint)get_field_offset(table, field)),
lenlen);
- /* In a column prefix index, we may need to truncate
- the stored value: */
-
- cs = key_part->field->charset();
+ true_len = len;
- if (cs->mbmaxlen > 1 && key_part->length > 0) {
- key_len = (ulint) cs->cset->well_formed_len(cs,
- (const char *) data,
- (const char *) data + key_part->length,
- key_part->length / cs->mbmaxlen,
- &error);
- } else {
- key_len = key_part->length;
+ /* For multi byte character sets we need to calculate
+ the true length of the key */
+
+ if (len > 0 && cs->mbmaxlen > 1) {
+ true_len = (ulint) cs->cset->well_formed_len(cs,
+ (const char *) data,
+ (const char *) data + len,
+ key_len / cs->mbmaxlen,
+ &error);
}
- if (len > key_len) {
- len = key_len;
+ /* In a column prefix index, we may need to truncate
+ the stored value: */
+
+ if (true_len > key_len) {
+ true_len = key_len;
}
/* The length in a key value is always stored in 2
bytes */
- row_mysql_store_true_var_len((byte*)buff, len, 2);
+ row_mysql_store_true_var_len((byte*)buff, true_len, 2);
buff += 2;
- memcpy(buff, data, len);
+ memcpy(buff, data, true_len);
/* Note that we always reserve the maximum possible
length of the true VARCHAR in the key value, though
@@ -2984,7 +2976,7 @@
actual data. The rest of the space was reset to zero
in the bzero() call above. */
- buff += key_part->length;
+ buff += key_len;
} else if (mysql_type == FIELD_TYPE_TINY_BLOB
|| mysql_type == FIELD_TYPE_MEDIUM_BLOB
@@ -2994,58 +2986,66 @@
CHARSET_INFO* cs;
ulint key_len;
ulint len;
+ ulint true_len;
int error=0;
+ ulint blob_len;
+ byte* blob_data;
ut_a(key_part->key_part_flag & HA_PART_KEY_SEG);
+ key_len = key_part->length;
+
if (is_null) {
- buff += key_part->length + 2;
+ buff += key_len + 2;
continue;
}
+ cs = field->charset();
+
blob_data = row_mysql_read_blob_ref(&blob_len,
(byte*) (record
+ (ulint)get_field_offset(table, field)),
(ulint) field->pack_length());
+ true_len = blob_len;
+
ut_a(get_field_offset(table, field)
== key_part->offset);
+ /* For multi byte character sets we need to calculate
+ the true length of the key */
+
+ if (blob_len > 0 && cs->mbmaxlen > 1) {
+ true_len = (ulint) cs->cset->well_formed_len(cs,
+ (const char *) blob_data,
+ (const char *) blob_data
+ + blob_len,
+ key_len / cs->mbmaxlen,
+ &error);
+ }
+
/* All indexes on BLOB and TEXT are column prefix
indexes, and we may need to truncate the data to be
stored in the key value: */
- cs = key_part->field->charset();
-
- if (cs->mbmaxlen > 1 && key_part->length > 0) {
- key_len = (ulint) cs->cset->well_formed_len(cs,
- (const char *) blob_data,
- (const char *) blob_data
- + key_part->length,
- key_part->length / cs->mbmaxlen,
- &error);
- } else {
- key_len = key_part->length;
- }
-
- if (blob_len > key_len) {
- blob_len = key_len;
+ if (true_len > key_len) {
+ true_len = key_len;
}
/* MySQL reserves 2 bytes for the length and the
storage of the number is little-endian */
innobase_write_to_2_little_endian(
- (byte*)buff, (ulint)blob_len);
+ (byte*)buff, true_len);
buff += 2;
- memcpy(buff, blob_data, blob_len);
+ memcpy(buff, blob_data, true_len);
/* Note that we always reserve the maximum possible
length of the BLOB prefix in the key value. */
- buff += key_part->length;
+ buff += key_len;
} else {
/* Here we handle all other data types except the
true VARCHAR, BLOB and TEXT. Note that the column
@@ -3053,34 +3053,53 @@
index. */
CHARSET_INFO* cs;
- ulint len;
+ ulint true_len;
+ ulint key_len;
const mysql_byte* src_start;
int error=0;
+ enum_field_types real_type;
+
+ key_len = key_part->length;
if (is_null) {
- buff += key_part->length;
+ buff += key_len;
continue;
}
- /* In a column prefix index, we may need to truncate
- the stored value: */
-
- cs = key_part->field->charset();
src_start = record + key_part->offset;
+ real_type = field->real_type();
+ true_len = key_len;
- if (key_part->length > 0 && cs->mbmaxlen > 1) {
- len = (ulint) cs->cset->well_formed_len(cs,
- (const char *) src_start,
- (const char *) src_start + key_part->length,
- key_part->length / cs->mbmaxlen,
- &error);
- } else {
- len = key_part->length;
+ /* Character set for the field is defined only
+ to fields whose type is string and real field
+ type is not enum or set. For these fields check
+ if character set is multi byte. */
+
+ if (real_type != FIELD_TYPE_ENUM
+ && real_type != FIELD_TYPE_SET
+ && ( mysql_type == MYSQL_TYPE_VAR_STRING
+ || mysql_type == MYSQL_TYPE_STRING)) {
+
+ cs = field->charset();
+
+ /* For multi byte character sets we need to
+ calculate the true length of the key */
+
+ if (key_len > 0 && cs->mbmaxlen > 1) {
+
+ true_len = (ulint)
+ cs->cset->well_formed_len(cs,
+ (const char *)src_start,
+ (const char *)src_start
+ + key_len,
+ key_len / cs->mbmaxlen,
+ &error);
+ }
}
- memcpy(buff, src_start, len);
- buff+=len;
+ memcpy(buff, src_start, true_len);
+ buff += true_len;
/* Pad the unused space with spaces. Note that no
padding is ever needed for UCS-2 because in MySQL,
@@ -3088,10 +3107,10 @@
support surrogate pairs, which are needed to represent
characters in the range U+10000 to U+10FFFF. */
- if (len < key_part->length) {
- len = key_part->length - len;
- memset(buff, ' ', len);
- buff+=len;
+ if (true_len < key_len) {
+ ulint pad_len = key_len - true_len;
+ memset(buff, ' ', pad_len);
+ buff += pad_len;
}
}
}
@@ -5764,7 +5783,7 @@
}
/**************************************************************************
-This is mapped to "ALTER TABLE tablename ENGINE=InnoDB", which rebuilds
+This is mapped to "ALTER TABLE tablename TYPE=InnoDB", which rebuilds
the table in MySQL. */
int
@@ -5828,6 +5847,7 @@
uint length = (uint) strlen(comment);
char* str;
row_prebuilt_t* prebuilt = (row_prebuilt_t*)innobase_prebuilt;
+ long flen;
/* We do not know if MySQL can call this function before calling
external_lock(). To be safe, update the thd of the current table
@@ -5847,43 +5867,43 @@
trx_search_latch_release_if_reserved(prebuilt->trx);
str = NULL;
- if (FILE* file = os_file_create_tmpfile()) {
- long flen;
+ /* output the data to a temporary file */
- /* output the data to a temporary file */
- fprintf(file, "InnoDB free: %lu kB",
+ mutex_enter_noninline(&srv_dict_tmpfile_mutex);
+ rewind(srv_dict_tmpfile);
+
+ fprintf(srv_dict_tmpfile, "InnoDB free: %lu kB",
(ulong) fsp_get_available_space_in_free_extents(
prebuilt->table->space));
- dict_print_info_on_foreign_keys(FALSE, file,
+ dict_print_info_on_foreign_keys(FALSE, srv_dict_tmpfile,
prebuilt->trx, prebuilt->table);
- flen = ftell(file);
- if (flen < 0) {
- flen = 0;
- } else if (length + flen + 3 > 64000) {
- flen = 64000 - 3 - length;
- }
-
- /* allocate buffer for the full string, and
- read the contents of the temporary file */
-
- str = my_malloc(length + flen + 3, MYF(0));
-
- if (str) {
- char* pos = str + length;
- if (length) {
- memcpy(str, comment, length);
- *pos++ = ';';
- *pos++ = ' ';
- }
- rewind(file);
- flen = (uint) fread(pos, 1, flen, file);
- pos[flen] = 0;
- }
+ flen = ftell(srv_dict_tmpfile);
+ if (flen < 0) {
+ flen = 0;
+ } else if (length + flen + 3 > 64000) {
+ flen = 64000 - 3 - length;
+ }
- fclose(file);
+ /* allocate buffer for the full string, and
+ read the contents of the temporary file */
+
+ str = my_malloc(length + flen + 3, MYF(0));
+
+ if (str) {
+ char* pos = str + length;
+ if (length) {
+ memcpy(str, comment, length);
+ *pos++ = ';';
+ *pos++ = ' ';
+ }
+ rewind(srv_dict_tmpfile);
+ flen = (uint) fread(pos, 1, flen, srv_dict_tmpfile);
+ pos[flen] = 0;
}
+ mutex_exit_noninline(&srv_dict_tmpfile_mutex);
+
prebuilt->trx->op_info = (char*)"";
return(str ? str : (char*) comment);
@@ -5901,6 +5921,7 @@
{
row_prebuilt_t* prebuilt = (row_prebuilt_t*)innobase_prebuilt;
char* str = 0;
+ long flen;
ut_a(prebuilt != NULL);
@@ -5910,47 +5931,42 @@
update_thd(current_thd);
- if (FILE* file = os_file_create_tmpfile()) {
- long flen;
+ prebuilt->trx->op_info = (char*)"getting info on foreign keys";
- prebuilt->trx->op_info = (char*)"getting info on foreign keys";
+ /* In case MySQL calls this in the middle of a SELECT query,
+ release possible adaptive hash latch to avoid
+ deadlocks of threads */
- /* In case MySQL calls this in the middle of a SELECT query,
- release possible adaptive hash latch to avoid
- deadlocks of threads */
+ trx_search_latch_release_if_reserved(prebuilt->trx);
- trx_search_latch_release_if_reserved(prebuilt->trx);
+ mutex_enter_noninline(&srv_dict_tmpfile_mutex);
+ rewind(srv_dict_tmpfile);
- /* output the data to a temporary file */
- dict_print_info_on_foreign_keys(TRUE, file,
+ /* output the data to a temporary file */
+ dict_print_info_on_foreign_keys(TRUE, srv_dict_tmpfile,
prebuilt->trx, prebuilt->table);
- prebuilt->trx->op_info = (char*)"";
-
- flen = ftell(file);
- if (flen < 0) {
- flen = 0;
- } else if (flen > 64000 - 1) {
- flen = 64000 - 1;
- }
+ prebuilt->trx->op_info = (char*)"";
- /* allocate buffer for the string, and
- read the contents of the temporary file */
+ flen = ftell(srv_dict_tmpfile);
+ if (flen < 0) {
+ flen = 0;
+ } else if (flen > 64000 - 1) {
+ flen = 64000 - 1;
+ }
- str = my_malloc(flen + 1, MYF(0));
+ /* allocate buffer for the string, and
+ read the contents of the temporary file */
- if (str) {
- rewind(file);
- flen = (uint) fread(str, 1, flen, file);
- str[flen] = 0;
- }
+ str = my_malloc(flen + 1, MYF(0));
- fclose(file);
- } else {
- /* unable to create temporary file */
- str = my_strdup(
-"/* Error: cannot display foreign key constraints */", MYF(0));
+ if (str) {
+ rewind(srv_dict_tmpfile);
+ flen = (uint) fread(str, 1, flen, srv_dict_tmpfile);
+ str[flen] = 0;
}
+ mutex_exit_noninline(&srv_dict_tmpfile_mutex);
+
return(str);
}
@@ -6380,14 +6396,17 @@
TABLES if AUTOCOMMIT=1. It does not make much sense to acquire
an InnoDB table lock if it is released immediately at the end
of LOCK TABLES, and InnoDB's table locks in that case cause
- VERY easily deadlocks. We do not set InnoDB table locks when
- MySQL sets them at the start of a stored procedure call
- (MySQL does have thd->in_lock_tables TRUE there). */
+ VERY easily deadlocks.
+
+ We do not set InnoDB table locks if user has not explicitly
+ requested a table lock. Note that thd->in_lock_tables
+ can be TRUE on some cases e.g. at the start of a stored
+ procedure call (SQLCOM_CALL). */
if (prebuilt->select_lock_type != LOCK_NONE) {
if (thd->in_lock_tables &&
- thd->lex->sql_command != SQLCOM_CALL &&
+ thd->lex->sql_command == SQLCOM_LOCK_TABLES &&
thd->variables.innodb_table_locks &&
(thd->options & OPTION_NOT_AUTOCOMMIT)) {
@@ -6542,7 +6561,7 @@
int
innodb_export_status()
-/*======================*/
+/*==================*/
{
if (innodb_inited)
srv_export_innodb_status();
@@ -6875,7 +6894,7 @@
} else if (lock_type != TL_IGNORE) {
- /* We set possible LOCK_X value in external_lock, not yet
+ /* We set possible LOCK_X value in external_lock, not yet
here even if this would be SELECT ... FOR UPDATE */
prebuilt->select_lock_type = LOCK_NONE;
@@ -6884,7 +6903,7 @@
if (lock_type != TL_IGNORE && lock.type == TL_UNLOCK) {
- /* Starting from 5.0.7, we weaken also the table locks
+ /* Starting from 5.0.7, we weaken also the table locks
set at the start of a MySQL stored procedure call, just like
we weaken the locks set at the start of an SQL statement.
MySQL does set thd->in_lock_tables TRUE there, but in reality
@@ -6907,26 +6926,36 @@
lock_type = TL_READ_NO_INSERT;
}
- /* If we are not doing a LOCK TABLE or DISCARD/IMPORT
- TABLESPACE or TRUNCATE TABLE, then allow multiple writers */
+ /* If we are not doing a LOCK TABLE, DISCARD/IMPORT
+ TABLESPACE or TRUNCATE TABLE then allow multiple
+ writers. Note that ALTER TABLE uses a TL_WRITE_ALLOW_READ
+ < TL_WRITE_CONCURRENT_INSERT.
+
+ We especially allow multiple writers if MySQL is at the
+ start of a stored procedure call (SQLCOM_CALL)
+ (MySQL does have thd->in_lock_tables TRUE there). */
- if ((lock_type >= TL_WRITE_CONCURRENT_INSERT &&
- lock_type <= TL_WRITE)
+ if ((lock_type >= TL_WRITE_CONCURRENT_INSERT
+ && lock_type <= TL_WRITE)
&& (!thd->in_lock_tables
- || thd->lex->sql_command == SQLCOM_CALL)
+ || thd->lex->sql_command == SQLCOM_CALL)
&& !thd->tablespace_op
&& thd->lex->sql_command != SQLCOM_TRUNCATE
- && thd->lex->sql_command != SQLCOM_OPTIMIZE
- && thd->lex->sql_command != SQLCOM_CREATE_TABLE) {
+ && thd->lex->sql_command != SQLCOM_OPTIMIZE
+ && thd->lex->sql_command != SQLCOM_CREATE_TABLE) {
- lock_type = TL_WRITE_ALLOW_WRITE;
+ lock_type = TL_WRITE_ALLOW_WRITE;
}
/* In queries of type INSERT INTO t1 SELECT ... FROM t2 ...
MySQL would use the lock TL_READ_NO_INSERT on t2, and that
would conflict with TL_WRITE_ALLOW_WRITE, blocking all inserts
to t2. Convert the lock to a normal read lock to allow
- concurrent inserts to t2. */
+ concurrent inserts to t2.
+
+ We especially allow concurrent inserts if MySQL is at the
+ start of a stored procedure call (SQLCOM_CALL)
+ (MySQL does have thd->in_lock_tables TRUE there). */
if (lock_type == TL_READ_NO_INSERT
&& (!thd->in_lock_tables
@@ -6935,10 +6964,10 @@
lock_type = TL_READ;
}
- lock.type = lock_type;
- }
+ lock.type = lock_type;
+ }
- *to++= &lock;
+ *to++= &lock;
return(to);
}
--- 1.117/sql/ha_innodb.h 2006-02-08 13:58:49 +03:00
+++ 1.118/sql/ha_innodb.h 2006-03-03 22:34:15 +03:00
@@ -52,7 +52,6 @@
THR_LOCK_DATA lock;
INNOBASE_SHARE *share;
- gptr alloc_ptr;
byte* upd_buff; /* buffer used in updates */
byte* key_val_buff; /* buffer used in converting
search key values from MySQL format
@@ -62,7 +61,6 @@
two buffers */
ulong int_table_flags;
uint primary_key;
- uint last_dup_key;
ulong start_of_scan; /* this is set to 1 when we are
starting a table scan but have not
yet fetched any row, else 0 */
@@ -70,7 +68,6 @@
ROW_SEL_EXACT, ROW_SEL_EXACT_PREFIX,
or undefined */
uint num_write_row; /* number of write_row() calls */
- ulong max_supported_row_length(const byte *buf);
uint store_key_val_for_row(uint keynr, char* buff, uint buff_len,
const byte* record);
@@ -213,12 +210,8 @@
};
extern SHOW_VAR innodb_status_variables[];
-extern uint innobase_init_flags, innobase_lock_type;
-extern uint innobase_flush_log_at_trx_commit;
-extern ulong innobase_cache_size, innobase_fast_shutdown;
+extern ulong innobase_fast_shutdown;
extern ulong innobase_large_page_size;
-extern char *innobase_home, *innobase_tmpdir, *innobase_logdir;
-extern long innobase_lock_scan_time;
extern long innobase_mirrored_log_groups, innobase_log_files_in_group;
extern longlong innobase_buffer_pool_size, innobase_log_file_size;
extern long innobase_log_buffer_size;
@@ -252,10 +245,9 @@
extern ulong srv_thread_sleep_delay;
extern ulong srv_thread_concurrency;
extern ulong srv_commit_concurrency;
+extern ulong srv_flush_log_at_trx_commit;
}
-extern TYPELIB innobase_lock_typelib;
-
bool innobase_init(void);
int innobase_end(ha_panic_function type);
bool innobase_flush_logs(void);
@@ -321,9 +313,6 @@
int innobase_rollback_by_xid(
/* out: 0 or error number */
XID *xid); /* in : X/Open XA Transaction Identification */
-
-
-int innobase_xa_end(THD *thd);
int innobase_repl_report_sent_binlog(THD *thd, char *log_file_name,
--- 1.13/mysql-test/r/innodb_cache.result 2006-01-23 14:16:57 +03:00
+++ 1.14/mysql-test/r/innodb_cache.result 2006-03-03 22:34:14 +03:00
@@ -121,7 +121,7 @@
begin;
insert into t3 VALUES ( NULL, 1, 1, 2 );
insert into t3 VALUES ( NULL, 1, 1, 2 );
-ERROR 23000: Duplicate entry '1-1' for key 't1_id'
+ERROR 23000: Duplicate entry '1-1' for key 2
commit;
select t1.* from t1, t2, t3 where t3.state & 1 = 0 and t3.t1_id = t1.id and t3.t2_id = t2.id and t1.id = 1 order by t1.a asc;
id a
--- 1.12/mysql-test/t/innodb_cache.test 2006-01-26 19:54:27 +03:00
+++ 1.13/mysql-test/t/innodb_cache.test 2006-03-03 22:34:15 +03:00
@@ -63,7 +63,6 @@
#
# one statement roll back inside transation
#
-let $save_query_cache_size=`select @@global.query_cache_size`;
set GLOBAL query_cache_size=1355776;
CREATE TABLE t1 ( id int(10) NOT NULL auto_increment, a varchar(25) default NULL, PRIMARY KEY (id), UNIQUE KEY a (a)) ENGINE=innodb;
CREATE TABLE t2 ( id int(10) NOT NULL auto_increment, b varchar(25) default NULL, PRIMARY KEY (id), UNIQUE KEY b (b)) ENGINE=innodb;
@@ -80,8 +79,5 @@
commit;
select t1.* from t1, t2, t3 where t3.state & 1 = 0 and t3.t1_id = t1.id and t3.t2_id = t2.id and t1.id = 1 order by t1.a asc;
drop table t3,t2,t1;
---disable_query_log
-eval set GLOBAL query_cache_size=$save_query_cache_size;
---enable_query_log
# End of 4.1 tests
| Thread |
|---|
| • bk commit into 5.1 tree (aivanov:1.2214) | Alex Ivanov Notebook | 3 Mar |