mirror of
https://github.com/MariaDB/server.git
synced 2025-04-02 05:15:33 +02:00
Merge 10.4 into 10.5
This commit is contained in:
commit
23047d3ed4
89 changed files with 1905 additions and 872 deletions
client
include
libmariadbmysql-test
main
custom_aggregate_functions.resultcustom_aggregate_functions.testfunc_math.resultfunc_math.testsubselect4.resultsubselect4.testtable_value_constr.resulttable_value_constr.testudf.resultudf.test
suite
encryption
r
t
galera
innodb
parts
inc
r
rpl
vcol
mysys
sql
field.ccfield.hitem.hitem_func.ccitem_subselect.ccitem_sum.cclog_event.ccsp_head.ccsql_base.ccsql_repl.ccsql_statistics.ccsql_tvc.cctable.cc
storage
innobase
btr
buf
dict
fil
fsp
handler
ibuf
include
row
srv
sync
trx
tokudb/mysql-test/tokudb_parts/r
|
@ -92,6 +92,9 @@ extern "C" {
|
|||
#include <conio.h>
|
||||
#else
|
||||
#include <readline.h>
|
||||
#if !defined(USE_LIBEDIT_INTERFACE)
|
||||
#include <history.h>
|
||||
#endif
|
||||
#define HAVE_READLINE
|
||||
#define USE_POPEN
|
||||
#endif
|
||||
|
@ -1043,22 +1046,6 @@ static const char *embedded_server_groups[]=
|
|||
{ "server", "embedded", "mysql_SERVER", "mariadb_SERVER", 0 };
|
||||
|
||||
#ifdef HAVE_READLINE
|
||||
/*
|
||||
HIST_ENTRY is defined for libedit, but not for the real readline
|
||||
Need to redefine it for real readline to find it
|
||||
*/
|
||||
#if !defined(HAVE_HIST_ENTRY)
|
||||
typedef struct _hist_entry {
|
||||
const char *line;
|
||||
const char *data;
|
||||
} HIST_ENTRY;
|
||||
#endif
|
||||
|
||||
extern "C" int add_history(const char *command); /* From readline directory */
|
||||
extern "C" int read_history(const char *command);
|
||||
extern "C" int write_history(const char *command);
|
||||
extern "C" HIST_ENTRY *history_get(int num);
|
||||
extern "C" int history_length;
|
||||
static int not_in_history(const char *line);
|
||||
static void initialize_readline ();
|
||||
static void fix_history(String *final_command);
|
||||
|
|
|
@ -587,9 +587,10 @@ ATTRIBUTE_NORETURN
|
|||
static void cleanup_and_exit(int exit_code);
|
||||
|
||||
ATTRIBUTE_NORETURN
|
||||
void really_die(const char *msg);
|
||||
static void really_die(const char *msg);
|
||||
void report_or_die(const char *fmt, ...);
|
||||
ATTRIBUTE_NORETURN void die(const char *fmt, ...);
|
||||
ATTRIBUTE_NORETURN
|
||||
static void die(const char *fmt, ...);
|
||||
static void make_error_message(char *buf, size_t len, const char *fmt, va_list args);
|
||||
ATTRIBUTE_NORETURN ATTRIBUTE_FORMAT(printf, 1, 2)
|
||||
void abort_not_supported_test(const char *fmt, ...);
|
||||
|
@ -1540,7 +1541,7 @@ static void make_error_message(char *buf, size_t len, const char *fmt, va_list a
|
|||
s+= my_snprintf(s, end -s, "\n");
|
||||
}
|
||||
|
||||
void die(const char *fmt, ...)
|
||||
static void die(const char *fmt, ...)
|
||||
{
|
||||
char buff[DIE_BUFF_SIZE];
|
||||
va_list args;
|
||||
|
@ -1549,7 +1550,7 @@ void die(const char *fmt, ...)
|
|||
really_die(buff);
|
||||
}
|
||||
|
||||
void really_die(const char *msg)
|
||||
static void really_die(const char *msg)
|
||||
{
|
||||
static int dying= 0;
|
||||
fflush(stdout);
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
#define MY_ATOMIC_INCLUDED
|
||||
|
||||
/* Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved.
|
||||
Copyright (c) 2018, 2020, MariaDB
|
||||
|
||||
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
|
||||
|
@ -169,4 +170,48 @@
|
|||
my_atomic_casptr((P), (E), (D))
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
#include <atomic>
|
||||
/**
|
||||
A wrapper for std::atomic, defaulting to std::memory_order_relaxed.
|
||||
|
||||
When it comes to atomic loads or stores at std::memory_order_relaxed
|
||||
on IA-32 or AMD64, this wrapper is only introducing some constraints
|
||||
to the C++ compiler, to prevent some optimizations of loads or
|
||||
stores.
|
||||
|
||||
On POWER and ARM, atomic loads and stores involve different instructions
|
||||
from normal loads and stores and will thus incur some overhead.
|
||||
|
||||
Because atomic read-modify-write operations will always incur
|
||||
overhead, we intentionally do not define
|
||||
operator++(), operator--(), operator+=(), operator-=(), or similar,
|
||||
to make the overhead stand out in the users of this code.
|
||||
*/
|
||||
template <typename Type> class Atomic_relaxed
|
||||
{
|
||||
std::atomic<Type> m;
|
||||
public:
|
||||
Atomic_relaxed(const Atomic_relaxed<Type> &rhs)
|
||||
{ m.store(rhs, std::memory_order_relaxed); }
|
||||
Atomic_relaxed(Type val) : m(val) {}
|
||||
Atomic_relaxed() {}
|
||||
|
||||
operator Type() const { return m.load(std::memory_order_relaxed); }
|
||||
Type operator=(const Type val)
|
||||
{ m.store(val, std::memory_order_relaxed); return val; }
|
||||
Type operator=(const Atomic_relaxed<Type> &rhs) { return *this= Type{rhs}; }
|
||||
Type fetch_add(const Type i, std::memory_order o= std::memory_order_relaxed)
|
||||
{ return m.fetch_add(i, o); }
|
||||
Type fetch_sub(const Type i, std::memory_order o= std::memory_order_relaxed)
|
||||
{ return m.fetch_sub(i, o); }
|
||||
bool compare_exchange_strong(Type& i1, const Type i2,
|
||||
std::memory_order o1= std::memory_order_relaxed,
|
||||
std::memory_order o2= std::memory_order_relaxed)
|
||||
{ return m.compare_exchange_strong(i1, i2, o1, o2); }
|
||||
Type exchange(const Type i, std::memory_order o= std::memory_order_relaxed)
|
||||
{ return m.exchange(i, o); }
|
||||
};
|
||||
#endif /* __cplusplus */
|
||||
|
||||
#endif /* MY_ATOMIC_INCLUDED */
|
||||
|
|
|
@ -32,6 +32,7 @@
|
|||
|
||||
#if defined(HAVE_VALGRIND_MEMCHECK_H) && defined(HAVE_valgrind)
|
||||
# include <valgrind/memcheck.h>
|
||||
# define HAVE_valgrind_or_MSAN
|
||||
# define MEM_UNDEFINED(a,len) VALGRIND_MAKE_MEM_UNDEFINED(a,len)
|
||||
# define MEM_MAKE_DEFINED(a,len) VALGRIND_MAKE_MEM_DEFINED(a,len)
|
||||
# define MEM_NOACCESS(a,len) VALGRIND_MAKE_MEM_NOACCESS(a,len)
|
||||
|
@ -50,6 +51,7 @@ https://github.com/google/sanitizers/wiki/AddressSanitizerManualPoisoning */
|
|||
# define REDZONE_SIZE 8
|
||||
#elif __has_feature(memory_sanitizer)
|
||||
# include <sanitizer/msan_interface.h>
|
||||
# define HAVE_valgrind_or_MSAN
|
||||
# define MEM_UNDEFINED(a,len) __msan_allocated_memory(a,len)
|
||||
# define MEM_MAKE_DEFINED(a,len) __msan_unpoison(a,len)
|
||||
# define MEM_NOACCESS(a,len) ((void) 0)
|
||||
|
@ -65,16 +67,19 @@ https://github.com/google/sanitizers/wiki/AddressSanitizerManualPoisoning */
|
|||
# define REDZONE_SIZE 0
|
||||
#endif /* HAVE_VALGRIND_MEMCHECK_H */
|
||||
|
||||
#if defined(TRASH_FREED_MEMORY)
|
||||
/* NOTE: Do not invoke TRASH_FILL directly! Use TRASH_ALLOC or TRASH_FREE.
|
||||
|
||||
The MEM_UNDEFINED() call before memset() is for canceling the effect
|
||||
of any previous MEM_NOACCESS(). We must invoke MEM_UNDEFINED() after
|
||||
writing the dummy pattern, unless MEM_NOACCESS() is going to be invoked.
|
||||
On AddressSanitizer, the MEM_UNDEFINED() in TRASH_ALLOC() has no effect. */
|
||||
#ifdef TRASH_FREED_MEMORY
|
||||
/*
|
||||
TRASH_FILL() has to call MEM_UNDEFINED() to cancel any effect of TRASH_FREE().
|
||||
This can happen in the case one does
|
||||
TRASH_ALLOC(A,B) ; TRASH_FREE(A,B) ; TRASH_ALLOC(A,B)
|
||||
to reuse the same memory in an internal memory allocator like MEM_ROOT.
|
||||
For my_malloc() and safemalloc() the extra MEM_UNDEFINED is bit of an
|
||||
overkill.
|
||||
TRASH_FILL() is an internal function and should not be used externally.
|
||||
*/
|
||||
#define TRASH_FILL(A,B,C) do { const size_t trash_tmp= (B); MEM_UNDEFINED(A, trash_tmp); memset(A, C, trash_tmp); } while (0)
|
||||
#else
|
||||
#define TRASH_FILL(A,B,C) while (0)
|
||||
#define TRASH_FILL(A,B,C) do { MEM_UNDEFINED((A), (B)); } while (0)
|
||||
#endif
|
||||
/** Note that some memory became allocated or uninitialized. */
|
||||
#define TRASH_ALLOC(A,B) do { TRASH_FILL(A,B,0xA5); MEM_UNDEFINED(A,B); } while(0)
|
||||
|
|
|
@ -24,11 +24,33 @@ this program; if not, write to the Free Software Foundation, Inc.,
|
|||
namespace st_
|
||||
{
|
||||
|
||||
namespace detail
|
||||
{
|
||||
|
||||
template <class T> struct remove_cv
|
||||
{
|
||||
typedef T type;
|
||||
};
|
||||
template <class T> struct remove_cv<const T>
|
||||
{
|
||||
typedef T type;
|
||||
};
|
||||
template <class T> struct remove_cv<volatile T>
|
||||
{
|
||||
typedef T type;
|
||||
};
|
||||
template <class T> struct remove_cv<const volatile T>
|
||||
{
|
||||
typedef T type;
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
template <class ElementType> class span
|
||||
{
|
||||
public:
|
||||
typedef ElementType element_type;
|
||||
typedef ElementType value_type;
|
||||
typedef typename detail::remove_cv<ElementType>::type value_type;
|
||||
typedef size_t size_type;
|
||||
typedef ptrdiff_t difference_type;
|
||||
typedef element_type *pointer;
|
||||
|
@ -38,7 +60,6 @@ public:
|
|||
typedef pointer iterator;
|
||||
typedef const_pointer const_iterator;
|
||||
typedef std::reverse_iterator<iterator> reverse_iterator;
|
||||
typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
|
||||
|
||||
span() : data_(NULL), size_(0) {}
|
||||
|
||||
|
@ -64,73 +85,72 @@ public:
|
|||
|
||||
span &operator=(const span &other)
|
||||
{
|
||||
data_= other.data_;
|
||||
size_= other.size_;
|
||||
data_= other.data();
|
||||
size_= other.size();
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <size_t Count> span<element_type> first() const
|
||||
{
|
||||
assert(!empty());
|
||||
return span(data_, 1);
|
||||
return span(data(), 1);
|
||||
}
|
||||
template <size_t Count> span<element_type> last() const
|
||||
{
|
||||
assert(!empty());
|
||||
return span(data_ + size() - 1, 1);
|
||||
return span(data() + size() - 1, 1);
|
||||
}
|
||||
|
||||
span<element_type> first(size_type count) const
|
||||
{
|
||||
assert(!empty());
|
||||
return span(data_, 1);
|
||||
return span(data(), 1);
|
||||
}
|
||||
span<element_type> last(size_type count) const
|
||||
{
|
||||
assert(!empty());
|
||||
return span(data_ + size() - 1, 1);
|
||||
return span(data() + size() - 1, 1);
|
||||
}
|
||||
span<element_type> subspan(size_type offset, size_type count) const
|
||||
{
|
||||
assert(!empty());
|
||||
assert(size() >= offset + count);
|
||||
return span(data_ + offset, count);
|
||||
return span(data() + offset, count);
|
||||
}
|
||||
|
||||
size_type size() const { return size_; }
|
||||
size_type size_bytes() const { return size_ * sizeof(ElementType); }
|
||||
bool empty() const __attribute__((warn_unused_result)) { return size_ == 0; }
|
||||
size_type size_bytes() const { return size() * sizeof(ElementType); }
|
||||
bool empty() const __attribute__((warn_unused_result))
|
||||
{
|
||||
return size() == 0;
|
||||
}
|
||||
|
||||
reference operator[](size_type idx) const
|
||||
{
|
||||
assert(size() > idx);
|
||||
return data_[idx];
|
||||
return data()[idx];
|
||||
}
|
||||
reference front() const
|
||||
{
|
||||
assert(!empty());
|
||||
return data_[0];
|
||||
return data()[0];
|
||||
}
|
||||
reference back() const
|
||||
{
|
||||
assert(!empty());
|
||||
return data_[size() - 1];
|
||||
}
|
||||
pointer data() const
|
||||
{
|
||||
assert(!empty());
|
||||
return data_;
|
||||
return data()[size() - 1];
|
||||
}
|
||||
pointer data() const { return data_; }
|
||||
|
||||
iterator begin() const { return data_; }
|
||||
iterator end() const { return data_ + size_; }
|
||||
reverse_iterator rbegin() const
|
||||
{
|
||||
return std::reverse_iterator<iterator>(std::advance(end(), -1));
|
||||
return std::reverse_iterator<iterator>(end());
|
||||
}
|
||||
reverse_iterator rend() const
|
||||
{
|
||||
return std::reverse_iterator<iterator>(std::advance(begin(), -1));
|
||||
return std::reverse_iterator<iterator>(begin());
|
||||
}
|
||||
|
||||
private:
|
||||
|
|
|
@ -1 +1 @@
|
|||
Subproject commit 2759b87d72926b7c9b5426437a7c8dd15ff57945
|
||||
Subproject commit cdfecebc9932a0dd5516c10505bfe78d79132e7d
|
|
@ -1154,6 +1154,41 @@ NULL 8
|
|||
drop function agg_sum;
|
||||
drop table t1;
|
||||
#
|
||||
# User defined aggregate functions not working correctly when the schema is changed
|
||||
#
|
||||
CREATE SCHEMA IF NOT EXISTS common_schema;
|
||||
CREATE SCHEMA IF NOT EXISTS another_schema;
|
||||
DROP FUNCTION IF EXISTS common_schema.add_ints |
|
||||
Warnings:
|
||||
Note 1305 FUNCTION common_schema.add_ints does not exist
|
||||
CREATE FUNCTION common_schema.add_ints(int_1 INT, int_2 INT) RETURNS INT NO SQL
|
||||
BEGIN
|
||||
RETURN int_1 + int_2;
|
||||
END |
|
||||
DROP FUNCTION IF EXISTS common_schema.sum_ints |
|
||||
Warnings:
|
||||
Note 1305 FUNCTION common_schema.sum_ints does not exist
|
||||
CREATE AGGREGATE FUNCTION common_schema.sum_ints(int_val INT) RETURNS INT
|
||||
BEGIN
|
||||
DECLARE result INT DEFAULT 0;
|
||||
DECLARE CONTINUE HANDLER FOR NOT FOUND RETURN result;
|
||||
LOOP FETCH GROUP NEXT ROW;
|
||||
SET result = common_schema.add_ints(result, int_val);
|
||||
END LOOP;
|
||||
END |
|
||||
use common_schema;
|
||||
SELECT common_schema.sum_ints(seq) FROM (SELECT 1 seq UNION ALL SELECT 2) t;
|
||||
common_schema.sum_ints(seq)
|
||||
3
|
||||
USE another_schema;
|
||||
SELECT common_schema.sum_ints(seq) FROM (SELECT 1 seq UNION ALL SELECT 2) t;
|
||||
common_schema.sum_ints(seq)
|
||||
3
|
||||
drop database common_schema;
|
||||
drop database another_schema;
|
||||
USE test;
|
||||
# End of 10.3 tests
|
||||
#
|
||||
# MDEV-18813 PROCEDURE and anonymous blocks silently ignore FETCH GROUP NEXT ROW
|
||||
#
|
||||
CREATE PROCEDURE p1()
|
||||
|
@ -1186,3 +1221,4 @@ STARTS CURRENT_TIMESTAMP + INTERVAL 1 MONTH
|
|||
ENDS CURRENT_TIMESTAMP + INTERVAL 1 MONTH + INTERVAL 1 WEEK
|
||||
DO FETCH GROUP NEXT ROW;
|
||||
ERROR HY000: Aggregate specific instruction (FETCH GROUP NEXT ROW) used in a wrong context
|
||||
# End of 10.4 tests
|
||||
|
|
|
@ -966,6 +966,42 @@ select i, sum(i) from t1 group by i with rollup;
|
|||
drop function agg_sum;
|
||||
drop table t1;
|
||||
|
||||
--echo #
|
||||
--echo # User defined aggregate functions not working correctly when the schema is changed
|
||||
--echo #
|
||||
|
||||
CREATE SCHEMA IF NOT EXISTS common_schema;
|
||||
CREATE SCHEMA IF NOT EXISTS another_schema;
|
||||
DELIMITER |;
|
||||
DROP FUNCTION IF EXISTS common_schema.add_ints |
|
||||
CREATE FUNCTION common_schema.add_ints(int_1 INT, int_2 INT) RETURNS INT NO SQL
|
||||
BEGIN
|
||||
RETURN int_1 + int_2;
|
||||
END |
|
||||
DROP FUNCTION IF EXISTS common_schema.sum_ints |
|
||||
CREATE AGGREGATE FUNCTION common_schema.sum_ints(int_val INT) RETURNS INT
|
||||
BEGIN
|
||||
DECLARE result INT DEFAULT 0;
|
||||
DECLARE CONTINUE HANDLER FOR NOT FOUND RETURN result;
|
||||
LOOP FETCH GROUP NEXT ROW;
|
||||
SET result = common_schema.add_ints(result, int_val);
|
||||
END LOOP;
|
||||
END |
|
||||
|
||||
DELIMITER ;|
|
||||
|
||||
use common_schema;
|
||||
SELECT common_schema.sum_ints(seq) FROM (SELECT 1 seq UNION ALL SELECT 2) t;
|
||||
|
||||
USE another_schema;
|
||||
SELECT common_schema.sum_ints(seq) FROM (SELECT 1 seq UNION ALL SELECT 2) t;
|
||||
|
||||
drop database common_schema;
|
||||
drop database another_schema;
|
||||
|
||||
USE test;
|
||||
|
||||
--echo # End of 10.3 tests
|
||||
|
||||
--echo #
|
||||
--echo # MDEV-18813 PROCEDURE and anonymous blocks silently ignore FETCH GROUP NEXT ROW
|
||||
|
@ -1016,3 +1052,5 @@ CREATE EVENT ev1
|
|||
STARTS CURRENT_TIMESTAMP + INTERVAL 1 MONTH
|
||||
ENDS CURRENT_TIMESTAMP + INTERVAL 1 MONTH + INTERVAL 1 WEEK
|
||||
DO FETCH GROUP NEXT ROW;
|
||||
|
||||
--echo # End of 10.4 tests
|
||||
|
|
|
@ -1015,6 +1015,742 @@ SELECT -9223372036854775808 MOD -9223372036854775808;
|
|||
-9223372036854775808 MOD -9223372036854775808
|
||||
0
|
||||
#
|
||||
# MDEV-22502 MDB crashes in CREATE TABLE AS SELECT when the precision of returning type = 0
|
||||
#
|
||||
CREATE TABLE t1 (d decimal(5,5));
|
||||
INSERT INTO t1 VALUES (0.55555);
|
||||
SELECT TRUNCATE(d,0) FROM t1;
|
||||
TRUNCATE(d,0)
|
||||
0
|
||||
CREATE TABLE t2 AS SELECT TRUNCATE(d,0) FROM t1;
|
||||
SELECT * FROM t2;
|
||||
TRUNCATE(d,0)
|
||||
0
|
||||
SHOW CREATE TABLE t2;
|
||||
Table Create Table
|
||||
t2 CREATE TABLE `t2` (
|
||||
`TRUNCATE(d,0)` decimal(1,0) DEFAULT NULL
|
||||
) ENGINE=MyISAM DEFAULT CHARSET=latin1
|
||||
DROP TABLE t1, t2;
|
||||
#
|
||||
# MDEV-22503 MDB limits DECIMAL column precision to 16 doing CTAS with floor/ceil over DECIMAL(X,Y) where X > 16
|
||||
#
|
||||
CREATE TABLE t44 (d1 decimal(38,0) DEFAULT NULL);
|
||||
INSERT INTO t44 VALUES (12345678901234567890123456789012345678);
|
||||
SELECT FLOOR(d1) FROM t44;
|
||||
FLOOR(d1)
|
||||
12345678901234567890123456789012345678
|
||||
CREATE TABLE t45 AS SELECT FLOOR(d1) FROM t44;
|
||||
SELECT * FROM t45;
|
||||
FLOOR(d1)
|
||||
12345678901234567890123456789012345678
|
||||
SHOW CREATE TABLE t45;
|
||||
Table Create Table
|
||||
t45 CREATE TABLE `t45` (
|
||||
`FLOOR(d1)` decimal(38,0) DEFAULT NULL
|
||||
) ENGINE=MyISAM DEFAULT CHARSET=latin1
|
||||
DROP TABLE t44, t45;
|
||||
CREATE PROCEDURE p1(prec INT, scale INT)
|
||||
BEGIN
|
||||
DECLARE maxval VARCHAR(128) DEFAULT '';
|
||||
SET @type= CONCAT('DECIMAL(', prec, ',', scale,')');
|
||||
SET @stmt= CONCAT('CREATE TABLE t1 (a ', @type, ',b ', @type, 'unsigned)');
|
||||
PREPARE stmt FROM @stmt;
|
||||
EXECUTE stmt;
|
||||
DEALLOCATE PREPARE stmt;
|
||||
SET maxval= CONCAT(REPEAT('9', prec-scale), '.', REPEAT('9',scale));
|
||||
INSERT INTO t1 VALUES (maxval, maxval);
|
||||
CREATE TABLE t2 AS SELECT a, b, FLOOR(a) AS fa, FLOOR(b) AS fb FROM t1;
|
||||
SHOW CREATE TABLE t2;
|
||||
SELECT * FROM t2;
|
||||
DROP TABLE t1, t2;
|
||||
END;
|
||||
$$
|
||||
CREATE PROCEDURE p2(prec INT)
|
||||
BEGIN
|
||||
DECLARE scale INT DEFAULT 0;
|
||||
WHILE scale < prec AND scale <= 30 DO
|
||||
CALL p1(prec, scale);
|
||||
SET scale= scale + 1;
|
||||
END WHILE;
|
||||
END;
|
||||
$$
|
||||
CALL p2(38);
|
||||
Table t2
|
||||
Create Table CREATE TABLE `t2` (
|
||||
`a` decimal(38,0) DEFAULT NULL,
|
||||
`b` decimal(38,0) unsigned DEFAULT NULL,
|
||||
`fa` decimal(38,0) DEFAULT NULL,
|
||||
`fb` decimal(38,0) DEFAULT NULL
|
||||
) ENGINE=MyISAM DEFAULT CHARSET=latin1
|
||||
a 99999999999999999999999999999999999999
|
||||
b 99999999999999999999999999999999999999
|
||||
fa 99999999999999999999999999999999999999
|
||||
fb 99999999999999999999999999999999999999
|
||||
Table t2
|
||||
Create Table CREATE TABLE `t2` (
|
||||
`a` decimal(38,1) DEFAULT NULL,
|
||||
`b` decimal(38,1) unsigned DEFAULT NULL,
|
||||
`fa` decimal(37,0) DEFAULT NULL,
|
||||
`fb` decimal(37,0) DEFAULT NULL
|
||||
) ENGINE=MyISAM DEFAULT CHARSET=latin1
|
||||
a 9999999999999999999999999999999999999.9
|
||||
b 9999999999999999999999999999999999999.9
|
||||
fa 9999999999999999999999999999999999999
|
||||
fb 9999999999999999999999999999999999999
|
||||
Table t2
|
||||
Create Table CREATE TABLE `t2` (
|
||||
`a` decimal(38,2) DEFAULT NULL,
|
||||
`b` decimal(38,2) unsigned DEFAULT NULL,
|
||||
`fa` decimal(36,0) DEFAULT NULL,
|
||||
`fb` decimal(36,0) DEFAULT NULL
|
||||
) ENGINE=MyISAM DEFAULT CHARSET=latin1
|
||||
a 999999999999999999999999999999999999.99
|
||||
b 999999999999999999999999999999999999.99
|
||||
fa 999999999999999999999999999999999999
|
||||
fb 999999999999999999999999999999999999
|
||||
Table t2
|
||||
Create Table CREATE TABLE `t2` (
|
||||
`a` decimal(38,3) DEFAULT NULL,
|
||||
`b` decimal(38,3) unsigned DEFAULT NULL,
|
||||
`fa` decimal(35,0) DEFAULT NULL,
|
||||
`fb` decimal(35,0) DEFAULT NULL
|
||||
) ENGINE=MyISAM DEFAULT CHARSET=latin1
|
||||
a 99999999999999999999999999999999999.999
|
||||
b 99999999999999999999999999999999999.999
|
||||
fa 99999999999999999999999999999999999
|
||||
fb 99999999999999999999999999999999999
|
||||
Table t2
|
||||
Create Table CREATE TABLE `t2` (
|
||||
`a` decimal(38,4) DEFAULT NULL,
|
||||
`b` decimal(38,4) unsigned DEFAULT NULL,
|
||||
`fa` decimal(34,0) DEFAULT NULL,
|
||||
`fb` decimal(34,0) DEFAULT NULL
|
||||
) ENGINE=MyISAM DEFAULT CHARSET=latin1
|
||||
a 9999999999999999999999999999999999.9999
|
||||
b 9999999999999999999999999999999999.9999
|
||||
fa 9999999999999999999999999999999999
|
||||
fb 9999999999999999999999999999999999
|
||||
Table t2
|
||||
Create Table CREATE TABLE `t2` (
|
||||
`a` decimal(38,5) DEFAULT NULL,
|
||||
`b` decimal(38,5) unsigned DEFAULT NULL,
|
||||
`fa` decimal(33,0) DEFAULT NULL,
|
||||
`fb` decimal(33,0) DEFAULT NULL
|
||||
) ENGINE=MyISAM DEFAULT CHARSET=latin1
|
||||
a 999999999999999999999999999999999.99999
|
||||
b 999999999999999999999999999999999.99999
|
||||
fa 999999999999999999999999999999999
|
||||
fb 999999999999999999999999999999999
|
||||
Table t2
|
||||
Create Table CREATE TABLE `t2` (
|
||||
`a` decimal(38,6) DEFAULT NULL,
|
||||
`b` decimal(38,6) unsigned DEFAULT NULL,
|
||||
`fa` decimal(32,0) DEFAULT NULL,
|
||||
`fb` decimal(32,0) DEFAULT NULL
|
||||
) ENGINE=MyISAM DEFAULT CHARSET=latin1
|
||||
a 99999999999999999999999999999999.999999
|
||||
b 99999999999999999999999999999999.999999
|
||||
fa 99999999999999999999999999999999
|
||||
fb 99999999999999999999999999999999
|
||||
Table t2
|
||||
Create Table CREATE TABLE `t2` (
|
||||
`a` decimal(38,7) DEFAULT NULL,
|
||||
`b` decimal(38,7) unsigned DEFAULT NULL,
|
||||
`fa` decimal(31,0) DEFAULT NULL,
|
||||
`fb` decimal(31,0) DEFAULT NULL
|
||||
) ENGINE=MyISAM DEFAULT CHARSET=latin1
|
||||
a 9999999999999999999999999999999.9999999
|
||||
b 9999999999999999999999999999999.9999999
|
||||
fa 9999999999999999999999999999999
|
||||
fb 9999999999999999999999999999999
|
||||
Table t2
|
||||
Create Table CREATE TABLE `t2` (
|
||||
`a` decimal(38,8) DEFAULT NULL,
|
||||
`b` decimal(38,8) unsigned DEFAULT NULL,
|
||||
`fa` decimal(30,0) DEFAULT NULL,
|
||||
`fb` decimal(30,0) DEFAULT NULL
|
||||
) ENGINE=MyISAM DEFAULT CHARSET=latin1
|
||||
a 999999999999999999999999999999.99999999
|
||||
b 999999999999999999999999999999.99999999
|
||||
fa 999999999999999999999999999999
|
||||
fb 999999999999999999999999999999
|
||||
Table t2
|
||||
Create Table CREATE TABLE `t2` (
|
||||
`a` decimal(38,9) DEFAULT NULL,
|
||||
`b` decimal(38,9) unsigned DEFAULT NULL,
|
||||
`fa` decimal(29,0) DEFAULT NULL,
|
||||
`fb` decimal(29,0) DEFAULT NULL
|
||||
) ENGINE=MyISAM DEFAULT CHARSET=latin1
|
||||
a 99999999999999999999999999999.999999999
|
||||
b 99999999999999999999999999999.999999999
|
||||
fa 99999999999999999999999999999
|
||||
fb 99999999999999999999999999999
|
||||
Table t2
|
||||
Create Table CREATE TABLE `t2` (
|
||||
`a` decimal(38,10) DEFAULT NULL,
|
||||
`b` decimal(38,10) unsigned DEFAULT NULL,
|
||||
`fa` decimal(28,0) DEFAULT NULL,
|
||||
`fb` decimal(28,0) DEFAULT NULL
|
||||
) ENGINE=MyISAM DEFAULT CHARSET=latin1
|
||||
a 9999999999999999999999999999.9999999999
|
||||
b 9999999999999999999999999999.9999999999
|
||||
fa 9999999999999999999999999999
|
||||
fb 9999999999999999999999999999
|
||||
Table t2
|
||||
Create Table CREATE TABLE `t2` (
|
||||
`a` decimal(38,11) DEFAULT NULL,
|
||||
`b` decimal(38,11) unsigned DEFAULT NULL,
|
||||
`fa` decimal(27,0) DEFAULT NULL,
|
||||
`fb` decimal(27,0) DEFAULT NULL
|
||||
) ENGINE=MyISAM DEFAULT CHARSET=latin1
|
||||
a 999999999999999999999999999.99999999999
|
||||
b 999999999999999999999999999.99999999999
|
||||
fa 999999999999999999999999999
|
||||
fb 999999999999999999999999999
|
||||
Table t2
|
||||
Create Table CREATE TABLE `t2` (
|
||||
`a` decimal(38,12) DEFAULT NULL,
|
||||
`b` decimal(38,12) unsigned DEFAULT NULL,
|
||||
`fa` decimal(26,0) DEFAULT NULL,
|
||||
`fb` decimal(26,0) DEFAULT NULL
|
||||
) ENGINE=MyISAM DEFAULT CHARSET=latin1
|
||||
a 99999999999999999999999999.999999999999
|
||||
b 99999999999999999999999999.999999999999
|
||||
fa 99999999999999999999999999
|
||||
fb 99999999999999999999999999
|
||||
Table t2
|
||||
Create Table CREATE TABLE `t2` (
|
||||
`a` decimal(38,13) DEFAULT NULL,
|
||||
`b` decimal(38,13) unsigned DEFAULT NULL,
|
||||
`fa` decimal(25,0) DEFAULT NULL,
|
||||
`fb` decimal(25,0) DEFAULT NULL
|
||||
) ENGINE=MyISAM DEFAULT CHARSET=latin1
|
||||
a 9999999999999999999999999.9999999999999
|
||||
b 9999999999999999999999999.9999999999999
|
||||
fa 9999999999999999999999999
|
||||
fb 9999999999999999999999999
|
||||
Table t2
|
||||
Create Table CREATE TABLE `t2` (
|
||||
`a` decimal(38,14) DEFAULT NULL,
|
||||
`b` decimal(38,14) unsigned DEFAULT NULL,
|
||||
`fa` decimal(24,0) DEFAULT NULL,
|
||||
`fb` decimal(24,0) DEFAULT NULL
|
||||
) ENGINE=MyISAM DEFAULT CHARSET=latin1
|
||||
a 999999999999999999999999.99999999999999
|
||||
b 999999999999999999999999.99999999999999
|
||||
fa 999999999999999999999999
|
||||
fb 999999999999999999999999
|
||||
Table t2
|
||||
Create Table CREATE TABLE `t2` (
|
||||
`a` decimal(38,15) DEFAULT NULL,
|
||||
`b` decimal(38,15) unsigned DEFAULT NULL,
|
||||
`fa` decimal(23,0) DEFAULT NULL,
|
||||
`fb` decimal(23,0) DEFAULT NULL
|
||||
) ENGINE=MyISAM DEFAULT CHARSET=latin1
|
||||
a 99999999999999999999999.999999999999999
|
||||
b 99999999999999999999999.999999999999999
|
||||
fa 99999999999999999999999
|
||||
fb 99999999999999999999999
|
||||
Table t2
|
||||
Create Table CREATE TABLE `t2` (
|
||||
`a` decimal(38,16) DEFAULT NULL,
|
||||
`b` decimal(38,16) unsigned DEFAULT NULL,
|
||||
`fa` decimal(22,0) DEFAULT NULL,
|
||||
`fb` decimal(22,0) DEFAULT NULL
|
||||
) ENGINE=MyISAM DEFAULT CHARSET=latin1
|
||||
a 9999999999999999999999.9999999999999999
|
||||
b 9999999999999999999999.9999999999999999
|
||||
fa 9999999999999999999999
|
||||
fb 9999999999999999999999
|
||||
Table t2
|
||||
Create Table CREATE TABLE `t2` (
|
||||
`a` decimal(38,17) DEFAULT NULL,
|
||||
`b` decimal(38,17) unsigned DEFAULT NULL,
|
||||
`fa` decimal(21,0) DEFAULT NULL,
|
||||
`fb` decimal(21,0) DEFAULT NULL
|
||||
) ENGINE=MyISAM DEFAULT CHARSET=latin1
|
||||
a 999999999999999999999.99999999999999999
|
||||
b 999999999999999999999.99999999999999999
|
||||
fa 999999999999999999999
|
||||
fb 999999999999999999999
|
||||
Table t2
|
||||
Create Table CREATE TABLE `t2` (
|
||||
`a` decimal(38,18) DEFAULT NULL,
|
||||
`b` decimal(38,18) unsigned DEFAULT NULL,
|
||||
`fa` decimal(20,0) DEFAULT NULL,
|
||||
`fb` decimal(20,0) DEFAULT NULL
|
||||
) ENGINE=MyISAM DEFAULT CHARSET=latin1
|
||||
a 99999999999999999999.999999999999999999
|
||||
b 99999999999999999999.999999999999999999
|
||||
fa 99999999999999999999
|
||||
fb 99999999999999999999
|
||||
Table t2
|
||||
Create Table CREATE TABLE `t2` (
|
||||
`a` decimal(38,19) DEFAULT NULL,
|
||||
`b` decimal(38,19) unsigned DEFAULT NULL,
|
||||
`fa` decimal(19,0) DEFAULT NULL,
|
||||
`fb` decimal(19,0) DEFAULT NULL
|
||||
) ENGINE=MyISAM DEFAULT CHARSET=latin1
|
||||
a 9999999999999999999.9999999999999999999
|
||||
b 9999999999999999999.9999999999999999999
|
||||
fa 9999999999999999999
|
||||
fb 9999999999999999999
|
||||
Table t2
|
||||
Create Table CREATE TABLE `t2` (
|
||||
`a` decimal(38,20) DEFAULT NULL,
|
||||
`b` decimal(38,20) unsigned DEFAULT NULL,
|
||||
`fa` decimal(18,0) DEFAULT NULL,
|
||||
`fb` bigint(17) unsigned DEFAULT NULL
|
||||
) ENGINE=MyISAM DEFAULT CHARSET=latin1
|
||||
a 999999999999999999.99999999999999999999
|
||||
b 999999999999999999.99999999999999999999
|
||||
fa 999999999999999999
|
||||
fb 999999999999999999
|
||||
Table t2
|
||||
Create Table CREATE TABLE `t2` (
|
||||
`a` decimal(38,21) DEFAULT NULL,
|
||||
`b` decimal(38,21) unsigned DEFAULT NULL,
|
||||
`fa` bigint(17) DEFAULT NULL,
|
||||
`fb` bigint(17) unsigned DEFAULT NULL
|
||||
) ENGINE=MyISAM DEFAULT CHARSET=latin1
|
||||
a 99999999999999999.999999999999999999999
|
||||
b 99999999999999999.999999999999999999999
|
||||
fa 99999999999999999
|
||||
fb 99999999999999999
|
||||
Table t2
|
||||
Create Table CREATE TABLE `t2` (
|
||||
`a` decimal(38,22) DEFAULT NULL,
|
||||
`b` decimal(38,22) unsigned DEFAULT NULL,
|
||||
`fa` bigint(17) DEFAULT NULL,
|
||||
`fb` bigint(17) unsigned DEFAULT NULL
|
||||
) ENGINE=MyISAM DEFAULT CHARSET=latin1
|
||||
a 9999999999999999.9999999999999999999999
|
||||
b 9999999999999999.9999999999999999999999
|
||||
fa 9999999999999999
|
||||
fb 9999999999999999
|
||||
Table t2
|
||||
Create Table CREATE TABLE `t2` (
|
||||
`a` decimal(38,23) DEFAULT NULL,
|
||||
`b` decimal(38,23) unsigned DEFAULT NULL,
|
||||
`fa` bigint(17) DEFAULT NULL,
|
||||
`fb` bigint(17) unsigned DEFAULT NULL
|
||||
) ENGINE=MyISAM DEFAULT CHARSET=latin1
|
||||
a 999999999999999.99999999999999999999999
|
||||
b 999999999999999.99999999999999999999999
|
||||
fa 999999999999999
|
||||
fb 999999999999999
|
||||
Table t2
|
||||
Create Table CREATE TABLE `t2` (
|
||||
`a` decimal(38,24) DEFAULT NULL,
|
||||
`b` decimal(38,24) unsigned DEFAULT NULL,
|
||||
`fa` bigint(17) DEFAULT NULL,
|
||||
`fb` bigint(16) unsigned DEFAULT NULL
|
||||
) ENGINE=MyISAM DEFAULT CHARSET=latin1
|
||||
a 99999999999999.999999999999999999999999
|
||||
b 99999999999999.999999999999999999999999
|
||||
fa 99999999999999
|
||||
fb 99999999999999
|
||||
Table t2
|
||||
Create Table CREATE TABLE `t2` (
|
||||
`a` decimal(38,25) DEFAULT NULL,
|
||||
`b` decimal(38,25) unsigned DEFAULT NULL,
|
||||
`fa` bigint(16) DEFAULT NULL,
|
||||
`fb` bigint(15) unsigned DEFAULT NULL
|
||||
) ENGINE=MyISAM DEFAULT CHARSET=latin1
|
||||
a 9999999999999.9999999999999999999999999
|
||||
b 9999999999999.9999999999999999999999999
|
||||
fa 9999999999999
|
||||
fb 9999999999999
|
||||
Table t2
|
||||
Create Table CREATE TABLE `t2` (
|
||||
`a` decimal(38,26) DEFAULT NULL,
|
||||
`b` decimal(38,26) unsigned DEFAULT NULL,
|
||||
`fa` bigint(15) DEFAULT NULL,
|
||||
`fb` bigint(14) unsigned DEFAULT NULL
|
||||
) ENGINE=MyISAM DEFAULT CHARSET=latin1
|
||||
a 999999999999.99999999999999999999999999
|
||||
b 999999999999.99999999999999999999999999
|
||||
fa 999999999999
|
||||
fb 999999999999
|
||||
Table t2
|
||||
Create Table CREATE TABLE `t2` (
|
||||
`a` decimal(38,27) DEFAULT NULL,
|
||||
`b` decimal(38,27) unsigned DEFAULT NULL,
|
||||
`fa` bigint(14) DEFAULT NULL,
|
||||
`fb` bigint(13) unsigned DEFAULT NULL
|
||||
) ENGINE=MyISAM DEFAULT CHARSET=latin1
|
||||
a 99999999999.999999999999999999999999999
|
||||
b 99999999999.999999999999999999999999999
|
||||
fa 99999999999
|
||||
fb 99999999999
|
||||
Table t2
|
||||
Create Table CREATE TABLE `t2` (
|
||||
`a` decimal(38,28) DEFAULT NULL,
|
||||
`b` decimal(38,28) unsigned DEFAULT NULL,
|
||||
`fa` bigint(13) DEFAULT NULL,
|
||||
`fb` bigint(12) unsigned DEFAULT NULL
|
||||
) ENGINE=MyISAM DEFAULT CHARSET=latin1
|
||||
a 9999999999.9999999999999999999999999999
|
||||
b 9999999999.9999999999999999999999999999
|
||||
fa 9999999999
|
||||
fb 9999999999
|
||||
Table t2
|
||||
Create Table CREATE TABLE `t2` (
|
||||
`a` decimal(38,29) DEFAULT NULL,
|
||||
`b` decimal(38,29) unsigned DEFAULT NULL,
|
||||
`fa` bigint(12) DEFAULT NULL,
|
||||
`fb` bigint(11) unsigned DEFAULT NULL
|
||||
) ENGINE=MyISAM DEFAULT CHARSET=latin1
|
||||
a 999999999.99999999999999999999999999999
|
||||
b 999999999.99999999999999999999999999999
|
||||
fa 999999999
|
||||
fb 999999999
|
||||
Table t2
|
||||
Create Table CREATE TABLE `t2` (
|
||||
`a` decimal(38,30) DEFAULT NULL,
|
||||
`b` decimal(38,30) unsigned DEFAULT NULL,
|
||||
`fa` bigint(11) DEFAULT NULL,
|
||||
`fb` bigint(10) unsigned DEFAULT NULL
|
||||
) ENGINE=MyISAM DEFAULT CHARSET=latin1
|
||||
a 99999999.999999999999999999999999999999
|
||||
b 99999999.999999999999999999999999999999
|
||||
fa 99999999
|
||||
fb 99999999
|
||||
CALL p2(30);
|
||||
Table t2
|
||||
Create Table CREATE TABLE `t2` (
|
||||
`a` decimal(30,0) DEFAULT NULL,
|
||||
`b` decimal(30,0) unsigned DEFAULT NULL,
|
||||
`fa` decimal(30,0) DEFAULT NULL,
|
||||
`fb` decimal(31,0) unsigned DEFAULT NULL
|
||||
) ENGINE=MyISAM DEFAULT CHARSET=latin1
|
||||
a 999999999999999999999999999999
|
||||
b 999999999999999999999999999999
|
||||
fa 999999999999999999999999999999
|
||||
fb 999999999999999999999999999999
|
||||
Table t2
|
||||
Create Table CREATE TABLE `t2` (
|
||||
`a` decimal(30,1) DEFAULT NULL,
|
||||
`b` decimal(30,1) unsigned DEFAULT NULL,
|
||||
`fa` decimal(29,0) DEFAULT NULL,
|
||||
`fb` decimal(30,0) unsigned DEFAULT NULL
|
||||
) ENGINE=MyISAM DEFAULT CHARSET=latin1
|
||||
a 99999999999999999999999999999.9
|
||||
b 99999999999999999999999999999.9
|
||||
fa 99999999999999999999999999999
|
||||
fb 99999999999999999999999999999
|
||||
Table t2
|
||||
Create Table CREATE TABLE `t2` (
|
||||
`a` decimal(30,2) DEFAULT NULL,
|
||||
`b` decimal(30,2) unsigned DEFAULT NULL,
|
||||
`fa` decimal(28,0) DEFAULT NULL,
|
||||
`fb` decimal(29,0) unsigned DEFAULT NULL
|
||||
) ENGINE=MyISAM DEFAULT CHARSET=latin1
|
||||
a 9999999999999999999999999999.99
|
||||
b 9999999999999999999999999999.99
|
||||
fa 9999999999999999999999999999
|
||||
fb 9999999999999999999999999999
|
||||
Table t2
|
||||
Create Table CREATE TABLE `t2` (
|
||||
`a` decimal(30,3) DEFAULT NULL,
|
||||
`b` decimal(30,3) unsigned DEFAULT NULL,
|
||||
`fa` decimal(27,0) DEFAULT NULL,
|
||||
`fb` decimal(28,0) unsigned DEFAULT NULL
|
||||
) ENGINE=MyISAM DEFAULT CHARSET=latin1
|
||||
a 999999999999999999999999999.999
|
||||
b 999999999999999999999999999.999
|
||||
fa 999999999999999999999999999
|
||||
fb 999999999999999999999999999
|
||||
Table t2
|
||||
Create Table CREATE TABLE `t2` (
|
||||
`a` decimal(30,4) DEFAULT NULL,
|
||||
`b` decimal(30,4) unsigned DEFAULT NULL,
|
||||
`fa` decimal(26,0) DEFAULT NULL,
|
||||
`fb` decimal(27,0) unsigned DEFAULT NULL
|
||||
) ENGINE=MyISAM DEFAULT CHARSET=latin1
|
||||
a 99999999999999999999999999.9999
|
||||
b 99999999999999999999999999.9999
|
||||
fa 99999999999999999999999999
|
||||
fb 99999999999999999999999999
|
||||
Table t2
|
||||
Create Table CREATE TABLE `t2` (
|
||||
`a` decimal(30,5) DEFAULT NULL,
|
||||
`b` decimal(30,5) unsigned DEFAULT NULL,
|
||||
`fa` decimal(25,0) DEFAULT NULL,
|
||||
`fb` decimal(26,0) unsigned DEFAULT NULL
|
||||
) ENGINE=MyISAM DEFAULT CHARSET=latin1
|
||||
a 9999999999999999999999999.99999
|
||||
b 9999999999999999999999999.99999
|
||||
fa 9999999999999999999999999
|
||||
fb 9999999999999999999999999
|
||||
Table t2
|
||||
Create Table CREATE TABLE `t2` (
|
||||
`a` decimal(30,6) DEFAULT NULL,
|
||||
`b` decimal(30,6) unsigned DEFAULT NULL,
|
||||
`fa` decimal(24,0) DEFAULT NULL,
|
||||
`fb` decimal(25,0) unsigned DEFAULT NULL
|
||||
) ENGINE=MyISAM DEFAULT CHARSET=latin1
|
||||
a 999999999999999999999999.999999
|
||||
b 999999999999999999999999.999999
|
||||
fa 999999999999999999999999
|
||||
fb 999999999999999999999999
|
||||
Table t2
|
||||
Create Table CREATE TABLE `t2` (
|
||||
`a` decimal(30,7) DEFAULT NULL,
|
||||
`b` decimal(30,7) unsigned DEFAULT NULL,
|
||||
`fa` decimal(23,0) DEFAULT NULL,
|
||||
`fb` decimal(24,0) unsigned DEFAULT NULL
|
||||
) ENGINE=MyISAM DEFAULT CHARSET=latin1
|
||||
a 99999999999999999999999.9999999
|
||||
b 99999999999999999999999.9999999
|
||||
fa 99999999999999999999999
|
||||
fb 99999999999999999999999
|
||||
Table t2
|
||||
Create Table CREATE TABLE `t2` (
|
||||
`a` decimal(30,8) DEFAULT NULL,
|
||||
`b` decimal(30,8) unsigned DEFAULT NULL,
|
||||
`fa` decimal(22,0) DEFAULT NULL,
|
||||
`fb` decimal(23,0) unsigned DEFAULT NULL
|
||||
) ENGINE=MyISAM DEFAULT CHARSET=latin1
|
||||
a 9999999999999999999999.99999999
|
||||
b 9999999999999999999999.99999999
|
||||
fa 9999999999999999999999
|
||||
fb 9999999999999999999999
|
||||
Table t2
|
||||
Create Table CREATE TABLE `t2` (
|
||||
`a` decimal(30,9) DEFAULT NULL,
|
||||
`b` decimal(30,9) unsigned DEFAULT NULL,
|
||||
`fa` decimal(21,0) DEFAULT NULL,
|
||||
`fb` decimal(22,0) unsigned DEFAULT NULL
|
||||
) ENGINE=MyISAM DEFAULT CHARSET=latin1
|
||||
a 999999999999999999999.999999999
|
||||
b 999999999999999999999.999999999
|
||||
fa 999999999999999999999
|
||||
fb 999999999999999999999
|
||||
Table t2
|
||||
Create Table CREATE TABLE `t2` (
|
||||
`a` decimal(30,10) DEFAULT NULL,
|
||||
`b` decimal(30,10) unsigned DEFAULT NULL,
|
||||
`fa` decimal(20,0) DEFAULT NULL,
|
||||
`fb` decimal(21,0) unsigned DEFAULT NULL
|
||||
) ENGINE=MyISAM DEFAULT CHARSET=latin1
|
||||
a 99999999999999999999.9999999999
|
||||
b 99999999999999999999.9999999999
|
||||
fa 99999999999999999999
|
||||
fb 99999999999999999999
|
||||
Table t2
|
||||
Create Table CREATE TABLE `t2` (
|
||||
`a` decimal(30,11) DEFAULT NULL,
|
||||
`b` decimal(30,11) unsigned DEFAULT NULL,
|
||||
`fa` decimal(19,0) DEFAULT NULL,
|
||||
`fb` decimal(20,0) unsigned DEFAULT NULL
|
||||
) ENGINE=MyISAM DEFAULT CHARSET=latin1
|
||||
a 9999999999999999999.99999999999
|
||||
b 9999999999999999999.99999999999
|
||||
fa 9999999999999999999
|
||||
fb 9999999999999999999
|
||||
Table t2
|
||||
Create Table CREATE TABLE `t2` (
|
||||
`a` decimal(30,12) DEFAULT NULL,
|
||||
`b` decimal(30,12) unsigned DEFAULT NULL,
|
||||
`fa` decimal(18,0) DEFAULT NULL,
|
||||
`fb` bigint(17) unsigned DEFAULT NULL
|
||||
) ENGINE=MyISAM DEFAULT CHARSET=latin1
|
||||
a 999999999999999999.999999999999
|
||||
b 999999999999999999.999999999999
|
||||
fa 999999999999999999
|
||||
fb 999999999999999999
|
||||
Table t2
|
||||
Create Table CREATE TABLE `t2` (
|
||||
`a` decimal(30,13) DEFAULT NULL,
|
||||
`b` decimal(30,13) unsigned DEFAULT NULL,
|
||||
`fa` bigint(17) DEFAULT NULL,
|
||||
`fb` bigint(17) unsigned DEFAULT NULL
|
||||
) ENGINE=MyISAM DEFAULT CHARSET=latin1
|
||||
a 99999999999999999.9999999999999
|
||||
b 99999999999999999.9999999999999
|
||||
fa 99999999999999999
|
||||
fb 99999999999999999
|
||||
Table t2
|
||||
Create Table CREATE TABLE `t2` (
|
||||
`a` decimal(30,14) DEFAULT NULL,
|
||||
`b` decimal(30,14) unsigned DEFAULT NULL,
|
||||
`fa` bigint(17) DEFAULT NULL,
|
||||
`fb` bigint(17) unsigned DEFAULT NULL
|
||||
) ENGINE=MyISAM DEFAULT CHARSET=latin1
|
||||
a 9999999999999999.99999999999999
|
||||
b 9999999999999999.99999999999999
|
||||
fa 9999999999999999
|
||||
fb 9999999999999999
|
||||
Table t2
|
||||
Create Table CREATE TABLE `t2` (
|
||||
`a` decimal(30,15) DEFAULT NULL,
|
||||
`b` decimal(30,15) unsigned DEFAULT NULL,
|
||||
`fa` bigint(17) DEFAULT NULL,
|
||||
`fb` bigint(17) unsigned DEFAULT NULL
|
||||
) ENGINE=MyISAM DEFAULT CHARSET=latin1
|
||||
a 999999999999999.999999999999999
|
||||
b 999999999999999.999999999999999
|
||||
fa 999999999999999
|
||||
fb 999999999999999
|
||||
Table t2
|
||||
Create Table CREATE TABLE `t2` (
|
||||
`a` decimal(30,16) DEFAULT NULL,
|
||||
`b` decimal(30,16) unsigned DEFAULT NULL,
|
||||
`fa` bigint(17) DEFAULT NULL,
|
||||
`fb` bigint(16) unsigned DEFAULT NULL
|
||||
) ENGINE=MyISAM DEFAULT CHARSET=latin1
|
||||
a 99999999999999.9999999999999999
|
||||
b 99999999999999.9999999999999999
|
||||
fa 99999999999999
|
||||
fb 99999999999999
|
||||
Table t2
|
||||
Create Table CREATE TABLE `t2` (
|
||||
`a` decimal(30,17) DEFAULT NULL,
|
||||
`b` decimal(30,17) unsigned DEFAULT NULL,
|
||||
`fa` bigint(16) DEFAULT NULL,
|
||||
`fb` bigint(15) unsigned DEFAULT NULL
|
||||
) ENGINE=MyISAM DEFAULT CHARSET=latin1
|
||||
a 9999999999999.99999999999999999
|
||||
b 9999999999999.99999999999999999
|
||||
fa 9999999999999
|
||||
fb 9999999999999
|
||||
Table t2
|
||||
Create Table CREATE TABLE `t2` (
|
||||
`a` decimal(30,18) DEFAULT NULL,
|
||||
`b` decimal(30,18) unsigned DEFAULT NULL,
|
||||
`fa` bigint(15) DEFAULT NULL,
|
||||
`fb` bigint(14) unsigned DEFAULT NULL
|
||||
) ENGINE=MyISAM DEFAULT CHARSET=latin1
|
||||
a 999999999999.999999999999999999
|
||||
b 999999999999.999999999999999999
|
||||
fa 999999999999
|
||||
fb 999999999999
|
||||
Table t2
|
||||
Create Table CREATE TABLE `t2` (
|
||||
`a` decimal(30,19) DEFAULT NULL,
|
||||
`b` decimal(30,19) unsigned DEFAULT NULL,
|
||||
`fa` bigint(14) DEFAULT NULL,
|
||||
`fb` bigint(13) unsigned DEFAULT NULL
|
||||
) ENGINE=MyISAM DEFAULT CHARSET=latin1
|
||||
a 99999999999.9999999999999999999
|
||||
b 99999999999.9999999999999999999
|
||||
fa 99999999999
|
||||
fb 99999999999
|
||||
Table t2
|
||||
Create Table CREATE TABLE `t2` (
|
||||
`a` decimal(30,20) DEFAULT NULL,
|
||||
`b` decimal(30,20) unsigned DEFAULT NULL,
|
||||
`fa` bigint(13) DEFAULT NULL,
|
||||
`fb` bigint(12) unsigned DEFAULT NULL
|
||||
) ENGINE=MyISAM DEFAULT CHARSET=latin1
|
||||
a 9999999999.99999999999999999999
|
||||
b 9999999999.99999999999999999999
|
||||
fa 9999999999
|
||||
fb 9999999999
|
||||
Table t2
|
||||
Create Table CREATE TABLE `t2` (
|
||||
`a` decimal(30,21) DEFAULT NULL,
|
||||
`b` decimal(30,21) unsigned DEFAULT NULL,
|
||||
`fa` bigint(12) DEFAULT NULL,
|
||||
`fb` bigint(11) unsigned DEFAULT NULL
|
||||
) ENGINE=MyISAM DEFAULT CHARSET=latin1
|
||||
a 999999999.999999999999999999999
|
||||
b 999999999.999999999999999999999
|
||||
fa 999999999
|
||||
fb 999999999
|
||||
Table t2
|
||||
Create Table CREATE TABLE `t2` (
|
||||
`a` decimal(30,22) DEFAULT NULL,
|
||||
`b` decimal(30,22) unsigned DEFAULT NULL,
|
||||
`fa` bigint(11) DEFAULT NULL,
|
||||
`fb` bigint(10) unsigned DEFAULT NULL
|
||||
) ENGINE=MyISAM DEFAULT CHARSET=latin1
|
||||
a 99999999.9999999999999999999999
|
||||
b 99999999.9999999999999999999999
|
||||
fa 99999999
|
||||
fb 99999999
|
||||
Table t2
|
||||
Create Table CREATE TABLE `t2` (
|
||||
`a` decimal(30,23) DEFAULT NULL,
|
||||
`b` decimal(30,23) unsigned DEFAULT NULL,
|
||||
`fa` bigint(10) DEFAULT NULL,
|
||||
`fb` int(9) unsigned DEFAULT NULL
|
||||
) ENGINE=MyISAM DEFAULT CHARSET=latin1
|
||||
a 9999999.99999999999999999999999
|
||||
b 9999999.99999999999999999999999
|
||||
fa 9999999
|
||||
fb 9999999
|
||||
Table t2
|
||||
Create Table CREATE TABLE `t2` (
|
||||
`a` decimal(30,24) DEFAULT NULL,
|
||||
`b` decimal(30,24) unsigned DEFAULT NULL,
|
||||
`fa` int(9) DEFAULT NULL,
|
||||
`fb` int(8) unsigned DEFAULT NULL
|
||||
) ENGINE=MyISAM DEFAULT CHARSET=latin1
|
||||
a 999999.999999999999999999999999
|
||||
b 999999.999999999999999999999999
|
||||
fa 999999
|
||||
fb 999999
|
||||
Table t2
|
||||
Create Table CREATE TABLE `t2` (
|
||||
`a` decimal(30,25) DEFAULT NULL,
|
||||
`b` decimal(30,25) unsigned DEFAULT NULL,
|
||||
`fa` int(8) DEFAULT NULL,
|
||||
`fb` int(7) unsigned DEFAULT NULL
|
||||
) ENGINE=MyISAM DEFAULT CHARSET=latin1
|
||||
a 99999.9999999999999999999999999
|
||||
b 99999.9999999999999999999999999
|
||||
fa 99999
|
||||
fb 99999
|
||||
Table t2
|
||||
Create Table CREATE TABLE `t2` (
|
||||
`a` decimal(30,26) DEFAULT NULL,
|
||||
`b` decimal(30,26) unsigned DEFAULT NULL,
|
||||
`fa` int(7) DEFAULT NULL,
|
||||
`fb` int(6) unsigned DEFAULT NULL
|
||||
) ENGINE=MyISAM DEFAULT CHARSET=latin1
|
||||
a 9999.99999999999999999999999999
|
||||
b 9999.99999999999999999999999999
|
||||
fa 9999
|
||||
fb 9999
|
||||
Table t2
|
||||
Create Table CREATE TABLE `t2` (
|
||||
`a` decimal(30,27) DEFAULT NULL,
|
||||
`b` decimal(30,27) unsigned DEFAULT NULL,
|
||||
`fa` int(6) DEFAULT NULL,
|
||||
`fb` int(5) unsigned DEFAULT NULL
|
||||
) ENGINE=MyISAM DEFAULT CHARSET=latin1
|
||||
a 999.999999999999999999999999999
|
||||
b 999.999999999999999999999999999
|
||||
fa 999
|
||||
fb 999
|
||||
Table t2
|
||||
Create Table CREATE TABLE `t2` (
|
||||
`a` decimal(30,28) DEFAULT NULL,
|
||||
`b` decimal(30,28) unsigned DEFAULT NULL,
|
||||
`fa` int(5) DEFAULT NULL,
|
||||
`fb` int(4) unsigned DEFAULT NULL
|
||||
) ENGINE=MyISAM DEFAULT CHARSET=latin1
|
||||
a 99.9999999999999999999999999999
|
||||
b 99.9999999999999999999999999999
|
||||
fa 99
|
||||
fb 99
|
||||
Table t2
|
||||
Create Table CREATE TABLE `t2` (
|
||||
`a` decimal(30,29) DEFAULT NULL,
|
||||
`b` decimal(30,29) unsigned DEFAULT NULL,
|
||||
`fa` int(4) DEFAULT NULL,
|
||||
`fb` int(3) unsigned DEFAULT NULL
|
||||
) ENGINE=MyISAM DEFAULT CHARSET=latin1
|
||||
a 9.99999999999999999999999999999
|
||||
b 9.99999999999999999999999999999
|
||||
fa 9
|
||||
fb 9
|
||||
DROP PROCEDURE p2;
|
||||
DROP PROCEDURE p1;
|
||||
#
|
||||
# End of 10.1 tests
|
||||
#
|
||||
#
|
||||
|
@ -1466,7 +2202,7 @@ SET @val = 'a';
|
|||
EXECUTE stmt1 USING @val;
|
||||
CRC32(?)
|
||||
3904355907
|
||||
DEALLOCATE PREPARE stmt;
|
||||
DEALLOCATE PREPARE stmt1;
|
||||
SET NAMES utf8;
|
||||
CREATE TABLE t1 (a TEXT) CHARACTER SET = utf8;
|
||||
LOAD DATA INFILE '../../std_data/loaddata_utf8.dat' INTO TABLE t1 CHARACTER SET utf8;
|
||||
|
|
|
@ -715,6 +715,65 @@ SELECT 9223372036854775808 MOD -9223372036854775808;
|
|||
SELECT -9223372036854775808 MOD 9223372036854775808;
|
||||
SELECT -9223372036854775808 MOD -9223372036854775808;
|
||||
|
||||
--echo #
|
||||
--echo # MDEV-22502 MDB crashes in CREATE TABLE AS SELECT when the precision of returning type = 0
|
||||
--echo #
|
||||
|
||||
CREATE TABLE t1 (d decimal(5,5));
|
||||
INSERT INTO t1 VALUES (0.55555);
|
||||
SELECT TRUNCATE(d,0) FROM t1;
|
||||
CREATE TABLE t2 AS SELECT TRUNCATE(d,0) FROM t1;
|
||||
SELECT * FROM t2;
|
||||
SHOW CREATE TABLE t2;
|
||||
DROP TABLE t1, t2;
|
||||
|
||||
|
||||
--echo #
|
||||
--echo # MDEV-22503 MDB limits DECIMAL column precision to 16 doing CTAS with floor/ceil over DECIMAL(X,Y) where X > 16
|
||||
--echo #
|
||||
|
||||
CREATE TABLE t44 (d1 decimal(38,0) DEFAULT NULL);
|
||||
INSERT INTO t44 VALUES (12345678901234567890123456789012345678);
|
||||
SELECT FLOOR(d1) FROM t44;
|
||||
CREATE TABLE t45 AS SELECT FLOOR(d1) FROM t44;
|
||||
SELECT * FROM t45;
|
||||
SHOW CREATE TABLE t45;
|
||||
DROP TABLE t44, t45;
|
||||
|
||||
|
||||
DELIMITER $$;
|
||||
CREATE PROCEDURE p1(prec INT, scale INT)
|
||||
BEGIN
|
||||
DECLARE maxval VARCHAR(128) DEFAULT '';
|
||||
SET @type= CONCAT('DECIMAL(', prec, ',', scale,')');
|
||||
SET @stmt= CONCAT('CREATE TABLE t1 (a ', @type, ',b ', @type, 'unsigned)');
|
||||
PREPARE stmt FROM @stmt;
|
||||
EXECUTE stmt;
|
||||
DEALLOCATE PREPARE stmt;
|
||||
SET maxval= CONCAT(REPEAT('9', prec-scale), '.', REPEAT('9',scale));
|
||||
INSERT INTO t1 VALUES (maxval, maxval);
|
||||
CREATE TABLE t2 AS SELECT a, b, FLOOR(a) AS fa, FLOOR(b) AS fb FROM t1;
|
||||
SHOW CREATE TABLE t2;
|
||||
SELECT * FROM t2;
|
||||
DROP TABLE t1, t2;
|
||||
END;
|
||||
$$
|
||||
CREATE PROCEDURE p2(prec INT)
|
||||
BEGIN
|
||||
DECLARE scale INT DEFAULT 0;
|
||||
WHILE scale < prec AND scale <= 30 DO
|
||||
CALL p1(prec, scale);
|
||||
SET scale= scale + 1;
|
||||
END WHILE;
|
||||
END;
|
||||
$$
|
||||
DELIMITER ;$$
|
||||
--vertical_results
|
||||
CALL p2(38);
|
||||
CALL p2(30);
|
||||
--horizontal_results
|
||||
DROP PROCEDURE p2;
|
||||
DROP PROCEDURE p1;
|
||||
|
||||
|
||||
--echo #
|
||||
|
@ -1013,7 +1072,7 @@ DROP FUNCTION crc32_func;
|
|||
PREPARE stmt1 FROM 'SELECT CRC32(?)';
|
||||
SET @val = 'a';
|
||||
EXECUTE stmt1 USING @val;
|
||||
DEALLOCATE PREPARE stmt;
|
||||
DEALLOCATE PREPARE stmt1;
|
||||
|
||||
# Test case for checksum on contents of a file
|
||||
SET NAMES utf8;
|
||||
|
|
|
@ -2535,6 +2535,38 @@ c1
|
|||
1
|
||||
drop table t1;
|
||||
#
|
||||
# MDEV-22498: SIGSEGV in Bitmap<64u>::merge on SELECT
|
||||
#
|
||||
set @save_sql_select_limit= @@sql_select_limit;
|
||||
SET sql_select_limit=0;
|
||||
CREATE TABLE t1(b INT, c INT);
|
||||
CREATE TABLE t2(a INT, b INT);
|
||||
INSERT INTO t1 VALUES (1,1),(2,2),(3,3);
|
||||
INSERT INTO t2 VALUES (1,1),(2,2),(3,3);
|
||||
EXPLAIN EXTENDED SELECT sum(a), t2.a, t2.b FROM t2 HAVING t2.a IN (SELECT t2.b FROM t1);
|
||||
id select_type table type possible_keys key key_len ref rows filtered Extra
|
||||
1 PRIMARY NULL NULL NULL NULL NULL NULL NULL NULL Zero limit
|
||||
2 DEPENDENT SUBQUERY t1 ALL NULL NULL NULL NULL 3 100.00
|
||||
Warnings:
|
||||
Note 1276 Field or reference 'test.t2.b' of SELECT #2 was resolved in SELECT #1
|
||||
Note 1276 Field or reference 'test.t2.b' of SELECT #2 was resolved in SELECT #1
|
||||
Note 1003 /* select#1 */ select sum(`test`.`t2`.`a`) AS `sum(a)`,`test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b` from `test`.`t2` having <in_optimizer>(`test`.`t2`.`a`,<exists>(/* select#2 */ select `test`.`t2`.`b` from `test`.`t1` where <cache>(`test`.`t2`.`a`) = `test`.`t2`.`b`))
|
||||
SELECT sum(a), t2.a, t2.b FROM t2 HAVING t2.a IN (SELECT t2.b FROM t1);
|
||||
sum(a) a b
|
||||
SET @@sql_select_limit= @save_sql_select_limit;
|
||||
EXPLAIN EXTENDED SELECT sum(a), t2.a, t2.b FROM t2 HAVING t2.a IN (SELECT t2.b FROM t1);
|
||||
id select_type table type possible_keys key key_len ref rows filtered Extra
|
||||
1 PRIMARY t2 ALL NULL NULL NULL NULL 3 100.00
|
||||
2 DEPENDENT SUBQUERY t1 ALL NULL NULL NULL NULL 3 100.00
|
||||
Warnings:
|
||||
Note 1276 Field or reference 'test.t2.b' of SELECT #2 was resolved in SELECT #1
|
||||
Note 1276 Field or reference 'test.t2.b' of SELECT #2 was resolved in SELECT #1
|
||||
Note 1003 /* select#1 */ select sum(`test`.`t2`.`a`) AS `sum(a)`,`test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b` from `test`.`t2` having <expr_cache><`test`.`t2`.`a`,`test`.`t2`.`b`>(<in_optimizer>(`test`.`t2`.`a`,<exists>(/* select#2 */ select `test`.`t2`.`b` from `test`.`t1` where <cache>(`test`.`t2`.`a`) = `test`.`t2`.`b`)))
|
||||
SELECT sum(a), t2.a, t2.b FROM t2 HAVING t2.a IN (SELECT t2.b FROM t1);
|
||||
sum(a) a b
|
||||
6 1 1
|
||||
DROP TABLE t1,t2;
|
||||
#
|
||||
# MDEV-19134: EXISTS() slower if ORDER BY is defined
|
||||
#
|
||||
create table t0 (a int);
|
||||
|
@ -2582,3 +2614,4 @@ id select_type table type possible_keys key key_len ref rows Extra
|
|||
1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 4 func 1
|
||||
2 MATERIALIZED t2 ALL NULL NULL NULL NULL 100
|
||||
drop table t0, t1, t2;
|
||||
# End of 10.4 tests
|
||||
|
|
|
@ -2078,6 +2078,30 @@ select (select c1 from t1 group by c1,c2 order by c1 limit 1) as x;
|
|||
(select c1 from t1 group by c1,c2 order by c1 limit 1);
|
||||
drop table t1;
|
||||
|
||||
--echo #
|
||||
--echo # MDEV-22498: SIGSEGV in Bitmap<64u>::merge on SELECT
|
||||
--echo #
|
||||
|
||||
set @save_sql_select_limit= @@sql_select_limit;
|
||||
SET sql_select_limit=0;
|
||||
|
||||
CREATE TABLE t1(b INT, c INT);
|
||||
CREATE TABLE t2(a INT, b INT);
|
||||
INSERT INTO t1 VALUES (1,1),(2,2),(3,3);
|
||||
INSERT INTO t2 VALUES (1,1),(2,2),(3,3);
|
||||
|
||||
let $query=
|
||||
SELECT sum(a), t2.a, t2.b FROM t2 HAVING t2.a IN (SELECT t2.b FROM t1);
|
||||
|
||||
eval EXPLAIN EXTENDED $query;
|
||||
eval $query;
|
||||
|
||||
SET @@sql_select_limit= @save_sql_select_limit;
|
||||
|
||||
eval EXPLAIN EXTENDED $query;
|
||||
eval $query;
|
||||
DROP TABLE t1,t2;
|
||||
|
||||
--echo #
|
||||
--echo # MDEV-19134: EXISTS() slower if ORDER BY is defined
|
||||
--echo #
|
||||
|
@ -2118,3 +2142,4 @@ select * from t1 where t1.a in (select t2.a from t2 order by t2.b);
|
|||
|
||||
drop table t0, t1, t2;
|
||||
|
||||
--echo # End of 10.4 tests
|
||||
|
|
|
@ -2599,3 +2599,14 @@ a
|
|||
2
|
||||
1
|
||||
drop view v1;
|
||||
#
|
||||
# MDEV-22560 Crash on a table value constructor with an SP variable
|
||||
#
|
||||
BEGIN NOT ATOMIC
|
||||
DECLARE a INT DEFAULT 0;
|
||||
VALUES (a) UNION SELECT 1;
|
||||
END;
|
||||
$$
|
||||
a
|
||||
0
|
||||
1
|
||||
|
|
|
@ -1326,3 +1326,16 @@ create view v1 as with t(a) as (values (2), (1)) select a from t;
|
|||
show create view v1;
|
||||
select * from v1;
|
||||
drop view v1;
|
||||
|
||||
|
||||
--echo #
|
||||
--echo # MDEV-22560 Crash on a table value constructor with an SP variable
|
||||
--echo #
|
||||
|
||||
DELIMITER $$;
|
||||
BEGIN NOT ATOMIC
|
||||
DECLARE a INT DEFAULT 0;
|
||||
VALUES (a) UNION SELECT 1;
|
||||
END;
|
||||
$$
|
||||
DELIMITER ;$$
|
||||
|
|
|
@ -30,9 +30,9 @@ lookup("127.0.0.1")
|
|||
127.0.0.1
|
||||
select lookup(127,0,0,1);
|
||||
ERROR HY000: Can't initialize function 'lookup'; Wrong arguments to lookup; Use the source
|
||||
select lookup("localhost");
|
||||
lookup("localhost")
|
||||
127.0.0.1
|
||||
select lookup("localhost") rlike '^127\.\\d+\.\\d+.\\d+$';
|
||||
lookup("localhost") rlike '^127\.\\d+\.\\d+.\\d+$'
|
||||
1
|
||||
select reverse_lookup();
|
||||
ERROR HY000: Can't initialize function 'reverse_lookup'; Wrong number of arguments to reverse_lookup; Use the source
|
||||
select reverse_lookup("127.0.0.1");
|
||||
|
|
|
@ -47,7 +47,7 @@ select lookup();
|
|||
select lookup("127.0.0.1");
|
||||
--error ER_CANT_INITIALIZE_UDF
|
||||
select lookup(127,0,0,1);
|
||||
select lookup("localhost");
|
||||
select lookup("localhost") rlike '^127\.\\d+\.\\d+.\\d+$';
|
||||
--error ER_CANT_INITIALIZE_UDF
|
||||
select reverse_lookup();
|
||||
|
||||
|
|
18
mysql-test/suite/encryption/r/tempfiles_encrypted.result
Normal file
18
mysql-test/suite/encryption/r/tempfiles_encrypted.result
Normal file
|
@ -0,0 +1,18 @@
|
|||
#
|
||||
# Tests when the temporary files are encrypted
|
||||
#
|
||||
select @@encrypt_tmp_files;
|
||||
@@encrypt_tmp_files
|
||||
1
|
||||
#
|
||||
# MDEV-22556: Incorrect result for window function when using encrypt-tmp-files=ON
|
||||
#
|
||||
set @save_sort_buffer_size=@@sort_buffer_size;
|
||||
set sort_buffer_size= 2000;
|
||||
create table t1( a DECIMAL(12,0) DEFAULT NULL, b VARCHAR(20) DEFAULT NULL, c DECIMAL(12,0) DEFAULT NULL)engine=INNODB;
|
||||
insert into t1 select seq, seq, seq from seq_1_to_5000;
|
||||
select count(*) from (select a, b, c, ROW_NUMBER() OVER (PARTITION BY a) FROM t1)q;
|
||||
count(*)
|
||||
5000
|
||||
set @@sort_buffer_size=@save_sort_buffer_size;
|
||||
drop table t1;
|
|
@ -1,6 +1,8 @@
|
|||
-- source include/have_innodb.inc
|
||||
-- source include/have_example_key_management_plugin.inc
|
||||
-- source include/not_embedded.inc
|
||||
# We can't run this test under valgrind as it 'takes forever'
|
||||
-- source include/not_valgrind.inc
|
||||
|
||||
create table innodb_normal(c1 bigint not null, b char(200)) engine=innodb;
|
||||
create table innodb_compact(c1 bigint not null, b char(200)) engine=innodb row_format=compact;
|
||||
|
|
1
mysql-test/suite/encryption/t/tempfiles_encrypted.opt
Normal file
1
mysql-test/suite/encryption/t/tempfiles_encrypted.opt
Normal file
|
@ -0,0 +1 @@
|
|||
--encrypt-tmp_files=ON
|
23
mysql-test/suite/encryption/t/tempfiles_encrypted.test
Normal file
23
mysql-test/suite/encryption/t/tempfiles_encrypted.test
Normal file
|
@ -0,0 +1,23 @@
|
|||
--echo #
|
||||
--echo # Tests when the temporary files are encrypted
|
||||
--echo #
|
||||
|
||||
source include/have_file_key_management_plugin.inc;
|
||||
source include/have_sequence.inc;
|
||||
source include/have_innodb.inc;
|
||||
|
||||
select @@encrypt_tmp_files;
|
||||
|
||||
--echo #
|
||||
--echo # MDEV-22556: Incorrect result for window function when using encrypt-tmp-files=ON
|
||||
--echo #
|
||||
|
||||
set @save_sort_buffer_size=@@sort_buffer_size;
|
||||
set sort_buffer_size= 2000;
|
||||
create table t1( a DECIMAL(12,0) DEFAULT NULL, b VARCHAR(20) DEFAULT NULL, c DECIMAL(12,0) DEFAULT NULL)engine=INNODB;
|
||||
insert into t1 select seq, seq, seq from seq_1_to_5000;
|
||||
select count(*) from (select a, b, c, ROW_NUMBER() OVER (PARTITION BY a) FROM t1)q;
|
||||
|
||||
set @@sort_buffer_size=@save_sort_buffer_size;
|
||||
|
||||
drop table t1;
|
|
@ -15,8 +15,6 @@ GCF-939 : MDEV-21520 galera.GCF-939
|
|||
MDEV-16509 : MDEV-21523 galera.MDEV-16509
|
||||
MDEV-20225 : MDEV-20886 galera.MDEV-20225
|
||||
MW-286 : MDEV-18464 Killing thread can cause mutex deadlock if done concurrently with Galera/replication victim kill
|
||||
MW-328A : MDEV-21483 galera.MW-328A galera.MW-328B
|
||||
MW-328B : MDEV-21483 galera.MW-328A galera.MW-328B
|
||||
MW-329 : MDEV-19962 Galera test failure on MW-329
|
||||
galera.galera_defaults : MDEV-21494 Galera test sporadic failure on galera.galera_defaults
|
||||
galera_as_slave_replication_bundle : MDEV-15785 OPTION_GTID_BEGIN is set in Gtid_log_event::do_apply_event()
|
||||
|
|
25
mysql-test/suite/galera/r/MW-328C.result
Normal file
25
mysql-test/suite/galera/r/MW-328C.result
Normal file
|
@ -0,0 +1,25 @@
|
|||
connection node_2;
|
||||
connection node_1;
|
||||
CREATE TABLE t1 (f1 INTEGER AUTO_INCREMENT PRIMARY KEY, f2 CHAR(20) DEFAULT 'abc') ENGINE=InnoDB;
|
||||
INSERT INTO t1 (f1) VALUES (1);
|
||||
CREATE TABLE t2 (f1 CHAR(20)) ENGINE=InnoDB;
|
||||
CREATE PROCEDURE proc_update ()
|
||||
BEGIN
|
||||
DECLARE CONTINUE HANDLER FOR SQLEXCEPTION BEGIN END;
|
||||
SET SESSION wsrep_sync_wait = 0;
|
||||
WHILE 1 DO
|
||||
UPDATE t1 SET f2 = LEFT(MD5(RAND()), 4);
|
||||
END WHILE;
|
||||
END|
|
||||
connect node_1X, 127.0.0.1, root, , test, $NODE_MYPORT_1;
|
||||
connection node_1X;
|
||||
CALL proc_update();;
|
||||
connection node_2;
|
||||
SET SESSION wsrep_retry_autocommit = 10000;
|
||||
connection node_1;
|
||||
connection node_1X;
|
||||
Got one of the listed errors
|
||||
connection node_1;
|
||||
DROP PROCEDURE proc_update;
|
||||
DROP TABLE t1, t2;
|
||||
CALL mtr.add_suppression("conflict state ABORTED after post commit");
|
|
@ -1,7 +1,7 @@
|
|||
!include ../galera_2nodes.cnf
|
||||
|
||||
[mysqld.1]
|
||||
wsrep-debug=ON
|
||||
wsrep-debug=SERVER
|
||||
|
||||
[mysqld.2]
|
||||
wsrep-debug=ON
|
||||
wsrep-debug=SERVER
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
!include ../galera_2nodes.cnf
|
||||
|
||||
[mysqld.1]
|
||||
wsrep-debug=ON
|
||||
wsrep-debug=SERVER
|
||||
|
||||
[mysqld.2]
|
||||
wsrep-debug=ON
|
||||
wsrep-debug=SERVER
|
||||
|
|
7
mysql-test/suite/galera/t/MW-328C.cnf
Normal file
7
mysql-test/suite/galera/t/MW-328C.cnf
Normal file
|
@ -0,0 +1,7 @@
|
|||
!include ../galera_2nodes.cnf
|
||||
|
||||
[mysqld.1]
|
||||
wsrep-debug=SERVER
|
||||
|
||||
[mysqld.2]
|
||||
wsrep-debug=SERVER
|
35
mysql-test/suite/galera/t/MW-328C.test
Normal file
35
mysql-test/suite/galera/t/MW-328C.test
Normal file
|
@ -0,0 +1,35 @@
|
|||
#
|
||||
# MW-328 Fix unnecessary/silent BF aborts
|
||||
#
|
||||
|
||||
#
|
||||
# Make sure that a high value of wsrep_retry_autocommit
|
||||
# masks all deadlock errors
|
||||
#
|
||||
|
||||
--source include/galera_cluster.inc
|
||||
--source suite/galera/t/MW-328-header.inc
|
||||
|
||||
--connection node_2
|
||||
--let $count = 100
|
||||
|
||||
SET SESSION wsrep_retry_autocommit = 10000;
|
||||
|
||||
--disable_query_log
|
||||
|
||||
while ($count)
|
||||
{
|
||||
--error 0
|
||||
INSERT IGNORE INTO t2 SELECT f2 FROM t1;
|
||||
|
||||
--disable_result_log
|
||||
--error 0
|
||||
SELECT 1 FROM DUAL;
|
||||
--enable_result_log
|
||||
|
||||
--dec $count
|
||||
}
|
||||
|
||||
--enable_query_log
|
||||
|
||||
--source suite/galera/t/MW-328-footer.inc
|
7
mysql-test/suite/galera/t/MW-328D.cnf
Normal file
7
mysql-test/suite/galera/t/MW-328D.cnf
Normal file
|
@ -0,0 +1,7 @@
|
|||
!include ../galera_2nodes.cnf
|
||||
|
||||
[mysqld.1]
|
||||
wsrep-debug=SERVER
|
||||
|
||||
[mysqld.2]
|
||||
wsrep-debug=SERVER
|
7
mysql-test/suite/galera/t/MW-328E.cnf
Normal file
7
mysql-test/suite/galera/t/MW-328E.cnf
Normal file
|
@ -0,0 +1,7 @@
|
|||
!include ../galera_2nodes.cnf
|
||||
|
||||
[mysqld.1]
|
||||
wsrep-debug=SERVER
|
||||
|
||||
[mysqld.2]
|
||||
wsrep-debug=SERVER
|
|
@ -1,26 +1,16 @@
|
|||
CREATE PROCEDURE populate_t1()
|
||||
BEGIN
|
||||
DECLARE i int DEFAULT 1;
|
||||
START TRANSACTION;
|
||||
WHILE (i <= 1000000) DO
|
||||
INSERT INTO t1 VALUES (i, i, CONCAT('a', i));
|
||||
SET i = i + 1;
|
||||
END WHILE;
|
||||
COMMIT;
|
||||
END|
|
||||
set use_stat_tables='preferably';
|
||||
CREATE TABLE t1(
|
||||
class INT,
|
||||
id INT,
|
||||
title VARCHAR(100)
|
||||
) ENGINE=InnoDB;
|
||||
insert into t1 select seq, seq, concat('a', seq) from seq_1_to_500;
|
||||
SELECT COUNT(*) FROM t1;
|
||||
COUNT(*)
|
||||
1000000
|
||||
SET GLOBAL innodb_stats_persistent_sample_pages=2000;
|
||||
500
|
||||
set @@max_heap_table_size=16384;
|
||||
ANALYZE TABLE t1;
|
||||
Table Op Msg_type Msg_text
|
||||
test.t1 analyze status Engine-independent statistics collected
|
||||
test.t1 analyze status OK
|
||||
DROP TABLE t1;
|
||||
DROP PROCEDURE populate_t1;
|
||||
SET GLOBAL innodb_stats_persistent_sample_pages=default;
|
||||
|
|
|
@ -1,23 +1,11 @@
|
|||
#
|
||||
# BUG#22385442 - INNODB: DIFFICULT TO FIND FREE BLOCKS IN THE BUFFER POOL
|
||||
#
|
||||
|
||||
--source include/have_innodb.inc
|
||||
--source include/big_test.inc
|
||||
--source include/have_sequence.inc
|
||||
|
||||
DELIMITER |;
|
||||
CREATE PROCEDURE populate_t1()
|
||||
BEGIN
|
||||
DECLARE i int DEFAULT 1;
|
||||
#
|
||||
# MDEV-22073 MSAN use-of-uninitialized-value in collect_statistics_for_table()
|
||||
#
|
||||
|
||||
START TRANSACTION;
|
||||
WHILE (i <= 1000000) DO
|
||||
INSERT INTO t1 VALUES (i, i, CONCAT('a', i));
|
||||
SET i = i + 1;
|
||||
END WHILE;
|
||||
COMMIT;
|
||||
END|
|
||||
DELIMITER ;|
|
||||
set use_stat_tables='preferably';
|
||||
|
||||
CREATE TABLE t1(
|
||||
class INT,
|
||||
|
@ -25,18 +13,11 @@ CREATE TABLE t1(
|
|||
title VARCHAR(100)
|
||||
) ENGINE=InnoDB;
|
||||
|
||||
-- disable_query_log
|
||||
CALL populate_t1();
|
||||
-- enable_query_log
|
||||
insert into t1 select seq, seq, concat('a', seq) from seq_1_to_500;
|
||||
|
||||
SELECT COUNT(*) FROM t1;
|
||||
|
||||
SET GLOBAL innodb_stats_persistent_sample_pages=2000;
|
||||
|
||||
set @@max_heap_table_size=16384;
|
||||
ANALYZE TABLE t1;
|
||||
|
||||
DROP TABLE t1;
|
||||
|
||||
DROP PROCEDURE populate_t1;
|
||||
|
||||
SET GLOBAL innodb_stats_persistent_sample_pages=default;
|
||||
|
|
|
@ -4,6 +4,10 @@
|
|||
# Embedded server does not support restarting
|
||||
--source include/not_embedded.inc
|
||||
|
||||
--disable_query_log
|
||||
FLUSH TABLES;
|
||||
--enable_query_log
|
||||
|
||||
--echo #
|
||||
--echo # Bug#20872655 XA ROLLBACK IS NOT CRASH-SAFE
|
||||
--echo #
|
||||
|
|
|
@ -861,6 +861,17 @@ SELECT * FROM t1;
|
|||
DROP TABLE t1;
|
||||
}
|
||||
|
||||
if (!$skip_update)
|
||||
{
|
||||
--echo #
|
||||
--echo # MDEV-19622 Assertion failures in
|
||||
--echo # ha_partition::set_auto_increment_if_higher upon UPDATE on Aria table
|
||||
--echo #
|
||||
CREATE OR REPLACE TABLE t1 (pk INT AUTO_INCREMENT, a INT, KEY(pk)) ENGINE=myisam PARTITION BY HASH(a);
|
||||
INSERT INTO t1 VALUES (1,1),(2,2);
|
||||
UPDATE t1 SET pk = 0;
|
||||
DROP TABLE t1;
|
||||
}
|
||||
|
||||
--echo ##############################################################################
|
||||
}
|
||||
|
|
|
@ -1101,4 +1101,12 @@ SELECT * FROM t1;
|
|||
a
|
||||
0
|
||||
DROP TABLE t1;
|
||||
#
|
||||
# MDEV-19622 Assertion failures in
|
||||
# ha_partition::set_auto_increment_if_higher upon UPDATE on Aria table
|
||||
#
|
||||
CREATE OR REPLACE TABLE t1 (pk INT AUTO_INCREMENT, a INT, KEY(pk)) ENGINE=myisam PARTITION BY HASH(a);
|
||||
INSERT INTO t1 VALUES (1,1),(2,2);
|
||||
UPDATE t1 SET pk = 0;
|
||||
DROP TABLE t1;
|
||||
##############################################################################
|
||||
|
|
|
@ -1148,4 +1148,12 @@ SELECT * FROM t1;
|
|||
a
|
||||
0
|
||||
DROP TABLE t1;
|
||||
#
|
||||
# MDEV-19622 Assertion failures in
|
||||
# ha_partition::set_auto_increment_if_higher upon UPDATE on Aria table
|
||||
#
|
||||
CREATE OR REPLACE TABLE t1 (pk INT AUTO_INCREMENT, a INT, KEY(pk)) ENGINE=myisam PARTITION BY HASH(a);
|
||||
INSERT INTO t1 VALUES (1,1),(2,2);
|
||||
UPDATE t1 SET pk = 0;
|
||||
DROP TABLE t1;
|
||||
##############################################################################
|
||||
|
|
|
@ -1129,4 +1129,12 @@ SELECT * FROM t1;
|
|||
a
|
||||
0
|
||||
DROP TABLE t1;
|
||||
#
|
||||
# MDEV-19622 Assertion failures in
|
||||
# ha_partition::set_auto_increment_if_higher upon UPDATE on Aria table
|
||||
#
|
||||
CREATE OR REPLACE TABLE t1 (pk INT AUTO_INCREMENT, a INT, KEY(pk)) ENGINE=myisam PARTITION BY HASH(a);
|
||||
INSERT INTO t1 VALUES (1,1),(2,2);
|
||||
UPDATE t1 SET pk = 0;
|
||||
DROP TABLE t1;
|
||||
##############################################################################
|
||||
|
|
|
@ -1148,4 +1148,12 @@ SELECT * FROM t1;
|
|||
a
|
||||
0
|
||||
DROP TABLE t1;
|
||||
#
|
||||
# MDEV-19622 Assertion failures in
|
||||
# ha_partition::set_auto_increment_if_higher upon UPDATE on Aria table
|
||||
#
|
||||
CREATE OR REPLACE TABLE t1 (pk INT AUTO_INCREMENT, a INT, KEY(pk)) ENGINE=myisam PARTITION BY HASH(a);
|
||||
INSERT INTO t1 VALUES (1,1),(2,2);
|
||||
UPDATE t1 SET pk = 0;
|
||||
DROP TABLE t1;
|
||||
##############################################################################
|
||||
|
|
|
@ -1,32 +0,0 @@
|
|||
include/master-slave.inc
|
||||
[connection master]
|
||||
create table t1 (a int) engine=innodb;
|
||||
create table t2 (b longblob) engine=innodb;
|
||||
create table t3 (c int) engine=innodb;
|
||||
insert into t2 values (repeat('b',1024*1024));
|
||||
insert into t2 select * from t2;
|
||||
insert into t2 select * from t2;
|
||||
insert into t2 select * from t2;
|
||||
insert into t2 select * from t2;
|
||||
set debug_sync='rm_table_no_locks_before_delete_table SIGNAL nogo WAIT_FOR go EXECUTE 2';
|
||||
drop table t1, t2, t3;
|
||||
connect foo,localhost,root;
|
||||
set debug_sync='now SIGNAL go';
|
||||
kill query CONNECTION_ID;
|
||||
connection master;
|
||||
ERROR 70100: Query execution was interrupted
|
||||
"Tables t2 and t3 should be listed"
|
||||
SHOW TABLES;
|
||||
Tables_in_test
|
||||
t2
|
||||
t3
|
||||
include/show_binlog_events.inc
|
||||
Log_name Pos Event_type Server_id End_log_pos Info
|
||||
master-bin.000001 # Gtid # # GTID #-#-#
|
||||
master-bin.000001 # Query # # use `test`; DROP TABLE `t1` /* generated by server */
|
||||
connection slave;
|
||||
drop table t2, t3;
|
||||
connection master;
|
||||
set debug_sync='RESET';
|
||||
drop table t2, t3;
|
||||
include/rpl_end.inc
|
|
@ -1,69 +0,0 @@
|
|||
# ==== Purpose ====
|
||||
#
|
||||
# Check that when the execution of a DROP TABLE command with single table
|
||||
# fails it should not be written to the binary log. Also test that when the
|
||||
# execution of DROP TABLE command with multiple tables fails the command
|
||||
# should be written into the binary log.
|
||||
#
|
||||
# ==== Implementation ====
|
||||
#
|
||||
# Steps:
|
||||
# 0 - Create tables named t1, t2, t3
|
||||
# 1 - Execute DROP TABLE t1,t2,t3 command.
|
||||
# 2 - Kill the DROP TABLE command while it is trying to drop table 't2'.
|
||||
# 3 - Verify that tables t2,t3 are present after the DROP command execution
|
||||
# was interrupted.
|
||||
# 4 - Check that table 't1' is present in binary log as part of DROP
|
||||
# command.
|
||||
#
|
||||
# ==== References ====
|
||||
#
|
||||
# MDEV-20348: DROP TABLE IF EXISTS killed on master but was replicated.
|
||||
#
|
||||
|
||||
--source include/have_innodb.inc
|
||||
--source include/have_debug_sync.inc
|
||||
--source include/have_binlog_format_statement.inc
|
||||
--source include/master-slave.inc
|
||||
|
||||
if (!`select @@GLOBAL.innodb_adaptive_hash_index`)
|
||||
{
|
||||
--skip Need innodb_adaptive_hash_index
|
||||
}
|
||||
|
||||
create table t1 (a int) engine=innodb;
|
||||
create table t2 (b longblob) engine=innodb;
|
||||
create table t3 (c int) engine=innodb;
|
||||
insert into t2 values (repeat('b',1024*1024));
|
||||
insert into t2 select * from t2;
|
||||
insert into t2 select * from t2;
|
||||
insert into t2 select * from t2;
|
||||
insert into t2 select * from t2;
|
||||
let $binlog_start= query_get_value(SHOW MASTER STATUS, Position, 1);
|
||||
|
||||
let $id=`select connection_id()`;
|
||||
set debug_sync='rm_table_no_locks_before_delete_table SIGNAL nogo WAIT_FOR go EXECUTE 2';
|
||||
send drop table t1, t2, t3;
|
||||
|
||||
connect foo,localhost,root;
|
||||
set debug_sync='now SIGNAL go';
|
||||
let $wait_condition=select 1 from information_schema.processlist where state like 'debug sync point:%';
|
||||
source include/wait_condition.inc;
|
||||
--replace_result $id CONNECTION_ID
|
||||
eval kill query $id;
|
||||
|
||||
connection master;
|
||||
error ER_QUERY_INTERRUPTED;
|
||||
reap;
|
||||
|
||||
--echo "Tables t2 and t3 should be listed"
|
||||
SHOW TABLES;
|
||||
--source include/show_binlog_events.inc
|
||||
--sync_slave_with_master
|
||||
drop table t2, t3;
|
||||
|
||||
connection master;
|
||||
set debug_sync='RESET';
|
||||
drop table t2, t3;
|
||||
|
||||
source include/rpl_end.inc;
|
|
@ -427,6 +427,26 @@ aaa
|
|||
Warnings:
|
||||
Warning 1918 Encountered illegal value '\xF0\xF1\xF2\xF3\xF4\xF5\xF6\xF7' when converting to DOUBLE
|
||||
#
|
||||
# MDEV-22579 No error when inserting DEFAULT(non_virtual_column) into a virtual column
|
||||
#
|
||||
SET sql_mode=STRICT_ALL_TABLES;
|
||||
CREATE OR REPLACE TABLE t1 (
|
||||
a INT NOT NULL DEFAULT 10,
|
||||
b INT AS (a+1) VIRTUAL
|
||||
) ENGINE=MyISAM;
|
||||
INSERT INTO t1 (b) VALUES (10);
|
||||
ERROR HY000: The value specified for generated column 'b' in table 't1' has been ignored
|
||||
INSERT INTO t1 (b) VALUES (DEFAULT(a));
|
||||
ERROR HY000: The value specified for generated column 'b' in table 't1' has been ignored
|
||||
INSERT INTO t1 (b) VALUES (DEFAULT);
|
||||
INSERT INTO t1 VALUES (10,10);
|
||||
ERROR HY000: The value specified for generated column 'b' in table 't1' has been ignored
|
||||
INSERT INTO t1 VALUES (10,DEFAULT(a));
|
||||
ERROR HY000: The value specified for generated column 'b' in table 't1' has been ignored
|
||||
INSERT INTO t1 VALUES (10, DEFAULT);
|
||||
DROP TABLE t1;
|
||||
SET sql_mode=DEFAULT;
|
||||
#
|
||||
# End of 10.1 tests
|
||||
#
|
||||
#
|
||||
|
@ -481,5 +501,37 @@ Warning 1264 Out of range value for column 'vi' at row 1
|
|||
DROP TABLE t1;
|
||||
SET @sql_mode=@old_sql_mode;
|
||||
#
|
||||
# MDEV-22579 No error when inserting DEFAULT(non_virtual_column) into a virtual column
|
||||
# 10.2+ specific part
|
||||
#
|
||||
SET sql_mode=STRICT_ALL_TABLES;
|
||||
CREATE OR REPLACE TABLE t1 (
|
||||
a INT NOT NULL DEFAULT 10,
|
||||
b INT AS (a+1) VIRTUAL
|
||||
) ENGINE=MyISAM;
|
||||
EXECUTE IMMEDIATE 'INSERT INTO t1 (b) VALUES(?)' USING DEFAULT;
|
||||
EXECUTE IMMEDIATE 'INSERT INTO t1 (b) VALUES(?)' USING IGNORE;
|
||||
INSERT INTO t1 (b) VALUES (DEFAULT);
|
||||
INSERT INTO t1 (b) VALUES (IGNORE);
|
||||
SELECT * FROM t1;
|
||||
a b
|
||||
10 11
|
||||
10 11
|
||||
10 11
|
||||
10 11
|
||||
DELETE FROM t1;
|
||||
EXECUTE IMMEDIATE 'INSERT INTO t1 VALUES(10,?)' USING DEFAULT;
|
||||
EXECUTE IMMEDIATE 'INSERT INTO t1 VALUES(11,?)' USING IGNORE;
|
||||
INSERT INTO t1 VALUES (12,DEFAULT);
|
||||
INSERT INTO t1 VALUES (13,IGNORE);
|
||||
SELECT * FROM t1;
|
||||
a b
|
||||
10 11
|
||||
11 12
|
||||
12 13
|
||||
13 14
|
||||
DROP TABLE t1;
|
||||
SET sql_mode=DEFAULT;
|
||||
#
|
||||
# End of 10.2 tests
|
||||
#
|
||||
|
|
|
@ -385,6 +385,36 @@ SELECT COLUMN_GET(@aaa, 'price' AS DECIMAL) aaa;
|
|||
SELECT COLUMN_GET(@aaa, 'price' AS INT) aaa;
|
||||
SELECT COLUMN_GET(@aaa, 'price' AS DOUBLE) aaa;
|
||||
|
||||
|
||||
--echo #
|
||||
--echo # MDEV-22579 No error when inserting DEFAULT(non_virtual_column) into a virtual column
|
||||
--echo #
|
||||
|
||||
SET sql_mode=STRICT_ALL_TABLES;
|
||||
CREATE OR REPLACE TABLE t1 (
|
||||
a INT NOT NULL DEFAULT 10,
|
||||
b INT AS (a+1) VIRTUAL
|
||||
) ENGINE=MyISAM;
|
||||
|
||||
# Testing with a column list
|
||||
|
||||
--error ER_WARNING_NON_DEFAULT_VALUE_FOR_GENERATED_COLUMN
|
||||
INSERT INTO t1 (b) VALUES (10);
|
||||
--error ER_WARNING_NON_DEFAULT_VALUE_FOR_GENERATED_COLUMN
|
||||
INSERT INTO t1 (b) VALUES (DEFAULT(a));
|
||||
INSERT INTO t1 (b) VALUES (DEFAULT);
|
||||
|
||||
# Testing without a column list
|
||||
--error ER_WARNING_NON_DEFAULT_VALUE_FOR_GENERATED_COLUMN
|
||||
INSERT INTO t1 VALUES (10,10);
|
||||
--error ER_WARNING_NON_DEFAULT_VALUE_FOR_GENERATED_COLUMN
|
||||
INSERT INTO t1 VALUES (10,DEFAULT(a));
|
||||
INSERT INTO t1 VALUES (10, DEFAULT);
|
||||
|
||||
DROP TABLE t1;
|
||||
SET sql_mode=DEFAULT;
|
||||
|
||||
|
||||
--echo #
|
||||
--echo # End of 10.1 tests
|
||||
--echo #
|
||||
|
@ -442,6 +472,37 @@ REPLACE INTO t1 (pk,i) VALUES (1,2);
|
|||
DROP TABLE t1;
|
||||
SET @sql_mode=@old_sql_mode;
|
||||
|
||||
--echo #
|
||||
--echo # MDEV-22579 No error when inserting DEFAULT(non_virtual_column) into a virtual column
|
||||
--echo # 10.2+ specific part
|
||||
--echo #
|
||||
|
||||
SET sql_mode=STRICT_ALL_TABLES;
|
||||
CREATE OR REPLACE TABLE t1 (
|
||||
a INT NOT NULL DEFAULT 10,
|
||||
b INT AS (a+1) VIRTUAL
|
||||
) ENGINE=MyISAM;
|
||||
|
||||
# Testing with column list
|
||||
|
||||
EXECUTE IMMEDIATE 'INSERT INTO t1 (b) VALUES(?)' USING DEFAULT;
|
||||
EXECUTE IMMEDIATE 'INSERT INTO t1 (b) VALUES(?)' USING IGNORE;
|
||||
INSERT INTO t1 (b) VALUES (DEFAULT);
|
||||
INSERT INTO t1 (b) VALUES (IGNORE);
|
||||
SELECT * FROM t1;
|
||||
DELETE FROM t1;
|
||||
|
||||
# Testing without column list
|
||||
|
||||
EXECUTE IMMEDIATE 'INSERT INTO t1 VALUES(10,?)' USING DEFAULT;
|
||||
EXECUTE IMMEDIATE 'INSERT INTO t1 VALUES(11,?)' USING IGNORE;
|
||||
INSERT INTO t1 VALUES (12,DEFAULT);
|
||||
INSERT INTO t1 VALUES (13,IGNORE);
|
||||
SELECT * FROM t1;
|
||||
|
||||
DROP TABLE t1;
|
||||
SET sql_mode=DEFAULT;
|
||||
|
||||
--echo #
|
||||
--echo # End of 10.2 tests
|
||||
--echo #
|
||||
|
|
|
@ -217,7 +217,6 @@ main.type_int : Modified in 10.4.12
|
|||
main.type_newdecimal : MDEV-20532 - Floating point differences
|
||||
main.type_ranges : MDEV-20532 - Floating point differences
|
||||
main.type_time : Modified in 10.4.12
|
||||
main.udf : MDEV-21976: Fails on Ubuntu Bionic 18.04, our Travis-CI platform
|
||||
main.union_crash-714 : Modified in 10.4.12
|
||||
main.upgrade_MDEV-19650 : Added in 10.4.13
|
||||
main.userstat : MDEV-12904 - SSL errors
|
||||
|
|
|
@ -515,8 +515,11 @@ my_bool reinit_io_cache(IO_CACHE *info, enum cache_type type,
|
|||
if (info->type == WRITE_CACHE)
|
||||
info->end_of_file= my_b_tell(info);
|
||||
else
|
||||
info->end_of_file= mysql_file_seek(info->file, 0L, MY_SEEK_END,
|
||||
MYF(0));
|
||||
{
|
||||
if (!(info->myflags & MY_ENCRYPT))
|
||||
info->end_of_file= mysql_file_seek(info->file, 0L,
|
||||
MY_SEEK_END, MYF(0));
|
||||
}
|
||||
}
|
||||
/* flush cache if we want to reuse it */
|
||||
if (!clear_cache && my_b_flush_io_cache(info,1))
|
||||
|
|
11
sql/field.cc
11
sql/field.cc
|
@ -1455,7 +1455,7 @@ void Field::error_generated_column_function_is_not_allowed(THD *thd,
|
|||
QT_ITEM_IDENT_SKIP_TABLE_NAMES));
|
||||
my_error(ER_GENERATED_COLUMN_FUNCTION_IS_NOT_ALLOWED,
|
||||
MYF(error ? 0 : ME_WARNING),
|
||||
tmp.c_ptr(), vcol_info->get_vcol_type_name(),
|
||||
tmp.c_ptr_safe(), vcol_info->get_vcol_type_name(),
|
||||
const_cast<const char*>(field_name.str));
|
||||
}
|
||||
|
||||
|
@ -7680,6 +7680,15 @@ my_decimal *Field_varstring::val_decimal(my_decimal *decimal_value)
|
|||
}
|
||||
|
||||
|
||||
#ifdef HAVE_valgrind_or_MSAN
|
||||
void Field_varstring::mark_unused_memory_as_defined()
|
||||
{
|
||||
uint used_length= get_length();
|
||||
MEM_MAKE_DEFINED(get_data() + used_length, field_length - used_length);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
int Field_varstring::cmp_max(const uchar *a_ptr, const uchar *b_ptr,
|
||||
uint max_len) const
|
||||
{
|
||||
|
|
16
sql/field.h
16
sql/field.h
|
@ -977,6 +977,19 @@ public:
|
|||
DBUG_ASSERT(ls.length < UINT_MAX32);
|
||||
return store(ls.str, (uint) ls.length, cs);
|
||||
}
|
||||
|
||||
#ifdef HAVE_valgrind_or_MSAN
|
||||
/**
|
||||
Mark unused memory in the field as defined. Mainly used to ensure
|
||||
that if we write full field to disk (for example in
|
||||
Count_distinct_field::add(), we don't write unitalized data to
|
||||
disk which would confuse valgrind or MSAN.
|
||||
*/
|
||||
virtual void mark_unused_memory_as_defined() {}
|
||||
#else
|
||||
void mark_unused_memory_as_defined() {}
|
||||
#endif
|
||||
|
||||
virtual double val_real()=0;
|
||||
virtual longlong val_int()=0;
|
||||
/*
|
||||
|
@ -4096,6 +4109,9 @@ public:
|
|||
}
|
||||
int store(const char *to,size_t length,CHARSET_INFO *charset) override;
|
||||
using Field_str::store;
|
||||
#ifdef HAVE_valgrind_or_MSAN
|
||||
void mark_unused_memory_as_defined() override;
|
||||
#endif
|
||||
double val_real() override;
|
||||
longlong val_int() override;
|
||||
String *val_str(String *, String *) override;
|
||||
|
|
26
sql/item.h
26
sql/item.h
|
@ -1592,7 +1592,14 @@ public:
|
|||
a constant expression. Used in the optimizer to propagate basic constants.
|
||||
*/
|
||||
virtual bool basic_const_item() const { return 0; }
|
||||
/*
|
||||
/**
|
||||
Determines if the expression is allowed as
|
||||
a virtual column assignment source:
|
||||
INSERT INTO t1 (vcol) VALUES (10) -> error
|
||||
INSERT INTO t1 (vcol) VALUES (NULL) -> ok
|
||||
*/
|
||||
virtual bool vcol_assignment_allowed_value() const { return false; }
|
||||
/**
|
||||
Test if "this" is an ORDER position (rather than an expression).
|
||||
Notes:
|
||||
- can be called before fix_fields().
|
||||
|
@ -3616,6 +3623,7 @@ public:
|
|||
collation.set(cs, DERIVATION_IGNORABLE, MY_REPERTOIRE_ASCII);
|
||||
}
|
||||
enum Type type() const { return NULL_ITEM; }
|
||||
bool vcol_assignment_allowed_value() const { return true; }
|
||||
double val_real();
|
||||
longlong val_int();
|
||||
String *val_str(String *str);
|
||||
|
@ -3861,6 +3869,21 @@ public:
|
|||
const Type_handler *type_handler() const
|
||||
{ return Type_handler_hybrid_field_type::type_handler(); }
|
||||
|
||||
bool vcol_assignment_allowed_value() const
|
||||
{
|
||||
switch (state) {
|
||||
case NULL_VALUE:
|
||||
case DEFAULT_VALUE:
|
||||
case IGNORE_VALUE:
|
||||
return true;
|
||||
case NO_VALUE:
|
||||
case SHORT_DATA_VALUE:
|
||||
case LONG_DATA_VALUE:
|
||||
break;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
Item_param(THD *thd, const LEX_CSTRING *name_arg,
|
||||
uint pos_in_query_arg, uint len_in_query_arg);
|
||||
|
||||
|
@ -6255,6 +6278,7 @@ public:
|
|||
Item_default_value(THD *thd, Name_resolution_context *context_arg, Field *a)
|
||||
:Item_field(thd, context_arg) {}
|
||||
enum Type type() const { return DEFAULT_VALUE_ITEM; }
|
||||
bool vcol_assignment_allowed_value() const { return arg == NULL; }
|
||||
bool eq(const Item *item, bool binary_cmp) const;
|
||||
bool fix_fields(THD *, Item **);
|
||||
void cleanup();
|
||||
|
|
|
@ -2184,6 +2184,12 @@ longlong Item_func_bit_neg::val_int()
|
|||
|
||||
void Item_func_int_val::fix_length_and_dec_int_or_decimal()
|
||||
{
|
||||
/*
|
||||
The INT branch of this code should be revised.
|
||||
It creates too large data types, e.g.
|
||||
CREATE OR REPLACE TABLE t2 AS SELECT FLOOR(9999999.999) AS fa;
|
||||
results in a BININT(10) column, while INT(7) should probably be enough.
|
||||
*/
|
||||
ulonglong tmp_max_length= (ulonglong ) args[0]->max_length -
|
||||
(args[0]->decimals ? args[0]->decimals + 1 : 0) + 2;
|
||||
max_length= tmp_max_length > (ulonglong) UINT_MAX32 ?
|
||||
|
@ -2198,6 +2204,9 @@ void Item_func_int_val::fix_length_and_dec_int_or_decimal()
|
|||
*/
|
||||
if (args[0]->max_length - args[0]->decimals >= DECIMAL_LONGLONG_DIGITS - 2)
|
||||
{
|
||||
fix_char_length(
|
||||
my_decimal_precision_to_length_no_truncation(
|
||||
args[0]->decimal_int_part(), 0, false));
|
||||
set_handler(&type_handler_newdecimal);
|
||||
}
|
||||
else
|
||||
|
@ -2314,6 +2323,8 @@ void Item_func_round::fix_length_and_dec_decimal(uint decimals_to_set)
|
|||
set_handler(&type_handler_newdecimal);
|
||||
unsigned_flag= args[0]->unsigned_flag;
|
||||
decimals= decimals_to_set;
|
||||
if (!precision)
|
||||
precision= 1; // DECIMAL(0,0) -> DECIMAL(1,0)
|
||||
max_length= my_decimal_precision_to_length_no_truncation(precision,
|
||||
decimals,
|
||||
unsigned_flag);
|
||||
|
|
|
@ -2192,10 +2192,13 @@ Item_in_subselect::create_single_in_to_exists_cond(JOIN *join,
|
|||
}
|
||||
else
|
||||
{
|
||||
/*
|
||||
No need to use real_item for the item, as the ref items that are possible
|
||||
in the subquery either belong to views or to the parent select.
|
||||
For such case we need to refer to the reference and not to the original
|
||||
item.
|
||||
*/
|
||||
Item *item= (Item*) select_lex->item_list.head();
|
||||
if (item->type() != REF_ITEM ||
|
||||
((Item_ref*)item)->ref_type() != Item_ref::VIEW_REF)
|
||||
item= item->real_item();
|
||||
|
||||
if (select_lex->table_list.elements)
|
||||
{
|
||||
|
|
|
@ -1387,10 +1387,12 @@ Item_sum_sp::execute()
|
|||
bool res;
|
||||
uint old_server_status= thd->server_status;
|
||||
|
||||
/* We set server status so we can send a signal to exit from the
|
||||
function with the return value. */
|
||||
/*
|
||||
We set server status so we can send a signal to exit from the
|
||||
function with the return value.
|
||||
*/
|
||||
|
||||
thd->server_status= SERVER_STATUS_LAST_ROW_SENT;
|
||||
thd->server_status|= SERVER_STATUS_LAST_ROW_SENT;
|
||||
res= Item_sp::execute(thd, &null_value, args, arg_count);
|
||||
thd->server_status= old_server_status;
|
||||
return res;
|
||||
|
|
|
@ -3134,6 +3134,8 @@ const char *sql_ex_info::init(const char *buf, const char *buf_end,
|
|||
}
|
||||
else
|
||||
{
|
||||
if (buf_end - buf < 7)
|
||||
return 0; // Wrong data
|
||||
field_term_len= enclosed_len= line_term_len= line_start_len= escaped_len=1;
|
||||
field_term = buf++; // Use first byte in string
|
||||
enclosed= buf++;
|
||||
|
|
|
@ -4648,7 +4648,7 @@ sp_instr_agg_cfetch::execute(THD *thd, uint *nextp)
|
|||
else
|
||||
{
|
||||
thd->spcont->pause_state= FALSE;
|
||||
if (thd->server_status == SERVER_STATUS_LAST_ROW_SENT)
|
||||
if (thd->server_status & SERVER_STATUS_LAST_ROW_SENT)
|
||||
{
|
||||
my_message(ER_SP_FETCH_NO_DATA,
|
||||
ER_THD(thd, ER_SP_FETCH_NO_DATA), MYF(0));
|
||||
|
|
|
@ -8375,11 +8375,9 @@ fill_record(THD *thd, TABLE *table_arg, List<Item> &fields, List<Item> &values,
|
|||
if (table->next_number_field &&
|
||||
rfield->field_index == table->next_number_field->field_index)
|
||||
table->auto_increment_field_not_null= TRUE;
|
||||
Item::Type type= value->type();
|
||||
const bool skip_sys_field= rfield->vers_sys_field(); // TODO: && !thd->vers_modify_history() [MDEV-16546]
|
||||
if ((rfield->vcol_info || skip_sys_field) &&
|
||||
type != Item::DEFAULT_VALUE_ITEM &&
|
||||
type != Item::NULL_ITEM &&
|
||||
!value->vcol_assignment_allowed_value() &&
|
||||
table->s->table_category != TABLE_CATEGORY_TEMPORARY)
|
||||
{
|
||||
push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN,
|
||||
|
@ -8660,20 +8658,16 @@ fill_record(THD *thd, TABLE *table, Field **ptr, List<Item> &values,
|
|||
|
||||
if (field->field_index == autoinc_index)
|
||||
table->auto_increment_field_not_null= TRUE;
|
||||
if (unlikely(field->vcol_info) || (vers_sys_field && !ignore_errors))
|
||||
if ((unlikely(field->vcol_info) || (vers_sys_field && !ignore_errors)) &&
|
||||
!value->vcol_assignment_allowed_value() &&
|
||||
table->s->table_category != TABLE_CATEGORY_TEMPORARY)
|
||||
{
|
||||
Item::Type type= value->type();
|
||||
if (type != Item::DEFAULT_VALUE_ITEM &&
|
||||
type != Item::NULL_ITEM &&
|
||||
table->s->table_category != TABLE_CATEGORY_TEMPORARY)
|
||||
{
|
||||
push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN,
|
||||
ER_WARNING_NON_DEFAULT_VALUE_FOR_GENERATED_COLUMN,
|
||||
ER_THD(thd, ER_WARNING_NON_DEFAULT_VALUE_FOR_GENERATED_COLUMN),
|
||||
field->field_name.str, table->s->table_name.str);
|
||||
if (vers_sys_field)
|
||||
continue;
|
||||
}
|
||||
push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN,
|
||||
ER_WARNING_NON_DEFAULT_VALUE_FOR_GENERATED_COLUMN,
|
||||
ER_THD(thd, ER_WARNING_NON_DEFAULT_VALUE_FOR_GENERATED_COLUMN),
|
||||
field->field_name.str, table->s->table_name.str);
|
||||
if (vers_sys_field)
|
||||
continue;
|
||||
}
|
||||
|
||||
if (use_value)
|
||||
|
|
|
@ -2006,7 +2006,7 @@ send_event_to_slave(binlog_send_info *info, Log_event_type event_type,
|
|||
|
||||
pos= my_b_tell(log);
|
||||
if (repl_semisync_master.update_sync_header(info->thd,
|
||||
(uchar*) packet->ptr(),
|
||||
(uchar*) packet->c_ptr_safe(),
|
||||
info->log_file_name + info->dirlen,
|
||||
pos, &need_sync))
|
||||
{
|
||||
|
@ -2030,7 +2030,8 @@ send_event_to_slave(binlog_send_info *info, Log_event_type event_type,
|
|||
}
|
||||
}
|
||||
|
||||
if (need_sync && repl_semisync_master.flush_net(info->thd, packet->c_ptr()))
|
||||
if (need_sync && repl_semisync_master.flush_net(info->thd,
|
||||
packet->c_ptr_safe()))
|
||||
{
|
||||
info->error= ER_UNKNOWN_ERROR;
|
||||
return "Failed to run hook 'after_send_event'";
|
||||
|
|
|
@ -1671,6 +1671,7 @@ public:
|
|||
*/
|
||||
virtual bool add()
|
||||
{
|
||||
table_field->mark_unused_memory_as_defined();
|
||||
return tree->unique_add(table_field->ptr);
|
||||
}
|
||||
|
||||
|
|
|
@ -52,7 +52,14 @@ bool fix_fields_for_tvc(THD *thd, List_iterator_fast<List_item> &li)
|
|||
|
||||
while ((item= it++))
|
||||
{
|
||||
if (item->fix_fields(thd, 0))
|
||||
/*
|
||||
Some items have already been fixed.
|
||||
For example Item_splocal items get fixed in
|
||||
Item_splocal::append_for_log(), which is called from subst_spvars()
|
||||
while replacing their values to NAME_CONST()s.
|
||||
So fix only those that have not been.
|
||||
*/
|
||||
if (item->fix_fields_if_needed(thd, 0))
|
||||
DBUG_RETURN(true);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7219,6 +7219,12 @@ void TABLE::mark_columns_needed_for_update()
|
|||
}
|
||||
need_signal= true;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (found_next_number_field)
|
||||
mark_auto_increment_column();
|
||||
}
|
||||
|
||||
if (file->ha_table_flags() & HA_PRIMARY_KEY_REQUIRED_FOR_DELETE)
|
||||
{
|
||||
/*
|
||||
|
|
|
@ -717,8 +717,10 @@ void btr_page_free(dict_index_t* index, buf_block_t* block, mtr_t* mtr,
|
|||
{
|
||||
ut_ad(mtr_memo_contains(mtr, block, MTR_MEMO_PAGE_X_FIX));
|
||||
#ifdef BTR_CUR_HASH_ADAPT
|
||||
ut_ad(!block->index || !blob);
|
||||
ut_ad(!block->index || page_is_leaf(block->frame));
|
||||
if (block->index && !block->index->freed()) {
|
||||
ut_ad(!blob);
|
||||
ut_ad(page_is_leaf(block->frame));
|
||||
}
|
||||
#endif
|
||||
ut_ad(index->table->space_id == block->page.id.space());
|
||||
/* The root page is freed by btr_free_root(). */
|
||||
|
@ -743,8 +745,7 @@ void btr_page_free(dict_index_t* index, buf_block_t* block, mtr_t* mtr,
|
|||
? PAGE_HEADER + PAGE_BTR_SEG_LEAF
|
||||
: PAGE_HEADER + PAGE_BTR_SEG_TOP];
|
||||
fseg_free_page(seg_header,
|
||||
index->table->space, block->page.id.page_no(),
|
||||
block->index != NULL, mtr);
|
||||
index->table->space, block->page.id.page_no(), mtr);
|
||||
|
||||
/* The page was marked free in the allocation bitmap, but it
|
||||
should remain exclusively latched until mtr_t::commit() or until it
|
||||
|
@ -987,8 +988,7 @@ static void btr_free_root(buf_block_t *block, mtr_t *mtr, bool invalidate)
|
|||
}
|
||||
|
||||
/* Free the entire segment in small steps. */
|
||||
while (!fseg_free_step(PAGE_HEADER + PAGE_BTR_SEG_TOP + block->frame,
|
||||
true, mtr));
|
||||
while (!fseg_free_step(PAGE_HEADER + PAGE_BTR_SEG_TOP + block->frame, mtr));
|
||||
}
|
||||
|
||||
/** Prepare to free a B-tree.
|
||||
|
@ -1204,7 +1204,7 @@ leaf_loop:
|
|||
fsp0fsp. */
|
||||
|
||||
bool finished = fseg_free_step(root + PAGE_HEADER + PAGE_BTR_SEG_LEAF,
|
||||
true, &mtr);
|
||||
&mtr);
|
||||
mtr_commit(&mtr);
|
||||
|
||||
if (!finished) {
|
||||
|
@ -1224,7 +1224,7 @@ top_loop:
|
|||
#endif /* UNIV_BTR_DEBUG */
|
||||
|
||||
finished = fseg_free_step_not_header(
|
||||
root + PAGE_HEADER + PAGE_BTR_SEG_TOP, true, &mtr);
|
||||
root + PAGE_HEADER + PAGE_BTR_SEG_TOP, &mtr);
|
||||
mtr_commit(&mtr);
|
||||
|
||||
if (!finished) {
|
||||
|
|
|
@ -3360,7 +3360,7 @@ btr_cur_optimistic_insert(
|
|||
page_t* page;
|
||||
rec_t* dummy;
|
||||
bool leaf;
|
||||
bool reorg;
|
||||
bool reorg __attribute__((unused));
|
||||
bool inherit = true;
|
||||
ulint rec_size;
|
||||
dberr_t err;
|
||||
|
|
|
@ -191,15 +191,8 @@ static
|
|||
void
|
||||
btr_search_check_free_space_in_heap(const dict_index_t* index)
|
||||
{
|
||||
hash_table_t* table;
|
||||
mem_heap_t* heap;
|
||||
|
||||
ut_ad(!btr_search_own_any(RW_LOCK_S));
|
||||
ut_ad(!btr_search_own_any(RW_LOCK_X));
|
||||
|
||||
table = btr_get_search_table(index);
|
||||
|
||||
heap = table->heap;
|
||||
hash_table_t* table = btr_get_search_table(index);
|
||||
mem_heap_t* heap = table->heap;
|
||||
|
||||
/* Note that we peek the value of heap->free_block without reserving
|
||||
the latch: this is ok, because we will not guarantee that there will
|
||||
|
@ -335,20 +328,29 @@ void btr_search_sys_free()
|
|||
|
||||
/** Set index->ref_count = 0 on all indexes of a table.
|
||||
@param[in,out] table table handler */
|
||||
static
|
||||
void
|
||||
btr_search_disable_ref_count(
|
||||
dict_table_t* table)
|
||||
static void btr_search_disable_ref_count(dict_table_t *table)
|
||||
{
|
||||
dict_index_t* index;
|
||||
for (dict_index_t *index= dict_table_get_first_index(table); index;
|
||||
index= dict_table_get_next_index(index))
|
||||
index->search_info->ref_count= 0;
|
||||
}
|
||||
|
||||
ut_ad(mutex_own(&dict_sys.mutex));
|
||||
/** Lazily free detached metadata when removing the last reference. */
|
||||
ATTRIBUTE_COLD static void btr_search_lazy_free(dict_index_t *index)
|
||||
{
|
||||
ut_ad(index->freed());
|
||||
dict_table_t *table= index->table;
|
||||
/* Perform the skipped steps of dict_index_remove_from_cache_low(). */
|
||||
UT_LIST_REMOVE(table->freed_indexes, index);
|
||||
rw_lock_free(&index->lock);
|
||||
dict_mem_index_free(index);
|
||||
|
||||
for (index = dict_table_get_first_index(table);
|
||||
index != NULL;
|
||||
index = dict_table_get_next_index(index)) {
|
||||
index->search_info->ref_count = 0;
|
||||
}
|
||||
if (!UT_LIST_GET_LEN(table->freed_indexes) &&
|
||||
!UT_LIST_GET_LEN(table->indexes))
|
||||
{
|
||||
ut_ad(table->id == 0);
|
||||
dict_mem_table_free(table);
|
||||
}
|
||||
}
|
||||
|
||||
/** Disable the adaptive hash search system and empty the index.
|
||||
|
@ -420,31 +422,6 @@ void btr_search_enable()
|
|||
btr_search_x_unlock_all();
|
||||
}
|
||||
|
||||
/** Returns the value of ref_count. The value is protected by latch.
|
||||
@param[in] info search info
|
||||
@param[in] index index identifier
|
||||
@return ref_count value. */
|
||||
ulint
|
||||
btr_search_info_get_ref_count(
|
||||
btr_search_t* info,
|
||||
dict_index_t* index)
|
||||
{
|
||||
ulint ret = 0;
|
||||
|
||||
if (!btr_search_enabled) {
|
||||
return(ret);
|
||||
}
|
||||
|
||||
ut_ad(info);
|
||||
|
||||
rw_lock_t* ahi_latch = btr_get_search_latch(index);
|
||||
rw_lock_s_lock(ahi_latch);
|
||||
ret = info->ref_count;
|
||||
rw_lock_s_unlock(ahi_latch);
|
||||
|
||||
return(ret);
|
||||
}
|
||||
|
||||
/** Updates the search info of an index about hash successes. NOTE that info
|
||||
is NOT protected by any semaphore, to save CPU time! Do not assume its fields
|
||||
are consistent.
|
||||
|
@ -637,30 +614,28 @@ btr_search_update_hash_ref(
|
|||
buf_block_t* block,
|
||||
const btr_cur_t* cursor)
|
||||
{
|
||||
dict_index_t* index;
|
||||
ulint fold;
|
||||
rec_t* rec;
|
||||
|
||||
ut_ad(cursor->flag == BTR_CUR_HASH_FAIL);
|
||||
ut_ad(rw_lock_own(btr_get_search_latch(cursor->index), RW_LOCK_X));
|
||||
|
||||
ut_ad(rw_lock_own_flagged(&block->lock,
|
||||
RW_LOCK_FLAG_X | RW_LOCK_FLAG_S));
|
||||
ut_ad(page_align(btr_cur_get_rec(cursor)) == block->frame);
|
||||
ut_ad(page_is_leaf(block->frame));
|
||||
assert_block_ahi_valid(block);
|
||||
|
||||
index = block->index;
|
||||
|
||||
if (!index) {
|
||||
dict_index_t* index = block->index;
|
||||
|
||||
if (!index || !info->n_hash_potential) {
|
||||
return;
|
||||
}
|
||||
|
||||
ut_ad(block->page.id.space() == index->table->space_id);
|
||||
ut_ad(index == cursor->index);
|
||||
ut_ad(!dict_index_is_ibuf(index));
|
||||
rw_lock_t* const latch = btr_get_search_latch(index);
|
||||
rw_lock_x_lock(latch);
|
||||
ut_ad(!block->index || block->index == index);
|
||||
|
||||
if ((info->n_hash_potential > 0)
|
||||
if (block->index
|
||||
&& (block->curr_n_fields == info->n_fields)
|
||||
&& (block->curr_n_bytes == info->n_bytes)
|
||||
&& (block->curr_left_side == info->left_side)) {
|
||||
|
@ -668,18 +643,18 @@ btr_search_update_hash_ref(
|
|||
rec_offs offsets_[REC_OFFS_NORMAL_SIZE];
|
||||
rec_offs_init(offsets_);
|
||||
|
||||
rec = btr_cur_get_rec(cursor);
|
||||
const rec_t* rec = btr_cur_get_rec(cursor);
|
||||
|
||||
if (!page_rec_is_user_rec(rec)) {
|
||||
|
||||
return;
|
||||
goto func_exit;
|
||||
}
|
||||
|
||||
fold = rec_fold(rec,
|
||||
rec_get_offsets(rec, index, offsets_, true,
|
||||
ULINT_UNDEFINED, &heap),
|
||||
block->curr_n_fields,
|
||||
block->curr_n_bytes, index->id);
|
||||
ulint fold = rec_fold(
|
||||
rec,
|
||||
rec_get_offsets(rec, index, offsets_, true,
|
||||
ULINT_UNDEFINED, &heap),
|
||||
block->curr_n_fields,
|
||||
block->curr_n_bytes, index->id);
|
||||
if (UNIV_LIKELY_NULL(heap)) {
|
||||
mem_heap_free(heap);
|
||||
}
|
||||
|
@ -689,6 +664,9 @@ btr_search_update_hash_ref(
|
|||
|
||||
MONITOR_INC(MONITOR_ADAPTIVE_HASH_ROW_ADDED);
|
||||
}
|
||||
|
||||
func_exit:
|
||||
rw_lock_x_unlock(latch);
|
||||
}
|
||||
|
||||
/** Checks if a guessed position for a tree cursor is right. Note that if
|
||||
|
@ -847,6 +825,8 @@ inline void buf_pool_t::clear_hash_index()
|
|||
ut_ad(!resizing);
|
||||
ut_ad(!btr_search_enabled);
|
||||
|
||||
std::set<dict_index_t*> garbage;
|
||||
|
||||
for (chunk_t *chunk= chunks + n_chunks; chunk-- != chunks; )
|
||||
{
|
||||
for (buf_block_t *block= chunk->blocks, * const end= block + chunk->size;
|
||||
|
@ -855,8 +835,9 @@ inline void buf_pool_t::clear_hash_index()
|
|||
dict_index_t *index= block->index;
|
||||
assert_block_ahi_valid(block);
|
||||
|
||||
/* We can clear block->index block->n_pointers when
|
||||
/* We can clear block->index and block->n_pointers when
|
||||
btr_search_own_all(RW_LOCK_X); see the comments in buf0buf.h */
|
||||
|
||||
if (!index)
|
||||
{
|
||||
# if defined UNIV_AHI_DEBUG || defined UNIV_DEBUG
|
||||
|
@ -877,9 +858,14 @@ inline void buf_pool_t::clear_hash_index()
|
|||
# if defined UNIV_AHI_DEBUG || defined UNIV_DEBUG
|
||||
block->n_pointers= 0;
|
||||
# endif /* UNIV_AHI_DEBUG || UNIV_DEBUG */
|
||||
if (index->freed())
|
||||
garbage.insert(index);
|
||||
block->index= nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
for (dict_index_t *index : garbage)
|
||||
btr_search_lazy_free(index);
|
||||
}
|
||||
|
||||
/** Get a buffer block from an adaptive hash index pointer.
|
||||
|
@ -943,7 +929,6 @@ btr_search_guess_on_hash(
|
|||
rw_lock_t* ahi_latch,
|
||||
mtr_t* mtr)
|
||||
{
|
||||
const rec_t* rec;
|
||||
ulint fold;
|
||||
index_id_t index_id;
|
||||
|
||||
|
@ -952,7 +937,7 @@ btr_search_guess_on_hash(
|
|||
ahi_latch, RW_LOCK_FLAG_X | RW_LOCK_FLAG_S));
|
||||
|
||||
if (!btr_search_enabled) {
|
||||
return(FALSE);
|
||||
return false;
|
||||
}
|
||||
|
||||
ut_ad(!index->is_ibuf());
|
||||
|
@ -969,16 +954,14 @@ btr_search_guess_on_hash(
|
|||
any latch here! */
|
||||
|
||||
if (info->n_hash_potential == 0) {
|
||||
|
||||
return(FALSE);
|
||||
return false;
|
||||
}
|
||||
|
||||
cursor->n_fields = info->n_fields;
|
||||
cursor->n_bytes = info->n_bytes;
|
||||
|
||||
if (dtuple_get_n_fields(tuple) < btr_search_get_n_fields(cursor)) {
|
||||
|
||||
return(FALSE);
|
||||
return false;
|
||||
}
|
||||
|
||||
index_id = index->id;
|
||||
|
@ -992,6 +975,7 @@ btr_search_guess_on_hash(
|
|||
cursor->flag = BTR_CUR_HASH;
|
||||
|
||||
rw_lock_t* use_latch = ahi_latch ? NULL : btr_get_search_latch(index);
|
||||
const rec_t* rec;
|
||||
|
||||
if (use_latch) {
|
||||
rw_lock_s_lock(use_latch);
|
||||
|
@ -1004,18 +988,17 @@ btr_search_guess_on_hash(
|
|||
ut_ad(rw_lock_own(ahi_latch, RW_LOCK_S));
|
||||
}
|
||||
|
||||
rec = (rec_t*) ha_search_and_get_data(
|
||||
btr_get_search_table(index), fold);
|
||||
rec = static_cast<const rec_t*>(
|
||||
ha_search_and_get_data(btr_get_search_table(index), fold));
|
||||
|
||||
if (rec == NULL) {
|
||||
if (!rec) {
|
||||
if (use_latch) {
|
||||
fail:
|
||||
rw_lock_s_unlock(use_latch);
|
||||
}
|
||||
|
||||
btr_search_failure(info, cursor);
|
||||
|
||||
return(FALSE);
|
||||
return false;
|
||||
}
|
||||
|
||||
buf_block_t* block = buf_pool.block_from_ahi(rec);
|
||||
|
@ -1031,8 +1014,11 @@ fail:
|
|||
goto fail;
|
||||
}
|
||||
|
||||
const bool fail = index != block->index
|
||||
&& index_id == block->index->id;
|
||||
ut_a(!fail || block->index->freed());
|
||||
ut_ad(buf_block_get_state(block) == BUF_BLOCK_FILE_PAGE);
|
||||
DBUG_ASSERT(block->page.status != buf_page_t::FREED);
|
||||
DBUG_ASSERT(fail || block->page.status != buf_page_t::FREED);
|
||||
|
||||
buf_page_set_accessed(&block->page);
|
||||
buf_block_buf_fix_inc(block, __FILE__, __LINE__);
|
||||
|
@ -1062,20 +1048,27 @@ got_no_latch:
|
|||
rw_lock_s_unlock(use_latch);
|
||||
|
||||
buf_block_dbg_add_level(block, SYNC_TREE_NODE_FROM_HASH);
|
||||
if (UNIV_UNLIKELY(fail)) {
|
||||
btr_search_drop_page_hash_index(block);
|
||||
goto fail_and_release_page;
|
||||
}
|
||||
} else if (UNIV_UNLIKELY(index != block->index
|
||||
&& index_id == block->index->id)) {
|
||||
ut_a(block->index->freed());
|
||||
goto fail_and_release_page;
|
||||
}
|
||||
|
||||
if (buf_block_get_state(block) != BUF_BLOCK_FILE_PAGE) {
|
||||
|
||||
ut_ad(buf_block_get_state(block) == BUF_BLOCK_REMOVE_HASH);
|
||||
|
||||
fail_and_release_page:
|
||||
if (!ahi_latch) {
|
||||
|
||||
btr_leaf_page_release(block, latch_mode, mtr);
|
||||
}
|
||||
|
||||
btr_search_failure(info, cursor);
|
||||
|
||||
return(FALSE);
|
||||
return false;
|
||||
}
|
||||
|
||||
ut_ad(page_rec_is_user_rec(rec));
|
||||
|
@ -1091,14 +1084,7 @@ got_no_latch:
|
|||
right. */
|
||||
if (index_id != btr_page_get_index_id(block->frame)
|
||||
|| !btr_search_check_guess(cursor, !!ahi_latch, tuple, mode)) {
|
||||
|
||||
if (!ahi_latch) {
|
||||
btr_leaf_page_release(block, latch_mode, mtr);
|
||||
}
|
||||
|
||||
btr_search_failure(info, cursor);
|
||||
|
||||
return(FALSE);
|
||||
goto fail_and_release_page;
|
||||
}
|
||||
|
||||
if (info->n_hash_potential < BTR_SEARCH_BUILD_LIMIT + 5) {
|
||||
|
@ -1176,32 +1162,28 @@ void btr_search_drop_page_hash_index(buf_block_t* block)
|
|||
ulint* folds;
|
||||
ulint i;
|
||||
mem_heap_t* heap;
|
||||
const dict_index_t* index;
|
||||
rec_offs* offsets;
|
||||
rw_lock_t* latch;
|
||||
btr_search_t* info;
|
||||
|
||||
retry:
|
||||
/* Do a dirty check on block->index, return if the block is
|
||||
not in the adaptive hash index. */
|
||||
index = block->index;
|
||||
/* This debug check uses a dirty read that could theoretically cause
|
||||
false positives while buf_pool.clear_hash_index() is executing. */
|
||||
assert_block_ahi_valid(block);
|
||||
ut_ad(!btr_search_own_any(RW_LOCK_S));
|
||||
ut_ad(!btr_search_own_any(RW_LOCK_X));
|
||||
|
||||
if (index == NULL) {
|
||||
if (!block->index) {
|
||||
return;
|
||||
}
|
||||
|
||||
ut_ad(block->page.buf_fix_count == 0
|
||||
|| buf_block_get_state(block) == BUF_BLOCK_REMOVE_HASH
|
||||
|| rw_lock_own_flagged(&block->lock,
|
||||
RW_LOCK_FLAG_X | RW_LOCK_FLAG_S));
|
||||
RW_LOCK_FLAG_X | RW_LOCK_FLAG_S
|
||||
| RW_LOCK_FLAG_SX));
|
||||
ut_ad(page_is_leaf(block->frame));
|
||||
|
||||
/* We must not dereference index here, because it could be freed
|
||||
/* We must not dereference block->index here, because it could be freed
|
||||
if (index->table->n_ref_count == 0 && !mutex_own(&dict_sys.mutex)).
|
||||
Determine the ahi_slot based on the block contents. */
|
||||
|
||||
|
@ -1216,18 +1198,12 @@ retry:
|
|||
rw_lock_s_lock(latch);
|
||||
assert_block_ahi_valid(block);
|
||||
|
||||
if (block->index == NULL) {
|
||||
if (!block->index) {
|
||||
rw_lock_s_unlock(latch);
|
||||
return;
|
||||
}
|
||||
|
||||
/* The index associated with a block must remain the
|
||||
same, because we are holding block->lock or the block is
|
||||
not accessible by other threads (BUF_BLOCK_REMOVE_HASH),
|
||||
or the index is not accessible to other threads
|
||||
(buf_fix_count == 0 when DROP TABLE or similar is executing
|
||||
buf_LRU_drop_page_hash_for_tablespace()). */
|
||||
ut_a(index == block->index);
|
||||
dict_index_t* index = block->index;
|
||||
#ifdef MYSQL_INDEX_DISABLE_AHI
|
||||
ut_ad(!index->disable_ahi);
|
||||
#endif
|
||||
|
@ -1235,7 +1211,7 @@ retry:
|
|||
|
||||
ut_ad(block->page.id.space() == index->table->space_id);
|
||||
ut_a(index_id == index->id);
|
||||
ut_a(!dict_index_is_ibuf(index));
|
||||
ut_ad(!dict_index_is_ibuf(index));
|
||||
#ifdef UNIV_DEBUG
|
||||
switch (dict_index_get_online_status(index)) {
|
||||
case ONLINE_INDEX_CREATION:
|
||||
|
@ -1343,9 +1319,14 @@ next_rec:
|
|||
folds[i], page);
|
||||
}
|
||||
|
||||
info = btr_search_get_info(block->index);
|
||||
ut_a(info->ref_count > 0);
|
||||
info->ref_count--;
|
||||
switch (index->search_info->ref_count--) {
|
||||
case 0:
|
||||
ut_error;
|
||||
case 1:
|
||||
if (index->freed()) {
|
||||
btr_search_lazy_free(index);
|
||||
}
|
||||
}
|
||||
|
||||
block->index = NULL;
|
||||
|
||||
|
@ -1446,11 +1427,12 @@ btr_search_build_page_hash_index(
|
|||
ut_ad(ahi_latch == btr_get_search_latch(index));
|
||||
ut_ad(index);
|
||||
ut_ad(block->page.id.space() == index->table->space_id);
|
||||
ut_a(!dict_index_is_ibuf(index));
|
||||
ut_ad(!dict_index_is_ibuf(index));
|
||||
ut_ad(page_is_leaf(block->frame));
|
||||
|
||||
ut_ad(rw_lock_own_flagged(&block->lock,
|
||||
RW_LOCK_FLAG_X | RW_LOCK_FLAG_S));
|
||||
ut_ad(block->page.id.page_no() >= 3);
|
||||
|
||||
rw_lock_s_lock(ahi_latch);
|
||||
|
||||
|
@ -1643,11 +1625,7 @@ btr_search_info_update_slow(btr_search_t* info, btr_cur_t* cursor)
|
|||
btr_search_n_hash_fail++;
|
||||
#endif /* UNIV_SEARCH_PERF_STAT */
|
||||
|
||||
rw_lock_x_lock(ahi_latch);
|
||||
|
||||
btr_search_update_hash_ref(info, block, cursor);
|
||||
|
||||
rw_lock_x_unlock(ahi_latch);
|
||||
}
|
||||
|
||||
if (build_index) {
|
||||
|
@ -1765,7 +1743,7 @@ void btr_search_update_hash_on_delete(btr_cur_t* cursor)
|
|||
ut_ad(block->page.id.space() == index->table->space_id);
|
||||
ut_a(index == cursor->index);
|
||||
ut_a(block->curr_n_fields > 0 || block->curr_n_bytes > 0);
|
||||
ut_a(!dict_index_is_ibuf(index));
|
||||
ut_ad(!dict_index_is_ibuf(index));
|
||||
|
||||
table = btr_get_search_table(index);
|
||||
|
||||
|
@ -1836,7 +1814,7 @@ btr_search_update_hash_node_on_insert(btr_cur_t* cursor, rw_lock_t* ahi_latch)
|
|||
}
|
||||
|
||||
ut_a(cursor->index == index);
|
||||
ut_a(!dict_index_is_ibuf(index));
|
||||
ut_ad(!dict_index_is_ibuf(index));
|
||||
rw_lock_x_lock(ahi_latch);
|
||||
|
||||
if (!block->index) {
|
||||
|
@ -1889,8 +1867,6 @@ btr_search_update_hash_on_insert(btr_cur_t* cursor, rw_lock_t* ahi_latch)
|
|||
ulint next_fold = 0; /* remove warning (??? bug ???) */
|
||||
ulint n_fields;
|
||||
ulint n_bytes;
|
||||
ibool left_side;
|
||||
bool locked = false;
|
||||
mem_heap_t* heap = NULL;
|
||||
rec_offs offsets_[REC_OFFS_NORMAL_SIZE];
|
||||
rec_offs* offsets = offsets_;
|
||||
|
@ -1930,11 +1906,11 @@ btr_search_update_hash_on_insert(btr_cur_t* cursor, rw_lock_t* ahi_latch)
|
|||
ut_a(!index->disable_ahi);
|
||||
#endif
|
||||
ut_a(index == cursor->index);
|
||||
ut_a(!dict_index_is_ibuf(index));
|
||||
ut_ad(!dict_index_is_ibuf(index));
|
||||
|
||||
n_fields = block->curr_n_fields;
|
||||
n_bytes = block->curr_n_bytes;
|
||||
left_side = block->curr_left_side;
|
||||
const bool left_side = block->curr_left_side;
|
||||
|
||||
ins_rec = page_rec_get_next_const(rec);
|
||||
next_rec = page_rec_get_next_const(ins_rec);
|
||||
|
@ -1951,6 +1927,8 @@ btr_search_update_hash_on_insert(btr_cur_t* cursor, rw_lock_t* ahi_latch)
|
|||
n_bytes, index->id);
|
||||
}
|
||||
|
||||
bool locked = false;
|
||||
|
||||
if (!page_rec_is_infimum(rec) && !rec_is_metadata(rec, *index)) {
|
||||
offsets = rec_get_offsets(
|
||||
rec, index, offsets, true,
|
||||
|
@ -2009,7 +1987,6 @@ check_next_rec:
|
|||
}
|
||||
|
||||
if (ins_fold != next_fold) {
|
||||
|
||||
if (!locked) {
|
||||
locked = true;
|
||||
rw_lock_x_lock(ahi_latch);
|
||||
|
@ -2135,7 +2112,7 @@ btr_search_hash_table_validate(ulint hash_table_id)
|
|||
== BUF_BLOCK_REMOVE_HASH);
|
||||
}
|
||||
|
||||
ut_a(!dict_index_is_ibuf(block->index));
|
||||
ut_ad(!dict_index_is_ibuf(block->index));
|
||||
ut_ad(block->page.id.space()
|
||||
== block->index->table->space_id);
|
||||
|
||||
|
|
|
@ -3231,7 +3231,7 @@ static buf_block_t* buf_page_mtr_lock(buf_block_t *block,
|
|||
{
|
||||
case RW_NO_LATCH:
|
||||
fix_type= MTR_MEMO_BUF_FIX;
|
||||
break;
|
||||
goto done;
|
||||
case RW_S_LATCH:
|
||||
rw_lock_s_lock_inline(&block->lock, 0, file, line);
|
||||
fix_type= MTR_MEMO_PAGE_S_FIX;
|
||||
|
@ -3247,6 +3247,15 @@ static buf_block_t* buf_page_mtr_lock(buf_block_t *block,
|
|||
break;
|
||||
}
|
||||
|
||||
#ifdef BTR_CUR_HASH_ADAPT
|
||||
{
|
||||
dict_index_t *index= block->index;
|
||||
if (index && index->freed())
|
||||
btr_search_drop_page_hash_index(block);
|
||||
}
|
||||
#endif /* BTR_CUR_HASH_ADAPT */
|
||||
|
||||
done:
|
||||
mtr_memo_push(mtr, block, fix_type);
|
||||
return block;
|
||||
}
|
||||
|
@ -3578,6 +3587,7 @@ evict_from_pool:
|
|||
mutex_exit(&buf_pool.mutex);
|
||||
return(NULL);
|
||||
}
|
||||
|
||||
break;
|
||||
default:
|
||||
ut_error;
|
||||
|
@ -4538,6 +4548,12 @@ buf_page_create(
|
|||
rw_lock_x_unlock(hash_lock);
|
||||
|
||||
buf_block_free(free_block);
|
||||
#ifdef BTR_CUR_HASH_ADAPT
|
||||
if (block->page.state == BUF_BLOCK_FILE_PAGE
|
||||
&& UNIV_LIKELY_NULL(block->index)) {
|
||||
btr_search_drop_page_hash_index(block);
|
||||
}
|
||||
#endif /* BTR_CUR_HASH_ADAPT */
|
||||
|
||||
if (!recv_recovery_is_on()) {
|
||||
/* FIXME: Remove the redundant lookup and avoid
|
||||
|
@ -5015,9 +5031,8 @@ buf_page_io_complete(buf_page_t* bpage, bool dblwr, bool evict)
|
|||
|
||||
err = buf_page_check_corrupt(bpage, space);
|
||||
|
||||
database_corrupted:
|
||||
|
||||
if (err != DB_SUCCESS) {
|
||||
database_corrupted:
|
||||
/* Not a real corruption if it was triggered by
|
||||
error injection */
|
||||
DBUG_EXECUTE_IF(
|
||||
|
@ -5034,6 +5049,11 @@ database_corrupted:
|
|||
goto page_not_corrupt;
|
||||
);
|
||||
|
||||
if (uncompressed && bpage->zip.data) {
|
||||
memset(reinterpret_cast<buf_block_t*>(bpage)
|
||||
->frame, 0, srv_page_size);
|
||||
}
|
||||
|
||||
if (err == DB_PAGE_CORRUPTED) {
|
||||
ib::error()
|
||||
<< "Database page corruption on disk"
|
||||
|
|
|
@ -210,157 +210,6 @@ bool buf_LRU_evict_from_unzip_LRU()
|
|||
}
|
||||
|
||||
#ifdef BTR_CUR_HASH_ADAPT
|
||||
/** Attempts to drop page hash index on a batch of pages belonging to a
|
||||
particular space id.
|
||||
@param[in] space_id space id
|
||||
@param[in] arr array of page_no
|
||||
@param[in] count number of entries in array */
|
||||
static
|
||||
void
|
||||
buf_LRU_drop_page_hash_batch(ulint space_id, const ulint* arr, ulint count)
|
||||
{
|
||||
ut_ad(count <= BUF_LRU_DROP_SEARCH_SIZE);
|
||||
|
||||
for (const ulint* const end = arr + count; arr != end; ) {
|
||||
/* While our only caller
|
||||
buf_LRU_drop_page_hash_for_tablespace()
|
||||
is being executed for DROP TABLE or similar,
|
||||
the table cannot be evicted from the buffer pool. */
|
||||
btr_search_drop_page_hash_when_freed(
|
||||
page_id_t(space_id, *arr++));
|
||||
}
|
||||
}
|
||||
|
||||
/******************************************************************//**
|
||||
When doing a DROP TABLE/DISCARD TABLESPACE we have to drop all page
|
||||
hash index entries belonging to that table. This function tries to
|
||||
do that in batch. Note that this is a 'best effort' attempt and does
|
||||
not guarantee that ALL hash entries will be removed.
|
||||
@param[in] id space id */
|
||||
static
|
||||
void
|
||||
buf_LRU_drop_page_hash_for_tablespace(ulint id)
|
||||
{
|
||||
ulint* page_arr = static_cast<ulint*>(ut_malloc_nokey(
|
||||
sizeof(ulint) * BUF_LRU_DROP_SEARCH_SIZE));
|
||||
|
||||
ulint num_entries = 0;
|
||||
|
||||
mutex_enter(&buf_pool.mutex);
|
||||
|
||||
scan_again:
|
||||
for (buf_page_t* bpage = UT_LIST_GET_LAST(buf_pool.LRU);
|
||||
bpage != NULL;
|
||||
/* No op */) {
|
||||
|
||||
buf_page_t* prev_bpage = UT_LIST_GET_PREV(LRU, bpage);
|
||||
|
||||
ut_a(buf_page_in_file(bpage));
|
||||
|
||||
if (buf_page_get_state(bpage) != BUF_BLOCK_FILE_PAGE
|
||||
|| bpage->id.space() != id
|
||||
|| bpage->io_fix != BUF_IO_NONE) {
|
||||
/* Compressed pages are never hashed.
|
||||
Skip blocks of other tablespaces.
|
||||
Skip I/O-fixed blocks (to be dealt with later). */
|
||||
next_page:
|
||||
bpage = prev_bpage;
|
||||
continue;
|
||||
}
|
||||
|
||||
buf_block_t* block = reinterpret_cast<buf_block_t*>(bpage);
|
||||
|
||||
mutex_enter(&block->mutex);
|
||||
|
||||
/* This debug check uses a dirty read that could
|
||||
theoretically cause false positives while
|
||||
buf_pool.clear_hash_index() is executing.
|
||||
(Other conflicting access paths to the adaptive hash
|
||||
index should not be possible, because when a
|
||||
tablespace is being discarded or dropped, there must
|
||||
be no concurrect access to the contained tables.) */
|
||||
assert_block_ahi_valid(block);
|
||||
|
||||
bool skip = bpage->buf_fix_count > 0 || !block->index;
|
||||
|
||||
mutex_exit(&block->mutex);
|
||||
|
||||
if (skip) {
|
||||
/* Skip this block, because there are
|
||||
no adaptive hash index entries
|
||||
pointing to it, or because we cannot
|
||||
drop them due to the buffer-fix. */
|
||||
goto next_page;
|
||||
}
|
||||
|
||||
/* Store the page number so that we can drop the hash
|
||||
index in a batch later. */
|
||||
page_arr[num_entries] = bpage->id.page_no();
|
||||
ut_a(num_entries < BUF_LRU_DROP_SEARCH_SIZE);
|
||||
++num_entries;
|
||||
|
||||
if (num_entries < BUF_LRU_DROP_SEARCH_SIZE) {
|
||||
goto next_page;
|
||||
}
|
||||
|
||||
/* Array full. We release the buf_pool.mutex to obey
|
||||
the latching order. */
|
||||
mutex_exit(&buf_pool.mutex);
|
||||
|
||||
buf_LRU_drop_page_hash_batch(id, page_arr, num_entries);
|
||||
|
||||
num_entries = 0;
|
||||
|
||||
mutex_enter(&buf_pool.mutex);
|
||||
|
||||
/* Note that we released the buf_pool mutex above
|
||||
after reading the prev_bpage during processing of a
|
||||
page_hash_batch (i.e.: when the array was full).
|
||||
Because prev_bpage could belong to a compressed-only
|
||||
block, it may have been relocated, and thus the
|
||||
pointer cannot be trusted. Because bpage is of type
|
||||
buf_block_t, it is safe to dereference.
|
||||
|
||||
bpage can change in the LRU list. This is OK because
|
||||
this function is a 'best effort' to drop as many
|
||||
search hash entries as possible and it does not
|
||||
guarantee that ALL such entries will be dropped. */
|
||||
|
||||
/* If, however, bpage has been removed from LRU list
|
||||
to the free list then we should restart the scan.
|
||||
bpage->state is protected by buf_pool mutex. */
|
||||
if (bpage != NULL
|
||||
&& buf_page_get_state(bpage) != BUF_BLOCK_FILE_PAGE) {
|
||||
|
||||
goto scan_again;
|
||||
}
|
||||
}
|
||||
|
||||
mutex_exit(&buf_pool.mutex);
|
||||
|
||||
/* Drop any remaining batch of search hashed pages. */
|
||||
buf_LRU_drop_page_hash_batch(id, page_arr, num_entries);
|
||||
ut_free(page_arr);
|
||||
}
|
||||
|
||||
/** Try to drop the adaptive hash index for a tablespace.
|
||||
@param[in,out] table table
|
||||
@return whether anything was dropped */
|
||||
bool buf_LRU_drop_page_hash_for_tablespace(dict_table_t* table)
|
||||
{
|
||||
for (dict_index_t* index = dict_table_get_first_index(table);
|
||||
index != NULL;
|
||||
index = dict_table_get_next_index(index)) {
|
||||
if (btr_search_info_get_ref_count(btr_search_get_info(index),
|
||||
index)) {
|
||||
buf_LRU_drop_page_hash_for_tablespace(table->space_id);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
While flushing (or removing dirty) pages from a tablespace we don't
|
||||
want to hog the CPU and resources. Release the buffer pool and block
|
||||
|
|
|
@ -26,7 +26,9 @@ Created 1/8/1996 Heikki Tuuri
|
|||
|
||||
#include "dict0crea.h"
|
||||
#include "btr0pcur.h"
|
||||
#include "btr0btr.h"
|
||||
#ifdef BTR_CUR_HASH_ADAPT
|
||||
# include "btr0sea.h"
|
||||
#endif /* BTR_CUR_HASH_ADAPT */
|
||||
#include "page0page.h"
|
||||
#include "mach0data.h"
|
||||
#include "dict0boot.h"
|
||||
|
@ -1300,6 +1302,9 @@ dict_create_index_step(
|
|||
&node->table->fts->cache->init_lock);
|
||||
}
|
||||
|
||||
#ifdef BTR_CUR_HASH_ADAPT
|
||||
ut_ad(!node->index->search_info->ref_count);
|
||||
#endif /* BTR_CUR_HASH_ADAPT */
|
||||
dict_index_remove_from_cache(node->table, node->index);
|
||||
node->index = NULL;
|
||||
|
||||
|
|
|
@ -1249,25 +1249,12 @@ dict_table_can_be_evicted(
|
|||
}
|
||||
|
||||
#ifdef BTR_CUR_HASH_ADAPT
|
||||
/* We cannot really evict the table if adaptive hash
|
||||
index entries are pointing to any of its indexes. */
|
||||
for (dict_index_t* index = dict_table_get_first_index(table);
|
||||
index != NULL;
|
||||
index = dict_table_get_next_index(index)) {
|
||||
|
||||
btr_search_t* info = btr_search_get_info(index);
|
||||
|
||||
/* We are not allowed to free the in-memory index
|
||||
struct dict_index_t until all entries in the adaptive
|
||||
hash index that point to any of the page belonging to
|
||||
his b-tree index are dropped. This is so because
|
||||
dropping of these entries require access to
|
||||
dict_index_t struct. To avoid such scenario we keep
|
||||
a count of number of such pages in the search_info and
|
||||
only free the dict_index_t struct when this count
|
||||
drops to zero.
|
||||
|
||||
See also: dict_index_remove_from_cache_low() */
|
||||
|
||||
if (btr_search_info_get_ref_count(info, index) > 0) {
|
||||
if (index->n_ahi_pages()) {
|
||||
return(FALSE);
|
||||
}
|
||||
}
|
||||
|
@ -1279,6 +1266,70 @@ dict_table_can_be_evicted(
|
|||
return(FALSE);
|
||||
}
|
||||
|
||||
#ifdef BTR_CUR_HASH_ADAPT
|
||||
/** @return a clone of this */
|
||||
dict_index_t *dict_index_t::clone() const
|
||||
{
|
||||
ut_ad(n_fields);
|
||||
ut_ad(!(type & (DICT_IBUF | DICT_SPATIAL | DICT_FTS)));
|
||||
ut_ad(online_status == ONLINE_INDEX_COMPLETE);
|
||||
ut_ad(is_committed());
|
||||
ut_ad(!is_dummy);
|
||||
ut_ad(!parser);
|
||||
ut_ad(!online_log);
|
||||
ut_ad(!rtr_track);
|
||||
|
||||
const size_t size= sizeof *this + n_fields * sizeof(*fields) +
|
||||
#ifdef BTR_CUR_ADAPT
|
||||
sizeof *search_info +
|
||||
#endif
|
||||
1 + strlen(name) +
|
||||
n_uniq * (sizeof *stat_n_diff_key_vals +
|
||||
sizeof *stat_n_sample_sizes +
|
||||
sizeof *stat_n_non_null_key_vals);
|
||||
|
||||
mem_heap_t* heap= mem_heap_create(size);
|
||||
dict_index_t *index= static_cast<dict_index_t*>(mem_heap_dup(heap, this,
|
||||
sizeof *this));
|
||||
*index= *this;
|
||||
rw_lock_create(index_tree_rw_lock_key, &index->lock, SYNC_INDEX_TREE);
|
||||
index->heap= heap;
|
||||
index->name= mem_heap_strdup(heap, name);
|
||||
index->fields= static_cast<dict_field_t*>
|
||||
(mem_heap_dup(heap, fields, n_fields * sizeof *fields));
|
||||
#ifdef BTR_CUR_ADAPT
|
||||
index->search_info= btr_search_info_create(index->heap);
|
||||
#endif /* BTR_CUR_ADAPT */
|
||||
index->stat_n_diff_key_vals= static_cast<ib_uint64_t*>
|
||||
(mem_heap_zalloc(heap, n_uniq * sizeof *stat_n_diff_key_vals));
|
||||
index->stat_n_sample_sizes= static_cast<ib_uint64_t*>
|
||||
(mem_heap_zalloc(heap, n_uniq * sizeof *stat_n_sample_sizes));
|
||||
index->stat_n_non_null_key_vals= static_cast<ib_uint64_t*>
|
||||
(mem_heap_zalloc(heap, n_uniq * sizeof *stat_n_non_null_key_vals));
|
||||
mutex_create(LATCH_ID_ZIP_PAD_MUTEX, &index->zip_pad.mutex);
|
||||
return index;
|
||||
}
|
||||
|
||||
/** Clone this index for lazy dropping of the adaptive hash.
|
||||
@return this or a clone */
|
||||
dict_index_t *dict_index_t::clone_if_needed()
|
||||
{
|
||||
if (!search_info->ref_count)
|
||||
return this;
|
||||
dict_index_t *prev= UT_LIST_GET_PREV(indexes, this);
|
||||
|
||||
UT_LIST_REMOVE(table->indexes, this);
|
||||
UT_LIST_ADD_LAST(table->freed_indexes, this);
|
||||
dict_index_t *index= clone();
|
||||
set_freed();
|
||||
if (prev)
|
||||
UT_LIST_INSERT_AFTER(table->indexes, prev, index);
|
||||
else
|
||||
UT_LIST_ADD_FIRST(table->indexes, index);
|
||||
return index;
|
||||
}
|
||||
#endif /* BTR_CUR_HASH_ADAPT */
|
||||
|
||||
/**********************************************************************//**
|
||||
Make room in the table cache by evicting an unused table. The unused table
|
||||
should not be part of FK relationship and currently not used in any user
|
||||
|
@ -1919,9 +1970,19 @@ void dict_sys_t::remove(dict_table_t* table, bool lru, bool keep)
|
|||
|
||||
mutex_free(&table->autoinc_mutex);
|
||||
|
||||
if (!keep) {
|
||||
dict_mem_table_free(table);
|
||||
if (keep) {
|
||||
return;
|
||||
}
|
||||
|
||||
#ifdef BTR_CUR_HASH_ADAPT
|
||||
if (UNIV_UNLIKELY(UT_LIST_GET_LEN(table->freed_indexes) != 0)) {
|
||||
table->vc_templ = NULL;
|
||||
table->id = 0;
|
||||
return;
|
||||
}
|
||||
#endif /* BTR_CUR_HASH_ADAPT */
|
||||
|
||||
dict_mem_table_free(table);
|
||||
}
|
||||
|
||||
/****************************************************************//**
|
||||
|
@ -2099,6 +2160,8 @@ dict_index_remove_from_cache_low(
|
|||
ut_ad(table->magic_n == DICT_TABLE_MAGIC_N);
|
||||
ut_ad(index->magic_n == DICT_INDEX_MAGIC_N);
|
||||
ut_ad(mutex_own(&dict_sys.mutex));
|
||||
ut_ad(table->id);
|
||||
ut_ad(!index->freed());
|
||||
|
||||
/* No need to acquire the dict_index_t::lock here because
|
||||
there can't be any active operations on this index (or table). */
|
||||
|
@ -2108,13 +2171,22 @@ dict_index_remove_from_cache_low(
|
|||
row_log_free(index->online_log);
|
||||
}
|
||||
|
||||
/* Remove the index from the list of indexes of the table */
|
||||
UT_LIST_REMOVE(table->indexes, index);
|
||||
|
||||
/* The index is being dropped, remove any compression stats for it. */
|
||||
if (!lru_evict && DICT_TF_GET_ZIP_SSIZE(index->table->flags)) {
|
||||
mutex_enter(&page_zip_stat_per_index_mutex);
|
||||
page_zip_stat_per_index.erase(index->id);
|
||||
mutex_exit(&page_zip_stat_per_index_mutex);
|
||||
}
|
||||
|
||||
/* Remove the index from affected virtual column index list */
|
||||
index->detach_columns();
|
||||
|
||||
#ifdef BTR_CUR_HASH_ADAPT
|
||||
/* We always create search info whether or not adaptive
|
||||
hash index is enabled or not. */
|
||||
btr_search_t* info = btr_search_get_info(index);
|
||||
ulint retries = 0;
|
||||
ut_ad(info);
|
||||
|
||||
/* We are not allowed to free the in-memory index struct
|
||||
dict_index_t until all entries in the adaptive hash index
|
||||
that point to any of the page belonging to his b-tree index
|
||||
|
@ -2124,31 +2196,15 @@ dict_index_remove_from_cache_low(
|
|||
only free the dict_index_t struct when this count drops to
|
||||
zero. See also: dict_table_can_be_evicted() */
|
||||
|
||||
do {
|
||||
if (!btr_search_info_get_ref_count(info, index)
|
||||
|| !buf_LRU_drop_page_hash_for_tablespace(table)) {
|
||||
break;
|
||||
}
|
||||
|
||||
ut_a(++retries < 10000);
|
||||
} while (srv_shutdown_state == SRV_SHUTDOWN_NONE || !lru_evict);
|
||||
if (index->n_ahi_pages()) {
|
||||
index->set_freed();
|
||||
UT_LIST_ADD_LAST(table->freed_indexes, index);
|
||||
return;
|
||||
}
|
||||
#endif /* BTR_CUR_HASH_ADAPT */
|
||||
|
||||
rw_lock_free(&index->lock);
|
||||
|
||||
/* The index is being dropped, remove any compression stats for it. */
|
||||
if (!lru_evict && DICT_TF_GET_ZIP_SSIZE(index->table->flags)) {
|
||||
mutex_enter(&page_zip_stat_per_index_mutex);
|
||||
page_zip_stat_per_index.erase(index->id);
|
||||
mutex_exit(&page_zip_stat_per_index_mutex);
|
||||
}
|
||||
|
||||
/* Remove the index from the list of indexes of the table */
|
||||
UT_LIST_REMOVE(table->indexes, index);
|
||||
|
||||
/* Remove the index from affected virtual column index list */
|
||||
index->detach_columns();
|
||||
|
||||
dict_mem_index_free(index);
|
||||
}
|
||||
|
||||
|
@ -5075,10 +5131,7 @@ dict_index_zip_pad_update(
|
|||
beyond max pad size. */
|
||||
if (info->pad + ZIP_PAD_INCR
|
||||
< (srv_page_size * zip_pad_max) / 100) {
|
||||
/* Use atomics even though we have the mutex.
|
||||
This is to ensure that we are able to read
|
||||
info->pad atomically. */
|
||||
info->pad += ZIP_PAD_INCR;
|
||||
info->pad.fetch_add(ZIP_PAD_INCR);
|
||||
|
||||
MONITOR_INC(MONITOR_PAD_INCREMENTS);
|
||||
}
|
||||
|
@ -5095,11 +5148,7 @@ dict_index_zip_pad_update(
|
|||
padding. */
|
||||
if (info->n_rounds >= ZIP_PAD_SUCCESSFUL_ROUND_LIMIT
|
||||
&& info->pad > 0) {
|
||||
|
||||
/* Use atomics even though we have the mutex.
|
||||
This is to ensure that we are able to read
|
||||
info->pad atomically. */
|
||||
info->pad -= ZIP_PAD_INCR;
|
||||
info->pad.fetch_sub(ZIP_PAD_INCR);
|
||||
|
||||
info->n_rounds = 0;
|
||||
|
||||
|
|
|
@ -157,6 +157,9 @@ dict_mem_table_create(
|
|||
lock_table_lock_list_init(&table->locks);
|
||||
|
||||
UT_LIST_INIT(table->indexes, &dict_index_t::indexes);
|
||||
#ifdef BTR_CUR_HASH_ADAPT
|
||||
UT_LIST_INIT(table->freed_indexes, &dict_index_t::indexes);
|
||||
#endif /* BTR_CUR_HASH_ADAPT */
|
||||
|
||||
table->heap = heap;
|
||||
|
||||
|
@ -216,6 +219,10 @@ dict_mem_table_free(
|
|||
{
|
||||
ut_ad(table);
|
||||
ut_ad(table->magic_n == DICT_TABLE_MAGIC_N);
|
||||
ut_ad(UT_LIST_GET_LEN(table->indexes) == 0);
|
||||
#ifdef BTR_CUR_HASH_ADAPT
|
||||
ut_ad(UT_LIST_GET_LEN(table->freed_indexes) == 0);
|
||||
#endif /* BTR_CUR_HASH_ADAPT */
|
||||
ut_d(table->cached = FALSE);
|
||||
|
||||
if (dict_table_has_fts_index(table)
|
||||
|
|
|
@ -419,6 +419,9 @@ dict_stats_table_clone_create(
|
|||
t->corrupted = table->corrupted;
|
||||
|
||||
UT_LIST_INIT(t->indexes, &dict_index_t::indexes);
|
||||
#ifdef BTR_CUR_HASH_ADAPT
|
||||
UT_LIST_INIT(t->freed_indexes, &dict_index_t::indexes);
|
||||
#endif /* BTR_CUR_HASH_ADAPT */
|
||||
|
||||
for (index = dict_table_get_first_index(table);
|
||||
index != NULL;
|
||||
|
@ -4028,6 +4031,9 @@ test_dict_stats_save()
|
|||
table.stat_clustered_index_size = TEST_CLUSTERED_INDEX_SIZE;
|
||||
table.stat_sum_of_other_index_sizes = TEST_SUM_OF_OTHER_INDEX_SIZES;
|
||||
UT_LIST_INIT(table.indexes, &dict_index_t::indexes);
|
||||
#ifdef BTR_CUR_HASH_ADAPT
|
||||
UT_LIST_INIT(table.freed_indexes, &dict_index_t::indexes);
|
||||
#endif /* BTR_CUR_HASH_ADAPT */
|
||||
UT_LIST_ADD_LAST(table.indexes, &index1);
|
||||
UT_LIST_ADD_LAST(table.indexes, &index2);
|
||||
ut_d(table.magic_n = DICT_TABLE_MAGIC_N);
|
||||
|
@ -4177,6 +4183,9 @@ test_dict_stats_fetch_from_ps()
|
|||
/* craft a dummy dict_table_t */
|
||||
table.name.m_name = (char*) (TEST_DATABASE_NAME "/" TEST_TABLE_NAME);
|
||||
UT_LIST_INIT(table.indexes, &dict_index_t::indexes);
|
||||
#ifdef BTR_CUR_HASH_ADAPT
|
||||
UT_LIST_INIT(table.freed_indexes, &dict_index_t::indexes);
|
||||
#endif /* BTR_CUR_HASH_ADAPT */
|
||||
UT_LIST_ADD_LAST(table.indexes, &index1);
|
||||
UT_LIST_ADD_LAST(table.indexes, &index2);
|
||||
ut_d(table.magic_n = DICT_TABLE_MAGIC_N);
|
||||
|
|
|
@ -27,7 +27,6 @@ Updated 14/02/2015
|
|||
#include "fil0fil.h"
|
||||
#include "fil0pagecompress.h"
|
||||
|
||||
#include <debug_sync.h>
|
||||
#include <my_dbug.h>
|
||||
|
||||
#include "mem0mem.h"
|
||||
|
|
|
@ -2485,8 +2485,6 @@ try_to_extend:
|
|||
@param[in] seg_inode segment inode
|
||||
@param[in,out] space tablespace
|
||||
@param[in] offset page number
|
||||
@param[in] ahi whether we may need to drop the adaptive
|
||||
hash index
|
||||
@param[in,out] mtr mini-transaction */
|
||||
static
|
||||
void
|
||||
|
@ -2495,9 +2493,6 @@ fseg_free_page_low(
|
|||
buf_block_t* iblock,
|
||||
fil_space_t* space,
|
||||
page_no_t offset,
|
||||
#ifdef BTR_CUR_HASH_ADAPT
|
||||
bool ahi,
|
||||
#endif /* BTR_CUR_HASH_ADAPT */
|
||||
mtr_t* mtr)
|
||||
{
|
||||
ib_id_t descr_id;
|
||||
|
@ -2510,15 +2505,6 @@ fseg_free_page_low(
|
|||
ut_ad(!((page_offset(seg_inode) - FSEG_ARR_OFFSET) % FSEG_INODE_SIZE));
|
||||
ut_ad(iblock->frame == page_align(seg_inode));
|
||||
ut_d(space->modify_check(*mtr));
|
||||
#ifdef BTR_CUR_HASH_ADAPT
|
||||
/* Drop search system page hash index if the page is found in
|
||||
the pool and is hashed */
|
||||
|
||||
if (ahi) {
|
||||
btr_search_drop_page_hash_when_freed(
|
||||
page_id_t(space->id, offset));
|
||||
}
|
||||
#endif /* BTR_CUR_HASH_ADAPT */
|
||||
|
||||
buf_block_t* xdes;
|
||||
xdes_t* descr = xdes_get_descriptor(space, offset, &xdes, mtr);
|
||||
|
@ -2607,26 +2593,16 @@ fseg_free_page_low(
|
|||
mtr->free(page_id_t(space->id, offset));
|
||||
}
|
||||
|
||||
#ifndef BTR_CUR_HASH_ADAPT
|
||||
# define fseg_free_page_low(inode, space, offset, ahi, mtr) \
|
||||
fseg_free_page_low(inode, space, offset, mtr)
|
||||
#endif /* !BTR_CUR_HASH_ADAPT */
|
||||
|
||||
/** Free a page in a file segment.
|
||||
@param[in,out] seg_header file segment header
|
||||
@param[in,out] space tablespace
|
||||
@param[in] offset page number
|
||||
@param[in] ahi whether we may need to drop the adaptive
|
||||
hash index
|
||||
@param[in,out] mtr mini-transaction */
|
||||
void
|
||||
fseg_free_page_func(
|
||||
fseg_free_page(
|
||||
fseg_header_t* seg_header,
|
||||
fil_space_t* space,
|
||||
ulint offset,
|
||||
#ifdef BTR_CUR_HASH_ADAPT
|
||||
bool ahi,
|
||||
#endif /* BTR_CUR_HASH_ADAPT */
|
||||
mtr_t* mtr)
|
||||
{
|
||||
DBUG_ENTER("fseg_free_page");
|
||||
|
@ -2644,7 +2620,7 @@ fseg_free_page_func(
|
|||
fil_block_check_type(*iblock, FIL_PAGE_INODE, mtr);
|
||||
}
|
||||
|
||||
fseg_free_page_low(seg_inode, iblock, space, offset, ahi, mtr);
|
||||
fseg_free_page_low(seg_inode, iblock, space, offset, mtr);
|
||||
|
||||
buf_page_free(page_id_t(space->id, offset), mtr, __FILE__, __LINE__);
|
||||
|
||||
|
@ -2683,8 +2659,6 @@ fseg_page_is_free(fil_space_t* space, unsigned page)
|
|||
@param[in,out] seg_inode segment inode
|
||||
@param[in,out] space tablespace
|
||||
@param[in] page page number in the extent
|
||||
@param[in] ahi whether we may need to drop
|
||||
the adaptive hash index
|
||||
@param[in,out] mtr mini-transaction */
|
||||
MY_ATTRIBUTE((nonnull))
|
||||
static
|
||||
|
@ -2694,12 +2668,8 @@ fseg_free_extent(
|
|||
buf_block_t* iblock,
|
||||
fil_space_t* space,
|
||||
ulint page,
|
||||
#ifdef BTR_CUR_HASH_ADAPT
|
||||
bool ahi,
|
||||
#endif /* BTR_CUR_HASH_ADAPT */
|
||||
mtr_t* mtr)
|
||||
{
|
||||
ulint first_page_in_extent;
|
||||
|
||||
ut_ad(mtr != NULL);
|
||||
|
||||
|
@ -2712,23 +2682,9 @@ fseg_free_extent(
|
|||
== FSEG_MAGIC_N_VALUE);
|
||||
ut_d(space->modify_check(*mtr));
|
||||
|
||||
first_page_in_extent = page - (page % FSP_EXTENT_SIZE);
|
||||
|
||||
#ifdef BTR_CUR_HASH_ADAPT
|
||||
if (ahi) {
|
||||
for (ulint i = 0; i < FSP_EXTENT_SIZE; i++) {
|
||||
if (!xdes_is_free(descr, i)) {
|
||||
/* Drop search system page hash index
|
||||
if the page is found in the pool and
|
||||
is hashed */
|
||||
|
||||
btr_search_drop_page_hash_when_freed(
|
||||
page_id_t(space->id,
|
||||
first_page_in_extent + i));
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif /* BTR_CUR_HASH_ADAPT */
|
||||
#if defined BTR_CUR_HASH_ADAPT || defined UNIV_DEBUG
|
||||
const ulint first_page_in_extent = page - (page % FSP_EXTENT_SIZE);
|
||||
#endif /* BTR_CUR_HASH_ADAPT || UNIV_DEBUG */
|
||||
|
||||
const uint16_t xoffset= uint16_t(descr - xdes->frame + XDES_FLST_NODE);
|
||||
const uint16_t ioffset= uint16_t(seg_inode - iblock->frame);
|
||||
|
@ -2762,27 +2718,18 @@ fseg_free_extent(
|
|||
}
|
||||
}
|
||||
|
||||
#ifndef BTR_CUR_HASH_ADAPT
|
||||
# define fseg_free_extent(inode, iblock, space, page, ahi, mtr) \
|
||||
fseg_free_extent(inode, iblock, space, page, mtr)
|
||||
#endif /* !BTR_CUR_HASH_ADAPT */
|
||||
|
||||
/**********************************************************************//**
|
||||
Frees part of a segment. This function can be used to free a segment by
|
||||
repeatedly calling this function in different mini-transactions. Doing
|
||||
the freeing in a single mini-transaction might result in too big a
|
||||
mini-transaction.
|
||||
@return true if freeing completed */
|
||||
@return whether the freeing was completed */
|
||||
bool
|
||||
fseg_free_step_func(
|
||||
fseg_free_step(
|
||||
fseg_header_t* header, /*!< in, own: segment header; NOTE: if the header
|
||||
resides on the first page of the frag list
|
||||
of the segment, this pointer becomes obsolete
|
||||
after the last freeing step */
|
||||
#ifdef BTR_CUR_HASH_ADAPT
|
||||
bool ahi, /*!< in: whether we may need to drop
|
||||
the adaptive hash index */
|
||||
#endif /* BTR_CUR_HASH_ADAPT */
|
||||
mtr_t* mtr) /*!< in/out: mini-transaction */
|
||||
{
|
||||
ulint n;
|
||||
|
@ -2822,7 +2769,7 @@ fseg_free_step_func(
|
|||
if (descr != NULL) {
|
||||
/* Free the extent held by the segment */
|
||||
page = xdes_get_offset(descr);
|
||||
fseg_free_extent(inode, iblock, space, page, ahi, mtr);
|
||||
fseg_free_extent(inode, iblock, space, page, mtr);
|
||||
DBUG_RETURN(false);
|
||||
}
|
||||
|
||||
|
@ -2839,7 +2786,7 @@ fseg_free_step_func(
|
|||
fseg_free_page_low(
|
||||
inode, iblock, space,
|
||||
fseg_get_nth_frag_page_no(inode, n, mtr),
|
||||
ahi, mtr);
|
||||
mtr);
|
||||
|
||||
n = fseg_find_last_used_frag_page_slot(inode, mtr);
|
||||
|
||||
|
@ -2856,15 +2803,11 @@ fseg_free_step_func(
|
|||
/**********************************************************************//**
|
||||
Frees part of a segment. Differs from fseg_free_step because this function
|
||||
leaves the header page unfreed.
|
||||
@return true if freeing completed, except the header page */
|
||||
@return whether the freeing was completed, except for the header page */
|
||||
bool
|
||||
fseg_free_step_not_header_func(
|
||||
fseg_free_step_not_header(
|
||||
fseg_header_t* header, /*!< in: segment header which must reside on
|
||||
the first fragment page of the segment */
|
||||
#ifdef BTR_CUR_HASH_ADAPT
|
||||
bool ahi, /*!< in: whether we may need to drop
|
||||
the adaptive hash index */
|
||||
#endif /* BTR_CUR_HASH_ADAPT */
|
||||
mtr_t* mtr) /*!< in/out: mini-transaction */
|
||||
{
|
||||
ulint n;
|
||||
|
@ -2891,30 +2834,24 @@ fseg_free_step_not_header_func(
|
|||
if (descr != NULL) {
|
||||
/* Free the extent held by the segment */
|
||||
page = xdes_get_offset(descr);
|
||||
|
||||
fseg_free_extent(inode, iblock, space, page, ahi, mtr);
|
||||
|
||||
return(false);
|
||||
fseg_free_extent(inode, iblock, space, page, mtr);
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Free a frag page */
|
||||
|
||||
n = fseg_find_last_used_frag_page_slot(inode, mtr);
|
||||
|
||||
if (n == ULINT_UNDEFINED) {
|
||||
ut_error;
|
||||
}
|
||||
ut_a(n != ULINT_UNDEFINED);
|
||||
|
||||
page_no = fseg_get_nth_frag_page_no(inode, n, mtr);
|
||||
|
||||
if (page_no == page_get_page_no(page_align(header))) {
|
||||
|
||||
return(true);
|
||||
return true;
|
||||
}
|
||||
|
||||
fseg_free_page_low(inode, iblock, space, page_no, ahi, mtr);
|
||||
|
||||
return(false);
|
||||
fseg_free_page_low(inode, iblock, space, page_no, mtr);
|
||||
return false;
|
||||
}
|
||||
|
||||
/** Returns the first extent descriptor for a segment.
|
||||
|
|
|
@ -1024,6 +1024,7 @@ struct ha_innobase_inplace_ctx : public inplace_alter_handler_ctx
|
|||
for (ulint i = 0; i < num_to_add_index; i++) {
|
||||
if (!add_index[i]->is_committed()) {
|
||||
add_index[i]->detach_columns();
|
||||
add_index[i]->n_fields = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -11117,21 +11118,14 @@ foreign_fail:
|
|||
|| (ctx0->is_instant()
|
||||
&& m_prebuilt->table->n_v_cols
|
||||
&& ha_alter_info->handler_flags & ALTER_STORED_COLUMN_ORDER)) {
|
||||
/* FIXME: this workaround does not seem to work with
|
||||
partitioned tables */
|
||||
DBUG_ASSERT(ctx0->old_table->get_ref_count() == 1);
|
||||
|
||||
trx_commit_for_mysql(m_prebuilt->trx);
|
||||
#ifdef BTR_CUR_HASH_ADAPT
|
||||
if (btr_search_enabled) {
|
||||
btr_search_disable(false);
|
||||
btr_search_enable();
|
||||
}
|
||||
#endif /* BTR_CUR_HASH_ADAPT */
|
||||
|
||||
char tb_name[FN_REFLEN];
|
||||
char tb_name[NAME_LEN * 2 + 1 + 1];
|
||||
strcpy(tb_name, m_prebuilt->table->name.m_name);
|
||||
|
||||
tb_name[strlen(m_prebuilt->table->name.m_name)] = 0;
|
||||
|
||||
dict_table_close(m_prebuilt->table, true, false);
|
||||
if (ctx0->is_instant()) {
|
||||
for (unsigned i = ctx0->old_n_v_cols; i--; ) {
|
||||
|
|
|
@ -1951,7 +1951,7 @@ ibuf_remove_free_page(void)
|
|||
|
||||
compile_time_assert(IBUF_SPACE_ID == 0);
|
||||
fseg_free_page(header_page + IBUF_HEADER + IBUF_TREE_SEG_HEADER,
|
||||
fil_system.sys_space, page_no, false, &mtr);
|
||||
fil_system.sys_space, page_no, &mtr);
|
||||
|
||||
const page_id_t page_id(IBUF_SPACE_ID, page_no);
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/*****************************************************************************
|
||||
|
||||
Copyright (c) 1996, 2016, 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
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/*****************************************************************************
|
||||
|
||||
Copyright (c) 1996, 2015, Oracle and/or its affiliates. All Rights Reserved.
|
||||
Copyright (c) 2015, 2019, MariaDB Corporation.
|
||||
Copyright (c) 2015, 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
|
||||
|
|
|
@ -48,15 +48,6 @@ void btr_search_disable(bool need_mutex);
|
|||
/** Enable the adaptive hash search system. */
|
||||
void btr_search_enable();
|
||||
|
||||
/** Returns the value of ref_count. The value is protected by latch.
|
||||
@param[in] info search info
|
||||
@param[in] index index identifier
|
||||
@return ref_count value. */
|
||||
ulint
|
||||
btr_search_info_get_ref_count(
|
||||
btr_search_t* info,
|
||||
dict_index_t* index);
|
||||
|
||||
/*********************************************************************//**
|
||||
Updates the search info. */
|
||||
UNIV_INLINE
|
||||
|
@ -272,6 +263,18 @@ struct btr_search_t{
|
|||
};
|
||||
|
||||
#ifdef BTR_CUR_HASH_ADAPT
|
||||
/** @return number of leaf pages pointed to by the adaptive hash index */
|
||||
inline ulint dict_index_t::n_ahi_pages() const
|
||||
{
|
||||
if (!btr_search_enabled)
|
||||
return 0;
|
||||
rw_lock_t *latch = btr_get_search_latch(this);
|
||||
rw_lock_s_lock(latch);
|
||||
ulint ref_count= search_info->ref_count;
|
||||
rw_lock_s_unlock(latch);
|
||||
return ref_count;
|
||||
}
|
||||
|
||||
/** The hash index system */
|
||||
struct btr_search_sys_t{
|
||||
hash_table_t** hash_tables; /*!< the adaptive hash tables,
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/*****************************************************************************
|
||||
|
||||
Copyright (c) 1996, 2015, Oracle and/or its affiliates. All Rights Reserved.
|
||||
Copyright (c) 2018, MariaDB Corporation.
|
||||
Copyright (c) 2018, 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
|
||||
|
|
|
@ -45,17 +45,6 @@ These are low-level functions
|
|||
/** Minimum LRU list length for which the LRU_old pointer is defined */
|
||||
#define BUF_LRU_OLD_MIN_LEN 512 /* 8 megabytes of 16k pages */
|
||||
|
||||
#ifdef BTR_CUR_HASH_ADAPT
|
||||
struct dict_table_t;
|
||||
/** Try to drop the adaptive hash index for a tablespace.
|
||||
@param[in,out] table table
|
||||
@return whether anything was dropped */
|
||||
bool buf_LRU_drop_page_hash_for_tablespace(dict_table_t* table)
|
||||
MY_ATTRIBUTE((warn_unused_result,nonnull));
|
||||
#else
|
||||
# define buf_LRU_drop_page_hash_for_tablespace(table)
|
||||
#endif /* BTR_CUR_HASH_ADAPT */
|
||||
|
||||
/** Empty the flush list for all pages belonging to a tablespace.
|
||||
@param[in] id tablespace identifier
|
||||
@param[in] flush whether to write the pages to files
|
||||
|
|
|
@ -932,7 +932,7 @@ an uncompressed page should be left as padding to avoid compression
|
|||
failures. This estimate is based on a self-adapting heuristic. */
|
||||
struct zip_pad_info_t {
|
||||
SysMutex mutex; /*!< mutex protecting the info */
|
||||
Atomic_counter<ulint>
|
||||
Atomic_relaxed<ulint>
|
||||
pad; /*!< number of bytes used as pad */
|
||||
ulint success;/*!< successful compression ops during
|
||||
current round */
|
||||
|
@ -960,7 +960,10 @@ struct dict_index_t {
|
|||
mem_heap_t* heap; /*!< memory heap */
|
||||
id_name_t name; /*!< index name */
|
||||
dict_table_t* table; /*!< back pointer to table */
|
||||
unsigned page:32;/*!< index tree root page number */
|
||||
/** root page number, or FIL_NULL if the index has been detached
|
||||
from storage (DISCARD TABLESPACE or similar),
|
||||
or 1 if the index is in table->freed_indexes */
|
||||
unsigned page:32;
|
||||
unsigned merge_threshold:6;
|
||||
/*!< In the pessimistic delete, if the page
|
||||
data size drops below this limit in percent,
|
||||
|
@ -1105,19 +1108,11 @@ struct dict_index_t {
|
|||
/* @} */
|
||||
private:
|
||||
/** R-tree split sequence number */
|
||||
std::atomic<node_seq_t> rtr_ssn;
|
||||
Atomic_relaxed<node_seq_t> rtr_ssn;
|
||||
public:
|
||||
|
||||
void set_ssn(node_seq_t ssn)
|
||||
{
|
||||
rtr_ssn.store(ssn, std::memory_order_relaxed);
|
||||
}
|
||||
node_seq_t assign_ssn()
|
||||
{
|
||||
node_seq_t ssn= rtr_ssn.fetch_add(1, std::memory_order_relaxed);
|
||||
return ssn + 1;
|
||||
}
|
||||
node_seq_t ssn() const { return rtr_ssn.load(std::memory_order_relaxed); }
|
||||
void set_ssn(node_seq_t ssn) { rtr_ssn= ssn; }
|
||||
node_seq_t assign_ssn() { return rtr_ssn.fetch_add(1) + 1; }
|
||||
node_seq_t ssn() const { return rtr_ssn; }
|
||||
|
||||
rtr_info_track_t*
|
||||
rtr_track;/*!< tracking all R-Tree search cursors */
|
||||
|
@ -1216,8 +1211,6 @@ public:
|
|||
for (unsigned i = 0; i < n_fields; i++) {
|
||||
fields[i].col->detach(*this);
|
||||
}
|
||||
|
||||
n_fields = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1280,15 +1273,29 @@ public:
|
|||
bool
|
||||
vers_history_row(const rec_t* rec, bool &history_row);
|
||||
|
||||
/** Reconstruct the clustered index fields. */
|
||||
inline void reconstruct_fields();
|
||||
/** Reconstruct the clustered index fields. */
|
||||
inline void reconstruct_fields();
|
||||
|
||||
/** Check if the index contains a column or a prefix of that column.
|
||||
@param[in] n column number
|
||||
@param[in] is_virtual whether it is a virtual col
|
||||
@return whether the index contains the column or its prefix */
|
||||
bool contains_col_or_prefix(ulint n, bool is_virtual) const
|
||||
MY_ATTRIBUTE((warn_unused_result));
|
||||
/** Check if the index contains a column or a prefix of that column.
|
||||
@param[in] n column number
|
||||
@param[in] is_virtual whether it is a virtual col
|
||||
@return whether the index contains the column or its prefix */
|
||||
bool contains_col_or_prefix(ulint n, bool is_virtual) const
|
||||
MY_ATTRIBUTE((warn_unused_result));
|
||||
|
||||
#ifdef BTR_CUR_HASH_ADAPT
|
||||
/** @return a clone of this */
|
||||
dict_index_t* clone() const;
|
||||
/** Clone this index for lazy dropping of the adaptive hash index.
|
||||
@return this or a clone */
|
||||
dict_index_t* clone_if_needed();
|
||||
/** @return number of leaf pages pointed to by the adaptive hash index */
|
||||
inline ulint n_ahi_pages() const;
|
||||
/** @return whether mark_freed() had been invoked */
|
||||
bool freed() const { return UNIV_UNLIKELY(page == 1); }
|
||||
/** Note that the index is waiting for btr_search_lazy_free() */
|
||||
void set_freed() { ut_ad(!freed()); page= 1; }
|
||||
#endif /* BTR_CUR_HASH_ADAPT */
|
||||
|
||||
/** This ad-hoc class is used by record_size_info only. */
|
||||
class record_size_info_t {
|
||||
|
@ -2062,6 +2069,11 @@ public:
|
|||
|
||||
/** List of indexes of the table. */
|
||||
UT_LIST_BASE_NODE_T(dict_index_t) indexes;
|
||||
#ifdef BTR_CUR_HASH_ADAPT
|
||||
/** List of detached indexes that are waiting to be freed along with
|
||||
the last adaptive hash index entry */
|
||||
UT_LIST_BASE_NODE_T(dict_index_t) freed_indexes;
|
||||
#endif /* BTR_CUR_HASH_ADAPT */
|
||||
|
||||
/** List of foreign key constraints in the table. These refer to
|
||||
columns in other tables. */
|
||||
|
|
|
@ -487,25 +487,13 @@ fsp_reserve_free_extents(
|
|||
@param[in,out] seg_header file segment header
|
||||
@param[in,out] space tablespace
|
||||
@param[in] offset page number
|
||||
@param[in] ahi whether we may need to drop the adaptive
|
||||
hash index
|
||||
@param[in,out] mtr mini-transaction */
|
||||
void
|
||||
fseg_free_page_func(
|
||||
fseg_free_page(
|
||||
fseg_header_t* seg_header,
|
||||
fil_space_t* space,
|
||||
ulint offset,
|
||||
#ifdef BTR_CUR_HASH_ADAPT
|
||||
bool ahi,
|
||||
#endif /* BTR_CUR_HASH_ADAPT */
|
||||
mtr_t* mtr);
|
||||
#ifdef BTR_CUR_HASH_ADAPT
|
||||
# define fseg_free_page(header, space, offset, ahi, mtr) \
|
||||
fseg_free_page_func(header, space, offset, ahi, mtr)
|
||||
#else /* BTR_CUR_HASH_ADAPT */
|
||||
# define fseg_free_page(header, space, offset, ahi, mtr) \
|
||||
fseg_free_page_func(header, space, offset, mtr)
|
||||
#endif /* BTR_CUR_HASH_ADAPT */
|
||||
/** Determine whether a page is free.
|
||||
@param[in,out] space tablespace
|
||||
@param[in] page page number
|
||||
|
@ -518,45 +506,25 @@ Frees part of a segment. This function can be used to free a segment
|
|||
by repeatedly calling this function in different mini-transactions.
|
||||
Doing the freeing in a single mini-transaction might result in
|
||||
too big a mini-transaction.
|
||||
@return TRUE if freeing completed */
|
||||
@return whether the freeing was completed */
|
||||
bool
|
||||
fseg_free_step_func(
|
||||
fseg_free_step(
|
||||
fseg_header_t* header, /*!< in, own: segment header; NOTE: if the header
|
||||
resides on the first page of the frag list
|
||||
of the segment, this pointer becomes obsolete
|
||||
after the last freeing step */
|
||||
#ifdef BTR_CUR_HASH_ADAPT
|
||||
bool ahi, /*!< in: whether we may need to drop
|
||||
the adaptive hash index */
|
||||
#endif /* BTR_CUR_HASH_ADAPT */
|
||||
mtr_t* mtr) /*!< in/out: mini-transaction */
|
||||
MY_ATTRIBUTE((warn_unused_result));
|
||||
#ifdef BTR_CUR_HASH_ADAPT
|
||||
# define fseg_free_step(header, ahi, mtr) fseg_free_step_func(header, ahi, mtr)
|
||||
#else /* BTR_CUR_HASH_ADAPT */
|
||||
# define fseg_free_step(header, ahi, mtr) fseg_free_step_func(header, mtr)
|
||||
#endif /* BTR_CUR_HASH_ADAPT */
|
||||
/**********************************************************************//**
|
||||
Frees part of a segment. Differs from fseg_free_step because this function
|
||||
leaves the header page unfreed.
|
||||
@return true if freeing completed, except the header page */
|
||||
@return whether the freeing was completed, except for the header page */
|
||||
bool
|
||||
fseg_free_step_not_header_func(
|
||||
fseg_free_step_not_header(
|
||||
fseg_header_t* header, /*!< in: segment header which must reside on
|
||||
the first fragment page of the segment */
|
||||
#ifdef BTR_CUR_HASH_ADAPT
|
||||
bool ahi, /*!< in: whether we may need to drop
|
||||
the adaptive hash index */
|
||||
#endif /* BTR_CUR_HASH_ADAPT */
|
||||
mtr_t* mtr) /*!< in/out: mini-transaction */
|
||||
MY_ATTRIBUTE((warn_unused_result));
|
||||
#ifdef BTR_CUR_HASH_ADAPT
|
||||
# define fseg_free_step_not_header(header, ahi, mtr) \
|
||||
fseg_free_step_not_header_func(header, ahi, mtr)
|
||||
#else /* BTR_CUR_HASH_ADAPT */
|
||||
# define fseg_free_step_not_header(header, ahi, mtr) \
|
||||
fseg_free_step_not_header_func(header, mtr)
|
||||
#endif /* BTR_CUR_HASH_ADAPT */
|
||||
|
||||
/** Reset the page type.
|
||||
Data files created before MySQL 5.1.48 may contain garbage in FIL_PAGE_TYPE.
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
Copyright (c) 1995, 2016, Oracle and/or its affiliates. All Rights Reserved.
|
||||
Copyright (c) 2008, 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
|
||||
|
@ -568,11 +568,11 @@ struct rw_lock_t
|
|||
: public latch_t
|
||||
#endif /* UNIV_DEBUG */
|
||||
{
|
||||
/** Holds the state of the lock. */
|
||||
std::atomic<int32_t> lock_word;
|
||||
/** Holds the state of the lock. */
|
||||
Atomic_relaxed<int32_t> lock_word;
|
||||
|
||||
/** 1: there are waiters */
|
||||
std::atomic<int32_t> waiters;
|
||||
/** 0=no waiters, 1=waiters for X or SX lock exist */
|
||||
Atomic_relaxed<uint32_t> waiters;
|
||||
|
||||
/** number of granted SX locks. */
|
||||
volatile ulint sx_recursive;
|
||||
|
|
|
@ -77,7 +77,7 @@ rw_lock_get_writer(
|
|||
/*===============*/
|
||||
const rw_lock_t* lock) /*!< in: rw-lock */
|
||||
{
|
||||
auto lock_word = lock->lock_word.load(std::memory_order_relaxed);
|
||||
int32_t lock_word = lock->lock_word;
|
||||
|
||||
ut_ad(lock_word <= X_LOCK_DECR);
|
||||
if (lock_word > X_LOCK_HALF_DECR) {
|
||||
|
@ -109,7 +109,7 @@ rw_lock_get_reader_count(
|
|||
/*=====================*/
|
||||
const rw_lock_t* lock) /*!< in: rw-lock */
|
||||
{
|
||||
auto lock_word = lock->lock_word.load(std::memory_order_relaxed);
|
||||
int32_t lock_word = lock->lock_word;
|
||||
ut_ad(lock_word <= X_LOCK_DECR);
|
||||
|
||||
if (lock_word > X_LOCK_HALF_DECR) {
|
||||
|
@ -145,7 +145,7 @@ rw_lock_get_x_lock_count(
|
|||
/*=====================*/
|
||||
const rw_lock_t* lock) /*!< in: rw-lock */
|
||||
{
|
||||
auto lock_copy = lock->lock_word.load(std::memory_order_relaxed);
|
||||
int32_t lock_copy = lock->lock_word;
|
||||
ut_ad(lock_copy <= X_LOCK_DECR);
|
||||
|
||||
if (lock_copy == 0 || lock_copy == -X_LOCK_HALF_DECR) {
|
||||
|
@ -178,7 +178,7 @@ rw_lock_get_sx_lock_count(
|
|||
const rw_lock_t* lock) /*!< in: rw-lock */
|
||||
{
|
||||
#ifdef UNIV_DEBUG
|
||||
auto lock_copy = lock->lock_word.load(std::memory_order_relaxed);
|
||||
int32_t lock_copy = lock->lock_word;
|
||||
|
||||
ut_ad(lock_copy <= X_LOCK_DECR);
|
||||
|
||||
|
@ -209,7 +209,7 @@ rw_lock_lock_word_decr(
|
|||
int32_t amount, /*!< in: amount to decrement */
|
||||
int32_t threshold) /*!< in: threshold of judgement */
|
||||
{
|
||||
auto lock_copy = lock->lock_word.load(std::memory_order_relaxed);
|
||||
int32_t lock_copy = lock->lock_word;
|
||||
|
||||
while (lock_copy > threshold) {
|
||||
if (lock->lock_word.compare_exchange_strong(
|
||||
|
@ -352,26 +352,20 @@ rw_lock_s_unlock_func(
|
|||
#endif /* UNIV_DEBUG */
|
||||
rw_lock_t* lock) /*!< in/out: rw-lock */
|
||||
{
|
||||
#ifdef UNIV_DEBUG
|
||||
auto dbg_lock_word = lock->lock_word.load(std::memory_order_relaxed);
|
||||
ut_ad(dbg_lock_word > -X_LOCK_DECR);
|
||||
ut_ad(dbg_lock_word != 0);
|
||||
ut_ad(dbg_lock_word < X_LOCK_DECR);
|
||||
#endif
|
||||
|
||||
ut_d(rw_lock_remove_debug_info(lock, pass, RW_LOCK_S));
|
||||
|
||||
/* Increment lock_word to indicate 1 less reader */
|
||||
auto lock_word = lock->lock_word.fetch_add(
|
||||
1, std::memory_order_release) + 1;
|
||||
if (lock_word == 0 || lock_word == -X_LOCK_HALF_DECR) {
|
||||
int32_t lock_word = lock->lock_word.fetch_add(1);
|
||||
|
||||
if (lock_word == -1 || lock_word == -X_LOCK_HALF_DECR - 1) {
|
||||
/* wait_ex waiter exists. It may not be asleep, but we signal
|
||||
anyway. We do not wake other waiters, because they can't
|
||||
exist without wait_ex waiter and wait_ex waiter goes first.*/
|
||||
os_event_set(lock->wait_ex_event);
|
||||
sync_array_object_signalled();
|
||||
|
||||
} else {
|
||||
ut_ad(lock_word > -X_LOCK_DECR);
|
||||
ut_ad(lock_word < X_LOCK_DECR);
|
||||
}
|
||||
|
||||
ut_ad(rw_lock_validate(lock));
|
||||
|
@ -389,10 +383,7 @@ rw_lock_x_unlock_func(
|
|||
#endif /* UNIV_DEBUG */
|
||||
rw_lock_t* lock) /*!< in/out: rw-lock */
|
||||
{
|
||||
auto lock_word = lock->lock_word.load(std::memory_order_relaxed);
|
||||
|
||||
ut_ad(lock_word == 0 || lock_word == -X_LOCK_HALF_DECR
|
||||
|| lock_word <= -X_LOCK_DECR);
|
||||
int32_t lock_word = lock->lock_word;
|
||||
|
||||
if (lock_word == 0) {
|
||||
/* Last caller in a possible recursive chain. */
|
||||
|
@ -414,21 +405,19 @@ rw_lock_x_unlock_func(
|
|||
We need to signal read/write waiters.
|
||||
We do not need to signal wait_ex waiters, since they cannot
|
||||
exist when there is a writer. */
|
||||
if (lock->waiters.load(std::memory_order_relaxed)) {
|
||||
lock->waiters.store(0, std::memory_order_relaxed);
|
||||
if (lock->waiters) {
|
||||
lock->waiters = 0;
|
||||
os_event_set(lock->event);
|
||||
sync_array_object_signalled();
|
||||
}
|
||||
} else if (lock_word == -X_LOCK_DECR
|
||||
|| lock_word == -(X_LOCK_DECR + X_LOCK_HALF_DECR)) {
|
||||
/* There are 2 x-locks */
|
||||
lock->lock_word.fetch_add(X_LOCK_DECR,
|
||||
std::memory_order_relaxed);
|
||||
lock->lock_word.fetch_add(X_LOCK_DECR);
|
||||
} else {
|
||||
/* There are more than 2 x-locks. */
|
||||
ut_ad(lock_word < -X_LOCK_DECR);
|
||||
lock->lock_word.fetch_add(1,
|
||||
std::memory_order_relaxed);
|
||||
lock->lock_word.fetch_add(1);
|
||||
}
|
||||
|
||||
ut_ad(rw_lock_validate(lock));
|
||||
|
@ -454,8 +443,7 @@ rw_lock_sx_unlock_func(
|
|||
ut_d(rw_lock_remove_debug_info(lock, pass, RW_LOCK_SX));
|
||||
|
||||
if (lock->sx_recursive == 0) {
|
||||
auto lock_word =
|
||||
lock->lock_word.load(std::memory_order_relaxed);
|
||||
int32_t lock_word = lock->lock_word;
|
||||
/* Last caller in a possible recursive chain. */
|
||||
if (lock_word > 0) {
|
||||
lock->writer_thread = 0;
|
||||
|
@ -472,8 +460,8 @@ rw_lock_sx_unlock_func(
|
|||
waiters. We do not need to signal wait_ex waiters,
|
||||
since they cannot exist when there is an sx-lock
|
||||
holder. */
|
||||
if (lock->waiters.load(std::memory_order_relaxed)) {
|
||||
lock->waiters.store(0, std::memory_order_relaxed);
|
||||
if (lock->waiters) {
|
||||
lock->waiters = 0;
|
||||
os_event_set(lock->event);
|
||||
sync_array_object_signalled();
|
||||
}
|
||||
|
@ -481,8 +469,7 @@ rw_lock_sx_unlock_func(
|
|||
/* still has x-lock */
|
||||
ut_ad(lock_word == -X_LOCK_HALF_DECR ||
|
||||
lock_word <= -(X_LOCK_DECR + X_LOCK_HALF_DECR));
|
||||
lock->lock_word.fetch_add(X_LOCK_HALF_DECR,
|
||||
std::memory_order_relaxed);
|
||||
lock->lock_word.fetch_add(X_LOCK_HALF_DECR);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1497,10 +1497,11 @@ row_fts_build_sel_tree(
|
|||
sel_tree[i + start] = int(i);
|
||||
}
|
||||
|
||||
for (i = treelevel; --i; ) {
|
||||
i = treelevel;
|
||||
do {
|
||||
row_fts_build_sel_tree_level(
|
||||
sel_tree, i, mrec, offsets, index);
|
||||
}
|
||||
sel_tree, --i, mrec, offsets, index);
|
||||
} while (i > 0);
|
||||
|
||||
return(treelevel);
|
||||
}
|
||||
|
|
|
@ -26,6 +26,9 @@ Created 2012-02-08 by Sunny Bains.
|
|||
|
||||
#include "row0import.h"
|
||||
#include "btr0pcur.h"
|
||||
#ifdef BTR_CUR_HASH_ADAPT
|
||||
# include "btr0sea.h"
|
||||
#endif
|
||||
#include "que0que.h"
|
||||
#include "dict0boot.h"
|
||||
#include "dict0load.h"
|
||||
|
@ -4048,15 +4051,12 @@ row_import_for_mysql(
|
|||
index entries that point to cached garbage pages in the buffer
|
||||
pool, because PageConverter::operator() only evicted those
|
||||
pages that were replaced by the imported pages. We must
|
||||
discard all remaining adaptive hash index entries, because the
|
||||
detach any remaining adaptive hash index entries, because the
|
||||
adaptive hash index must be a subset of the table contents;
|
||||
false positives are not tolerated. */
|
||||
while (buf_LRU_drop_page_hash_for_tablespace(table)) {
|
||||
if (trx_is_interrupted(trx)
|
||||
|| srv_shutdown_state != SRV_SHUTDOWN_NONE) {
|
||||
err = DB_INTERRUPTED;
|
||||
break;
|
||||
}
|
||||
for (dict_index_t* index = UT_LIST_GET_FIRST(table->indexes); index;
|
||||
index = UT_LIST_GET_NEXT(indexes, index)) {
|
||||
index = index->clone_if_needed();
|
||||
}
|
||||
#endif /* BTR_CUR_HASH_ADAPT */
|
||||
|
||||
|
|
|
@ -46,6 +46,9 @@ Completed by Sunny Bains and Marko Makela
|
|||
#include "row0vers.h"
|
||||
#include "handler0alter.h"
|
||||
#include "btr0bulk.h"
|
||||
#ifdef BTR_CUR_ADAPT
|
||||
# include "btr0sea.h"
|
||||
#endif /* BTR_CUR_ADAPT */
|
||||
#include "ut0stage.h"
|
||||
#include "fil0crypt.h"
|
||||
|
||||
|
@ -197,7 +200,6 @@ public:
|
|||
&ins_cur, 0,
|
||||
__FILE__, __LINE__, &mtr);
|
||||
|
||||
|
||||
error = btr_cur_pessimistic_insert(
|
||||
flag, &ins_cur, &ins_offsets,
|
||||
&row_heap, dtuple, &rec,
|
||||
|
@ -1957,8 +1959,7 @@ row_merge_read_clustered_index(
|
|||
goto scan_next;
|
||||
}
|
||||
|
||||
if (clust_index->lock.waiters.load(
|
||||
std::memory_order_relaxed)) {
|
||||
if (clust_index->lock.waiters) {
|
||||
/* There are waiters on the clustered
|
||||
index tree lock, likely the purge
|
||||
thread. Store and restore the cursor
|
||||
|
@ -3872,6 +3873,9 @@ row_merge_drop_indexes(
|
|||
we should exclude FTS entries from
|
||||
prebuilt->ins_node->entry_list
|
||||
in ins_node_create_entry_list(). */
|
||||
#ifdef BTR_CUR_HASH_ADAPT
|
||||
ut_ad(!index->search_info->ref_count);
|
||||
#endif /* BTR_CUR_HASH_ADAPT */
|
||||
dict_index_remove_from_cache(
|
||||
table, index);
|
||||
index = prev;
|
||||
|
|
|
@ -2563,6 +2563,9 @@ row_create_index_for_mysql(
|
|||
UT_BITS_IN_BYTES(unsigned(index->n_nullable)));
|
||||
|
||||
err = dict_create_index_tree_in_mem(index, trx);
|
||||
#ifdef BTR_CUR_HASH_ADAPT
|
||||
ut_ad(!index->search_info->ref_count);
|
||||
#endif /* BTR_CUR_HASH_ADAPT */
|
||||
|
||||
if (err != DB_SUCCESS) {
|
||||
dict_index_remove_from_cache(table, index);
|
||||
|
@ -3400,35 +3403,6 @@ row_drop_table_for_mysql(
|
|||
ut_ad(!(table->stats_bg_flag & BG_STAT_IN_PROGRESS));
|
||||
if (!table->no_rollback()) {
|
||||
if (table->space != fil_system.sys_space) {
|
||||
#ifdef BTR_CUR_HASH_ADAPT
|
||||
/* On DISCARD TABLESPACE, we would not drop the
|
||||
adaptive hash index entries. If the tablespace is
|
||||
missing here, delete-marking the record in SYS_INDEXES
|
||||
would not free any pages in the buffer pool. Thus,
|
||||
dict_index_remove_from_cache() would hang due to
|
||||
adaptive hash index entries existing in the buffer
|
||||
pool. To prevent this hang, and also to guarantee
|
||||
that btr_search_drop_page_hash_when_freed() will avoid
|
||||
calling btr_search_drop_page_hash_index() while we
|
||||
hold the InnoDB dictionary lock, we will drop any
|
||||
adaptive hash index entries upfront. */
|
||||
const bool immune = is_temp_name
|
||||
|| create_failed
|
||||
|| sqlcom == SQLCOM_CREATE_TABLE
|
||||
|| strstr(table->name.m_name, "/FTS");
|
||||
|
||||
while (buf_LRU_drop_page_hash_for_tablespace(table)) {
|
||||
if ((!immune && trx_is_interrupted(trx))
|
||||
|| srv_shutdown_state
|
||||
!= SRV_SHUTDOWN_NONE) {
|
||||
err = DB_INTERRUPTED;
|
||||
table->to_be_dropped = false;
|
||||
dict_table_close(table, true, false);
|
||||
goto funct_exit;
|
||||
}
|
||||
}
|
||||
#endif /* BTR_CUR_HASH_ADAPT */
|
||||
|
||||
/* Delete the link file if used. */
|
||||
if (DICT_TF_HAS_DATA_DIR(table->flags)) {
|
||||
RemoteDatafile::delete_link_file(name);
|
||||
|
|
|
@ -46,7 +46,6 @@ Created 3/14/1997 Heikki Tuuri
|
|||
#include "handler.h"
|
||||
#include "ha_innodb.h"
|
||||
#include "fil0fil.h"
|
||||
#include "debug_sync.h"
|
||||
|
||||
/*************************************************************************
|
||||
IMPORTANT NOTE: Any operation that generates redo MUST check that there
|
||||
|
|
|
@ -459,8 +459,6 @@ row_vers_build_clust_v_col(
|
|||
ut_ad(dict_index_has_virtual(index));
|
||||
ut_ad(index->table == clust_index->table);
|
||||
|
||||
DEBUG_SYNC(current_thd, "ib_clust_v_col_before_row_allocated");
|
||||
|
||||
innobase_allocate_row_for_vcol(thd, index,
|
||||
&local_heap,
|
||||
&maria_table,
|
||||
|
|
|
@ -2173,7 +2173,6 @@ void release_thd(THD *thd, void *ctx)
|
|||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
Called by timer when purge coordinator decides
|
||||
to delay processing of purge records.
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
Copyright (c) 1995, 2016, Oracle and/or its affiliates. All Rights Reserved.
|
||||
Copyright (c) 2008, Google Inc.
|
||||
Copyright (c) 2013, 2019, MariaDB Corporation.
|
||||
Copyright (c) 2013, 2020, MariaDB Corporation.
|
||||
|
||||
Portions of this file contain modifications contributed and copyrighted by
|
||||
Google, Inc. Those modifications are gratefully acknowledged and are described
|
||||
|
@ -595,8 +595,8 @@ sync_array_cell_print(
|
|||
#endif
|
||||
"\n",
|
||||
rw_lock_get_reader_count(rwlock),
|
||||
rwlock->waiters.load(std::memory_order_relaxed),
|
||||
rwlock->lock_word.load(std::memory_order_relaxed),
|
||||
uint32_t{rwlock->waiters},
|
||||
int32_t{rwlock->lock_word},
|
||||
innobase_basename(rwlock->last_x_file_name),
|
||||
rwlock->last_x_line
|
||||
#if 0 /* JAN: TODO: FIX LATER */
|
||||
|
@ -1384,10 +1384,10 @@ sync_arr_fill_sys_semphore_waits_table(
|
|||
//fields[SYS_SEMAPHORE_WAITS_HOLDER_LINE]->set_notnull();
|
||||
OK(fields[SYS_SEMAPHORE_WAITS_READERS]->store(rw_lock_get_reader_count(rwlock), true));
|
||||
OK(fields[SYS_SEMAPHORE_WAITS_WAITERS_FLAG]->store(
|
||||
rwlock->waiters.load(std::memory_order_relaxed),
|
||||
rwlock->waiters,
|
||||
true));
|
||||
OK(fields[SYS_SEMAPHORE_WAITS_LOCK_WORD]->store(
|
||||
rwlock->lock_word.load(std::memory_order_relaxed),
|
||||
rwlock->lock_word,
|
||||
true));
|
||||
OK(field_store_string(fields[SYS_SEMAPHORE_WAITS_LAST_WRITER_FILE], innobase_basename(rwlock->last_x_file_name)));
|
||||
OK(fields[SYS_SEMAPHORE_WAITS_LAST_WRITER_LINE]->store(rwlock->last_x_line, true));
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
Copyright (c) 1995, 2016, Oracle and/or its affiliates. All Rights Reserved.
|
||||
Copyright (c) 2008, 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
|
||||
|
@ -202,11 +202,8 @@ rw_lock_create_func(
|
|||
new(lock) rw_lock_t();
|
||||
#endif /* UNIV_DEBUG */
|
||||
|
||||
/* If this is the very first time a synchronization object is
|
||||
created, then the following call initializes the sync system. */
|
||||
|
||||
lock->lock_word.store(X_LOCK_DECR, std::memory_order_relaxed);
|
||||
lock->waiters.store(0, std::memory_order_relaxed);
|
||||
lock->lock_word = X_LOCK_DECR;
|
||||
lock->waiters = 0;
|
||||
|
||||
lock->sx_recursive = 0;
|
||||
lock->writer_thread= 0;
|
||||
|
@ -252,7 +249,7 @@ rw_lock_free_func(
|
|||
rw_lock_t* lock) /*!< in/out: rw-lock */
|
||||
{
|
||||
ut_ad(rw_lock_validate(lock));
|
||||
ut_a(lock->lock_word.load(std::memory_order_relaxed) == X_LOCK_DECR);
|
||||
ut_a(lock->lock_word == X_LOCK_DECR);
|
||||
|
||||
mutex_enter(&rw_lock_list_mutex);
|
||||
|
||||
|
@ -289,12 +286,15 @@ rw_lock_s_lock_spin(
|
|||
|
||||
ut_ad(rw_lock_validate(lock));
|
||||
|
||||
rw_lock_stats.rw_s_spin_wait_count.inc();
|
||||
|
||||
lock_loop:
|
||||
|
||||
/* Spin waiting for the writer field to become free */
|
||||
HMT_low();
|
||||
ulint j = i;
|
||||
while (i < srv_n_spin_wait_rounds &&
|
||||
lock->lock_word.load(std::memory_order_relaxed) <= 0) {
|
||||
lock->lock_word <= 0) {
|
||||
ut_delay(srv_spin_wait_delay);
|
||||
i++;
|
||||
}
|
||||
|
@ -304,7 +304,7 @@ lock_loop:
|
|||
os_thread_yield();
|
||||
}
|
||||
|
||||
++spin_count;
|
||||
spin_count += lint(i - j);
|
||||
|
||||
/* We try once again to obtain the lock */
|
||||
if (rw_lock_s_lock_low(lock, pass, file_name, line)) {
|
||||
|
@ -412,10 +412,10 @@ rw_lock_x_lock_wait_func(
|
|||
sync_array_t* sync_arr;
|
||||
int64_t count_os_wait = 0;
|
||||
|
||||
ut_ad(lock->lock_word.load(std::memory_order_relaxed) <= threshold);
|
||||
ut_ad(lock->lock_word <= threshold);
|
||||
|
||||
HMT_low();
|
||||
while (lock->lock_word.load(std::memory_order_relaxed) < threshold) {
|
||||
while (lock->lock_word < threshold) {
|
||||
ut_delay(srv_spin_wait_delay);
|
||||
|
||||
if (i < srv_n_spin_wait_rounds) {
|
||||
|
@ -424,7 +424,7 @@ rw_lock_x_lock_wait_func(
|
|||
}
|
||||
|
||||
/* If there is still a reader, then go to sleep.*/
|
||||
++n_spins;
|
||||
n_spins += i;
|
||||
|
||||
sync_cell_t* cell;
|
||||
|
||||
|
@ -434,8 +434,7 @@ rw_lock_x_lock_wait_func(
|
|||
i = 0;
|
||||
|
||||
/* Check lock_word to ensure wake-up isn't missed.*/
|
||||
if (lock->lock_word.load(std::memory_order_relaxed) < threshold) {
|
||||
|
||||
if (lock->lock_word < threshold) {
|
||||
++count_os_wait;
|
||||
|
||||
/* Add debug info as it is needed to detect possible
|
||||
|
@ -524,17 +523,15 @@ rw_lock_x_lock_low(
|
|||
file_name, line);
|
||||
|
||||
} else {
|
||||
auto lock_word = lock->lock_word.load(std::memory_order_relaxed);
|
||||
int32_t lock_word = lock->lock_word;
|
||||
/* At least one X lock by this thread already
|
||||
exists. Add another. */
|
||||
if (lock_word == 0
|
||||
|| lock_word == -X_LOCK_HALF_DECR) {
|
||||
lock->lock_word.fetch_sub(X_LOCK_DECR,
|
||||
std::memory_order_relaxed);
|
||||
lock->lock_word.fetch_sub(X_LOCK_DECR);
|
||||
} else {
|
||||
ut_ad(lock_word <= -X_LOCK_DECR);
|
||||
lock->lock_word.fetch_sub(1,
|
||||
std::memory_order_relaxed);
|
||||
lock->lock_word.fetch_sub(1);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -657,6 +654,12 @@ rw_lock_x_lock_func(
|
|||
ut_ad(rw_lock_validate(lock));
|
||||
ut_ad(!rw_lock_own(lock, RW_LOCK_S));
|
||||
|
||||
if (rw_lock_x_lock_low(lock, pass, file_name, line)) {
|
||||
/* Locking succeeded */
|
||||
return;
|
||||
}
|
||||
rw_lock_stats.rw_x_spin_wait_count.inc();
|
||||
|
||||
lock_loop:
|
||||
|
||||
if (rw_lock_x_lock_low(lock, pass, file_name, line)) {
|
||||
|
@ -676,14 +679,15 @@ lock_loop:
|
|||
|
||||
/* Spin waiting for the lock_word to become free */
|
||||
HMT_low();
|
||||
ulint j = i;
|
||||
while (i < srv_n_spin_wait_rounds
|
||||
&& lock->lock_word.load(std::memory_order_relaxed) <= X_LOCK_HALF_DECR) {
|
||||
&& lock->lock_word <= X_LOCK_HALF_DECR) {
|
||||
ut_delay(srv_spin_wait_delay);
|
||||
i++;
|
||||
}
|
||||
|
||||
HMT_medium();
|
||||
spin_count += lint(i);
|
||||
spin_count += lint(i - j);
|
||||
|
||||
if (i >= srv_n_spin_wait_rounds) {
|
||||
|
||||
|
@ -751,11 +755,17 @@ rw_lock_sx_lock_func(
|
|||
sync_array_t* sync_arr;
|
||||
lint spin_count = 0;
|
||||
int64_t count_os_wait = 0;
|
||||
lint spin_wait_count = 0;
|
||||
|
||||
ut_ad(rw_lock_validate(lock));
|
||||
ut_ad(!rw_lock_own(lock, RW_LOCK_S));
|
||||
|
||||
if (rw_lock_sx_lock_low(lock, pass, file_name, line)) {
|
||||
/* Locking succeeded */
|
||||
return;
|
||||
}
|
||||
|
||||
rw_lock_stats.rw_sx_spin_wait_count.inc();
|
||||
|
||||
lock_loop:
|
||||
|
||||
if (rw_lock_sx_lock_low(lock, pass, file_name, line)) {
|
||||
|
@ -767,23 +777,21 @@ lock_loop:
|
|||
}
|
||||
|
||||
rw_lock_stats.rw_sx_spin_round_count.add(spin_count);
|
||||
rw_lock_stats.rw_sx_spin_wait_count.add(spin_wait_count);
|
||||
|
||||
/* Locking succeeded */
|
||||
return;
|
||||
|
||||
} else {
|
||||
|
||||
++spin_wait_count;
|
||||
|
||||
/* Spin waiting for the lock_word to become free */
|
||||
ulint j = i;
|
||||
while (i < srv_n_spin_wait_rounds
|
||||
&& lock->lock_word.load(std::memory_order_relaxed) <= X_LOCK_HALF_DECR) {
|
||||
&& lock->lock_word <= X_LOCK_HALF_DECR) {
|
||||
ut_delay(srv_spin_wait_delay);
|
||||
i++;
|
||||
}
|
||||
|
||||
spin_count += lint(i);
|
||||
spin_count += lint(i - j);
|
||||
|
||||
if (i >= srv_n_spin_wait_rounds) {
|
||||
|
||||
|
@ -815,7 +823,6 @@ lock_loop:
|
|||
}
|
||||
|
||||
rw_lock_stats.rw_sx_spin_round_count.add(spin_count);
|
||||
rw_lock_stats.rw_sx_spin_wait_count.add(spin_wait_count);
|
||||
|
||||
/* Locking succeeded */
|
||||
return;
|
||||
|
@ -841,13 +848,11 @@ rw_lock_validate(
|
|||
/*=============*/
|
||||
const rw_lock_t* lock) /*!< in: rw-lock */
|
||||
{
|
||||
int32_t lock_word;
|
||||
|
||||
ut_ad(lock);
|
||||
|
||||
lock_word = lock->lock_word.load(std::memory_order_relaxed);
|
||||
int32_t lock_word = lock->lock_word;
|
||||
|
||||
ut_ad(lock->waiters.load(std::memory_order_relaxed) < 2);
|
||||
ut_ad(lock->waiters < 2);
|
||||
ut_ad(lock_word > -(2 * X_LOCK_DECR));
|
||||
ut_ad(lock_word <= X_LOCK_DECR);
|
||||
|
||||
|
@ -910,7 +915,7 @@ rw_lock_add_debug_info(
|
|||
rw_lock_debug_mutex_exit();
|
||||
|
||||
if (pass == 0 && lock_type != RW_LOCK_X_WAIT) {
|
||||
auto lock_word = lock->lock_word.load(std::memory_order_relaxed);
|
||||
int32_t lock_word = lock->lock_word;
|
||||
|
||||
/* Recursive x while holding SX
|
||||
(lock_type == RW_LOCK_X && lock_word == -X_LOCK_HALF_DECR)
|
||||
|
@ -1096,11 +1101,11 @@ rw_lock_list_print_info(
|
|||
|
||||
count++;
|
||||
|
||||
if (lock->lock_word.load(std::memory_order_relaxed) != X_LOCK_DECR) {
|
||||
if (lock->lock_word != X_LOCK_DECR) {
|
||||
|
||||
fprintf(file, "RW-LOCK: %p ", (void*) lock);
|
||||
|
||||
if (int32_t waiters= lock->waiters.load(std::memory_order_relaxed)) {
|
||||
if (int32_t waiters= lock->waiters) {
|
||||
fprintf(file, " (%d waiters)\n", waiters);
|
||||
} else {
|
||||
putc('\n', file);
|
||||
|
|
|
@ -369,7 +369,7 @@ trx_purge_free_segment(trx_rseg_t* rseg, fil_addr_t hdr_addr)
|
|||
|
||||
while (!fseg_free_step_not_header(
|
||||
TRX_UNDO_SEG_HDR + TRX_UNDO_FSEG_HEADER
|
||||
+ block->frame, false, &mtr)) {
|
||||
+ block->frame, &mtr)) {
|
||||
mutex_exit(&rseg->mutex);
|
||||
|
||||
mtr.commit();
|
||||
|
@ -405,7 +405,7 @@ trx_purge_free_segment(trx_rseg_t* rseg, fil_addr_t hdr_addr)
|
|||
fsp0fsp.cc. */
|
||||
|
||||
} while (!fseg_free_step(TRX_UNDO_SEG_HDR + TRX_UNDO_FSEG_HEADER
|
||||
+ block->frame, false, &mtr));
|
||||
+ block->frame, &mtr));
|
||||
|
||||
byte* hist = TRX_RSEG + TRX_RSEG_HISTORY_SIZE + rseg_hdr->frame;
|
||||
ut_ad(mach_read_from_4(hist) >= seg_size);
|
||||
|
|
|
@ -628,7 +628,7 @@ trx_undo_free_page(
|
|||
|
||||
fseg_free_page(TRX_UNDO_SEG_HDR + TRX_UNDO_FSEG_HEADER
|
||||
+ header_block->frame,
|
||||
rseg->space, page_no, false, mtr);
|
||||
rseg->space, page_no, mtr);
|
||||
|
||||
const fil_addr_t last_addr = flst_get_last(
|
||||
TRX_UNDO_SEG_HDR + TRX_UNDO_PAGE_LIST + header_block->frame);
|
||||
|
@ -813,7 +813,7 @@ static void trx_undo_seg_free(const trx_undo_t* undo, bool noredo)
|
|||
fseg_header_t* file_seg = TRX_UNDO_SEG_HDR
|
||||
+ TRX_UNDO_FSEG_HEADER + block->frame;
|
||||
|
||||
finished = fseg_free_step(file_seg, false, &mtr);
|
||||
finished = fseg_free_step(file_seg, &mtr);
|
||||
|
||||
if (finished) {
|
||||
/* Update the rseg header */
|
||||
|
|
|
@ -1115,5 +1115,13 @@ SELECT * FROM t1;
|
|||
a
|
||||
0
|
||||
DROP TABLE t1;
|
||||
#
|
||||
# MDEV-19622 Assertion failures in
|
||||
# ha_partition::set_auto_increment_if_higher upon UPDATE on Aria table
|
||||
#
|
||||
CREATE OR REPLACE TABLE t1 (pk INT AUTO_INCREMENT, a INT, KEY(pk)) ENGINE=myisam PARTITION BY HASH(a);
|
||||
INSERT INTO t1 VALUES (1,1),(2,2);
|
||||
UPDATE t1 SET pk = 0;
|
||||
DROP TABLE t1;
|
||||
##############################################################################
|
||||
SET GLOBAL tokudb_prelock_empty = @tokudb_prelock_empty_saved;
|
||||
|
|
Loading…
Add table
Reference in a new issue