diff options
author | unknown <tsmith@sita.local> | 2007-07-10 07:31:08 -0600 |
---|---|---|
committer | unknown <tsmith@sita.local> | 2007-07-10 07:31:08 -0600 |
commit | 1f741d8bbd0c6b9ff529ab1a7ac75e34aedd7929 (patch) | |
tree | f2140a31fc52a8ea5958c4de2ca69952c41a2693 /storage | |
parent | 22531a8e7b6f83d7059e703e52b5bcf78d0b1a73 (diff) | |
parent | 32b5fb73233422429cd1ed9629c56367e4e922fa (diff) | |
download | mariadb-git-1f741d8bbd0c6b9ff529ab1a7ac75e34aedd7929.tar.gz |
Merge sita.local:/Users/tsmith/m/bk/inno/jul5/51-snap
into sita.local:/Users/tsmith/m/bk/maint/51
Diffstat (limited to 'storage')
68 files changed, 1155 insertions, 1480 deletions
diff --git a/storage/innobase/Makefile.am b/storage/innobase/Makefile.am index 62c0f8e817c..0b23ae74f9e 100644 --- a/storage/innobase/Makefile.am +++ b/storage/innobase/Makefile.am @@ -25,102 +25,146 @@ INCLUDES = -I$(top_srcdir)/include -I$(top_builddir)/include \ -I$(top_srcdir)/sql \ -I$(srcdir) -AUTOMAKE_OPTIONS = foreign -TAR = gtar +DEFS = @DEFS@ -noinst_HEADERS = -SUBDIRS = os ut btr buf data dict dyn eval fil fsp fut \ - ha ibuf lock log mach mem mtr page \ - handler \ - pars que read rem row srv sync thr trx usr +noinst_HEADERS = include/btr0btr.h include/btr0btr.ic \ + include/btr0cur.h include/btr0cur.ic \ + include/btr0pcur.h include/btr0pcur.ic \ + include/btr0sea.h include/btr0sea.ic \ + include/btr0types.h include/buf0buf.h \ + include/buf0buf.ic include/buf0flu.h \ + include/buf0flu.ic include/buf0lru.h \ + include/buf0lru.ic include/buf0rea.h \ + include/buf0types.h include/data0data.h \ + include/data0data.ic include/data0type.h \ + include/data0type.ic include/data0types.h \ + include/db0err.h include/dict0boot.h \ + include/dict0boot.ic include/dict0crea.h \ + include/dict0crea.ic include/dict0dict.h \ + include/dict0dict.ic include/dict0load.h \ + include/dict0load.ic include/dict0mem.h \ + include/dict0mem.ic include/dict0types.h \ + include/dyn0dyn.h include/dyn0dyn.ic \ + include/eval0eval.h include/eval0eval.ic \ + include/eval0proc.h include/eval0proc.ic \ + include/fil0fil.h include/fsp0fsp.h \ + include/fsp0fsp.ic include/fut0fut.h \ + include/fut0fut.ic include/fut0lst.h \ + include/fut0lst.ic include/ha0ha.h \ + include/ha0ha.ic include/hash0hash.h \ + include/hash0hash.ic include/ibuf0ibuf.h \ + include/ibuf0ibuf.ic include/ibuf0types.h \ + include/lock0lock.h include/lock0lock.ic \ + include/lock0types.h include/log0log.h \ + include/log0log.ic include/log0recv.h \ + include/log0recv.ic include/mach0data.h \ + include/mach0data.ic include/mem0dbg.h \ + include/mem0dbg.ic mem/mem0dbg.c \ + include/mem0mem.h include/mem0mem.ic \ + include/mem0pool.h include/mem0pool.ic \ + include/mtr0log.h include/mtr0log.ic \ + include/mtr0mtr.h include/mtr0mtr.ic \ + include/mtr0types.h include/os0file.h \ + include/os0proc.h include/os0proc.ic \ + include/os0sync.h include/os0sync.ic \ + include/os0thread.h include/os0thread.ic \ + include/page0cur.h include/page0cur.ic \ + include/page0page.h include/page0page.ic \ + include/page0types.h include/pars0grm.h \ + include/pars0opt.h include/pars0opt.ic \ + include/pars0pars.h include/pars0pars.ic \ + include/pars0sym.h include/pars0sym.ic \ + include/pars0types.h include/que0que.h \ + include/que0que.ic include/que0types.h \ + include/read0read.h include/read0read.ic \ + include/read0types.h include/rem0cmp.h \ + include/rem0cmp.ic include/rem0rec.h \ + include/rem0rec.ic include/rem0types.h \ + include/row0ins.h include/row0ins.ic \ + include/row0mysql.h include/row0mysql.ic \ + include/row0purge.h include/row0purge.ic \ + include/row0row.h include/row0row.ic \ + include/row0sel.h include/row0sel.ic \ + include/row0types.h include/row0uins.h \ + include/row0uins.ic include/row0umod.h \ + include/row0umod.ic include/row0undo.h \ + include/row0undo.ic include/row0upd.h \ + include/row0upd.ic include/row0vers.h \ + include/row0vers.ic include/srv0que.h \ + include/srv0srv.h include/srv0srv.ic \ + include/srv0start.h include/sync0arr.h \ + include/sync0arr.ic include/sync0rw.h \ + include/sync0rw.ic include/sync0sync.h \ + include/sync0sync.ic include/sync0types.h \ + include/thr0loc.h include/thr0loc.ic \ + include/trx0purge.h include/trx0purge.ic \ + include/trx0rec.h include/trx0rec.ic \ + include/trx0roll.h include/trx0roll.ic \ + include/trx0rseg.h include/trx0rseg.ic \ + include/trx0sys.h include/trx0sys.ic \ + include/trx0trx.h include/trx0trx.ic \ + include/trx0types.h include/trx0undo.h \ + include/trx0undo.ic include/trx0xa.h \ + include/univ.i include/usr0sess.h \ + include/usr0sess.ic include/usr0types.h \ + include/ut0byte.h include/ut0byte.ic \ + include/ut0dbg.h include/ut0lst.h \ + include/ut0mem.h include/ut0mem.ic \ + include/ut0rnd.h include/ut0rnd.ic \ + include/ut0sort.h include/ut0ut.h \ + include/ut0ut.ic include/ut0vec.h \ + include/ut0vec.ic include/ut0list.h \ + include/ut0list.ic include/ut0wqueue.h \ + include/ha_prototypes.h handler/ha_innodb.h -EXTRA_DIST = include/btr0btr.h include/btr0btr.ic include/btr0cur.h include/btr0cur.ic \ - include/btr0pcur.h include/btr0pcur.ic include/btr0sea.h include/btr0sea.ic \ - include/btr0types.h \ - include/buf0buf.h include/buf0buf.ic include/buf0flu.h include/buf0flu.ic \ - include/buf0lru.h include/buf0lru.ic include/buf0rea.h include/buf0types.h \ - include/data0data.h include/data0data.ic include/data0type.h include/data0type.ic \ - include/data0types.h include/db0err.h \ - include/dict0boot.h include/dict0boot.ic include/dict0crea.h include/dict0crea.ic \ - include/dict0dict.h include/dict0dict.ic include/dict0load.h include/dict0load.ic \ - include/dict0mem.h include/dict0mem.ic include/dict0types.h \ - include/dyn0dyn.h include/dyn0dyn.ic \ - include/eval0eval.h include/eval0eval.ic include/eval0proc.h include/eval0proc.ic \ - include/fil0fil.h include/fsp0fsp.h include/fsp0fsp.ic \ - include/fut0fut.h include/fut0fut.ic include/fut0lst.h include/fut0lst.ic \ - include/ha0ha.h include/ha0ha.ic include/hash0hash.h include/hash0hash.ic \ - include/ibuf0ibuf.h include/ibuf0ibuf.ic include/ibuf0types.h \ - include/lock0lock.h include/lock0lock.ic include/lock0types.h \ - include/log0log.h include/log0log.ic include/log0recv.h include/log0recv.ic \ - include/mach0data.h include/mach0data.ic include/mem0dbg.h include/mem0dbg.ic \ - include/mem0mem.h include/mem0mem.ic include/mem0pool.h include/mem0pool.ic \ - include/mtr0log.h include/mtr0log.ic include/mtr0mtr.h include/mtr0mtr.ic \ - include/mtr0types.h include/os0file.h \ - include/os0proc.h include/os0proc.ic include/os0sync.h include/os0sync.ic \ - include/os0thread.h include/os0thread.ic \ - include/page0cur.h include/page0cur.ic include/page0page.h include/page0page.ic \ - include/page0types.h \ - include/pars0grm.h include/pars0opt.h include/pars0opt.ic \ - include/pars0pars.h include/pars0pars.ic include/pars0sym.h include/pars0sym.ic \ - include/pars0types.h \ - include/que0que.h include/que0que.ic include/que0types.h \ - include/read0read.h include/read0read.ic include/read0types.h \ - include/rem0cmp.h include/rem0cmp.ic include/rem0rec.h include/rem0rec.ic \ - include/rem0types.h \ - include/row0ins.h include/row0ins.ic include/row0mysql.h include/row0mysql.ic \ - include/row0purge.h include/row0purge.ic include/row0row.h include/row0row.ic \ - include/row0sel.h include/row0sel.ic include/row0types.h \ - include/row0uins.h include/row0uins.ic include/row0umod.h include/row0umod.ic \ - include/row0undo.h include/row0undo.ic include/row0upd.h include/row0upd.ic \ - include/row0vers.h include/row0vers.ic \ - include/srv0que.h include/srv0srv.h include/srv0srv.ic include/srv0start.h \ - include/sync0arr.h include/sync0arr.ic include/sync0rw.h include/sync0rw.ic \ - include/sync0sync.h include/sync0sync.ic include/sync0types.h \ - include/thr0loc.h include/thr0loc.ic \ - include/trx0purge.h include/trx0purge.ic include/trx0rec.h include/trx0rec.ic \ - include/trx0roll.h include/trx0roll.ic include/trx0rseg.h include/trx0rseg.ic \ - include/trx0sys.h include/trx0sys.ic include/trx0trx.h include/trx0trx.ic \ - include/trx0types.h include/trx0undo.h include/trx0undo.ic include/trx0xa.h \ - include/univ.i include/usr0sess.h include/usr0sess.ic include/usr0types.h \ - include/ut0byte.h include/ut0byte.ic include/ut0dbg.h include/ut0lst.h \ - include/ut0mem.h include/ut0mem.ic include/ut0rnd.h include/ut0rnd.ic \ - handler/ha_innodb.h \ - include/ut0sort.h include/ut0ut.h include/ut0ut.ic include/ut0vec.h include/ut0vec.ic include/ha_prototypes.h \ - include/ut0list.h include/ut0list.ic \ - include/ut0wqueue.h \ - pars/make_bison.sh pars/make_flex.sh \ - pars/pars0grm.y pars/pars0lex.l \ - CMakeLists.txt plug.in +EXTRA_LIBRARIES = libinnobase.a +noinst_LIBRARIES = @plugin_innobase_static_target@ +libinnobase_a_SOURCES = btr/btr0btr.c btr/btr0cur.c btr/btr0pcur.c \ + btr/btr0sea.c buf/buf0buf.c buf/buf0flu.c \ + buf/buf0lru.c buf/buf0rea.c data/data0data.c \ + data/data0type.c dict/dict0boot.c \ + dict/dict0crea.c dict/dict0dict.c \ + dict/dict0load.c dict/dict0mem.c dyn/dyn0dyn.c \ + eval/eval0eval.c eval/eval0proc.c \ + fil/fil0fil.c fsp/fsp0fsp.c fut/fut0fut.c \ + fut/fut0lst.c ha/ha0ha.c ha/hash0hash.c \ + ibuf/ibuf0ibuf.c lock/lock0lock.c \ + log/log0log.c log/log0recv.c mach/mach0data.c \ + mem/mem0mem.c mem/mem0pool.c mtr/mtr0log.c \ + mtr/mtr0mtr.c os/os0file.c os/os0proc.c \ + os/os0sync.c os/os0thread.c page/page0cur.c \ + page/page0page.c pars/lexyy.c pars/pars0grm.c \ + pars/pars0opt.c pars/pars0pars.c \ + pars/pars0sym.c que/que0que.c read/read0read.c \ + rem/rem0cmp.c rem/rem0rec.c row/row0ins.c \ + row/row0mysql.c row/row0purge.c row/row0row.c \ + row/row0sel.c row/row0uins.c row/row0umod.c \ + row/row0undo.c row/row0upd.c row/row0vers.c \ + srv/srv0que.c srv/srv0srv.c srv/srv0start.c \ + sync/sync0arr.c sync/sync0rw.c \ + sync/sync0sync.c thr/thr0loc.c trx/trx0purge.c \ + trx/trx0rec.c trx/trx0roll.c trx/trx0rseg.c \ + trx/trx0sys.c trx/trx0trx.c trx/trx0undo.c \ + usr/usr0sess.c ut/ut0byte.c ut/ut0dbg.c \ + ut/ut0list.c ut/ut0mem.c ut/ut0rnd.c \ + ut/ut0ut.c ut/ut0vec.c ut/ut0wqueue.c \ + handler/ha_innodb.cc -noinst_LIBRARIES = libinnobase.a -libinnobase_a_LIBADD = usr/libusr.a srv/libsrv.a dict/libdict.a \ - que/libque.a srv/libsrv.a ibuf/libibuf.a \ - row/librow.a pars/libpars.a btr/libbtr.a \ - trx/libtrx.a read/libread.a usr/libusr.a \ - buf/libbuf.a ibuf/libibuf.a eval/libeval.a \ - log/liblog.a fsp/libfsp.a fut/libfut.a \ - fil/libfil.a lock/liblock.a mtr/libmtr.a \ - page/libpage.a rem/librem.a thr/libthr.a \ - sync/libsync.a data/libdata.a mach/libmach.a \ - ha/libha.a dyn/libdyn.a mem/libmem.a \ - handler/libhandler.a \ - ut/libut.a os/libos.a ut/libut.a -libinnobase_a_SOURCES = +libinnobase_a_CXXFLAGS= $(AM_CFLAGS) +libinnobase_a_CFLAGS = $(AM_CFLAGS) +EXTRA_LTLIBRARIES = ha_innodb.la +pkglib_LTLIBRARIES = @plugin_innobase_shared_target@ -libinnobase.a: $(libinnobase_a_LIBADD) - -rm -f $@ - if test "$(host_os)" = "netware" ; \ - then \ - $(libinnobase_a_AR) $@ $(libinnobase_a_LIBADD) ; \ - else \ - for arc in $(libinnobase_a_LIBADD); do \ - arpath=`echo $$arc|sed 's|[^/]*$$||'`; \ - $(AR) t $$arc|sed "s|^|$$arpath|"; \ - done | sort -u | xargs $(AR) cq $@ ; \ - $(RANLIB) $@ ; \ - fi +ha_innodb_la_LDFLAGS = -module -rpath $(MYSQLLIBdir) +ha_innodb_la_CXXFLAGS= $(AM_CFLAGS) -DMYSQL_DYNAMIC_PLUGIN +ha_innodb_la_CFLAGS = $(AM_CFLAGS) -DMYSQL_DYNAMIC_PLUGIN +ha_innodb_la_SOURCES = $(libinnobase_a_SOURCES) + +EXTRA_DIST = CMakeLists.txt plug.in \ + pars/make_bison.sh pars/make_flex.sh \ + pars/pars0grm.y pars/pars0lex.l # Don't update the files from bitkeeper %::SCCS/s.% diff --git a/storage/innobase/btr/Makefile.am b/storage/innobase/btr/Makefile.am deleted file mode 100644 index 6b09b289cdc..00000000000 --- a/storage/innobase/btr/Makefile.am +++ /dev/null @@ -1,25 +0,0 @@ -# Copyright (C) 2001, 2003 MySQL AB & Innobase Oy -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; version 2 of the License. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - -include ../include/Makefile.i - -noinst_LIBRARIES = libbtr.a - -libbtr_a_SOURCES = btr0btr.c btr0cur.c btr0pcur.c btr0sea.c - -EXTRA_PROGRAMS = - -# Don't update the files from bitkeeper -%::SCCS/s.% diff --git a/storage/innobase/btr/btr0btr.c b/storage/innobase/btr/btr0btr.c index 50a349e78d6..6e8b43aeb8d 100644 --- a/storage/innobase/btr/btr0btr.c +++ b/storage/innobase/btr/btr0btr.c @@ -2606,8 +2606,11 @@ btr_index_rec_validate( rec_get_nth_field(rec, offsets, i, &len); - /* Note that prefix indexes are not fixed size even when - their type is CHAR. */ + /* Note that if fixed_size != 0, it equals the + length of a fixed-size column in the clustered index. + A prefix index of the column is of fixed, but different + length. When fixed_size == 0, prefix_len is the maximum + length of the prefix index column. */ if ((dict_index_get_nth_field(index, i)->prefix_len == 0 && len != UNIV_SQL_NULL && fixed_size diff --git a/storage/innobase/buf/Makefile.am b/storage/innobase/buf/Makefile.am deleted file mode 100644 index 946d5a2e5c2..00000000000 --- a/storage/innobase/buf/Makefile.am +++ /dev/null @@ -1,25 +0,0 @@ -# Copyright (C) 2001, 2003 MySQL AB & Innobase Oy -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; version 2 of the License. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - -include ../include/Makefile.i - -noinst_LIBRARIES = libbuf.a - -libbuf_a_SOURCES = buf0buf.c buf0flu.c buf0lru.c buf0rea.c - -EXTRA_PROGRAMS = - -# Don't update the files from bitkeeper -%::SCCS/s.% diff --git a/storage/innobase/data/Makefile.am b/storage/innobase/data/Makefile.am deleted file mode 100644 index 6f9407d40e5..00000000000 --- a/storage/innobase/data/Makefile.am +++ /dev/null @@ -1,25 +0,0 @@ -# Copyright (C) 2001, 2003 MySQL AB & Innobase Oy -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; version 2 of the License. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - -include ../include/Makefile.i - -noinst_LIBRARIES = libdata.a - -libdata_a_SOURCES = data0data.c data0type.c - -EXTRA_PROGRAMS = - -# Don't update the files from bitkeeper -%::SCCS/s.% diff --git a/storage/innobase/data/data0data.c b/storage/innobase/data/data0data.c index fc4494d991a..0f03de4ca9d 100644 --- a/storage/innobase/data/data0data.c +++ b/storage/innobase/data/data0data.c @@ -18,6 +18,8 @@ Created 5/30/1994 Heikki Tuuri #include "dict0dict.h" #include "btr0cur.h" +#include <ctype.h> + #ifdef UNIV_DEBUG byte data_error; /* data pointers of tuple fields are initialized to point here for error checking */ diff --git a/storage/innobase/data/data0type.c b/storage/innobase/data/data0type.c index 77779d185cf..305000d7c0a 100644 --- a/storage/innobase/data/data0type.c +++ b/storage/innobase/data/data0type.c @@ -190,7 +190,8 @@ dtype_validate( dtype_t* type) /* in: type struct to validate */ { ut_a(type); - ut_a((type->mtype >= DATA_VARCHAR) && (type->mtype <= DATA_MYSQL)); + ut_a(type->mtype >= DATA_VARCHAR); + ut_a(type->mtype <= DATA_MYSQL); if (type->mtype == DATA_SYS) { ut_a((type->prtype & DATA_MYSQL_TYPE_MASK) < DATA_N_SYS_COLS); diff --git a/storage/innobase/dict/Makefile.am b/storage/innobase/dict/Makefile.am deleted file mode 100644 index 15cacca6f58..00000000000 --- a/storage/innobase/dict/Makefile.am +++ /dev/null @@ -1,26 +0,0 @@ -# Copyright (C) 2001, 2003 MySQL AB & Innobase Oy -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; version 2 of the License. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - -include ../include/Makefile.i - -noinst_LIBRARIES = libdict.a - -libdict_a_SOURCES = dict0boot.c dict0crea.c dict0dict.c dict0load.c\ - dict0mem.c - -EXTRA_PROGRAMS = - -# Don't update the files from bitkeeper -%::SCCS/s.% diff --git a/storage/innobase/dict/dict0crea.c b/storage/innobase/dict/dict0crea.c index e060d45768e..51146c3c24c 100644 --- a/storage/innobase/dict/dict0crea.c +++ b/storage/innobase/dict/dict0crea.c @@ -1195,7 +1195,8 @@ dict_create_or_check_foreign_constraint_tables(void) fprintf(stderr, "InnoDB: error %lu in creation\n", (ulong) error); - ut_a(error == DB_OUT_OF_FILE_SPACE); + ut_a(error == DB_OUT_OF_FILE_SPACE + || error == DB_TOO_MANY_CONCURRENT_TRXS); fprintf(stderr, "InnoDB: creation failed\n" diff --git a/storage/innobase/dict/dict0dict.c b/storage/innobase/dict/dict0dict.c index f450d3553eb..e2a9535dc8b 100644 --- a/storage/innobase/dict/dict0dict.c +++ b/storage/innobase/dict/dict0dict.c @@ -30,6 +30,8 @@ Created 1/8/1996 Heikki Tuuri # include "m_ctype.h" /* my_isspace() */ #endif /* !UNIV_HOTBACKUP */ +#include <ctype.h> + dict_sys_t* dict_sys = NULL; /* the dictionary system */ rw_lock_t dict_operation_lock; /* table create, drop, etc. reserve @@ -1529,6 +1531,12 @@ dict_index_add_col( if (field->fixed_len > DICT_MAX_INDEX_COL_LEN) { field->fixed_len = 0; } +#if DICT_MAX_INDEX_COL_LEN != 768 + /* The comparison limit above must be constant. If it were + changed, the disk format of some fixed-length columns would + change, which would be a disaster. */ +# error "DICT_MAX_INDEX_COL_LEN != 768" +#endif if (!(col->prtype & DATA_NOT_NULL)) { index->n_nullable++; @@ -1585,9 +1593,6 @@ dict_index_copy_types( ifield = dict_index_get_nth_field(index, i); dfield_type = dfield_get_type(dtuple_get_nth_field(tuple, i)); dict_col_copy_type(dict_field_get_col(ifield), dfield_type); - if (UNIV_UNLIKELY(ifield->prefix_len)) { - dfield_type->len = ifield->prefix_len; - } } } @@ -3361,7 +3366,8 @@ dict_create_foreign_constraints( ulint err; mem_heap_t* heap; - ut_a(trx && trx->mysql_thd); + ut_a(trx); + ut_a(trx->mysql_thd); str = dict_strip_comments(sql_string); heap = mem_heap_create(10000); @@ -3403,7 +3409,8 @@ dict_foreign_parse_drop_constraints( FILE* ef = dict_foreign_err_file; struct charset_info_st* cs; - ut_a(trx && trx->mysql_thd); + ut_a(trx); + ut_a(trx->mysql_thd); cs = innobase_get_charset(trx->mysql_thd); @@ -3712,7 +3719,7 @@ dict_index_calc_min_rec_len( } /* round the NULL flags up to full bytes */ - sum += (nullable + 7) / 8; + sum += UT_BITS_IN_BYTES(nullable); return(sum); } diff --git a/storage/innobase/dyn/Makefile.am b/storage/innobase/dyn/Makefile.am deleted file mode 100644 index 57d9a25e481..00000000000 --- a/storage/innobase/dyn/Makefile.am +++ /dev/null @@ -1,25 +0,0 @@ -# Copyright (C) 2001, 2003 MySQL AB & Innobase Oy -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; version 2 of the License. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - -include ../include/Makefile.i - -noinst_LIBRARIES = libdyn.a - -libdyn_a_SOURCES = dyn0dyn.c - -EXTRA_PROGRAMS = - -# Don't update the files from bitkeeper -%::SCCS/s.% diff --git a/storage/innobase/eval/Makefile.am b/storage/innobase/eval/Makefile.am deleted file mode 100644 index 6c2b05d8b7a..00000000000 --- a/storage/innobase/eval/Makefile.am +++ /dev/null @@ -1,25 +0,0 @@ -# Copyright (C) 2001, 2003 MySQL AB & Innobase Oy -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; version 2 of the License. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - -include ../include/Makefile.i - -noinst_LIBRARIES = libeval.a - -libeval_a_SOURCES = eval0eval.c eval0proc.c - -EXTRA_PROGRAMS = - -# Don't update the files from bitkeeper -%::SCCS/s.% diff --git a/storage/innobase/fil/Makefile.am b/storage/innobase/fil/Makefile.am deleted file mode 100644 index 0a85ceb5b86..00000000000 --- a/storage/innobase/fil/Makefile.am +++ /dev/null @@ -1,25 +0,0 @@ -# Copyright (C) 2001, 2003 MySQL AB & Innobase Oy -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; version 2 of the License. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - -include ../include/Makefile.i - -noinst_LIBRARIES = libfil.a - -libfil_a_SOURCES = fil0fil.c - -EXTRA_PROGRAMS = - -# Don't update the files from bitkeeper -%::SCCS/s.% diff --git a/storage/innobase/fsp/Makefile.am b/storage/innobase/fsp/Makefile.am deleted file mode 100644 index 7818cdafc1b..00000000000 --- a/storage/innobase/fsp/Makefile.am +++ /dev/null @@ -1,26 +0,0 @@ -# Copyright (C) 2001, 2003 MySQL AB & Innobase Oy -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; version 2 of the License. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - - -include ../include/Makefile.i - -noinst_LIBRARIES = libfsp.a - -libfsp_a_SOURCES = fsp0fsp.c - -EXTRA_PROGRAMS = - -# Don't update the files from bitkeeper -%::SCCS/s.% diff --git a/storage/innobase/fsp/fsp0fsp.c b/storage/innobase/fsp/fsp0fsp.c index b5662fd24a4..78fb55e4ef3 100644 --- a/storage/innobase/fsp/fsp0fsp.c +++ b/storage/innobase/fsp/fsp0fsp.c @@ -205,10 +205,9 @@ the extent are free and which contain old tuple version to clean. */ space */ #define XDES_FSEG 4 /* extent belongs to a segment */ -/* File extent data structure size in bytes. The "+ 7 ) / 8" part in the -definition rounds the number of bytes upward. */ +/* File extent data structure size in bytes. */ #define XDES_SIZE \ - (XDES_BITMAP + (FSP_EXTENT_SIZE * XDES_BITS_PER_PAGE + 7) / 8) + (XDES_BITMAP + UT_BITS_IN_BYTES(FSP_EXTENT_SIZE * XDES_BITS_PER_PAGE)) /* Offset of the descriptor array on a descriptor page */ #define XDES_ARR_OFFSET (FSP_HEADER_OFFSET + FSP_HEADER_SIZE) @@ -3649,7 +3648,11 @@ fsp_validate( n_full_frag_pages = FSP_EXTENT_SIZE * flst_get_len(header + FSP_FULL_FRAG, &mtr); - ut_a(free_limit <= size || (space != 0 && size < FSP_EXTENT_SIZE)); + if (UNIV_UNLIKELY(free_limit > size)) { + + ut_a(space != 0); + ut_a(size < FSP_EXTENT_SIZE); + } flst_validate(header + FSP_FREE, &mtr); flst_validate(header + FSP_FREE_FRAG, &mtr); diff --git a/storage/innobase/fut/Makefile.am b/storage/innobase/fut/Makefile.am deleted file mode 100644 index ffe9835a023..00000000000 --- a/storage/innobase/fut/Makefile.am +++ /dev/null @@ -1,25 +0,0 @@ -# Copyright (C) 2001, 2003 MySQL AB & Innobase Oy -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; version 2 of the License. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - -include ../include/Makefile.i - -noinst_LIBRARIES = libfut.a - -libfut_a_SOURCES = fut0fut.c fut0lst.c - -EXTRA_PROGRAMS = - -# Don't update the files from bitkeeper -%::SCCS/s.% diff --git a/storage/innobase/ha/Makefile.am b/storage/innobase/ha/Makefile.am deleted file mode 100644 index 696cad0b203..00000000000 --- a/storage/innobase/ha/Makefile.am +++ /dev/null @@ -1,25 +0,0 @@ -# Copyright (C) 2001, 2003 MySQL AB & Innobase Oy -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; version 2 of the License. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - -include ../include/Makefile.i - -noinst_LIBRARIES = libha.a - -libha_a_SOURCES = ha0ha.c hash0hash.c - -EXTRA_PROGRAMS = - -# Don't update the files from bitkeeper -%::SCCS/s.% diff --git a/storage/innobase/handler/Makefile.am b/storage/innobase/handler/Makefile.am deleted file mode 100644 index 0d34212bdd4..00000000000 --- a/storage/innobase/handler/Makefile.am +++ /dev/null @@ -1,28 +0,0 @@ -# Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB -# & Innobase Oy -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; version 2 of the License. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - -include ../include/Makefile.i - -DEFS = -DMYSQL_SERVER @DEFS@ - -noinst_LIBRARIES = libhandler.a - -libhandler_a_SOURCES = ha_innodb.cc - -EXTRA_PROGRAMS = - -# Don't update the files from bitkeeper -%::SCCS/s.% diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc index c6319d977f7..b7d0c4417c3 100644 --- a/storage/innobase/handler/ha_innodb.cc +++ b/storage/innobase/handler/ha_innodb.cc @@ -15,11 +15,10 @@ /* This file defines the InnoDB handler: the interface between MySQL and InnoDB NOTE: You can only use noninlined InnoDB functions in this file, because we -have disables the InnoDB inlining in this file. */ +have disabled the InnoDB inlining in this file. */ /* TODO list for the InnoDB handler in 5.0: - - Remove the flag trx->active_trans and look at the InnoDB - trx struct state field + - Remove the flag trx->active_trans and look at trx->conc_state - fix savepoint functions to use savepoint storage area - Find out what kind of problems the OS X case-insensitivity causes to table and database names; should we 'normalize' the names like we do @@ -31,8 +30,7 @@ have disables the InnoDB inlining in this file. */ #endif #include <mysql_priv.h> - -#ifdef WITH_INNOBASE_STORAGE_ENGINE +#include <mysqld_error.h> #include <m_ctype.h> #include <hash.h> @@ -40,15 +38,23 @@ have disables the InnoDB inlining in this file. */ #include <mysys_err.h> #include <my_sys.h> #include "ha_innodb.h" - -pthread_mutex_t innobase_share_mutex, /* to protect innobase_open_files */ - prepare_commit_mutex; /* to force correct commit order in - binlog */ -ulong commit_threads= 0; -pthread_mutex_t commit_threads_m; -pthread_cond_t commit_cond; -pthread_mutex_t commit_cond_m; -bool innodb_inited= 0; +#include <mysql/plugin.h> + +#ifndef MYSQL_SERVER +/* This is needed because of Bug #3596. Let us hope that pthread_mutex_t +is defined the same in both builds: the MySQL server and the InnoDB plugin. */ +extern pthread_mutex_t LOCK_thread_count; +#endif /* MYSQL_SERVER */ + +/** to protect innobase_open_files */ +static pthread_mutex_t innobase_share_mutex; +/** to force correct commit order in binlog */ +static pthread_mutex_t prepare_commit_mutex; +static ulong commit_threads = 0; +static pthread_mutex_t commit_threads_m; +static pthread_cond_t commit_cond; +static pthread_mutex_t commit_cond_m; +static bool innodb_inited = 0; /* This needs to exist until the query cache callback is removed @@ -92,55 +98,41 @@ extern "C" { #include "../storage/innobase/include/ha_prototypes.h" } - -/* The default values for the following, type long or longlong, start-up -parameters are declared in mysqld.cc: */ - -long innobase_mirrored_log_groups, innobase_log_files_in_group, +static long innobase_mirrored_log_groups, innobase_log_files_in_group, innobase_log_buffer_size, innobase_buffer_pool_awe_mem_mb, innobase_additional_mem_pool_size, innobase_file_io_threads, innobase_lock_wait_timeout, innobase_force_recovery, innobase_open_files; -long long innobase_buffer_pool_size, innobase_log_file_size; +static long long innobase_buffer_pool_size, innobase_log_file_size; /* The default values for the following char* start-up parameters are determined in innobase_init below: */ -char* innobase_data_home_dir = NULL; -char* innobase_data_file_path = NULL; -char* innobase_log_group_home_dir = NULL; -char* innobase_log_arch_dir = NULL;/* unused */ +static char* innobase_data_home_dir = NULL; +static char* innobase_data_file_path = NULL; +static char* innobase_log_group_home_dir = NULL; /* The following has a misleading name: starting from 4.0.5, this also affects Windows: */ -char* innobase_unix_file_flush_method = NULL; +static char* innobase_unix_file_flush_method = NULL; /* Below we have boolean-valued start-up parameters, and their default values */ -static -ulong innobase_fast_shutdown = 1; +static ulong innobase_fast_shutdown = 1; #ifdef UNIV_LOG_ARCHIVE -static -my_bool innobase_log_archive = FALSE;/* unused */ -#endif /* UNIG_LOG_ARCHIVE */ -static -my_bool innobase_use_doublewrite = TRUE; -static -my_bool innobase_use_checksums = TRUE; -static -my_bool innobase_file_per_table = FALSE; -static -my_bool innobase_locks_unsafe_for_binlog = FALSE; -static -my_bool innobase_rollback_on_timeout = FALSE; -static -my_bool innobase_create_status_file = FALSE; -static -my_bool innobase_stats_on_metadata = TRUE; +static my_bool innobase_log_archive = FALSE; +static char* innobase_log_arch_dir = NULL; +#endif /* UNIV_LOG_ARCHIVE */ +static my_bool innobase_use_doublewrite = TRUE; +static my_bool innobase_use_checksums = TRUE; +static my_bool innobase_file_per_table = FALSE; +static my_bool innobase_locks_unsafe_for_binlog = FALSE; +static my_bool innobase_rollback_on_timeout = FALSE; +static my_bool innobase_create_status_file = FALSE; +static my_bool innobase_stats_on_metadata = TRUE; -static -char* internal_innobase_data_file_path = NULL; +static char* internal_innobase_data_file_path = NULL; /* The following counter is used to convey information to InnoDB about server activity: in selects it is not sensible to call @@ -427,6 +419,22 @@ static SHOW_VAR innodb_status_variables[]= { /* General functions */ /********************************************************************** +Returns true if the thread is the replication thread on the slave +server. Used in srv_conc_enter_innodb() to determine if the thread +should be allowed to enter InnoDB - the replication thread is treated +differently than other threads. Also used in +srv_conc_force_exit_innodb(). */ +extern "C" +ibool +thd_is_replication_slave_thread( +/*============================*/ + /* out: true if thd is the replication thread */ + void* thd) /* in: thread handle (THD*) */ +{ + return((ibool) thd_slave_thread((THD*) thd)); +} + +/********************************************************************** Save some CPU by testing the value of srv_thread_concurrency in inline functions. */ inline @@ -482,14 +490,30 @@ innobase_release_stat_resources( } } +/********************************************************************** +Returns true if the transaction this thread is processing has edited +non-transactional tables. Used by the deadlock detector when deciding +which transaction to rollback in case of a deadlock - we try to avoid +rolling back transactions that have edited non-transactional tables. */ +extern "C" +ibool +thd_has_edited_nontrans_tables( +/*===========================*/ + /* out: true if non-transactional tables have + been edited */ + void* thd) /* in: thread handle (THD*) */ +{ + return((ibool) thd_non_transactional_update((THD*) thd)); +} + /************************************************************************ Obtain the InnoDB transaction of a MySQL thread. */ inline trx_t*& thd_to_trx( /*=======*/ - /* out: reference to transaction pointer */ - THD* thd) /* in: MySQL thread */ + /* out: reference to transaction pointer */ + THD* thd) /* in: MySQL thread */ { return(*(trx_t**) thd_ha_data(thd, innodb_hton_ptr)); } @@ -502,11 +526,14 @@ static int innobase_release_temporary_latches( /*===============================*/ - handlerton *hton, - THD *thd) + /* out: 0 */ + handlerton* hton, /* in: handlerton */ + THD* thd) /* in: MySQL thread */ { trx_t* trx; + DBUG_ASSERT(hton == innodb_hton_ptr); + if (!innodb_inited) { return 0; @@ -645,6 +672,20 @@ convert_error_code_to_mysql( } return(HA_ERR_LOCK_TABLE_FULL); + } else if (error == DB_TOO_MANY_CONCURRENT_TRXS) { + + /* Once MySQL add the appropriate code to errmsg.txt then + we can get rid of this #ifdef. NOTE: The code checked by + the #ifdef is the suggested name for the error condition + and the actual error code name could very well be different. + This will require some monitoring, ie. the status + of this request on our part.*/ +#ifdef ER_TOO_MANY_CONCURRENT_TRXS + return(ER_TOO_MANY_CONCURRENT_TRXS); +#else + return(HA_ERR_RECORD_FILE_FULL); +#endif + } else { return(-1); // Unknown error } @@ -693,19 +734,19 @@ innobase_mysql_print_thd( use the default max length */ { THD* thd; - char buffer[1024]; + char buffer[1024]; - thd = (THD*) input_thd; - fputs(thd_security_context(thd, buffer, sizeof(buffer), + thd = (THD*) input_thd; + fputs(thd_security_context(thd, buffer, sizeof(buffer), max_query_len), f); - putc('\n', f); + putc('\n', f); } /********************************************************************** Get the variable length bounds of the given character set. NOTE that the exact prototype of this function has to be in -/innobase/data/data0type.ic! */ +/innobase/include/data0type.ic! */ extern "C" void innobase_get_cset_width( @@ -744,7 +785,7 @@ innobase_convert_from_table_id( { uint errors; - strconvert(current_thd->charset(), from, + strconvert(thd_charset(current_thd), from, &my_charset_filename, to, (uint) len, &errors); } @@ -763,7 +804,7 @@ innobase_convert_from_id( { uint errors; - strconvert(current_thd->charset(), from, + strconvert(thd_charset(current_thd), from, system_charset_info, to, (uint) len, &errors); } @@ -826,7 +867,7 @@ innobase_get_charset( /* out: connection character set */ void* mysql_thd) /* in: MySQL thread handle */ { - return(((THD*) mysql_thd)->charset()); + return(thd_charset((THD*) mysql_thd)); } /************************************************************************* @@ -837,22 +878,9 @@ innobase_mysql_tmpfile(void) /*========================*/ /* out: temporary file descriptor, or < 0 on error */ { - char filename[FN_REFLEN]; int fd2 = -1; - File fd = create_temp_file(filename, mysql_tmpdir, "ib", -#ifdef __WIN__ - O_BINARY | O_TRUNC | O_SEQUENTIAL | - O_TEMPORARY | O_SHORT_LIVED | -#endif /* __WIN__ */ - O_CREAT | O_EXCL | O_RDWR, - MYF(MY_WME)); + File fd = mysql_tmpfile("ib"); if (fd >= 0) { -#ifndef __WIN__ - /* On Windows, open files cannot be removed, but files can be - created with the O_TEMPORARY flag to the same effect - ("delete on close"). */ - unlink(filename); -#endif /* !__WIN__ */ /* Copy the file descriptor, so that the additional resources allocated by create_temp_file() can be freed by invoking my_close(). @@ -867,7 +895,7 @@ innobase_mysql_tmpfile(void) my_errno=errno; my_error(EE_OUT_OF_FILERESOURCES, MYF(ME_BELL+ME_WAITTANG), - filename, my_errno); + "ib*", my_errno); } my_close(fd, MYF(MY_WME)); } @@ -903,7 +931,6 @@ trx_t* check_trx_exists( /*=============*/ /* out: InnoDB transaction handle */ - handlerton* hton, /* in: handlerton for innodb */ THD* thd) /* in: user thread handle */ { trx_t*& trx = thd_to_trx(thd); @@ -915,8 +942,7 @@ check_trx_exists( trx = trx_allocate_for_mysql(); trx->mysql_thd = thd; - trx->mysql_query_str = &(thd->query); - trx->active_trans = 0; + trx->mysql_query_str = thd_query(thd); /* Update the info whether we should skip XA steps that eat CPU time */ @@ -927,7 +953,7 @@ check_trx_exists( if (trx->magic_n != TRX_MAGIC_N) { mem_analyze_corruption(trx); - ut_a(0); + ut_error; } } @@ -958,7 +984,7 @@ ha_innobase::ha_innobase(handlerton *hton, TABLE_SHARE *table_arg) HA_CAN_SQL_HANDLER | HA_PRIMARY_KEY_REQUIRED_FOR_POSITION | HA_PRIMARY_KEY_IN_READ_INDEX | - HA_BINLOG_ROW_CAPABLE | + HA_BINLOG_ROW_CAPABLE | HA_CAN_GEOMETRY | HA_PARTIAL_COLUMN_READ | HA_TABLE_SCAN_ON_INDEX), start_of_scan(0), @@ -978,7 +1004,7 @@ ha_innobase::update_thd( { trx_t* trx; - trx = check_trx_exists(ht, thd); + trx = check_trx_exists(thd); if (prebuilt->trx != trx) { @@ -1117,7 +1143,7 @@ innobase_query_caching_of_table_permitted( ut_a(full_name_len < 999); - trx = check_trx_exists(innodb_hton_ptr, thd); + trx = check_trx_exists(thd); if (trx->isolation_level == TRX_ISO_SERIALIZABLE) { /* In the SERIALIZABLE mode we add LOCK IN SHARE MODE to every @@ -1222,10 +1248,10 @@ innobase_invalidate_query_cache( /* Argument TRUE below means we are using transactions */ #ifdef HAVE_QUERY_CACHE - query_cache.invalidate((THD*)(trx->mysql_thd), - (const char*)full_name, - (uint32)full_name_len, - TRUE); + mysql_query_cache_invalidate4((THD*) trx->mysql_thd, + (const char*) full_name, + (uint32) full_name_len, + TRUE); #endif } @@ -1305,7 +1331,20 @@ trx_is_interrupted( /* out: TRUE if interrupted */ trx_t* trx) /* in: transaction */ { - return(trx && trx->mysql_thd && ((THD*) trx->mysql_thd)->killed); + return(trx && trx->mysql_thd && thd_killed((THD*) trx->mysql_thd)); +} + +/****************************************************************** +Resets some fields of a prebuilt struct. The template is used in fast +retrieval of just those column values MySQL needs in its processing. */ +static +void +reset_template( +/*===========*/ + row_prebuilt_t* prebuilt) /* in/out: prebuilt struct */ +{ + prebuilt->keep_other_fields_on_keyread = 0; + prebuilt->read_just_key = 0; } /********************************************************************* @@ -1343,7 +1382,7 @@ ha_innobase::init_table_handle_for_HANDLER(void) if (prebuilt->trx->active_trans == 0) { - innobase_register_trx_and_stmt(ht, ha_thd()); + innobase_register_trx_and_stmt(ht, user_thd); prebuilt->trx->active_trans = 1; } @@ -1366,19 +1405,18 @@ ha_innobase::init_table_handle_for_HANDLER(void) /* We want always to fetch all columns in the whole row? Or do we???? */ - prebuilt->read_just_key = FALSE; - prebuilt->used_in_HANDLER = TRUE; - - prebuilt->keep_other_fields_on_keyread = FALSE; + reset_template(prebuilt); } /************************************************************************* Opens an InnoDB database. */ static int -innobase_init(void *p) -/*===============*/ +innobase_init( +/*==========*/ + /* out: 0 on success, error code on failure */ + void *p) /* in: InnoDB handlerton */ { static char current_dir[3]; /* Set if using current lib */ int err; @@ -1387,9 +1425,9 @@ innobase_init(void *p) DBUG_ENTER("innobase_init"); handlerton *innobase_hton= (handlerton *)p; - innodb_hton_ptr= innobase_hton; + innodb_hton_ptr = innobase_hton; - innobase_hton->state= SHOW_OPTION_YES; + innobase_hton->state = SHOW_OPTION_YES; innobase_hton->db_type= DB_TYPE_INNODB; innobase_hton->savepoint_offset=sizeof(trx_named_savept_t); innobase_hton->close_connection=innobase_close_connection; @@ -1569,10 +1607,7 @@ innobase_init(void *p) changes the value so that it becomes the number of database pages. */ if (innobase_buffer_pool_awe_mem_mb == 0) { - /* Careful here: we first convert the signed long int to ulint - and only after that divide */ - - srv_pool_size = ((ulint) innobase_buffer_pool_size) / 1024; + srv_pool_size = (ulint)(innobase_buffer_pool_size / 1024); } else { srv_use_awe = TRUE; srv_pool_size = (ulint) @@ -1751,7 +1786,7 @@ innobase_start_trx_and_assign_read_view( /* Create a new trx struct for thd, if it does not yet have one */ - trx = check_trx_exists(hton, thd); + trx = check_trx_exists(thd); /* This is just to play safe: release a possible FIFO ticket and search latch. Since we will reserve the kernel mutex, we have to @@ -1796,7 +1831,7 @@ innobase_commit( DBUG_ENTER("innobase_commit"); DBUG_PRINT("trans", ("ending transaction")); - trx = check_trx_exists(hton, thd); + trx = check_trx_exists(thd); /* Update the info whether we should skip XA steps that eat CPU time */ trx->support_xa = THDVAR(thd, support_xa); @@ -1855,9 +1890,8 @@ retry: } } - trx->mysql_log_file_name = mysql_bin_log.get_log_fname(); - trx->mysql_log_offset = - (ib_longlong)mysql_bin_log.get_log_file()->pos_in_file; + trx->mysql_log_file_name = mysql_bin_log_file_name(); + trx->mysql_log_offset = (ib_longlong) mysql_bin_log_file_pos(); innobase_commit_low(trx); @@ -1987,7 +2021,6 @@ int innobase_commit_complete( /*=====================*/ /* out: 0 */ - handlerton *hton, /* in: Innodb handlerton */ THD* thd) /* in: user thread */ { trx_t* trx; @@ -2012,8 +2045,8 @@ innobase_commit_complete( /********************************************************************* Rolls back a transaction or the latest SQL statement. */ - -static int +static +int innobase_rollback( /*==============*/ /* out: 0 or error number */ @@ -2029,7 +2062,7 @@ innobase_rollback( DBUG_ENTER("innobase_rollback"); DBUG_PRINT("trans", ("aborting transaction")); - trx = check_trx_exists(hton, thd); + trx = check_trx_exists(thd); /* Update the info whether we should skip XA steps that eat CPU time */ trx->support_xa = THDVAR(thd, support_xa); @@ -2095,8 +2128,8 @@ innobase_rollback_trx( /********************************************************************* Rolls back a transaction to a savepoint. */ - -static int +static +int innobase_rollback_to_savepoint( /*===========================*/ /* out: 0 if success, HA_ERR_NO_SAVEPOINT if @@ -2113,7 +2146,7 @@ innobase_rollback_to_savepoint( DBUG_ENTER("innobase_rollback_to_savepoint"); - trx = check_trx_exists(hton, thd); + trx = check_trx_exists(thd); /* Release a possible FIFO ticket and search latch. Since we will reserve the kernel mutex, we have to release the search system latch @@ -2149,7 +2182,7 @@ innobase_release_savepoint( DBUG_ENTER("innobase_release_savepoint"); - trx = check_trx_exists(hton, thd); + trx = check_trx_exists(thd); /* TODO: use provided savepoint data area to store savepoint data */ @@ -2181,10 +2214,12 @@ innobase_savepoint( (unless we are in sub-statement), so SQL layer ensures that this method is never called in such situation. */ +#ifdef MYSQL_SERVER /* plugins cannot access thd->in_sub_stmt */ DBUG_ASSERT(thd_test_options(thd, OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN) || thd->in_sub_stmt); +#endif /* MYSQL_SERVER */ - trx = check_trx_exists(hton, thd); + trx = check_trx_exists(thd); /* Release a possible FIFO ticket and search latch. Since we will reserve the kernel mutex, we have to release the search system latch @@ -2217,6 +2252,8 @@ innobase_close_connection( { trx_t* trx; + DBUG_ENTER("innobase_close_connection"); + DBUG_ASSERT(hton == innodb_hton_ptr); trx = thd_to_trx(thd); ut_a(trx); @@ -2243,7 +2280,7 @@ innobase_close_connection( thr_local_free(trx->mysql_thread_id); trx_free_for_mysql(trx); - return(0); + DBUG_RETURN(0); } @@ -2523,8 +2560,15 @@ ha_innobase::close(void) /*====================*/ /* out: 0 */ { + THD* thd; + DBUG_ENTER("ha_innobase::close"); + thd = current_thd; // avoid calling current_thd twice, it may be slow + if (thd != NULL) { + innobase_release_temporary_latches(ht, thd); + } + row_prebuilt_free(prebuilt); my_free(upd_buff, MYF(0)); @@ -3099,7 +3143,7 @@ static void build_template( /*===========*/ - row_prebuilt_t* prebuilt, /* in: prebuilt struct */ + row_prebuilt_t* prebuilt, /* in/out: prebuilt struct */ THD* thd, /* in: current user thread, used only if templ_type is ROW_MYSQL_REC_FIELDS */ @@ -3319,8 +3363,8 @@ ha_innobase::write_row( longlong auto_inc; longlong dummy; ibool auto_inc_used= FALSE; - THD *thd= ha_thd(); - trx_t* trx = thd_to_trx(thd); + ulint sql_command; + trx_t* trx = thd_to_trx(user_thd); DBUG_ENTER("ha_innobase::write_row"); @@ -3344,11 +3388,13 @@ ha_innobase::write_row( if (table->timestamp_field_type & TIMESTAMP_AUTO_SET_ON_INSERT) table->timestamp_field->set_time(); - if ((thd_sql_command(thd) == SQLCOM_ALTER_TABLE - || thd_sql_command(thd) == SQLCOM_OPTIMIZE - || thd_sql_command(thd) == SQLCOM_CREATE_INDEX - || thd_sql_command(thd) == SQLCOM_DROP_INDEX) - && num_write_row >= 10000) { + sql_command = thd_sql_command(user_thd); + + if ((sql_command == SQLCOM_ALTER_TABLE + || sql_command == SQLCOM_OPTIMIZE + || sql_command == SQLCOM_CREATE_INDEX + || sql_command == SQLCOM_DROP_INDEX) + && num_write_row >= 10000) { /* ALTER TABLE is COMMITted at every 10000 copied rows. The IX table lock for the original table has to be re-issued. As this method will be called on a temporary table where the @@ -3490,30 +3536,32 @@ no_commit: /* This call will update the counter according to the value that was inserted in the table */ - dict_table_autoinc_update(prebuilt->table, auto_inc); - } - } + dict_table_autoinc_update(prebuilt->table, auto_inc); + } + } - /* A REPLACE command and LOAD DATA INFILE REPLACE handle a duplicate - key error themselves, and we must update the autoinc counter if we are - performing those statements. */ + /* A REPLACE command and LOAD DATA INFILE REPLACE handle a duplicate + key error themselves, and we must update the autoinc counter if we are + performing those statements. */ - if (error == DB_DUPLICATE_KEY && auto_inc_used - && (thd_sql_command(user_thd) == SQLCOM_REPLACE - || thd_sql_command(user_thd) == SQLCOM_REPLACE_SELECT - || (thd_sql_command(user_thd) == SQLCOM_INSERT - && prebuilt->trx->allow_duplicates - && !prebuilt->trx->replace_duplicates) - || (thd_sql_command(user_thd) == SQLCOM_LOAD - && prebuilt->trx->allow_duplicates - && prebuilt->trx->replace_duplicates))) { + if (error == DB_DUPLICATE_KEY && auto_inc_used + && (sql_command == SQLCOM_REPLACE + || sql_command == SQLCOM_REPLACE_SELECT + || (sql_command == SQLCOM_INSERT + && ((trx->duplicates + & (TRX_DUP_IGNORE | TRX_DUP_REPLACE)) + == TRX_DUP_IGNORE)) + || (sql_command == SQLCOM_LOAD + && ((trx->duplicates + & (TRX_DUP_IGNORE | TRX_DUP_REPLACE)) + == (TRX_DUP_IGNORE | TRX_DUP_REPLACE))))) { - auto_inc = table->next_number_field->val_int(); + auto_inc = table->next_number_field->val_int(); - if (auto_inc != 0) { - dict_table_autoinc_update(prebuilt->table, auto_inc); - } - } + if (auto_inc != 0) { + dict_table_autoinc_update(prebuilt->table, auto_inc); + } + } innodb_srv_conc_exit_innodb(prebuilt->trx); @@ -3694,7 +3742,7 @@ ha_innobase::update_row( { upd_t* uvect; int error = 0; - trx_t* trx = thd_to_trx(ha_thd()); + trx_t* trx = thd_to_trx(user_thd); DBUG_ENTER("ha_innobase::update_row"); @@ -3747,7 +3795,7 @@ ha_innobase::delete_row( const mysql_byte* record) /* in: a row in MySQL format */ { int error = 0; - trx_t* trx = thd_to_trx(ha_thd()); + trx_t* trx = thd_to_trx(user_thd); DBUG_ENTER("ha_innobase::delete_row"); @@ -3833,7 +3881,8 @@ ha_innobase::try_semi_consistent_read(bool yes) option is used or this session is using READ COMMITTED isolation level. */ - if (yes && (srv_locks_unsafe_for_binlog + if (yes + && (srv_locks_unsafe_for_binlog || prebuilt->trx->isolation_level == TRX_ISO_READ_COMMITTED)) { prebuilt->row_read_type = ROW_READ_TRY_SEMI_CONSISTENT; } else { @@ -3991,7 +4040,7 @@ ha_innobase::index_read( DBUG_ENTER("index_read"); - ut_a(prebuilt->trx == thd_to_trx(ha_thd())); + ut_a(prebuilt->trx == thd_to_trx(user_thd)); ha_statistic_increment(&SSV::ha_read_key_count); @@ -4183,7 +4232,7 @@ ha_innobase::general_fetch( DBUG_ENTER("general_fetch"); - ut_a(prebuilt->trx == thd_to_trx(ha_thd())); + ut_a(prebuilt->trx == thd_to_trx(user_thd)); innodb_srv_conc_enter_innodb(prebuilt->trx); @@ -4482,6 +4531,25 @@ ha_innobase::position( } /********************************************************************* +If it's a DB_TOO_BIG_RECORD error then set a suitable message to +return to the client.*/ +static +void +innodb_check_for_record_too_big_error( +/*==================================*/ + dict_table_t* table, /* in: table to check */ + int error) /* in: error code to check */ +{ + if (error == (int)DB_TOO_BIG_RECORD) { + ulint max_row_size; + + max_row_size = page_get_free_space_of_empty_noninline(table); + + my_error(ER_TOO_BIG_ROWSIZE, MYF(0), max_row_size); + } +} + +/********************************************************************* Creates a table definition to an InnoDB database. */ static int @@ -4589,6 +4657,10 @@ create_table_def( error = row_create_table_for_mysql(table, trx); + /* We need access to the table and so we do the error checking + and set the error message here, before the error translation.*/ + innodb_check_for_record_too_big_error(table, error); + error = convert_error_code_to_mysql(error, NULL); DBUG_RETURN(error); @@ -4711,6 +4783,10 @@ create_index( sure we don't create too long indexes. */ error = row_create_index_for_mysql(index, trx, field_lengths); + /* We need access to the table and so we do the error checking + and set the error message here, before the error translation.*/ + innodb_check_for_record_too_big_error(index->table, error); + error = convert_error_code_to_mysql(error, NULL); my_free(field_lengths, MYF(0)); @@ -4738,6 +4814,10 @@ create_clustered_index_when_no_primary( (char*) "GEN_CLUST_INDEX", 0, DICT_CLUSTERED, 0); error = row_create_index_for_mysql(index, trx, NULL); + /* We need access to the table and so we do the error checking + and set the error message here, before the error translation.*/ + innodb_check_for_record_too_big_error(index->table, error); + error = convert_error_code_to_mysql(error, NULL); return(error); @@ -4779,7 +4859,7 @@ ha_innobase::create( uint i; char name2[FN_REFLEN]; char norm_name[FN_REFLEN]; - THD *thd= ha_thd(); + THD* thd = ha_thd(); ib_longlong auto_inc_value; ulint flags; @@ -4797,7 +4877,7 @@ ha_innobase::create( /* Get the transaction associated with the current thd, or create one if not yet created */ - parent_trx = check_trx_exists(ht, thd); + parent_trx = check_trx_exists(thd); /* In case MySQL calls this in the middle of a SELECT query, release possible adaptive hash latch to avoid deadlocks of threads */ @@ -4807,7 +4887,7 @@ ha_innobase::create( trx = trx_allocate_for_mysql(); trx->mysql_thd = thd; - trx->mysql_query_str = &((*thd).query); + trx->mysql_query_str = thd_query(thd); if (thd_test_options(thd, OPTION_NO_FOREIGN_KEY_CHECKS)) { trx->check_foreigns = FALSE; @@ -4893,9 +4973,9 @@ ha_innobase::create( } } - if (thd->query != NULL) { + if (*trx->mysql_query_str) { error = row_table_add_foreign_constraints(trx, - thd->query, norm_name, + *trx->mysql_query_str, norm_name, create_info->options & HA_LEX_CREATE_TMP_TABLE); error = convert_error_code_to_mysql(error, NULL); @@ -4994,33 +5074,32 @@ ha_innobase::delete_all_rows(void) /* out: error number */ { int error; - THD* thd = ha_thd(); DBUG_ENTER("ha_innobase::delete_all_rows"); /* Get the transaction associated with the current thd, or create one if not yet created, and update prebuilt->trx */ - update_thd(thd); - - if (thd_sql_command(thd) == SQLCOM_TRUNCATE) { - /* Truncate the table in InnoDB */ + update_thd(ha_thd()); - error = row_truncate_table_for_mysql(prebuilt->table, prebuilt->trx); - if (error == DB_ERROR) { - /* Cannot truncate; resort to ha_innobase::delete_row() */ - goto fallback; - } + if (thd_sql_command(user_thd) != SQLCOM_TRUNCATE) { + fallback: + /* We only handle TRUNCATE TABLE t as a special case. + DELETE FROM t will have to use ha_innobase::delete_row(). */ + DBUG_RETURN(my_errno=HA_ERR_WRONG_COMMAND); + } - error = convert_error_code_to_mysql(error, NULL); + /* Truncate the table in InnoDB */ - DBUG_RETURN(error); + error = row_truncate_table_for_mysql(prebuilt->table, prebuilt->trx); + if (error == DB_ERROR) { + /* Cannot truncate; resort to ha_innobase::delete_row() */ + goto fallback; } -fallback: - /* We only handle TRUNCATE TABLE t as a special case. - DELETE FROM t will have to use ha_innobase::delete_row(). */ - DBUG_RETURN(my_errno=HA_ERR_WRONG_COMMAND); + error = convert_error_code_to_mysql(error, NULL); + + DBUG_RETURN(error); } /********************************************************************* @@ -5040,7 +5119,7 @@ ha_innobase::delete_table( int error; trx_t* parent_trx; trx_t* trx; - THD *thd= ha_thd(); + THD *thd = ha_thd(); char norm_name[1000]; DBUG_ENTER("ha_innobase::delete_table"); @@ -5048,7 +5127,7 @@ ha_innobase::delete_table( /* Get the transaction associated with the current thd, or create one if not yet created */ - parent_trx = check_trx_exists(ht, thd); + parent_trx = check_trx_exists(thd); /* In case MySQL calls this in the middle of a SELECT query, release possible adaptive hash latch to avoid deadlocks of threads */ @@ -5063,75 +5142,77 @@ ha_innobase::delete_table( trx = trx_allocate_for_mysql(); - trx->mysql_thd = ha_thd(); - trx->mysql_query_str = &(ha_thd()->query); + trx->mysql_thd = thd; + trx->mysql_query_str = thd_query(thd); - if (thd_test_options(thd, OPTION_NO_FOREIGN_KEY_CHECKS)) { - trx->check_foreigns = FALSE; - } + if (thd_test_options(thd, OPTION_NO_FOREIGN_KEY_CHECKS)) { + trx->check_foreigns = FALSE; + } - if (thd_test_options(thd, OPTION_RELAXED_UNIQUE_CHECKS)) { - trx->check_unique_secondary = FALSE; - } + if (thd_test_options(thd, OPTION_RELAXED_UNIQUE_CHECKS)) { + trx->check_unique_secondary = FALSE; + } - name_len = strlen(name); + name_len = strlen(name); - assert(name_len < 1000); + assert(name_len < 1000); - /* Strangely, MySQL passes the table name without the '.frm' - extension, in contrast to ::create */ + /* Strangely, MySQL passes the table name without the '.frm' + extension, in contrast to ::create */ - normalize_table_name(norm_name, name); + normalize_table_name(norm_name, name); - /* Drop the table in InnoDB */ + /* Drop the table in InnoDB */ - error = row_drop_table_for_mysql(norm_name, trx, - thd_sql_command(thd) == SQLCOM_DROP_DB); + error = row_drop_table_for_mysql(norm_name, trx, + thd_sql_command(thd) + == SQLCOM_DROP_DB); - /* Flush the log to reduce probability that the .frm files and - the InnoDB data dictionary get out-of-sync if the user runs - with innodb_flush_log_at_trx_commit = 0 */ + /* Flush the log to reduce probability that the .frm files and + the InnoDB data dictionary get out-of-sync if the user runs + with innodb_flush_log_at_trx_commit = 0 */ - log_buffer_flush_to_disk(); + log_buffer_flush_to_disk(); - /* Tell the InnoDB server that there might be work for - utility threads: */ + /* Tell the InnoDB server that there might be work for + utility threads: */ - srv_active_wake_master_thread(); + srv_active_wake_master_thread(); - innobase_commit_low(trx); + innobase_commit_low(trx); - trx_free_for_mysql(trx); + trx_free_for_mysql(trx); - error = convert_error_code_to_mysql(error, NULL); + error = convert_error_code_to_mysql(error, NULL); - DBUG_RETURN(error); + DBUG_RETURN(error); } /********************************************************************* - Removes all tables in the named database inside InnoDB. */ +Removes all tables in the named database inside InnoDB. */ static void innobase_drop_database( - /*===================*/ - /* out: error number */ - handlerton *hton, /* in: handlerton of Innodb */ - char* path) /* in: database path; inside InnoDB the name - of the last directory in the path is used as - the database name: for example, in 'mysql/data/test' - the database name is 'test' */ -{ - ulint len = 0; - trx_t* parent_trx; - trx_t* trx; - char* ptr; - int error; - char* namebuf; - - /* Get the transaction associated with the current thd, or create one - if not yet created */ - - parent_trx = check_trx_exists(hton, current_thd); +/*===================*/ + /* out: error number */ + handlerton *hton, /* in: handlerton of Innodb */ + char* path) /* in: database path; inside InnoDB the name + of the last directory in the path is used as + the database name: for example, in 'mysql/data/test' + the database name is 'test' */ +{ + ulint len = 0; + trx_t* parent_trx; + trx_t* trx; + char* ptr; + int error; + char* namebuf; + THD* thd = current_thd; + + /* Get the transaction associated with the current thd, or create one + if not yet created */ + + parent_trx = check_trx_exists(thd); /* In case MySQL calls this in the middle of a SELECT query, release possible adaptive hash latch to avoid deadlocks of threads */ @@ -5155,10 +5236,10 @@ innobase_drop_database( innobase_casedn_str(namebuf); #endif trx = trx_allocate_for_mysql(); - trx->mysql_thd = current_thd; - trx->mysql_query_str = &((*current_thd).query); + trx->mysql_thd = thd; + trx->mysql_query_str = thd_query(thd); - if (thd_test_options(current_thd, OPTION_NO_FOREIGN_KEY_CHECKS)) { + if (thd_test_options(thd, OPTION_NO_FOREIGN_KEY_CHECKS)) { trx->check_foreigns = FALSE; } @@ -5204,13 +5285,14 @@ ha_innobase::rename_table( trx_t* trx; char norm_from[1000]; char norm_to[1000]; + THD* thd = ha_thd(); DBUG_ENTER("ha_innobase::rename_table"); /* Get the transaction associated with the current thd, or create one if not yet created */ - parent_trx = check_trx_exists(ht, ha_thd()); + parent_trx = check_trx_exists(thd); /* In case MySQL calls this in the middle of a SELECT query, release possible adaptive hash latch to avoid deadlocks of threads */ @@ -5224,10 +5306,10 @@ ha_innobase::rename_table( } trx = trx_allocate_for_mysql(); - trx->mysql_thd = ha_thd(); - trx->mysql_query_str = &((*ha_thd()).query); + trx->mysql_thd = thd; + trx->mysql_query_str = thd_query(thd); - if (thd_test_options(ha_thd(), OPTION_NO_FOREIGN_KEY_CHECKS)) { + if (thd_test_options(thd, OPTION_NO_FOREIGN_KEY_CHECKS)) { trx->check_foreigns = FALSE; } @@ -5489,7 +5571,12 @@ ha_innobase::info( if (srv_force_recovery >= SRV_FORCE_NO_IBUF_MERGE) { - DBUG_RETURN(HA_ERR_CRASHED); + /* We return success (0) instead of HA_ERR_CRASHED, + because we want MySQL to process this query and not + stop, like it would do if it received the error code + HA_ERR_CRASHED. */ + + DBUG_RETURN(0); } /* We do not know if MySQL can call this function before calling @@ -5509,15 +5596,14 @@ ha_innobase::info( if (flag & HA_STATUS_TIME) { if (srv_stats_on_metadata) { - /* In sql_show we call with this flag: update then statistics - so that they are up-to-date */ + /* In sql_show we call with this flag: update + then statistics so that they are up-to-date */ - prebuilt->trx->op_info = (char*)"updating table statistics"; + prebuilt->trx->op_info = "updating table statistics"; dict_update_statistics(ib_table); - prebuilt->trx->op_info = (char*) - "returning various info to MySQL"; + prebuilt->trx->op_info = "returning various info to MySQL"; } my_snprintf(path, sizeof(path), "%s/%s%s", @@ -5642,7 +5728,8 @@ ha_innobase::info( } if (flag & HA_STATUS_ERRKEY) { - ut_a(prebuilt->trx && prebuilt->trx->magic_n == TRX_MAGIC_N); + ut_a(prebuilt->trx); + ut_a(prebuilt->trx->magic_n == TRX_MAGIC_N); errkey = (unsigned int) row_get_mysql_key_number_for_index( (dict_index_t*) trx_get_error_info(prebuilt->trx)); @@ -5726,8 +5813,10 @@ ha_innobase::check( { ulint ret; - ut_a(prebuilt->trx && prebuilt->trx->magic_n == TRX_MAGIC_N); - ut_a(prebuilt->trx == thd_to_trx(ha_thd())); + DBUG_ASSERT(thd == ha_thd()); + ut_a(prebuilt->trx); + ut_a(prebuilt->trx->magic_n == TRX_MAGIC_N); + ut_a(prebuilt->trx == thd_to_trx(thd)); if (prebuilt->mysql_template == NULL) { /* Build the template; we will use a dummy template @@ -6000,9 +6089,8 @@ ha_innobase::get_foreign_key_list(THD *thd, List<FOREIGN_KEY_INFO> *f_key_list) strlen(foreign->referenced_index->name), 1); } - FOREIGN_KEY_INFO *pf_key_info= ((FOREIGN_KEY_INFO *) - thd->memdup(&f_key_info, - sizeof(FOREIGN_KEY_INFO))); + FOREIGN_KEY_INFO *pf_key_info = (FOREIGN_KEY_INFO *) + thd_memdup(thd, &f_key_info, sizeof(FOREIGN_KEY_INFO)); f_key_list->push_back(pf_key_info); foreign = UT_LIST_GET_NEXT(foreign_list, foreign); } @@ -6094,8 +6182,7 @@ ha_innobase::extra( } break; case HA_EXTRA_RESET_STATE: - prebuilt->keep_other_fields_on_keyread = 0; - prebuilt->read_just_key = 0; + reset_template(prebuilt); break; case HA_EXTRA_NO_KEYREAD: prebuilt->read_just_key = 0; @@ -6106,18 +6193,25 @@ ha_innobase::extra( case HA_EXTRA_KEYREAD_PRESERVE_FIELDS: prebuilt->keep_other_fields_on_keyread = 1; break; + + /* IMPORTANT: prebuilt->trx can be obsolete in + this method, because it is not sure that MySQL + calls external_lock before this method with the + parameters below. We must not invoke update_thd() + either, because the calling threads may change. + CAREFUL HERE, OR MEMORY CORRUPTION MAY OCCUR! */ case HA_EXTRA_IGNORE_DUP_KEY: - prebuilt->trx->allow_duplicates= TRUE; + thd_to_trx(ha_thd())->duplicates |= TRX_DUP_IGNORE; break; case HA_EXTRA_WRITE_CAN_REPLACE: - prebuilt->trx->replace_duplicates= TRUE; + thd_to_trx(ha_thd())->duplicates |= TRX_DUP_REPLACE; break; case HA_EXTRA_WRITE_CANNOT_REPLACE: - prebuilt->trx->replace_duplicates= FALSE; + thd_to_trx(ha_thd())->duplicates &= ~TRX_DUP_REPLACE; break; case HA_EXTRA_NO_IGNORE_DUP_KEY: - prebuilt->trx->allow_duplicates= FALSE; - prebuilt->trx->replace_duplicates= FALSE; + thd_to_trx(ha_thd())->duplicates &= + ~(TRX_DUP_IGNORE | TRX_DUP_REPLACE); break; default:/* Do nothing */ ; @@ -6131,8 +6225,7 @@ int ha_innobase::reset() if (prebuilt->blob_heap) { row_mysql_prebuilt_free_blob_heap(prebuilt); } - prebuilt->keep_other_fields_on_keyread = 0; - prebuilt->read_just_key = 0; + reset_template(prebuilt); return 0; } @@ -6173,8 +6266,7 @@ ha_innobase::start_stmt( prebuilt->sql_stat_start = TRUE; prebuilt->hint_need_to_fetch_extra_cols = 0; - prebuilt->read_just_key = 0; - prebuilt->keep_other_fields_on_keyread = FALSE; + reset_template(prebuilt); if (!prebuilt->mysql_has_locked) { /* This handle is for a temporary table created inside @@ -6261,27 +6353,27 @@ ha_innobase::external_lock( update_thd(thd); - /* Statement based binlogging does not work in isolation level - READ UNCOMMITTED and READ COMMITTED since the necessary - locks cannot be taken. In this case, we print an - informative error message and return with an error. */ - if (lock_type == F_WRLCK) - { - ulong const binlog_format= thd->variables.binlog_format; - ulong const tx_isolation = thd_tx_isolation(current_thd); - if (tx_isolation <= ISO_READ_COMMITTED && - binlog_format == BINLOG_FORMAT_STMT) - { - char buf[256]; - my_snprintf(buf, sizeof(buf), - "Transaction level '%s' in" - " InnoDB is not safe for binlog mode '%s'", - tx_isolation_names[tx_isolation], - binlog_format_names[binlog_format]); - my_error(ER_BINLOG_LOGGING_IMPOSSIBLE, MYF(0), buf); - DBUG_RETURN(HA_ERR_LOGGING_IMPOSSIBLE); - } - } + /* Statement based binlogging does not work in isolation level + READ UNCOMMITTED and READ COMMITTED since the necessary + locks cannot be taken. In this case, we print an + informative error message and return with an error. */ + if (lock_type == F_WRLCK) + { + ulong const binlog_format= thd_binlog_format(thd); + ulong const tx_isolation = thd_tx_isolation(current_thd); + if (tx_isolation <= ISO_READ_COMMITTED && + binlog_format == BINLOG_FORMAT_STMT) + { + char buf[256]; + my_snprintf(buf, sizeof(buf), + "Transaction level '%s' in" + " InnoDB is not safe for binlog mode '%s'", + tx_isolation_names[tx_isolation], + binlog_format_names[binlog_format]); + my_error(ER_BINLOG_LOGGING_IMPOSSIBLE, MYF(0), buf); + DBUG_RETURN(HA_ERR_LOGGING_IMPOSSIBLE); + } + } trx = prebuilt->trx; @@ -6289,8 +6381,7 @@ ha_innobase::external_lock( prebuilt->sql_stat_start = TRUE; prebuilt->hint_need_to_fetch_extra_cols = 0; - prebuilt->read_just_key = 0; - prebuilt->keep_other_fields_on_keyread = FALSE; + reset_template(prebuilt); if (lock_type == F_WRLCK) { @@ -6348,17 +6439,17 @@ ha_innobase::external_lock( if (prebuilt->select_lock_type != LOCK_NONE) { - if (thd_in_lock_tables(thd) && - thd_sql_command(thd) == SQLCOM_LOCK_TABLES && - THDVAR(thd, table_locks) && - thd_test_options(thd, OPTION_NOT_AUTOCOMMIT)) { + if (thd_sql_command(thd) == SQLCOM_LOCK_TABLES + && THDVAR(thd, table_locks) + && thd_test_options(thd, OPTION_NOT_AUTOCOMMIT) + && thd_in_lock_tables(thd)) { ulint error = row_lock_table_for_mysql( prebuilt, NULL, 0); if (error != DB_SUCCESS) { error = convert_error_code_to_mysql( - (int) error, user_thd); + (int) error, thd); DBUG_RETURN((int) error); } } @@ -6374,6 +6465,12 @@ ha_innobase::external_lock( trx->n_mysql_tables_in_use--; prebuilt->mysql_has_locked = FALSE; + /* Release a possible FIFO ticket and search latch. Since we + may reserve the kernel mutex, we have to release the search + system latch first to obey the latching order. */ + + innobase_release_stat_resources(trx); + /* If the MySQL lock count drops to zero we know that the current SQL statement has ended */ @@ -6382,12 +6479,6 @@ ha_innobase::external_lock( trx->mysql_n_tables_locked = 0; prebuilt->used_in_HANDLER = FALSE; - /* Release a possible FIFO ticket and search latch. Since we - may reserve the kernel mutex, we have to release the search - system latch first to obey the latching order. */ - - innobase_release_stat_resources(trx); - if (!thd_test_options(thd, OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN)) { if (trx->active_trans != 0) { innobase_commit(ht, thd, TRUE); @@ -6429,8 +6520,7 @@ ha_innobase::transactional_table_lock( update_thd(thd); - if (prebuilt->table->ibd_file_missing - && !thd_tablespace_op(ha_thd())) { + if (prebuilt->table->ibd_file_missing && !thd_tablespace_op(thd)) { ut_print_timestamp(stderr); fprintf(stderr, " InnoDB error:\n" "MySQL is trying to use a table handle but the .ibd file for\n" @@ -6448,8 +6538,7 @@ ha_innobase::transactional_table_lock( prebuilt->sql_stat_start = TRUE; prebuilt->hint_need_to_fetch_extra_cols = 0; - prebuilt->read_just_key = 0; - prebuilt->keep_other_fields_on_keyread = FALSE; + reset_template(prebuilt); if (lock_type == F_WRLCK) { prebuilt->select_lock_type = LOCK_X; @@ -6475,13 +6564,13 @@ ha_innobase::transactional_table_lock( trx->active_trans = 1; } - if (thd_in_lock_tables(thd) && THDVAR(thd, table_locks)) { + if (THDVAR(thd, table_locks) && thd_in_lock_tables(thd)) { ulint error = DB_SUCCESS; error = row_lock_table_for_mysql(prebuilt, NULL, 0); if (error != DB_SUCCESS) { - error = convert_error_code_to_mysql((int) error, user_thd); + error = convert_error_code_to_mysql((int) error, thd); DBUG_RETURN((int) error); } @@ -6531,7 +6620,7 @@ innodb_show_status( DBUG_ENTER("innodb_show_status"); - trx = check_trx_exists(hton, thd); + trx = check_trx_exists(thd); innobase_release_stat_resources(trx); @@ -6809,7 +6898,7 @@ ha_innobase::store_lock( because we call update_thd() later, in ::external_lock()! Failure to understand this caused a serious memory corruption bug in 5.1.11. */ - trx = check_trx_exists(ht, thd); + trx = check_trx_exists(thd); /* NOTE: MySQL can call this function with lock 'type' TL_IGNORE! Be careful to ignore TL_IGNORE if we are going to do something with @@ -6819,9 +6908,9 @@ ha_innobase::store_lock( of the transaction. */ if (lock_type != TL_IGNORE - && trx->n_mysql_tables_in_use == 0) { + && trx->n_mysql_tables_in_use == 0) { trx->isolation_level = innobase_map_isolation_level( - (enum_tx_isolation)thd_tx_isolation(thd)); + (enum_tx_isolation) thd_tx_isolation(thd)); if (trx->isolation_level <= TRX_ISO_READ_COMMITTED && trx->global_read_view) { @@ -6843,12 +6932,12 @@ ha_innobase::store_lock( handle may belong to another thd that is running a query. Let us in that case skip any changes to the prebuilt struct. */ - } else if ((lock_type == TL_READ && in_lock_tables) || - (lock_type == TL_READ_HIGH_PRIORITY && in_lock_tables) || - lock_type == TL_READ_WITH_SHARED_LOCKS || - lock_type == TL_READ_NO_INSERT || - (sql_command != SQLCOM_SELECT - && lock_type != TL_IGNORE)) { + } else if ((lock_type == TL_READ && in_lock_tables) + || (lock_type == TL_READ_HIGH_PRIORITY && in_lock_tables) + || lock_type == TL_READ_WITH_SHARED_LOCKS + || lock_type == TL_READ_NO_INSERT + || (lock_type != TL_IGNORE + && sql_command != SQLCOM_SELECT)) { /* The OR cases above are in this order: 1) MySQL is doing LOCK TABLES ... READ LOCAL, or we @@ -6873,10 +6962,10 @@ ha_innobase::store_lock( isolation_level = trx->isolation_level; if ((srv_locks_unsafe_for_binlog - || isolation_level == TRX_ISO_READ_COMMITTED) - && isolation_level != TRX_ISO_SERIALIZABLE - && (lock_type == TL_READ || lock_type == TL_READ_NO_INSERT) - && (sql_command == SQLCOM_INSERT_SELECT + || isolation_level == TRX_ISO_READ_COMMITTED) + && isolation_level != TRX_ISO_SERIALIZABLE + && (lock_type == TL_READ || lock_type == TL_READ_NO_INSERT) + && (sql_command == SQLCOM_INSERT_SELECT || sql_command == SQLCOM_UPDATE || sql_command == SQLCOM_CREATE_TABLE)) { @@ -6947,24 +7036,25 @@ ha_innobase::store_lock( TRUE there). */ if ((lock_type >= TL_WRITE_CONCURRENT_INSERT - && lock_type <= TL_WRITE) - && !(in_lock_tables - && sql_command == SQLCOM_LOCK_TABLES) - && !thd_tablespace_op(thd) - && sql_command != SQLCOM_TRUNCATE - && sql_command != SQLCOM_OPTIMIZE + && lock_type <= TL_WRITE) + && !(in_lock_tables + && sql_command == SQLCOM_LOCK_TABLES) + && !thd_tablespace_op(thd) + && sql_command != SQLCOM_TRUNCATE + && sql_command != SQLCOM_OPTIMIZE #ifdef __WIN__ - /* For alter table on win32 for succesful operation - completion it is used TL_WRITE(=10) lock instead of - TL_WRITE_ALLOW_READ(=6), however here in innodb handler - TL_WRITE is lifted to TL_WRITE_ALLOW_WRITE, which causes - race condition when several clients do alter table - simultaneously (bug #17264). This fix avoids the problem. */ - && sql_command != SQLCOM_ALTER_TABLE + /* For alter table on win32 for successful + operation completion it is used TL_WRITE(=10) lock + instead of TL_WRITE_ALLOW_READ(=6), however here + in innodb handler TL_WRITE is lifted to + TL_WRITE_ALLOW_WRITE, which causes race condition + when several clients do alter table simultaneously + (bug #17264). This fix avoids the problem. */ + && sql_command != SQLCOM_ALTER_TABLE #endif - && sql_command != SQLCOM_CREATE_TABLE) { + && sql_command != SQLCOM_CREATE_TABLE) { lock_type = TL_WRITE_ALLOW_WRITE; } @@ -7009,11 +7099,16 @@ ha_innobase::innobase_read_and_init_auto_inc( longlong auto_inc; ulint old_select_lock_type; ibool trx_was_not_started = FALSE; + ibool stmt_start; int error; ut_a(prebuilt); ut_a(prebuilt->table); + /* Remember if we are in the beginning of an SQL statement. + This function must not change that flag. */ + stmt_start = prebuilt->sql_stat_start; + /* Prepare prebuilt->trx in the table handle */ update_thd(ha_thd()); @@ -7135,6 +7230,8 @@ func_exit_early: innobase_commit_low(prebuilt->trx); } + prebuilt->sql_stat_start = stmt_start; + return(error); } @@ -7206,7 +7303,7 @@ ha_innobase::reset_auto_increment(ulonglong value) bool ha_innobase::get_error_message(int error, String *buf) { - trx_t* trx = check_trx_exists(ht, ha_thd()); + trx_t* trx = check_trx_exists(ha_thd()); buf->copy(trx->detailed_error, strlen(trx->detailed_error), system_charset_info); @@ -7328,7 +7425,6 @@ ha_innobase::get_mysql_bin_log_pos() return(trx_sys_mysql_bin_log_pos); } -extern "C" { /********************************************************************** This function is used to find the storage length in bytes of the first n characters for prefix indexes using a multibyte character set. The function @@ -7337,7 +7433,7 @@ index field in bytes. NOTE: the prototype of this function is copied to data0type.c! If you change this function, you MUST change also data0type.c! */ - +extern "C" ulint innobase_get_at_most_n_mbchars( /*===========================*/ @@ -7402,39 +7498,6 @@ innobase_get_at_most_n_mbchars( return(char_length); } -} - -/********************************************************************** -This function returns true if - -1) SQL-query in the current thread -is either REPLACE or LOAD DATA INFILE REPLACE. - -2) SQL-query in the current thread -is INSERT ON DUPLICATE KEY UPDATE. - -NOTE that storage/innobase/row/row0ins.c must contain the -prototype for this function ! */ -extern "C" -ibool -innobase_query_is_update(void) -/*==========================*/ -{ - THD* thd = current_thd; - trx_t* trx; - - if (!thd) { - /* InnoDB's internal threads may run InnoDB stored procedures - that call this function. Then current_thd is not defined - (it is probably NULL). */ - - return(FALSE); - } - - trx = check_trx_exists(innodb_hton_ptr, thd); - - return(trx->allow_duplicates); -} /*********************************************************************** This function is used to prepare X/Open XA distributed transaction */ @@ -7450,7 +7513,7 @@ innobase_xa_prepare( FALSE - the current SQL statement ended */ { int error = 0; - trx_t* trx = check_trx_exists(hton, thd); + trx_t* trx = check_trx_exists(thd); if (thd_sql_command(thd) != SQLCOM_XA_PREPARE && (all || !thd_test_options(thd, OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN))) @@ -7484,7 +7547,7 @@ innobase_xa_prepare( return(0); } - trx->xid=thd->transaction.xid_state.xid; + thd_get_xid(thd, (MYSQL_XID*) &trx->xid); /* Release a possible FIFO ticket and search latch. Since we will reserve the kernel mutex, we have to release the search system latch @@ -7611,8 +7674,7 @@ innobase_create_cursor_view( handlerton *hton, /* in: innobase hton */ THD* thd) /* in: user thread handle */ { - return(read_cursor_view_create_for_mysql( - check_trx_exists(hton, thd))); + return(read_cursor_view_create_for_mysql(check_trx_exists(thd))); } /*********************************************************************** @@ -7627,8 +7689,8 @@ innobase_close_cursor_view( THD* thd, /* in: user thread handle */ void* curview)/* in: Consistent read view to be closed */ { - read_cursor_view_close_for_mysql(check_trx_exists(hton, current_thd), - (cursor_view_t*) curview); + read_cursor_view_close_for_mysql(check_trx_exists(thd), + (cursor_view_t*) curview); } /*********************************************************************** @@ -7644,8 +7706,8 @@ innobase_set_cursor_view( THD* thd, /* in: user thread handle */ void* curview)/* in: Consistent cursor view to be set */ { - read_cursor_set_for_mysql(check_trx_exists(hton, current_thd), - (cursor_view_t*) curview); + read_cursor_set_for_mysql(check_trx_exists(thd), + (cursor_view_t*) curview); } @@ -7728,8 +7790,9 @@ static MYSQL_SYSVAR_BOOL(file_per_table, innobase_file_per_table, static MYSQL_SYSVAR_ULONG(flush_log_at_trx_commit, srv_flush_log_at_trx_commit, PLUGIN_VAR_OPCMDARG, - "Set to 0 (write and flush once per second), 1 (write and flush at each commit)" - " or 2 (write at commit, flush once per second).", + "Set to 0 (write and flush once per second)," + " 1 (write and flush at each commit)" + " or 2 (write at commit, flush once per second).", NULL, NULL, 1, 0, 2, 0); static MYSQL_SYSVAR_STR(flush_method, innobase_unix_file_flush_method, @@ -7741,11 +7804,11 @@ static MYSQL_SYSVAR_BOOL(locks_unsafe_for_binlog, innobase_locks_unsafe_for_binl "Force InnoDB to not use next-key locking, to use only row-level locking.", NULL, NULL, FALSE); +#ifdef UNIV_LOG_ARCHIVE static MYSQL_SYSVAR_STR(log_arch_dir, innobase_log_arch_dir, PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY, "Where full logs should be archived.", NULL, NULL, NULL); -#ifdef UNIV_LOG_ARCHIVE static MYSQL_SYSVAR_BOOL(log_archive, innobase_log_archive, PLUGIN_VAR_OPCMDARG | PLUGIN_VAR_READONLY, "Set to 1 if you want to have logs archived.", NULL, NULL, FALSE); @@ -7883,8 +7946,8 @@ static struct st_mysql_sys_var* innobase_system_variables[]= { MYSQL_SYSVAR(force_recovery), MYSQL_SYSVAR(locks_unsafe_for_binlog), MYSQL_SYSVAR(lock_wait_timeout), - MYSQL_SYSVAR(log_arch_dir), #ifdef UNIV_LOG_ARCHIVE + MYSQL_SYSVAR(log_arch_dir), MYSQL_SYSVAR(log_archive), #endif /* UNIV_LOG_ARCHIVE */ MYSQL_SYSVAR(log_buffer_size), @@ -7922,5 +7985,3 @@ mysql_declare_plugin(innobase) NULL /* reserved */ } mysql_declare_plugin_end; - -#endif diff --git a/storage/innobase/handler/ha_innodb.h b/storage/innobase/handler/ha_innodb.h index c727243bfd3..b10cccded18 100644 --- a/storage/innobase/handler/ha_innodb.h +++ b/storage/innobase/handler/ha_innodb.h @@ -190,27 +190,50 @@ class ha_innobase: public handler uint table_changes); }; -extern long innobase_mirrored_log_groups, innobase_log_files_in_group; -extern long long innobase_buffer_pool_size, innobase_log_file_size; -extern long innobase_log_buffer_size; -extern long innobase_additional_mem_pool_size; -extern long innobase_buffer_pool_awe_mem_mb; -extern long innobase_file_io_threads, innobase_lock_wait_timeout; -extern long innobase_force_recovery; -extern long innobase_open_files; -extern char *innobase_data_home_dir, *innobase_data_file_path; -extern char *innobase_log_group_home_dir, *innobase_log_arch_dir; -extern char *innobase_unix_file_flush_method; +/* Some accessor functions which the InnoDB plugin needs, but which +can not be added to mysql/plugin.h as part of the public interface; +the definitions are bracketed with #ifdef INNODB_COMPATIBILITY_HOOKS */ + +#ifndef INNODB_COMPATIBILITY_HOOKS +#error InnoDB needs MySQL to be built with #define INNODB_COMPATIBILITY_HOOKS +#endif + extern "C" { -extern ulong srv_max_buf_pool_modified_pct; -extern ulong srv_max_purge_lag; -extern ulong srv_auto_extend_increment; -extern ulong srv_n_spin_wait_rounds; -extern ulong srv_n_free_tickets_to_enter; -extern ulong srv_thread_sleep_delay; -extern ulong srv_thread_concurrency; -extern ulong srv_commit_concurrency; -extern ulong srv_flush_log_at_trx_commit; +struct charset_info_st *thd_charset(MYSQL_THD thd); +char **thd_query(MYSQL_THD thd); + +/** Get the file name of the MySQL binlog. + * @return the name of the binlog file + */ +const char* mysql_bin_log_file_name(void); + +/** Get the current position of the MySQL binlog. + * @return byte offset from the beginning of the binlog + */ +ulonglong mysql_bin_log_file_pos(void); + +/** + Check if a user thread is a replication slave thread + @param thd user thread + @retval 0 the user thread is not a replication slave thread + @retval 1 the user thread is a replication slave thread +*/ +int thd_slave_thread(const MYSQL_THD thd); + +/** + Check if a user thread is running a non-transactional update + @param thd user thread + @retval 0 the user thread is not running a non-transactional update + @retval 1 the user thread is running a non-transactional update +*/ +int thd_non_transactional_update(const MYSQL_THD thd); + +/** + Get the user thread's binary logging format + @param thd user thread + @return Value to be used as index into the binlog_format_names array +*/ +int thd_binlog_format(const MYSQL_THD thd); } /* diff --git a/storage/innobase/ibuf/Makefile.am b/storage/innobase/ibuf/Makefile.am deleted file mode 100644 index 42adda9a4ef..00000000000 --- a/storage/innobase/ibuf/Makefile.am +++ /dev/null @@ -1,25 +0,0 @@ -# Copyright (C) 2001, 2003 MySQL AB & Innobase Oy -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; version 2 of the License. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - -include ../include/Makefile.i - -noinst_LIBRARIES = libibuf.a - -libibuf_a_SOURCES = ibuf0ibuf.c - -EXTRA_PROGRAMS = - -# Don't update the files from bitkeeper -%::SCCS/s.% diff --git a/storage/innobase/ibuf/ibuf0ibuf.c b/storage/innobase/ibuf/ibuf0ibuf.c index 1cbb6003cfc..4e291924e0e 100644 --- a/storage/innobase/ibuf/ibuf0ibuf.c +++ b/storage/innobase/ibuf/ibuf0ibuf.c @@ -150,9 +150,30 @@ ulint ibuf_flush_count = 0; #define IBUF_COUNT_N_PAGES 2000 /* Buffered entry counts for file pages, used in debugging */ -static ulint* ibuf_counts[IBUF_COUNT_N_SPACES]; +static ulint ibuf_counts[IBUF_COUNT_N_SPACES][IBUF_COUNT_N_PAGES]; -static ibool ibuf_counts_inited = FALSE; +/********************************************************************** +Checks that the indexes to ibuf_counts[][] are within limits. */ +UNIV_INLINE +void +ibuf_count_check( +/*=============*/ + ulint space_id, /* in: space identifier */ + ulint page_no) /* in: page number */ +{ + if (space_id < IBUF_COUNT_N_SPACES && page_no < IBUF_COUNT_N_PAGES) { + return; + } + + fprintf(stderr, + "InnoDB: UNIV_IBUF_DEBUG limits space_id and page_no\n" + "InnoDB: and breaks crash recovery.\n" + "InnoDB: space_id=%lu, should be 0<=space_id<%lu\n" + "InnoDB: page_no=%lu, should be 0<=page_no<%lu\n", + (ulint) space_id, (ulint) IBUF_COUNT_N_SPACES, + (ulint) page_no, (ulint) IBUF_COUNT_N_PAGES); + ut_error; +} #endif /* The start address for an insert buffer bitmap page bitmap */ @@ -328,15 +349,9 @@ ibuf_count_get( ulint space, /* in: space id */ ulint page_no)/* in: page number */ { - ut_ad(space < IBUF_COUNT_N_SPACES); - ut_ad(page_no < IBUF_COUNT_N_PAGES); - - if (!ibuf_counts_inited) { - - return(0); - } + ibuf_count_check(space, page_no); - return(*(ibuf_counts[space] + page_no)); + return(ibuf_counts[space][page_no]); } /********************************************************************** @@ -349,11 +364,10 @@ ibuf_count_set( ulint page_no,/* in: page number */ ulint val) /* in: value to set */ { - ut_a(space < IBUF_COUNT_N_SPACES); - ut_a(page_no < IBUF_COUNT_N_PAGES); + ibuf_count_check(space, page_no); ut_a(val < UNIV_PAGE_SIZE); - *(ibuf_counts[space] + page_no) = val; + ibuf_counts[space][page_no] = val; } #endif @@ -378,22 +392,6 @@ ibuf_init_at_db_start(void) ibuf->size = 0; -#ifdef UNIV_IBUF_DEBUG - { - ulint i, j; - - for (i = 0; i < IBUF_COUNT_N_SPACES; i++) { - - ibuf_counts[i] = mem_alloc(sizeof(ulint) - * IBUF_COUNT_N_PAGES); - for (j = 0; j < IBUF_COUNT_N_PAGES; j++) { - ibuf_count_set(i, j, 0); - } - } - - ibuf_counts_inited = TRUE; - } -#endif mutex_create(&ibuf_pessimistic_insert_mutex, SYNC_IBUF_PESS_INSERT_MUTEX); @@ -567,7 +565,8 @@ ibuf_bitmap_page_init( bit_offset = XDES_DESCRIBED_PER_PAGE * IBUF_BITS_PER_PAGE; - byte_offset = bit_offset / 8 + 1; /* better: (bit_offset + 7) / 8 */ + byte_offset = bit_offset / 8 + 1; + /* better: byte_offset = UT_BITS_IN_BYTES(bit_offset); */ fil_page_set_type(page, FIL_PAGE_IBUF_BITMAP); @@ -1441,6 +1440,9 @@ ibuf_entry_build( *buf2++ = 0; /* write the compact format indicator */ } for (i = 0; i < n_fields; i++) { + ulint fixed_len; + const dict_field_t* ifield; + /* We add 4 below because we have the 4 extra fields at the start of an ibuf record */ @@ -1448,10 +1450,30 @@ ibuf_entry_build( entry_field = dtuple_get_nth_field(entry, i); dfield_copy(field, entry_field); + ifield = dict_index_get_nth_field(index, i); + /* Prefix index columns of fixed-length columns are of + fixed length. However, in the function call below, + dfield_get_type(entry_field) contains the fixed length + of the column in the clustered index. Replace it with + the fixed length of the secondary index column. */ + fixed_len = ifield->fixed_len; + +#ifdef UNIV_DEBUG + if (fixed_len) { + /* dict_index_add_col() should guarantee these */ + ut_ad(fixed_len <= (ulint) entry_field->type.len); + if (ifield->prefix_len) { + ut_ad(ifield->prefix_len == fixed_len); + } else { + ut_ad(fixed_len + == (ulint) entry_field->type.len); + } + } +#endif /* UNIV_DEBUG */ + dtype_new_store_for_order_and_null_size( buf2 + i * DATA_NEW_ORDER_NULL_TYPE_BUF_SIZE, - dfield_get_type(entry_field), - dict_index_get_nth_field(index, i)->prefix_len); + dfield_get_type(entry_field), fixed_len); } /* Store the type info in buf2 to field 3 of tuple */ diff --git a/storage/innobase/include/Makefile.i b/storage/innobase/include/Makefile.i deleted file mode 100644 index db436c702ff..00000000000 --- a/storage/innobase/include/Makefile.i +++ /dev/null @@ -1,10 +0,0 @@ -# Makefile included in Makefile.am in every subdirectory - -INCLUDES = -I$(top_srcdir)/include -I$(top_builddir)/include \ - -I$(top_srcdir)/regex \ - -I$(top_srcdir)/storage/innobase/include \ - -I$(top_srcdir)/sql \ - -I$(srcdir) - -# Don't update the files from bitkeeper -%::SCCS/s.% diff --git a/storage/innobase/include/db0err.h b/storage/innobase/include/db0err.h index 843c70af577..0aa1b87e470 100644 --- a/storage/innobase/include/db0err.h +++ b/storage/innobase/include/db0err.h @@ -62,6 +62,11 @@ Created 5/24/1996 Heikki Tuuri lead to a duplicate key in some table */ +#define DB_TOO_MANY_CONCURRENT_TRXS 47 /* when InnoDB runs out of the + preconfigured undo slots, this can + only happen when there are too many + concurrent transactions */ + /* The following are partial failure codes */ #define DB_FAIL 1000 #define DB_OVERFLOW 1001 diff --git a/storage/innobase/include/dict0dict.h b/storage/innobase/include/dict0dict.h index 836a6290498..eb31043ecc3 100644 --- a/storage/innobase/include/dict0dict.h +++ b/storage/innobase/include/dict0dict.h @@ -92,6 +92,17 @@ dict_col_copy_type_noninline( /*=========================*/ const dict_col_t* col, /* in: column */ dtype_t* type); /* out: data type */ +#ifdef UNIV_DEBUG +/************************************************************************* +Assert that a column and a data type match. */ +UNIV_INLINE +ibool +dict_col_type_assert_equal( +/*=======================*/ + /* out: TRUE */ + const dict_col_t* col, /* in: column */ + const dtype_t* type); /* in: data type */ +#endif /* UNIV_DEBUG */ /*************************************************************************** Returns the minimum size of the column. */ UNIV_INLINE diff --git a/storage/innobase/include/dict0dict.ic b/storage/innobase/include/dict0dict.ic index 4a9afd2f3f5..7d38cbcd1fa 100644 --- a/storage/innobase/include/dict0dict.ic +++ b/storage/innobase/include/dict0dict.ic @@ -30,6 +30,30 @@ dict_col_copy_type( type->mbmaxlen = col->mbmaxlen; } +#ifdef UNIV_DEBUG +/************************************************************************* +Assert that a column and a data type match. */ +UNIV_INLINE +ibool +dict_col_type_assert_equal( +/*=======================*/ + /* out: TRUE */ + const dict_col_t* col, /* in: column */ + const dtype_t* type) /* in: data type */ +{ + ut_ad(col); + ut_ad(type); + + ut_ad(col->mtype == type->mtype); + ut_ad(col->prtype == type->prtype); + ut_ad(col->len == type->len); + ut_ad(col->mbminlen == type->mbminlen); + ut_ad(col->mbmaxlen == type->mbmaxlen); + + return(TRUE); +} +#endif /* UNIV_DEBUG */ + /*************************************************************************** Returns the minimum size of the column. */ UNIV_INLINE diff --git a/storage/innobase/include/dict0mem.h b/storage/innobase/include/dict0mem.h index a23f89954a4..647035c2fff 100644 --- a/storage/innobase/include/dict0mem.h +++ b/storage/innobase/include/dict0mem.h @@ -158,10 +158,13 @@ struct dict_col_struct{ of an index */ }; -/* DICT_MAX_INDEX_COL_LEN is measured in bytes and is the max index column -length + 1. Starting from 4.1.6, we set it to < 3 * 256, so that one can -create a column prefix index on 255 characters of a TEXT field also in the -UTF-8 charset. In that charset, a character may take at most 3 bytes. */ +/* DICT_MAX_INDEX_COL_LEN is measured in bytes and is the maximum +indexed column length (or indexed prefix length). It is set to 3*256, +so that one can create a column prefix index on 256 characters of a +TEXT or VARCHAR column also in the UTF-8 charset. In that charset, +a character may take at most 3 bytes. +This constant MUST NOT BE CHANGED, or the compatibility of InnoDB data +files would be at risk! */ #define DICT_MAX_INDEX_COL_LEN 768 diff --git a/storage/innobase/include/ha_prototypes.h b/storage/innobase/include/ha_prototypes.h index 2d27034fdfe..7fb50988941 100644 --- a/storage/innobase/include/ha_prototypes.h +++ b/storage/innobase/include/ha_prototypes.h @@ -1,6 +1,9 @@ #ifndef HA_INNODB_PROTOTYPES_H #define HA_INNODB_PROTOTYPES_H +#include "univ.i" /* ulint, uint */ +#include "m_ctype.h" /* CHARSET_INFO */ + /* Prototypes for global functions in ha_innodb.cc that are called by InnoDB's C-code. */ @@ -19,4 +22,30 @@ innobase_convert_string( CHARSET_INFO* from_cs, uint* errors); +/********************************************************************** +Returns true if the thread is the replication thread on the slave +server. Used in srv_conc_enter_innodb() to determine if the thread +should be allowed to enter InnoDB - the replication thread is treated +differently than other threads. Also used in +srv_conc_force_exit_innodb(). */ + +ibool +thd_is_replication_slave_thread( +/*============================*/ + /* out: true if thd is the replication thread */ + void* thd); /* in: thread handle (THD*) */ + +/********************************************************************** +Returns true if the transaction this thread is processing has edited +non-transactional tables. Used by the deadlock detector when deciding +which transaction to rollback in case of a deadlock - we try to avoid +rolling back transactions that have edited non-transactional tables. */ + +ibool +thd_has_edited_nontrans_tables( +/*===========================*/ + /* out: true if non-transactional tables have + been edited */ + void* thd); /* in: thread handle (THD*) */ + #endif diff --git a/storage/innobase/include/os0file.h b/storage/innobase/include/os0file.h index 5ffcdf7e58c..9eb44d3f4a8 100644 --- a/storage/innobase/include/os0file.h +++ b/storage/innobase/include/os0file.h @@ -94,7 +94,8 @@ log. */ #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 76 +#define OS_FILE_SHARING_VIOLATION 76 +#define OS_FILE_ERROR_NOT_SPECIFIED 77 /* Types for aio operations */ #define OS_FILE_READ 10 diff --git a/storage/innobase/include/rem0rec.ic b/storage/innobase/include/rem0rec.ic index 90a35af74dc..95aa65fabba 100644 --- a/storage/innobase/include/rem0rec.ic +++ b/storage/innobase/include/rem0rec.ic @@ -795,7 +795,8 @@ UNIV_INLINE void rec_offs_set_n_alloc( /*=================*/ - ulint* offsets, /* in: array for rec_get_offsets() */ + ulint* offsets, /* out: array for rec_get_offsets(), + must be allocated */ ulint n_alloc) /* in: number of elements */ { ut_ad(offsets); @@ -1282,7 +1283,8 @@ UNIV_INLINE void rec_offs_set_n_fields( /*==================*/ - ulint* offsets, /* in: array returned by rec_get_offsets() */ + ulint* offsets, /* in/out: array returned by + rec_get_offsets() */ ulint n_fields) /* in: number of fields */ { ut_ad(offsets); diff --git a/storage/innobase/include/row0mysql.h b/storage/innobase/include/row0mysql.h index 1448efe94fe..bda3494073f 100644 --- a/storage/innobase/include/row0mysql.h +++ b/storage/innobase/include/row0mysql.h @@ -460,6 +460,19 @@ row_check_table_for_mysql( /* out: DB_ERROR or DB_SUCCESS */ row_prebuilt_t* prebuilt); /* in: prebuilt struct in MySQL handle */ +/************************************************************************* +Get the min of the maximum possible row sizes. */ + +ulint +page_get_free_space_of_empty_noninline( +/*===================================*/ + /* out: The (approx) maximum size + of a row, this is a conservative + estimate, since the size can be + slightly larger depending upon + the ROW_FORMAT setting.*/ + dict_table_t* table); /* in: table for which max record + size required.*/ /* A struct describing a place for an individual column in the MySQL row format which is presented to the table handler in ha_innobase. diff --git a/storage/innobase/include/trx0trx.h b/storage/innobase/include/trx0trx.h index e75c200cc3a..eeda2a7a52c 100644 --- a/storage/innobase/include/trx0trx.h +++ b/storage/innobase/include/trx0trx.h @@ -371,6 +371,18 @@ trx_is_interrupted( #define trx_is_interrupted(trx) FALSE #endif /* !UNIV_HOTBACKUP */ +/*********************************************************************** +Compares the "weight" (or size) of two transactions. The weight of one +transaction is estimated as the number of altered rows + the number of +locked rows. Transactions that have edited non-transactional tables are +considered heavier than ones that have not. */ + +int +trx_weight_cmp( +/*===========*/ + /* out: <0, 0 or >0; similar to strcmp(3) */ + trx_t* a, /* in: the first transaction to be compared */ + trx_t* b); /* in: the second transaction to be compared */ /* Signal to a transaction */ struct trx_sig_struct{ @@ -453,7 +465,8 @@ struct trx_struct{ dulint table_id; /* table id if the preceding field is TRUE */ /*------------------------------*/ - int active_trans; /* 1 - if a transaction in MySQL + unsigned duplicates:2; /* TRX_DUP_IGNORE | TRX_DUP_REPLACE */ + unsigned active_trans:2; /* 1 - if a transaction in MySQL is active. 2 - if prepare_commit_mutex was taken */ void* mysql_thd; /* MySQL thread handle corresponding @@ -610,7 +623,7 @@ struct trx_struct{ NULL */ ibool was_chosen_as_deadlock_victim; /* when the transaction decides to wait - for a lock, this it sets this to FALSE; + for a lock, it sets this to FALSE; if another transaction chooses this transaction as a victim in deadlock resolution, it sets this to TRUE */ @@ -651,7 +664,12 @@ struct trx_struct{ cannot be any activity in the undo logs! */ dulint undo_no; /* next undo log record number to - assign */ + assign; since the undo log is + private for a transaction, this + is a simple ascending sequence + with no gaps; thus it represents + the number of modified/inserted + rows in a transaction */ trx_savept_t last_sql_stat_start; /* undo_no when the last sql statement was started: in case of an error, trx @@ -681,19 +699,19 @@ struct trx_struct{ single operation of a transaction, e.g., a parallel query */ -/* Transaction concurrency states */ +/* Transaction concurrency states (trx->conc_state) */ #define TRX_NOT_STARTED 1 #define TRX_ACTIVE 2 #define TRX_COMMITTED_IN_MEMORY 3 #define TRX_PREPARED 4 /* Support for 2PC/XA */ -/* Transaction execution states when trx state is TRX_ACTIVE */ +/* Transaction execution states when trx->conc_state == TRX_ACTIVE */ #define TRX_QUE_RUNNING 1 /* transaction is running */ #define TRX_QUE_LOCK_WAIT 2 /* transaction is waiting for a lock */ #define TRX_QUE_ROLLING_BACK 3 /* transaction is rolling back */ #define TRX_QUE_COMMITTING 4 /* transaction is committing */ -/* Transaction isolation levels */ +/* Transaction isolation levels (trx->isolation_level) */ #define TRX_ISO_READ_UNCOMMITTED 1 /* dirty read: non-locking SELECTs are performed so that we do not look at a possible @@ -728,6 +746,12 @@ struct trx_struct{ converted to LOCK IN SHARE MODE reads */ +/* Treatment of duplicate values (trx->duplicates; for example, in inserts). +Multiple flags can be combined with bitwise OR. */ +#define TRX_DUP_IGNORE 1 /* duplicate rows are to be updated */ +#define TRX_DUP_REPLACE 2 /* duplicate rows are to be replaced */ + + /* Types of a trx signal */ #define TRX_SIG_NO_SIGNAL 100 #define TRX_SIG_TOTAL_ROLLBACK 1 diff --git a/storage/innobase/include/trx0undo.h b/storage/innobase/include/trx0undo.h index 87849ab42c3..f53c6b01be4 100644 --- a/storage/innobase/include/trx0undo.h +++ b/storage/innobase/include/trx0undo.h @@ -222,13 +222,16 @@ trx_undo_lists_init( Assigns an undo log for a transaction. A new undo log is created or a cached undo log reused. */ -trx_undo_t* +ulint trx_undo_assign_undo( /*=================*/ - /* out: the undo log, NULL if did not succeed: out of - space */ - trx_t* trx, /* in: transaction */ - ulint type); /* in: TRX_UNDO_INSERT or TRX_UNDO_UPDATE */ + /* out: DB_SUCCESS if undo log assign + * successful, possible error codes are: + * ER_TOO_MANY_CONCURRENT_TRXS + * DB_OUT_OF_FILE_SPAC + * DB_OUT_OF_MEMORY */ + trx_t* trx, /* in: transaction */ + ulint type); /* in: TRX_UNDO_INSERT or TRX_UNDO_UPDATE */ /********************************************************************** Sets the state of the undo log segment at a transaction finish. */ diff --git a/storage/innobase/include/ut0ut.h b/storage/innobase/include/ut0ut.h index 8bfc1edd323..825c10d5f11 100644 --- a/storage/innobase/include/ut0ut.h +++ b/storage/innobase/include/ut0ut.h @@ -121,6 +121,11 @@ ut_2_power_up( /* out: first power of 2 which is >= n */ ulint n) /* in: number != 0 */ __attribute__((const)); + +/* Determine how many bytes (groups of 8 bits) are needed to +store the given number of bits. */ +#define UT_BITS_IN_BYTES(b) (((b) + 7) / 8) + /**************************************************************** Sort function for ulint arrays. */ diff --git a/storage/innobase/lock/Makefile.am b/storage/innobase/lock/Makefile.am deleted file mode 100644 index 4c6caa49853..00000000000 --- a/storage/innobase/lock/Makefile.am +++ /dev/null @@ -1,25 +0,0 @@ -# Copyright (C) 2001, 2003 MySQL AB & Innobase Oy -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; version 2 of the License. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - -include ../include/Makefile.i - -noinst_LIBRARIES = liblock.a - -liblock_a_SOURCES = lock0lock.c - -EXTRA_PROGRAMS = - -# Don't update the files from bitkeeper -%::SCCS/s.% diff --git a/storage/innobase/lock/lock0lock.c b/storage/innobase/lock/lock0lock.c index 93a43d9a30f..6f5390145b5 100644 --- a/storage/innobase/lock/lock0lock.c +++ b/storage/innobase/lock/lock0lock.c @@ -3174,7 +3174,8 @@ lock_deadlock_occurs( ulint ret; ulint cost = 0; - ut_ad(trx && lock); + ut_ad(trx); + ut_ad(lock); ut_ad(mutex_own(&kernel_mutex)); retry: /* We check that adding this trx to the waits-for graph @@ -3246,7 +3247,9 @@ lock_deadlock_recursive( trx_t* lock_trx; ulint ret; - ut_a(trx && start && wait_lock); + ut_a(trx); + ut_a(start); + ut_a(wait_lock); ut_ad(mutex_own(&kernel_mutex)); if (trx->deadlock_mark == 1) { @@ -3357,8 +3360,8 @@ lock_deadlock_recursive( return(LOCK_VICTIM_IS_START); } - if (ut_dulint_cmp(wait_lock->trx->undo_no, - start->undo_no) >= 0) { + if (trx_weight_cmp(wait_lock->trx, + start) >= 0) { /* Our recursion starting point transaction is 'smaller', let us choose 'start' as the victim and roll @@ -4423,12 +4426,9 @@ lock_table_queue_validate( dict_table_t* table) /* in: table */ { lock_t* lock; - ibool is_waiting; ut_ad(mutex_own(&kernel_mutex)); - is_waiting = FALSE; - lock = UT_LIST_GET_FIRST(table->locks); while (lock) { @@ -4438,13 +4438,10 @@ lock_table_queue_validate( if (!lock_get_wait(lock)) { - ut_a(!is_waiting); - ut_a(!lock_table_other_has_incompatible( lock->trx, 0, table, lock_get_mode(lock))); } else { - is_waiting = TRUE; ut_a(lock_table_has_to_wait_in_queue(lock)); } diff --git a/storage/innobase/log/Makefile.am b/storage/innobase/log/Makefile.am deleted file mode 100644 index a40572a64da..00000000000 --- a/storage/innobase/log/Makefile.am +++ /dev/null @@ -1,25 +0,0 @@ -# Copyright (C) 2001, 2003 MySQL AB & Innobase Oy -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; version 2 of the License. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - -include ../include/Makefile.i - -noinst_LIBRARIES = liblog.a - -liblog_a_SOURCES = log0log.c log0recv.c - -EXTRA_PROGRAMS = - -# Don't update the files from bitkeeper -%::SCCS/s.% diff --git a/storage/innobase/log/log0log.c b/storage/innobase/log/log0log.c index e9dedf6aac4..b10c348b24d 100644 --- a/storage/innobase/log/log0log.c +++ b/storage/innobase/log/log0log.c @@ -3039,10 +3039,22 @@ loop: mutex_enter(&kernel_mutex); - /* Check that there are no longer transactions. We need this wait - even for the 'very fast' shutdown, because the InnoDB layer may have - committed or prepared transactions and we don't want to lose - them. */ + /* We need the monitor threads to stop before we proceed with a + normal shutdown. In case of very fast shutdown, however, we can + proceed without waiting for monitor threads. */ + + if (srv_fast_shutdown < 2 + && (srv_error_monitor_active + || srv_lock_timeout_and_monitor_active)) { + + mutex_exit(&kernel_mutex); + + goto loop; + } + + /* Check that there are no longer transactions. We need this wait even + for the 'very fast' shutdown, because the InnoDB layer may have + committed or prepared transactions and we don't want to lose them. */ if (trx_n_mysql_transactions > 0 || UT_LIST_GET_LEN(trx_sys->trx_list) > 0) { @@ -3163,22 +3175,8 @@ loop: goto loop; } - /* The lock timeout thread should now have exited */ - - if (srv_lock_timeout_and_monitor_active) { - - goto loop; - } - - /* We now let also the InnoDB error monitor thread to exit */ - srv_shutdown_state = SRV_SHUTDOWN_LAST_PHASE; - if (srv_error_monitor_active) { - - goto loop; - } - /* Make some checks that the server really is quiet */ ut_a(srv_n_threads_active[SRV_MASTER] == 0); ut_a(buf_all_freed()); diff --git a/storage/innobase/mach/Makefile.am b/storage/innobase/mach/Makefile.am deleted file mode 100644 index 1a59cb3e4d7..00000000000 --- a/storage/innobase/mach/Makefile.am +++ /dev/null @@ -1,25 +0,0 @@ -# Copyright (C) 2001, 2003 MySQL AB & Innobase Oy -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; version 2 of the License. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - -include ../include/Makefile.i - -noinst_LIBRARIES = libmach.a - -libmach_a_SOURCES = mach0data.c - -EXTRA_PROGRAMS = - -# Don't update the files from bitkeeper -%::SCCS/s.% diff --git a/storage/innobase/mem/Makefile.am b/storage/innobase/mem/Makefile.am deleted file mode 100644 index 598dbb96124..00000000000 --- a/storage/innobase/mem/Makefile.am +++ /dev/null @@ -1,27 +0,0 @@ -# Copyright (C) 2001, 2003 MySQL AB & Innobase Oy -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; version 2 of the License. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - -include ../include/Makefile.i - -noinst_LIBRARIES = libmem.a - -libmem_a_SOURCES = mem0mem.c mem0pool.c - -EXTRA_DIST = mem0dbg.c - -EXTRA_PROGRAMS = - -# Don't update the files from bitkeeper -%::SCCS/s.% diff --git a/storage/innobase/mtr/Makefile.am b/storage/innobase/mtr/Makefile.am deleted file mode 100644 index 80eb7c907be..00000000000 --- a/storage/innobase/mtr/Makefile.am +++ /dev/null @@ -1,25 +0,0 @@ -# Copyright (C) 2001, 2003 MySQL AB & Innobase Oy -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; version 2 of the License. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - -include ../include/Makefile.i - -noinst_LIBRARIES = libmtr.a - -libmtr_a_SOURCES = mtr0mtr.c mtr0log.c - -EXTRA_PROGRAMS = - -# Don't update the files from bitkeeper -%::SCCS/s.% diff --git a/storage/innobase/os/Makefile.am b/storage/innobase/os/Makefile.am deleted file mode 100644 index d5c45eba54e..00000000000 --- a/storage/innobase/os/Makefile.am +++ /dev/null @@ -1,25 +0,0 @@ -# Copyright (C) 2001, 2003-2004 MySQL AB & Innobase Oy -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; version 2 of the License. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - -include ../include/Makefile.i - -noinst_LIBRARIES = libos.a - -libos_a_SOURCES = os0proc.c os0sync.c os0thread.c os0file.c - -EXTRA_PROGRAMS = - -# Don't update the files from bitkeeper -%::SCCS/s.% diff --git a/storage/innobase/os/os0file.c b/storage/innobase/os/os0file.c index c18ba047d4e..f496e1127ce 100644 --- a/storage/innobase/os/os0file.c +++ b/storage/innobase/os/os0file.c @@ -250,6 +250,15 @@ os_file_get_last_error( "InnoDB: the directory. It may also be" " you have created a subdirectory\n" "InnoDB: of the same name as a data file.\n"); + } else if (err == ERROR_SHARING_VIOLATION + || err == ERROR_LOCK_VIOLATION) { + fprintf(stderr, + "InnoDB: The error means that another program" + " is using InnoDB's files.\n" + "InnoDB: This might be a backup or antivirus" + " software or another instance\n" + "InnoDB: of MySQL." + " Please close it to get rid of this error.\n"); } else { fprintf(stderr, "InnoDB: Some operating system error numbers" @@ -268,6 +277,9 @@ os_file_get_last_error( return(OS_FILE_DISK_FULL); } else if (err == ERROR_FILE_EXISTS) { return(OS_FILE_ALREADY_EXISTS); + } else if (err == ERROR_SHARING_VIOLATION + || err == ERROR_LOCK_VIOLATION) { + return(OS_FILE_SHARING_VIOLATION); } else { return(100 + err); } @@ -388,6 +400,10 @@ os_file_handle_error_cond_exit( || err == OS_FILE_PATH_ERROR) { return(FALSE); + } else if (err == OS_FILE_SHARING_VIOLATION) { + + os_thread_sleep(10000000); /* 10 sec */ + return(TRUE); } else { if (name) { fprintf(stderr, "InnoDB: File name %s\n", name); diff --git a/storage/innobase/page/Makefile.am b/storage/innobase/page/Makefile.am deleted file mode 100644 index 1a5b202a2c9..00000000000 --- a/storage/innobase/page/Makefile.am +++ /dev/null @@ -1,25 +0,0 @@ -# Copyright (C) 2001, 2003 MySQL AB & Innobase Oy -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; version 2 of the License. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - -include ../include/Makefile.i - -noinst_LIBRARIES = libpage.a - -libpage_a_SOURCES = page0page.c page0cur.c - -EXTRA_PROGRAMS = - -# Don't update the files from bitkeeper -%::SCCS/s.% diff --git a/storage/innobase/pars/Makefile.am b/storage/innobase/pars/Makefile.am deleted file mode 100644 index b10796c3d5e..00000000000 --- a/storage/innobase/pars/Makefile.am +++ /dev/null @@ -1,27 +0,0 @@ -# Copyright (C) 2001, 2003 MySQL AB & Innobase Oy -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; version 2 of the License. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - -include ../include/Makefile.i - -noinst_LIBRARIES = libpars.a - -noinst_HEADERS = pars0grm.h - -libpars_a_SOURCES = pars0grm.c lexyy.c pars0opt.c pars0pars.c pars0sym.c - -EXTRA_PROGRAMS = - -# Don't update the files from bitkeeper -%::SCCS/s.% diff --git a/storage/innobase/plug.in b/storage/innobase/plug.in index 59634523399..6e26a7d3376 100644 --- a/storage/innobase/plug.in +++ b/storage/innobase/plug.in @@ -2,6 +2,7 @@ MYSQL_STORAGE_ENGINE(innobase, innodb, [InnoDB Storage Engine], [Transactional Tables using InnoDB], [max,max-no-ndb]) MYSQL_PLUGIN_DIRECTORY(innobase, [storage/innobase]) MYSQL_PLUGIN_STATIC(innobase, [libinnobase.a]) +MYSQL_PLUGIN_DYNAMIC(innobase, [ha_innodb.la]) MYSQL_PLUGIN_ACTIONS(innobase, [ AC_CHECK_LIB(rt, aio_read, [innodb_system_libs="-lrt"]) AC_SUBST(innodb_system_libs) @@ -38,37 +39,5 @@ MYSQL_PLUGIN_ACTIONS(innobase, [ openbsd*) CFLAGS="$CFLAGS -DUNIV_MUST_NOT_INLINE";; esac - AC_CONFIG_FILES( - storage/innobase/ut/Makefile - storage/innobase/btr/Makefile - storage/innobase/buf/Makefile - storage/innobase/data/Makefile - storage/innobase/dict/Makefile - storage/innobase/dyn/Makefile - storage/innobase/eval/Makefile - storage/innobase/fil/Makefile - storage/innobase/fsp/Makefile - storage/innobase/fut/Makefile - storage/innobase/ha/Makefile - storage/innobase/ibuf/Makefile - storage/innobase/lock/Makefile - storage/innobase/log/Makefile - storage/innobase/mach/Makefile - storage/innobase/mem/Makefile - storage/innobase/mtr/Makefile - storage/innobase/os/Makefile - storage/innobase/page/Makefile - storage/innobase/pars/Makefile - storage/innobase/que/Makefile - storage/innobase/read/Makefile - storage/innobase/rem/Makefile - storage/innobase/row/Makefile - storage/innobase/srv/Makefile - storage/innobase/sync/Makefile - storage/innobase/thr/Makefile - storage/innobase/trx/Makefile - storage/innobase/handler/Makefile - storage/innobase/usr/Makefile) ]) -MYSQL_PLUGIN_DEPENDS_ON_MYSQL_INTERNALS(innobase, [handler/ha_innodb.cc]) diff --git a/storage/innobase/que/Makefile.am b/storage/innobase/que/Makefile.am deleted file mode 100644 index 73f3fb07af4..00000000000 --- a/storage/innobase/que/Makefile.am +++ /dev/null @@ -1,25 +0,0 @@ -# Copyright (C) 2001, 2003 MySQL AB & Innobase Oy -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; version 2 of the License. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - -include ../include/Makefile.i - -noinst_LIBRARIES = libque.a - -libque_a_SOURCES = que0que.c - -EXTRA_PROGRAMS = - -# Don't update the files from bitkeeper -%::SCCS/s.% diff --git a/storage/innobase/read/Makefile.am b/storage/innobase/read/Makefile.am deleted file mode 100644 index 1e56a9716c3..00000000000 --- a/storage/innobase/read/Makefile.am +++ /dev/null @@ -1,25 +0,0 @@ -# Copyright (C) 2001, 2003 MySQL AB & Innobase Oy -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; version 2 of the License. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - -include ../include/Makefile.i - -noinst_LIBRARIES = libread.a - -libread_a_SOURCES = read0read.c - -EXTRA_PROGRAMS = - -# Don't update the files from bitkeeper -%::SCCS/s.% diff --git a/storage/innobase/rem/Makefile.am b/storage/innobase/rem/Makefile.am deleted file mode 100644 index 1026172b815..00000000000 --- a/storage/innobase/rem/Makefile.am +++ /dev/null @@ -1,25 +0,0 @@ -# Copyright (C) 2001, 2003 MySQL AB & Innobase Oy -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; version 2 of the License. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - -include ../include/Makefile.i - -noinst_LIBRARIES = librem.a - -librem_a_SOURCES = rem0rec.c rem0cmp.c - -EXTRA_PROGRAMS = - -# Don't update the files from bitkeeper -%::SCCS/s.% diff --git a/storage/innobase/rem/rem0rec.c b/storage/innobase/rem/rem0rec.c index 549b5ee8b28..3bc73eca9ea 100644 --- a/storage/innobase/rem/rem0rec.c +++ b/storage/innobase/rem/rem0rec.c @@ -153,7 +153,6 @@ static void rec_init_offsets( /*=============*/ - /* out: the offsets */ rec_t* rec, /* in: physical record */ dict_index_t* index, /* in: record descriptor */ ulint* offsets)/* in/out: array of offsets; @@ -189,7 +188,7 @@ rec_init_offsets( } nulls = rec - (REC_N_NEW_EXTRA_BYTES + 1); - lens = nulls - (index->n_nullable + 7) / 8; + lens = nulls - UT_BITS_IN_BYTES(index->n_nullable); offs = 0; null_mask = 1; @@ -304,7 +303,7 @@ rec_get_offsets_func( /* out: the new offsets */ rec_t* rec, /* in: physical record */ dict_index_t* index, /* in: record descriptor */ - ulint* offsets,/* in: array consisting of offsets[0] + ulint* offsets,/* in/out: array consisting of offsets[0] allocated elements, or an array from rec_get_offsets(), or NULL */ ulint n_fields,/* in: maximum number of initialized fields @@ -440,7 +439,7 @@ rec_get_converted_size_new( dtuple_t* dtuple) /* in: data tuple */ { ulint size = REC_N_NEW_EXTRA_BYTES - + (index->n_nullable + 7) / 8; + + UT_BITS_IN_BYTES(index->n_nullable); ulint i; ulint n_fields; ut_ad(index && dtuple); @@ -459,10 +458,10 @@ rec_get_converted_size_new( break; case REC_STATUS_INFIMUM: case REC_STATUS_SUPREMUM: - /* infimum or supremum record, 8 bytes */ - return(size + 8); /* no extra data needed */ + /* infimum or supremum record, 8 data bytes */ + return(REC_N_NEW_EXTRA_BYTES + 8); default: - ut_a(0); + ut_error; return(ULINT_UNDEFINED); } @@ -476,21 +475,31 @@ rec_get_converted_size_new( len = dtuple_get_nth_field(dtuple, i)->len; col = dict_field_get_col(field); - ut_ad(len != UNIV_SQL_NULL || !(col->prtype & DATA_NOT_NULL)); + ut_ad(dict_col_type_assert_equal( + col, dfield_get_type(dtuple_get_nth_field( + dtuple, i)))); if (len == UNIV_SQL_NULL) { /* No length is stored for NULL fields. */ + ut_ad(!(col->prtype & DATA_NOT_NULL)); continue; } ut_ad(len <= col->len || col->mtype == DATA_BLOB); - ut_ad(!field->fixed_len || len == field->fixed_len); if (field->fixed_len) { + ut_ad(len == field->fixed_len); + /* dict_index_add_col() should guarantee this */ + ut_ad(!field->prefix_len + || field->fixed_len == field->prefix_len); } else if (len < 128 || (col->len < 256 && col->mtype != DATA_BLOB)) { size++; } else { + /* For variable-length columns, we look up the + maximum length from the column itself. If this + is a prefix index column shorter than 256 bytes, + this will waste one byte. */ size += 2; } size += len; @@ -586,7 +595,7 @@ rec_set_nth_field_extern_bit_new( we do not write to log about the change */ { byte* nulls = rec - (REC_N_NEW_EXTRA_BYTES + 1); - byte* lens = nulls - (index->n_nullable + 7) / 8; + byte* lens = nulls - UT_BITS_IN_BYTES(index->n_nullable); ulint i; ulint n_fields; ulint null_mask = 1; @@ -875,7 +884,7 @@ rec_convert_dtuple_to_rec_new( /* Calculate the offset of the origin in the physical record. We must loop over all fields to do this. */ - rec += (index->n_nullable + 7) / 8; + rec += UT_BITS_IN_BYTES(index->n_nullable); for (i = 0; i < n_fields; i++) { if (UNIV_UNLIKELY(i == n_node_ptr_field)) { @@ -892,6 +901,11 @@ rec_convert_dtuple_to_rec_new( len = dfield_get_len(field); fixed_len = dict_index_get_nth_field(index, i)->fixed_len; + ut_ad(dict_col_type_assert_equal( + dict_field_get_col(dict_index_get_nth_field( + index, i)), + dfield_get_type(field))); + if (!(dtype_get_prtype(type) & DATA_NOT_NULL)) { if (len == UNIV_SQL_NULL) continue; @@ -915,7 +929,7 @@ rec_convert_dtuple_to_rec_new( init: end = rec; nulls = rec - (REC_N_NEW_EXTRA_BYTES + 1); - lens = nulls - (index->n_nullable + 7) / 8; + lens = nulls - UT_BITS_IN_BYTES(index->n_nullable); /* clear the SQL-null flags */ memset (lens + 1, 0, nulls - lens); @@ -1172,7 +1186,7 @@ rec_copy_prefix_to_buf( } nulls = rec - (REC_N_NEW_EXTRA_BYTES + 1); - lens = nulls - (index->n_nullable + 7) / 8; + lens = nulls - UT_BITS_IN_BYTES(index->n_nullable); UNIV_PREFETCH_R(lens); prefix_len = 0; null_mask = 1; diff --git a/storage/innobase/row/Makefile.am b/storage/innobase/row/Makefile.am deleted file mode 100644 index 6c1f960055d..00000000000 --- a/storage/innobase/row/Makefile.am +++ /dev/null @@ -1,26 +0,0 @@ -# Copyright (C) 2001, 2003 MySQL AB & Innobase Oy -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; version 2 of the License. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - -include ../include/Makefile.i - -noinst_LIBRARIES = librow.a - -librow_a_SOURCES = row0ins.c row0mysql.c row0purge.c row0row.c row0sel.c\ - row0uins.c row0umod.c row0undo.c row0upd.c row0vers.c - -EXTRA_PROGRAMS = - -# Don't update the files from bitkeeper -%::SCCS/s.% diff --git a/storage/innobase/row/row0ins.c b/storage/innobase/row/row0ins.c index 1fba0abcdaf..ad14b927170 100644 --- a/storage/innobase/row/row0ins.c +++ b/storage/innobase/row/row0ins.c @@ -51,21 +51,6 @@ innobase_invalidate_query_cache( ulint full_name_len); /* in: full name length where also the null chars count */ -/********************************************************************** -This function returns true if - -1) SQL-query in the current thread -is either REPLACE or LOAD DATA INFILE REPLACE. - -2) SQL-query in the current thread -is INSERT ON DUPLICATE KEY UPDATE. - -NOTE that /mysql/innobase/row/row0ins.c must contain the -prototype for this function ! */ - -ibool -innobase_query_is_update(void); - /************************************************************************* Creates an insert node struct. */ @@ -448,7 +433,11 @@ row_ins_cascade_calc_update_vec( ulint i; ulint j; - ut_a(node && foreign && cascade && table && index); + ut_a(node); + ut_a(foreign); + ut_a(cascade); + ut_a(table); + ut_a(index); /* Calculate the appropriate update vector which will set the fields in the child index record to the same value (possibly padded with @@ -791,7 +780,10 @@ row_ins_foreign_check_on_constraint( trx_t* trx; mem_heap_t* tmp_heap = NULL; - ut_a(thr && foreign && pcur && mtr); + ut_a(thr); + ut_a(foreign); + ut_a(pcur); + ut_a(mtr); trx = thr_get_trx(thr); @@ -1308,7 +1300,8 @@ run_again: goto exit_func; } - ut_a(check_table && check_index); + ut_a(check_table); + ut_a(check_index); if (check_table != table) { /* We already have a LOCK_IX on table, but not necessarily @@ -1336,11 +1329,9 @@ run_again: /* Scan index records and check if there is a matching record */ for (;;) { - page_t* page; rec = btr_pcur_get_rec(&pcur); - page = buf_frame_align(rec); - if (rec == page_get_infimum_rec(page)) { + if (page_rec_is_infimum(rec)) { goto next_rec; } @@ -1348,7 +1339,7 @@ run_again: offsets = rec_get_offsets(rec, check_index, offsets, ULINT_UNDEFINED, &heap); - if (rec == page_get_supremum_rec(page)) { + if (page_rec_is_supremum(rec)) { err = row_ins_set_shared_rec_lock( LOCK_ORDINARY, rec, check_index, offsets, thr); @@ -1654,6 +1645,7 @@ row_ins_scan_sec_index_for_duplicate( btr_pcur_t pcur; ulint err = DB_SUCCESS; ibool moved; + unsigned allow_duplicates; mtr_t mtr; mem_heap_t* heap = NULL; ulint offsets_[REC_OFFS_NORMAL_SIZE]; @@ -1684,12 +1676,14 @@ row_ins_scan_sec_index_for_duplicate( btr_pcur_open(index, entry, PAGE_CUR_GE, BTR_SEARCH_LEAF, &pcur, &mtr); + allow_duplicates = thr_get_trx(thr)->duplicates & TRX_DUP_IGNORE; + /* Scan index records and check if there is a duplicate */ for (;;) { rec = btr_pcur_get_rec(&pcur); - if (rec == page_get_infimum_rec(buf_frame_align(rec))) { + if (page_rec_is_infimum(rec)) { goto next_rec; } @@ -1697,7 +1691,7 @@ row_ins_scan_sec_index_for_duplicate( offsets = rec_get_offsets(rec, index, offsets, ULINT_UNDEFINED, &heap); - if (innobase_query_is_update()) { + if (allow_duplicates) { /* If the SQL-query will update or replace duplicate key we will take X-lock for @@ -1826,7 +1820,7 @@ row_ins_duplicate_error_in_clust( sure that in roll-forward we get the same duplicate errors as in original execution */ - if (innobase_query_is_update()) { + if (trx->duplicates & TRX_DUP_IGNORE) { /* If the SQL-query will update or replace duplicate key we will take X-lock for @@ -1864,7 +1858,7 @@ row_ins_duplicate_error_in_clust( offsets = rec_get_offsets(rec, cursor->index, offsets, ULINT_UNDEFINED, &heap); - if (innobase_query_is_update()) { + if (trx->duplicates & TRX_DUP_IGNORE) { /* If the SQL-query will update or replace duplicate key we will take X-lock for diff --git a/storage/innobase/row/row0mysql.c b/storage/innobase/row/row0mysql.c index 7c9427db0d2..9f88fd8040b 100644 --- a/storage/innobase/row/row0mysql.c +++ b/storage/innobase/row/row0mysql.c @@ -476,7 +476,8 @@ handle_new_error: /* MySQL will roll back the latest SQL statement */ } else if (err == DB_ROW_IS_REFERENCED || err == DB_NO_REFERENCED_ROW - || err == DB_CANNOT_ADD_CONSTRAINT) { + || err == DB_CANNOT_ADD_CONSTRAINT + || err == DB_TOO_MANY_CONCURRENT_TRXS) { if (savept) { /* Roll back the latest, possibly incomplete insertion or update */ @@ -4058,3 +4059,25 @@ row_check_table_for_mysql( return(ret); } + +/************************************************************************* +Get the maximum row size. */ + +ulint +page_get_free_space_of_empty_noninline( +/*===================================*/ + /* out: The (approx) maximum size + of a row, this is a conservative + estimate, since the size can be + slightly larger depending upon + the ROW_FORMAT setting.*/ + dict_table_t* table) /* in: table for which max record + size is required.*/ +{ + ibool compact; + + compact = dict_table_is_comp(table); + + return(page_get_free_space_of_empty(compact) / 2); +} + diff --git a/storage/innobase/row/row0row.c b/storage/innobase/row/row0row.c index efa129d6211..08e50817db9 100644 --- a/storage/innobase/row/row0row.c +++ b/storage/innobase/row/row0row.c @@ -142,20 +142,15 @@ row_build_index_entry( dfield_copy(dfield, dfield2); /* If a column prefix index, take only the prefix */ - if (ind_field->prefix_len) { - if (dfield_get_len(dfield2) != UNIV_SQL_NULL) { + if (ind_field->prefix_len > 0 + && dfield_get_len(dfield2) != UNIV_SQL_NULL) { - storage_len = dtype_get_at_most_n_mbchars( - col->prtype, - col->mbminlen, col->mbmaxlen, - ind_field->prefix_len, - dfield_get_len(dfield2), - dfield2->data); - - dfield_set_len(dfield, storage_len); - } + storage_len = dtype_get_at_most_n_mbchars( + col->prtype, col->mbminlen, col->mbmaxlen, + ind_field->prefix_len, + dfield_get_len(dfield2), dfield2->data); - dfield_get_type(dfield)->len = ind_field->prefix_len; + dfield_set_len(dfield, storage_len); } } @@ -478,7 +473,9 @@ row_build_row_ref_in_tuple( ulint* offsets = offsets_; *offsets_ = (sizeof offsets_) / sizeof *offsets_; - ut_a(ref && index && rec); + ut_a(ref); + ut_a(index); + ut_a(rec); if (UNIV_UNLIKELY(!index->table)) { fputs("InnoDB: table ", stderr); diff --git a/storage/innobase/row/row0sel.c b/storage/innobase/row/row0sel.c index a3199055b54..e70b3b8671f 100644 --- a/storage/innobase/row/row0sel.c +++ b/storage/innobase/row/row0sel.c @@ -3619,6 +3619,32 @@ shortcut_fails_too_big_rec: pcur, 0, &mtr); pcur->trx_if_known = trx; + + rec = btr_pcur_get_rec(pcur); + + if (!moves_up + && !page_rec_is_supremum(rec) + && set_also_gap_locks + && !(srv_locks_unsafe_for_binlog + || trx->isolation_level == TRX_ISO_READ_COMMITTED) + && prebuilt->select_lock_type != LOCK_NONE) { + + /* Try to place a gap lock on the next index record + to prevent phantoms in ORDER BY ... DESC queries */ + + offsets = rec_get_offsets(page_rec_get_next(rec), + index, offsets, + ULINT_UNDEFINED, &heap); + err = sel_set_rec_lock(page_rec_get_next(rec), + index, offsets, + prebuilt->select_lock_type, + LOCK_GAP, thr); + + if (err != DB_SUCCESS) { + + goto lock_wait_or_error; + } + } } else { if (mode == PAGE_CUR_G) { btr_pcur_open_at_index_side( diff --git a/storage/innobase/srv/Makefile.am b/storage/innobase/srv/Makefile.am deleted file mode 100644 index e0b5b911b04..00000000000 --- a/storage/innobase/srv/Makefile.am +++ /dev/null @@ -1,25 +0,0 @@ -# Copyright (C) 2001, 2003-2004 MySQL AB & Innobase Oy -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; version 2 of the License. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - -include ../include/Makefile.i - -noinst_LIBRARIES = libsrv.a - -libsrv_a_SOURCES = srv0srv.c srv0que.c srv0start.c - -EXTRA_PROGRAMS = - -# Don't update the files from bitkeeper -%::SCCS/s.% diff --git a/storage/innobase/srv/srv0srv.c b/storage/innobase/srv/srv0srv.c index 72e8fe751d0..8f8c9386f41 100644 --- a/storage/innobase/srv/srv0srv.c +++ b/storage/innobase/srv/srv0srv.c @@ -47,6 +47,7 @@ Created 10/8/1995 Heikki Tuuri #include "dict0boot.h" #include "srv0start.h" #include "row0mysql.h" +#include "ha_prototypes.h" /* This is set to TRUE if the MySQL user has set it in MySQL; currently affects only FOREIGN KEY definition parsing */ @@ -180,6 +181,16 @@ dulint srv_archive_recovery_limit_lsn; ulint srv_lock_wait_timeout = 1024 * 1024 * 1024; +/* This parameter is used to throttle the number of insert buffers that are +merged in a batch. By increasing this parameter on a faster disk you can +possibly reduce the number of I/O operations performed to complete the +merge operation. The value of this parameter is used as is by the +background loop when the system is idle (low load), on a busy system +the parameter is scaled down by a factor of 4, this is to avoid putting +a heavier load on the I/O sub system. */ + +ulong srv_insert_buffer_batch_size = 20; + char* srv_file_flush_method_str = NULL; ulint srv_unix_file_flush_method = SRV_UNIX_FDATASYNC; ulint srv_win_file_flush_method = SRV_WIN_IO_UNBUFFERED; @@ -977,6 +988,17 @@ srv_conc_enter_innodb( srv_conc_slot_t* slot = NULL; ulint i; + if (trx->mysql_thd != NULL + && thd_is_replication_slave_thread(trx->mysql_thd)) { + + /* TODO Do something more interesting (based on a config + parameter). Some users what to give the replication + thread very low priority, see http://bugs.mysql.com/25078 + This can be done by introducing + innodb_replication_delay(ms) config parameter */ + return; + } + /* If trx has 'free tickets' to enter the engine left, then use one such ticket */ @@ -1017,7 +1039,7 @@ retry: if (!has_slept && !trx->has_search_latch && NULL == UT_LIST_GET_FIRST(trx->trx_locks)) { - has_slept = TRUE; /* We let is sleep only once to avoid + has_slept = TRUE; /* We let it sleep only once to avoid starvation */ srv_conc_n_waiting_threads++; @@ -1130,7 +1152,7 @@ srv_conc_force_enter_innodb( srv_conc_n_threads++; trx->declared_to_be_inside_innodb = TRUE; - trx->n_tickets_to_enter_innodb = 0; + trx->n_tickets_to_enter_innodb = 1; os_fast_mutex_unlock(&srv_conc_mutex); } @@ -1152,6 +1174,12 @@ srv_conc_force_exit_innodb( return; } + if (trx->mysql_thd != NULL + && thd_is_replication_slave_thread(trx->mysql_thd)) { + + return; + } + if (trx->declared_to_be_inside_innodb == FALSE) { return; @@ -1853,6 +1881,7 @@ srv_lock_timeout_and_monitor_thread( double time_elapsed; time_t current_time; time_t last_table_monitor_time; + time_t last_tablespace_monitor_time; time_t last_monitor_time; ibool some_waits; double wait_time; @@ -1865,6 +1894,7 @@ srv_lock_timeout_and_monitor_thread( UT_NOT_USED(arg); srv_last_monitor_time = time(NULL); last_table_monitor_time = time(NULL); + last_tablespace_monitor_time = time(NULL); last_monitor_time = time(NULL); loop: srv_lock_timeout_and_monitor_active = TRUE; @@ -1901,9 +1931,9 @@ loop: } if (srv_print_innodb_tablespace_monitor - && difftime(current_time, last_table_monitor_time) > 60) { - - last_table_monitor_time = time(NULL); + && difftime(current_time, + last_tablespace_monitor_time) > 60) { + last_tablespace_monitor_time = time(NULL); fputs("========================" "========================\n", @@ -2100,7 +2130,7 @@ loop: os_thread_sleep(2000000); - if (srv_shutdown_state < SRV_SHUTDOWN_LAST_PHASE) { + if (srv_shutdown_state < SRV_SHUTDOWN_CLEANUP) { goto loop; } @@ -2270,7 +2300,8 @@ loop: + buf_pool->n_pages_written; if (n_pend_ios < 3 && (n_ios - n_ios_old < 5)) { srv_main_thread_op_info = "doing insert buffer merge"; - ibuf_contract_for_n_pages(TRUE, 5); + ibuf_contract_for_n_pages( + TRUE, srv_insert_buffer_batch_size / 4); srv_main_thread_op_info = "flushing log"; @@ -2331,7 +2362,7 @@ loop: even if the server were active */ srv_main_thread_op_info = "doing insert buffer merge"; - ibuf_contract_for_n_pages(TRUE, 5); + ibuf_contract_for_n_pages(TRUE, srv_insert_buffer_batch_size / 4); srv_main_thread_op_info = "flushing log"; log_buffer_flush_to_disk(); @@ -2469,7 +2500,8 @@ background_loop: if (srv_fast_shutdown && srv_shutdown_state > 0) { n_bytes_merged = 0; } else { - n_bytes_merged = ibuf_contract_for_n_pages(TRUE, 20); + n_bytes_merged = ibuf_contract_for_n_pages( + TRUE, srv_insert_buffer_batch_size); } srv_main_thread_op_info = "reserving kernel mutex"; diff --git a/storage/innobase/srv/srv0start.c b/storage/innobase/srv/srv0start.c index 25f6f05e878..dac84e1410d 100644 --- a/storage/innobase/srv/srv0start.c +++ b/storage/innobase/srv/srv0start.c @@ -1025,6 +1025,12 @@ innobase_start_or_create_for_mysql(void) "InnoDB: !!!!!!!! UNIV_DEBUG switched on !!!!!!!!!\n"); #endif +#ifdef UNIV_IBUF_DEBUG + fprintf(stderr, + "InnoDB: !!!!!!!! UNIV_IBUF_DEBUG switched on !!!!!!!!!\n" + "InnoDB: Crash recovery will fail with UNIV_IBUF_DEBUG\n"); +#endif + #ifdef UNIV_SYNC_DEBUG fprintf(stderr, "InnoDB: !!!!!!!! UNIV_SYNC_DEBUG switched on !!!!!!!!!\n"); diff --git a/storage/innobase/sync/Makefile.am b/storage/innobase/sync/Makefile.am deleted file mode 100644 index 7cf274b64e8..00000000000 --- a/storage/innobase/sync/Makefile.am +++ /dev/null @@ -1,25 +0,0 @@ -# Copyright (C) 2001, 2003-2004 MySQL AB & Innobase Oy -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; version 2 of the License. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - -include ../include/Makefile.i - -noinst_LIBRARIES = libsync.a - -libsync_a_SOURCES = sync0arr.c sync0rw.c sync0sync.c - -EXTRA_PROGRAMS = - -# Don't update the files from bitkeeper -%::SCCS/s.% diff --git a/storage/innobase/sync/sync0arr.c b/storage/innobase/sync/sync0arr.c index e45cd48a6b4..82b08a890e0 100644 --- a/storage/innobase/sync/sync0arr.c +++ b/storage/innobase/sync/sync0arr.c @@ -670,7 +670,9 @@ sync_array_detect_deadlock( ibool ret; rw_lock_debug_t*debug; - ut_a(arr && start && cell); + ut_a(arr); + ut_a(start); + ut_a(cell); ut_ad(cell->wait_object); ut_ad(os_thread_get_curr_id() == start->thread); ut_ad(depth < 100); diff --git a/storage/innobase/thr/Makefile.am b/storage/innobase/thr/Makefile.am deleted file mode 100644 index febcdf3e1a3..00000000000 --- a/storage/innobase/thr/Makefile.am +++ /dev/null @@ -1,25 +0,0 @@ -# Copyright (C) 2001, 2003 MySQL AB & Innobase Oy -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; version 2 of the License. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - -include ../include/Makefile.i - -noinst_LIBRARIES = libthr.a - -libthr_a_SOURCES = thr0loc.c - -EXTRA_PROGRAMS = - -# Don't update the files from bitkeeper -%::SCCS/s.% diff --git a/storage/innobase/trx/Makefile.am b/storage/innobase/trx/Makefile.am deleted file mode 100644 index f9722454ef5..00000000000 --- a/storage/innobase/trx/Makefile.am +++ /dev/null @@ -1,26 +0,0 @@ -# Copyright (C) 2001, 2003 MySQL AB & Innobase Oy -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; version 2 of the License. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - -include ../include/Makefile.i - -noinst_LIBRARIES = libtrx.a - -libtrx_a_SOURCES = trx0purge.c trx0rec.c trx0roll.c trx0rseg.c\ - trx0sys.c trx0trx.c trx0undo.c - -EXTRA_PROGRAMS = - -# Don't update the files from bitkeeper -%::SCCS/s.% diff --git a/storage/innobase/trx/trx0rec.c b/storage/innobase/trx/trx0rec.c index 69e858fe71d..50f8b011463 100644 --- a/storage/innobase/trx/trx0rec.c +++ b/storage/innobase/trx/trx0rec.c @@ -1024,6 +1024,7 @@ trx_undo_report_row_operation( ibool is_insert; trx_rseg_t* rseg; mtr_t mtr; + ulint err = DB_SUCCESS; mem_heap_t* heap = NULL; ulint offsets_[REC_OFFS_NORMAL_SIZE]; ulint* offsets = offsets_; @@ -1035,7 +1036,7 @@ trx_undo_report_row_operation( *roll_ptr = ut_dulint_zero; - return(DB_SUCCESS); + return(err); } ut_ad(thr); @@ -1053,7 +1054,7 @@ trx_undo_report_row_operation( if (trx->insert_undo == NULL) { - trx_undo_assign_undo(trx, TRX_UNDO_INSERT); + err = trx_undo_assign_undo(trx, TRX_UNDO_INSERT); } undo = trx->insert_undo; @@ -1063,7 +1064,7 @@ trx_undo_report_row_operation( if (trx->update_undo == NULL) { - trx_undo_assign_undo(trx, TRX_UNDO_UPDATE); + err = trx_undo_assign_undo(trx, TRX_UNDO_UPDATE); } @@ -1071,11 +1072,11 @@ trx_undo_report_row_operation( is_insert = FALSE; } - if (undo == NULL) { - /* Did not succeed: out of space */ + if (err != DB_SUCCESS) { + /* Did not succeed: return the error encountered */ mutex_exit(&(trx->undo_mutex)); - return(DB_OUT_OF_FILE_SPACE); + return(err); } page_no = undo->last_page_no; @@ -1107,7 +1108,9 @@ trx_undo_report_row_operation( if (offset == 0) { /* The record did not fit on the page. We erase the end segment of the undo log page and write a log - record of it to to ensure deterministic contents. */ + record of it: this is to ensure that in the debug + version the replicate page constructed using the log + records stays identical to the original page */ trx_undo_erase_page_end(undo_page, &mtr); } @@ -1163,7 +1166,7 @@ trx_undo_report_row_operation( if (UNIV_LIKELY_NULL(heap)) { mem_heap_free(heap); } - return(DB_SUCCESS); + return(err); } /*============== BUILDING PREVIOUS VERSION OF A RECORD ===============*/ diff --git a/storage/innobase/trx/trx0trx.c b/storage/innobase/trx/trx0trx.c index cdea3e9c477..2d5ce0e1c61 100644 --- a/storage/innobase/trx/trx0trx.c +++ b/storage/innobase/trx/trx0trx.c @@ -25,6 +25,7 @@ Created 3/26/1996 Heikki Tuuri #include "btr0sea.h" #include "os0proc.h" #include "trx0xa.h" +#include "ha_prototypes.h" /* Copy of the prototype for innobase_mysql_print_thd: this copy MUST be equal to the one in mysql/sql/ha_innodb.cc ! */ @@ -130,6 +131,8 @@ trx_create( trx->mysql_thd = NULL; trx->mysql_query_str = NULL; + trx->active_trans = 0; + trx->duplicates = 0; trx->n_mysql_tables_in_use = 0; trx->mysql_n_tables_locked = 0; @@ -1771,6 +1774,61 @@ trx_print( } } +/*********************************************************************** +Compares the "weight" (or size) of two transactions. The weight of one +transaction is estimated as the number of altered rows + the number of +locked rows. Transactions that have edited non-transactional tables are +considered heavier than ones that have not. */ + +int +trx_weight_cmp( +/*===========*/ + /* out: <0, 0 or >0; similar to strcmp(3) */ + trx_t* a, /* in: the first transaction to be compared */ + trx_t* b) /* in: the second transaction to be compared */ +{ + ibool a_notrans_edit; + ibool b_notrans_edit; + + /* If mysql_thd is NULL for a transaction we assume that it has + not edited non-transactional tables. */ + + a_notrans_edit = a->mysql_thd != NULL + && thd_has_edited_nontrans_tables(a->mysql_thd); + + b_notrans_edit = b->mysql_thd != NULL + && thd_has_edited_nontrans_tables(b->mysql_thd); + + if (a_notrans_edit && !b_notrans_edit) { + + return(1); + } + + if (!a_notrans_edit && b_notrans_edit) { + + return(-1); + } + + /* Either both had edited non-transactional tables or both had + not, we fall back to comparing the number of altered/locked + rows. */ + +#if 0 + fprintf(stderr, + "%s TRX_WEIGHT(a): %lld+%lu, TRX_WEIGHT(b): %lld+%lu\n", + __func__, + ut_conv_dulint_to_longlong(a->undo_no), + UT_LIST_GET_LEN(a->trx_locks), + ut_conv_dulint_to_longlong(b->undo_no), + UT_LIST_GET_LEN(b->trx_locks)); +#endif + +#define TRX_WEIGHT(t) \ + ut_dulint_add((t)->undo_no, UT_LIST_GET_LEN((t)->trx_locks)) + + return(ut_dulint_cmp(TRX_WEIGHT(a), TRX_WEIGHT(b))); +} + /******************************************************************** Prepares a transaction. */ @@ -1889,7 +1947,7 @@ Does the transaction prepare for MySQL. */ ulint trx_prepare_for_mysql( -/*====-=============*/ +/*==================*/ /* out: 0 or error number */ trx_t* trx) /* in: trx handle */ { diff --git a/storage/innobase/trx/trx0undo.c b/storage/innobase/trx/trx0undo.c index 831e337f513..64e5ad3c9a8 100644 --- a/storage/innobase/trx/trx0undo.c +++ b/storage/innobase/trx/trx0undo.c @@ -373,26 +373,31 @@ trx_undo_page_init( /******************************************************************* Creates a new undo log segment in file. */ static -page_t* +ulint trx_undo_seg_create( /*================*/ - /* out: segment header page x-latched, NULL - if no space left */ + /* out: DB_SUCCESS if page creation OK + possible error codes are: + DB_TOO_MANY_CONCURRENT_TRXS + DB_OUT_OF_FILE_SPACE */ trx_rseg_t* rseg __attribute__((unused)),/* in: rollback segment */ trx_rsegf_t* rseg_hdr,/* in: rollback segment header, page x-latched */ ulint type, /* in: type of the segment: TRX_UNDO_INSERT or TRX_UNDO_UPDATE */ ulint* id, /* out: slot index within rseg header */ + page_t** undo_page, + /* out: segment header page x-latched, NULL + if there was an error */ mtr_t* mtr) /* in: mtr */ { ulint slot_no; ulint space; - page_t* undo_page; trx_upagef_t* page_hdr; trx_usegf_t* seg_hdr; ulint n_reserved; ibool success; + ulint err = DB_SUCCESS; ut_ad(mtr && id && rseg_hdr); ut_ad(mutex_own(&(rseg->mutex))); @@ -410,7 +415,7 @@ trx_undo_seg_create( "InnoDB: many active transactions" " running concurrently?\n"); - return(NULL); + return(DB_TOO_MANY_CONCURRENT_TRXS); } space = buf_frame_get_space_id(rseg_hdr); @@ -419,30 +424,30 @@ trx_undo_seg_create( mtr); if (!success) { - return(NULL); + return(DB_OUT_OF_FILE_SPACE); } /* Allocate a new file segment for the undo log */ - undo_page = fseg_create_general(space, 0, + *undo_page = fseg_create_general(space, 0, TRX_UNDO_SEG_HDR + TRX_UNDO_FSEG_HEADER, TRUE, mtr); fil_space_release_free_extents(space, n_reserved); - if (undo_page == NULL) { + if (*undo_page == NULL) { /* No space left */ - return(NULL); + return(DB_OUT_OF_FILE_SPACE); } #ifdef UNIV_SYNC_DEBUG - buf_page_dbg_add_level(undo_page, SYNC_TRX_UNDO_PAGE); + buf_page_dbg_add_level(*undo_page, SYNC_TRX_UNDO_PAGE); #endif /* UNIV_SYNC_DEBUG */ - page_hdr = undo_page + TRX_UNDO_PAGE_HDR; - seg_hdr = undo_page + TRX_UNDO_SEG_HDR; + page_hdr = *undo_page + TRX_UNDO_PAGE_HDR; + seg_hdr = *undo_page + TRX_UNDO_SEG_HDR; - trx_undo_page_init(undo_page, type, mtr); + trx_undo_page_init(*undo_page, type, mtr); mlog_write_ulint(page_hdr + TRX_UNDO_PAGE_FREE, TRX_UNDO_SEG_HDR + TRX_UNDO_SEG_HDR_SIZE, @@ -456,10 +461,11 @@ trx_undo_seg_create( page_hdr + TRX_UNDO_PAGE_NODE, mtr); trx_rsegf_set_nth_undo(rseg_hdr, slot_no, - buf_frame_get_page_no(undo_page), mtr); + buf_frame_get_page_no(*undo_page), mtr); + *id = slot_no; - return(undo_page); + return(err); } /************************************************************************** @@ -1387,6 +1393,11 @@ trx_undo_mem_create( undo = mem_alloc(sizeof(trx_undo_t)); + if (undo == NULL) { + + return NULL; + } + undo->id = id; undo->type = type; undo->state = TRX_UNDO_ACTIVE; @@ -1464,11 +1475,15 @@ trx_undo_mem_free( /************************************************************************** Creates a new undo log. */ static -trx_undo_t* +ulint trx_undo_create( /*============*/ - /* out: undo log object, NULL if did not - succeed: out of space */ + /* out: DB_SUCCESS if successful in creating + the new undo lob object, possible error + codes are: + DB_TOO_MANY_CONCURRENT_TRXS + DB_OUT_OF_FILE_SPACE + DB_OUT_OF_MEMORY*/ trx_t* trx, /* in: transaction */ trx_rseg_t* rseg, /* in: rollback segment memory copy */ ulint type, /* in: type of the log: TRX_UNDO_INSERT or @@ -1476,34 +1491,37 @@ trx_undo_create( dulint trx_id, /* in: id of the trx for which the undo log is created */ XID* xid, /* in: X/Open transaction identification*/ + trx_undo_t** undo, /* out: the new undo log object, undefined + * if did not succeed */ mtr_t* mtr) /* in: mtr */ { trx_rsegf_t* rseg_header; ulint page_no; ulint offset; ulint id; - trx_undo_t* undo; page_t* undo_page; + ulint err; ut_ad(mutex_own(&(rseg->mutex))); if (rseg->curr_size == rseg->max_size) { - return(NULL); + return(DB_OUT_OF_FILE_SPACE); } rseg->curr_size++; rseg_header = trx_rsegf_get(rseg->space, rseg->page_no, mtr); - undo_page = trx_undo_seg_create(rseg, rseg_header, type, &id, mtr); + err = trx_undo_seg_create(rseg, rseg_header, type, &id, + &undo_page, mtr); - if (undo_page == NULL) { + if (err != DB_SUCCESS) { /* Did not succeed */ rseg->curr_size--; - return(NULL); + return(err); } page_no = buf_frame_get_page_no(undo_page); @@ -1515,9 +1533,14 @@ trx_undo_create( undo_page + offset, mtr); } - undo = trx_undo_mem_create(rseg, id, type, trx_id, xid, + *undo = trx_undo_mem_create(rseg, id, type, trx_id, xid, page_no, offset); - return(undo); + if (*undo == NULL) { + + err = DB_OUT_OF_MEMORY; + } + + return(err); } /*================ UNDO LOG ASSIGNMENT AND CLEANUP =====================*/ @@ -1634,17 +1657,20 @@ trx_undo_mark_as_dict_operation( Assigns an undo log for a transaction. A new undo log is created or a cached undo log reused. */ -trx_undo_t* +ulint trx_undo_assign_undo( /*=================*/ - /* out: the undo log, NULL if did not succeed: out of - space */ - trx_t* trx, /* in: transaction */ - ulint type) /* in: TRX_UNDO_INSERT or TRX_UNDO_UPDATE */ + /* out: DB_SUCCESS if undo log assign + successful, possible error codes are: + DD_TOO_MANY_CONCURRENT_TRXS + DB_OUT_OF_FILE_SPACE DB_OUT_OF_MEMORY*/ + trx_t* trx, /* in: transaction */ + ulint type) /* in: TRX_UNDO_INSERT or TRX_UNDO_UPDATE */ { trx_rseg_t* rseg; trx_undo_t* undo; mtr_t mtr; + ulint err = DB_SUCCESS; ut_ad(trx); ut_ad(trx->rseg); @@ -1662,15 +1688,11 @@ trx_undo_assign_undo( undo = trx_undo_reuse_cached(trx, rseg, type, trx->id, &trx->xid, &mtr); if (undo == NULL) { - undo = trx_undo_create(trx, rseg, type, trx->id, &trx->xid, - &mtr); - if (undo == NULL) { - /* Did not succeed */ + err = trx_undo_create(trx, rseg, type, trx->id, &trx->xid, + &undo, &mtr); + if (err != DB_SUCCESS) { - mutex_exit(&(rseg->mutex)); - mtr_commit(&mtr); - - return(NULL); + goto func_exit; } } @@ -1688,10 +1710,11 @@ trx_undo_assign_undo( trx_undo_mark_as_dict_operation(trx, undo, &mtr); } +func_exit: mutex_exit(&(rseg->mutex)); mtr_commit(&mtr); - return(undo); + return err; } /********************************************************************** diff --git a/storage/innobase/usr/Makefile.am b/storage/innobase/usr/Makefile.am deleted file mode 100644 index ea485022f71..00000000000 --- a/storage/innobase/usr/Makefile.am +++ /dev/null @@ -1,25 +0,0 @@ -# Copyright (C) 2001, 2003 MySQL AB & Innobase Oy -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; version 2 of the License. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - -include ../include/Makefile.i - -noinst_LIBRARIES = libusr.a - -libusr_a_SOURCES = usr0sess.c - -EXTRA_PROGRAMS = - -# Don't update the files from bitkeeper -%::SCCS/s.% diff --git a/storage/innobase/ut/Makefile.am b/storage/innobase/ut/Makefile.am deleted file mode 100644 index d79184759c1..00000000000 --- a/storage/innobase/ut/Makefile.am +++ /dev/null @@ -1,25 +0,0 @@ -# Copyright (C) 2001, 2003 MySQL AB & Innobase Oy -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; version 2 of the License. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - -include ../include/Makefile.i - -noinst_LIBRARIES = libut.a - -libut_a_SOURCES = ut0byte.c ut0dbg.c ut0mem.c ut0rnd.c ut0ut.c ut0vec.c ut0list.c ut0wqueue.c - -EXTRA_PROGRAMS = - -# Don't update the files from bitkeeper -%::SCCS/s.% diff --git a/storage/innobase/ut/ut0ut.c b/storage/innobase/ut/ut0ut.c index bc6778f4c2f..389063ad821 100644 --- a/storage/innobase/ut/ut0ut.c +++ b/storage/innobase/ut/ut0ut.c @@ -14,6 +14,7 @@ Created 5/11/1994 Heikki Tuuri #include <stdarg.h> #include <string.h> +#include <ctype.h> #include "ut0sort.h" #include "trx0trx.h" |