Merge branch '10.5' into bb-10.5-release
This commit is contained in:
commit
34c5019698
2
VERSION
2
VERSION
@ -1,4 +1,4 @@
|
|||||||
MYSQL_VERSION_MAJOR=10
|
MYSQL_VERSION_MAJOR=10
|
||||||
MYSQL_VERSION_MINOR=5
|
MYSQL_VERSION_MINOR=5
|
||||||
MYSQL_VERSION_PATCH=14
|
MYSQL_VERSION_PATCH=15
|
||||||
SERVER_MATURITY=stable
|
SERVER_MATURITY=stable
|
||||||
|
@ -31,7 +31,7 @@ extern ulong my_time_to_wait_for_lock;
|
|||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
#ifdef HAVE_SIGHANDLER_T
|
#ifdef HAVE_SIGHANDLER_T
|
||||||
#define sig_return sighandler_t
|
#define sig_return sighandler_t
|
||||||
#elif defined(SOLARIS) || defined(__sun) || defined(__APPLE__) || defined(__FreeBSD__)
|
#elif defined(SOLARIS) || defined(__sun) || defined(__APPLE__) || defined(__FreeBSD__) || defined(_AIX)
|
||||||
typedef void (*sig_return)(int); /* Returns type from signal */
|
typedef void (*sig_return)(int); /* Returns type from signal */
|
||||||
#else
|
#else
|
||||||
typedef void (*sig_return)(void); /* Returns type from signal */
|
typedef void (*sig_return)(void); /* Returns type from signal */
|
||||||
|
@ -39,6 +39,28 @@ MDL_INTENTION_EXCLUSIVE Schema metadata lock test
|
|||||||
select * from t1;
|
select * from t1;
|
||||||
ERROR 40001: Deadlock found when trying to get lock; try restarting transaction
|
ERROR 40001: Deadlock found when trying to get lock; try restarting transaction
|
||||||
backup unlock;
|
backup unlock;
|
||||||
|
connection con1;
|
||||||
|
connection default;
|
||||||
|
#
|
||||||
|
# Check that BACKUP LOCK blocks some operations
|
||||||
|
#
|
||||||
|
create sequence seq1;
|
||||||
|
create sequence seq2;
|
||||||
|
backup lock seq1;
|
||||||
|
connection con1;
|
||||||
|
CREATE OR REPLACE SEQUENCE seq1 START -28;
|
||||||
|
ERROR HY000: Sequence 'test.seq1' values are conflicting
|
||||||
|
SET STATEMENT max_statement_time=10 FOR CREATE OR REPLACE SEQUENCE seq1 START 50;
|
||||||
|
ERROR 70100: Query execution was interrupted (max_statement_time exceeded)
|
||||||
|
SET STATEMENT max_statement_time=10 FOR ALTER SEQUENCE IF EXISTS seq1 NOMAXVALUE;
|
||||||
|
ERROR 70100: Query execution was interrupted (max_statement_time exceeded)
|
||||||
|
SET STATEMENT max_statement_time=10 FOR ALTER SEQUENCE IF EXISTS seq1 MAXVALUE 1000;
|
||||||
|
ERROR 70100: Query execution was interrupted (max_statement_time exceeded)
|
||||||
|
SET STATEMENT max_statement_time=10 for rename table seq2 to seq3, seq3 to seq1;
|
||||||
|
ERROR 70100: Query execution was interrupted (max_statement_time exceeded)
|
||||||
|
connection default;
|
||||||
|
backup unlock;
|
||||||
|
drop table seq1,seq2;
|
||||||
#
|
#
|
||||||
# BACKUP LOCK and BACKUP UNLOCK are not allowed in procedures.
|
# BACKUP LOCK and BACKUP UNLOCK are not allowed in procedures.
|
||||||
#
|
#
|
||||||
@ -141,7 +163,6 @@ ERROR HY000: Can't execute the given command because you have active locked tabl
|
|||||||
SET STATEMENT max_statement_time=180 FOR BACKUP LOCK test.u;
|
SET STATEMENT max_statement_time=180 FOR BACKUP LOCK test.u;
|
||||||
# restart
|
# restart
|
||||||
#
|
#
|
||||||
connection con1;
|
|
||||||
connection default;
|
connection default;
|
||||||
disconnect con1;
|
disconnect con1;
|
||||||
show tables;
|
show tables;
|
||||||
|
@ -43,10 +43,39 @@ SELECT LOCK_MODE, LOCK_TYPE, TABLE_SCHEMA, TABLE_NAME FROM information_schema.me
|
|||||||
--error ER_LOCK_DEADLOCK
|
--error ER_LOCK_DEADLOCK
|
||||||
select * from t1;
|
select * from t1;
|
||||||
backup unlock;
|
backup unlock;
|
||||||
|
connection con1;
|
||||||
|
--reap
|
||||||
|
connection default;
|
||||||
|
|
||||||
|
--echo #
|
||||||
|
--echo # Check that BACKUP LOCK blocks some operations
|
||||||
|
--echo #
|
||||||
|
|
||||||
|
# These test has to be done with timeouts as we want to ensure that the tables
|
||||||
|
# doesn't change
|
||||||
|
|
||||||
|
create sequence seq1;
|
||||||
|
create sequence seq2;
|
||||||
|
backup lock seq1;
|
||||||
|
connection con1;
|
||||||
|
--error ER_SEQUENCE_INVALID_DATA
|
||||||
|
CREATE OR REPLACE SEQUENCE seq1 START -28;
|
||||||
|
--error ER_STATEMENT_TIMEOUT
|
||||||
|
SET STATEMENT max_statement_time=10 FOR CREATE OR REPLACE SEQUENCE seq1 START 50;
|
||||||
|
--error ER_STATEMENT_TIMEOUT
|
||||||
|
SET STATEMENT max_statement_time=10 FOR ALTER SEQUENCE IF EXISTS seq1 NOMAXVALUE;
|
||||||
|
--error ER_STATEMENT_TIMEOUT
|
||||||
|
SET STATEMENT max_statement_time=10 FOR ALTER SEQUENCE IF EXISTS seq1 MAXVALUE 1000;
|
||||||
|
--error ER_STATEMENT_TIMEOUT
|
||||||
|
SET STATEMENT max_statement_time=10 for rename table seq2 to seq3, seq3 to seq1;
|
||||||
|
connection default;
|
||||||
|
backup unlock;
|
||||||
|
drop table seq1,seq2;
|
||||||
|
|
||||||
--echo #
|
--echo #
|
||||||
--echo # BACKUP LOCK and BACKUP UNLOCK are not allowed in procedures.
|
--echo # BACKUP LOCK and BACKUP UNLOCK are not allowed in procedures.
|
||||||
--echo #
|
--echo #
|
||||||
|
|
||||||
delimiter |;
|
delimiter |;
|
||||||
--error ER_SP_BADSTATEMENT
|
--error ER_SP_BADSTATEMENT
|
||||||
CREATE PROCEDURE p_BACKUP_LOCK()
|
CREATE PROCEDURE p_BACKUP_LOCK()
|
||||||
@ -162,8 +191,6 @@ SET STATEMENT max_statement_time=180 FOR BACKUP LOCK test.u;
|
|||||||
|
|
||||||
--echo #
|
--echo #
|
||||||
|
|
||||||
connection con1;
|
|
||||||
--reap
|
|
||||||
connection default;
|
connection default;
|
||||||
disconnect con1;
|
disconnect con1;
|
||||||
show tables;
|
show tables;
|
||||||
|
@ -4027,3 +4027,40 @@ drop table t1;
|
|||||||
#
|
#
|
||||||
# End of 10.1 tests
|
# End of 10.1 tests
|
||||||
#
|
#
|
||||||
|
#
|
||||||
|
# MDEV-27442 Wrong result upon query with DISTINCT and EXISTS subquery
|
||||||
|
#
|
||||||
|
CREATE TABLE t1 (a int, b int, KEY b (b,a)) ENGINE=MyISAM;
|
||||||
|
INSERT INTO t1 VALUES (0,100),(2,100),(2,101),(3,102);
|
||||||
|
# Must not use Using index for group-by
|
||||||
|
explain SELECT DISTINCT b FROM t1 WHERE EXISTS ( SELECT 1 FROM DUAL WHERE a > 1 );
|
||||||
|
id select_type table type possible_keys key key_len ref rows Extra
|
||||||
|
1 PRIMARY t1 index NULL b 10 NULL 4 Using where; Using index
|
||||||
|
2 DEPENDENT SUBQUERY NULL NULL NULL NULL NULL NULL NULL No tables used
|
||||||
|
SELECT DISTINCT b FROM t1 WHERE EXISTS ( SELECT 1 FROM DUAL WHERE a > 1 );
|
||||||
|
b
|
||||||
|
100
|
||||||
|
101
|
||||||
|
102
|
||||||
|
DROP TABLE t1;
|
||||||
|
#
|
||||||
|
# MDEV-26585 Wrong query results when `using index for group-by`
|
||||||
|
#
|
||||||
|
CREATE TABLE `t1` (
|
||||||
|
`id` int(11) NOT NULL AUTO_INCREMENT,
|
||||||
|
`owner_id` int(11) DEFAULT NULL,
|
||||||
|
`foo` tinyint(1) DEFAULT 0,
|
||||||
|
`whatever` varchar(255) DEFAULT NULL,
|
||||||
|
PRIMARY KEY (`id`),
|
||||||
|
KEY `index_t1_on_owner_id_and_foo` (`owner_id`,`foo`)
|
||||||
|
) engine=InnoDB DEFAULT CHARSET=utf8;
|
||||||
|
INSERT INTO t1 (owner_id, foo, whatever)
|
||||||
|
VALUES (1, TRUE, "yello"), (1, FALSE, "yello"), (2, TRUE, "yello"),
|
||||||
|
(2, TRUE, "yello"), (2, FALSE, "yello");
|
||||||
|
EXPLAIN SELECT DISTINCT owner_id FROM t1 WHERE foo = true GROUP BY owner_id HAVING (COUNT(*) = 1);
|
||||||
|
id select_type table type possible_keys key key_len ref rows Extra
|
||||||
|
1 SIMPLE t1 index NULL index_t1_on_owner_id_and_foo 7 NULL 5 Using where; Using index
|
||||||
|
SELECT DISTINCT owner_id FROM t1 WHERE foo = true GROUP BY owner_id HAVING (COUNT(*) = 1);
|
||||||
|
owner_id
|
||||||
|
1
|
||||||
|
DROP TABLE t1;
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
#
|
#
|
||||||
|
|
||||||
--source include/default_optimizer_switch.inc
|
--source include/default_optimizer_switch.inc
|
||||||
|
--source include/have_innodb.inc
|
||||||
#
|
#
|
||||||
# TODO:
|
# TODO:
|
||||||
# Add queries with:
|
# Add queries with:
|
||||||
@ -1689,3 +1689,34 @@ drop table t1;
|
|||||||
--echo #
|
--echo #
|
||||||
--echo # End of 10.1 tests
|
--echo # End of 10.1 tests
|
||||||
--echo #
|
--echo #
|
||||||
|
|
||||||
|
--echo #
|
||||||
|
--echo # MDEV-27442 Wrong result upon query with DISTINCT and EXISTS subquery
|
||||||
|
--echo #
|
||||||
|
|
||||||
|
CREATE TABLE t1 (a int, b int, KEY b (b,a)) ENGINE=MyISAM;
|
||||||
|
INSERT INTO t1 VALUES (0,100),(2,100),(2,101),(3,102);
|
||||||
|
--echo # Must not use Using index for group-by
|
||||||
|
explain SELECT DISTINCT b FROM t1 WHERE EXISTS ( SELECT 1 FROM DUAL WHERE a > 1 );
|
||||||
|
SELECT DISTINCT b FROM t1 WHERE EXISTS ( SELECT 1 FROM DUAL WHERE a > 1 );
|
||||||
|
DROP TABLE t1;
|
||||||
|
|
||||||
|
--echo #
|
||||||
|
--echo # MDEV-26585 Wrong query results when `using index for group-by`
|
||||||
|
--echo #
|
||||||
|
|
||||||
|
CREATE TABLE `t1` (
|
||||||
|
`id` int(11) NOT NULL AUTO_INCREMENT,
|
||||||
|
`owner_id` int(11) DEFAULT NULL,
|
||||||
|
`foo` tinyint(1) DEFAULT 0,
|
||||||
|
`whatever` varchar(255) DEFAULT NULL,
|
||||||
|
PRIMARY KEY (`id`),
|
||||||
|
KEY `index_t1_on_owner_id_and_foo` (`owner_id`,`foo`)
|
||||||
|
) engine=InnoDB DEFAULT CHARSET=utf8;
|
||||||
|
|
||||||
|
INSERT INTO t1 (owner_id, foo, whatever)
|
||||||
|
VALUES (1, TRUE, "yello"), (1, FALSE, "yello"), (2, TRUE, "yello"),
|
||||||
|
(2, TRUE, "yello"), (2, FALSE, "yello");
|
||||||
|
EXPLAIN SELECT DISTINCT owner_id FROM t1 WHERE foo = true GROUP BY owner_id HAVING (COUNT(*) = 1);
|
||||||
|
SELECT DISTINCT owner_id FROM t1 WHERE foo = true GROUP BY owner_id HAVING (COUNT(*) = 1);
|
||||||
|
DROP TABLE t1;
|
||||||
|
@ -5,6 +5,7 @@ c INT,
|
|||||||
INDEX(b))
|
INDEX(b))
|
||||||
ENGINE=InnoDB STATS_PERSISTENT=0;
|
ENGINE=InnoDB STATS_PERSISTENT=0;
|
||||||
SET GLOBAL innodb_change_buffering_debug = 1;
|
SET GLOBAL innodb_change_buffering_debug = 1;
|
||||||
|
SET GLOBAL innodb_change_buffering=all;
|
||||||
INSERT INTO t1 SELECT 0,'x',1 FROM seq_1_to_1024;
|
INSERT INTO t1 SELECT 0,'x',1 FROM seq_1_to_1024;
|
||||||
# restart: --innodb-force-recovery=6 --innodb-change-buffer-dump
|
# restart: --innodb-force-recovery=6 --innodb-change-buffer-dump
|
||||||
check table t1;
|
check table t1;
|
||||||
|
@ -13,6 +13,7 @@ c INT,
|
|||||||
INDEX(b))
|
INDEX(b))
|
||||||
ENGINE=InnoDB STATS_PERSISTENT=0;
|
ENGINE=InnoDB STATS_PERSISTENT=0;
|
||||||
SET GLOBAL innodb_change_buffering_debug = 1;
|
SET GLOBAL innodb_change_buffering_debug = 1;
|
||||||
|
SET GLOBAL innodb_change_buffering = all;
|
||||||
INSERT INTO t1 SELECT 0,'x',1 FROM seq_1_to_8192;
|
INSERT INTO t1 SELECT 0,'x',1 FROM seq_1_to_8192;
|
||||||
BEGIN;
|
BEGIN;
|
||||||
SELECT b FROM t1 LIMIT 3;
|
SELECT b FROM t1 LIMIT 3;
|
||||||
|
@ -24,6 +24,7 @@ ENGINE=InnoDB STATS_PERSISTENT=0;
|
|||||||
# change buffering is possible, so that the change buffer will be used
|
# change buffering is possible, so that the change buffer will be used
|
||||||
# whenever possible.
|
# whenever possible.
|
||||||
SET GLOBAL innodb_change_buffering_debug = 1;
|
SET GLOBAL innodb_change_buffering_debug = 1;
|
||||||
|
SET GLOBAL innodb_change_buffering=all;
|
||||||
|
|
||||||
# Create enough rows for the table, so that the change buffer will be
|
# Create enough rows for the table, so that the change buffer will be
|
||||||
# used for modifying the secondary index page. There must be multiple
|
# used for modifying the secondary index page. There must be multiple
|
||||||
|
@ -33,6 +33,7 @@ ENGINE=InnoDB STATS_PERSISTENT=0;
|
|||||||
# change buffering is possible, so that the change buffer will be used
|
# change buffering is possible, so that the change buffer will be used
|
||||||
# whenever possible.
|
# whenever possible.
|
||||||
SET GLOBAL innodb_change_buffering_debug = 1;
|
SET GLOBAL innodb_change_buffering_debug = 1;
|
||||||
|
SET GLOBAL innodb_change_buffering = all;
|
||||||
let SEARCH_FILE = $MYSQLTEST_VARDIR/log/mysqld.1.err;
|
let SEARCH_FILE = $MYSQLTEST_VARDIR/log/mysqld.1.err;
|
||||||
|
|
||||||
# Create enough rows for the table, so that the change buffer will be
|
# Create enough rows for the table, so that the change buffer will be
|
||||||
|
@ -1,6 +1,8 @@
|
|||||||
--source include/have_innodb.inc
|
--source include/have_innodb.inc
|
||||||
--source include/big_test.inc
|
--source include/big_test.inc
|
||||||
--source include/not_embedded.inc
|
--source include/not_embedded.inc
|
||||||
|
# Valgrind is to slow for this test
|
||||||
|
--source include/not_valgrind.inc
|
||||||
|
|
||||||
set global innodb_defragment_stats_accuracy = 80;
|
set global innodb_defragment_stats_accuracy = 80;
|
||||||
|
|
||||||
|
@ -1,28 +1,28 @@
|
|||||||
SET @start_global_value = @@global.innodb_change_buffering;
|
SET @start_global_value = @@global.innodb_change_buffering;
|
||||||
SELECT @start_global_value;
|
SELECT @start_global_value;
|
||||||
@start_global_value
|
@start_global_value
|
||||||
all
|
none
|
||||||
Valid values are 'all', 'deletes', 'changes', 'inserts', 'none', 'purges'
|
Valid values are 'all', 'deletes', 'changes', 'inserts', 'none', 'purges'
|
||||||
select @@global.innodb_change_buffering in ('all', 'deletes', 'changes', 'inserts', 'none', 'purges');
|
select @@global.innodb_change_buffering in ('all', 'deletes', 'changes', 'inserts', 'none', 'purges');
|
||||||
@@global.innodb_change_buffering in ('all', 'deletes', 'changes', 'inserts', 'none', 'purges')
|
@@global.innodb_change_buffering in ('all', 'deletes', 'changes', 'inserts', 'none', 'purges')
|
||||||
1
|
1
|
||||||
select @@global.innodb_change_buffering;
|
select @@global.innodb_change_buffering;
|
||||||
@@global.innodb_change_buffering
|
@@global.innodb_change_buffering
|
||||||
all
|
none
|
||||||
select @@session.innodb_change_buffering;
|
select @@session.innodb_change_buffering;
|
||||||
ERROR HY000: Variable 'innodb_change_buffering' is a GLOBAL variable
|
ERROR HY000: Variable 'innodb_change_buffering' is a GLOBAL variable
|
||||||
show global variables like 'innodb_change_buffering';
|
show global variables like 'innodb_change_buffering';
|
||||||
Variable_name Value
|
Variable_name Value
|
||||||
innodb_change_buffering all
|
innodb_change_buffering none
|
||||||
show session variables like 'innodb_change_buffering';
|
show session variables like 'innodb_change_buffering';
|
||||||
Variable_name Value
|
Variable_name Value
|
||||||
innodb_change_buffering all
|
innodb_change_buffering none
|
||||||
select * from information_schema.global_variables where variable_name='innodb_change_buffering';
|
select * from information_schema.global_variables where variable_name='innodb_change_buffering';
|
||||||
VARIABLE_NAME VARIABLE_VALUE
|
VARIABLE_NAME VARIABLE_VALUE
|
||||||
INNODB_CHANGE_BUFFERING all
|
INNODB_CHANGE_BUFFERING none
|
||||||
select * from information_schema.session_variables where variable_name='innodb_change_buffering';
|
select * from information_schema.session_variables where variable_name='innodb_change_buffering';
|
||||||
VARIABLE_NAME VARIABLE_VALUE
|
VARIABLE_NAME VARIABLE_VALUE
|
||||||
INNODB_CHANGE_BUFFERING all
|
INNODB_CHANGE_BUFFERING none
|
||||||
set global innodb_change_buffering='none';
|
set global innodb_change_buffering='none';
|
||||||
select @@global.innodb_change_buffering;
|
select @@global.innodb_change_buffering;
|
||||||
@@global.innodb_change_buffering
|
@@global.innodb_change_buffering
|
||||||
@ -62,4 +62,4 @@ ERROR 42000: Variable 'innodb_change_buffering' can't be set to the value of 'so
|
|||||||
SET @@global.innodb_change_buffering = @start_global_value;
|
SET @@global.innodb_change_buffering = @start_global_value;
|
||||||
SELECT @@global.innodb_change_buffering;
|
SELECT @@global.innodb_change_buffering;
|
||||||
@@global.innodb_change_buffering
|
@@global.innodb_change_buffering
|
||||||
all
|
none
|
||||||
|
@ -311,7 +311,7 @@ READ_ONLY NO
|
|||||||
COMMAND_LINE_ARGUMENT OPTIONAL
|
COMMAND_LINE_ARGUMENT OPTIONAL
|
||||||
VARIABLE_NAME INNODB_CHANGE_BUFFERING
|
VARIABLE_NAME INNODB_CHANGE_BUFFERING
|
||||||
SESSION_VALUE NULL
|
SESSION_VALUE NULL
|
||||||
DEFAULT_VALUE all
|
DEFAULT_VALUE none
|
||||||
VARIABLE_SCOPE GLOBAL
|
VARIABLE_SCOPE GLOBAL
|
||||||
VARIABLE_TYPE ENUM
|
VARIABLE_TYPE ENUM
|
||||||
VARIABLE_COMMENT Buffer changes to secondary indexes.
|
VARIABLE_COMMENT Buffer changes to secondary indexes.
|
||||||
|
@ -170,6 +170,7 @@ static pid_t pid;
|
|||||||
static char addr2line_binary[1024];
|
static char addr2line_binary[1024];
|
||||||
static char output[1024];
|
static char output[1024];
|
||||||
static struct pollfd poll_fds;
|
static struct pollfd poll_fds;
|
||||||
|
static void *addr_offset;
|
||||||
|
|
||||||
int start_addr2line_fork(const char *binary_path)
|
int start_addr2line_fork(const char *binary_path)
|
||||||
{
|
{
|
||||||
@ -297,7 +298,6 @@ static int addr_resolve(void *ptr, my_addr_loc *loc)
|
|||||||
int my_addr_resolve(void *ptr, my_addr_loc *loc)
|
int my_addr_resolve(void *ptr, my_addr_loc *loc)
|
||||||
{
|
{
|
||||||
Dl_info info;
|
Dl_info info;
|
||||||
int error;
|
|
||||||
|
|
||||||
if (!dladdr(ptr, &info))
|
if (!dladdr(ptr, &info))
|
||||||
return 1;
|
return 1;
|
||||||
@ -307,7 +307,7 @@ int my_addr_resolve(void *ptr, my_addr_loc *loc)
|
|||||||
/*
|
/*
|
||||||
We use dli_fname in case the path is longer than the length of
|
We use dli_fname in case the path is longer than the length of
|
||||||
our static string. We don't want to allocate anything
|
our static string. We don't want to allocate anything
|
||||||
dynamicaly here as we are in a "crashed" state.
|
dynamically here as we are in a "crashed" state.
|
||||||
*/
|
*/
|
||||||
if (start_addr2line_fork(info.dli_fname))
|
if (start_addr2line_fork(info.dli_fname))
|
||||||
{
|
{
|
||||||
@ -318,10 +318,22 @@ int my_addr_resolve(void *ptr, my_addr_loc *loc)
|
|||||||
}
|
}
|
||||||
/* Save result for future comparisons. */
|
/* Save result for future comparisons. */
|
||||||
strnmov(addr2line_binary, info.dli_fname, sizeof(addr2line_binary));
|
strnmov(addr2line_binary, info.dli_fname, sizeof(addr2line_binary));
|
||||||
|
|
||||||
|
/*
|
||||||
|
Check if we should use info.dli_fbase as an offset or not
|
||||||
|
for the base program. This is depending on if the compilation is
|
||||||
|
done with PIE or not.
|
||||||
|
*/
|
||||||
|
addr_offset= (void*) info.dli_fbase;
|
||||||
|
#ifndef __PIE__
|
||||||
|
if (strcmp(info.dli_fname, my_progname) == 0 &&
|
||||||
|
addr_resolve((void*) my_addr_resolve, loc) == 0 &&
|
||||||
|
strcmp(loc->func, "my_addr_resolve") == 0)
|
||||||
|
addr_offset= 0;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
if (!(error= addr_resolve((void*) (ptr - info.dli_fbase), loc)))
|
|
||||||
return 0;
|
return addr_resolve((void*) (ptr - addr_offset), loc);
|
||||||
return error;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -23,6 +23,7 @@
|
|||||||
|
|
||||||
#ifndef MAIN
|
#ifndef MAIN
|
||||||
|
|
||||||
|
#if defined(__APPLE__) || defined(__FreeBSD__) || defined(__linux__) || defined(__sun) || defined(_WIN32)
|
||||||
static my_bool memcpy_and_test(uchar *to, uchar *from, uint len)
|
static my_bool memcpy_and_test(uchar *to, uchar *from, uint len)
|
||||||
{
|
{
|
||||||
uint i, res= 1;
|
uint i, res= 1;
|
||||||
@ -32,6 +33,7 @@ static my_bool memcpy_and_test(uchar *to, uchar *from, uint len)
|
|||||||
res= 0;
|
res= 0;
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
#if defined(__APPLE__) || defined(__FreeBSD__)
|
#if defined(__APPLE__) || defined(__FreeBSD__)
|
||||||
#include <net/ethernet.h>
|
#include <net/ethernet.h>
|
||||||
@ -195,4 +197,3 @@ int main(int argc __attribute__((unused)),char **argv)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -233,8 +233,12 @@ static bool backup_flush(THD *thd)
|
|||||||
This will probably require a callback from the InnoDB code.
|
This will probably require a callback from the InnoDB code.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/* Retry to get inital lock for 0.1 + 0.5 + 2.25 + 11.25 + 56.25 = 70.35 sec */
|
||||||
|
#define MAX_RETRY_COUNT 5
|
||||||
|
|
||||||
static bool backup_block_ddl(THD *thd)
|
static bool backup_block_ddl(THD *thd)
|
||||||
{
|
{
|
||||||
|
uint sleep_time;
|
||||||
DBUG_ENTER("backup_block_ddl");
|
DBUG_ENTER("backup_block_ddl");
|
||||||
|
|
||||||
kill_delayed_threads();
|
kill_delayed_threads();
|
||||||
@ -275,17 +279,32 @@ static bool backup_block_ddl(THD *thd)
|
|||||||
block new DDL's, in addition to all previous blocks
|
block new DDL's, in addition to all previous blocks
|
||||||
We didn't do this lock above, as we wanted DDL's to be executed while
|
We didn't do this lock above, as we wanted DDL's to be executed while
|
||||||
we wait for non transactional tables (which may take a while).
|
we wait for non transactional tables (which may take a while).
|
||||||
|
|
||||||
|
We do this lock in a loop as we can get a deadlock if there are multi-object
|
||||||
|
ddl statements like
|
||||||
|
RENAME TABLE t1 TO t2, t3 TO t3
|
||||||
|
and the MDL happens in the middle of it.
|
||||||
*/
|
*/
|
||||||
if (thd->mdl_context.upgrade_shared_lock(backup_flush_ticket,
|
sleep_time= 100; // Start with 0.1 seconds
|
||||||
MDL_BACKUP_WAIT_DDL,
|
for (uint i= 0 ; i <= MAX_RETRY_COUNT ; i++)
|
||||||
thd->variables.lock_wait_timeout))
|
|
||||||
{
|
{
|
||||||
/*
|
if (!thd->mdl_context.upgrade_shared_lock(backup_flush_ticket,
|
||||||
Could be a timeout. Downgrade lock to what is was before this function
|
MDL_BACKUP_WAIT_DDL,
|
||||||
was called so that this function can be called again
|
thd->variables.lock_wait_timeout))
|
||||||
*/
|
break;
|
||||||
backup_flush_ticket->downgrade_lock(MDL_BACKUP_FLUSH);
|
if (thd->get_stmt_da()->sql_errno() != ER_LOCK_DEADLOCK || thd->killed ||
|
||||||
DBUG_RETURN(1);
|
i == MAX_RETRY_COUNT)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
Could be a timeout. Downgrade lock to what is was before this function
|
||||||
|
was called so that this function can be called again
|
||||||
|
*/
|
||||||
|
backup_flush_ticket->downgrade_lock(MDL_BACKUP_FLUSH);
|
||||||
|
DBUG_RETURN(1);
|
||||||
|
}
|
||||||
|
thd->clear_error(); // Forget the DEADLOCK error
|
||||||
|
my_sleep(sleep_time);
|
||||||
|
sleep_time*= 5; // Wait a bit longer next time
|
||||||
}
|
}
|
||||||
DBUG_RETURN(0);
|
DBUG_RETURN(0);
|
||||||
}
|
}
|
||||||
|
@ -14039,7 +14039,7 @@ get_best_group_min_max(PARAM *param, SEL_TREE *tree, double read_time)
|
|||||||
key_part_range[1]= last_part;
|
key_part_range[1]= last_part;
|
||||||
|
|
||||||
/* Check if cur_part is referenced in the WHERE clause. */
|
/* Check if cur_part is referenced in the WHERE clause. */
|
||||||
if (join->conds->walk(&Item::find_item_in_field_list_processor, 0,
|
if (join->conds->walk(&Item::find_item_in_field_list_processor, true,
|
||||||
key_part_range))
|
key_part_range))
|
||||||
{
|
{
|
||||||
cause= "keypart reference from where clause";
|
cause= "keypart reference from where clause";
|
||||||
|
@ -1589,7 +1589,8 @@ bool JOIN::prepare_stage2()
|
|||||||
#endif
|
#endif
|
||||||
if (select_lex->olap == ROLLUP_TYPE && rollup_init())
|
if (select_lex->olap == ROLLUP_TYPE && rollup_init())
|
||||||
goto err;
|
goto err;
|
||||||
if (alloc_func_list())
|
if (alloc_func_list() ||
|
||||||
|
make_sum_func_list(all_fields, fields_list, false))
|
||||||
goto err;
|
goto err;
|
||||||
|
|
||||||
res= FALSE;
|
res= FALSE;
|
||||||
@ -2204,7 +2205,21 @@ JOIN::optimize_inner()
|
|||||||
If all items were resolved by opt_sum_query, there is no need to
|
If all items were resolved by opt_sum_query, there is no need to
|
||||||
open any tables.
|
open any tables.
|
||||||
*/
|
*/
|
||||||
if ((res=opt_sum_query(thd, select_lex->leaf_tables, all_fields, conds)))
|
|
||||||
|
/*
|
||||||
|
The following resetting and restoring of sum_funcs is needed to
|
||||||
|
go around a bug in spider where it assumes that
|
||||||
|
make_sum_func_list() has not been called yet and do logical
|
||||||
|
choices based on this if special handling of min/max functions should
|
||||||
|
be done. We disable this special handling while we are trying to find
|
||||||
|
out if we can replace MIN/MAX values with constants.
|
||||||
|
*/
|
||||||
|
Item_sum **save_func_sums= sum_funcs, *tmp_sum_funcs= 0;
|
||||||
|
sum_funcs= &tmp_sum_funcs;
|
||||||
|
res= opt_sum_query(thd, select_lex->leaf_tables, all_fields, conds);
|
||||||
|
sum_funcs= save_func_sums;
|
||||||
|
|
||||||
|
if (res)
|
||||||
{
|
{
|
||||||
DBUG_ASSERT(res >= 0);
|
DBUG_ASSERT(res >= 0);
|
||||||
if (res == HA_ERR_KEY_NOT_FOUND)
|
if (res == HA_ERR_KEY_NOT_FOUND)
|
||||||
@ -2776,13 +2791,15 @@ int JOIN::optimize_stage2()
|
|||||||
calc_group_buffer(this, group_list);
|
calc_group_buffer(this, group_list);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (test_if_subpart(group_list, order) ||
|
/*
|
||||||
(!group_list && tmp_table_param.sum_func_count))
|
We can ignore ORDER BY if it's a prefix of the GROUP BY list
|
||||||
{
|
(as MariaDB is by default sorting on GROUP BY) or
|
||||||
|
if there is no GROUP BY and aggregate functions are used
|
||||||
|
(as the result will only contain one row).
|
||||||
|
*/
|
||||||
|
if (order && (test_if_subpart(group_list, order) ||
|
||||||
|
(!group_list && tmp_table_param.sum_func_count)))
|
||||||
order=0;
|
order=0;
|
||||||
if (is_indexed_agg_distinct(this, NULL))
|
|
||||||
sort_and_group= 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Can't use sort on head table if using join buffering
|
// Can't use sort on head table if using join buffering
|
||||||
if (full_join || hash_join)
|
if (full_join || hash_join)
|
||||||
@ -2814,7 +2831,6 @@ int JOIN::optimize_stage2()
|
|||||||
if (select_lex->have_window_funcs())
|
if (select_lex->have_window_funcs())
|
||||||
simple_order= FALSE;
|
simple_order= FALSE;
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
If the hint FORCE INDEX FOR ORDER BY/GROUP BY is used for the table
|
If the hint FORCE INDEX FOR ORDER BY/GROUP BY is used for the table
|
||||||
whose columns are required to be returned in a sorted order, then
|
whose columns are required to be returned in a sorted order, then
|
||||||
@ -3548,7 +3564,7 @@ bool JOIN::make_aggr_tables_info()
|
|||||||
// for the first table
|
// for the first table
|
||||||
if (group_list || tmp_table_param.sum_func_count)
|
if (group_list || tmp_table_param.sum_func_count)
|
||||||
{
|
{
|
||||||
if (make_sum_func_list(*curr_all_fields, *curr_fields_list, true, true))
|
if (make_sum_func_list(*curr_all_fields, *curr_fields_list, true))
|
||||||
DBUG_RETURN(true);
|
DBUG_RETURN(true);
|
||||||
if (prepare_sum_aggregators(sum_funcs,
|
if (prepare_sum_aggregators(sum_funcs,
|
||||||
!join_tab->is_using_agg_loose_index_scan()))
|
!join_tab->is_using_agg_loose_index_scan()))
|
||||||
@ -3658,7 +3674,7 @@ bool JOIN::make_aggr_tables_info()
|
|||||||
last_tab->all_fields= &tmp_all_fields3;
|
last_tab->all_fields= &tmp_all_fields3;
|
||||||
last_tab->fields= &tmp_fields_list3;
|
last_tab->fields= &tmp_fields_list3;
|
||||||
}
|
}
|
||||||
if (make_sum_func_list(*curr_all_fields, *curr_fields_list, true, true))
|
if (make_sum_func_list(*curr_all_fields, *curr_fields_list, true))
|
||||||
DBUG_RETURN(true);
|
DBUG_RETURN(true);
|
||||||
if (prepare_sum_aggregators(sum_funcs,
|
if (prepare_sum_aggregators(sum_funcs,
|
||||||
!join_tab ||
|
!join_tab ||
|
||||||
@ -3854,8 +3870,6 @@ JOIN::create_postjoin_aggr_table(JOIN_TAB *tab, List<Item> *table_fields,
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (make_sum_func_list(all_fields, fields_list, false))
|
|
||||||
goto err;
|
|
||||||
if (prepare_sum_aggregators(sum_funcs,
|
if (prepare_sum_aggregators(sum_funcs,
|
||||||
!join_tab->is_using_agg_loose_index_scan()))
|
!join_tab->is_using_agg_loose_index_scan()))
|
||||||
goto err;
|
goto err;
|
||||||
@ -7097,8 +7111,7 @@ void optimize_keyuse(JOIN *join, DYNAMIC_ARRAY *keyuse_array)
|
|||||||
Check for the presence of AGGFN(DISTINCT a) queries that may be subject
|
Check for the presence of AGGFN(DISTINCT a) queries that may be subject
|
||||||
to loose index scan.
|
to loose index scan.
|
||||||
|
|
||||||
|
Check if the query is a subject to AGGFN(DISTINCT) using loose index scan
|
||||||
Check if the query is a subject to AGGFN(DISTINCT) using loose index scan
|
|
||||||
(QUICK_GROUP_MIN_MAX_SELECT).
|
(QUICK_GROUP_MIN_MAX_SELECT).
|
||||||
Optionally (if out_args is supplied) will push the arguments of
|
Optionally (if out_args is supplied) will push the arguments of
|
||||||
AGGFN(DISTINCT) to the list
|
AGGFN(DISTINCT) to the list
|
||||||
@ -7131,14 +7144,11 @@ is_indexed_agg_distinct(JOIN *join, List<Item_field> *out_args)
|
|||||||
Item_sum **sum_item_ptr;
|
Item_sum **sum_item_ptr;
|
||||||
bool result= false;
|
bool result= false;
|
||||||
|
|
||||||
if (join->table_count != 1 || /* reference more than 1 table */
|
if (join->table_count != 1 || /* reference more than 1 table */
|
||||||
join->select_distinct || /* or a DISTINCT */
|
join->select_distinct || /* or a DISTINCT */
|
||||||
join->select_lex->olap == ROLLUP_TYPE) /* Check (B3) for ROLLUP */
|
join->select_lex->olap == ROLLUP_TYPE) /* Check (B3) for ROLLUP */
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (join->make_sum_func_list(join->all_fields, join->fields_list, true))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
Bitmap<MAX_FIELDS> first_aggdistinct_fields;
|
Bitmap<MAX_FIELDS> first_aggdistinct_fields;
|
||||||
bool first_aggdistinct_fields_initialized= false;
|
bool first_aggdistinct_fields_initialized= false;
|
||||||
for (sum_item_ptr= join->sum_funcs; *sum_item_ptr; sum_item_ptr++)
|
for (sum_item_ptr= join->sum_funcs; *sum_item_ptr; sum_item_ptr++)
|
||||||
@ -7240,16 +7250,23 @@ add_group_and_distinct_keys(JOIN *join, JOIN_TAB *join_tab)
|
|||||||
while ((item= select_items_it++))
|
while ((item= select_items_it++))
|
||||||
item->walk(&Item::collect_item_field_processor, 0, &indexed_fields);
|
item->walk(&Item::collect_item_field_processor, 0, &indexed_fields);
|
||||||
}
|
}
|
||||||
else if (join->tmp_table_param.sum_func_count &&
|
else if (!join->tmp_table_param.sum_func_count ||
|
||||||
is_indexed_agg_distinct(join, &indexed_fields))
|
!is_indexed_agg_distinct(join, &indexed_fields))
|
||||||
{
|
{
|
||||||
join->sort_and_group= 1;
|
/*
|
||||||
}
|
There where no GROUP BY fields and also either no aggregate
|
||||||
else
|
functions or not all aggregate functions where used with the
|
||||||
|
same DISTINCT (or MIN() / MAX() that works similarly).
|
||||||
|
Nothing to do there.
|
||||||
|
*/
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (indexed_fields.elements == 0)
|
if (indexed_fields.elements == 0)
|
||||||
|
{
|
||||||
|
/* There where no index we could use to satisfy the GROUP BY */
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
/* Intersect the keys of all group fields. */
|
/* Intersect the keys of all group fields. */
|
||||||
cur_item= indexed_fields_it++;
|
cur_item= indexed_fields_it++;
|
||||||
@ -25693,16 +25710,13 @@ bool JOIN::alloc_func_list()
|
|||||||
|
|
||||||
bool JOIN::make_sum_func_list(List<Item> &field_list,
|
bool JOIN::make_sum_func_list(List<Item> &field_list,
|
||||||
List<Item> &send_result_set_metadata,
|
List<Item> &send_result_set_metadata,
|
||||||
bool before_group_by, bool recompute)
|
bool before_group_by)
|
||||||
{
|
{
|
||||||
List_iterator_fast<Item> it(field_list);
|
List_iterator_fast<Item> it(field_list);
|
||||||
Item_sum **func;
|
Item_sum **func;
|
||||||
Item *item;
|
Item *item;
|
||||||
DBUG_ENTER("make_sum_func_list");
|
DBUG_ENTER("make_sum_func_list");
|
||||||
|
|
||||||
if (*sum_funcs && !recompute)
|
|
||||||
DBUG_RETURN(FALSE); /* We have already initialized sum_funcs. */
|
|
||||||
|
|
||||||
func= sum_funcs;
|
func= sum_funcs;
|
||||||
while ((item=it++))
|
while ((item=it++))
|
||||||
{
|
{
|
||||||
@ -25849,7 +25863,7 @@ change_to_use_tmp_fields(THD *thd, Ref_ptr_array ref_pointer_array,
|
|||||||
Change all funcs to be fields in tmp table.
|
Change all funcs to be fields in tmp table.
|
||||||
|
|
||||||
@param thd THD pointer
|
@param thd THD pointer
|
||||||
@param ref_pointer_array array of pointers to top elements of filed list
|
@param ref_pointer_array array of pointers to top elements of field list
|
||||||
@param res_selected_fields new list of items of select item list
|
@param res_selected_fields new list of items of select item list
|
||||||
@param res_all_fields new list of all items
|
@param res_all_fields new list of all items
|
||||||
@param elements number of elements in select item list
|
@param elements number of elements in select item list
|
||||||
|
@ -1196,7 +1196,17 @@ public:
|
|||||||
Indicates that grouping will be performed on the result set during
|
Indicates that grouping will be performed on the result set during
|
||||||
query execution. This field belongs to query execution.
|
query execution. This field belongs to query execution.
|
||||||
|
|
||||||
@see make_group_fields, alloc_group_fields, JOIN::exec
|
If 'sort_and_group' is set, then the optimizer is going to use on of
|
||||||
|
the following algorithms to resolve GROUP BY.
|
||||||
|
|
||||||
|
- If one table, sort the table and then calculate groups on the fly.
|
||||||
|
- If more than one table, create a temporary table to hold the join,
|
||||||
|
sort it and then resolve group by on the fly.
|
||||||
|
|
||||||
|
The 'on the fly' calculation is done in end_send_group()
|
||||||
|
|
||||||
|
@see make_group_fields, alloc_group_fields, JOIN::exec,
|
||||||
|
setup_end_select_func
|
||||||
*/
|
*/
|
||||||
bool sort_and_group;
|
bool sort_and_group;
|
||||||
bool first_record,full_join, no_field_update;
|
bool first_record,full_join, no_field_update;
|
||||||
@ -1654,7 +1664,7 @@ public:
|
|||||||
bool make_range_rowid_filters();
|
bool make_range_rowid_filters();
|
||||||
bool init_range_rowid_filters();
|
bool init_range_rowid_filters();
|
||||||
bool make_sum_func_list(List<Item> &all_fields, List<Item> &send_fields,
|
bool make_sum_func_list(List<Item> &all_fields, List<Item> &send_fields,
|
||||||
bool before_group_by, bool recompute= FALSE);
|
bool before_group_by);
|
||||||
|
|
||||||
/// Initialzes a slice, see comments for ref_ptrs above.
|
/// Initialzes a slice, see comments for ref_ptrs above.
|
||||||
Ref_ptr_array ref_ptr_array_slice(size_t slice_num)
|
Ref_ptr_array ref_ptr_array_slice(size_t slice_num)
|
||||||
|
@ -19659,7 +19659,7 @@ static MYSQL_SYSVAR_BOOL(numa_interleave, srv_numa_interleave,
|
|||||||
static MYSQL_SYSVAR_ENUM(change_buffering, innodb_change_buffering,
|
static MYSQL_SYSVAR_ENUM(change_buffering, innodb_change_buffering,
|
||||||
PLUGIN_VAR_RQCMDARG,
|
PLUGIN_VAR_RQCMDARG,
|
||||||
"Buffer changes to secondary indexes.",
|
"Buffer changes to secondary indexes.",
|
||||||
NULL, NULL, IBUF_USE_ALL, &innodb_change_buffering_typelib);
|
NULL, NULL, IBUF_USE_NONE, &innodb_change_buffering_typelib);
|
||||||
|
|
||||||
static MYSQL_SYSVAR_UINT(change_buffer_max_size,
|
static MYSQL_SYSVAR_UINT(change_buffer_max_size,
|
||||||
srv_change_buffer_max_size,
|
srv_change_buffer_max_size,
|
||||||
|
@ -639,8 +639,7 @@ loop:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Flush the recently written changes to the log file.
|
/** Flush the recently written changes to the log file.*/
|
||||||
and invoke mysql_mutex_lock(&log_sys.mutex). */
|
|
||||||
static void log_write_flush_to_disk_low(lsn_t lsn)
|
static void log_write_flush_to_disk_low(lsn_t lsn)
|
||||||
{
|
{
|
||||||
if (!log_sys.log.writes_are_durable())
|
if (!log_sys.log.writes_are_durable())
|
||||||
@ -780,10 +779,6 @@ static void log_write(bool rotate_key)
|
|||||||
start_offset - area_start);
|
start_offset - area_start);
|
||||||
srv_stats.log_padded.add(pad_size);
|
srv_stats.log_padded.add(pad_size);
|
||||||
log_sys.write_lsn = write_lsn;
|
log_sys.write_lsn = write_lsn;
|
||||||
if (log_sys.log.writes_are_durable()) {
|
|
||||||
log_sys.set_flushed_lsn(write_lsn);
|
|
||||||
log_flush_notify(write_lsn);
|
|
||||||
}
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user