diff options
author | Marko Mäkelä <marko.makela@mariadb.com> | 2019-08-16 10:51:20 +0300 |
---|---|---|
committer | Marko Mäkelä <marko.makela@mariadb.com> | 2019-08-16 10:51:20 +0300 |
commit | c221bcdce7714a74b89a02de941e8d8df2994ce3 (patch) | |
tree | 87a4e2d595ea3cc1465f212f26a9b9030655aa0c | |
parent | 3bbf008096fc997556459442bc2503c504248345 (diff) | |
parent | 395e1dcd176bbf0fcdb5d156bc58604590245a26 (diff) | |
download | mariadb-git-c221bcdce7714a74b89a02de941e8d8df2994ce3.tar.gz |
Merge 10.3 into 10.4
24 files changed, 563 insertions, 247 deletions
diff --git a/extra/innochecksum.cc b/extra/innochecksum.cc index f7fbb76b66b..aa591de944e 100644 --- a/extra/innochecksum.cc +++ b/extra/innochecksum.cc @@ -1557,10 +1557,8 @@ int main( byte* xdes = NULL; /* bytes read count */ ulint bytes; - /* current time */ - time_t now; /* last time */ - time_t lastt; + time_t lastt = 0; /* stat, to get file size. */ #ifdef _WIN32 struct _stat64 st; @@ -1903,7 +1901,6 @@ int main( /* main checksumming loop */ cur_page_num = start_page ? start_page : cur_page_num + 1; - lastt = 0; while (!feof(fil_in)) { bytes = read_file(buf, partial_page_read, @@ -1982,12 +1979,10 @@ first_non_zero: if (verbose && !read_from_stdin) { if ((cur_page_num % 64) == 0) { - now = time(0); + time_t now = time(0); if (!lastt) { lastt= now; - } - if (now - lastt >= 1 - && is_log_enabled) { + } else if (now - lastt >= 1 && is_log_enabled) { fprintf(log_file, "page::%llu " "okay: %.3f%% done\n", (cur_page_num - 1), diff --git a/mysql-test/main/win.result b/mysql-test/main/win.result index 51a0f35ad61..4adb5c84f1e 100644 --- a/mysql-test/main/win.result +++ b/mysql-test/main/win.result @@ -3654,6 +3654,41 @@ d x 00:00:02 NULL DROP TABLE t1; # +# MDEV-20351 Window function BIT_OR() OVER (..) return a wrong data type +# +CREATE TABLE t1 (pk INT, a INT, b BIGINT UNSIGNED); +INSERT INTO t1 VALUES (1, 0, 1), (2, 0, 18446744073709551615); +CREATE TABLE t2 AS +SELECT pk, a, bit_or(b) AS bit_or FROM t1 GROUP BY pk; +SHOW CREATE TABLE t2; +Table Create Table +t2 CREATE TABLE `t2` ( + `pk` int(11) DEFAULT NULL, + `a` int(11) DEFAULT NULL, + `bit_or` bigint(21) unsigned NOT NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +SELECT * FROM t1; +pk a b +1 0 1 +2 0 18446744073709551615 +DROP TABLE t2; +CREATE OR REPLACE TABLE t2 AS +SELECT pk, a, BIT_OR(b) OVER (PARTITION BY a ORDER BY pk ROWS BETWEEN 1 PRECEDING AND 1 FOLLOWING) AS bit_or +FROM t1; +SHOW CREATE TABLE t2; +Table Create Table +t2 CREATE TABLE `t2` ( + `pk` int(11) DEFAULT NULL, + `a` int(11) DEFAULT NULL, + `bit_or` bigint(21) unsigned NOT NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +SELECT * FROM t2; +pk a bit_or +1 0 18446744073709551615 +2 0 18446744073709551615 +DROP TABLE t2; +DROP TABLE t1; +# # End of 10.3 tests # # diff --git a/mysql-test/main/win.test b/mysql-test/main/win.test index 01b8f17b0f2..3d5fb2240de 100644 --- a/mysql-test/main/win.test +++ b/mysql-test/main/win.test @@ -2359,6 +2359,29 @@ INSERT INTO t1 VALUES ('00:00:01'),('00:00:02'); SELECT *, LEAD(d) OVER (ORDER BY d) AS x FROM t1; DROP TABLE t1; + +--echo # +--echo # MDEV-20351 Window function BIT_OR() OVER (..) return a wrong data type +--echo # +CREATE TABLE t1 (pk INT, a INT, b BIGINT UNSIGNED); +INSERT INTO t1 VALUES (1, 0, 1), (2, 0, 18446744073709551615); + +CREATE TABLE t2 AS +SELECT pk, a, bit_or(b) AS bit_or FROM t1 GROUP BY pk; +SHOW CREATE TABLE t2; +SELECT * FROM t1; +DROP TABLE t2; + +CREATE OR REPLACE TABLE t2 AS +SELECT pk, a, BIT_OR(b) OVER (PARTITION BY a ORDER BY pk ROWS BETWEEN 1 PRECEDING AND 1 FOLLOWING) AS bit_or + FROM t1; +SHOW CREATE TABLE t2; +SELECT * FROM t2; +DROP TABLE t2; + +DROP TABLE t1; + + --echo # --echo # End of 10.3 tests --echo # diff --git a/mysql-test/suite/galera/disabled.def b/mysql-test/suite/galera/disabled.def index 92a806710da..6306686e53d 100644 --- a/mysql-test/suite/galera/disabled.def +++ b/mysql-test/suite/galera/disabled.def @@ -47,3 +47,4 @@ galera_sst_mariabackup_encrypt_with_key : MDEV-19926 Galera SST tests fail galera_wan : MDEV-17259: Test failure on galera.galera_wan mysql-wsrep#198 : MDEV-18935 Galera test mysql-wsrep#198 sporaric assertion transaction.cpp:362: int wsrep::transaction::before_commit(): Assertion `state() == s_executing || state() == s_committing || state() == s_must_abort || state() == s_replaying' failed. partition : MDEV-19958 Galera test failure on galera.partition +query_cache: MDEV-15805 Test failure on galera.query_cache
\ No newline at end of file diff --git a/mysql-test/suite/innodb/r/innodb_bug14704286.result b/mysql-test/suite/innodb/r/innodb_bug14704286.result deleted file mode 100644 index f84d5206e07..00000000000 --- a/mysql-test/suite/innodb/r/innodb_bug14704286.result +++ /dev/null @@ -1,65 +0,0 @@ -use test; -drop table if exists t1; -create table t1 (id int primary key, value int, value2 int, -value3 int, index(value,value2)) engine=innodb; -insert into t1 values -(10,10,10,10),(11,11,11,11),(12,12,12,12),(13,13,13,13),(14,14,14,14), -(15,15,15,15),(16,16,16,16),(17,17,17,17),(18,18,18,18),(19,19,19,19), -(20,20,20,20); -connect conn1, localhost, root,,; -connect conn2, localhost, root,,; -connect conn3, localhost, root,,; -connection conn1; -use test; -start transaction with consistent snapshot; -connection conn2; -use test; -CREATE PROCEDURE update_t1() -BEGIN -DECLARE i INT DEFAULT 1; -while (i <= 5000) DO -update test.t1 set value2=value2+1, value3=value3+1 where id=12; -SET i = i + 1; -END WHILE; -END| -set autocommit=0; -CALL update_t1(); -select * from t1; -id value value2 value3 -10 10 10 10 -11 11 11 11 -12 12 5012 5012 -13 13 13 13 -14 14 14 14 -15 15 15 15 -16 16 16 16 -17 17 17 17 -18 18 18 18 -19 19 19 19 -20 20 20 20 -set autocommit=1; -select * from t1; -id value value2 value3 -10 10 10 10 -11 11 11 11 -12 12 5012 5012 -13 13 13 13 -14 14 14 14 -15 15 15 15 -16 16 16 16 -17 17 17 17 -18 18 18 18 -19 19 19 19 -20 20 20 20 -connection conn1; -select * from t1 force index(value) where value=12; -connection conn3; -kill query @id; -connection conn1; -ERROR 70100: Query execution was interrupted -connection default; -disconnect conn1; -disconnect conn2; -disconnect conn3; -drop procedure if exists update_t1; -drop table if exists t1; diff --git a/mysql-test/suite/innodb/r/innodb_bug84958.result b/mysql-test/suite/innodb/r/innodb_bug84958.result new file mode 100644 index 00000000000..1a59a10eb2f --- /dev/null +++ b/mysql-test/suite/innodb/r/innodb_bug84958.result @@ -0,0 +1,81 @@ +# +# Bug #84958 InnoDB's MVCC has O(N^2) behaviors +# https://bugs.mysql.com/bug.php?id=84958 +# +# Set up the test with a procedure and a function. +# +CREATE PROCEDURE insert_n(start int, end int) +BEGIN +DECLARE i INT DEFAULT start; +WHILE i <= end do +INSERT INTO t1 VALUES (1, 2, 3) ON DUPLICATE KEY UPDATE c = i; +SET i = i + 1; +END WHILE; +END~~ +CREATE FUNCTION num_pages_get() +RETURNS INT +BEGIN +DECLARE ret INT; +SELECT variable_value INTO ret +FROM information_schema.global_status +WHERE variable_name = 'innodb_buffer_pool_read_requests'; +RETURN ret; +END~~ +# +# Create a table with one record in it and start an RR transaction +# +CREATE TABLE t1 (a INT, b INT, c INT, PRIMARY KEY(a,b), KEY (b,c)) +ENGINE=InnoDB; +BEGIN; +SELECT * FROM t1; +a b c +# +# Create 100 newer record versions in con2 and con3 +# +connect con2, localhost, root,,; +connection con2; +INSERT INTO t1 VALUES (1, 2, 3) ON DUPLICATE KEY UPDATE c = NULL; +CALL insert_n(1, 50);; +connect con3, localhost, root,,; +connection con3; +CALL insert_n(51, 100);; +connection con2; +connection con3; +INSERT INTO t1 VALUES (1, 2, 1) ON DUPLICATE KEY UPDATE c = NULL; +connection default; +# +# Connect to default and record how many pages were accessed +# when selecting the record using the secondary key. +# +SET @num_pages_1 = num_pages_get(); +SELECT * FROM t1 force index (b); +a b c +SET @num_pages_2= num_pages_get(); +SELECT @num_pages_2 - @num_pages_1 < 500; +@num_pages_2 - @num_pages_1 < 500 +1 +# +# Commit and show the final record. +# +SELECT * FROM t1; +a b c +SELECT * FROM t1 force index (b); +a b c +COMMIT; +SELECT * FROM t1 force index (b); +a b c +1 2 NULL +SELECT * FROM t1; +a b c +1 2 NULL +CHECK TABLE t1; +Table Op Msg_type Msg_text +test.t1 check status OK +# +# Cleanup +# +disconnect con2; +disconnect con3; +DROP TABLE t1; +DROP PROCEDURE insert_n; +DROP FUNCTION num_pages_get; diff --git a/mysql-test/suite/innodb/r/undo_truncate_recover.result b/mysql-test/suite/innodb/r/undo_truncate_recover.result index 212a1658e18..428a2dec0bb 100644 --- a/mysql-test/suite/innodb/r/undo_truncate_recover.result +++ b/mysql-test/suite/innodb/r/undo_truncate_recover.result @@ -9,8 +9,8 @@ update t1 set c = 'MariaDB'; update t1 set c = 'InnoDB'; set global debug_dbug = '+d,ib_undo_trunc'; commit; +drop table t1; call mtr.add_suppression("InnoDB: innodb_undo_tablespaces=0 disables dedicated undo log tablespaces"); SET GLOBAL innodb_fast_shutdown=0; FOUND 1 /ib_undo_trunc/ in mysqld.1.err # restart: with restart_parameters -drop table t1; diff --git a/mysql-test/suite/innodb/t/innodb_bug14704286.test b/mysql-test/suite/innodb/t/innodb_bug14704286.test deleted file mode 100644 index fb5e6b829a1..00000000000 --- a/mysql-test/suite/innodb/t/innodb_bug14704286.test +++ /dev/null @@ -1,95 +0,0 @@ ---source include/have_innodb.inc - -# -# create test-bed to run test -# -use test; ---disable_warnings -drop table if exists t1; ---enable_warnings -create table t1 (id int primary key, value int, value2 int, -value3 int, index(value,value2)) engine=innodb; - -insert into t1 values -(10,10,10,10),(11,11,11,11),(12,12,12,12),(13,13,13,13),(14,14,14,14), -(15,15,15,15),(16,16,16,16),(17,17,17,17),(18,18,18,18),(19,19,19,19), -(20,20,20,20); -let $ID= `SELECT @id := CONNECTION_ID()`; - -# -# we need multiple connections as we need to keep one connection -# active with trx requesting consistent read. -# -connect (conn1, localhost, root,,); -connect (conn2, localhost, root,,); -connect (conn3, localhost, root,,); - -# -# start trx with consistent read -# -connection conn1; -use test; - -start transaction with consistent snapshot; - -# -# update table such that secondary index is updated. -# -connection conn2; -use test; -delimiter |; -CREATE PROCEDURE update_t1() -BEGIN - DECLARE i INT DEFAULT 1; - while (i <= 5000) DO - update test.t1 set value2=value2+1, value3=value3+1 where id=12; - SET i = i + 1; - END WHILE; -END| - -delimiter ;| -set autocommit=0; -CALL update_t1(); -select * from t1; -set autocommit=1; -select * from t1; - -# -# Now try to fire select query from connection-1 enforcing -# use of secondary index. -# -connection conn1; -let $ID= `SELECT @id := CONNECTION_ID()`; -#--error ER_QUERY_INTERRUPTED ---send -select * from t1 force index(value) where value=12; - -# -# select is going to take good time so let's kill query. -# -connection conn3; -let $wait_condition= - select * from information_schema.processlist where state = 'Sending data' and - info = 'select * from t1 force index(value) where value=12'; ---source include/wait_condition.inc -let $ignore= `SELECT @id := $ID`; -kill query @id; - -# -# reap the value of connection-1 -# -connection conn1; ---error ER_QUERY_INTERRUPTED -reap; - -# -# clean test-bed. -# -connection default; -disconnect conn1; -disconnect conn2; -disconnect conn3; -drop procedure if exists update_t1; -drop table if exists t1; - - diff --git a/mysql-test/suite/innodb/t/innodb_bug84958.test b/mysql-test/suite/innodb/t/innodb_bug84958.test new file mode 100644 index 00000000000..4456df21cb9 --- /dev/null +++ b/mysql-test/suite/innodb/t/innodb_bug84958.test @@ -0,0 +1,86 @@ +--echo # +--echo # Bug #84958 InnoDB's MVCC has O(N^2) behaviors +--echo # https://bugs.mysql.com/bug.php?id=84958 +--echo # +--echo # Set up the test with a procedure and a function. +--echo # + +--source include/have_innodb.inc + +DELIMITER ~~; +CREATE PROCEDURE insert_n(start int, end int) +BEGIN + DECLARE i INT DEFAULT start; + WHILE i <= end do + INSERT INTO t1 VALUES (1, 2, 3) ON DUPLICATE KEY UPDATE c = i; + SET i = i + 1; + END WHILE; +END~~ + +CREATE FUNCTION num_pages_get() +RETURNS INT +BEGIN + DECLARE ret INT; + SELECT variable_value INTO ret + FROM information_schema.global_status + WHERE variable_name = 'innodb_buffer_pool_read_requests'; + RETURN ret; +END~~ +DELIMITER ;~~ + +--echo # +--echo # Create a table with one record in it and start an RR transaction +--echo # +CREATE TABLE t1 (a INT, b INT, c INT, PRIMARY KEY(a,b), KEY (b,c)) +ENGINE=InnoDB; +BEGIN; +SELECT * FROM t1; + +--echo # +--echo # Create 100 newer record versions in con2 and con3 +--echo # +connect (con2, localhost, root,,); +connection con2; +INSERT INTO t1 VALUES (1, 2, 3) ON DUPLICATE KEY UPDATE c = NULL; +--send CALL insert_n(1, 50); + +connect (con3, localhost, root,,); +connection con3; +--send CALL insert_n(51, 100); + +connection con2; +reap; +connection con3; +reap; +INSERT INTO t1 VALUES (1, 2, 1) ON DUPLICATE KEY UPDATE c = NULL; + +connection default; + +--echo # +--echo # Connect to default and record how many pages were accessed +--echo # when selecting the record using the secondary key. +--echo # +SET @num_pages_1 = num_pages_get(); +SELECT * FROM t1 force index (b); +SET @num_pages_2= num_pages_get(); + +SELECT @num_pages_2 - @num_pages_1 < 500; + +--echo # +--echo # Commit and show the final record. +--echo # +SELECT * FROM t1; +SELECT * FROM t1 force index (b); +COMMIT; +SELECT * FROM t1 force index (b); +SELECT * FROM t1; +CHECK TABLE t1; + +--echo # +--echo # Cleanup +--echo # +disconnect con2; +disconnect con3; +DROP TABLE t1; +DROP PROCEDURE insert_n; +DROP FUNCTION num_pages_get; diff --git a/mysql-test/suite/innodb/t/undo_truncate_recover.opt b/mysql-test/suite/innodb/t/undo_truncate_recover.opt new file mode 100644 index 00000000000..a1207721427 --- /dev/null +++ b/mysql-test/suite/innodb/t/undo_truncate_recover.opt @@ -0,0 +1 @@ +--innodb-purge-threads=1 diff --git a/mysql-test/suite/innodb/t/undo_truncate_recover.test b/mysql-test/suite/innodb/t/undo_truncate_recover.test index a143c25eaf0..64b1f6f23a1 100644 --- a/mysql-test/suite/innodb/t/undo_truncate_recover.test +++ b/mysql-test/suite/innodb/t/undo_truncate_recover.test @@ -35,6 +35,7 @@ update t1 set c = 'MariaDB'; update t1 set c = 'InnoDB'; eval set global debug_dbug = '+d,$SEARCH_PATTERN'; commit; +drop table t1; call mtr.add_suppression("InnoDB: innodb_undo_tablespaces=0 disables dedicated undo log tablespaces"); SET GLOBAL innodb_fast_shutdown=0; --source include/shutdown_mysqld.inc @@ -51,5 +52,3 @@ if ($checksum_algorithm == "strict_crc32") let $restart_parameters= $restart_parameters --innodb_checksum_algorithm=strict_full_crc32; } --source include/start_mysqld.inc - -drop table t1; diff --git a/mysql-test/suite/rpl/r/rpl_failed_drop_tbl_binlog.result b/mysql-test/suite/rpl/r/rpl_failed_drop_tbl_binlog.result new file mode 100644 index 00000000000..df36fa82e0f --- /dev/null +++ b/mysql-test/suite/rpl/r/rpl_failed_drop_tbl_binlog.result @@ -0,0 +1,32 @@ +include/master-slave.inc +[connection master] +create table t1 (a int) engine=innodb; +create table t2 (b longblob) engine=innodb; +create table t3 (c int) engine=innodb; +insert into t2 values (repeat('b',1024*1024)); +insert into t2 select * from t2; +insert into t2 select * from t2; +insert into t2 select * from t2; +insert into t2 select * from t2; +set debug_sync='rm_table_no_locks_before_delete_table SIGNAL nogo WAIT_FOR go EXECUTE 2'; +drop table t1, t2, t3; +connect foo,localhost,root; +set debug_sync='now SIGNAL go'; +kill query CONNECTION_ID; +connection master; +ERROR 70100: Query execution was interrupted +"Tables t2 and t3 should be listed" +SHOW TABLES; +Tables_in_test +t2 +t3 +include/show_binlog_events.inc +Log_name Pos Event_type Server_id End_log_pos Info +master-bin.000001 # Gtid # # GTID #-#-# +master-bin.000001 # Query # # use `test`; DROP TABLE `t1` /* generated by server */ +connection slave; +drop table t2, t3; +connection master; +set debug_sync='RESET'; +drop table t2, t3; +include/rpl_end.inc diff --git a/mysql-test/suite/rpl/t/rpl_failed_drop_tbl_binlog.test b/mysql-test/suite/rpl/t/rpl_failed_drop_tbl_binlog.test new file mode 100644 index 00000000000..281e2a2ab47 --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_failed_drop_tbl_binlog.test @@ -0,0 +1,64 @@ +# ==== Purpose ==== +# +# Check that when the execution of a DROP TABLE command with single table +# fails it should not be written to the binary log. Also test that when the +# execution of DROP TABLE command with multiple tables fails the command +# should be written into the binary log. +# +# ==== Implementation ==== +# +# Steps: +# 0 - Create tables named t1, t2, t3 +# 1 - Execute DROP TABLE t1,t2,t3 command. +# 2 - Kill the DROP TABLE command while it is trying to drop table 't2'. +# 3 - Verify that tables t2,t3 are present after the DROP command execution +# was interrupted. +# 4 - Check that table 't1' is present in binary log as part of DROP +# command. +# +# ==== References ==== +# +# MDEV-20348: DROP TABLE IF EXISTS killed on master but was replicated. +# + +--source include/have_innodb.inc +--source include/have_debug_sync.inc +--source include/have_binlog_format_statement.inc +--source include/master-slave.inc + +create table t1 (a int) engine=innodb; +create table t2 (b longblob) engine=innodb; +create table t3 (c int) engine=innodb; +insert into t2 values (repeat('b',1024*1024)); +insert into t2 select * from t2; +insert into t2 select * from t2; +insert into t2 select * from t2; +insert into t2 select * from t2; +let $binlog_start= query_get_value(SHOW MASTER STATUS, Position, 1); + +let $id=`select connection_id()`; +set debug_sync='rm_table_no_locks_before_delete_table SIGNAL nogo WAIT_FOR go EXECUTE 2'; +send drop table t1, t2, t3; + +connect foo,localhost,root; +set debug_sync='now SIGNAL go'; +let $wait_condition=select 1 from information_schema.processlist where state like 'debug sync point:%'; +source include/wait_condition.inc; +--replace_result $id CONNECTION_ID +eval kill query $id; + +connection master; +error ER_QUERY_INTERRUPTED; +reap; + +--echo "Tables t2 and t3 should be listed" +SHOW TABLES; +--source include/show_binlog_events.inc +--sync_slave_with_master +drop table t2, t3; + +connection master; +set debug_sync='RESET'; +drop table t2, t3; + +source include/rpl_end.inc; diff --git a/mysql-test/valgrind.supp b/mysql-test/valgrind.supp index 6e275ac478e..e58d0a10124 100644 --- a/mysql-test/valgrind.supp +++ b/mysql-test/valgrind.supp @@ -1,5 +1,5 @@ # Copyright (c) 2005, 2015, Oracle and/or its affiliates. -# Copyright (c) 2008, 2017, MariaDB +# Copyright (c) 2008, 2019, MariaDB # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU Library General Public @@ -1799,3 +1799,121 @@ fun:FIPS_mode_set obj:/usr/lib64/libcrypto.so* } + + + +## +## The following is a copy of facebook/mysql-5.6 suppressions: +## + +# +# RocksDB Storage Engine suppressions start +# + +{ + Still reachable for once-per-process initializations + Memcheck:Leak + match-leak-kinds: reachable + ... + fun:_ZN7rocksdb16ThreadStatusUtil19NewColumnFamilyInfoEPKNS_2DBEPKNS_16ColumnFamilyDataERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEPKNS_3EnvE + fun:_ZNK7rocksdb6DBImpl21NewThreadStatusCfInfoEPNS_16ColumnFamilyDataE + fun:_ZN7rocksdb2DB4OpenERKNS_9DBOptionsERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKSt6vectorINS_22ColumnFamilyDescriptorESaISD_EEPSC_IPNS_18ColumnFamilyHandleESaISJ_EEPPS0_ + fun:_ZN7rocksdb13TransactionDB4OpenERKNS_9DBOptionsERKNS_20TransactionDBOptionsERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKSt6vectorINS_22ColumnFamilyDescriptorESaISG_EEPSF_IPNS_18ColumnFamilyHandleESaISM_EEPPS0_ + fun:_ZN7myrocksL17rocksdb_init_funcEPv +} + + +{ + Still reachable for once-per-process initializations 2 + Memcheck:Leak + match-leak-kinds: reachable + ... + fun:_ZN7rocksdb16ThreadStatusUtil19NewColumnFamilyInfoEPKNS_2DBEPKNS_16ColumnFamilyDataERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEPKNS_3EnvE + fun:_ZNK7rocksdb6DBImpl21NewThreadStatusCfInfoEPNS_16ColumnFamilyDataE + fun:_ZN7rocksdb6DBImpl4OpenERKNS_9DBOptionsERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKSt6vectorINS_22ColumnFamilyDescriptorESaISD_EEPSC_IPNS_18ColumnFamilyHandleESaISJ_EEPPNS_2DBEbb + fun:_ZN7rocksdb13TransactionDB4OpenERKNS_9DBOptionsERKNS_20TransactionDBOptionsERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKSt6vectorINS_22ColumnFamilyDescriptorESaISG_EEPSF_IPNS_18ColumnFamilyHandleESaISM_EEPPS0_ +# fun:_ZN7myrocksL17rocksdb_init_funcEPv +# ^ commenting the above out because we are hitting the --num-callers=16 +# limitation that MTR sets for valgrind +} + +{ + Still reachable for once-per-process initializations 3 + Memcheck:Leak + match-leak-kinds: reachable + ... + fun:_ZN7rocksdb16ThreadStatusUtil19NewColumnFamilyInfoEPKNS_2DBEPKNS_16ColumnFamilyDataERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEPKNS_3EnvE + fun:_ZNK7rocksdb6DBImpl21NewThreadStatusCfInfoEPNS_16ColumnFamilyDataE + fun:_ZN7rocksdb6DBImpl22CreateColumnFamilyImplERKNS_19ColumnFamilyOptionsERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEPPNS_18ColumnFamilyHandleE +} + +{ + Still reachable for once-per-process initializations + Memcheck:Leak + match-leak-kinds: reachable + ... + fun:_ZN7rocksdb19ThreadStatusUpdater14RegisterThreadENS_12ThreadStatus10ThreadTypeEm + fun:_ZN7rocksdb16ThreadStatusUtil14RegisterThreadEPKNS_3EnvENS_12ThreadStatus10ThreadTypeE + fun:_ZN7rocksdb14ThreadPoolImpl4Impl15BGThreadWrapperEPv + ... +} + +{ + Still reachable for once-per-process initializations + Memcheck:Leak + match-leak-kinds: reachable + ... + fun:_ZN7rocksdb14ThreadLocalPtr14InitSingletonsEv + fun:_ZN7rocksdb3Env7DefaultEv + fun:_ZN7rocksdb9DBOptionsC1Ev + ... + fun:_ZN7myrocksL27rdb_init_rocksdb_db_optionsEv +} + +{ + Still reachable for once-per-process initializations + Memcheck:Leak + match-leak-kinds: reachable + ... + fun:_ZN7rocksdb12_GLOBAL__N_18PosixEnv* + fun:_ZN7rocksdb3Env7DefaultEv + fun:_ZN7rocksdb9DBOptionsC1Ev + ... + fun:_ZN7myrocksL27rdb_init_rocksdb_db_optionsEv +} + +{ + Still reachable for thread local storage initialization (SetHandle) + Memcheck:Leak + match-leak-kinds: reachable + ... + fun:_ZNSt13unordered_mapIjPFvPvESt4hashIjESt8equal_toIjESaISt4pairIKjS2_EEEixERS8_ + fun:_ZN7rocksdb14ThreadLocalPtr10StaticMeta10SetHandlerEjPFvPvE + fun:_ZN7rocksdb14ThreadLocalPtrC1EPFvPvE + ... +} + +{ + Still reachable for thread local storage initialization (ReclaimId) + Memcheck:Leak + match-leak-kinds: reachable + ... + fun:_ZN7rocksdb10autovectorIjLm8EE9push_backERKj + fun:_ZN7rocksdb14ThreadLocalPtr10StaticMeta9ReclaimIdEj + fun:_ZN7rocksdb14ThreadLocalPtrD1Ev + ... +} + +{ + Static initialization + Memcheck:Leak + match-leak-kinds: reachable + ... + fun:_Z41__static_initialization_and_destruction_0ii + ... +} + +## +## RocksDB Storage Engine suppressions end +## + diff --git a/sql/item.h b/sql/item.h index c39a3514d04..5cda78d42fa 100644 --- a/sql/item.h +++ b/sql/item.h @@ -2,7 +2,7 @@ #define SQL_ITEM_INCLUDED /* Copyright (c) 2000, 2017, Oracle and/or its affiliates. - Copyright (c) 2009, 2018, MariaDB Corporation + Copyright (c) 2009, 2019, 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 @@ -719,7 +719,6 @@ public: class Item: public Value_source, public Type_all_attributes { - void operator=(Item &); /** The index in the JOIN::join_tab array of the JOIN_TAB this Item is attached to. Items are attached (or 'pushed') to JOIN_TABs during optimization by the diff --git a/sql/item_windowfunc.h b/sql/item_windowfunc.h index 5c63eb11547..5b3aa4f0e41 100644 --- a/sql/item_windowfunc.h +++ b/sql/item_windowfunc.h @@ -1294,7 +1294,7 @@ public: bool fix_length_and_dec() { - decimals = window_func()->decimals; + Type_std_attributes::set(window_func()); return FALSE; } diff --git a/sql/sql_list.h b/sql/sql_list.h index f5d8ed98b02..3585adbd714 100644 --- a/sql/sql_list.h +++ b/sql/sql_list.h @@ -1,6 +1,7 @@ #ifndef INCLUDES_MYSQL_SQL_LIST_H #define INCLUDES_MYSQL_SQL_LIST_H /* Copyright (c) 2000, 2012, Oracle and/or its affiliates. + Copyright (c) 2019, 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 @@ -48,6 +49,14 @@ public: next= elements ? tmp.next : &first; } + SQL_I_List& operator=(const SQL_I_List &tmp) + { + elements= tmp.elements; + first= tmp.first; + next= tmp.next; + return *this; + } + inline void empty() { elements= 0; @@ -488,7 +497,6 @@ template <class T> class List :public base_list { public: inline List() :base_list() {} - inline List(const List<T> &tmp) :base_list(tmp) {} inline List(const List<T> &tmp, MEM_ROOT *mem_root) : base_list(tmp, mem_root) {} inline bool push_back(T *a) { return base_list::push_back(a); } diff --git a/sql/sql_table.cc b/sql/sql_table.cc index f94676730b7..f3e4d35c0f5 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -2392,35 +2392,6 @@ int mysql_rm_table_no_locks(THD *thd, TABLE_LIST *tables, bool if_exists, /* remove .frm file and engine files */ path_length= build_table_filename(path, sizeof(path) - 1, db.str, alias.str, reg_ext, 0); - - /* - This handles the case where a "DROP" was executed and a regular - table "may be" dropped as drop_temporary is FALSE and error is - TRUE. If the error was FALSE a temporary table was dropped and - regardless of the status of drop_temporary a "DROP TEMPORARY" - must be used. - */ - if (!dont_log_query) - { - /* - Note that unless if_exists is TRUE or a temporary table was deleted, - there is no means to know if the statement should be written to the - binary log. See further information on this variable in what follows. - */ - non_tmp_table_deleted= (if_exists ? TRUE : non_tmp_table_deleted); - /* - Don't write the database name if it is the current one (or if - thd->db is NULL). - */ - if (thd->db.str == NULL || cmp(&db, &thd->db) != 0) - { - append_identifier(thd, &built_query, &db); - built_query.append("."); - } - - append_identifier(thd, &built_query, &table->table_name); - built_query.append(","); - } } DEBUG_SYNC(thd, "rm_table_no_locks_before_delete_table"); error= 0; @@ -2500,9 +2471,16 @@ int mysql_rm_table_no_locks(THD *thd, TABLE_LIST *tables, bool if_exists, // Remove extension for delete *(end= path + path_length - reg_ext_length)= '\0'; - error= ha_delete_table(thd, table_type, path, &db, &table->table_name, - !dont_log_query); - if (!error) + if ((error= ha_delete_table(thd, table_type, path, &db, &table->table_name, + !dont_log_query))) + { + if (thd->is_killed()) + { + error= -1; + goto err; + } + } + else { /* Delete the table definition file */ strmov(end,reg_ext); @@ -2546,7 +2524,7 @@ int mysql_rm_table_no_locks(THD *thd, TABLE_LIST *tables, bool if_exists, if (error) { if (wrong_tables.length()) - wrong_tables.append(','); + wrong_tables.append(','); wrong_tables.append(&db); wrong_tables.append('.'); wrong_tables.append(&table->table_name); @@ -2559,6 +2537,22 @@ int mysql_rm_table_no_locks(THD *thd, TABLE_LIST *tables, bool if_exists, mysql_audit_drop_table(thd, table); } + if (!dont_log_query && !drop_temporary) + { + non_tmp_table_deleted= (if_exists ? TRUE : non_tmp_table_deleted); + /* + Don't write the database name if it is the current one (or if + thd->db is NULL). + */ + if (thd->db.str == NULL || cmp(&db, &thd->db) != 0) + { + append_identifier(thd, &built_query, &db); + built_query.append("."); + } + + append_identifier(thd, &built_query, &table->table_name); + built_query.append(","); + } DBUG_PRINT("table", ("table: %p s: %p", table->table, table->table ? table->table->s : NULL)); } diff --git a/storage/innobase/row/row0ins.cc b/storage/innobase/row/row0ins.cc index e1749f9ea78..a036821cab1 100644 --- a/storage/innobase/row/row0ins.cc +++ b/storage/innobase/row/row0ins.cc @@ -71,7 +71,11 @@ ins_node_create( ins_node_t* node; node = static_cast<ins_node_t*>( - mem_heap_alloc(heap, sizeof(ins_node_t))); + mem_heap_zalloc(heap, sizeof(ins_node_t))); + + if (!node) { + return(NULL); + } node->common.type = QUE_NODE_INSERT; @@ -79,12 +83,6 @@ ins_node_create( node->state = INS_NODE_SET_IX_LOCK; node->table = table; - node->index = NULL; - node->entry = NULL; - - node->select = NULL; - - node->trx_id = 0; node->entry_sys_heap = mem_heap_create(128); diff --git a/storage/innobase/row/row0log.cc b/storage/innobase/row/row0log.cc index 25930cb86f1..1a10657cf99 100644 --- a/storage/innobase/row/row0log.cc +++ b/storage/innobase/row/row0log.cc @@ -1005,7 +1005,7 @@ row_log_table_low( extra_size = rec_extra_size + is_instant; unsigned fake_extra_size = 0; - byte fake_extra_buf[2]; + byte fake_extra_buf[3]; if (is_instant && UNIV_UNLIKELY(!index->is_instant())) { /* The source table was emptied after ALTER TABLE started, and it was converted to non-instant format. @@ -1017,9 +1017,9 @@ row_log_table_low( fake_extra_size = rec_get_n_add_field_len(n_add); ut_ad(fake_extra_size == 1 || fake_extra_size == 2); extra_size += fake_extra_size; - byte* fake_extra = fake_extra_buf + fake_extra_size - 1; + byte* fake_extra = fake_extra_buf + fake_extra_size; rec_set_n_add_field(fake_extra, n_add); - ut_ad(fake_extra + 1 == fake_extra_buf); + ut_ad(fake_extra == fake_extra_buf); } mrec_size = ROW_LOG_HEADER_SIZE @@ -1078,7 +1078,7 @@ row_log_table_low( memcpy(b, rec - rec_extra_size - omit_size, rec_extra_size); b += rec_extra_size; - memcpy(b, fake_extra_buf, fake_extra_size); + memcpy(b, fake_extra_buf + 1, fake_extra_size); b += fake_extra_size; ulint len; ulint trx_id_offs = rec_get_nth_field_offs( diff --git a/storage/innobase/row/row0mysql.cc b/storage/innobase/row/row0mysql.cc index 6d70cbfa0fa..3ca8b54354c 100644 --- a/storage/innobase/row/row0mysql.cc +++ b/storage/innobase/row/row0mysql.cc @@ -2151,7 +2151,9 @@ This is used in UPDATE CASCADE/SET NULL of a system versioning table. @return DB_SUCCESS or some error */ static dberr_t row_update_vers_insert(que_thr_t* thr, upd_node_t* node) { - const trx_t* trx = thr_get_trx(thr); + trx_t* trx = thr_get_trx(thr); + dfield_t* row_end; + char row_end_data[8]; dict_table_t* table = node->table; ut_ad(table->versioned()); @@ -2162,10 +2164,15 @@ static dberr_t row_update_vers_insert(que_thr_t* thr, upd_node_t* node) ins_node_t* insert_node = ins_node_create(INS_DIRECT, table, node->historical_heap); + if (!insert_node) { + trx->error_state = DB_OUT_OF_MEMORY; + goto exit; + } + + insert_node->common.parent = thr; ins_node_set_new_row(insert_node, row); - dfield_t* row_end = dtuple_get_nth_field(row, table->vers_end); - char row_end_data[8]; + row_end = dtuple_get_nth_field(row, table->vers_end); if (dict_table_get_nth_col(table, table->vers_end)->vers_native()) { mach_write_to_8(row_end_data, trx->id); dfield_set_data(row_end, row_end_data, 8); @@ -2203,6 +2210,7 @@ static dberr_t row_update_vers_insert(que_thr_t* thr, upd_node_t* node) } } exit: + que_graph_free_recursive(insert_node); mem_heap_free(node->historical_heap); node->historical_heap = NULL; return trx->error_state; diff --git a/storage/innobase/row/row0sel.cc b/storage/innobase/row/row0sel.cc index f7eec2dc8c2..6c7a54ece7d 100644 --- a/storage/innobase/row/row0sel.cc +++ b/storage/innobase/row/row0sel.cc @@ -3199,14 +3199,29 @@ row_sel_build_prev_vers_for_mysql( return(err); } +/** Helper class to cache clust_rec and old_ver */ +class Row_sel_get_clust_rec_for_mysql +{ + const rec_t *cached_clust_rec; + rec_t *cached_old_vers; + +public: + Row_sel_get_clust_rec_for_mysql() : + cached_clust_rec(NULL), cached_old_vers(NULL) {} + + dberr_t operator()(row_prebuilt_t *prebuilt, dict_index_t *sec_index, + const rec_t *rec, que_thr_t *thr, const rec_t **out_rec, + ulint **offsets, mem_heap_t **offset_heap, + dtuple_t **vrow, mtr_t *mtr); +}; + /*********************************************************************//** Retrieves the clustered index record corresponding to a record in a non-clustered index. Does the necessary locking. Used in the MySQL interface. @return DB_SUCCESS, DB_SUCCESS_LOCKED_REC, or error code */ -static MY_ATTRIBUTE((warn_unused_result)) dberr_t -row_sel_get_clust_rec_for_mysql( +Row_sel_get_clust_rec_for_mysql::operator()( /*============================*/ row_prebuilt_t* prebuilt,/*!< in: prebuilt struct in the handle */ dict_index_t* sec_index,/*!< in: secondary index where rec resides */ @@ -3398,15 +3413,36 @@ row_sel_get_clust_rec_for_mysql( clust_rec, clust_index, *offsets, &trx->read_view)) { - /* The following call returns 'offsets' associated with - 'old_vers' */ - err = row_sel_build_prev_vers_for_mysql( - &trx->read_view, clust_index, prebuilt, - clust_rec, offsets, offset_heap, &old_vers, - vrow, mtr); + if (clust_rec != cached_clust_rec) { + /* The following call returns 'offsets' associated with + 'old_vers' */ + err = row_sel_build_prev_vers_for_mysql( + &trx->read_view, clust_index, prebuilt, + clust_rec, offsets, offset_heap, &old_vers, + vrow, mtr); + + if (err != DB_SUCCESS) { - if (err != DB_SUCCESS || old_vers == NULL) { + goto err_exit; + } + cached_clust_rec = clust_rec; + cached_old_vers = old_vers; + } else { + err = DB_SUCCESS; + old_vers = cached_old_vers; + + /* The offsets need not be same for the latest + version of clust_rec and its old version + old_vers. Re-calculate the offsets for old_vers. */ + + if (old_vers != NULL) { + *offsets = rec_get_offsets( + old_vers, clust_index, *offsets, + true, ULINT_UNDEFINED, offset_heap); + } + } + if (old_vers == NULL) { goto err_exit; } @@ -4160,6 +4196,7 @@ row_search_mvcc( dtuple_t* vrow = NULL; const rec_t* result_rec = NULL; const rec_t* clust_rec; + Row_sel_get_clust_rec_for_mysql row_sel_get_clust_rec_for_mysql; dberr_t err = DB_SUCCESS; ibool unique_search = FALSE; ibool mtr_has_extra_clust_latch = FALSE; @@ -4594,7 +4631,7 @@ wait_table_again: if (err != DB_SUCCESS) { rec = NULL; - goto lock_wait_or_error; + goto page_read_error; } pcur->trx_if_known = trx; @@ -4648,7 +4685,7 @@ wait_table_again: index->table->file_unreadable = true; } rec = NULL; - goto lock_wait_or_error; + goto page_read_error; } } @@ -4669,7 +4706,7 @@ rec_loop: if (!index->table->is_readable()) { err = DB_DECRYPTION_FAILED; - goto lock_wait_or_error; + goto page_read_error; } ut_ad(!!page_rec_is_comp(rec) == comp); @@ -4776,7 +4813,7 @@ wrong_offs: ut_ad(0); err = DB_CORRUPTION; - goto lock_wait_or_error; + goto page_read_error; } else { /* The user may be dumping a corrupt table. Jump over the corruption to recover as much as possible. */ @@ -5604,6 +5641,10 @@ not_moved: goto normal_return; lock_wait_or_error: + if (!dict_index_is_spatial(index)) { + btr_pcur_store_position(pcur, &mtr); + } +page_read_error: /* Reset the old and new "did semi-consistent read" flags. */ if (UNIV_UNLIKELY(prebuilt->row_read_type == ROW_READ_DID_SEMI_CONSISTENT)) { @@ -5611,13 +5652,6 @@ lock_wait_or_error: } did_semi_consistent_read = FALSE; - /*-------------------------------------------------------------*/ - if (!dict_index_is_spatial(index)) { - if (rec) { - btr_pcur_store_position(pcur, &mtr); - } - } - lock_table_wait: mtr.commit(); mtr_has_extra_clust_latch = FALSE; diff --git a/storage/rocksdb/ha_rocksdb.cc b/storage/rocksdb/ha_rocksdb.cc index 8ef8c349e9f..1929c5235f7 100644 --- a/storage/rocksdb/ha_rocksdb.cc +++ b/storage/rocksdb/ha_rocksdb.cc @@ -5836,11 +5836,11 @@ static int rocksdb_done_func(void *const p) { // Disown the cache data since we're shutting down. // This results in memory leaks but it improved the shutdown time. // Don't disown when running under valgrind -#ifndef HAVE_purify +#ifndef HAVE_valgrind if (rocksdb_tbl_options->block_cache) { rocksdb_tbl_options->block_cache->DisownData(); } -#endif /* HAVE_purify */ +#endif /* HAVE_valgrind */ /* MariaDB: don't clear rocksdb_db_options and rocksdb_tbl_options. diff --git a/storage/rocksdb/mysql-test/rocksdb/suite.pm b/storage/rocksdb/mysql-test/rocksdb/suite.pm index 3423d34ded5..e4f074df471 100644 --- a/storage/rocksdb/mysql-test/rocksdb/suite.pm +++ b/storage/rocksdb/mysql-test/rocksdb/suite.pm @@ -20,8 +20,8 @@ my $sst_dump= return "RocksDB is not compiled, no sst_dump" unless $sst_dump; $ENV{MARIAROCKS_SST_DUMP}="$sst_dump"; -# Temporarily disable testing under valgrind, due to MDEV-12439 -return "RocksDB tests disabled under valgrind" if ($::opt_valgrind); +## Temporarily disable testing under valgrind, due to MDEV-12439 +#return "RocksDB tests disabled under valgrind" if ($::opt_valgrind); bless { }; |