mirror of
https://github.com/MariaDB/server.git
synced 2025-01-16 12:02:42 +01:00
Merge kindahl-laptop.dnsalias.net:/home/bkroot/mysql-5.1-rpl
into kindahl-laptop.dnsalias.net:/home/bk/b23051-mysql-5.1-rpl BitKeeper/deleted/.del-binlog_row_blackhole.result: Auto merged sql/ha_ndbcluster.cc: Auto merged sql/handler.cc: Auto merged sql/mysql_priv.h: Auto merged sql/sql_base.cc: Auto merged sql/share/errmsg.txt: Auto merged storage/blackhole/ha_blackhole.h: Auto merged storage/innobase/handler/ha_innodb.cc: Auto merged storage/innobase/handler/ha_innodb.h: Auto merged storage/myisam/ha_myisam.cc: Auto merged mysql-test/t/partition_hash.test: Manual merge sql/handler.h: Manual merge sql/set_var.cc: Manual merge sql/sql_class.h: Manual merge sql/sql_insert.cc: Manual merge sql/sql_parse.cc: Manual merge
This commit is contained in:
commit
492ebf924b
27 changed files with 619 additions and 215 deletions
114
mysql-test/r/binlog_innodb.result
Normal file
114
mysql-test/r/binlog_innodb.result
Normal file
|
@ -0,0 +1,114 @@
|
|||
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;
|
||||
SET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READ;
|
||||
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;
|
||||
ERROR HY000: Logging not possible. Message: InnoDB: Transaction level 'READ-UNCOMMITTED' is not safe for binlog mode 'STATEMENT'
|
||||
COMMIT;
|
||||
BEGIN;
|
||||
SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED;
|
||||
UPDATE t1 SET b = 2*a WHERE a > 2;
|
||||
ERROR HY000: Logging not possible. Message: InnoDB: Transaction level 'READ-COMMITTED' is not safe for binlog mode 'STATEMENT'
|
||||
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 = 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 # 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;
|
86
mysql-test/r/binlog_multi_engine.result
Normal file
86
mysql-test/r/binlog_multi_engine.result
Normal file
|
@ -0,0 +1,86 @@
|
|||
CREATE TABLE t1m (m INT, n INT) ENGINE=MYISAM;
|
||||
CREATE TABLE t1b (b INT, c INT) ENGINE=BLACKHOLE;
|
||||
CREATE TABLE t1n (e INT, f INT) ENGINE=NDB;
|
||||
SET SESSION BINLOG_FORMAT=STATEMENT;
|
||||
INSERT INTO t1m VALUES (1,1), (1,2), (2,1), (2,2);
|
||||
INSERT INTO t1b VALUES (1,1), (1,2), (2,1), (2,2);
|
||||
INSERT INTO t1n VALUES (1,1), (1,2), (2,1), (2,2);
|
||||
ERROR HY000: Attempting to log statement in in statement format, but statement format is not possible with this combination of engines
|
||||
UPDATE t1m, t1b SET m = 2, b = 3 WHERE n = c;
|
||||
UPDATE t1m, t1n SET m = 2, e = 3 WHERE n = f;
|
||||
ERROR HY000: Attempting to log statement in in statement format, but statement format is not possible with this combination of engines
|
||||
UPDATE t1n, t1b SET e = 2, b = 3 WHERE f = c;
|
||||
ERROR HY000: It is not possible to log anything with this combination of engines
|
||||
TRUNCATE t1m;
|
||||
TRUNCATE t1b;
|
||||
TRUNCATE t1n;
|
||||
SET SESSION BINLOG_FORMAT=MIXED;
|
||||
INSERT INTO t1m VALUES (1,1), (1,2), (2,1), (2,2);
|
||||
INSERT INTO t1b VALUES (1,1), (1,2), (2,1), (2,2);
|
||||
INSERT INTO t1n VALUES (1,1), (1,2), (2,1), (2,2);
|
||||
UPDATE t1m, t1b SET m = 2, b = 3 WHERE n = c;
|
||||
UPDATE t1m, t1n SET m = 2, e = 3 WHERE n = f;
|
||||
UPDATE t1n, t1b SET e = 2, b = 3 WHERE f = c;
|
||||
ERROR HY000: It is not possible to log anything with this combination of engines
|
||||
TRUNCATE t1m;
|
||||
TRUNCATE t1b;
|
||||
TRUNCATE t1n;
|
||||
SET SESSION BINLOG_FORMAT=ROW;
|
||||
INSERT INTO t1m VALUES (1,1), (1,2), (2,1), (2,2);
|
||||
INSERT INTO t1b VALUES (1,1), (1,2), (2,1), (2,2);
|
||||
ERROR HY000: Attempting to log statement in in row format, but row format is not possible with this combination of engines
|
||||
INSERT INTO t1n VALUES (1,1), (1,2), (2,1), (2,2);
|
||||
UPDATE t1m, t1b SET m = 2, b = 3 WHERE n = c;
|
||||
ERROR HY000: Attempting to log statement in in row format, but row format is not possible with this combination of engines
|
||||
UPDATE t1m, t1n SET m = 2, e = 3 WHERE n = f;
|
||||
UPDATE t1n, t1b SET e = 2, b = 3 WHERE f = c;
|
||||
ERROR HY000: It is not possible to log anything with this combination of engines
|
||||
TRUNCATE t1m;
|
||||
TRUNCATE t1b;
|
||||
TRUNCATE t1n;
|
||||
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 t1m (m INT, n INT) ENGINE=MYISAM
|
||||
master-bin.000001 # Query # # use `test`; CREATE TABLE t1b (b INT, c INT) ENGINE=BLACKHOLE
|
||||
master-bin.000001 # Query # # use `test`; CREATE TABLE t1n (e INT, f INT) ENGINE=NDB
|
||||
master-bin.000001 # Query # # use `test`; INSERT INTO t1m VALUES (1,1), (1,2), (2,1), (2,2)
|
||||
master-bin.000001 # Query # # use `test`; INSERT INTO t1b VALUES (1,1), (1,2), (2,1), (2,2)
|
||||
master-bin.000001 # Query # # use `test`; UPDATE t1m, t1b SET m = 2, b = 3 WHERE n = c
|
||||
master-bin.000001 # Query # # use `test`; TRUNCATE t1m
|
||||
master-bin.000001 # Query # # use `test`; TRUNCATE t1b
|
||||
master-bin.000001 # Query # # use `test`; TRUNCATE t1n
|
||||
master-bin.000001 # Query # # use `test`; INSERT INTO t1m VALUES (1,1), (1,2), (2,1), (2,2)
|
||||
master-bin.000001 # Query # # use `test`; INSERT INTO t1b VALUES (1,1), (1,2), (2,1), (2,2)
|
||||
master-bin.000001 # Query # # use `test`; INSERT INTO t1n VALUES (1,1), (1,2), (2,1), (2,2)
|
||||
master-bin.000001 # Query # # use `test`; UPDATE t1m, t1b SET m = 2, b = 3 WHERE n = c
|
||||
master-bin.000001 # Query # # use `test`; UPDATE t1m, t1n SET m = 2, e = 3 WHERE n = f
|
||||
master-bin.000001 # Query # # use `test`; TRUNCATE t1m
|
||||
master-bin.000001 # Query # # use `test`; TRUNCATE t1b
|
||||
master-bin.000001 # Query # # BEGIN
|
||||
master-bin.000001 # Table_map # # table_id: # (test.t1n)
|
||||
master-bin.000001 # Table_map # # table_id: # (mysql.ndb_apply_status)
|
||||
master-bin.000001 # Write_rows # # table_id: #
|
||||
master-bin.000001 # Write_rows # # table_id: #
|
||||
master-bin.000001 # Write_rows # # table_id: #
|
||||
master-bin.000001 # Update_rows # # table_id: #
|
||||
master-bin.000001 # Update_rows # # table_id: # flags: STMT_END_F
|
||||
master-bin.000001 # Query # # COMMIT
|
||||
master-bin.000001 # Query # # use `test`; TRUNCATE t1n
|
||||
master-bin.000001 # Table_map # # table_id: # (test.t1m)
|
||||
master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
|
||||
master-bin.000001 # Table_map # # table_id: # (test.t1m)
|
||||
master-bin.000001 # Table_map # # table_id: # (test.t1n)
|
||||
master-bin.000001 # Update_rows # # table_id: # flags: STMT_END_F
|
||||
master-bin.000001 # Query # # use `test`; TRUNCATE t1m
|
||||
master-bin.000001 # Query # # use `test`; TRUNCATE t1b
|
||||
master-bin.000001 # Query # # BEGIN
|
||||
master-bin.000001 # Table_map # # table_id: # (test.t1n)
|
||||
master-bin.000001 # Table_map # # table_id: # (mysql.ndb_apply_status)
|
||||
master-bin.000001 # Write_rows # # table_id: #
|
||||
master-bin.000001 # Write_rows # # table_id: #
|
||||
master-bin.000001 # Write_rows # # table_id: #
|
||||
master-bin.000001 # Update_rows # # table_id: #
|
||||
master-bin.000001 # Update_rows # # table_id: # flags: STMT_END_F
|
||||
master-bin.000001 # Query # # COMMIT
|
||||
master-bin.000001 # Query # # use `test`; TRUNCATE t1n
|
||||
DROP TABLE t1m, t1b, t1n;
|
|
@ -1,155 +0,0 @@
|
|||
drop table if exists t1,t2;
|
||||
CREATE TABLE t1 (
|
||||
Period smallint(4) unsigned zerofill DEFAULT '0000' NOT NULL,
|
||||
Varor_period smallint(4) unsigned DEFAULT '0' NOT NULL
|
||||
) ENGINE=blackhole;
|
||||
INSERT INTO t1 VALUES (9410,9412);
|
||||
select period from t1;
|
||||
period
|
||||
select * from t1;
|
||||
Period Varor_period
|
||||
select t1.* from t1;
|
||||
Period Varor_period
|
||||
CREATE TABLE t2 (
|
||||
auto int NOT NULL auto_increment,
|
||||
fld1 int(6) unsigned zerofill DEFAULT '000000' NOT NULL,
|
||||
companynr tinyint(2) unsigned zerofill DEFAULT '00' NOT NULL,
|
||||
fld3 char(30) DEFAULT '' NOT NULL,
|
||||
fld4 char(35) DEFAULT '' NOT NULL,
|
||||
fld5 char(35) DEFAULT '' NOT NULL,
|
||||
fld6 char(4) DEFAULT '' NOT NULL,
|
||||
primary key (auto)
|
||||
) ENGINE=blackhole;
|
||||
INSERT INTO t2 VALUES (1192,068305,00,'Colombo','hardware','colicky','');
|
||||
INSERT INTO t2 VALUES (1193,000000,00,'nondecreasing','implant','thrillingly','');
|
||||
select t2.fld3 from t2 where companynr = 58 and fld3 like "%imaginable%";
|
||||
fld3
|
||||
select fld3 from t2 where fld3 like "%cultivation" ;
|
||||
fld3
|
||||
select t2.fld3,companynr from t2 where companynr = 57+1 order by fld3;
|
||||
fld3 companynr
|
||||
select fld3,companynr from t2 where companynr = 58 order by fld3;
|
||||
fld3 companynr
|
||||
select fld3 from t2 order by fld3 desc limit 10;
|
||||
fld3
|
||||
select fld3 from t2 order by fld3 desc limit 5;
|
||||
fld3
|
||||
select fld3 from t2 order by fld3 desc limit 5,5;
|
||||
fld3
|
||||
select t2.fld3 from t2 where fld3 = 'honeysuckle';
|
||||
fld3
|
||||
select t2.fld3 from t2 where fld3 LIKE 'honeysuckl_';
|
||||
fld3
|
||||
select t2.fld3 from t2 where fld3 LIKE 'hon_ysuckl_';
|
||||
fld3
|
||||
select t2.fld3 from t2 where fld3 LIKE 'honeysuckle%';
|
||||
fld3
|
||||
select t2.fld3 from t2 where fld3 LIKE 'h%le';
|
||||
fld3
|
||||
select t2.fld3 from t2 where fld3 LIKE 'honeysuckle_';
|
||||
fld3
|
||||
select t2.fld3 from t2 where fld3 LIKE 'don_t_find_me_please%';
|
||||
fld3
|
||||
select t2.fld3 from t2 where fld3 >= 'honeysuckle' and fld3 <= 'honoring' order by fld3;
|
||||
fld3
|
||||
select fld1,fld3 from t2 where fld3="Colombo" or fld3 = "nondecreasing" order by fld3;
|
||||
fld1 fld3
|
||||
DROP TABLE t1;
|
||||
CREATE TABLE t1 (a VARCHAR(200), b TEXT, FULLTEXT (a,b));
|
||||
INSERT INTO t1 VALUES('MySQL has now support', 'for full-text search'),
|
||||
('Full-text indexes', 'are called collections'),
|
||||
('Only MyISAM tables','support collections'),
|
||||
('Function MATCH ... AGAINST()','is used to do a search'),
|
||||
('Full-text search in MySQL', 'implements vector space model');
|
||||
SHOW INDEX FROM t1;
|
||||
Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment
|
||||
t1 1 a 1 a NULL NULL NULL NULL YES FULLTEXT
|
||||
t1 1 a 2 b NULL NULL NULL NULL YES FULLTEXT
|
||||
select * from t1 where MATCH(a,b) AGAINST ("collections");
|
||||
a b
|
||||
Only MyISAM tables support collections
|
||||
Full-text indexes are called collections
|
||||
explain extended select * from t1 where MATCH(a,b) AGAINST ("collections");
|
||||
id select_type table type possible_keys key key_len ref rows filtered Extra
|
||||
1 SIMPLE t1 fulltext a a 0 1 100.00 Using where
|
||||
Warnings:
|
||||
Note 1003 select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t1` where (match `test`.`t1`.`a`,`test`.`t1`.`b` against (_latin1'collections'))
|
||||
select * from t1 where MATCH(a,b) AGAINST ("indexes");
|
||||
a b
|
||||
Full-text indexes are called collections
|
||||
select * from t1 where MATCH(a,b) AGAINST ("indexes collections");
|
||||
a b
|
||||
Full-text indexes are called collections
|
||||
Only MyISAM tables support collections
|
||||
select * from t1 where MATCH(a,b) AGAINST ("only");
|
||||
a b
|
||||
reset master;
|
||||
drop table t1,t2;
|
||||
create table t1 (a int) engine=blackhole;
|
||||
delete from t1 where a=10;
|
||||
update t1 set a=11 where a=15;
|
||||
insert into t1 values(1);
|
||||
insert ignore into t1 values(1);
|
||||
replace into t1 values(100);
|
||||
create table t2 (a varchar(200)) engine=blackhole;
|
||||
load data infile '../std_data_ln/words.dat' into table t2;
|
||||
alter table t1 add b int;
|
||||
alter table t1 drop b;
|
||||
create table t3 like t1;
|
||||
insert into t1 select * from t3;
|
||||
replace into t1 select * from t3;
|
||||
select * from t1;
|
||||
a
|
||||
select * from t2;
|
||||
a
|
||||
select * from t3;
|
||||
a
|
||||
show binlog events from <binlog_start>;
|
||||
Log_name Pos Event_type Server_id End_log_pos Info
|
||||
master-bin.000001 # Query # # use `test`; drop table t1,t2
|
||||
master-bin.000001 # Query # # use `test`; create table t1 (a int) engine=blackhole
|
||||
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 # Table_map # # table_id: # (test.t1)
|
||||
master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
|
||||
master-bin.000001 # Query # # use `test`; create table t2 (a varchar(200)) engine=blackhole
|
||||
master-bin.000001 # Table_map # # table_id: # (test.t2)
|
||||
master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
|
||||
master-bin.000001 # Query # # use `test`; alter table t1 add b int
|
||||
master-bin.000001 # Query # # use `test`; alter table t1 drop b
|
||||
master-bin.000001 # Query # # use `test`; create table t3 like t1
|
||||
drop table t1,t2,t3;
|
||||
CREATE TABLE t1(a INT) ENGINE=BLACKHOLE;
|
||||
INSERT DELAYED INTO t1 VALUES(1);
|
||||
DROP TABLE t1;
|
||||
CREATE TABLE t1(a INT, b INT) ENGINE=BLACKHOLE;
|
||||
DELETE FROM t1 WHERE a=10;
|
||||
ALTER TABLE t1 ADD INDEX(a);
|
||||
DELETE FROM t1 WHERE a=10;
|
||||
ALTER TABLE t1 DROP INDEX a;
|
||||
ALTER TABLE t1 ADD UNIQUE INDEX(a);
|
||||
DELETE FROM t1 WHERE a=10;
|
||||
ALTER TABLE t1 DROP INDEX a;
|
||||
ALTER TABLE t1 ADD PRIMARY KEY(a);
|
||||
DELETE FROM t1 WHERE a=10;
|
||||
DROP TABLE t1;
|
||||
reset master;
|
||||
create table t1 (a int) engine=blackhole;
|
||||
set autocommit=0;
|
||||
start transaction;
|
||||
insert into t1 values(1);
|
||||
commit;
|
||||
start transaction;
|
||||
insert into t1 values(2);
|
||||
rollback;
|
||||
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`; create table t1 (a int) engine=blackhole
|
||||
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 # Query # # use `test`; COMMIT
|
||||
drop table if exists t1;
|
95
mysql-test/t/binlog_innodb.test
Normal file
95
mysql-test/t/binlog_innodb.test
Normal file
|
@ -0,0 +1,95 @@
|
|||
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;
|
||||
SET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READ;
|
||||
# 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 level in STATEMENT binlog mode.
|
||||
|
||||
SET BINLOG_FORMAT=STATEMENT;
|
||||
|
||||
BEGIN;
|
||||
SET SESSION TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;
|
||||
error ER_BINLOG_LOGGING_IMPOSSIBLE;
|
||||
UPDATE t1 SET b = 1*a WHERE a > 1;
|
||||
COMMIT;
|
||||
|
||||
BEGIN;
|
||||
SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED;
|
||||
error ER_BINLOG_LOGGING_IMPOSSIBLE;
|
||||
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;
|
59
mysql-test/t/binlog_multi_engine.test
Normal file
59
mysql-test/t/binlog_multi_engine.test
Normal file
|
@ -0,0 +1,59 @@
|
|||
source include/have_blackhole.inc;
|
||||
source include/have_ndb.inc;
|
||||
|
||||
CREATE TABLE t1m (m INT, n INT) ENGINE=MYISAM;
|
||||
CREATE TABLE t1b (b INT, c INT) ENGINE=BLACKHOLE;
|
||||
CREATE TABLE t1n (e INT, f INT) ENGINE=NDB;
|
||||
|
||||
SET SESSION BINLOG_FORMAT=STATEMENT;
|
||||
|
||||
INSERT INTO t1m VALUES (1,1), (1,2), (2,1), (2,2);
|
||||
INSERT INTO t1b VALUES (1,1), (1,2), (2,1), (2,2);
|
||||
error ER_BINLOG_STMT_FORMAT_FORBIDDEN;
|
||||
INSERT INTO t1n VALUES (1,1), (1,2), (2,1), (2,2);
|
||||
|
||||
UPDATE t1m, t1b SET m = 2, b = 3 WHERE n = c;
|
||||
error ER_BINLOG_STMT_FORMAT_FORBIDDEN;
|
||||
UPDATE t1m, t1n SET m = 2, e = 3 WHERE n = f;
|
||||
error ER_BINLOG_ENGINES_INCOMPATIBLE;
|
||||
UPDATE t1n, t1b SET e = 2, b = 3 WHERE f = c;
|
||||
|
||||
TRUNCATE t1m;
|
||||
TRUNCATE t1b;
|
||||
TRUNCATE t1n;
|
||||
|
||||
SET SESSION BINLOG_FORMAT=MIXED;
|
||||
|
||||
INSERT INTO t1m VALUES (1,1), (1,2), (2,1), (2,2);
|
||||
INSERT INTO t1b VALUES (1,1), (1,2), (2,1), (2,2);
|
||||
INSERT INTO t1n VALUES (1,1), (1,2), (2,1), (2,2);
|
||||
|
||||
UPDATE t1m, t1b SET m = 2, b = 3 WHERE n = c;
|
||||
UPDATE t1m, t1n SET m = 2, e = 3 WHERE n = f;
|
||||
error ER_BINLOG_ENGINES_INCOMPATIBLE;
|
||||
UPDATE t1n, t1b SET e = 2, b = 3 WHERE f = c;
|
||||
|
||||
TRUNCATE t1m;
|
||||
TRUNCATE t1b;
|
||||
TRUNCATE t1n;
|
||||
|
||||
SET SESSION BINLOG_FORMAT=ROW;
|
||||
|
||||
INSERT INTO t1m VALUES (1,1), (1,2), (2,1), (2,2);
|
||||
error ER_BINLOG_ROW_FORMAT_FORBIDDEN;
|
||||
INSERT INTO t1b VALUES (1,1), (1,2), (2,1), (2,2);
|
||||
INSERT INTO t1n VALUES (1,1), (1,2), (2,1), (2,2);
|
||||
|
||||
error ER_BINLOG_ROW_FORMAT_FORBIDDEN;
|
||||
UPDATE t1m, t1b SET m = 2, b = 3 WHERE n = c;
|
||||
UPDATE t1m, t1n SET m = 2, e = 3 WHERE n = f;
|
||||
error ER_BINLOG_ENGINES_INCOMPATIBLE;
|
||||
UPDATE t1n, t1b SET e = 2, b = 3 WHERE f = c;
|
||||
|
||||
TRUNCATE t1m;
|
||||
TRUNCATE t1b;
|
||||
TRUNCATE t1n;
|
||||
|
||||
source include/show_binlog_events.inc;
|
||||
|
||||
DROP TABLE t1m, t1b, t1n;
|
|
@ -1,11 +0,0 @@
|
|||
# This is a wrapper for binlog.test so that the same test case can be used
|
||||
# For both statement and row based bin logs 9/19/2005 [jbm]
|
||||
|
||||
-- source include/have_binlog_format_row.inc
|
||||
|
||||
# Bug#18326: Do not lock table for writing during prepare of statement
|
||||
# The use of the ps protocol causes extra table maps in the binlog, so
|
||||
# we disable the ps-protocol for this statement.
|
||||
--disable_ps_protocol
|
||||
-- source extra/binlog_tests/blackhole.test
|
||||
--enable_ps_protocol
|
|
@ -134,6 +134,7 @@ drop table t1;
|
|||
--disable_warnings
|
||||
CREATE TABLE t1 (s1 int) ENGINE=BLACKHOLE PARTITION BY HASH (s1);
|
||||
--enable_warnings
|
||||
--error 0,ER_BINLOG_ROW_FORMAT_FORBIDDEN
|
||||
INSERT INTO t1 VALUES (0);
|
||||
DROP TABLE t1;
|
||||
|
||||
|
|
|
@ -4509,7 +4509,6 @@ int ha_ndbcluster::external_lock(THD *thd, int lock_type)
|
|||
DBUG_PRINT("warning", ("ops_pending != 0L"));
|
||||
m_ops_pending= 0;
|
||||
}
|
||||
thd->set_current_stmt_binlog_row_based_if_mixed();
|
||||
DBUG_RETURN(error);
|
||||
}
|
||||
|
||||
|
@ -4559,7 +4558,6 @@ int ha_ndbcluster::start_stmt(THD *thd, thr_lock_type lock_type)
|
|||
m_active_trans= trans;
|
||||
// Start of statement
|
||||
m_ops_pending= 0;
|
||||
thd->set_current_stmt_binlog_row_based_if_mixed();
|
||||
|
||||
DBUG_RETURN(error);
|
||||
}
|
||||
|
@ -6117,6 +6115,7 @@ void ha_ndbcluster::get_auto_increment(ulonglong offset, ulonglong increment,
|
|||
HA_PRIMARY_KEY_REQUIRED_FOR_DELETE | \
|
||||
HA_PARTIAL_COLUMN_READ | \
|
||||
HA_HAS_OWN_BINLOGGING | \
|
||||
HA_BINLOG_ROW_CAPABLE | \
|
||||
HA_HAS_RECORDS
|
||||
|
||||
ha_ndbcluster::ha_ndbcluster(handlerton *hton, TABLE_SHARE *table_arg):
|
||||
|
@ -8923,7 +8922,6 @@ pthread_handler_t ndb_util_thread_func(void *arg __attribute__((unused)))
|
|||
my_net_init(&thd->net, 0);
|
||||
thd->main_security_ctx.master_access= ~0;
|
||||
thd->main_security_ctx.priv_user = 0;
|
||||
thd->current_stmt_binlog_row_based= TRUE; // If in mixed mode
|
||||
|
||||
/* Signal successful initialization */
|
||||
ndb_util_thread_running= 1;
|
||||
|
|
|
@ -3639,7 +3639,15 @@ int handler::ha_external_lock(THD *thd, int lock_type)
|
|||
taken a table lock), ha_release_auto_increment() was too.
|
||||
*/
|
||||
DBUG_ASSERT(next_insert_id == 0);
|
||||
DBUG_RETURN(external_lock(thd, lock_type));
|
||||
|
||||
/*
|
||||
We cache the table flags if the locking succeeded. Otherwise, we
|
||||
keep them as they were when they were fetched in ha_open().
|
||||
*/
|
||||
int error= external_lock(thd, lock_type);
|
||||
if (error == 0)
|
||||
cached_table_flags= table_flags();
|
||||
DBUG_RETURN(error);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -117,6 +117,18 @@
|
|||
#define HA_HAS_RECORDS (LL(1) << 32) /* records() gives exact count*/
|
||||
/* Has it's own method of binlog logging */
|
||||
#define HA_HAS_OWN_BINLOGGING (LL(1) << 33)
|
||||
/*
|
||||
Engine is capable of row-format and statement-format logging,
|
||||
respectively
|
||||
*/
|
||||
#define HA_BINLOG_ROW_CAPABLE (LL(1) << 34)
|
||||
#define HA_BINLOG_STMT_CAPABLE (LL(1) << 35)
|
||||
|
||||
/*
|
||||
Set of all binlog flags. Currently only contain the capabilities
|
||||
flags.
|
||||
*/
|
||||
#define HA_BINLOG_FLAGS (HA_BINLOG_ROW_CAPABLE | HA_BINLOG_STMT_CAPABLE)
|
||||
|
||||
/* bits in index_flags(index_number) for what you can do with index */
|
||||
#define HA_READ_NEXT 1 /* TODO really use this flag */
|
||||
|
@ -688,7 +700,7 @@ struct handlerton
|
|||
};
|
||||
|
||||
|
||||
/* Possible flags of a handlerton */
|
||||
/* Possible flags of a handlerton (there can be 32 of them) */
|
||||
#define HTON_NO_FLAGS 0
|
||||
#define HTON_CLOSE_CURSORS_AT_COMMIT (1 << 0)
|
||||
#define HTON_ALTER_NOT_SUPPORTED (1 << 1) //Engine does not support alter
|
||||
|
@ -793,19 +805,37 @@ typedef struct st_key_create_information
|
|||
class TABLEOP_HOOKS
|
||||
{
|
||||
public:
|
||||
TABLEOP_HOOKS() {}
|
||||
virtual ~TABLEOP_HOOKS() {}
|
||||
|
||||
inline void prelock(TABLE **tables, uint count)
|
||||
{
|
||||
do_prelock(tables, count);
|
||||
}
|
||||
virtual ~TABLEOP_HOOKS() {}
|
||||
TABLEOP_HOOKS() {}
|
||||
|
||||
inline int postlock(TABLE **tables, uint count)
|
||||
{
|
||||
return do_postlock(tables, count);
|
||||
}
|
||||
private:
|
||||
/* Function primitive that is called prior to locking tables */
|
||||
virtual void do_prelock(TABLE **tables, uint count)
|
||||
{
|
||||
/* Default is to do nothing */
|
||||
}
|
||||
|
||||
/**
|
||||
Primitive called after tables are locked.
|
||||
|
||||
If an error is returned, the tables will be unlocked and error
|
||||
handling start.
|
||||
|
||||
@return Error code or zero.
|
||||
*/
|
||||
virtual int do_postlock(TABLE **tables, uint count)
|
||||
{
|
||||
return 0; /* Default is to do nothing */
|
||||
}
|
||||
};
|
||||
|
||||
typedef struct st_savepoint SAVEPOINT;
|
||||
|
@ -892,10 +922,13 @@ class handler :public Sql_alloc
|
|||
friend int ha_delete_table(THD*,handlerton*,const char*,const char*,
|
||||
const char*,bool);
|
||||
|
||||
public:
|
||||
typedef ulonglong Table_flags;
|
||||
|
||||
protected:
|
||||
struct st_table_share *table_share; /* The table definition */
|
||||
struct st_table *table; /* The current open table */
|
||||
ulonglong cached_table_flags; /* Set on init() and open() */
|
||||
Table_flags cached_table_flags; /* Set on init() and open() */
|
||||
|
||||
virtual int index_init(uint idx, bool sorted) { active_index=idx; return 0; }
|
||||
virtual int index_end() { active_index=MAX_KEY; return 0; }
|
||||
|
@ -908,7 +941,7 @@ class handler :public Sql_alloc
|
|||
*/
|
||||
virtual int rnd_init(bool scan) =0;
|
||||
virtual int rnd_end() { return 0; }
|
||||
virtual ulonglong table_flags(void) const =0;
|
||||
virtual Table_flags table_flags(void) const =0;
|
||||
|
||||
void ha_statistic_increment(ulong SSV::*offset) const;
|
||||
void **ha_data(THD *) const;
|
||||
|
@ -1122,7 +1155,7 @@ public:
|
|||
{
|
||||
return inited == INDEX ? ha_index_end() : inited == RND ? ha_rnd_end() : 0;
|
||||
}
|
||||
longlong ha_table_flags() { return cached_table_flags; }
|
||||
Table_flags ha_table_flags() const { return cached_table_flags; }
|
||||
|
||||
/*
|
||||
Signal that the table->read_set and table->write_set table maps changed
|
||||
|
@ -1686,6 +1719,8 @@ private:
|
|||
/* 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;
|
||||
|
|
|
@ -1274,6 +1274,7 @@ int simple_open_n_lock_tables(THD *thd,TABLE_LIST *tables);
|
|||
bool open_and_lock_tables(THD *thd,TABLE_LIST *tables);
|
||||
bool open_normal_and_derived_tables(THD *thd, TABLE_LIST *tables, uint flags);
|
||||
int lock_tables(THD *thd, TABLE_LIST *tables, uint counter, bool *need_reopen);
|
||||
int decide_logging_format(THD *thd, TABLE_LIST *tables);
|
||||
TABLE *open_temporary_table(THD *thd, const char *path, const char *db,
|
||||
const char *table_name, bool link_in_list);
|
||||
bool rm_temporary_table(handlerton *base, char *path);
|
||||
|
|
|
@ -1007,17 +1007,6 @@ bool sys_var_thd_binlog_format::is_readonly() const
|
|||
my_error(ER_STORED_FUNCTION_PREVENTS_SWITCH_BINLOG_FORMAT, MYF(0));
|
||||
return 1;
|
||||
}
|
||||
#ifdef HAVE_NDB_BINLOG
|
||||
/*
|
||||
Cluster does not support changing the binlog format on the fly yet.
|
||||
*/
|
||||
LEX_STRING ndb_name= {(char*)STRING_WITH_LEN("ndbcluster")};
|
||||
if (opt_bin_log && plugin_is_ready(&ndb_name, MYSQL_STORAGE_ENGINE_PLUGIN))
|
||||
{
|
||||
my_error(ER_NDB_CANT_SWITCH_BINLOG_FORMAT, MYF(0));
|
||||
return 1;
|
||||
}
|
||||
#endif /* HAVE_NDB_BINLOG */
|
||||
return sys_var_thd_enum::is_readonly();
|
||||
}
|
||||
|
||||
|
|
|
@ -6062,3 +6062,5 @@ ER_NO_PARTITION_FOR_GIVEN_VALUE_SILENT
|
|||
ER_BINLOG_UNSAFE_STATEMENT
|
||||
eng "Statement is not safe to log in statement format."
|
||||
swe "Detta är inte säkert att logga i statement-format."
|
||||
ER_BINLOG_LOGGING_IMPOSSIBLE
|
||||
eng "Binary logging not possible. Message: %s"
|
||||
|
|
128
sql/sql_base.cc
128
sql/sql_base.cc
|
@ -3948,6 +3948,121 @@ static void mark_real_tables_as_free_for_reuse(TABLE_LIST *table)
|
|||
}
|
||||
|
||||
|
||||
/**
|
||||
Decide on logging format to use for the statement.
|
||||
|
||||
Compute the capabilities vector for the involved storage engines
|
||||
and mask out the flags for the binary log. Right now, the binlog
|
||||
flags only include the capabilities of the storage engines, so this
|
||||
is safe.
|
||||
|
||||
We now have three alternatives that prevent the statement from
|
||||
being loggable:
|
||||
|
||||
1. If there are no capabilities left (all flags are clear) it is
|
||||
not possible to log the statement at all, so we roll back the
|
||||
statement and report an error.
|
||||
|
||||
2. Statement mode is set, but the capabilities indicate that
|
||||
statement format is not possible.
|
||||
|
||||
3. Row mode is set, but the capabilities indicate that row
|
||||
format is not possible.
|
||||
|
||||
4. Statement is unsafe, but the capabilities indicate that row
|
||||
format is not possible.
|
||||
|
||||
If we are in MIXED mode, we then decide what logging format to use:
|
||||
|
||||
1. If the statement is unsafe, row-based logging is used.
|
||||
|
||||
2. If statement-based logging is not possible, row-based logging is
|
||||
used.
|
||||
|
||||
3. Otherwise, statement-based logging is used.
|
||||
|
||||
@param thd Client thread
|
||||
@param tables Tables involved in the query
|
||||
*/
|
||||
|
||||
int decide_logging_format(THD *thd, TABLE_LIST *tables)
|
||||
{
|
||||
if (mysql_bin_log.is_open() && (thd->options & OPTION_BIN_LOG))
|
||||
{
|
||||
handler::Table_flags binlog_flags= ~handler::Table_flags();
|
||||
for (TABLE_LIST *table= tables; table; table= table->next_global)
|
||||
if (!table->placeholder() && table->lock_type >= TL_WRITE_ALLOW_WRITE)
|
||||
{
|
||||
#define FLAGSTR(S,F) ((S) & (F) ? #F " " : "")
|
||||
#ifndef DBUG_OFF
|
||||
ulonglong flags= table->table->file->ha_table_flags();
|
||||
DBUG_PRINT("info", ("table: %s; ha_table_flags: %s%s",
|
||||
table->table_name,
|
||||
FLAGSTR(flags, HA_BINLOG_STMT_CAPABLE),
|
||||
FLAGSTR(flags, HA_BINLOG_ROW_CAPABLE)));
|
||||
#endif
|
||||
binlog_flags &= table->table->file->ha_table_flags();
|
||||
}
|
||||
binlog_flags&= HA_BINLOG_FLAGS;
|
||||
DBUG_PRINT("info", ("binlog_flags: %s%s",
|
||||
FLAGSTR(binlog_flags, HA_BINLOG_STMT_CAPABLE),
|
||||
FLAGSTR(binlog_flags, HA_BINLOG_ROW_CAPABLE)));
|
||||
DBUG_PRINT("info", ("thd->variables.binlog_format: %ld",
|
||||
thd->variables.binlog_format));
|
||||
|
||||
int error= 0;
|
||||
if (binlog_flags == 0)
|
||||
{
|
||||
my_error((error= ER_BINLOG_LOGGING_IMPOSSIBLE), MYF(0),
|
||||
"Statement cannot be logged to the binary log in"
|
||||
" row-based nor statement-based format");
|
||||
}
|
||||
else if (thd->variables.binlog_format == BINLOG_FORMAT_STMT &&
|
||||
(binlog_flags & HA_BINLOG_STMT_CAPABLE) == 0)
|
||||
{
|
||||
my_error((error= ER_BINLOG_LOGGING_IMPOSSIBLE), MYF(0),
|
||||
"Statement-based format required for this statement,"
|
||||
" but not allowed by this combination of engines");
|
||||
}
|
||||
else if ((thd->variables.binlog_format == BINLOG_FORMAT_ROW ||
|
||||
thd->lex->is_stmt_unsafe()) &&
|
||||
(binlog_flags & HA_BINLOG_ROW_CAPABLE) == 0)
|
||||
{
|
||||
my_error((error= ER_BINLOG_LOGGING_IMPOSSIBLE), MYF(0),
|
||||
"Row-based format required for this statement,"
|
||||
" but not allowed by this combination of engines");
|
||||
}
|
||||
|
||||
DBUG_PRINT("info", ("error: %d", error));
|
||||
|
||||
if (error)
|
||||
{
|
||||
ha_rollback_stmt(thd);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/*
|
||||
We switch to row-based format if we are in mixed mode and one of
|
||||
the following are true:
|
||||
|
||||
1. If the statement is unsafe
|
||||
2. If statement format cannot be used
|
||||
|
||||
Observe that point to cannot be decided before the tables
|
||||
involved in a statement has been checked, i.e., we cannot put
|
||||
this code in reset_current_stmt_binlog_row_based(), it has to be
|
||||
here.
|
||||
*/
|
||||
if (thd->lex->is_stmt_unsafe() ||
|
||||
(binlog_flags & HA_BINLOG_STMT_CAPABLE) == 0)
|
||||
{
|
||||
thd->set_current_stmt_binlog_row_based_if_mixed();
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
Lock all tables in list
|
||||
|
||||
|
@ -3986,17 +4101,10 @@ int lock_tables(THD *thd, TABLE_LIST *tables, uint count, bool *need_reopen)
|
|||
in prelocked mode.
|
||||
*/
|
||||
DBUG_ASSERT(!thd->prelocked_mode || !thd->lex->requires_prelocking());
|
||||
|
||||
*need_reopen= FALSE;
|
||||
|
||||
/*
|
||||
CREATE ... SELECT UUID() locks no tables, we have to test here.
|
||||
*/
|
||||
if (thd->lex->is_stmt_unsafe())
|
||||
thd->set_current_stmt_binlog_row_based_if_mixed();
|
||||
|
||||
if (!tables && !thd->lex->requires_prelocking())
|
||||
DBUG_RETURN(0);
|
||||
DBUG_RETURN(decide_logging_format(thd, tables));
|
||||
|
||||
/*
|
||||
We need this extra check for thd->prelocked_mode because we want to avoid
|
||||
|
@ -4049,6 +4157,7 @@ int lock_tables(THD *thd, TABLE_LIST *tables, uint count, bool *need_reopen)
|
|||
}
|
||||
DBUG_RETURN(-1);
|
||||
}
|
||||
|
||||
if (thd->lex->requires_prelocking() &&
|
||||
thd->lex->sql_command != SQLCOM_LOCK_TABLES)
|
||||
{
|
||||
|
@ -4115,7 +4224,8 @@ int lock_tables(THD *thd, TABLE_LIST *tables, uint count, bool *need_reopen)
|
|||
thd->prelocked_mode= PRELOCKED_UNDER_LOCK_TABLES;
|
||||
}
|
||||
}
|
||||
DBUG_RETURN(0);
|
||||
|
||||
DBUG_RETURN(decide_logging_format(thd, tables));
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -2002,20 +2002,21 @@ class select_insert :public select_result_interceptor {
|
|||
class select_create: public select_insert {
|
||||
ORDER *group;
|
||||
TABLE_LIST *create_table;
|
||||
TABLE_LIST *select_tables;
|
||||
HA_CREATE_INFO *create_info;
|
||||
Alter_info *alter_info;
|
||||
Field **field;
|
||||
public:
|
||||
select_create(TABLE_LIST *table_arg,
|
||||
HA_CREATE_INFO *create_info_arg,
|
||||
Alter_info *alter_info_arg,
|
||||
List<Item> &select_fields,
|
||||
enum_duplicates duplic, bool ignore)
|
||||
:select_insert(NULL, NULL, &select_fields, 0, 0, duplic, ignore),
|
||||
select_create (TABLE_LIST *table_arg,
|
||||
HA_CREATE_INFO *create_info_par,
|
||||
List<create_field> &fields_par,
|
||||
List<Key> &keys_par,
|
||||
List<Item> &select_fields,enum_duplicates duplic, bool ignore,
|
||||
TABLE_LIST *select_tables_arg)
|
||||
:select_insert (NULL, NULL, &select_fields, 0, 0, duplic, ignore),
|
||||
create_table(table_arg),
|
||||
create_info(create_info_arg),
|
||||
alter_info(alter_info_arg)
|
||||
{}
|
||||
create_info(create_info_par), select_tables(select_tables_arg)
|
||||
{}
|
||||
int prepare(List<Item> &list, SELECT_LEX_UNIT *u);
|
||||
|
||||
void binlog_show_create_table(TABLE **tables, uint count);
|
||||
|
|
|
@ -3341,8 +3341,15 @@ static TABLE *create_table_from_items(THD *thd, HA_CREATE_INFO *create_info,
|
|||
table->reginfo.lock_type=TL_WRITE;
|
||||
hooks->prelock(&table, 1); // Call prelock hooks
|
||||
if (! ((*lock)= mysql_lock_tables(thd, &table, 1,
|
||||
MYSQL_LOCK_IGNORE_FLUSH, ¬_used)))
|
||||
MYSQL_LOCK_IGNORE_FLUSH, ¬_used)) ||
|
||||
hooks->postlock(&table, 1))
|
||||
{
|
||||
if (*lock)
|
||||
{
|
||||
mysql_unlock_tables(thd, *lock);
|
||||
*lock= 0;
|
||||
}
|
||||
|
||||
if (!create_info->table_existed)
|
||||
drop_open_table(thd, table, create_table->db, create_table->table_name);
|
||||
DBUG_RETURN(0);
|
||||
|
@ -3377,24 +3384,35 @@ select_create::prepare(List<Item> &values, SELECT_LEX_UNIT *u)
|
|||
*/
|
||||
class MY_HOOKS : public TABLEOP_HOOKS {
|
||||
public:
|
||||
MY_HOOKS(select_create *x) : ptr(x) { }
|
||||
MY_HOOKS(select_create *x, TABLE_LIST *create_table,
|
||||
TABLE_LIST *select_tables)
|
||||
: ptr(x), all_tables(*create_table)
|
||||
{
|
||||
all_tables.next_global= select_tables;
|
||||
}
|
||||
|
||||
private:
|
||||
virtual void do_prelock(TABLE **tables, uint count)
|
||||
virtual int do_postlock(TABLE **tables, uint count)
|
||||
{
|
||||
THD *thd= const_cast<THD*>(ptr->get_thd());
|
||||
if (int error= decide_logging_format(thd, &all_tables))
|
||||
return error;
|
||||
|
||||
TABLE const *const table = *tables;
|
||||
if (ptr->get_thd()->current_stmt_binlog_row_based &&
|
||||
if (thd->current_stmt_binlog_row_based &&
|
||||
!table->s->tmp_table &&
|
||||
!ptr->get_create_info()->table_existed)
|
||||
{
|
||||
ptr->binlog_show_create_table(tables, count);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
select_create *ptr;
|
||||
TABLE_LIST all_tables;
|
||||
};
|
||||
|
||||
MY_HOOKS hooks(this);
|
||||
MY_HOOKS hooks(this, create_table, select_tables);
|
||||
hook_ptr= &hooks;
|
||||
|
||||
unit= u;
|
||||
|
|
|
@ -2227,7 +2227,8 @@ mysql_execute_command(THD *thd)
|
|||
&alter_info,
|
||||
select_lex->item_list,
|
||||
lex->duplicates,
|
||||
lex->ignore)))
|
||||
lex->ignore,
|
||||
select_tables)))
|
||||
{
|
||||
/*
|
||||
CREATE from SELECT give its SELECT_LEX for SELECT,
|
||||
|
|
|
@ -87,6 +87,7 @@ public:
|
|||
ulonglong table_flags() const
|
||||
{
|
||||
return (HA_NO_TRANSACTIONS | HA_REC_NOT_IN_SEQ | HA_CAN_BIT_FIELD |
|
||||
HA_BINLOG_ROW_CAPABLE | HA_BINLOG_STMT_CAPABLE |
|
||||
HA_FILE_BASED | HA_CAN_INSERT_DELAYED | HA_CAN_GEOMETRY);
|
||||
}
|
||||
ulong index_flags(uint idx, uint part, bool all_parts) const
|
||||
|
|
|
@ -53,6 +53,7 @@ public:
|
|||
ulonglong table_flags() const
|
||||
{
|
||||
return(HA_NULL_IN_KEY | HA_CAN_FULLTEXT | HA_CAN_SQL_HANDLER |
|
||||
HA_BINLOG_STMT_CAPABLE |
|
||||
HA_CAN_INDEX_BLOBS | HA_AUTO_PART_KEY |
|
||||
HA_FILE_BASED | HA_CAN_GEOMETRY | HA_CAN_INSERT_DELAYED);
|
||||
}
|
||||
|
|
|
@ -99,7 +99,8 @@ public:
|
|||
const char **bas_ext() const;
|
||||
ulonglong table_flags() const
|
||||
{
|
||||
return (HA_NO_TRANSACTIONS | HA_REC_NOT_IN_SEQ | HA_NO_AUTO_INCREMENT);
|
||||
return (HA_NO_TRANSACTIONS | HA_REC_NOT_IN_SEQ | HA_NO_AUTO_INCREMENT |
|
||||
HA_BINLOG_ROW_CAPABLE | HA_BINLOG_STMT_CAPABLE);
|
||||
}
|
||||
ulong index_flags(uint idx, uint part, bool all_parts) const
|
||||
{
|
||||
|
|
|
@ -82,7 +82,12 @@ public:
|
|||
*/
|
||||
ulonglong table_flags() const
|
||||
{
|
||||
return 0;
|
||||
/*
|
||||
We are saying that this engine is just row capable to have an
|
||||
engine that can only handle row-based logging. This is used in
|
||||
testing.
|
||||
*/
|
||||
return HA_BINLOG_ROW_CAPABLE;
|
||||
}
|
||||
|
||||
/** @brief
|
||||
|
|
|
@ -128,6 +128,7 @@ public:
|
|||
/* fix server to be able to get remote server table flags */
|
||||
return (HA_PRIMARY_KEY_IN_READ_INDEX | HA_FILE_BASED
|
||||
| HA_REC_NOT_IN_SEQ | HA_AUTO_PART_KEY | HA_CAN_INDEX_BLOBS |
|
||||
HA_BINLOG_ROW_CAPABLE | HA_BINLOG_STMT_CAPABLE |
|
||||
HA_NO_PREFIX_CHAR_KEYS | HA_PRIMARY_KEY_REQUIRED_FOR_DELETE |
|
||||
HA_PARTIAL_COLUMN_READ | HA_NULL_IN_KEY);
|
||||
}
|
||||
|
|
|
@ -48,6 +48,7 @@ public:
|
|||
ulonglong table_flags() const
|
||||
{
|
||||
return (HA_FAST_KEY_READ | HA_NO_BLOBS | HA_NULL_IN_KEY |
|
||||
HA_BINLOG_ROW_CAPABLE | HA_BINLOG_STMT_CAPABLE |
|
||||
HA_REC_NOT_IN_SEQ | HA_CAN_INSERT_DELAYED | HA_NO_TRANSACTIONS |
|
||||
HA_HAS_RECORDS | HA_STATS_RECORDS_IS_EXACT);
|
||||
}
|
||||
|
|
|
@ -958,6 +958,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_CAN_GEOMETRY | HA_PARTIAL_COLUMN_READ |
|
||||
HA_TABLE_SCAN_ON_INDEX),
|
||||
start_of_scan(0),
|
||||
|
@ -2268,6 +2269,45 @@ ha_innobase::get_row_type() const
|
|||
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;
|
||||
/* We are using thd->variables.tx_isolation here instead of
|
||||
trx->isolation_level since store_lock() has not been called
|
||||
yet.
|
||||
|
||||
The trx->isolation_level is set inside store_lock() (which
|
||||
is called from mysql_lock_tables()) until after this
|
||||
function has been called (which is called in lock_tables()
|
||||
before that function calls mysql_lock_tables()). */
|
||||
ulong const tx_isolation= thd->variables.tx_isolation;
|
||||
if (tx_isolation <= ISO_READ_COMMITTED)
|
||||
{
|
||||
ulong const binlog_format= thd->variables.binlog_format;
|
||||
/* Statement based binlogging does not work in these
|
||||
isolation levels since the necessary locks cannot
|
||||
be taken */
|
||||
if (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);
|
||||
}
|
||||
return int_table_flags;
|
||||
}
|
||||
|
||||
return int_table_flags | HA_BINLOG_STMT_CAPABLE;
|
||||
}
|
||||
|
||||
/********************************************************************
|
||||
Gives the file extension of an InnoDB single-table tablespace. */
|
||||
static const char* ha_innobase_exts[] = {
|
||||
|
|
|
@ -54,7 +54,7 @@ class ha_innobase: public handler
|
|||
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 @@ class ha_innobase: public handler
|
|||
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 |
|
||||
|
|
|
@ -474,6 +474,7 @@ void mi_check_print_warning(MI_CHECK *param, const char *fmt,...)
|
|||
ha_myisam::ha_myisam(handlerton *hton, TABLE_SHARE *table_arg)
|
||||
:handler(hton, table_arg), file(0),
|
||||
int_table_flags(HA_NULL_IN_KEY | HA_CAN_FULLTEXT | HA_CAN_SQL_HANDLER |
|
||||
HA_BINLOG_ROW_CAPABLE | HA_BINLOG_STMT_CAPABLE |
|
||||
HA_DUPLICATE_POS | HA_CAN_INDEX_BLOBS | HA_AUTO_PART_KEY |
|
||||
HA_FILE_BASED | HA_CAN_GEOMETRY | HA_NO_TRANSACTIONS |
|
||||
HA_CAN_INSERT_DELAYED | HA_CAN_BIT_FIELD | HA_CAN_RTREEKEYS |
|
||||
|
|
|
@ -35,6 +35,7 @@ class ha_myisammrg: public handler
|
|||
ulonglong table_flags() const
|
||||
{
|
||||
return (HA_REC_NOT_IN_SEQ | HA_AUTO_PART_KEY | HA_NO_TRANSACTIONS |
|
||||
HA_BINLOG_ROW_CAPABLE | HA_BINLOG_STMT_CAPABLE |
|
||||
HA_NULL_IN_KEY | HA_CAN_INDEX_BLOBS | HA_FILE_BASED |
|
||||
HA_ANY_INDEX_MAY_BE_UNIQUE | HA_CAN_BIT_FIELD |
|
||||
HA_NO_COPY_ON_ALTER);
|
||||
|
|
Loading…
Reference in a new issue