summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarko Mäkelä <marko.makela@mariadb.com>2020-08-20 11:01:47 +0300
committerMarko Mäkelä <marko.makela@mariadb.com>2020-08-20 11:01:47 +0300
commit2fa9f8c53a80e8b52c14d8c3260b18e7e77cc154 (patch)
treee1e69ba81d7dd1b170b8572edc6e7625b38567b8
parentf8bf5b0f8431493975f8f4488d0bef6e0e4e289e (diff)
parentde0e7cd72a6e071aba686178a8ff461dd5a757f5 (diff)
downloadmariadb-git-2fa9f8c53a80e8b52c14d8c3260b18e7e77cc154.tar.gz
Merge 10.3 into 10.4
-rw-r--r--client/mysqltest.cc4
-rw-r--r--extra/mariabackup/xtrabackup.cc10
-rw-r--r--include/my_stacktrace.h3
-rw-r--r--mysql-test/main/mysql_tzinfo_to_sql_symlink.result6
-rw-r--r--mysql-test/suite/encryption/r/innodb_encrypt_log.result2
-rw-r--r--mysql-test/suite/innodb/r/foreign_key.result27
-rw-r--r--mysql-test/suite/innodb/r/innodb.result2
-rw-r--r--mysql-test/suite/innodb/t/foreign_key.test23
-rw-r--r--mysql-test/suite/innodb/t/innodb.test2
-rw-r--r--mysql-test/suite/sys_vars/r/innodb_log_checksums_basic.result4
-rw-r--r--mysql-test/suite/sys_vars/r/sysvars_innodb.result2
-rw-r--r--mysql-test/suite/wsrep/r/mysql_tzinfo_to_sql_symlink.result4
-rw-r--r--mysql-test/suite/wsrep/r/mysql_tzinfo_to_sql_symlink_skip.result4
-rw-r--r--mysys/stacktrace.c133
-rw-r--r--scripts/mysqld_safe.sh20
-rw-r--r--sql/mysqld.cc1
-rw-r--r--sql/tztime.cc3
-rw-r--r--storage/innobase/btr/btr0btr.cc1
-rw-r--r--storage/innobase/btr/btr0cur.cc5
-rw-r--r--storage/innobase/buf/buf0buf.cc24
-rw-r--r--storage/innobase/buf/buf0flu.cc4
-rw-r--r--storage/innobase/handler/ha_innodb.cc74
-rw-r--r--storage/innobase/handler/handler0alter.cc9
-rw-r--r--storage/innobase/include/log0log.h24
-rw-r--r--storage/innobase/include/log0log.ic23
-rw-r--r--storage/innobase/include/srv0srv.h25
-rw-r--r--storage/innobase/log/log0log.cc9
-rw-r--r--storage/innobase/page/page0page.cc57
-rw-r--r--storage/innobase/row/row0mysql.cc12
-rw-r--r--storage/innobase/row/row0uins.cc7
-rw-r--r--storage/innobase/row/row0umod.cc57
-rw-r--r--storage/innobase/row/row0undo.cc18
-rw-r--r--storage/innobase/srv/srv0srv.cc96
-rw-r--r--storage/innobase/srv/srv0start.cc4
-rw-r--r--storage/innobase/trx/trx0roll.cc3
-rw-r--r--storage/innobase/trx/trx0trx.cc5
-rw-r--r--unittest/mysys/CMakeLists.txt2
-rw-r--r--unittest/mysys/stacktrace-t.c67
38 files changed, 453 insertions, 323 deletions
diff --git a/client/mysqltest.cc b/client/mysqltest.cc
index 33e4d04527f..368ac6a0fb7 100644
--- a/client/mysqltest.cc
+++ b/client/mysqltest.cc
@@ -9043,10 +9043,6 @@ static void init_signal_handling(void)
struct sigaction sa;
DBUG_ENTER("init_signal_handling");
-#ifdef HAVE_STACKTRACE
- my_init_stacktrace();
-#endif
-
sa.sa_flags = SA_RESETHAND | SA_NODEFER;
sigemptyset(&sa.sa_mask);
sigprocmask(SIG_SETMASK, &sa.sa_mask, NULL);
diff --git a/extra/mariabackup/xtrabackup.cc b/extra/mariabackup/xtrabackup.cc
index 67e38ebf821..69005b69b63 100644
--- a/extra/mariabackup/xtrabackup.cc
+++ b/extra/mariabackup/xtrabackup.cc
@@ -252,6 +252,12 @@ my_bool innobase_locks_unsafe_for_binlog;
my_bool innobase_rollback_on_timeout;
my_bool innobase_create_status_file;
+/* The following counter is used to convey information to InnoDB
+about server activity: in selects it is not sensible to call
+srv_active_wake_master_thread after each fetch or search, we only do
+it every INNOBASE_WAKE_INTERVAL'th step. */
+
+#define INNOBASE_WAKE_INTERVAL 32
ulong innobase_active_counter = 0;
#ifndef _WIN32
@@ -2002,10 +2008,6 @@ static bool innodb_init_param()
srv_undo_dir = (char*) ".";
}
- log_checksum_algorithm_ptr = innodb_log_checksums || srv_encrypt_log
- ? log_block_calc_checksum_crc32
- : log_block_calc_checksum_none;
-
#ifdef _WIN32
srv_use_native_aio = TRUE;
#endif
diff --git a/include/my_stacktrace.h b/include/my_stacktrace.h
index 922a59c196a..015fa062752 100644
--- a/include/my_stacktrace.h
+++ b/include/my_stacktrace.h
@@ -41,7 +41,6 @@
C_MODE_START
#if defined(HAVE_STACKTRACE) || defined(HAVE_BACKTRACE)
-void my_init_stacktrace();
void my_print_stacktrace(uchar* stack_bottom, ulong thread_stack,
my_bool silent);
int my_safe_print_str(const char* val, size_t max_len);
@@ -52,8 +51,6 @@ char *my_demangle(const char *mangled_name, int *status);
#ifdef __WIN__
void my_set_exception_pointers(EXCEPTION_POINTERS *ep);
#endif /* __WIN__ */
-#else
-#define my_init_stacktrace() do { } while(0)
#endif /* ! (defined(HAVE_STACKTRACE) || defined(HAVE_BACKTRACE)) */
#ifndef _WIN32
diff --git a/mysql-test/main/mysql_tzinfo_to_sql_symlink.result b/mysql-test/main/mysql_tzinfo_to_sql_symlink.result
index 9de067b0e3f..a7426327ecf 100644
--- a/mysql-test/main/mysql_tzinfo_to_sql_symlink.result
+++ b/mysql-test/main/mysql_tzinfo_to_sql_symlink.result
@@ -15,6 +15,7 @@ TRUNCATE TABLE time_zone;
TRUNCATE TABLE time_zone_name;
TRUNCATE TABLE time_zone_transition;
TRUNCATE TABLE time_zone_transition_type;
+START TRANSACTION;
INSERT INTO time_zone (Use_leap_seconds) VALUES ('N');
SET @time_zone_id= LAST_INSERT_ID();
INSERT INTO time_zone_name (Name, Time_zone_id) VALUES ('GMT', @time_zone_id);
@@ -32,6 +33,7 @@ INSERT INTO time_zone_transition_type (Time_zone_id, Transition_type_id, Offset,
Warning: Unable to load 'MYSQLTEST_VARDIR/zoneinfo/posix/garbage' as time zone. Skipping it.
Warning: Unable to load 'MYSQLTEST_VARDIR/zoneinfo/posix/ignored.tab' as time zone. Skipping it.
Warning: Skipping directory 'MYSQLTEST_VARDIR/zoneinfo/posix/posix': to avoid infinite symlink recursion.
+COMMIT;
ALTER TABLE time_zone_transition ORDER BY Time_zone_id, Transition_time;
ALTER TABLE time_zone_transition_type ORDER BY Time_zone_id, Transition_type_id;
\d |
@@ -57,6 +59,7 @@ TRUNCATE TABLE time_zone;
TRUNCATE TABLE time_zone_name;
TRUNCATE TABLE time_zone_transition;
TRUNCATE TABLE time_zone_transition_type;
+START TRANSACTION;
INSERT INTO time_zone (Use_leap_seconds) VALUES ('N');
SET @time_zone_id= LAST_INSERT_ID();
INSERT INTO time_zone_name (Name, Time_zone_id) VALUES ('GMT', @time_zone_id);
@@ -71,6 +74,7 @@ INSERT INTO time_zone_transition_type (Time_zone_id, Transition_type_id, Offset,
(@time_zone_id, 0, 0, 0, 'GMT')
;
Warning: Unable to load 'MYSQLTEST_VARDIR/zoneinfo/posix/garbage' as time zone. Skipping it.
+COMMIT;
ALTER TABLE time_zone_transition ORDER BY Time_zone_id, Transition_time;
ALTER TABLE time_zone_transition_type ORDER BY Time_zone_id, Transition_type_id;
\d |
@@ -160,6 +164,8 @@ TRUNCATE TABLE time_zone;
TRUNCATE TABLE time_zone_name;
TRUNCATE TABLE time_zone_transition;
TRUNCATE TABLE time_zone_transition_type;
+START TRANSACTION;
+COMMIT;
ALTER TABLE time_zone_transition ORDER BY Time_zone_id, Transition_time;
ALTER TABLE time_zone_transition_type ORDER BY Time_zone_id, Transition_type_id;
\d |
diff --git a/mysql-test/suite/encryption/r/innodb_encrypt_log.result b/mysql-test/suite/encryption/r/innodb_encrypt_log.result
index ff5b7c15b8b..e2b456aa2ed 100644
--- a/mysql-test/suite/encryption/r/innodb_encrypt_log.result
+++ b/mysql-test/suite/encryption/r/innodb_encrypt_log.result
@@ -7,7 +7,7 @@
#
SET GLOBAL innodb_log_checksums=0;
Warnings:
-Warning 138 innodb_encrypt_log implies innodb_log_checksums
+Warning 138 innodb_log_checksums is deprecated and has no effect outside recovery
SELECT @@global.innodb_log_checksums;
@@global.innodb_log_checksums
1
diff --git a/mysql-test/suite/innodb/r/foreign_key.result b/mysql-test/suite/innodb/r/foreign_key.result
index d54228dd090..c2ec14e3bfe 100644
--- a/mysql-test/suite/innodb/r/foreign_key.result
+++ b/mysql-test/suite/innodb/r/foreign_key.result
@@ -659,6 +659,7 @@ SET GLOBAL innodb_purge_rseg_truncate_frequency = @saved_frequency;
# MDEV-17187 table doesn't exist in engine after ALTER other tables
# with CONSTRAINTs
#
+call mtr.add_suppression("\\[Warning\\] InnoDB: In ALTER TABLE `test`\\.`t2` has or is referenced in foreign key constraints which are not compatible with the new table definition.");
set foreign_key_checks=on;
create table t1 (id int not null primary key) engine=innodb;
create table t2 (id int not null primary key, fid int not null,
@@ -714,6 +715,32 @@ drop table t1,t2;
ERROR 23000: Cannot delete or update a parent row: a foreign key constraint fails
drop table t1,t2;
ERROR 42S02: Unknown table 'test.t2'
+#
+# MDEV-22934 Table disappear after two alter table command
+#
+CREATE TABLE t1(f1 INT NOT NULL AUTO_INCREMENT,
+f2 INT NOT NULL,
+PRIMARY KEY (f1), INDEX (f2))ENGINE=InnoDB;
+CREATE TABLE t2(f1 INT NOT NULL,
+f2 INT NOT NULL, f3 INT NOT NULL,
+PRIMARY KEY(f1, f2), UNIQUE KEY(f2),
+CONSTRAINT `t2_ibfk_1` FOREIGN KEY (f2) REFERENCES t1(f2) ON DELETE CASCADE,
+CONSTRAINT `t2_ibfk_2` FOREIGN KEY (f1) REFERENCES t1(f1) ON DELETE CASCADE
+) ENGINE=InnoDB;
+SET FOREIGN_KEY_CHECKS=0;
+ALTER TABLE t2 DROP PRIMARY KEY, ADD PRIMARY KEY(f3), ALGORITHM=INPLACE;
+ALTER TABLE t2 DROP INDEX `f2`, ALGORITHM=COPY;
+SHOW CREATE TABLE t2;
+Table Create Table
+t2 CREATE TABLE `t2` (
+ `f1` int(11) NOT NULL,
+ `f2` int(11) NOT NULL,
+ `f3` int(11) NOT NULL,
+ PRIMARY KEY (`f3`)
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+CREATE TABLE t2 (f1 INT NOT NULL)ENGINE=InnoDB;
+ERROR 42S01: Table 't2' already exists
+DROP TABLE t2, t1;
# End of 10.2 tests
CREATE TABLE t1 (a GEOMETRY, INDEX(a(8)),
FOREIGN KEY (a) REFERENCES x (xx)) ENGINE=InnoDB;
diff --git a/mysql-test/suite/innodb/r/innodb.result b/mysql-test/suite/innodb/r/innodb.result
index e2937fe2073..b48a85a2443 100644
--- a/mysql-test/suite/innodb/r/innodb.result
+++ b/mysql-test/suite/innodb/r/innodb.result
@@ -2544,7 +2544,6 @@ set foreign_key_checks=0;
create table t2 (a varchar(10), foreign key (a) references t1(a)) engine = innodb;
create table t1(a varchar(10) primary key) engine = innodb;
alter table t1 modify column a int;
-Got one of the listed errors
set foreign_key_checks=1;
drop table t2,t1;
set foreign_key_checks=0;
@@ -2553,6 +2552,7 @@ create table t1(a varchar(10) primary key) engine = innodb DEFAULT CHARSET=latin
alter table t1 convert to character set utf8;
set foreign_key_checks=1;
drop table t2,t1;
+call mtr.add_suppression("\\[Warning\\] InnoDB: In ALTER TABLE `test`.`t1` has or is referenced in foreign key constraints which are not compatible with the new table definition.");
set foreign_key_checks=0;
create table t2 (a varchar(10), foreign key (a) references t1(a)) engine = innodb DEFAULT CHARSET=latin1;
create table t3(a varchar(10) primary key) engine = innodb DEFAULT CHARSET=utf8;
diff --git a/mysql-test/suite/innodb/t/foreign_key.test b/mysql-test/suite/innodb/t/foreign_key.test
index 7ff154538cb..acf31bc6131 100644
--- a/mysql-test/suite/innodb/t/foreign_key.test
+++ b/mysql-test/suite/innodb/t/foreign_key.test
@@ -657,6 +657,8 @@ SET GLOBAL innodb_purge_rseg_truncate_frequency = @saved_frequency;
--echo # with CONSTRAINTs
--echo #
+call mtr.add_suppression("\\[Warning\\] InnoDB: In ALTER TABLE `test`\\.`t2` has or is referenced in foreign key constraints which are not compatible with the new table definition.");
+
set foreign_key_checks=on;
create table t1 (id int not null primary key) engine=innodb;
create table t2 (id int not null primary key, fid int not null,
@@ -698,6 +700,27 @@ drop table t1,t2;
--error ER_BAD_TABLE_ERROR
drop table t1,t2;
+--echo #
+--echo # MDEV-22934 Table disappear after two alter table command
+--echo #
+CREATE TABLE t1(f1 INT NOT NULL AUTO_INCREMENT,
+ f2 INT NOT NULL,
+ PRIMARY KEY (f1), INDEX (f2))ENGINE=InnoDB;
+CREATE TABLE t2(f1 INT NOT NULL,
+ f2 INT NOT NULL, f3 INT NOT NULL,
+ PRIMARY KEY(f1, f2), UNIQUE KEY(f2),
+CONSTRAINT `t2_ibfk_1` FOREIGN KEY (f2) REFERENCES t1(f2) ON DELETE CASCADE,
+CONSTRAINT `t2_ibfk_2` FOREIGN KEY (f1) REFERENCES t1(f1) ON DELETE CASCADE
+) ENGINE=InnoDB;
+
+SET FOREIGN_KEY_CHECKS=0;
+ALTER TABLE t2 DROP PRIMARY KEY, ADD PRIMARY KEY(f3), ALGORITHM=INPLACE;
+ALTER TABLE t2 DROP INDEX `f2`, ALGORITHM=COPY;
+SHOW CREATE TABLE t2;
+--error ER_TABLE_EXISTS_ERROR
+CREATE TABLE t2 (f1 INT NOT NULL)ENGINE=InnoDB;
+DROP TABLE t2, t1;
+
--echo # End of 10.2 tests
# MDEV-21792 Server aborts upon attempt to create foreign key on spatial field
diff --git a/mysql-test/suite/innodb/t/innodb.test b/mysql-test/suite/innodb/t/innodb.test
index ab12cac5ea1..a81e6c3f900 100644
--- a/mysql-test/suite/innodb/t/innodb.test
+++ b/mysql-test/suite/innodb/t/innodb.test
@@ -1626,7 +1626,6 @@ drop table t1;
set foreign_key_checks=0;
create table t2 (a varchar(10), foreign key (a) references t1(a)) engine = innodb;
create table t1(a varchar(10) primary key) engine = innodb;
--- error 1025,1025
alter table t1 modify column a int;
set foreign_key_checks=1;
drop table t2,t1;
@@ -1642,6 +1641,7 @@ drop table t2,t1;
# test that RENAME does not allow invalid charsets when f_k_c is 0
+call mtr.add_suppression("\\[Warning\\] InnoDB: In ALTER TABLE `test`.`t1` has or is referenced in foreign key constraints which are not compatible with the new table definition.");
set foreign_key_checks=0;
create table t2 (a varchar(10), foreign key (a) references t1(a)) engine = innodb DEFAULT CHARSET=latin1;
create table t3(a varchar(10) primary key) engine = innodb DEFAULT CHARSET=utf8;
diff --git a/mysql-test/suite/sys_vars/r/innodb_log_checksums_basic.result b/mysql-test/suite/sys_vars/r/innodb_log_checksums_basic.result
index 6679ca87249..7724ef9c2ee 100644
--- a/mysql-test/suite/sys_vars/r/innodb_log_checksums_basic.result
+++ b/mysql-test/suite/sys_vars/r/innodb_log_checksums_basic.result
@@ -28,9 +28,11 @@ SELECT @@global.innodb_log_checksums;
@@global.innodb_log_checksums
1
SET GLOBAL innodb_log_checksums = OFF;
+Warnings:
+Warning 138 innodb_log_checksums is deprecated and has no effect outside recovery
SELECT @@global.innodb_log_checksums;
@@global.innodb_log_checksums
-0
+1
SET GLOBAL innodb_log_checksums = default;
SET GLOBAL innodb_log_checksums = ON;
SELECT @@global.innodb_log_checksums;
diff --git a/mysql-test/suite/sys_vars/r/sysvars_innodb.result b/mysql-test/suite/sys_vars/r/sysvars_innodb.result
index 183dab52cbf..2da3ae77b9f 100644
--- a/mysql-test/suite/sys_vars/r/sysvars_innodb.result
+++ b/mysql-test/suite/sys_vars/r/sysvars_innodb.result
@@ -1250,7 +1250,7 @@ SESSION_VALUE NULL
DEFAULT_VALUE ON
VARIABLE_SCOPE GLOBAL
VARIABLE_TYPE BOOLEAN
-VARIABLE_COMMENT Whether to compute and require checksums for InnoDB redo log blocks
+VARIABLE_COMMENT DEPRECATED. Whether to require checksums for InnoDB redo log blocks.
NUMERIC_MIN_VALUE NULL
NUMERIC_MAX_VALUE NULL
NUMERIC_BLOCK_SIZE NULL
diff --git a/mysql-test/suite/wsrep/r/mysql_tzinfo_to_sql_symlink.result b/mysql-test/suite/wsrep/r/mysql_tzinfo_to_sql_symlink.result
index f219625b490..d5bbecfa7c2 100644
--- a/mysql-test/suite/wsrep/r/mysql_tzinfo_to_sql_symlink.result
+++ b/mysql-test/suite/wsrep/r/mysql_tzinfo_to_sql_symlink.result
@@ -15,6 +15,7 @@ TRUNCATE TABLE time_zone;
TRUNCATE TABLE time_zone_name;
TRUNCATE TABLE time_zone_transition;
TRUNCATE TABLE time_zone_transition_type;
+START TRANSACTION;
INSERT INTO time_zone (Use_leap_seconds) VALUES ('N');
SET @time_zone_id= LAST_INSERT_ID();
INSERT INTO time_zone_name (Name, Time_zone_id) VALUES ('GMT', @time_zone_id);
@@ -32,6 +33,7 @@ INSERT INTO time_zone_transition_type (Time_zone_id, Transition_type_id, Offset,
Warning: Unable to load 'MYSQLTEST_VARDIR/zoneinfo/posix/garbage' as time zone. Skipping it.
Warning: Unable to load 'MYSQLTEST_VARDIR/zoneinfo/posix/ignored.tab' as time zone. Skipping it.
Warning: Skipping directory 'MYSQLTEST_VARDIR/zoneinfo/posix/posix': to avoid infinite symlink recursion.
+COMMIT;
ALTER TABLE time_zone_transition ORDER BY Time_zone_id, Transition_time;
ALTER TABLE time_zone_transition_type ORDER BY Time_zone_id, Transition_type_id;
\d |
@@ -57,6 +59,7 @@ TRUNCATE TABLE time_zone;
TRUNCATE TABLE time_zone_name;
TRUNCATE TABLE time_zone_transition;
TRUNCATE TABLE time_zone_transition_type;
+START TRANSACTION;
INSERT INTO time_zone (Use_leap_seconds) VALUES ('N');
SET @time_zone_id= LAST_INSERT_ID();
INSERT INTO time_zone_name (Name, Time_zone_id) VALUES ('GMT', @time_zone_id);
@@ -71,6 +74,7 @@ INSERT INTO time_zone_transition_type (Time_zone_id, Transition_type_id, Offset,
(@time_zone_id, 0, 0, 0, 'GMT')
;
Warning: Unable to load 'MYSQLTEST_VARDIR/zoneinfo/posix/garbage' as time zone. Skipping it.
+COMMIT;
ALTER TABLE time_zone_transition ORDER BY Time_zone_id, Transition_time;
ALTER TABLE time_zone_transition_type ORDER BY Time_zone_id, Transition_type_id;
\d |
diff --git a/mysql-test/suite/wsrep/r/mysql_tzinfo_to_sql_symlink_skip.result b/mysql-test/suite/wsrep/r/mysql_tzinfo_to_sql_symlink_skip.result
index 85c4d858be2..aff02cb413e 100644
--- a/mysql-test/suite/wsrep/r/mysql_tzinfo_to_sql_symlink_skip.result
+++ b/mysql-test/suite/wsrep/r/mysql_tzinfo_to_sql_symlink_skip.result
@@ -9,6 +9,7 @@ TRUNCATE TABLE time_zone;
TRUNCATE TABLE time_zone_name;
TRUNCATE TABLE time_zone_transition;
TRUNCATE TABLE time_zone_transition_type;
+START TRANSACTION;
INSERT INTO time_zone (Use_leap_seconds) VALUES ('N');
SET @time_zone_id= LAST_INSERT_ID();
INSERT INTO time_zone_name (Name, Time_zone_id) VALUES ('GMT', @time_zone_id);
@@ -26,6 +27,7 @@ INSERT INTO time_zone_transition_type (Time_zone_id, Transition_type_id, Offset,
Warning: Unable to load 'MYSQLTEST_VARDIR/zoneinfo/posix/garbage' as time zone. Skipping it.
Warning: Unable to load 'MYSQLTEST_VARDIR/zoneinfo/posix/ignored.tab' as time zone. Skipping it.
Warning: Skipping directory 'MYSQLTEST_VARDIR/zoneinfo/posix/posix': to avoid infinite symlink recursion.
+COMMIT;
ALTER TABLE time_zone_transition ORDER BY Time_zone_id, Transition_time;
ALTER TABLE time_zone_transition_type ORDER BY Time_zone_id, Transition_type_id;
# Silent run
@@ -36,6 +38,7 @@ TRUNCATE TABLE time_zone;
TRUNCATE TABLE time_zone_name;
TRUNCATE TABLE time_zone_transition;
TRUNCATE TABLE time_zone_transition_type;
+START TRANSACTION;
INSERT INTO time_zone (Use_leap_seconds) VALUES ('N');
SET @time_zone_id= LAST_INSERT_ID();
INSERT INTO time_zone_name (Name, Time_zone_id) VALUES ('GMT', @time_zone_id);
@@ -50,6 +53,7 @@ INSERT INTO time_zone_transition_type (Time_zone_id, Transition_type_id, Offset,
(@time_zone_id, 0, 0, 0, 'GMT')
;
Warning: Unable to load 'MYSQLTEST_VARDIR/zoneinfo/posix/garbage' as time zone. Skipping it.
+COMMIT;
ALTER TABLE time_zone_transition ORDER BY Time_zone_id, Transition_time;
ALTER TABLE time_zone_transition_type ORDER BY Time_zone_id, Transition_type_id;
#
diff --git a/mysys/stacktrace.c b/mysys/stacktrace.c
index a512f5879d6..f5e6352a72e 100644
--- a/mysys/stacktrace.c
+++ b/mysys/stacktrace.c
@@ -34,108 +34,11 @@
#include <execinfo.h>
#endif
-#ifdef __linux__
-#define PTR_SANE(p) ((p) && (char*)(p) >= heap_start && (char*)(p) <= heap_end)
-static char *heap_start;
-char *__bss_start;
-#else
-#define PTR_SANE(p) (p)
-#endif /* __linux */
-
-
-void my_init_stacktrace()
-{
-#ifdef __linux__
- heap_start = (char*) &__bss_start;
-#endif /* __linux */
-}
-
-#ifdef __linux__
-
-static void print_buffer(char *buffer, size_t count)
-{
- const char s[]= " ";
- for (; count && *buffer; --count)
- {
- my_write_stderr(isprint(*buffer) ? buffer : s, 1);
- ++buffer;
- }
-}
-
-/**
- Access the pages of this process through /proc/self/task/<tid>/mem
- in order to safely print the contents of a memory address range.
-
- @param addr The address at the start of the memory region.
- @param max_len The length of the memory region.
-
- @return Zero on success.
-*/
-static int safe_print_str(const char *addr, size_t max_len)
-{
- int fd;
- pid_t tid;
- off_t offset;
- ssize_t nbytes= 0;
- size_t total, count;
- char buf[256];
-
- tid= (pid_t) syscall(SYS_gettid);
-
- sprintf(buf, "/proc/self/task/%d/mem", tid);
-
- if ((fd= open(buf, O_RDONLY)) < 0)
- return -1;
-
- /* Ensure that off_t can hold a pointer. */
- compile_time_assert(sizeof(off_t) >= sizeof(intptr));
-
- total= max_len;
- offset= (intptr) addr;
-
- /* Read up to the maximum number of bytes. */
- while (total)
- {
- count= MY_MIN(sizeof(buf), total);
-
- if ((nbytes= pread(fd, buf, count, offset)) < 0)
- {
- /* Just in case... */
- if (errno == EINTR)
- continue;
- else
- break;
- }
-
- /* Advance offset into memory. */
- total-= nbytes;
- offset+= nbytes;
- addr+= nbytes;
-
- /* Output the printable characters. */
- print_buffer(buf, nbytes);
-
- /* Break if less than requested... */
- if ((count - nbytes))
- break;
- }
-
- if (nbytes == -1)
- my_safe_printf_stderr("Can't read from address %p", addr);
-
- close(fd);
-
- return 0;
-}
-
-#endif
-
/*
Attempt to print a char * pointer as a string.
SYNOPSIS
- Prints either until the end of string ('\0'), or max_len characters have
- been printed.
+ Prints until max_len characters have been printed.
RETURN VALUE
0 Pointer was within the heap address space.
@@ -150,24 +53,25 @@ static int safe_print_str(const char *addr, size_t max_len)
int my_safe_print_str(const char* val, size_t max_len)
{
-#ifdef __linux__
- char *heap_end;
-
- // Try and make use of /proc filesystem to safely print memory contents.
- if (!safe_print_str(val, max_len))
- return 0;
-
- heap_end= (char*) sbrk(0);
-#endif
-
- if (!PTR_SANE(val))
+ const char *orig_val= val;
+ if (!val)
{
- my_safe_printf_stderr("%s", "is an invalid pointer");
+ my_safe_printf_stderr("%s", "(null)");
return 1;
}
- for (; max_len && PTR_SANE(val) && *val; --max_len)
- my_write_stderr((val++), 1);
+ for (; max_len; --max_len)
+ {
+ if (my_write_stderr((val++), 1) != 1)
+ {
+ if ((errno == EFAULT) &&(val == orig_val + 1))
+ {
+ // We can not read the address from very beginning
+ my_safe_printf_stderr("Can't access address %p", orig_val);
+ }
+ break;
+ }
+ }
my_safe_printf_stderr("%s", "\n");
return 0;
@@ -511,11 +415,6 @@ static EXCEPTION_POINTERS *exception_ptrs;
#define MODULE64_SIZE_WINXP 576
#define STACKWALK_MAX_FRAMES 64
-void my_init_stacktrace()
-{
-}
-
-
void my_set_exception_pointers(EXCEPTION_POINTERS *ep)
{
exception_ptrs = ep;
diff --git a/scripts/mysqld_safe.sh b/scripts/mysqld_safe.sh
index 3dda22507af..dc04c18a6c1 100644
--- a/scripts/mysqld_safe.sh
+++ b/scripts/mysqld_safe.sh
@@ -23,6 +23,7 @@ numa_interleave=0
wsrep_on=0
dry_run=0
defaults_group_suffix=
+ignore_unknown=1
# Initial logging status: error log is not open, and not using syslog
logging=init
@@ -370,11 +371,22 @@ parse_arguments() {
--help) usage ;;
+ --ignore-unknown) ignore_unknown=1 ;;
+ --no-ignore-unknown|--not-ignore-unknown) ignore_unknown=0 ;;
+
*)
- case "$unrecognized_handling" in
- collect) append_arg_to_args "$arg" ;;
- complain) log_error "unknown option '$arg'" ;;
- esac
+ if test $ignore_unknown -eq 0
+ then
+ case "$unrecognized_handling" in
+ collect) append_arg_to_args "$arg" ;;
+ complain) log_error "unknown option '$arg'"
+ esac
+ else
+ case "$arg" in
+ "--loose-"*) append_arg_to_args "$arg" ;;
+ *) append_arg_to_args "--loose-$arg"
+ esac
+ fi
esac
done
}
diff --git a/sql/mysqld.cc b/sql/mysqld.cc
index 106151c4989..856d9bb0d98 100644
--- a/sql/mysqld.cc
+++ b/sql/mysqld.cc
@@ -3092,7 +3092,6 @@ void init_signals(void)
sigemptyset(&sa.sa_mask);
sigprocmask(SIG_SETMASK,&sa.sa_mask,NULL);
- my_init_stacktrace();
#if defined(__amiga__)
sa.sa_handler=(void(*)())handle_fatal_signal;
#else
diff --git a/sql/tztime.cc b/sql/tztime.cc
index 9465a51f3fe..05b8389a521 100644
--- a/sql/tztime.cc
+++ b/sql/tztime.cc
@@ -2739,9 +2739,11 @@ main(int argc, char **argv)
printf("TRUNCATE TABLE time_zone_name;\n");
printf("TRUNCATE TABLE time_zone_transition;\n");
printf("TRUNCATE TABLE time_zone_transition_type;\n");
+ printf("START TRANSACTION;\n");
if (scan_tz_dir(root_name_end, 0, opt_verbose))
{
+ printf("ROLLBACK;\n");
fflush(stdout);
fprintf(stderr,
"There were fatal errors during processing "
@@ -2749,6 +2751,7 @@ main(int argc, char **argv)
return 1;
}
+ printf("COMMIT;\n");
printf("ALTER TABLE time_zone_transition "
"ORDER BY Time_zone_id, Transition_time;\n");
printf("ALTER TABLE time_zone_transition_type "
diff --git a/storage/innobase/btr/btr0btr.cc b/storage/innobase/btr/btr0btr.cc
index 7ff0820dd13..1f104e59db8 100644
--- a/storage/innobase/btr/btr0btr.cc
+++ b/storage/innobase/btr/btr0btr.cc
@@ -5325,7 +5325,6 @@ btr_validate_index(
if (!btr_validate_level(index, trx, n - i, lockout)) {
err = DB_CORRUPTION;
- break;
}
}
diff --git a/storage/innobase/btr/btr0cur.cc b/storage/innobase/btr/btr0cur.cc
index 0dae73c56d7..ac88ea26d39 100644
--- a/storage/innobase/btr/btr0cur.cc
+++ b/storage/innobase/btr/btr0cur.cc
@@ -3497,7 +3497,7 @@ fail:
/* prefetch siblings of the leaf for the pessimistic
operation, if the page is leaf. */
- if (page_is_leaf(page)) {
+ if (page_is_leaf(page) && !index->is_ibuf()) {
btr_cur_prefetch_siblings(block);
}
fail_err:
@@ -4585,6 +4585,7 @@ btr_cur_optimistic_update(
if (rec_offs_any_extern(*offsets)) {
any_extern:
+ ut_ad(!index->is_ibuf());
/* Externally stored fields are treated in pessimistic
update */
@@ -4781,7 +4782,7 @@ func_exit:
}
}
- if (err != DB_SUCCESS) {
+ if (err != DB_SUCCESS && !index->is_ibuf()) {
/* prefetch siblings of the leaf for the pessimistic
operation. */
btr_cur_prefetch_siblings(block);
diff --git a/storage/innobase/buf/buf0buf.cc b/storage/innobase/buf/buf0buf.cc
index 905c04fa811..51b67237f22 100644
--- a/storage/innobase/buf/buf0buf.cc
+++ b/storage/innobase/buf/buf0buf.cc
@@ -5615,9 +5615,21 @@ buf_page_create(
&& block->index);
if (drop_hash_entry) {
- mutex_enter(&block->mutex);
- buf_page_set_sticky(&block->page);
- mutex_exit(&block->mutex);
+ /* Avoid a hang if I/O is going on. Release
+ the buffer pool mutex and page hash lock
+ and wait for I/O to complete */
+ while (buf_block_get_io_fix(block) != BUF_IO_NONE) {
+ block->fix();
+ buf_pool_mutex_exit(buf_pool);
+ rw_lock_x_unlock(hash_lock);
+
+ os_thread_yield();
+
+ buf_pool_mutex_enter(buf_pool);
+ rw_lock_x_lock(hash_lock);
+ block->unfix();
+ }
+ rw_lock_x_lock(&block->lock);
}
#endif
/* Page can be found in buf_pool */
@@ -5628,11 +5640,7 @@ buf_page_create(
#ifdef BTR_CUR_HASH_ADAPT
if (drop_hash_entry) {
btr_search_drop_page_hash_index(block);
- buf_pool_mutex_enter(buf_pool);
- mutex_enter(&block->mutex);
- buf_page_unset_sticky(&block->page);
- mutex_exit(&block->mutex);
- buf_pool_mutex_exit(buf_pool);
+ rw_lock_x_unlock(&block->lock);
}
#endif /* BTR_CUR_HASH_ADAPT */
diff --git a/storage/innobase/buf/buf0flu.cc b/storage/innobase/buf/buf0flu.cc
index 9b49b9570e2..45c9b661d6f 100644
--- a/storage/innobase/buf/buf0flu.cc
+++ b/storage/innobase/buf/buf0flu.cc
@@ -3079,7 +3079,7 @@ DECLARE_THREAD(buf_flush_page_cleaner_coordinator)(void*)
/* The page_cleaner skips sleep if the server is
idle and there are no pending IOs in the buffer pool
and there is work to do. */
- if (srv_check_activity(&last_activity)
+ if (srv_check_activity(last_activity)
|| buf_get_n_pending_read_ios()
|| n_flushed == 0) {
@@ -3171,7 +3171,7 @@ DECLARE_THREAD(buf_flush_page_cleaner_coordinator)(void*)
n_flushed = n_flushed_lru + n_flushed_list;
- } else if (srv_check_activity(&last_activity)) {
+ } else if (srv_check_activity(last_activity)) {
ulint n_to_flush;
lsn_t lsn_limit = 0;
diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc
index 38429878b65..c088a5c7dc1 100644
--- a/storage/innobase/handler/ha_innodb.cc
+++ b/storage/innobase/handler/ha_innodb.cc
@@ -431,6 +431,14 @@ TYPELIB innodb_flush_method_typelib = {
NULL
};
+/* The following counter is used to convey information to InnoDB
+about server activity: in case of normal DML ops it is not
+sensible to call srv_active_wake_master_thread after each
+operation, we only do it every INNOBASE_WAKE_INTERVAL'th step. */
+
+#define INNOBASE_WAKE_INTERVAL 32
+static ulong innobase_active_counter = 0;
+
/** Allowed values of innodb_change_buffering */
static const char* innodb_change_buffering_names[] = {
"none", /* IBUF_USE_NONE */
@@ -1830,6 +1838,23 @@ static int innobase_wsrep_set_checkpoint(handlerton* hton, const XID* xid);
static int innobase_wsrep_get_checkpoint(handlerton* hton, XID* xid);
#endif /* WITH_WSREP */
/********************************************************************//**
+Increments innobase_active_counter and every INNOBASE_WAKE_INTERVALth
+time calls srv_active_wake_master_thread. This function should be used
+when a single database operation may introduce a small need for
+server utility activity, like checkpointing. */
+inline
+void
+innobase_active_small(void)
+/*=======================*/
+{
+ innobase_active_counter++;
+
+ if ((innobase_active_counter % INNOBASE_WAKE_INTERVAL) == 0) {
+ srv_active_wake_master_thread();
+ }
+}
+
+/********************************************************************//**
Converts an InnoDB error code to a MySQL error code and also tells to MySQL
about a possible transaction rollback inside InnoDB caused by a lock wait
timeout or a deadlock.
@@ -3478,8 +3503,7 @@ static int innodb_init_abort()
DBUG_RETURN(1);
}
-/** Update log_checksum_algorithm_ptr with a pointer to the function
-corresponding to whether checksums are enabled.
+/** If applicable, emit a message that log checksums cannot be disabled.
@param[in,out] thd client session, or NULL if at startup
@param[in] check whether redo log block checksums are enabled
@return whether redo log block checksums are enabled */
@@ -3487,34 +3511,21 @@ static inline
bool
innodb_log_checksums_func_update(THD* thd, bool check)
{
- static const char msg[] = "innodb_encrypt_log implies"
- " innodb_log_checksums";
+ static const char msg[] = "innodb_log_checksums is deprecated"
+ " and has no effect outside recovery";
ut_ad(!thd == !srv_was_started);
if (!check) {
- check = srv_encrypt_log;
- if (!check) {
- } else if (thd) {
+ if (thd) {
push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN,
HA_ERR_UNSUPPORTED, msg);
+ check = true;
} else {
sql_print_warning(msg);
}
}
- if (thd) {
- log_mutex_enter();
- log_checksum_algorithm_ptr = check
- ? log_block_calc_checksum_crc32
- : log_block_calc_checksum_none;
- log_mutex_exit();
- } else {
- log_checksum_algorithm_ptr = check
- ? log_block_calc_checksum_crc32
- : log_block_calc_checksum_none;
- }
-
return(check);
}
@@ -6453,6 +6464,11 @@ ha_innobase::close()
MONITOR_INC(MONITOR_TABLE_CLOSE);
+ /* Tell InnoDB server that there might be work for
+ utility threads: */
+
+ srv_active_wake_master_thread();
+
DBUG_RETURN(0);
}
@@ -8150,6 +8166,8 @@ report_error:
}
func_exit:
+ innobase_active_small();
+
DBUG_RETURN(error_result);
}
@@ -8829,6 +8847,11 @@ func_exit:
error, m_prebuilt->table->flags, m_user_thd);
}
+ /* Tell InnoDB server that there might be work for
+ utility threads: */
+
+ innobase_active_small();
+
#ifdef WITH_WSREP
if (error == DB_SUCCESS && trx->is_wsrep()
&& wsrep_thd_is_local(m_user_thd)
@@ -8890,6 +8913,11 @@ ha_innobase::delete_row(
innobase_srv_conc_exit_innodb(m_prebuilt);
+ /* Tell the InnoDB server that there might be work for
+ utility threads: */
+
+ innobase_active_small();
+
#ifdef WITH_WSREP
if (error == DB_SUCCESS && trx->is_wsrep()
&& wsrep_thd_is_local(m_user_thd)
@@ -12705,6 +12733,7 @@ create_table_info_t::create_table_update_dict()
if (m_flags2 & DICT_TF2_FTS) {
if (!innobase_fts_load_stopword(innobase_table, NULL, m_thd)) {
dict_table_close(innobase_table, FALSE, FALSE);
+ srv_active_wake_master_thread();
trx_free(m_trx);
DBUG_RETURN(-1);
}
@@ -12854,6 +12883,11 @@ ha_innobase::create(
error = info.create_table_update_dict();
+ /* Tell the InnoDB server that there might be work for
+ utility threads: */
+
+ srv_active_wake_master_thread();
+
DBUG_RETURN(error);
}
@@ -18782,7 +18816,7 @@ static MYSQL_SYSVAR_ENUM(checksum_algorithm, srv_checksum_algorithm,
static MYSQL_SYSVAR_BOOL(log_checksums, innodb_log_checksums,
PLUGIN_VAR_RQCMDARG,
- "Whether to compute and require checksums for InnoDB redo log blocks",
+ "DEPRECATED. Whether to require checksums for InnoDB redo log blocks.",
NULL, innodb_log_checksums_update, TRUE);
static MYSQL_SYSVAR_BOOL(checksums, innobase_use_checksums,
diff --git a/storage/innobase/handler/handler0alter.cc b/storage/innobase/handler/handler0alter.cc
index df42f20c55d..2b74d2a4b4c 100644
--- a/storage/innobase/handler/handler0alter.cc
+++ b/storage/innobase/handler/handler0alter.cc
@@ -10863,11 +10863,11 @@ ha_innobase::commit_inplace_alter_table(
/* Exclusively lock the table, to ensure that no other
transaction is holding locks on the table while we
- change the table definition. The MySQL meta-data lock
+ change the table definition. The meta-data lock (MDL)
should normally guarantee that no conflicting locks
exist. However, FOREIGN KEY constraints checks and any
transactions collected during crash recovery could be
- holding InnoDB locks only, not MySQL locks. */
+ holding InnoDB locks only, not MDL. */
dberr_t error = row_merge_lock_table(
m_prebuilt->trx, ctx->old_table, LOCK_X);
@@ -11244,6 +11244,11 @@ foreign_fail:
log_append_on_checkpoint(NULL);
+ /* Tell the InnoDB server that there might be work for
+ utility threads: */
+
+ srv_active_wake_master_thread();
+
if (fail) {
for (inplace_alter_handler_ctx** pctx = ctx_array;
*pctx; pctx++) {
diff --git a/storage/innobase/include/log0log.h b/storage/innobase/include/log0log.h
index 399319537c8..368d912f07f 100644
--- a/storage/innobase/include/log0log.h
+++ b/storage/innobase/include/log0log.h
@@ -2,7 +2,7 @@
Copyright (c) 1995, 2017, Oracle and/or its affiliates. All rights reserved.
Copyright (c) 2009, Google Inc.
-Copyright (c) 2017, 2019, MariaDB Corporation.
+Copyright (c) 2017, 2020, MariaDB Corporation.
Portions of this file contain modifications contributed and copyrighted by
Google, Inc. Those modifications are gratefully acknowledged and are described
@@ -56,12 +56,6 @@ step which modifies the database, is started */
#define LOG_CHECKPOINT_FREE_PER_THREAD (4U << srv_page_size_shift)
#define LOG_CHECKPOINT_EXTRA_FREE (8U << srv_page_size_shift)
-typedef ulint (*log_checksum_func_t)(const byte* log_block);
-
-/** Pointer to the log checksum calculation function. Protected with
-log_sys.mutex. */
-extern log_checksum_func_t log_checksum_algorithm_ptr;
-
/** Append a string to the log.
@param[in] str string
@param[in] len string length
@@ -263,14 +257,6 @@ log_block_set_data_len(
/*===================*/
byte* log_block, /*!< in/out: log block */
ulint len); /*!< in: data length */
-/************************************************************//**
-Calculates the checksum for a log block.
-@return checksum */
-UNIV_INLINE
-ulint
-log_block_calc_checksum(
-/*====================*/
- const byte* block); /*!< in: log block */
/** Calculates the checksum for a log block using the CRC32 algorithm.
@param[in] block log block
@@ -280,12 +266,6 @@ ulint
log_block_calc_checksum_crc32(
const byte* block);
-/** Calculates the checksum for a log block using the "no-op" algorithm.
-@return the calculated checksum value */
-UNIV_INLINE
-ulint
-log_block_calc_checksum_none(const byte*);
-
/************************************************************//**
Gets a log block checksum field value.
@return checksum */
@@ -362,7 +342,7 @@ void
log_refresh_stats(void);
/*===================*/
-/** Whether to generate and require checksums on the redo log pages */
+/** Whether to require checksums on the redo log pages */
extern my_bool innodb_log_checksums;
/* Values used as flags */
diff --git a/storage/innobase/include/log0log.ic b/storage/innobase/include/log0log.ic
index 7dfa7c0db68..8dfd86d3078 100644
--- a/storage/innobase/include/log0log.ic
+++ b/storage/innobase/include/log0log.ic
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 1995, 2015, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2017, 2019, MariaDB Corporation.
+Copyright (c) 2017, 2020, 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
@@ -190,18 +190,6 @@ log_block_convert_lsn_to_no(
0xFUL, 0x3FFFFFFFUL)) + 1);
}
-/************************************************************//**
-Calculates the checksum for a log block.
-@return checksum */
-UNIV_INLINE
-ulint
-log_block_calc_checksum(
-/*====================*/
- const byte* block) /*!< in: log block */
-{
- return(log_checksum_algorithm_ptr(block));
-}
-
/** Calculate the checksum for a log block using the pre-5.7.9 algorithm.
@param[in] block log block
@return checksum */
@@ -242,15 +230,6 @@ log_block_calc_checksum_crc32(
return ut_crc32(block, OS_FILE_LOG_BLOCK_SIZE - LOG_BLOCK_CHECKSUM);
}
-/** Calculates the checksum for a log block using the "no-op" algorithm.
-@return checksum */
-UNIV_INLINE
-ulint
-log_block_calc_checksum_none(const byte*)
-{
- return(LOG_NO_CHECKSUM_MAGIC);
-}
-
/************************************************************//**
Gets a log block checksum field value.
@return checksum */
diff --git a/storage/innobase/include/srv0srv.h b/storage/innobase/include/srv0srv.h
index 961d6aa1073..e1d37613dc9 100644
--- a/storage/innobase/include/srv0srv.h
+++ b/storage/innobase/include/srv0srv.h
@@ -784,6 +784,19 @@ srv_reset_io_thread_op_info();
/** Wake up the purge threads if there is work to do. */
void
srv_wake_purge_thread_if_not_active();
+/** Wake up the InnoDB master thread if it was suspended (not sleeping). */
+void
+srv_active_wake_master_thread_low();
+
+#define srv_active_wake_master_thread() \
+ do { \
+ if (!srv_read_only_mode) { \
+ srv_active_wake_master_thread_low(); \
+ } \
+ } while (0)
+/** Wake up the master thread if it is suspended or being suspended. */
+void
+srv_wake_master_thread();
/******************************************************************//**
Outputs to a file the output of the InnoDB Monitor.
@@ -812,13 +825,13 @@ reading this value as it is only used in heuristics.
ulint
srv_get_activity_count(void);
/*========================*/
-
-/** Check if there has been any activity.
-@param[in,out] activity_count recent activity count to be returned
-if there is a change
+/*******************************************************************//**
+Check if there has been any activity.
@return FALSE if no change in activity counter. */
-bool srv_check_activity(ulint *activity_count);
-
+ibool
+srv_check_activity(
+/*===============*/
+ ulint old_activity_count); /*!< old activity count */
/******************************************************************//**
Increment the server activity counter. */
void
diff --git a/storage/innobase/log/log0log.cc b/storage/innobase/log/log0log.cc
index 8e0fe582c84..130c830858b 100644
--- a/storage/innobase/log/log0log.cc
+++ b/storage/innobase/log/log0log.cc
@@ -2,7 +2,7 @@
Copyright (c) 1995, 2017, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2009, Google Inc.
-Copyright (c) 2014, 2019, MariaDB Corporation.
+Copyright (c) 2014, 2020, MariaDB Corporation.
Portions of this file contain modifications contributed and copyrighted by
Google, Inc. Those modifications are gratefully acknowledged and are described
@@ -83,12 +83,9 @@ reduce the size of the log.
/** Redo log system */
log_t log_sys;
-/** Whether to generate and require checksums on the redo log pages */
+/** Whether to require checksums on the redo log pages */
my_bool innodb_log_checksums;
-/** Pointer to the log checksum calculation function */
-log_checksum_func_t log_checksum_algorithm_ptr;
-
/* Next log block number to do dummy record filling if no log records written
for a while */
static ulint next_lbn_to_pad = 0;
@@ -674,7 +671,7 @@ log_block_store_checksum(
/*=====================*/
byte* block) /*!< in/out: pointer to a log block */
{
- log_block_set_checksum(block, log_block_calc_checksum(block));
+ log_block_set_checksum(block, log_block_calc_checksum_crc32(block));
}
/******************************************************//**
diff --git a/storage/innobase/page/page0page.cc b/storage/innobase/page/page0page.cc
index 86c86bd084d..ae2cf1870e1 100644
--- a/storage/innobase/page/page0page.cc
+++ b/storage/innobase/page/page0page.cc
@@ -2455,6 +2455,7 @@ wrong_page_type:
/* Validate the record list in a loop checking also that
it is consistent with the directory. */
ulint count = 0, data_size = 0, own_count = 1, slot_no = 0;
+ ulint info_bits;
slot_no = 0;
slot = page_dir_get_nth_slot(page, slot_no);
@@ -2478,9 +2479,16 @@ wrong_page_type:
goto next_rec;
}
+ info_bits = rec_get_info_bits(rec, page_is_comp(page));
+ if (info_bits
+ & ~(REC_INFO_MIN_REC_FLAG | REC_INFO_DELETED_FLAG)) {
+ ib::error() << "info_bits has an incorrect value "
+ << info_bits;
+ ret = false;
+ }
+
if (rec == first_rec) {
- if ((rec_get_info_bits(rec, page_is_comp(page))
- & REC_INFO_MIN_REC_FLAG)) {
+ if (info_bits & REC_INFO_MIN_REC_FLAG) {
if (page_has_prev(page)) {
ib::error() << "REC_INFO_MIN_REC_FLAG "
"is set on non-left page";
@@ -2491,8 +2499,7 @@ wrong_page_type:
ib::error() << "REC_INFO_MIN_REC_FLAG "
"is set in a leaf-page record";
ret = false;
- } else if (!rec_get_deleted_flag(
- rec, page_is_comp(page))
+ } else if (!(info_bits & REC_INFO_DELETED_FLAG)
!= !index->table->instant) {
ib::error() << (index->table->instant
? "Metadata record "
@@ -2506,13 +2513,51 @@ wrong_page_type:
ib::error() << "Metadata record is missing";
ret = false;
}
- } else if (rec_get_info_bits(rec, page_is_comp(page))
- & REC_INFO_MIN_REC_FLAG) {
+ } else if (info_bits & REC_INFO_MIN_REC_FLAG) {
ib::error() << "REC_INFO_MIN_REC_FLAG record is not "
"first in page";
ret = false;
}
+ if (page_is_comp(page)) {
+ const rec_comp_status_t status = rec_get_status(rec);
+ if (status != REC_STATUS_ORDINARY
+ && status != REC_STATUS_NODE_PTR
+ && status != REC_STATUS_INFIMUM
+ && status != REC_STATUS_SUPREMUM
+ && status != REC_STATUS_INSTANT) {
+ ib::error() << "impossible record status "
+ << status;
+ ret = false;
+ } else if (page_rec_is_infimum(rec)) {
+ if (status != REC_STATUS_INFIMUM) {
+ ib::error()
+ << "infimum record has status "
+ << status;
+ ret = false;
+ }
+ } else if (page_rec_is_supremum(rec)) {
+ if (status != REC_STATUS_SUPREMUM) {
+ ib::error() << "supremum record has "
+ "status "
+ << status;
+ ret = false;
+ }
+ } else if (!page_is_leaf(page)) {
+ if (status != REC_STATUS_NODE_PTR) {
+ ib::error() << "node ptr record has "
+ "status "
+ << status;
+ ret = false;
+ }
+ } else if (!index->is_instant()
+ && status == REC_STATUS_INSTANT) {
+ ib::error() << "instantly added record in a "
+ "non-instant index";
+ ret = false;
+ }
+ }
+
/* Check that the records are in the ascending order */
if (count >= PAGE_HEAP_NO_USER_LOW
&& !page_rec_is_supremum(rec)) {
diff --git a/storage/innobase/row/row0mysql.cc b/storage/innobase/row/row0mysql.cc
index ac5986243d6..86cdf1995db 100644
--- a/storage/innobase/row/row0mysql.cc
+++ b/storage/innobase/row/row0mysql.cc
@@ -3811,7 +3811,7 @@ funct_exit_all_freed:
trx->op_info = "";
- srv_inc_activity_count();
+ srv_wake_master_thread();
DBUG_RETURN(err);
}
@@ -4522,12 +4522,20 @@ end:
if (err != DB_SUCCESS) {
if (old_is_tmp) {
- ib::error() << "In ALTER TABLE "
+ /* In case of copy alter, ignore the
+ loading of foreign key constraint
+ when foreign_key_check is disabled */
+ ib::error_or_warn(trx->check_foreigns)
+ << "In ALTER TABLE "
<< ut_get_name(trx, new_name)
<< " has or is referenced in foreign"
" key constraints which are not"
" compatible with the new table"
" definition.";
+ if (!trx->check_foreigns) {
+ err = DB_SUCCESS;
+ goto funct_exit;
+ }
} else {
ib::error() << "In RENAME TABLE table "
<< ut_get_name(trx, new_name)
diff --git a/storage/innobase/row/row0uins.cc b/storage/innobase/row/row0uins.cc
index 2f66f3636ff..2f4cb90e265 100644
--- a/storage/innobase/row/row0uins.cc
+++ b/storage/innobase/row/row0uins.cc
@@ -84,11 +84,11 @@ row_undo_ins_remove_clust_rec(
online = false;
} else {
index->set_modified(mtr);
+ ut_ad(lock_table_has_locks(index->table));
online = dict_index_is_online_ddl(index);
if (online) {
ut_ad(node->rec_type == TRX_UNDO_INSERT_REC);
- ut_ad(node->trx->dict_operation_lock_mode
- != RW_X_LATCH);
+ ut_ad(!node->trx->dict_operation_lock_mode);
ut_ad(node->table->id != DICT_INDEXES_ID);
ut_ad(node->table->id != DICT_COLUMNS_ID);
mtr_s_lock_index(index, &mtr);
@@ -551,6 +551,9 @@ row_undo_ins(
return DB_SUCCESS;
}
+ ut_ad(node->table->is_temporary()
+ || lock_table_has_locks(node->table));
+
/* Iterate over all the indexes and undo the insert.*/
node->index = dict_table_get_first_index(node->table);
diff --git a/storage/innobase/row/row0umod.cc b/storage/innobase/row/row0umod.cc
index e9551d33c73..e4654354068 100644
--- a/storage/innobase/row/row0umod.cc
+++ b/storage/innobase/row/row0umod.cc
@@ -269,10 +269,7 @@ row_undo_mod_clust(
bool online;
ut_ad(thr_get_trx(thr) == node->trx);
- ut_ad(node->trx->dict_operation_lock_mode);
ut_ad(node->trx->in_rollback);
- ut_ad(rw_lock_own_flagged(&dict_sys.latch,
- RW_LOCK_FLAG_X | RW_LOCK_FLAG_S));
log_free_check();
pcur = &node->pcur;
@@ -284,11 +281,12 @@ row_undo_mod_clust(
mtr.set_log_mode(MTR_LOG_NO_REDO);
} else {
index->set_modified(mtr);
+ ut_ad(lock_table_has_locks(index->table));
}
online = dict_index_is_online_ddl(index);
if (online) {
- ut_ad(node->trx->dict_operation_lock_mode != RW_X_LATCH);
+ ut_ad(!node->trx->dict_operation_lock_mode);
mtr_s_lock_index(index, &mtr);
}
@@ -327,17 +325,7 @@ row_undo_mod_clust(
ut_ad(err == DB_SUCCESS || err == DB_OUT_OF_FILE_SPACE);
}
- /* Online rebuild cannot be initiated while we are holding
- dict_sys.latch and index->lock. (It can be aborted.) */
- ut_ad(online || !dict_index_is_online_ddl(index));
-
- if (err == DB_SUCCESS && online) {
-
- ut_ad(rw_lock_own_flagged(
- &index->lock,
- RW_LOCK_FLAG_S | RW_LOCK_FLAG_X
- | RW_LOCK_FLAG_SX));
-
+ if (err == DB_SUCCESS && online && dict_index_is_online_ddl(index)) {
switch (node->rec_type) {
case TRX_UNDO_DEL_MARK_REC:
row_log_table_insert(
@@ -911,37 +899,6 @@ func_exit_no_pcur:
}
/***********************************************************//**
-Flags a secondary index corrupted. */
-static MY_ATTRIBUTE((nonnull))
-void
-row_undo_mod_sec_flag_corrupted(
-/*============================*/
- trx_t* trx, /*!< in/out: transaction */
- dict_index_t* index) /*!< in: secondary index */
-{
- ut_ad(!dict_index_is_clust(index));
-
- switch (trx->dict_operation_lock_mode) {
- case RW_S_LATCH:
- /* Because row_undo() is holding an S-latch
- on the data dictionary during normal rollback,
- we can only mark the index corrupted in the
- data dictionary cache. TODO: fix this somehow.*/
- mutex_enter(&dict_sys.mutex);
- dict_set_corrupted_index_cache_only(index);
- mutex_exit(&dict_sys.mutex);
- break;
- default:
- ut_ad(0);
- /* fall through */
- case RW_X_LATCH:
- /* This should be the rollback of a data dictionary
- transaction. */
- dict_set_corrupted(index, trx, "rollback");
- }
-}
-
-/***********************************************************//**
Undoes a modify in secondary indexes when undo record type is UPD_DEL.
@return DB_SUCCESS or DB_OUT_OF_FILE_SPACE */
static MY_ATTRIBUTE((nonnull, warn_unused_result))
@@ -1054,8 +1011,7 @@ row_undo_mod_del_mark_sec(
}
if (err == DB_DUPLICATE_KEY) {
- row_undo_mod_sec_flag_corrupted(
- thr_get_trx(thr), index);
+ index->type |= DICT_CORRUPT;
err = DB_SUCCESS;
/* Do not return any error to the caller. The
duplicate will be reported by ALTER TABLE or
@@ -1200,8 +1156,7 @@ row_undo_mod_upd_exist_sec(
}
if (err == DB_DUPLICATE_KEY) {
- row_undo_mod_sec_flag_corrupted(
- thr_get_trx(thr), index);
+ index->type |= DICT_CORRUPT;
err = DB_SUCCESS;
} else if (err != DB_SUCCESS) {
break;
@@ -1364,6 +1319,8 @@ row_undo_mod(
return DB_SUCCESS;
}
+ ut_ad(node->table->is_temporary()
+ || lock_table_has_locks(node->table));
node->index = dict_table_get_first_index(node->table);
ut_ad(dict_index_is_clust(node->index));
diff --git a/storage/innobase/row/row0undo.cc b/storage/innobase/row/row0undo.cc
index a07258910b4..789bcc441bc 100644
--- a/storage/innobase/row/row0undo.cc
+++ b/storage/innobase/row/row0undo.cc
@@ -418,15 +418,17 @@ row_undo(
return DB_SUCCESS;
}
- /* Prevent DROP TABLE etc. while we are rolling back this row.
- If we are doing a TABLE CREATE or some other dictionary operation,
- then we already have dict_sys.latch locked in x-mode. Do not
- try to lock again, because that would cause a hang. */
-
+ /* Prevent prepare_inplace_alter_table_dict() from adding
+ dict_table_t::indexes while we are processing the record.
+ Recovered transactions are not protected by MDL, and the
+ secondary index creation is not protected by table locks
+ for online operation. (A table lock would only be acquired
+ when committing the ALTER TABLE operation.) */
trx_t* trx = node->trx;
- const bool locked_data_dict = (trx->dict_operation_lock_mode == 0);
+ const bool locked_data_dict = UNIV_UNLIKELY(trx->is_recovered)
+ && !trx->dict_operation_lock_mode;
- if (locked_data_dict) {
+ if (UNIV_UNLIKELY(locked_data_dict)) {
row_mysql_freeze_data_dictionary(trx);
}
@@ -446,7 +448,7 @@ row_undo(
err = DB_CORRUPTION;
}
- if (locked_data_dict) {
+ if (UNIV_UNLIKELY(locked_data_dict)) {
row_mysql_unfreeze_data_dictionary(trx);
}
diff --git a/storage/innobase/srv/srv0srv.cc b/storage/innobase/srv/srv0srv.cc
index 0bd52cb486d..a5305684935 100644
--- a/storage/innobase/srv/srv0srv.cc
+++ b/storage/innobase/srv/srv0srv.cc
@@ -1910,6 +1910,33 @@ srv_get_active_thread_type(void)
return(ret);
}
+/** Wake up the InnoDB master thread if it was suspended (not sleeping). */
+void
+srv_active_wake_master_thread_low()
+{
+ ut_ad(!srv_read_only_mode);
+ ut_ad(!mutex_own(&srv_sys.mutex));
+
+ srv_inc_activity_count();
+
+ if (srv_sys.n_threads_active[SRV_MASTER] == 0) {
+ srv_slot_t* slot;
+
+ srv_sys_mutex_enter();
+
+ slot = &srv_sys.sys_threads[SRV_MASTER_SLOT];
+
+ /* Only if the master thread has been started. */
+
+ if (slot->in_use) {
+ ut_a(srv_slot_get_type(slot) == SRV_MASTER);
+ os_event_set(slot->event);
+ }
+
+ srv_sys_mutex_exit();
+ }
+}
+
/** Wake up the purge threads if there is work to do. */
void
srv_wake_purge_thread_if_not_active()
@@ -1925,6 +1952,14 @@ srv_wake_purge_thread_if_not_active()
}
}
+/** Wake up the master thread if it is suspended or being suspended. */
+void
+srv_wake_master_thread()
+{
+ srv_inc_activity_count();
+ srv_release_threads(SRV_MASTER, 1);
+}
+
/*******************************************************************//**
Get current server activity count. We don't hold srv_sys::mutex while
reading this value as it is only used in heuristics.
@@ -1936,20 +1971,15 @@ srv_get_activity_count(void)
return(srv_sys.activity_count);
}
-/** Check if there has been any activity.
-@param[in,out] activity_count recent activity count to be returned
-if there is a change
+/*******************************************************************//**
+Check if there has been any activity.
@return FALSE if no change in activity counter. */
-bool srv_check_activity(ulint *activity_count)
+ibool
+srv_check_activity(
+/*===============*/
+ ulint old_activity_count) /*!< in: old activity count */
{
- ulint new_activity_count= srv_sys.activity_count;
- if (new_activity_count != *activity_count)
- {
- *activity_count= new_activity_count;
- return true;
- }
-
- return false;
+ return(srv_sys.activity_count != old_activity_count);
}
/********************************************************************//**
@@ -2346,30 +2376,48 @@ DECLARE_THREAD(srv_master_thread)(
slot = srv_reserve_slot(SRV_MASTER);
ut_a(slot == srv_sys.sys_threads);
+loop:
while (srv_shutdown_state <= SRV_SHUTDOWN_INITIATED) {
srv_master_sleep();
MONITOR_INC(MONITOR_MASTER_THREAD_SLEEP);
- if (srv_check_activity(&old_activity_count)) {
+ if (srv_check_activity(old_activity_count)) {
+ old_activity_count = srv_get_activity_count();
srv_master_do_active_tasks();
} else {
srv_master_do_idle_tasks();
}
}
- ut_ad(srv_shutdown_state == SRV_SHUTDOWN_EXIT_THREADS
- || srv_shutdown_state == SRV_SHUTDOWN_CLEANUP);
-
- if (srv_shutdown_state == SRV_SHUTDOWN_CLEANUP
- && srv_fast_shutdown < 2) {
- srv_shutdown(srv_fast_shutdown == 0);
+ switch (srv_shutdown_state) {
+ case SRV_SHUTDOWN_NONE:
+ case SRV_SHUTDOWN_INITIATED:
+ break;
+ case SRV_SHUTDOWN_FLUSH_PHASE:
+ case SRV_SHUTDOWN_LAST_PHASE:
+ ut_ad(0);
+ /* fall through */
+ case SRV_SHUTDOWN_EXIT_THREADS:
+ /* srv_init_abort() must have been invoked */
+ case SRV_SHUTDOWN_CLEANUP:
+ if (srv_shutdown_state == SRV_SHUTDOWN_CLEANUP
+ && srv_fast_shutdown < 2) {
+ srv_shutdown(srv_fast_shutdown == 0);
+ }
+ srv_suspend_thread(slot);
+ my_thread_end();
+ os_thread_exit();
}
+ srv_main_thread_op_info = "suspending";
+
srv_suspend_thread(slot);
- my_thread_end();
- os_thread_exit();
- OS_THREAD_DUMMY_RETURN;
+
+ srv_main_thread_op_info = "waiting for server activity";
+
+ srv_resume_thread(slot);
+ goto loop;
}
/** @return whether purge should exit due to shutdown */
@@ -2537,13 +2585,15 @@ static uint32_t srv_do_purge(ulint* n_total_purged
++n_use_threads;
}
- } else if (srv_check_activity(&old_activity_count)
+ } else if (srv_check_activity(old_activity_count)
&& n_use_threads > 1) {
/* History length same or smaller since last snapshot,
use fewer threads. */
--n_use_threads;
+
+ old_activity_count = srv_get_activity_count();
}
/* Ensure that the purge threads are less than what
diff --git a/storage/innobase/srv/srv0start.cc b/storage/innobase/srv/srv0start.cc
index 42d757d1a84..746935f5794 100644
--- a/storage/innobase/srv/srv0start.cc
+++ b/storage/innobase/srv/srv0start.cc
@@ -1088,7 +1088,7 @@ srv_shutdown_all_bg_threads()
if (srv_start_state_is_set(SRV_START_STATE_MASTER)) {
/* c. We wake the master thread so that
it exits */
- srv_inc_activity_count();
+ srv_wake_master_thread();
}
if (srv_start_state_is_set(SRV_START_STATE_PURGE)) {
@@ -2420,7 +2420,7 @@ void srv_shutdown_bg_undo_sources()
fts_optimize_shutdown();
dict_stats_shutdown();
while (row_get_background_drop_list_len_low()) {
- srv_inc_activity_count();
+ srv_wake_master_thread();
os_thread_yield();
}
srv_undo_sources = false;
diff --git a/storage/innobase/trx/trx0roll.cc b/storage/innobase/trx/trx0roll.cc
index 917274d5f0d..32b053b2bab 100644
--- a/storage/innobase/trx/trx0roll.cc
+++ b/storage/innobase/trx/trx0roll.cc
@@ -160,6 +160,9 @@ trx_rollback_to_savepoint_low(
mem_heap_free(heap);
+ /* There might be work for utility threads.*/
+ srv_active_wake_master_thread();
+
MONITOR_DEC(MONITOR_TRX_ACTIVE);
}
diff --git a/storage/innobase/trx/trx0trx.cc b/storage/innobase/trx/trx0trx.cc
index d63d7db4e32..7da5b2bc738 100644
--- a/storage/innobase/trx/trx0trx.cc
+++ b/storage/innobase/trx/trx0trx.cc
@@ -1485,6 +1485,11 @@ inline void trx_t::commit_in_memory(const mtr_t *mtr)
must_flush_log_later= true;
else if (srv_flush_log_at_trx_commit)
trx_flush_log_if_needed(commit_lsn, this);
+
+ /* Tell server some activity has happened, since the trx does
+ changes something. Background utility threads like master thread,
+ purge thread or page_cleaner thread might have some work to do. */
+ srv_active_wake_master_thread();
}
ut_ad(!rsegs.m_noredo.undo);
diff --git a/unittest/mysys/CMakeLists.txt b/unittest/mysys/CMakeLists.txt
index ec4e0b91626..984b033e7aa 100644
--- a/unittest/mysys/CMakeLists.txt
+++ b/unittest/mysys/CMakeLists.txt
@@ -15,7 +15,7 @@
MY_ADD_TESTS(bitmap base64 my_atomic my_rdtsc lf my_malloc my_getopt dynstring
byte_order
- queues LINK_LIBRARIES mysys)
+ queues stacktrace LINK_LIBRARIES mysys)
MY_ADD_TESTS(my_vsnprintf LINK_LIBRARIES strings mysys)
MY_ADD_TESTS(aes LINK_LIBRARIES mysys mysys_ssl)
ADD_DEFINITIONS(${SSL_DEFINES})
diff --git a/unittest/mysys/stacktrace-t.c b/unittest/mysys/stacktrace-t.c
new file mode 100644
index 00000000000..8fa0db15b36
--- /dev/null
+++ b/unittest/mysys/stacktrace-t.c
@@ -0,0 +1,67 @@
+
+/* Copyright (c) 2020, 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 Foundation; version 2 of the License.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335 USA */
+
+#include <my_global.h>
+#include <my_sys.h>
+#include <stdio.h>
+#include <my_stacktrace.h>
+#include <tap.h>
+
+char b_bss[10];
+
+void test_my_safe_print_str()
+{
+ char b_stack[10];
+ char *b_heap= strdup("LEGAL");
+ memcpy(b_stack, "LEGAL", 6);
+ memcpy(b_bss, "LEGAL", 6);
+
+#ifndef __SANITIZE_ADDRESS__
+ fprintf(stderr, "\n===== stack =====\n");
+ my_safe_print_str(b_stack, 65535);
+ fprintf(stderr, "\n===== heap =====\n");
+ my_safe_print_str(b_heap, 65535);
+ fprintf(stderr, "\n===== BSS =====\n");
+ my_safe_print_str(b_bss, 65535);
+ fprintf(stderr, "\n===== data =====\n");
+ my_safe_print_str("LEGAL", 65535);
+ fprintf(stderr, "\n===== Above is a junk, but it is expected. =====\n");
+#endif /*__SANITIZE_ADDRESS__*/
+ fprintf(stderr, "\n===== Nornal length test =====\n");
+ my_safe_print_str("LEGAL", 5);
+ fprintf(stderr, "\n===== NULL =====\n");
+ my_safe_print_str(0, 5);
+#ifndef __SANITIZE_ADDRESS__
+ fprintf(stderr, "\n===== (const char*) 1 =====\n");
+ my_safe_print_str((const char*)1, 5);
+#endif /*__SANITIZE_ADDRESS__*/
+
+ free(b_heap);
+
+ ok(1, "test_my_safe_print_str");
+}
+
+
+int main(int argc __attribute__((unused)), char **argv)
+{
+ MY_INIT(argv[0]);
+ plan(1);
+
+ test_my_safe_print_str();
+
+ my_end(0);
+ return exit_status();
+}