diff options
author | Marko Mäkelä <marko.makela@mariadb.com> | 2022-11-08 17:01:28 +0200 |
---|---|---|
committer | Marko Mäkelä <marko.makela@mariadb.com> | 2022-11-08 17:01:28 +0200 |
commit | a732d5e2ba3d63a08e20670535d4cd29f667daf0 (patch) | |
tree | 692f6d95ded214a3cbf1e259f4f58dac67d37eea | |
parent | fe330b63fe4ee51a26ac6e222d8eb4ee44a73d50 (diff) | |
parent | 8fb176c3c1c71516f0562399d055e92686519588 (diff) | |
download | mariadb-git-a732d5e2ba3d63a08e20670535d4cd29f667daf0.tar.gz |
Merge 10.4 into 10.5
47 files changed, 476 insertions, 480 deletions
diff --git a/extra/mariabackup/xtrabackup.cc b/extra/mariabackup/xtrabackup.cc index 03b8a1d3ea5..3f7dec5ceda 100644 --- a/extra/mariabackup/xtrabackup.cc +++ b/extra/mariabackup/xtrabackup.cc @@ -3736,10 +3736,6 @@ static dberr_t xb_assign_undo_space_start() int n_retries = 5; ulint fsp_flags; - if (srv_undo_tablespaces == 0) { - return error; - } - file = os_file_create(0, srv_sys_space.first_datafile()->filepath(), OS_FILE_OPEN, OS_FILE_NORMAL, OS_DATA_FILE, true, &ret); diff --git a/include/my_alarm.h b/include/my_alarm.h index df5cb7f51de..652b460cba3 100644 --- a/include/my_alarm.h +++ b/include/my_alarm.h @@ -31,7 +31,10 @@ extern ulong my_time_to_wait_for_lock; #include <signal.h> #ifdef HAVE_SIGHANDLER_T #define sig_return sighandler_t -#elif defined(SOLARIS) || defined(__sun) || defined(__APPLE__) || defined(__FreeBSD__) || defined(_AIX) +#elif defined(SOLARIS) || defined(__sun) || defined(__APPLE__) || \ + defined(_AIX) || \ + defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) || \ + defined(__DragonFly__) typedef void (*sig_return)(int); /* Returns type from signal */ #else typedef void (*sig_return)(void); /* Returns type from signal */ diff --git a/man/mysqld_safe.1 b/man/mysqld_safe.1 index a995d61dca1..06e3dbdee0b 100644 --- a/man/mysqld_safe.1 +++ b/man/mysqld_safe.1 @@ -340,7 +340,9 @@ program to set the server\'s scheduling priority to the given value\&. .\} .\" mysqld_safe: no-auto-restart option .\" no-auto-restart option: mysqld_safe -\fB\-\-no\-auto\-restart\fR +\fB\-\-no\-auto\-restart\fR, +\fB\-\-nowatch\fR, +\fB\-\-no\-watch\fR .sp Exit after starting mysqld\&. .RE @@ -368,21 +370,6 @@ Do not read any option files\&. This must be the first option on the command lin .sp -1 .IP \(bu 2.3 .\} -.\" mysqld_safe: no-watch option -.\" no-watch option: mysqld_safe -\fB\-\-no\-auto\-restart\fR -.sp -Exit after starting mysqld\&. -.RE -.sp -.RS 4 -.ie n \{\ -\h'-04'\(bu\h'+03'\c -.\} -.el \{\ -.sp -1 -.IP \(bu 2.3 -.\} .\" mysqld_safe: numa-interleave option .\" numa-interleave option: mysqld_safe \fB\-\-numa\-interleave\fR diff --git a/mysql-test/include/rowid_filter_debug_kill.inc b/mysql-test/include/rowid_filter_debug_kill.inc index c701d206297..513efed8a4c 100644 --- a/mysql-test/include/rowid_filter_debug_kill.inc +++ b/mysql-test/include/rowid_filter_debug_kill.inc @@ -1,17 +1,14 @@ --source include/have_debug.inc --source include/have_debug_sync.inc +--source include/have_sequence.inc --source include/count_sessions.inc --echo # --echo # MDEV-22761 KILL QUERY during rowid_filter, crashes --echo # -create table t0(a int); -insert into t0 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9); - -# 100 rows create table t2(a int); -insert into t2 select A.a + B.a* 10 from t0 A, t0 B; +insert into t2 select * from seq_0_to_99; # 10K rows CREATE TABLE t3 ( @@ -26,11 +23,10 @@ where table_schema=database() and table_name='t3'; insert into t3 select - A.a, - B.a, + A.seq, + B.seq, 'filler-data-filler-data' -from - t2 A, t2 B; +from seq_0_to_99 A, seq_0_to_99 B; analyze table t2,t3; @@ -48,7 +44,6 @@ where t3.key1=t2.a and t3.key2 in (2,3); connect (con1, localhost, root,,); -connection con1; set debug_sync='now WAIT_FOR at_rowid_filter_check'; evalp kill query $target_id; set debug_sync='now SIGNAL go'; @@ -60,6 +55,5 @@ disconnect con1; reap; set debug_sync='RESET'; -drop table t0,t2,t3; +drop table t2,t3; --source include/wait_until_count_sessions.inc - diff --git a/mysql-test/main/long_unique_bugs.result b/mysql-test/main/long_unique_bugs.result index 1b59c0f2ea0..4b47deee7f1 100644 --- a/mysql-test/main/long_unique_bugs.result +++ b/mysql-test/main/long_unique_bugs.result @@ -315,6 +315,15 @@ ERROR 23000: Duplicate entry '1' for key 'v2' update t1,t2 set v1 = v2 , v5 = 0; ERROR 23000: Duplicate entry '-128' for key 'v1' drop table t1, t2; +CREATE TABLE t1 (f TEXT UNIQUE); +INSERT INTO t1 VALUES (NULL),(NULL); +UPDATE t1 SET f = ''; +ERROR 23000: Duplicate entry '' for key 'f' +SELECT * FROM t1; +f + +NULL +DROP TABLE t1; # # MDEV-21540 Initialization of already inited long unique index on reorganize partition # diff --git a/mysql-test/main/long_unique_bugs.test b/mysql-test/main/long_unique_bugs.test index e313d1d434e..f2160bb7f68 100644 --- a/mysql-test/main/long_unique_bugs.test +++ b/mysql-test/main/long_unique_bugs.test @@ -397,6 +397,17 @@ update t1 set v2 = 1, v3 = -128; update t1,t2 set v1 = v2 , v5 = 0; drop table t1, t2; +# +# MDEV-23264 Unique blobs allow duplicate values upon UPDATE +# + +CREATE TABLE t1 (f TEXT UNIQUE); +INSERT INTO t1 VALUES (NULL),(NULL); +--error ER_DUP_ENTRY +UPDATE t1 SET f = ''; +SELECT * FROM t1; +DROP TABLE t1; + --echo # --echo # MDEV-21540 Initialization of already inited long unique index on reorganize partition --echo # diff --git a/mysql-test/main/order_by_innodb.result b/mysql-test/main/order_by_innodb.result index 28922ef65f2..17d39eb12e6 100644 --- a/mysql-test/main/order_by_innodb.result +++ b/mysql-test/main/order_by_innodb.result @@ -1,8 +1,8 @@ -drop table if exists t0,t1,t2,t3; # # MDEV-6434: Wrong result (extra rows) with ORDER BY, multiple-column index, InnoDB # -CREATE TABLE t1 (a INT, b INT, c INT, d TEXT, KEY idx(a,b,c)) ENGINE=InnoDB; +CREATE TABLE t1 (a INT, b INT, c INT, d TEXT, KEY idx(a,b,c)) ENGINE=InnoDB +STATS_PERSISTENT=0; INSERT INTO t1 (a,c) VALUES (8, 9),(8, 10),(13, 15),(16, 17),(16, 18),(16, 19),(20, 21), (20, 22),(20, 24),(20, 25),(20, 26),(20, 27),(20, 28); @@ -14,8 +14,6 @@ DROP TABLE t1; # # MDEV-9457: Poor query plan chosen for ORDER BY query by a recent 10.1 # -create table t0 (a int); -insert into t0 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9); create table t1 ( pk int primary key, key1 int, @@ -23,15 +21,9 @@ key2 int, col1 char(255), key(key1), key(key2) -) engine=innodb; -set @a=-1; +) engine=innodb stats_persistent=0; insert into t1 -select -@a:=@a+1, -@a, -@a, -repeat('abcd', 63) -from t0 A, t0 B, t0 C, t0 D; +select seq,seq,seq,repeat('abcd', 63) from seq_0_to_9999; # The following must NOT use 'index' on PK. # It should use index_merge(key1,key2) + filesort explain @@ -47,7 +39,7 @@ from t1 where key1<3 or key2<3; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 index_merge key1,key2 key1,key2 5,5 NULL # Using sort_union(key1,key2); Using where -drop table t0, t1; +drop table t1; # # MDEV-18094: Query with order by limit picking index scan over filesort # @@ -78,9 +70,12 @@ drop table t1,t0; # MDEV-14071: wrong results with orderby_uses_equalities=on # (duplicate of MDEV-13994) # -CREATE TABLE t1 (i int, j int, z int,PRIMARY KEY (i,j), KEY (z)) ENGINE=InnoDB; -CREATE TABLE t2 (i int, j int, PRIMARY KEY (i,j)) ENGINE=InnoDB; -CREATE TABLE t3 (j int, n varchar(5), PRIMARY KEY (j)) ENGINE=InnoDB; +CREATE TABLE t1 (i int, j int, z int,PRIMARY KEY (i,j), KEY (z)) ENGINE=InnoDB +STATS_PERSISTENT=0; +CREATE TABLE t2 (i int, j int, PRIMARY KEY (i,j)) ENGINE=InnoDB +STATS_PERSISTENT=0; +CREATE TABLE t3 (j int, n varchar(5), PRIMARY KEY (j)) ENGINE=InnoDB +STATS_PERSISTENT=0; INSERT INTO t1 VALUES (127,0,1),(188,0,1),(206,0,1),(218,0,1),(292,0,1),(338,0,1),(375,0,1), (381,0,1),(409,0,1),(466,0,1),(469,0,1),(498,0,1),(656,0,1); @@ -150,7 +145,8 @@ DROP TABLE t1,t2,t3; # # MDEV-25858: Query results are incorrect when indexes are added # -CREATE TABLE t1 (id int NOT NULL PRIMARY KEY) engine=innodb; +CREATE TABLE t1 (id int NOT NULL PRIMARY KEY) engine=innodb +STATS_PERSISTENT=0; insert into t1 values (1),(2),(3); CREATE TABLE t2 ( id int NOT NULL PRIMARY KEY, diff --git a/mysql-test/main/order_by_innodb.test b/mysql-test/main/order_by_innodb.test index af12644c073..29b796f67bc 100644 --- a/mysql-test/main/order_by_innodb.test +++ b/mysql-test/main/order_by_innodb.test @@ -2,16 +2,14 @@ # ORDER BY handling (e.g. filesort) tests that require innodb # -- source include/have_innodb.inc - ---disable_warnings -drop table if exists t0,t1,t2,t3; ---enable_warnings +-- source include/have_sequence.inc --echo # --echo # MDEV-6434: Wrong result (extra rows) with ORDER BY, multiple-column index, InnoDB --echo # -CREATE TABLE t1 (a INT, b INT, c INT, d TEXT, KEY idx(a,b,c)) ENGINE=InnoDB; +CREATE TABLE t1 (a INT, b INT, c INT, d TEXT, KEY idx(a,b,c)) ENGINE=InnoDB +STATS_PERSISTENT=0; INSERT INTO t1 (a,c) VALUES (8, 9),(8, 10),(13, 15),(16, 17),(16, 18),(16, 19),(20, 21), @@ -24,9 +22,6 @@ DROP TABLE t1; --echo # --echo # MDEV-9457: Poor query plan chosen for ORDER BY query by a recent 10.1 --echo # -create table t0 (a int); -insert into t0 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9); - create table t1 ( pk int primary key, key1 int, @@ -34,16 +29,10 @@ create table t1 ( col1 char(255), key(key1), key(key2) -) engine=innodb; +) engine=innodb stats_persistent=0; -set @a=-1; insert into t1 -select - @a:=@a+1, - @a, - @a, - repeat('abcd', 63) -from t0 A, t0 B, t0 C, t0 D; +select seq,seq,seq,repeat('abcd', 63) from seq_0_to_9999; --echo # The following must NOT use 'index' on PK. --echo # It should use index_merge(key1,key2) + filesort @@ -60,7 +49,7 @@ select * from t1 where key1<3 or key2<3; -drop table t0, t1; +drop table t1; --echo # --echo # MDEV-18094: Query with order by limit picking index scan over filesort @@ -93,9 +82,12 @@ drop table t1,t0; --echo # (duplicate of MDEV-13994) --echo # -CREATE TABLE t1 (i int, j int, z int,PRIMARY KEY (i,j), KEY (z)) ENGINE=InnoDB; -CREATE TABLE t2 (i int, j int, PRIMARY KEY (i,j)) ENGINE=InnoDB; -CREATE TABLE t3 (j int, n varchar(5), PRIMARY KEY (j)) ENGINE=InnoDB; +CREATE TABLE t1 (i int, j int, z int,PRIMARY KEY (i,j), KEY (z)) ENGINE=InnoDB +STATS_PERSISTENT=0; +CREATE TABLE t2 (i int, j int, PRIMARY KEY (i,j)) ENGINE=InnoDB +STATS_PERSISTENT=0; +CREATE TABLE t3 (j int, n varchar(5), PRIMARY KEY (j)) ENGINE=InnoDB +STATS_PERSISTENT=0; INSERT INTO t1 VALUES (127,0,1),(188,0,1),(206,0,1),(218,0,1),(292,0,1),(338,0,1),(375,0,1), @@ -139,7 +131,8 @@ DROP TABLE t1,t2,t3; --echo # MDEV-25858: Query results are incorrect when indexes are added --echo # -CREATE TABLE t1 (id int NOT NULL PRIMARY KEY) engine=innodb; +CREATE TABLE t1 (id int NOT NULL PRIMARY KEY) engine=innodb +STATS_PERSISTENT=0; insert into t1 values (1),(2),(3); CREATE TABLE t2 ( diff --git a/mysql-test/main/range_innodb.result b/mysql-test/main/range_innodb.result index 1d98fad0295..e7792fec0ff 100644 --- a/mysql-test/main/range_innodb.result +++ b/mysql-test/main/range_innodb.result @@ -1,15 +1,11 @@ # # Range optimizer (and related) tests that need InnoDB. # -drop table if exists t0, t1, t2; # # MDEV-6735: Range checked for each record used with key # create table t0(a int); insert into t0 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9); -create table t1(a int); -insert into t1 select A.a + B.a* 10 + C.a * 100 + D.a * 1000 -from t0 A, t0 B, t0 C, t0 D; create table t2 ( a int, b int, @@ -22,12 +18,12 @@ key(b) ) engine=innodb; insert into t2 select -a,a, +seq,seq, repeat('0123456789', 10), repeat('0123456789', 10), repeat('0123456789', 10), repeat('0123456789', 10) -from t1; +from seq_0_to_9999; analyze table t2; Table Op Msg_type Msg_text test.t2 analyze status Engine-independent statistics collected @@ -37,7 +33,7 @@ explain select * from t0 left join t2 on t2.a <t0.a and t2.b between 50 and 250; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t0 ALL NULL NULL NULL NULL 10 1 SIMPLE t2 range a,b b 5 NULL 201 Using where; Using join buffer (flat, BNL join) -drop table t0,t1,t2; +drop table t0,t2; # # MDEV-10466: constructing an invalid SEL_ARG # @@ -89,15 +85,14 @@ drop table t1,t2; # set @optimizer_switch_save= @@optimizer_switch; set optimizer_switch='index_merge_sort_intersection=off'; -create table t0 (a int)engine=innodb; +create table t0(a int); insert into t0 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9); create table t1 ( a int, b int, c int, key(a),key(b),key(c) )engine=innodb; insert into t1 -select A.a+10*B.a, A.a+10*B.a, A.a+10*B.a+100*C.a -from t0 A, t0 B, t0 C, t0 D where D.a<5; +select a.seq/10, a.seq/10, a.seq from seq_0_to_499 a, seq_0_to_4 b; SET @saved_dbug = @@GLOBAL.debug_dbug; set @@global.debug_dbug="+d,ha_index_init_fail"; explain select * from t1 where a=10 and b=10; diff --git a/mysql-test/main/range_innodb.test b/mysql-test/main/range_innodb.test index a9fef01b941..cf342c90bb8 100644 --- a/mysql-test/main/range_innodb.test +++ b/mysql-test/main/range_innodb.test @@ -4,12 +4,9 @@ --source include/have_innodb.inc --source include/have_debug.inc +--source include/have_sequence.inc --source include/no_valgrind_without_big.inc ---disable_warnings -drop table if exists t0, t1, t2; ---enable_warnings - --echo # --echo # MDEV-6735: Range checked for each record used with key --echo # @@ -17,10 +14,6 @@ drop table if exists t0, t1, t2; create table t0(a int); insert into t0 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9); -create table t1(a int); -insert into t1 select A.a + B.a* 10 + C.a * 100 + D.a * 1000 -from t0 A, t0 B, t0 C, t0 D; - create table t2 ( a int, b int, @@ -34,18 +27,18 @@ create table t2 ( insert into t2 select - a,a, + seq,seq, repeat('0123456789', 10), repeat('0123456789', 10), repeat('0123456789', 10), repeat('0123456789', 10) -from t1; +from seq_0_to_9999; analyze table t2; --echo # The following must not use "Range checked for each record": explain select * from t0 left join t2 on t2.a <t0.a and t2.b between 50 and 250; -drop table t0,t1,t2; +drop table t0,t2; --echo # @@ -98,15 +91,14 @@ drop table t1,t2; set @optimizer_switch_save= @@optimizer_switch; set optimizer_switch='index_merge_sort_intersection=off'; -create table t0 (a int)engine=innodb; +create table t0(a int); insert into t0 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9); create table t1 ( a int, b int, c int, key(a),key(b),key(c) )engine=innodb; insert into t1 -select A.a+10*B.a, A.a+10*B.a, A.a+10*B.a+100*C.a -from t0 A, t0 B, t0 C, t0 D where D.a<5; +select a.seq/10, a.seq/10, a.seq from seq_0_to_499 a, seq_0_to_4 b; SET @saved_dbug = @@GLOBAL.debug_dbug; set @@global.debug_dbug="+d,ha_index_init_fail"; explain select * from t1 where a=10 and b=10; @@ -122,8 +114,6 @@ set @@optimizer_switch= @optimizer_switch_save; --echo # MDEV-27262: Index intersection with full scan over an index --echo # ---source include/have_sequence.inc - CREATE TABLE t1 ( id int(10) unsigned NOT NULL AUTO_INCREMENT, p char(32) DEFAULT NULL, diff --git a/mysql-test/main/rowid_filter_innodb_debug.result b/mysql-test/main/rowid_filter_innodb_debug.result index 56226fe25ce..5a3fa374bd1 100644 --- a/mysql-test/main/rowid_filter_innodb_debug.result +++ b/mysql-test/main/rowid_filter_innodb_debug.result @@ -2,10 +2,8 @@ set default_storage_engine=innodb; # # MDEV-22761 KILL QUERY during rowid_filter, crashes # -create table t0(a int); -insert into t0 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9); create table t2(a int); -insert into t2 select A.a + B.a* 10 from t0 A, t0 B; +insert into t2 select * from seq_0_to_99; CREATE TABLE t3 ( key1 int , key2 int, @@ -19,11 +17,10 @@ engine InnoDB insert into t3 select -A.a, -B.a, +A.seq, +B.seq, 'filler-data-filler-data' -from -t2 A, t2 B; +from seq_0_to_99 A, seq_0_to_99 B; analyze table t2,t3; Table Op Msg_type Msg_text test.t2 analyze status Engine-independent statistics collected @@ -42,7 +39,6 @@ select * from t2, t3 where t3.key1=t2.a and t3.key2 in (2,3); connect con1, localhost, root,,; -connection con1; set debug_sync='now WAIT_FOR at_rowid_filter_check'; kill query $target_id; set debug_sync='now SIGNAL go'; @@ -50,7 +46,7 @@ connection default; disconnect con1; ERROR 70100: Query execution was interrupted set debug_sync='RESET'; -drop table t0,t2,t3; +drop table t2,t3; set default_storage_engine=default; set @save_optimizer_switch= @@optimizer_switch; set @save_use_stat_tables= @@use_stat_tables; @@ -67,7 +63,6 @@ INSERT INTO t1 VALUES (0,0),(1,0),(-1,1), (-2,1), (-2,3), (-3,4), (-2,4); set debug_sync='handler_rowid_filter_check SIGNAL killme WAIT_FOR go'; SELECT * FROM t1 WHERE a > 0 AND b=0; connect con1, localhost, root,,; -connection con1; set debug_sync='now WAIT_FOR killme'; kill query @id; set debug_sync='now SIGNAL go'; diff --git a/mysql-test/main/rowid_filter_innodb_debug.test b/mysql-test/main/rowid_filter_innodb_debug.test index 31fbd937304..f89a2a82da8 100644 --- a/mysql-test/main/rowid_filter_innodb_debug.test +++ b/mysql-test/main/rowid_filter_innodb_debug.test @@ -31,7 +31,6 @@ set debug_sync='handler_rowid_filter_check SIGNAL killme WAIT_FOR go'; send SELECT * FROM t1 WHERE a > 0 AND b=0; connect (con1, localhost, root,,); -connection con1; let $ignore= `SELECT @id := $ID`; set debug_sync='now WAIT_FOR killme'; kill query @id; diff --git a/mysql-test/main/rowid_filter_myisam_debug.result b/mysql-test/main/rowid_filter_myisam_debug.result index 32a989f50da..75a8fad6947 100644 --- a/mysql-test/main/rowid_filter_myisam_debug.result +++ b/mysql-test/main/rowid_filter_myisam_debug.result @@ -1,10 +1,8 @@ # # MDEV-22761 KILL QUERY during rowid_filter, crashes # -create table t0(a int); -insert into t0 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9); create table t2(a int); -insert into t2 select A.a + B.a* 10 from t0 A, t0 B; +insert into t2 select * from seq_0_to_99; CREATE TABLE t3 ( key1 int , key2 int, @@ -18,11 +16,10 @@ engine MyISAM insert into t3 select -A.a, -B.a, +A.seq, +B.seq, 'filler-data-filler-data' -from -t2 A, t2 B; +from seq_0_to_99 A, seq_0_to_99 B; analyze table t2,t3; Table Op Msg_type Msg_text test.t2 analyze status Engine-independent statistics collected @@ -41,7 +38,6 @@ select * from t2, t3 where t3.key1=t2.a and t3.key2 in (2,3); connect con1, localhost, root,,; -connection con1; set debug_sync='now WAIT_FOR at_rowid_filter_check'; kill query $target_id; set debug_sync='now SIGNAL go'; @@ -49,4 +45,4 @@ connection default; disconnect con1; ERROR 70100: Query execution was interrupted set debug_sync='RESET'; -drop table t0,t2,t3; +drop table t2,t3; diff --git a/mysql-test/suite/federated/federatedx_create_handlers.result b/mysql-test/suite/federated/federatedx_create_handlers.result index bf1df903947..c0b91a68da7 100644 --- a/mysql-test/suite/federated/federatedx_create_handlers.result +++ b/mysql-test/suite/federated/federatedx_create_handlers.result @@ -471,6 +471,51 @@ a 1 2 3 +# +# MDEV-29655: ASAN heap-use-after-free in +# Pushdown_derived::Pushdown_derived +# +connection slave; +DROP TABLE IF EXISTS federated.t1; +CREATE TABLE federated.t1 ( +id int(20) NOT NULL, +name varchar(16) NOT NULL default '' +) +DEFAULT CHARSET=latin1; +INSERT INTO federated.t1 VALUES +(3,'xxx'), (7,'yyy'), (4,'xxx'), (1,'zzz'), (5,'yyy'); +connection master; +DROP TABLE IF EXISTS federated.t1; +CREATE TABLE federated.t1 ( +id int(20) NOT NULL, +name varchar(16) NOT NULL default '' +) +ENGINE="FEDERATED" DEFAULT CHARSET=latin1 +CONNECTION='mysql://root@127.0.0.1:SLAVE_PORT/federated/t1'; +use federated; +SELECT * FROM (SELECT * FROM (SELECT * FROM (SELECT * FROM t1 where id=3) dt3 +WHERE id=2) dt2) dt; +id name +connection slave; +CREATE TABLE federated.t10 (a INT,b INT); +CREATE TABLE federated.t11 (a INT, b INT); +INSERT INTO federated.t10 VALUES (1,1),(2,2); +INSERT INTO federated.t11 VALUES (1,1),(2,2); +connection master; +CREATE TABLE federated.t10 +ENGINE="FEDERATED" DEFAULT CHARSET=latin1 +CONNECTION='mysql://root@127.0.0.1:SLAVE_PORT/federated/t10'; +CREATE TABLE federated.t11 +ENGINE="FEDERATED" DEFAULT CHARSET=latin1 +CONNECTION='mysql://root@127.0.0.1:SLAVE_PORT/federated/t11'; +use federated; +SELECT * FROM t10 LEFT JOIN +(t11, (SELECT * FROM (SELECT * FROM (SELECT * FROM t1 where id=3) dt3 +WHERE id=2) dt2) dt +) ON t10.a=t11.a; +a b a b id name +1 1 NULL NULL NULL NULL +2 2 NULL NULL NULL NULL set global federated_pushdown=0; connection master; DROP TABLE IF EXISTS federated.t1; diff --git a/mysql-test/suite/federated/federatedx_create_handlers.test b/mysql-test/suite/federated/federatedx_create_handlers.test index 2d6c2bc4197..f827c141f3d 100644 --- a/mysql-test/suite/federated/federatedx_create_handlers.test +++ b/mysql-test/suite/federated/federatedx_create_handlers.test @@ -267,7 +267,6 @@ INSERT INTO federated.t2 SELECT * FROM (SELECT * FROM federated.t1 LIMIT 70000) dt; SELECT COUNT(DISTINCT a) FROM federated.t2; - --echo # --echo # MDEV-29640 FederatedX does not properly handle pushdown --echo # in case of difference in local and remote table names @@ -314,6 +313,64 @@ CREATE TABLE federated.t3 (a INT) EXPLAIN SELECT * FROM federated.t3; SELECT * FROM federated.t3; +--echo # +--echo # MDEV-29655: ASAN heap-use-after-free in +--echo # Pushdown_derived::Pushdown_derived +--echo # + +connection slave; +DROP TABLE IF EXISTS federated.t1; + +CREATE TABLE federated.t1 ( + id int(20) NOT NULL, + name varchar(16) NOT NULL default '' +) +DEFAULT CHARSET=latin1; + +INSERT INTO federated.t1 VALUES + (3,'xxx'), (7,'yyy'), (4,'xxx'), (1,'zzz'), (5,'yyy'); + +connection master; +DROP TABLE IF EXISTS federated.t1; + +--replace_result $SLAVE_MYPORT SLAVE_PORT +eval +CREATE TABLE federated.t1 ( + id int(20) NOT NULL, + name varchar(16) NOT NULL default '' +) +ENGINE="FEDERATED" DEFAULT CHARSET=latin1 +CONNECTION='mysql://root@127.0.0.1:$SLAVE_MYPORT/federated/t1'; + +use federated; +SELECT * FROM (SELECT * FROM (SELECT * FROM (SELECT * FROM t1 where id=3) dt3 + WHERE id=2) dt2) dt; + +connection slave; +CREATE TABLE federated.t10 (a INT,b INT); +CREATE TABLE federated.t11 (a INT, b INT); +INSERT INTO federated.t10 VALUES (1,1),(2,2); +INSERT INTO federated.t11 VALUES (1,1),(2,2); + +connection master; +--replace_result $SLAVE_MYPORT SLAVE_PORT +eval +CREATE TABLE federated.t10 +ENGINE="FEDERATED" DEFAULT CHARSET=latin1 +CONNECTION='mysql://root@127.0.0.1:$SLAVE_MYPORT/federated/t10'; + +--replace_result $SLAVE_MYPORT SLAVE_PORT +eval +CREATE TABLE federated.t11 +ENGINE="FEDERATED" DEFAULT CHARSET=latin1 +CONNECTION='mysql://root@127.0.0.1:$SLAVE_MYPORT/federated/t11'; + +use federated; +SELECT * FROM t10 LEFT JOIN + (t11, (SELECT * FROM (SELECT * FROM (SELECT * FROM t1 where id=3) dt3 + WHERE id=2) dt2) dt + ) ON t10.a=t11.a; + set global federated_pushdown=0; source include/federated_cleanup.inc; diff --git a/mysql-test/suite/innodb_gis/disabled.def b/mysql-test/suite/innodb_gis/disabled.def index 2d4d3686dd1..ba492f4f033 100644 --- a/mysql-test/suite/innodb_gis/disabled.def +++ b/mysql-test/suite/innodb_gis/disabled.def @@ -13,3 +13,4 @@ rtree_concurrent_srch : MDEV-15284 COUNT(*) mismatch rtree_recovery : MDEV-15284 COUNT(*) mismatch rtree_compress2 : MDEV-16269 CHECK TABLE reports wrong count +types : MDEV-22512 recovery runs out of memory before 10.5 diff --git a/mysql-test/suite/innodb_gis/r/alter_spatial_index.result b/mysql-test/suite/innodb_gis/r/alter_spatial_index.result index 6e7cf74373d..bf75105db2a 100644 --- a/mysql-test/suite/innodb_gis/r/alter_spatial_index.result +++ b/mysql-test/suite/innodb_gis/r/alter_spatial_index.result @@ -795,4 +795,14 @@ ENGINE=InnoDB; INSERT INTO t VALUES (REPEAT('MariaDB Corporation Ab ',351),POINT(0,0)); ALTER TABLE t FORCE; DROP TABLE t; +# +# MDEV-29856 heap-use-after-poison in row_merge_spatial_rows() +# with PRIMARY KEY on column prefix +# +CREATE TABLE t (id INT, f TEXT, s POINT NOT NULL, +PRIMARY KEY(id,f(1)), SPATIAL(s)) ENGINE=InnoDB; +INSERT INTO t VALUES +(1,REPEAT('x',8192),@p:=ST_GeomFromText('POINT(0 0)')),(2,'',@p); +ALTER TABLE t FORCE; +DROP TABLE t; # End of 10.3 tests diff --git a/mysql-test/suite/innodb_gis/t/alter_spatial_index.test b/mysql-test/suite/innodb_gis/t/alter_spatial_index.test index fdeac824d41..20df437d4d5 100644 --- a/mysql-test/suite/innodb_gis/t/alter_spatial_index.test +++ b/mysql-test/suite/innodb_gis/t/alter_spatial_index.test @@ -791,4 +791,16 @@ ALTER TABLE t FORCE; # Cleanup DROP TABLE t; +--echo # +--echo # MDEV-29856 heap-use-after-poison in row_merge_spatial_rows() +--echo # with PRIMARY KEY on column prefix +--echo # + +CREATE TABLE t (id INT, f TEXT, s POINT NOT NULL, + PRIMARY KEY(id,f(1)), SPATIAL(s)) ENGINE=InnoDB; +INSERT INTO t VALUES +(1,REPEAT('x',8192),@p:=ST_GeomFromText('POINT(0 0)')),(2,'',@p); +ALTER TABLE t FORCE; +DROP TABLE t; + --echo # End of 10.3 tests diff --git a/mysql-test/suite/innodb_zip/disabled.def b/mysql-test/suite/innodb_zip/disabled.def index 8b137891791..fcf7333f843 100644 --- a/mysql-test/suite/innodb_zip/disabled.def +++ b/mysql-test/suite/innodb_zip/disabled.def @@ -1 +1 @@ - +recover : MDEV-22512 recovery runs out of memory before 10.5 diff --git a/mysql-test/suite/mariabackup/full_backup.opt b/mysql-test/suite/mariabackup/full_backup.opt new file mode 100644 index 00000000000..7928cd812d0 --- /dev/null +++ b/mysql-test/suite/mariabackup/full_backup.opt @@ -0,0 +1 @@ +--innodb_undo_tablespaces=2 diff --git a/mysql-test/suite/mariabackup/full_backup.result b/mysql-test/suite/mariabackup/full_backup.result index e2d5cf185d5..e69d00f86f6 100644 --- a/mysql-test/suite/mariabackup/full_backup.result +++ b/mysql-test/suite/mariabackup/full_backup.result @@ -12,3 +12,18 @@ SELECT * FROM t; i 1 DROP TABLE t; +# +# MDEV-27121 mariabackup incompatible with disabled dedicated +# undo log tablespaces +# +call mtr.add_suppression("InnoDB: innodb_undo_tablespaces=0 disables dedicated undo log tablespaces"); +# restart: --innodb_undo_tablespaces=0 +# xtrabackup backup +# xtrabackup prepare +# shutdown server +# remove datadir +# xtrabackup move back +# restart: --innodb_undo_tablespaces=0 +# Display undo log files from target directory +undo001 +undo002 diff --git a/mysql-test/suite/mariabackup/full_backup.test b/mysql-test/suite/mariabackup/full_backup.test index 66bed34cf3d..a0243527438 100644 --- a/mysql-test/suite/mariabackup/full_backup.test +++ b/mysql-test/suite/mariabackup/full_backup.test @@ -29,3 +29,27 @@ SELECT * FROM t; DROP TABLE t; rmdir $targetdir; +--echo # +--echo # MDEV-27121 mariabackup incompatible with disabled dedicated +--echo # undo log tablespaces +--echo # +call mtr.add_suppression("InnoDB: innodb_undo_tablespaces=0 disables dedicated undo log tablespaces"); + +let $restart_parameters=--innodb_undo_tablespaces=0; +--source include/restart_mysqld.inc + +echo # xtrabackup backup; +--disable_result_log +exec $XTRABACKUP --defaults-file=$MYSQLTEST_VARDIR/my.cnf --backup --target-dir=$targetdir; +--enable_result_log + +echo # xtrabackup prepare; +--disable_result_log +exec $XTRABACKUP --prepare --target-dir=$targetdir; +-- source include/restart_and_restore.inc +--enable_result_log + +--echo # Display undo log files from target directory +list_files $targetdir undo*; + +rmdir $targetdir; diff --git a/mysql-test/suite/mariabackup/mdev-14447.combinations b/mysql-test/suite/mariabackup/mdev-14447.combinations new file mode 100644 index 00000000000..79e5f7836ed --- /dev/null +++ b/mysql-test/suite/mariabackup/mdev-14447.combinations @@ -0,0 +1,5 @@ +[crc32] +--innodb-checksum-algorithm=crc32 + +[full_crc32] +--innodb-checksum-algorithm=full_crc32 diff --git a/mysys/my_addr_resolve.c b/mysys/my_addr_resolve.c index 444a47bb7c5..336e419806d 100644 --- a/mysys/my_addr_resolve.c +++ b/mysys/my_addr_resolve.c @@ -202,7 +202,7 @@ int start_addr2line_fork(const char *binary_path) close(out[0]); close(out[1]); execlp("addr2line", "addr2line", "-C", "-f", "-e", binary_path, NULL); - exit(1); + _exit(1); } close(in[0]); diff --git a/mysys/my_gethwaddr.c b/mysys/my_gethwaddr.c index a2b159cf3b0..24054aa4151 100644 --- a/mysys/my_gethwaddr.c +++ b/mysys/my_gethwaddr.c @@ -35,8 +35,14 @@ static my_bool memcpy_and_test(uchar *to, uchar *from, uint len) } #endif -#if defined(__APPLE__) || defined(__FreeBSD__) +#if defined(__APPLE__) || defined(__FreeBSD__) || defined(__OpenBSD__) +#ifdef __OpenBSD__ +#include <netinet/in.h> +#include <net/if_arp.h> +#include <netinet/if_ether.h> +#else #include <net/ethernet.h> +#endif #include <sys/sysctl.h> #include <net/route.h> #include <net/if.h> diff --git a/sql/derived_handler.cc b/sql/derived_handler.cc index f48b95cbf76..70cc04bf9c7 100644 --- a/sql/derived_handler.cc +++ b/sql/derived_handler.cc @@ -44,11 +44,6 @@ Pushdown_derived::Pushdown_derived(TABLE_LIST *tbl, derived_handler *h) } -Pushdown_derived::~Pushdown_derived() -{ - delete handler; -} - int Pushdown_derived::execute() { diff --git a/sql/field.h b/sql/field.h index 9831745f971..ca0cf293d09 100644 --- a/sql/field.h +++ b/sql/field.h @@ -1757,12 +1757,6 @@ public: Used by the ALTER TABLE */ virtual bool is_equal(const Column_definition &new_field) const= 0; - // Used as double dispatch pattern: calls virtual method of handler - virtual bool - can_be_converted_by_engine(const Column_definition &new_type) const - { - return false; - } /* convert decimal to longlong with overflow check */ longlong convert_decimal2longlong(const my_decimal *val, bool unsigned_flag, int *err); @@ -4045,11 +4039,6 @@ public: void sql_type(String &str) const override; void sql_rpl_type(String*) const override; bool is_equal(const Column_definition &new_field) const override; - bool can_be_converted_by_engine(const Column_definition &new_type) const - override - { - return table->file->can_convert_string(this, new_type); - } uchar *pack(uchar *to, const uchar *from, uint max_length) override; const uchar *unpack(uchar* to, const uchar *from, const uchar *from_end, uint param_data) override; @@ -4204,11 +4193,6 @@ public: uchar *new_ptr, uint32 length, uchar *new_null_ptr, uint new_null_bit) override; bool is_equal(const Column_definition &new_field) const override; - bool can_be_converted_by_engine(const Column_definition &new_type) const - override - { - return table->file->can_convert_varstring(this, new_type); - } void hash(ulong *nr, ulong *nr2) override; uint length_size() const override { return length_bytes; } void print_key_value(String *out, uint32 length) override; @@ -4647,11 +4631,6 @@ public: uint32 char_length() const override; uint32 character_octet_length() const override; bool is_equal(const Column_definition &new_field) const override; - bool can_be_converted_by_engine(const Column_definition &new_type) const - override - { - return table->file->can_convert_blob(this, new_type); - } void print_key_value(String *out, uint32 length) override; Binlog_type_info binlog_type_info() const override; diff --git a/sql/ha_partition.cc b/sql/ha_partition.cc index bafa821e200..7298dcd15c6 100644 --- a/sql/ha_partition.cc +++ b/sql/ha_partition.cc @@ -1,6 +1,6 @@ /* Copyright (c) 2005, 2019, Oracle and/or its affiliates. - Copyright (c) 2009, 2021, MariaDB + Copyright (c) 2009, 2022, MariaDB This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -12103,35 +12103,12 @@ int ha_partition::info_push(uint info_type, void *info) bool -ha_partition::can_convert_string(const Field_string* field, - const Column_definition& new_type) const +ha_partition::can_convert_nocopy(const Field &field, + const Column_definition &new_type) const { for (uint index= 0; index < m_tot_parts; index++) { - if (!m_file[index]->can_convert_string(field, new_type)) - return false; - } - return true; -} - -bool -ha_partition::can_convert_varstring(const Field_varstring* field, - const Column_definition& new_type) const{ - for (uint index= 0; index < m_tot_parts; index++) - { - if (!m_file[index]->can_convert_varstring(field, new_type)) - return false; - } - return true; -} - -bool -ha_partition::can_convert_blob(const Field_blob* field, - const Column_definition& new_type) const -{ - for (uint index= 0; index < m_tot_parts; index++) - { - if (!m_file[index]->can_convert_blob(field, new_type)) + if (!m_file[index]->can_convert_nocopy(field, new_type)) return false; } return true; diff --git a/sql/ha_partition.h b/sql/ha_partition.h index 72a9314409c..49119037f2a 100644 --- a/sql/ha_partition.h +++ b/sql/ha_partition.h @@ -1627,16 +1627,8 @@ public: friend int cmp_key_rowid_part_id(void *ptr, uchar *ref1, uchar *ref2); friend int cmp_key_part_id(void *key_p, uchar *ref1, uchar *ref2); - bool can_convert_string( - const Field_string* field, - const Column_definition& new_field) const override; - bool can_convert_varstring( - const Field_varstring* field, - const Column_definition& new_field) const override; - - bool can_convert_blob( - const Field_blob* field, - const Column_definition& new_field) const override; + bool can_convert_nocopy(const Field &field, + const Column_definition &new_field) const override; }; #endif /* HA_PARTITION_INCLUDED */ diff --git a/sql/handler.cc b/sql/handler.cc index a5b3a9c0af5..5942eca6698 100644 --- a/sql/handler.cc +++ b/sql/handler.cc @@ -6967,8 +6967,13 @@ int handler::check_duplicate_long_entries_update(const uchar *new_rec) { int error; field= keypart->field; - /* Compare fields if they are different then check for duplicates */ - if (field->cmp_binary_offset(reclength)) + /* + Compare fields if they are different then check for duplicates + cmp_binary_offset cannot differentiate between null and empty string + So also check for that too + */ + if((field->is_null(0) != field->is_null(reclength)) || + field->cmp_binary_offset(reclength)) { if((error= check_duplicate_long_entry_key(new_rec, i))) return error; diff --git a/sql/handler.h b/sql/handler.h index f3c3819ef0f..742f1750a59 100644 --- a/sql/handler.h +++ b/sql/handler.h @@ -5009,18 +5009,8 @@ public: These functions check for such possibility. Implementation could be based on Field_xxx::is_equal() */ - virtual bool can_convert_string(const Field_string *field, - const Column_definition &new_type) const - { - return false; - } - virtual bool can_convert_varstring(const Field_varstring *field, - const Column_definition &new_type) const - { - return false; - } - virtual bool can_convert_blob(const Field_blob *field, - const Column_definition &new_type) const + virtual bool can_convert_nocopy(const Field &, + const Column_definition &) const { return false; } diff --git a/sql/mysqld.cc b/sql/mysqld.cc index fe63d674360..e5dc3dbd72f 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -3929,8 +3929,8 @@ static int init_common_variables() files= my_set_max_open_files(max_open_files); SYSVAR_AUTOSIZE_IF_CHANGED(open_files_limit, files, ulong); - if (files < wanted_files && global_system_variables.log_warnings) - sql_print_warning("Could not increase number of max_open_files to more than %u (request: %u)", files, wanted_files); + if (files < max_open_files && global_system_variables.log_warnings) + sql_print_warning("Could not increase number of max_open_files to more than %u (request: %u)", files, max_open_files); /* If we required too much tc_instances than we reduce */ SYSVAR_AUTOSIZE_IF_CHANGED(tc_instances, diff --git a/sql/sql_derived.cc b/sql/sql_derived.cc index f8ee3475af8..fa060afde8d 100644 --- a/sql/sql_derived.cc +++ b/sql/sql_derived.cc @@ -1000,11 +1000,7 @@ bool mysql_derived_optimize(THD *thd, LEX *lex, TABLE_LIST *derived) /* Create an object for execution of the query specifying the table */ if (!(derived->pushdown_derived= new (thd->mem_root) Pushdown_derived(derived, derived->dt_handler))) - { - delete derived->dt_handler; - derived->dt_handler= NULL; DBUG_RETURN(TRUE); - } } lex->current_select= first_select; @@ -1229,7 +1225,6 @@ bool mysql_derived_fill(THD *thd, LEX *lex, TABLE_LIST *derived) /* Execute the query that specifies the derived table by a foreign engine */ res= derived->pushdown_derived->execute(); unit->executed= true; - delete derived->pushdown_derived; DBUG_RETURN(res); } diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 332c8a786c5..8e85409dafb 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -67,6 +67,7 @@ #include "select_handler.h" #include "my_json_writer.h" #include "opt_trace.h" +#include "derived_handler.h" /* A key part number that means we're using a fulltext scan. @@ -14218,6 +14219,7 @@ void JOIN::cleanup(bool full) } } } + free_pushdown_handlers(*join_list); } /* Restore ref array to original state */ if (current_ref_ptrs != items0) @@ -14228,6 +14230,32 @@ void JOIN::cleanup(bool full) DBUG_VOID_RETURN; } +/** + Clean up all derived pushdown handlers in this join. + + @detail + Note that dt_handler is picked at the prepare stage (as opposed + to optimization stage where one could expect this). + Because of that, we have to do cleanups in this function that is called + from JOIN::cleanup() and not in JOIN_TAB::cleanup. + */ +void JOIN::free_pushdown_handlers(List<TABLE_LIST>& join_list) +{ + List_iterator<TABLE_LIST> li(join_list); + TABLE_LIST *table_ref; + while ((table_ref= li++)) + { + if (table_ref->nested_join) + free_pushdown_handlers(table_ref->nested_join->join_list); + if (table_ref->pushdown_derived) + { + delete table_ref->pushdown_derived; + table_ref->pushdown_derived= NULL; + } + delete table_ref->dt_handler; + table_ref->dt_handler= NULL; + } +} /** Remove the following expressions from ORDER BY and GROUP BY: @@ -27668,12 +27696,6 @@ bool mysql_explain_union(THD *thd, SELECT_LEX_UNIT *unit, select_result *result) result, unit, first); } - if (unit->derived && unit->derived->pushdown_derived) - { - delete unit->derived->pushdown_derived; - unit->derived->pushdown_derived= NULL; - } - DBUG_RETURN(res || thd->is_error()); } diff --git a/sql/sql_select.h b/sql/sql_select.h index 32013f4f295..e24dc19d755 100644 --- a/sql/sql_select.h +++ b/sql/sql_select.h @@ -1851,6 +1851,7 @@ private: bool add_having_as_table_cond(JOIN_TAB *tab); bool make_aggr_tables_info(); bool add_fields_for_current_rowid(JOIN_TAB *cur, List<Item> *fields); + void free_pushdown_handlers(List<TABLE_LIST>& join_list); void init_join_cache_and_keyread(); }; @@ -2524,8 +2525,6 @@ public: Pushdown_derived(TABLE_LIST *tbl, derived_handler *h); - ~Pushdown_derived(); - int execute(); }; diff --git a/sql/sql_table.cc b/sql/sql_table.cc index b76b3b94baf..1ca09332872 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -7247,7 +7247,7 @@ static bool fill_alter_inplace_info(THD *thd, TABLE *table, bool varchar, bool is_equal= field->is_equal(*new_field); if (!is_equal) { - if (field->can_be_converted_by_engine(*new_field)) + if (field->table->file->can_convert_nocopy(*field, *new_field)) { /* New column type differs from the old one, but storage engine can diff --git a/sql/sql_type_geom.h b/sql/sql_type_geom.h index fed988c3113..ff00beea598 100644 --- a/sql/sql_type_geom.h +++ b/sql/sql_type_geom.h @@ -2,7 +2,7 @@ #define SQL_TYPE_GEOM_H_INCLUDED /* Copyright (c) 2015 MariaDB Foundation - Copyright (c) 2019 MariaDB + Copyright (c) 2019, 2022, MariaDB Corporation. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -396,12 +396,6 @@ public: !table->copy_blobs; } bool is_equal(const Column_definition &new_field) const override; - bool can_be_converted_by_engine(const Column_definition &new_type) - const override - { - return false; // Override the Field_blob behavior - } - int store(const char *to, size_t length, CHARSET_INFO *charset) override; int store(double nr) override; int store(longlong nr, bool unsigned_val) override; diff --git a/storage/innobase/btr/btr0bulk.cc b/storage/innobase/btr/btr0bulk.cc index c23b6a7e107..0dca1b2c02f 100644 --- a/storage/innobase/btr/btr0bulk.cc +++ b/storage/innobase/btr/btr0bulk.cc @@ -555,8 +555,9 @@ inline void PageBulk::finish() void PageBulk::commit(bool success) { finish(); - if (success && !dict_index_is_clust(m_index) && page_is_leaf(m_page)) - ibuf_set_bitmap_for_bulk_load(m_block, innobase_fill_factor == 100); + if (success && !m_index->is_clust() && page_is_leaf(m_page)) + ibuf_set_bitmap_for_bulk_load(m_block, &m_mtr, + innobase_fill_factor == 100); m_mtr.commit(); } diff --git a/storage/innobase/buf/buf0buf.cc b/storage/innobase/buf/buf0buf.cc index 4340d294aba..c788a0ff3f2 100644 --- a/storage/innobase/buf/buf0buf.cc +++ b/storage/innobase/buf/buf0buf.cc @@ -738,7 +738,7 @@ buf_page_is_corrupted( DBUG_EXECUTE_IF( "page_intermittent_checksum_mismatch", { static int page_counter; - if (page_counter++ == 2) { + if (page_counter++ == 3) { crc32++; } }); @@ -907,7 +907,7 @@ buf_page_is_corrupted( DBUG_EXECUTE_IF( "page_intermittent_checksum_mismatch", { static int page_counter; - if (page_counter++ == 2) return true; + if (page_counter++ == 3) return true; }); if ((checksum_field1 != crc32 diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc index 5af52a3240d..7cd41c6e529 100644 --- a/storage/innobase/handler/ha_innodb.cc +++ b/storage/innobase/handler/ha_innodb.cc @@ -54,7 +54,7 @@ this program; if not, write to the Free Software Foundation, Inc., #include <my_bitmap.h> #include <mysql/service_thd_alloc.h> #include <mysql/service_thd_wait.h> -#include "field.h" +#include "sql_type_geom.h" #include "scope.h" #include "srv0srv.h" @@ -20878,6 +20878,26 @@ bool ha_innobase::can_convert_blob(const Field_blob *field, return true; } + +bool ha_innobase::can_convert_nocopy(const Field &field, + const Column_definition &new_type) const +{ + if (const Field_string *tf= dynamic_cast<const Field_string *>(&field)) + return can_convert_string(tf, new_type); + + if (const Field_varstring *tf= dynamic_cast<const Field_varstring *>(&field)) + return can_convert_varstring(tf, new_type); + + if (dynamic_cast<const Field_geom *>(&field)) + return false; + + if (const Field_blob *tf= dynamic_cast<const Field_blob *>(&field)) + return can_convert_blob(tf, new_type); + + return false; +} + + Compare_keys ha_innobase::compare_key_parts( const Field &old_field, const Column_definition &new_field, const KEY_PART_INFO &old_part, const KEY_PART_INFO &new_part) const @@ -20888,7 +20908,7 @@ Compare_keys ha_innobase::compare_key_parts( if (!is_equal) { - if (!old_field.can_be_converted_by_engine(new_field)) + if (!old_field.table->file->can_convert_nocopy(old_field, new_field)) return Compare_keys::NotEqual; if (!Charset(old_cs).eq_collation_specific_names(new_cs)) diff --git a/storage/innobase/handler/ha_innodb.h b/storage/innobase/handler/ha_innodb.h index b97bbd982e5..13d36e71e40 100644 --- a/storage/innobase/handler/ha_innodb.h +++ b/storage/innobase/handler/ha_innodb.h @@ -420,15 +420,9 @@ public: @retval false if pushed (always) */ bool rowid_filter_push(Rowid_filter *rowid_filter) override; - bool - can_convert_string(const Field_string* field, - const Column_definition& new_field) const override; - bool can_convert_varstring( - const Field_varstring* field, - const Column_definition& new_field) const override; - bool - can_convert_blob(const Field_blob* field, - const Column_definition& new_field) const override; + bool can_convert_nocopy(const Field &field, + const Column_definition& new_field) const + override; /** @return whether innodb_strict_mode is active */ static bool is_innodb_strict_mode(THD* thd); @@ -443,6 +437,16 @@ public: const KEY_PART_INFO& new_part) const override; protected: + bool + can_convert_string(const Field_string* field, + const Column_definition& new_field) const; + bool can_convert_varstring( + const Field_varstring* field, + const Column_definition& new_field) const; + bool + can_convert_blob(const Field_blob* field, + const Column_definition& new_field) const; + dberr_t innobase_get_autoinc(ulonglong* value); dberr_t innobase_lock_autoinc(); ulonglong innobase_peek_autoinc(); diff --git a/storage/innobase/ibuf/ibuf0ibuf.cc b/storage/innobase/ibuf/ibuf0ibuf.cc index 53d27eeaacd..31fc317c90b 100644 --- a/storage/innobase/ibuf/ibuf0ibuf.cc +++ b/storage/innobase/ibuf/ibuf0ibuf.cc @@ -1872,7 +1872,6 @@ static bool ibuf_add_free_page() &mtr); ibuf_mtr_commit(&mtr); - return true; } @@ -2468,6 +2467,7 @@ ibuf_merge_space( ut_ad(space < SRV_SPACE_ID_UPPER_BOUND); + log_free_check(); ibuf_mtr_start(&mtr); /* Position the cursor on the first matching record. */ @@ -2572,6 +2572,7 @@ ulint ibuf_merge_all() ulint n_pages = srv_io_capacity; for (ulint sum_pages = 0; sum_pages < n_pages; ) { + log_free_check(); ulint n_pag2; ulint n_bytes = ibuf_merge(&n_pag2); @@ -4513,7 +4514,7 @@ reset_bit: } /** Delete all change buffer entries for a tablespace, -in DISCARD TABLESPACE, IMPORT TABLESPACE, or crash recovery. +in DISCARD TABLESPACE, IMPORT TABLESPACE, or read-ahead. @param[in] space missing or to-be-discarded tablespace */ void ibuf_delete_for_discarded_space(ulint space) { @@ -4535,6 +4536,7 @@ void ibuf_delete_for_discarded_space(ulint space) memset(dops, 0, sizeof(dops)); loop: + log_free_check(); ibuf_mtr_start(&mtr); /* Position pcur in the insert buffer at the first entry for the @@ -4672,9 +4674,6 @@ dberr_t ibuf_check_bitmap_on_import(const trx_t* trx, fil_space_t* space) } mtr_start(&mtr); - - mtr_set_log_mode(&mtr, MTR_LOG_NO_REDO); - ibuf_enter(&mtr); buf_block_t* bitmap_page = ibuf_bitmap_get_map_page( @@ -4759,37 +4758,25 @@ dberr_t ibuf_check_bitmap_on_import(const trx_t* trx, fil_space_t* space) return(DB_SUCCESS); } -/** Updates free bits and buffered bits for bulk loaded page. -@param[in] block index page -@param[in] reset flag if reset free val */ -void -ibuf_set_bitmap_for_bulk_load( - buf_block_t* block, - bool reset) +void ibuf_set_bitmap_for_bulk_load(buf_block_t *block, mtr_t *mtr, bool reset) { - mtr_t mtr; ulint free_val; ut_a(page_is_leaf(buf_block_get_frame(block))); free_val = ibuf_index_page_calc_free(block); - mtr.start(); - fil_space_t* space = mtr.set_named_space_id(block->page.id().space()); - buf_block_t* bitmap_page = ibuf_bitmap_get_map_page(block->page.id(), - space->zip_size(), - &mtr); + block->zip_size(), + mtr); free_val = reset ? 0 : ibuf_index_page_calc_free(block); /* FIXME: update the bitmap byte only once! */ ibuf_bitmap_page_set_bits<IBUF_BITMAP_FREE>( bitmap_page, block->page.id(), block->physical_size(), - free_val, &mtr); + free_val, mtr); ibuf_bitmap_page_set_bits<IBUF_BITMAP_BUFFERED>( bitmap_page, block->page.id(), block->physical_size(), - false, &mtr); - - mtr.commit(); + false, mtr); } diff --git a/storage/innobase/include/ibuf0ibuf.h b/storage/innobase/include/ibuf0ibuf.h index ff80db5f92a..8cf0aeaeb99 100644 --- a/storage/innobase/include/ibuf0ibuf.h +++ b/storage/innobase/include/ibuf0ibuf.h @@ -1,7 +1,7 @@ /***************************************************************************** Copyright (c) 1997, 2016, Oracle and/or its affiliates. All Rights Reserved. -Copyright (c) 2016, 2020, MariaDB Corporation. +Copyright (c) 2016, 2022, MariaDB Corporation. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -268,7 +268,6 @@ ibuf_page_low( MY_ATTRIBUTE((warn_unused_result)); #ifdef UNIV_DEBUG - /** Checks if a page is a level 2 or 3 page in the ibuf hierarchy of pages. Must not be called when recv_no_ibuf_operations==true. @param[in] page_id tablespace/page identifier @@ -278,7 +277,7 @@ Must not be called when recv_no_ibuf_operations==true. # define ibuf_page(page_id, zip_size, mtr) \ ibuf_page_low(page_id, zip_size, true, __FILE__, __LINE__, mtr) -#else /* UVIV_DEBUG */ +#else /* UNIV_DEBUG */ /** Checks if a page is a level 2 or 3 page in the ibuf hierarchy of pages. Must not be called when recv_no_ibuf_operations==true. @@ -289,7 +288,7 @@ Must not be called when recv_no_ibuf_operations==true. # define ibuf_page(page_id, zip_size, mtr) \ ibuf_page_low(page_id, zip_size, __FILE__, __LINE__, mtr) -#endif /* UVIV_DEBUG */ +#endif /* UNIV_DEBUG */ /***********************************************************************//** Frees excess pages from the ibuf free list. This function is called when an OS thread calls fsp services to allocate a new file segment, or a new page to a @@ -336,7 +335,7 @@ void ibuf_merge_or_delete_for_page(buf_block_t *block, const page_id_t page_id, ulint zip_size); /** Delete all change buffer entries for a tablespace, -in DISCARD TABLESPACE, IMPORT TABLESPACE, or crash recovery. +in DISCARD TABLESPACE, IMPORT TABLESPACE, or read-ahead. @param[in] space missing or to-be-discarded tablespace */ void ibuf_delete_for_discarded_space(ulint space); @@ -387,13 +386,11 @@ ibuf_close(void); dberr_t ibuf_check_bitmap_on_import(const trx_t* trx, fil_space_t* space) MY_ATTRIBUTE((nonnull, warn_unused_result)); -/** Updates free bits and buffered bits for bulk loaded page. -@param[in] block index page -@param]in] reset flag if reset free val */ -void -ibuf_set_bitmap_for_bulk_load( - buf_block_t* block, - bool reset); +/** Update free bits and buffered bits for bulk loaded page. +@param block secondary index leaf page +@param mtr mini-transaction +@param reset whether the page is full */ +void ibuf_set_bitmap_for_bulk_load(buf_block_t *block, mtr_t *mtr, bool reset); #define IBUF_HEADER_PAGE_NO FSP_IBUF_HEADER_PAGE_NO #define IBUF_TREE_ROOT_PAGE_NO FSP_IBUF_TREE_ROOT_PAGE_NO diff --git a/storage/innobase/log/log0recv.cc b/storage/innobase/log/log0recv.cc index 44b77c03952..8c8d87b974c 100644 --- a/storage/innobase/log/log0recv.cc +++ b/storage/innobase/log/log0recv.cc @@ -54,6 +54,7 @@ Created 9/20/1997 Heikki Tuuri #include "srv0srv.h" #include "srv0start.h" #include "fil0pagecompress.h" +#include "log.h" /** The recovery system */ recv_sys_t recv_sys; @@ -1327,7 +1328,7 @@ ATTRIBUTE_COLD static dberr_t recv_log_recover_pre_10_2() if (!log_crypt_101_read_checkpoint(buf)) { - ib::error() << "Decrypting checkpoint failed"; + sql_print_error("InnoDB: Decrypting checkpoint failed"); continue; } @@ -1349,11 +1350,11 @@ ATTRIBUTE_COLD static dberr_t recv_log_recover_pre_10_2() if (!lsn) { - ib::error() << "Upgrade after a crash is not supported." - " This redo log was created before MariaDB 10.2.2," - " and we did not find a valid checkpoint." - " Please follow the instructions at" - " https://mariadb.com/kb/en/library/upgrading/"; + sql_print_error("InnoDB: Upgrade after a crash is not supported." + " This redo log was created before MariaDB 10.2.2," + " and we did not find a valid checkpoint." + " Please follow the instructions at" + " https://mariadb.com/kb/en/library/upgrading/"); return DB_ERROR; } @@ -1362,7 +1363,7 @@ ATTRIBUTE_COLD static dberr_t recv_log_recover_pre_10_2() const lsn_t source_offset= log_sys.log.calc_lsn_offset_old(lsn); static constexpr char NO_UPGRADE_RECOVERY_MSG[]= - "Upgrade after a crash is not supported." + "InnoDB: Upgrade after a crash is not supported." " This redo log was created before MariaDB 10.2.2"; recv_sys.read(source_offset & ~511, {buf, 512}); @@ -1370,7 +1371,7 @@ ATTRIBUTE_COLD static dberr_t recv_log_recover_pre_10_2() if (log_block_calc_checksum_format_0(buf) != log_block_get_checksum(buf) && !log_crypt_101_read_block(buf, lsn)) { - ib::error() << NO_UPGRADE_RECOVERY_MSG << ", and it appears corrupted."; + sql_print_error("%s, and it appears corrupted.", NO_UPGRADE_RECOVERY_MSG); return DB_CORRUPTION; } @@ -1387,10 +1388,13 @@ ATTRIBUTE_COLD static dberr_t recv_log_recover_pre_10_2() } if (buf[20 + 32 * 9] == 2) - ib::error() << "Cannot decrypt log for upgrading." - " The encrypted log was created before MariaDB 10.2.2."; + sql_print_error("InnoDB: Cannot decrypt log for upgrading." + " The encrypted log was created before MariaDB 10.2.2."); else - ib::error() << NO_UPGRADE_RECOVERY_MSG << "."; + sql_print_error("%s. You must start up and shut down" + " MariaDB 10.1 or MySQL 5.6 or earlier" + " on the data directory.", + NO_UPGRADE_RECOVERY_MSG); return DB_ERROR; } @@ -1497,8 +1501,8 @@ recv_find_max_checkpoint(ulint* max_field) : 0; if (log_sys.log.format != log_t::FORMAT_3_23 && !recv_check_log_header_checksum(buf)) { - ib::error() << "Invalid redo log header checksum."; - return(DB_CORRUPTION); + sql_print_error("InnoDB: Invalid redo log header checksum."); + return DB_CORRUPTION; } char creator[LOG_HEADER_CREATOR_END - LOG_HEADER_CREATOR + 1]; @@ -1520,9 +1524,9 @@ recv_find_max_checkpoint(ulint* max_field) case log_t::FORMAT_10_5 | log_t::FORMAT_ENCRYPTED: break; default: - ib::error() << "Unsupported redo log format." - " The redo log was created with " << creator << "."; - return(DB_ERROR); + sql_print_error("InnoDB: Unsupported redo log format." + " The redo log was created with %s.", creator); + return DB_ERROR; } for (field = LOG_CHECKPOINT_1; field <= LOG_CHECKPOINT_2; @@ -1544,8 +1548,8 @@ recv_find_max_checkpoint(ulint* max_field) if (log_sys.is_encrypted() && !log_crypt_read_checkpoint_buf(buf)) { - ib::error() << "Reading checkpoint" - " encryption info failed."; + sql_print_error("InnoDB: Reading checkpoint" + " encryption info failed."); continue; } @@ -1574,11 +1578,11 @@ recv_find_max_checkpoint(ulint* max_field) was filled with zeroes, and were killed. After 10.2.2, we would reject such a file already earlier, when checking the file header. */ - ib::error() << "No valid checkpoint found" - " (corrupted redo log)." - " You can try --innodb-force-recovery=6" - " as a last resort."; - return(DB_ERROR); + sql_print_error("InnoDB: No valid checkpoint found" + " (corrupted redo log)." + " You can try --innodb-force-recovery=6" + " as a last resort."); + return DB_ERROR; } switch (log_sys.log.format) { @@ -1587,11 +1591,15 @@ recv_find_max_checkpoint(ulint* max_field) break; default: if (dberr_t err = recv_log_recover_10_4()) { - ib::error() - << "Upgrade after a crash is not supported." - " The redo log was created with " << creator - << (err == DB_ERROR - ? "." : ", and it appears corrupted."); + sql_print_error("InnoDB: Upgrade after a crash " + "is not supported." + " The redo log was created with %s%s.", + creator, + err == DB_ERROR + ? ". You must start up and shut down" + " MariaDB 10.4 or earlier" + " on the data directory" + : ", and it appears corrupted"); return err; } } diff --git a/storage/innobase/plugin_exports b/storage/innobase/plugin_exports deleted file mode 100644 index 235ae3d5e72..00000000000 --- a/storage/innobase/plugin_exports +++ /dev/null @@ -1,14 +0,0 @@ -{ - global: - _maria_plugin_interface_version_; - _maria_sizeof_struct_st_plugin_; - _maria_plugin_declarations_; - my_snprintf_service; - thd_alloc_service; - thd_autoinc_service; - thd_error_context_service; - thd_kill_statement_service; - thd_wait_service; - local: - *; -}; diff --git a/storage/innobase/que/que0que.cc b/storage/innobase/que/que0que.cc index e70fdd9c522..125c50fbc8b 100644 --- a/storage/innobase/que/que0que.cc +++ b/storage/innobase/que/que0que.cc @@ -1,7 +1,7 @@ /***************************************************************************** Copyright (c) 1996, 2016, Oracle and/or its affiliates. All Rights Reserved. -Copyright (c) 2017, 2021, MariaDB Corporation. +Copyright (c) 2017, 2022, MariaDB Corporation. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -384,17 +384,10 @@ que_graph_free_recursive( ind_node_t* cre_ind; purge_node_t* purge; - DBUG_ENTER("que_graph_free_recursive"); - if (node == NULL) { - - DBUG_VOID_RETURN; + return; } - DBUG_PRINT("que_graph_free_recursive", - ("node: %p, type: " ULINTPF, node, - que_node_get_type(node))); - switch (que_node_get_type(node)) { case QUE_NODE_FORK: @@ -534,8 +527,6 @@ que_graph_free_recursive( default: ut_error; } - - DBUG_VOID_RETURN; } /**********************************************************************//** @@ -800,65 +791,6 @@ que_node_get_containing_loop_node( return(node); } -#ifdef DBUG_TRACE -/** Gets information of an SQL query graph node. -@return type description */ -static MY_ATTRIBUTE((warn_unused_result, nonnull)) -const char* -que_node_type_string( -/*=================*/ - const que_node_t* node) /*!< in: query graph node */ -{ - switch (que_node_get_type(node)) { - case QUE_NODE_SELECT: - return("SELECT"); - case QUE_NODE_INSERT: - return("INSERT"); - case QUE_NODE_UPDATE: - return("UPDATE"); - case QUE_NODE_WHILE: - return("WHILE"); - case QUE_NODE_ASSIGNMENT: - return("ASSIGNMENT"); - case QUE_NODE_IF: - return("IF"); - case QUE_NODE_FETCH: - return("FETCH"); - case QUE_NODE_OPEN: - return("OPEN"); - case QUE_NODE_PROC: - return("STORED PROCEDURE"); - case QUE_NODE_FUNC: - return("FUNCTION"); - case QUE_NODE_LOCK: - return("LOCK"); - case QUE_NODE_THR: - return("QUERY THREAD"); - case QUE_NODE_COMMIT: - return("COMMIT"); - case QUE_NODE_UNDO: - return("UNDO ROW"); - case QUE_NODE_PURGE: - return("PURGE ROW"); - case QUE_NODE_ROLLBACK: - return("ROLLBACK"); - case QUE_NODE_CREATE_TABLE: - return("CREATE TABLE"); - case QUE_NODE_CREATE_INDEX: - return("CREATE INDEX"); - case QUE_NODE_FOR: - return("FOR LOOP"); - case QUE_NODE_RETURN: - return("RETURN"); - case QUE_NODE_EXIT: - return("EXIT"); - default: - ut_ad(0); - return("UNKNOWN NODE TYPE"); - } -} -#endif /* DBUG_TRACE */ - /**********************************************************************//** Performs an execution step on a query thread. @return query thread to run next: it may differ from the input @@ -886,10 +818,6 @@ que_thr_step( old_thr = thr; - DBUG_PRINT("ib_que", ("Execute %u (%s) at %p", - unsigned(type), que_node_type_string(node), - (const void*) node)); - if (type & QUE_NODE_CONTROL_STAT) { if ((thr->prev_node != que_node_get_parent(node)) && que_node_get_next(thr->prev_node)) { diff --git a/storage/innobase/row/row0merge.cc b/storage/innobase/row/row0merge.cc index 8ec7cd91975..aadf1c6bab0 100644 --- a/storage/innobase/row/row0merge.cc +++ b/storage/innobase/row/row0merge.cc @@ -60,57 +60,49 @@ Completed by Sunny Bains and Marko Makela /* Whether to disable file system cache */ char srv_disable_sort_file_cache; -/** Class that caches index row tuples made from a single cluster +/** Class that caches spatial index row tuples made from a single cluster index page scan, and then insert into corresponding index tree */ -class index_tuple_info_t { +class spatial_index_info { public: - /** constructor - @param[in] heap memory heap - @param[in] index index to be created */ - index_tuple_info_t(mem_heap_t* heap, dict_index_t* index) : - m_dtuple_vec(UT_NEW_NOKEY(idx_tuple_vec())), - m_index(index), m_heap(heap) - { ut_ad(index->is_spatial()); } - - /** destructor */ - ~index_tuple_info_t() - { - UT_DELETE(m_dtuple_vec); - } - - /** Get the index object - @return the index object */ - dict_index_t* get_index() UNIV_NOTHROW - { - return(m_index); - } - - /** Caches an index row into index tuple vector - @param[in] row table row - @param[in] ext externally stored column - prefixes, or NULL */ - void add( - const dtuple_t* row, - const row_ext_t* ext) UNIV_NOTHROW - { - dtuple_t* dtuple; - - dtuple = row_build_index_entry(row, ext, m_index, m_heap); - - ut_ad(dtuple); - - m_dtuple_vec->push_back(dtuple); - } + /** constructor + @param index spatial index to be created */ + spatial_index_info(dict_index_t *index) : index(index) + { + ut_ad(index->is_spatial()); + } + + /** Caches an index row into index tuple vector + @param[in] row table row + @param[in] ext externally stored column prefixes, or NULL */ + void add(const dtuple_t *row, const row_ext_t *ext, mem_heap_t *heap) + { + dtuple_t *dtuple= row_build_index_entry(row, ext, index, heap); + ut_ad(dtuple); + ut_ad(dtuple->n_fields == index->n_fields); + if (ext) + { + /* Replace any references to ext, because ext will be allocated + from row_heap. */ + for (ulint i= 1; i < dtuple->n_fields; i++) + { + dfield_t &dfield= dtuple->fields[i]; + if (dfield.data >= ext->buf && + dfield.data <= &ext->buf[ext->n_ext * ext->max_len]) + dfield_dup(&dfield, heap); + } + } + m_dtuple_vec.push_back(dtuple); + } /** Insert spatial index rows cached in vector into spatial index @param[in] trx_id transaction id - @param[in,out] row_heap memory heap @param[in] pcur cluster index scanning cursor @param[in,out] mtr_started whether scan_mtr is active + @param[in,out] heap temporary memory heap @param[in,out] scan_mtr mini-transaction for pcur @return DB_SUCCESS if successful, else error number */ - dberr_t insert(trx_id_t trx_id, mem_heap_t* row_heap, btr_pcur_t* pcur, - bool& mtr_started, mtr_t* scan_mtr) const + dberr_t insert(trx_id_t trx_id, btr_pcur_t* pcur, + bool& mtr_started, mem_heap_t* heap, mtr_t* scan_mtr) { big_rec_t* big_rec; rec_t* rec; @@ -129,8 +121,8 @@ public: DBUG_EXECUTE_IF("row_merge_instrument_log_check_flush", log_sys.set_check_flush_or_checkpoint();); - for (idx_tuple_vec::iterator it = m_dtuple_vec->begin(); - it != m_dtuple_vec->end(); + for (idx_tuple_vec::iterator it = m_dtuple_vec.begin(); + it != m_dtuple_vec.end(); ++it) { dtuple = *it; ut_ad(dtuple); @@ -147,14 +139,14 @@ public: } mtr.start(); - m_index->set_modified(mtr); + index->set_modified(mtr); - ins_cur.index = m_index; - rtr_init_rtr_info(&rtr_info, false, &ins_cur, m_index, + ins_cur.index = index; + rtr_init_rtr_info(&rtr_info, false, &ins_cur, index, false); rtr_info_update_btr(&ins_cur, &rtr_info); - btr_cur_search_to_nth_level(m_index, 0, dtuple, + btr_cur_search_to_nth_level(index, 0, dtuple, PAGE_CUR_RTREE_INSERT, BTR_MODIFY_LEAF, &ins_cur, __FILE__, __LINE__, @@ -163,44 +155,44 @@ public: /* It need to update MBR in parent entry, so change search mode to BTR_MODIFY_TREE */ if (rtr_info.mbr_adj) { - mtr_commit(&mtr); + mtr.commit(); rtr_clean_rtr_info(&rtr_info, true); rtr_init_rtr_info(&rtr_info, false, &ins_cur, - m_index, false); + index, false); rtr_info_update_btr(&ins_cur, &rtr_info); - mtr_start(&mtr); - m_index->set_modified(mtr); + mtr.start(); + index->set_modified(mtr); btr_cur_search_to_nth_level( - m_index, 0, dtuple, + index, 0, dtuple, PAGE_CUR_RTREE_INSERT, BTR_MODIFY_TREE, &ins_cur, __FILE__, __LINE__, &mtr); } error = btr_cur_optimistic_insert( - flag, &ins_cur, &ins_offsets, &row_heap, + flag, &ins_cur, &ins_offsets, &heap, dtuple, &rec, &big_rec, 0, NULL, &mtr); if (error == DB_FAIL) { ut_ad(!big_rec); mtr.commit(); mtr.start(); - m_index->set_modified(mtr); + index->set_modified(mtr); rtr_clean_rtr_info(&rtr_info, true); rtr_init_rtr_info(&rtr_info, false, - &ins_cur, m_index, false); + &ins_cur, index, false); rtr_info_update_btr(&ins_cur, &rtr_info); btr_cur_search_to_nth_level( - m_index, 0, dtuple, + index, 0, dtuple, PAGE_CUR_RTREE_INSERT, BTR_MODIFY_TREE, &ins_cur, __FILE__, __LINE__, &mtr); error = btr_cur_pessimistic_insert( flag, &ins_cur, &ins_offsets, - &row_heap, dtuple, &rec, + &heap, dtuple, &rec, &big_rec, 0, NULL, &mtr); } @@ -223,30 +215,26 @@ public: } } - mtr_commit(&mtr); + mtr.commit(); rtr_clean_rtr_info(&rtr_info, true); } - m_dtuple_vec->clear(); + m_dtuple_vec.clear(); return(error); } private: - /** Cache index rows made from a cluster index scan. Usually - for rows on single cluster index page */ - typedef std::vector<dtuple_t*, ut_allocator<dtuple_t*> > - idx_tuple_vec; - - /** vector used to cache index rows made from cluster index scan */ - idx_tuple_vec* const m_dtuple_vec; + /** Cache index rows made from a cluster index scan. Usually + for rows on single cluster index page */ + typedef std::vector<dtuple_t*, ut_allocator<dtuple_t*> > idx_tuple_vec; - /** the index being built */ - dict_index_t* const m_index; - - /** memory heap for creating index tuples */ - mem_heap_t* const m_heap; + /** vector used to cache index rows made from cluster index scan */ + idx_tuple_vec m_dtuple_vec; +public: + /** the index being built */ + dict_index_t*const index; }; /* Maximum pending doc memory limit in bytes for a fts tokenization thread */ @@ -1558,8 +1546,7 @@ row_mtuple_cmp( @param[in] trx_id transaction id @param[in] sp_tuples cached spatial rows @param[in] num_spatial number of spatial indexes -@param[in,out] heap heap for insert -@param[in,out] sp_heap heap for tuples +@param[in,out] heap temporary memory heap @param[in,out] pcur cluster index cursor @param[in,out] started whether mtr is active @param[in,out] mtr mini-transaction @@ -1568,10 +1555,9 @@ static dberr_t row_merge_spatial_rows( trx_id_t trx_id, - index_tuple_info_t** sp_tuples, + spatial_index_info** sp_tuples, ulint num_spatial, mem_heap_t* heap, - mem_heap_t* sp_heap, btr_pcur_t* pcur, bool& started, mtr_t* mtr) @@ -1580,10 +1566,10 @@ row_merge_spatial_rows( return DB_SUCCESS; for (ulint j= 0; j < num_spatial; j++) - if (dberr_t err= sp_tuples[j]->insert(trx_id, heap, pcur, started, mtr)) + if (dberr_t err= sp_tuples[j]->insert(trx_id, pcur, started, heap, mtr)) return err; - mem_heap_empty(sp_heap); + mem_heap_empty(heap); return DB_SUCCESS; } @@ -1699,8 +1685,7 @@ row_merge_read_clustered_index( os_event_t fts_parallel_sort_event = NULL; ibool fts_pll_sort = FALSE; int64_t sig_count = 0; - index_tuple_info_t** sp_tuples = NULL; - mem_heap_t* sp_heap = NULL; + spatial_index_info** sp_tuples = NULL; ulint num_spatial = 0; BtrBulk* clust_btr_bulk = NULL; bool clust_temp_file = false; @@ -1790,9 +1775,7 @@ row_merge_read_clustered_index( if (num_spatial > 0) { ulint count = 0; - sp_heap = mem_heap_create(512); - - sp_tuples = static_cast<index_tuple_info_t**>( + sp_tuples = static_cast<spatial_index_info**>( ut_malloc_nokey(num_spatial * sizeof(*sp_tuples))); @@ -1800,9 +1783,7 @@ row_merge_read_clustered_index( if (dict_index_is_spatial(index[i])) { sp_tuples[count] = UT_NEW_NOKEY( - index_tuple_info_t( - sp_heap, - index[i])); + spatial_index_info(index[i])); count++; } } @@ -1935,7 +1916,7 @@ row_merge_read_clustered_index( /* Insert the cached spatial index rows. */ err = row_merge_spatial_rows( trx->id, sp_tuples, num_spatial, - row_heap, sp_heap, &pcur, mtr_started, &mtr); + row_heap, &pcur, mtr_started, &mtr); if (err != DB_SUCCESS) { goto func_exit; @@ -2313,7 +2294,7 @@ write_buffers: continue; } - ut_ad(sp_tuples[s_idx_cnt]->get_index() + ut_ad(sp_tuples[s_idx_cnt]->index == buf->index); /* If the geometry field is invalid, report @@ -2323,7 +2304,7 @@ write_buffers: break; } - sp_tuples[s_idx_cnt]->add(row, ext); + sp_tuples[s_idx_cnt]->add(row, ext, buf->heap); s_idx_cnt++; continue; @@ -2444,7 +2425,7 @@ write_buffers: err = row_merge_spatial_rows( trx->id, sp_tuples, num_spatial, - row_heap, sp_heap, + row_heap, &pcur, mtr_started, &mtr); @@ -2802,10 +2783,6 @@ wait_again: UT_DELETE(sp_tuples[i]); } ut_free(sp_tuples); - - if (sp_heap) { - mem_heap_free(sp_heap); - } } /* Update the next Doc ID we used. Table should be locked, so |