Below is the list of changes that have just been committed into a local
5.1 repository of mats. When mats does a push these changes will
be propagated to the main repository and, within 24 hours after the
push, to the public repository.
For information on how to access the public repository
see http://dev.mysql.com/doc/mysql/en/installing-source-tree.html
ChangeSet@stripped, 2007-05-31 11:12:23+02:00, mats@stripped +6 -0
BUG#23051 (READ COMMITTED breaks mixed and statement-based
replication):
Patch to add capabilities to the InnoDB storage engine. The engine will
not allow statement format logging when in READ COMMITTED transaction
isolation level.
In addition, an informative error message is printed when trying to use
READ COMMITTED transaction isolation level in STATEMENT binlog mode.
mysql-test/r/binlog_innodb.result@stripped, 2007-05-31 11:12:20+02:00, mats@stripped +114 -0
New BitKeeper file ``mysql-test/r/binlog_innodb.result''
mysql-test/r/binlog_innodb.result@stripped, 2007-05-31 11:12:20+02:00, mats@stripped +0 -0
mysql-test/r/binlog_tx_isolation.result@stripped, 2007-05-31 11:12:20+02:00, mats@stripped +48 -0
New BitKeeper file ``mysql-test/r/binlog_tx_isolation.result''
mysql-test/r/binlog_tx_isolation.result@stripped, 2007-05-31 11:12:20+02:00, mats@stripped +0 -0
mysql-test/t/binlog_innodb.test@stripped, 2007-05-31 11:12:20+02:00, mats@stripped +93 -0
New BitKeeper file ``mysql-test/t/binlog_innodb.test''
mysql-test/t/binlog_innodb.test@stripped, 2007-05-31 11:12:20+02:00, mats@stripped +0 -0
sql/handler.h@stripped, 2007-05-31 11:12:19+02:00, mats@stripped +2 -0
Adding declaration of already global arrays.
storage/innobase/handler/ha_innodb.cc@stripped, 2007-05-31 11:12:19+02:00, mats@stripped +30 -0
Adding capabilities to storage engine.
Ha_innobase:table_flags() now compute flags on a per-statement basis
and the statement capabilities flag is just set if the transaction
isolation level is not READ COMMITTED.
An informative message is printed in the event that the transaction
isolation level is READ COMMITTED and the binlog mode is STATEMENT.
storage/innobase/handler/ha_innodb.h@stripped, 2007-05-31 11:12:20+02:00, mats@stripped +2 -2
Accomodating to changes in the server code that switched from ulong
to Table_flags as type for the table flags.
# This is a BitKeeper patch. What follows are the unified diffs for the
# set of deltas contained in the patch. The rest of the patch, the part
# that BitKeeper cares about, is below these diffs.
# User: mats
# Host: kindahl-laptop.dnsalias.net
# Root: /home/bk/b23051-mysql-5.1-rpl
--- 1.258/sql/handler.h 2007-05-31 11:12:33 +02:00
+++ 1.259/sql/handler.h 2007-05-31 11:12:33 +02:00
@@ -1708,6 +1708,8 @@
/* Some extern variables used with handlers */
extern const char *ha_row_type[];
+extern const char *tx_isolation_names[];
+extern const char *binlog_format_names[];
extern TYPELIB tx_isolation_typelib;
extern TYPELIB myisam_stats_method_typelib;
extern ulong total_ha, total_ha_2pc;
--- New file ---
+++ mysql-test/r/binlog_innodb.result 07/05/31 11:12:20
SET BINLOG_FORMAT=MIXED;
RESET MASTER;
CREATE TABLE t1 (a INT PRIMARY KEY, b INT) ENGINE=INNODB;
INSERT INTO t1 VALUES (1,1),(2,2),(3,3),(4,4),(5,5),(6,6);
BEGIN;
UPDATE t1 SET b = 2*a WHERE a > 1;
COMMIT;
BEGIN;
SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED;
UPDATE t1 SET b = a * a WHERE a > 3;
COMMIT;
SET BINLOG_FORMAT=STATEMENT;
BEGIN;
SET SESSION TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;
UPDATE t1 SET b = 1*a WHERE a > 1;
COMMIT;
BEGIN;
SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED;
UPDATE t1 SET b = 2*a WHERE a > 2;
ERROR HY000: Attempting to log statement in in statement format, but statement format is not possible with this combination of engines
COMMIT;
BEGIN;
SET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READ;
UPDATE t1 SET b = 3*a WHERE a > 3;
COMMIT;
BEGIN;
SET SESSION TRANSACTION ISOLATION LEVEL SERIALIZABLE;
UPDATE t1 SET b = 4*a WHERE a > 4;
COMMIT;
SET BINLOG_FORMAT=MIXED;
BEGIN;
SET SESSION TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;
UPDATE t1 SET b = 1*a WHERE a > 1;
COMMIT;
BEGIN;
SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED;
UPDATE t1 SET b = 2*a WHERE a > 2;
COMMIT;
BEGIN;
SET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READ;
UPDATE t1 SET b = 3*a WHERE a > 3;
COMMIT;
BEGIN;
SET SESSION TRANSACTION ISOLATION LEVEL SERIALIZABLE;
UPDATE t1 SET b = 4*a WHERE a > 4;
COMMIT;
SET BINLOG_FORMAT=ROW;
BEGIN;
SET SESSION TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;
UPDATE t1 SET b = 1*a WHERE a > 1;
COMMIT;
BEGIN;
SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED;
UPDATE t1 SET b = 2*a WHERE a > 2;
COMMIT;
BEGIN;
SET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READ;
UPDATE t1 SET b = 3*a WHERE a > 3;
COMMIT;
BEGIN;
SET SESSION TRANSACTION ISOLATION LEVEL SERIALIZABLE;
UPDATE t1 SET b = 4*a WHERE a > 4;
COMMIT;
show binlog events from <binlog_start>;
Log_name Pos Event_type Server_id End_log_pos Info
master-bin.000001 # Query # # use `test`; CREATE TABLE t1 (a INT PRIMARY KEY, b INT) ENGINE=INNODB
master-bin.000001 # Query # # use `test`; INSERT INTO t1 VALUES (1,1),(2,2),(3,3),(4,4),(5,5),(6,6)
master-bin.000001 # Xid # # COMMIT /* XID */
master-bin.000001 # Query # # use `test`; BEGIN
master-bin.000001 # Query # # use `test`; UPDATE t1 SET b = 2*a WHERE a > 1
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 # Update_rows # # table_id: # flags: STMT_END_F
master-bin.000001 # Xid # # COMMIT /* XID */
master-bin.000001 # Query # # use `test`; BEGIN
master-bin.000001 # Query # # use `test`; UPDATE t1 SET b = 1*a WHERE a > 1
master-bin.000001 # Xid # # COMMIT /* XID */
master-bin.000001 # Query # # use `test`; BEGIN
master-bin.000001 # Query # # use `test`; UPDATE t1 SET b = 3*a WHERE a > 3
master-bin.000001 # Xid # # COMMIT /* XID */
master-bin.000001 # Query # # use `test`; BEGIN
master-bin.000001 # Query # # use `test`; UPDATE t1 SET b = 4*a WHERE a > 4
master-bin.000001 # Xid # # COMMIT /* XID */
master-bin.000001 # Query # # use `test`; BEGIN
master-bin.000001 # Query # # use `test`; UPDATE t1 SET b = 1*a WHERE a > 1
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 # Update_rows # # table_id: # flags: STMT_END_F
master-bin.000001 # Xid # # COMMIT /* XID */
master-bin.000001 # Query # # use `test`; BEGIN
master-bin.000001 # Query # # use `test`; UPDATE t1 SET b = 3*a WHERE a > 3
master-bin.000001 # Xid # # COMMIT /* XID */
master-bin.000001 # Query # # use `test`; BEGIN
master-bin.000001 # Query # # use `test`; UPDATE t1 SET b = 4*a WHERE a > 4
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 # Update_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 # Update_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 # Update_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 # Update_rows # # table_id: # flags: STMT_END_F
master-bin.000001 # Xid # # COMMIT /* XID */
DROP TABLE t1;
--- New file ---
+++ mysql-test/r/binlog_tx_isolation.result 07/05/31 11:12:20
CREATE TABLE t1 (a INT PRIMARY KEY, b INT) ENGINE=INNODB;
INSERT INTO t1 VALUES (1,1),(2,2),(3,3),(4,4),(5,5),(6,6);
SET BINLOG_FORMAT=STATEMENT;
BEGIN;
SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED;
ERROR HY000: Transaction isolation level 'READ-COMMITTED' is not safe for 'STATEMENT' binlog mode
UPDATE t1 SET b = a*a WHERE a > 1;
COMMIT;
BEGIN;
SET SESSION TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;
UPDATE t1 SET b = a*a WHERE a > 1;
COMMIT;
BEGIN;
SET SESSION TRANSACTION ISOLATION LEVEL SERIALIZABLE;
UPDATE t1 SET b = a*a WHERE a > 1;
COMMIT;
SET BINLOG_FORMAT=MIXED;
BEGIN;
SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED;
ERROR HY000: Transaction isolation level 'READ-COMMITTED' is not safe for 'MIXED' binlog mode
UPDATE t1 SET b = a*a*a WHERE a > 2;
COMMIT;
SET BINLOG_FORMAT=ROW;
BEGIN;
SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED;
UPDATE t1 SET b = a*a*a*a WHERE a > 3;
COMMIT;
SELECT @@session.tx_isolation, @@session.binlog_format;
@@session.tx_isolation READ-COMMITTED
@@session.binlog_format ROW
BEGIN;
SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED;
SET BINLOG_FORMAT=MIXED;
ERROR HY000: Transaction isolation level 'READ-COMMITTED' prevents leaving 'ROW' binlog mode
UPDATE t1 SET b = a*a*a*a WHERE a > 3;
COMMIT;
SELECT @@session.tx_isolation, @@session.binlog_format;
@@session.tx_isolation READ-COMMITTED
@@session.binlog_format ROW
BEGIN;
SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED;
SET BINLOG_FORMAT=STATEMENT;
ERROR HY000: Transaction isolation level 'READ-COMMITTED' prevents leaving 'ROW' binlog mode
UPDATE t1 SET b = a*a*a*a WHERE a > 3;
COMMIT;
SELECT @@session.tx_isolation, @@session.binlog_format;
@@session.tx_isolation READ-COMMITTED
@@session.binlog_format ROW
--- New file ---
+++ mysql-test/t/binlog_innodb.test 07/05/31 11:12:20
source include/have_innodb.inc;
SET BINLOG_FORMAT=MIXED;
RESET MASTER;
CREATE TABLE t1 (a INT PRIMARY KEY, b INT) ENGINE=INNODB;
INSERT INTO t1 VALUES (1,1),(2,2),(3,3),(4,4),(5,5),(6,6);
BEGIN;
# Should be logged as statement
UPDATE t1 SET b = 2*a WHERE a > 1;
COMMIT;
BEGIN;
SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED;
# Should be logged as rows
UPDATE t1 SET b = a * a WHERE a > 3;
COMMIT;
# Check that errors are generated when trying to use READ COMMITTED
# transaction isolation leve in STATEMENT binlog mode.
SET BINLOG_FORMAT=STATEMENT;
BEGIN;
SET SESSION TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;
UPDATE t1 SET b = 1*a WHERE a > 1;
COMMIT;
BEGIN;
SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED;
error ER_BINLOG_STMT_FORMAT_FORBIDDEN;
UPDATE t1 SET b = 2*a WHERE a > 2;
COMMIT;
BEGIN;
SET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READ;
UPDATE t1 SET b = 3*a WHERE a > 3;
COMMIT;
BEGIN;
SET SESSION TRANSACTION ISOLATION LEVEL SERIALIZABLE;
UPDATE t1 SET b = 4*a WHERE a > 4;
COMMIT;
SET BINLOG_FORMAT=MIXED;
BEGIN;
SET SESSION TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;
UPDATE t1 SET b = 1*a WHERE a > 1;
COMMIT;
BEGIN;
SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED;
UPDATE t1 SET b = 2*a WHERE a > 2;
COMMIT;
BEGIN;
SET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READ;
UPDATE t1 SET b = 3*a WHERE a > 3;
COMMIT;
BEGIN;
SET SESSION TRANSACTION ISOLATION LEVEL SERIALIZABLE;
UPDATE t1 SET b = 4*a WHERE a > 4;
COMMIT;
SET BINLOG_FORMAT=ROW;
BEGIN;
SET SESSION TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;
UPDATE t1 SET b = 1*a WHERE a > 1;
COMMIT;
BEGIN;
SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED;
UPDATE t1 SET b = 2*a WHERE a > 2;
COMMIT;
BEGIN;
SET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READ;
UPDATE t1 SET b = 3*a WHERE a > 3;
COMMIT;
BEGIN;
SET SESSION TRANSACTION ISOLATION LEVEL SERIALIZABLE;
UPDATE t1 SET b = 4*a WHERE a > 4;
COMMIT;
source include/show_binlog_events.inc;
DROP TABLE t1;
--- 1.331/storage/innobase/handler/ha_innodb.cc 2007-05-31 11:12:33 +02:00
+++ 1.332/storage/innobase/handler/ha_innodb.cc 2007-05-31 11:12:33 +02:00
@@ -1003,6 +1003,7 @@
HA_CAN_SQL_HANDLER |
HA_PRIMARY_KEY_REQUIRED_FOR_POSITION |
HA_PRIMARY_KEY_IN_READ_INDEX |
+ HA_BINLOG_ROW_CAPABLE |
HA_CAN_GEOMETRY | HA_PARTIAL_COLUMN_READ |
HA_TABLE_SCAN_ON_INDEX),
start_of_scan(0),
@@ -2312,6 +2313,35 @@
}
ut_ad(0);
return(ROW_TYPE_NOT_USED);
+}
+
+
+
+/********************************************************************
+Get the table flags to use for the statement. */
+handler::Table_flags
+ha_innobase::table_flags() const
+{
+ THD *const thd= current_thd;
+
+ ulong const binlog_format= thd->variables.binlog_format;
+ ulong const tx_isolation= thd->variables.tx_isolation;
+
+ /* Print an informative error in the case that an error will be
+ printed by the server. */
+ if (binlog_format == BINLOG_FORMAT_STMT
+ && tx_isolation == ISO_READ_COMMITTED)
+ {
+ sql_print_error("Transaction level '%s' is not safe"
+ " for binlog mode '%s'",
+ tx_isolation_names[tx_isolation],
+ binlog_format_names[binlog_format]);
+ }
+
+ Table_flags flags= int_table_flags;
+ if (thd->variables.tx_isolation != ISO_READ_COMMITTED)
+ flags|= HA_BINLOG_STMT_CAPABLE;
+ return flags;
}
/********************************************************************
--- 1.136/storage/innobase/handler/ha_innodb.h 2007-05-31 11:12:33 +02:00
+++ 1.137/storage/innobase/handler/ha_innodb.h 2007-05-31 11:12:33 +02:00
@@ -54,7 +54,7 @@
ulong upd_and_key_val_buff_len;
/* the length of each of the previous
two buffers */
- ulong int_table_flags;
+ Table_flags int_table_flags;
uint primary_key;
ulong start_of_scan; /* this is set to 1 when we are
starting a table scan but have not
@@ -84,7 +84,7 @@
const char* table_type() const { return("InnoDB");}
const char *index_type(uint key_number) { return "BTREE"; }
const char** bas_ext() const;
- ulonglong table_flags() const { return int_table_flags; }
+ Table_flags table_flags() const;
ulong index_flags(uint idx, uint part, bool all_parts) const
{
return (HA_READ_NEXT |
| Thread |
|---|
| • bk commit into 5.1 tree (mats:1.2584) BUG#23051 | Mats Kindahl | 31 May |