List:Commits« Previous MessageNext Message »
From:Christopher Powers Date:June 10 2008 8:01pm
Subject:commit into mysql-6.0-falcon:mysql-6.0-falcon branch (cpowers:2693)
View as plain text  
#At bzr+ssh://bk-internal.mysql.com/bzrroot/server/mysql-6.0-falcon/

 2693 Christopher Powers	2008-06-10 [merge]
      (no message)
added:
  mysql-test/extra/binlog_tests/implicit.test
  mysql-test/suite/binlog/r/binlog_implicit_commit.result
  mysql-test/suite/binlog/t/binlog_implicit_commit.test
  mysql-test/suite/falcon/r/rpl_falcon_bug_37221.result
  mysql-test/suite/falcon/t/rpl_falcon_bug_37221.test
  storage/falcon/SectorBuffer.cpp
  storage/falcon/SectorBuffer.h
  storage/falcon/SectorCache.cpp
  storage/falcon/SectorCache.h
modified:
  .bzr-mysql/default.conf
  sql/set_var.cc
  storage/falcon/Backup.cpp
  storage/falcon/CMakeLists.txt
  storage/falcon/Cache.cpp
  storage/falcon/Cache.h
  storage/falcon/DeferredIndex.h
  storage/falcon/Gopher.cpp
  storage/falcon/Makefile.am
  storage/falcon/SRLDropTableSpace.cpp
  storage/falcon/SerialLog.h
  storage/falcon/SerialLogTransaction.cpp
  storage/falcon/SerialLogTransaction.h
  storage/falcon/SymbolManager.cpp
  storage/falcon/TableSpaceManager.cpp
  storage/falcon/TableSpaceManager.h

=== modified file '.bzr-mysql/default.conf'
--- a/.bzr-mysql/default.conf	2008-05-27 11:53:11 +0000
+++ b/.bzr-mysql/default.conf	2008-06-06 13:22:16 +0000
@@ -1,6 +1,7 @@
 [MYSQL]
 tree_location = bzr+ssh://bk-internal.mysql.com/bzrroot/server/mysql-6.0-falcon/
 post_commit_to = commits@stripped
+post_push_to = commits@stripped
 post_commit_url = bzr+ssh://bk-internal.mysql.com/bzrroot/server/mysql-6.0-falcon/
 tree_name = mysql-6.0-falcon
 project_name = "mysql-6.0-falcon"

=== added file 'mysql-test/extra/binlog_tests/implicit.test'
--- a/mysql-test/extra/binlog_tests/implicit.test	1970-01-01 00:00:00 +0000
+++ b/mysql-test/extra/binlog_tests/implicit.test	2008-06-09 19:32:42 +0000
@@ -0,0 +1,28 @@
+# First part: outside a transaction
+RESET MASTER;
+eval $prepare;
+
+INSERT INTO t1 VALUES (1);
+source include/show_binlog_events.inc;
+eval $statement;
+source include/show_binlog_events.inc;
+if (`select '$cleanup' != ''`) {
+  eval $cleanup;
+}
+
+# Second part: inside a transaction
+RESET MASTER;
+eval $prepare;
+BEGIN;
+INSERT INTO t1 VALUES (2);
+source include/show_binlog_events.inc;
+eval $statement;
+source include/show_binlog_events.inc;
+INSERT INTO t1 VALUES (3);
+source include/show_binlog_events.inc;
+COMMIT;
+source include/show_binlog_events.inc;
+if (`select '$cleanup' != ''`) {
+  eval $cleanup;
+}
+

=== added file 'mysql-test/suite/binlog/r/binlog_implicit_commit.result'
--- a/mysql-test/suite/binlog/r/binlog_implicit_commit.result	1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/binlog/r/binlog_implicit_commit.result	2008-06-09 19:32:42 +0000
@@ -0,0 +1,345 @@
+CREATE TABLE t1 (id INT) ENGINE = InnoDB;
+SET BINLOG_FORMAT = STATEMENT;
+RESET MASTER;
+SET AUTOCOMMIT = 0;
+INSERT INTO t1 VALUES (1);
+show binlog events from <binlog_start>;
+Log_name	Pos	Event_type	Server_id	End_log_pos	Info
+SET AUTOCOMMIT = 1;
+show binlog events from <binlog_start>;
+Log_name	Pos	Event_type	Server_id	End_log_pos	Info
+master-bin.000001	#	Query	#	#	use `test`; BEGIN
+master-bin.000001	#	Query	#	#	use `test`; INSERT INTO t1 VALUES (1)
+master-bin.000001	#	Xid	#	#	COMMIT /* XID */
+COMMIT;
+RESET MASTER;
+SET AUTOCOMMIT = 0;
+BEGIN;
+INSERT INTO t1 VALUES (2);
+show binlog events from <binlog_start>;
+Log_name	Pos	Event_type	Server_id	End_log_pos	Info
+SET AUTOCOMMIT = 1;
+show binlog events from <binlog_start>;
+Log_name	Pos	Event_type	Server_id	End_log_pos	Info
+master-bin.000001	#	Query	#	#	use `test`; BEGIN
+master-bin.000001	#	Query	#	#	use `test`; INSERT INTO t1 VALUES (2)
+master-bin.000001	#	Xid	#	#	COMMIT /* XID */
+INSERT INTO t1 VALUES (3);
+show binlog events from <binlog_start>;
+Log_name	Pos	Event_type	Server_id	End_log_pos	Info
+master-bin.000001	#	Query	#	#	use `test`; BEGIN
+master-bin.000001	#	Query	#	#	use `test`; INSERT INTO t1 VALUES (2)
+master-bin.000001	#	Xid	#	#	COMMIT /* XID */
+master-bin.000001	#	Query	#	#	use `test`; BEGIN
+master-bin.000001	#	Query	#	#	use `test`; INSERT INTO t1 VALUES (3)
+master-bin.000001	#	Xid	#	#	COMMIT /* XID */
+COMMIT;
+show binlog events from <binlog_start>;
+Log_name	Pos	Event_type	Server_id	End_log_pos	Info
+master-bin.000001	#	Query	#	#	use `test`; BEGIN
+master-bin.000001	#	Query	#	#	use `test`; INSERT INTO t1 VALUES (2)
+master-bin.000001	#	Xid	#	#	COMMIT /* XID */
+master-bin.000001	#	Query	#	#	use `test`; BEGIN
+master-bin.000001	#	Query	#	#	use `test`; INSERT INTO t1 VALUES (3)
+master-bin.000001	#	Xid	#	#	COMMIT /* XID */
+COMMIT;
+RESET MASTER;
+SET AUTOCOMMIT = 1;
+INSERT INTO t1 VALUES (1);
+show binlog events from <binlog_start>;
+Log_name	Pos	Event_type	Server_id	End_log_pos	Info
+master-bin.000001	#	Query	#	#	use `test`; BEGIN
+master-bin.000001	#	Query	#	#	use `test`; INSERT INTO t1 VALUES (1)
+master-bin.000001	#	Xid	#	#	COMMIT /* XID */
+SET AUTOCOMMIT = 1;
+show binlog events from <binlog_start>;
+Log_name	Pos	Event_type	Server_id	End_log_pos	Info
+master-bin.000001	#	Query	#	#	use `test`; BEGIN
+master-bin.000001	#	Query	#	#	use `test`; INSERT INTO t1 VALUES (1)
+master-bin.000001	#	Xid	#	#	COMMIT /* XID */
+COMMIT;
+RESET MASTER;
+SET AUTOCOMMIT = 1;
+BEGIN;
+INSERT INTO t1 VALUES (2);
+show binlog events from <binlog_start>;
+Log_name	Pos	Event_type	Server_id	End_log_pos	Info
+SET AUTOCOMMIT = 1;
+show binlog events from <binlog_start>;
+Log_name	Pos	Event_type	Server_id	End_log_pos	Info
+INSERT INTO t1 VALUES (3);
+show binlog events from <binlog_start>;
+Log_name	Pos	Event_type	Server_id	End_log_pos	Info
+COMMIT;
+show binlog events from <binlog_start>;
+Log_name	Pos	Event_type	Server_id	End_log_pos	Info
+master-bin.000001	#	Query	#	#	use `test`; BEGIN
+master-bin.000001	#	Query	#	#	use `test`; INSERT INTO t1 VALUES (2)
+master-bin.000001	#	Query	#	#	use `test`; INSERT INTO t1 VALUES (3)
+master-bin.000001	#	Xid	#	#	COMMIT /* XID */
+COMMIT;
+RESET MASTER;
+SET AUTOCOMMIT = 0;
+INSERT INTO t1 VALUES (1);
+show binlog events from <binlog_start>;
+Log_name	Pos	Event_type	Server_id	End_log_pos	Info
+SET AUTOCOMMIT = 0;
+show binlog events from <binlog_start>;
+Log_name	Pos	Event_type	Server_id	End_log_pos	Info
+COMMIT;
+RESET MASTER;
+SET AUTOCOMMIT = 0;
+BEGIN;
+INSERT INTO t1 VALUES (2);
+show binlog events from <binlog_start>;
+Log_name	Pos	Event_type	Server_id	End_log_pos	Info
+SET AUTOCOMMIT = 0;
+show binlog events from <binlog_start>;
+Log_name	Pos	Event_type	Server_id	End_log_pos	Info
+INSERT INTO t1 VALUES (3);
+show binlog events from <binlog_start>;
+Log_name	Pos	Event_type	Server_id	End_log_pos	Info
+COMMIT;
+show binlog events from <binlog_start>;
+Log_name	Pos	Event_type	Server_id	End_log_pos	Info
+master-bin.000001	#	Query	#	#	use `test`; BEGIN
+master-bin.000001	#	Query	#	#	use `test`; INSERT INTO t1 VALUES (2)
+master-bin.000001	#	Query	#	#	use `test`; INSERT INTO t1 VALUES (3)
+master-bin.000001	#	Xid	#	#	COMMIT /* XID */
+COMMIT;
+RESET MASTER;
+SET AUTOCOMMIT = 1;
+INSERT INTO t1 VALUES (1);
+show binlog events from <binlog_start>;
+Log_name	Pos	Event_type	Server_id	End_log_pos	Info
+master-bin.000001	#	Query	#	#	use `test`; BEGIN
+master-bin.000001	#	Query	#	#	use `test`; INSERT INTO t1 VALUES (1)
+master-bin.000001	#	Xid	#	#	COMMIT /* XID */
+SET AUTOCOMMIT = 0;
+show binlog events from <binlog_start>;
+Log_name	Pos	Event_type	Server_id	End_log_pos	Info
+master-bin.000001	#	Query	#	#	use `test`; BEGIN
+master-bin.000001	#	Query	#	#	use `test`; INSERT INTO t1 VALUES (1)
+master-bin.000001	#	Xid	#	#	COMMIT /* XID */
+COMMIT;
+RESET MASTER;
+SET AUTOCOMMIT = 1;
+BEGIN;
+INSERT INTO t1 VALUES (2);
+show binlog events from <binlog_start>;
+Log_name	Pos	Event_type	Server_id	End_log_pos	Info
+SET AUTOCOMMIT = 0;
+show binlog events from <binlog_start>;
+Log_name	Pos	Event_type	Server_id	End_log_pos	Info
+INSERT INTO t1 VALUES (3);
+show binlog events from <binlog_start>;
+Log_name	Pos	Event_type	Server_id	End_log_pos	Info
+COMMIT;
+show binlog events from <binlog_start>;
+Log_name	Pos	Event_type	Server_id	End_log_pos	Info
+master-bin.000001	#	Query	#	#	use `test`; BEGIN
+master-bin.000001	#	Query	#	#	use `test`; INSERT INTO t1 VALUES (2)
+master-bin.000001	#	Query	#	#	use `test`; INSERT INTO t1 VALUES (3)
+master-bin.000001	#	Xid	#	#	COMMIT /* XID */
+COMMIT;
+SET BINLOG_FORMAT = ROW;
+RESET MASTER;
+SET AUTOCOMMIT = 0;
+INSERT INTO t1 VALUES (1);
+show binlog events from <binlog_start>;
+Log_name	Pos	Event_type	Server_id	End_log_pos	Info
+SET AUTOCOMMIT = 1;
+show binlog events from <binlog_start>;
+Log_name	Pos	Event_type	Server_id	End_log_pos	Info
+master-bin.000001	#	Query	#	#	use `test`; BEGIN
+master-bin.000001	#	Table_map	#	#	table_id: # (test.t1)
+master-bin.000001	#	Write_rows	#	#	table_id: # flags: STMT_END_F
+master-bin.000001	#	Xid	#	#	COMMIT /* XID */
+COMMIT;
+RESET MASTER;
+SET AUTOCOMMIT = 0;
+BEGIN;
+INSERT INTO t1 VALUES (2);
+show binlog events from <binlog_start>;
+Log_name	Pos	Event_type	Server_id	End_log_pos	Info
+SET AUTOCOMMIT = 1;
+show binlog events from <binlog_start>;
+Log_name	Pos	Event_type	Server_id	End_log_pos	Info
+master-bin.000001	#	Query	#	#	use `test`; BEGIN
+master-bin.000001	#	Table_map	#	#	table_id: # (test.t1)
+master-bin.000001	#	Write_rows	#	#	table_id: # flags: STMT_END_F
+master-bin.000001	#	Xid	#	#	COMMIT /* XID */
+INSERT INTO t1 VALUES (3);
+show binlog events from <binlog_start>;
+Log_name	Pos	Event_type	Server_id	End_log_pos	Info
+master-bin.000001	#	Query	#	#	use `test`; BEGIN
+master-bin.000001	#	Table_map	#	#	table_id: # (test.t1)
+master-bin.000001	#	Write_rows	#	#	table_id: # flags: STMT_END_F
+master-bin.000001	#	Xid	#	#	COMMIT /* XID */
+master-bin.000001	#	Query	#	#	use `test`; BEGIN
+master-bin.000001	#	Table_map	#	#	table_id: # (test.t1)
+master-bin.000001	#	Write_rows	#	#	table_id: # flags: STMT_END_F
+master-bin.000001	#	Xid	#	#	COMMIT /* XID */
+COMMIT;
+show binlog events from <binlog_start>;
+Log_name	Pos	Event_type	Server_id	End_log_pos	Info
+master-bin.000001	#	Query	#	#	use `test`; BEGIN
+master-bin.000001	#	Table_map	#	#	table_id: # (test.t1)
+master-bin.000001	#	Write_rows	#	#	table_id: # flags: STMT_END_F
+master-bin.000001	#	Xid	#	#	COMMIT /* XID */
+master-bin.000001	#	Query	#	#	use `test`; BEGIN
+master-bin.000001	#	Table_map	#	#	table_id: # (test.t1)
+master-bin.000001	#	Write_rows	#	#	table_id: # flags: STMT_END_F
+master-bin.000001	#	Xid	#	#	COMMIT /* XID */
+COMMIT;
+RESET MASTER;
+SET AUTOCOMMIT = 1;
+INSERT INTO t1 VALUES (1);
+show binlog events from <binlog_start>;
+Log_name	Pos	Event_type	Server_id	End_log_pos	Info
+master-bin.000001	#	Query	#	#	use `test`; BEGIN
+master-bin.000001	#	Table_map	#	#	table_id: # (test.t1)
+master-bin.000001	#	Write_rows	#	#	table_id: # flags: STMT_END_F
+master-bin.000001	#	Xid	#	#	COMMIT /* XID */
+SET AUTOCOMMIT = 1;
+show binlog events from <binlog_start>;
+Log_name	Pos	Event_type	Server_id	End_log_pos	Info
+master-bin.000001	#	Query	#	#	use `test`; BEGIN
+master-bin.000001	#	Table_map	#	#	table_id: # (test.t1)
+master-bin.000001	#	Write_rows	#	#	table_id: # flags: STMT_END_F
+master-bin.000001	#	Xid	#	#	COMMIT /* XID */
+COMMIT;
+RESET MASTER;
+SET AUTOCOMMIT = 1;
+BEGIN;
+INSERT INTO t1 VALUES (2);
+show binlog events from <binlog_start>;
+Log_name	Pos	Event_type	Server_id	End_log_pos	Info
+SET AUTOCOMMIT = 1;
+show binlog events from <binlog_start>;
+Log_name	Pos	Event_type	Server_id	End_log_pos	Info
+INSERT INTO t1 VALUES (3);
+show binlog events from <binlog_start>;
+Log_name	Pos	Event_type	Server_id	End_log_pos	Info
+COMMIT;
+show binlog events from <binlog_start>;
+Log_name	Pos	Event_type	Server_id	End_log_pos	Info
+master-bin.000001	#	Query	#	#	use `test`; BEGIN
+master-bin.000001	#	Table_map	#	#	table_id: # (test.t1)
+master-bin.000001	#	Write_rows	#	#	table_id: # flags: STMT_END_F
+master-bin.000001	#	Table_map	#	#	table_id: # (test.t1)
+master-bin.000001	#	Write_rows	#	#	table_id: # flags: STMT_END_F
+master-bin.000001	#	Xid	#	#	COMMIT /* XID */
+COMMIT;
+RESET MASTER;
+SET AUTOCOMMIT = 0;
+INSERT INTO t1 VALUES (1);
+show binlog events from <binlog_start>;
+Log_name	Pos	Event_type	Server_id	End_log_pos	Info
+SET AUTOCOMMIT = 0;
+show binlog events from <binlog_start>;
+Log_name	Pos	Event_type	Server_id	End_log_pos	Info
+COMMIT;
+RESET MASTER;
+SET AUTOCOMMIT = 0;
+BEGIN;
+INSERT INTO t1 VALUES (2);
+show binlog events from <binlog_start>;
+Log_name	Pos	Event_type	Server_id	End_log_pos	Info
+SET AUTOCOMMIT = 0;
+show binlog events from <binlog_start>;
+Log_name	Pos	Event_type	Server_id	End_log_pos	Info
+INSERT INTO t1 VALUES (3);
+show binlog events from <binlog_start>;
+Log_name	Pos	Event_type	Server_id	End_log_pos	Info
+COMMIT;
+show binlog events from <binlog_start>;
+Log_name	Pos	Event_type	Server_id	End_log_pos	Info
+master-bin.000001	#	Query	#	#	use `test`; BEGIN
+master-bin.000001	#	Table_map	#	#	table_id: # (test.t1)
+master-bin.000001	#	Write_rows	#	#	table_id: # flags: STMT_END_F
+master-bin.000001	#	Table_map	#	#	table_id: # (test.t1)
+master-bin.000001	#	Write_rows	#	#	table_id: # flags: STMT_END_F
+master-bin.000001	#	Xid	#	#	COMMIT /* XID */
+COMMIT;
+RESET MASTER;
+SET AUTOCOMMIT = 1;
+INSERT INTO t1 VALUES (1);
+show binlog events from <binlog_start>;
+Log_name	Pos	Event_type	Server_id	End_log_pos	Info
+master-bin.000001	#	Query	#	#	use `test`; BEGIN
+master-bin.000001	#	Table_map	#	#	table_id: # (test.t1)
+master-bin.000001	#	Write_rows	#	#	table_id: # flags: STMT_END_F
+master-bin.000001	#	Xid	#	#	COMMIT /* XID */
+SET AUTOCOMMIT = 0;
+show binlog events from <binlog_start>;
+Log_name	Pos	Event_type	Server_id	End_log_pos	Info
+master-bin.000001	#	Query	#	#	use `test`; BEGIN
+master-bin.000001	#	Table_map	#	#	table_id: # (test.t1)
+master-bin.000001	#	Write_rows	#	#	table_id: # flags: STMT_END_F
+master-bin.000001	#	Xid	#	#	COMMIT /* XID */
+COMMIT;
+RESET MASTER;
+SET AUTOCOMMIT = 1;
+BEGIN;
+INSERT INTO t1 VALUES (2);
+show binlog events from <binlog_start>;
+Log_name	Pos	Event_type	Server_id	End_log_pos	Info
+SET AUTOCOMMIT = 0;
+show binlog events from <binlog_start>;
+Log_name	Pos	Event_type	Server_id	End_log_pos	Info
+INSERT INTO t1 VALUES (3);
+show binlog events from <binlog_start>;
+Log_name	Pos	Event_type	Server_id	End_log_pos	Info
+COMMIT;
+show binlog events from <binlog_start>;
+Log_name	Pos	Event_type	Server_id	End_log_pos	Info
+master-bin.000001	#	Query	#	#	use `test`; BEGIN
+master-bin.000001	#	Table_map	#	#	table_id: # (test.t1)
+master-bin.000001	#	Write_rows	#	#	table_id: # flags: STMT_END_F
+master-bin.000001	#	Table_map	#	#	table_id: # (test.t1)
+master-bin.000001	#	Write_rows	#	#	table_id: # flags: STMT_END_F
+master-bin.000001	#	Xid	#	#	COMMIT /* XID */
+COMMIT;
+RESET MASTER;
+SET AUTOCOMMIT = 0;
+INSERT INTO t1 VALUES (1);
+show binlog events from <binlog_start>;
+Log_name	Pos	Event_type	Server_id	End_log_pos	Info
+LOCK TABLES t1 WRITE;
+show binlog events from <binlog_start>;
+Log_name	Pos	Event_type	Server_id	End_log_pos	Info
+master-bin.000001	#	Query	#	#	use `test`; BEGIN
+master-bin.000001	#	Table_map	#	#	table_id: # (test.t1)
+master-bin.000001	#	Write_rows	#	#	table_id: # flags: STMT_END_F
+master-bin.000001	#	Xid	#	#	COMMIT /* XID */
+INSERT INTO t1 VALUES (2);
+show binlog events from <binlog_start>;
+Log_name	Pos	Event_type	Server_id	End_log_pos	Info
+master-bin.000001	#	Query	#	#	use `test`; BEGIN
+master-bin.000001	#	Table_map	#	#	table_id: # (test.t1)
+master-bin.000001	#	Write_rows	#	#	table_id: # flags: STMT_END_F
+master-bin.000001	#	Xid	#	#	COMMIT /* XID */
+UNLOCK TABLES;
+show binlog events from <binlog_start>;
+Log_name	Pos	Event_type	Server_id	End_log_pos	Info
+master-bin.000001	#	Query	#	#	use `test`; BEGIN
+master-bin.000001	#	Table_map	#	#	table_id: # (test.t1)
+master-bin.000001	#	Write_rows	#	#	table_id: # flags: STMT_END_F
+master-bin.000001	#	Xid	#	#	COMMIT /* XID */
+master-bin.000001	#	Query	#	#	use `test`; BEGIN
+master-bin.000001	#	Table_map	#	#	table_id: # (test.t1)
+master-bin.000001	#	Write_rows	#	#	table_id: # flags: STMT_END_F
+master-bin.000001	#	Xid	#	#	COMMIT /* XID */
+COMMIT;
+show binlog events from <binlog_start>;
+Log_name	Pos	Event_type	Server_id	End_log_pos	Info
+master-bin.000001	#	Query	#	#	use `test`; BEGIN
+master-bin.000001	#	Table_map	#	#	table_id: # (test.t1)
+master-bin.000001	#	Write_rows	#	#	table_id: # flags: STMT_END_F
+master-bin.000001	#	Xid	#	#	COMMIT /* XID */
+master-bin.000001	#	Query	#	#	use `test`; BEGIN
+master-bin.000001	#	Table_map	#	#	table_id: # (test.t1)
+master-bin.000001	#	Write_rows	#	#	table_id: # flags: STMT_END_F
+master-bin.000001	#	Xid	#	#	COMMIT /* XID */
+DROP TABLE t1;

=== added file 'mysql-test/suite/binlog/t/binlog_implicit_commit.test'
--- a/mysql-test/suite/binlog/t/binlog_implicit_commit.test	1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/binlog/t/binlog_implicit_commit.test	2008-06-09 19:32:42 +0000
@@ -0,0 +1,63 @@
+# The purpose of this test is to test that setting autocommit does a
+# commit of outstanding transactions and nothing is left pending in
+# the transaction cache.
+
+source include/have_log_bin.inc;
+source include/have_innodb.inc;
+
+# We need a transactional engine, so let's use InnoDB
+CREATE TABLE t1 (id INT) ENGINE = InnoDB;
+
+# Testing SET AUTOCOMMIT
+SET BINLOG_FORMAT = STATEMENT;
+
+let $cleanup = COMMIT;
+
+let $prepare = SET AUTOCOMMIT = 0;
+let $statement = SET AUTOCOMMIT = 1;
+source extra/binlog_tests/implicit.test;
+
+let $prepare = SET AUTOCOMMIT = 1;
+let $statement = SET AUTOCOMMIT = 1;
+source extra/binlog_tests/implicit.test;
+
+let $prepare = SET AUTOCOMMIT = 0;
+let $statement = SET AUTOCOMMIT = 0;
+source extra/binlog_tests/implicit.test;
+
+let $prepare = SET AUTOCOMMIT = 1;
+let $statement = SET AUTOCOMMIT = 0;
+source extra/binlog_tests/implicit.test;
+
+SET BINLOG_FORMAT = ROW;
+let $prepare = SET AUTOCOMMIT = 0;
+let $statement = SET AUTOCOMMIT = 1;
+source extra/binlog_tests/implicit.test;
+
+let $prepare = SET AUTOCOMMIT = 1;
+let $statement = SET AUTOCOMMIT = 1;
+source extra/binlog_tests/implicit.test;
+
+let $prepare = SET AUTOCOMMIT = 0;
+let $statement = SET AUTOCOMMIT = 0;
+source extra/binlog_tests/implicit.test;
+
+let $prepare = SET AUTOCOMMIT = 1;
+let $statement = SET AUTOCOMMIT = 0;
+source extra/binlog_tests/implicit.test;
+
+RESET MASTER;
+SET AUTOCOMMIT = 0;
+INSERT INTO t1 VALUES (1);
+source include/show_binlog_events.inc;
+LOCK TABLES t1 WRITE;
+source include/show_binlog_events.inc;
+INSERT INTO t1 VALUES (2);
+source include/show_binlog_events.inc;
+UNLOCK TABLES;
+source include/show_binlog_events.inc;
+COMMIT;
+source include/show_binlog_events.inc;
+
+# Cleaning up
+DROP TABLE t1;

=== added file 'mysql-test/suite/falcon/r/rpl_falcon_bug_37221.result'
--- a/mysql-test/suite/falcon/r/rpl_falcon_bug_37221.result	1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/falcon/r/rpl_falcon_bug_37221.result	2008-06-09 19:32:42 +0000
@@ -0,0 +1,38 @@
+stop slave;
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
+reset master;
+reset slave;
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
+start slave;
+[master]
+SET BINLOG_FORMAT = 'ROW';
+CREATE TABLE IF NOT EXISTS t1 (id INT) ENGINE = Falcon;
+SET AUTOCOMMIT=0;
+INSERT INTO t1 VALUES (1);
+SET AUTOCOMMIT=1;
+SELECT * FROM t1;
+id
+1
+[slave]
+SELECT * FROM t1;
+id
+1
+[master]
+BEGIN;
+INSERT INTO t1 VALUES (2);
+SET AUTOCOMMIT=1;
+[slave]
+SELECT * FROM t1 /* Should not contain 2 */;
+id
+1
+[master]
+INSERT INTO t1 VALUES (3);
+COMMIT;
+[slave]
+SELECT * FROM t1 /* Should contain 2 and 3 */;
+id
+1
+2
+3
+[master]
+DROP TABLE t1;

=== added file 'mysql-test/suite/falcon/t/rpl_falcon_bug_37221.test'
--- a/mysql-test/suite/falcon/t/rpl_falcon_bug_37221.test	1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/falcon/t/rpl_falcon_bug_37221.test	2008-06-10 12:39:13 +0000
@@ -0,0 +1,53 @@
+# BUG#37221: SET AUTOCOMMIT=1 does not commit binary log
+
+# Regression test to ensure that the bug does not re-appear. The test
+# is using the Falcon engine, but the problem is a generic case. See
+# binlog_implicit_commit.test for a more elaborate test.
+
+source include/master-slave.inc;
+
+--echo [master]
+connection master;
+SET BINLOG_FORMAT = 'ROW';
+
+CREATE TABLE IF NOT EXISTS t1 (id INT) ENGINE = Falcon;
+
+# When switching to AUTOCOMMIT=1, there is an implicit commit if we
+# are outside a real transaction.
+
+SET AUTOCOMMIT=0;
+INSERT INTO t1 VALUES (1);
+SET AUTOCOMMIT=1;
+SELECT * FROM t1;
+--echo [slave]
+sync_slave_with_master;
+SELECT * FROM t1;
+
+# When inside a transaction, AUTOCOMMIT=1 should not commit the
+# transaction. This is hard to test for sure (since delays might cause
+# the transaction to not propagate fast enough), but it will not cause
+# any false negatives (just false positives).
+
+--echo [master]
+connection master;
+BEGIN;
+INSERT INTO t1 VALUES (2);
+SET AUTOCOMMIT=1;
+
+--echo [slave]
+connection slave;
+SELECT * FROM t1 /* Should not contain 2 */;
+
+--echo [master]
+connection master;
+INSERT INTO t1 VALUES (3);
+COMMIT;
+
+--echo [slave]
+sync_slave_with_master;
+SELECT * FROM t1 /* Should contain 2 and 3 */;
+
+--echo [master]
+connection master;
+DROP TABLE t1;
+sync_slave_with_master;

=== modified file 'sql/set_var.cc'
--- a/sql/set_var.cc	2008-05-21 10:17:29 +0000
+++ b/sql/set_var.cc	2008-06-09 19:32:42 +0000
@@ -2970,6 +2970,15 @@
 
   ulonglong org_options= thd->options;
 
+  /*
+    If we are setting AUTOCOMMIT=1 and it was not already 1, then we
+    need to commit any outstanding transactions.
+   */
+  if (var->save_result.ulong_value != 0 &&
+      (thd->options & OPTION_NOT_AUTOCOMMIT) &&
+      ha_commit(thd))
+    return 1;
+
   if (var->save_result.ulong_value != 0)
     thd->options&= ~((sys_var_thd_bit*) var->var)->bit_flag;
   else
@@ -2983,8 +2992,6 @@
       thd->options&= ~(ulonglong) (OPTION_BEGIN | OPTION_KEEP_LOG);
       thd->transaction.all.modified_non_trans_table= FALSE;
       thd->server_status|= SERVER_STATUS_AUTOCOMMIT;
-      if (ha_commit(thd))
-	return 1;
     }
     else
     {

=== modified file 'storage/falcon/Backup.cpp'
--- a/storage/falcon/Backup.cpp	2008-05-29 22:49:01 +0000
+++ b/storage/falcon/Backup.cpp	2008-06-06 19:24:32 +0000
@@ -17,7 +17,7 @@
 #include "Backup.h"
 #include "Database.h"
 #include "Dbb.h"
-#include "Bdb.h"
+#include "BDB.h"
 #include "IndexPage.h"
 #include "RecordLocatorPage.h"
 #include "DataPage.h"

=== modified file 'storage/falcon/CMakeLists.txt'
--- a/storage/falcon/CMakeLists.txt	2008-05-14 14:12:04 +0000
+++ b/storage/falcon/CMakeLists.txt	2008-06-06 19:20:10 +0000
@@ -204,6 +204,8 @@
 		SearchWords.cpp 
 		Section.cpp 
 		SectionPage.cpp 
+		SectorBuffer.cpp
+		SectorCache.cpp
 		Sequence.cpp
 		SequenceManager.cpp 
 		SequenceResultSet.cpp
@@ -480,6 +482,8 @@
 		SearchWords.h 
 		Section.h 
 		SectionPage.h 
+		SectorBuffer.h
+		SectorCache.h
 		Sequence.h
 		SequenceManager.h 
 		SequencePage.h 

=== modified file 'storage/falcon/Cache.cpp'
--- a/storage/falcon/Cache.cpp	2008-05-14 18:39:57 +0000
+++ b/storage/falcon/Cache.cpp	2008-06-06 19:20:10 +0000
@@ -38,6 +38,7 @@
 #include "Database.h"
 #include "Bitmap.h"
 #include "Priority.h"
+#include "SectorCache.h"
 
 extern uint falcon_io_threads;
 
@@ -48,7 +49,7 @@
 
 static const uint64 cacheHunkSize		= 1024 * 1024 * 128;
 static const int	ASYNC_BUFFER_SIZE	= 1024000;
-
+static const int	sectorCacheSize		= 20000000;
 #ifdef _DEBUG
 #undef THIS_FILE
 static const char THIS_FILE[]=__FILE__;
@@ -74,7 +75,7 @@
 	pageWriter = NULL;
 	hashTable = new Bdb* [hashSz];
 	memset (hashTable, 0, sizeof (Bdb*) * hashSize);
-
+	sectorCache = new SectorCache(sectorCacheSize / SECTOR_BUFFER_SIZE, pageSize);
 	uint64 n = ((uint64) pageSize * numberBuffers + cacheHunkSize - 1) / cacheHunkSize;
 	numberHunks = (int) n;
 	bufferHunks = new char* [numberHunks];
@@ -141,7 +142,8 @@
 	delete [] bdbs;
 	delete [] ioThreads;
 	delete flushBitmap;
-
+	delete sectorCache;
+	
 	if (bufferHunks)
 		{
 		for (int n = 0; n < numberHunks; ++n)
@@ -257,7 +259,8 @@
 			
 			Priority priority(database->ioScheduler);
 			priority.schedule(PRIORITY_MEDIUM);	
-			dbb->readPage(bdb);
+			//dbb->readPage(bdb);
+			sectorCache->readPage(bdb);
 			priority.finished();
 #ifdef HAVE_PAGE_NUMBER
 			ASSERT(bdb->buffer->pageNumber == pageNumber);
@@ -521,6 +524,7 @@
 
 	try
 		{
+		sectorCache->writePage(bdb);
 		dbb->writePage(bdb, type);
 		}
 	catch (SQLException& exception)
@@ -791,6 +795,7 @@
 						bdb->incrementUseCount(ADD_HISTORY);
 						sync.unlock();
 						bdb->addRef(Shared  COMMA_ADD_HISTORY);
+						sectorCache->writePage(bdb);
 						
 						bdb->syncWrite.lock(NULL, Exclusive);
 						bdb->ioThreadNext = bdbList;

=== modified file 'storage/falcon/Cache.h'
--- a/storage/falcon/Cache.h	2008-03-27 06:09:29 +0000
+++ b/storage/falcon/Cache.h	2008-06-06 19:20:10 +0000
@@ -36,6 +36,7 @@
 class Thread;
 class Database;
 class Bitmap;
+class SectorCache;
 
 class Cache  
 {
@@ -95,6 +96,7 @@
 	Bitmap		*flushBitmap;
 	char		**bufferHunks;
 	Thread		**ioThreads;
+	SectorCache	*sectorCache;
 	SyncObject	syncFlush;
 	SyncObject	syncDirty;
 	SyncObject	syncThreads;

=== modified file 'storage/falcon/DeferredIndex.h'
--- a/storage/falcon/DeferredIndex.h	2008-03-11 16:15:47 +0000
+++ b/storage/falcon/DeferredIndex.h	2008-06-08 06:52:51 +0000
@@ -111,7 +111,7 @@
 	DIHunk			*hunks;
 	DINode			*minValue;
 	DINode			*maxValue;
-	UCHAR			initialSpace[500];
+	UCHAR			initialSpace[512];
 	UCHAR			*base;
 	void			*root;
 	uint			currentHunkOffset;

=== modified file 'storage/falcon/Gopher.cpp'
--- a/storage/falcon/Gopher.cpp	2008-03-25 03:55:03 +0000
+++ b/storage/falcon/Gopher.cpp	2008-06-08 22:12:35 +0000
@@ -64,11 +64,22 @@
 		
 		SerialLogTransaction *transaction = log->pending.first;
 		log->pending.remove(transaction);
+
+		
+		Sync serializeGophers(&log->syncSerializeGophers, "Gopher::gopherThread(4)");
+
+		if (transaction->allowConcurrentGophers)
+			serializeGophers.lock(Shared);
+		else
+			serializeGophers.lock(Exclusive);
+
 		sync.unlock();
 
 		transaction->doAction();
 
 		sync.lock(Exclusive);
+		serializeGophers.unlock();
+
 		log->inactions.append(transaction);
 		
 		if (log->pending.count > log->maxTransactions && !log->blocking)

=== modified file 'storage/falcon/Makefile.am'
--- a/storage/falcon/Makefile.am	2008-04-28 20:47:43 +0000
+++ b/storage/falcon/Makefile.am	2008-06-06 19:26:53 +0000
@@ -117,8 +117,11 @@
 		ScaledBinary.h ScanDir.h \
 		Scan.h ScanType.h Scavenger.h Scheduled.h ScheduleElement.h \
 		Schedule.h Scheduler.h Schema.h Search.h SearchHit.h \
-		SearchWords.h Section.h \
+		SearchWords.h \
+		Section.h \
 		SectionPage.h \
+		SectorBuffer.h \
+		SectorCache.h \
 		Sequence.h SequenceManager.h SequencePage.h \
 		SequenceResultSet.h \
 		Serialize.h \
@@ -291,8 +294,12 @@
 		ScaledBinary.cpp Scan.cpp \
 		ScanDir.cpp Scavenger.cpp Schedule.cpp Scheduled.cpp \
 		ScheduleElement.cpp Scheduler.cpp Schema.cpp Search.cpp \
-		SearchHit.cpp SearchWords.cpp Section.cpp \
-		SectionPage.cpp Sequence.cpp \
+		SearchHit.cpp SearchWords.cpp \
+		Section.cpp \
+		SectionPage.cpp \
+		SectorBuffer.cpp \
+		SectorCache.cpp \
+		Sequence.cpp \
 		SequenceManager.cpp SequenceResultSet.cpp \
 		Serialize.cpp \
 		SerialLogAction.cpp SerialLogControl.cpp SerialLog.cpp \

=== modified file 'storage/falcon/SRLDropTableSpace.cpp'
--- a/storage/falcon/SRLDropTableSpace.cpp	2007-11-14 23:24:47 +0000
+++ b/storage/falcon/SRLDropTableSpace.cpp	2008-06-08 22:12:35 +0000
@@ -24,6 +24,7 @@
 #include "SRLVersion.h"
 #include "SerialLogControl.h"
 #include "Transaction.h"
+#include "SerialLogTransaction.h"
 
 //////////////////////////////////////////////////////////////////////
 // Construction/Destruction
@@ -42,7 +43,12 @@
 void SRLDropTableSpace::append(TableSpace *tableSpace, Transaction *transaction)
 {
 	START_RECORD(srlDropTableSpace, "SRLDropTableSpace::append");
-	log->getTransaction(transaction->transactionId);
+
+	SerialLogTransaction* serialLogTransaction 
+		= log->getTransaction(transaction->transactionId);
+
+	serialLogTransaction->allowConcurrentGophers = false;
+
 	putInt(tableSpace->tableSpaceId);
 	putInt(transaction->transactionId);
 }

=== added file 'storage/falcon/SectorBuffer.cpp'
--- a/storage/falcon/SectorBuffer.cpp	1970-01-01 00:00:00 +0000
+++ b/storage/falcon/SectorBuffer.cpp	2008-06-06 19:24:32 +0000
@@ -0,0 +1,58 @@
+/* Copyright (C) 2008 MySQL AB
+
+   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 <memory.h>
+#include "Engine.h"
+#include "SectorBuffer.h"
+#include "SectorCache.h"
+#include "BDB.h"
+#include "Dbb.h"
+
+SectorBuffer::SectorBuffer()
+{
+	activeLength = 0;
+	sectorNumber = -1;
+}
+
+SectorBuffer::~SectorBuffer(void)
+{
+}
+
+void SectorBuffer::readPage(Bdb* bdb)
+{
+	int offset = (bdb->pageNumber % cache->pagesPerSector) * cache->pageSize;
+	ASSERT(offset < activeLength);
+	memcpy(bdb->buffer, buffer + offset, cache->pageSize);
+}
+
+void SectorBuffer::readSector()
+{
+	uint64 offset = sectorNumber * cache->pagesPerSector * cache->pageSize;
+	activeLength = dbb->pread(offset, SECTOR_BUFFER_SIZE, buffer);
+}
+
+void SectorBuffer::setSector(Dbb* db, int sector)
+{
+	dbb = db;
+	sectorNumber = sector;
+}
+
+void SectorBuffer::writePage(Bdb* bdb)
+{
+	int offset = (bdb->pageNumber % cache->pagesPerSector) * cache->pageSize;
+	memcpy(buffer + offset, bdb->buffer, cache->pageSize);
+	offset += cache->pageSize;
+	activeLength = MAX(activeLength, offset);
+}

=== added file 'storage/falcon/SectorBuffer.h'
--- a/storage/falcon/SectorBuffer.h	1970-01-01 00:00:00 +0000
+++ b/storage/falcon/SectorBuffer.h	2008-06-06 19:20:10 +0000
@@ -0,0 +1,46 @@
+/* Copyright (C) 2008 MySQL AB
+
+   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 */
+
+#ifndef _SECTOR_BUFFER_H_
+#define _SECTOR_BUFFER_H_
+
+#include "SyncObject.h"
+
+class SectorCache;
+class Dbb;
+class Bdb;
+
+class SectorBuffer
+{
+public:
+	SectorBuffer();
+	~SectorBuffer(void);
+
+	void		readPage(Bdb* bdb);
+	void		readSector();
+	
+	SyncObject		syncObject;
+	SectorCache		*cache;
+	SectorBuffer	*next;
+	SectorBuffer	*collision;
+	Dbb				*dbb;
+	UCHAR			*buffer;
+	int				activeLength;
+	int				sectorNumber;
+	void setSector(Dbb* dbb, int sectorNumber);
+	void writePage(Bdb* bdb);
+};
+
+#endif

=== added file 'storage/falcon/SectorCache.cpp'
--- a/storage/falcon/SectorCache.cpp	1970-01-01 00:00:00 +0000
+++ b/storage/falcon/SectorCache.cpp	2008-06-06 19:24:32 +0000
@@ -0,0 +1,129 @@
+/* Copyright (C) 2008 MySQL AB
+
+   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 "Engine.h"
+#include "SectorCache.h"
+#include "SectorBuffer.h"
+#include "Dbb.h"
+#include "BDB.h"
+#include "Sync.h"
+
+#define SECTOR_BUFFER_ALIGNMENT	= 4096;
+
+#ifdef _DEBUG
+#undef THIS_FILE
+static const char THIS_FILE[]=__FILE__;
+#endif
+
+
+SectorCache::SectorCache(int numBuffers, int pgSize)
+{
+	memset(hashTable, 0, sizeof(hashTable));
+	numberBuffers = numBuffers;
+	pageSize = pgSize;
+	pagesPerSector = SECTOR_BUFFER_SIZE / pageSize;
+	bufferSpace = new UCHAR[(numberBuffers + 1) * SECTOR_BUFFER_SIZE];
+	UCHAR *p = (UCHAR*) (((UIPTR) bufferSpace + SECTOR_BUFFER_SIZE - 1) / SECTOR_BUFFER_SIZE
* SECTOR_BUFFER_SIZE);
+	SectorBuffer *buffer = buffers = nextBuffer = new SectorBuffer[numberBuffers];
+	SectorBuffer *prior = buffer + numberBuffers - 1;
+	
+	for (int n = 0; n < numberBuffers; ++n, ++buffer, p += SECTOR_BUFFER_SIZE)
+		{
+		prior->next = buffer;
+		prior = buffer;
+		buffer->cache = this;
+		buffer->buffer = p;
+		}
+}
+
+SectorCache::~SectorCache(void)
+{
+	delete [] bufferSpace;
+	delete [] buffers;
+}
+
+void SectorCache::readPage(Bdb* bdb)
+{
+	Sync sync(&syncObject, "SectorCache::readPage");
+	sync.lock(Shared);
+	int sectorNumber = bdb->pageNumber / pagesPerSector;
+	int slot = sectorNumber % SECTOR_HASH_SIZE;
+	SectorBuffer *buffer;
+	
+	for (buffer = hashTable[slot]; buffer; buffer = buffer->collision)
+		if (buffer->sectorNumber == sectorNumber && buffer->dbb == bdb->dbb)
+			{
+			Sync syncBuffer(&buffer->syncObject, "SectorCache::readPage(2)");
+			syncBuffer.lock(Shared);
+			sync.unlock();
+			buffer->readPage(bdb);
+			
+			return;
+			}
+	
+	sync.unlock();
+	sync.lock(Exclusive);
+	
+	for (buffer = hashTable[slot]; buffer; buffer = buffer->collision)
+		if (buffer->sectorNumber == sectorNumber && buffer->dbb == bdb->dbb)
+			{
+			Sync syncBuffer(&buffer->syncObject, "SectorCache::readPage(3)");
+			syncBuffer.lock(Shared);
+			sync.unlock();
+			buffer->readPage(bdb);
+			
+			return;
+			}
+	
+	buffer = nextBuffer;
+	nextBuffer = buffer->next;
+	Sync syncBuffer(&buffer->syncObject, "SectorCache::readPage(3)");
+	syncBuffer.lock(Exclusive);
+	
+	if (buffer->sectorNumber >= 0)
+		for (SectorBuffer **ptr = hashTable + (buffer->sectorNumber % SECTOR_HASH_SIZE);
*ptr; ptr = &(*ptr)->collision)
+			if (*ptr == buffer)
+				{
+				*ptr = buffer->collision;
+				
+				break;
+				}
+		
+	buffer->collision = hashTable[slot];
+	hashTable[slot] = buffer;
+	buffer->setSector(bdb->dbb, sectorNumber);
+	sync.unlock();
+	buffer->readSector();
+	buffer->readPage(bdb);	
+}
+
+void SectorCache::writePage(Bdb* bdb)
+{
+	Sync sync(&syncObject, "SectorCache::writePage");
+	sync.lock(Shared);
+	int sectorNumber = bdb->pageNumber / pagesPerSector;
+	int slot = sectorNumber % SECTOR_HASH_SIZE;
+	
+	for (SectorBuffer *buffer = hashTable[slot]; buffer; buffer = buffer->collision)
+		if (buffer->sectorNumber == sectorNumber && buffer->dbb == bdb->dbb)
+			{
+			Sync syncBuffer(&buffer->syncObject, "SectorCache::writePage(2)");
+			syncBuffer.lock(Shared);
+			sync.unlock();
+			buffer->writePage(bdb);
+			
+			return;
+			}
+}

=== added file 'storage/falcon/SectorCache.h'
--- a/storage/falcon/SectorCache.h	1970-01-01 00:00:00 +0000
+++ b/storage/falcon/SectorCache.h	2008-06-06 19:20:10 +0000
@@ -0,0 +1,47 @@
+/* Copyright (C) 2008 MySQL AB
+
+   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 */
+
+#ifndef _SECTOR_CACHE_H_
+#define _SECTOR_CACHE_H_
+
+#include "SyncObject.h"
+
+static const int SECTOR_BUFFER_SIZE		= 65536;
+static const int SECTOR_HASH_SIZE		= 1024;
+
+class SectorBuffer;
+class Dbb;
+class Bdb;
+
+class SectorCache
+{
+public:
+	SectorCache(int numberBuffers, int pageSize);
+	~SectorCache(void);
+	
+	void readPage(Bdb* bdb);
+
+	SyncObject		syncObject;
+	SectorBuffer	*buffers;
+	SectorBuffer	*nextBuffer;
+	SectorBuffer	*hashTable[SECTOR_HASH_SIZE];
+	UCHAR			*bufferSpace;
+	int				numberBuffers;
+	int				pageSize;
+	int				pagesPerSector;
+	void writePage(Bdb* bdb);
+};
+
+#endif

=== modified file 'storage/falcon/SerialLog.h'
--- a/storage/falcon/SerialLog.h	2008-03-11 16:15:47 +0000
+++ b/storage/falcon/SerialLog.h	2008-06-08 22:12:35 +0000
@@ -188,6 +188,7 @@
 	SyncObject			syncSections;
 	SyncObject			syncIndexes;
 	SyncObject			syncGopher;
+	SyncObject			syncSerializeGophers;
 	SyncObject			syncUpdateStall;
 	Stack				buffers;
 	UCHAR				*bufferSpace;

=== modified file 'storage/falcon/SerialLogTransaction.cpp'
--- a/storage/falcon/SerialLogTransaction.cpp	2008-02-14 21:45:27 +0000
+++ b/storage/falcon/SerialLogTransaction.cpp	2008-06-08 22:12:35 +0000
@@ -46,6 +46,7 @@
 	window = NULL;
 	finished = false;
 	ordered = false;
+	allowConcurrentGophers = true;
 	transaction = NULL;
 	rolledBackSavepoints = NULL;
 	blockNumber = maxBlockNumber = minBlockNumber = physicalBlockNumber = 0;

=== modified file 'storage/falcon/SerialLogTransaction.h'
--- a/storage/falcon/SerialLogTransaction.h	2008-03-11 16:15:47 +0000
+++ b/storage/falcon/SerialLogTransaction.h	2008-06-08 22:12:35 +0000
@@ -71,6 +71,7 @@
 	int						xidLength;
 	UCHAR					*xid;
 	bool					finished;
+	bool					allowConcurrentGophers;
 
 	SerialLog				*log;
 	SerialLogTransaction	*next;

=== modified file 'storage/falcon/SymbolManager.cpp'
--- a/storage/falcon/SymbolManager.cpp	2007-09-20 15:44:25 +0000
+++ b/storage/falcon/SymbolManager.cpp	2008-06-06 12:34:19 +0000
@@ -124,7 +124,9 @@
 
 	sync.unlock();
 	sync.lock (Exclusive);
-	symbol = (Symbol*) ((IPTR)(next + 3) & ~3);
+
+	// Allocate space for the new symbol with necessary address alignment
+	symbol = (Symbol*) (ROUNDUP(((IPTR)(next)), sizeof(void*)));
 	IPTR length = p - string;
 
 	if (symbol->symbol + length > sections->space + sizeof (sections->space))
@@ -180,7 +182,9 @@
 
 	sync.unlock();
 	sync.lock (Exclusive);
-	symbol = (Symbol*) ((IPTR)(next + 3) & ~3);
+
+	// Allocate space for the new symbol with necessary address alignment
+	symbol = (Symbol*) (ROUNDUP(((IPTR)(next)), sizeof(void*)));
 	IPTR length = p - string;
 
 	if (symbol->symbol + length > sections->space + sizeof (sections->space))

=== modified file 'storage/falcon/TableSpaceManager.cpp'
--- a/storage/falcon/TableSpaceManager.cpp	2008-05-06 23:37:54 +0000
+++ b/storage/falcon/TableSpaceManager.cpp	2008-06-08 22:12:35 +0000
@@ -41,6 +41,7 @@
 #include "SRLDropTableSpace.h"
 #include "Log.h"
 #include "InfoTable.h"
+#include "Thread.h"
 
 #ifdef _DEBUG
 #undef THIS_FILE
@@ -57,6 +58,7 @@
 	memset(nameHash, 0, sizeof(nameHash));
 	memset(idHash, 0, sizeof(nameHash));
 	tableSpaces = NULL;
+	pendingDrops = 0;
 }
 
 TableSpaceManager::~TableSpaceManager()
@@ -168,10 +170,32 @@
 	
 	TableSpace *tableSpace = new TableSpace(database, name, id, fileName, type, tsInit);
 	
-	if (!repository && tableSpace->dbb->doesFileExist(fileName))
+	if (!repository)
 		{
-		delete tableSpace;
-		throw SQLError(TABLESPACE_DATAFILE_EXIST_ERROR, "table space file name \"%s\" already
exists\n", fileName);
+		bool fileExists;
+
+		// Check if table space file already exists.
+		// Take into account, that tablespace might have been already  dropped
+		// by another transaction, yet file can still be present on the disk,
+		// if log record is not yet fully committed by the gopher thread).
+		// So we'll wait for a few seconds if there are pending drops and 
+		// tablespace file exists.
+
+		for (int i=0; i < 10; i++)
+			{
+			fileExists = tableSpace->dbb->doesFileExist(fileName);
+
+			if (fileExists && pendingDrops > 0)
+				Thread::getThread("TableSpaceManager::createTableSpace")->sleep(1000);
+			else
+				break;
+			}
+
+		if (fileExists)
+			{
+			delete tableSpace;
+			throw SQLError(TABLESPACE_DATAFILE_EXIST_ERROR, "table space file name \"%s\" already
exists\n", fileName);
+			}
 		}
 		
 	try
@@ -302,6 +326,7 @@
 	statement->executeUpdate();
 	Transaction *transaction = database->getSystemTransaction();
 	transaction->hasUpdates = true;
+	pendingDrops++;
 	database->serialLog->logControl->dropTableSpace.append(tableSpace,
transaction);
 
 	syncDDL.unlock();
@@ -386,6 +411,9 @@
 	sync.unlock();
 	tableSpace->dropTableSpace();
 	delete tableSpace;
+
+	sync.lock(Exclusive);
+	if(pendingDrops >0) pendingDrops--;
 }
 
 void TableSpaceManager::reportWrites(void)

=== modified file 'storage/falcon/TableSpaceManager.h'
--- a/storage/falcon/TableSpaceManager.h	2008-04-05 22:09:17 +0000
+++ b/storage/falcon/TableSpaceManager.h	2008-06-08 22:12:35 +0000
@@ -69,6 +69,7 @@
 	TableSpace	*idHash[TS_HASH_SIZE];
 	SyncObject	syncObject;
 	void postRecovery(void);
+	int pendingDrops;
 };
 
 #endif //
!defined(AFX_TABLESPACEMANAGER_H__BD1D39F6_2201_4136_899C_7CB106E99B8C__INCLUDED_)

Thread
commit into mysql-6.0-falcon:mysql-6.0-falcon branch (cpowers:2693) Christopher Powers10 Jun