Merge 10.3 into 10.4

This commit is contained in:
Marko Mäkelä 2020-08-20 11:01:47 +03:00
commit 2fa9f8c53a
38 changed files with 453 additions and 323 deletions

View File

@ -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);

View File

@ -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

View File

@ -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

View File

@ -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 |

View File

@ -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

View File

@ -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;

View File

@ -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;

View File

@ -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

View File

@ -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;

View File

@ -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;

View File

@ -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

View File

@ -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 |

View File

@ -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;
#

View File

@ -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;

View File

@ -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
}

View File

@ -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

View File

@ -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 "

View File

@ -5325,7 +5325,6 @@ btr_validate_index(
if (!btr_validate_level(index, trx, n - i, lockout)) {
err = DB_CORRUPTION;
break;
}
}

View File

@ -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);

View File

@ -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 */

View File

@ -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;

View File

@ -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 */
@ -1829,6 +1837,23 @@ wsrep_abort_transaction(handlerton* hton, THD *bf_thd, THD *victim_thd,
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
@ -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,

View File

@ -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++) {

View File

@ -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 */

View File

@ -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 */

View File

@ -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

View File

@ -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));
}
/******************************************************//**

View File

@ -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)) {

View File

@ -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)

View File

@ -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);

View File

@ -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(
@ -910,37 +898,6 @@ func_exit_no_pcur:
return(err);
}
/***********************************************************//**
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 */
@ -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));

View File

@ -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);
}

View File

@ -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

View File

@ -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;

View File

@ -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);
}

View File

@ -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);

View File

@ -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})

View File

@ -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();
}