From fe40eedb851eaa5e3ec8be31389a8a7389e405e5 Mon Sep 17 00:00:00 2001 From: "lzhou/zhl@dev3-63.(none)" <> Date: Fri, 15 Jun 2007 09:23:27 +0000 Subject: [PATCH 01/24] BUG#25941 Output warning messages from stdout to stderr when abitrator warnings exist --- ndb/src/mgmsrv/ConfigInfo.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ndb/src/mgmsrv/ConfigInfo.cpp b/ndb/src/mgmsrv/ConfigInfo.cpp index 0cf37b5f874..3600dfdeab3 100644 --- a/ndb/src/mgmsrv/ConfigInfo.cpp +++ b/ndb/src/mgmsrv/ConfigInfo.cpp @@ -3761,9 +3761,9 @@ check_node_vs_replicas(Vector§ions, } } if (db_host_count > 1 && node_group_warning.length() > 0) - ndbout_c("Cluster configuration warning:\n%s",node_group_warning.c_str()); + ctx.reportWarning("Cluster configuration warning:\n%s",node_group_warning.c_str()); if (db_host_count > 1 && arbitration_warning.length() > 0) - ndbout_c("Cluster configuration warning:%s%s",arbitration_warning.c_str(), + ctx.reportWarning("Cluster configuration warning:%s%s",arbitration_warning.c_str(), "\n Running arbitrator on the same host as a database node may" "\n cause complete cluster shutdown in case of host failure."); } From 1ce7a24766fa8e9d7ce4e53c177d4389598fc820 Mon Sep 17 00:00:00 2001 From: "dkatz@damien-katzs-computer.local" <> Date: Tue, 26 Jun 2007 21:10:51 -0400 Subject: [PATCH 02/24] Bug #29307 status.test fails with different Table_locks_immediate Instead of sleeping for a fixed period of time, we wait until the other query is executing. --- mysql-test/t/status.test | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/mysql-test/t/status.test b/mysql-test/t/status.test index 746d3a352a4..1208393aa09 100644 --- a/mysql-test/t/status.test +++ b/mysql-test/t/status.test @@ -22,11 +22,14 @@ connection con2; lock tables t1 read; unlock tables; lock tables t1 read; +let $ID= `select connection_id()`; connection con1; --send update t1 set n = 3; connection con2; -sleep 0.5; +# wait for the other query to start executing +let $wait_condition= select 1 from INFORMATION_SCHEMA.PROCESSLIST where ID = $ID and STATE = 0; +--source include/wait_condition.inc unlock tables; connection con1; reap; From 403c0b35a6f295b40cf8106adcd82d8224a87cca Mon Sep 17 00:00:00 2001 From: "Justin.He/justin.he@dev3-240.dev.cn.tlan" <> Date: Fri, 6 Jul 2007 16:58:56 +0800 Subject: [PATCH 03/24] update some description in t/disable.def for testcase rpl_ndb_innodb2ndb and rpl_ndb_myisam2ndb --- mysql-test/t/disabled.def | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/mysql-test/t/disabled.def b/mysql-test/t/disabled.def index 90fd997e615..feb08c6f743 100644 --- a/mysql-test/t/disabled.def +++ b/mysql-test/t/disabled.def @@ -27,8 +27,8 @@ rpl_ndb_2myisam : BUG#19227 Seems to pass currently rpl_ndb_dd_partitions : BUG#19259 2006-04-21 rpl_ndb_dd_partitions fails on s/AMD rpl_ndb_ddl : BUG#18946 result file needs update + test needs to checked rpl_ddl : BUG#26418 2007-03-01 mleich Slave out of sync after CREATE/DROP TEMPORARY TABLE + ROLLBACK on master -rpl_ndb_innodb2ndb : Bug #19710 Cluster replication to partition table fails on DELETE FROM statement -rpl_ndb_myisam2ndb : Bug #19710 Cluster replication to partition table fails on DELETE FROM statement +rpl_ndb_innodb2ndb : Bug#29549 rpl_ndb_myisam2ndb,rpl_ndb_innodb2ndb failed on Solaris for pack_length issue +rpl_ndb_myisam2ndb : Bug#29549 rpl_ndb_myisam2ndb,rpl_ndb_innodb2ndb failed on Solaris for pack_length issue rpl_row_blob_innodb : BUG#18980 2006-04-10 kent Test fails randomly synchronization : Bug#24529 Test 'synchronization' fails on Mac pushbuild; Also on Linux 64 bit. From 3dfc83f1a136e21242d061bbc8a06fefb8748bf9 Mon Sep 17 00:00:00 2001 From: "tnurnberg@mysql.com/sin.intern.azundris.com" <> Date: Mon, 9 Jul 2007 08:11:38 +0200 Subject: [PATCH 04/24] Bug#22540: Incorrect value in column End_log_pos of SHOW BINLOG EVENTS using InnoDB dollin' it up for Guilhem ;) -- test streamlined, better comments, faster code, add'l assert. --- mysql-test/r/binlog.result | 97 -------------------------------------- mysql-test/t/binlog.test | 61 ------------------------ sql/log.cc | 16 ++++--- 3 files changed, 9 insertions(+), 165 deletions(-) diff --git a/mysql-test/r/binlog.result b/mysql-test/r/binlog.result index aa5c6e88d65..0a199c87545 100644 --- a/mysql-test/r/binlog.result +++ b/mysql-test/r/binlog.result @@ -153,105 +153,8 @@ master-bin.000001 353 Query 1 441 use `test`; insert into t1 values (2) master-bin.000001 441 Query 1 529 use `test`; insert into t1 values (3) master-bin.000001 529 Xid 1 556 COMMIT /* XID */ master-bin.000001 556 Query 1 632 use `test`; drop table t1 -set autocommit= 1; -reset master; -create table t1(n int) engine=innodb; -insert into t1 values (1); -insert into t1 values (2); -insert into t1 values (3); -commit; -drop table t1; -show binlog events from 0; -Log_name Pos Event_type Server_id End_log_pos Info -master-bin.000001 4 Format_desc 1 98 Server version, Binlog ver: 4 -master-bin.000001 98 Query 1 197 use `test`; create table t1(n int) engine=innodb -master-bin.000001 197 Query 1 285 use `test`; insert into t1 values (1) -master-bin.000001 285 Xid 1 312 COMMIT /* XID */ -master-bin.000001 312 Query 1 400 use `test`; insert into t1 values (2) -master-bin.000001 400 Xid 1 427 COMMIT /* XID */ -master-bin.000001 427 Query 1 515 use `test`; insert into t1 values (3) -master-bin.000001 515 Xid 1 542 COMMIT /* XID */ -master-bin.000001 542 Query 1 618 use `test`; drop table t1 -reset master; -create table t1(n int) engine=myisam; -begin; -insert into t1 values (4); -insert into t1 values (5); -insert into t1 values (6); -commit; -drop table t1; -show binlog events from 0; -Log_name Pos Event_type Server_id End_log_pos Info -master-bin.000001 4 Format_desc 1 98 Server version, Binlog ver: 4 -master-bin.000001 98 Query 1 197 use `test`; create table t1(n int) engine=myisam -master-bin.000001 197 Query 1 285 use `test`; insert into t1 values (4) -master-bin.000001 285 Query 1 373 use `test`; insert into t1 values (5) -master-bin.000001 373 Query 1 461 use `test`; insert into t1 values (6) -master-bin.000001 461 Query 1 537 use `test`; drop table t1 -set autocommit= 1; -reset master; -create table t1(n int) engine=innodb; -show master status; -File Position Binlog_Do_DB Binlog_Ignore_DB -master-bin.000001 197 -insert into t1 values (1); -show master status; -File Position Binlog_Do_DB Binlog_Ignore_DB -master-bin.000001 312 -insert into t1 values (2); -insert into t1 values (3); -show master status; -File Position Binlog_Do_DB Binlog_Ignore_DB -master-bin.000001 542 -commit; -show master status; -File Position Binlog_Do_DB Binlog_Ignore_DB -master-bin.000001 542 -drop table t1; -show binlog events from 0; -Log_name Pos Event_type Server_id End_log_pos Info -master-bin.000001 4 Format_desc 1 98 Server version, Binlog ver: 4 -master-bin.000001 98 Query 1 197 use `test`; create table t1(n int) engine=innodb -master-bin.000001 197 Query 1 285 use `test`; insert into t1 values (1) -master-bin.000001 285 Xid 1 312 COMMIT /* XID */ -master-bin.000001 312 Query 1 400 use `test`; insert into t1 values (2) -master-bin.000001 400 Xid 1 427 COMMIT /* XID */ -master-bin.000001 427 Query 1 515 use `test`; insert into t1 values (3) -master-bin.000001 515 Xid 1 542 COMMIT /* XID */ -master-bin.000001 542 Query 1 618 use `test`; drop table t1 -set autocommit= 0; -reset master; -create table t1(n int) engine=myisam; -show master status; -File Position Binlog_Do_DB Binlog_Ignore_DB -master-bin.000001 197 -insert into t1 values (4); -show master status; -File Position Binlog_Do_DB Binlog_Ignore_DB -master-bin.000001 285 -insert into t1 values (5); -insert into t1 values (6); -show master status; -File Position Binlog_Do_DB Binlog_Ignore_DB -master-bin.000001 461 -commit; -show master status; -File Position Binlog_Do_DB Binlog_Ignore_DB -master-bin.000001 461 -drop table t1; -show binlog events from 0; -Log_name Pos Event_type Server_id End_log_pos Info -master-bin.000001 4 Format_desc 1 98 Server version, Binlog ver: 4 -master-bin.000001 98 Query 1 197 use `test`; create table t1(n int) engine=myisam -master-bin.000001 197 Query 1 285 use `test`; insert into t1 values (4) -master-bin.000001 285 Query 1 373 use `test`; insert into t1 values (5) -master-bin.000001 373 Query 1 461 use `test`; insert into t1 values (6) -master-bin.000001 461 Query 1 537 use `test`; drop table t1 -set session autocommit = @ac; set @bcs = @@binlog_cache_size; -set @ac = @@autocommit; set global binlog_cache_size=4096; -set autocommit= 0; reset master; create table t1 (a int) engine=innodb; show binlog events from 0; diff --git a/mysql-test/t/binlog.test b/mysql-test/t/binlog.test index b9996a2b380..5d1399925c3 100644 --- a/mysql-test/t/binlog.test +++ b/mysql-test/t/binlog.test @@ -78,72 +78,11 @@ drop table t1; --replace_regex /\/\* xid=.* \*\//\/* XID *\// /table_id: [0-9]+/table_id: #/ /Server ver: [^,]*,/Server version,/ show binlog events from 0; -set autocommit= 1; -reset master; -create table t1(n int) engine=innodb; -insert into t1 values (1); -insert into t1 values (2); -insert into t1 values (3); -commit; -drop table t1; ---replace_regex /\/\* xid=.* \*\//\/* XID *\// /table_id: [0-9]+/table_id: #/ /Server ver: [^,]*,/Server version,/ -show binlog events from 0; - -reset master; -create table t1(n int) engine=myisam; -begin; -insert into t1 values (4); -insert into t1 values (5); -insert into t1 values (6); -commit; -drop table t1; ---replace_regex /\/\* xid=.* \*\//\/* XID *\// /table_id: [0-9]+/table_id: #/ /Server ver: [^,]*,/Server version,/ -show binlog events from 0; - -# now show this also works for SHOW MASTER STATUS -# as this is what "mysqldump --master-data=1" uses. - -set autocommit= 1; -reset master; -create table t1(n int) engine=innodb; -show master status; -insert into t1 values (1); -show master status; -insert into t1 values (2); -insert into t1 values (3); -show master status; -commit; -show master status; -drop table t1; ---replace_regex /\/\* xid=.* \*\//\/* XID *\// /table_id: [0-9]+/table_id: #/ /Server ver: [^,]*,/Server version,/ -show binlog events from 0; - -set autocommit= 0; -reset master; -create table t1(n int) engine=myisam; -show master status; -insert into t1 values (4); -show master status; -insert into t1 values (5); -insert into t1 values (6); - -show master status; -commit; -show master status; -drop table t1; ---replace_regex /\/\* xid=.* \*\//\/* XID *\// /table_id: [0-9]+/table_id: #/ /Server ver: [^,]*,/Server version,/ -show binlog events from 0; - -set session autocommit = @ac; - # now show that nothing breaks if we need to read from the cache more # than once, resulting in split event-headers set @bcs = @@binlog_cache_size; -set @ac = @@autocommit; - set global binlog_cache_size=4096; -set autocommit= 0; reset master; create table t1 (a int) engine=innodb; diff --git a/sql/log.cc b/sql/log.cc index bcaf352f620..164dbd0d2d5 100644 --- a/sql/log.cc +++ b/sql/log.cc @@ -1965,14 +1965,14 @@ bool MYSQL_LOG::write(THD *thd, IO_CACHE *cache, Log_event *commit_event) } /* - Adjust hdr_offs. Note that this doesn't mean it will necessarily - be valid in the next iteration; if the current event is very long, - it may take a couple of read-iterations (and subsequent fixings - of hdr_offs) for it to become valid again. - if we had a split header, hdr_offs was already fixed above. + Adjust hdr_offs. Note that it may still point beyond the segment + read in the next iteration; if the current event is very long, + it may take a couple of read-iterations (and subsequent adjustments + of hdr_offs) for it to point into the then-current segment. + If we have a split header (!carry), hdr_offs will be set at the + beginning of the next iteration, overwriting the value we set here: */ - if (carry == 0) - hdr_offs -= length; + hdr_offs -= length; } /* Write data to the binary log file */ @@ -1982,6 +1982,8 @@ bool MYSQL_LOG::write(THD *thd, IO_CACHE *cache, Log_event *commit_event) DBUG_EXECUTE_IF("half_binlogged_transaction", goto DBUG_skip_commit;); } while ((length=my_b_fill(cache))); + DBUG_ASSERT(carry == 0); + if (commit_event->write(&log_file)) goto err; #ifndef DBUG_OFF From 7cb5374120e6d69d696106fff9cf4b58d34d6f3b Mon Sep 17 00:00:00 2001 From: "tsmith@sita.local" <> Date: Tue, 10 Jul 2007 05:37:43 -0600 Subject: [PATCH 05/24] Apply the following innodb-5.1-* snapshots: ss1489, ss1496, ss1550, ss1569. After applying the snapshots, ensure that code conforms to the final version of WL 3914. It is signficant that, after these changes, InnoDB does not define MYSQL_SERVER, and can be built as an independent storage engine plugin. Fixes: Bug#9709: InnoDB inconsistensy causes "Operating System Error 32/33" Bug#18828: If InnoDB runs out of undo slots, it returns misleading 'table is full' Bug#20090: InnoDB: Error: trying to declare trx to enter InnoDB Bug#20352: Make ibuf_contract_for_n_pages tunable Bug#21101: Wrong error on exceeding max row size for InnoDB table Bug#21293: Deadlock detection prefers to kill long running FOR UPDATE queries Bug#22819: SHOW INNODB STATUS crashes the server with an assertion failure under high load Bug#25078: Make the replication thread to ignore innodb_thread_concurrency Bug#25645: Assertion failure in file srv0srv.c Bug#28138: indexing column prefixes produces corruption in InnoDB --- mysql-test/include/innodb_trx_weight.inc | 51 ++ mysql-test/r/innodb.result | 11 + mysql-test/r/innodb_trx_weight.result | 1 + mysql-test/t/innodb.test | 15 + mysql-test/t/innodb_trx_weight.test | 108 ++++ sql/sql_class.cc | 2 +- storage/innobase/Makefile.am | 232 ++++--- storage/innobase/btr/Makefile.am | 25 - storage/innobase/btr/btr0btr.c | 7 +- storage/innobase/buf/Makefile.am | 25 - storage/innobase/data/Makefile.am | 25 - storage/innobase/data/data0data.c | 2 + storage/innobase/data/data0type.c | 3 +- storage/innobase/dict/Makefile.am | 26 - storage/innobase/dict/dict0crea.c | 3 +- storage/innobase/dict/dict0dict.c | 19 +- storage/innobase/dyn/Makefile.am | 25 - storage/innobase/eval/Makefile.am | 25 - storage/innobase/fil/Makefile.am | 25 - storage/innobase/fsp/Makefile.am | 26 - storage/innobase/fsp/fsp0fsp.c | 11 +- storage/innobase/fut/Makefile.am | 25 - storage/innobase/ha/Makefile.am | 25 - storage/innobase/handler/Makefile.am | 28 - storage/innobase/handler/ha_innodb.cc | 785 ++++++++++++----------- storage/innobase/handler/ha_innodb.h | 63 +- storage/innobase/ibuf/Makefile.am | 25 - storage/innobase/ibuf/ibuf0ibuf.c | 86 ++- storage/innobase/include/Makefile.i | 10 - storage/innobase/include/db0err.h | 5 + storage/innobase/include/dict0dict.h | 11 + storage/innobase/include/dict0dict.ic | 24 + storage/innobase/include/dict0mem.h | 11 +- storage/innobase/include/ha_prototypes.h | 29 + storage/innobase/include/os0file.h | 3 +- storage/innobase/include/rem0rec.ic | 6 +- storage/innobase/include/row0mysql.h | 13 + storage/innobase/include/trx0trx.h | 36 +- storage/innobase/include/trx0undo.h | 13 +- storage/innobase/include/ut0ut.h | 5 + storage/innobase/lock/Makefile.am | 25 - storage/innobase/lock/lock0lock.c | 17 +- storage/innobase/log/Makefile.am | 25 - storage/innobase/log/log0log.c | 34 +- storage/innobase/mach/Makefile.am | 25 - storage/innobase/mem/Makefile.am | 27 - storage/innobase/mtr/Makefile.am | 25 - storage/innobase/os/Makefile.am | 25 - storage/innobase/os/os0file.c | 16 + storage/innobase/page/Makefile.am | 25 - storage/innobase/pars/Makefile.am | 27 - storage/innobase/plug.in | 33 +- storage/innobase/que/Makefile.am | 25 - storage/innobase/read/Makefile.am | 25 - storage/innobase/rem/Makefile.am | 25 - storage/innobase/rem/rem0rec.c | 40 +- storage/innobase/row/Makefile.am | 26 - storage/innobase/row/row0ins.c | 46 +- storage/innobase/row/row0mysql.c | 25 +- storage/innobase/row/row0row.c | 23 +- storage/innobase/row/row0sel.c | 26 + storage/innobase/srv/Makefile.am | 25 - storage/innobase/srv/srv0srv.c | 50 +- storage/innobase/srv/srv0start.c | 6 + storage/innobase/sync/Makefile.am | 25 - storage/innobase/sync/sync0arr.c | 4 +- storage/innobase/thr/Makefile.am | 25 - storage/innobase/trx/Makefile.am | 26 - storage/innobase/trx/trx0rec.c | 19 +- storage/innobase/trx/trx0trx.c | 60 +- storage/innobase/trx/trx0undo.c | 101 +-- storage/innobase/usr/Makefile.am | 25 - storage/innobase/ut/Makefile.am | 25 - storage/innobase/ut/ut0ut.c | 1 + 74 files changed, 1344 insertions(+), 1483 deletions(-) create mode 100644 mysql-test/include/innodb_trx_weight.inc create mode 100644 mysql-test/r/innodb_trx_weight.result create mode 100644 mysql-test/t/innodb_trx_weight.test delete mode 100644 storage/innobase/btr/Makefile.am delete mode 100644 storage/innobase/buf/Makefile.am delete mode 100644 storage/innobase/data/Makefile.am delete mode 100644 storage/innobase/dict/Makefile.am delete mode 100644 storage/innobase/dyn/Makefile.am delete mode 100644 storage/innobase/eval/Makefile.am delete mode 100644 storage/innobase/fil/Makefile.am delete mode 100644 storage/innobase/fsp/Makefile.am delete mode 100644 storage/innobase/fut/Makefile.am delete mode 100644 storage/innobase/ha/Makefile.am delete mode 100644 storage/innobase/handler/Makefile.am delete mode 100644 storage/innobase/ibuf/Makefile.am delete mode 100644 storage/innobase/include/Makefile.i delete mode 100644 storage/innobase/lock/Makefile.am delete mode 100644 storage/innobase/log/Makefile.am delete mode 100644 storage/innobase/mach/Makefile.am delete mode 100644 storage/innobase/mem/Makefile.am delete mode 100644 storage/innobase/mtr/Makefile.am delete mode 100644 storage/innobase/os/Makefile.am delete mode 100644 storage/innobase/page/Makefile.am delete mode 100644 storage/innobase/pars/Makefile.am delete mode 100644 storage/innobase/que/Makefile.am delete mode 100644 storage/innobase/read/Makefile.am delete mode 100644 storage/innobase/rem/Makefile.am delete mode 100644 storage/innobase/row/Makefile.am delete mode 100644 storage/innobase/srv/Makefile.am delete mode 100644 storage/innobase/sync/Makefile.am delete mode 100644 storage/innobase/thr/Makefile.am delete mode 100644 storage/innobase/trx/Makefile.am delete mode 100644 storage/innobase/usr/Makefile.am delete mode 100644 storage/innobase/ut/Makefile.am diff --git a/mysql-test/include/innodb_trx_weight.inc b/mysql-test/include/innodb_trx_weight.inc new file mode 100644 index 00000000000..56d3d47da36 --- /dev/null +++ b/mysql-test/include/innodb_trx_weight.inc @@ -0,0 +1,51 @@ +-- connect (con1,localhost,root,,) +-- connect (con2,localhost,root,,) + +-- connection con1 +SET autocommit=0; +SELECT * FROM t1 FOR UPDATE; +-- if ($con1_extra_sql_present) { + -- eval $con1_extra_sql +-- } + +-- connection con2 +SET autocommit=0; +SELECT * FROM t2 FOR UPDATE; +-- if ($con2_extra_sql_present) { + -- eval $con2_extra_sql +-- } + +-- if ($con1_should_be_rolledback) { + -- connection con1 + -- send + INSERT INTO t2 VALUES (0); + + -- connection con2 + INSERT INTO t1 VALUES (0); + ROLLBACK; + + -- connection con1 + -- error ER_LOCK_DEADLOCK + -- reap +-- } +# else +-- if (!$con1_should_be_rolledback) { + -- connection con2 + -- send + INSERT INTO t1 VALUES (0); + + -- connection con1 + INSERT INTO t2 VALUES (0); + ROLLBACK; + + -- connection con2 + -- error ER_LOCK_DEADLOCK + -- reap +-- } + +-- connection default + +DELETE FROM t5_nontrans; + +-- disconnect con1 +-- disconnect con2 diff --git a/mysql-test/r/innodb.result b/mysql-test/r/innodb.result index ad79a2a837a..9a96145ef06 100644 --- a/mysql-test/r/innodb.result +++ b/mysql-test/r/innodb.result @@ -3211,3 +3211,14 @@ t1 CREATE TABLE `t1` ( CONSTRAINT `t1_t2` FOREIGN KEY (`id`) REFERENCES `t2` (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=349 DEFAULT CHARSET=latin1 DROP TABLE t1,t2; +CREATE TABLE t1 ( +c01 CHAR(255), c02 CHAR(255), c03 CHAR(255), c04 CHAR(255), +c05 CHAR(255), c06 CHAR(255), c07 CHAR(255), c08 CHAR(255), +c09 CHAR(255), c10 CHAR(255), c11 CHAR(255), c12 CHAR(255), +c13 CHAR(255), c14 CHAR(255), c15 CHAR(255), c16 CHAR(255), +c17 CHAR(255), c18 CHAR(255), c19 CHAR(255), c20 CHAR(255), +c21 CHAR(255), c22 CHAR(255), c23 CHAR(255), c24 CHAR(255), +c25 CHAR(255), c26 CHAR(255), c27 CHAR(255), c28 CHAR(255), +c29 CHAR(255), c30 CHAR(255), c31 CHAR(255), c32 CHAR(255) +) ENGINE = InnoDB; +ERROR 42000: Row size too large. The maximum row size for the used table type, not counting BLOBs, is 8126. You have to change some columns to TEXT or BLOBs diff --git a/mysql-test/r/innodb_trx_weight.result b/mysql-test/r/innodb_trx_weight.result new file mode 100644 index 00000000000..195775f74c8 --- /dev/null +++ b/mysql-test/r/innodb_trx_weight.result @@ -0,0 +1 @@ +SET storage_engine=InnoDB; diff --git a/mysql-test/t/innodb.test b/mysql-test/t/innodb.test index 321a1f4763a..96b2ffda7d6 100644 --- a/mysql-test/t/innodb.test +++ b/mysql-test/t/innodb.test @@ -2349,6 +2349,21 @@ SHOW CREATE TABLE t1; DROP TABLE t1,t2; +# +# Bug #21101 (Prints wrong error message if max row size is too large) +# +--error 1118 +CREATE TABLE t1 ( + c01 CHAR(255), c02 CHAR(255), c03 CHAR(255), c04 CHAR(255), + c05 CHAR(255), c06 CHAR(255), c07 CHAR(255), c08 CHAR(255), + c09 CHAR(255), c10 CHAR(255), c11 CHAR(255), c12 CHAR(255), + c13 CHAR(255), c14 CHAR(255), c15 CHAR(255), c16 CHAR(255), + c17 CHAR(255), c18 CHAR(255), c19 CHAR(255), c20 CHAR(255), + c21 CHAR(255), c22 CHAR(255), c23 CHAR(255), c24 CHAR(255), + c25 CHAR(255), c26 CHAR(255), c27 CHAR(255), c28 CHAR(255), + c29 CHAR(255), c30 CHAR(255), c31 CHAR(255), c32 CHAR(255) + ) ENGINE = InnoDB; + ####################################################################### # # # Please, DO NOT TOUCH this file as well as the innodb.result file. # diff --git a/mysql-test/t/innodb_trx_weight.test b/mysql-test/t/innodb_trx_weight.test new file mode 100644 index 00000000000..b72eaad345f --- /dev/null +++ b/mysql-test/t/innodb_trx_weight.test @@ -0,0 +1,108 @@ +# +# Ensure that the number of locks (SELECT FOR UPDATE for example) is +# added to the number of altered rows when choosing the smallest +# transaction to kill as a victim when a deadlock is detected. +# Also transactions what had edited non-transactional tables should +# be heavier than ones that had not. +# + +-- source include/have_innodb.inc + +SET storage_engine=InnoDB; + +# we do not really care about what gets printed, we are only +# interested in getting the deadlock resolved according to our +# expectations +-- disable_query_log +-- disable_result_log + +# we want to use "-- eval statement1; statement2" which does not work with +# prepared statements. Because this test should not behave differently with +# or without prepared statements we disable them so the test does not fail +# if someone runs ./mysql-test-run.pl --ps-protocol +-- disable_ps_protocol + +-- disable_warnings +DROP TABLE IF EXISTS t1, t2, t3, t4, t5_nontrans; +-- enable_warnings + +# we will create a simple deadlock with t1, t2 and two connections +CREATE TABLE t1 (a INT); +CREATE TABLE t2 (a INT); + +# auxiliary table with a bulk of rows which will be locked by a +# transaction to increase its weight +CREATE TABLE t3 (a INT); + +# auxiliary empty table which will be inserted by a +# transaction to increase its weight +CREATE TABLE t4 (a INT); + +# auxiliary non-transactional table which will be edited by a +# transaction to tremendously increase its weight +CREATE TABLE t5_nontrans (a INT) ENGINE=MyISAM; + +INSERT INTO t1 VALUES (1); +INSERT INTO t2 VALUES (1); +# insert a lot of rows in t3 +INSERT INTO t3 VALUES (1); +INSERT INTO t3 SELECT * FROM t3; +INSERT INTO t3 SELECT * FROM t3; +INSERT INTO t3 SELECT * FROM t3; +INSERT INTO t3 SELECT * FROM t3; +INSERT INTO t3 SELECT * FROM t3; +INSERT INTO t3 SELECT * FROM t3; +INSERT INTO t3 SELECT * FROM t3; +INSERT INTO t3 SELECT * FROM t3; +INSERT INTO t3 SELECT * FROM t3; +INSERT INTO t3 SELECT * FROM t3; +INSERT INTO t3 SELECT * FROM t3; + +# test locking weight + +-- let $con1_extra_sql = +-- let $con1_extra_sql_present = 0 +-- let $con2_extra_sql = SELECT * FROM t3 FOR UPDATE +-- let $con2_extra_sql_present = 1 +-- let $con1_should_be_rolledback = 1 +-- source include/innodb_trx_weight.inc + +-- let $con1_extra_sql = INSERT INTO t4 VALUES (1), (1) +-- let $con1_extra_sql_present = 1 +-- let $con2_extra_sql = SELECT * FROM t3 FOR UPDATE +-- let $con2_extra_sql_present = 1 +-- let $con1_should_be_rolledback = 1 +-- source include/innodb_trx_weight.inc + +-- let $con1_extra_sql = INSERT INTO t4 VALUES (1), (1), (1), (1), (1), (1) +-- let $con1_extra_sql_present = 1 +-- let $con2_extra_sql = SELECT * FROM t3 FOR UPDATE +-- let $con2_extra_sql_present = 1 +-- let $con1_should_be_rolledback = 0 +-- source include/innodb_trx_weight.inc + +# test weight when non-transactional tables are edited + +-- let $con1_extra_sql = INSERT INTO t4 VALUES (1), (1), (1) +-- let $con1_extra_sql_present = 1 +-- let $con2_extra_sql = +-- let $con2_extra_sql_present = 0 +-- let $con1_should_be_rolledback = 0 +-- source include/innodb_trx_weight.inc + +-- let $con1_extra_sql = INSERT INTO t4 VALUES (1), (1), (1) +-- let $con1_extra_sql_present = 1 +-- let $con2_extra_sql = INSERT INTO t5_nontrans VALUES (1) +-- let $con2_extra_sql_present = 1 +-- let $con1_should_be_rolledback = 1 +-- source include/innodb_trx_weight.inc + +-- let $con1_extra_sql = INSERT INTO t4 VALUES (1), (1), (1) +-- let $con1_extra_sql = $con1_extra_sql; INSERT INTO t5_nontrans VALUES (1) +-- let $con1_extra_sql_present = 1 +-- let $con2_extra_sql = INSERT INTO t5_nontrans VALUES (1) +-- let $con2_extra_sql_present = 1 +-- let $con1_should_be_rolledback = 0 +-- source include/innodb_trx_weight.inc + +DROP TABLE t1, t2, t3, t4, t5_nontrans; diff --git a/sql/sql_class.cc b/sql/sql_class.cc index 4945b805578..a56ce6d02a4 100644 --- a/sql/sql_class.cc +++ b/sql/sql_class.cc @@ -2570,7 +2570,7 @@ extern "C" int thd_non_transactional_update(const MYSQL_THD thd) return(thd->no_trans_update.all); } -extern "C" int thd_binlog_format(const THD *thd) +extern "C" int thd_binlog_format(const MYSQL_THD thd) { return (int) thd->variables.binlog_format; } 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 - -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 - -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 - -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 = +DEFS = @DEFS@ -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 +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_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 + +libinnobase_a_CXXFLAGS= $(AM_CFLAGS) +libinnobase_a_CFLAGS = $(AM_CFLAGS) + +EXTRA_LTLIBRARIES = ha_innodb.la +pkglib_LTLIBRARIES = @plugin_innobase_shared_target@ + +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 + #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 + 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 - -#ifdef WITH_INNOBASE_STORAGE_ENGINE +#include #include #include @@ -40,15 +38,23 @@ have disables the InnoDB inlining in this file. */ #include #include #include "ha_innodb.h" +#include -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; +#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 @@ -426,6 +418,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. */ @@ -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); @@ -4481,6 +4530,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 @@ -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); + update_thd(ha_thd()); - if (thd_sql_command(thd) == SQLCOM_TRUNCATE) { - /* Truncate the table in InnoDB */ - - error = row_truncate_table_for_mysql(prebuilt->table, prebuilt->trx); - if (error == DB_ERROR) { - /* Cannot truncate; resort to ha_innobase::delete_row() */ - goto fallback; - } - - error = convert_error_code_to_mysql(error, NULL); - - DBUG_RETURN(error); + 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); } -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); + /* Truncate the table in InnoDB */ + + error = row_truncate_table_for_mysql(prebuilt->table, prebuilt->trx); + if (error == DB_ERROR) { + /* Cannot truncate; resort to ha_innobase::delete_row() */ + goto fallback; + } + + 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' */ +/*===================*/ + /* 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; + 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 */ + /* Get the transaction associated with the current thd, or create one + if not yet created */ - parent_trx = check_trx_exists(hton, current_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 */ @@ -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 *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); + ibuf_count_check(space, page_no); - if (!ibuf_counts_inited) { - - return(0); - } - - 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); + 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); - } - - 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 #include +#include #include "ut0sort.h" #include "trx0trx.h" From ccea97fa6f6fd8adefaf7e168e72d56041dc7253 Mon Sep 17 00:00:00 2001 From: "tsmith@sita.local" <> Date: Tue, 10 Jul 2007 08:16:51 -0600 Subject: [PATCH 06/24] NULL MERGE UP to 5.1. Apply innodb-5.0-* snapshots: ss1489 and ss1547. Fixes: Bug#9709: InnoDB inconsistensy causes "Operating System Error 32/33" Bug#22819: SHOW INNODB STATUS crashes the server with an assertion failure under high load Bug#25645: Assertion failure in file srv0srv.c Bug#27294: insert into ... select ... causes crash with innodb_locks_unsafe_for_binlog=1 Bug#28138: indexing column prefixes produces corruption in InnoDB --- innobase/btr/btr0btr.c | 7 ++- innobase/buf/buf0buf.c | 108 +++++++++++++++++++++++++++++++--- innobase/buf/buf0lru.c | 2 - innobase/ibuf/ibuf0ibuf.c | 30 ++++++++-- innobase/include/buf0buf.ic | 21 +++++-- innobase/include/buf0lru.h | 2 - innobase/include/dict0dict.h | 11 ++++ innobase/include/dict0dict.ic | 24 ++++++++ innobase/include/dict0mem.h | 11 ++-- innobase/include/os0file.h | 3 +- innobase/include/trx0trx.h | 2 +- innobase/lock/lock0lock.c | 6 -- innobase/log/log0log.c | 33 +++++------ innobase/mtr/mtr0mtr.c | 13 +++- innobase/os/os0file.c | 17 +++++- innobase/rem/rem0rec.c | 24 ++++++-- innobase/row/row0sel.c | 25 ++++++++ innobase/srv/srv0srv.c | 10 ++-- sql/ha_innodb.cc | 39 ++++++++---- 19 files changed, 315 insertions(+), 73 deletions(-) diff --git a/innobase/btr/btr0btr.c b/innobase/btr/btr0btr.c index 07bc04feae6..a339405372d 100644 --- a/innobase/btr/btr0btr.c +++ b/innobase/btr/btr0btr.c @@ -2542,8 +2542,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/innobase/buf/buf0buf.c b/innobase/buf/buf0buf.c index f24f1744363..9df48495355 100644 --- a/innobase/buf/buf0buf.c +++ b/innobase/buf/buf0buf.c @@ -1220,7 +1220,8 @@ loop: ut_ad(buf_validate()); } #endif - ut_ad(block->buf_fix_count > 0); + /* This debug code has been upgraded to narrow down Bug# 26081 */ + ut_a(block->buf_fix_count > 0); ut_ad(block->state == BUF_BLOCK_FILE_PAGE); if (mode == BUF_GET_NOWAIT) { @@ -1238,6 +1239,13 @@ loop: if (!success) { mutex_enter(&block->mutex); + /* This debug code has been added to narrow + down Bug# 26081 */ + if (UNIV_UNLIKELY(block->buf_fix_count == 0)) { + buf_print_diagnostic(mtr, block); + ut_error; + } + block->buf_fix_count--; mutex_exit(&block->mutex); @@ -1362,7 +1370,14 @@ buf_page_optimistic_get_func( if (UNIV_UNLIKELY(!success)) { mutex_enter(&block->mutex); - + + /* This debug code has been added to narrow + down Bug# 26081 */ + if (UNIV_UNLIKELY(block->buf_fix_count == 0)) { + buf_print_diagnostic(mtr, block); + ut_error; + } + block->buf_fix_count--; mutex_exit(&block->mutex); @@ -1384,7 +1399,14 @@ buf_page_optimistic_get_func( } mutex_enter(&block->mutex); - + + /* This debug code has been added to narrow + down Bug# 26081 */ + if (UNIV_UNLIKELY(block->buf_fix_count == 0)) { + buf_print_diagnostic(mtr, block); + ut_error; + } + block->buf_fix_count--; mutex_exit(&block->mutex); @@ -1404,7 +1426,10 @@ buf_page_optimistic_get_func( ut_ad(buf_validate()); } #endif - ut_ad(block->buf_fix_count > 0); + /* This debug code has been upgraded from ut_ad() to narrow + down Bug# 26081 */ + ut_a(block->buf_fix_count > 0); + ut_ad(block->state == BUF_BLOCK_FILE_PAGE); #ifdef UNIV_DEBUG_FILE_ACCESSES @@ -1493,7 +1518,14 @@ buf_page_get_known_nowait( if (!success) { mutex_enter(&block->mutex); - + + /* This debug code has been added to narrow + down Bug# 26081 */ + if (UNIV_UNLIKELY(block->buf_fix_count == 0)) { + buf_print_diagnostic(mtr, block); + ut_error; + } + block->buf_fix_count--; mutex_exit(&block->mutex); @@ -1514,7 +1546,8 @@ buf_page_get_known_nowait( ut_ad(buf_validate()); } #endif - ut_ad(block->buf_fix_count > 0); + /* This debug code has been upgraded to narrow down Bug# 26081 */ + ut_a(block->buf_fix_count > 0); ut_ad(block->state == BUF_BLOCK_FILE_PAGE); #ifdef UNIV_DEBUG_FILE_ACCESSES ut_a(block->file_page_was_freed == FALSE); @@ -2027,7 +2060,6 @@ buf_pool_invalidate(void) mutex_exit(&(buf_pool->mutex)); } -#ifdef UNIV_DEBUG /************************************************************************* Validates the buffer buf_pool data structure. */ @@ -2227,7 +2259,6 @@ buf_print(void) ut_a(buf_validate()); } -#endif /* UNIV_DEBUG */ /************************************************************************* Returns the number of latched pages in the buffer pool. */ @@ -2483,3 +2514,64 @@ buf_get_free_list_len(void) return(len); } + +/************************************************************************* +Print the block fields. */ + +void +buf_block_print( +/*============*/ + const buf_block_t* block) /* in: block to print */ +{ + fprintf(stderr, + "BLOCK fields\nmagic_n: 0x%lx\n" + "state: %lu frame: 0x%lx space:offset: 0x%lx:0x%lx\n" + "hash value: 0x%lx check_index_page_at_flush: %ld\n" + "newest_modification %lu:%lu oldest_modification %lu:%lu\n" + "flush_type: %lu in_free_list: %ld in_LRU_list: %ld\n" + "LRU_position: %ld freed_page_clock: %lu old: %ld\n" + "accessed: %ld buf_fix_count: %lu io_fix: %ld " + "modify_clock: %lu:%lu\n" + "n_hash_helps: %lu n_fields: %ld n_bytes: %lu side: %lu\n" + "is_hashed: %lu n_pointers: %lu curr_n_fields: %lu\n" + "curr_n_bytes: %lu curr_side: %lu index name: %s\n" + "file_page_was_freed: %lu\n", + block->magic_n, block->state, (ulint) block->frame, + block->space, block->offset, block->lock_hash_val, + block->check_index_page_at_flush, + ut_dulint_get_high(block->newest_modification), + ut_dulint_get_low(block->newest_modification), + ut_dulint_get_high(block->oldest_modification), + ut_dulint_get_low(block->oldest_modification), + block->flush_type, block->in_free_list, block->in_LRU_list, + block->LRU_position, block->freed_page_clock, + block->old, block->accessed, block->buf_fix_count, + block->io_fix, + ut_dulint_get_high(block->modify_clock), + ut_dulint_get_low(block->modify_clock), + block->n_hash_helps, block->n_fields, block->n_bytes, + block->side, block->is_hashed, block->n_pointers, + block->curr_n_fields, block->curr_n_bytes, + block->curr_side, block->index->name, + block->file_page_was_freed); +} + +/************************************************************************ +Print some diagnostics related to the buffer pool.*/ + +void +buf_print_diagnostic( +/*=================*/ + mtr_t* mtr, /* in: mtr to print */ + const buf_block_t* block) /* in: block to print */ +{ + fprintf(stderr, "=== MTR ===\n"); + mtr_print(mtr); + buf_LRU_print(); + buf_print(); + buf_LRU_validate(); + buf_print_io(stderr); + fprintf(stderr, "=== BLOCK ===\n"); + buf_block_print(block); +} + diff --git a/innobase/buf/buf0lru.c b/innobase/buf/buf0lru.c index dfee2add045..0f632f0752a 100644 --- a/innobase/buf/buf0lru.c +++ b/innobase/buf/buf0lru.c @@ -945,7 +945,6 @@ buf_LRU_block_free_hashed_page( buf_LRU_block_free_non_file_page(block); } -#ifdef UNIV_DEBUG /************************************************************************** Validates the LRU list. */ @@ -1076,4 +1075,3 @@ buf_LRU_print(void) mutex_exit(&(buf_pool->mutex)); } -#endif /* UNIV_DEBUG */ diff --git a/innobase/ibuf/ibuf0ibuf.c b/innobase/ibuf/ibuf0ibuf.c index eb10a88d1d1..031add1c9ba 100644 --- a/innobase/ibuf/ibuf0ibuf.c +++ b/innobase/ibuf/ibuf0ibuf.c @@ -1436,6 +1436,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 */ @@ -1443,11 +1446,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); + buf2 + i * DATA_NEW_ORDER_NULL_TYPE_BUF_SIZE, + dfield_get_type(entry_field), fixed_len); } /* Store the type info in buf2 to field 3 of tuple */ diff --git a/innobase/include/buf0buf.ic b/innobase/include/buf0buf.ic index ddc91b8d66c..844d3fbd6d1 100644 --- a/innobase/include/buf0buf.ic +++ b/innobase/include/buf0buf.ic @@ -11,6 +11,15 @@ Created 11/5/1995 Heikki Tuuri #include "buf0rea.h" #include "mtr0mtr.h" +/************************************************************************* +Print the mtr and block fields. */ + +void +buf_print_diagnostic( +/*=================*/ + mtr_t* mtr, /* in: mtr to print */ + const buf_block_t* block); /* in: block to print */ + #ifdef UNIV_DEBUG extern ulint buf_dbg_counter; /* This is used to insert validation operations in execution in the @@ -618,12 +627,9 @@ buf_page_release( RW_NO_LATCH */ mtr_t* mtr) /* in: mtr */ { - ulint buf_fix_count; - ut_ad(block); ut_a(block->state == BUF_BLOCK_FILE_PAGE); - ut_a(block->buf_fix_count > 0); if (rw_latch == RW_X_LATCH && mtr->modifications) { mutex_enter(&buf_pool->mutex); @@ -633,11 +639,16 @@ buf_page_release( mutex_enter(&block->mutex); + /* This debug code has been added to narrow down Bug# 26081 */ + if (UNIV_UNLIKELY(block->buf_fix_count == 0)) { + buf_print_diagnostic(mtr, block); + ut_error; + } + #ifdef UNIV_SYNC_DEBUG rw_lock_s_unlock(&(block->debug_latch)); #endif - buf_fix_count = block->buf_fix_count; - block->buf_fix_count = buf_fix_count - 1; + --block->buf_fix_count; mutex_exit(&block->mutex); diff --git a/innobase/include/buf0lru.h b/innobase/include/buf0lru.h index 790bf65c698..e0f511cf7b8 100644 --- a/innobase/include/buf0lru.h +++ b/innobase/include/buf0lru.h @@ -122,7 +122,6 @@ void buf_LRU_make_block_old( /*===================*/ buf_block_t* block); /* in: control block */ -#ifdef UNIV_DEBUG /************************************************************************** Validates the LRU list. */ @@ -135,7 +134,6 @@ Prints the LRU list. */ void buf_LRU_print(void); /*===============*/ -#endif /* UNIV_DEBUG */ #ifndef UNIV_NONINL #include "buf0lru.ic" diff --git a/innobase/include/dict0dict.h b/innobase/include/dict0dict.h index 642037494b5..7fd9be1ebd6 100644 --- a/innobase/include/dict0dict.h +++ b/innobase/include/dict0dict.h @@ -84,6 +84,17 @@ dtype_t* dict_col_get_type( /*==============*/ dict_col_t* col); +#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 */ /************************************************************************* Gets the column number. */ UNIV_INLINE diff --git a/innobase/include/dict0dict.ic b/innobase/include/dict0dict.ic index 861da5d057a..cbd7285e20f 100644 --- a/innobase/include/dict0dict.ic +++ b/innobase/include/dict0dict.ic @@ -23,6 +23,30 @@ dict_col_get_type( return(&col->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 */ +{ + ut_ad(col); + ut_ad(type); + + ut_ad(col->type.mtype == type->mtype); + ut_ad(col->type.prtype == type->prtype); + ut_ad(col->type.len == type->len); + ut_ad(col->type.mbminlen == type->mbminlen); + ut_ad(col->type.mbmaxlen == type->mbmaxlen); + + return(TRUE); +} +#endif /* UNIV_DEBUG */ + /************************************************************************* Gets the column number. */ UNIV_INLINE diff --git a/innobase/include/dict0mem.h b/innobase/include/dict0mem.h index 3c10e82342b..7d8dc404290 100644 --- a/innobase/include/dict0mem.h +++ b/innobase/include/dict0mem.h @@ -159,10 +159,13 @@ struct dict_col_struct{ in some of the functions below */ }; -/* 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/innobase/include/os0file.h b/innobase/include/os0file.h index d5bc5a2b115..49460dbaf19 100644 --- a/innobase/include/os0file.h +++ b/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/innobase/include/trx0trx.h b/innobase/include/trx0trx.h index 0dc82893ad1..cf9d1788ad8 100644 --- a/innobase/include/trx0trx.h +++ b/innobase/include/trx0trx.h @@ -604,7 +604,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 */ diff --git a/innobase/lock/lock0lock.c b/innobase/lock/lock0lock.c index 77dfca5fdf4..e0f3f58f737 100644 --- a/innobase/lock/lock0lock.c +++ b/innobase/lock/lock0lock.c @@ -4438,14 +4438,11 @@ lock_table_queue_validate( dict_table_t* table) /* in: table */ { lock_t* lock; - ibool is_waiting; #ifdef UNIV_SYNC_DEBUG ut_ad(mutex_own(&kernel_mutex)); #endif /* UNIV_SYNC_DEBUG */ - is_waiting = FALSE; - lock = UT_LIST_GET_FIRST(table->locks); while (lock) { @@ -4455,12 +4452,9 @@ 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/innobase/log/log0log.c b/innobase/log/log0log.c index 2d3bff522e2..26c0ce60c69 100644 --- a/innobase/log/log0log.c +++ b/innobase/log/log0log.c @@ -3061,9 +3061,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) { @@ -3184,22 +3197,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/innobase/mtr/mtr0mtr.c b/innobase/mtr/mtr0mtr.c index da045be1f62..143db0ce0dd 100644 --- a/innobase/mtr/mtr0mtr.c +++ b/innobase/mtr/mtr0mtr.c @@ -326,7 +326,16 @@ mtr_print( mtr_t* mtr) /* in: mtr */ { fprintf(stderr, - "Mini-transaction handle: memo size %lu bytes log size %lu bytes\n", + "Mini-transaction handle: memo size %lu bytes log " + "size %lu bytes\n" + "state: %lu modifications: %lu n_lock_recs %lu\n" + "log_mode: %lu start_lsn: %lu:%lu end_lsn: %lu:%lu\n", (ulong) dyn_array_get_data_size(&(mtr->memo)), - (ulong) dyn_array_get_data_size(&(mtr->log))); + (ulong) dyn_array_get_data_size(&(mtr->log)), + mtr->state, (ulint) mtr->modifications, + mtr->n_log_recs, mtr->log_mode, + ut_dulint_get_high(mtr->start_lsn), + ut_dulint_get_low(mtr->start_lsn), + ut_dulint_get_high(mtr->end_lsn), + ut_dulint_get_low(mtr->end_lsn)); } diff --git a/innobase/os/os0file.c b/innobase/os/os0file.c index 7133b28ecb2..3030b20a685 100644 --- a/innobase/os/os0file.c +++ b/innobase/os/os0file.c @@ -243,7 +243,13 @@ os_file_get_last_error( fprintf(stderr, "InnoDB: The error means mysqld does not have the access rights to\n" "InnoDB: the directory. It may also be you have created a subdirectory\n" - "InnoDB: of the same name as a data file.\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 are described at\n" @@ -260,6 +266,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); } @@ -369,6 +378,12 @@ 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/innobase/rem/rem0rec.c b/innobase/rem/rem0rec.c index 9480c978755..65da8352dc7 100644 --- a/innobase/rem/rem0rec.c +++ b/innobase/rem/rem0rec.c @@ -462,7 +462,7 @@ rec_get_converted_size_new( case REC_STATUS_INFIMUM: case REC_STATUS_SUPREMUM: /* infimum or supremum record, 8 bytes */ - return(size + 8); /* no extra data needed */ + return(8); /* no extra data needed */ default: ut_a(0); return(ULINT_UNDEFINED); @@ -473,23 +473,34 @@ rec_get_converted_size_new( ulint len = dtuple_get_nth_field(dtuple, i)->len; field = dict_index_get_nth_field(index, i); type = dict_col_get_type(dict_field_get_col(field)); - ut_ad(len != UNIV_SQL_NULL || - !(dtype_get_prtype(type) & DATA_NOT_NULL)); + + ut_ad(dict_col_type_assert_equal( + dict_field_get_col(field), + dfield_get_type(dtuple_get_nth_field( + dtuple, i)))); if (len == UNIV_SQL_NULL) { /* No length is stored for NULL fields. */ + ut_ad(!(dtype_get_prtype(type) & DATA_NOT_NULL)); continue; } ut_ad(len <= dtype_get_len(type) || dtype_get_mtype(type) == 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 || (dtype_get_len(type) < 256 && dtype_get_mtype(type) != 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; @@ -885,6 +896,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; diff --git a/innobase/row/row0sel.c b/innobase/row/row0sel.c index f8a65e6ff82..c956492900d 100644 --- a/innobase/row/row0sel.c +++ b/innobase/row/row0sel.c @@ -3451,6 +3451,31 @@ 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 + && 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(TRUE, index, diff --git a/innobase/srv/srv0srv.c b/innobase/srv/srv0srv.c index 96c0f05111b..e4ce29f445c 100644 --- a/innobase/srv/srv0srv.c +++ b/innobase/srv/srv0srv.c @@ -1037,7 +1037,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++; @@ -1858,6 +1858,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; @@ -1870,6 +1871,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; @@ -1905,9 +1907,9 @@ loop: } if (srv_print_innodb_tablespace_monitor - && difftime(current_time, last_table_monitor_time) > 60) { + && difftime(current_time, last_tablespace_monitor_time) > 60) { - last_table_monitor_time = time(NULL); + last_tablespace_monitor_time = time(NULL); fputs("================================================\n", stderr); @@ -2103,7 +2105,7 @@ loop: os_thread_sleep(2000000); - if (srv_shutdown_state < SRV_SHUTDOWN_LAST_PHASE) { + if (srv_shutdown_state < SRV_SHUTDOWN_CLEANUP) { goto loop; } diff --git a/sql/ha_innodb.cc b/sql/ha_innodb.cc index a3676bd7e1b..b03dc9bb986 100644 --- a/sql/ha_innodb.cc +++ b/sql/ha_innodb.cc @@ -15,7 +15,7 @@ /* 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 @@ -2313,8 +2313,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(thd); + } + row_prebuilt_free((row_prebuilt_t*) innobase_prebuilt); my_free((gptr) upd_buff, MYF(0)); @@ -5305,7 +5312,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 @@ -6150,6 +6162,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 */ @@ -6158,12 +6176,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->options & (OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN))) { if (trx->active_trans != 0) { innobase_commit(thd, TRUE); @@ -6593,8 +6605,15 @@ ha_innobase::store_lock( TL_IGNORE */ { row_prebuilt_t* prebuilt = (row_prebuilt_t*) innobase_prebuilt; + trx_t* trx; - /* NOTE: MySQL can call this function with lock 'type' TL_IGNORE! + /* Note that trx in this function is NOT necessarily prebuilt->trx + 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(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 only 'real' locks! */ @@ -6624,7 +6643,7 @@ ha_innobase::store_lock( used. */ if (srv_locks_unsafe_for_binlog && - prebuilt->trx->isolation_level != TRX_ISO_SERIALIZABLE && + trx->isolation_level != TRX_ISO_SERIALIZABLE && (lock_type == TL_READ || lock_type == TL_READ_NO_INSERT) && (thd->lex->sql_command == SQLCOM_INSERT_SELECT || thd->lex->sql_command == SQLCOM_UPDATE || From bef7899334ceb167a8f9932d36b87b2a5ea8e3db Mon Sep 17 00:00:00 2001 From: "tnurnberg@mysql.com/sin.intern.azundris.com" <> Date: Tue, 10 Jul 2007 18:31:50 +0200 Subject: [PATCH 07/24] Bug#22540: Incorrect value in column End_log_pos of SHOW BINLOG EVENTS using InnoDB streamlining the test --- .../suite/binlog/r/binlog_stm_binlog.result | 826 +++++++++--------- 1 file changed, 413 insertions(+), 413 deletions(-) diff --git a/mysql-test/suite/binlog/r/binlog_stm_binlog.result b/mysql-test/suite/binlog/r/binlog_stm_binlog.result index c02c8f7ef8d..80908e6b450 100644 --- a/mysql-test/suite/binlog/r/binlog_stm_binlog.result +++ b/mysql-test/suite/binlog/r/binlog_stm_binlog.result @@ -157,425 +157,425 @@ commit; drop table t1; show binlog events from 0; Log_name Pos Event_type Server_id End_log_pos Info -master-bin.000001 4 Format_desc 1 98 Server version, Binlog ver: 4 -master-bin.000001 98 Query 1 197 use `test`; create table t1(n int) engine=innodb -master-bin.000001 197 Query 1 265 use `test`; BEGIN -master-bin.000001 265 Query 1 353 use `test`; insert into t1 values (1) -master-bin.000001 353 Query 1 441 use `test`; insert into t1 values (2) -master-bin.000001 441 Query 1 529 use `test`; insert into t1 values (3) -master-bin.000001 529 Xid 1 556 COMMIT /* XID */ -master-bin.000001 556 Query 1 632 use `test`; drop table t1 +master-bin.000001 4 Format_desc 1 106 Server version, Binlog ver: 4 +master-bin.000001 106 Query 1 205 use `test`; create table t1(n int) engine=innodb +master-bin.000001 205 Query 1 273 use `test`; BEGIN +master-bin.000001 273 Query 1 361 use `test`; insert into t1 values (1) +master-bin.000001 361 Query 1 449 use `test`; insert into t1 values (2) +master-bin.000001 449 Query 1 537 use `test`; insert into t1 values (3) +master-bin.000001 537 Xid 1 564 COMMIT /* XID */ +master-bin.000001 564 Query 1 640 use `test`; drop table t1 set @bcs = @@binlog_cache_size; set global binlog_cache_size=4096; reset master; create table t1 (a int) engine=innodb; show binlog events from 0; Log_name Pos Event_type Server_id End_log_pos Info -master-bin.000001 4 Format_desc 1 98 Server version, Binlog ver: 4 -master-bin.000001 98 Query 1 198 use `test`; create table t1 (a int) engine=innodb -master-bin.000001 198 Query 1 266 use `test`; BEGIN -master-bin.000001 266 Query 1 357 use `test`; insert into t1 values( 400 ) -master-bin.000001 357 Query 1 448 use `test`; insert into t1 values( 399 ) -master-bin.000001 448 Query 1 539 use `test`; insert into t1 values( 398 ) -master-bin.000001 539 Query 1 630 use `test`; insert into t1 values( 397 ) -master-bin.000001 630 Query 1 721 use `test`; insert into t1 values( 396 ) -master-bin.000001 721 Query 1 812 use `test`; insert into t1 values( 395 ) -master-bin.000001 812 Query 1 903 use `test`; insert into t1 values( 394 ) -master-bin.000001 903 Query 1 994 use `test`; insert into t1 values( 393 ) -master-bin.000001 994 Query 1 1085 use `test`; insert into t1 values( 392 ) -master-bin.000001 1085 Query 1 1176 use `test`; insert into t1 values( 391 ) -master-bin.000001 1176 Query 1 1267 use `test`; insert into t1 values( 390 ) -master-bin.000001 1267 Query 1 1358 use `test`; insert into t1 values( 389 ) -master-bin.000001 1358 Query 1 1449 use `test`; insert into t1 values( 388 ) -master-bin.000001 1449 Query 1 1540 use `test`; insert into t1 values( 387 ) -master-bin.000001 1540 Query 1 1631 use `test`; insert into t1 values( 386 ) -master-bin.000001 1631 Query 1 1722 use `test`; insert into t1 values( 385 ) -master-bin.000001 1722 Query 1 1813 use `test`; insert into t1 values( 384 ) -master-bin.000001 1813 Query 1 1904 use `test`; insert into t1 values( 383 ) -master-bin.000001 1904 Query 1 1995 use `test`; insert into t1 values( 382 ) -master-bin.000001 1995 Query 1 2086 use `test`; insert into t1 values( 381 ) -master-bin.000001 2086 Query 1 2177 use `test`; insert into t1 values( 380 ) -master-bin.000001 2177 Query 1 2268 use `test`; insert into t1 values( 379 ) -master-bin.000001 2268 Query 1 2359 use `test`; insert into t1 values( 378 ) -master-bin.000001 2359 Query 1 2450 use `test`; insert into t1 values( 377 ) -master-bin.000001 2450 Query 1 2541 use `test`; insert into t1 values( 376 ) -master-bin.000001 2541 Query 1 2632 use `test`; insert into t1 values( 375 ) -master-bin.000001 2632 Query 1 2723 use `test`; insert into t1 values( 374 ) -master-bin.000001 2723 Query 1 2814 use `test`; insert into t1 values( 373 ) -master-bin.000001 2814 Query 1 2905 use `test`; insert into t1 values( 372 ) -master-bin.000001 2905 Query 1 2996 use `test`; insert into t1 values( 371 ) -master-bin.000001 2996 Query 1 3087 use `test`; insert into t1 values( 370 ) -master-bin.000001 3087 Query 1 3178 use `test`; insert into t1 values( 369 ) -master-bin.000001 3178 Query 1 3269 use `test`; insert into t1 values( 368 ) -master-bin.000001 3269 Query 1 3360 use `test`; insert into t1 values( 367 ) -master-bin.000001 3360 Query 1 3451 use `test`; insert into t1 values( 366 ) -master-bin.000001 3451 Query 1 3542 use `test`; insert into t1 values( 365 ) -master-bin.000001 3542 Query 1 3633 use `test`; insert into t1 values( 364 ) -master-bin.000001 3633 Query 1 3724 use `test`; insert into t1 values( 363 ) -master-bin.000001 3724 Query 1 3815 use `test`; insert into t1 values( 362 ) -master-bin.000001 3815 Query 1 3906 use `test`; insert into t1 values( 361 ) -master-bin.000001 3906 Query 1 3997 use `test`; insert into t1 values( 360 ) -master-bin.000001 3997 Query 1 4088 use `test`; insert into t1 values( 359 ) -master-bin.000001 4088 Query 1 4179 use `test`; insert into t1 values( 358 ) -master-bin.000001 4179 Query 1 4270 use `test`; insert into t1 values( 357 ) -master-bin.000001 4270 Query 1 4361 use `test`; insert into t1 values( 356 ) -master-bin.000001 4361 Query 1 4452 use `test`; insert into t1 values( 355 ) -master-bin.000001 4452 Query 1 4543 use `test`; insert into t1 values( 354 ) -master-bin.000001 4543 Query 1 4634 use `test`; insert into t1 values( 353 ) -master-bin.000001 4634 Query 1 4725 use `test`; insert into t1 values( 352 ) -master-bin.000001 4725 Query 1 4816 use `test`; insert into t1 values( 351 ) -master-bin.000001 4816 Query 1 4907 use `test`; insert into t1 values( 350 ) -master-bin.000001 4907 Query 1 4998 use `test`; insert into t1 values( 349 ) -master-bin.000001 4998 Query 1 5089 use `test`; insert into t1 values( 348 ) -master-bin.000001 5089 Query 1 5180 use `test`; insert into t1 values( 347 ) -master-bin.000001 5180 Query 1 5271 use `test`; insert into t1 values( 346 ) -master-bin.000001 5271 Query 1 5362 use `test`; insert into t1 values( 345 ) -master-bin.000001 5362 Query 1 5453 use `test`; insert into t1 values( 344 ) -master-bin.000001 5453 Query 1 5544 use `test`; insert into t1 values( 343 ) -master-bin.000001 5544 Query 1 5635 use `test`; insert into t1 values( 342 ) -master-bin.000001 5635 Query 1 5726 use `test`; insert into t1 values( 341 ) -master-bin.000001 5726 Query 1 5817 use `test`; insert into t1 values( 340 ) -master-bin.000001 5817 Query 1 5908 use `test`; insert into t1 values( 339 ) -master-bin.000001 5908 Query 1 5999 use `test`; insert into t1 values( 338 ) -master-bin.000001 5999 Query 1 6090 use `test`; insert into t1 values( 337 ) -master-bin.000001 6090 Query 1 6181 use `test`; insert into t1 values( 336 ) -master-bin.000001 6181 Query 1 6272 use `test`; insert into t1 values( 335 ) -master-bin.000001 6272 Query 1 6363 use `test`; insert into t1 values( 334 ) -master-bin.000001 6363 Query 1 6454 use `test`; insert into t1 values( 333 ) -master-bin.000001 6454 Query 1 6545 use `test`; insert into t1 values( 332 ) -master-bin.000001 6545 Query 1 6636 use `test`; insert into t1 values( 331 ) -master-bin.000001 6636 Query 1 6727 use `test`; insert into t1 values( 330 ) -master-bin.000001 6727 Query 1 6818 use `test`; insert into t1 values( 329 ) -master-bin.000001 6818 Query 1 6909 use `test`; insert into t1 values( 328 ) -master-bin.000001 6909 Query 1 7000 use `test`; insert into t1 values( 327 ) -master-bin.000001 7000 Query 1 7091 use `test`; insert into t1 values( 326 ) -master-bin.000001 7091 Query 1 7182 use `test`; insert into t1 values( 325 ) -master-bin.000001 7182 Query 1 7273 use `test`; insert into t1 values( 324 ) -master-bin.000001 7273 Query 1 7364 use `test`; insert into t1 values( 323 ) -master-bin.000001 7364 Query 1 7455 use `test`; insert into t1 values( 322 ) -master-bin.000001 7455 Query 1 7546 use `test`; insert into t1 values( 321 ) -master-bin.000001 7546 Query 1 7637 use `test`; insert into t1 values( 320 ) -master-bin.000001 7637 Query 1 7728 use `test`; insert into t1 values( 319 ) -master-bin.000001 7728 Query 1 7819 use `test`; insert into t1 values( 318 ) -master-bin.000001 7819 Query 1 7910 use `test`; insert into t1 values( 317 ) -master-bin.000001 7910 Query 1 8001 use `test`; insert into t1 values( 316 ) -master-bin.000001 8001 Query 1 8092 use `test`; insert into t1 values( 315 ) -master-bin.000001 8092 Query 1 8183 use `test`; insert into t1 values( 314 ) -master-bin.000001 8183 Query 1 8274 use `test`; insert into t1 values( 313 ) -master-bin.000001 8274 Query 1 8365 use `test`; insert into t1 values( 312 ) -master-bin.000001 8365 Query 1 8456 use `test`; insert into t1 values( 311 ) -master-bin.000001 8456 Query 1 8547 use `test`; insert into t1 values( 310 ) -master-bin.000001 8547 Query 1 8638 use `test`; insert into t1 values( 309 ) -master-bin.000001 8638 Query 1 8729 use `test`; insert into t1 values( 308 ) -master-bin.000001 8729 Query 1 8820 use `test`; insert into t1 values( 307 ) -master-bin.000001 8820 Query 1 8911 use `test`; insert into t1 values( 306 ) -master-bin.000001 8911 Query 1 9002 use `test`; insert into t1 values( 305 ) -master-bin.000001 9002 Query 1 9093 use `test`; insert into t1 values( 304 ) -master-bin.000001 9093 Query 1 9184 use `test`; insert into t1 values( 303 ) -master-bin.000001 9184 Query 1 9275 use `test`; insert into t1 values( 302 ) -master-bin.000001 9275 Query 1 9366 use `test`; insert into t1 values( 301 ) -master-bin.000001 9366 Query 1 9457 use `test`; insert into t1 values( 300 ) -master-bin.000001 9457 Query 1 9548 use `test`; insert into t1 values( 299 ) -master-bin.000001 9548 Query 1 9639 use `test`; insert into t1 values( 298 ) -master-bin.000001 9639 Query 1 9730 use `test`; insert into t1 values( 297 ) -master-bin.000001 9730 Query 1 9821 use `test`; insert into t1 values( 296 ) -master-bin.000001 9821 Query 1 9912 use `test`; insert into t1 values( 295 ) -master-bin.000001 9912 Query 1 10003 use `test`; insert into t1 values( 294 ) -master-bin.000001 10003 Query 1 10094 use `test`; insert into t1 values( 293 ) -master-bin.000001 10094 Query 1 10185 use `test`; insert into t1 values( 292 ) -master-bin.000001 10185 Query 1 10276 use `test`; insert into t1 values( 291 ) -master-bin.000001 10276 Query 1 10367 use `test`; insert into t1 values( 290 ) -master-bin.000001 10367 Query 1 10458 use `test`; insert into t1 values( 289 ) -master-bin.000001 10458 Query 1 10549 use `test`; insert into t1 values( 288 ) -master-bin.000001 10549 Query 1 10640 use `test`; insert into t1 values( 287 ) -master-bin.000001 10640 Query 1 10731 use `test`; insert into t1 values( 286 ) -master-bin.000001 10731 Query 1 10822 use `test`; insert into t1 values( 285 ) -master-bin.000001 10822 Query 1 10913 use `test`; insert into t1 values( 284 ) -master-bin.000001 10913 Query 1 11004 use `test`; insert into t1 values( 283 ) -master-bin.000001 11004 Query 1 11095 use `test`; insert into t1 values( 282 ) -master-bin.000001 11095 Query 1 11186 use `test`; insert into t1 values( 281 ) -master-bin.000001 11186 Query 1 11277 use `test`; insert into t1 values( 280 ) -master-bin.000001 11277 Query 1 11368 use `test`; insert into t1 values( 279 ) -master-bin.000001 11368 Query 1 11459 use `test`; insert into t1 values( 278 ) -master-bin.000001 11459 Query 1 11550 use `test`; insert into t1 values( 277 ) -master-bin.000001 11550 Query 1 11641 use `test`; insert into t1 values( 276 ) -master-bin.000001 11641 Query 1 11732 use `test`; insert into t1 values( 275 ) -master-bin.000001 11732 Query 1 11823 use `test`; insert into t1 values( 274 ) -master-bin.000001 11823 Query 1 11914 use `test`; insert into t1 values( 273 ) -master-bin.000001 11914 Query 1 12005 use `test`; insert into t1 values( 272 ) -master-bin.000001 12005 Query 1 12096 use `test`; insert into t1 values( 271 ) -master-bin.000001 12096 Query 1 12187 use `test`; insert into t1 values( 270 ) -master-bin.000001 12187 Query 1 12278 use `test`; insert into t1 values( 269 ) -master-bin.000001 12278 Query 1 12369 use `test`; insert into t1 values( 268 ) -master-bin.000001 12369 Query 1 12460 use `test`; insert into t1 values( 267 ) -master-bin.000001 12460 Query 1 12551 use `test`; insert into t1 values( 266 ) -master-bin.000001 12551 Query 1 12642 use `test`; insert into t1 values( 265 ) -master-bin.000001 12642 Query 1 12733 use `test`; insert into t1 values( 264 ) -master-bin.000001 12733 Query 1 12824 use `test`; insert into t1 values( 263 ) -master-bin.000001 12824 Query 1 12915 use `test`; insert into t1 values( 262 ) -master-bin.000001 12915 Query 1 13006 use `test`; insert into t1 values( 261 ) -master-bin.000001 13006 Query 1 13097 use `test`; insert into t1 values( 260 ) -master-bin.000001 13097 Query 1 13188 use `test`; insert into t1 values( 259 ) -master-bin.000001 13188 Query 1 13279 use `test`; insert into t1 values( 258 ) -master-bin.000001 13279 Query 1 13370 use `test`; insert into t1 values( 257 ) -master-bin.000001 13370 Query 1 13461 use `test`; insert into t1 values( 256 ) -master-bin.000001 13461 Query 1 13552 use `test`; insert into t1 values( 255 ) -master-bin.000001 13552 Query 1 13643 use `test`; insert into t1 values( 254 ) -master-bin.000001 13643 Query 1 13734 use `test`; insert into t1 values( 253 ) -master-bin.000001 13734 Query 1 13825 use `test`; insert into t1 values( 252 ) -master-bin.000001 13825 Query 1 13916 use `test`; insert into t1 values( 251 ) -master-bin.000001 13916 Query 1 14007 use `test`; insert into t1 values( 250 ) -master-bin.000001 14007 Query 1 14098 use `test`; insert into t1 values( 249 ) -master-bin.000001 14098 Query 1 14189 use `test`; insert into t1 values( 248 ) -master-bin.000001 14189 Query 1 14280 use `test`; insert into t1 values( 247 ) -master-bin.000001 14280 Query 1 14371 use `test`; insert into t1 values( 246 ) -master-bin.000001 14371 Query 1 14462 use `test`; insert into t1 values( 245 ) -master-bin.000001 14462 Query 1 14553 use `test`; insert into t1 values( 244 ) -master-bin.000001 14553 Query 1 14644 use `test`; insert into t1 values( 243 ) -master-bin.000001 14644 Query 1 14735 use `test`; insert into t1 values( 242 ) -master-bin.000001 14735 Query 1 14826 use `test`; insert into t1 values( 241 ) -master-bin.000001 14826 Query 1 14917 use `test`; insert into t1 values( 240 ) -master-bin.000001 14917 Query 1 15008 use `test`; insert into t1 values( 239 ) -master-bin.000001 15008 Query 1 15099 use `test`; insert into t1 values( 238 ) -master-bin.000001 15099 Query 1 15190 use `test`; insert into t1 values( 237 ) -master-bin.000001 15190 Query 1 15281 use `test`; insert into t1 values( 236 ) -master-bin.000001 15281 Query 1 15372 use `test`; insert into t1 values( 235 ) -master-bin.000001 15372 Query 1 15463 use `test`; insert into t1 values( 234 ) -master-bin.000001 15463 Query 1 15554 use `test`; insert into t1 values( 233 ) -master-bin.000001 15554 Query 1 15645 use `test`; insert into t1 values( 232 ) -master-bin.000001 15645 Query 1 15736 use `test`; insert into t1 values( 231 ) -master-bin.000001 15736 Query 1 15827 use `test`; insert into t1 values( 230 ) -master-bin.000001 15827 Query 1 15918 use `test`; insert into t1 values( 229 ) -master-bin.000001 15918 Query 1 16009 use `test`; insert into t1 values( 228 ) -master-bin.000001 16009 Query 1 16100 use `test`; insert into t1 values( 227 ) -master-bin.000001 16100 Query 1 16191 use `test`; insert into t1 values( 226 ) -master-bin.000001 16191 Query 1 16282 use `test`; insert into t1 values( 225 ) -master-bin.000001 16282 Query 1 16373 use `test`; insert into t1 values( 224 ) -master-bin.000001 16373 Query 1 16464 use `test`; insert into t1 values( 223 ) -master-bin.000001 16464 Query 1 16555 use `test`; insert into t1 values( 222 ) -master-bin.000001 16555 Query 1 16646 use `test`; insert into t1 values( 221 ) -master-bin.000001 16646 Query 1 16737 use `test`; insert into t1 values( 220 ) -master-bin.000001 16737 Query 1 16828 use `test`; insert into t1 values( 219 ) -master-bin.000001 16828 Query 1 16919 use `test`; insert into t1 values( 218 ) -master-bin.000001 16919 Query 1 17010 use `test`; insert into t1 values( 217 ) -master-bin.000001 17010 Query 1 17101 use `test`; insert into t1 values( 216 ) -master-bin.000001 17101 Query 1 17192 use `test`; insert into t1 values( 215 ) -master-bin.000001 17192 Query 1 17283 use `test`; insert into t1 values( 214 ) -master-bin.000001 17283 Query 1 17374 use `test`; insert into t1 values( 213 ) -master-bin.000001 17374 Query 1 17465 use `test`; insert into t1 values( 212 ) -master-bin.000001 17465 Query 1 17556 use `test`; insert into t1 values( 211 ) -master-bin.000001 17556 Query 1 17647 use `test`; insert into t1 values( 210 ) -master-bin.000001 17647 Query 1 17738 use `test`; insert into t1 values( 209 ) -master-bin.000001 17738 Query 1 17829 use `test`; insert into t1 values( 208 ) -master-bin.000001 17829 Query 1 17920 use `test`; insert into t1 values( 207 ) -master-bin.000001 17920 Query 1 18011 use `test`; insert into t1 values( 206 ) -master-bin.000001 18011 Query 1 18102 use `test`; insert into t1 values( 205 ) -master-bin.000001 18102 Query 1 18193 use `test`; insert into t1 values( 204 ) -master-bin.000001 18193 Query 1 18284 use `test`; insert into t1 values( 203 ) -master-bin.000001 18284 Query 1 18375 use `test`; insert into t1 values( 202 ) -master-bin.000001 18375 Query 1 18466 use `test`; insert into t1 values( 201 ) -master-bin.000001 18466 Query 1 18557 use `test`; insert into t1 values( 200 ) -master-bin.000001 18557 Query 1 18648 use `test`; insert into t1 values( 199 ) -master-bin.000001 18648 Query 1 18739 use `test`; insert into t1 values( 198 ) -master-bin.000001 18739 Query 1 18830 use `test`; insert into t1 values( 197 ) -master-bin.000001 18830 Query 1 18921 use `test`; insert into t1 values( 196 ) -master-bin.000001 18921 Query 1 19012 use `test`; insert into t1 values( 195 ) -master-bin.000001 19012 Query 1 19103 use `test`; insert into t1 values( 194 ) -master-bin.000001 19103 Query 1 19194 use `test`; insert into t1 values( 193 ) -master-bin.000001 19194 Query 1 19285 use `test`; insert into t1 values( 192 ) -master-bin.000001 19285 Query 1 19376 use `test`; insert into t1 values( 191 ) -master-bin.000001 19376 Query 1 19467 use `test`; insert into t1 values( 190 ) -master-bin.000001 19467 Query 1 19558 use `test`; insert into t1 values( 189 ) -master-bin.000001 19558 Query 1 19649 use `test`; insert into t1 values( 188 ) -master-bin.000001 19649 Query 1 19740 use `test`; insert into t1 values( 187 ) -master-bin.000001 19740 Query 1 19831 use `test`; insert into t1 values( 186 ) -master-bin.000001 19831 Query 1 19922 use `test`; insert into t1 values( 185 ) -master-bin.000001 19922 Query 1 20013 use `test`; insert into t1 values( 184 ) -master-bin.000001 20013 Query 1 20104 use `test`; insert into t1 values( 183 ) -master-bin.000001 20104 Query 1 20195 use `test`; insert into t1 values( 182 ) -master-bin.000001 20195 Query 1 20286 use `test`; insert into t1 values( 181 ) -master-bin.000001 20286 Query 1 20377 use `test`; insert into t1 values( 180 ) -master-bin.000001 20377 Query 1 20468 use `test`; insert into t1 values( 179 ) -master-bin.000001 20468 Query 1 20559 use `test`; insert into t1 values( 178 ) -master-bin.000001 20559 Query 1 20650 use `test`; insert into t1 values( 177 ) -master-bin.000001 20650 Query 1 20741 use `test`; insert into t1 values( 176 ) -master-bin.000001 20741 Query 1 20832 use `test`; insert into t1 values( 175 ) -master-bin.000001 20832 Query 1 20923 use `test`; insert into t1 values( 174 ) -master-bin.000001 20923 Query 1 21014 use `test`; insert into t1 values( 173 ) -master-bin.000001 21014 Query 1 21105 use `test`; insert into t1 values( 172 ) -master-bin.000001 21105 Query 1 21196 use `test`; insert into t1 values( 171 ) -master-bin.000001 21196 Query 1 21287 use `test`; insert into t1 values( 170 ) -master-bin.000001 21287 Query 1 21378 use `test`; insert into t1 values( 169 ) -master-bin.000001 21378 Query 1 21469 use `test`; insert into t1 values( 168 ) -master-bin.000001 21469 Query 1 21560 use `test`; insert into t1 values( 167 ) -master-bin.000001 21560 Query 1 21651 use `test`; insert into t1 values( 166 ) -master-bin.000001 21651 Query 1 21742 use `test`; insert into t1 values( 165 ) -master-bin.000001 21742 Query 1 21833 use `test`; insert into t1 values( 164 ) -master-bin.000001 21833 Query 1 21924 use `test`; insert into t1 values( 163 ) -master-bin.000001 21924 Query 1 22015 use `test`; insert into t1 values( 162 ) -master-bin.000001 22015 Query 1 22106 use `test`; insert into t1 values( 161 ) -master-bin.000001 22106 Query 1 22197 use `test`; insert into t1 values( 160 ) -master-bin.000001 22197 Query 1 22288 use `test`; insert into t1 values( 159 ) -master-bin.000001 22288 Query 1 22379 use `test`; insert into t1 values( 158 ) -master-bin.000001 22379 Query 1 22470 use `test`; insert into t1 values( 157 ) -master-bin.000001 22470 Query 1 22561 use `test`; insert into t1 values( 156 ) -master-bin.000001 22561 Query 1 22652 use `test`; insert into t1 values( 155 ) -master-bin.000001 22652 Query 1 22743 use `test`; insert into t1 values( 154 ) -master-bin.000001 22743 Query 1 22834 use `test`; insert into t1 values( 153 ) -master-bin.000001 22834 Query 1 22925 use `test`; insert into t1 values( 152 ) -master-bin.000001 22925 Query 1 23016 use `test`; insert into t1 values( 151 ) -master-bin.000001 23016 Query 1 23107 use `test`; insert into t1 values( 150 ) -master-bin.000001 23107 Query 1 23198 use `test`; insert into t1 values( 149 ) -master-bin.000001 23198 Query 1 23289 use `test`; insert into t1 values( 148 ) -master-bin.000001 23289 Query 1 23380 use `test`; insert into t1 values( 147 ) -master-bin.000001 23380 Query 1 23471 use `test`; insert into t1 values( 146 ) -master-bin.000001 23471 Query 1 23562 use `test`; insert into t1 values( 145 ) -master-bin.000001 23562 Query 1 23653 use `test`; insert into t1 values( 144 ) -master-bin.000001 23653 Query 1 23744 use `test`; insert into t1 values( 143 ) -master-bin.000001 23744 Query 1 23835 use `test`; insert into t1 values( 142 ) -master-bin.000001 23835 Query 1 23926 use `test`; insert into t1 values( 141 ) -master-bin.000001 23926 Query 1 24017 use `test`; insert into t1 values( 140 ) -master-bin.000001 24017 Query 1 24108 use `test`; insert into t1 values( 139 ) -master-bin.000001 24108 Query 1 24199 use `test`; insert into t1 values( 138 ) -master-bin.000001 24199 Query 1 24290 use `test`; insert into t1 values( 137 ) -master-bin.000001 24290 Query 1 24381 use `test`; insert into t1 values( 136 ) -master-bin.000001 24381 Query 1 24472 use `test`; insert into t1 values( 135 ) -master-bin.000001 24472 Query 1 24563 use `test`; insert into t1 values( 134 ) -master-bin.000001 24563 Query 1 24654 use `test`; insert into t1 values( 133 ) -master-bin.000001 24654 Query 1 24745 use `test`; insert into t1 values( 132 ) -master-bin.000001 24745 Query 1 24836 use `test`; insert into t1 values( 131 ) -master-bin.000001 24836 Query 1 24927 use `test`; insert into t1 values( 130 ) -master-bin.000001 24927 Query 1 25018 use `test`; insert into t1 values( 129 ) -master-bin.000001 25018 Query 1 25109 use `test`; insert into t1 values( 128 ) -master-bin.000001 25109 Query 1 25200 use `test`; insert into t1 values( 127 ) -master-bin.000001 25200 Query 1 25291 use `test`; insert into t1 values( 126 ) -master-bin.000001 25291 Query 1 25382 use `test`; insert into t1 values( 125 ) -master-bin.000001 25382 Query 1 25473 use `test`; insert into t1 values( 124 ) -master-bin.000001 25473 Query 1 25564 use `test`; insert into t1 values( 123 ) -master-bin.000001 25564 Query 1 25655 use `test`; insert into t1 values( 122 ) -master-bin.000001 25655 Query 1 25746 use `test`; insert into t1 values( 121 ) -master-bin.000001 25746 Query 1 25837 use `test`; insert into t1 values( 120 ) -master-bin.000001 25837 Query 1 25928 use `test`; insert into t1 values( 119 ) -master-bin.000001 25928 Query 1 26019 use `test`; insert into t1 values( 118 ) -master-bin.000001 26019 Query 1 26110 use `test`; insert into t1 values( 117 ) -master-bin.000001 26110 Query 1 26201 use `test`; insert into t1 values( 116 ) -master-bin.000001 26201 Query 1 26292 use `test`; insert into t1 values( 115 ) -master-bin.000001 26292 Query 1 26383 use `test`; insert into t1 values( 114 ) -master-bin.000001 26383 Query 1 26474 use `test`; insert into t1 values( 113 ) -master-bin.000001 26474 Query 1 26565 use `test`; insert into t1 values( 112 ) -master-bin.000001 26565 Query 1 26656 use `test`; insert into t1 values( 111 ) -master-bin.000001 26656 Query 1 26747 use `test`; insert into t1 values( 110 ) -master-bin.000001 26747 Query 1 26838 use `test`; insert into t1 values( 109 ) -master-bin.000001 26838 Query 1 26929 use `test`; insert into t1 values( 108 ) -master-bin.000001 26929 Query 1 27020 use `test`; insert into t1 values( 107 ) -master-bin.000001 27020 Query 1 27111 use `test`; insert into t1 values( 106 ) -master-bin.000001 27111 Query 1 27202 use `test`; insert into t1 values( 105 ) -master-bin.000001 27202 Query 1 27293 use `test`; insert into t1 values( 104 ) -master-bin.000001 27293 Query 1 27384 use `test`; insert into t1 values( 103 ) -master-bin.000001 27384 Query 1 27475 use `test`; insert into t1 values( 102 ) -master-bin.000001 27475 Query 1 27566 use `test`; insert into t1 values( 101 ) -master-bin.000001 27566 Query 1 27657 use `test`; insert into t1 values( 100 ) -master-bin.000001 27657 Query 1 27747 use `test`; insert into t1 values( 99 ) -master-bin.000001 27747 Query 1 27837 use `test`; insert into t1 values( 98 ) -master-bin.000001 27837 Query 1 27927 use `test`; insert into t1 values( 97 ) -master-bin.000001 27927 Query 1 28017 use `test`; insert into t1 values( 96 ) -master-bin.000001 28017 Query 1 28107 use `test`; insert into t1 values( 95 ) -master-bin.000001 28107 Query 1 28197 use `test`; insert into t1 values( 94 ) -master-bin.000001 28197 Query 1 28287 use `test`; insert into t1 values( 93 ) -master-bin.000001 28287 Query 1 28377 use `test`; insert into t1 values( 92 ) -master-bin.000001 28377 Query 1 28467 use `test`; insert into t1 values( 91 ) -master-bin.000001 28467 Query 1 28557 use `test`; insert into t1 values( 90 ) -master-bin.000001 28557 Query 1 28647 use `test`; insert into t1 values( 89 ) -master-bin.000001 28647 Query 1 28737 use `test`; insert into t1 values( 88 ) -master-bin.000001 28737 Query 1 28827 use `test`; insert into t1 values( 87 ) -master-bin.000001 28827 Query 1 28917 use `test`; insert into t1 values( 86 ) -master-bin.000001 28917 Query 1 29007 use `test`; insert into t1 values( 85 ) -master-bin.000001 29007 Query 1 29097 use `test`; insert into t1 values( 84 ) -master-bin.000001 29097 Query 1 29187 use `test`; insert into t1 values( 83 ) -master-bin.000001 29187 Query 1 29277 use `test`; insert into t1 values( 82 ) -master-bin.000001 29277 Query 1 29367 use `test`; insert into t1 values( 81 ) -master-bin.000001 29367 Query 1 29457 use `test`; insert into t1 values( 80 ) -master-bin.000001 29457 Query 1 29547 use `test`; insert into t1 values( 79 ) -master-bin.000001 29547 Query 1 29637 use `test`; insert into t1 values( 78 ) -master-bin.000001 29637 Query 1 29727 use `test`; insert into t1 values( 77 ) -master-bin.000001 29727 Query 1 29817 use `test`; insert into t1 values( 76 ) -master-bin.000001 29817 Query 1 29907 use `test`; insert into t1 values( 75 ) -master-bin.000001 29907 Query 1 29997 use `test`; insert into t1 values( 74 ) -master-bin.000001 29997 Query 1 30087 use `test`; insert into t1 values( 73 ) -master-bin.000001 30087 Query 1 30177 use `test`; insert into t1 values( 72 ) -master-bin.000001 30177 Query 1 30267 use `test`; insert into t1 values( 71 ) -master-bin.000001 30267 Query 1 30357 use `test`; insert into t1 values( 70 ) -master-bin.000001 30357 Query 1 30447 use `test`; insert into t1 values( 69 ) -master-bin.000001 30447 Query 1 30537 use `test`; insert into t1 values( 68 ) -master-bin.000001 30537 Query 1 30627 use `test`; insert into t1 values( 67 ) -master-bin.000001 30627 Query 1 30717 use `test`; insert into t1 values( 66 ) -master-bin.000001 30717 Query 1 30807 use `test`; insert into t1 values( 65 ) -master-bin.000001 30807 Query 1 30897 use `test`; insert into t1 values( 64 ) -master-bin.000001 30897 Query 1 30987 use `test`; insert into t1 values( 63 ) -master-bin.000001 30987 Query 1 31077 use `test`; insert into t1 values( 62 ) -master-bin.000001 31077 Query 1 31167 use `test`; insert into t1 values( 61 ) -master-bin.000001 31167 Query 1 31257 use `test`; insert into t1 values( 60 ) -master-bin.000001 31257 Query 1 31347 use `test`; insert into t1 values( 59 ) -master-bin.000001 31347 Query 1 31437 use `test`; insert into t1 values( 58 ) -master-bin.000001 31437 Query 1 31527 use `test`; insert into t1 values( 57 ) -master-bin.000001 31527 Query 1 31617 use `test`; insert into t1 values( 56 ) -master-bin.000001 31617 Query 1 31707 use `test`; insert into t1 values( 55 ) -master-bin.000001 31707 Query 1 31797 use `test`; insert into t1 values( 54 ) -master-bin.000001 31797 Query 1 31887 use `test`; insert into t1 values( 53 ) -master-bin.000001 31887 Query 1 31977 use `test`; insert into t1 values( 52 ) -master-bin.000001 31977 Query 1 32067 use `test`; insert into t1 values( 51 ) -master-bin.000001 32067 Query 1 32157 use `test`; insert into t1 values( 50 ) -master-bin.000001 32157 Query 1 32247 use `test`; insert into t1 values( 49 ) -master-bin.000001 32247 Query 1 32337 use `test`; insert into t1 values( 48 ) -master-bin.000001 32337 Query 1 32427 use `test`; insert into t1 values( 47 ) -master-bin.000001 32427 Query 1 32517 use `test`; insert into t1 values( 46 ) -master-bin.000001 32517 Query 1 32607 use `test`; insert into t1 values( 45 ) -master-bin.000001 32607 Query 1 32697 use `test`; insert into t1 values( 44 ) -master-bin.000001 32697 Query 1 32787 use `test`; insert into t1 values( 43 ) -master-bin.000001 32787 Query 1 32877 use `test`; insert into t1 values( 42 ) -master-bin.000001 32877 Query 1 32967 use `test`; insert into t1 values( 41 ) -master-bin.000001 32967 Query 1 33057 use `test`; insert into t1 values( 40 ) -master-bin.000001 33057 Query 1 33147 use `test`; insert into t1 values( 39 ) -master-bin.000001 33147 Query 1 33237 use `test`; insert into t1 values( 38 ) -master-bin.000001 33237 Query 1 33327 use `test`; insert into t1 values( 37 ) -master-bin.000001 33327 Query 1 33417 use `test`; insert into t1 values( 36 ) -master-bin.000001 33417 Query 1 33507 use `test`; insert into t1 values( 35 ) -master-bin.000001 33507 Query 1 33597 use `test`; insert into t1 values( 34 ) -master-bin.000001 33597 Query 1 33687 use `test`; insert into t1 values( 33 ) -master-bin.000001 33687 Query 1 33777 use `test`; insert into t1 values( 32 ) -master-bin.000001 33777 Query 1 33867 use `test`; insert into t1 values( 31 ) -master-bin.000001 33867 Query 1 33957 use `test`; insert into t1 values( 30 ) -master-bin.000001 33957 Query 1 34047 use `test`; insert into t1 values( 29 ) -master-bin.000001 34047 Query 1 34137 use `test`; insert into t1 values( 28 ) -master-bin.000001 34137 Query 1 34227 use `test`; insert into t1 values( 27 ) -master-bin.000001 34227 Query 1 34317 use `test`; insert into t1 values( 26 ) -master-bin.000001 34317 Query 1 34407 use `test`; insert into t1 values( 25 ) -master-bin.000001 34407 Query 1 34497 use `test`; insert into t1 values( 24 ) -master-bin.000001 34497 Query 1 34587 use `test`; insert into t1 values( 23 ) -master-bin.000001 34587 Query 1 34677 use `test`; insert into t1 values( 22 ) -master-bin.000001 34677 Query 1 34767 use `test`; insert into t1 values( 21 ) -master-bin.000001 34767 Query 1 34857 use `test`; insert into t1 values( 20 ) -master-bin.000001 34857 Query 1 34947 use `test`; insert into t1 values( 19 ) -master-bin.000001 34947 Query 1 35037 use `test`; insert into t1 values( 18 ) -master-bin.000001 35037 Query 1 35127 use `test`; insert into t1 values( 17 ) -master-bin.000001 35127 Query 1 35217 use `test`; insert into t1 values( 16 ) -master-bin.000001 35217 Query 1 35307 use `test`; insert into t1 values( 15 ) -master-bin.000001 35307 Query 1 35397 use `test`; insert into t1 values( 14 ) -master-bin.000001 35397 Query 1 35487 use `test`; insert into t1 values( 13 ) -master-bin.000001 35487 Query 1 35577 use `test`; insert into t1 values( 12 ) -master-bin.000001 35577 Query 1 35667 use `test`; insert into t1 values( 11 ) -master-bin.000001 35667 Query 1 35757 use `test`; insert into t1 values( 10 ) -master-bin.000001 35757 Query 1 35846 use `test`; insert into t1 values( 9 ) -master-bin.000001 35846 Query 1 35935 use `test`; insert into t1 values( 8 ) -master-bin.000001 35935 Query 1 36024 use `test`; insert into t1 values( 7 ) -master-bin.000001 36024 Query 1 36113 use `test`; insert into t1 values( 6 ) -master-bin.000001 36113 Query 1 36202 use `test`; insert into t1 values( 5 ) -master-bin.000001 36202 Query 1 36291 use `test`; insert into t1 values( 4 ) -master-bin.000001 36291 Query 1 36380 use `test`; insert into t1 values( 3 ) -master-bin.000001 36380 Query 1 36469 use `test`; insert into t1 values( 2 ) -master-bin.000001 36469 Query 1 36558 use `test`; insert into t1 values( 1 ) -master-bin.000001 36558 Xid 1 36585 COMMIT /* XID */ -master-bin.000001 36585 Rotate 1 36629 master-bin.000002;pos=4 +master-bin.000001 4 Format_desc 1 106 Server version, Binlog ver: 4 +master-bin.000001 106 Query 1 206 use `test`; create table t1 (a int) engine=innodb +master-bin.000001 206 Query 1 274 use `test`; BEGIN +master-bin.000001 274 Query 1 365 use `test`; insert into t1 values( 400 ) +master-bin.000001 365 Query 1 456 use `test`; insert into t1 values( 399 ) +master-bin.000001 456 Query 1 547 use `test`; insert into t1 values( 398 ) +master-bin.000001 547 Query 1 638 use `test`; insert into t1 values( 397 ) +master-bin.000001 638 Query 1 729 use `test`; insert into t1 values( 396 ) +master-bin.000001 729 Query 1 820 use `test`; insert into t1 values( 395 ) +master-bin.000001 820 Query 1 911 use `test`; insert into t1 values( 394 ) +master-bin.000001 911 Query 1 1002 use `test`; insert into t1 values( 393 ) +master-bin.000001 1002 Query 1 1093 use `test`; insert into t1 values( 392 ) +master-bin.000001 1093 Query 1 1184 use `test`; insert into t1 values( 391 ) +master-bin.000001 1184 Query 1 1275 use `test`; insert into t1 values( 390 ) +master-bin.000001 1275 Query 1 1366 use `test`; insert into t1 values( 389 ) +master-bin.000001 1366 Query 1 1457 use `test`; insert into t1 values( 388 ) +master-bin.000001 1457 Query 1 1548 use `test`; insert into t1 values( 387 ) +master-bin.000001 1548 Query 1 1639 use `test`; insert into t1 values( 386 ) +master-bin.000001 1639 Query 1 1730 use `test`; insert into t1 values( 385 ) +master-bin.000001 1730 Query 1 1821 use `test`; insert into t1 values( 384 ) +master-bin.000001 1821 Query 1 1912 use `test`; insert into t1 values( 383 ) +master-bin.000001 1912 Query 1 2003 use `test`; insert into t1 values( 382 ) +master-bin.000001 2003 Query 1 2094 use `test`; insert into t1 values( 381 ) +master-bin.000001 2094 Query 1 2185 use `test`; insert into t1 values( 380 ) +master-bin.000001 2185 Query 1 2276 use `test`; insert into t1 values( 379 ) +master-bin.000001 2276 Query 1 2367 use `test`; insert into t1 values( 378 ) +master-bin.000001 2367 Query 1 2458 use `test`; insert into t1 values( 377 ) +master-bin.000001 2458 Query 1 2549 use `test`; insert into t1 values( 376 ) +master-bin.000001 2549 Query 1 2640 use `test`; insert into t1 values( 375 ) +master-bin.000001 2640 Query 1 2731 use `test`; insert into t1 values( 374 ) +master-bin.000001 2731 Query 1 2822 use `test`; insert into t1 values( 373 ) +master-bin.000001 2822 Query 1 2913 use `test`; insert into t1 values( 372 ) +master-bin.000001 2913 Query 1 3004 use `test`; insert into t1 values( 371 ) +master-bin.000001 3004 Query 1 3095 use `test`; insert into t1 values( 370 ) +master-bin.000001 3095 Query 1 3186 use `test`; insert into t1 values( 369 ) +master-bin.000001 3186 Query 1 3277 use `test`; insert into t1 values( 368 ) +master-bin.000001 3277 Query 1 3368 use `test`; insert into t1 values( 367 ) +master-bin.000001 3368 Query 1 3459 use `test`; insert into t1 values( 366 ) +master-bin.000001 3459 Query 1 3550 use `test`; insert into t1 values( 365 ) +master-bin.000001 3550 Query 1 3641 use `test`; insert into t1 values( 364 ) +master-bin.000001 3641 Query 1 3732 use `test`; insert into t1 values( 363 ) +master-bin.000001 3732 Query 1 3823 use `test`; insert into t1 values( 362 ) +master-bin.000001 3823 Query 1 3914 use `test`; insert into t1 values( 361 ) +master-bin.000001 3914 Query 1 4005 use `test`; insert into t1 values( 360 ) +master-bin.000001 4005 Query 1 4096 use `test`; insert into t1 values( 359 ) +master-bin.000001 4096 Query 1 4187 use `test`; insert into t1 values( 358 ) +master-bin.000001 4187 Query 1 4278 use `test`; insert into t1 values( 357 ) +master-bin.000001 4278 Query 1 4369 use `test`; insert into t1 values( 356 ) +master-bin.000001 4369 Query 1 4460 use `test`; insert into t1 values( 355 ) +master-bin.000001 4460 Query 1 4551 use `test`; insert into t1 values( 354 ) +master-bin.000001 4551 Query 1 4642 use `test`; insert into t1 values( 353 ) +master-bin.000001 4642 Query 1 4733 use `test`; insert into t1 values( 352 ) +master-bin.000001 4733 Query 1 4824 use `test`; insert into t1 values( 351 ) +master-bin.000001 4824 Query 1 4915 use `test`; insert into t1 values( 350 ) +master-bin.000001 4915 Query 1 5006 use `test`; insert into t1 values( 349 ) +master-bin.000001 5006 Query 1 5097 use `test`; insert into t1 values( 348 ) +master-bin.000001 5097 Query 1 5188 use `test`; insert into t1 values( 347 ) +master-bin.000001 5188 Query 1 5279 use `test`; insert into t1 values( 346 ) +master-bin.000001 5279 Query 1 5370 use `test`; insert into t1 values( 345 ) +master-bin.000001 5370 Query 1 5461 use `test`; insert into t1 values( 344 ) +master-bin.000001 5461 Query 1 5552 use `test`; insert into t1 values( 343 ) +master-bin.000001 5552 Query 1 5643 use `test`; insert into t1 values( 342 ) +master-bin.000001 5643 Query 1 5734 use `test`; insert into t1 values( 341 ) +master-bin.000001 5734 Query 1 5825 use `test`; insert into t1 values( 340 ) +master-bin.000001 5825 Query 1 5916 use `test`; insert into t1 values( 339 ) +master-bin.000001 5916 Query 1 6007 use `test`; insert into t1 values( 338 ) +master-bin.000001 6007 Query 1 6098 use `test`; insert into t1 values( 337 ) +master-bin.000001 6098 Query 1 6189 use `test`; insert into t1 values( 336 ) +master-bin.000001 6189 Query 1 6280 use `test`; insert into t1 values( 335 ) +master-bin.000001 6280 Query 1 6371 use `test`; insert into t1 values( 334 ) +master-bin.000001 6371 Query 1 6462 use `test`; insert into t1 values( 333 ) +master-bin.000001 6462 Query 1 6553 use `test`; insert into t1 values( 332 ) +master-bin.000001 6553 Query 1 6644 use `test`; insert into t1 values( 331 ) +master-bin.000001 6644 Query 1 6735 use `test`; insert into t1 values( 330 ) +master-bin.000001 6735 Query 1 6826 use `test`; insert into t1 values( 329 ) +master-bin.000001 6826 Query 1 6917 use `test`; insert into t1 values( 328 ) +master-bin.000001 6917 Query 1 7008 use `test`; insert into t1 values( 327 ) +master-bin.000001 7008 Query 1 7099 use `test`; insert into t1 values( 326 ) +master-bin.000001 7099 Query 1 7190 use `test`; insert into t1 values( 325 ) +master-bin.000001 7190 Query 1 7281 use `test`; insert into t1 values( 324 ) +master-bin.000001 7281 Query 1 7372 use `test`; insert into t1 values( 323 ) +master-bin.000001 7372 Query 1 7463 use `test`; insert into t1 values( 322 ) +master-bin.000001 7463 Query 1 7554 use `test`; insert into t1 values( 321 ) +master-bin.000001 7554 Query 1 7645 use `test`; insert into t1 values( 320 ) +master-bin.000001 7645 Query 1 7736 use `test`; insert into t1 values( 319 ) +master-bin.000001 7736 Query 1 7827 use `test`; insert into t1 values( 318 ) +master-bin.000001 7827 Query 1 7918 use `test`; insert into t1 values( 317 ) +master-bin.000001 7918 Query 1 8009 use `test`; insert into t1 values( 316 ) +master-bin.000001 8009 Query 1 8100 use `test`; insert into t1 values( 315 ) +master-bin.000001 8100 Query 1 8191 use `test`; insert into t1 values( 314 ) +master-bin.000001 8191 Query 1 8282 use `test`; insert into t1 values( 313 ) +master-bin.000001 8282 Query 1 8373 use `test`; insert into t1 values( 312 ) +master-bin.000001 8373 Query 1 8464 use `test`; insert into t1 values( 311 ) +master-bin.000001 8464 Query 1 8555 use `test`; insert into t1 values( 310 ) +master-bin.000001 8555 Query 1 8646 use `test`; insert into t1 values( 309 ) +master-bin.000001 8646 Query 1 8737 use `test`; insert into t1 values( 308 ) +master-bin.000001 8737 Query 1 8828 use `test`; insert into t1 values( 307 ) +master-bin.000001 8828 Query 1 8919 use `test`; insert into t1 values( 306 ) +master-bin.000001 8919 Query 1 9010 use `test`; insert into t1 values( 305 ) +master-bin.000001 9010 Query 1 9101 use `test`; insert into t1 values( 304 ) +master-bin.000001 9101 Query 1 9192 use `test`; insert into t1 values( 303 ) +master-bin.000001 9192 Query 1 9283 use `test`; insert into t1 values( 302 ) +master-bin.000001 9283 Query 1 9374 use `test`; insert into t1 values( 301 ) +master-bin.000001 9374 Query 1 9465 use `test`; insert into t1 values( 300 ) +master-bin.000001 9465 Query 1 9556 use `test`; insert into t1 values( 299 ) +master-bin.000001 9556 Query 1 9647 use `test`; insert into t1 values( 298 ) +master-bin.000001 9647 Query 1 9738 use `test`; insert into t1 values( 297 ) +master-bin.000001 9738 Query 1 9829 use `test`; insert into t1 values( 296 ) +master-bin.000001 9829 Query 1 9920 use `test`; insert into t1 values( 295 ) +master-bin.000001 9920 Query 1 10011 use `test`; insert into t1 values( 294 ) +master-bin.000001 10011 Query 1 10102 use `test`; insert into t1 values( 293 ) +master-bin.000001 10102 Query 1 10193 use `test`; insert into t1 values( 292 ) +master-bin.000001 10193 Query 1 10284 use `test`; insert into t1 values( 291 ) +master-bin.000001 10284 Query 1 10375 use `test`; insert into t1 values( 290 ) +master-bin.000001 10375 Query 1 10466 use `test`; insert into t1 values( 289 ) +master-bin.000001 10466 Query 1 10557 use `test`; insert into t1 values( 288 ) +master-bin.000001 10557 Query 1 10648 use `test`; insert into t1 values( 287 ) +master-bin.000001 10648 Query 1 10739 use `test`; insert into t1 values( 286 ) +master-bin.000001 10739 Query 1 10830 use `test`; insert into t1 values( 285 ) +master-bin.000001 10830 Query 1 10921 use `test`; insert into t1 values( 284 ) +master-bin.000001 10921 Query 1 11012 use `test`; insert into t1 values( 283 ) +master-bin.000001 11012 Query 1 11103 use `test`; insert into t1 values( 282 ) +master-bin.000001 11103 Query 1 11194 use `test`; insert into t1 values( 281 ) +master-bin.000001 11194 Query 1 11285 use `test`; insert into t1 values( 280 ) +master-bin.000001 11285 Query 1 11376 use `test`; insert into t1 values( 279 ) +master-bin.000001 11376 Query 1 11467 use `test`; insert into t1 values( 278 ) +master-bin.000001 11467 Query 1 11558 use `test`; insert into t1 values( 277 ) +master-bin.000001 11558 Query 1 11649 use `test`; insert into t1 values( 276 ) +master-bin.000001 11649 Query 1 11740 use `test`; insert into t1 values( 275 ) +master-bin.000001 11740 Query 1 11831 use `test`; insert into t1 values( 274 ) +master-bin.000001 11831 Query 1 11922 use `test`; insert into t1 values( 273 ) +master-bin.000001 11922 Query 1 12013 use `test`; insert into t1 values( 272 ) +master-bin.000001 12013 Query 1 12104 use `test`; insert into t1 values( 271 ) +master-bin.000001 12104 Query 1 12195 use `test`; insert into t1 values( 270 ) +master-bin.000001 12195 Query 1 12286 use `test`; insert into t1 values( 269 ) +master-bin.000001 12286 Query 1 12377 use `test`; insert into t1 values( 268 ) +master-bin.000001 12377 Query 1 12468 use `test`; insert into t1 values( 267 ) +master-bin.000001 12468 Query 1 12559 use `test`; insert into t1 values( 266 ) +master-bin.000001 12559 Query 1 12650 use `test`; insert into t1 values( 265 ) +master-bin.000001 12650 Query 1 12741 use `test`; insert into t1 values( 264 ) +master-bin.000001 12741 Query 1 12832 use `test`; insert into t1 values( 263 ) +master-bin.000001 12832 Query 1 12923 use `test`; insert into t1 values( 262 ) +master-bin.000001 12923 Query 1 13014 use `test`; insert into t1 values( 261 ) +master-bin.000001 13014 Query 1 13105 use `test`; insert into t1 values( 260 ) +master-bin.000001 13105 Query 1 13196 use `test`; insert into t1 values( 259 ) +master-bin.000001 13196 Query 1 13287 use `test`; insert into t1 values( 258 ) +master-bin.000001 13287 Query 1 13378 use `test`; insert into t1 values( 257 ) +master-bin.000001 13378 Query 1 13469 use `test`; insert into t1 values( 256 ) +master-bin.000001 13469 Query 1 13560 use `test`; insert into t1 values( 255 ) +master-bin.000001 13560 Query 1 13651 use `test`; insert into t1 values( 254 ) +master-bin.000001 13651 Query 1 13742 use `test`; insert into t1 values( 253 ) +master-bin.000001 13742 Query 1 13833 use `test`; insert into t1 values( 252 ) +master-bin.000001 13833 Query 1 13924 use `test`; insert into t1 values( 251 ) +master-bin.000001 13924 Query 1 14015 use `test`; insert into t1 values( 250 ) +master-bin.000001 14015 Query 1 14106 use `test`; insert into t1 values( 249 ) +master-bin.000001 14106 Query 1 14197 use `test`; insert into t1 values( 248 ) +master-bin.000001 14197 Query 1 14288 use `test`; insert into t1 values( 247 ) +master-bin.000001 14288 Query 1 14379 use `test`; insert into t1 values( 246 ) +master-bin.000001 14379 Query 1 14470 use `test`; insert into t1 values( 245 ) +master-bin.000001 14470 Query 1 14561 use `test`; insert into t1 values( 244 ) +master-bin.000001 14561 Query 1 14652 use `test`; insert into t1 values( 243 ) +master-bin.000001 14652 Query 1 14743 use `test`; insert into t1 values( 242 ) +master-bin.000001 14743 Query 1 14834 use `test`; insert into t1 values( 241 ) +master-bin.000001 14834 Query 1 14925 use `test`; insert into t1 values( 240 ) +master-bin.000001 14925 Query 1 15016 use `test`; insert into t1 values( 239 ) +master-bin.000001 15016 Query 1 15107 use `test`; insert into t1 values( 238 ) +master-bin.000001 15107 Query 1 15198 use `test`; insert into t1 values( 237 ) +master-bin.000001 15198 Query 1 15289 use `test`; insert into t1 values( 236 ) +master-bin.000001 15289 Query 1 15380 use `test`; insert into t1 values( 235 ) +master-bin.000001 15380 Query 1 15471 use `test`; insert into t1 values( 234 ) +master-bin.000001 15471 Query 1 15562 use `test`; insert into t1 values( 233 ) +master-bin.000001 15562 Query 1 15653 use `test`; insert into t1 values( 232 ) +master-bin.000001 15653 Query 1 15744 use `test`; insert into t1 values( 231 ) +master-bin.000001 15744 Query 1 15835 use `test`; insert into t1 values( 230 ) +master-bin.000001 15835 Query 1 15926 use `test`; insert into t1 values( 229 ) +master-bin.000001 15926 Query 1 16017 use `test`; insert into t1 values( 228 ) +master-bin.000001 16017 Query 1 16108 use `test`; insert into t1 values( 227 ) +master-bin.000001 16108 Query 1 16199 use `test`; insert into t1 values( 226 ) +master-bin.000001 16199 Query 1 16290 use `test`; insert into t1 values( 225 ) +master-bin.000001 16290 Query 1 16381 use `test`; insert into t1 values( 224 ) +master-bin.000001 16381 Query 1 16472 use `test`; insert into t1 values( 223 ) +master-bin.000001 16472 Query 1 16563 use `test`; insert into t1 values( 222 ) +master-bin.000001 16563 Query 1 16654 use `test`; insert into t1 values( 221 ) +master-bin.000001 16654 Query 1 16745 use `test`; insert into t1 values( 220 ) +master-bin.000001 16745 Query 1 16836 use `test`; insert into t1 values( 219 ) +master-bin.000001 16836 Query 1 16927 use `test`; insert into t1 values( 218 ) +master-bin.000001 16927 Query 1 17018 use `test`; insert into t1 values( 217 ) +master-bin.000001 17018 Query 1 17109 use `test`; insert into t1 values( 216 ) +master-bin.000001 17109 Query 1 17200 use `test`; insert into t1 values( 215 ) +master-bin.000001 17200 Query 1 17291 use `test`; insert into t1 values( 214 ) +master-bin.000001 17291 Query 1 17382 use `test`; insert into t1 values( 213 ) +master-bin.000001 17382 Query 1 17473 use `test`; insert into t1 values( 212 ) +master-bin.000001 17473 Query 1 17564 use `test`; insert into t1 values( 211 ) +master-bin.000001 17564 Query 1 17655 use `test`; insert into t1 values( 210 ) +master-bin.000001 17655 Query 1 17746 use `test`; insert into t1 values( 209 ) +master-bin.000001 17746 Query 1 17837 use `test`; insert into t1 values( 208 ) +master-bin.000001 17837 Query 1 17928 use `test`; insert into t1 values( 207 ) +master-bin.000001 17928 Query 1 18019 use `test`; insert into t1 values( 206 ) +master-bin.000001 18019 Query 1 18110 use `test`; insert into t1 values( 205 ) +master-bin.000001 18110 Query 1 18201 use `test`; insert into t1 values( 204 ) +master-bin.000001 18201 Query 1 18292 use `test`; insert into t1 values( 203 ) +master-bin.000001 18292 Query 1 18383 use `test`; insert into t1 values( 202 ) +master-bin.000001 18383 Query 1 18474 use `test`; insert into t1 values( 201 ) +master-bin.000001 18474 Query 1 18565 use `test`; insert into t1 values( 200 ) +master-bin.000001 18565 Query 1 18656 use `test`; insert into t1 values( 199 ) +master-bin.000001 18656 Query 1 18747 use `test`; insert into t1 values( 198 ) +master-bin.000001 18747 Query 1 18838 use `test`; insert into t1 values( 197 ) +master-bin.000001 18838 Query 1 18929 use `test`; insert into t1 values( 196 ) +master-bin.000001 18929 Query 1 19020 use `test`; insert into t1 values( 195 ) +master-bin.000001 19020 Query 1 19111 use `test`; insert into t1 values( 194 ) +master-bin.000001 19111 Query 1 19202 use `test`; insert into t1 values( 193 ) +master-bin.000001 19202 Query 1 19293 use `test`; insert into t1 values( 192 ) +master-bin.000001 19293 Query 1 19384 use `test`; insert into t1 values( 191 ) +master-bin.000001 19384 Query 1 19475 use `test`; insert into t1 values( 190 ) +master-bin.000001 19475 Query 1 19566 use `test`; insert into t1 values( 189 ) +master-bin.000001 19566 Query 1 19657 use `test`; insert into t1 values( 188 ) +master-bin.000001 19657 Query 1 19748 use `test`; insert into t1 values( 187 ) +master-bin.000001 19748 Query 1 19839 use `test`; insert into t1 values( 186 ) +master-bin.000001 19839 Query 1 19930 use `test`; insert into t1 values( 185 ) +master-bin.000001 19930 Query 1 20021 use `test`; insert into t1 values( 184 ) +master-bin.000001 20021 Query 1 20112 use `test`; insert into t1 values( 183 ) +master-bin.000001 20112 Query 1 20203 use `test`; insert into t1 values( 182 ) +master-bin.000001 20203 Query 1 20294 use `test`; insert into t1 values( 181 ) +master-bin.000001 20294 Query 1 20385 use `test`; insert into t1 values( 180 ) +master-bin.000001 20385 Query 1 20476 use `test`; insert into t1 values( 179 ) +master-bin.000001 20476 Query 1 20567 use `test`; insert into t1 values( 178 ) +master-bin.000001 20567 Query 1 20658 use `test`; insert into t1 values( 177 ) +master-bin.000001 20658 Query 1 20749 use `test`; insert into t1 values( 176 ) +master-bin.000001 20749 Query 1 20840 use `test`; insert into t1 values( 175 ) +master-bin.000001 20840 Query 1 20931 use `test`; insert into t1 values( 174 ) +master-bin.000001 20931 Query 1 21022 use `test`; insert into t1 values( 173 ) +master-bin.000001 21022 Query 1 21113 use `test`; insert into t1 values( 172 ) +master-bin.000001 21113 Query 1 21204 use `test`; insert into t1 values( 171 ) +master-bin.000001 21204 Query 1 21295 use `test`; insert into t1 values( 170 ) +master-bin.000001 21295 Query 1 21386 use `test`; insert into t1 values( 169 ) +master-bin.000001 21386 Query 1 21477 use `test`; insert into t1 values( 168 ) +master-bin.000001 21477 Query 1 21568 use `test`; insert into t1 values( 167 ) +master-bin.000001 21568 Query 1 21659 use `test`; insert into t1 values( 166 ) +master-bin.000001 21659 Query 1 21750 use `test`; insert into t1 values( 165 ) +master-bin.000001 21750 Query 1 21841 use `test`; insert into t1 values( 164 ) +master-bin.000001 21841 Query 1 21932 use `test`; insert into t1 values( 163 ) +master-bin.000001 21932 Query 1 22023 use `test`; insert into t1 values( 162 ) +master-bin.000001 22023 Query 1 22114 use `test`; insert into t1 values( 161 ) +master-bin.000001 22114 Query 1 22205 use `test`; insert into t1 values( 160 ) +master-bin.000001 22205 Query 1 22296 use `test`; insert into t1 values( 159 ) +master-bin.000001 22296 Query 1 22387 use `test`; insert into t1 values( 158 ) +master-bin.000001 22387 Query 1 22478 use `test`; insert into t1 values( 157 ) +master-bin.000001 22478 Query 1 22569 use `test`; insert into t1 values( 156 ) +master-bin.000001 22569 Query 1 22660 use `test`; insert into t1 values( 155 ) +master-bin.000001 22660 Query 1 22751 use `test`; insert into t1 values( 154 ) +master-bin.000001 22751 Query 1 22842 use `test`; insert into t1 values( 153 ) +master-bin.000001 22842 Query 1 22933 use `test`; insert into t1 values( 152 ) +master-bin.000001 22933 Query 1 23024 use `test`; insert into t1 values( 151 ) +master-bin.000001 23024 Query 1 23115 use `test`; insert into t1 values( 150 ) +master-bin.000001 23115 Query 1 23206 use `test`; insert into t1 values( 149 ) +master-bin.000001 23206 Query 1 23297 use `test`; insert into t1 values( 148 ) +master-bin.000001 23297 Query 1 23388 use `test`; insert into t1 values( 147 ) +master-bin.000001 23388 Query 1 23479 use `test`; insert into t1 values( 146 ) +master-bin.000001 23479 Query 1 23570 use `test`; insert into t1 values( 145 ) +master-bin.000001 23570 Query 1 23661 use `test`; insert into t1 values( 144 ) +master-bin.000001 23661 Query 1 23752 use `test`; insert into t1 values( 143 ) +master-bin.000001 23752 Query 1 23843 use `test`; insert into t1 values( 142 ) +master-bin.000001 23843 Query 1 23934 use `test`; insert into t1 values( 141 ) +master-bin.000001 23934 Query 1 24025 use `test`; insert into t1 values( 140 ) +master-bin.000001 24025 Query 1 24116 use `test`; insert into t1 values( 139 ) +master-bin.000001 24116 Query 1 24207 use `test`; insert into t1 values( 138 ) +master-bin.000001 24207 Query 1 24298 use `test`; insert into t1 values( 137 ) +master-bin.000001 24298 Query 1 24389 use `test`; insert into t1 values( 136 ) +master-bin.000001 24389 Query 1 24480 use `test`; insert into t1 values( 135 ) +master-bin.000001 24480 Query 1 24571 use `test`; insert into t1 values( 134 ) +master-bin.000001 24571 Query 1 24662 use `test`; insert into t1 values( 133 ) +master-bin.000001 24662 Query 1 24753 use `test`; insert into t1 values( 132 ) +master-bin.000001 24753 Query 1 24844 use `test`; insert into t1 values( 131 ) +master-bin.000001 24844 Query 1 24935 use `test`; insert into t1 values( 130 ) +master-bin.000001 24935 Query 1 25026 use `test`; insert into t1 values( 129 ) +master-bin.000001 25026 Query 1 25117 use `test`; insert into t1 values( 128 ) +master-bin.000001 25117 Query 1 25208 use `test`; insert into t1 values( 127 ) +master-bin.000001 25208 Query 1 25299 use `test`; insert into t1 values( 126 ) +master-bin.000001 25299 Query 1 25390 use `test`; insert into t1 values( 125 ) +master-bin.000001 25390 Query 1 25481 use `test`; insert into t1 values( 124 ) +master-bin.000001 25481 Query 1 25572 use `test`; insert into t1 values( 123 ) +master-bin.000001 25572 Query 1 25663 use `test`; insert into t1 values( 122 ) +master-bin.000001 25663 Query 1 25754 use `test`; insert into t1 values( 121 ) +master-bin.000001 25754 Query 1 25845 use `test`; insert into t1 values( 120 ) +master-bin.000001 25845 Query 1 25936 use `test`; insert into t1 values( 119 ) +master-bin.000001 25936 Query 1 26027 use `test`; insert into t1 values( 118 ) +master-bin.000001 26027 Query 1 26118 use `test`; insert into t1 values( 117 ) +master-bin.000001 26118 Query 1 26209 use `test`; insert into t1 values( 116 ) +master-bin.000001 26209 Query 1 26300 use `test`; insert into t1 values( 115 ) +master-bin.000001 26300 Query 1 26391 use `test`; insert into t1 values( 114 ) +master-bin.000001 26391 Query 1 26482 use `test`; insert into t1 values( 113 ) +master-bin.000001 26482 Query 1 26573 use `test`; insert into t1 values( 112 ) +master-bin.000001 26573 Query 1 26664 use `test`; insert into t1 values( 111 ) +master-bin.000001 26664 Query 1 26755 use `test`; insert into t1 values( 110 ) +master-bin.000001 26755 Query 1 26846 use `test`; insert into t1 values( 109 ) +master-bin.000001 26846 Query 1 26937 use `test`; insert into t1 values( 108 ) +master-bin.000001 26937 Query 1 27028 use `test`; insert into t1 values( 107 ) +master-bin.000001 27028 Query 1 27119 use `test`; insert into t1 values( 106 ) +master-bin.000001 27119 Query 1 27210 use `test`; insert into t1 values( 105 ) +master-bin.000001 27210 Query 1 27301 use `test`; insert into t1 values( 104 ) +master-bin.000001 27301 Query 1 27392 use `test`; insert into t1 values( 103 ) +master-bin.000001 27392 Query 1 27483 use `test`; insert into t1 values( 102 ) +master-bin.000001 27483 Query 1 27574 use `test`; insert into t1 values( 101 ) +master-bin.000001 27574 Query 1 27665 use `test`; insert into t1 values( 100 ) +master-bin.000001 27665 Query 1 27755 use `test`; insert into t1 values( 99 ) +master-bin.000001 27755 Query 1 27845 use `test`; insert into t1 values( 98 ) +master-bin.000001 27845 Query 1 27935 use `test`; insert into t1 values( 97 ) +master-bin.000001 27935 Query 1 28025 use `test`; insert into t1 values( 96 ) +master-bin.000001 28025 Query 1 28115 use `test`; insert into t1 values( 95 ) +master-bin.000001 28115 Query 1 28205 use `test`; insert into t1 values( 94 ) +master-bin.000001 28205 Query 1 28295 use `test`; insert into t1 values( 93 ) +master-bin.000001 28295 Query 1 28385 use `test`; insert into t1 values( 92 ) +master-bin.000001 28385 Query 1 28475 use `test`; insert into t1 values( 91 ) +master-bin.000001 28475 Query 1 28565 use `test`; insert into t1 values( 90 ) +master-bin.000001 28565 Query 1 28655 use `test`; insert into t1 values( 89 ) +master-bin.000001 28655 Query 1 28745 use `test`; insert into t1 values( 88 ) +master-bin.000001 28745 Query 1 28835 use `test`; insert into t1 values( 87 ) +master-bin.000001 28835 Query 1 28925 use `test`; insert into t1 values( 86 ) +master-bin.000001 28925 Query 1 29015 use `test`; insert into t1 values( 85 ) +master-bin.000001 29015 Query 1 29105 use `test`; insert into t1 values( 84 ) +master-bin.000001 29105 Query 1 29195 use `test`; insert into t1 values( 83 ) +master-bin.000001 29195 Query 1 29285 use `test`; insert into t1 values( 82 ) +master-bin.000001 29285 Query 1 29375 use `test`; insert into t1 values( 81 ) +master-bin.000001 29375 Query 1 29465 use `test`; insert into t1 values( 80 ) +master-bin.000001 29465 Query 1 29555 use `test`; insert into t1 values( 79 ) +master-bin.000001 29555 Query 1 29645 use `test`; insert into t1 values( 78 ) +master-bin.000001 29645 Query 1 29735 use `test`; insert into t1 values( 77 ) +master-bin.000001 29735 Query 1 29825 use `test`; insert into t1 values( 76 ) +master-bin.000001 29825 Query 1 29915 use `test`; insert into t1 values( 75 ) +master-bin.000001 29915 Query 1 30005 use `test`; insert into t1 values( 74 ) +master-bin.000001 30005 Query 1 30095 use `test`; insert into t1 values( 73 ) +master-bin.000001 30095 Query 1 30185 use `test`; insert into t1 values( 72 ) +master-bin.000001 30185 Query 1 30275 use `test`; insert into t1 values( 71 ) +master-bin.000001 30275 Query 1 30365 use `test`; insert into t1 values( 70 ) +master-bin.000001 30365 Query 1 30455 use `test`; insert into t1 values( 69 ) +master-bin.000001 30455 Query 1 30545 use `test`; insert into t1 values( 68 ) +master-bin.000001 30545 Query 1 30635 use `test`; insert into t1 values( 67 ) +master-bin.000001 30635 Query 1 30725 use `test`; insert into t1 values( 66 ) +master-bin.000001 30725 Query 1 30815 use `test`; insert into t1 values( 65 ) +master-bin.000001 30815 Query 1 30905 use `test`; insert into t1 values( 64 ) +master-bin.000001 30905 Query 1 30995 use `test`; insert into t1 values( 63 ) +master-bin.000001 30995 Query 1 31085 use `test`; insert into t1 values( 62 ) +master-bin.000001 31085 Query 1 31175 use `test`; insert into t1 values( 61 ) +master-bin.000001 31175 Query 1 31265 use `test`; insert into t1 values( 60 ) +master-bin.000001 31265 Query 1 31355 use `test`; insert into t1 values( 59 ) +master-bin.000001 31355 Query 1 31445 use `test`; insert into t1 values( 58 ) +master-bin.000001 31445 Query 1 31535 use `test`; insert into t1 values( 57 ) +master-bin.000001 31535 Query 1 31625 use `test`; insert into t1 values( 56 ) +master-bin.000001 31625 Query 1 31715 use `test`; insert into t1 values( 55 ) +master-bin.000001 31715 Query 1 31805 use `test`; insert into t1 values( 54 ) +master-bin.000001 31805 Query 1 31895 use `test`; insert into t1 values( 53 ) +master-bin.000001 31895 Query 1 31985 use `test`; insert into t1 values( 52 ) +master-bin.000001 31985 Query 1 32075 use `test`; insert into t1 values( 51 ) +master-bin.000001 32075 Query 1 32165 use `test`; insert into t1 values( 50 ) +master-bin.000001 32165 Query 1 32255 use `test`; insert into t1 values( 49 ) +master-bin.000001 32255 Query 1 32345 use `test`; insert into t1 values( 48 ) +master-bin.000001 32345 Query 1 32435 use `test`; insert into t1 values( 47 ) +master-bin.000001 32435 Query 1 32525 use `test`; insert into t1 values( 46 ) +master-bin.000001 32525 Query 1 32615 use `test`; insert into t1 values( 45 ) +master-bin.000001 32615 Query 1 32705 use `test`; insert into t1 values( 44 ) +master-bin.000001 32705 Query 1 32795 use `test`; insert into t1 values( 43 ) +master-bin.000001 32795 Query 1 32885 use `test`; insert into t1 values( 42 ) +master-bin.000001 32885 Query 1 32975 use `test`; insert into t1 values( 41 ) +master-bin.000001 32975 Query 1 33065 use `test`; insert into t1 values( 40 ) +master-bin.000001 33065 Query 1 33155 use `test`; insert into t1 values( 39 ) +master-bin.000001 33155 Query 1 33245 use `test`; insert into t1 values( 38 ) +master-bin.000001 33245 Query 1 33335 use `test`; insert into t1 values( 37 ) +master-bin.000001 33335 Query 1 33425 use `test`; insert into t1 values( 36 ) +master-bin.000001 33425 Query 1 33515 use `test`; insert into t1 values( 35 ) +master-bin.000001 33515 Query 1 33605 use `test`; insert into t1 values( 34 ) +master-bin.000001 33605 Query 1 33695 use `test`; insert into t1 values( 33 ) +master-bin.000001 33695 Query 1 33785 use `test`; insert into t1 values( 32 ) +master-bin.000001 33785 Query 1 33875 use `test`; insert into t1 values( 31 ) +master-bin.000001 33875 Query 1 33965 use `test`; insert into t1 values( 30 ) +master-bin.000001 33965 Query 1 34055 use `test`; insert into t1 values( 29 ) +master-bin.000001 34055 Query 1 34145 use `test`; insert into t1 values( 28 ) +master-bin.000001 34145 Query 1 34235 use `test`; insert into t1 values( 27 ) +master-bin.000001 34235 Query 1 34325 use `test`; insert into t1 values( 26 ) +master-bin.000001 34325 Query 1 34415 use `test`; insert into t1 values( 25 ) +master-bin.000001 34415 Query 1 34505 use `test`; insert into t1 values( 24 ) +master-bin.000001 34505 Query 1 34595 use `test`; insert into t1 values( 23 ) +master-bin.000001 34595 Query 1 34685 use `test`; insert into t1 values( 22 ) +master-bin.000001 34685 Query 1 34775 use `test`; insert into t1 values( 21 ) +master-bin.000001 34775 Query 1 34865 use `test`; insert into t1 values( 20 ) +master-bin.000001 34865 Query 1 34955 use `test`; insert into t1 values( 19 ) +master-bin.000001 34955 Query 1 35045 use `test`; insert into t1 values( 18 ) +master-bin.000001 35045 Query 1 35135 use `test`; insert into t1 values( 17 ) +master-bin.000001 35135 Query 1 35225 use `test`; insert into t1 values( 16 ) +master-bin.000001 35225 Query 1 35315 use `test`; insert into t1 values( 15 ) +master-bin.000001 35315 Query 1 35405 use `test`; insert into t1 values( 14 ) +master-bin.000001 35405 Query 1 35495 use `test`; insert into t1 values( 13 ) +master-bin.000001 35495 Query 1 35585 use `test`; insert into t1 values( 12 ) +master-bin.000001 35585 Query 1 35675 use `test`; insert into t1 values( 11 ) +master-bin.000001 35675 Query 1 35765 use `test`; insert into t1 values( 10 ) +master-bin.000001 35765 Query 1 35854 use `test`; insert into t1 values( 9 ) +master-bin.000001 35854 Query 1 35943 use `test`; insert into t1 values( 8 ) +master-bin.000001 35943 Query 1 36032 use `test`; insert into t1 values( 7 ) +master-bin.000001 36032 Query 1 36121 use `test`; insert into t1 values( 6 ) +master-bin.000001 36121 Query 1 36210 use `test`; insert into t1 values( 5 ) +master-bin.000001 36210 Query 1 36299 use `test`; insert into t1 values( 4 ) +master-bin.000001 36299 Query 1 36388 use `test`; insert into t1 values( 3 ) +master-bin.000001 36388 Query 1 36477 use `test`; insert into t1 values( 2 ) +master-bin.000001 36477 Query 1 36566 use `test`; insert into t1 values( 1 ) +master-bin.000001 36566 Xid 1 36593 COMMIT /* XID */ +master-bin.000001 36593 Rotate 1 36637 master-bin.000002;pos=4 drop table t1; set global binlog_cache_size=@bcs; set session autocommit = @ac; From 3a9e84826e6956e6893114e4d19d68e86e58dcb8 Mon Sep 17 00:00:00 2001 From: "tnurnberg@mysql.com/sin.intern.azundris.com" <> Date: Wed, 11 Jul 2007 04:33:19 +0200 Subject: [PATCH 08/24] Bug#22540: Incorrect value in column End_log_pos of SHOW BINLOG EVENTS using InnoDB Streamlining test for RBR --- .../suite/binlog/r/binlog_row_binlog.result | 109 ------------------ 1 file changed, 109 deletions(-) diff --git a/mysql-test/suite/binlog/r/binlog_row_binlog.result b/mysql-test/suite/binlog/r/binlog_row_binlog.result index 37fe49e79dc..1d1656889f4 100644 --- a/mysql-test/suite/binlog/r/binlog_row_binlog.result +++ b/mysql-test/suite/binlog/r/binlog_row_binlog.result @@ -258,117 +258,8 @@ master-bin.000001 419 Table_map 1 458 table_id: # (test.t1) master-bin.000001 458 Write_rows 1 492 table_id: # flags: STMT_END_F master-bin.000001 492 Xid 1 519 COMMIT /* XID */ master-bin.000001 519 Query 1 595 use `test`; drop table t1 -set autocommit= 1; -reset master; -create table t1(n int) engine=innodb; -insert into t1 values (1); -insert into t1 values (2); -insert into t1 values (3); -commit; -drop table t1; -show binlog events from 0; -Log_name Pos Event_type Server_id End_log_pos Info -master-bin.000001 4 Format_desc 1 106 Server version, Binlog ver: 4 -master-bin.000001 106 Query 1 205 use `test`; create table t1(n int) engine=innodb -master-bin.000001 205 Table_map 1 244 table_id: # (test.t1) -master-bin.000001 244 Write_rows 1 278 table_id: # flags: STMT_END_F -master-bin.000001 278 Xid 1 305 COMMIT /* XID */ -master-bin.000001 305 Table_map 1 344 table_id: # (test.t1) -master-bin.000001 344 Write_rows 1 378 table_id: # flags: STMT_END_F -master-bin.000001 378 Xid 1 405 COMMIT /* XID */ -master-bin.000001 405 Table_map 1 444 table_id: # (test.t1) -master-bin.000001 444 Write_rows 1 478 table_id: # flags: STMT_END_F -master-bin.000001 478 Xid 1 505 COMMIT /* XID */ -master-bin.000001 505 Query 1 581 use `test`; drop table t1 -reset master; -create table t1(n int) engine=myisam; -begin; -insert into t1 values (4); -insert into t1 values (5); -insert into t1 values (6); -commit; -drop table t1; -show binlog events from 0; -Log_name Pos Event_type Server_id End_log_pos Info -master-bin.000001 4 Format_desc 1 106 Server version, Binlog ver: 4 -master-bin.000001 106 Query 1 205 use `test`; create table t1(n int) engine=myisam -master-bin.000001 205 Table_map 1 244 table_id: # (test.t1) -master-bin.000001 244 Write_rows 1 278 table_id: # flags: STMT_END_F -master-bin.000001 278 Table_map 1 317 table_id: # (test.t1) -master-bin.000001 317 Write_rows 1 351 table_id: # flags: STMT_END_F -master-bin.000001 351 Table_map 1 390 table_id: # (test.t1) -master-bin.000001 390 Write_rows 1 424 table_id: # flags: STMT_END_F -master-bin.000001 424 Query 1 500 use `test`; drop table t1 -set autocommit= 1; -reset master; -create table t1(n int) engine=innodb; -show master status; -File Position Binlog_Do_DB Binlog_Ignore_DB -master-bin.000001 205 -insert into t1 values (1); -show master status; -File Position Binlog_Do_DB Binlog_Ignore_DB -master-bin.000001 305 -insert into t1 values (2); -insert into t1 values (3); -show master status; -File Position Binlog_Do_DB Binlog_Ignore_DB -master-bin.000001 505 -commit; -show master status; -File Position Binlog_Do_DB Binlog_Ignore_DB -master-bin.000001 505 -drop table t1; -show binlog events from 0; -Log_name Pos Event_type Server_id End_log_pos Info -master-bin.000001 4 Format_desc 1 106 Server version, Binlog ver: 4 -master-bin.000001 106 Query 1 205 use `test`; create table t1(n int) engine=innodb -master-bin.000001 205 Table_map 1 244 table_id: # (test.t1) -master-bin.000001 244 Write_rows 1 278 table_id: # flags: STMT_END_F -master-bin.000001 278 Xid 1 305 COMMIT /* XID */ -master-bin.000001 305 Table_map 1 344 table_id: # (test.t1) -master-bin.000001 344 Write_rows 1 378 table_id: # flags: STMT_END_F -master-bin.000001 378 Xid 1 405 COMMIT /* XID */ -master-bin.000001 405 Table_map 1 444 table_id: # (test.t1) -master-bin.000001 444 Write_rows 1 478 table_id: # flags: STMT_END_F -master-bin.000001 478 Xid 1 505 COMMIT /* XID */ -master-bin.000001 505 Query 1 581 use `test`; drop table t1 -set autocommit= 0; -reset master; -create table t1(n int) engine=myisam; -show master status; -File Position Binlog_Do_DB Binlog_Ignore_DB -master-bin.000001 205 -insert into t1 values (4); -show master status; -File Position Binlog_Do_DB Binlog_Ignore_DB -master-bin.000001 278 -insert into t1 values (5); -insert into t1 values (6); -show master status; -File Position Binlog_Do_DB Binlog_Ignore_DB -master-bin.000001 424 -commit; -show master status; -File Position Binlog_Do_DB Binlog_Ignore_DB -master-bin.000001 424 -drop table t1; -show binlog events from 0; -Log_name Pos Event_type Server_id End_log_pos Info -master-bin.000001 4 Format_desc 1 106 Server version, Binlog ver: 4 -master-bin.000001 106 Query 1 205 use `test`; create table t1(n int) engine=myisam -master-bin.000001 205 Table_map 1 244 table_id: # (test.t1) -master-bin.000001 244 Write_rows 1 278 table_id: # flags: STMT_END_F -master-bin.000001 278 Table_map 1 317 table_id: # (test.t1) -master-bin.000001 317 Write_rows 1 351 table_id: # flags: STMT_END_F -master-bin.000001 351 Table_map 1 390 table_id: # (test.t1) -master-bin.000001 390 Write_rows 1 424 table_id: # flags: STMT_END_F -master-bin.000001 424 Query 1 500 use `test`; drop table t1 -set session autocommit = @ac; set @bcs = @@binlog_cache_size; -set @ac = @@autocommit; set global binlog_cache_size=4096; -set autocommit= 0; reset master; create table t1 (a int) engine=innodb; show binlog events from 0; From e22ba29c2b6e363f9a5e102f4b2791af050b4a71 Mon Sep 17 00:00:00 2001 From: "tomas@whalegate.ndb.mysql.com" <> Date: Wed, 11 Jul 2007 14:36:44 +0200 Subject: [PATCH 09/24] fix ndb_version.h so that it is usable and make some functions public to handle ndb version --- storage/ndb/include/ndb_version.h.in | 57 ++++++++++++------- storage/ndb/include/util/version.h | 23 +++----- storage/ndb/src/common/util/version.c | 23 +++++--- .../kernel/blocks/dbdict/printSchemaFile.cpp | 2 +- storage/ndb/src/kernel/blocks/diskpage.cpp | 2 +- .../ndb/src/kernel/blocks/qmgr/QmgrMain.cpp | 2 +- storage/ndb/src/kernel/blocks/restore.cpp | 2 +- storage/ndb/src/kernel/vm/SimulatedBlock.hpp | 2 +- storage/ndb/src/mgmsrv/Services.cpp | 2 +- storage/ndb/src/ndbapi/ClusterMgr.cpp | 2 +- storage/ndb/src/ndbapi/NdbDictionaryImpl.cpp | 2 +- storage/ndb/tools/restore/restore_main.cpp | 6 +- 12 files changed, 70 insertions(+), 55 deletions(-) diff --git a/storage/ndb/include/ndb_version.h.in b/storage/ndb/include/ndb_version.h.in index 9e1edeecd1e..5405ad4d7aa 100644 --- a/storage/ndb/include/ndb_version.h.in +++ b/storage/ndb/include/ndb_version.h.in @@ -16,8 +16,7 @@ #ifndef NDB_VERSION_H #define NDB_VERSION_H -#include -#include +#include /* NDB build version */ #define NDB_VERSION_BUILD @NDB_VERSION_BUILD@ @@ -32,19 +31,35 @@ #define NDB_VERSION_STATUS "@NDB_VERSION_STATUS@" -#define MAKE_VERSION(A,B,C) (((A) << 16) | ((B) << 8) | ((C) << 0)) +#define NDB_MAKE_VERSION(A,B,C) (((A) << 16) | ((B) << 8) | ((C) << 0)) -#define NDB_VERSION_D MAKE_VERSION(NDB_VERSION_MAJOR, NDB_VERSION_MINOR, NDB_VERSION_BUILD) +#define NDB_VERSION_D NDB_MAKE_VERSION(NDB_VERSION_MAJOR, NDB_VERSION_MINOR, NDB_VERSION_BUILD) #define NDB_VERSION_STRING_BUF_SZ 100 #ifdef __cplusplus -extern "C" -#else -extern +extern "C" { #endif -char ndb_version_string_buf[NDB_VERSION_STRING_BUF_SZ]; -#define NDB_VERSION_STRING (getVersionString(NDB_VERSION, NDB_VERSION_STATUS, \ - ndb_version_string_buf, \ - sizeof(ndb_version_string_buf))) + +void ndbPrintVersion(); + +Uint32 ndbMakeVersion(Uint32 major, Uint32 minor, Uint32 build); + +Uint32 ndbGetMajor(Uint32 version); + +Uint32 ndbGetMinor(Uint32 version); + +Uint32 ndbGetBuild(Uint32 version); + +const char* ndbGetVersionString(Uint32 version, const char * status, + char *buf, unsigned sz); +const char* ndbGetOwnVersionString(); + +Uint32 ndbGetOwnVersion(); + +#ifdef __cplusplus +} +#endif + +#define NDB_VERSION_STRING ndbGetOwnVersionString() #define NDB_VERSION ndbGetOwnVersion() @@ -59,19 +74,19 @@ char ndb_version_string_buf[NDB_VERSION_STRING_BUF_SZ]; /** * From which version do we support rowid */ -#define NDBD_ROWID_VERSION (MAKE_VERSION(5,1,6)) -#define NDBD_INCL_NODECONF_VERSION_4 MAKE_VERSION(4,1,17) -#define NDBD_INCL_NODECONF_VERSION_5 MAKE_VERSION(5,0,18) -#define NDBD_FRAGID_VERSION (MAKE_VERSION(5,1,6)) -#define NDBD_DICT_LOCK_VERSION_5 MAKE_VERSION(5,0,23) -#define NDBD_DICT_LOCK_VERSION_5_1 MAKE_VERSION(5,1,12) +#define NDBD_ROWID_VERSION (NDB_MAKE_VERSION(5,1,6)) +#define NDBD_INCL_NODECONF_VERSION_4 NDB_MAKE_VERSION(4,1,17) +#define NDBD_INCL_NODECONF_VERSION_5 NDB_MAKE_VERSION(5,0,18) +#define NDBD_FRAGID_VERSION (NDB_MAKE_VERSION(5,1,6)) +#define NDBD_DICT_LOCK_VERSION_5 NDB_MAKE_VERSION(5,0,23) +#define NDBD_DICT_LOCK_VERSION_5_1 NDB_MAKE_VERSION(5,1,12) -#define NDBD_UPDATE_FRAG_DIST_KEY_50 MAKE_VERSION(5,0,26) -#define NDBD_UPDATE_FRAG_DIST_KEY_51 MAKE_VERSION(5,1,12) +#define NDBD_UPDATE_FRAG_DIST_KEY_50 NDB_MAKE_VERSION(5,0,26) +#define NDBD_UPDATE_FRAG_DIST_KEY_51 NDB_MAKE_VERSION(5,1,12) -#define NDBD_QMGR_SINGLEUSER_VERSION_5 MAKE_VERSION(5,0,25) +#define NDBD_QMGR_SINGLEUSER_VERSION_5 NDB_MAKE_VERSION(5,0,25) -#define NDBD_NODE_VERSION_REP MAKE_VERSION(6,1,1) +#define NDBD_NODE_VERSION_REP NDB_MAKE_VERSION(6,1,1) #endif diff --git a/storage/ndb/include/util/version.h b/storage/ndb/include/util/version.h index 42513d00442..9ea18ecd9d9 100644 --- a/storage/ndb/include/util/version.h +++ b/storage/ndb/include/util/version.h @@ -16,25 +16,18 @@ #ifndef VERSION_H #define VERSION_H -#include +#include + +/* some backwards compatible macros */ +#define MAKE_VERSION(A,B,C) NDB_MAKE_VERSION(A,B,C) +#define getMajor(a) ndbGetMajor(a) +#define getMinor(a) ndbGetMinor(a) +#define getBuild(a) ndbGetBuild(a) + #ifdef __cplusplus extern "C" { #endif - Uint32 getMajor(Uint32 version); - - Uint32 getMinor(Uint32 version); - - Uint32 getBuild(Uint32 version); - - Uint32 makeVersion(Uint32 major, Uint32 minor, Uint32 build); - - const char* getVersionString(Uint32 version, const char * status, - char *buf, unsigned sz); - - void ndbPrintVersion(); - Uint32 ndbGetOwnVersion(); - int ndbCompatible_mgmt_ndb(Uint32 ownVersion, Uint32 otherVersion); int ndbCompatible_ndb_mgmt(Uint32 ownVersion, Uint32 otherVersion); int ndbCompatible_mgmt_api(Uint32 ownVersion, Uint32 otherVersion); diff --git a/storage/ndb/src/common/util/version.c b/storage/ndb/src/common/util/version.c index f309a3d4ad5..56a92489131 100644 --- a/storage/ndb/src/common/util/version.c +++ b/storage/ndb/src/common/util/version.c @@ -20,26 +20,33 @@ #include #include -Uint32 getMajor(Uint32 version) { +Uint32 ndbGetMajor(Uint32 version) { return (version >> 16) & 0xFF; } -Uint32 getMinor(Uint32 version) { +Uint32 ndbGetMinor(Uint32 version) { return (version >> 8) & 0xFF; } -Uint32 getBuild(Uint32 version) { +Uint32 ndbGetBuild(Uint32 version) { return (version >> 0) & 0xFF; } -Uint32 makeVersion(Uint32 major, Uint32 minor, Uint32 build) { - return MAKE_VERSION(major, minor, build); +Uint32 ndbMakeVersion(Uint32 major, Uint32 minor, Uint32 build) { + return NDB_MAKE_VERSION(major, minor, build); } -char ndb_version_string_buf[NDB_VERSION_STRING_BUF_SZ]; -const char * getVersionString(Uint32 version, const char * status, - char *buf, unsigned sz) +const char * ndbGetOwnVersionString() +{ + static char ndb_version_string_buf[NDB_VERSION_STRING_BUF_SZ]; + return ndbGetVersionString(NDB_VERSION, NDB_VERSION_STATUS, + ndb_version_string_buf, + sizeof(ndb_version_string_buf)); +} + +const char * ndbGetVersionString(Uint32 version, const char * status, + char *buf, unsigned sz) { if (status && status[0] != 0) basestring_snprintf(buf, sz, diff --git a/storage/ndb/src/kernel/blocks/dbdict/printSchemaFile.cpp b/storage/ndb/src/kernel/blocks/dbdict/printSchemaFile.cpp index 602881095c3..44326e213d0 100644 --- a/storage/ndb/src/kernel/blocks/dbdict/printSchemaFile.cpp +++ b/storage/ndb/src/kernel/blocks/dbdict/printSchemaFile.cpp @@ -15,7 +15,7 @@ #include -#include +#include #include #include diff --git a/storage/ndb/src/kernel/blocks/diskpage.cpp b/storage/ndb/src/kernel/blocks/diskpage.cpp index 3f98e078746..50e9b6e53cb 100644 --- a/storage/ndb/src/kernel/blocks/diskpage.cpp +++ b/storage/ndb/src/kernel/blocks/diskpage.cpp @@ -49,7 +49,7 @@ operator<<(NdbOut& out, const File_formats::Zero_page_header& obj) char buf[256]; out << "page size: " << obj.m_page_size << endl; out << "ndb version: " << obj.m_ndb_version << ", " << - getVersionString(obj.m_ndb_version, 0, buf, sizeof(buf)) << endl; + ndbGetVersionString(obj.m_ndb_version, 0, buf, sizeof(buf)) << endl; out << "ndb node id: " << obj.m_node_id << endl; out << "file type: " << obj.m_file_type << endl; out << "time: " << obj.m_time << ", " diff --git a/storage/ndb/src/kernel/blocks/qmgr/QmgrMain.cpp b/storage/ndb/src/kernel/blocks/qmgr/QmgrMain.cpp index 52045fd63cd..1fba4d62e17 100644 --- a/storage/ndb/src/kernel/blocks/qmgr/QmgrMain.cpp +++ b/storage/ndb/src/kernel/blocks/qmgr/QmgrMain.cpp @@ -2793,7 +2793,7 @@ void Qmgr::execAPI_REGREQ(Signal* signal) "incompatible with %s", type == NodeInfo::API ? "api or mysqld" : "management server", apiNodePtr.i, - getVersionString(version,"",buf,sizeof(buf)), + ndbGetVersionString(version,"",buf,sizeof(buf)), NDB_VERSION_STRING); apiNodePtr.p->phase = ZAPI_INACTIVE; sendApiRegRef(signal, ref, ApiRegRef::UnsupportedVersion); diff --git a/storage/ndb/src/kernel/blocks/restore.cpp b/storage/ndb/src/kernel/blocks/restore.cpp index 2d40cd79daa..efc4bc1948a 100644 --- a/storage/ndb/src/kernel/blocks/restore.cpp +++ b/storage/ndb/src/kernel/blocks/restore.cpp @@ -1271,7 +1271,7 @@ Restore::check_file_version(Signal* signal, Uint32 file_version) { char buf[255]; char verbuf[255]; - getVersionString(file_version, 0, verbuf, sizeof(verbuf)); + ndbGetVersionString(file_version, 0, verbuf, sizeof(verbuf)); BaseString::snprintf(buf, sizeof(buf), "Unsupported version of LCP files found on disk, " " found: %s", verbuf); diff --git a/storage/ndb/src/kernel/vm/SimulatedBlock.hpp b/storage/ndb/src/kernel/vm/SimulatedBlock.hpp index a78ee21fb8f..31f219718e5 100644 --- a/storage/ndb/src/kernel/vm/SimulatedBlock.hpp +++ b/storage/ndb/src/kernel/vm/SimulatedBlock.hpp @@ -18,7 +18,7 @@ #include #include -#include +#include #include #include "VMSignal.hpp" diff --git a/storage/ndb/src/mgmsrv/Services.cpp b/storage/ndb/src/mgmsrv/Services.cpp index f260ff7e3ec..9272b5ab532 100644 --- a/storage/ndb/src/mgmsrv/Services.cpp +++ b/storage/ndb/src/mgmsrv/Services.cpp @@ -18,7 +18,7 @@ #include #include -#include +#include #include #include #include diff --git a/storage/ndb/src/ndbapi/ClusterMgr.cpp b/storage/ndb/src/ndbapi/ClusterMgr.cpp index f51a5098c53..448bc1025e8 100644 --- a/storage/ndb/src/ndbapi/ClusterMgr.cpp +++ b/storage/ndb/src/ndbapi/ClusterMgr.cpp @@ -16,7 +16,7 @@ #include #include #include -#include +#include #include "TransporterFacade.hpp" #include "ClusterMgr.hpp" diff --git a/storage/ndb/src/ndbapi/NdbDictionaryImpl.cpp b/storage/ndb/src/ndbapi/NdbDictionaryImpl.cpp index 63d36bf012f..ab6d90ad59e 100644 --- a/storage/ndb/src/ndbapi/NdbDictionaryImpl.cpp +++ b/storage/ndb/src/ndbapi/NdbDictionaryImpl.cpp @@ -42,7 +42,7 @@ #include #include #include -#include +#include #define DEBUG_PRINT 0 #define INCOMPATIBLE_VERSION -2 diff --git a/storage/ndb/tools/restore/restore_main.cpp b/storage/ndb/tools/restore/restore_main.cpp index 79aebbaac45..30ecc695eba 100644 --- a/storage/ndb/tools/restore/restore_main.cpp +++ b/storage/ndb/tools/restore/restore_main.cpp @@ -684,7 +684,7 @@ main(int argc, char** argv) char buf[NDB_VERSION_STRING_BUF_SZ]; info.setLevel(254); info << "Ndb version in backup files: " - << getVersionString(version, 0, buf, sizeof(buf)) << endl; + << ndbGetVersionString(version, 0, buf, sizeof(buf)) << endl; /** * check wheater we can restore the backup (right version). @@ -694,9 +694,9 @@ main(int argc, char** argv) if (version >= MAKE_VERSION(5,1,3) && version <= MAKE_VERSION(5,1,9)) { err << "Restore program incompatible with backup versions between " - << getVersionString(MAKE_VERSION(5,1,3), 0, buf, sizeof(buf)) + << ndbGetVersionString(MAKE_VERSION(5,1,3), 0, buf, sizeof(buf)) << " and " - << getVersionString(MAKE_VERSION(5,1,9), 0, buf, sizeof(buf)) + << ndbGetVersionString(MAKE_VERSION(5,1,9), 0, buf, sizeof(buf)) << endl; exitHandler(NDBT_FAILED); } From b270fa6736e38866cc98a566aceb3d368c4a5022 Mon Sep 17 00:00:00 2001 From: "kaa@polly.local" <> Date: Wed, 11 Jul 2007 18:38:45 +0400 Subject: [PATCH 10/24] Fix for bug #24192 "MySQL replication does not exit server when running out of memory" In case of out-of-memory error received from the master, print the corresponding message to the error log and stop slave I/O thread to avoid reconnecting with a wrong binary log position. --- sql/slave.cc | 30 +++++++++++++++++------------- 1 file changed, 17 insertions(+), 13 deletions(-) diff --git a/sql/slave.cc b/sql/slave.cc index 97615165803..32f500723d3 100644 --- a/sql/slave.cc +++ b/sql/slave.cc @@ -26,6 +26,7 @@ #include #include #include +#include #define MAX_SLAVE_RETRY_PAUSE 5 bool use_slave_mask = 0; @@ -3610,22 +3611,25 @@ after reconnect"); if (event_len == packet_error) { - uint mysql_error_number= mysql_errno(mysql); - if (mysql_error_number == CR_NET_PACKET_TOO_LARGE) - { - sql_print_error("\ + uint mysql_error_number= mysql_errno(mysql); + switch (mysql_error_number) { + case CR_NET_PACKET_TOO_LARGE: + sql_print_error("\ Log entry on master is longer than max_allowed_packet (%ld) on \ slave. If the entry is correct, restart the server with a higher value of \ max_allowed_packet", - thd->variables.max_allowed_packet); - goto err; - } - if (mysql_error_number == ER_MASTER_FATAL_ERROR_READING_BINLOG) - { - sql_print_error(ER(mysql_error_number), mysql_error_number, - mysql_error(mysql)); - goto err; - } + thd->variables.max_allowed_packet); + goto err; + case ER_MASTER_FATAL_ERROR_READING_BINLOG: + sql_print_error(ER(mysql_error_number), mysql_error_number, + mysql_error(mysql)); + goto err; + case EE_OUTOFMEMORY: + case ER_OUTOFMEMORY: + sql_print_error("\ +Stopping slave I/O thread due to out-of-memory error from master"); + goto err; + } mi->slave_running= MYSQL_SLAVE_RUN_NOT_CONNECT; thd->proc_info = "Waiting to reconnect after a failed master event read"; #ifdef SIGNAL_WITH_VIO_CLOSE From 899aaa6bb2a684b366ec462c8e7160897fde4299 Mon Sep 17 00:00:00 2001 From: "dkatz@damien-katzs-computer.local" <> Date: Thu, 12 Jul 2007 22:06:33 -0400 Subject: [PATCH 11/24] Bug #29579 Clients using SSL can hang the server Added an option to yassl to allow "quiet shutdown" like openssl does. This option causes the SSL libs to NOT perform the close_notify handshake during shutdown. This fixes a hang we experience because we hold a lock during socket shutdown. --- client/mysqltest.c | 85 +++++++++++++++++++++++++------ extra/yassl/include/openssl/ssl.h | 2 + extra/yassl/include/yassl_int.hpp | 3 ++ extra/yassl/src/ssl.cpp | 18 ++++++- extra/yassl/src/yassl_int.cpp | 14 ++++- mysql-test/r/ssl-big.result | 3 ++ mysql-test/t/ssl-big.test | 56 ++++++++++++++++++++ mysql-test/t/ssl_big.test | 62 ++++++++++++++++++++++ vio/viossl.c | 10 ++++ 9 files changed, 234 insertions(+), 19 deletions(-) create mode 100644 mysql-test/r/ssl-big.result create mode 100644 mysql-test/t/ssl-big.test create mode 100644 mysql-test/t/ssl_big.test diff --git a/client/mysqltest.c b/client/mysqltest.c index 7eb80e4594f..2e964056a73 100644 --- a/client/mysqltest.c +++ b/client/mysqltest.c @@ -280,6 +280,7 @@ enum enum_commands { Q_REPLACE_REGEX, Q_REMOVE_FILE, Q_FILE_EXIST, Q_WRITE_FILE, Q_COPY_FILE, Q_PERL, Q_DIE, Q_EXIT, Q_SKIP, Q_CHMOD_FILE, Q_APPEND_FILE, Q_CAT_FILE, Q_DIFF_FILES, + Q_SEND_QUIT, Q_UNKNOWN, /* Unknown command. */ Q_COMMENT, /* Comments, ignored. */ @@ -367,6 +368,7 @@ const char *command_names[]= "append_file", "cat_file", "diff_files", + "send_quit", 0 }; @@ -2555,6 +2557,48 @@ void do_diff_files(struct st_command *command) DBUG_VOID_RETURN; } + /* + SYNOPSIS + do_send_quit + command called command + + DESCRIPTION + Sends a simple quit command to the server for the named connection. + + */ + +void do_send_quit(struct st_command *command) +{ + char *p= command->first_argument, *name; + struct st_connection *con; + + DBUG_ENTER("do_send_quit"); + DBUG_PRINT("enter",("name: '%s'",p)); + + if (!*p) + die("Missing connection name in do_send_quit"); + name= p; + while (*p && !my_isspace(charset_info,*p)) + p++; + + if (*p) + *p++= 0; + command->last_argument= p; + + /* Loop through connection pool for connection to close */ + for (con= connections; con < next_con; con++) + { + DBUG_PRINT("info", ("con->name: %s", con->name)); + if (!strcmp(con->name, name)) + { + simple_command(&con->mysql,COM_QUIT,NullS,0,1); + DBUG_VOID_RETURN; + } + } + die("connection '%s' not found in connection pool", name); +} + + /* SYNOPSIS do_perl @@ -3464,11 +3508,10 @@ void do_close_connection(struct st_command *command) my_free(con->name, MYF(0)); /* - When the connection is closed set name to "closed_connection" + When the connection is closed set name to "-closed_connection-" to make it possible to reuse the connection name. - The connection slot will not be reused */ - if (!(con->name = my_strdup("closed_connection", MYF(MY_WME)))) + if (!(con->name = my_strdup("-closed_connection-", MYF(MY_WME)))) die("Out of memory"); DBUG_VOID_RETURN; @@ -3646,6 +3689,7 @@ void do_connect(struct st_command *command) int con_port= opt_port; char *con_options; bool con_ssl= 0, con_compress= 0; + struct st_connection* con_slot; static DYNAMIC_STRING ds_connection_name; static DYNAMIC_STRING ds_host; @@ -3731,19 +3775,24 @@ void do_connect(struct st_command *command) con_options= end; } - if (next_con == connections_end) - die("Connection limit exhausted, you can have max %d connections", - (int) (sizeof(connections)/sizeof(struct st_connection))); - if (find_connection_by_name(ds_connection_name.str)) die("Connection %s already exists", ds_connection_name.str); + + if (!(con_slot= find_connection_by_name("-closed_connection-"))) + { + if (next_con == connections_end) + die("Connection limit exhausted, you can have max %d connections", + (int) (sizeof(connections)/sizeof(struct st_connection))); + + con_slot= next_con; + } - if (!mysql_init(&next_con->mysql)) + if (!mysql_init(&con_slot->mysql)) die("Failed on mysql_init()"); if (opt_compress || con_compress) - mysql_options(&next_con->mysql, MYSQL_OPT_COMPRESS, NullS); - mysql_options(&next_con->mysql, MYSQL_OPT_LOCAL_INFILE, 0); - mysql_options(&next_con->mysql, MYSQL_SET_CHARSET_NAME, + mysql_options(&con_slot->mysql, MYSQL_OPT_COMPRESS, NullS); + mysql_options(&con_slot->mysql, MYSQL_OPT_LOCAL_INFILE, 0); + mysql_options(&con_slot->mysql, MYSQL_SET_CHARSET_NAME, charset_info->csname); if (opt_charsets_dir) mysql_options(&cur_con->mysql, MYSQL_SET_CHARSET_DIR, @@ -3752,12 +3801,12 @@ void do_connect(struct st_command *command) #ifdef HAVE_OPENSSL if (opt_use_ssl || con_ssl) { - mysql_ssl_set(&next_con->mysql, opt_ssl_key, opt_ssl_cert, opt_ssl_ca, + mysql_ssl_set(&con_slot->mysql, opt_ssl_key, opt_ssl_cert, opt_ssl_ca, opt_ssl_capath, opt_ssl_cipher); #if MYSQL_VERSION_ID >= 50000 /* Turn on ssl_verify_server_cert only if host is "localhost" */ opt_ssl_verify_server_cert= !strcmp(ds_host.str, "localhost"); - mysql_options(&next_con->mysql, MYSQL_OPT_SSL_VERIFY_SERVER_CERT, + mysql_options(&con_slot->mysql, MYSQL_OPT_SSL_VERIFY_SERVER_CERT, &opt_ssl_verify_server_cert); #endif } @@ -3771,16 +3820,19 @@ void do_connect(struct st_command *command) if (ds_database.length && !strcmp(ds_database.str,"*NO-ONE*")) dynstr_set(&ds_database, ""); - if (connect_n_handle_errors(command, &next_con->mysql, + if (connect_n_handle_errors(command, &con_slot->mysql, ds_host.str,ds_user.str, ds_password.str, ds_database.str, con_port, ds_sock.str)) { DBUG_PRINT("info", ("Inserting connection %s in connection pool", ds_connection_name.str)); - if (!(next_con->name= my_strdup(ds_connection_name.str, MYF(MY_WME)))) + if (!(con_slot->name= my_strdup(ds_connection_name.str, MYF(MY_WME)))) die("Out of memory"); - cur_con= next_con++; + cur_con= con_slot; + + if (con_slot == next_con) + next_con++; /* if we used the next_con slot, advance the pointer */ } dynstr_free(&ds_connection_name); @@ -6349,6 +6401,7 @@ int main(int argc, char **argv) case Q_WRITE_FILE: do_write_file(command); break; case Q_APPEND_FILE: do_append_file(command); break; case Q_DIFF_FILES: do_diff_files(command); break; + case Q_SEND_QUIT: do_send_quit(command); break; case Q_CAT_FILE: do_cat_file(command); break; case Q_COPY_FILE: do_copy_file(command); break; case Q_CHMOD_FILE: do_chmod_file(command); break; diff --git a/extra/yassl/include/openssl/ssl.h b/extra/yassl/include/openssl/ssl.h index 7dd33e3fcad..efd0dec75b6 100644 --- a/extra/yassl/include/openssl/ssl.h +++ b/extra/yassl/include/openssl/ssl.h @@ -277,6 +277,8 @@ int SSL_session_reused(SSL*); int SSL_set_rfd(SSL*, int); int SSL_set_wfd(SSL*, int); void SSL_set_shutdown(SSL*, int); +void SSL_set_quiet_shutdown(SSL *ssl,int mode); +int SSL_get_quiet_shutdown(SSL *ssl); int SSL_want_read(SSL*); int SSL_want_write(SSL*); diff --git a/extra/yassl/include/yassl_int.hpp b/extra/yassl/include/yassl_int.hpp index 94cb85c3300..b207f0bffbd 100644 --- a/extra/yassl/include/yassl_int.hpp +++ b/extra/yassl/include/yassl_int.hpp @@ -584,6 +584,7 @@ class SSL { Socket socket_; // socket wrapper Buffers buffers_; // buffered handshakes and data Log log_; // logger + bool quietShutdown_; // optimization variables bool has_data_; // buffered data ready? @@ -610,6 +611,7 @@ public: Buffers& useBuffers(); bool HasData() const; + bool GetQuietShutdown() const; // sets void set_pending(Cipher suite); @@ -621,6 +623,7 @@ public: void SetError(YasslError); int SetCompression(); void UnSetCompression(); + void SetQuietShutdown(bool mode); // helpers bool isTLS() const; diff --git a/extra/yassl/src/ssl.cpp b/extra/yassl/src/ssl.cpp index 86dfa1c6ebd..c3d580a93ab 100644 --- a/extra/yassl/src/ssl.cpp +++ b/extra/yassl/src/ssl.cpp @@ -411,8 +411,10 @@ int SSL_clear(SSL* ssl) int SSL_shutdown(SSL* ssl) { - Alert alert(warning, close_notify); - sendAlert(*ssl, alert); + if (!ssl->GetQuietShutdown()) { + Alert alert(warning, close_notify); + sendAlert(*ssl, alert); + } ssl->useLog().ShowTCP(ssl->getSocket().get_fd(), true); GetErrors().Remove(); @@ -421,6 +423,18 @@ int SSL_shutdown(SSL* ssl) } +void SSL_set_quiet_shutdown(SSL *ssl,int mode) +{ + ssl->SetQuietShutdown(mode != 0); +} + + +int SSL_get_quiet_shutdown(SSL *ssl) +{ + return ssl->GetQuietShutdown(); +} + + /* on by default but allow user to turn off */ long SSL_CTX_set_session_cache_mode(SSL_CTX* ctx, long mode) { diff --git a/extra/yassl/src/yassl_int.cpp b/extra/yassl/src/yassl_int.cpp index ae16abf9e49..ba4678d70b9 100644 --- a/extra/yassl/src/yassl_int.cpp +++ b/extra/yassl/src/yassl_int.cpp @@ -291,7 +291,7 @@ const ClientKeyFactory& sslFactory::getClientKey() const SSL::SSL(SSL_CTX* ctx) : secure_(ctx->getMethod()->getVersion(), crypto_.use_random(), ctx->getMethod()->getSide(), ctx->GetCiphers(), ctx, - ctx->GetDH_Parms().set_), has_data_(false) + ctx->GetDH_Parms().set_), has_data_(false), quietShutdown_(false) { if (int err = crypto_.get_random().GetError()) { SetError(YasslError(err)); @@ -773,6 +773,12 @@ void SSL::SetError(YasslError ye) // TODO: add string here } +// set the quiet shutdown mode (close_nofiy not sent or received on shutdown) +void SSL::SetQuietShutdown(bool mode) +{ + quietShutdown_ = mode; +} + Buffers& SSL::useBuffers() { @@ -1330,6 +1336,12 @@ YasslError SSL::GetError() const } +bool SSL::GetQuietShutdown() const +{ + return quietShutdown_; +} + + bool SSL::GetMultiProtocol() const { return secure_.GetContext()->getMethod()->multipleProtocol(); diff --git a/mysql-test/r/ssl-big.result b/mysql-test/r/ssl-big.result new file mode 100644 index 00000000000..39c4f34e46c --- /dev/null +++ b/mysql-test/r/ssl-big.result @@ -0,0 +1,3 @@ +DROP TABLE IF EXISTS t1, t2; +create table t1 (a int); +drop table t1; diff --git a/mysql-test/t/ssl-big.test b/mysql-test/t/ssl-big.test new file mode 100644 index 00000000000..099c64df08f --- /dev/null +++ b/mysql-test/t/ssl-big.test @@ -0,0 +1,56 @@ +# Turn on ssl between the client and server +# and run a number of tests + +-- source include/have_ssl.inc +-- source include/big_test.inc + +--disable_warnings +DROP TABLE IF EXISTS t1, t2; +--enable_warnings + +# +# Bug #29579 Clients using SSL can hang the server +# + +connect (ssl_con,localhost,root,,,,,SSL); + +create table t1 (a int); + +disconnect ssl_con; + + +--disable_query_log +--disable_result_log + +let $count= 2000; +while ($count) +{ + connect (ssl_con,localhost,root,,,,,SSL); + + eval insert into t1 values ($count); + dec $count; + + # This select causes the net buffer to fill as the server sends the results + # but the client doesn't reap the results. The results are larger each time + # through the loop, so that eventually the buffer is completely full + # at the exact moment the server attempts to the close the connection with + # the lock held. + send select * from t1; + + # now send the quit the command so the server will initiate the shutdown. + send_quit ssl_con; + + # if the server is hung, this will hang too: + connect (ssl_con2,localhost,root,,,,,SSL); + + # no hang if we get here, close and retry + disconnect ssl_con2; + disconnect ssl_con; +} +--enable_query_log +--enable_result_log + +connect (ssl_con,localhost,root,,,,,SSL); + +drop table t1; + diff --git a/mysql-test/t/ssl_big.test b/mysql-test/t/ssl_big.test new file mode 100644 index 00000000000..58c11899e55 --- /dev/null +++ b/mysql-test/t/ssl_big.test @@ -0,0 +1,62 @@ +# Turn on ssl between the client and server +# and run a number of tests + +-- source include/have_ssl.inc + +connect (ssl_con,localhost,root,,,,,SSL); + +# Check ssl turned on +SHOW STATUS LIKE 'Ssl_cipher'; + +# Source select test case +-- source include/common-tests.inc + +# Check ssl turned on +SHOW STATUS LIKE 'Ssl_cipher'; + +disconnect ssl_con; + + +# +# Bug #29579 Clients using SSL can hang the server +# + +connect (ssl_con,localhost,root,,,,,SSL); + +create table t1 (a int); + +disconnect ssl_con; + +let $count= 2000; +while ($count) +{ + + connect (ssl_con,localhost,root,,,,,SSL); + + let $i= 1; + while ($i) + { + eval insert into t1 values ($count); + dec $count; + dec $i; + } + + # This select causes the net buffer to fill as the server sends the results + # but the client doesn't reap the results. The results are larger each time + # through the loop, so that eventually the buffer is completely full + # at the exact moment the server attempts to the close the connection with + # the lock held. + send select * from t1; + + # now send the quit the command so the server will initiate the shutdown. + send_quit ssl_con; + + # if the server is hung, this will hang too: + connect (ssl_con2,localhost,root,,,,,SSL); + + # no hang if we get here, close and retry + disconnect ssl_con2; + + disconnect ssl_con; +} + diff --git a/vio/viossl.c b/vio/viossl.c index 5e4203a3fb5..861989136d3 100644 --- a/vio/viossl.c +++ b/vio/viossl.c @@ -123,6 +123,16 @@ int vio_ssl_close(Vio *vio) if (ssl) { + /* + THE SSL standard says that SSL sockets must send and receive a close_notify + alert on socket shutdown to avoid truncation attacks. However, this can + cause problems since we often hold a lock during shutdown and this IO can + take an unbounded amount of time to complete. Since our packets are self + describing with length, we aren't vunerable to these attacks. Therefore, + we just shutdown by closing the socket (quiet shutdown). + */ + SSL_set_quiet_shutdown(ssl, 1); + switch ((r= SSL_shutdown(ssl))) { case 1: From d2e45f205cd9e6d6caf2051cc5f7e3fd2eb6fabf Mon Sep 17 00:00:00 2001 From: "dkatz@damien-katzs-computer.local" <> Date: Fri, 13 Jul 2007 00:45:54 -0400 Subject: [PATCH 12/24] Minor fixes for test failures and compiler warnings for Bug #29579. --- extra/yassl/include/yassl_int.hpp | 2 +- extra/yassl/src/yassl_int.cpp | 2 +- mysql-test/r/mysqltest.result | 2 +- mysql-test/t/mysqltest.test | 2 +- mysql-test/t/ssl_big.test | 62 ------------------------------- 5 files changed, 4 insertions(+), 66 deletions(-) delete mode 100644 mysql-test/t/ssl_big.test diff --git a/extra/yassl/include/yassl_int.hpp b/extra/yassl/include/yassl_int.hpp index b207f0bffbd..b7bd35f5fa2 100644 --- a/extra/yassl/include/yassl_int.hpp +++ b/extra/yassl/include/yassl_int.hpp @@ -584,7 +584,7 @@ class SSL { Socket socket_; // socket wrapper Buffers buffers_; // buffered handshakes and data Log log_; // logger - bool quietShutdown_; + bool quietShutdown_; // shutdown without handshakes // optimization variables bool has_data_; // buffered data ready? diff --git a/extra/yassl/src/yassl_int.cpp b/extra/yassl/src/yassl_int.cpp index ba4678d70b9..f5ab2f200a5 100644 --- a/extra/yassl/src/yassl_int.cpp +++ b/extra/yassl/src/yassl_int.cpp @@ -291,7 +291,7 @@ const ClientKeyFactory& sslFactory::getClientKey() const SSL::SSL(SSL_CTX* ctx) : secure_(ctx->getMethod()->getVersion(), crypto_.use_random(), ctx->getMethod()->getSide(), ctx->GetCiphers(), ctx, - ctx->GetDH_Parms().set_), has_data_(false), quietShutdown_(false) + ctx->GetDH_Parms().set_), quietShutdown_(false), has_data_(false) { if (int err = crypto_.get_random().GetError()) { SetError(YasslError(err)); diff --git a/mysql-test/r/mysqltest.result b/mysql-test/r/mysqltest.result index 8cf5f99dca3..55f78d22272 100644 --- a/mysql-test/r/mysqltest.result +++ b/mysql-test/r/mysqltest.result @@ -420,7 +420,7 @@ mysqltest: At line 1: query 'connect con2,localhost,root,,illegal_db' failed: 1 mysqltest: At line 1: Illegal argument for port: 'illegal_port' mysqltest: At line 1: Illegal option to connect: SMTP OK -mysqltest: In included file "MYSQLTEST_VARDIR/tmp/mysqltest.sql": At line 7: Connection limit exhausted, you can have max 128 connections +mysqltest: The test didn't produce any output mysqltest: In included file "MYSQLTEST_VARDIR/tmp/mysqltest.sql": At line 3: connection 'test_con1' not found in connection pool mysqltest: In included file "MYSQLTEST_VARDIR/tmp/mysqltest.sql": At line 2: Connection test_con1 already exists connect(localhost,root,,test,MASTER_PORT,MASTER_SOCKET); diff --git a/mysql-test/t/mysqltest.test b/mysql-test/t/mysqltest.test index aa0e2f89382..b01579dce53 100644 --- a/mysql-test/t/mysqltest.test +++ b/mysql-test/t/mysqltest.test @@ -1263,7 +1263,7 @@ while ($i) EOF --exec echo "source $MYSQLTEST_VARDIR/tmp/mysqltest.sql; echo OK;" | $MYSQL_TEST 2>&1 -# Repeat connect/disconnect, exceed max number of connections +# Repeat connect/disconnect --write_file $MYSQLTEST_VARDIR/tmp/mysqltest.sql let $i=200; while ($i) diff --git a/mysql-test/t/ssl_big.test b/mysql-test/t/ssl_big.test deleted file mode 100644 index 58c11899e55..00000000000 --- a/mysql-test/t/ssl_big.test +++ /dev/null @@ -1,62 +0,0 @@ -# Turn on ssl between the client and server -# and run a number of tests - --- source include/have_ssl.inc - -connect (ssl_con,localhost,root,,,,,SSL); - -# Check ssl turned on -SHOW STATUS LIKE 'Ssl_cipher'; - -# Source select test case --- source include/common-tests.inc - -# Check ssl turned on -SHOW STATUS LIKE 'Ssl_cipher'; - -disconnect ssl_con; - - -# -# Bug #29579 Clients using SSL can hang the server -# - -connect (ssl_con,localhost,root,,,,,SSL); - -create table t1 (a int); - -disconnect ssl_con; - -let $count= 2000; -while ($count) -{ - - connect (ssl_con,localhost,root,,,,,SSL); - - let $i= 1; - while ($i) - { - eval insert into t1 values ($count); - dec $count; - dec $i; - } - - # This select causes the net buffer to fill as the server sends the results - # but the client doesn't reap the results. The results are larger each time - # through the loop, so that eventually the buffer is completely full - # at the exact moment the server attempts to the close the connection with - # the lock held. - send select * from t1; - - # now send the quit the command so the server will initiate the shutdown. - send_quit ssl_con; - - # if the server is hung, this will hang too: - connect (ssl_con2,localhost,root,,,,,SSL); - - # no hang if we get here, close and retry - disconnect ssl_con2; - - disconnect ssl_con; -} - From 0a308745892bd99e4f5582b233b6daa4f3d38593 Mon Sep 17 00:00:00 2001 From: "dkatz@damien-katzs-computer.local" <> Date: Fri, 13 Jul 2007 01:55:04 -0400 Subject: [PATCH 13/24] When opening a new connecgtion, changed mysqltest to prefer a brand new connection slot over an existing, closed slot. Fixes a problem with reused slots that can cause tests to fail. bug#29579 --- client/mysqltest.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/client/mysqltest.c b/client/mysqltest.c index 2e964056a73..d1ec753b54b 100644 --- a/client/mysqltest.c +++ b/client/mysqltest.c @@ -3777,14 +3777,14 @@ void do_connect(struct st_command *command) if (find_connection_by_name(ds_connection_name.str)) die("Connection %s already exists", ds_connection_name.str); - - if (!(con_slot= find_connection_by_name("-closed_connection-"))) + + if (next_con != connections_end) + con_slot= next_con; + else { - if (next_con == connections_end) + if (!(con_slot= find_connection_by_name("-closed_connection-"))) die("Connection limit exhausted, you can have max %d connections", (int) (sizeof(connections)/sizeof(struct st_connection))); - - con_slot= next_con; } if (!mysql_init(&con_slot->mysql)) From a11153663dcc87326e0e1947340762a74eed6a11 Mon Sep 17 00:00:00 2001 From: "tomas@whalegate.ndb.mysql.com" <> Date: Fri, 13 Jul 2007 14:31:40 +0200 Subject: [PATCH 14/24] avoid some sporadic startup issues --- mysql-test/include/have_ndb.inc | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/mysql-test/include/have_ndb.inc b/mysql-test/include/have_ndb.inc index cb2f2f7cd9e..d087a45a15a 100644 --- a/mysql-test/include/have_ndb.inc +++ b/mysql-test/include/have_ndb.inc @@ -1,6 +1,10 @@ # Check that server is compiled and started with support for NDB -disable_query_log; ---require r/true.require -select support = 'Enabled' as `TRUE` from information_schema.engines where engine = 'ndbcluster'; ---source include/ndb_not_readonly.inc -enable_query_log; +#disable_query_log; +#--require r/true.require +#select support = 'Enabled' as `TRUE` from information_schema.engines where engine = 'ndbcluster'; +#--source include/ndb_not_readonly.inc +#enable_query_log; +# always make sure we have both mysql servers started ok before test starts +# there are some initial startup bugs that are avoided by doing this, avoiding sporadic +# failures in mysql-test-run +--source include/have_multi_ndb.inc From b46bb155d66df3974117c4822965b73f73c6d613 Mon Sep 17 00:00:00 2001 From: "tomas@whalegate.ndb.mysql.com" <> Date: Fri, 13 Jul 2007 15:30:36 +0200 Subject: [PATCH 15/24] Bug #29762 The ndbapi-examples don't work as expected due to api changes in MySQL 5.1.16] --- .../ndbapi-examples/ndbapi_simple/ndbapi_simple.cpp | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/storage/ndb/ndbapi-examples/ndbapi_simple/ndbapi_simple.cpp b/storage/ndb/ndbapi-examples/ndbapi_simple/ndbapi_simple.cpp index 0a4f6d92f2c..4e82fc3e42b 100644 --- a/storage/ndb/ndbapi-examples/ndbapi_simple/ndbapi_simple.cpp +++ b/storage/ndb/ndbapi-examples/ndbapi_simple/ndbapi_simple.cpp @@ -281,12 +281,14 @@ static void do_read(Ndb &myNdb) if (myRecAttr == NULL) APIERROR(myTransaction->getNdbError()); if(myTransaction->execute( NdbTransaction::Commit ) == -1) - if (i == 3) { - std::cout << "Detected that deleted tuple doesn't exist!" << std::endl; - } else { - APIERROR(myTransaction->getNdbError()); - } + APIERROR(myTransaction->getNdbError()); + if (myTransaction->getNdbError().classification == NdbError::NoDataFound) + if (i == 3) + std::cout << "Detected that deleted tuple doesn't exist!" << std::endl; + else + APIERROR(myTransaction->getNdbError()); + if (i != 3) { printf(" %2d %2d\n", i, myRecAttr->u_32_value()); } From 6ecee9d5dafeed4f078d86851b78be016db4c28c Mon Sep 17 00:00:00 2001 From: "tomas@whalegate.ndb.mysql.com" <> Date: Fri, 13 Jul 2007 16:06:12 +0200 Subject: [PATCH 16/24] update bug dependency on failing test --- mysql-test/{ => suite/ndb}/r/ndb_binlog_format.result | 0 mysql-test/{ => suite/ndb}/t/ndb_binlog_format.test | 0 mysql-test/suite/rpl_ndb/t/disabled.def | 5 ++--- 3 files changed, 2 insertions(+), 3 deletions(-) rename mysql-test/{ => suite/ndb}/r/ndb_binlog_format.result (100%) rename mysql-test/{ => suite/ndb}/t/ndb_binlog_format.test (100%) diff --git a/mysql-test/r/ndb_binlog_format.result b/mysql-test/suite/ndb/r/ndb_binlog_format.result similarity index 100% rename from mysql-test/r/ndb_binlog_format.result rename to mysql-test/suite/ndb/r/ndb_binlog_format.result diff --git a/mysql-test/t/ndb_binlog_format.test b/mysql-test/suite/ndb/t/ndb_binlog_format.test similarity index 100% rename from mysql-test/t/ndb_binlog_format.test rename to mysql-test/suite/ndb/t/ndb_binlog_format.test diff --git a/mysql-test/suite/rpl_ndb/t/disabled.def b/mysql-test/suite/rpl_ndb/t/disabled.def index f5c99129c89..e4c1d875a67 100644 --- a/mysql-test/suite/rpl_ndb/t/disabled.def +++ b/mysql-test/suite/rpl_ndb/t/disabled.def @@ -15,9 +15,8 @@ rpl_ndb_circular_simplex : BUG#27972 2007-04-20 mats Slave cannot start where it rpl_ndb_2innodb : BUG#19227 2006-04-20 pekka pk delete apparently not replicated rpl_ndb_2myisam : BUG#19227 Seems to pass currently rpl_ndb_dd_partitions : BUG#19259 2006-04-21 rpl_ndb_dd_partitions fails on s/AMD -rpl_ndb_innodb2ndb : Bug #19710 Cluster replication to partition table fails on DELETE FROM statement -rpl_ndb_myisam2ndb : Bug #19710 Cluster replication to partition table fails on DELETE FROM statement -#rpl_row_blob_innodb : BUG#18980 2006-04-10 kent Test fails randomly +rpl_ndb_innodb2ndb : Bug#29549 rpl_ndb_myisam2ndb,rpl_ndb_innodb2ndb failed on Solaris for pack_length issue +rpl_ndb_myisam2ndb : Bug#29549 rpl_ndb_myisam2ndb,rpl_ndb_innodb2ndb failed on Solaris for pack_length issue rpl_ndb_ddl : BUG#28798 2007-05-31 lars Valgrind failure in NDB rpl_ndb_mix_innodb : BUG#28123 rpl_ndb_mix_innodb.test casue slave to core on sol10-sparc-a rpl_ndb_ctype_ucs2_def : BUG#27404 util thd mysql_parse sig11 when mysqld default multibyte charset From 5cbe511f3b8309093ec9314e6eace5a2d39d0db1 Mon Sep 17 00:00:00 2001 From: "tnurnberg@sin.intern.azundris.com" <> Date: Fri, 13 Jul 2007 17:50:58 +0200 Subject: [PATCH 17/24] Bug#27198: Error returns from time() are ignored gettimeofday() can fail and presumably, so can time(). Keep an eye on it. Since we have no data on this at all so far, we just retry on failure (and log the event), assuming that this is just an intermittant failure. This might of course hang the threat until we succeed. Once we know more about these failures, an appropriate more clever scheme may be picked (only try so many times per thread, etc., if that fails, return last "good" time() we got or some such). Using sql_print_information() to log as this probably only occurs in high load scenarios where the debug- trace likely is disabled (or might interfere with testing the effect). No test-case as this is a non-deterministic issue. --- sql/mysql_priv.h | 17 ++++++++--------- sql/sql_class.h | 26 +++++++++++++++++++++----- 2 files changed, 29 insertions(+), 14 deletions(-) diff --git a/sql/mysql_priv.h b/sql/mysql_priv.h index 3972a01f7ba..173bfe678e8 100644 --- a/sql/mysql_priv.h +++ b/sql/mysql_priv.h @@ -302,6 +302,14 @@ inline THD *_current_thd(void) } #define current_thd _current_thd() +/* log.cc */ +void sql_perror(const char *message); + +void vprint_msg_to_log( enum loglevel level, const char *format, va_list args ); +void sql_print_error( const char *format, ... ); +void sql_print_warning( const char *format, ...); +void sql_print_information( const char *format, ...); + #include "sql_string.h" #include "sql_list.h" #include "sql_map.h" @@ -657,15 +665,6 @@ void key_unpack(String *to,TABLE *form,uint index); bool check_if_key_used(TABLE *table, uint idx, List &fields); void init_errmessage(void); -void sql_perror(const char *message); - -void vprint_msg_to_log( enum loglevel level, const char *format, va_list args ); -void sql_print_error( const char *format, ... ); -void sql_print_warning( const char *format, ...); -void sql_print_information( const char *format, ...); - - - bool fn_format_relative_to_data_home(my_string to, const char *name, const char *dir, const char *extension); bool open_log(MYSQL_LOG *log, const char *hostname, diff --git a/sql/sql_class.h b/sql/sql_class.h index 17d371d3dc0..25828ac2b7e 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -569,17 +569,33 @@ public: proc_info = old_msg; pthread_mutex_unlock(&mysys_var->mutex); } + + static inline void safe_time(time_t *t) + { + /** + Wrapper around time() which retries on error (-1) + + @details + This is needed because, despite the documentation, time() may fail + in some circumstances. Here we retry time() until it succeeds, and + log the failure so that performance problems related to this can be + identified. + */ + while(unlikely(time(t) == ((time_t) -1))) + sql_print_information("time() failed with %d", errno); + } + inline time_t query_start() { query_start_used=1; return start_time; } - inline void set_time() { if (user_time) start_time=time_after_lock=user_time; else time_after_lock=time(&start_time); } - inline void end_time() { time(&start_time); } + inline void set_time() { if (user_time) start_time=time_after_lock=user_time; else { safe_time(&start_time); time_after_lock= start_time; }} + inline void end_time() { safe_time(&start_time); } inline void set_time(time_t t) { time_after_lock=start_time=user_time=t; } - inline void lock_time() { time(&time_after_lock); } + inline void lock_time() { safe_time(&time_after_lock); } inline void insert_id(ulonglong id) { last_insert_id=id; insert_id_used=1; } inline ulonglong insert_id(void) { if (!last_insert_id_used) - { + { last_insert_id_used=1; current_insert_id=last_insert_id; } @@ -588,7 +604,7 @@ public: inline ulonglong found_rows(void) { return limit_found_rows; - } + } inline bool active_transaction() { #ifdef USING_TRANSACTIONS From 11a0cf3a6fa72f19c1eaf880a2c0fcda7b161d52 Mon Sep 17 00:00:00 2001 From: "ramil/ram@mysql.com/ramil.myoffice.izhnet.ru" <> Date: Sat, 14 Jul 2007 00:13:37 +0500 Subject: [PATCH 18/24] Fix for bug #29253: csv table reportedly marked as crashed Problem: the data file changes made during delete/update are not visible to other threads as the file is reopened, so reading data with old descriptors might miss the changes. Fix: reopen the data file before reading if it was reopened during delete/update to ensure there's no data behind. Note: there's no simple test case. --- storage/csv/ha_tina.cc | 52 +++++++++++++++++++++++++++++++++++++----- storage/csv/ha_tina.h | 3 +++ 2 files changed, 49 insertions(+), 6 deletions(-) diff --git a/storage/csv/ha_tina.cc b/storage/csv/ha_tina.cc index 07bd28f8e65..34c1fcde58d 100644 --- a/storage/csv/ha_tina.cc +++ b/storage/csv/ha_tina.cc @@ -163,6 +163,7 @@ static TINA_SHARE *get_share(const char *table_name, TABLE *table) share->rows_recorded= 0; share->update_file_opened= FALSE; share->tina_write_opened= FALSE; + share->data_file_version= 0; strmov(share->table_name, table_name); fn_format(share->data_file_name, table_name, "", CSV_EXT, MY_REPLACE_EXT|MY_UNPACK_FILENAME); @@ -440,7 +441,7 @@ ha_tina::ha_tina(handlerton *hton, TABLE_SHARE *table_arg) */ current_position(0), next_position(0), local_saved_data_file_length(0), file_buff(0), chain_alloced(0), chain_size(DEFAULT_CHAIN_LENGTH), - records_is_known(0) + local_data_file_version(0), records_is_known(0) { /* Set our original buffers from pre-allocated memory */ buffer.set((char*)byte_buffer, IO_SIZE, &my_charset_bin); @@ -815,6 +816,7 @@ int ha_tina::open(const char *name, int mode, uint open_options) DBUG_RETURN(HA_ERR_CRASHED_ON_USAGE); } + local_data_file_version= share->data_file_version; if ((data_file= my_open(share->data_file_name, O_RDONLY, MYF(0))) == -1) DBUG_RETURN(0); @@ -985,6 +987,33 @@ int ha_tina::delete_row(const uchar * buf) } +/** + @brief Initialize the data file. + + @details Compare the local version of the data file with the shared one. + If they differ, there are some changes behind and we have to reopen + the data file to make the changes visible. + Call @c file_buff->init_buff() at the end to read the beginning of the + data file into buffer. + + @retval 0 OK. + @retval 1 There was an error. +*/ + +int ha_tina::init_data_file() +{ + if (local_data_file_version != share->data_file_version) + { + local_data_file_version= share->data_file_version; + if (my_close(data_file, MYF(0)) || + (data_file= my_open(share->data_file_name, O_RDONLY, MYF(0))) == -1) + return 1; + } + file_buff->init_buff(data_file); + return 0; +} + + /* All table scans call this first. The order of a table scan is: @@ -1021,9 +1050,8 @@ int ha_tina::rnd_init(bool scan) DBUG_ENTER("ha_tina::rnd_init"); /* set buffer to the beginning of the file */ - file_buff->init_buff(data_file); - if (share->crashed) - DBUG_RETURN(HA_ERR_CRASHED_ON_USAGE); + if (share->crashed || init_data_file()) + DBUG_RETURN(HA_ERR_CRASHED_ON_USAGE); current_position= next_position= 0; stats.records= 0; @@ -1246,6 +1274,16 @@ int ha_tina::rnd_end() /* Open the file again */ if (((data_file= my_open(share->data_file_name, O_RDONLY, MYF(0))) == -1)) DBUG_RETURN(-1); + /* + As we reopened the data file, increase share->data_file_version + in order to force other threads waiting on a table lock and + have already opened the table to reopen the data file. + That makes the latest changes become visible to them. + Update local_data_file_version as no need to reopen it in the + current thread. + */ + share->data_file_version++; + local_data_file_version= share->data_file_version; /* The datafile is consistent at this point and the write filedes is closed, so nothing worrying will happen to it in case of a crash. @@ -1308,7 +1346,8 @@ int ha_tina::repair(THD* thd, HA_CHECK_OPT* check_opt) DBUG_RETURN(HA_ERR_OUT_OF_MEM); /* position buffer to the start of the file */ - file_buff->init_buff(data_file); + if (init_data_file()) + DBUG_RETURN(HA_ERR_CRASHED_ON_REPAIR); /* Local_saved_data_file_length is initialized during the lock phase. @@ -1480,7 +1519,8 @@ int ha_tina::check(THD* thd, HA_CHECK_OPT* check_opt) DBUG_RETURN(HA_ERR_OUT_OF_MEM); /* position buffer to the start of the file */ - file_buff->init_buff(data_file); + if (init_data_file()) + DBUG_RETURN(HA_ERR_CRASHED); /* Local_saved_data_file_length is initialized during the lock phase. diff --git a/storage/csv/ha_tina.h b/storage/csv/ha_tina.h index 2e43f1a2307..5bb3e9a79a0 100644 --- a/storage/csv/ha_tina.h +++ b/storage/csv/ha_tina.h @@ -49,6 +49,7 @@ typedef struct st_tina_share { File tina_write_filedes; /* File handler for readers */ bool crashed; /* Meta file is crashed */ ha_rows rows_recorded; /* Number of rows in tables */ + uint data_file_version; /* Version of the data file used */ } TINA_SHARE; struct tina_set { @@ -79,12 +80,14 @@ class ha_tina: public handler tina_set *chain_ptr; uchar chain_alloced; uint32 chain_size; + uint local_data_file_version; /* Saved version of the data file used */ bool records_is_known; private: bool get_write_pos(off_t *end_pos, tina_set *closest_hole); int open_update_temp_file_if_needed(); int init_tina_writer(); + int init_data_file(); public: ha_tina(handlerton *hton, TABLE_SHARE *table_arg); From d00282ae3604e2638be6894faca4998fb2c11402 Mon Sep 17 00:00:00 2001 From: "tomas@whalegate.ndb.mysql.com" <> Date: Fri, 13 Jul 2007 22:21:19 +0200 Subject: [PATCH 19/24] avoid multiple defines of server1/2 --- mysql-test/include/ndb_master-slave.inc | 7 ++++++- mysql-test/t/ndb_multi.test | 1 - mysql-test/t/ndb_multi_row.test | 1 - 3 files changed, 6 insertions(+), 3 deletions(-) diff --git a/mysql-test/include/ndb_master-slave.inc b/mysql-test/include/ndb_master-slave.inc index 81dd63be78a..ad4eb103803 100644 --- a/mysql-test/include/ndb_master-slave.inc +++ b/mysql-test/include/ndb_master-slave.inc @@ -4,7 +4,12 @@ connect (slave,127.0.0.1,root,,test,$SLAVE_MYPORT,); connect (slave1,127.0.0.1,root,,test,$SLAVE_MYPORT,); connection slave; --- source include/have_ndb.inc +# Check that server is compiled and started with support for NDB +disable_query_log; +--require r/true.require +select support = 'Enabled' as `TRUE` from information_schema.engines where engine = 'ndbcluster'; +--source include/ndb_not_readonly.inc +enable_query_log; -- source include/master-slave-reset.inc diff --git a/mysql-test/t/ndb_multi.test b/mysql-test/t/ndb_multi.test index 3482db1d1b2..b8e052d606b 100644 --- a/mysql-test/t/ndb_multi.test +++ b/mysql-test/t/ndb_multi.test @@ -1,4 +1,3 @@ --- source include/have_ndb.inc -- source include/have_multi_ndb.inc -- source include/not_embedded.inc diff --git a/mysql-test/t/ndb_multi_row.test b/mysql-test/t/ndb_multi_row.test index 632a9fda89a..543e282b900 100644 --- a/mysql-test/t/ndb_multi_row.test +++ b/mysql-test/t/ndb_multi_row.test @@ -1,4 +1,3 @@ --- source include/have_ndb.inc -- source include/have_multi_ndb.inc -- source include/not_embedded.inc -- source include/have_binlog_format_row.inc From 07656398a8961f724c91348d1874ba1915fb693e Mon Sep 17 00:00:00 2001 From: "tomas@whalegate.ndb.mysql.com" <> Date: Fri, 13 Jul 2007 22:45:05 +0200 Subject: [PATCH 20/24] correct cluster support check --- mysql-test/include/ndb_master-slave.inc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mysql-test/include/ndb_master-slave.inc b/mysql-test/include/ndb_master-slave.inc index ad4eb103803..1568072202b 100644 --- a/mysql-test/include/ndb_master-slave.inc +++ b/mysql-test/include/ndb_master-slave.inc @@ -7,7 +7,7 @@ connection slave; # Check that server is compiled and started with support for NDB disable_query_log; --require r/true.require -select support = 'Enabled' as `TRUE` from information_schema.engines where engine = 'ndbcluster'; +select (support = 'YES' or support = 'DEFAULT') as `TRUE` from information_schema.engines where engine = 'ndbcluster'; --source include/ndb_not_readonly.inc enable_query_log; From 639fd4c555360e6ac34bb594337b66d7b4faa857 Mon Sep 17 00:00:00 2001 From: "dkatz@damien-katzs-computer.local" <> Date: Mon, 16 Jul 2007 14:53:05 -0400 Subject: [PATCH 21/24] Bug #29692 Single row inserts can incorrectly report a huge number of row insertions This bug was caused by unitialized value that was the result of a bad 5.0 merge. --- sql/sql_class.h | 20 ++++++++++++++++---- sql/sql_insert.cc | 9 +++++---- tests/mysql_client_test.c | 33 +++++++++++++++++++++++++++++++++ 3 files changed, 54 insertions(+), 8 deletions(-) diff --git a/sql/sql_class.h b/sql/sql_class.h index 004c4aa4f5a..52feee47499 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -65,11 +65,23 @@ typedef struct st_user_var_events #define RP_LOCK_LOG_IS_ALREADY_LOCKED 1 #define RP_FORCE_ROTATE 2 +/* + The COPY_INFO structure is used by INSERT/REPLACE code. + The schema of the row counting by the INSERT/INSERT ... ON DUPLICATE KEY + UPDATE code: + If a row is inserted then the copied variable is incremented. + If a row is updated by the INSERT ... ON DUPLICATE KEY UPDATE and the + new data differs from the old one then the copied and the updated + variables are incremented. + The touched variable is incremented if a row was touched by the update part + of the INSERT ... ON DUPLICATE KEY UPDATE no matter whether the row + was actually changed or not. +*/ typedef struct st_copy_info { - ha_rows records; - ha_rows deleted; - ha_rows updated; - ha_rows copied; + ha_rows records; /* Number of processed records */ + ha_rows deleted; /* Number of deleted records */ + ha_rows updated; /* Number of updated records */ + ha_rows copied; /* Number of copied records */ ha_rows error_count; ha_rows touched; /* Number of touched records */ enum enum_duplicates handle_duplicates; diff --git a/sql/sql_insert.cc b/sql/sql_insert.cc index 11db88d8f5e..b4cf5231827 100644 --- a/sql/sql_insert.cc +++ b/sql/sql_insert.cc @@ -661,7 +661,7 @@ bool mysql_insert(THD *thd,TABLE_LIST *table_list, /* Fill in the given fields and dump it to the table file */ - info.records= info.deleted= info.copied= info.updated= 0; + bzero((char*) &info,sizeof(info)); info.ignore= ignore; info.handle_duplicates=duplic; info.update_fields= &update_fields; @@ -1421,6 +1421,10 @@ int write_record(THD *thd, TABLE *table,COPY_INFO *info) goto before_trg_err; table->file->restore_auto_increment(prev_insert_id); + if (table->next_number_field) + table->file->adjust_next_insert_id_after_explicit_value( + table->next_number_field->val_int()); + info->touched++; if ((table->file->ha_table_flags() & HA_PARTIAL_COLUMN_READ) || compare_record(table)) { @@ -1448,9 +1452,6 @@ int write_record(THD *thd, TABLE *table,COPY_INFO *info) handled separately by THD::arg_of_last_insert_id_function. */ insert_id_for_cur_row= table->file->insert_id_for_cur_row= 0; - if (table->next_number_field) - table->file->adjust_next_insert_id_after_explicit_value( - table->next_number_field->val_int()); trg_error= (table->triggers && table->triggers->process_triggers(thd, TRG_EVENT_UPDATE, TRG_ACTION_AFTER, TRUE)); diff --git a/tests/mysql_client_test.c b/tests/mysql_client_test.c index cb1561ad6f5..51f627a16de 100644 --- a/tests/mysql_client_test.c +++ b/tests/mysql_client_test.c @@ -16271,6 +16271,38 @@ static void test_bug27592() } +/* + Bug #29692 Single row inserts can incorrectly report a huge number of + row insertions +*/ + +static void test_bug29692() +{ + MYSQL* conn; + + if (!(conn= mysql_init(NULL))) + { + myerror("test_bug29692 init failed"); + exit(1); + } + + if (!(mysql_real_connect(conn, opt_host, opt_user, + opt_password, opt_db ? opt_db:"test", opt_port, + opt_unix_socket, CLIENT_FOUND_ROWS))) + { + myerror("test_bug29692 connection failed"); + mysql_close(mysql); + exit(1); + } + myquery(mysql_query(conn, "drop table if exists t1")); + myquery(mysql_query(conn, "create table t1(f1 int)")); + myquery(mysql_query(conn, "insert into t1 values(1)")); + DIE_UNLESS(1 == mysql_affected_rows(conn)); + myquery(mysql_query(conn, "drop table t1")); + mysql_close(conn); +} + + /* Read and parse arguments and MySQL options from my.cnf */ @@ -16560,6 +16592,7 @@ static struct my_tests_st my_tests[]= { { "test_bug28505", test_bug28505 }, { "test_bug28934", test_bug28934 }, { "test_bug27592", test_bug27592 }, + { "test_bug29692", test_bug29692 }, { 0, 0 } }; From 5d0b7dea044f4607fb24e35fb5ef23bec7911ba0 Mon Sep 17 00:00:00 2001 From: "cmiller@zippy.cornsilk.net" <> Date: Wed, 18 Jul 2007 12:27:54 -0400 Subject: [PATCH 22/24] Move the filling of the table_name column above the initialization, so that the init function has access to the name. --- sql/sql_show.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sql/sql_show.cc b/sql/sql_show.cc index c6bf816b290..4d0783a9a92 100644 --- a/sql/sql_show.cc +++ b/sql/sql_show.cc @@ -5904,6 +5904,7 @@ int initialize_schema_table(st_plugin_int *plugin) schema_table->old_format= make_old_format; schema_table->idx_field1= -1, schema_table->idx_field2= -1; + schema_table->table_name= plugin->name.str; if (plugin->plugin->init(schema_table)) { @@ -5911,7 +5912,6 @@ int initialize_schema_table(st_plugin_int *plugin) plugin->name.str); goto err; } - schema_table->table_name= plugin->name.str; } DBUG_RETURN(0); From 4463163c1165b6d95d1637e00336c89f3851dfb1 Mon Sep 17 00:00:00 2001 From: "cmiller@zippy.cornsilk.net" <> Date: Wed, 18 Jul 2007 13:37:56 -0400 Subject: [PATCH 23/24] Re-set the plugin name so that we can be sure the plugin init() function doesn't set it to something else. --- sql/sql_show.cc | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/sql/sql_show.cc b/sql/sql_show.cc index 4d0783a9a92..5b8cb93baab 100644 --- a/sql/sql_show.cc +++ b/sql/sql_show.cc @@ -5904,6 +5904,8 @@ int initialize_schema_table(st_plugin_int *plugin) schema_table->old_format= make_old_format; schema_table->idx_field1= -1, schema_table->idx_field2= -1; + + /* Make the name available to the init() function. */ schema_table->table_name= plugin->name.str; if (plugin->plugin->init(schema_table)) @@ -5912,6 +5914,9 @@ int initialize_schema_table(st_plugin_int *plugin) plugin->name.str); goto err; } + + /* Make sure the plugin name is not set inside the init() function. */ + schema_table->table_name= plugin->name.str; } DBUG_RETURN(0); From f4309e1777300921bfb0d009d29750a50141575f Mon Sep 17 00:00:00 2001 From: "tsmith@ramayana.hindu.god" <> Date: Wed, 18 Jul 2007 15:31:24 -0600 Subject: [PATCH 24/24] ddl_i18n_utf8.test, ddl_i18n_koi8r.test: Don't run test with embedded server; requires external client connections --- mysql-test/t/ddl_i18n_koi8r.test | 2 ++ mysql-test/t/ddl_i18n_utf8.test | 2 ++ 2 files changed, 4 insertions(+) diff --git a/mysql-test/t/ddl_i18n_koi8r.test b/mysql-test/t/ddl_i18n_koi8r.test index e636d801b07..1d16adbad55 100644 --- a/mysql-test/t/ddl_i18n_koi8r.test +++ b/mysql-test/t/ddl_i18n_koi8r.test @@ -30,6 +30,8 @@ # ########################################################################### +# Test requires server to accept client connections (for mysqldump portions) +--source include/not_embedded.inc --source include/have_utf8.inc --source include/have_cp866.inc --source include/have_cp1251.inc diff --git a/mysql-test/t/ddl_i18n_utf8.test b/mysql-test/t/ddl_i18n_utf8.test index 5f032232e56..c80137a58b5 100644 --- a/mysql-test/t/ddl_i18n_utf8.test +++ b/mysql-test/t/ddl_i18n_utf8.test @@ -30,6 +30,8 @@ # ########################################################################### +# Test requires server to accept client connections (for mysqldump portions) +--source include/not_embedded.inc --source include/have_utf8.inc --source include/have_cp866.inc --source include/have_cp1251.inc