mirror of
https://github.com/MariaDB/server.git
synced 2025-07-29 05:21:33 +03:00
Merge 10.1 into 10.2
This commit is contained in:
@ -101,18 +101,7 @@
|
|||||||
sort-buffer-size 2097152
|
sort-buffer-size 2097152
|
||||||
sql-mode STRICT_TRANS_TABLES,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION
|
sql-mode STRICT_TRANS_TABLES,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION
|
||||||
stack-trace TRUE
|
stack-trace TRUE
|
||||||
@@ -1516,14 +1532,16 @@
|
@@ -1516,6 +1532,8 @@
|
||||||
sync-relay-log 10000
|
|
||||||
sync-relay-log-info 10000
|
|
||||||
sysdate-is-now FALSE
|
|
||||||
-table-cache 421
|
|
||||||
+table-cache 2000
|
|
||||||
table-definition-cache 400
|
|
||||||
-table-open-cache 421
|
|
||||||
-table-open-cache-instances 1
|
|
||||||
+table-open-cache 2000
|
|
||||||
+table-open-cache-instances 8
|
|
||||||
tc-heuristic-recover OFF
|
|
||||||
thread-cache-size 151
|
thread-cache-size 151
|
||||||
thread-pool-idle-timeout 60
|
thread-pool-idle-timeout 60
|
||||||
thread-pool-max-threads 65536
|
thread-pool-max-threads 65536
|
||||||
|
@ -1343,7 +1343,6 @@ max-binlog-cache-size 18446744073709547520
|
|||||||
max-binlog-size 1073741824
|
max-binlog-size 1073741824
|
||||||
max-binlog-stmt-cache-size 18446744073709547520
|
max-binlog-stmt-cache-size 18446744073709547520
|
||||||
max-connect-errors 100
|
max-connect-errors 100
|
||||||
max-connections 151
|
|
||||||
max-delayed-threads 20
|
max-delayed-threads 20
|
||||||
max-digest-length 1024
|
max-digest-length 1024
|
||||||
max-error-count 64
|
max-error-count 64
|
||||||
@ -1516,10 +1515,7 @@ sync-master-info 10000
|
|||||||
sync-relay-log 10000
|
sync-relay-log 10000
|
||||||
sync-relay-log-info 10000
|
sync-relay-log-info 10000
|
||||||
sysdate-is-now FALSE
|
sysdate-is-now FALSE
|
||||||
table-cache 421
|
|
||||||
table-definition-cache 400
|
table-definition-cache 400
|
||||||
table-open-cache 421
|
|
||||||
table-open-cache-instances 1
|
|
||||||
tc-heuristic-recover OFF
|
tc-heuristic-recover OFF
|
||||||
thread-cache-size 151
|
thread-cache-size 151
|
||||||
thread-pool-idle-timeout 60
|
thread-pool-idle-timeout 60
|
||||||
|
@ -2609,6 +2609,47 @@ Central America and the Caribbean 442 66422
|
|||||||
SET @@optimizer_switch= @save_optimizer_switch;
|
SET @@optimizer_switch= @save_optimizer_switch;
|
||||||
DROP TABLE t1;
|
DROP TABLE t1;
|
||||||
#
|
#
|
||||||
|
# MDEV-9513: Assertion `join->group_list || !join->is_in_subquery()' failed in create_sort_index
|
||||||
|
#
|
||||||
|
CREATE TABLE t1 (a INT);
|
||||||
|
INSERT INTO t1 VALUES (1),(2);
|
||||||
|
CREATE TABLE t2 (a INT);
|
||||||
|
INSERT INTO t2 VALUES (2),(3);
|
||||||
|
EXPLAIN
|
||||||
|
SELECT t1.a FROM t1 WHERE t1.a IN ( SELECT A.a FROM t1 A UNION SELECT B.a FROM t2 B ORDER BY 1);
|
||||||
|
id select_type table type possible_keys key key_len ref rows Extra
|
||||||
|
1 PRIMARY t1 ALL NULL NULL NULL NULL 2 Using where
|
||||||
|
2 DEPENDENT SUBQUERY A ALL NULL NULL NULL NULL 2 Using where
|
||||||
|
3 DEPENDENT UNION B ALL NULL NULL NULL NULL 2 Using where
|
||||||
|
NULL UNION RESULT <union2,3> ALL NULL NULL NULL NULL NULL
|
||||||
|
SELECT t1.a FROM t1 WHERE t1.a IN ( SELECT A.a FROM t1 A UNION SELECT B.a FROM t2 B ORDER BY 1);
|
||||||
|
a
|
||||||
|
1
|
||||||
|
2
|
||||||
|
EXPLAIN
|
||||||
|
SELECT t1.a FROM t1 WHERE EXISTS (SELECT A.a FROM t1 A UNION SELECT B.a FROM t2 B ORDER BY 1);
|
||||||
|
id select_type table type possible_keys key key_len ref rows Extra
|
||||||
|
1 PRIMARY t1 ALL NULL NULL NULL NULL 2
|
||||||
|
2 SUBQUERY A ALL NULL NULL NULL NULL 2
|
||||||
|
3 UNION B ALL NULL NULL NULL NULL 2
|
||||||
|
NULL UNION RESULT <union2,3> ALL NULL NULL NULL NULL NULL
|
||||||
|
SELECT t1.a FROM t1 WHERE EXISTS (SELECT A.a FROM t1 A UNION SELECT B.a FROM t2 B ORDER BY 1);
|
||||||
|
a
|
||||||
|
1
|
||||||
|
2
|
||||||
|
EXPLAIN
|
||||||
|
SELECT t1.a FROM t1 WHERE t1.a IN ( SELECT A.a FROM t1 A UNION ALL SELECT B.a FROM t2 B ORDER BY 1);
|
||||||
|
id select_type table type possible_keys key key_len ref rows Extra
|
||||||
|
1 PRIMARY t1 ALL NULL NULL NULL NULL 2 Using where
|
||||||
|
2 DEPENDENT SUBQUERY A ALL NULL NULL NULL NULL 2 Using where
|
||||||
|
3 DEPENDENT UNION B ALL NULL NULL NULL NULL 2 Using where
|
||||||
|
SELECT t1.a FROM t1 WHERE t1.a IN ( SELECT A.a FROM t1 A UNION ALL SELECT B.a FROM t2 B ORDER BY 1);
|
||||||
|
a
|
||||||
|
1
|
||||||
|
2
|
||||||
|
DROP TABLE t1,t2;
|
||||||
|
# end of 10.1 tests
|
||||||
|
#
|
||||||
# MDEV-22852: SIGSEGV in sortlength (optimized builds)
|
# MDEV-22852: SIGSEGV in sortlength (optimized builds)
|
||||||
#
|
#
|
||||||
SET @save_optimizer_switch=@@optimizer_switch;
|
SET @save_optimizer_switch=@@optimizer_switch;
|
||||||
|
@ -2340,6 +2340,53 @@ t1 CREATE TABLE `t1` (
|
|||||||
) ENGINE=MyISAM DEFAULT CHARSET=latin1
|
) ENGINE=MyISAM DEFAULT CHARSET=latin1
|
||||||
DROP TABLE t1;
|
DROP TABLE t1;
|
||||||
#
|
#
|
||||||
|
# MDEV-23105 Cast number string with many leading zeros to decimal gives unexpected result
|
||||||
|
#
|
||||||
|
SELECT CAST(0000000000000000000000000000000000000000000000000000000000000000000000000000000020.01 AS DECIMAL(15,2)) as val;
|
||||||
|
val
|
||||||
|
20.01
|
||||||
|
SET sql_mode='';
|
||||||
|
CREATE TABLE t1 (a TEXT);
|
||||||
|
INSERT INTO t1 VALUES (CONCAT(REPEAT('0',100),1));
|
||||||
|
INSERT INTO t1 VALUES (CONCAT(REPEAT('0',100),1,'.0'));
|
||||||
|
INSERT INTO t1 VALUES (CONCAT(REPEAT('0',100),1,'.9'));
|
||||||
|
INSERT INTO t1 VALUES (CONCAT(REPEAT('0',100),1,'.99'));
|
||||||
|
INSERT INTO t1 VALUES (CONCAT(REPEAT('0',100),1,'.994'));
|
||||||
|
INSERT INTO t1 VALUES (CONCAT(REPEAT('0',100),1,'.995'));
|
||||||
|
INSERT INTO t1 VALUES (CONCAT(REPEAT('0',100),1,'.999'));
|
||||||
|
CREATE TABLE t2 (a TEXT, d DECIMAL(15,2));
|
||||||
|
INSERT IGNORE INTO t2 (a,d) SELECT a, a FROM t1;
|
||||||
|
Warnings:
|
||||||
|
Note 1265 Data truncated for column 'd' at row 5
|
||||||
|
Note 1265 Data truncated for column 'd' at row 6
|
||||||
|
Note 1265 Data truncated for column 'd' at row 7
|
||||||
|
INSERT IGNORE INTO t2 (a,d) SELECT CONCAT('-',a), CONCAT('-',a) FROM t1;
|
||||||
|
Warnings:
|
||||||
|
Note 1265 Data truncated for column 'd' at row 5
|
||||||
|
Note 1265 Data truncated for column 'd' at row 6
|
||||||
|
Note 1265 Data truncated for column 'd' at row 7
|
||||||
|
SELECT d, a FROM t2 ORDER BY d,a;
|
||||||
|
d a
|
||||||
|
-2.00 -00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001.995
|
||||||
|
-2.00 -00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001.999
|
||||||
|
-1.99 -00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001.99
|
||||||
|
-1.99 -00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001.994
|
||||||
|
-1.90 -00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001.9
|
||||||
|
-1.00 -00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001
|
||||||
|
-1.00 -00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001.0
|
||||||
|
1.00 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001
|
||||||
|
1.00 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001.0
|
||||||
|
1.90 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001.9
|
||||||
|
1.99 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001.99
|
||||||
|
1.99 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001.994
|
||||||
|
2.00 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001.995
|
||||||
|
2.00 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001.999
|
||||||
|
DROP TABLE t1, t2;
|
||||||
|
SET sql_mode=DEFAULT;
|
||||||
|
#
|
||||||
|
# End of 10.1 tests
|
||||||
|
#
|
||||||
|
#
|
||||||
# Bug#18408499 UNSIGNED BIGINT HIGH VALUES
|
# Bug#18408499 UNSIGNED BIGINT HIGH VALUES
|
||||||
# WRONG NUMERICAL COMPARISON RESULTS
|
# WRONG NUMERICAL COMPARISON RESULTS
|
||||||
#
|
#
|
||||||
|
@ -23,7 +23,9 @@ perl;
|
|||||||
log-slow-queries pid-file slow-query-log-file log-basename
|
log-slow-queries pid-file slow-query-log-file log-basename
|
||||||
datadir slave-load-tmpdir tmpdir socket thread-pool-size
|
datadir slave-load-tmpdir tmpdir socket thread-pool-size
|
||||||
large-files-support lower-case-file-system system-time-zone
|
large-files-support lower-case-file-system system-time-zone
|
||||||
collation-server character-set-server log-tc-size version.*/;
|
collation-server character-set-server log-tc-size table-cache
|
||||||
|
table-open-cache table-open-cache-instances max-connections
|
||||||
|
version.*/;
|
||||||
|
|
||||||
# Plugins which may or may not be there:
|
# Plugins which may or may not be there:
|
||||||
@plugins=qw/innodb archive blackhole federated partition
|
@plugins=qw/innodb archive blackhole federated partition
|
||||||
|
@ -2143,6 +2143,31 @@ SET @@optimizer_switch= @save_optimizer_switch;
|
|||||||
|
|
||||||
DROP TABLE t1;
|
DROP TABLE t1;
|
||||||
|
|
||||||
|
--echo #
|
||||||
|
--echo # MDEV-9513: Assertion `join->group_list || !join->is_in_subquery()' failed in create_sort_index
|
||||||
|
--echo #
|
||||||
|
|
||||||
|
CREATE TABLE t1 (a INT);
|
||||||
|
INSERT INTO t1 VALUES (1),(2);
|
||||||
|
|
||||||
|
CREATE TABLE t2 (a INT);
|
||||||
|
INSERT INTO t2 VALUES (2),(3);
|
||||||
|
EXPLAIN
|
||||||
|
SELECT t1.a FROM t1 WHERE t1.a IN ( SELECT A.a FROM t1 A UNION SELECT B.a FROM t2 B ORDER BY 1);
|
||||||
|
SELECT t1.a FROM t1 WHERE t1.a IN ( SELECT A.a FROM t1 A UNION SELECT B.a FROM t2 B ORDER BY 1);
|
||||||
|
|
||||||
|
EXPLAIN
|
||||||
|
SELECT t1.a FROM t1 WHERE EXISTS (SELECT A.a FROM t1 A UNION SELECT B.a FROM t2 B ORDER BY 1);
|
||||||
|
SELECT t1.a FROM t1 WHERE EXISTS (SELECT A.a FROM t1 A UNION SELECT B.a FROM t2 B ORDER BY 1);
|
||||||
|
|
||||||
|
EXPLAIN
|
||||||
|
SELECT t1.a FROM t1 WHERE t1.a IN ( SELECT A.a FROM t1 A UNION ALL SELECT B.a FROM t2 B ORDER BY 1);
|
||||||
|
SELECT t1.a FROM t1 WHERE t1.a IN ( SELECT A.a FROM t1 A UNION ALL SELECT B.a FROM t2 B ORDER BY 1);
|
||||||
|
|
||||||
|
DROP TABLE t1,t2;
|
||||||
|
|
||||||
|
--echo # end of 10.1 tests
|
||||||
|
|
||||||
--echo #
|
--echo #
|
||||||
--echo # MDEV-22852: SIGSEGV in sortlength (optimized builds)
|
--echo # MDEV-22852: SIGSEGV in sortlength (optimized builds)
|
||||||
--echo #
|
--echo #
|
||||||
|
@ -1824,6 +1824,32 @@ CREATE TABLE t1 (a DECIMAL(2,1) DEFAULT 0.10001e0);
|
|||||||
SHOW CREATE TABLE t1;
|
SHOW CREATE TABLE t1;
|
||||||
DROP TABLE t1;
|
DROP TABLE t1;
|
||||||
|
|
||||||
|
--echo #
|
||||||
|
--echo # MDEV-23105 Cast number string with many leading zeros to decimal gives unexpected result
|
||||||
|
--echo #
|
||||||
|
|
||||||
|
SELECT CAST(0000000000000000000000000000000000000000000000000000000000000000000000000000000020.01 AS DECIMAL(15,2)) as val;
|
||||||
|
|
||||||
|
SET sql_mode='';
|
||||||
|
CREATE TABLE t1 (a TEXT);
|
||||||
|
INSERT INTO t1 VALUES (CONCAT(REPEAT('0',100),1));
|
||||||
|
INSERT INTO t1 VALUES (CONCAT(REPEAT('0',100),1,'.0'));
|
||||||
|
INSERT INTO t1 VALUES (CONCAT(REPEAT('0',100),1,'.9'));
|
||||||
|
INSERT INTO t1 VALUES (CONCAT(REPEAT('0',100),1,'.99'));
|
||||||
|
INSERT INTO t1 VALUES (CONCAT(REPEAT('0',100),1,'.994'));
|
||||||
|
INSERT INTO t1 VALUES (CONCAT(REPEAT('0',100),1,'.995'));
|
||||||
|
INSERT INTO t1 VALUES (CONCAT(REPEAT('0',100),1,'.999'));
|
||||||
|
CREATE TABLE t2 (a TEXT, d DECIMAL(15,2));
|
||||||
|
INSERT IGNORE INTO t2 (a,d) SELECT a, a FROM t1;
|
||||||
|
INSERT IGNORE INTO t2 (a,d) SELECT CONCAT('-',a), CONCAT('-',a) FROM t1;
|
||||||
|
SELECT d, a FROM t2 ORDER BY d,a;
|
||||||
|
DROP TABLE t1, t2;
|
||||||
|
SET sql_mode=DEFAULT;
|
||||||
|
|
||||||
|
--echo #
|
||||||
|
--echo # End of 10.1 tests
|
||||||
|
--echo #
|
||||||
|
|
||||||
--echo #
|
--echo #
|
||||||
--echo # Bug#18408499 UNSIGNED BIGINT HIGH VALUES
|
--echo # Bug#18408499 UNSIGNED BIGINT HIGH VALUES
|
||||||
--echo # WRONG NUMERICAL COMPARISON RESULTS
|
--echo # WRONG NUMERICAL COMPARISON RESULTS
|
||||||
|
@ -145,6 +145,10 @@ public:
|
|||||||
Item_subselect(THD *thd);
|
Item_subselect(THD *thd);
|
||||||
|
|
||||||
virtual subs_type substype() { return UNKNOWN_SUBS; }
|
virtual subs_type substype() { return UNKNOWN_SUBS; }
|
||||||
|
bool is_exists_predicate()
|
||||||
|
{
|
||||||
|
return substype() == Item_subselect::EXISTS_SUBS;
|
||||||
|
}
|
||||||
bool is_in_predicate()
|
bool is_in_predicate()
|
||||||
{
|
{
|
||||||
return (substype() == Item_subselect::IN_SUBS ||
|
return (substype() == Item_subselect::IN_SUBS ||
|
||||||
|
@ -514,6 +514,25 @@ bool st_select_lex_unit::prepare(THD *thd_arg, select_result *sel_result,
|
|||||||
found_rows_for_union= first_sl->options & OPTION_FOUND_ROWS;
|
found_rows_for_union= first_sl->options & OPTION_FOUND_ROWS;
|
||||||
is_union_select= is_union() || fake_select_lex;
|
is_union_select= is_union() || fake_select_lex;
|
||||||
|
|
||||||
|
/*
|
||||||
|
If we are reading UNION output and the UNION is in the
|
||||||
|
IN/ANY/ALL/EXISTS subquery, then ORDER BY is redundant and hence should
|
||||||
|
be removed.
|
||||||
|
Example:
|
||||||
|
select ... col IN (select col2 FROM t1 union select col3 from t2 ORDER BY 1)
|
||||||
|
|
||||||
|
(as for ORDER BY ... LIMIT, it currently not supported inside
|
||||||
|
IN/ALL/ANY subqueries)
|
||||||
|
(For non-UNION this removal of ORDER BY clause is done in
|
||||||
|
check_and_do_in_subquery_rewrites())
|
||||||
|
*/
|
||||||
|
if (is_union() && item &&
|
||||||
|
(item->is_in_predicate() || item->is_exists_predicate()))
|
||||||
|
{
|
||||||
|
global_parameters()->order_list.first= NULL;
|
||||||
|
global_parameters()->order_list.elements= 0;
|
||||||
|
}
|
||||||
|
|
||||||
/* Global option */
|
/* Global option */
|
||||||
|
|
||||||
if (is_union_select || is_recursive)
|
if (is_union_select || is_recursive)
|
||||||
|
13
sql/table.h
13
sql/table.h
@ -1281,9 +1281,16 @@ public:
|
|||||||
/* number of select if it is derived table */
|
/* number of select if it is derived table */
|
||||||
uint derived_select_number;
|
uint derived_select_number;
|
||||||
/*
|
/*
|
||||||
0 or JOIN_TYPE_{LEFT|RIGHT}. Currently this is only compared to 0.
|
Possible values:
|
||||||
If maybe_null !=0, this table is inner w.r.t. some outer join operation,
|
- 0 by default
|
||||||
and null_row may be true.
|
- JOIN_TYPE_{LEFT|RIGHT} if the table is inner w.r.t an outer join
|
||||||
|
operation
|
||||||
|
- 1 if the SELECT has mixed_implicit_grouping=1. example:
|
||||||
|
select max(col1), col2 from t1. In this case, the query produces
|
||||||
|
one row with all columns having NULL values.
|
||||||
|
|
||||||
|
Interpetation: If maybe_null!=0, all fields of the table are considered
|
||||||
|
NULLable (and have NULL values when null_row=true)
|
||||||
*/
|
*/
|
||||||
uint maybe_null;
|
uint maybe_null;
|
||||||
int current_lock; /* Type of lock on table */
|
int current_lock; /* Type of lock on table */
|
||||||
|
@ -41,9 +41,6 @@ Modified Jan Lindström jan.lindstrom@mariadb.com
|
|||||||
#include "fil0pagecompress.h"
|
#include "fil0pagecompress.h"
|
||||||
#include <my_crypt.h>
|
#include <my_crypt.h>
|
||||||
|
|
||||||
/** Mutex for keys */
|
|
||||||
static ib_mutex_t fil_crypt_key_mutex;
|
|
||||||
|
|
||||||
static bool fil_crypt_threads_inited = false;
|
static bool fil_crypt_threads_inited = false;
|
||||||
|
|
||||||
/** Is encryption enabled/disabled */
|
/** Is encryption enabled/disabled */
|
||||||
@ -113,8 +110,6 @@ UNIV_INTERN
|
|||||||
void
|
void
|
||||||
fil_space_crypt_init()
|
fil_space_crypt_init()
|
||||||
{
|
{
|
||||||
mutex_create(LATCH_ID_FIL_CRYPT_MUTEX, &fil_crypt_key_mutex);
|
|
||||||
|
|
||||||
fil_crypt_throttle_sleep_event = os_event_create(0);
|
fil_crypt_throttle_sleep_event = os_event_create(0);
|
||||||
|
|
||||||
mutex_create(LATCH_ID_FIL_CRYPT_STAT_MUTEX, &crypt_stat_mutex);
|
mutex_create(LATCH_ID_FIL_CRYPT_STAT_MUTEX, &crypt_stat_mutex);
|
||||||
@ -128,7 +123,6 @@ void
|
|||||||
fil_space_crypt_cleanup()
|
fil_space_crypt_cleanup()
|
||||||
{
|
{
|
||||||
os_event_destroy(fil_crypt_throttle_sleep_event);
|
os_event_destroy(fil_crypt_throttle_sleep_event);
|
||||||
mutex_free(&fil_crypt_key_mutex);
|
|
||||||
mutex_free(&crypt_stat_mutex);
|
mutex_free(&crypt_stat_mutex);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1384,6 +1378,94 @@ fil_crypt_return_iops(
|
|||||||
fil_crypt_update_total_stat(state);
|
fil_crypt_update_total_stat(state);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Return the next tablespace from rotation_list.
|
||||||
|
@param space previous tablespace (NULL to start from the start)
|
||||||
|
@param recheck whether the removal condition needs to be rechecked after
|
||||||
|
the encryption parameters were changed
|
||||||
|
@param encrypt expected state of innodb_encrypt_tables
|
||||||
|
@return the next tablespace to process (n_pending_ops incremented)
|
||||||
|
@retval NULL if this was the last */
|
||||||
|
inline fil_space_t *fil_system_t::keyrotate_next(fil_space_t *space,
|
||||||
|
bool recheck, bool encrypt)
|
||||||
|
{
|
||||||
|
ut_ad(mutex_own(&fil_system->mutex));
|
||||||
|
|
||||||
|
sized_ilist<fil_space_t, rotation_list_tag_t>::iterator it=
|
||||||
|
space ? space : fil_system->rotation_list.begin();
|
||||||
|
const sized_ilist<fil_space_t, rotation_list_tag_t>::iterator end=
|
||||||
|
fil_system->rotation_list.end();
|
||||||
|
|
||||||
|
if (space)
|
||||||
|
{
|
||||||
|
while (++it != end && (!UT_LIST_GET_LEN(it->chain) || it->is_stopping()));
|
||||||
|
|
||||||
|
/* If one of the encryption threads already started the encryption
|
||||||
|
of the table then don't remove the unencrypted spaces from rotation list
|
||||||
|
|
||||||
|
If there is a change in innodb_encrypt_tables variables value then
|
||||||
|
don't remove the last processed tablespace from the rotation list. */
|
||||||
|
if (!--space->n_pending_ops &&
|
||||||
|
(!recheck || space->crypt_data) && !encrypt == !srv_encrypt_tables &&
|
||||||
|
space->is_in_rotation_list)
|
||||||
|
{
|
||||||
|
ut_a(!fil_system->rotation_list.empty());
|
||||||
|
fil_system->rotation_list.remove(*space);
|
||||||
|
space->is_in_rotation_list= false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (it == end)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
space= &*it;
|
||||||
|
space->n_pending_ops++;
|
||||||
|
return space;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Return the next tablespace.
|
||||||
|
@param space previous tablespace (NULL to start from the beginning)
|
||||||
|
@param recheck whether the removal condition needs to be rechecked after
|
||||||
|
the encryption parameters were changed
|
||||||
|
@param encrypt expected state of innodb_encrypt_tables
|
||||||
|
@return pointer to the next tablespace (with n_pending_ops incremented)
|
||||||
|
@retval NULL if this was the last */
|
||||||
|
static fil_space_t *fil_space_next(fil_space_t *space, bool recheck,
|
||||||
|
bool encrypt)
|
||||||
|
{
|
||||||
|
mutex_enter(&fil_system->mutex);
|
||||||
|
ut_ad(!space || space->n_pending_ops);
|
||||||
|
|
||||||
|
if (!srv_fil_crypt_rotate_key_age)
|
||||||
|
space= fil_system->keyrotate_next(space, recheck, encrypt);
|
||||||
|
else if (!space)
|
||||||
|
{
|
||||||
|
space= UT_LIST_GET_FIRST(fil_system->space_list);
|
||||||
|
/* We can trust that space is not NULL because at least the
|
||||||
|
system tablespace is always present and loaded first. */
|
||||||
|
space->n_pending_ops++;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ut_ad(space->n_pending_ops > 0);
|
||||||
|
/* Move on to the next fil_space_t */
|
||||||
|
space->n_pending_ops--;
|
||||||
|
space= UT_LIST_GET_NEXT(space_list, space);
|
||||||
|
|
||||||
|
/* Skip abnormal tablespaces or those that are being created by
|
||||||
|
fil_ibd_create(), or being dropped. */
|
||||||
|
while (space &&
|
||||||
|
(UT_LIST_GET_LEN(space->chain) == 0 ||
|
||||||
|
space->is_stopping() || space->purpose != FIL_TYPE_TABLESPACE))
|
||||||
|
space= UT_LIST_GET_NEXT(space_list, space);
|
||||||
|
|
||||||
|
if (space)
|
||||||
|
space->n_pending_ops++;
|
||||||
|
}
|
||||||
|
|
||||||
|
mutex_exit(&fil_system->mutex);
|
||||||
|
return space;
|
||||||
|
}
|
||||||
|
|
||||||
/** Search for a space needing rotation
|
/** Search for a space needing rotation
|
||||||
@param[in,out] key_state Key state
|
@param[in,out] key_state Key state
|
||||||
@param[in,out] state Rotation state
|
@param[in,out] state Rotation state
|
||||||
@ -1416,16 +1498,8 @@ static bool fil_crypt_find_space_to_rotate(
|
|||||||
state->space = NULL;
|
state->space = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* If key rotation is enabled (default) we iterate all tablespaces.
|
state->space = fil_space_next(state->space, *recheck,
|
||||||
If key rotation is not enabled we iterate only the tablespaces
|
key_state->key_version != 0);
|
||||||
added to keyrotation list. */
|
|
||||||
if (srv_fil_crypt_rotate_key_age) {
|
|
||||||
state->space = fil_space_next(state->space);
|
|
||||||
} else {
|
|
||||||
state->space = fil_system->keyrotate_next(
|
|
||||||
state->space, *recheck,
|
|
||||||
key_state->key_version);
|
|
||||||
}
|
|
||||||
|
|
||||||
while (!state->should_shutdown() && state->space) {
|
while (!state->should_shutdown() && state->space) {
|
||||||
/* If there is no crypt data and we have not yet read
|
/* If there is no crypt data and we have not yet read
|
||||||
@ -1443,16 +1517,16 @@ static bool fil_crypt_find_space_to_rotate(
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (srv_fil_crypt_rotate_key_age) {
|
state->space = fil_space_next(state->space, *recheck,
|
||||||
state->space = fil_space_next(state->space);
|
key_state->key_version != 0);
|
||||||
} else {
|
|
||||||
state->space = fil_system->keyrotate_next(
|
|
||||||
state->space, *recheck,
|
|
||||||
key_state->key_version);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* if we didn't find any space return iops */
|
if (state->space) {
|
||||||
|
fil_space_release(state->space);
|
||||||
|
state->space = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* no work to do; release our allocation of I/O capacity */
|
||||||
fil_crypt_return_iops(state);
|
fil_crypt_return_iops(state);
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
|
@ -5892,136 +5892,6 @@ fil_space_t::release_free_extents(ulint n_reserved)
|
|||||||
n_reserved_extents -= n_reserved;
|
n_reserved_extents -= n_reserved;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Return the next fil_space_t.
|
|
||||||
Once started, the caller must keep calling this until it returns NULL.
|
|
||||||
fil_space_acquire() and fil_space_release() are invoked here which
|
|
||||||
blocks a concurrent operation from dropping the tablespace.
|
|
||||||
@param[in] prev_space Pointer to the previous fil_space_t.
|
|
||||||
If NULL, use the first fil_space_t on fil_system->space_list.
|
|
||||||
@return pointer to the next fil_space_t.
|
|
||||||
@retval NULL if this was the last*/
|
|
||||||
fil_space_t*
|
|
||||||
fil_space_next(fil_space_t* prev_space)
|
|
||||||
{
|
|
||||||
fil_space_t* space=prev_space;
|
|
||||||
|
|
||||||
mutex_enter(&fil_system->mutex);
|
|
||||||
|
|
||||||
if (prev_space == NULL) {
|
|
||||||
space = UT_LIST_GET_FIRST(fil_system->space_list);
|
|
||||||
|
|
||||||
/* We can trust that space is not NULL because at least the
|
|
||||||
system tablespace is always present and loaded first. */
|
|
||||||
space->n_pending_ops++;
|
|
||||||
} else {
|
|
||||||
ut_ad(space->n_pending_ops > 0);
|
|
||||||
|
|
||||||
/* Move on to the next fil_space_t */
|
|
||||||
space->n_pending_ops--;
|
|
||||||
space = UT_LIST_GET_NEXT(space_list, space);
|
|
||||||
|
|
||||||
/* Skip spaces that are being created by
|
|
||||||
fil_ibd_create(), or dropped, or !tablespace. */
|
|
||||||
while (space != NULL
|
|
||||||
&& (UT_LIST_GET_LEN(space->chain) == 0
|
|
||||||
|| space->is_stopping()
|
|
||||||
|| space->purpose != FIL_TYPE_TABLESPACE)) {
|
|
||||||
space = UT_LIST_GET_NEXT(space_list, space);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (space != NULL) {
|
|
||||||
space->n_pending_ops++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
mutex_exit(&fil_system->mutex);
|
|
||||||
|
|
||||||
return(space);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
Remove space from key rotation list if there are no more
|
|
||||||
pending operations.
|
|
||||||
@param[in,out] space Tablespace */
|
|
||||||
static
|
|
||||||
void
|
|
||||||
fil_space_remove_from_keyrotation(fil_space_t* space)
|
|
||||||
{
|
|
||||||
ut_ad(mutex_own(&fil_system->mutex));
|
|
||||||
ut_ad(space);
|
|
||||||
|
|
||||||
if (space->n_pending_ops == 0 && space->is_in_rotation_list) {
|
|
||||||
ut_a(!fil_system->rotation_list.empty());
|
|
||||||
fil_system->rotation_list.remove(*space);
|
|
||||||
space->is_in_rotation_list = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/** Return the next fil_space_t from key rotation list.
|
|
||||||
Once started, the caller must keep calling this until it returns NULL.
|
|
||||||
fil_space_acquire() and fil_space_release() are invoked here which
|
|
||||||
blocks a concurrent operation from dropping the tablespace.
|
|
||||||
@param[in] prev_space Previous tablespace or NULL to start
|
|
||||||
from beginning of fil_system->rotation list
|
|
||||||
@param[in] recheck recheck of the tablespace is needed or
|
|
||||||
still encryption thread does write page0 for it
|
|
||||||
@param[in] key_version key version of the key state thread
|
|
||||||
If NULL, use the first fil_space_t on fil_system->space_list.
|
|
||||||
@return pointer to the next fil_space_t.
|
|
||||||
@retval NULL if this was the last */
|
|
||||||
fil_space_t *fil_system_t::keyrotate_next(fil_space_t *prev_space,
|
|
||||||
bool recheck, uint key_version)
|
|
||||||
{
|
|
||||||
mutex_enter(&fil_system->mutex);
|
|
||||||
|
|
||||||
/* If one of the encryption threads already started the encryption
|
|
||||||
of the table then don't remove the unencrypted spaces from rotation list
|
|
||||||
|
|
||||||
If there is a change in innodb_encrypt_tables variables value then
|
|
||||||
don't remove the last processed tablespace from the rotation list. */
|
|
||||||
const bool remove= (!recheck || prev_space->crypt_data) &&
|
|
||||||
!key_version == !srv_encrypt_tables;
|
|
||||||
sized_ilist<fil_space_t, rotation_list_tag_t>::iterator it=
|
|
||||||
prev_space == NULL ? fil_system->rotation_list.end() : prev_space;
|
|
||||||
|
|
||||||
if (it == fil_system->rotation_list.end())
|
|
||||||
{
|
|
||||||
it= fil_system->rotation_list.begin();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
ut_ad(prev_space->n_pending_ops > 0);
|
|
||||||
|
|
||||||
/* Move on to the next fil_space_t */
|
|
||||||
prev_space->n_pending_ops--;
|
|
||||||
|
|
||||||
++it;
|
|
||||||
|
|
||||||
while (it != fil_system->rotation_list.end() &&
|
|
||||||
(UT_LIST_GET_LEN(it->chain) == 0 || it->is_stopping()))
|
|
||||||
{
|
|
||||||
++it;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (remove)
|
|
||||||
{
|
|
||||||
fil_space_remove_from_keyrotation(prev_space);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fil_space_t *space= it == fil_system->rotation_list.end() ? NULL : &*it;
|
|
||||||
|
|
||||||
if (space)
|
|
||||||
{
|
|
||||||
space->n_pending_ops++;
|
|
||||||
}
|
|
||||||
|
|
||||||
mutex_exit(&fil_system->mutex);
|
|
||||||
|
|
||||||
return space;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Determine the block size of the data file.
|
/** Determine the block size of the data file.
|
||||||
@param[in] space tablespace
|
@param[in] space tablespace
|
||||||
@param[in] offset page number
|
@param[in] offset page number
|
||||||
|
@ -556,24 +556,15 @@ struct fil_system_t {
|
|||||||
@retval NULL if the tablespace does not exist or cannot be read */
|
@retval NULL if the tablespace does not exist or cannot be read */
|
||||||
fil_space_t* read_page0(ulint id);
|
fil_space_t* read_page0(ulint id);
|
||||||
|
|
||||||
/** Return the next fil_space_t from key rotation list.
|
/** Return the next tablespace from rotation_list.
|
||||||
Once started, the caller must keep calling this until it returns NULL.
|
@param space previous tablespace (NULL to start from the start)
|
||||||
fil_space_acquire() and fil_space_release() are invoked here which
|
@param recheck whether the removal condition needs to be rechecked after
|
||||||
blocks a concurrent operation from dropping the tablespace.
|
the encryption parameters were changed
|
||||||
@param[in] prev_space Previous tablespace or NULL to start
|
@param encrypt expected state of innodb_encrypt_tables
|
||||||
from beginning of fil_system->rotation
|
@return the next tablespace to process (n_pending_ops incremented)
|
||||||
list
|
@retval NULL if this was the last */
|
||||||
@param[in] recheck recheck of the tablespace is needed or
|
inline fil_space_t* keyrotate_next(fil_space_t *space, bool recheck,
|
||||||
still encryption thread does write page0
|
bool encrypt);
|
||||||
for it
|
|
||||||
@param[in] key_version key version of the key state thread
|
|
||||||
If NULL, use the first fil_space_t on fil_system->space_list.
|
|
||||||
@return pointer to the next fil_space_t.
|
|
||||||
@retval NULL if this was the last */
|
|
||||||
fil_space_t* keyrotate_next(
|
|
||||||
fil_space_t* prev_space,
|
|
||||||
bool remove,
|
|
||||||
uint key_version);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/** The tablespace memory cache. This variable is NULL before the module is
|
/** The tablespace memory cache. This variable is NULL before the module is
|
||||||
@ -803,34 +794,6 @@ fil_space_acquire_for_io(ulint id);
|
|||||||
void
|
void
|
||||||
fil_space_release_for_io(fil_space_t* space);
|
fil_space_release_for_io(fil_space_t* space);
|
||||||
|
|
||||||
/** Return the next fil_space_t.
|
|
||||||
Once started, the caller must keep calling this until it returns NULL.
|
|
||||||
fil_space_acquire() and fil_space_release() are invoked here which
|
|
||||||
blocks a concurrent operation from dropping the tablespace.
|
|
||||||
@param[in,out] prev_space Pointer to the previous fil_space_t.
|
|
||||||
If NULL, use the first fil_space_t on fil_system->space_list.
|
|
||||||
@return pointer to the next fil_space_t.
|
|
||||||
@retval NULL if this was the last */
|
|
||||||
fil_space_t*
|
|
||||||
fil_space_next(
|
|
||||||
fil_space_t* prev_space)
|
|
||||||
MY_ATTRIBUTE((warn_unused_result));
|
|
||||||
|
|
||||||
/** Return the next fil_space_t from key rotation list.
|
|
||||||
Once started, the caller must keep calling this until it returns NULL.
|
|
||||||
fil_space_acquire() and fil_space_release() are invoked here which
|
|
||||||
blocks a concurrent operation from dropping the tablespace.
|
|
||||||
@param[in] prev_space Previous tablespace or NULL to start
|
|
||||||
from beginning of fil_system->rotation list
|
|
||||||
@param[in] remove Whether to remove the previous tablespace from
|
|
||||||
the rotation list
|
|
||||||
If NULL, use the first fil_space_t on fil_system->space_list.
|
|
||||||
@return pointer to the next fil_space_t.
|
|
||||||
@retval NULL if this was the last*/
|
|
||||||
fil_space_t*
|
|
||||||
fil_space_keyrotate_next(fil_space_t* prev_space, bool remove)
|
|
||||||
MY_ATTRIBUTE((warn_unused_result));
|
|
||||||
|
|
||||||
/** Wrapper with reference-counting for a fil_space_t. */
|
/** Wrapper with reference-counting for a fil_space_t. */
|
||||||
class FilSpace
|
class FilSpace
|
||||||
{
|
{
|
||||||
|
@ -379,7 +379,6 @@ enum latch_id_t {
|
|||||||
LATCH_ID_BTR_DEFRAGMENT_MUTEX,
|
LATCH_ID_BTR_DEFRAGMENT_MUTEX,
|
||||||
LATCH_ID_MTFLUSH_THREAD_MUTEX,
|
LATCH_ID_MTFLUSH_THREAD_MUTEX,
|
||||||
LATCH_ID_MTFLUSH_MUTEX,
|
LATCH_ID_MTFLUSH_MUTEX,
|
||||||
LATCH_ID_FIL_CRYPT_MUTEX,
|
|
||||||
LATCH_ID_FIL_CRYPT_STAT_MUTEX,
|
LATCH_ID_FIL_CRYPT_STAT_MUTEX,
|
||||||
LATCH_ID_FIL_CRYPT_DATA_MUTEX,
|
LATCH_ID_FIL_CRYPT_DATA_MUTEX,
|
||||||
LATCH_ID_FIL_CRYPT_THREADS_MUTEX,
|
LATCH_ID_FIL_CRYPT_THREADS_MUTEX,
|
||||||
|
@ -1511,8 +1511,6 @@ sync_latch_meta_init()
|
|||||||
PFS_NOT_INSTRUMENTED);
|
PFS_NOT_INSTRUMENTED);
|
||||||
LATCH_ADD_MUTEX(MTFLUSH_MUTEX, SYNC_NO_ORDER_CHECK,
|
LATCH_ADD_MUTEX(MTFLUSH_MUTEX, SYNC_NO_ORDER_CHECK,
|
||||||
PFS_NOT_INSTRUMENTED);
|
PFS_NOT_INSTRUMENTED);
|
||||||
LATCH_ADD_MUTEX(FIL_CRYPT_MUTEX, SYNC_NO_ORDER_CHECK,
|
|
||||||
PFS_NOT_INSTRUMENTED);
|
|
||||||
LATCH_ADD_MUTEX(FIL_CRYPT_STAT_MUTEX, SYNC_NO_ORDER_CHECK,
|
LATCH_ADD_MUTEX(FIL_CRYPT_STAT_MUTEX, SYNC_NO_ORDER_CHECK,
|
||||||
PFS_NOT_INSTRUMENTED);
|
PFS_NOT_INSTRUMENTED);
|
||||||
LATCH_ADD_MUTEX(FIL_CRYPT_DATA_MUTEX, SYNC_NO_ORDER_CHECK,
|
LATCH_ADD_MUTEX(FIL_CRYPT_DATA_MUTEX, SYNC_NO_ORDER_CHECK,
|
||||||
|
@ -44,15 +44,8 @@ Modified Jan Lindström jan.lindstrom@mariadb.com
|
|||||||
#include "ha_prototypes.h" // IB_LOG_
|
#include "ha_prototypes.h" // IB_LOG_
|
||||||
#include <my_crypt.h>
|
#include <my_crypt.h>
|
||||||
|
|
||||||
/** Mutex for keys */
|
|
||||||
static ib_mutex_t fil_crypt_key_mutex;
|
|
||||||
|
|
||||||
static bool fil_crypt_threads_inited = false;
|
static bool fil_crypt_threads_inited = false;
|
||||||
|
|
||||||
#ifdef UNIV_PFS_MUTEX
|
|
||||||
static mysql_pfs_key_t fil_crypt_key_mutex_key;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/** Is encryption enabled/disabled */
|
/** Is encryption enabled/disabled */
|
||||||
UNIV_INTERN ulong srv_encrypt_tables = 0;
|
UNIV_INTERN ulong srv_encrypt_tables = 0;
|
||||||
|
|
||||||
@ -133,9 +126,6 @@ UNIV_INTERN
|
|||||||
void
|
void
|
||||||
fil_space_crypt_init()
|
fil_space_crypt_init()
|
||||||
{
|
{
|
||||||
mutex_create(fil_crypt_key_mutex_key,
|
|
||||||
&fil_crypt_key_mutex, SYNC_NO_ORDER_CHECK);
|
|
||||||
|
|
||||||
fil_crypt_throttle_sleep_event = os_event_create();
|
fil_crypt_throttle_sleep_event = os_event_create();
|
||||||
|
|
||||||
mutex_create(fil_crypt_stat_mutex_key,
|
mutex_create(fil_crypt_stat_mutex_key,
|
||||||
@ -152,7 +142,6 @@ fil_space_crypt_cleanup()
|
|||||||
{
|
{
|
||||||
os_event_free(fil_crypt_throttle_sleep_event);
|
os_event_free(fil_crypt_throttle_sleep_event);
|
||||||
fil_crypt_throttle_sleep_event = NULL;
|
fil_crypt_throttle_sleep_event = NULL;
|
||||||
mutex_free(&fil_crypt_key_mutex);
|
|
||||||
mutex_free(&crypt_stat_mutex);
|
mutex_free(&crypt_stat_mutex);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1451,6 +1440,109 @@ fil_crypt_return_iops(
|
|||||||
fil_crypt_update_total_stat(state);
|
fil_crypt_update_total_stat(state);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Remove space from key rotation list if there are no pending operations. */
|
||||||
|
static void fil_space_remove_from_keyrotation(fil_space_t *space)
|
||||||
|
{
|
||||||
|
ut_ad(mutex_own(&fil_system->mutex));
|
||||||
|
|
||||||
|
if (space->n_pending_ops == 0 && space->is_in_rotation_list)
|
||||||
|
{
|
||||||
|
space->is_in_rotation_list= false;
|
||||||
|
ut_a(UT_LIST_GET_LEN(fil_system->rotation_list) > 0);
|
||||||
|
UT_LIST_REMOVE(rotation_list, fil_system->rotation_list, space);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Return the next tablespace from key rotation list.
|
||||||
|
@param space previous tablespace (NULL to start from the beginning)
|
||||||
|
@return pointer to the next tablespace (with n_pending_ops incremented)
|
||||||
|
@retval NULL if this was the last */
|
||||||
|
static fil_space_t *fil_space_keyrotate_next(fil_space_t *space)
|
||||||
|
{
|
||||||
|
ut_ad(mutex_own(&fil_system->mutex));
|
||||||
|
|
||||||
|
if (UT_LIST_GET_LEN(fil_system->rotation_list) == 0)
|
||||||
|
{
|
||||||
|
if (space)
|
||||||
|
{
|
||||||
|
space->n_pending_ops--;
|
||||||
|
fil_space_remove_from_keyrotation(space);
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!space)
|
||||||
|
{
|
||||||
|
space= UT_LIST_GET_FIRST(fil_system->rotation_list);
|
||||||
|
/* We can trust that space is not NULL because we
|
||||||
|
checked list length above */
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
space->n_pending_ops--;
|
||||||
|
fil_space_t *old = space;
|
||||||
|
space= UT_LIST_GET_NEXT(rotation_list, space);
|
||||||
|
fil_space_remove_from_keyrotation(old);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Skip spaces that are being created by fil_ibd_create(),
|
||||||
|
or dropped. Note that rotation_list contains only
|
||||||
|
space->purpose == FIL_TABLESPACE. */
|
||||||
|
while (space && (!UT_LIST_GET_LEN(space->chain) || space->is_stopping()))
|
||||||
|
{
|
||||||
|
fil_space_t *old = space;
|
||||||
|
space= UT_LIST_GET_NEXT(rotation_list, space);
|
||||||
|
fil_space_remove_from_keyrotation(old);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (space)
|
||||||
|
space->n_pending_ops++;
|
||||||
|
|
||||||
|
return space;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Return the next tablespace.
|
||||||
|
@param space previous tablespace (NULL to start from the beginning)
|
||||||
|
@return pointer to the next tablespace (with n_pending_ops incremented)
|
||||||
|
@retval NULL if this was the last */
|
||||||
|
static fil_space_t *fil_space_next(fil_space_t *space)
|
||||||
|
{
|
||||||
|
mutex_enter(&fil_system->mutex);
|
||||||
|
ut_ad(!space || space->n_pending_ops);
|
||||||
|
|
||||||
|
if (!srv_fil_crypt_rotate_key_age)
|
||||||
|
space= fil_space_keyrotate_next(space);
|
||||||
|
else if (!space)
|
||||||
|
{
|
||||||
|
space= UT_LIST_GET_FIRST(fil_system->space_list);
|
||||||
|
/* We can trust that space is not NULL because at least the
|
||||||
|
system tablespace is always present and loaded first. */
|
||||||
|
space->n_pending_ops++;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ut_ad(space->n_pending_ops > 0);
|
||||||
|
/* Move on to the next fil_space_t */
|
||||||
|
space->n_pending_ops--;
|
||||||
|
space= UT_LIST_GET_NEXT(space_list, space);
|
||||||
|
|
||||||
|
/* Skip abnormal tablespaces or those that are being created by
|
||||||
|
fil_ibd_create(), or being dropped. */
|
||||||
|
while (space &&
|
||||||
|
(UT_LIST_GET_LEN(space->chain) == 0 ||
|
||||||
|
space->is_stopping() || space->purpose != FIL_TABLESPACE))
|
||||||
|
space= UT_LIST_GET_NEXT(space_list, space);
|
||||||
|
|
||||||
|
if (space)
|
||||||
|
space->n_pending_ops++;
|
||||||
|
}
|
||||||
|
|
||||||
|
mutex_exit(&fil_system->mutex);
|
||||||
|
|
||||||
|
return space;
|
||||||
|
}
|
||||||
|
|
||||||
/***********************************************************************
|
/***********************************************************************
|
||||||
Search for a space needing rotation
|
Search for a space needing rotation
|
||||||
@param[in,out] key_state Key state
|
@param[in,out] key_state Key state
|
||||||
@ -1485,14 +1577,7 @@ fil_crypt_find_space_to_rotate(
|
|||||||
state->space = NULL;
|
state->space = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* If key rotation is enabled (default) we iterate all tablespaces.
|
state->space = fil_space_next(state->space);
|
||||||
If key rotation is not enabled we iterate only the tablespaces
|
|
||||||
added to keyrotation list. */
|
|
||||||
if (srv_fil_crypt_rotate_key_age) {
|
|
||||||
state->space = fil_space_next(state->space);
|
|
||||||
} else {
|
|
||||||
state->space = fil_space_keyrotate_next(state->space);
|
|
||||||
}
|
|
||||||
|
|
||||||
while (!state->should_shutdown() && state->space) {
|
while (!state->should_shutdown() && state->space) {
|
||||||
fil_crypt_read_crypt_data(state->space);
|
fil_crypt_read_crypt_data(state->space);
|
||||||
@ -1505,14 +1590,15 @@ fil_crypt_find_space_to_rotate(
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (srv_fil_crypt_rotate_key_age) {
|
state->space = fil_space_next(state->space);
|
||||||
state->space = fil_space_next(state->space);
|
|
||||||
} else {
|
|
||||||
state->space = fil_space_keyrotate_next(state->space);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* if we didn't find any space return iops */
|
if (state->space) {
|
||||||
|
fil_space_release(state->space);
|
||||||
|
state->space = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* no work to do; release our allocation of I/O capacity */
|
||||||
fil_crypt_return_iops(state);
|
fil_crypt_return_iops(state);
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
|
@ -6863,137 +6863,3 @@ fil_space_release(fil_space_t* space)
|
|||||||
space->n_pending_ops--;
|
space->n_pending_ops--;
|
||||||
mutex_exit(&fil_system->mutex);
|
mutex_exit(&fil_system->mutex);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Return the next fil_space_t.
|
|
||||||
Once started, the caller must keep calling this until it returns NULL.
|
|
||||||
fil_space_acquire() and fil_space_release() are invoked here which
|
|
||||||
blocks a concurrent operation from dropping the tablespace.
|
|
||||||
@param[in] prev_space Pointer to the previous fil_space_t.
|
|
||||||
If NULL, use the first fil_space_t on fil_system->space_list.
|
|
||||||
@return pointer to the next fil_space_t.
|
|
||||||
@retval NULL if this was the last*/
|
|
||||||
UNIV_INTERN
|
|
||||||
fil_space_t*
|
|
||||||
fil_space_next(fil_space_t* prev_space)
|
|
||||||
{
|
|
||||||
fil_space_t* space=prev_space;
|
|
||||||
|
|
||||||
mutex_enter(&fil_system->mutex);
|
|
||||||
|
|
||||||
if (prev_space == NULL) {
|
|
||||||
space = UT_LIST_GET_FIRST(fil_system->space_list);
|
|
||||||
|
|
||||||
/* We can trust that space is not NULL because at least the
|
|
||||||
system tablespace is always present and loaded first. */
|
|
||||||
space->n_pending_ops++;
|
|
||||||
} else {
|
|
||||||
ut_ad(space->n_pending_ops > 0);
|
|
||||||
|
|
||||||
/* Move on to the next fil_space_t */
|
|
||||||
space->n_pending_ops--;
|
|
||||||
space = UT_LIST_GET_NEXT(space_list, space);
|
|
||||||
|
|
||||||
/* Skip spaces that are being created by
|
|
||||||
fil_ibd_create(), or dropped, or !tablespace. */
|
|
||||||
while (space != NULL
|
|
||||||
&& (UT_LIST_GET_LEN(space->chain) == 0
|
|
||||||
|| space->is_stopping()
|
|
||||||
|| space->purpose != FIL_TABLESPACE)) {
|
|
||||||
space = UT_LIST_GET_NEXT(space_list, space);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (space != NULL) {
|
|
||||||
space->n_pending_ops++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
mutex_exit(&fil_system->mutex);
|
|
||||||
|
|
||||||
return(space);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
Remove space from key rotation list if there are no more
|
|
||||||
pending operations.
|
|
||||||
@param[in] space Tablespace */
|
|
||||||
static
|
|
||||||
void
|
|
||||||
fil_space_remove_from_keyrotation(
|
|
||||||
fil_space_t* space)
|
|
||||||
{
|
|
||||||
ut_ad(mutex_own(&fil_system->mutex));
|
|
||||||
ut_ad(space);
|
|
||||||
|
|
||||||
if (space->n_pending_ops == 0 && space->is_in_rotation_list) {
|
|
||||||
space->is_in_rotation_list = false;
|
|
||||||
ut_a(UT_LIST_GET_LEN(fil_system->rotation_list) > 0);
|
|
||||||
UT_LIST_REMOVE(rotation_list, fil_system->rotation_list, space);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/** Return the next fil_space_t from key rotation list.
|
|
||||||
Once started, the caller must keep calling this until it returns NULL.
|
|
||||||
fil_space_acquire() and fil_space_release() are invoked here which
|
|
||||||
blocks a concurrent operation from dropping the tablespace.
|
|
||||||
@param[in] prev_space Pointer to the previous fil_space_t.
|
|
||||||
If NULL, use the first fil_space_t on fil_system->space_list.
|
|
||||||
@return pointer to the next fil_space_t.
|
|
||||||
@retval NULL if this was the last*/
|
|
||||||
UNIV_INTERN
|
|
||||||
fil_space_t*
|
|
||||||
fil_space_keyrotate_next(
|
|
||||||
fil_space_t* prev_space)
|
|
||||||
{
|
|
||||||
fil_space_t* space = prev_space;
|
|
||||||
fil_space_t* old = NULL;
|
|
||||||
|
|
||||||
mutex_enter(&fil_system->mutex);
|
|
||||||
|
|
||||||
if (UT_LIST_GET_LEN(fil_system->rotation_list) == 0) {
|
|
||||||
if (space) {
|
|
||||||
ut_ad(space->n_pending_ops > 0);
|
|
||||||
space->n_pending_ops--;
|
|
||||||
fil_space_remove_from_keyrotation(space);
|
|
||||||
}
|
|
||||||
mutex_exit(&fil_system->mutex);
|
|
||||||
return(NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (prev_space == NULL) {
|
|
||||||
space = UT_LIST_GET_FIRST(fil_system->rotation_list);
|
|
||||||
|
|
||||||
/* We can trust that space is not NULL because we
|
|
||||||
checked list length above */
|
|
||||||
} else {
|
|
||||||
ut_ad(space->n_pending_ops > 0);
|
|
||||||
|
|
||||||
/* Move on to the next fil_space_t */
|
|
||||||
space->n_pending_ops--;
|
|
||||||
|
|
||||||
old = space;
|
|
||||||
space = UT_LIST_GET_NEXT(rotation_list, space);
|
|
||||||
|
|
||||||
fil_space_remove_from_keyrotation(old);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Skip spaces that are being created by fil_ibd_create(),
|
|
||||||
or dropped. Note that rotation_list contains only
|
|
||||||
space->purpose == FIL_TABLESPACE. */
|
|
||||||
while (space != NULL
|
|
||||||
&& (UT_LIST_GET_LEN(space->chain) == 0
|
|
||||||
|| space->is_stopping())) {
|
|
||||||
|
|
||||||
old = space;
|
|
||||||
space = UT_LIST_GET_NEXT(rotation_list, space);
|
|
||||||
fil_space_remove_from_keyrotation(old);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (space != NULL) {
|
|
||||||
space->n_pending_ops++;
|
|
||||||
}
|
|
||||||
|
|
||||||
mutex_exit(&fil_system->mutex);
|
|
||||||
|
|
||||||
return(space);
|
|
||||||
}
|
|
||||||
|
@ -705,34 +705,6 @@ UNIV_INTERN
|
|||||||
void
|
void
|
||||||
fil_space_release_for_io(fil_space_t* space);
|
fil_space_release_for_io(fil_space_t* space);
|
||||||
|
|
||||||
/** Return the next fil_space_t.
|
|
||||||
Once started, the caller must keep calling this until it returns NULL.
|
|
||||||
fil_space_acquire() and fil_space_release() are invoked here which
|
|
||||||
blocks a concurrent operation from dropping the tablespace.
|
|
||||||
@param[in,out] prev_space Pointer to the previous fil_space_t.
|
|
||||||
If NULL, use the first fil_space_t on fil_system->space_list.
|
|
||||||
@return pointer to the next fil_space_t.
|
|
||||||
@retval NULL if this was the last */
|
|
||||||
UNIV_INTERN
|
|
||||||
fil_space_t*
|
|
||||||
fil_space_next(
|
|
||||||
fil_space_t* prev_space)
|
|
||||||
MY_ATTRIBUTE((warn_unused_result));
|
|
||||||
|
|
||||||
/** Return the next fil_space_t from key rotation list.
|
|
||||||
Once started, the caller must keep calling this until it returns NULL.
|
|
||||||
fil_space_acquire() and fil_space_release() are invoked here which
|
|
||||||
blocks a concurrent operation from dropping the tablespace.
|
|
||||||
@param[in,out] prev_space Pointer to the previous fil_space_t.
|
|
||||||
If NULL, use the first fil_space_t on fil_system->space_list.
|
|
||||||
@return pointer to the next fil_space_t.
|
|
||||||
@retval NULL if this was the last*/
|
|
||||||
UNIV_INTERN
|
|
||||||
fil_space_t*
|
|
||||||
fil_space_keyrotate_next(
|
|
||||||
fil_space_t* prev_space)
|
|
||||||
MY_ATTRIBUTE((warn_unused_result));
|
|
||||||
|
|
||||||
/** Wrapper with reference-counting for a fil_space_t. */
|
/** Wrapper with reference-counting for a fil_space_t. */
|
||||||
class FilSpace
|
class FilSpace
|
||||||
{
|
{
|
||||||
|
@ -812,6 +812,24 @@ internal_str2dec(const char *from, decimal_t *to, char **end, my_bool fixed)
|
|||||||
while (s < end_of_string && my_isdigit(&my_charset_latin1, *s))
|
while (s < end_of_string && my_isdigit(&my_charset_latin1, *s))
|
||||||
s++;
|
s++;
|
||||||
intg= (int) (s-s1);
|
intg= (int) (s-s1);
|
||||||
|
/*
|
||||||
|
If the integer part is long enough and it has multiple leading zeros,
|
||||||
|
let's trim them, so this expression can return 1 without overflowing:
|
||||||
|
CAST(CONCAT(REPEAT('0',90),'1') AS DECIMAL(10))
|
||||||
|
*/
|
||||||
|
if (intg > DIG_PER_DEC1 && s1[0] == '0' && s1[1] == '0')
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
Keep at least one digit, to avoid an empty string.
|
||||||
|
So we trim '0000' to '0' rather than to ''.
|
||||||
|
Otherwise the below code (converting digits to to->buf)
|
||||||
|
would fail on a fatal error.
|
||||||
|
*/
|
||||||
|
const char *iend= s - 1;
|
||||||
|
for ( ; s1 < iend && *s1 == '0'; s1++)
|
||||||
|
{ }
|
||||||
|
intg= (int) (s-s1);
|
||||||
|
}
|
||||||
if (s < end_of_string && *s=='.')
|
if (s < end_of_string && *s=='.')
|
||||||
{
|
{
|
||||||
endp= s+1;
|
endp= s+1;
|
||||||
|
Reference in New Issue
Block a user