From 1392eba62a80ee303e13fd84b2fb78ce0dcffb34 Mon Sep 17 00:00:00 2001 From: Michael Widenius Date: Tue, 22 Feb 2011 19:24:24 +0200 Subject: [PATCH] Merged InnoDB plugin from MySQL 5.1.54 -> MySQL 5.1.55 into xtradb mysql-test/r/innodb-zip.result: File has been moved to suite/innodb_plugin mysql-test/t/innodb-zip.test: File has been moved to suite/innodb_plugin --- mysql-test/r/innodb-zip.result | 421 ------------------ .../r/innodb-create-options.result | 78 ++-- .../r/partition_auto_increment_innodb.result | 4 +- mysql-test/t/innodb-zip.test | 347 --------------- storage/xtradb/ChangeLog | 40 ++ storage/xtradb/btr/btr0btr.c | 2 +- storage/xtradb/btr/btr0cur.c | 156 ++----- storage/xtradb/buf/buf0buf.c | 4 +- storage/xtradb/buf/buf0lru.c | 16 +- storage/xtradb/dict/dict0dict.c | 12 +- storage/xtradb/fsp/fsp0fsp.c | 2 +- storage/xtradb/handler/ha_innodb.cc | 216 ++++----- storage/xtradb/handler/i_s.cc | 23 +- storage/xtradb/include/btr0cur.h | 42 +- storage/xtradb/include/data0data.h | 11 +- storage/xtradb/include/data0data.ic | 22 +- storage/xtradb/include/row0upd.h | 14 +- storage/xtradb/include/trx0i_s.h | 2 + storage/xtradb/include/univ.i | 14 +- storage/xtradb/include/ut0vec.h | 19 + storage/xtradb/include/ut0vec.ic | 29 ++ storage/xtradb/lock/lock0lock.c | 78 +++- storage/xtradb/log/log0recv.c | 5 +- storage/xtradb/plug.in | 23 +- storage/xtradb/row/row0merge.c | 4 +- storage/xtradb/row/row0mysql.c | 2 +- storage/xtradb/row/row0purge.c | 2 +- storage/xtradb/row/row0umod.c | 13 +- storage/xtradb/row/row0upd.c | 339 ++++++++++---- storage/xtradb/trx/trx0i_s.c | 5 +- storage/xtradb/ut/ut0dbg.c | 2 +- 31 files changed, 723 insertions(+), 1224 deletions(-) delete mode 100644 mysql-test/r/innodb-zip.result mode change 100755 => 100644 mysql-test/suite/innodb_plugin/r/innodb-create-options.result delete mode 100644 mysql-test/t/innodb-zip.test diff --git a/mysql-test/r/innodb-zip.result b/mysql-test/r/innodb-zip.result deleted file mode 100644 index 21396d81ba8..00000000000 --- a/mysql-test/r/innodb-zip.result +++ /dev/null @@ -1,421 +0,0 @@ -set global innodb_file_per_table=off; -set global innodb_file_format=`0`; -create table t0(a int primary key) engine=innodb row_format=compressed; -Warnings: -Warning 1478 InnoDB: ROW_FORMAT=COMPRESSED requires innodb_file_per_table. -Warning 1478 InnoDB: assuming ROW_FORMAT=COMPACT. -create table t00(a int primary key) engine=innodb -key_block_size=4 row_format=compressed; -Warnings: -Warning 1478 InnoDB: KEY_BLOCK_SIZE requires innodb_file_per_table. -Warning 1478 InnoDB: KEY_BLOCK_SIZE requires innodb_file_format > Antelope. -Warning 1478 InnoDB: ignoring KEY_BLOCK_SIZE=4. -Warning 1478 InnoDB: ROW_FORMAT=COMPRESSED requires innodb_file_per_table. -Warning 1478 InnoDB: assuming ROW_FORMAT=COMPACT. -create table t1(a int primary key) engine=innodb row_format=dynamic; -Warnings: -Warning 1478 InnoDB: ROW_FORMAT=DYNAMIC requires innodb_file_per_table. -Warning 1478 InnoDB: assuming ROW_FORMAT=COMPACT. -create table t2(a int primary key) engine=innodb row_format=redundant; -create table t3(a int primary key) engine=innodb row_format=compact; -create table t4(a int primary key) engine=innodb key_block_size=9; -Warnings: -Warning 1478 InnoDB: KEY_BLOCK_SIZE requires innodb_file_per_table. -Warning 1478 InnoDB: KEY_BLOCK_SIZE requires innodb_file_format > Antelope. -Warning 1478 InnoDB: ignoring KEY_BLOCK_SIZE=9. -create table t5(a int primary key) engine=innodb -key_block_size=1 row_format=redundant; -Warnings: -Warning 1478 InnoDB: KEY_BLOCK_SIZE requires innodb_file_per_table. -Warning 1478 InnoDB: KEY_BLOCK_SIZE requires innodb_file_format > Antelope. -Warning 1478 InnoDB: ignoring KEY_BLOCK_SIZE=1. -set global innodb_file_per_table=on; -create table t6(a int primary key) engine=innodb -key_block_size=1 row_format=redundant; -Warnings: -Warning 1478 InnoDB: KEY_BLOCK_SIZE requires innodb_file_format > Antelope. -Warning 1478 InnoDB: ignoring KEY_BLOCK_SIZE=1. -set global innodb_file_format=`1`; -create table t7(a int primary key) engine=innodb -key_block_size=1 row_format=redundant; -Warnings: -Warning 1478 InnoDB: ignoring KEY_BLOCK_SIZE=1 unless ROW_FORMAT=COMPRESSED. -create table t8(a int primary key) engine=innodb -key_block_size=1 row_format=fixed; -Warnings: -Warning 1478 InnoDB: ignoring KEY_BLOCK_SIZE=1 unless ROW_FORMAT=COMPRESSED. -Warning 1478 InnoDB: assuming ROW_FORMAT=COMPACT. -create table t9(a int primary key) engine=innodb -key_block_size=1 row_format=compact; -Warnings: -Warning 1478 InnoDB: ignoring KEY_BLOCK_SIZE=1 unless ROW_FORMAT=COMPRESSED. -create table t10(a int primary key) engine=innodb -key_block_size=1 row_format=dynamic; -Warnings: -Warning 1478 InnoDB: ignoring KEY_BLOCK_SIZE=1 unless ROW_FORMAT=COMPRESSED. -create table t11(a int primary key) engine=innodb -key_block_size=1 row_format=compressed; -create table t12(a int primary key) engine=innodb -key_block_size=1; -create table t13(a int primary key) engine=innodb -row_format=compressed; -create table t14(a int primary key) engine=innodb key_block_size=9; -Warnings: -Warning 1478 InnoDB: ignoring KEY_BLOCK_SIZE=9. -SELECT table_schema, table_name, row_format -FROM information_schema.tables WHERE engine='innodb'; -table_schema table_name row_format -test t0 Compact -test t00 Compact -test t1 Compact -test t10 Dynamic -test t11 Compressed -test t12 Compressed -test t13 Compressed -test t14 Compact -test t2 Redundant -test t3 Compact -test t4 Compact -test t5 Redundant -test t6 Redundant -test t7 Redundant -test t8 Compact -test t9 Compact -drop table t0,t00,t2,t3,t4,t5,t6,t7,t8,t9,t10,t11,t12,t13,t14; -alter table t1 key_block_size=0; -Warnings: -Warning 1478 InnoDB: ignoring KEY_BLOCK_SIZE=0. -alter table t1 row_format=dynamic; -SELECT table_schema, table_name, row_format -FROM information_schema.tables WHERE engine='innodb'; -table_schema table_name row_format -test t1 Dynamic -alter table t1 row_format=compact; -SELECT table_schema, table_name, row_format -FROM information_schema.tables WHERE engine='innodb'; -table_schema table_name row_format -test t1 Compact -alter table t1 row_format=redundant; -SELECT table_schema, table_name, row_format -FROM information_schema.tables WHERE engine='innodb'; -table_schema table_name row_format -test t1 Redundant -drop table t1; -create table t1(a int not null, b text, index(b(10))) engine=innodb -key_block_size=1; -create table t2(b text)engine=innodb; -insert into t2 values(concat('1abcdefghijklmnopqrstuvwxyz', repeat('A',5000))); -insert into t1 select 1, b from t2; -commit; -begin; -update t1 set b=repeat('B',100); -select a,left(b,40) from t1 natural join t2; -a left(b,40) -1 1abcdefghijklmnopqrstuvwxyzAAAAAAAAAAAAA -rollback; -select a,left(b,40) from t1 natural join t2; -a left(b,40) -1 1abcdefghijklmnopqrstuvwxyzAAAAAAAAAAAAA -SELECT table_schema, table_name, row_format -FROM information_schema.tables WHERE engine='innodb'; -table_schema table_name row_format -test t1 Compressed -test t2 Compact -drop table t1,t2; -SET SESSION innodb_strict_mode = off; -CREATE TABLE t1( -c TEXT NOT NULL, d TEXT NOT NULL, -PRIMARY KEY (c(767),d(767))) -ENGINE=InnoDB ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=1 CHARSET=ASCII; -ERROR 42000: Row size too large. The maximum row size for the used table type, not counting BLOBs, is 8126. You have to change some columns to TEXT or BLOBs -CREATE TABLE t1( -c TEXT NOT NULL, d TEXT NOT NULL, -PRIMARY KEY (c(767),d(767))) -ENGINE=InnoDB ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=2 CHARSET=ASCII; -ERROR 42000: Row size too large. The maximum row size for the used table type, not counting BLOBs, is 8126. You have to change some columns to TEXT or BLOBs -CREATE TABLE t1( -c TEXT NOT NULL, d TEXT NOT NULL, -PRIMARY KEY (c(767),d(767))) -ENGINE=InnoDB ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=4 CHARSET=ASCII; -drop table t1; -CREATE TABLE t1(c TEXT, PRIMARY KEY (c(440))) -ENGINE=InnoDB ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=1 CHARSET=ASCII; -ERROR 42000: Row size too large. The maximum row size for the used table type, not counting BLOBs, is 8126. You have to change some columns to TEXT or BLOBs -CREATE TABLE t1(c TEXT, PRIMARY KEY (c(438))) -ENGINE=InnoDB ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=1 CHARSET=ASCII; -INSERT INTO t1 VALUES(REPEAT('A',512)),(REPEAT('B',512)); -DROP TABLE t1; -create table t1( c1 int not null, c2 blob, c3 blob, c4 blob, -primary key(c1, c2(22), c3(22))) -engine = innodb row_format = dynamic; -begin; -insert into t1 values(1, repeat('A', 20000), repeat('B', 20000), -repeat('C', 20000)); -update t1 set c3 = repeat('D', 20000) where c1 = 1; -commit; -select count(*) from t1 where c2 = repeat('A', 20000); -count(*) -1 -select count(*) from t1 where c3 = repeat('D', 20000); -count(*) -1 -select count(*) from t1 where c4 = repeat('C', 20000); -count(*) -1 -update t1 set c3 = repeat('E', 20000) where c1 = 1; -drop table t1; -set global innodb_file_format=`0`; -select @@innodb_file_format; -@@innodb_file_format -Antelope -set global innodb_file_format=`1`; -select @@innodb_file_format; -@@innodb_file_format -Barracuda -set global innodb_file_format=`2`; -ERROR HY000: Incorrect arguments to SET -set global innodb_file_format=`-1`; -ERROR HY000: Incorrect arguments to SET -set global innodb_file_format=`Antelope`; -set global innodb_file_format=`Barracuda`; -set global innodb_file_format=`Cheetah`; -ERROR HY000: Incorrect arguments to SET -set global innodb_file_format=`abc`; -ERROR HY000: Incorrect arguments to SET -set global innodb_file_format=`1a`; -ERROR HY000: Incorrect arguments to SET -set global innodb_file_format=``; -ERROR HY000: Incorrect arguments to SET -set global innodb_file_per_table = on; -set global innodb_file_format = `1`; -set innodb_strict_mode = off; -create table t1 (id int primary key) engine = innodb key_block_size = 0; -Warnings: -Warning 1478 InnoDB: ignoring KEY_BLOCK_SIZE=0. -drop table t1; -set innodb_strict_mode = on; -create table t1 (id int primary key) engine = innodb key_block_size = 0; -ERROR HY000: Can't create table 'test.t1' (errno: 1478) -show warnings; -Level Code Message -Warning 1478 InnoDB: invalid KEY_BLOCK_SIZE = 0. Valid values are [1, 2, 4, 8, 16] -Error 1005 Can't create table 'test.t1' (errno: 1478) -create table t2 (id int primary key) engine = innodb key_block_size = 9; -ERROR HY000: Can't create table 'test.t2' (errno: 1478) -show warnings; -Level Code Message -Warning 1478 InnoDB: invalid KEY_BLOCK_SIZE = 9. Valid values are [1, 2, 4, 8, 16] -Error 1005 Can't create table 'test.t2' (errno: 1478) -create table t3 (id int primary key) engine = innodb key_block_size = 1; -create table t4 (id int primary key) engine = innodb key_block_size = 2; -create table t5 (id int primary key) engine = innodb key_block_size = 4; -create table t6 (id int primary key) engine = innodb key_block_size = 8; -create table t7 (id int primary key) engine = innodb key_block_size = 16; -create table t8 (id int primary key) engine = innodb row_format = compressed; -create table t9 (id int primary key) engine = innodb row_format = dynamic; -create table t10(id int primary key) engine = innodb row_format = compact; -create table t11(id int primary key) engine = innodb row_format = redundant; -SELECT table_schema, table_name, row_format -FROM information_schema.tables WHERE engine='innodb'; -table_schema table_name row_format -test t10 Compact -test t11 Redundant -test t3 Compressed -test t4 Compressed -test t5 Compressed -test t6 Compressed -test t7 Compressed -test t8 Compressed -test t9 Dynamic -drop table t3, t4, t5, t6, t7, t8, t9, t10, t11; -create table t1 (id int primary key) engine = innodb -key_block_size = 8 row_format = compressed; -create table t2 (id int primary key) engine = innodb -key_block_size = 8 row_format = redundant; -ERROR HY000: Can't create table 'test.t2' (errno: 1478) -show warnings; -Level Code Message -Warning 1478 InnoDB: cannot specify ROW_FORMAT = REDUNDANT with KEY_BLOCK_SIZE. -Error 1005 Can't create table 'test.t2' (errno: 1478) -create table t3 (id int primary key) engine = innodb -key_block_size = 8 row_format = compact; -ERROR HY000: Can't create table 'test.t3' (errno: 1478) -show warnings; -Level Code Message -Warning 1478 InnoDB: cannot specify ROW_FORMAT = COMPACT with KEY_BLOCK_SIZE. -Error 1005 Can't create table 'test.t3' (errno: 1478) -create table t4 (id int primary key) engine = innodb -key_block_size = 8 row_format = dynamic; -ERROR HY000: Can't create table 'test.t4' (errno: 1478) -show warnings; -Level Code Message -Warning 1478 InnoDB: cannot specify ROW_FORMAT = DYNAMIC with KEY_BLOCK_SIZE. -Error 1005 Can't create table 'test.t4' (errno: 1478) -create table t5 (id int primary key) engine = innodb -key_block_size = 8 row_format = default; -ERROR HY000: Can't create table 'test.t5' (errno: 1478) -show warnings; -Level Code Message -Warning 1478 InnoDB: cannot specify ROW_FORMAT = COMPACT with KEY_BLOCK_SIZE. -Error 1005 Can't create table 'test.t5' (errno: 1478) -SELECT table_schema, table_name, row_format -FROM information_schema.tables WHERE engine='innodb'; -table_schema table_name row_format -test t1 Compressed -drop table t1; -create table t1 (id int primary key) engine = innodb -key_block_size = 9 row_format = redundant; -ERROR HY000: Can't create table 'test.t1' (errno: 1478) -show warnings; -Level Code Message -Warning 1478 InnoDB: invalid KEY_BLOCK_SIZE = 9. Valid values are [1, 2, 4, 8, 16] -Warning 1478 InnoDB: cannot specify ROW_FORMAT = REDUNDANT with KEY_BLOCK_SIZE. -Error 1005 Can't create table 'test.t1' (errno: 1478) -create table t2 (id int primary key) engine = innodb -key_block_size = 9 row_format = compact; -ERROR HY000: Can't create table 'test.t2' (errno: 1478) -show warnings; -Level Code Message -Warning 1478 InnoDB: invalid KEY_BLOCK_SIZE = 9. Valid values are [1, 2, 4, 8, 16] -Warning 1478 InnoDB: cannot specify ROW_FORMAT = COMPACT with KEY_BLOCK_SIZE. -Error 1005 Can't create table 'test.t2' (errno: 1478) -create table t2 (id int primary key) engine = innodb -key_block_size = 9 row_format = dynamic; -ERROR HY000: Can't create table 'test.t2' (errno: 1478) -show warnings; -Level Code Message -Warning 1478 InnoDB: invalid KEY_BLOCK_SIZE = 9. Valid values are [1, 2, 4, 8, 16] -Warning 1478 InnoDB: cannot specify ROW_FORMAT = DYNAMIC with KEY_BLOCK_SIZE. -Error 1005 Can't create table 'test.t2' (errno: 1478) -SELECT table_schema, table_name, row_format -FROM information_schema.tables WHERE engine='innodb'; -table_schema table_name row_format -set global innodb_file_per_table = off; -create table t1 (id int primary key) engine = innodb key_block_size = 1; -ERROR HY000: Can't create table 'test.t1' (errno: 1478) -show warnings; -Level Code Message -Warning 1478 InnoDB: KEY_BLOCK_SIZE requires innodb_file_per_table. -Error 1005 Can't create table 'test.t1' (errno: 1478) -create table t2 (id int primary key) engine = innodb key_block_size = 2; -ERROR HY000: Can't create table 'test.t2' (errno: 1478) -show warnings; -Level Code Message -Warning 1478 InnoDB: KEY_BLOCK_SIZE requires innodb_file_per_table. -Error 1005 Can't create table 'test.t2' (errno: 1478) -create table t3 (id int primary key) engine = innodb key_block_size = 4; -ERROR HY000: Can't create table 'test.t3' (errno: 1478) -show warnings; -Level Code Message -Warning 1478 InnoDB: KEY_BLOCK_SIZE requires innodb_file_per_table. -Error 1005 Can't create table 'test.t3' (errno: 1478) -create table t4 (id int primary key) engine = innodb key_block_size = 8; -ERROR HY000: Can't create table 'test.t4' (errno: 1478) -show warnings; -Level Code Message -Warning 1478 InnoDB: KEY_BLOCK_SIZE requires innodb_file_per_table. -Error 1005 Can't create table 'test.t4' (errno: 1478) -create table t5 (id int primary key) engine = innodb key_block_size = 16; -ERROR HY000: Can't create table 'test.t5' (errno: 1478) -show warnings; -Level Code Message -Warning 1478 InnoDB: KEY_BLOCK_SIZE requires innodb_file_per_table. -Error 1005 Can't create table 'test.t5' (errno: 1478) -create table t6 (id int primary key) engine = innodb row_format = compressed; -ERROR HY000: Can't create table 'test.t6' (errno: 1478) -show warnings; -Level Code Message -Warning 1478 InnoDB: ROW_FORMAT=COMPRESSED requires innodb_file_per_table. -Error 1005 Can't create table 'test.t6' (errno: 1478) -create table t7 (id int primary key) engine = innodb row_format = dynamic; -ERROR HY000: Can't create table 'test.t7' (errno: 1478) -show warnings; -Level Code Message -Warning 1478 InnoDB: ROW_FORMAT=DYNAMIC requires innodb_file_per_table. -Error 1005 Can't create table 'test.t7' (errno: 1478) -create table t8 (id int primary key) engine = innodb row_format = compact; -create table t9 (id int primary key) engine = innodb row_format = redundant; -SELECT table_schema, table_name, row_format -FROM information_schema.tables WHERE engine='innodb'; -table_schema table_name row_format -test t8 Compact -test t9 Redundant -drop table t8, t9; -set global innodb_file_per_table = on; -set global innodb_file_format = `0`; -create table t1 (id int primary key) engine = innodb key_block_size = 1; -ERROR HY000: Can't create table 'test.t1' (errno: 1478) -show warnings; -Level Code Message -Warning 1478 InnoDB: KEY_BLOCK_SIZE requires innodb_file_format > Antelope. -Error 1005 Can't create table 'test.t1' (errno: 1478) -create table t2 (id int primary key) engine = innodb key_block_size = 2; -ERROR HY000: Can't create table 'test.t2' (errno: 1478) -show warnings; -Level Code Message -Warning 1478 InnoDB: KEY_BLOCK_SIZE requires innodb_file_format > Antelope. -Error 1005 Can't create table 'test.t2' (errno: 1478) -create table t3 (id int primary key) engine = innodb key_block_size = 4; -ERROR HY000: Can't create table 'test.t3' (errno: 1478) -show warnings; -Level Code Message -Warning 1478 InnoDB: KEY_BLOCK_SIZE requires innodb_file_format > Antelope. -Error 1005 Can't create table 'test.t3' (errno: 1478) -create table t4 (id int primary key) engine = innodb key_block_size = 8; -ERROR HY000: Can't create table 'test.t4' (errno: 1478) -show warnings; -Level Code Message -Warning 1478 InnoDB: KEY_BLOCK_SIZE requires innodb_file_format > Antelope. -Error 1005 Can't create table 'test.t4' (errno: 1478) -create table t5 (id int primary key) engine = innodb key_block_size = 16; -ERROR HY000: Can't create table 'test.t5' (errno: 1478) -show warnings; -Level Code Message -Warning 1478 InnoDB: KEY_BLOCK_SIZE requires innodb_file_format > Antelope. -Error 1005 Can't create table 'test.t5' (errno: 1478) -create table t6 (id int primary key) engine = innodb row_format = compressed; -ERROR HY000: Can't create table 'test.t6' (errno: 1478) -show warnings; -Level Code Message -Warning 1478 InnoDB: ROW_FORMAT=COMPRESSED requires innodb_file_format > Antelope. -Error 1005 Can't create table 'test.t6' (errno: 1478) -create table t7 (id int primary key) engine = innodb row_format = dynamic; -ERROR HY000: Can't create table 'test.t7' (errno: 1478) -show warnings; -Level Code Message -Warning 1478 InnoDB: ROW_FORMAT=DYNAMIC requires innodb_file_format > Antelope. -Error 1005 Can't create table 'test.t7' (errno: 1478) -create table t8 (id int primary key) engine = innodb row_format = compact; -create table t9 (id int primary key) engine = innodb row_format = redundant; -SELECT table_schema, table_name, row_format -FROM information_schema.tables WHERE engine='innodb'; -table_schema table_name row_format -test t8 Compact -test t9 Redundant -drop table t8, t9; -set global innodb_file_per_table=0; -set global innodb_file_format=Antelope; -set global innodb_file_per_table=on; -set global innodb_file_format=`Barracuda`; -set global innodb_file_format_check=`Antelope`; -create table normal_table ( -c1 int -) engine = innodb; -select @@innodb_file_format_check; -@@innodb_file_format_check -Antelope -create table zip_table ( -c1 int -) engine = innodb key_block_size = 8; -select @@innodb_file_format_check; -@@innodb_file_format_check -Barracuda -set global innodb_file_format_check=`Antelope`; -select @@innodb_file_format_check; -@@innodb_file_format_check -Antelope -show table status; -select @@innodb_file_format_check; -@@innodb_file_format_check -Barracuda -drop table normal_table, zip_table; diff --git a/mysql-test/suite/innodb_plugin/r/innodb-create-options.result b/mysql-test/suite/innodb_plugin/r/innodb-create-options.result old mode 100755 new mode 100644 index aec9d731ce6..94c84fcf60f --- a/mysql-test/suite/innodb_plugin/r/innodb-create-options.result +++ b/mysql-test/suite/innodb_plugin/r/innodb-create-options.result @@ -80,26 +80,26 @@ SHOW WARNINGS; Level Code Message SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 't1'; TABLE_NAME ROW_FORMAT CREATE_OPTIONS -t1 Compressed row_format=COMPRESSED KEY_BLOCK_SIZE=8 +t1 Compressed row_format=COMPRESSED key_block_size=8 ALTER TABLE t1 ADD COLUMN f1 INT; SHOW WARNINGS; Level Code Message SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 't1'; TABLE_NAME ROW_FORMAT CREATE_OPTIONS -t1 Compressed row_format=COMPRESSED KEY_BLOCK_SIZE=8 +t1 Compressed row_format=COMPRESSED key_block_size=8 DROP TABLE IF EXISTS t1; CREATE TABLE t1 ( i INT ) ROW_FORMAT=DEFAULT KEY_BLOCK_SIZE=16; SHOW WARNINGS; Level Code Message SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 't1'; TABLE_NAME ROW_FORMAT CREATE_OPTIONS -t1 Compressed KEY_BLOCK_SIZE=16 +t1 Compressed key_block_size=16 ALTER TABLE t1 ADD COLUMN f1 INT; SHOW WARNINGS; Level Code Message SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 't1'; TABLE_NAME ROW_FORMAT CREATE_OPTIONS -t1 Compressed KEY_BLOCK_SIZE=16 +t1 Compressed key_block_size=16 # Test 3) StrictMode=ON, ALTER with each ROW_FORMAT & a valid non-zero KEY_BLOCK_SIZE DROP TABLE IF EXISTS t1; CREATE TABLE t1 ( i INT ); @@ -132,13 +132,13 @@ SHOW WARNINGS; Level Code Message SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 't1'; TABLE_NAME ROW_FORMAT CREATE_OPTIONS -t1 Compressed KEY_BLOCK_SIZE=16 +t1 Compressed key_block_size=16 ALTER TABLE t1 ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=1; SHOW WARNINGS; Level Code Message SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 't1'; TABLE_NAME ROW_FORMAT CREATE_OPTIONS -t1 Compressed row_format=COMPRESSED KEY_BLOCK_SIZE=1 +t1 Compressed row_format=COMPRESSED key_block_size=1 # Test 4) StrictMode=ON, CREATE with ROW_FORMAT=COMPACT, ALTER with a valid non-zero KEY_BLOCK_SIZE DROP TABLE IF EXISTS t1; CREATE TABLE t1 ( i INT ) ROW_FORMAT=COMPACT; @@ -186,7 +186,7 @@ SHOW WARNINGS; Level Code Message SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 't1'; TABLE_NAME ROW_FORMAT CREATE_OPTIONS -t1 Compressed row_format=COMPRESSED KEY_BLOCK_SIZE=16 +t1 Compressed row_format=COMPRESSED key_block_size=16 DROP TABLE IF EXISTS t1; CREATE TABLE t1 ( i INT ) ROW_FORMAT=COMPACT; ALTER TABLE t1 ROW_FORMAT=DEFAULT KEY_BLOCK_SIZE=1; @@ -194,7 +194,7 @@ SHOW WARNINGS; Level Code Message SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 't1'; TABLE_NAME ROW_FORMAT CREATE_OPTIONS -t1 Compressed KEY_BLOCK_SIZE=1 +t1 Compressed key_block_size=1 # Test 5) StrictMode=ON, CREATE with a valid KEY_BLOCK_SIZE # ALTER with each ROW_FORMAT DROP TABLE IF EXISTS t1; @@ -234,7 +234,7 @@ SHOW WARNINGS; Level Code Message SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 't1'; TABLE_NAME ROW_FORMAT CREATE_OPTIONS -t1 Compressed row_format=COMPRESSED KEY_BLOCK_SIZE=2 +t1 Compressed row_format=COMPRESSED key_block_size=2 ALTER TABLE t1 ROW_FORMAT=DEFAULT KEY_BLOCK_SIZE=0; SHOW WARNINGS; Level Code Message @@ -495,7 +495,7 @@ Level Code Message Warning 1478 InnoDB: ignoring KEY_BLOCK_SIZE=1 unless ROW_FORMAT=COMPRESSED. SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 't1'; TABLE_NAME ROW_FORMAT CREATE_OPTIONS -t1 Compact row_format=COMPACT KEY_BLOCK_SIZE=1 +t1 Compact row_format=COMPACT key_block_size=1 DROP TABLE IF EXISTS t1; CREATE TABLE t1 ( i INT ) ROW_FORMAT=REDUNDANT KEY_BLOCK_SIZE=2; Warnings: @@ -505,7 +505,7 @@ Level Code Message Warning 1478 InnoDB: ignoring KEY_BLOCK_SIZE=2 unless ROW_FORMAT=COMPRESSED. SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 't1'; TABLE_NAME ROW_FORMAT CREATE_OPTIONS -t1 Redundant row_format=REDUNDANT KEY_BLOCK_SIZE=2 +t1 Redundant row_format=REDUNDANT key_block_size=2 DROP TABLE IF EXISTS t1; CREATE TABLE t1 ( i INT ) ROW_FORMAT=DYNAMIC KEY_BLOCK_SIZE=4; Warnings: @@ -515,33 +515,33 @@ Level Code Message Warning 1478 InnoDB: ignoring KEY_BLOCK_SIZE=4 unless ROW_FORMAT=COMPRESSED. SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 't1'; TABLE_NAME ROW_FORMAT CREATE_OPTIONS -t1 Dynamic row_format=DYNAMIC KEY_BLOCK_SIZE=4 +t1 Dynamic row_format=DYNAMIC key_block_size=4 DROP TABLE IF EXISTS t1; CREATE TABLE t1 ( i INT ) ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=8; SHOW WARNINGS; Level Code Message SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 't1'; TABLE_NAME ROW_FORMAT CREATE_OPTIONS -t1 Compressed row_format=COMPRESSED KEY_BLOCK_SIZE=8 +t1 Compressed row_format=COMPRESSED key_block_size=8 ALTER TABLE t1 ADD COLUMN f1 INT; SHOW WARNINGS; Level Code Message SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 't1'; TABLE_NAME ROW_FORMAT CREATE_OPTIONS -t1 Compressed row_format=COMPRESSED KEY_BLOCK_SIZE=8 +t1 Compressed row_format=COMPRESSED key_block_size=8 DROP TABLE IF EXISTS t1; CREATE TABLE t1 ( i INT ) ROW_FORMAT=DEFAULT KEY_BLOCK_SIZE=16; SHOW WARNINGS; Level Code Message SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 't1'; TABLE_NAME ROW_FORMAT CREATE_OPTIONS -t1 Compressed KEY_BLOCK_SIZE=16 +t1 Compressed key_block_size=16 ALTER TABLE t1 ADD COLUMN f1 INT; SHOW WARNINGS; Level Code Message SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 't1'; TABLE_NAME ROW_FORMAT CREATE_OPTIONS -t1 Compressed KEY_BLOCK_SIZE=16 +t1 Compressed key_block_size=16 # Test 11) StrictMode=OFF, ALTER with each ROW_FORMAT & a valid KEY_BLOCK_SIZE DROP TABLE IF EXISTS t1; CREATE TABLE t1 ( i INT ); @@ -555,7 +555,7 @@ Warning 1478 InnoDB: ignoring KEY_BLOCK_SIZE=1 unless ROW_FORMAT=COMPRESSED. Warning 1478 InnoDB: assuming ROW_FORMAT=COMPACT. SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 't1'; TABLE_NAME ROW_FORMAT CREATE_OPTIONS -t1 Compact row_format=FIXED KEY_BLOCK_SIZE=1 +t1 Compact row_format=FIXED key_block_size=1 DROP TABLE IF EXISTS t1; CREATE TABLE t1 ( i INT ); ALTER TABLE t1 ROW_FORMAT=COMPACT KEY_BLOCK_SIZE=2; @@ -566,7 +566,7 @@ Level Code Message Warning 1478 InnoDB: ignoring KEY_BLOCK_SIZE=2 unless ROW_FORMAT=COMPRESSED. SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 't1'; TABLE_NAME ROW_FORMAT CREATE_OPTIONS -t1 Compact row_format=COMPACT KEY_BLOCK_SIZE=2 +t1 Compact row_format=COMPACT key_block_size=2 DROP TABLE IF EXISTS t1; CREATE TABLE t1 ( i INT ); ALTER TABLE t1 ROW_FORMAT=DYNAMIC KEY_BLOCK_SIZE=4; @@ -577,7 +577,7 @@ Level Code Message Warning 1478 InnoDB: ignoring KEY_BLOCK_SIZE=4 unless ROW_FORMAT=COMPRESSED. SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 't1'; TABLE_NAME ROW_FORMAT CREATE_OPTIONS -t1 Dynamic row_format=DYNAMIC KEY_BLOCK_SIZE=4 +t1 Dynamic row_format=DYNAMIC key_block_size=4 DROP TABLE IF EXISTS t1; CREATE TABLE t1 ( i INT ); ALTER TABLE t1 ROW_FORMAT=REDUNDANT KEY_BLOCK_SIZE=8; @@ -588,7 +588,7 @@ Level Code Message Warning 1478 InnoDB: ignoring KEY_BLOCK_SIZE=8 unless ROW_FORMAT=COMPRESSED. SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 't1'; TABLE_NAME ROW_FORMAT CREATE_OPTIONS -t1 Redundant row_format=REDUNDANT KEY_BLOCK_SIZE=8 +t1 Redundant row_format=REDUNDANT key_block_size=8 DROP TABLE IF EXISTS t1; CREATE TABLE t1 ( i INT ); ALTER TABLE t1 ROW_FORMAT=DEFAULT KEY_BLOCK_SIZE=16; @@ -596,13 +596,13 @@ SHOW WARNINGS; Level Code Message SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 't1'; TABLE_NAME ROW_FORMAT CREATE_OPTIONS -t1 Compressed KEY_BLOCK_SIZE=16 +t1 Compressed key_block_size=16 ALTER TABLE t1 ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=1; SHOW WARNINGS; Level Code Message SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 't1'; TABLE_NAME ROW_FORMAT CREATE_OPTIONS -t1 Compressed row_format=COMPRESSED KEY_BLOCK_SIZE=1 +t1 Compressed row_format=COMPRESSED key_block_size=1 # Test 12) StrictMode=OFF, CREATE with ROW_FORMAT=COMPACT, ALTER with a valid KEY_BLOCK_SIZE DROP TABLE IF EXISTS t1; CREATE TABLE t1 ( i INT ) ROW_FORMAT=COMPACT; @@ -617,7 +617,7 @@ Level Code Message Warning 1478 InnoDB: ignoring KEY_BLOCK_SIZE=2 unless ROW_FORMAT=COMPRESSED. SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 't1'; TABLE_NAME ROW_FORMAT CREATE_OPTIONS -t1 Compact row_format=COMPACT KEY_BLOCK_SIZE=2 +t1 Compact row_format=COMPACT key_block_size=2 ALTER TABLE t1 ROW_FORMAT=REDUNDANT; Warnings: Warning 1478 InnoDB: ignoring KEY_BLOCK_SIZE=2 unless ROW_FORMAT=COMPRESSED. @@ -626,7 +626,7 @@ Level Code Message Warning 1478 InnoDB: ignoring KEY_BLOCK_SIZE=2 unless ROW_FORMAT=COMPRESSED. SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 't1'; TABLE_NAME ROW_FORMAT CREATE_OPTIONS -t1 Redundant row_format=REDUNDANT KEY_BLOCK_SIZE=2 +t1 Redundant row_format=REDUNDANT key_block_size=2 ALTER TABLE t1 ROW_FORMAT=DYNAMIC; Warnings: Warning 1478 InnoDB: ignoring KEY_BLOCK_SIZE=2 unless ROW_FORMAT=COMPRESSED. @@ -635,19 +635,19 @@ Level Code Message Warning 1478 InnoDB: ignoring KEY_BLOCK_SIZE=2 unless ROW_FORMAT=COMPRESSED. SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 't1'; TABLE_NAME ROW_FORMAT CREATE_OPTIONS -t1 Dynamic row_format=DYNAMIC KEY_BLOCK_SIZE=2 +t1 Dynamic row_format=DYNAMIC key_block_size=2 ALTER TABLE t1 ROW_FORMAT=COMPRESSED; SHOW WARNINGS; Level Code Message SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 't1'; TABLE_NAME ROW_FORMAT CREATE_OPTIONS -t1 Compressed row_format=COMPRESSED KEY_BLOCK_SIZE=2 +t1 Compressed row_format=COMPRESSED key_block_size=2 ALTER TABLE t1 KEY_BLOCK_SIZE=4; SHOW WARNINGS; Level Code Message SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 't1'; TABLE_NAME ROW_FORMAT CREATE_OPTIONS -t1 Compressed row_format=COMPRESSED KEY_BLOCK_SIZE=4 +t1 Compressed row_format=COMPRESSED key_block_size=4 DROP TABLE IF EXISTS t1; CREATE TABLE t1 ( i INT ) ROW_FORMAT=COMPACT; ALTER TABLE t1 ROW_FORMAT=DEFAULT KEY_BLOCK_SIZE=8; @@ -655,7 +655,7 @@ SHOW WARNINGS; Level Code Message SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 't1'; TABLE_NAME ROW_FORMAT CREATE_OPTIONS -t1 Compressed KEY_BLOCK_SIZE=8 +t1 Compressed key_block_size=8 # Test 13) StrictMode=OFF, CREATE with a valid KEY_BLOCK_SIZE # ALTER with each ROW_FORMAT DROP TABLE IF EXISTS t1; @@ -684,7 +684,7 @@ Level Code Message Warning 1478 InnoDB: ignoring KEY_BLOCK_SIZE=16 unless ROW_FORMAT=COMPRESSED. SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 't1'; TABLE_NAME ROW_FORMAT CREATE_OPTIONS -t1 Compact row_format=COMPACT KEY_BLOCK_SIZE=16 +t1 Compact row_format=COMPACT key_block_size=16 ALTER TABLE t1 ROW_FORMAT=REDUNDANT; Warnings: Warning 1478 InnoDB: ignoring KEY_BLOCK_SIZE=16 unless ROW_FORMAT=COMPRESSED. @@ -693,7 +693,7 @@ Level Code Message Warning 1478 InnoDB: ignoring KEY_BLOCK_SIZE=16 unless ROW_FORMAT=COMPRESSED. SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 't1'; TABLE_NAME ROW_FORMAT CREATE_OPTIONS -t1 Redundant row_format=REDUNDANT KEY_BLOCK_SIZE=16 +t1 Redundant row_format=REDUNDANT key_block_size=16 ALTER TABLE t1 ROW_FORMAT=DYNAMIC; Warnings: Warning 1478 InnoDB: ignoring KEY_BLOCK_SIZE=16 unless ROW_FORMAT=COMPRESSED. @@ -702,13 +702,13 @@ Level Code Message Warning 1478 InnoDB: ignoring KEY_BLOCK_SIZE=16 unless ROW_FORMAT=COMPRESSED. SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 't1'; TABLE_NAME ROW_FORMAT CREATE_OPTIONS -t1 Dynamic row_format=DYNAMIC KEY_BLOCK_SIZE=16 +t1 Dynamic row_format=DYNAMIC key_block_size=16 ALTER TABLE t1 ROW_FORMAT=COMPRESSED; SHOW WARNINGS; Level Code Message SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 't1'; TABLE_NAME ROW_FORMAT CREATE_OPTIONS -t1 Compressed row_format=COMPRESSED KEY_BLOCK_SIZE=16 +t1 Compressed row_format=COMPRESSED key_block_size=16 ALTER TABLE t1 ROW_FORMAT=DEFAULT KEY_BLOCK_SIZE=0; SHOW WARNINGS; Level Code Message @@ -731,7 +731,7 @@ Level Code Message Warning 1478 InnoDB: ignoring KEY_BLOCK_SIZE=15. SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 't1'; TABLE_NAME ROW_FORMAT CREATE_OPTIONS -t1 Compact KEY_BLOCK_SIZE=15 +t1 Compact key_block_size=15 # Test 15) StrictMode=OFF, Make sure ROW_FORMAT= COMPRESSED & DYNAMIC and a valid KEY_BLOCK_SIZE are remembered but not used when ROW_FORMAT is reverted to Antelope and then used again when ROW_FORMAT=Barracuda. @@ -741,7 +741,7 @@ SHOW WARNINGS; Level Code Message SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 't1'; TABLE_NAME ROW_FORMAT CREATE_OPTIONS -t1 Compressed row_format=COMPRESSED KEY_BLOCK_SIZE=1 +t1 Compressed row_format=COMPRESSED key_block_size=1 SET GLOBAL innodb_file_format=Antelope; ALTER TABLE t1 ADD COLUMN f1 INT; Warnings: @@ -757,14 +757,14 @@ Warning 1478 InnoDB: ROW_FORMAT=COMPRESSED requires innodb_file_format > Antelop Warning 1478 InnoDB: assuming ROW_FORMAT=COMPACT. SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 't1'; TABLE_NAME ROW_FORMAT CREATE_OPTIONS -t1 Compact row_format=COMPRESSED KEY_BLOCK_SIZE=1 +t1 Compact row_format=COMPRESSED key_block_size=1 SET GLOBAL innodb_file_format=Barracuda; ALTER TABLE t1 ADD COLUMN f2 INT; SHOW WARNINGS; Level Code Message SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 't1'; TABLE_NAME ROW_FORMAT CREATE_OPTIONS -t1 Compressed row_format=COMPRESSED KEY_BLOCK_SIZE=1 +t1 Compressed row_format=COMPRESSED key_block_size=1 DROP TABLE IF EXISTS t1; CREATE TABLE t1 ( i INT ) ROW_FORMAT=DYNAMIC; SHOW WARNINGS; @@ -800,7 +800,7 @@ SHOW WARNINGS; Level Code Message SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 't1'; TABLE_NAME ROW_FORMAT CREATE_OPTIONS -t1 Compressed row_format=COMPRESSED KEY_BLOCK_SIZE=2 +t1 Compressed row_format=COMPRESSED key_block_size=2 SET GLOBAL innodb_file_per_table=OFF; ALTER TABLE t1 ADD COLUMN f1 INT; Warnings: @@ -816,14 +816,14 @@ Warning 1478 InnoDB: ROW_FORMAT=COMPRESSED requires innodb_file_per_table. Warning 1478 InnoDB: assuming ROW_FORMAT=COMPACT. SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 't1'; TABLE_NAME ROW_FORMAT CREATE_OPTIONS -t1 Compact row_format=COMPRESSED KEY_BLOCK_SIZE=2 +t1 Compact row_format=COMPRESSED key_block_size=2 SET GLOBAL innodb_file_per_table=ON; ALTER TABLE t1 ADD COLUMN f2 INT; SHOW WARNINGS; Level Code Message SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 't1'; TABLE_NAME ROW_FORMAT CREATE_OPTIONS -t1 Compressed row_format=COMPRESSED KEY_BLOCK_SIZE=2 +t1 Compressed row_format=COMPRESSED key_block_size=2 DROP TABLE IF EXISTS t1; CREATE TABLE t1 ( i INT ) ROW_FORMAT=DYNAMIC; SHOW WARNINGS; diff --git a/mysql-test/suite/parts/r/partition_auto_increment_innodb.result b/mysql-test/suite/parts/r/partition_auto_increment_innodb.result index 5fd576322d5..34e47f58272 100644 --- a/mysql-test/suite/parts/r/partition_auto_increment_innodb.result +++ b/mysql-test/suite/parts/r/partition_auto_increment_innodb.result @@ -134,7 +134,7 @@ Table Create Table t1 CREATE TABLE `t1` ( `c1` int(11) NOT NULL AUTO_INCREMENT, PRIMARY KEY (`c1`) -) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=latin1 +) ENGINE=InnoDB AUTO_INCREMENT=102 DEFAULT CHARSET=latin1 DROP TABLE t1; CREATE TABLE t1 (a INT NULL AUTO_INCREMENT, @@ -440,7 +440,7 @@ Table Create Table t1 CREATE TABLE `t1` ( `c1` int(11) NOT NULL AUTO_INCREMENT, PRIMARY KEY (`c1`) -) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=latin1 +) ENGINE=InnoDB AUTO_INCREMENT=102 DEFAULT CHARSET=latin1 /*!50100 PARTITION BY HASH (c1) PARTITIONS 2 */ DROP TABLE t1; diff --git a/mysql-test/t/innodb-zip.test b/mysql-test/t/innodb-zip.test deleted file mode 100644 index 7514da087eb..00000000000 --- a/mysql-test/t/innodb-zip.test +++ /dev/null @@ -1,347 +0,0 @@ --- source include/have_innodb.inc - -let $per_table=`select @@innodb_file_per_table`; -let $format=`select @@innodb_file_format`; -let $innodb_file_format_check_orig=`select @@innodb_file_format_check`; -set global innodb_file_per_table=off; -set global innodb_file_format=`0`; - -create table t0(a int primary key) engine=innodb row_format=compressed; -create table t00(a int primary key) engine=innodb -key_block_size=4 row_format=compressed; -create table t1(a int primary key) engine=innodb row_format=dynamic; -create table t2(a int primary key) engine=innodb row_format=redundant; -create table t3(a int primary key) engine=innodb row_format=compact; -create table t4(a int primary key) engine=innodb key_block_size=9; -create table t5(a int primary key) engine=innodb -key_block_size=1 row_format=redundant; - -set global innodb_file_per_table=on; -create table t6(a int primary key) engine=innodb -key_block_size=1 row_format=redundant; -set global innodb_file_format=`1`; -create table t7(a int primary key) engine=innodb -key_block_size=1 row_format=redundant; -create table t8(a int primary key) engine=innodb -key_block_size=1 row_format=fixed; -create table t9(a int primary key) engine=innodb -key_block_size=1 row_format=compact; -create table t10(a int primary key) engine=innodb -key_block_size=1 row_format=dynamic; -create table t11(a int primary key) engine=innodb -key_block_size=1 row_format=compressed; -create table t12(a int primary key) engine=innodb -key_block_size=1; -create table t13(a int primary key) engine=innodb -row_format=compressed; -create table t14(a int primary key) engine=innodb key_block_size=9; - -SELECT table_schema, table_name, row_format -FROM information_schema.tables WHERE engine='innodb'; - -drop table t0,t00,t2,t3,t4,t5,t6,t7,t8,t9,t10,t11,t12,t13,t14; -alter table t1 key_block_size=0; -alter table t1 row_format=dynamic; -SELECT table_schema, table_name, row_format -FROM information_schema.tables WHERE engine='innodb'; -alter table t1 row_format=compact; -SELECT table_schema, table_name, row_format -FROM information_schema.tables WHERE engine='innodb'; -alter table t1 row_format=redundant; -SELECT table_schema, table_name, row_format -FROM information_schema.tables WHERE engine='innodb'; -drop table t1; - -create table t1(a int not null, b text, index(b(10))) engine=innodb -key_block_size=1; - -create table t2(b text)engine=innodb; -insert into t2 values(concat('1abcdefghijklmnopqrstuvwxyz', repeat('A',5000))); - -insert into t1 select 1, b from t2; -commit; - -connect (a,localhost,root,,); -connect (b,localhost,root,,); - -connection a; -begin; -update t1 set b=repeat('B',100); - -connection b; -select a,left(b,40) from t1 natural join t2; - -connection a; -rollback; - -connection b; -select a,left(b,40) from t1 natural join t2; - -connection default; -disconnect a; -disconnect b; - -SELECT table_schema, table_name, row_format -FROM information_schema.tables WHERE engine='innodb'; -drop table t1,t2; - -# The following should fail even in non-strict mode. -SET SESSION innodb_strict_mode = off; ---error ER_TOO_BIG_ROWSIZE -CREATE TABLE t1( - c TEXT NOT NULL, d TEXT NOT NULL, - PRIMARY KEY (c(767),d(767))) -ENGINE=InnoDB ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=1 CHARSET=ASCII; ---error ER_TOO_BIG_ROWSIZE -CREATE TABLE t1( - c TEXT NOT NULL, d TEXT NOT NULL, - PRIMARY KEY (c(767),d(767))) -ENGINE=InnoDB ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=2 CHARSET=ASCII; -CREATE TABLE t1( - c TEXT NOT NULL, d TEXT NOT NULL, - PRIMARY KEY (c(767),d(767))) -ENGINE=InnoDB ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=4 CHARSET=ASCII; -drop table t1; ---error ER_TOO_BIG_ROWSIZE -CREATE TABLE t1(c TEXT, PRIMARY KEY (c(440))) -ENGINE=InnoDB ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=1 CHARSET=ASCII; -# The maximum key size for a compressed row actually depends on the -# version of libz used, as account must be taken for the maximum -# compressed size of a key, and this differs between libz -# versions. Some libz versions allow a size of 439, some only 438. -CREATE TABLE t1(c TEXT, PRIMARY KEY (c(438))) -ENGINE=InnoDB ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=1 CHARSET=ASCII; -INSERT INTO t1 VALUES(REPEAT('A',512)),(REPEAT('B',512)); -DROP TABLE t1; - -# -# Test blob column inheritance (mantis issue#36) -# - -create table t1( c1 int not null, c2 blob, c3 blob, c4 blob, - primary key(c1, c2(22), c3(22))) - engine = innodb row_format = dynamic; -begin; -insert into t1 values(1, repeat('A', 20000), repeat('B', 20000), - repeat('C', 20000)); - -update t1 set c3 = repeat('D', 20000) where c1 = 1; -commit; - -# one blob column which is unchanged in update and part of PK -# one blob column which is changed and part of of PK -# one blob column which is not part of PK and is unchanged -select count(*) from t1 where c2 = repeat('A', 20000); -select count(*) from t1 where c3 = repeat('D', 20000); -select count(*) from t1 where c4 = repeat('C', 20000); - -update t1 set c3 = repeat('E', 20000) where c1 = 1; -drop table t1; - -# -# -# Test innodb_file_format -# -set global innodb_file_format=`0`; -select @@innodb_file_format; -set global innodb_file_format=`1`; -select @@innodb_file_format; --- error ER_WRONG_ARGUMENTS -set global innodb_file_format=`2`; --- error ER_WRONG_ARGUMENTS -set global innodb_file_format=`-1`; -set global innodb_file_format=`Antelope`; -set global innodb_file_format=`Barracuda`; --- error ER_WRONG_ARGUMENTS -set global innodb_file_format=`Cheetah`; --- error ER_WRONG_ARGUMENTS -set global innodb_file_format=`abc`; --- error ER_WRONG_ARGUMENTS -set global innodb_file_format=`1a`; --- error ER_WRONG_ARGUMENTS -set global innodb_file_format=``; - -#test strict mode. -# this does not work anymore, has been removed from mysqltest -# -- enable_errors -set global innodb_file_per_table = on; -set global innodb_file_format = `1`; - -set innodb_strict_mode = off; -create table t1 (id int primary key) engine = innodb key_block_size = 0; -drop table t1; - -#set strict_mode -set innodb_strict_mode = on; - -#Test different values of KEY_BLOCK_SIZE - ---error ER_CANT_CREATE_TABLE -create table t1 (id int primary key) engine = innodb key_block_size = 0; -show warnings; - ---error ER_CANT_CREATE_TABLE -create table t2 (id int primary key) engine = innodb key_block_size = 9; -show warnings; - - -create table t3 (id int primary key) engine = innodb key_block_size = 1; -create table t4 (id int primary key) engine = innodb key_block_size = 2; -create table t5 (id int primary key) engine = innodb key_block_size = 4; -create table t6 (id int primary key) engine = innodb key_block_size = 8; -create table t7 (id int primary key) engine = innodb key_block_size = 16; - -#check various ROW_FORMAT values. -create table t8 (id int primary key) engine = innodb row_format = compressed; -create table t9 (id int primary key) engine = innodb row_format = dynamic; -create table t10(id int primary key) engine = innodb row_format = compact; -create table t11(id int primary key) engine = innodb row_format = redundant; - -SELECT table_schema, table_name, row_format -FROM information_schema.tables WHERE engine='innodb'; -drop table t3, t4, t5, t6, t7, t8, t9, t10, t11; - -#test different values of ROW_FORMAT with KEY_BLOCK_SIZE -create table t1 (id int primary key) engine = innodb -key_block_size = 8 row_format = compressed; - ---error ER_CANT_CREATE_TABLE -create table t2 (id int primary key) engine = innodb -key_block_size = 8 row_format = redundant; -show warnings; - ---error ER_CANT_CREATE_TABLE -create table t3 (id int primary key) engine = innodb -key_block_size = 8 row_format = compact; -show warnings; - ---error ER_CANT_CREATE_TABLE -create table t4 (id int primary key) engine = innodb -key_block_size = 8 row_format = dynamic; -show warnings; - ---error ER_CANT_CREATE_TABLE -create table t5 (id int primary key) engine = innodb -key_block_size = 8 row_format = default; -show warnings; - -SELECT table_schema, table_name, row_format -FROM information_schema.tables WHERE engine='innodb'; -drop table t1; - -#test multiple errors ---error ER_CANT_CREATE_TABLE -create table t1 (id int primary key) engine = innodb -key_block_size = 9 row_format = redundant; -show warnings; - ---error ER_CANT_CREATE_TABLE -create table t2 (id int primary key) engine = innodb -key_block_size = 9 row_format = compact; -show warnings; - ---error ER_CANT_CREATE_TABLE -create table t2 (id int primary key) engine = innodb -key_block_size = 9 row_format = dynamic; -show warnings; - -SELECT table_schema, table_name, row_format -FROM information_schema.tables WHERE engine='innodb'; - -#test valid values with innodb_file_per_table unset -set global innodb_file_per_table = off; - ---error ER_CANT_CREATE_TABLE -create table t1 (id int primary key) engine = innodb key_block_size = 1; -show warnings; ---error ER_CANT_CREATE_TABLE -create table t2 (id int primary key) engine = innodb key_block_size = 2; -show warnings; ---error ER_CANT_CREATE_TABLE -create table t3 (id int primary key) engine = innodb key_block_size = 4; -show warnings; ---error ER_CANT_CREATE_TABLE -create table t4 (id int primary key) engine = innodb key_block_size = 8; -show warnings; ---error ER_CANT_CREATE_TABLE -create table t5 (id int primary key) engine = innodb key_block_size = 16; -show warnings; ---error ER_CANT_CREATE_TABLE -create table t6 (id int primary key) engine = innodb row_format = compressed; -show warnings; ---error ER_CANT_CREATE_TABLE -create table t7 (id int primary key) engine = innodb row_format = dynamic; -show warnings; -create table t8 (id int primary key) engine = innodb row_format = compact; -create table t9 (id int primary key) engine = innodb row_format = redundant; - -SELECT table_schema, table_name, row_format -FROM information_schema.tables WHERE engine='innodb'; -drop table t8, t9; - -#test valid values with innodb_file_format unset -set global innodb_file_per_table = on; -set global innodb_file_format = `0`; - ---error ER_CANT_CREATE_TABLE -create table t1 (id int primary key) engine = innodb key_block_size = 1; -show warnings; ---error ER_CANT_CREATE_TABLE -create table t2 (id int primary key) engine = innodb key_block_size = 2; -show warnings; ---error ER_CANT_CREATE_TABLE -create table t3 (id int primary key) engine = innodb key_block_size = 4; -show warnings; ---error ER_CANT_CREATE_TABLE -create table t4 (id int primary key) engine = innodb key_block_size = 8; -show warnings; ---error ER_CANT_CREATE_TABLE -create table t5 (id int primary key) engine = innodb key_block_size = 16; -show warnings; ---error ER_CANT_CREATE_TABLE -create table t6 (id int primary key) engine = innodb row_format = compressed; -show warnings; ---error ER_CANT_CREATE_TABLE -create table t7 (id int primary key) engine = innodb row_format = dynamic; -show warnings; -create table t8 (id int primary key) engine = innodb row_format = compact; -create table t9 (id int primary key) engine = innodb row_format = redundant; - -SELECT table_schema, table_name, row_format -FROM information_schema.tables WHERE engine='innodb'; -drop table t8, t9; - -eval set global innodb_file_per_table=$per_table; -eval set global innodb_file_format=$format; -# -# Testing of tablespace tagging -# --- disable_info -set global innodb_file_per_table=on; -set global innodb_file_format=`Barracuda`; -set global innodb_file_format_check=`Antelope`; -create table normal_table ( - c1 int -) engine = innodb; -select @@innodb_file_format_check; -create table zip_table ( - c1 int -) engine = innodb key_block_size = 8; -select @@innodb_file_format_check; -set global innodb_file_format_check=`Antelope`; -select @@innodb_file_format_check; --- disable_result_log -show table status; --- enable_result_log -select @@innodb_file_format_check; -drop table normal_table, zip_table; --- disable_result_log - -# -# restore environment to the state it was before this test execution -# - --- disable_query_log -eval set global innodb_file_format=$format; -eval set global innodb_file_per_table=$per_table; -eval set global innodb_file_format_check=$innodb_file_format_check_orig; diff --git a/storage/xtradb/ChangeLog b/storage/xtradb/ChangeLog index 5ca60eb73d5..bf003b810d2 100644 --- a/storage/xtradb/ChangeLog +++ b/storage/xtradb/ChangeLog @@ -1,4 +1,44 @@ +2011-01-06 The InnoDB Team + * row/row0merge.c: + Fix Bug#59312 Examine MAX_FULL_NAME_LEN in InnoDB to address + possible insufficient name buffer + +2011-01-06 The InnoDB Team + * dict/dict0dict.c, handler/ha_innodb.cc, handler/i_s.cc, + include/univ.i: + Fix Bug#58643 InnoDB: too long table name + +2011-01-06 The InnoDB Team + * handler/i_s.cc, include/trx0i_s.h, trx/trx0i_s.c: + Fix Bug#55397 cannot select from innodb_trx when trx_query contains + blobs that aren't strings + +2011-01-04 The InnoDB Team + * dict/dict0dict.c: + Fix Bug#59197 double quote in field comment prevents foreign + key constraint creation + +2010-12-21 The InnoDB Team + * include/btr0cur.h, include/row0upd.h, btr/btr0cur.c, + row/row0umod.c, row/row0upd.c: + Fix Bug#55284 Double free of off-page columns due to lock wait + while updating PRIMARY KEY + +2010-12-21 The InnoDB Team + + * include/data0data.h, include/data0data.ic, include/row0upd.h, + btr/btr0cur.c, row/row0purge.c, row/row0umod.c, row/row0upd.c, + innodb.result, innodb.test: + Fix Bug#58912 InnoDB unnecessarily avoids update-in-place + on column prefix indexes + +2010-12-09 The InnoDB Team + + * buf/buf0lru.c: + Fix Bug#57600 output of I/O sum[%lu] can go negative + 2010-11-11 The InnoDB Team + * thr/thr0loc.c, trx/trx0i_s.c: Fix Bug#57802 Empty ASSERTION parameter passed to the HASH_SEARCH macro diff --git a/storage/xtradb/btr/btr0btr.c b/storage/xtradb/btr/btr0btr.c index 4d6cd8d80fc..55204691400 100644 --- a/storage/xtradb/btr/btr0btr.c +++ b/storage/xtradb/btr/btr0btr.c @@ -675,7 +675,7 @@ btr_page_get_father_node_ptr_func( " to fix the\n" "InnoDB: corruption. If the crash happens at " "the database startup, see\n" - "InnoDB: " REFMAN "forcing-recovery.html about\n" + "InnoDB: " REFMAN "forcing-innodb-recovery.html about\n" "InnoDB: forcing recovery. " "Then dump + drop + reimport.\n", stderr); diff --git a/storage/xtradb/btr/btr0cur.c b/storage/xtradb/btr/btr0cur.c index 25bdd176880..321504a2b25 100644 --- a/storage/xtradb/btr/btr0cur.c +++ b/storage/xtradb/btr/btr0cur.c @@ -1933,7 +1933,8 @@ btr_cur_update_in_place( NOT call it if index is secondary */ if (!dict_index_is_clust(index) - || row_upd_changes_ord_field_binary(NULL, index, update)) { + || row_upd_changes_ord_field_binary(NULL, NULL, + index, update)) { /* Remove possible hash index pointer to this record */ btr_search_update_hash_on_delete(cursor); @@ -2685,27 +2686,24 @@ ulint btr_cur_del_mark_set_clust_rec( /*===========================*/ ulint flags, /*!< in: undo logging and locking flags */ - btr_cur_t* cursor, /*!< in: cursor */ + buf_block_t* block, /*!< in/out: buffer block of the record */ + rec_t* rec, /*!< in/out: record */ + dict_index_t* index, /*!< in: clustered index of the record */ + const ulint* offsets,/*!< in: rec_get_offsets(rec) */ ibool val, /*!< in: value to set */ que_thr_t* thr, /*!< in: query thread */ mtr_t* mtr) /*!< in: mtr */ { - dict_index_t* index; - buf_block_t* block; roll_ptr_t roll_ptr; ulint err; - rec_t* rec; page_zip_des_t* page_zip; trx_t* trx; - mem_heap_t* heap = NULL; - ulint offsets_[REC_OFFS_NORMAL_SIZE]; - ulint* offsets = offsets_; - rec_offs_init(offsets_); - rec = btr_cur_get_rec(cursor); - index = cursor->index; + ut_ad(dict_index_is_clust(index)); + ut_ad(rec_offs_validate(rec, index, offsets)); ut_ad(!!page_rec_is_comp(rec) == dict_table_is_comp(index->table)); - offsets = rec_get_offsets(rec, index, offsets, ULINT_UNDEFINED, &heap); + ut_ad(buf_block_get_frame(block) == page_align(rec)); + ut_ad(page_is_leaf(page_align(rec))); #ifdef UNIV_DEBUG if (btr_cur_print_record_ops && thr) { @@ -2717,13 +2715,12 @@ btr_cur_del_mark_set_clust_rec( ut_ad(dict_index_is_clust(index)); ut_ad(!rec_get_deleted_flag(rec, rec_offs_comp(offsets))); - err = lock_clust_rec_modify_check_and_lock(flags, - btr_cur_get_block(cursor), + err = lock_clust_rec_modify_check_and_lock(flags, block, rec, index, offsets, thr); if (err != DB_SUCCESS) { - goto func_exit; + return(err); } err = trx_undo_report_row_operation(flags, TRX_UNDO_MODIFY_OP, thr, @@ -2731,11 +2728,9 @@ btr_cur_del_mark_set_clust_rec( &roll_ptr); if (err != DB_SUCCESS) { - goto func_exit; + return(err); } - block = btr_cur_get_block(cursor); - if (block->is_hashed) { rw_lock_x_lock(&btr_search_latch); } @@ -2758,10 +2753,6 @@ btr_cur_del_mark_set_clust_rec( btr_cur_del_mark_set_clust_rec_log(flags, rec, index, val, trx, roll_ptr, mtr); -func_exit: - if (UNIV_LIKELY_NULL(heap)) { - mem_heap_free(heap); - } return(err); } @@ -3856,108 +3847,36 @@ btr_cur_set_ownership_of_extern_field( } /*******************************************************************//** -Marks not updated extern fields as not-owned by this record. The ownership -is transferred to the updated record which is inserted elsewhere in the +Marks non-updated off-page fields as disowned by this record. The ownership +must be transferred to the updated record which is inserted elsewhere in the index tree. In purge only the owner of externally stored field is allowed -to free the field. -@return TRUE if BLOB ownership was transferred */ +to free the field. */ UNIV_INTERN -ibool -btr_cur_mark_extern_inherited_fields( -/*=================================*/ +void +btr_cur_disown_inherited_fields( +/*============================*/ page_zip_des_t* page_zip,/*!< in/out: compressed page whose uncompressed part will be updated, or NULL */ rec_t* rec, /*!< in/out: record in a clustered index */ dict_index_t* index, /*!< in: index of the page */ const ulint* offsets,/*!< in: array returned by rec_get_offsets() */ const upd_t* update, /*!< in: update vector */ - mtr_t* mtr) /*!< in: mtr, or NULL if not logged */ + mtr_t* mtr) /*!< in/out: mini-transaction */ { - ulint n; - ulint j; ulint i; - ibool change_ownership = FALSE; - ut_ad(rec_offs_validate(rec, NULL, offsets)); + ut_ad(rec_offs_validate(rec, index, offsets)); ut_ad(!rec_offs_comp(offsets) || !rec_get_node_ptr_flag(rec)); + ut_ad(rec_offs_any_extern(offsets)); + ut_ad(mtr); - if (!rec_offs_any_extern(offsets)) { - - return(FALSE); - } - - n = rec_offs_n_fields(offsets); - - for (i = 0; i < n; i++) { - if (rec_offs_nth_extern(offsets, i)) { - - /* Check it is not in updated fields */ - - if (update) { - for (j = 0; j < upd_get_n_fields(update); - j++) { - if (upd_get_nth_field(update, j) - ->field_no == i) { - - goto updated; - } - } - } - + for (i = 0; i < rec_offs_n_fields(offsets); i++) { + if (rec_offs_nth_extern(offsets, i) + && !upd_get_field_by_field_no(update, i)) { btr_cur_set_ownership_of_extern_field( page_zip, rec, index, offsets, i, FALSE, mtr); - - change_ownership = TRUE; -updated: - ; } } - - return(change_ownership); -} - -/*******************************************************************//** -The complement of the previous function: in an update entry may inherit -some externally stored fields from a record. We must mark them as inherited -in entry, so that they are not freed in a rollback. */ -UNIV_INTERN -void -btr_cur_mark_dtuple_inherited_extern( -/*=================================*/ - dtuple_t* entry, /*!< in/out: updated entry to be - inserted to clustered index */ - const upd_t* update) /*!< in: update vector */ -{ - ulint i; - - for (i = 0; i < dtuple_get_n_fields(entry); i++) { - - dfield_t* dfield = dtuple_get_nth_field(entry, i); - byte* data; - ulint len; - ulint j; - - if (!dfield_is_ext(dfield)) { - continue; - } - - /* Check if it is in updated fields */ - - for (j = 0; j < upd_get_n_fields(update); j++) { - if (upd_get_nth_field(update, j)->field_no == i) { - - goto is_updated; - } - } - - data = dfield_get_data(dfield); - len = dfield_get_len(dfield); - data[len - BTR_EXTERN_FIELD_REF_SIZE + BTR_EXTERN_LEN] - |= BTR_EXTERN_INHERITED_FLAG; - -is_updated: - ; - } } /*******************************************************************//** @@ -3995,29 +3914,6 @@ btr_cur_unmark_extern_fields( } } -/*******************************************************************//** -Marks all extern fields in a dtuple as owned by the record. */ -UNIV_INTERN -void -btr_cur_unmark_dtuple_extern_fields( -/*================================*/ - dtuple_t* entry) /*!< in/out: clustered index entry */ -{ - ulint i; - - for (i = 0; i < dtuple_get_n_fields(entry); i++) { - dfield_t* dfield = dtuple_get_nth_field(entry, i); - - if (dfield_is_ext(dfield)) { - byte* data = dfield_get_data(dfield); - ulint len = dfield_get_len(dfield); - - data[len - BTR_EXTERN_FIELD_REF_SIZE + BTR_EXTERN_LEN] - &= ~BTR_EXTERN_OWNER_FLAG; - } - } -} - /*******************************************************************//** Flags the data tuple fields that are marked as extern storage in the update vector. We use this function to remember which fields we must diff --git a/storage/xtradb/buf/buf0buf.c b/storage/xtradb/buf/buf0buf.c index cf48d95d505..b4fe99236e8 100644 --- a/storage/xtradb/buf/buf0buf.c +++ b/storage/xtradb/buf/buf0buf.c @@ -457,7 +457,7 @@ buf_page_is_corrupted( "you may have copied the InnoDB\n" "InnoDB: tablespace but not the InnoDB " "log files. See\n" - "InnoDB: " REFMAN "forcing-recovery.html\n" + "InnoDB: " REFMAN "forcing-innodb-recovery.html\n" "InnoDB: for more information.\n", (ulong) mach_read_from_4(read_buf + FIL_PAGE_OFFSET), @@ -3999,7 +3999,7 @@ corrupt: "InnoDB: TABLE to scan your" " table for corruption.\n" "InnoDB: See also " - REFMAN "forcing-recovery.html\n" + REFMAN "forcing-innodb-recovery.html\n" "InnoDB: about forcing recovery.\n", stderr); if (srv_pass_corrupt_table && !trx_sys_sys_space(bpage->space) diff --git a/storage/xtradb/buf/buf0lru.c b/storage/xtradb/buf/buf0lru.c index f90d92eb732..92a645ef2f5 100644 --- a/storage/xtradb/buf/buf0lru.c +++ b/storage/xtradb/buf/buf0lru.c @@ -2093,6 +2093,7 @@ buf_LRU_stat_update(void) /*=====================*/ { buf_LRU_stat_t* item; + buf_LRU_stat_t cur_stat; /* If we haven't started eviction yet then don't update stats. */ if (buf_pool->freed_page_clock == 0) { @@ -2107,12 +2108,19 @@ buf_LRU_stat_update(void) buf_LRU_stat_arr_ind++; buf_LRU_stat_arr_ind %= BUF_LRU_STAT_N_INTERVAL; - /* Add the current value and subtract the obsolete entry. */ - buf_LRU_stat_sum.io += buf_LRU_stat_cur.io - item->io; - buf_LRU_stat_sum.unzip += buf_LRU_stat_cur.unzip - item->unzip; + /* Add the current value and subtract the obsolete entry. + Since buf_LRU_stat_cur is not protected by any mutex, + it can be changing between adding to buf_LRU_stat_sum + and copying to item. Assign it to local variables to make + sure the same value assign to the buf_LRU_stat_sum + and item */ + cur_stat = buf_LRU_stat_cur; + + buf_LRU_stat_sum.io += cur_stat.io - item->io; + buf_LRU_stat_sum.unzip += cur_stat.unzip - item->unzip; /* Put current entry in the array. */ - memcpy(item, &buf_LRU_stat_cur, sizeof *item); + memcpy(item, &cur_stat, sizeof *item); //buf_pool_mutex_exit(); mutex_exit(&buf_pool_mutex); diff --git a/storage/xtradb/dict/dict0dict.c b/storage/xtradb/dict/dict0dict.c index 4d99907f093..638ab55703b 100644 --- a/storage/xtradb/dict/dict0dict.c +++ b/storage/xtradb/dict/dict0dict.c @@ -937,7 +937,7 @@ dict_table_rename_in_cache( dict_foreign_t* foreign; dict_index_t* index; ulint fold; - char old_name[MAX_TABLE_NAME_LEN + 1]; + char old_name[MAX_FULL_NAME_LEN + 1]; ut_ad(table); ut_ad(mutex_own(&(dict_sys->mutex))); @@ -949,7 +949,7 @@ dict_table_rename_in_cache( ut_print_timestamp(stderr); fprintf(stderr, "InnoDB: too long table name: '%s', " "max length is %d\n", table->name, - MAX_TABLE_NAME_LEN); + MAX_FULL_NAME_LEN); ut_error; } @@ -999,11 +999,11 @@ dict_table_rename_in_cache( ut_fold_string(old_name), table); if (strlen(new_name) > strlen(table->name)) { - /* We allocate MAX_TABLE_NAME_LEN+1 bytes here to avoid + /* We allocate MAX_FULL_NAME_LEN + 1 bytes here to avoid memory fragmentation, we assume a repeated calls of ut_realloc() with the same size do not cause fragmentation */ - ut_a(strlen(new_name) <= MAX_TABLE_NAME_LEN); - table->name = ut_realloc(table->name, MAX_TABLE_NAME_LEN + 1); + ut_a(strlen(new_name) <= MAX_FULL_NAME_LEN); + table->name = ut_realloc(table->name, MAX_FULL_NAME_LEN + 1); } memcpy(table->name, new_name, strlen(new_name) + 1); @@ -2756,7 +2756,7 @@ dict_scan_to( quote = '\0'; } else if (quote) { /* Within quotes: do nothing. */ - } else if (*ptr == '`' || *ptr == '"') { + } else if (*ptr == '`' || *ptr == '"' || *ptr == '\'') { /* Starting quote: remember the quote character. */ quote = *ptr; } else { diff --git a/storage/xtradb/fsp/fsp0fsp.c b/storage/xtradb/fsp/fsp0fsp.c index 0561bcc77fc..44ebe6819b7 100644 --- a/storage/xtradb/fsp/fsp0fsp.c +++ b/storage/xtradb/fsp/fsp0fsp.c @@ -3355,7 +3355,7 @@ fseg_free_page_low( "InnoDB: database!\n", (ulong) page); crash: fputs("InnoDB: Please refer to\n" - "InnoDB: " REFMAN "forcing-recovery.html\n" + "InnoDB: " REFMAN "forcing-innodb-recovery.html\n" "InnoDB: about forcing recovery.\n", stderr); ut_error; } diff --git a/storage/xtradb/handler/ha_innodb.cc b/storage/xtradb/handler/ha_innodb.cc index 3e742fbac87..2a6689eb38f 100644 --- a/storage/xtradb/handler/ha_innodb.cc +++ b/storage/xtradb/handler/ha_innodb.cc @@ -6420,6 +6420,16 @@ create_table_def( DBUG_RETURN(HA_ERR_GENERIC); } + /* MySQL does the name length check. But we do additional check + on the name length here */ + if (strlen(table_name) > MAX_FULL_NAME_LEN) { + push_warning_printf( + (THD*) trx->mysql_thd, MYSQL_ERROR::WARN_LEVEL_WARN, + ER_TABLE_NAME, + "InnoDB: Table Name or Database Name is too long"); + DBUG_RETURN(ER_TABLE_NAME); + } + n_cols = form->s->fields; /* We pass 0 as the space id, and determine at a lower level the space @@ -6704,10 +6714,11 @@ create_clustered_index_when_no_primary( /*****************************************************************//** Return a display name for the row format @return row format name */ - -const char *get_row_format_name( -/*============================*/ -enum row_type row_format) /*!< in: Row Format */ +UNIV_INTERN +const char* +get_row_format_name( +/*================*/ + enum row_type row_format) /*!< in: Row Format */ { switch (row_format) { case ROW_TYPE_COMPACT: @@ -6722,12 +6733,38 @@ enum row_type row_format) /*!< in: Row Format */ return("DEFAULT"); case ROW_TYPE_FIXED: return("FIXED"); - default: + case ROW_TYPE_PAGE: + case ROW_TYPE_NOT_USED: break; } return("NOT USED"); } +/** If file-per-table is missing, issue warning and set ret false */ +#define CHECK_ERROR_ROW_TYPE_NEEDS_FILE_PER_TABLE \ + if (!srv_file_per_table) { \ + push_warning_printf( \ + thd, MYSQL_ERROR::WARN_LEVEL_WARN, \ + ER_ILLEGAL_HA_CREATE_OPTION, \ + "InnoDB: ROW_FORMAT=%s requires" \ + " innodb_file_per_table.", \ + get_row_format_name(row_format)); \ + ret = FALSE; \ + } + +/** If file-format is Antelope, issue warning and set ret false */ +#define CHECK_ERROR_ROW_TYPE_NEEDS_GT_ANTELOPE \ + if (srv_file_format < DICT_TF_FORMAT_ZIP) { \ + push_warning_printf( \ + thd, MYSQL_ERROR::WARN_LEVEL_WARN, \ + ER_ILLEGAL_HA_CREATE_OPTION, \ + "InnoDB: ROW_FORMAT=%s requires" \ + " innodb_file_format > Antelope.", \ + get_row_format_name(row_format)); \ + ret = FALSE; \ + } + + /*****************************************************************//** Validates the create options. We may build on this function in future. For now, it checks two specifiers: @@ -6745,7 +6782,7 @@ create_options_are_valid( { ibool kbs_specified = FALSE; ibool ret = TRUE; - enum row_type row_type = form->s->row_type; + enum row_type row_format = form->s->row_type; ut_ad(thd != NULL); @@ -6754,23 +6791,6 @@ create_options_are_valid( return(TRUE); } - /* Check for a valid Innodb ROW_FORMAT specifier. For example, - ROW_TYPE_FIXED can be sent to Innodb */ - switch (row_type) { - case ROW_TYPE_COMPACT: - case ROW_TYPE_COMPRESSED: - case ROW_TYPE_DYNAMIC: - case ROW_TYPE_REDUNDANT: - case ROW_TYPE_DEFAULT: - break; - default: - push_warning( - thd, MYSQL_ERROR::WARN_LEVEL_WARN, - ER_ILLEGAL_HA_CREATE_OPTION, - "InnoDB: invalid ROW_FORMAT specifier."); - ret = FALSE; - } - ut_ad(form != NULL); ut_ad(create_info != NULL); @@ -6783,7 +6803,23 @@ create_options_are_valid( case 4: case 8: case 16: - /* Valid value. */ + /* Valid KEY_BLOCK_SIZE, check its dependencies. */ + if (!srv_file_per_table) { + push_warning( + thd, MYSQL_ERROR::WARN_LEVEL_WARN, + ER_ILLEGAL_HA_CREATE_OPTION, + "InnoDB: KEY_BLOCK_SIZE requires" + " innodb_file_per_table."); + ret = FALSE; + } + if (srv_file_format < DICT_TF_FORMAT_ZIP) { + push_warning( + thd, MYSQL_ERROR::WARN_LEVEL_WARN, + ER_ILLEGAL_HA_CREATE_OPTION, + "InnoDB: KEY_BLOCK_SIZE requires" + " innodb_file_format > Antelope."); + ret = FALSE; + } break; default: push_warning_printf( @@ -6793,72 +6829,43 @@ create_options_are_valid( " Valid values are [1, 2, 4, 8, 16]", create_info->key_block_size); ret = FALSE; + break; } } - /* If KEY_BLOCK_SIZE was specified, check for its - dependencies. */ - if (kbs_specified && !srv_file_per_table) { - push_warning( - thd, MYSQL_ERROR::WARN_LEVEL_WARN, - ER_ILLEGAL_HA_CREATE_OPTION, - "InnoDB: KEY_BLOCK_SIZE" - " requires innodb_file_per_table."); - ret = FALSE; - } - - if (kbs_specified && srv_file_format < DICT_TF_FORMAT_ZIP) { - push_warning( - thd, MYSQL_ERROR::WARN_LEVEL_WARN, - ER_ILLEGAL_HA_CREATE_OPTION, - "InnoDB: KEY_BLOCK_SIZE requires" - " innodb_file_format > Antelope."); - ret = FALSE; - } - - switch (row_type) { + /* Check for a valid Innodb ROW_FORMAT specifier and + other incompatibilities. */ + switch (row_format) { case ROW_TYPE_COMPRESSED: - case ROW_TYPE_DYNAMIC: - /* These two ROW_FORMATs require srv_file_per_table - and srv_file_format > Antelope */ - if (!srv_file_per_table) { - push_warning_printf( - thd, MYSQL_ERROR::WARN_LEVEL_WARN, - ER_ILLEGAL_HA_CREATE_OPTION, - "InnoDB: ROW_FORMAT=%s" - " requires innodb_file_per_table.", - get_row_format_name(row_type)); - ret = FALSE; - } - - if (srv_file_format < DICT_TF_FORMAT_ZIP) { - push_warning_printf( - thd, MYSQL_ERROR::WARN_LEVEL_WARN, - ER_ILLEGAL_HA_CREATE_OPTION, - "InnoDB: ROW_FORMAT=%s requires" - " innodb_file_format > Antelope.", - get_row_format_name(row_type)); - ret = FALSE; - } - default: + CHECK_ERROR_ROW_TYPE_NEEDS_FILE_PER_TABLE; + CHECK_ERROR_ROW_TYPE_NEEDS_GT_ANTELOPE; break; - } - - switch (row_type) { - case ROW_TYPE_REDUNDANT: - case ROW_TYPE_COMPACT: case ROW_TYPE_DYNAMIC: - /* KEY_BLOCK_SIZE is only allowed with Compressed or Default */ + CHECK_ERROR_ROW_TYPE_NEEDS_FILE_PER_TABLE; + CHECK_ERROR_ROW_TYPE_NEEDS_GT_ANTELOPE; + /* fall through since dynamic also shuns KBS */ + case ROW_TYPE_COMPACT: + case ROW_TYPE_REDUNDANT: if (kbs_specified) { push_warning_printf( thd, MYSQL_ERROR::WARN_LEVEL_WARN, ER_ILLEGAL_HA_CREATE_OPTION, "InnoDB: cannot specify ROW_FORMAT = %s" " with KEY_BLOCK_SIZE.", - get_row_format_name(row_type)); - ret = FALSE; + get_row_format_name(row_format)); + ret = FALSE; } - default: + break; + case ROW_TYPE_DEFAULT: + break; + case ROW_TYPE_FIXED: + case ROW_TYPE_PAGE: + case ROW_TYPE_NOT_USED: + push_warning( + thd, MYSQL_ERROR::WARN_LEVEL_WARN, + ER_ILLEGAL_HA_CREATE_OPTION, \ + "InnoDB: invalid ROW_FORMAT specifier."); + ret = FALSE; break; } @@ -6909,7 +6916,7 @@ ha_innobase::create( const ulint file_format = srv_file_format; const char* stmt; size_t stmt_len; - enum row_type row_type; + enum row_type row_format; DBUG_ENTER("ha_innobase::create"); @@ -7009,8 +7016,8 @@ ha_innobase::create( push_warning( thd, MYSQL_ERROR::WARN_LEVEL_WARN, ER_ILLEGAL_HA_CREATE_OPTION, - "InnoDB: KEY_BLOCK_SIZE" - " requires innodb_file_per_table."); + "InnoDB: KEY_BLOCK_SIZE requires" + " innodb_file_per_table."); flags = 0; } @@ -7027,20 +7034,19 @@ ha_innobase::create( push_warning_printf( thd, MYSQL_ERROR::WARN_LEVEL_WARN, ER_ILLEGAL_HA_CREATE_OPTION, - "InnoDB: ignoring" - " KEY_BLOCK_SIZE=%lu.", + "InnoDB: ignoring KEY_BLOCK_SIZE=%lu.", create_info->key_block_size); } } - row_type = form->s->row_type; + row_format = form->s->row_type; if (flags) { /* if ROW_FORMAT is set to default, automatically change it to COMPRESSED.*/ - if (row_type == ROW_TYPE_DEFAULT) { - row_type = ROW_TYPE_COMPRESSED; - } else if (row_type != ROW_TYPE_COMPRESSED) { + if (row_format == ROW_TYPE_DEFAULT) { + row_format = ROW_TYPE_COMPRESSED; + } else if (row_format != ROW_TYPE_COMPRESSED) { /* ROW_FORMAT other than COMPRESSED ignores KEY_BLOCK_SIZE. It does not make sense to reject conflicting @@ -7057,7 +7063,7 @@ ha_innobase::create( } } else { /* flags == 0 means no KEY_BLOCK_SIZE.*/ - if (row_type == ROW_TYPE_COMPRESSED) { + if (row_format == ROW_TYPE_COMPRESSED) { /* ROW_FORMAT=COMPRESSED without KEY_BLOCK_SIZE implies half the maximum KEY_BLOCK_SIZE. */ @@ -7072,7 +7078,7 @@ ha_innobase::create( } } - switch (row_type) { + switch (row_format) { case ROW_TYPE_REDUNDANT: break; case ROW_TYPE_COMPRESSED: @@ -7083,25 +7089,25 @@ ha_innobase::create( ER_ILLEGAL_HA_CREATE_OPTION, "InnoDB: ROW_FORMAT=%s requires" " innodb_file_per_table.", - get_row_format_name(row_type)); + get_row_format_name(row_format)); } else if (file_format < DICT_TF_FORMAT_ZIP) { push_warning_printf( thd, MYSQL_ERROR::WARN_LEVEL_WARN, ER_ILLEGAL_HA_CREATE_OPTION, "InnoDB: ROW_FORMAT=%s requires" " innodb_file_format > Antelope.", - get_row_format_name(row_type)); + get_row_format_name(row_format)); } else { flags |= DICT_TF_COMPACT - | (DICT_TF_FORMAT_ZIP - << DICT_TF_FORMAT_SHIFT); + | (DICT_TF_FORMAT_ZIP + << DICT_TF_FORMAT_SHIFT); break; } /* fall through */ case ROW_TYPE_NOT_USED: case ROW_TYPE_FIXED: - default: + case ROW_TYPE_PAGE: push_warning( thd, MYSQL_ERROR::WARN_LEVEL_WARN, ER_ILLEGAL_HA_CREATE_OPTION, @@ -7219,23 +7225,25 @@ ha_innobase::create( setup at this stage and so we use thd. */ /* We need to copy the AUTOINC value from the old table if - this is an ALTER TABLE or CREATE INDEX because CREATE INDEX - does a table copy too. */ + this is an ALTER|OPTIMIZE TABLE or CREATE INDEX because CREATE INDEX + does a table copy too. If query was one of : + + CREATE TABLE ...AUTO_INCREMENT = x; or + ALTER TABLE...AUTO_INCREMENT = x; or + OPTIMIZE TABLE t; or + CREATE INDEX x on t(...); + + Find out a table definition from the dictionary and get + the current value of the auto increment field. Set a new + value to the auto increment field if the value is greater + than the maximum value in the column. */ if (((create_info->used_fields & HA_CREATE_USED_AUTO) || thd_sql_command(thd) == SQLCOM_ALTER_TABLE + || thd_sql_command(thd) == SQLCOM_OPTIMIZE || thd_sql_command(thd) == SQLCOM_CREATE_INDEX) && create_info->auto_increment_value > 0) { - /* Query was one of : - CREATE TABLE ...AUTO_INCREMENT = x; or - ALTER TABLE...AUTO_INCREMENT = x; or - CREATE INDEX x on t(...); - Find out a table definition from the dictionary and get - the current value of the auto increment field. Set a new - value to the auto increment field if the value is greater - than the maximum value in the column. */ - auto_inc_value = create_info->auto_increment_value; dict_table_autoinc_lock(innobase_table); diff --git a/storage/xtradb/handler/i_s.cc b/storage/xtradb/handler/i_s.cc index d90afc6dbc4..ca22375baba 100644 --- a/storage/xtradb/handler/i_s.cc +++ b/storage/xtradb/handler/i_s.cc @@ -1239,8 +1239,16 @@ fill_innodb_trx_from_cache( row->trx_mysql_thread_id)); /* trx_query */ - OK(field_store_string(fields[IDX_TRX_QUERY], - row->trx_query)); + if (row->trx_query) { + /* store will do appropriate character set + conversion check */ + fields[IDX_TRX_QUERY]->store( + row->trx_query, strlen(row->trx_query), + row->trx_query_cs); + fields[IDX_TRX_QUERY]->set_notnull(); + } else { + fields[IDX_TRX_QUERY]->set_null(); + } OK(schema_table_store_record(thd, table)); } @@ -1443,16 +1451,7 @@ fill_innodb_locks_from_cache( for (i = 0; i < rows_num; i++) { i_s_locks_row_t* row; - - /* note that the decoded database or table name is - never expected to be longer than NAME_LEN; - NAME_LEN for database name - 2 for surrounding quotes around database name - NAME_LEN for table name - 2 for surrounding quotes around table name - 1 for the separating dot (.) - 9 for the #mysql50# prefix */ - char buf[2 * NAME_LEN + 14]; + char buf[MAX_FULL_NAME_LEN + 1]; const char* bufend; char lock_trx_id[TRX_ID_MAX_LEN + 1]; diff --git a/storage/xtradb/include/btr0cur.h b/storage/xtradb/include/btr0cur.h index 1e1dc0f580a..b477ad0320a 100644 --- a/storage/xtradb/include/btr0cur.h +++ b/storage/xtradb/include/btr0cur.h @@ -332,10 +332,14 @@ ulint btr_cur_del_mark_set_clust_rec( /*===========================*/ ulint flags, /*!< in: undo logging and locking flags */ - btr_cur_t* cursor, /*!< in: cursor */ + buf_block_t* block, /*!< in/out: buffer block of the record */ + rec_t* rec, /*!< in/out: record */ + dict_index_t* index, /*!< in: clustered index of the record */ + const ulint* offsets,/*!< in: rec_get_offsets(rec) */ ibool val, /*!< in: value to set */ que_thr_t* thr, /*!< in: query thread */ - mtr_t* mtr); /*!< in: mtr */ + mtr_t* mtr) /*!< in: mtr */ + __attribute__((nonnull)); /***********************************************************//** Sets a secondary index record delete mark to TRUE or FALSE. @return DB_SUCCESS, DB_LOCK_WAIT, or error number */ @@ -481,40 +485,22 @@ btr_estimate_number_of_different_key_vals( /*======================================*/ dict_index_t* index); /*!< in: index */ /*******************************************************************//** -Marks not updated extern fields as not-owned by this record. The ownership -is transferred to the updated record which is inserted elsewhere in the +Marks non-updated off-page fields as disowned by this record. The ownership +must be transferred to the updated record which is inserted elsewhere in the index tree. In purge only the owner of externally stored field is allowed -to free the field. -@return TRUE if BLOB ownership was transferred */ +to free the field. */ UNIV_INTERN -ibool -btr_cur_mark_extern_inherited_fields( -/*=================================*/ +void +btr_cur_disown_inherited_fields( +/*============================*/ page_zip_des_t* page_zip,/*!< in/out: compressed page whose uncompressed part will be updated, or NULL */ rec_t* rec, /*!< in/out: record in a clustered index */ dict_index_t* index, /*!< in: index of the page */ const ulint* offsets,/*!< in: array returned by rec_get_offsets() */ const upd_t* update, /*!< in: update vector */ - mtr_t* mtr); /*!< in: mtr, or NULL if not logged */ -/*******************************************************************//** -The complement of the previous function: in an update entry may inherit -some externally stored fields from a record. We must mark them as inherited -in entry, so that they are not freed in a rollback. */ -UNIV_INTERN -void -btr_cur_mark_dtuple_inherited_extern( -/*=================================*/ - dtuple_t* entry, /*!< in/out: updated entry to be - inserted to clustered index */ - const upd_t* update); /*!< in: update vector */ -/*******************************************************************//** -Marks all extern fields in a dtuple as owned by the record. */ -UNIV_INTERN -void -btr_cur_unmark_dtuple_extern_fields( -/*================================*/ - dtuple_t* entry); /*!< in/out: clustered index entry */ + mtr_t* mtr) /*!< in/out: mini-transaction */ + __attribute__((nonnull(2,3,4,5,6))); /*******************************************************************//** Stores the fields in big_rec_vec to the tablespace and puts pointers to them in rec. The extern flags in rec will have to be set beforehand. diff --git a/storage/xtradb/include/data0data.h b/storage/xtradb/include/data0data.h index f9fce3f3657..cab8d790ac1 100644 --- a/storage/xtradb/include/data0data.h +++ b/storage/xtradb/include/data0data.h @@ -154,14 +154,19 @@ dfield_dup( dfield_t* field, /*!< in/out: data field */ mem_heap_t* heap); /*!< in: memory heap where allocated */ /*********************************************************************//** -Tests if data length and content is equal for two dfields. -@return TRUE if equal */ +Tests if two data fields are equal. +If len==0, tests the data length and content for equality. +If len>0, tests the first len bytes of the content for equality. +@return TRUE if both fields are NULL or if they are equal */ UNIV_INLINE ibool dfield_datas_are_binary_equal( /*==========================*/ const dfield_t* field1, /*!< in: field */ - const dfield_t* field2);/*!< in: field */ + const dfield_t* field2, /*!< in: field */ + ulint len) /*!< in: maximum prefix to compare, + or 0 to compare the whole field length */ + __attribute__((nonnull, warn_unused_result)); /*********************************************************************//** Tests if dfield data length and content is equal to the given. @return TRUE if equal */ diff --git a/storage/xtradb/include/data0data.ic b/storage/xtradb/include/data0data.ic index da79aa33702..74e0f7d09a0 100644 --- a/storage/xtradb/include/data0data.ic +++ b/storage/xtradb/include/data0data.ic @@ -229,20 +229,30 @@ dfield_dup( } /*********************************************************************//** -Tests if data length and content is equal for two dfields. -@return TRUE if equal */ +Tests if two data fields are equal. +If len==0, tests the data length and content for equality. +If len>0, tests the first len bytes of the content for equality. +@return TRUE if both fields are NULL or if they are equal */ UNIV_INLINE ibool dfield_datas_are_binary_equal( /*==========================*/ const dfield_t* field1, /*!< in: field */ - const dfield_t* field2) /*!< in: field */ + const dfield_t* field2, /*!< in: field */ + ulint len) /*!< in: maximum prefix to compare, + or 0 to compare the whole field length */ { - ulint len; + ulint len2 = len; - len = field1->len; + if (field1->len == UNIV_SQL_NULL || len == 0 || field1->len < len) { + len = field1->len; + } - return(len == field2->len + if (field2->len == UNIV_SQL_NULL || len2 == 0 || field2->len < len2) { + len2 = field2->len; + } + + return(len == len2 && (len == UNIV_SQL_NULL || !memcmp(field1->data, field2->data, len))); } diff --git a/storage/xtradb/include/row0upd.h b/storage/xtradb/include/row0upd.h index ea14cd64213..b61e6b6dca1 100644 --- a/storage/xtradb/include/row0upd.h +++ b/storage/xtradb/include/row0upd.h @@ -286,10 +286,13 @@ row_upd_changes_ord_field_binary( row and the data values in update are not known when this function is called, e.g., at compile time */ + const row_ext_t*ext, /*!< NULL, or prefixes of the externally + stored columns in the old row */ dict_index_t* index, /*!< in: index of the record */ - const upd_t* update);/*!< in: update vector for the row; NOTE: the + const upd_t* update) /*!< in: update vector for the row; NOTE: the field numbers in this MUST be clustered index positions! */ + __attribute__((nonnull(3,4), warn_unused_result)); /***********************************************************//** Checks if an update vector changes an ordering field of an index record. This function is fast if the update vector is short or the number of ordering @@ -462,11 +465,16 @@ struct upd_node_struct{ #define UPD_NODE_INSERT_CLUSTERED 3 /* clustered index record should be inserted, old record is already delete marked */ -#define UPD_NODE_UPDATE_ALL_SEC 4 /* an ordering field of the clustered +#define UPD_NODE_INSERT_BLOB 4 /* clustered index record should be + inserted, old record is already + delete-marked; non-updated BLOBs + should be inherited by the new record + and disowned by the old record */ +#define UPD_NODE_UPDATE_ALL_SEC 5 /* an ordering field of the clustered index record was changed, or this is a delete operation: should update all the secondary index records */ -#define UPD_NODE_UPDATE_SOME_SEC 5 /* secondary index entries should be +#define UPD_NODE_UPDATE_SOME_SEC 6 /* secondary index entries should be looked at and updated if an ordering field changed */ diff --git a/storage/xtradb/include/trx0i_s.h b/storage/xtradb/include/trx0i_s.h index 7bd4e1b88c8..48d41038ea4 100644 --- a/storage/xtradb/include/trx0i_s.h +++ b/storage/xtradb/include/trx0i_s.h @@ -110,6 +110,8 @@ struct i_s_trx_row_struct { /*!< thd_get_thread_id() */ const char* trx_query; /*!< MySQL statement being executed in the transaction */ + struct charset_info_st* trx_query_cs; /*!< charset encode the MySQL + statement */ }; /** This structure represents INFORMATION_SCHEMA.innodb_lock_waits row */ diff --git a/storage/xtradb/include/univ.i b/storage/xtradb/include/univ.i index 918ee221094..111bda1a3c5 100644 --- a/storage/xtradb/include/univ.i +++ b/storage/xtradb/include/univ.i @@ -46,7 +46,7 @@ Created 1/20/1994 Heikki Tuuri #define INNODB_VERSION_MAJOR 1 #define INNODB_VERSION_MINOR 0 -#define INNODB_VERSION_BUGFIX 14 +#define INNODB_VERSION_BUGFIX 15 #define PERCONA_INNODB_VERSION 12.5 /* The following is the InnoDB version as shown in @@ -303,6 +303,18 @@ number does not include a terminating '\0'. InnoDB probably can handle longer names internally */ #define MAX_TABLE_NAME_LEN 192 +/* The maximum length of a database name. Like MAX_TABLE_NAME_LEN this is +the MySQL's NAME_LEN, see check_and_convert_db_name(). */ +#define MAX_DATABASE_NAME_LEN MAX_TABLE_NAME_LEN + +/* MAX_FULL_NAME_LEN defines the full name path including the +database name and table name. In addition, 14 bytes is added for: + 2 for surrounding quotes around table name + 1 for the separating dot (.) + 9 for the #mysql50# prefix */ +#define MAX_FULL_NAME_LEN \ + (MAX_TABLE_NAME_LEN + MAX_DATABASE_NAME_LEN + 14) + /* UNIVERSAL TYPE DEFINITIONS ========================== diff --git a/storage/xtradb/include/ut0vec.h b/storage/xtradb/include/ut0vec.h index a770f671cfc..0f8b955b098 100644 --- a/storage/xtradb/include/ut0vec.h +++ b/storage/xtradb/include/ut0vec.h @@ -93,6 +93,25 @@ ib_vector_get( ib_vector_t* vec, /*!< in: vector */ ulint n); /*!< in: element index to get */ +/****************************************************************//** +Get last element. The vector must not be empty. +@return last element */ +UNIV_INLINE +void* +ib_vector_get_last( +/*===============*/ + ib_vector_t* vec); /*!< in: vector */ + +/****************************************************************//** +Set the n'th element. */ +UNIV_INLINE +void +ib_vector_set( +/*==========*/ + ib_vector_t* vec, /*!< in/out: vector */ + ulint n, /*!< in: element index to set */ + void* elem); /*!< in: data element */ + /****************************************************************//** Remove the last element from the vector. */ UNIV_INLINE diff --git a/storage/xtradb/include/ut0vec.ic b/storage/xtradb/include/ut0vec.ic index 02e881f9bca..34c858868ce 100644 --- a/storage/xtradb/include/ut0vec.ic +++ b/storage/xtradb/include/ut0vec.ic @@ -50,6 +50,35 @@ ib_vector_get( return(vec->data[n]); } +/****************************************************************//** +Get last element. The vector must not be empty. +@return last element */ +UNIV_INLINE +void* +ib_vector_get_last( +/*===============*/ + ib_vector_t* vec) /*!< in: vector */ +{ + ut_a(vec->used > 0); + + return(vec->data[vec->used - 1]); +} + +/****************************************************************//** +Set the n'th element. */ +UNIV_INLINE +void +ib_vector_set( +/*==========*/ + ib_vector_t* vec, /*!< in/out: vector */ + ulint n, /*!< in: element index to set */ + void* elem) /*!< in: data element */ +{ + ut_a(n < vec->used); + + vec->data[n] = elem; +} + /****************************************************************//** Remove the last element from the vector. @return last vector element */ diff --git a/storage/xtradb/lock/lock0lock.c b/storage/xtradb/lock/lock0lock.c index 1ded67d9147..4fcb5b2c522 100644 --- a/storage/xtradb/lock/lock0lock.c +++ b/storage/xtradb/lock/lock0lock.c @@ -3631,6 +3631,80 @@ lock_table_create( return(lock); } +/*************************************************************//** +Pops autoinc lock requests from the transaction's autoinc_locks. We +handle the case where there are gaps in the array and they need to +be popped off the stack. */ +UNIV_INLINE +void +lock_table_pop_autoinc_locks( +/*=========================*/ + trx_t* trx) /*!< in/out: transaction that owns the AUTOINC locks */ +{ + ut_ad(mutex_own(&kernel_mutex)); + ut_ad(!ib_vector_is_empty(trx->autoinc_locks)); + + /* Skip any gaps, gaps are NULL lock entries in the + trx->autoinc_locks vector. */ + + do { + ib_vector_pop(trx->autoinc_locks); + + if (ib_vector_is_empty(trx->autoinc_locks)) { + return; + } + + } while (ib_vector_get_last(trx->autoinc_locks) == NULL); +} + +/*************************************************************//** +Removes an autoinc lock request from the transaction's autoinc_locks. */ +UNIV_INLINE +void +lock_table_remove_autoinc_lock( +/*===========================*/ + lock_t* lock, /*!< in: table lock */ + trx_t* trx) /*!< in/out: transaction that owns the lock */ +{ + lock_t* autoinc_lock; + lint i = ib_vector_size(trx->autoinc_locks) - 1; + + ut_ad(mutex_own(&kernel_mutex)); + ut_ad(lock_get_mode(lock) == LOCK_AUTO_INC); + ut_ad(lock_get_type_low(lock) & LOCK_TABLE); + ut_ad(!ib_vector_is_empty(trx->autoinc_locks)); + + /* With stored functions and procedures the user may drop + a table within the same "statement". This special case has + to be handled by deleting only those AUTOINC locks that were + held by the table being dropped. */ + + autoinc_lock = ib_vector_get(trx->autoinc_locks, i); + + /* This is the default fast case. */ + + if (autoinc_lock == lock) { + lock_table_pop_autoinc_locks(trx); + } else { + /* The last element should never be NULL */ + ut_a(autoinc_lock != NULL); + + /* Handle freeing the locks from within the stack. */ + + while (--i >= 0) { + autoinc_lock = ib_vector_get(trx->autoinc_locks, i); + + if (UNIV_LIKELY(autoinc_lock == lock)) { + ib_vector_set(trx->autoinc_locks, i, NULL); + return; + } + } + + /* Must find the autoinc lock. */ + ut_error; + } +} + /*************************************************************//** Removes a table lock request from the queue and the trx list of locks; this is a low-level function which does NOT check if waiting requests @@ -3670,10 +3744,8 @@ lock_table_remove_low( if (!lock_get_wait(lock) && !ib_vector_is_empty(trx->autoinc_locks)) { - lock_t* autoinc_lock; - autoinc_lock = ib_vector_pop(trx->autoinc_locks); - ut_a(autoinc_lock == lock); + lock_table_remove_autoinc_lock(lock, trx); } ut_a(table->n_waiting_or_granted_auto_inc_locks > 0); diff --git a/storage/xtradb/log/log0recv.c b/storage/xtradb/log/log0recv.c index 5702f47ad5f..895067c700a 100644 --- a/storage/xtradb/log/log0recv.c +++ b/storage/xtradb/log/log0recv.c @@ -2260,7 +2260,7 @@ recv_report_corrupt_log( "InnoDB: far enough in recovery! Please run CHECK TABLE\n" "InnoDB: on your InnoDB tables to check that they are ok!\n" "InnoDB: If mysqld crashes after this recovery, look at\n" - "InnoDB: " REFMAN "forcing-recovery.html\n" + "InnoDB: " REFMAN "forcing-innodb-recovery.html\n" "InnoDB: about forcing recovery.\n", stderr); fflush(stderr); @@ -2968,9 +2968,10 @@ recv_recovery_from_checkpoint_start_func( #endif /* UNIV_LOG_ARCHIVE */ byte* buf; byte* log_hdr_buf; - byte log_hdr_buf_base[LOG_FILE_HDR_SIZE + OS_FILE_LOG_BLOCK_SIZE]; + byte *log_hdr_buf_base; ulint err; + log_hdr_buf_base= alloca(LOG_FILE_HDR_SIZE + OS_FILE_LOG_BLOCK_SIZE); log_hdr_buf = ut_align(log_hdr_buf_base, OS_FILE_LOG_BLOCK_SIZE); #ifdef UNIV_LOG_ARCHIVE diff --git a/storage/xtradb/plug.in b/storage/xtradb/plug.in index b68b59725d4..2e0c873094a 100644 --- a/storage/xtradb/plug.in +++ b/storage/xtradb/plug.in @@ -140,17 +140,24 @@ MYSQL_PLUGIN_ACTIONS(xtradb, [ ) AC_MSG_CHECKING(whether Solaris libc atomic functions are available) - # either define HAVE_IB_SOLARIS_ATOMICS or not - AC_CHECK_FUNCS(atomic_cas_ulong \ + # Define HAVE_IB_SOLARIS_ATOMICS if _all_ of the following + # functions are present. + AC_CHECK_FUNCS(atomic_add_long_nv \ atomic_cas_32 \ atomic_cas_64 \ - atomic_add_long_nv \ - atomic_swap_uchar, + atomic_cas_ulong \ + atomic_swap_uchar) - AC_DEFINE([HAVE_IB_SOLARIS_ATOMICS], [1], - [Define to 1 if Solaris libc atomic functions \ - are available]) - ) + if test "${ac_cv_func_atomic_add_long_nv}" = "yes" -a \ + "${ac_cv_func_atomic_cas_32}" = "yes" -a \ + "${ac_cv_func_atomic_cas_64}" = "yes" -a \ + "${ac_cv_func_atomic_cas_ulong}" = "yes" -a \ + "${ac_cv_func_atomic_swap_uchar}" = "yes" ; then + + AC_DEFINE([HAVE_IB_SOLARIS_ATOMICS], [1], + [Define to 1 if Solaris libc atomic functions are available] + ) + fi AC_MSG_CHECKING(whether pthread_t can be used by Solaris libc atomic functions) # either define HAVE_IB_ATOMIC_PTHREAD_T_SOLARIS or not diff --git a/storage/xtradb/row/row0merge.c b/storage/xtradb/row/row0merge.c index 402a168f5dd..782c029fbcc 100644 --- a/storage/xtradb/row/row0merge.c +++ b/storage/xtradb/row/row0merge.c @@ -2350,7 +2350,7 @@ row_merge_rename_tables( { ulint err = DB_ERROR; pars_info_t* info; - char old_name[MAX_TABLE_NAME_LEN + 1]; + char old_name[MAX_FULL_NAME_LEN + 1]; ut_ad(trx->mysql_thread_id == os_thread_get_curr_id()); ut_ad(old_table != new_table); @@ -2365,7 +2365,7 @@ row_merge_rename_tables( ut_print_timestamp(stderr); fprintf(stderr, "InnoDB: too long table name: '%s', " "max length is %d\n", old_table->name, - MAX_TABLE_NAME_LEN); + MAX_FULL_NAME_LEN); ut_error; } diff --git a/storage/xtradb/row/row0mysql.c b/storage/xtradb/row/row0mysql.c index 775ea222544..205aead8efe 100644 --- a/storage/xtradb/row/row0mysql.c +++ b/storage/xtradb/row/row0mysql.c @@ -574,7 +574,7 @@ handle_new_error: "InnoDB: If the mysqld server crashes" " after the startup or when\n" "InnoDB: you dump the tables, look at\n" - "InnoDB: " REFMAN "forcing-recovery.html" + "InnoDB: " REFMAN "forcing-innodb-recovery.html" " for help.\n", stderr); break; case DB_FOREIGN_EXCEED_MAX_CASCADE: diff --git a/storage/xtradb/row/row0purge.c b/storage/xtradb/row/row0purge.c index 31b255cf2d4..8bf2ae0f458 100644 --- a/storage/xtradb/row/row0purge.c +++ b/storage/xtradb/row/row0purge.c @@ -413,7 +413,7 @@ row_purge_upd_exist_or_extern( while (node->index != NULL) { index = node->index; - if (row_upd_changes_ord_field_binary(NULL, node->index, + if (row_upd_changes_ord_field_binary(NULL, NULL, node->index, node->update)) { /* Build the older version of the index entry */ entry = row_build_index_entry(node->row, NULL, diff --git a/storage/xtradb/row/row0umod.c b/storage/xtradb/row/row0umod.c index 5998dadd16d..562f8093c38 100644 --- a/storage/xtradb/row/row0umod.c +++ b/storage/xtradb/row/row0umod.c @@ -668,19 +668,18 @@ row_undo_mod_upd_exist_sec( while (node->index != NULL) { index = node->index; - if (row_upd_changes_ord_field_binary(node->row, node->index, - node->update)) { + if (row_upd_changes_ord_field_binary( + node->row, node->ext, node->index, node->update)) { /* Build the newest version of the index entry */ entry = row_build_index_entry(node->row, node->ext, index, heap); if (UNIV_UNLIKELY(!entry)) { /* The server must have crashed in - row_upd_clust_rec_by_insert(), in - row_ins_index_entry_low() before - btr_store_big_rec_extern_fields() - has written the externally stored columns - (BLOBs) of the new clustered index entry. */ + row_upd_clust_rec_by_insert() before + the updated externally stored columns (BLOBs) + of the new clustered index entry were + written. */ /* The table must be in DYNAMIC or COMPRESSED format. REDUNDANT and COMPACT formats diff --git a/storage/xtradb/row/row0upd.c b/storage/xtradb/row/row0upd.c index 0dc550b93f5..4aa1474a25b 100644 --- a/storage/xtradb/row/row0upd.c +++ b/storage/xtradb/row/row0upd.c @@ -1198,20 +1198,21 @@ row_upd_changes_ord_field_binary( row and the data values in update are not known when this function is called, e.g., at compile time */ + const row_ext_t*ext, /*!< NULL, or prefixes of the externally + stored columns in the old row */ dict_index_t* index, /*!< in: index of the record */ const upd_t* update) /*!< in: update vector for the row; NOTE: the field numbers in this MUST be clustered index positions! */ { - ulint n_unique; - ulint n_upd_fields; - ulint i, j; - dict_index_t* clust_index; + ulint n_unique; + ulint i; + const dict_index_t* clust_index; - ut_ad(update && index); + ut_ad(update); + ut_ad(index); n_unique = dict_index_get_n_unique(index); - n_upd_fields = upd_get_n_fields(update); clust_index = dict_table_get_first_index(index->table); @@ -1219,33 +1220,72 @@ row_upd_changes_ord_field_binary( const dict_field_t* ind_field; const dict_col_t* col; - ulint col_pos; ulint col_no; + const upd_field_t* upd_field; + const dfield_t* dfield; + dfield_t dfield_ext; + ulint dfield_len; + const byte* buf; ind_field = dict_index_get_nth_field(index, i); col = dict_field_get_col(ind_field); - col_pos = dict_col_get_clust_pos(col, clust_index); col_no = dict_col_get_no(col); - for (j = 0; j < n_upd_fields; j++) { + upd_field = upd_get_field_by_field_no( + update, dict_col_get_clust_pos(col, clust_index)); - const upd_field_t* upd_field - = upd_get_nth_field(update, j); + if (upd_field == NULL) { + continue; + } - /* Note that if the index field is a column prefix - then it may be that row does not contain an externally - stored part of the column value, and we cannot compare - the datas */ + if (row == NULL) { + ut_ad(ext == NULL); + return(TRUE); + } - if (col_pos == upd_field->field_no - && (row == NULL - || ind_field->prefix_len > 0 - || !dfield_datas_are_binary_equal( - dtuple_get_nth_field(row, col_no), - &(upd_field->new_val)))) { + dfield = dtuple_get_nth_field(row, col_no); - return(TRUE); + /* This treatment of column prefix indexes is loosely + based on row_build_index_entry(). */ + + if (UNIV_LIKELY(ind_field->prefix_len == 0) + || dfield_is_null(dfield)) { + /* do nothing special */ + } else if (UNIV_LIKELY_NULL(ext)) { + /* See if the column is stored externally. */ + buf = row_ext_lookup(ext, col_no, &dfield_len); + + ut_ad(col->ord_part); + + if (UNIV_LIKELY_NULL(buf)) { + if (UNIV_UNLIKELY(buf == field_ref_zero)) { + /* This should never happen, but + we try to fail safe here. */ + ut_ad(0); + return(TRUE); + } + + goto copy_dfield; } + } else if (dfield_is_ext(dfield)) { + dfield_len = dfield_get_len(dfield); + ut_a(dfield_len > BTR_EXTERN_FIELD_REF_SIZE); + dfield_len -= BTR_EXTERN_FIELD_REF_SIZE; + ut_a(dict_index_is_clust(index) + || ind_field->prefix_len <= dfield_len); + buf = dfield_get_data(dfield); +copy_dfield: + ut_a(dfield_len > 0); + dfield_copy(&dfield_ext, dfield); + dfield_set_data(&dfield_ext, buf, dfield_len); + dfield = &dfield_ext; + } + + if (!dfield_datas_are_binary_equal( + dfield, &upd_field->new_val, + ind_field->prefix_len)) { + + return(TRUE); } } @@ -1329,7 +1369,7 @@ row_upd_changes_first_fields_binary( if (col_pos == upd_field->field_no && !dfield_datas_are_binary_equal( dtuple_get_nth_field(entry, i), - &(upd_field->new_val))) { + &upd_field->new_val, 0)) { return(TRUE); } @@ -1568,14 +1608,99 @@ row_upd_sec_step( ut_ad(!dict_index_is_clust(node->index)); if (node->state == UPD_NODE_UPDATE_ALL_SEC - || row_upd_changes_ord_field_binary(node->row, node->index, - node->update)) { + || row_upd_changes_ord_field_binary(node->row, node->ext, + node->index, node->update)) { return(row_upd_sec_index_entry(node, thr)); } return(DB_SUCCESS); } +#ifdef UNIV_DEBUG +# define row_upd_clust_rec_by_insert_inherit(rec,offsets,entry,update) \ + row_upd_clust_rec_by_insert_inherit_func(rec,offsets,entry,update) +#else /* UNIV_DEBUG */ +# define row_upd_clust_rec_by_insert_inherit(rec,offsets,entry,update) \ + row_upd_clust_rec_by_insert_inherit_func(entry,update) +#endif /* UNIV_DEBUG */ +/*******************************************************************//** +Mark non-updated off-page columns inherited when the primary key is +updated. We must mark them as inherited in entry, so that they are not +freed in a rollback. A limited version of this function used to be +called btr_cur_mark_dtuple_inherited_extern(). +@return TRUE if any columns were inherited */ +static __attribute__((warn_unused_result)) +ibool +row_upd_clust_rec_by_insert_inherit_func( +/*=====================================*/ +#ifdef UNIV_DEBUG + const rec_t* rec, /*!< in: old record, or NULL */ + const ulint* offsets,/*!< in: rec_get_offsets(rec), or NULL */ +#endif /* UNIV_DEBUG */ + dtuple_t* entry, /*!< in/out: updated entry to be + inserted into the clustered index */ + const upd_t* update) /*!< in: update vector */ +{ + ibool inherit = FALSE; + ulint i; + + ut_ad(!rec == !offsets); + ut_ad(!rec || rec_offs_any_extern(offsets)); + + for (i = 0; i < dtuple_get_n_fields(entry); i++) { + dfield_t* dfield = dtuple_get_nth_field(entry, i); + byte* data; + ulint len; + + ut_ad(!offsets + || !rec_offs_nth_extern(offsets, i) + == !dfield_is_ext(dfield) + || upd_get_field_by_field_no(update, i)); + if (!dfield_is_ext(dfield) + || upd_get_field_by_field_no(update, i)) { + continue; + } + +#ifdef UNIV_DEBUG + if (UNIV_LIKELY(rec != NULL)) { + const byte* rec_data + = rec_get_nth_field(rec, offsets, i, &len); + ut_ad(len == dfield_get_len(dfield)); + ut_ad(len != UNIV_SQL_NULL); + ut_ad(len >= BTR_EXTERN_FIELD_REF_SIZE); + + rec_data += len - BTR_EXTERN_FIELD_REF_SIZE; + + /* The pointer must not be zero. */ + ut_ad(memcmp(rec_data, field_ref_zero, + BTR_EXTERN_FIELD_REF_SIZE)); + /* The BLOB must be owned. */ + ut_ad(!(rec_data[BTR_EXTERN_LEN] + & BTR_EXTERN_OWNER_FLAG)); + } +#endif /* UNIV_DEBUG */ + + len = dfield_get_len(dfield); + ut_a(len != UNIV_SQL_NULL); + ut_a(len >= BTR_EXTERN_FIELD_REF_SIZE); + data = dfield_get_data(dfield); + data += len - BTR_EXTERN_FIELD_REF_SIZE; + /* The pointer must not be zero. */ + ut_a(memcmp(data, field_ref_zero, BTR_EXTERN_FIELD_REF_SIZE)); + /* The BLOB must be owned. */ + ut_a(!(data[BTR_EXTERN_LEN] & BTR_EXTERN_OWNER_FLAG)); + + data[BTR_EXTERN_LEN] |= BTR_EXTERN_INHERITED_FLAG; + /* The BTR_EXTERN_INHERITED_FLAG only matters in + rollback. Purge will always free the extern fields of + a delete-marked row. */ + + inherit = TRUE; + } + + return(inherit); +} + /***********************************************************//** Marks the clustered index record deleted and inserts the updated version of the record to the index. This function should be used when the ordering @@ -1594,14 +1719,16 @@ row_upd_clust_rec_by_insert( a foreign key constraint */ mtr_t* mtr) /*!< in/out: mtr; gets committed here */ { - mem_heap_t* heap = NULL; + mem_heap_t* heap; btr_pcur_t* pcur; btr_cur_t* btr_cur; trx_t* trx; dict_table_t* table; dtuple_t* entry; ulint err; - ibool change_ownership = FALSE; + ibool change_ownership = FALSE; + rec_t* rec; + ulint* offsets = NULL; ut_ad(node); ut_ad(dict_index_is_clust(index)); @@ -1611,53 +1738,7 @@ row_upd_clust_rec_by_insert( pcur = node->pcur; btr_cur = btr_pcur_get_btr_cur(pcur); - if (node->state != UPD_NODE_INSERT_CLUSTERED) { - rec_t* rec; - dict_index_t* index; - ulint offsets_[REC_OFFS_NORMAL_SIZE]; - ulint* offsets; - rec_offs_init(offsets_); - - err = btr_cur_del_mark_set_clust_rec(BTR_NO_LOCKING_FLAG, - btr_cur, TRUE, thr, mtr); - if (err != DB_SUCCESS) { - mtr_commit(mtr); - return(err); - } - - /* Mark as not-owned the externally stored fields which the new - row inherits from the delete marked record: purge should not - free those externally stored fields even if the delete marked - record is removed from the index tree, or updated. */ - - rec = btr_cur_get_rec(btr_cur); - index = dict_table_get_first_index(table); - offsets = rec_get_offsets(rec, index, offsets_, - ULINT_UNDEFINED, &heap); - change_ownership = btr_cur_mark_extern_inherited_fields( - btr_cur_get_page_zip(btr_cur), rec, index, offsets, - node->update, mtr); - if (check_ref) { - /* NOTE that the following call loses - the position of pcur ! */ - err = row_upd_check_references_constraints( - node, pcur, table, index, offsets, thr, mtr); - if (err != DB_SUCCESS) { - mtr_commit(mtr); - if (UNIV_LIKELY_NULL(heap)) { - mem_heap_free(heap); - } - return(err); - } - } - } - - mtr_commit(mtr); - - if (!heap) { - heap = mem_heap_create(500); - } - node->state = UPD_NODE_INSERT_CLUSTERED; + heap = mem_heap_create(1000); entry = row_build_index_entry(node->upd_row, node->upd_ext, index, heap); @@ -1665,23 +1746,104 @@ row_upd_clust_rec_by_insert( row_upd_index_entry_sys_field(entry, index, DATA_TRX_ID, trx->id); - if (change_ownership) { - /* If we return from a lock wait, for example, we may have - extern fields marked as not-owned in entry (marked in the - if-branch above). We must unmark them, take the ownership - back. */ + switch (node->state) { + default: + ut_error; + case UPD_NODE_INSERT_BLOB: + /* A lock wait occurred in row_ins_index_entry() in + the previous invocation of this function. Mark the + off-page columns in the entry inherited. */ - btr_cur_unmark_dtuple_extern_fields(entry); + change_ownership = row_upd_clust_rec_by_insert_inherit( + NULL, NULL, entry, node->update); + ut_a(change_ownership); + /* fall through */ + case UPD_NODE_INSERT_CLUSTERED: + /* A lock wait occurred in row_ins_index_entry() in + the previous invocation of this function. */ + break; + case UPD_NODE_UPDATE_CLUSTERED: + /* This is the first invocation of the function where + we update the primary key. Delete-mark the old record + in the clustered index and prepare to insert a new entry. */ + rec = btr_cur_get_rec(btr_cur); + offsets = rec_get_offsets(rec, index, NULL, + ULINT_UNDEFINED, &heap); + ut_ad(page_rec_is_user_rec(rec)); - /* We must mark non-updated extern fields in entry as - inherited, so that a possible rollback will not free them. */ + err = btr_cur_del_mark_set_clust_rec( + BTR_NO_LOCKING_FLAG, btr_cur_get_block(btr_cur), + rec, index, offsets, TRUE, thr, mtr); + if (err != DB_SUCCESS) { +err_exit: + mtr_commit(mtr); + mem_heap_free(heap); + return(err); + } - btr_cur_mark_dtuple_inherited_extern(entry, node->update); + /* If the the new row inherits externally stored + fields (off-page columns a.k.a. BLOBs) from the + delete-marked old record, mark them disowned by the + old record and owned by the new entry. */ + + if (rec_offs_any_extern(offsets)) { + change_ownership = row_upd_clust_rec_by_insert_inherit( + rec, offsets, entry, node->update); + + if (change_ownership) { + btr_pcur_store_position(pcur, mtr); + } + } + + if (check_ref) { + /* NOTE that the following call loses + the position of pcur ! */ + err = row_upd_check_references_constraints( + node, pcur, table, index, offsets, thr, mtr); + if (err != DB_SUCCESS) { + goto err_exit; + } + } } + mtr_commit(mtr); + err = row_ins_index_entry(index, entry, node->upd_ext ? node->upd_ext->n_ext : 0, TRUE, thr); + node->state = change_ownership + ? UPD_NODE_INSERT_BLOB + : UPD_NODE_INSERT_CLUSTERED; + + if (err == DB_SUCCESS && change_ownership) { + /* Mark the non-updated fields disowned by the old record. */ + + /* NOTE: this transaction has an x-lock on the record + and therefore other transactions cannot modify the + record when we have no latch on the page. In addition, + we assume that other query threads of the same + transaction do not modify the record in the meantime. + Therefore we can assert that the restoration of the + cursor succeeds. */ + + mtr_start(mtr); + + if (!btr_pcur_restore_position(BTR_MODIFY_LEAF, pcur, mtr)) { + ut_error; + } + + rec = btr_cur_get_rec(btr_cur); + offsets = rec_get_offsets(rec, index, offsets, + ULINT_UNDEFINED, &heap); + ut_ad(page_rec_is_user_rec(rec)); + + btr_cur_disown_inherited_fields( + btr_cur_get_page_zip(btr_cur), + rec, index, offsets, node->update, mtr); + + mtr_commit(mtr); + } + mem_heap_free(heap); return(err); @@ -1825,8 +1987,9 @@ row_upd_del_mark_clust_rec( /* Mark the clustered index record deleted; we do not have to check locks, because we assume that we have an x-lock on the record */ - err = btr_cur_del_mark_set_clust_rec(BTR_NO_LOCKING_FLAG, - btr_cur, TRUE, thr, mtr); + err = btr_cur_del_mark_set_clust_rec( + BTR_NO_LOCKING_FLAG, btr_cur_get_block(btr_cur), + btr_cur_get_rec(btr_cur), index, offsets, TRUE, thr, mtr); if (err == DB_SUCCESS && check_ref) { /* NOTE that the following call loses the position of pcur ! */ @@ -1973,7 +2136,8 @@ exit_func: row_upd_store_row(node); - if (row_upd_changes_ord_field_binary(node->row, index, node->update)) { + if (row_upd_changes_ord_field_binary(node->row, node->ext, index, + node->update)) { /* Update causes an ordering field (ordering fields within the B-tree) of the clustered index record to change: perform @@ -2042,7 +2206,8 @@ row_upd( } if (node->state == UPD_NODE_UPDATE_CLUSTERED - || node->state == UPD_NODE_INSERT_CLUSTERED) { + || node->state == UPD_NODE_INSERT_CLUSTERED + || node->state == UPD_NODE_INSERT_BLOB) { log_free_check(); err = row_upd_clust_step(node, thr); diff --git a/storage/xtradb/trx/trx0i_s.c b/storage/xtradb/trx/trx0i_s.c index c11ebb6397e..e148234888b 100644 --- a/storage/xtradb/trx/trx0i_s.c +++ b/storage/xtradb/trx/trx0i_s.c @@ -431,7 +431,7 @@ i_s_locks_row_validate( /* record lock */ ut_ad(!strcmp("RECORD", row->lock_type)); ut_ad(row->lock_index != NULL); - ut_ad(row->lock_data != NULL); + /* row->lock_data == NULL if buf_page_try_get() == NULL */ ut_ad(row->lock_page != ULINT_UNDEFINED); ut_ad(row->lock_rec != ULINT_UNDEFINED); } @@ -494,7 +494,6 @@ fill_trx_row( stmt = innobase_get_stmt(trx->mysql_thd, &stmt_len); if (stmt != NULL) { - char query[TRX_I_S_TRX_QUERY_MAX_LEN + 1]; if (stmt_len > TRX_I_S_TRX_QUERY_MAX_LEN) { @@ -508,6 +507,8 @@ fill_trx_row( cache->storage, stmt, stmt_len + 1, MAX_ALLOWED_FOR_STORAGE(cache)); + row->trx_query_cs = innobase_get_charset(trx->mysql_thd); + if (row->trx_query == NULL) { return(FALSE); diff --git a/storage/xtradb/ut/ut0dbg.c b/storage/xtradb/ut/ut0dbg.c index 4484e6c36de..7839466e16f 100644 --- a/storage/xtradb/ut/ut0dbg.c +++ b/storage/xtradb/ut/ut0dbg.c @@ -79,7 +79,7 @@ ut_dbg_assertion_failed( " or crashes, even\n" "InnoDB: immediately after the mysqld startup, there may be\n" "InnoDB: corruption in the InnoDB tablespace. Please refer to\n" - "InnoDB: " REFMAN "forcing-recovery.html\n" + "InnoDB: " REFMAN "forcing-innodb-recovery.html\n" "InnoDB: about forcing recovery.\n", stderr); #if defined(UNIV_SYNC_DEBUG) || !defined(UT_DBG_USE_ABORT) ut_dbg_stop_threads = TRUE;