Merge 10.5 into 10.6

This commit is contained in:
Marko Mäkelä 2024-06-10 15:22:15 +03:00
commit 27834ebc91
41 changed files with 444 additions and 197 deletions

View file

@ -1117,6 +1117,8 @@ inline int get_command_index(char cmd_char)
static int delimiter_index= -1;
static int charset_index= -1;
static int sandbox_index= -1;
static bool real_binary_mode= FALSE;
@ -1127,7 +1129,8 @@ int main(int argc,char *argv[])
MY_INIT(argv[0]);
DBUG_ENTER("main");
DBUG_PROCESS(argv[0]);
sandbox_index= get_command_index('-');
charset_index= get_command_index('C');
delimiter_index= get_command_index('d');
delimiter_str= delimiter;
@ -2261,8 +2264,9 @@ static int read_and_execute(bool interactive)
/**
It checks if the input is a short form command. It returns the command's
pointer if a command is found, else return NULL. Note that if binary-mode
is set, then only \C is searched for.
pointer if a command is found, else return NULL.
Note that if binary-mode is set, then only \C and \- are searched for.
@param cmd_char A character of one byte.
@ -2277,13 +2281,23 @@ static COMMANDS *find_command(char cmd_char)
int index= -1;
/*
In binary-mode, we disallow all mysql commands except '\C'
and DELIMITER.
In binary-mode, we disallow all client commands except '\C',
DELIMITER (see long comand finding find_command(char *))
and '\-' (sandbox, see following comment).
*/
if (real_binary_mode)
{
if (cmd_char == 'C')
index= charset_index;
/*
binary-mode enforces stricter controls compared to sandbox mode.
Whether sandbox mode is enabled or not is irrelevant when
binary-mode is active.
The only purpose of processing sandbox mode here is to avoid error
messages on files made by mysqldump.
*/
else if (cmd_char == '-')
index= sandbox_index;
}
else
index= get_command_index(cmd_char);
@ -2339,6 +2353,12 @@ static COMMANDS *find_command(char *name)
len= (uint) strlen(name);
int index= -1;
/*
In binary-mode, we disallow all client commands except DELIMITER
and short commands '\C' and '\-' (see short command finding
find_command(char)).
*/
if (real_binary_mode)
{
if (is_delimiter_command(name, len))

View file

@ -686,7 +686,7 @@ static int load_plugin_data(char *plugin_name, char *config_file)
if (i == -1) /* if first pass, read this line as so_name */
{
/* Add proper file extension for soname */
if (safe_strcpy(line + line_len - 1, sizeof(line), FN_SOEXT))
if (safe_strcpy_truncated(line + line_len - 1, sizeof line, FN_SOEXT))
{
reason= "Plugin name too long.";
fclose(file_ptr);
@ -749,7 +749,7 @@ static int check_options(int argc, char **argv, char *operation)
const char *plugin_dir_prefix = "--plugin_dir=";
size_t plugin_dir_len= strlen(plugin_dir_prefix);
strcpy(plugin_name, "");
*plugin_name= '\0';
for (i = 0; i < argc && num_found < 5; i++)
{
@ -787,8 +787,8 @@ static int check_options(int argc, char **argv, char *operation)
/* read the plugin config file and check for match against argument */
else
{
if (safe_strcpy(plugin_name, sizeof(plugin_name), argv[i]) ||
safe_strcpy(config_file, sizeof(config_file), argv[i]) ||
if (safe_strcpy_truncated(plugin_name, sizeof plugin_name, argv[i]) ||
safe_strcpy_truncated(config_file, sizeof config_file, argv[i]) ||
safe_strcat(config_file, sizeof(config_file), ".ini"))
{
fprintf(stderr, "ERROR: argument is too long.\n");

View file

@ -6277,7 +6277,7 @@ int do_done(struct st_command *command)
if (*cur_block->delim)
{
/* Restore "old" delimiter after false if block */
if (safe_strcpy(delimiter, sizeof(delimiter), cur_block->delim))
if (safe_strcpy_truncated(delimiter, sizeof delimiter, cur_block->delim))
die("Delimiter too long, truncated");
delimiter_length= strlen(delimiter);
@ -6538,7 +6538,8 @@ void do_block(enum block_cmd cmd, struct st_command* command)
else
{
/* Remember "old" delimiter if entering a false if block */
if (safe_strcpy(cur_block->delim, sizeof(cur_block->delim), delimiter))
if (safe_strcpy_truncated(cur_block->delim, sizeof cur_block->delim,
delimiter))
die("Delimiter too long, truncated");
}

View file

@ -239,15 +239,14 @@ static inline void lex_string_set3(LEX_CSTRING *lex_str, const char *c_str,
lex_str->length= len;
}
/*
Copies src into dst and ensures dst is a NULL terminated C string.
/**
Copies a string.
Returns 1 if the src string was truncated due to too small size of dst.
Returns 0 if src completely fit within dst. Pads the remaining dst with '\0'
Note: dst_size must be > 0
@param dst destination buffer, will be NUL padded.
@param dst_size size of dst buffer, must be > 0
@param src NUL terminated source string
*/
static inline int safe_strcpy(char *dst, size_t dst_size, const char *src)
static inline void safe_strcpy(char *dst, size_t dst_size, const char *src)
{
DBUG_ASSERT(dst_size > 0);
@ -256,45 +255,49 @@ static inline int safe_strcpy(char *dst, size_t dst_size, const char *src)
*
* 2) IF there is no 0 byte in the first dst_size bytes of src, strncpy will
* copy dst_size bytes, and the final byte won't be 0.
*
* In GCC 8+, the `-Wstringop-truncation` warning will object to strncpy()
* being used in this way, so we need to disable this warning for this
* single statement.
*/
#if defined(__GNUC__) && __GNUC__ >= 8
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wstringop-truncation"
#endif
strncpy(dst, src, dst_size);
#if defined(__GNUC__) && __GNUC__ >= 8
#pragma GCC diagnostic pop
#endif
dst[dst_size - 1]= 0;
}
if (dst[dst_size-1])
/**
Copies a string, checking for truncation.
@param dst destination buffer, will be NUL padded.
@param dst_size size of dst buffer, must be > 0
@param src NUL terminated source string
@retval 1 if the src string was truncated due to too small size of dst.
@retval 0 if src completely fit within dst,
*/
static inline int safe_strcpy_truncated(char *dst, size_t dst_size,
const char *src)
{
DBUG_ASSERT(dst_size > 0);
strncpy(dst, src, dst_size);
if (dst[dst_size - 1])
{
/* Only possible in case (2), meaning src was truncated. */
dst[dst_size-1]= 0;
dst[dst_size - 1]= 0;
return 1;
}
return 0;
}
/*
Appends src to dst and ensures dst is a NULL terminated C string.
/**
Appends src to dst and ensures dst is a NUL terminated C string.
Returns 1 if the src string was truncated due to too small size of dst.
Returns 0 if src completely fit within the remaining dst space. Pads the
remaining dst with '\0'.
Note: dst_size must be > 0
@retval 1 if the src string was truncated due to too small size of dst.
@retval 0 if src completely fit within the remaining dst space,
including NUL termination.
*/
static inline int safe_strcat(char *dst, size_t dst_size, const char *src)
{
size_t init_len= strlen(dst);
if (init_len >= dst_size - 1)
if (init_len > dst_size)
return 1;
return safe_strcpy(dst + init_len, dst_size - init_len, src);
return safe_strcpy_truncated(dst + init_len, dst_size - init_len, src);
}
#ifdef __cplusplus

View file

@ -0,0 +1,4 @@
[binlogoff]
[binlogon]
log-bin

View file

@ -0,0 +1,3 @@
# include file for test files that can be run with and without log-bin
# (see include/log_bin.combinations)

View file

@ -2061,4 +2061,11 @@ DROP TABLE t1;
#
CREATE TABLE t1 (id1 INT, id2 INT, primary key (id1), unique index (id2) visible);
drop table t1;
#
# MDEV-32376 SHOW CREATE DATABASE statement crashes the server when db name contains some unicode characters, ASAN stack-buffer-overflow
#
SET NAMES utf8mb3;
SHOW CREATE DATABASE `#testone#■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■`;
ERROR 42000: Incorrect database name '#testone#■■■■■■■■■■■■■■■■■■■■■■■■■■■■■...'
SET NAMES DEFAULT;
# End of 10.5 Test

View file

@ -1935,4 +1935,13 @@ DROP TABLE t1;
CREATE TABLE t1 (id1 INT, id2 INT, primary key (id1), unique index (id2) visible);
drop table t1;
--echo #
--echo # MDEV-32376 SHOW CREATE DATABASE statement crashes the server when db name contains some unicode characters, ASAN stack-buffer-overflow
--echo #
SET NAMES utf8mb3;
--error ER_WRONG_DB_NAME
SHOW CREATE DATABASE `#testone#■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■`;
SET NAMES DEFAULT;
--echo # End of 10.5 Test

View file

@ -658,4 +658,15 @@ tee
source
^^^
3
#
# MDEV-34203: Sandbox mode \- is not compatible with --binary-mode
#
create table t1 (a int);
drop table t1;
show create table t1;
Table Create Table
t1 CREATE TABLE `t1` (
`a` int(11) DEFAULT NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
drop table t1;
# End of 10.5 tests

View file

@ -757,4 +757,20 @@ source $MYSQL_TMP_DIR/mysql_in;" $MYSQL_TMP_DIR/mysql_in2;
--remove_file $MYSQL_TMP_DIR/mysql_in
--remove_file $MYSQL_TMP_DIR/mysql_in2
--echo #
--echo # MDEV-34203: Sandbox mode \- is not compatible with --binary-mode
--echo #
create table t1 (a int);
--exec $MYSQL_DUMP test t1 > $MYSQLTEST_VARDIR/tmp/MDEV-34203.sql
drop table t1;
--exec $MYSQL --binary-mode test 2>&1 < $MYSQLTEST_VARDIR/tmp/MDEV-34203.sql
show create table t1;
drop table t1;
--remove_file $MYSQLTEST_VARDIR/tmp/MDEV-34203.sql
--echo # End of 10.5 tests

View file

@ -0,0 +1,46 @@
connection node_2;
connection node_1;
connection node_1;
CREATE TABLE `t1` (
`id` int(10) unsigned NOT NULL,
`other_id` int(10) unsigned NOT NULL,
PRIMARY KEY (`id`,`other_id`)
) ENGINE=InnoDB
PARTITION BY LIST (`id` MOD 2)
(PARTITION `p0` VALUES IN (0) ENGINE = InnoDB,
PARTITION `p1` VALUES IN (1) ENGINE = InnoDB);
INSERT INTO t1 VALUES (1, 0);
CREATE TABLE t2 LIKE t1;
START TRANSACTION;
INSERT INTO t2(SELECT * FROM t1 WHERE id = 1);
DELETE FROM t1 WHERE id = 1;
COMMIT;
connection node_2;
SELECT * from t1;
id other_id
SELECT * from t2;
id other_id
1 0
DROP TABLE t1, t2;
connection node_1;
CREATE TABLE `t1` (
`id` int(10) unsigned NOT NULL,
`other_id` int(10) unsigned NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB
PARTITION BY LIST (`id` MOD 2)
(PARTITION `p0` VALUES IN (0) ENGINE = InnoDB,
PARTITION `p1` VALUES IN (1) ENGINE = InnoDB);
INSERT INTO t1 VALUES (1, 0);
CREATE TABLE t2 LIKE t1;
START TRANSACTION;
INSERT INTO t2(SELECT * FROM t1 WHERE id = 1);
DELETE FROM t1 WHERE id = 1;
COMMIT;
connection node_2;
SELECT * from t1;
id other_id
SELECT * from t2;
id other_id
1 0
DROP TABLE t1, t2;

View file

@ -1,5 +1,6 @@
--source include/galera_cluster.inc
--source include/have_innodb.inc
--source include/log_bin.inc
#
# This tests simple autocommit replication of MyISAM tables.

View file

@ -2,6 +2,7 @@
--source include/have_partition.inc
--source include/big_test.inc
--source include/force_restart.inc
--source include/log_bin.inc
--connection node_1

View file

@ -0,0 +1,55 @@
--source include/galera_cluster.inc
--source include/have_partition.inc
--source include/log_bin.inc
--connection node_1
CREATE TABLE `t1` (
`id` int(10) unsigned NOT NULL,
`other_id` int(10) unsigned NOT NULL,
PRIMARY KEY (`id`,`other_id`)
) ENGINE=InnoDB
PARTITION BY LIST (`id` MOD 2)
(PARTITION `p0` VALUES IN (0) ENGINE = InnoDB,
PARTITION `p1` VALUES IN (1) ENGINE = InnoDB);
INSERT INTO t1 VALUES (1, 0);
CREATE TABLE t2 LIKE t1;
START TRANSACTION;
INSERT INTO t2(SELECT * FROM t1 WHERE id = 1);
DELETE FROM t1 WHERE id = 1;
COMMIT;
--connection node_2
SELECT * from t1;
SELECT * from t2;
DROP TABLE t1, t2;
--connection node_1
CREATE TABLE `t1` (
`id` int(10) unsigned NOT NULL,
`other_id` int(10) unsigned NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB
PARTITION BY LIST (`id` MOD 2)
(PARTITION `p0` VALUES IN (0) ENGINE = InnoDB,
PARTITION `p1` VALUES IN (1) ENGINE = InnoDB);
INSERT INTO t1 VALUES (1, 0);
CREATE TABLE t2 LIKE t1;
START TRANSACTION;
INSERT INTO t2(SELECT * FROM t1 WHERE id = 1);
DELETE FROM t1 WHERE id = 1;
COMMIT;
--connection node_2
SELECT * from t1;
SELECT * from t2;
DROP TABLE t1, t2;

View file

@ -1,6 +1,6 @@
--source include/galera_cluster.inc
--source include/have_innodb.inc
--source include/have_log_bin.inc
--source include/log_bin.inc
--source include/have_sequence.inc
--source include/have_aria.inc

View file

@ -0,0 +1,6 @@
call mtr.add_suppression("\\[Warning\\] InnoDB: innodb_open_files=.* is not greater than the number of system tablespace files, temporary tablespace files, innodb_undo_tablespaces=.*");
call mtr.add_suppression("\\[Warning\\] InnoDB: innodb_open_files=.* is exceeded \\(.* files stay open\\)");
FOUND 1 /\[Warning\] InnoDB: innodb_open_files=.* is not greater than the number of system tablespace files, temporary tablespace files, innodb_undo_tablespaces=.*/ in mysqld.1.err
CREATE TABLE t1(f1 INT NOT NULL)ENGINE=InnoDB;
DROP TABLE t1;
# restart: --innodb_open_files=0

View file

@ -0,0 +1,3 @@
--innodb_undo_tablespaces=8
--innodb_open_files=10
--innodb_temp_data_file_path=ibtmp1:32M;ibtmp2:32M:autoextend

View file

@ -0,0 +1,12 @@
--source include/have_innodb.inc
--source include/not_embedded.inc
call mtr.add_suppression("\\[Warning\\] InnoDB: innodb_open_files=.* is not greater than the number of system tablespace files, temporary tablespace files, innodb_undo_tablespaces=.*");
call mtr.add_suppression("\\[Warning\\] InnoDB: innodb_open_files=.* is exceeded \\(.* files stay open\\)");
let SEARCH_PATTERN= \[Warning\] InnoDB: innodb_open_files=.* is not greater than the number of system tablespace files, temporary tablespace files, innodb_undo_tablespaces=.*;
let SEARCH_FILE= $MYSQLTEST_VARDIR/log/mysqld.1.err;
--source include/search_pattern_in_file.inc
CREATE TABLE t1(f1 INT NOT NULL)ENGINE=InnoDB;
DROP TABLE t1;
let $restart_parameters=--innodb_open_files=0;
--source include/restart_mysqld.inc

View file

@ -526,7 +526,7 @@ extern "C" const char *my_crc32c_implementation()
} // namespace crc32c
} // namespace mysys_namespace
extern "C" unsigned my_crc32c(unsigned int crc, const char *buf, size_t size)
extern "C" uint32 my_crc32c(uint32 crc, const void *buf, size_t size)
{
return mysys_namespace::crc32c::ChosenExtend(crc,buf, size);
}

View file

@ -184,9 +184,9 @@ static inline uint64_t CombineCRC(
// Compute CRC-32C using the Intel hardware instruction.
extern "C"
USE_PCLMUL
uint32_t crc32c_3way(uint32_t crc, const char *buf, size_t len)
uint32_t crc32c_3way(uint32_t crc, const void *buf, size_t len)
{
const unsigned char* next = (const unsigned char*)buf;
const unsigned char* next = static_cast<const unsigned char*>(buf);
uint64_t count;
uint64_t crc0, crc1, crc2;
crc0 = crc ^ 0xffffffffu;

View file

@ -54,9 +54,9 @@ static uint32_t cpuid_ecx()
#endif
}
typedef unsigned (*my_crc32_t)(unsigned, const void *, size_t);
extern "C" unsigned int crc32_pclmul(unsigned int, const void *, size_t);
extern "C" unsigned int crc32c_3way(unsigned int, const void *, size_t);
typedef uint32_t (*my_crc32_t)(uint32_t, const void *, size_t);
extern "C" uint32_t crc32_pclmul(uint32_t, const void *, size_t);
extern "C" uint32_t crc32c_3way(uint32_t, const void *, size_t);
#ifdef USE_VPCLMULQDQ
# include <immintrin.h>

View file

@ -242,8 +242,10 @@ void lf_pinbox_put_pins(LF_PINS *pins)
return;
}
static int ptr_cmp(void **a, void **b)
static int ptr_cmp(const void *pa, const void *pb)
{
const void *const*a= pa;
const void *const*b= pb;
return *a < *b ? -1 : *a == *b ? 0 : 1;
}
@ -283,8 +285,10 @@ struct st_harvester {
callback forlf_dynarray_iterate:
scan all pins of all threads and accumulate all pins
*/
static int harvest_pins(LF_PINS *el, struct st_harvester *hv)
static int harvest_pins(void *e, void *h)
{
LF_PINS *el= e;
struct st_harvester *hv= h;
int i;
LF_PINS *el_end= el+MY_MIN(hv->npins, LF_DYNARRAY_LEVEL_LENGTH);
for (; el < el_end; el++)
@ -310,8 +314,9 @@ static int harvest_pins(LF_PINS *el, struct st_harvester *hv)
callback forlf_dynarray_iterate:
scan all pins of all threads and see if addr is present there
*/
static int match_pins(LF_PINS *el, void *addr)
static int match_pins(void *e, void *addr)
{
LF_PINS *el= e;
int i;
LF_PINS *el_end= el+LF_DYNARRAY_LEVEL_LENGTH;
for (; el < el_end; el++)
@ -352,13 +357,12 @@ static void lf_pinbox_real_free(LF_PINS *pins)
hv.granary= addr;
hv.npins= npins;
/* scan the dynarray and accumulate all pinned addresses */
lf_dynarray_iterate(&pinbox->pinarray,
(lf_dynarray_func)harvest_pins, &hv);
lf_dynarray_iterate(&pinbox->pinarray, harvest_pins, &hv);
npins= (int)(hv.granary-addr);
/* and sort them */
if (npins)
qsort(addr, npins, sizeof(void *), (qsort_cmp)ptr_cmp);
qsort(addr, npins, sizeof(void *), ptr_cmp);
}
}
#endif
@ -387,8 +391,7 @@ static void lf_pinbox_real_free(LF_PINS *pins)
}
else /* no alloca - no cookie. linear search here */
{
if (lf_dynarray_iterate(&pinbox->pinarray,
(lf_dynarray_func)match_pins, cur))
if (lf_dynarray_iterate(&pinbox->pinarray, match_pins, cur))
goto found;
}
}
@ -416,10 +419,11 @@ found:
'first' and 'last' are the ends of the linked list of nodes:
first->el->el->....->el->last. Use first==last to free only one element.
*/
static void alloc_free(uchar *first,
uchar volatile *last,
LF_ALLOCATOR *allocator)
static void alloc_free(void *f, void *l, void *alloc)
{
uchar *first= f;
uchar volatile *last= l;
LF_ALLOCATOR *allocator= alloc;
/*
we need a union here to access type-punned pointer reliably.
otherwise gcc -fstrict-aliasing will not see 'tmp' changed in the loop
@ -448,8 +452,7 @@ static void alloc_free(uchar *first,
*/
void lf_alloc_init(LF_ALLOCATOR *allocator, uint size, uint free_ptr_offset)
{
lf_pinbox_init(&allocator->pinbox, free_ptr_offset,
(lf_pinbox_free_func *)alloc_free, allocator);
lf_pinbox_init(&allocator->pinbox, free_ptr_offset, alloc_free, allocator);
allocator->top= 0;
allocator->mallocs= 0;
allocator->element_size= size;

View file

@ -62,14 +62,10 @@ my_bool safe_mutex_deadlock_detector= 1; /* On by default */
static struct st_safe_mutex_create_info_t *safe_mutex_create_root= NULL;
#endif
static my_bool add_used_to_locked_mutex(safe_mutex_t *used_mutex,
safe_mutex_deadlock_t *locked_mutex);
static my_bool add_to_locked_mutex(safe_mutex_deadlock_t *locked_mutex,
safe_mutex_t *current_mutex);
static my_bool remove_from_locked_mutex(safe_mutex_t *mp,
safe_mutex_t *delete_mutex);
static my_bool remove_from_used_mutex(safe_mutex_deadlock_t *locked_mutex,
safe_mutex_t *mutex);
static my_bool add_used_to_locked_mutex(void *used, void *locked);
static my_bool add_to_locked_mutex(void *locked, void *current);
static my_bool remove_from_locked_mutex(void *m, void* remove);
static my_bool remove_from_used_mutex(void *locked, void *m);
static void print_deadlock_warning(safe_mutex_t *new_mutex,
safe_mutex_t *conflicting_mutex);
#endif
@ -373,8 +369,7 @@ int safe_mutex_lock(safe_mutex_t *mp, myf my_flags, const char *file,
are now locking (C) in B->C, then we would add C into
B->locked_mutex and A->locked_mutex
*/
my_hash_iterate(mutex_root->used_mutex,
(my_hash_walk_action) add_used_to_locked_mutex,
my_hash_iterate(mutex_root->used_mutex, add_used_to_locked_mutex,
deadlock);
/*
@ -654,12 +649,8 @@ void safe_mutex_free_deadlock_data(safe_mutex_t *mp)
if (!(mp->create_flags & MYF_NO_DEADLOCK_DETECTION) && mp->used_mutex != NULL)
{
pthread_mutex_lock(&THR_LOCK_mutex);
my_hash_iterate(mp->used_mutex,
(my_hash_walk_action) remove_from_locked_mutex,
mp);
my_hash_iterate(mp->locked_mutex,
(my_hash_walk_action) remove_from_used_mutex,
mp);
my_hash_iterate(mp->used_mutex, remove_from_locked_mutex, mp);
my_hash_iterate(mp->locked_mutex, remove_from_used_mutex, mp);
pthread_mutex_unlock(&THR_LOCK_mutex);
my_hash_free(mp->used_mutex);
@ -710,15 +701,15 @@ void safe_mutex_end(FILE *file __attribute__((unused)))
#endif /* SAFE_MUTEX_DETECT_DESTROY */
}
static my_bool add_used_to_locked_mutex(safe_mutex_t *used_mutex,
safe_mutex_deadlock_t *locked_mutex)
static my_bool add_used_to_locked_mutex(void *used, void *locked)
{
safe_mutex_t *used_mutex= used;
safe_mutex_deadlock_t *locked_mutex= locked;
/* Add mutex to all parent of the current mutex */
if (!locked_mutex->warning_only)
{
(void) my_hash_iterate(locked_mutex->mutex->locked_mutex,
(my_hash_walk_action) add_to_locked_mutex,
used_mutex);
add_to_locked_mutex, used_mutex);
/* mark that locked_mutex is locked after used_mutex */
(void) add_to_locked_mutex(locked_mutex, used_mutex);
}
@ -730,12 +721,13 @@ static my_bool add_used_to_locked_mutex(safe_mutex_t *used_mutex,
register that locked_mutex was locked after current_mutex
*/
static my_bool add_to_locked_mutex(safe_mutex_deadlock_t *locked_mutex,
safe_mutex_t *current_mutex)
static my_bool add_to_locked_mutex(void *locked, void *current)
{
safe_mutex_deadlock_t *locked_mutex= locked;
safe_mutex_t *current_mutex= current;
DBUG_ENTER("add_to_locked_mutex");
DBUG_PRINT("info", ("inserting 0x%lx into 0x%lx (id: %lu -> %lu)",
(ulong) locked_mutex, (long) current_mutex,
DBUG_PRINT("info", ("inserting %p into %p (id: %lu -> %lu)",
locked_mutex, current_mutex,
locked_mutex->id, current_mutex->id));
if (my_hash_insert(current_mutex->locked_mutex, (uchar*) locked_mutex))
{
@ -763,13 +755,14 @@ static my_bool add_to_locked_mutex(safe_mutex_deadlock_t *locked_mutex,
When counter goes to 0, we delete the safe_mutex_deadlock_t entry.
*/
static my_bool remove_from_locked_mutex(safe_mutex_t *mp,
safe_mutex_t *delete_mutex)
static my_bool remove_from_locked_mutex(void *m, void *remove)
{
safe_mutex_t *mp= m;
safe_mutex_t *delete_mutex= remove;
safe_mutex_deadlock_t *found;
DBUG_ENTER("remove_from_locked_mutex");
DBUG_PRINT("enter", ("delete_mutex: 0x%lx mutex: 0x%lx (id: %lu <- %lu)",
(ulong) delete_mutex, (ulong) mp,
DBUG_PRINT("enter", ("delete_mutex: %p mutex: %p (id: %lu <- %lu)",
delete_mutex, mp,
delete_mutex->id, mp->id));
found= (safe_mutex_deadlock_t *) my_hash_search(mp->locked_mutex,
@ -787,12 +780,13 @@ static my_bool remove_from_locked_mutex(safe_mutex_t *mp,
DBUG_RETURN(0);
}
static my_bool remove_from_used_mutex(safe_mutex_deadlock_t *locked_mutex,
safe_mutex_t *mutex)
static my_bool remove_from_used_mutex(void *locked, void *m)
{
safe_mutex_deadlock_t *locked_mutex= locked;
safe_mutex_t *mutex= m;
DBUG_ENTER("remove_from_used_mutex");
DBUG_PRINT("enter", ("delete_mutex: 0x%lx mutex: 0x%lx (id: %lu <- %lu)",
(ulong) mutex, (ulong) locked_mutex,
DBUG_PRINT("enter", ("delete_mutex: %p mutex: %p (id: %lu <- %lu)",
mutex, locked_mutex,
mutex->id, locked_mutex->id));
if (my_hash_delete(locked_mutex->mutex->used_mutex, (uchar*) mutex))
{

View file

@ -424,8 +424,10 @@ static void wt_resource_destroy(uchar *arg)
It's called from lf_hash when an element is inserted.
*/
static void wt_resource_init(LF_HASH *hash __attribute__((unused)),
WT_RESOURCE *rc, WT_RESOURCE_ID *id)
void *resource, const void *ident)
{
WT_RESOURCE *rc= resource;
const WT_RESOURCE_ID *id= ident;
DBUG_ENTER("wt_resource_init");
rc->id= *id;
rc->waiter_count= 0;

View file

@ -673,8 +673,10 @@ public:
{ ((MDL_lock*)(arg + LF_HASH_OVERHEAD))->~MDL_lock(); }
static void lf_hash_initializer(LF_HASH *hash __attribute__((unused)),
MDL_lock *lock, MDL_key *key_arg)
void *_lock, const void *_key_arg)
{
MDL_lock *lock= static_cast<MDL_lock *>(_lock);
const MDL_key *key_arg= static_cast<const MDL_key *>(_key_arg);
DBUG_ASSERT(key_arg->mdl_namespace() != MDL_key::BACKUP);
new (&lock->key) MDL_key(key_arg);
if (key_arg->mdl_namespace() == MDL_key::SCHEMA)
@ -760,8 +762,10 @@ struct mdl_iterate_arg
};
static my_bool mdl_iterate_lock(MDL_lock *lock, mdl_iterate_arg *arg)
static my_bool mdl_iterate_lock(void *lk, void *a)
{
MDL_lock *lock= static_cast<MDL_lock*>(lk);
mdl_iterate_arg *arg= static_cast<mdl_iterate_arg*>(a);
/*
We can skip check for m_strategy here, becase m_granted
must be empty for such locks anyway.
@ -784,14 +788,13 @@ int mdl_iterate(mdl_iterator_callback callback, void *arg)
{
DBUG_ENTER("mdl_iterate");
mdl_iterate_arg argument= { callback, arg };
LF_PINS *pins= mdl_locks.get_pins();
int res= 1;
if (pins)
if (LF_PINS *pins= mdl_locks.get_pins())
{
res= mdl_iterate_lock(mdl_locks.m_backup_lock, &argument) ||
lf_hash_iterate(&mdl_locks.m_locks, pins,
(my_hash_walk_action) mdl_iterate_lock, &argument);
lf_hash_iterate(&mdl_locks.m_locks, pins, mdl_iterate_lock,
&argument);
lf_hash_put_pins(pins);
}
DBUG_RETURN(res);

View file

@ -253,9 +253,10 @@ public:
};
static my_bool list_open_tables_callback(TDC_element *element,
list_open_tables_arg *arg)
static my_bool list_open_tables_callback(void *el, void *a)
{
TDC_element *element= static_cast<TDC_element*>(el);
list_open_tables_arg *arg= static_cast<list_open_tables_arg*>(a);
const Lex_ident_db
db= Lex_ident_db(Lex_cstring_strlen((const char*) element->m_key));
const char *table_name= db.str + db.length + 1;
@ -303,8 +304,7 @@ OPEN_TABLE_LIST *list_open_tables(THD *thd,
DBUG_ENTER("list_open_tables");
list_open_tables_arg argument(thd, db, wild);
if (tdc_iterate(thd, (my_hash_walk_action) list_open_tables_callback,
&argument, true))
if (tdc_iterate(thd, list_open_tables_callback, &argument, true))
DBUG_RETURN(0);
DBUG_RETURN(argument.open_list);
@ -463,9 +463,10 @@ struct tc_collect_arg
flush_tables_type flush_type;
};
static my_bool tc_collect_used_shares(TDC_element *element,
tc_collect_arg *arg)
static my_bool tc_collect_used_shares(void *el, void *a)
{
TDC_element *element= static_cast<TDC_element*>(el);
tc_collect_arg *arg= static_cast<tc_collect_arg*>(a);
my_bool result= FALSE;
DYNAMIC_ARRAY *shares= &arg->shares;
@ -575,8 +576,7 @@ bool flush_tables(THD *thd, flush_tables_type flag)
my_init_dynamic_array(PSI_INSTRUMENT_ME, &collect_arg.shares,
sizeof(TABLE_SHARE*), 100, 100, MYF(0));
collect_arg.flush_type= flag;
if (tdc_iterate(thd, (my_hash_walk_action) tc_collect_used_shares,
&collect_arg, true))
if (tdc_iterate(thd, tc_collect_used_shares, &collect_arg, true))
{
/* Release already collected shares */
for (uint i= 0 ; i < collect_arg.shares.elements ; i++)

View file

@ -119,10 +119,8 @@ public:
*/
if (WSREP(thd) && wsrep_load_data_splitting)
{
handlerton *ht= table->s->db_type();
// For partitioned tables find underlying hton
if (table->file->partition_ht())
ht= table->file->partition_ht();
handlerton *ht= table->file->partition_ht();
if (ht->db_type != DB_TYPE_INNODB)
{
push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN,

View file

@ -4705,7 +4705,7 @@ mysql_execute_command(THD *thd, bool is_called_from_prepared_stmt)
#ifdef WITH_WSREP
if (wsrep && !first_table->view)
{
bool is_innodb= (first_table->table->file->ht->db_type == DB_TYPE_INNODB);
bool is_innodb= first_table->table->file->partition_ht()->db_type == DB_TYPE_INNODB;
// For consistency check inserted table needs to be InnoDB
if (!is_innodb && thd->wsrep_consistency_check != NO_CONSISTENCY_CHECK)
@ -6592,6 +6592,23 @@ show_create_db(THD *thd, LEX *lex)
DBUG_EXECUTE_IF("4x_server_emul",
my_error(ER_UNKNOWN_ERROR, MYF(0)); return 1;);
#if MYSQL_VERSION_ID<=110301
/*
This piece of the code was added in 10.5 to fix MDEV-32376.
It should not get to 11.3 or higer, as MDEV-32376 was fixed
in a different way in 11.3.1 (see MDEV-31948).
*/
if (lex->name.length > sizeof(db_name_buff) - 1)
{
my_error(ER_WRONG_DB_NAME, MYF(0),
ErrConvString(lex->name.str, lex->name.length,
system_charset_info).ptr());
return 1;
}
#else
#error Remove this preprocessor-conditional code in 11.3.1+
#endif
db_name.str= db_name_buff;
db_name.length= lex->name.length;
strmov(db_name_buff, lex->name.str);

View file

@ -3556,7 +3556,8 @@ bool JOIN::make_aggr_tables_info()
{
List<Item> *curr_all_fields= &all_fields;
List<Item> *curr_fields_list= &fields_list;
JOIN_TAB *curr_tab= join_tab + const_tables;
// Avoid UB (applying .. offset to nullptr) when join_tab is nullptr
JOIN_TAB *curr_tab= join_tab ? join_tab + const_tables : nullptr;
TABLE *exec_tmp_table= NULL;
bool distinct= false;
const bool has_group_by= this->group;
@ -4117,9 +4118,9 @@ bool JOIN::make_aggr_tables_info()
- duplicate value removal
Both of these operations are done after window function computation step.
*/
curr_tab= join_tab + total_join_tab_cnt();
if (select_lex->window_funcs.elements)
{
curr_tab= join_tab + total_join_tab_cnt();
if (!(curr_tab->window_funcs_step= new Window_funcs_computation))
DBUG_RETURN(true);
if (curr_tab->window_funcs_step->setup(thd, &select_lex->window_funcs,

View file

@ -133,9 +133,10 @@ struct close_cached_connection_tables_arg
};
static my_bool close_cached_connection_tables_callback(
TDC_element *element, close_cached_connection_tables_arg *arg)
static my_bool close_cached_connection_tables_callback(void *el, void *a)
{
TDC_element *element= static_cast<TDC_element*>(el);
auto arg= static_cast<close_cached_connection_tables_arg*>(a);
TABLE_LIST *tmp;
mysql_mutex_lock(&element->LOCK_table_share);
@ -188,9 +189,7 @@ static bool close_cached_connection_tables(THD *thd, LEX_CSTRING *connection)
close_cached_connection_tables_arg argument= { thd, connection, 0 };
DBUG_ENTER("close_cached_connections");
if (tdc_iterate(thd,
(my_hash_walk_action) close_cached_connection_tables_callback,
&argument))
if (tdc_iterate(thd, close_cached_connection_tables_callback, &argument))
DBUG_RETURN(true);
DBUG_RETURN(argument.tables ?

View file

@ -3818,7 +3818,7 @@ static bool show_status_array(THD *thd, const char *wild,
*/
for (var=variables; var->type == SHOW_FUNC ||
var->type == SHOW_SIMPLE_FUNC; var= &tmp)
((mysql_show_var_func)(var->value))(thd, &tmp, buff,
((mysql_show_var_func)(var->value))(thd, &tmp, (void *) buff,
status_var, scope);
SHOW_TYPE show_type=var->type;

View file

@ -118,7 +118,7 @@ static void print_cached_tables(void)
/* purecov: begin tested */
puts("DB Table Version Thread Open Lock");
tdc_iterate(0, (my_hash_walk_action) print_cached_tables_callback, NULL, true);
tdc_iterate(0, print_cached_tables_callback, NULL, true);
fflush(stdout);
/* purecov: end */

View file

@ -303,9 +303,11 @@ static void tc_remove_all_unused_tables(TDC_element *element,
periodicly flush all not used tables.
*/
static my_bool tc_purge_callback(TDC_element *element,
Share_free_tables::List *purge_tables)
static my_bool tc_purge_callback(void *_element, void *_purge_tables)
{
TDC_element *element= static_cast<TDC_element *>(_element);
Share_free_tables::List *purge_tables=
static_cast<Share_free_tables::List *>(_purge_tables);
mysql_mutex_lock(&element->LOCK_table_share);
tc_remove_all_unused_tables(element, purge_tables);
mysql_mutex_unlock(&element->LOCK_table_share);
@ -317,7 +319,7 @@ void tc_purge()
{
Share_free_tables::List purge_tables;
tdc_iterate(0, (my_hash_walk_action) tc_purge_callback, &purge_tables);
tdc_iterate(0, tc_purge_callback, &purge_tables);
while (auto table= purge_tables.pop_front())
intern_close_table(table);
}
@ -576,17 +578,20 @@ static void lf_alloc_destructor(uchar *arg)
static void tdc_hash_initializer(LF_HASH *,
TDC_element *element, LEX_STRING *key)
void *_element, const void *_key)
{
TDC_element *element= static_cast<TDC_element *>(_element);
const LEX_STRING *key= static_cast<const LEX_STRING *>(_key);
memcpy(element->m_key, key->str, key->length);
element->m_key_length= (uint)key->length;
tdc_assert_clean_share(element);
}
static uchar *tdc_hash_key(const TDC_element *element, size_t *length,
static uchar *tdc_hash_key(const unsigned char *_element, size_t *length,
my_bool)
{
const TDC_element *element= (const TDC_element *) _element;
*length= element->m_key_length;
return (uchar*) element->m_key;
}
@ -1139,7 +1144,7 @@ struct eliminate_duplicates_arg
static uchar *eliminate_duplicates_get_key(const uchar *element, size_t *length,
my_bool not_used __attribute__((unused)))
my_bool)
{
LEX_STRING *key= (LEX_STRING *) element;
*length= key->length;
@ -1147,9 +1152,10 @@ static uchar *eliminate_duplicates_get_key(const uchar *element, size_t *length,
}
static my_bool eliminate_duplicates(TDC_element *element,
eliminate_duplicates_arg *arg)
static my_bool eliminate_duplicates(void *el, void *a)
{
TDC_element *element= static_cast<TDC_element*>(el);
eliminate_duplicates_arg *arg= static_cast<eliminate_duplicates_arg*>(a);
LEX_STRING *key= (LEX_STRING *) alloc_root(&arg->root, sizeof(LEX_STRING));
if (!key || !(key->str= (char*) memdup_root(&arg->root, element->m_key,
@ -1195,7 +1201,7 @@ int tdc_iterate(THD *thd, my_hash_walk_action action, void *argument,
hash_flags);
no_dups_argument.action= action;
no_dups_argument.argument= argument;
action= (my_hash_walk_action) eliminate_duplicates;
action= eliminate_duplicates;
argument= &no_dups_argument;
}

View file

@ -126,10 +126,11 @@ public:
}
return true;
}
static void lf_hash_initializer(LF_HASH *hash __attribute__((unused)),
XID_cache_element *element,
XID_cache_insert_element *new_element)
static void lf_hash_initializer(LF_HASH *, void *el, const void *ie)
{
XID_cache_element *element= static_cast<XID_cache_element*>(el);
XID_cache_insert_element *new_element=
static_cast<XID_cache_insert_element*>(const_cast<void*>(ie));
DBUG_ASSERT(!element->is_set(ACQUIRED | RECOVERED));
element->rm_error= 0;
element->xa_state= new_element->xa_state;
@ -146,11 +147,11 @@ public:
DBUG_ASSERT(!reinterpret_cast<XID_cache_element*>(ptr + LF_HASH_OVERHEAD)
->is_set(ACQUIRED));
}
static uchar *key(const XID_cache_element *element, size_t *length,
my_bool not_used __attribute__((unused)))
static uchar *key(const unsigned char *el, size_t *length, my_bool)
{
*length= element->xid.key_length();
return element->xid.key();
const XID &xid= reinterpret_cast<const XID_cache_element*>(el)->xid;
*length= xid.key_length();
return xid.key();
}
};
@ -221,11 +222,10 @@ void xid_cache_init()
{
xid_cache_inited= true;
lf_hash_init(&xid_cache, sizeof(XID_cache_element), LF_HASH_UNIQUE, 0, 0,
(my_hash_get_key) XID_cache_element::key, &my_charset_bin);
XID_cache_element::key, &my_charset_bin);
xid_cache.alloc.constructor= XID_cache_element::lf_alloc_constructor;
xid_cache.alloc.destructor= XID_cache_element::lf_alloc_destructor;
xid_cache.initializer=
(lf_hash_initializer) XID_cache_element::lf_hash_initializer;
xid_cache.initializer= XID_cache_element::lf_hash_initializer;
}
@ -331,9 +331,10 @@ struct xid_cache_iterate_arg
void *argument;
};
static my_bool xid_cache_iterate_callback(XID_cache_element *element,
xid_cache_iterate_arg *arg)
static my_bool xid_cache_iterate_callback(void *el, void *a)
{
XID_cache_element *element= static_cast<XID_cache_element*>(el);
xid_cache_iterate_arg *arg= static_cast<xid_cache_iterate_arg*>(a);
my_bool res= FALSE;
if (element->lock())
{
@ -348,8 +349,7 @@ static int xid_cache_iterate(THD *thd, my_hash_walk_action action, void *arg)
xid_cache_iterate_arg argument= { action, arg };
return thd->fix_xid_hash_pins() ? -1 :
lf_hash_iterate(&xid_cache, thd->xid_hash_pins,
(my_hash_walk_action) xid_cache_iterate_callback,
&argument);
xid_cache_iterate_callback, &argument);
}
@ -1039,17 +1039,19 @@ static my_bool xa_recover_callback(XID_cache_element *xs, Protocol *protocol,
}
static my_bool xa_recover_callback_short(XID_cache_element *xs,
Protocol *protocol)
static my_bool xa_recover_callback_short(void *x, void *p)
{
XID_cache_element *xs= static_cast<XID_cache_element*>(x);
Protocol *protocol= static_cast<Protocol*>(p);
return xa_recover_callback(xs, protocol, xs->xid.data,
xs->xid.gtrid_length + xs->xid.bqual_length, &my_charset_bin);
}
static my_bool xa_recover_callback_verbose(XID_cache_element *xs,
Protocol *protocol)
static my_bool xa_recover_callback_verbose(void *x, void *p)
{
XID_cache_element *xs= static_cast<XID_cache_element*>(x);
Protocol *protocol= static_cast<Protocol*>(p);
char buf[SQL_XIDSIZE];
uint len= get_sql_xid(&xs->xid, buf);
return xa_recover_callback(xs, protocol, buf, len,
@ -1089,14 +1091,14 @@ void xa_recover_get_fields(THD *thd, List<Item> *field_list,
len= SQL_XIDSIZE;
cs= &my_charset_utf8mb3_general_ci;
if (action)
*action= (my_hash_walk_action) xa_recover_callback_verbose;
*action= xa_recover_callback_verbose;
}
else
{
len= XIDDATASIZE;
cs= &my_charset_bin;
if (action)
*action= (my_hash_walk_action) xa_recover_callback_short;
*action= xa_recover_callback_short;
}
field_list->push_back(new (mem_root)

View file

@ -69,13 +69,16 @@ inline bool fil_is_user_tablespace_id(ulint space_id)
}
/** Try to close a file to adhere to the innodb_open_files limit.
@param ignore_space Ignore the tablespace which is acquired by caller
@param print_info whether to diagnose why a file cannot be closed
@return whether a file was closed */
bool fil_space_t::try_to_close(bool print_info)
bool fil_space_t::try_to_close(fil_space_t *ignore_space, bool print_info)
{
mysql_mutex_assert_owner(&fil_system.mutex);
for (fil_space_t &space : fil_system.space_list)
{
if (&space == ignore_space)
continue;
switch (space.purpose) {
case FIL_TYPE_TEMPORARY:
continue;
@ -340,7 +343,7 @@ fil_node_t* fil_space_t::add(const char* name, pfs_os_file_t handle,
clear_closing();
if (++fil_system.n_open >= srv_max_n_open_files) {
reacquire();
try_to_close(true);
try_to_close(this, true);
release();
}
}
@ -394,7 +397,7 @@ static bool fil_node_open_file_low(fil_node_t *node)
/* The following call prints an error message */
if (os_file_get_last_error(true) == EMFILE + 100 &&
fil_space_t::try_to_close(true))
fil_space_t::try_to_close(nullptr, true))
continue;
ib::warn() << "Cannot open '" << node->name << "'.";
@ -438,7 +441,7 @@ static bool fil_node_open_file(fil_node_t *node)
for (ulint count= 0; fil_system.n_open >= srv_max_n_open_files; count++)
{
if (fil_space_t::try_to_close(count > 1))
if (fil_space_t::try_to_close(nullptr, count > 1))
count= 0;
else if (count >= 2)
{

View file

@ -4091,6 +4091,21 @@ static int innodb_init_params()
}
}
ulint min_open_files_limit = srv_undo_tablespaces
+ srv_sys_space.m_files.size()
+ srv_tmp_space.m_files.size() + 1;
if (min_open_files_limit > innobase_open_files) {
sql_print_warning(
"InnoDB: innodb_open_files=%lu is not greater "
"than the number of system tablespace files, "
"temporary tablespace files, "
"innodb_undo_tablespaces=%lu; adjusting "
"to innodb_open_files=%zu",
innobase_open_files, srv_undo_tablespaces,
min_open_files_limit);
innobase_open_files = (ulong) min_open_files_limit;
}
srv_max_n_open_files = innobase_open_files;
srv_innodb_status = (ibool) innobase_create_status_file;

View file

@ -648,9 +648,10 @@ private:
public:
/** Try to close a file to adhere to the innodb_open_files limit.
@param ignore_space Ignore the tablespace which is acquired by caller
@param print_info whether to diagnose why a file cannot be closed
@return whether a file was closed */
static bool try_to_close(bool print_info);
static bool try_to_close(fil_space_t *ignore_space, bool print_info);
/** Close all tablespace files at shutdown */
static void close_all();

View file

@ -437,10 +437,10 @@ class rw_trx_hash_t
not accessible by concurrent threads.
*/
static void rw_trx_hash_initializer(LF_HASH *,
rw_trx_hash_element_t *element,
trx_t *trx)
static void rw_trx_hash_initializer(LF_HASH *, void *el, const void *t)
{
rw_trx_hash_element_t *element= static_cast<rw_trx_hash_element_t*>(el);
trx_t *trx= static_cast<trx_t*>(const_cast<void*>(t));
ut_ad(element->trx == 0);
element->trx= trx;
element->id= trx->id;
@ -454,7 +454,7 @@ class rw_trx_hash_t
Pins are used to protect object from being destroyed or reused. They are
normally stored in trx object for quick access. If caller doesn't have trx
available, we try to get it using currnet_trx(). If caller doesn't have trx
available, we try to get it using current_trx(). If caller doesn't have trx
at all, temporary pins are allocated.
*/
@ -480,9 +480,10 @@ class rw_trx_hash_t
template <typename T>
static my_bool eliminate_duplicates(rw_trx_hash_element_t *element,
eliminate_duplicates_arg<T> *arg)
static my_bool eliminate_duplicates(void *el, void *a)
{
rw_trx_hash_element_t *element= static_cast<rw_trx_hash_element_t*>(el);
auto arg= static_cast<eliminate_duplicates_arg<T>*>(a);
for (trx_ids_t::iterator it= arg->ids.begin(); it != arg->ids.end(); it++)
{
if (*it == element->id)
@ -508,17 +509,17 @@ class rw_trx_hash_t
}
template <typename T> struct debug_iterator_arg
struct debug_iterator_arg
{
walk_action<T> *action;
T *argument;
my_hash_walk_action action;
void *argument;
};
template <typename T>
static my_bool debug_iterator(rw_trx_hash_element_t *element,
debug_iterator_arg<T> *arg)
static my_bool debug_iterator(void *el, void *a)
{
rw_trx_hash_element_t *element= static_cast<rw_trx_hash_element_t*>(el);
debug_iterator_arg *arg= static_cast<debug_iterator_arg*>(a);
element->mutex.wr_lock();
if (element->trx)
validate_element(element->trx);
@ -726,7 +727,7 @@ public:
@param caller_trx used to get/set pins
@param action called for every element in hash
@param argument opque argument passed to action
@param argument opaque argument passed to action
May return the same element multiple times if hash is under contention.
If caller doesn't like to see the same transaction multiple times, it has
@ -749,28 +750,24 @@ public:
@retval 1 iteration was interrupted (action returned 1)
*/
template <typename T>
int iterate(trx_t *caller_trx, walk_action<T> *action, T *argument= nullptr)
int iterate(trx_t *caller_trx, my_hash_walk_action action,
void *argument= nullptr)
{
LF_PINS *pins= caller_trx ? get_pins(caller_trx) : lf_hash_get_pins(&hash);
ut_a(pins);
#ifdef UNIV_DEBUG
debug_iterator_arg<T> debug_arg= { action, argument };
action= reinterpret_cast<decltype(action)>(debug_iterator<T>);
argument= reinterpret_cast<T*>(&debug_arg);
debug_iterator_arg debug_arg= { action, argument };
action= debug_iterator;
argument= reinterpret_cast<void*>(&debug_arg);
#endif
int res= lf_hash_iterate(&hash, pins,
reinterpret_cast<my_hash_walk_action>(action),
const_cast<void*>(static_cast<const void*>
(argument)));
int res= lf_hash_iterate(&hash, pins, action, argument);
if (!caller_trx)
lf_hash_put_pins(pins);
return res;
}
template <typename T>
int iterate(walk_action<T> *action, T *argument= nullptr)
int iterate(my_hash_walk_action action, void *argument= nullptr)
{
return iterate(current_trx(), action, argument);
}
@ -1195,9 +1192,10 @@ public:
inline void undo_truncate_start(fil_space_t &space);
private:
static my_bool find_same_or_older_callback(rw_trx_hash_element_t *element,
trx_id_t *id)
static my_bool find_same_or_older_callback(void *el, void *i)
{
auto element= static_cast<rw_trx_hash_element_t *>(el);
auto id= static_cast<trx_id_t*>(i);
return element->id <= *id;
}
@ -1211,9 +1209,10 @@ private:
};
static my_bool copy_one_id(rw_trx_hash_element_t *element,
snapshot_ids_arg *arg)
static my_bool copy_one_id(void* el, void *a)
{
auto element= static_cast<const rw_trx_hash_element_t *>(el);
auto arg= static_cast<snapshot_ids_arg*>(a);
if (element->id < arg->m_id)
{
trx_id_t no= element->no;

View file

@ -5445,8 +5445,10 @@ static void lock_rec_block_validate(const page_id_t page_id)
}
}
static my_bool lock_validate_table_locks(rw_trx_hash_element_t *element, void*)
static my_bool lock_validate_table_locks(void *el, void*)
{
rw_trx_hash_element_t *element= static_cast<rw_trx_hash_element_t*>(el);
lock_sys.assert_locked();
element->mutex.wr_lock();
if (element->trx)
@ -5654,10 +5656,10 @@ struct lock_rec_other_trx_holds_expl_arg
};
static my_bool lock_rec_other_trx_holds_expl_callback(
rw_trx_hash_element_t *element,
lock_rec_other_trx_holds_expl_arg *arg)
static my_bool lock_rec_other_trx_holds_expl_callback(void *el, void *a)
{
auto element= static_cast<rw_trx_hash_element_t*>(el);
auto arg= static_cast<lock_rec_other_trx_holds_expl_arg*>(a);
element->mutex.wr_lock();
if (element->trx)
{
@ -6473,13 +6475,14 @@ dberr_t lock_trx_handle_wait(trx_t *trx)
/**
Do an exhaustive check for any locks (table or rec) against the table.
@param[in] table check if there are any locks held on records in this table
or on the table itself
@param t check if there are any locks held on records in this table
or on the table itself
*/
static my_bool lock_table_locks_lookup(rw_trx_hash_element_t *element,
const dict_table_t *table)
static my_bool lock_table_locks_lookup(void *el, void *t)
{
auto element= static_cast<rw_trx_hash_element_t*>(el);
const dict_table_t *table= static_cast<const dict_table_t*>(t);
lock_sys.assert_locked();
element->mutex.wr_lock();
if (element->trx)
@ -6539,7 +6542,7 @@ bool lock_table_has_locks(dict_table_t *table)
{
LockMutexGuard g{SRW_LOCK_CALL};
trx_sys.rw_trx_hash.iterate(lock_table_locks_lookup,
const_cast<const dict_table_t*>(table));
static_cast<void*>(table));
}
#endif /* UNIV_DEBUG */
return false;

View file

@ -2085,9 +2085,9 @@ static my_bool trx_recover_for_mysql_callback(rw_trx_hash_element_t *element,
}
static my_bool trx_recover_reset_callback(rw_trx_hash_element_t *element,
void*)
static my_bool trx_recover_reset_callback(void *el, void*)
{
rw_trx_hash_element_t *element= static_cast<rw_trx_hash_element_t*>(el);
element->mutex.wr_lock();
if (trx_t *trx= element->trx)
{
@ -2139,9 +2139,10 @@ struct trx_get_trx_by_xid_callback_arg
};
static my_bool trx_get_trx_by_xid_callback(rw_trx_hash_element_t *element,
trx_get_trx_by_xid_callback_arg *arg)
static my_bool trx_get_trx_by_xid_callback(void *el, void *a)
{
auto element= static_cast<rw_trx_hash_element_t*>(el);
auto arg= static_cast<trx_get_trx_by_xid_callback_arg*>(a);
my_bool found= 0;
element->mutex.wr_lock();
if (trx_t *trx= element->trx)

View file

@ -133,7 +133,9 @@ static int pfs_done_func(void *p)
DBUG_RETURN(0);
}
static int show_func_mutex_instances_lost(THD *thd, SHOW_VAR *var, char *buff)
static int show_func_mutex_instances_lost(THD *thd, SHOW_VAR *var, void *buff,
struct system_status_var *status_var,
enum enum_var_type)
{
var->type= SHOW_LONG;
var->value= buff;