mirror of
https://github.com/MariaDB/server.git
synced 2025-11-25 17:25:02 +03:00
Merge 10.4 into 10.5
This commit is contained in:
@@ -1,7 +1,6 @@
|
|||||||
Code status:
|
Code status:
|
||||||
------------
|
------------
|
||||||
|
|
||||||
* [](https://travis-ci.org/MariaDB/server) travis-ci.org (10.5 branch)
|
|
||||||
* [](https://ci.appveyor.com/project/rasmushoj/server) ci.appveyor.com
|
* [](https://ci.appveyor.com/project/rasmushoj/server) ci.appveyor.com
|
||||||
|
|
||||||
## MariaDB: The open source relational database
|
## MariaDB: The open source relational database
|
||||||
@@ -78,5 +77,3 @@ https://mariadb.org/about/security-policy/
|
|||||||
|
|
||||||
The code for MariaDB, including all revision history, can be found at:
|
The code for MariaDB, including all revision history, can be found at:
|
||||||
https://github.com/MariaDB/server
|
https://github.com/MariaDB/server
|
||||||
|
|
||||||
***************************************************************************
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/* Copyright (c) 2000, 2013, Oracle and/or its affiliates.
|
/* Copyright (c) 2000, 2013, Oracle and/or its affiliates.
|
||||||
Copyright (c) 2009, 2020, MariaDB
|
Copyright (c) 2009, 2021, MariaDB
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
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
|
it under the terms of the GNU General Public License as published by
|
||||||
@@ -91,6 +91,8 @@ static my_bool non_blocking_api_enabled= 0;
|
|||||||
|
|
||||||
#define QUERY_PRINT_ORIGINAL_FLAG 4
|
#define QUERY_PRINT_ORIGINAL_FLAG 4
|
||||||
|
|
||||||
|
#define CLOSED_CONNECTION "-closed_connection-"
|
||||||
|
|
||||||
#ifndef HAVE_SETENV
|
#ifndef HAVE_SETENV
|
||||||
static int setenv(const char *name, const char *value, int overwrite);
|
static int setenv(const char *name, const char *value, int overwrite);
|
||||||
#endif
|
#endif
|
||||||
@@ -5583,11 +5585,13 @@ void do_close_connection(struct st_command *command)
|
|||||||
my_free(con->name);
|
my_free(con->name);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
When the connection is closed set name to "-closed_connection-"
|
When the connection is closed set name to CLOSED_CONNECTION
|
||||||
to make it possible to reuse the connection name.
|
to make it possible to reuse the connection name.
|
||||||
*/
|
*/
|
||||||
if (!(con->name = my_strdup(PSI_NOT_INSTRUMENTED, "-closed_connection-", MYF(MY_WME))))
|
if (!(con->name = my_strdup(PSI_NOT_INSTRUMENTED, CLOSED_CONNECTION,
|
||||||
|
MYF(MY_WME))))
|
||||||
die("Out of memory");
|
die("Out of memory");
|
||||||
|
con->name_len= sizeof(CLOSED_CONNECTION)-1;
|
||||||
|
|
||||||
if (con == cur_con)
|
if (con == cur_con)
|
||||||
{
|
{
|
||||||
@@ -5990,7 +5994,7 @@ void do_connect(struct st_command *command)
|
|||||||
con_slot= next_con;
|
con_slot= next_con;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (!(con_slot= find_connection_by_name("-closed_connection-")))
|
if (!(con_slot= find_connection_by_name(CLOSED_CONNECTION)))
|
||||||
die("Connection limit exhausted, you can have max %d connections",
|
die("Connection limit exhausted, you can have max %d connections",
|
||||||
opt_max_connections);
|
opt_max_connections);
|
||||||
my_free(con_slot->name);
|
my_free(con_slot->name);
|
||||||
@@ -8603,7 +8607,7 @@ void run_query(struct st_connection *cn, struct st_command *command, int flags)
|
|||||||
log_file.flush();
|
log_file.flush();
|
||||||
dynstr_set(&ds_res, 0);
|
dynstr_set(&ds_res, 0);
|
||||||
|
|
||||||
if (view_protocol_enabled &&
|
if (view_protocol_enabled && mysql &&
|
||||||
complete_query &&
|
complete_query &&
|
||||||
match_re(&view_re, query))
|
match_re(&view_re, query))
|
||||||
{
|
{
|
||||||
@@ -8649,7 +8653,7 @@ void run_query(struct st_connection *cn, struct st_command *command, int flags)
|
|||||||
dynstr_free(&query_str);
|
dynstr_free(&query_str);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sp_protocol_enabled &&
|
if (sp_protocol_enabled && mysql &&
|
||||||
complete_query &&
|
complete_query &&
|
||||||
match_re(&sp_re, query))
|
match_re(&sp_re, query))
|
||||||
{
|
{
|
||||||
@@ -9012,7 +9016,7 @@ static void dump_backtrace(void)
|
|||||||
struct st_connection *conn= cur_con;
|
struct st_connection *conn= cur_con;
|
||||||
|
|
||||||
fprintf(stderr, "read_command_buf (%p): ", read_command_buf);
|
fprintf(stderr, "read_command_buf (%p): ", read_command_buf);
|
||||||
my_safe_print_str(read_command_buf, sizeof(read_command_buf));
|
fprintf(stderr, "%.*s\n", (int)read_command_buflen, read_command_buf);
|
||||||
fputc('\n', stderr);
|
fputc('\n', stderr);
|
||||||
|
|
||||||
if (conn)
|
if (conn)
|
||||||
|
|||||||
@@ -75,7 +75,9 @@ FOREACH(file ${ABI_HEADERS})
|
|||||||
FILE(REMOVE ${tmpfile})
|
FILE(REMOVE ${tmpfile})
|
||||||
EXECUTE_PROCESS(
|
EXECUTE_PROCESS(
|
||||||
COMMAND diff -w ${file}.pp ${abi_check_out} RESULT_VARIABLE result)
|
COMMAND diff -w ${file}.pp ${abi_check_out} RESULT_VARIABLE result)
|
||||||
IF(NOT ${result} EQUAL 0)
|
IF(result MATCHES "No such file or directory")
|
||||||
|
MESSAGE("Command 'diff' not found. ABI check for ${file} skipped.")
|
||||||
|
ELSEIF(NOT result EQUAL 0)
|
||||||
IF(ABI_UPDATE)
|
IF(ABI_UPDATE)
|
||||||
EXECUTE_PROCESS(COMMAND mv -v ${abi_check_out} ${file}.pp)
|
EXECUTE_PROCESS(COMMAND mv -v ${abi_check_out} ${file}.pp)
|
||||||
ELSE(ABI_UPDATE)
|
ELSE(ABI_UPDATE)
|
||||||
@@ -85,4 +87,3 @@ FOREACH(file ${ABI_HEADERS})
|
|||||||
ENDIF()
|
ENDIF()
|
||||||
FILE(REMOVE ${abi_check_out})
|
FILE(REMOVE ${abi_check_out})
|
||||||
ENDFOREACH()
|
ENDFOREACH()
|
||||||
|
|
||||||
|
|||||||
22
cmake/os/OpenBSD.cmake
Normal file
22
cmake/os/OpenBSD.cmake
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
# Copyright (C) 2012 Monty Program Ab, 2021 Brad Smith
|
||||||
|
#
|
||||||
|
# This program is free software; you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
# the Free Software Foundation; version 2 of the License.
|
||||||
|
#
|
||||||
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with this program; if not, write to the Free Software
|
||||||
|
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1335 USA
|
||||||
|
|
||||||
|
# This file includes OpenBSD specific options and quirks, related to system checks
|
||||||
|
|
||||||
|
# Find libexecinfo (library that contains backtrace_symbols etc)
|
||||||
|
FIND_LIBRARY(EXECINFO NAMES execinfo)
|
||||||
|
IF(EXECINFO)
|
||||||
|
SET(LIBEXECINFO ${EXECINFO})
|
||||||
|
ENDIF()
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
Copyright (c) 2005, 2016, Oracle and/or its affiliates. All rights reserved.
|
Copyright (c) 2005, 2016, Oracle and/or its affiliates. All rights reserved.
|
||||||
Copyright (c) 2014, 2020, MariaDB Corporation.
|
Copyright (c) 2014, 2021, MariaDB Corporation.
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
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
|
it under the terms of the GNU General Public License as published by
|
||||||
@@ -111,13 +111,10 @@ static ulong write_check;
|
|||||||
struct innodb_page_type {
|
struct innodb_page_type {
|
||||||
int n_undo_state_active;
|
int n_undo_state_active;
|
||||||
int n_undo_state_cached;
|
int n_undo_state_cached;
|
||||||
int n_undo_state_to_free;
|
|
||||||
int n_undo_state_to_purge;
|
int n_undo_state_to_purge;
|
||||||
int n_undo_state_prepared;
|
int n_undo_state_prepared;
|
||||||
int n_undo_state_other;
|
int n_undo_state_other;
|
||||||
int n_undo_insert;
|
int n_undo;
|
||||||
int n_undo_update;
|
|
||||||
int n_undo_other;
|
|
||||||
int n_fil_page_index;
|
int n_fil_page_index;
|
||||||
int n_fil_page_undo_log;
|
int n_fil_page_undo_log;
|
||||||
int n_fil_page_inode;
|
int n_fil_page_inode;
|
||||||
@@ -937,21 +934,7 @@ parse_page(
|
|||||||
fprintf(file, "#::%llu\t\t|\t\tUndo log page\t\t\t|",
|
fprintf(file, "#::%llu\t\t|\t\tUndo log page\t\t\t|",
|
||||||
cur_page_num);
|
cur_page_num);
|
||||||
}
|
}
|
||||||
if (undo_page_type == TRX_UNDO_INSERT) {
|
page_type.n_undo++;
|
||||||
page_type.n_undo_insert++;
|
|
||||||
if (page_type_dump) {
|
|
||||||
fprintf(file, "\t%s",
|
|
||||||
"Insert Undo log page");
|
|
||||||
}
|
|
||||||
|
|
||||||
} else if (undo_page_type == TRX_UNDO_UPDATE) {
|
|
||||||
page_type.n_undo_update++;
|
|
||||||
if (page_type_dump) {
|
|
||||||
fprintf(file, "\t%s",
|
|
||||||
"Update undo log page");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
undo_page_type = mach_read_from_2(page + TRX_UNDO_SEG_HDR +
|
undo_page_type = mach_read_from_2(page + TRX_UNDO_SEG_HDR +
|
||||||
TRX_UNDO_STATE);
|
TRX_UNDO_STATE);
|
||||||
switch (undo_page_type) {
|
switch (undo_page_type) {
|
||||||
@@ -971,14 +954,6 @@ parse_page(
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case TRX_UNDO_TO_FREE:
|
|
||||||
page_type.n_undo_state_to_free++;
|
|
||||||
if (page_type_dump) {
|
|
||||||
fprintf(file, ", %s", "Insert undo "
|
|
||||||
"segment that can be freed");
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case TRX_UNDO_TO_PURGE:
|
case TRX_UNDO_TO_PURGE:
|
||||||
page_type.n_undo_state_to_purge++;
|
page_type.n_undo_state_to_purge++;
|
||||||
if (page_type_dump) {
|
if (page_type_dump) {
|
||||||
@@ -1202,15 +1177,11 @@ print_summary(
|
|||||||
|
|
||||||
fprintf(fil_out, "\n===============================================\n");
|
fprintf(fil_out, "\n===============================================\n");
|
||||||
fprintf(fil_out, "Additional information:\n");
|
fprintf(fil_out, "Additional information:\n");
|
||||||
fprintf(fil_out, "Undo page type: %d insert, %d update, %d other\n",
|
fprintf(fil_out, "Undo page type: %d\n", page_type.n_undo);
|
||||||
page_type.n_undo_insert,
|
fprintf(fil_out, "Undo page state: %d active, %d cached, %d"
|
||||||
page_type.n_undo_update,
|
|
||||||
page_type.n_undo_other);
|
|
||||||
fprintf(fil_out, "Undo page state: %d active, %d cached, %d to_free, %d"
|
|
||||||
" to_purge, %d prepared, %d other\n",
|
" to_purge, %d prepared, %d other\n",
|
||||||
page_type.n_undo_state_active,
|
page_type.n_undo_state_active,
|
||||||
page_type.n_undo_state_cached,
|
page_type.n_undo_state_cached,
|
||||||
page_type.n_undo_state_to_free,
|
|
||||||
page_type.n_undo_state_to_purge,
|
page_type.n_undo_state_to_purge,
|
||||||
page_type.n_undo_state_prepared,
|
page_type.n_undo_state_prepared,
|
||||||
page_type.n_undo_state_other);
|
page_type.n_undo_state_other);
|
||||||
|
|||||||
@@ -134,6 +134,7 @@ IF(WOLFSSL_X86_64_BUILD)
|
|||||||
SET(USE_INTEL_SPEEDUP 1)
|
SET(USE_INTEL_SPEEDUP 1)
|
||||||
LIST(APPEND WOLFCRYPT_SOURCES
|
LIST(APPEND WOLFCRYPT_SOURCES
|
||||||
${WOLFCRYPT_SRCDIR}/aes_asm.S
|
${WOLFCRYPT_SRCDIR}/aes_asm.S
|
||||||
|
${WOLFCRYPT_SRCDIR}/aes_gcm_asm.S
|
||||||
${WOLFCRYPT_SRCDIR}/sha512_asm.S
|
${WOLFCRYPT_SRCDIR}/sha512_asm.S
|
||||||
${WOLFCRYPT_SRCDIR}/sha256_asm.S)
|
${WOLFCRYPT_SRCDIR}/sha256_asm.S)
|
||||||
ADD_DEFINITIONS(-maes -msse4.2 -mpclmul)
|
ADD_DEFINITIONS(-maes -msse4.2 -mpclmul)
|
||||||
|
|||||||
@@ -17,10 +17,11 @@
|
|||||||
#define WC_RSA_BLINDING
|
#define WC_RSA_BLINDING
|
||||||
#define HAVE_TLS_EXTENSIONS
|
#define HAVE_TLS_EXTENSIONS
|
||||||
#define HAVE_AES_ECB
|
#define HAVE_AES_ECB
|
||||||
|
#define HAVE_AESGCM
|
||||||
#define WOLFSSL_AES_COUNTER
|
#define WOLFSSL_AES_COUNTER
|
||||||
#define NO_WOLFSSL_STUB
|
#define NO_WOLFSSL_STUB
|
||||||
#define OPENSSL_ALL
|
#define OPENSSL_ALL
|
||||||
#undef WOLFSSL_ALLOW_TLSV10 /* see https://github.com/wolfSSL/wolfssl/issues/2960 */
|
#define WOLFSSL_ALLOW_TLSV10
|
||||||
#define NO_OLD_TIMEVAL_NAME
|
#define NO_OLD_TIMEVAL_NAME
|
||||||
/*
|
/*
|
||||||
FP_MAX_BITS is set high solely to satisfy ssl_8k_key.test
|
FP_MAX_BITS is set high solely to satisfy ssl_8k_key.test
|
||||||
|
|||||||
@@ -45,7 +45,7 @@ extern "C" {
|
|||||||
/* The max key length of all supported algorithms */
|
/* The max key length of all supported algorithms */
|
||||||
#define MY_AES_MAX_KEY_LENGTH 32
|
#define MY_AES_MAX_KEY_LENGTH 32
|
||||||
|
|
||||||
#define MY_AES_CTX_SIZE 640
|
#define MY_AES_CTX_SIZE 656
|
||||||
|
|
||||||
enum my_aes_mode {
|
enum my_aes_mode {
|
||||||
MY_AES_ECB, MY_AES_CBC
|
MY_AES_ECB, MY_AES_CBC
|
||||||
|
|||||||
Submodule libmariadb updated: 180c543704...802ce584a2
@@ -1,9 +1,6 @@
|
|||||||
|
|
||||||
!include include/default_my.cnf
|
!include include/default_my.cnf
|
||||||
|
|
||||||
[mysqld.1]
|
|
||||||
socket= @ENV.ABSTRACT_SOCKET
|
|
||||||
|
|
||||||
# Using @OPT.port here for uniqueness
|
# Using @OPT.port here for uniqueness
|
||||||
[ENV]
|
[ENV]
|
||||||
ABSTRACT_SOCKET= @mtr-test-abstract-socket-@OPT.port
|
ABSTRACT_SOCKET= @mtr-test-abstract-socket-@OPT.port
|
||||||
|
|||||||
@@ -1,5 +1,3 @@
|
|||||||
connect con1,localhost,root,,test,,$ABSTRACT_SOCKET;
|
|
||||||
select 1;
|
select 1;
|
||||||
1
|
1
|
||||||
1
|
1
|
||||||
disconnect con1;
|
|
||||||
|
|||||||
@@ -1,6 +1,9 @@
|
|||||||
--source include/linux.inc
|
--source include/linux.inc
|
||||||
--source include/not_embedded.inc
|
--source include/not_embedded.inc
|
||||||
|
|
||||||
|
let $restart_parameters=--socket=$ABSTRACT_SOCKET
|
||||||
|
--source include/kill_mysqld.inc
|
||||||
|
--source include/start_mysqld.inc
|
||||||
|
|
||||||
connect(con1,localhost,root,,test,,$ABSTRACT_SOCKET);
|
connect(con1,localhost,root,,test,,$ABSTRACT_SOCKET);
|
||||||
select 1;
|
select 1;
|
||||||
disconnect con1;
|
|
||||||
|
|||||||
@@ -1,7 +1,10 @@
|
|||||||
update mysql.global_priv set priv=json_insert(priv, '$.plugin', 'unix_socket') where user='root';
|
create table global_priv_backup select * from mysql.global_priv;
|
||||||
|
update mysql.global_priv set priv=json_insert(priv, '$.plugin', 'unix_socket');
|
||||||
|
delete from mysql.global_priv where user != 'root';
|
||||||
flush privileges;
|
flush privileges;
|
||||||
connect(localhost,USER,,test,MASTER_PORT,MASTER_SOCKET);
|
connect(localhost,USER,,test,MASTER_PORT,MASTER_SOCKET);
|
||||||
ERROR 28000: Access denied for user 'USER'@'localhost'
|
ERROR 28000: Access denied for user 'USER'@'localhost'
|
||||||
ERROR 28000: Access denied for user 'USER'@'localhost'
|
ERROR 28000: Access denied for user 'USER'@'localhost'
|
||||||
update mysql.global_priv set priv=json_compact(json_remove(priv, '$.plugin')) where user='root';
|
replace mysql.global_priv select * from global_priv_backup;
|
||||||
flush privileges;
|
flush privileges;
|
||||||
|
drop table global_priv_backup;
|
||||||
|
|||||||
@@ -4,7 +4,9 @@
|
|||||||
# MDEV-3909 remote user enumeration
|
# MDEV-3909 remote user enumeration
|
||||||
# unix_socket tests
|
# unix_socket tests
|
||||||
#
|
#
|
||||||
update mysql.global_priv set priv=json_insert(priv, '$.plugin', 'unix_socket') where user='root';
|
create table global_priv_backup select * from mysql.global_priv;
|
||||||
|
update mysql.global_priv set priv=json_insert(priv, '$.plugin', 'unix_socket');
|
||||||
|
delete from mysql.global_priv where user != 'root';
|
||||||
flush privileges;
|
flush privileges;
|
||||||
|
|
||||||
# Make sure that the replace works, even if $USER is 'user' or something else
|
# Make sure that the replace works, even if $USER is 'user' or something else
|
||||||
@@ -22,5 +24,6 @@ connect (fail,localhost,$USER);
|
|||||||
--error ER_ACCESS_DENIED_NO_PASSWORD_ERROR
|
--error ER_ACCESS_DENIED_NO_PASSWORD_ERROR
|
||||||
change_user $USER;
|
change_user $USER;
|
||||||
|
|
||||||
update mysql.global_priv set priv=json_compact(json_remove(priv, '$.plugin')) where user='root';
|
replace mysql.global_priv select * from global_priv_backup;
|
||||||
flush privileges;
|
flush privileges;
|
||||||
|
drop table global_priv_backup;
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
#
|
#
|
||||||
# A password cannot expire, if there is no password
|
# A password cannot expire, if there is no password
|
||||||
#
|
#
|
||||||
create user USER identified via unix_socket;
|
create user 'USER' identified via unix_socket;
|
||||||
alter user USER password expire;
|
alter user 'USER' password expire;
|
||||||
1
|
1
|
||||||
1
|
1
|
||||||
drop user USER;
|
drop user 'USER';
|
||||||
|
|||||||
@@ -9,16 +9,16 @@
|
|||||||
--echo # A password cannot expire, if there is no password
|
--echo # A password cannot expire, if there is no password
|
||||||
--echo #
|
--echo #
|
||||||
|
|
||||||
--let $replace=create user $USER
|
--let $replace=create user '$USER'
|
||||||
--replace_result $replace "create user USER"
|
--replace_result $replace "create user 'USER'"
|
||||||
--eval create user $USER identified via unix_socket
|
--eval create user '$USER' identified via unix_socket
|
||||||
|
|
||||||
--let $replace=alter user $USER
|
--let $replace=alter user '$USER'
|
||||||
--replace_result $replace "alter user USER"
|
--replace_result $replace "alter user 'USER'"
|
||||||
--eval alter user $USER password expire
|
--eval alter user '$USER' password expire
|
||||||
|
|
||||||
--exec $MYSQL -u $USER -e 'select 1'
|
--exec $MYSQL -u $USER -e 'select 1'
|
||||||
|
|
||||||
--let $replace=drop user $USER
|
--let $replace=drop user '$USER'
|
||||||
--replace_result $replace "drop user USER"
|
--replace_result $replace "drop user 'USER'"
|
||||||
--eval drop user $USER
|
--eval drop user '$USER'
|
||||||
|
|||||||
@@ -3893,6 +3893,25 @@ id rn
|
|||||||
1 1
|
1 1
|
||||||
drop table t1;
|
drop table t1;
|
||||||
#
|
#
|
||||||
|
# MDEV-25630: Crash with window function in left expr of IN subquery
|
||||||
|
#
|
||||||
|
CREATE TABLE t1 (i int);
|
||||||
|
INSERT INTO t1 VALUES (1),(2),(3);
|
||||||
|
SELECT lag(i) over (ORDER BY i) IN ( SELECT 1 FROM t1 a) FROM t1;
|
||||||
|
lag(i) over (ORDER BY i) IN ( SELECT 1 FROM t1 a)
|
||||||
|
NULL
|
||||||
|
1
|
||||||
|
0
|
||||||
|
DROP TABLE t1;
|
||||||
|
CREATE TABLE t1 (i int);
|
||||||
|
INSERT INTO t1 VALUES (1),(2),(3);
|
||||||
|
SELECT sum(i) over () IN ( SELECT 1 FROM t1 a) FROM t1;
|
||||||
|
sum(i) over () IN ( SELECT 1 FROM t1 a)
|
||||||
|
0
|
||||||
|
0
|
||||||
|
0
|
||||||
|
DROP TABLE t1;
|
||||||
|
#
|
||||||
# End of 10.2 tests
|
# End of 10.2 tests
|
||||||
#
|
#
|
||||||
#
|
#
|
||||||
|
|||||||
@@ -2541,6 +2541,20 @@ order by rn desc;
|
|||||||
|
|
||||||
drop table t1;
|
drop table t1;
|
||||||
|
|
||||||
|
--echo #
|
||||||
|
--echo # MDEV-25630: Crash with window function in left expr of IN subquery
|
||||||
|
--echo #
|
||||||
|
|
||||||
|
CREATE TABLE t1 (i int);
|
||||||
|
INSERT INTO t1 VALUES (1),(2),(3);
|
||||||
|
SELECT lag(i) over (ORDER BY i) IN ( SELECT 1 FROM t1 a) FROM t1;
|
||||||
|
DROP TABLE t1;
|
||||||
|
|
||||||
|
CREATE TABLE t1 (i int);
|
||||||
|
INSERT INTO t1 VALUES (1),(2),(3);
|
||||||
|
SELECT sum(i) over () IN ( SELECT 1 FROM t1 a) FROM t1;
|
||||||
|
DROP TABLE t1;
|
||||||
|
|
||||||
--echo #
|
--echo #
|
||||||
--echo # End of 10.2 tests
|
--echo # End of 10.2 tests
|
||||||
--echo #
|
--echo #
|
||||||
|
|||||||
1
mysql-test/main/wolfssl.opt
Normal file
1
mysql-test/main/wolfssl.opt
Normal file
@@ -0,0 +1 @@
|
|||||||
|
--ssl_cipher=ECDHE-RSA-AES256-GCM-SHA384
|
||||||
6
mysql-test/main/wolfssl.test
Normal file
6
mysql-test/main/wolfssl.test
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
#
|
||||||
|
# Various tests that require WolfSSL
|
||||||
|
#
|
||||||
|
--source include/have_ssl_communication.inc
|
||||||
|
--source include/not_embedded.inc
|
||||||
|
SELECT @@ssl_cipher;
|
||||||
@@ -80,8 +80,6 @@ sub skip_combinations {
|
|||||||
$skip{'main/ssl_verify_ip.test'} = 'x509v3 support required'
|
$skip{'main/ssl_verify_ip.test'} = 'x509v3 support required'
|
||||||
unless $openssl_ver ge "1.0.2";
|
unless $openssl_ver ge "1.0.2";
|
||||||
|
|
||||||
$skip{'main/tls_version1.test'} = 'https://github.com/wolfSSL/wolfssl/issues/2960'
|
|
||||||
if $ssl_lib =~ /WolfSSL 4.4.0/;
|
|
||||||
|
|
||||||
%skip;
|
%skip;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,3 @@
|
|||||||
SELECT NAME FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION WHERE MIN_KEY_VERSION <> 0;
|
|
||||||
NAME
|
|
||||||
SELECT NAME FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION WHERE MIN_KEY_VERSION = 0;
|
|
||||||
NAME
|
|
||||||
SET GLOBAL innodb_file_per_table = ON;
|
SET GLOBAL innodb_file_per_table = ON;
|
||||||
set global innodb_compression_algorithm = 1;
|
set global innodb_compression_algorithm = 1;
|
||||||
create database enctests;
|
create database enctests;
|
||||||
|
|||||||
20
mysql-test/suite/encryption/r/key_version_rotation.result
Normal file
20
mysql-test/suite/encryption/r/key_version_rotation.result
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
create table t1(f1 int not null)engine=innodb;
|
||||||
|
create table t2(f1 int not null)engine=innodb;
|
||||||
|
insert into t1 select * from seq_1_to_100;
|
||||||
|
insert into t2 select * from seq_1_to_100;
|
||||||
|
# restart: --innodb_encrypt_tables=0 --innodb_encryption_threads=1 --innodb_encryption_rotate_key_age=9
|
||||||
|
# Enable encryption
|
||||||
|
set global innodb_encrypt_tables=ON;
|
||||||
|
# Create a new table and it is added to rotation list
|
||||||
|
create table t3(f1 int not null)engine=innodb;
|
||||||
|
insert into t3 select * from seq_1_to_100;
|
||||||
|
# Increase the version and it should set rotation
|
||||||
|
# variable for the encryption plugin
|
||||||
|
set global debug_key_management_version=10;
|
||||||
|
select @@debug_key_management_version;
|
||||||
|
@@debug_key_management_version
|
||||||
|
10
|
||||||
|
# Decrease the key version and Disable the encryption
|
||||||
|
set global debug_key_management_version=1;
|
||||||
|
set global innodb_encrypt_tables=off;
|
||||||
|
DROP TABLE t1, t2, t3;
|
||||||
@@ -3899,6 +3899,25 @@ id rn
|
|||||||
1 1
|
1 1
|
||||||
drop table t1;
|
drop table t1;
|
||||||
#
|
#
|
||||||
|
# MDEV-25630: Crash with window function in left expr of IN subquery
|
||||||
|
#
|
||||||
|
CREATE TABLE t1 (i int);
|
||||||
|
INSERT INTO t1 VALUES (1),(2),(3);
|
||||||
|
SELECT lag(i) over (ORDER BY i) IN ( SELECT 1 FROM t1 a) FROM t1;
|
||||||
|
lag(i) over (ORDER BY i) IN ( SELECT 1 FROM t1 a)
|
||||||
|
NULL
|
||||||
|
1
|
||||||
|
0
|
||||||
|
DROP TABLE t1;
|
||||||
|
CREATE TABLE t1 (i int);
|
||||||
|
INSERT INTO t1 VALUES (1),(2),(3);
|
||||||
|
SELECT sum(i) over () IN ( SELECT 1 FROM t1 a) FROM t1;
|
||||||
|
sum(i) over () IN ( SELECT 1 FROM t1 a)
|
||||||
|
0
|
||||||
|
0
|
||||||
|
0
|
||||||
|
DROP TABLE t1;
|
||||||
|
#
|
||||||
# End of 10.2 tests
|
# End of 10.2 tests
|
||||||
#
|
#
|
||||||
#
|
#
|
||||||
|
|||||||
@@ -3,9 +3,6 @@
|
|||||||
# not embedded because of restarts
|
# not embedded because of restarts
|
||||||
-- source include/not_embedded.inc
|
-- source include/not_embedded.inc
|
||||||
|
|
||||||
SELECT NAME FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION WHERE MIN_KEY_VERSION <> 0;
|
|
||||||
SELECT NAME FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION WHERE MIN_KEY_VERSION = 0;
|
|
||||||
|
|
||||||
let $encryption = `SELECT @@innodb_encrypt_tables`;
|
let $encryption = `SELECT @@innodb_encrypt_tables`;
|
||||||
SET GLOBAL innodb_file_per_table = ON;
|
SET GLOBAL innodb_file_per_table = ON;
|
||||||
# zlib
|
# zlib
|
||||||
|
|||||||
2
mysql-test/suite/encryption/t/key_version_rotation.opt
Normal file
2
mysql-test/suite/encryption/t/key_version_rotation.opt
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
--innodb-tablespaces-encryption
|
||||||
|
--plugin-load-add=$DEBUG_KEY_MANAGEMENT_SO
|
||||||
41
mysql-test/suite/encryption/t/key_version_rotation.test
Normal file
41
mysql-test/suite/encryption/t/key_version_rotation.test
Normal file
@@ -0,0 +1,41 @@
|
|||||||
|
--source include/have_innodb.inc
|
||||||
|
--source include/have_debug.inc
|
||||||
|
--source include/have_sequence.inc
|
||||||
|
|
||||||
|
create table t1(f1 int not null)engine=innodb;
|
||||||
|
create table t2(f1 int not null)engine=innodb;
|
||||||
|
insert into t1 select * from seq_1_to_100;
|
||||||
|
insert into t2 select * from seq_1_to_100;
|
||||||
|
|
||||||
|
let $restart_parameters=--innodb_encrypt_tables=0 --innodb_encryption_threads=1 --innodb_encryption_rotate_key_age=9;
|
||||||
|
--source include/restart_mysqld.inc
|
||||||
|
|
||||||
|
--echo # Enable encryption
|
||||||
|
|
||||||
|
set global innodb_encrypt_tables=ON;
|
||||||
|
--let $tables_count= `select count(*) from information_schema.tables where engine = 'InnoDB'`
|
||||||
|
--let $wait_timeout= 600
|
||||||
|
--let $wait_condition=SELECT COUNT(*) >= $tables_count FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION WHERE MIN_KEY_VERSION <> 0;
|
||||||
|
--source include/wait_condition.inc
|
||||||
|
--echo # Create a new table and it is added to rotation list
|
||||||
|
create table t3(f1 int not null)engine=innodb;
|
||||||
|
insert into t3 select * from seq_1_to_100;
|
||||||
|
|
||||||
|
--echo # Increase the version and it should set rotation
|
||||||
|
--echo # variable for the encryption plugin
|
||||||
|
|
||||||
|
set global debug_key_management_version=10;
|
||||||
|
select @@debug_key_management_version;
|
||||||
|
--let $tables_count= `select count(*) from information_schema.tables where engine = 'InnoDB'`
|
||||||
|
--let $wait_timeout= 600
|
||||||
|
--let $wait_condition=SELECT COUNT(*) >= $tables_count FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION WHERE MIN_KEY_VERSION <> 0;
|
||||||
|
--source include/wait_condition.inc
|
||||||
|
|
||||||
|
--echo # Decrease the key version and Disable the encryption
|
||||||
|
set global debug_key_management_version=1;
|
||||||
|
set global innodb_encrypt_tables=off;
|
||||||
|
|
||||||
|
--let $wait_timeout= 600
|
||||||
|
--let $wait_condition=SELECT COUNT(*) >= $tables_count FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION WHERE MIN_KEY_VERSION = 0;
|
||||||
|
--source include/wait_condition.inc
|
||||||
|
DROP TABLE t1, t2, t3;
|
||||||
@@ -262,3 +262,37 @@ CHECK TABLE t1;
|
|||||||
Table Op Msg_type Msg_text
|
Table Op Msg_type Msg_text
|
||||||
test.t1 check status OK
|
test.t1 check status OK
|
||||||
DROP TABLE t1;
|
DROP TABLE t1;
|
||||||
|
#
|
||||||
|
# MDEV-25872 InnoDB: Assertion failure in row_merge_read_clustered_index
|
||||||
|
# upon ALTER on table with indexed virtual columns
|
||||||
|
#
|
||||||
|
CREATE TABLE t1 (
|
||||||
|
id BIGINT AUTO_INCREMENT PRIMARY KEY,
|
||||||
|
a INT,
|
||||||
|
va INT ZEROFILL AS (a) VIRTUAL,
|
||||||
|
b TIMESTAMP,
|
||||||
|
c CHAR(204),
|
||||||
|
vc CHAR(8),
|
||||||
|
KEY(vc,c(64),b,va)
|
||||||
|
) ENGINE=InnoDB CHARACTER SET utf32;
|
||||||
|
INSERT INTO t1 (id) SELECT NULL FROM seq_1_to_75;
|
||||||
|
INSERT IGNORE INTO t1 (id, a) VALUES (NULL, -1);
|
||||||
|
Warnings:
|
||||||
|
Warning 1264 Out of range value for column 'va' at row 1
|
||||||
|
ALTER TABLE t1 FORCE;
|
||||||
|
ERROR 22003: Out of range value for column 'va' at row 1
|
||||||
|
DROP TABLE t1;
|
||||||
|
#
|
||||||
|
# MDEV-24713 Assertion `dict_table_is_comp(index->table)' failed
|
||||||
|
# in row_merge_buf_add()
|
||||||
|
#
|
||||||
|
CREATE TABLE t1 (id INT PRIMARY KEY, a CHAR(3),
|
||||||
|
b CHAR(8) AS (a) VIRTUAL, KEY(b))
|
||||||
|
ROW_FORMAT=REDUNDANT ENGINE=InnoDB
|
||||||
|
CHARACTER SET utf8;
|
||||||
|
INSERT INTO t1 (id,a) VALUES (1,'foo');
|
||||||
|
OPTIMIZE TABLE t1;
|
||||||
|
Table Op Msg_type Msg_text
|
||||||
|
test.t1 optimize note Table does not support optimize, doing recreate + analyze instead
|
||||||
|
test.t1 optimize status OK
|
||||||
|
DROP TABLE t1;
|
||||||
|
|||||||
1
mysql-test/suite/gcol/t/innodb_virtual_index.opt
Normal file
1
mysql-test/suite/gcol/t/innodb_virtual_index.opt
Normal file
@@ -0,0 +1 @@
|
|||||||
|
--innodb_sort_buffer_size=64k
|
||||||
@@ -1,4 +1,5 @@
|
|||||||
--source include/have_innodb.inc
|
--source include/have_innodb.inc
|
||||||
|
--source include/have_sequence.inc
|
||||||
|
|
||||||
# Ensure that the history list length will actually be decremented by purge.
|
# Ensure that the history list length will actually be decremented by purge.
|
||||||
SET @saved_frequency = @@GLOBAL.innodb_purge_rseg_truncate_frequency;
|
SET @saved_frequency = @@GLOBAL.innodb_purge_rseg_truncate_frequency;
|
||||||
@@ -281,3 +282,35 @@ ROLLBACK;
|
|||||||
SELECT * FROM t1;
|
SELECT * FROM t1;
|
||||||
CHECK TABLE t1;
|
CHECK TABLE t1;
|
||||||
DROP TABLE t1;
|
DROP TABLE t1;
|
||||||
|
|
||||||
|
--echo #
|
||||||
|
--echo # MDEV-25872 InnoDB: Assertion failure in row_merge_read_clustered_index
|
||||||
|
--echo # upon ALTER on table with indexed virtual columns
|
||||||
|
--echo #
|
||||||
|
|
||||||
|
CREATE TABLE t1 (
|
||||||
|
id BIGINT AUTO_INCREMENT PRIMARY KEY,
|
||||||
|
a INT,
|
||||||
|
va INT ZEROFILL AS (a) VIRTUAL,
|
||||||
|
b TIMESTAMP,
|
||||||
|
c CHAR(204),
|
||||||
|
vc CHAR(8),
|
||||||
|
KEY(vc,c(64),b,va)
|
||||||
|
) ENGINE=InnoDB CHARACTER SET utf32;
|
||||||
|
INSERT INTO t1 (id) SELECT NULL FROM seq_1_to_75;
|
||||||
|
INSERT IGNORE INTO t1 (id, a) VALUES (NULL, -1);
|
||||||
|
--error ER_WARN_DATA_OUT_OF_RANGE
|
||||||
|
ALTER TABLE t1 FORCE;
|
||||||
|
DROP TABLE t1;
|
||||||
|
|
||||||
|
--echo #
|
||||||
|
--echo # MDEV-24713 Assertion `dict_table_is_comp(index->table)' failed
|
||||||
|
--echo # in row_merge_buf_add()
|
||||||
|
--echo #
|
||||||
|
CREATE TABLE t1 (id INT PRIMARY KEY, a CHAR(3),
|
||||||
|
b CHAR(8) AS (a) VIRTUAL, KEY(b))
|
||||||
|
ROW_FORMAT=REDUNDANT ENGINE=InnoDB
|
||||||
|
CHARACTER SET utf8;
|
||||||
|
INSERT INTO t1 (id,a) VALUES (1,'foo');
|
||||||
|
OPTIMIZE TABLE t1;
|
||||||
|
DROP TABLE t1;
|
||||||
|
|||||||
@@ -1052,10 +1052,13 @@ a
|
|||||||
10
|
10
|
||||||
DROP TABLE t1;
|
DROP TABLE t1;
|
||||||
CREATE TABLE t1 (a INT NOT NULL DEFAULT 0) ENGINE=InnoDB;
|
CREATE TABLE t1 (a INT NOT NULL DEFAULT 0) ENGINE=InnoDB;
|
||||||
|
SET @save_allowed = @@GLOBAL.innodb_instant_alter_column_allowed;
|
||||||
|
SET GLOBAL innodb_instant_alter_column_allowed=never;
|
||||||
iNSERT INTO t1 VALUES (10);
|
iNSERT INTO t1 VALUES (10);
|
||||||
ALTER TABLE t1 ADD b DATE NOT NULL DEFAULT if(unix_timestamp()>1,TIMESTAMP'2001-01-01 10:20:30',0);
|
ALTER TABLE t1 ADD b DATE NOT NULL DEFAULT if(unix_timestamp()>1,TIMESTAMP'2001-01-01 10:20:30',0);
|
||||||
affected rows: 0
|
affected rows: 0
|
||||||
info: Records: 0 Duplicates: 0 Warnings: 0
|
info: Records: 0 Duplicates: 0 Warnings: 0
|
||||||
|
SET GLOBAL innodb_instant_alter_column_allowed=@save_allowed;
|
||||||
SELECT * FROM t1;
|
SELECT * FROM t1;
|
||||||
a b
|
a b
|
||||||
10 2001-01-01
|
10 2001-01-01
|
||||||
|
|||||||
@@ -656,10 +656,13 @@ DROP TABLE t1;
|
|||||||
|
|
||||||
# DATETIME-to-DATE truncation is OK
|
# DATETIME-to-DATE truncation is OK
|
||||||
CREATE TABLE t1 (a INT NOT NULL DEFAULT 0) ENGINE=InnoDB;
|
CREATE TABLE t1 (a INT NOT NULL DEFAULT 0) ENGINE=InnoDB;
|
||||||
|
SET @save_allowed = @@GLOBAL.innodb_instant_alter_column_allowed;
|
||||||
|
SET GLOBAL innodb_instant_alter_column_allowed=never;
|
||||||
iNSERT INTO t1 VALUES (10);
|
iNSERT INTO t1 VALUES (10);
|
||||||
--enable_info
|
--enable_info
|
||||||
ALTER TABLE t1 ADD b DATE NOT NULL DEFAULT if(unix_timestamp()>1,TIMESTAMP'2001-01-01 10:20:30',0);
|
ALTER TABLE t1 ADD b DATE NOT NULL DEFAULT if(unix_timestamp()>1,TIMESTAMP'2001-01-01 10:20:30',0);
|
||||||
--disable_info
|
--disable_info
|
||||||
|
SET GLOBAL innodb_instant_alter_column_allowed=@save_allowed;
|
||||||
SELECT * FROM t1;
|
SELECT * FROM t1;
|
||||||
DROP TABLE t1;
|
DROP TABLE t1;
|
||||||
|
|
||||||
|
|||||||
@@ -31,19 +31,17 @@ DROP TABLE t2, t1;
|
|||||||
#
|
#
|
||||||
CREATE TABLE t1(a INT, b TEXT, c TEXT, FULLTEXT INDEX(b)) ENGINE=InnoDB;
|
CREATE TABLE t1(a INT, b TEXT, c TEXT, FULLTEXT INDEX(b)) ENGINE=InnoDB;
|
||||||
connect con1,localhost,root,,test;
|
connect con1,localhost,root,,test;
|
||||||
SET DEBUG_SYNC='innodb_inplace_alter_table_enter SIGNAL s1 WAIT_FOR g1';
|
SET DEBUG_DBUG="+d,innodb_OOM_inplace_alter";
|
||||||
SET DEBUG_SYNC='innodb_commit_inplace_alter_table_enter SIGNAL s2 WAIT_FOR g2';
|
SET DEBUG_SYNC='innodb_commit_inplace_alter_table_enter SIGNAL s2 WAIT_FOR g2';
|
||||||
ALTER TABLE t1 ADD FULLTEXT(c);
|
ALTER TABLE t1 ADD FULLTEXT(c);
|
||||||
connection default;
|
connection default;
|
||||||
SET DEBUG_SYNC='now WAIT_FOR s1';
|
SET DEBUG_SYNC='now WAIT_FOR s2';
|
||||||
KILL QUERY @id;
|
|
||||||
SET DEBUG_SYNC='now SIGNAL g1 WAIT_FOR s2';
|
|
||||||
START TRANSACTION;
|
START TRANSACTION;
|
||||||
SELECT * FROM t1;
|
SELECT * FROM t1;
|
||||||
a b c
|
a b c
|
||||||
SET DEBUG_SYNC='now SIGNAL s2';
|
SET DEBUG_SYNC='now SIGNAL g2';
|
||||||
connection con1;
|
connection con1;
|
||||||
ERROR 70100: Query execution was interrupted
|
ERROR HY000: Out of memory.
|
||||||
disconnect con1;
|
disconnect con1;
|
||||||
connection default;
|
connection default;
|
||||||
SET DEBUG_SYNC=RESET;
|
SET DEBUG_SYNC=RESET;
|
||||||
|
|||||||
@@ -60,20 +60,16 @@ DROP TABLE t2, t1;
|
|||||||
--echo #
|
--echo #
|
||||||
CREATE TABLE t1(a INT, b TEXT, c TEXT, FULLTEXT INDEX(b)) ENGINE=InnoDB;
|
CREATE TABLE t1(a INT, b TEXT, c TEXT, FULLTEXT INDEX(b)) ENGINE=InnoDB;
|
||||||
connect(con1,localhost,root,,test);
|
connect(con1,localhost,root,,test);
|
||||||
let $ID= `SELECT @id := CONNECTION_ID()`;
|
SET DEBUG_DBUG="+d,innodb_OOM_inplace_alter";
|
||||||
SET DEBUG_SYNC='innodb_inplace_alter_table_enter SIGNAL s1 WAIT_FOR g1';
|
|
||||||
SET DEBUG_SYNC='innodb_commit_inplace_alter_table_enter SIGNAL s2 WAIT_FOR g2';
|
SET DEBUG_SYNC='innodb_commit_inplace_alter_table_enter SIGNAL s2 WAIT_FOR g2';
|
||||||
send ALTER TABLE t1 ADD FULLTEXT(c);
|
send ALTER TABLE t1 ADD FULLTEXT(c);
|
||||||
connection default;
|
connection default;
|
||||||
SET DEBUG_SYNC='now WAIT_FOR s1';
|
SET DEBUG_SYNC='now WAIT_FOR s2';
|
||||||
let $ignore= `SELECT @id := $ID`;
|
|
||||||
KILL QUERY @id;
|
|
||||||
SET DEBUG_SYNC='now SIGNAL g1 WAIT_FOR s2';
|
|
||||||
START TRANSACTION;
|
START TRANSACTION;
|
||||||
SELECT * FROM t1;
|
SELECT * FROM t1;
|
||||||
SET DEBUG_SYNC='now SIGNAL s2';
|
SET DEBUG_SYNC='now SIGNAL g2';
|
||||||
connection con1;
|
connection con1;
|
||||||
--error ER_QUERY_INTERRUPTED
|
--error ER_OUT_OF_RESOURCES
|
||||||
reap;
|
reap;
|
||||||
disconnect con1;
|
disconnect con1;
|
||||||
connection default;
|
connection default;
|
||||||
|
|||||||
@@ -112,8 +112,8 @@ File::tab#.ibd
|
|||||||
|
|
||||||
===============================================
|
===============================================
|
||||||
Additional information:
|
Additional information:
|
||||||
Undo page type: # insert, # update, # other
|
Undo page type: #
|
||||||
Undo page state: # active, # cached, # to_free, # to_purge, # prepared, # other
|
Undo page state: # active, # cached, # to_purge, # prepared, # other
|
||||||
index_id #pages #leaf_pages #recs_per_page #bytes_per_page
|
index_id #pages #leaf_pages #recs_per_page #bytes_per_page
|
||||||
# # # # #
|
# # # # #
|
||||||
# # # # #
|
# # # # #
|
||||||
@@ -147,8 +147,8 @@ File::tab#.ibd
|
|||||||
|
|
||||||
===============================================
|
===============================================
|
||||||
Additional information:
|
Additional information:
|
||||||
Undo page type: # insert, # update, # other
|
Undo page type: #
|
||||||
Undo page state: # active, # cached, # to_free, # to_purge, # prepared, # other
|
Undo page state: # active, # cached, # to_purge, # prepared, # other
|
||||||
index_id #pages #leaf_pages #recs_per_page #bytes_per_page
|
index_id #pages #leaf_pages #recs_per_page #bytes_per_page
|
||||||
# # # # #
|
# # # # #
|
||||||
# # # # #
|
# # # # #
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
INSTALL SONAME 'auth_named_pipe';
|
INSTALL SONAME 'auth_named_pipe';
|
||||||
CREATE USER 'USERNAME' IDENTIFIED WITH named_pipe;
|
CREATE USER 'USERNAME' IDENTIFIED WITH named_pipe;
|
||||||
GRANT ALL PRIVILEGES ON *.* to USERNAME;
|
GRANT ALL PRIVILEGES ON *.* to 'USERNAME';
|
||||||
DROP USER 'USERNAME';
|
DROP USER 'USERNAME';
|
||||||
UNINSTALL SONAME 'auth_named_pipe';
|
UNINSTALL SONAME 'auth_named_pipe';
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ INSTALL SONAME 'auth_named_pipe';
|
|||||||
--replace_result $USERNAME USERNAME
|
--replace_result $USERNAME USERNAME
|
||||||
eval CREATE USER '$USERNAME' IDENTIFIED WITH named_pipe;
|
eval CREATE USER '$USERNAME' IDENTIFIED WITH named_pipe;
|
||||||
--replace_result $USERNAME USERNAME
|
--replace_result $USERNAME USERNAME
|
||||||
eval GRANT ALL PRIVILEGES ON *.* to $USERNAME;
|
eval GRANT ALL PRIVILEGES ON *.* to '$USERNAME';
|
||||||
|
|
||||||
let $targetdir=$MYSQLTEST_VARDIR/tmp/backup;
|
let $targetdir=$MYSQLTEST_VARDIR/tmp/backup;
|
||||||
--disable_result_log
|
--disable_result_log
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
install soname 'auth_ed25519';
|
install soname 'auth_ed25519';
|
||||||
create user USER identified via unix_socket OR mysql_native_password as password("GOOD");
|
create user 'USER' identified via unix_socket OR mysql_native_password as password("GOOD");
|
||||||
create user mysqltest1 identified via unix_socket OR mysql_native_password as password("good");
|
create user mysqltest1 identified via unix_socket OR mysql_native_password as password("good");
|
||||||
show create user mysqltest1;
|
show create user mysqltest1;
|
||||||
CREATE USER for mysqltest1@%
|
CREATE USER for mysqltest1@%
|
||||||
@@ -14,8 +14,8 @@ user() current_user() database()
|
|||||||
mysqltest1@localhost mysqltest1@% test
|
mysqltest1@localhost mysqltest1@% test
|
||||||
# name does not match, password bad = failure
|
# name does not match, password bad = failure
|
||||||
mysqltest: Could not open connection 'default': 1045 Access denied for user 'mysqltest1'@'localhost' (using password: YES)
|
mysqltest: Could not open connection 'default': 1045 Access denied for user 'mysqltest1'@'localhost' (using password: YES)
|
||||||
drop user USER, mysqltest1;
|
drop user 'USER', mysqltest1;
|
||||||
create user USER identified via mysql_native_password as password("GOOD") OR unix_socket;
|
create user 'USER' identified via mysql_native_password as password("GOOD") OR unix_socket;
|
||||||
create user mysqltest1 identified via mysql_native_password as password("good") OR unix_socket;
|
create user mysqltest1 identified via mysql_native_password as password("good") OR unix_socket;
|
||||||
show create user mysqltest1;
|
show create user mysqltest1;
|
||||||
CREATE USER for mysqltest1@%
|
CREATE USER for mysqltest1@%
|
||||||
@@ -30,8 +30,8 @@ user() current_user() database()
|
|||||||
mysqltest1@localhost mysqltest1@% test
|
mysqltest1@localhost mysqltest1@% test
|
||||||
# name does not match, password bad = failure
|
# name does not match, password bad = failure
|
||||||
mysqltest: Could not open connection 'default': 1698 Access denied for user 'mysqltest1'@'localhost'
|
mysqltest: Could not open connection 'default': 1698 Access denied for user 'mysqltest1'@'localhost'
|
||||||
drop user USER, mysqltest1;
|
drop user 'USER', mysqltest1;
|
||||||
create user USER identified via unix_socket OR ed25519 as password("GOOD");
|
create user 'USER' identified via unix_socket OR ed25519 as password("GOOD");
|
||||||
create user mysqltest1 identified via unix_socket OR ed25519 as password("good");
|
create user mysqltest1 identified via unix_socket OR ed25519 as password("good");
|
||||||
show create user mysqltest1;
|
show create user mysqltest1;
|
||||||
CREATE USER for mysqltest1@%
|
CREATE USER for mysqltest1@%
|
||||||
@@ -46,8 +46,8 @@ user() current_user() database()
|
|||||||
mysqltest1@localhost mysqltest1@% test
|
mysqltest1@localhost mysqltest1@% test
|
||||||
# name does not match, password bad = failure
|
# name does not match, password bad = failure
|
||||||
mysqltest: Could not open connection 'default': 1045 Access denied for user 'mysqltest1'@'localhost' (using password: YES)
|
mysqltest: Could not open connection 'default': 1045 Access denied for user 'mysqltest1'@'localhost' (using password: YES)
|
||||||
drop user USER, mysqltest1;
|
drop user 'USER', mysqltest1;
|
||||||
create user USER identified via ed25519 as password("GOOD") OR unix_socket;
|
create user 'USER' identified via ed25519 as password("GOOD") OR unix_socket;
|
||||||
create user mysqltest1 identified via ed25519 as password("good") OR unix_socket;
|
create user mysqltest1 identified via ed25519 as password("good") OR unix_socket;
|
||||||
show create user mysqltest1;
|
show create user mysqltest1;
|
||||||
CREATE USER for mysqltest1@%
|
CREATE USER for mysqltest1@%
|
||||||
@@ -62,8 +62,8 @@ user() current_user() database()
|
|||||||
mysqltest1@localhost mysqltest1@% test
|
mysqltest1@localhost mysqltest1@% test
|
||||||
# name does not match, password bad = failure
|
# name does not match, password bad = failure
|
||||||
mysqltest: Could not open connection 'default': 1698 Access denied for user 'mysqltest1'@'localhost'
|
mysqltest: Could not open connection 'default': 1698 Access denied for user 'mysqltest1'@'localhost'
|
||||||
drop user USER, mysqltest1;
|
drop user 'USER', mysqltest1;
|
||||||
create user USER identified via ed25519 as password("GOOD") OR unix_socket OR mysql_native_password as password("works");
|
create user 'USER' identified via ed25519 as password("GOOD") OR unix_socket OR mysql_native_password as password("works");
|
||||||
create user mysqltest1 identified via ed25519 as password("good") OR unix_socket OR mysql_native_password as password("works");
|
create user mysqltest1 identified via ed25519 as password("good") OR unix_socket OR mysql_native_password as password("works");
|
||||||
show create user mysqltest1;
|
show create user mysqltest1;
|
||||||
CREATE USER for mysqltest1@%
|
CREATE USER for mysqltest1@%
|
||||||
@@ -82,7 +82,7 @@ user() current_user() database()
|
|||||||
mysqltest1@localhost mysqltest1@% test
|
mysqltest1@localhost mysqltest1@% test
|
||||||
# name does not match, password bad = failure
|
# name does not match, password bad = failure
|
||||||
mysqltest: Could not open connection 'default': 1045 Access denied for user 'mysqltest1'@'localhost' (using password: YES)
|
mysqltest: Could not open connection 'default': 1045 Access denied for user 'mysqltest1'@'localhost' (using password: YES)
|
||||||
drop user USER, mysqltest1;
|
drop user 'USER', mysqltest1;
|
||||||
create user mysqltest1 identified via mysql_native_password as password("good") OR mysql_native_password as password("works");
|
create user mysqltest1 identified via mysql_native_password as password("good") OR mysql_native_password as password("works");
|
||||||
show create user mysqltest1;
|
show create user mysqltest1;
|
||||||
CREATE USER for mysqltest1@%
|
CREATE USER for mysqltest1@%
|
||||||
@@ -157,7 +157,7 @@ drop user mysqltest1;
|
|||||||
create user mysqltest1 identified via ed25519 as password("good") OR unix_socket OR mysql_native_password as password("works");
|
create user mysqltest1 identified via ed25519 as password("good") OR unix_socket OR mysql_native_password as password("works");
|
||||||
ERROR HY000: Column count of mysql.user is wrong. Expected 3, found 47. Created with MariaDB XX.YY.ZZ, now running XX.YY.ZZ. Please use mariadb-upgrade to fix this error
|
ERROR HY000: Column count of mysql.user is wrong. Expected 3, found 47. Created with MariaDB XX.YY.ZZ, now running XX.YY.ZZ. Please use mariadb-upgrade to fix this error
|
||||||
# switching back from mysql.user to mysql.global_priv
|
# switching back from mysql.user to mysql.global_priv
|
||||||
create user USER identified via mysql_native_password as '1234567890123456789012345678901234567890a' OR unix_socket;
|
create user 'USER' identified via mysql_native_password as '1234567890123456789012345678901234567890a' OR unix_socket;
|
||||||
create user mysqltest1 identified via mysql_native_password as '1234567890123456789012345678901234567890a' OR unix_socket;
|
create user mysqltest1 identified via mysql_native_password as '1234567890123456789012345678901234567890a' OR unix_socket;
|
||||||
update mysql.global_priv set priv=replace(priv, '1234567890123456789012345678901234567890a', 'invalid password');
|
update mysql.global_priv set priv=replace(priv, '1234567890123456789012345678901234567890a', 'invalid password');
|
||||||
flush privileges;
|
flush privileges;
|
||||||
@@ -175,7 +175,7 @@ set password for mysqltest1 = password('bla');
|
|||||||
select user(), current_user(), database();
|
select user(), current_user(), database();
|
||||||
user() current_user() database()
|
user() current_user() database()
|
||||||
mysqltest1@localhost mysqltest1@% test
|
mysqltest1@localhost mysqltest1@% test
|
||||||
drop user USER, mysqltest1;
|
drop user 'USER', mysqltest1;
|
||||||
create user mysqltest1 identified via ed25519 as password("good");
|
create user mysqltest1 identified via ed25519 as password("good");
|
||||||
show create user mysqltest1;
|
show create user mysqltest1;
|
||||||
CREATE USER for mysqltest1@%
|
CREATE USER for mysqltest1@%
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
#
|
#
|
||||||
# with named user
|
# with named user
|
||||||
#
|
#
|
||||||
create user USER identified via unix_socket;
|
create user 'USER' identified via unix_socket;
|
||||||
#
|
#
|
||||||
# name match = ok
|
# name match = ok
|
||||||
#
|
#
|
||||||
@@ -11,7 +11,7 @@ USER@localhost USER@% test
|
|||||||
#
|
#
|
||||||
# name does not match = failure
|
# name does not match = failure
|
||||||
#
|
#
|
||||||
drop user USER;
|
drop user 'USER';
|
||||||
#
|
#
|
||||||
# and now with anonymous user
|
# and now with anonymous user
|
||||||
#
|
#
|
||||||
|
|||||||
@@ -26,13 +26,13 @@ install soname 'auth_ed25519';
|
|||||||
select user(), current_user(), database();
|
select user(), current_user(), database();
|
||||||
EOF
|
EOF
|
||||||
|
|
||||||
--let $creplace=create user $USER
|
--let $creplace=create user '$USER'
|
||||||
--let $dreplace=drop user $USER
|
--let $dreplace=drop user '$USER'
|
||||||
|
|
||||||
#
|
#
|
||||||
# socket,password
|
# socket,password
|
||||||
#
|
#
|
||||||
--replace_result $creplace "create user USER"
|
--replace_result $creplace "create user 'USER'"
|
||||||
eval $creplace identified via unix_socket OR mysql_native_password as password("GOOD");
|
eval $creplace identified via unix_socket OR mysql_native_password as password("GOOD");
|
||||||
create user mysqltest1 identified via unix_socket OR mysql_native_password as password("good");
|
create user mysqltest1 identified via unix_socket OR mysql_native_password as password("good");
|
||||||
show create user mysqltest1;
|
show create user mysqltest1;
|
||||||
@@ -43,13 +43,13 @@ show create user mysqltest1;
|
|||||||
--echo # name does not match, password bad = failure
|
--echo # name does not match, password bad = failure
|
||||||
--error 1
|
--error 1
|
||||||
--exec $try_auth -u mysqltest1 -pbad
|
--exec $try_auth -u mysqltest1 -pbad
|
||||||
--replace_result $dreplace "drop user USER"
|
--replace_result $dreplace "drop user 'USER'"
|
||||||
eval $dreplace, mysqltest1;
|
eval $dreplace, mysqltest1;
|
||||||
|
|
||||||
#
|
#
|
||||||
# password,socket
|
# password,socket
|
||||||
#
|
#
|
||||||
--replace_result $creplace "create user USER"
|
--replace_result $creplace "create user 'USER'"
|
||||||
eval $creplace identified via mysql_native_password as password("GOOD") OR unix_socket;
|
eval $creplace identified via mysql_native_password as password("GOOD") OR unix_socket;
|
||||||
create user mysqltest1 identified via mysql_native_password as password("good") OR unix_socket;
|
create user mysqltest1 identified via mysql_native_password as password("good") OR unix_socket;
|
||||||
show create user mysqltest1;
|
show create user mysqltest1;
|
||||||
@@ -60,13 +60,13 @@ show create user mysqltest1;
|
|||||||
--echo # name does not match, password bad = failure
|
--echo # name does not match, password bad = failure
|
||||||
--error 1
|
--error 1
|
||||||
--exec $try_auth -u mysqltest1 -pbad
|
--exec $try_auth -u mysqltest1 -pbad
|
||||||
--replace_result $dreplace "drop user USER"
|
--replace_result $dreplace "drop user 'USER'"
|
||||||
eval $dreplace, mysqltest1;
|
eval $dreplace, mysqltest1;
|
||||||
|
|
||||||
#
|
#
|
||||||
# socket,ed25519
|
# socket,ed25519
|
||||||
#
|
#
|
||||||
--replace_result $creplace "create user USER"
|
--replace_result $creplace "create user 'USER'"
|
||||||
eval $creplace identified via unix_socket OR ed25519 as password("GOOD");
|
eval $creplace identified via unix_socket OR ed25519 as password("GOOD");
|
||||||
create user mysqltest1 identified via unix_socket OR ed25519 as password("good");
|
create user mysqltest1 identified via unix_socket OR ed25519 as password("good");
|
||||||
show create user mysqltest1;
|
show create user mysqltest1;
|
||||||
@@ -77,13 +77,13 @@ show create user mysqltest1;
|
|||||||
--echo # name does not match, password bad = failure
|
--echo # name does not match, password bad = failure
|
||||||
--error 1
|
--error 1
|
||||||
--exec $try_auth -u mysqltest1 -pbad
|
--exec $try_auth -u mysqltest1 -pbad
|
||||||
--replace_result $dreplace "drop user USER"
|
--replace_result $dreplace "drop user 'USER'"
|
||||||
eval $dreplace, mysqltest1;
|
eval $dreplace, mysqltest1;
|
||||||
|
|
||||||
#
|
#
|
||||||
# ed25519,socket
|
# ed25519,socket
|
||||||
#
|
#
|
||||||
--replace_result $creplace "create user USER"
|
--replace_result $creplace "create user 'USER'"
|
||||||
eval $creplace identified via ed25519 as password("GOOD") OR unix_socket;
|
eval $creplace identified via ed25519 as password("GOOD") OR unix_socket;
|
||||||
create user mysqltest1 identified via ed25519 as password("good") OR unix_socket;
|
create user mysqltest1 identified via ed25519 as password("good") OR unix_socket;
|
||||||
show create user mysqltest1;
|
show create user mysqltest1;
|
||||||
@@ -94,13 +94,13 @@ show create user mysqltest1;
|
|||||||
--echo # name does not match, password bad = failure
|
--echo # name does not match, password bad = failure
|
||||||
--error 1
|
--error 1
|
||||||
--exec $try_auth -u mysqltest1 -pbad
|
--exec $try_auth -u mysqltest1 -pbad
|
||||||
--replace_result $dreplace "drop user USER"
|
--replace_result $dreplace "drop user 'USER'"
|
||||||
eval $dreplace, mysqltest1;
|
eval $dreplace, mysqltest1;
|
||||||
|
|
||||||
#
|
#
|
||||||
# ed25519,socket,password
|
# ed25519,socket,password
|
||||||
#
|
#
|
||||||
--replace_result $creplace "create user USER"
|
--replace_result $creplace "create user 'USER'"
|
||||||
eval $creplace identified via ed25519 as password("GOOD") OR unix_socket OR mysql_native_password as password("works");
|
eval $creplace identified via ed25519 as password("GOOD") OR unix_socket OR mysql_native_password as password("works");
|
||||||
create user mysqltest1 identified via ed25519 as password("good") OR unix_socket OR mysql_native_password as password("works");
|
create user mysqltest1 identified via ed25519 as password("good") OR unix_socket OR mysql_native_password as password("works");
|
||||||
show create user mysqltest1;
|
show create user mysqltest1;
|
||||||
@@ -113,7 +113,7 @@ show create user mysqltest1;
|
|||||||
--echo # name does not match, password bad = failure
|
--echo # name does not match, password bad = failure
|
||||||
--error 1
|
--error 1
|
||||||
--exec $try_auth -u mysqltest1 -pbad
|
--exec $try_auth -u mysqltest1 -pbad
|
||||||
--replace_result $dreplace "drop user USER"
|
--replace_result $dreplace "drop user 'USER'"
|
||||||
eval $dreplace, mysqltest1;
|
eval $dreplace, mysqltest1;
|
||||||
|
|
||||||
#
|
#
|
||||||
@@ -162,7 +162,7 @@ create user mysqltest1 identified via ed25519 as password("good") OR unix_socket
|
|||||||
#
|
#
|
||||||
# invalid password,socket
|
# invalid password,socket
|
||||||
#
|
#
|
||||||
--replace_result $creplace "create user USER"
|
--replace_result $creplace "create user 'USER'"
|
||||||
eval $creplace identified via mysql_native_password as '1234567890123456789012345678901234567890a' OR unix_socket;
|
eval $creplace identified via mysql_native_password as '1234567890123456789012345678901234567890a' OR unix_socket;
|
||||||
create user mysqltest1 identified via mysql_native_password as '1234567890123456789012345678901234567890a' OR unix_socket;
|
create user mysqltest1 identified via mysql_native_password as '1234567890123456789012345678901234567890a' OR unix_socket;
|
||||||
update mysql.global_priv set priv=replace(priv, '1234567890123456789012345678901234567890a', 'invalid password');
|
update mysql.global_priv set priv=replace(priv, '1234567890123456789012345678901234567890a', 'invalid password');
|
||||||
@@ -176,7 +176,7 @@ show create user mysqltest1;
|
|||||||
--echo # SET PASSWORD helps
|
--echo # SET PASSWORD helps
|
||||||
set password for mysqltest1 = password('bla');
|
set password for mysqltest1 = password('bla');
|
||||||
--exec $try_auth -u mysqltest1 -pbla
|
--exec $try_auth -u mysqltest1 -pbla
|
||||||
--replace_result $dreplace "drop user USER"
|
--replace_result $dreplace "drop user 'USER'"
|
||||||
eval $dreplace, mysqltest1;
|
eval $dreplace, mysqltest1;
|
||||||
|
|
||||||
#
|
#
|
||||||
|
|||||||
@@ -4,9 +4,9 @@
|
|||||||
--echo # with named user
|
--echo # with named user
|
||||||
--echo #
|
--echo #
|
||||||
|
|
||||||
--let $replace=create user $USER
|
--let $replace=create user '$USER'
|
||||||
--replace_result $replace "create user USER"
|
--replace_result $replace "create user 'USER'"
|
||||||
eval create user $USER identified via unix_socket;
|
eval create user '$USER' identified via unix_socket;
|
||||||
|
|
||||||
--write_file $MYSQLTEST_VARDIR/tmp/peercred_test.txt
|
--write_file $MYSQLTEST_VARDIR/tmp/peercred_test.txt
|
||||||
--let $replace1=$USER@localhost
|
--let $replace1=$USER@localhost
|
||||||
@@ -26,9 +26,9 @@ EOF
|
|||||||
--error 1
|
--error 1
|
||||||
--exec $MYSQL_TEST -u foobar < $MYSQLTEST_VARDIR/tmp/peercred_test.txt
|
--exec $MYSQL_TEST -u foobar < $MYSQLTEST_VARDIR/tmp/peercred_test.txt
|
||||||
|
|
||||||
--let $replace=drop user $USER
|
--let $replace=drop user '$USER'
|
||||||
--replace_result $replace "drop user USER"
|
--replace_result $replace "drop user 'USER'"
|
||||||
eval drop user $USER;
|
eval drop user '$USER';
|
||||||
|
|
||||||
--echo #
|
--echo #
|
||||||
--echo # and now with anonymous user
|
--echo # and now with anonymous user
|
||||||
|
|||||||
@@ -1349,7 +1349,7 @@ static void copy_to_read_buffer(IO_CACHE *write_cache,
|
|||||||
|
|
||||||
static int _my_b_seq_read(IO_CACHE *info, uchar *Buffer, size_t Count)
|
static int _my_b_seq_read(IO_CACHE *info, uchar *Buffer, size_t Count)
|
||||||
{
|
{
|
||||||
size_t length, diff_length, left_length= 0, save_count, max_length;
|
size_t length, diff_length, save_count, max_length;
|
||||||
my_off_t pos_in_file;
|
my_off_t pos_in_file;
|
||||||
save_count=Count;
|
save_count=Count;
|
||||||
|
|
||||||
@@ -1400,7 +1400,6 @@ static int _my_b_seq_read(IO_CACHE *info, uchar *Buffer, size_t Count)
|
|||||||
*/
|
*/
|
||||||
goto read_append_buffer;
|
goto read_append_buffer;
|
||||||
}
|
}
|
||||||
left_length+=length;
|
|
||||||
diff_length=0;
|
diff_length=0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1190,7 +1190,6 @@ trim_string()
|
|||||||
check_pid()
|
check_pid()
|
||||||
{
|
{
|
||||||
local pid_file="$1"
|
local pid_file="$1"
|
||||||
local remove=${2:-0}
|
|
||||||
if [ -r "$pid_file" ]; then
|
if [ -r "$pid_file" ]; then
|
||||||
local pid=$(cat "$pid_file" 2>/dev/null)
|
local pid=$(cat "$pid_file" 2>/dev/null)
|
||||||
if [ -n "$pid" ]; then
|
if [ -n "$pid" ]; then
|
||||||
@@ -1201,6 +1200,7 @@ check_pid()
|
|||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
local remove=${2:-0}
|
||||||
if [ $remove -eq 1 ]; then
|
if [ $remove -eq 1 ]; then
|
||||||
rm -f "$pid_file"
|
rm -f "$pid_file"
|
||||||
fi
|
fi
|
||||||
@@ -1223,7 +1223,7 @@ check_pid()
|
|||||||
#
|
#
|
||||||
cleanup_pid()
|
cleanup_pid()
|
||||||
{
|
{
|
||||||
local pid="$1"
|
local pid=$1
|
||||||
local pid_file="${2:-}"
|
local pid_file="${2:-}"
|
||||||
local config="${3:-}"
|
local config="${3:-}"
|
||||||
|
|
||||||
@@ -1241,8 +1241,9 @@ cleanup_pid()
|
|||||||
round=8
|
round=8
|
||||||
force=1
|
force=1
|
||||||
kill -9 $pid >/dev/null 2>&1
|
kill -9 $pid >/dev/null 2>&1
|
||||||
|
sleep 0.5
|
||||||
else
|
else
|
||||||
return 1;
|
return 1
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
done
|
done
|
||||||
|
|||||||
@@ -741,15 +741,15 @@ recv_joiner()
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
# check donor supplied secret
|
# check donor supplied secret
|
||||||
SECRET=$(grep -- "$SECRET_TAG " "$MAGIC_FILE" 2>/dev/null | cut -d ' ' -f 2)
|
SECRET=$(grep -F -- "$SECRET_TAG " "$MAGIC_FILE" 2>/dev/null | cut -d ' ' -f 2)
|
||||||
if [ "$SECRET" != "$MY_SECRET" ]; then
|
if [ "$SECRET" != "$MY_SECRET" ]; then
|
||||||
wsrep_log_error "Donor does not know my secret!"
|
wsrep_log_error "Donor does not know my secret!"
|
||||||
wsrep_log_info "Donor:'$SECRET', my:'$MY_SECRET'"
|
wsrep_log_info "Donor:'$SECRET', my:'$MY_SECRET'"
|
||||||
exit 32
|
exit 32
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# remove secret from magic file
|
# remove secret from the magic file
|
||||||
grep -v -- "$SECRET_TAG " "$MAGIC_FILE" > "$MAGIC_FILE.new"
|
grep -v -F -- "$SECRET_TAG " "$MAGIC_FILE" > "$MAGIC_FILE.new"
|
||||||
mv "$MAGIC_FILE.new" "$MAGIC_FILE"
|
mv "$MAGIC_FILE.new" "$MAGIC_FILE"
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -68,6 +68,8 @@ cleanup_joiner()
|
|||||||
if [ "$WSREP_SST_OPT_ROLE" = 'joiner' ]; then
|
if [ "$WSREP_SST_OPT_ROLE" = 'joiner' ]; then
|
||||||
wsrep_cleanup_progress_file
|
wsrep_cleanup_progress_file
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
[ -f "$SST_PID" ] && rm -f "$SST_PID"
|
||||||
}
|
}
|
||||||
|
|
||||||
check_pid_and_port()
|
check_pid_and_port()
|
||||||
@@ -281,6 +283,7 @@ then
|
|||||||
*)
|
*)
|
||||||
wsrep_log_error "Unrecognized ssl-mode option: '$SSLMODE'"
|
wsrep_log_error "Unrecognized ssl-mode option: '$SSLMODE'"
|
||||||
exit 22 # EINVAL
|
exit 22 # EINVAL
|
||||||
|
;;
|
||||||
esac
|
esac
|
||||||
if [ -z "$CAFILE_OPT" ]; then
|
if [ -z "$CAFILE_OPT" ]; then
|
||||||
wsrep_log_error "Can't have ssl-mode='$SSLMODE' without CA file"
|
wsrep_log_error "Can't have ssl-mode='$SSLMODE' without CA file"
|
||||||
@@ -426,7 +429,7 @@ EOF
|
|||||||
exit 255 # unknown error
|
exit 255 # unknown error
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# second, we transfer InnoDB log files
|
# second, we transfer InnoDB and Aria log files
|
||||||
rsync ${STUNNEL:+--rsh="$STUNNEL"} \
|
rsync ${STUNNEL:+--rsh="$STUNNEL"} \
|
||||||
--owner --group --perms --links --specials \
|
--owner --group --perms --links --specials \
|
||||||
--ignore-times --inplace --dirs --delete --quiet \
|
--ignore-times --inplace --dirs --delete --quiet \
|
||||||
@@ -499,7 +502,22 @@ elif [ "$WSREP_SST_OPT_ROLE" = 'joiner' ]
|
|||||||
then
|
then
|
||||||
check_sockets_utils
|
check_sockets_utils
|
||||||
|
|
||||||
# give some time for lingering stunnel from previous SST to complete
|
SST_PID="$WSREP_SST_OPT_DATA/wsrep_rsync_sst.pid"
|
||||||
|
|
||||||
|
# give some time for previous SST to complete:
|
||||||
|
check_round=0
|
||||||
|
while check_pid "$SST_PID" 0
|
||||||
|
do
|
||||||
|
wsrep_log_info "previous SST is not completed, waiting for it to exit"
|
||||||
|
check_round=$(( check_round + 1 ))
|
||||||
|
if [ $check_round -eq 10 ]; then
|
||||||
|
wsrep_log_error "previous SST script still running."
|
||||||
|
exit 114 # EALREADY
|
||||||
|
fi
|
||||||
|
sleep 1
|
||||||
|
done
|
||||||
|
|
||||||
|
# give some time for stunnel from the previous SST to complete:
|
||||||
check_round=0
|
check_round=0
|
||||||
while check_pid "$STUNNEL_PID" 1
|
while check_pid "$STUNNEL_PID" 1
|
||||||
do
|
do
|
||||||
@@ -516,7 +534,7 @@ then
|
|||||||
RSYNC_PID="$WSREP_SST_OPT_DATA/$MODULE.pid"
|
RSYNC_PID="$WSREP_SST_OPT_DATA/$MODULE.pid"
|
||||||
RSYNC_CONF="$WSREP_SST_OPT_DATA/$MODULE.conf"
|
RSYNC_CONF="$WSREP_SST_OPT_DATA/$MODULE.conf"
|
||||||
|
|
||||||
# give some time for lingering rsync from previous SST to complete
|
# give some time for rsync from the previous SST to complete:
|
||||||
check_round=0
|
check_round=0
|
||||||
while check_pid "$RSYNC_PID" 1
|
while check_pid "$RSYNC_PID" 1
|
||||||
do
|
do
|
||||||
@@ -583,12 +601,14 @@ EOF
|
|||||||
RSYNC_ADDR="*"
|
RSYNC_ADDR="*"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
echo $$ > "$SST_PID"
|
||||||
|
|
||||||
if [ -z "$STUNNEL" ]
|
if [ -z "$STUNNEL" ]
|
||||||
then
|
then
|
||||||
rsync --daemon --no-detach --port "$RSYNC_PORT" --config "$RSYNC_CONF" $RSYNC_EXTRA_ARGS &
|
rsync --daemon --no-detach --port "$RSYNC_PORT" --config "$RSYNC_CONF" $RSYNC_EXTRA_ARGS &
|
||||||
RSYNC_REAL_PID=$!
|
RSYNC_REAL_PID=$!
|
||||||
TRANSFER_REAL_PID="$RSYNC_REAL_PID"
|
TRANSFER_REAL_PID=$RSYNC_REAL_PID
|
||||||
TRANSFER_PID=$RSYNC_PID
|
TRANSFER_PID="$RSYNC_PID"
|
||||||
else
|
else
|
||||||
# Let's check if the path to the config file contains a space?
|
# Let's check if the path to the config file contains a space?
|
||||||
if [ "${RSYNC_CONF#* }" = "$RSYNC_CONF" ]; then
|
if [ "${RSYNC_CONF#* }" = "$RSYNC_CONF" ]; then
|
||||||
@@ -631,8 +651,8 @@ EOF
|
|||||||
fi
|
fi
|
||||||
stunnel "$STUNNEL_CONF" &
|
stunnel "$STUNNEL_CONF" &
|
||||||
STUNNEL_REAL_PID=$!
|
STUNNEL_REAL_PID=$!
|
||||||
TRANSFER_REAL_PID="$STUNNEL_REAL_PID"
|
TRANSFER_REAL_PID=$STUNNEL_REAL_PID
|
||||||
TRANSFER_PID=$STUNNEL_PID
|
TRANSFER_PID="$STUNNEL_PID"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [ "${SSLMODE#VERIFY}" != "$SSLMODE" ]
|
if [ "${SSLMODE#VERIFY}" != "$SSLMODE" ]
|
||||||
@@ -691,21 +711,35 @@ EOF
|
|||||||
|
|
||||||
# Clean up old binlog files first
|
# Clean up old binlog files first
|
||||||
rm -f "$BINLOG_FILENAME".[0-9]*
|
rm -f "$BINLOG_FILENAME".[0-9]*
|
||||||
[ -f "$binlog_index" ] && rm "$binlog_index"
|
[ -f "$binlog_index" ] && rm -f "$binlog_index"
|
||||||
|
|
||||||
|
# Create a temporary file:
|
||||||
|
tmpdir=$(parse_cnf '--mysqld|sst' 'tmpdir')
|
||||||
|
if [ -z "$tmpdir" ]; then
|
||||||
|
tmpfile="$(mktemp)"
|
||||||
|
else
|
||||||
|
tmpfile=$(mktemp "--tmpdir=$tmpdir")
|
||||||
|
fi
|
||||||
|
|
||||||
wsrep_log_info "Extracting binlog files:"
|
wsrep_log_info "Extracting binlog files:"
|
||||||
tar -xvf "$BINLOG_TAR_FILE" >> _binlog_tmp_files_$!
|
if ! tar -xvf "$BINLOG_TAR_FILE" > "$tmpfile"; then
|
||||||
|
wsrep_log_error "Error unpacking tar file with binlog files"
|
||||||
|
rm -f "$tmpfile"
|
||||||
|
exit 32
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Rebuild binlog index:
|
||||||
while read bin_file; do
|
while read bin_file; do
|
||||||
echo "$BINLOG_DIRNAME/$bin_file" >> "$binlog_index"
|
echo "$BINLOG_DIRNAME/$bin_file" >> "$binlog_index"
|
||||||
done < _binlog_tmp_files_$!
|
done < "$tmpfile"
|
||||||
rm -f _binlog_tmp_files_$!
|
rm -f "$tmpfile"
|
||||||
|
|
||||||
cd "$OLD_PWD"
|
cd "$OLD_PWD"
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [ -r "$MAGIC_FILE" ]
|
if [ -r "$MAGIC_FILE" ]; then
|
||||||
then
|
if [ -n "$MY_SECRET" ]; then
|
||||||
# check donor supplied secret
|
# check donor supplied secret
|
||||||
SECRET=$(grep -F -- "$SECRET_TAG " "$MAGIC_FILE" 2>/dev/null | cut -d ' ' -f 2)
|
SECRET=$(grep -F -- "$SECRET_TAG " "$MAGIC_FILE" 2>/dev/null | cut -d ' ' -f 2)
|
||||||
if [ "$SECRET" != "$MY_SECRET" ]; then
|
if [ "$SECRET" != "$MY_SECRET" ]; then
|
||||||
@@ -713,13 +747,13 @@ EOF
|
|||||||
wsrep_log_info "Donor:'$SECRET', my:'$MY_SECRET'"
|
wsrep_log_info "Donor:'$SECRET', my:'$MY_SECRET'"
|
||||||
exit 32
|
exit 32
|
||||||
fi
|
fi
|
||||||
|
# remove secret from the magic file, and output
|
||||||
# remove secret from magic file
|
# the UUID:seqno & wsrep_gtid_domain_id:
|
||||||
grep -v -F -- "$SECRET_TAG " "$MAGIC_FILE" > "$MAGIC_FILE.new"
|
grep -v -F -- "$SECRET_TAG " "$MAGIC_FILE"
|
||||||
|
else
|
||||||
mv "$MAGIC_FILE.new" "$MAGIC_FILE"
|
# Output the UUID:seqno and wsrep_gtid_domain_id:
|
||||||
# UUID:seqno & wsrep_gtid_domain_id is received here.
|
cat "$MAGIC_FILE"
|
||||||
cat "$MAGIC_FILE" # Output : UUID:seqno wsrep_gtid_domain_id
|
fi
|
||||||
else
|
else
|
||||||
# this message should cause joiner to abort
|
# this message should cause joiner to abort
|
||||||
echo "rsync process ended without creating '$MAGIC_FILE'"
|
echo "rsync process ended without creating '$MAGIC_FILE'"
|
||||||
|
|||||||
@@ -448,7 +448,7 @@ Event_scheduler::start(int *err_no)
|
|||||||
scheduler_thd= NULL;
|
scheduler_thd= NULL;
|
||||||
deinit_event_thread(new_thd);
|
deinit_event_thread(new_thd);
|
||||||
|
|
||||||
delete scheduler_param_value;
|
my_free(scheduler_param_value);
|
||||||
ret= true;
|
ret= true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -8544,6 +8544,7 @@ Item_cache_wrapper::Item_cache_wrapper(THD *thd, Item *item_arg):
|
|||||||
with_field= orig_item->with_field;
|
with_field= orig_item->with_field;
|
||||||
name= item_arg->name;
|
name= item_arg->name;
|
||||||
m_with_subquery= orig_item->with_subquery();
|
m_with_subquery= orig_item->with_subquery();
|
||||||
|
with_window_func= orig_item->with_window_func;
|
||||||
|
|
||||||
if ((expr_value= orig_item->get_cache(thd)))
|
if ((expr_value= orig_item->get_cache(thd)))
|
||||||
expr_value->setup(thd, orig_item);
|
expr_value->setup(thd, orig_item);
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/* Copyright (c) 2000, 2013, Oracle and/or its affiliates.
|
/* Copyright (c) 2000, 2013, Oracle and/or its affiliates.
|
||||||
Copyright (c) 2009, 2020, MariaDB
|
Copyright (c) 2009, 2021, MariaDB
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
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
|
it under the terms of the GNU General Public License as published by
|
||||||
@@ -1391,6 +1391,9 @@ bool Item_in_optimizer::fix_fields(THD *thd, Item **ref)
|
|||||||
maybe_null=1;
|
maybe_null=1;
|
||||||
m_with_subquery= true;
|
m_with_subquery= true;
|
||||||
join_with_sum_func(args[1]);
|
join_with_sum_func(args[1]);
|
||||||
|
with_window_func= args[0]->with_window_func;
|
||||||
|
// The subquery cannot have window functions aggregated in this select
|
||||||
|
DBUG_ASSERT(!args[1]->with_window_func);
|
||||||
with_field= with_field || args[1]->with_field;
|
with_field= with_field || args[1]->with_field;
|
||||||
with_param= args[0]->with_param || args[1]->with_param;
|
with_param= args[0]->with_param || args[1]->with_param;
|
||||||
used_tables_and_const_cache_join(args[1]);
|
used_tables_and_const_cache_join(args[1]);
|
||||||
|
|||||||
64
sql/mdl.cc
64
sql/mdl.cc
@@ -241,6 +241,35 @@ private:
|
|||||||
static const uint MAX_SEARCH_DEPTH= 32;
|
static const uint MAX_SEARCH_DEPTH= 32;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#ifndef DBUG_OFF
|
||||||
|
|
||||||
|
/*
|
||||||
|
Print a list of all locks to DBUG trace to help with debugging
|
||||||
|
*/
|
||||||
|
|
||||||
|
static int mdl_dbug_print_lock(MDL_ticket *mdl_ticket, void *arg, bool granted)
|
||||||
|
{
|
||||||
|
String *tmp= (String*) arg;
|
||||||
|
char buffer[128];
|
||||||
|
MDL_key *mdl_key= mdl_ticket->get_key();
|
||||||
|
size_t length;
|
||||||
|
length= my_snprintf(buffer, sizeof(buffer)-1,
|
||||||
|
"\nname: %s db: %.*s key_name: %.*s (%s)",
|
||||||
|
mdl_ticket->get_type_name()->str,
|
||||||
|
(int) mdl_key->db_name_length(), mdl_key->db_name(),
|
||||||
|
(int) mdl_key->name_length(), mdl_key->name(),
|
||||||
|
granted ? "granted" : "waiting");
|
||||||
|
tmp->append(buffer, length);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
const char *mdl_dbug_print_locks()
|
||||||
|
{
|
||||||
|
static String tmp;
|
||||||
|
mdl_iterate(mdl_dbug_print_lock, (void*) &tmp);
|
||||||
|
return tmp.c_ptr();
|
||||||
|
}
|
||||||
|
#endif /* DBUG_OFF */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Enter a node of a wait-for graph. After
|
Enter a node of a wait-for graph. After
|
||||||
@@ -2368,7 +2397,9 @@ MDL_context::acquire_lock(MDL_request *mdl_request, double lock_wait_timeout)
|
|||||||
switch (wait_status)
|
switch (wait_status)
|
||||||
{
|
{
|
||||||
case MDL_wait::VICTIM:
|
case MDL_wait::VICTIM:
|
||||||
mdl_dbug_print_locks();
|
DBUG_LOCK_FILE;
|
||||||
|
DBUG_PRINT("mdl_locks", ("%s", mdl_dbug_print_locks()));
|
||||||
|
DBUG_UNLOCK_FILE;
|
||||||
my_error(ER_LOCK_DEADLOCK, MYF(0));
|
my_error(ER_LOCK_DEADLOCK, MYF(0));
|
||||||
break;
|
break;
|
||||||
case MDL_wait::TIMEOUT:
|
case MDL_wait::TIMEOUT:
|
||||||
@@ -3247,34 +3278,3 @@ void MDL_ticket::wsrep_report(bool debug) const
|
|||||||
psi_stage->m_name);
|
psi_stage->m_name);
|
||||||
}
|
}
|
||||||
#endif /* WITH_WSREP */
|
#endif /* WITH_WSREP */
|
||||||
|
|
||||||
|
|
||||||
#ifndef DBUG_OFF
|
|
||||||
|
|
||||||
/*
|
|
||||||
Print a list of all locks to DBUG trace to help with debugging
|
|
||||||
*/
|
|
||||||
|
|
||||||
static int mdl_dbug_print_lock(MDL_ticket *mdl_ticket, void *arg, bool granted)
|
|
||||||
{
|
|
||||||
String *tmp= (String*) arg;
|
|
||||||
char buffer[128];
|
|
||||||
MDL_key *mdl_key= mdl_ticket->get_key();
|
|
||||||
size_t length;
|
|
||||||
length= my_snprintf(buffer, sizeof(buffer)-1,
|
|
||||||
"\nname: %s db: %.*s key_name: %.*s (%s)",
|
|
||||||
mdl_ticket->get_type_name()->str,
|
|
||||||
(int) mdl_key->db_name_length(), mdl_key->db_name(),
|
|
||||||
(int) mdl_key->name_length(), mdl_key->name(),
|
|
||||||
granted ? "granted" : "waiting");
|
|
||||||
tmp->append(buffer, length);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void mdl_dbug_print_locks()
|
|
||||||
{
|
|
||||||
String tmp;
|
|
||||||
mdl_iterate(mdl_dbug_print_lock, (void*) &tmp);
|
|
||||||
DBUG_PRINT("mdl_locks", ("%s", tmp.c_ptr()));
|
|
||||||
}
|
|
||||||
#endif /* DBUG_OFF */
|
|
||||||
|
|||||||
@@ -1130,9 +1130,4 @@ typedef int (*mdl_iterator_callback)(MDL_ticket *ticket, void *arg,
|
|||||||
bool granted);
|
bool granted);
|
||||||
extern MYSQL_PLUGIN_IMPORT
|
extern MYSQL_PLUGIN_IMPORT
|
||||||
int mdl_iterate(mdl_iterator_callback callback, void *arg);
|
int mdl_iterate(mdl_iterator_callback callback, void *arg);
|
||||||
#ifndef DBUG_OFF
|
|
||||||
void mdl_dbug_print_locks();
|
|
||||||
#else
|
|
||||||
static inline void mdl_dbug_print_locks() {}
|
|
||||||
#endif /* DBUG_OFF */
|
|
||||||
#endif /* MDL_H */
|
#endif /* MDL_H */
|
||||||
|
|||||||
@@ -4935,7 +4935,7 @@ make_join_statistics(JOIN *join, List<TABLE_LIST> &tables_list,
|
|||||||
int error= 0;
|
int error= 0;
|
||||||
TABLE *UNINIT_VAR(table); /* inited in all loops */
|
TABLE *UNINIT_VAR(table); /* inited in all loops */
|
||||||
uint i,table_count,const_count,key;
|
uint i,table_count,const_count,key;
|
||||||
table_map found_const_table_map, all_table_map, found_ref, refs;
|
table_map found_const_table_map, all_table_map;
|
||||||
key_map const_ref, eq_part;
|
key_map const_ref, eq_part;
|
||||||
bool has_expensive_keyparts;
|
bool has_expensive_keyparts;
|
||||||
TABLE **table_vector;
|
TABLE **table_vector;
|
||||||
@@ -5201,7 +5201,6 @@ make_join_statistics(JOIN *join, List<TABLE_LIST> &tables_list,
|
|||||||
{
|
{
|
||||||
ref_changed = 0;
|
ref_changed = 0;
|
||||||
more_const_tables_found:
|
more_const_tables_found:
|
||||||
found_ref=0;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
We only have to loop from stat_vector + const_count as
|
We only have to loop from stat_vector + const_count as
|
||||||
@@ -5291,7 +5290,6 @@ make_join_statistics(JOIN *join, List<TABLE_LIST> &tables_list,
|
|||||||
key=keyuse->key;
|
key=keyuse->key;
|
||||||
s->keys.set_bit(key); // TODO: remove this ?
|
s->keys.set_bit(key); // TODO: remove this ?
|
||||||
|
|
||||||
refs=0;
|
|
||||||
const_ref.clear_all();
|
const_ref.clear_all();
|
||||||
eq_part.clear_all();
|
eq_part.clear_all();
|
||||||
has_expensive_keyparts= false;
|
has_expensive_keyparts= false;
|
||||||
@@ -5307,8 +5305,6 @@ make_join_statistics(JOIN *join, List<TABLE_LIST> &tables_list,
|
|||||||
if (keyuse->val->is_expensive())
|
if (keyuse->val->is_expensive())
|
||||||
has_expensive_keyparts= true;
|
has_expensive_keyparts= true;
|
||||||
}
|
}
|
||||||
else
|
|
||||||
refs|=keyuse->used_tables;
|
|
||||||
eq_part.set_bit(keyuse->keypart);
|
eq_part.set_bit(keyuse->keypart);
|
||||||
}
|
}
|
||||||
keyuse++;
|
keyuse++;
|
||||||
@@ -5360,8 +5356,6 @@ make_join_statistics(JOIN *join, List<TABLE_LIST> &tables_list,
|
|||||||
found_const_table_map|= table->map;
|
found_const_table_map|= table->map;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
else
|
|
||||||
found_ref|= refs; // Table is const if all refs are const
|
|
||||||
}
|
}
|
||||||
else if (base_const_ref == base_eq_part)
|
else if (base_const_ref == base_eq_part)
|
||||||
s->const_keys.set_bit(key);
|
s->const_keys.set_bit(key);
|
||||||
@@ -28324,7 +28318,6 @@ static bool get_range_limit_read_cost(const JOIN_TAB *tab,
|
|||||||
*/
|
*/
|
||||||
if (tab)
|
if (tab)
|
||||||
{
|
{
|
||||||
key_part_map const_parts= 0;
|
|
||||||
key_part_map map= 1;
|
key_part_map map= 1;
|
||||||
uint kp;
|
uint kp;
|
||||||
/* Find how many key parts would be used by ref(const) */
|
/* Find how many key parts would be used by ref(const) */
|
||||||
@@ -28332,7 +28325,6 @@ static bool get_range_limit_read_cost(const JOIN_TAB *tab,
|
|||||||
{
|
{
|
||||||
if (!(table->const_key_parts[keynr] & map))
|
if (!(table->const_key_parts[keynr] & map))
|
||||||
break;
|
break;
|
||||||
const_parts |= map;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (kp > 0)
|
if (kp > 0)
|
||||||
|
|||||||
@@ -55,6 +55,9 @@ UNIV_INTERN uint srv_n_fil_crypt_threads_started = 0;
|
|||||||
/** At this age or older a space/page will be rotated */
|
/** At this age or older a space/page will be rotated */
|
||||||
UNIV_INTERN uint srv_fil_crypt_rotate_key_age;
|
UNIV_INTERN uint srv_fil_crypt_rotate_key_age;
|
||||||
|
|
||||||
|
/** Whether the encryption plugin does key rotation */
|
||||||
|
static bool srv_encrypt_rotate;
|
||||||
|
|
||||||
/** Event to signal FROM the key rotation threads. */
|
/** Event to signal FROM the key rotation threads. */
|
||||||
static os_event_t fil_crypt_event;
|
static os_event_t fil_crypt_event;
|
||||||
|
|
||||||
@@ -128,6 +131,14 @@ fil_space_crypt_t::key_get_latest_version(void)
|
|||||||
|
|
||||||
if (is_key_found()) {
|
if (is_key_found()) {
|
||||||
key_version = encryption_key_get_latest_version(key_id);
|
key_version = encryption_key_get_latest_version(key_id);
|
||||||
|
/* InnoDB does dirty read of srv_fil_crypt_rotate_key_age.
|
||||||
|
It doesn't matter because srv_encrypt_rotate
|
||||||
|
can be set to true only once */
|
||||||
|
if (!srv_encrypt_rotate
|
||||||
|
&& key_version > srv_fil_crypt_rotate_key_age) {
|
||||||
|
srv_encrypt_rotate = true;
|
||||||
|
}
|
||||||
|
|
||||||
srv_stats.n_key_requests.inc();
|
srv_stats.n_key_requests.inc();
|
||||||
key_found = key_version;
|
key_found = key_version;
|
||||||
}
|
}
|
||||||
@@ -1453,47 +1464,65 @@ inline bool fil_space_t::acquire_if_not_stopped()
|
|||||||
return UNIV_LIKELY(!(n & CLOSING)) || prepare(true);
|
return UNIV_LIKELY(!(n & CLOSING)) || prepare(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Return the next tablespace from rotation_list.
|
bool fil_crypt_must_default_encrypt()
|
||||||
@param space previous tablespace (NULL to start from the start)
|
{
|
||||||
|
return !srv_fil_crypt_rotate_key_age || !srv_encrypt_rotate;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Return the next tablespace from default_encrypt_tables list.
|
||||||
|
@param space previous tablespace (nullptr to start from the start)
|
||||||
@param recheck whether the removal condition needs to be rechecked after
|
@param recheck whether the removal condition needs to be rechecked after
|
||||||
the encryption parameters were changed
|
the encryption parameters were changed
|
||||||
@param encrypt expected state of innodb_encrypt_tables
|
@param encrypt expected state of innodb_encrypt_tables
|
||||||
@return the next tablespace to process (n_pending_ops incremented)
|
@return the next tablespace to process (n_pending_ops incremented)
|
||||||
@retval fil_system.temp_space if there is no work to do
|
@retval fil_system.temp_space if there is no work to do
|
||||||
@retval nullptr upon reaching the end of the iteration */
|
@retval nullptr upon reaching the end of the iteration */
|
||||||
inline fil_space_t *fil_system_t::keyrotate_next(fil_space_t *space,
|
inline fil_space_t *fil_system_t::default_encrypt_next(fil_space_t *space,
|
||||||
bool recheck, bool encrypt)
|
bool recheck,
|
||||||
|
bool encrypt)
|
||||||
{
|
{
|
||||||
ut_ad(mutex_own(&mutex));
|
ut_ad(mutex_own(&mutex));
|
||||||
|
|
||||||
sized_ilist<fil_space_t, rotation_list_tag_t>::iterator it=
|
sized_ilist<fil_space_t, rotation_list_tag_t>::iterator it=
|
||||||
space && space->is_in_rotation_list ? space : rotation_list.begin();
|
space && space->is_in_default_encrypt
|
||||||
|
? space
|
||||||
|
: default_encrypt_tables.begin();
|
||||||
const sized_ilist<fil_space_t, rotation_list_tag_t>::iterator end=
|
const sized_ilist<fil_space_t, rotation_list_tag_t>::iterator end=
|
||||||
rotation_list.end();
|
default_encrypt_tables.end();
|
||||||
|
|
||||||
if (space)
|
if (space)
|
||||||
{
|
{
|
||||||
const bool released= !space->release();
|
const bool released= !space->release();
|
||||||
|
|
||||||
if (space->is_in_rotation_list)
|
if (space->is_in_default_encrypt)
|
||||||
{
|
{
|
||||||
while (++it != end &&
|
while (++it != end &&
|
||||||
(!UT_LIST_GET_LEN(it->chain) || it->is_stopping()));
|
(!UT_LIST_GET_LEN(it->chain) || it->is_stopping()));
|
||||||
|
|
||||||
/* If one of the encryption threads already started the encryption
|
/* If one of the encryption threads already started
|
||||||
of the table then don't remove the unencrypted spaces from rotation list
|
the encryption of the table then don't remove the
|
||||||
|
unencrypted spaces from default encrypt list.
|
||||||
|
|
||||||
If there is a change in innodb_encrypt_tables variables value then
|
If there is a change in innodb_encrypt_tables variables
|
||||||
don't remove the last processed tablespace from the rotation list. */
|
value then don't remove the last processed tablespace
|
||||||
|
from the default encrypt list. */
|
||||||
if (released && (!recheck || space->crypt_data) &&
|
if (released && (!recheck || space->crypt_data) &&
|
||||||
!encrypt == !srv_encrypt_tables)
|
!encrypt == !srv_encrypt_tables)
|
||||||
{
|
{
|
||||||
ut_a(!rotation_list.empty());
|
ut_a(!default_encrypt_tables.empty());
|
||||||
rotation_list.remove(*space);
|
default_encrypt_tables.remove(*space);
|
||||||
space->is_in_rotation_list= false;
|
space->is_in_default_encrypt= false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else while (it != end &&
|
||||||
|
(!UT_LIST_GET_LEN(it->chain) || it->is_stopping()))
|
||||||
|
{
|
||||||
|
/* Find the next suitable default encrypt table if
|
||||||
|
beginning of default_encrypt_tables list has been scheduled
|
||||||
|
to be deleted */
|
||||||
|
it++;
|
||||||
|
}
|
||||||
|
|
||||||
if (it == end)
|
if (it == end)
|
||||||
return temp_space;
|
return temp_space;
|
||||||
@@ -1524,8 +1553,8 @@ inline fil_space_t *fil_space_t::next(fil_space_t *space, bool recheck,
|
|||||||
{
|
{
|
||||||
mutex_enter(&fil_system.mutex);
|
mutex_enter(&fil_system.mutex);
|
||||||
|
|
||||||
if (!srv_fil_crypt_rotate_key_age)
|
if (fil_crypt_must_default_encrypt())
|
||||||
space= fil_system.keyrotate_next(space, recheck, encrypt);
|
space= fil_system.default_encrypt_next(space, recheck, encrypt);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (!space)
|
if (!space)
|
||||||
@@ -2271,9 +2300,9 @@ fil_crypt_set_thread_cnt(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Initialize the tablespace rotation_list
|
/** Initialize the tablespace default_encrypt_tables
|
||||||
if innodb_encryption_rotate_key_age=0. */
|
if innodb_encryption_rotate_key_age=0. */
|
||||||
static void fil_crypt_rotation_list_fill()
|
static void fil_crypt_default_encrypt_tables_fill()
|
||||||
{
|
{
|
||||||
ut_ad(mutex_own(&fil_system.mutex));
|
ut_ad(mutex_own(&fil_system.mutex));
|
||||||
|
|
||||||
@@ -2281,7 +2310,7 @@ static void fil_crypt_rotation_list_fill()
|
|||||||
space != NULL;
|
space != NULL;
|
||||||
space = UT_LIST_GET_NEXT(space_list, space)) {
|
space = UT_LIST_GET_NEXT(space_list, space)) {
|
||||||
if (space->purpose != FIL_TYPE_TABLESPACE
|
if (space->purpose != FIL_TYPE_TABLESPACE
|
||||||
|| space->is_in_rotation_list
|
|| space->is_in_default_encrypt
|
||||||
|| UT_LIST_GET_LEN(space->chain) == 0
|
|| UT_LIST_GET_LEN(space->chain) == 0
|
||||||
|| !space->acquire_if_not_stopped()) {
|
|| !space->acquire_if_not_stopped()) {
|
||||||
continue;
|
continue;
|
||||||
@@ -2312,8 +2341,8 @@ static void fil_crypt_rotation_list_fill()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fil_system.rotation_list.push_back(*space);
|
fil_system.default_encrypt_tables.push_back(*space);
|
||||||
space->is_in_rotation_list = true;
|
space->is_in_default_encrypt = true;
|
||||||
next:
|
next:
|
||||||
space->release();
|
space->release();
|
||||||
}
|
}
|
||||||
@@ -2330,7 +2359,7 @@ fil_crypt_set_rotate_key_age(
|
|||||||
mutex_enter(&fil_system.mutex);
|
mutex_enter(&fil_system.mutex);
|
||||||
srv_fil_crypt_rotate_key_age = val;
|
srv_fil_crypt_rotate_key_age = val;
|
||||||
if (val == 0) {
|
if (val == 0) {
|
||||||
fil_crypt_rotation_list_fill();
|
fil_crypt_default_encrypt_tables_fill();
|
||||||
}
|
}
|
||||||
mutex_exit(&fil_system.mutex);
|
mutex_exit(&fil_system.mutex);
|
||||||
os_event_set(fil_crypt_threads_event);
|
os_event_set(fil_crypt_threads_event);
|
||||||
@@ -2357,8 +2386,8 @@ void fil_crypt_set_encrypt_tables(ulong val)
|
|||||||
|
|
||||||
srv_encrypt_tables = val;
|
srv_encrypt_tables = val;
|
||||||
|
|
||||||
if (srv_fil_crypt_rotate_key_age == 0) {
|
if (fil_crypt_must_default_encrypt()) {
|
||||||
fil_crypt_rotation_list_fill();
|
fil_crypt_default_encrypt_tables_fill();
|
||||||
}
|
}
|
||||||
|
|
||||||
mutex_exit(&fil_system.mutex);
|
mutex_exit(&fil_system.mutex);
|
||||||
|
|||||||
@@ -776,10 +776,10 @@ std::vector<pfs_os_file_t> fil_system_t::detach(fil_space_t *space,
|
|||||||
unflushed_spaces.remove(*space);
|
unflushed_spaces.remove(*space);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (space->is_in_rotation_list)
|
if (space->is_in_default_encrypt)
|
||||||
{
|
{
|
||||||
space->is_in_rotation_list= false;
|
space->is_in_default_encrypt= false;
|
||||||
rotation_list.remove(*space);
|
default_encrypt_tables.remove(*space);
|
||||||
}
|
}
|
||||||
UT_LIST_REMOVE(space_list, space);
|
UT_LIST_REMOVE(space_list, space);
|
||||||
if (space == sys_space)
|
if (space == sys_space)
|
||||||
@@ -1001,20 +1001,25 @@ fil_space_t *fil_space_t::create(const char *name, ulint id, ulint flags,
|
|||||||
fil_system.max_assigned_id = id;
|
fil_system.max_assigned_id = id;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const bool rotate =
|
||||||
|
(purpose == FIL_TYPE_TABLESPACE
|
||||||
|
&& (mode == FIL_ENCRYPTION_ON
|
||||||
|
|| mode == FIL_ENCRYPTION_OFF || srv_encrypt_tables)
|
||||||
|
&& fil_crypt_must_default_encrypt());
|
||||||
|
|
||||||
/* Inform key rotation that there could be something
|
/* Inform key rotation that there could be something
|
||||||
to do */
|
to do */
|
||||||
if (purpose == FIL_TYPE_TABLESPACE
|
if (rotate) {
|
||||||
&& !srv_fil_crypt_rotate_key_age && fil_crypt_threads_event &&
|
|
||||||
(mode == FIL_ENCRYPTION_ON || mode == FIL_ENCRYPTION_OFF
|
|
||||||
|| srv_encrypt_tables)) {
|
|
||||||
/* Key rotation is not enabled, need to inform background
|
/* Key rotation is not enabled, need to inform background
|
||||||
encryption threads. */
|
encryption threads. */
|
||||||
fil_system.rotation_list.push_back(*space);
|
fil_system.default_encrypt_tables.push_back(*space);
|
||||||
space->is_in_rotation_list = true;
|
space->is_in_default_encrypt = true;
|
||||||
|
}
|
||||||
|
|
||||||
mutex_exit(&fil_system.mutex);
|
mutex_exit(&fil_system.mutex);
|
||||||
|
|
||||||
|
if (rotate && srv_n_fil_crypt_threads_started) {
|
||||||
os_event_set(fil_crypt_threads_event);
|
os_event_set(fil_crypt_threads_event);
|
||||||
} else {
|
|
||||||
mutex_exit(&fil_system.mutex);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return(space);
|
return(space);
|
||||||
|
|||||||
@@ -2323,7 +2323,6 @@ fsp_reserve_free_extents(
|
|||||||
uint32_t n_pages)
|
uint32_t n_pages)
|
||||||
{
|
{
|
||||||
ulint reserve;
|
ulint reserve;
|
||||||
size_t total_reserved = 0;
|
|
||||||
|
|
||||||
ut_ad(mtr);
|
ut_ad(mtr);
|
||||||
*n_reserved = n_ext;
|
*n_reserved = n_ext;
|
||||||
@@ -2409,8 +2408,7 @@ try_again:
|
|||||||
return(true);
|
return(true);
|
||||||
}
|
}
|
||||||
try_to_extend:
|
try_to_extend:
|
||||||
if (ulint n = fsp_try_extend_data_file(space, header, mtr)) {
|
if (fsp_try_extend_data_file(space, header, mtr)) {
|
||||||
total_reserved += n;
|
|
||||||
goto try_again;
|
goto try_again;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -446,4 +446,10 @@ encrypted, or corrupted.
|
|||||||
bool fil_space_verify_crypt_checksum(const byte* page, ulint zip_size)
|
bool fil_space_verify_crypt_checksum(const byte* page, ulint zip_size)
|
||||||
MY_ATTRIBUTE((warn_unused_result));
|
MY_ATTRIBUTE((warn_unused_result));
|
||||||
|
|
||||||
|
/** Add the tablespace to the rotation list if
|
||||||
|
innodb_encrypt_rotate_key_age is 0 or encryption plugin does
|
||||||
|
not do key version rotation
|
||||||
|
@return whether the tablespace should be added to rotation list */
|
||||||
|
bool fil_crypt_must_default_encrypt();
|
||||||
|
|
||||||
#endif /* fil0crypt_h */
|
#endif /* fil0crypt_h */
|
||||||
|
|||||||
@@ -405,7 +405,7 @@ public:
|
|||||||
bool is_in_unflushed_spaces;
|
bool is_in_unflushed_spaces;
|
||||||
|
|
||||||
/** Checks that this tablespace needs key rotation. */
|
/** Checks that this tablespace needs key rotation. */
|
||||||
bool is_in_rotation_list;
|
bool is_in_default_encrypt;
|
||||||
|
|
||||||
/** True if the device this filespace is on supports atomic writes */
|
/** True if the device this filespace is on supports atomic writes */
|
||||||
bool atomic_write_supported;
|
bool atomic_write_supported;
|
||||||
@@ -1404,23 +1404,24 @@ public:
|
|||||||
record has been written since
|
record has been written since
|
||||||
the latest redo log checkpoint.
|
the latest redo log checkpoint.
|
||||||
Protected only by log_sys.mutex. */
|
Protected only by log_sys.mutex. */
|
||||||
ilist<fil_space_t, rotation_list_tag_t> rotation_list;
|
|
||||||
/*!< list of all file spaces needing
|
/** List of all file spaces need key rotation */
|
||||||
key rotation.*/
|
ilist<fil_space_t, rotation_list_tag_t> default_encrypt_tables;
|
||||||
|
|
||||||
bool space_id_reuse_warned;
|
bool space_id_reuse_warned;
|
||||||
/*!< whether fil_space_t::create()
|
/*!< whether fil_space_t::create()
|
||||||
has issued a warning about
|
has issued a warning about
|
||||||
potential space_id reuse */
|
potential space_id reuse */
|
||||||
|
|
||||||
/** Return the next tablespace from rotation_list.
|
/** Return the next tablespace from default_encrypt_tables list.
|
||||||
@param space previous tablespace (NULL to start from the start)
|
@param space previous tablespace (nullptr to start from the start)
|
||||||
@param recheck whether the removal condition needs to be rechecked after
|
@param recheck whether the removal condition needs to be rechecked after
|
||||||
the encryption parameters were changed
|
the encryption parameters were changed
|
||||||
@param encrypt expected state of innodb_encrypt_tables
|
@param encrypt expected state of innodb_encrypt_tables
|
||||||
@return the next tablespace to process (n_pending_ops incremented)
|
@return the next tablespace to process (n_pending_ops incremented)
|
||||||
@retval NULL if this was the last */
|
@retval fil_system.temp_space if there is no work to do
|
||||||
inline fil_space_t* keyrotate_next(fil_space_t *space, bool recheck,
|
@retval nullptr upon reaching the end of the iteration */
|
||||||
|
inline fil_space_t* default_encrypt_next(fil_space_t *space, bool recheck,
|
||||||
bool encrypt);
|
bool encrypt);
|
||||||
|
|
||||||
/** Extend all open data files to the recovered size */
|
/** Extend all open data files to the recovered size */
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
/*****************************************************************************
|
/*****************************************************************************
|
||||||
|
|
||||||
Copyright (c) 1996, 2016, Oracle and/or its affiliates. All Rights Reserved.
|
Copyright (c) 1996, 2016, Oracle and/or its affiliates. All Rights Reserved.
|
||||||
Copyright (c) 2017, 2020, MariaDB Corporation.
|
Copyright (c) 2017, 2021, MariaDB Corporation.
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify it under
|
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
|
the terms of the GNU General Public License as published by the Free Software
|
||||||
@@ -60,20 +60,17 @@ public:
|
|||||||
typedef trx_rsegs_t::iterator iterator;
|
typedef trx_rsegs_t::iterator iterator;
|
||||||
typedef trx_rsegs_t::const_iterator const_iterator;
|
typedef trx_rsegs_t::const_iterator const_iterator;
|
||||||
|
|
||||||
/** Default constructor */
|
|
||||||
TrxUndoRsegs() {}
|
TrxUndoRsegs() {}
|
||||||
|
|
||||||
/** Constructor */
|
/** Constructor */
|
||||||
TrxUndoRsegs(trx_rseg_t& rseg)
|
TrxUndoRsegs(trx_rseg_t& rseg)
|
||||||
: m_commit(rseg.last_commit), m_rsegs(1, &rseg) {}
|
: trx_no(rseg.last_trx_no()), m_rsegs(1, &rseg) {}
|
||||||
/** Constructor */
|
/** Constructor */
|
||||||
TrxUndoRsegs(trx_id_t trx_no, trx_rseg_t& rseg)
|
TrxUndoRsegs(trx_id_t trx_no, trx_rseg_t& rseg)
|
||||||
: m_commit(trx_no << 1), m_rsegs(1, &rseg) {}
|
: trx_no(trx_no), m_rsegs(1, &rseg) {}
|
||||||
|
|
||||||
/** @return the transaction commit identifier */
|
|
||||||
trx_id_t trx_no() const { return m_commit >> 1; }
|
|
||||||
|
|
||||||
bool operator!=(const TrxUndoRsegs& other) const
|
bool operator!=(const TrxUndoRsegs& other) const
|
||||||
{ return m_commit != other.m_commit; }
|
{ return trx_no != other.trx_no; }
|
||||||
bool empty() const { return m_rsegs.empty(); }
|
bool empty() const { return m_rsegs.empty(); }
|
||||||
void erase(iterator& it) { m_rsegs.erase(it); }
|
void erase(iterator& it) { m_rsegs.erase(it); }
|
||||||
iterator begin() { return(m_rsegs.begin()); }
|
iterator begin() { return(m_rsegs.begin()); }
|
||||||
@@ -87,14 +84,14 @@ public:
|
|||||||
@return true if elem1 > elem2 else false.*/
|
@return true if elem1 > elem2 else false.*/
|
||||||
bool operator()(const TrxUndoRsegs& lhs, const TrxUndoRsegs& rhs)
|
bool operator()(const TrxUndoRsegs& lhs, const TrxUndoRsegs& rhs)
|
||||||
{
|
{
|
||||||
return(lhs.m_commit > rhs.m_commit);
|
return(lhs.trx_no > rhs.trx_no);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Copy of trx_rseg_t::last_trx_no() */
|
||||||
|
trx_id_t trx_no= 0;
|
||||||
private:
|
private:
|
||||||
/** Copy trx_rseg_t::last_commit */
|
|
||||||
trx_id_t m_commit;
|
|
||||||
/** Rollback segments of a transaction, scheduled for purge. */
|
/** Rollback segments of a transaction, scheduled for purge. */
|
||||||
trx_rsegs_t m_rsegs;
|
trx_rsegs_t m_rsegs{};
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef std::priority_queue<
|
typedef std::priority_queue<
|
||||||
@@ -146,17 +143,13 @@ public:
|
|||||||
{
|
{
|
||||||
bool operator<=(const iterator& other) const
|
bool operator<=(const iterator& other) const
|
||||||
{
|
{
|
||||||
if (commit < other.commit) return true;
|
if (trx_no < other.trx_no) return true;
|
||||||
if (commit > other.commit) return false;
|
if (trx_no > other.trx_no) return false;
|
||||||
return undo_no <= other.undo_no;
|
return undo_no <= other.undo_no;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @return the commit number of the transaction */
|
/** trx_t::no of the committed transaction */
|
||||||
trx_id_t trx_no() const { return commit >> 1; }
|
trx_id_t trx_no;
|
||||||
void reset_trx_no(trx_id_t trx_no) { commit = trx_no << 1; }
|
|
||||||
|
|
||||||
/** 2 * trx_t::no + old_insert of the committed transaction */
|
|
||||||
trx_id_t commit;
|
|
||||||
/** The record number within the committed transaction's undo
|
/** The record number within the committed transaction's undo
|
||||||
log, increasing, purged from from 0 onwards */
|
log, increasing, purged from from 0 onwards */
|
||||||
undo_no_t undo_no;
|
undo_no_t undo_no;
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
/*****************************************************************************
|
/*****************************************************************************
|
||||||
|
|
||||||
Copyright (c) 1996, 2016, Oracle and/or its affiliates. All Rights Reserved.
|
Copyright (c) 1996, 2016, Oracle and/or its affiliates. All Rights Reserved.
|
||||||
Copyright (c) 2017, 2020, MariaDB Corporation.
|
Copyright (c) 2017, 2021, MariaDB Corporation.
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify it under
|
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
|
the terms of the GNU General Public License as published by the Free Software
|
||||||
@@ -65,9 +65,8 @@ trx_rseg_header_create(
|
|||||||
buf_block_t* sys_header,
|
buf_block_t* sys_header,
|
||||||
mtr_t* mtr);
|
mtr_t* mtr);
|
||||||
|
|
||||||
/** Initialize the rollback segments in memory at database startup. */
|
/** Initialize or recover the rollback segments at startup. */
|
||||||
void
|
dberr_t trx_rseg_array_init();
|
||||||
trx_rseg_array_init();
|
|
||||||
|
|
||||||
/** Free a rollback segment in memory. */
|
/** Free a rollback segment in memory. */
|
||||||
void
|
void
|
||||||
@@ -119,21 +118,13 @@ struct trx_rseg_t {
|
|||||||
/** List of undo log segments cached for fast reuse */
|
/** List of undo log segments cached for fast reuse */
|
||||||
UT_LIST_BASE_NODE_T(trx_undo_t) undo_cached;
|
UT_LIST_BASE_NODE_T(trx_undo_t) undo_cached;
|
||||||
|
|
||||||
/** List of recovered old insert_undo logs of incomplete
|
|
||||||
transactions (to roll back or XA COMMIT & purge) */
|
|
||||||
UT_LIST_BASE_NODE_T(trx_undo_t) old_insert_list;
|
|
||||||
|
|
||||||
/*--------------------------------------------------------*/
|
/*--------------------------------------------------------*/
|
||||||
|
|
||||||
/** Page number of the last not yet purged log header in the history
|
/** Last not yet purged undo log header; FIL_NULL if all purged */
|
||||||
list; FIL_NULL if all list purged */
|
|
||||||
uint32_t last_page_no;
|
uint32_t last_page_no;
|
||||||
|
|
||||||
/** Byte offset of the last not yet purged log header */
|
/** trx_t::no | last_offset << 48 */
|
||||||
uint16_t last_offset;
|
uint64_t last_commit_and_offset;
|
||||||
|
|
||||||
/** trx_t::no * 2 + old_insert of the last not yet purged log */
|
|
||||||
trx_id_t last_commit;
|
|
||||||
|
|
||||||
/** Whether the log segment needs purge */
|
/** Whether the log segment needs purge */
|
||||||
bool needs_purge;
|
bool needs_purge;
|
||||||
@@ -146,11 +137,15 @@ struct trx_rseg_t {
|
|||||||
bool skip_allocation;
|
bool skip_allocation;
|
||||||
|
|
||||||
/** @return the commit ID of the last committed transaction */
|
/** @return the commit ID of the last committed transaction */
|
||||||
trx_id_t last_trx_no() const { return last_commit >> 1; }
|
trx_id_t last_trx_no() const
|
||||||
|
{ return last_commit_and_offset & ((1ULL << 48) - 1); }
|
||||||
|
/** @return header offset of the last committed transaction */
|
||||||
|
uint16_t last_offset() const
|
||||||
|
{ return static_cast<uint16_t>(last_commit_and_offset >> 48); }
|
||||||
|
|
||||||
void set_last_trx_no(trx_id_t trx_no, bool is_update)
|
void set_last_commit(uint16_t last_offset, trx_id_t trx_no)
|
||||||
{
|
{
|
||||||
last_commit = trx_no << 1 | trx_id_t(is_update);
|
last_commit_and_offset= static_cast<uint64_t>(last_offset) << 48 | trx_no;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @return whether the rollback segment is persistent */
|
/** @return whether the rollback segment is persistent */
|
||||||
|
|||||||
@@ -79,7 +79,7 @@ void trx_free_at_shutdown(trx_t *trx);
|
|||||||
void trx_disconnect_prepared(trx_t *trx);
|
void trx_disconnect_prepared(trx_t *trx);
|
||||||
|
|
||||||
/** Initialize (resurrect) transactions at startup. */
|
/** Initialize (resurrect) transactions at startup. */
|
||||||
void trx_lists_init_at_db_start();
|
dberr_t trx_lists_init_at_db_start();
|
||||||
|
|
||||||
/*************************************************************//**
|
/*************************************************************//**
|
||||||
Starts the transaction if it is not yet started. */
|
Starts the transaction if it is not yet started. */
|
||||||
@@ -621,10 +621,6 @@ struct trx_undo_ptr_t {
|
|||||||
yet */
|
yet */
|
||||||
trx_undo_t* undo; /*!< pointer to the undo log, or
|
trx_undo_t* undo; /*!< pointer to the undo log, or
|
||||||
NULL if nothing logged yet */
|
NULL if nothing logged yet */
|
||||||
trx_undo_t* old_insert; /*!< pointer to recovered
|
|
||||||
insert undo log, or NULL if no
|
|
||||||
INSERT transactions were
|
|
||||||
recovered from old-format undo logs */
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/** An instance of temporary rollback segment. */
|
/** An instance of temporary rollback segment. */
|
||||||
@@ -945,13 +941,6 @@ public:
|
|||||||
return(has_logged_persistent() || rsegs.m_noredo.undo);
|
return(has_logged_persistent() || rsegs.m_noredo.undo);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @return whether any undo log has been generated or
|
|
||||||
recovered */
|
|
||||||
bool has_logged_or_recovered() const
|
|
||||||
{
|
|
||||||
return(has_logged() || rsegs.m_redo.old_insert);
|
|
||||||
}
|
|
||||||
|
|
||||||
/** @return rollback segment for modifying temporary tables */
|
/** @return rollback segment for modifying temporary tables */
|
||||||
trx_rseg_t* get_temp_rseg()
|
trx_rseg_t* get_temp_rseg()
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
/*****************************************************************************
|
/*****************************************************************************
|
||||||
|
|
||||||
Copyright (c) 1996, 2014, Oracle and/or its affiliates. All Rights Reserved.
|
Copyright (c) 1996, 2014, Oracle and/or its affiliates. All Rights Reserved.
|
||||||
Copyright (c) 2017, 2019, MariaDB Corporation.
|
Copyright (c) 2017, 2021, MariaDB Corporation.
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify it under
|
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
|
the terms of the GNU General Public License as published by the Free Software
|
||||||
@@ -93,8 +93,6 @@ enum trx_dict_op_t {
|
|||||||
struct trx_t;
|
struct trx_t;
|
||||||
/** The locks and state of an active transaction */
|
/** The locks and state of an active transaction */
|
||||||
struct trx_lock_t;
|
struct trx_lock_t;
|
||||||
/** Signal */
|
|
||||||
struct trx_sig_t;
|
|
||||||
/** Rollback segment */
|
/** Rollback segment */
|
||||||
struct trx_rseg_t;
|
struct trx_rseg_t;
|
||||||
/** Transaction undo log */
|
/** Transaction undo log */
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
/*****************************************************************************
|
/*****************************************************************************
|
||||||
|
|
||||||
Copyright (c) 1996, 2016, Oracle and/or its affiliates. All Rights Reserved.
|
Copyright (c) 1996, 2016, Oracle and/or its affiliates. All Rights Reserved.
|
||||||
Copyright (c) 2017, 2020, MariaDB Corporation.
|
Copyright (c) 2017, 2021, MariaDB Corporation.
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify it under
|
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
|
the terms of the GNU General Public License as published by the Free Software
|
||||||
@@ -244,13 +244,11 @@ void trx_undo_set_state_at_prepare(trx_t *trx, trx_undo_t *undo, bool rollback,
|
|||||||
mtr_t *mtr)
|
mtr_t *mtr)
|
||||||
MY_ATTRIBUTE((nonnull));
|
MY_ATTRIBUTE((nonnull));
|
||||||
|
|
||||||
/** Free an old insert or temporary undo log after commit or rollback.
|
/** Free temporary undo log after commit or rollback.
|
||||||
The information is not needed after a commit or rollback, therefore
|
The information is not needed after a commit or rollback, therefore
|
||||||
the data can be discarded.
|
the data can be discarded.
|
||||||
@param[in,out] undo undo log
|
@param undo temporary undo log */
|
||||||
@param[in] is_temp whether this is temporary undo log */
|
void trx_undo_commit_cleanup(trx_undo_t *undo);
|
||||||
void
|
|
||||||
trx_undo_commit_cleanup(trx_undo_t* undo, bool is_temp);
|
|
||||||
|
|
||||||
/** At shutdown, frees the undo logs of a transaction. */
|
/** At shutdown, frees the undo logs of a transaction. */
|
||||||
void
|
void
|
||||||
@@ -261,26 +259,21 @@ trx_undo_free_at_shutdown(trx_t *trx);
|
|||||||
@param[in] id rollback segment slot
|
@param[in] id rollback segment slot
|
||||||
@param[in] page_no undo log segment page number
|
@param[in] page_no undo log segment page number
|
||||||
@param[in,out] max_trx_id the largest observed transaction ID
|
@param[in,out] max_trx_id the largest observed transaction ID
|
||||||
@return size of the undo log in pages */
|
@return the undo log
|
||||||
uint32_t
|
@retval nullptr on error */
|
||||||
|
trx_undo_t *
|
||||||
trx_undo_mem_create_at_db_start(trx_rseg_t *rseg, ulint id, uint32_t page_no,
|
trx_undo_mem_create_at_db_start(trx_rseg_t *rseg, ulint id, uint32_t page_no,
|
||||||
trx_id_t &max_trx_id);
|
trx_id_t &max_trx_id);
|
||||||
|
|
||||||
#endif /* !UNIV_INNOCHECKSUM */
|
#endif /* !UNIV_INNOCHECKSUM */
|
||||||
|
|
||||||
/* Types of an undo log segment */
|
/** the only rollback segment type since MariaDB 10.3.1 */
|
||||||
#define TRX_UNDO_INSERT 1 /* contains undo entries for inserts */
|
constexpr uint16_t TRX_UNDO_UPDATE= 2;
|
||||||
#define TRX_UNDO_UPDATE 2 /* contains undo entries for updates
|
|
||||||
and delete markings: in short,
|
|
||||||
modifys (the name 'UPDATE' is a
|
|
||||||
historical relic) */
|
|
||||||
/* TRX_UNDO_STATE values of an undo log segment */
|
/* TRX_UNDO_STATE values of an undo log segment */
|
||||||
/** contains an undo log of an active transaction */
|
/** contains an undo log of an active transaction */
|
||||||
constexpr uint16_t TRX_UNDO_ACTIVE = 1;
|
constexpr uint16_t TRX_UNDO_ACTIVE = 1;
|
||||||
/** cached for quick reuse */
|
/** cached for quick reuse */
|
||||||
constexpr uint16_t TRX_UNDO_CACHED = 2;
|
constexpr uint16_t TRX_UNDO_CACHED = 2;
|
||||||
/** old_insert undo segment that can be freed */
|
|
||||||
constexpr uint16_t TRX_UNDO_TO_FREE = 3;
|
|
||||||
/** can be freed in purge when all undo data in it is removed */
|
/** can be freed in purge when all undo data in it is removed */
|
||||||
constexpr uint16_t TRX_UNDO_TO_PURGE = 4;
|
constexpr uint16_t TRX_UNDO_TO_PURGE = 4;
|
||||||
/** contains an undo log of a prepared transaction */
|
/** contains an undo log of a prepared transaction */
|
||||||
@@ -343,7 +336,8 @@ struct trx_undo_t {
|
|||||||
/** Transaction undo log page header offsets */
|
/** Transaction undo log page header offsets */
|
||||||
/* @{ */
|
/* @{ */
|
||||||
#define TRX_UNDO_PAGE_TYPE 0 /*!< unused; 0 (before MariaDB 10.3.1:
|
#define TRX_UNDO_PAGE_TYPE 0 /*!< unused; 0 (before MariaDB 10.3.1:
|
||||||
TRX_UNDO_INSERT or TRX_UNDO_UPDATE) */
|
1=TRX_UNDO_INSERT or
|
||||||
|
2=TRX_UNDO_UPDATE) */
|
||||||
#define TRX_UNDO_PAGE_START 2 /*!< Byte offset where the undo log
|
#define TRX_UNDO_PAGE_START 2 /*!< Byte offset where the undo log
|
||||||
records for the LATEST transaction
|
records for the LATEST transaction
|
||||||
start on this page (remember that
|
start on this page (remember that
|
||||||
|
|||||||
@@ -4476,7 +4476,7 @@ lock_print_info_summary(
|
|||||||
"Purge done for trx's n:o < " TRX_ID_FMT
|
"Purge done for trx's n:o < " TRX_ID_FMT
|
||||||
" undo n:o < " TRX_ID_FMT " state: %s\n"
|
" undo n:o < " TRX_ID_FMT " state: %s\n"
|
||||||
"History list length %u\n",
|
"History list length %u\n",
|
||||||
purge_sys.tail.trx_no(),
|
purge_sys.tail.trx_no,
|
||||||
purge_sys.tail.undo_no,
|
purge_sys.tail.undo_no,
|
||||||
purge_sys.enabled()
|
purge_sys.enabled()
|
||||||
? (purge_sys.running() ? "running"
|
? (purge_sys.running() ? "running"
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
/*****************************************************************************
|
/*****************************************************************************
|
||||||
|
|
||||||
Copyright (c) 2010, 2016, Oracle and/or its affiliates. All Rights Reserved.
|
Copyright (c) 2010, 2016, Oracle and/or its affiliates. All Rights Reserved.
|
||||||
Copyright (c) 2015, 2020, MariaDB Corporation.
|
Copyright (c) 2015, 2021, MariaDB Corporation.
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify it under
|
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
|
the terms of the GNU General Public License as published by the Free Software
|
||||||
@@ -755,7 +755,6 @@ void fts_parallel_tokenization(
|
|||||||
row_merge_block_t** crypt_block;
|
row_merge_block_t** crypt_block;
|
||||||
pfs_os_file_t tmpfd[FTS_NUM_AUX_INDEX];
|
pfs_os_file_t tmpfd[FTS_NUM_AUX_INDEX];
|
||||||
ulint mycount[FTS_NUM_AUX_INDEX];
|
ulint mycount[FTS_NUM_AUX_INDEX];
|
||||||
ib_uint64_t total_rec = 0;
|
|
||||||
ulint num_doc_processed = 0;
|
ulint num_doc_processed = 0;
|
||||||
doc_id_t last_doc_id = 0;
|
doc_id_t last_doc_id = 0;
|
||||||
mem_heap_t* blob_heap = NULL;
|
mem_heap_t* blob_heap = NULL;
|
||||||
@@ -1023,7 +1022,6 @@ exit:
|
|||||||
goto func_exit;
|
goto func_exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
total_rec += merge_file[i]->n_rec;
|
|
||||||
row_merge_file_destroy_low(tmpfd[i]);
|
row_merge_file_destroy_low(tmpfd[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -517,7 +517,9 @@ row_merge_buf_add(
|
|||||||
DBUG_ENTER("row_merge_buf_add");
|
DBUG_ENTER("row_merge_buf_add");
|
||||||
|
|
||||||
if (buf->n_tuples >= buf->max_tuples) {
|
if (buf->n_tuples >= buf->max_tuples) {
|
||||||
DBUG_RETURN(0);
|
error:
|
||||||
|
n_row_added = 0;
|
||||||
|
goto end;
|
||||||
}
|
}
|
||||||
|
|
||||||
DBUG_EXECUTE_IF(
|
DBUG_EXECUTE_IF(
|
||||||
@@ -683,7 +685,10 @@ row_merge_buf_add(
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (field->len != UNIV_SQL_NULL
|
/* innobase_get_computed_value() sets the
|
||||||
|
length of the virtual column field. */
|
||||||
|
if (v_col == NULL
|
||||||
|
&& field->len != UNIV_SQL_NULL
|
||||||
&& col->mtype == DATA_MYSQL
|
&& col->mtype == DATA_MYSQL
|
||||||
&& col->len != field->len) {
|
&& col->len != field->len) {
|
||||||
if (conv_heap != NULL) {
|
if (conv_heap != NULL) {
|
||||||
@@ -839,11 +844,6 @@ end:
|
|||||||
if (vcol_storage.innobase_record)
|
if (vcol_storage.innobase_record)
|
||||||
innobase_free_row_for_vcol(&vcol_storage);
|
innobase_free_row_for_vcol(&vcol_storage);
|
||||||
DBUG_RETURN(n_row_added);
|
DBUG_RETURN(n_row_added);
|
||||||
|
|
||||||
error:
|
|
||||||
if (vcol_storage.innobase_record)
|
|
||||||
innobase_free_row_for_vcol(&vcol_storage);
|
|
||||||
DBUG_RETURN(0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*************************************************************//**
|
/*************************************************************//**
|
||||||
@@ -2669,14 +2669,16 @@ write_buffers:
|
|||||||
&err, &v_heap, eval_table, trx)))) {
|
&err, &v_heap, eval_table, trx)))) {
|
||||||
/* An empty buffer should have enough
|
/* An empty buffer should have enough
|
||||||
room for at least one record. */
|
room for at least one record. */
|
||||||
ut_error;
|
ut_ad(err == DB_COMPUTE_VALUE_FAILED
|
||||||
}
|
|| err == DB_OUT_OF_MEMORY
|
||||||
|
|| err == DB_TOO_BIG_RECORD);
|
||||||
if (err != DB_SUCCESS) {
|
} else if (err == DB_SUCCESS) {
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
file->n_rec += rows_added;
|
file->n_rec += rows_added;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
trx->error_key_num = i;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -284,23 +284,13 @@ static bool row_undo_rec_get(undo_node_t* node)
|
|||||||
}
|
}
|
||||||
|
|
||||||
trx_undo_t* undo = NULL;
|
trx_undo_t* undo = NULL;
|
||||||
trx_undo_t* insert = trx->rsegs.m_redo.old_insert;
|
|
||||||
trx_undo_t* update = trx->rsegs.m_redo.undo;
|
trx_undo_t* update = trx->rsegs.m_redo.undo;
|
||||||
trx_undo_t* temp = trx->rsegs.m_noredo.undo;
|
trx_undo_t* temp = trx->rsegs.m_noredo.undo;
|
||||||
const undo_no_t limit = trx->roll_limit;
|
const undo_no_t limit = trx->roll_limit;
|
||||||
|
|
||||||
ut_ad(!insert || !update || insert->empty() || update->empty()
|
|
||||||
|| insert->top_undo_no != update->top_undo_no);
|
|
||||||
ut_ad(!insert || !temp || insert->empty() || temp->empty()
|
|
||||||
|| insert->top_undo_no != temp->top_undo_no);
|
|
||||||
ut_ad(!update || !temp || update->empty() || temp->empty()
|
ut_ad(!update || !temp || update->empty() || temp->empty()
|
||||||
|| update->top_undo_no != temp->top_undo_no);
|
|| update->top_undo_no != temp->top_undo_no);
|
||||||
|
|
||||||
if (UNIV_LIKELY_NULL(insert)
|
|
||||||
&& !insert->empty() && limit <= insert->top_undo_no) {
|
|
||||||
undo = insert;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (update && !update->empty() && update->top_undo_no >= limit) {
|
if (update && !update->empty() && update->top_undo_no >= limit) {
|
||||||
if (!undo) {
|
if (!undo) {
|
||||||
undo = update;
|
undo = update;
|
||||||
@@ -369,19 +359,16 @@ static bool row_undo_rec_get(undo_node_t* node)
|
|||||||
MDEV-12288 removed the insert_undo log. There is no
|
MDEV-12288 removed the insert_undo log. There is no
|
||||||
instant ADD COLUMN for temporary tables. Therefore,
|
instant ADD COLUMN for temporary tables. Therefore,
|
||||||
this record can only be present in the main undo log. */
|
this record can only be present in the main undo log. */
|
||||||
ut_ad(undo == update);
|
|
||||||
/* fall through */
|
/* fall through */
|
||||||
case TRX_UNDO_RENAME_TABLE:
|
case TRX_UNDO_RENAME_TABLE:
|
||||||
ut_ad(undo == insert || undo == update);
|
ut_ad(undo == update);
|
||||||
/* fall through */
|
/* fall through */
|
||||||
case TRX_UNDO_INSERT_REC:
|
case TRX_UNDO_INSERT_REC:
|
||||||
ut_ad(undo == insert || undo == update || undo == temp);
|
|
||||||
node->roll_ptr |= 1ULL << ROLL_PTR_INSERT_FLAG_POS;
|
node->roll_ptr |= 1ULL << ROLL_PTR_INSERT_FLAG_POS;
|
||||||
node->state = undo == temp
|
node->state = undo == temp
|
||||||
? UNDO_INSERT_TEMPORARY : UNDO_INSERT_PERSISTENT;
|
? UNDO_INSERT_TEMPORARY : UNDO_INSERT_PERSISTENT;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
ut_ad(undo == update || undo == temp);
|
|
||||||
node->state = undo == temp
|
node->state = undo == temp
|
||||||
? UNDO_UPDATE_TEMPORARY : UNDO_UPDATE_PERSISTENT;
|
? UNDO_UPDATE_TEMPORARY : UNDO_UPDATE_PERSISTENT;
|
||||||
break;
|
break;
|
||||||
|
|||||||
@@ -1059,6 +1059,11 @@ dberr_t srv_start(bool create_new_db)
|
|||||||
|| srv_operation == SRV_OPERATION_RESTORE
|
|| srv_operation == SRV_OPERATION_RESTORE
|
||||||
|| srv_operation == SRV_OPERATION_RESTORE_EXPORT);
|
|| srv_operation == SRV_OPERATION_RESTORE_EXPORT);
|
||||||
|
|
||||||
|
if (srv_force_recovery) {
|
||||||
|
ib::info() << "!!! innodb_force_recovery is set to "
|
||||||
|
<< srv_force_recovery << " !!!";
|
||||||
|
}
|
||||||
|
|
||||||
if (srv_force_recovery == SRV_FORCE_NO_LOG_REDO) {
|
if (srv_force_recovery == SRV_FORCE_NO_LOG_REDO) {
|
||||||
srv_read_only_mode = true;
|
srv_read_only_mode = true;
|
||||||
}
|
}
|
||||||
@@ -1414,7 +1419,11 @@ file_checked:
|
|||||||
All the remaining rollback segments will be created later,
|
All the remaining rollback segments will be created later,
|
||||||
after the double write buffer has been created. */
|
after the double write buffer has been created. */
|
||||||
trx_sys_create_sys_pages();
|
trx_sys_create_sys_pages();
|
||||||
trx_lists_init_at_db_start();
|
err = trx_lists_init_at_db_start();
|
||||||
|
|
||||||
|
if (err != DB_SUCCESS) {
|
||||||
|
return(srv_init_abort(err));
|
||||||
|
}
|
||||||
|
|
||||||
err = dict_create();
|
err = dict_create();
|
||||||
|
|
||||||
@@ -1476,7 +1485,10 @@ file_checked:
|
|||||||
if (srv_operation == SRV_OPERATION_RESTORE) {
|
if (srv_operation == SRV_OPERATION_RESTORE) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
trx_lists_init_at_db_start();
|
err = trx_lists_init_at_db_start();
|
||||||
|
if (err != DB_SUCCESS) {
|
||||||
|
return srv_init_abort(err);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case SRV_OPERATION_RESTORE_DELTA:
|
case SRV_OPERATION_RESTORE_DELTA:
|
||||||
case SRV_OPERATION_BACKUP:
|
case SRV_OPERATION_BACKUP:
|
||||||
@@ -1899,11 +1911,6 @@ skip_monitors:
|
|||||||
<< "; transaction id " << trx_sys.get_max_trx_id();
|
<< "; transaction id " << trx_sys.get_max_trx_id();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (srv_force_recovery > 0) {
|
|
||||||
ib::info() << "!!! innodb_force_recovery is set to "
|
|
||||||
<< srv_force_recovery << " !!!";
|
|
||||||
}
|
|
||||||
|
|
||||||
if (srv_force_recovery == 0) {
|
if (srv_force_recovery == 0) {
|
||||||
/* In the change buffer we may have even bigger tablespace
|
/* In the change buffer we may have even bigger tablespace
|
||||||
id's, because we may have dropped those tablespaces, but
|
id's, because we may have dropped those tablespaces, but
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
/*****************************************************************************
|
/*****************************************************************************
|
||||||
|
|
||||||
Copyright (c) 1996, 2017, Oracle and/or its affiliates. All Rights Reserved.
|
Copyright (c) 1996, 2017, Oracle and/or its affiliates. All Rights Reserved.
|
||||||
Copyright (c) 2017, 2020, MariaDB Corporation.
|
Copyright (c) 2017, 2021, MariaDB Corporation.
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify it under
|
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
|
the terms of the GNU General Public License as published by the Free Software
|
||||||
@@ -89,7 +89,7 @@ inline bool TrxUndoRsegsIterator::set_next()
|
|||||||
number shouldn't increase. Undo the increment of
|
number shouldn't increase. Undo the increment of
|
||||||
expected commit done by caller assuming rollback
|
expected commit done by caller assuming rollback
|
||||||
segments from given transaction are done. */
|
segments from given transaction are done. */
|
||||||
purge_sys.tail.commit = (*m_iter)->last_commit;
|
purge_sys.tail.trx_no = (*m_iter)->last_trx_no();
|
||||||
} else if (!purge_sys.purge_queue.empty()) {
|
} else if (!purge_sys.purge_queue.empty()) {
|
||||||
m_rsegs = purge_sys.purge_queue.top();
|
m_rsegs = purge_sys.purge_queue.top();
|
||||||
purge_sys.purge_queue.pop();
|
purge_sys.purge_queue.pop();
|
||||||
@@ -110,17 +110,17 @@ inline bool TrxUndoRsegsIterator::set_next()
|
|||||||
mutex_enter(&purge_sys.rseg->mutex);
|
mutex_enter(&purge_sys.rseg->mutex);
|
||||||
|
|
||||||
ut_a(purge_sys.rseg->last_page_no != FIL_NULL);
|
ut_a(purge_sys.rseg->last_page_no != FIL_NULL);
|
||||||
ut_ad(purge_sys.rseg->last_trx_no() == m_rsegs.trx_no());
|
ut_ad(purge_sys.rseg->last_trx_no() == m_rsegs.trx_no);
|
||||||
|
|
||||||
/* We assume in purge of externally stored fields that space id is
|
/* We assume in purge of externally stored fields that space id is
|
||||||
in the range of UNDO tablespace space ids */
|
in the range of UNDO tablespace space ids */
|
||||||
ut_ad(purge_sys.rseg->space->id == TRX_SYS_SPACE
|
ut_ad(purge_sys.rseg->space->id == TRX_SYS_SPACE
|
||||||
|| srv_is_undo_tablespace(purge_sys.rseg->space->id));
|
|| srv_is_undo_tablespace(purge_sys.rseg->space->id));
|
||||||
|
|
||||||
ut_a(purge_sys.tail.commit <= purge_sys.rseg->last_commit);
|
ut_a(purge_sys.tail.trx_no <= purge_sys.rseg->last_trx_no());
|
||||||
|
|
||||||
purge_sys.tail.commit = purge_sys.rseg->last_commit;
|
purge_sys.tail.trx_no = purge_sys.rseg->last_trx_no();
|
||||||
purge_sys.hdr_offset = purge_sys.rseg->last_offset;
|
purge_sys.hdr_offset = purge_sys.rseg->last_offset();
|
||||||
purge_sys.hdr_page_no = purge_sys.rseg->last_page_no;
|
purge_sys.hdr_page_no = purge_sys.rseg->last_page_no;
|
||||||
|
|
||||||
mutex_exit(&purge_sys.rseg->mutex);
|
mutex_exit(&purge_sys.rseg->mutex);
|
||||||
@@ -211,8 +211,7 @@ trx_purge_add_undo_to_history(const trx_t* trx, trx_undo_t*& undo, mtr_t* mtr)
|
|||||||
{
|
{
|
||||||
DBUG_PRINT("trx", ("commit(" TRX_ID_FMT "," TRX_ID_FMT ")",
|
DBUG_PRINT("trx", ("commit(" TRX_ID_FMT "," TRX_ID_FMT ")",
|
||||||
trx->id, trx_id_t{trx->rw_trx_hash_element->no}));
|
trx->id, trx_id_t{trx->rw_trx_hash_element->no}));
|
||||||
ut_ad(undo == trx->rsegs.m_redo.undo
|
ut_ad(undo == trx->rsegs.m_redo.undo);
|
||||||
|| undo == trx->rsegs.m_redo.old_insert);
|
|
||||||
trx_rseg_t* rseg = trx->rsegs.m_redo.rseg;
|
trx_rseg_t* rseg = trx->rsegs.m_redo.rseg;
|
||||||
ut_ad(undo->rseg == rseg);
|
ut_ad(undo->rseg == rseg);
|
||||||
buf_block_t* rseg_header = trx_rsegf_get(
|
buf_block_t* rseg_header = trx_rsegf_get(
|
||||||
@@ -303,19 +302,13 @@ trx_purge_add_undo_to_history(const trx_t* trx, trx_undo_t*& undo, mtr_t* mtr)
|
|||||||
mtr->write<8,mtr_t::MAYBE_NOP>(*undo_page,
|
mtr->write<8,mtr_t::MAYBE_NOP>(*undo_page,
|
||||||
undo_header + TRX_UNDO_TRX_NO,
|
undo_header + TRX_UNDO_TRX_NO,
|
||||||
trx->rw_trx_hash_element->no);
|
trx->rw_trx_hash_element->no);
|
||||||
/* This is needed for upgrading old undo log pages from
|
mtr->write<2,mtr_t::MAYBE_NOP>(*undo_page, undo_header
|
||||||
before MariaDB 10.3.1. */
|
+ TRX_UNDO_NEEDS_PURGE, 1U);
|
||||||
if (UNIV_UNLIKELY(!mach_read_from_2(undo_header
|
|
||||||
+ TRX_UNDO_NEEDS_PURGE))) {
|
|
||||||
mtr->write<2>(*undo_page, undo_header + TRX_UNDO_NEEDS_PURGE,
|
|
||||||
1U);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (rseg->last_page_no == FIL_NULL) {
|
if (rseg->last_page_no == FIL_NULL) {
|
||||||
rseg->last_page_no = undo->hdr_page_no;
|
rseg->last_page_no = undo->hdr_page_no;
|
||||||
rseg->last_offset = undo->hdr_offset;
|
rseg->set_last_commit(undo->hdr_offset,
|
||||||
rseg->set_last_trx_no(trx->rw_trx_hash_element->no,
|
trx->rw_trx_hash_element->no);
|
||||||
undo == trx->rsegs.m_redo.undo);
|
|
||||||
rseg->needs_purge = true;
|
rseg->needs_purge = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -462,8 +455,8 @@ func_exit:
|
|||||||
undo_trx_no = mach_read_from_8(block->frame + hdr_addr.boffset
|
undo_trx_no = mach_read_from_8(block->frame + hdr_addr.boffset
|
||||||
+ TRX_UNDO_TRX_NO);
|
+ TRX_UNDO_TRX_NO);
|
||||||
|
|
||||||
if (undo_trx_no >= limit.trx_no()) {
|
if (undo_trx_no >= limit.trx_no) {
|
||||||
if (undo_trx_no == limit.trx_no()) {
|
if (undo_trx_no == limit.trx_no) {
|
||||||
trx_undo_truncate_start(
|
trx_undo_truncate_start(
|
||||||
&rseg, hdr_addr.page,
|
&rseg, hdr_addr.page,
|
||||||
hdr_addr.boffset, limit.undo_no);
|
hdr_addr.boffset, limit.undo_no);
|
||||||
@@ -554,12 +547,12 @@ function is called, the caller must not have any latches on undo log pages!
|
|||||||
static void trx_purge_truncate_history()
|
static void trx_purge_truncate_history()
|
||||||
{
|
{
|
||||||
ut_ad(purge_sys.head <= purge_sys.tail);
|
ut_ad(purge_sys.head <= purge_sys.tail);
|
||||||
purge_sys_t::iterator& head = purge_sys.head.commit
|
purge_sys_t::iterator& head = purge_sys.head.trx_no
|
||||||
? purge_sys.head : purge_sys.tail;
|
? purge_sys.head : purge_sys.tail;
|
||||||
|
|
||||||
if (head.trx_no() >= purge_sys.low_limit_no()) {
|
if (head.trx_no >= purge_sys.low_limit_no()) {
|
||||||
/* This is sometimes necessary. TODO: find out why. */
|
/* This is sometimes necessary. TODO: find out why. */
|
||||||
head.reset_trx_no(purge_sys.low_limit_no());
|
head.trx_no = purge_sys.low_limit_no();
|
||||||
head.undo_no = 0;
|
head.undo_no = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -649,7 +642,7 @@ not_free:
|
|||||||
undo;
|
undo;
|
||||||
undo = UT_LIST_GET_NEXT(undo_list,
|
undo = UT_LIST_GET_NEXT(undo_list,
|
||||||
undo)) {
|
undo)) {
|
||||||
if (head.trx_no() < undo->trx_id) {
|
if (head.trx_no < undo->trx_id) {
|
||||||
goto not_free;
|
goto not_free;
|
||||||
} else {
|
} else {
|
||||||
cached += undo->size;
|
cached += undo->size;
|
||||||
@@ -728,7 +721,6 @@ not_free:
|
|||||||
free the existing structure. There can't be
|
free the existing structure. There can't be
|
||||||
any active transactions. */
|
any active transactions. */
|
||||||
ut_a(UT_LIST_GET_LEN(rseg->undo_list) == 0);
|
ut_a(UT_LIST_GET_LEN(rseg->undo_list) == 0);
|
||||||
ut_a(UT_LIST_GET_LEN(rseg->old_insert_list) == 0);
|
|
||||||
|
|
||||||
trx_undo_t* next_undo;
|
trx_undo_t* next_undo;
|
||||||
|
|
||||||
@@ -746,8 +738,6 @@ not_free:
|
|||||||
&trx_undo_t::undo_list);
|
&trx_undo_t::undo_list);
|
||||||
UT_LIST_INIT(rseg->undo_cached,
|
UT_LIST_INIT(rseg->undo_cached,
|
||||||
&trx_undo_t::undo_list);
|
&trx_undo_t::undo_list);
|
||||||
UT_LIST_INIT(rseg->old_insert_list,
|
|
||||||
&trx_undo_t::undo_list);
|
|
||||||
|
|
||||||
/* These were written by trx_rseg_header_create(). */
|
/* These were written by trx_rseg_header_create(). */
|
||||||
ut_ad(!mach_read_from_4(TRX_RSEG + TRX_RSEG_FORMAT
|
ut_ad(!mach_read_from_4(TRX_RSEG + TRX_RSEG_FORMAT
|
||||||
@@ -760,8 +750,7 @@ not_free:
|
|||||||
rseg->curr_size = 1;
|
rseg->curr_size = 1;
|
||||||
rseg->trx_ref_count = 0;
|
rseg->trx_ref_count = 0;
|
||||||
rseg->last_page_no = FIL_NULL;
|
rseg->last_page_no = FIL_NULL;
|
||||||
rseg->last_offset = 0;
|
rseg->last_commit_and_offset = 0;
|
||||||
rseg->last_commit = 0;
|
|
||||||
rseg->needs_purge = false;
|
rseg->needs_purge = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -836,7 +825,7 @@ static void trx_purge_rseg_get_next_history_log(
|
|||||||
|
|
||||||
ut_a(purge_sys.rseg->last_page_no != FIL_NULL);
|
ut_a(purge_sys.rseg->last_page_no != FIL_NULL);
|
||||||
|
|
||||||
purge_sys.tail.commit = purge_sys.rseg->last_commit + 1;
|
purge_sys.tail.trx_no = purge_sys.rseg->last_trx_no() + 1;
|
||||||
purge_sys.tail.undo_no = 0;
|
purge_sys.tail.undo_no = 0;
|
||||||
purge_sys.next_stored = false;
|
purge_sys.next_stored = false;
|
||||||
|
|
||||||
@@ -847,7 +836,7 @@ static void trx_purge_rseg_get_next_history_log(
|
|||||||
purge_sys.rseg->last_page_no), &mtr);
|
purge_sys.rseg->last_page_no), &mtr);
|
||||||
|
|
||||||
const trx_ulogf_t* log_hdr = undo_page->frame
|
const trx_ulogf_t* log_hdr = undo_page->frame
|
||||||
+ purge_sys.rseg->last_offset;
|
+ purge_sys.rseg->last_offset();
|
||||||
|
|
||||||
/* Increase the purge page count by one for every handled log */
|
/* Increase the purge page count by one for every handled log */
|
||||||
|
|
||||||
@@ -881,17 +870,15 @@ static void trx_purge_rseg_get_next_history_log(
|
|||||||
+ prev_log_addr.boffset;
|
+ prev_log_addr.boffset;
|
||||||
|
|
||||||
trx_no = mach_read_from_8(log_hdr + TRX_UNDO_TRX_NO);
|
trx_no = mach_read_from_8(log_hdr + TRX_UNDO_TRX_NO);
|
||||||
unsigned purge = mach_read_from_2(log_hdr + TRX_UNDO_NEEDS_PURGE);
|
ut_ad(mach_read_from_2(log_hdr + TRX_UNDO_NEEDS_PURGE) <= 1);
|
||||||
ut_ad(purge <= 1);
|
|
||||||
|
|
||||||
mtr_commit(&mtr);
|
mtr_commit(&mtr);
|
||||||
|
|
||||||
mutex_enter(&purge_sys.rseg->mutex);
|
mutex_enter(&purge_sys.rseg->mutex);
|
||||||
|
|
||||||
purge_sys.rseg->last_page_no = prev_log_addr.page;
|
purge_sys.rseg->last_page_no = prev_log_addr.page;
|
||||||
purge_sys.rseg->last_offset = prev_log_addr.boffset;
|
purge_sys.rseg->set_last_commit(prev_log_addr.boffset, trx_no);
|
||||||
purge_sys.rseg->set_last_trx_no(trx_no, purge != 0);
|
purge_sys.rseg->needs_purge = log_hdr[TRX_UNDO_NEEDS_PURGE + 1] != 0;
|
||||||
purge_sys.rseg->needs_purge = purge != 0;
|
|
||||||
|
|
||||||
/* Purge can also produce events, however these are already ordered
|
/* Purge can also produce events, however these are already ordered
|
||||||
in the rollback segment and any user generated event will be greater
|
in the rollback segment and any user generated event will be greater
|
||||||
@@ -908,15 +895,13 @@ static void trx_purge_rseg_get_next_history_log(
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** Position the purge sys "iterator" on the undo record to use for purging. */
|
/** Position the purge sys "iterator" on the undo record to use for purging. */
|
||||||
static
|
static void trx_purge_read_undo_rec()
|
||||||
void
|
|
||||||
trx_purge_read_undo_rec()
|
|
||||||
{
|
{
|
||||||
uint16_t offset;
|
uint16_t offset;
|
||||||
uint32_t page_no;
|
uint32_t page_no;
|
||||||
ib_uint64_t undo_no;
|
ib_uint64_t undo_no;
|
||||||
|
|
||||||
purge_sys.hdr_offset = purge_sys.rseg->last_offset;
|
purge_sys.hdr_offset = purge_sys.rseg->last_offset();
|
||||||
page_no = purge_sys.hdr_page_no = purge_sys.rseg->last_page_no;
|
page_no = purge_sys.hdr_page_no = purge_sys.rseg->last_page_no;
|
||||||
|
|
||||||
if (purge_sys.rseg->needs_purge) {
|
if (purge_sys.rseg->needs_purge) {
|
||||||
@@ -983,7 +968,7 @@ trx_purge_get_next_rec(
|
|||||||
mtr_t mtr;
|
mtr_t mtr;
|
||||||
|
|
||||||
ut_ad(purge_sys.next_stored);
|
ut_ad(purge_sys.next_stored);
|
||||||
ut_ad(purge_sys.tail.trx_no() < purge_sys.low_limit_no());
|
ut_ad(purge_sys.tail.trx_no < purge_sys.low_limit_no());
|
||||||
|
|
||||||
const ulint space = purge_sys.rseg->space->id;
|
const ulint space = purge_sys.rseg->space->id;
|
||||||
const uint32_t page_no = purge_sys.page_no;
|
const uint32_t page_no = purge_sys.page_no;
|
||||||
@@ -1073,7 +1058,7 @@ trx_purge_fetch_next_rec(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (purge_sys.tail.trx_no() >= purge_sys.low_limit_no()) {
|
if (purge_sys.tail.trx_no >= purge_sys.low_limit_no()) {
|
||||||
|
|
||||||
return(NULL);
|
return(NULL);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -71,12 +71,6 @@ inline bool trx_t::rollback_finish()
|
|||||||
ut_a(!srv_undo_sources);
|
ut_a(!srv_undo_sources);
|
||||||
ut_ad(srv_fast_shutdown);
|
ut_ad(srv_fast_shutdown);
|
||||||
ut_d(in_rollback= false);
|
ut_d(in_rollback= false);
|
||||||
if (trx_undo_t *&undo= rsegs.m_redo.old_insert)
|
|
||||||
{
|
|
||||||
UT_LIST_REMOVE(rsegs.m_redo.rseg->old_insert_list, undo);
|
|
||||||
ut_free(undo);
|
|
||||||
undo= nullptr;
|
|
||||||
}
|
|
||||||
if (trx_undo_t *&undo= rsegs.m_redo.undo)
|
if (trx_undo_t *&undo= rsegs.m_redo.undo)
|
||||||
{
|
{
|
||||||
UT_LIST_REMOVE(rsegs.m_redo.rseg->undo_list, undo);
|
UT_LIST_REMOVE(rsegs.m_redo.rseg->undo_list, undo);
|
||||||
@@ -119,7 +113,7 @@ inline void trx_t::rollback_low(trx_savept_t *savept)
|
|||||||
|
|
||||||
error_state = DB_SUCCESS;
|
error_state = DB_SUCCESS;
|
||||||
|
|
||||||
if (has_logged_or_recovered())
|
if (has_logged())
|
||||||
{
|
{
|
||||||
ut_ad(rsegs.m_redo.rseg || rsegs.m_noredo.rseg);
|
ut_ad(rsegs.m_redo.rseg || rsegs.m_noredo.rseg);
|
||||||
que_thr_t *thr= pars_complete_graph_for_exec(roll_node, this, heap,
|
que_thr_t *thr= pars_complete_graph_for_exec(roll_node, this, heap,
|
||||||
@@ -231,7 +225,7 @@ dberr_t trx_rollback_for_mysql(trx_t* trx)
|
|||||||
case TRX_STATE_PREPARED:
|
case TRX_STATE_PREPARED:
|
||||||
case TRX_STATE_PREPARED_RECOVERED:
|
case TRX_STATE_PREPARED_RECOVERED:
|
||||||
ut_ad(!trx->is_autocommit_non_locking());
|
ut_ad(!trx->is_autocommit_non_locking());
|
||||||
if (trx->rsegs.m_redo.undo || trx->rsegs.m_redo.old_insert) {
|
if (trx->rsegs.m_redo.undo) {
|
||||||
/* The XA ROLLBACK of a XA PREPARE transaction
|
/* The XA ROLLBACK of a XA PREPARE transaction
|
||||||
will consist of multiple mini-transactions.
|
will consist of multiple mini-transactions.
|
||||||
|
|
||||||
@@ -247,11 +241,7 @@ dberr_t trx_rollback_for_mysql(trx_t* trx)
|
|||||||
killed, and finally, the transaction would be
|
killed, and finally, the transaction would be
|
||||||
recovered in XA PREPARE state, with some of
|
recovered in XA PREPARE state, with some of
|
||||||
the actions already having been rolled back. */
|
the actions already having been rolled back. */
|
||||||
ut_ad(!trx->rsegs.m_redo.undo
|
ut_ad(trx->rsegs.m_redo.undo->rseg
|
||||||
|| trx->rsegs.m_redo.undo->rseg
|
|
||||||
== trx->rsegs.m_redo.rseg);
|
|
||||||
ut_ad(!trx->rsegs.m_redo.old_insert
|
|
||||||
|| trx->rsegs.m_redo.old_insert->rseg
|
|
||||||
== trx->rsegs.m_redo.rseg);
|
== trx->rsegs.m_redo.rseg);
|
||||||
mtr_t mtr;
|
mtr_t mtr;
|
||||||
mtr.start();
|
mtr.start();
|
||||||
@@ -260,10 +250,6 @@ dberr_t trx_rollback_for_mysql(trx_t* trx)
|
|||||||
trx_undo_set_state_at_prepare(trx, undo, true,
|
trx_undo_set_state_at_prepare(trx, undo, true,
|
||||||
&mtr);
|
&mtr);
|
||||||
}
|
}
|
||||||
if (trx_undo_t* undo = trx->rsegs.m_redo.old_insert) {
|
|
||||||
trx_undo_set_state_at_prepare(trx, undo, true,
|
|
||||||
&mtr);
|
|
||||||
}
|
|
||||||
mutex_exit(&trx->rsegs.m_redo.rseg->mutex);
|
mutex_exit(&trx->rsegs.m_redo.rseg->mutex);
|
||||||
/* Write the redo log for the XA ROLLBACK
|
/* Write the redo log for the XA ROLLBACK
|
||||||
state change to the global buffer. It is
|
state change to the global buffer. It is
|
||||||
|
|||||||
@@ -367,7 +367,6 @@ trx_rseg_mem_free(trx_rseg_t* rseg)
|
|||||||
|
|
||||||
/* There can't be any active transactions. */
|
/* There can't be any active transactions. */
|
||||||
ut_a(UT_LIST_GET_LEN(rseg->undo_list) == 0);
|
ut_a(UT_LIST_GET_LEN(rseg->undo_list) == 0);
|
||||||
ut_a(UT_LIST_GET_LEN(rseg->old_insert_list) == 0);
|
|
||||||
|
|
||||||
for (undo = UT_LIST_GET_FIRST(rseg->undo_cached);
|
for (undo = UT_LIST_GET_FIRST(rseg->undo_cached);
|
||||||
undo != NULL;
|
undo != NULL;
|
||||||
@@ -407,7 +406,6 @@ trx_rseg_mem_create(ulint id, fil_space_t* space, uint32_t page_no)
|
|||||||
&rseg->mutex);
|
&rseg->mutex);
|
||||||
|
|
||||||
UT_LIST_INIT(rseg->undo_list, &trx_undo_t::undo_list);
|
UT_LIST_INIT(rseg->undo_list, &trx_undo_t::undo_list);
|
||||||
UT_LIST_INIT(rseg->old_insert_list, &trx_undo_t::undo_list);
|
|
||||||
UT_LIST_INIT(rseg->undo_cached, &trx_undo_t::undo_list);
|
UT_LIST_INIT(rseg->undo_cached, &trx_undo_t::undo_list);
|
||||||
|
|
||||||
return(rseg);
|
return(rseg);
|
||||||
@@ -417,34 +415,36 @@ trx_rseg_mem_create(ulint id, fil_space_t* space, uint32_t page_no)
|
|||||||
@param[in,out] rseg rollback segment
|
@param[in,out] rseg rollback segment
|
||||||
@param[in,out] max_trx_id maximum observed transaction identifier
|
@param[in,out] max_trx_id maximum observed transaction identifier
|
||||||
@param[in] rseg_header rollback segment header
|
@param[in] rseg_header rollback segment header
|
||||||
@return the combined size of undo log segments in pages */
|
@return error code */
|
||||||
static uint32_t trx_undo_lists_init(trx_rseg_t *rseg, trx_id_t &max_trx_id,
|
static dberr_t trx_undo_lists_init(trx_rseg_t *rseg, trx_id_t &max_trx_id,
|
||||||
const buf_block_t *rseg_header)
|
const buf_block_t *rseg_header)
|
||||||
{
|
{
|
||||||
ut_ad(srv_force_recovery < SRV_FORCE_NO_UNDO_LOG_SCAN);
|
ut_ad(srv_force_recovery < SRV_FORCE_NO_UNDO_LOG_SCAN);
|
||||||
|
|
||||||
uint32_t size= 0;
|
|
||||||
|
|
||||||
for (ulint i= 0; i < TRX_RSEG_N_SLOTS; i++)
|
for (ulint i= 0; i < TRX_RSEG_N_SLOTS; i++)
|
||||||
{
|
{
|
||||||
uint32_t page_no= trx_rsegf_get_nth_undo(rseg_header, i);
|
uint32_t page_no= trx_rsegf_get_nth_undo(rseg_header, i);
|
||||||
if (page_no != FIL_NULL)
|
if (page_no != FIL_NULL)
|
||||||
{
|
{
|
||||||
size+= trx_undo_mem_create_at_db_start(rseg, i, page_no, max_trx_id);
|
const trx_undo_t *undo= trx_undo_mem_create_at_db_start(rseg, i, page_no,
|
||||||
|
max_trx_id);
|
||||||
|
if (!undo)
|
||||||
|
return DB_CORRUPTION;
|
||||||
|
rseg->curr_size+= undo->size;
|
||||||
MONITOR_INC(MONITOR_NUM_UNDO_SLOT_USED);
|
MONITOR_INC(MONITOR_NUM_UNDO_SLOT_USED);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return size;
|
return DB_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Restore the state of a persistent rollback segment.
|
/** Restore the state of a persistent rollback segment.
|
||||||
@param[in,out] rseg persistent rollback segment
|
@param[in,out] rseg persistent rollback segment
|
||||||
@param[in,out] max_trx_id maximum observed transaction identifier
|
@param[in,out] max_trx_id maximum observed transaction identifier
|
||||||
@param[in,out] mtr mini-transaction */
|
@param[in,out] mtr mini-transaction
|
||||||
static
|
@return error code */
|
||||||
void
|
static dberr_t trx_rseg_mem_restore(trx_rseg_t *rseg, trx_id_t &max_trx_id,
|
||||||
trx_rseg_mem_restore(trx_rseg_t* rseg, trx_id_t& max_trx_id, mtr_t* mtr)
|
mtr_t *mtr)
|
||||||
{
|
{
|
||||||
buf_block_t* rseg_hdr = trx_rsegf_get_new(
|
buf_block_t* rseg_hdr = trx_rsegf_get_new(
|
||||||
rseg->space->id, rseg->page_no, mtr);
|
rseg->space->id, rseg->page_no, mtr);
|
||||||
@@ -489,14 +489,17 @@ trx_rseg_mem_restore(trx_rseg_t* rseg, trx_id_t& max_trx_id, mtr_t* mtr)
|
|||||||
/* mariabackup --prepare only deals with
|
/* mariabackup --prepare only deals with
|
||||||
the redo log and the data files, not with
|
the redo log and the data files, not with
|
||||||
transactions or the data dictionary. */
|
transactions or the data dictionary. */
|
||||||
return;
|
return DB_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Initialize the undo log lists according to the rseg header */
|
/* Initialize the undo log lists according to the rseg header */
|
||||||
|
|
||||||
rseg->curr_size = mach_read_from_4(TRX_RSEG + TRX_RSEG_HISTORY_SIZE
|
rseg->curr_size = mach_read_from_4(TRX_RSEG + TRX_RSEG_HISTORY_SIZE
|
||||||
+ rseg_hdr->frame)
|
+ rseg_hdr->frame)
|
||||||
+ 1 + trx_undo_lists_init(rseg, max_trx_id, rseg_hdr);
|
+ 1;
|
||||||
|
if (dberr_t err = trx_undo_lists_init(rseg, max_trx_id, rseg_hdr)) {
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
if (auto len = flst_get_len(TRX_RSEG + TRX_RSEG_HISTORY
|
if (auto len = flst_get_len(TRX_RSEG + TRX_RSEG_HISTORY
|
||||||
+ rseg_hdr->frame)) {
|
+ rseg_hdr->frame)) {
|
||||||
@@ -509,7 +512,6 @@ trx_rseg_mem_restore(trx_rseg_t* rseg, trx_id_t& max_trx_id, mtr_t* mtr)
|
|||||||
node_addr.boffset - TRX_UNDO_HISTORY_NODE);
|
node_addr.boffset - TRX_UNDO_HISTORY_NODE);
|
||||||
|
|
||||||
rseg->last_page_no = node_addr.page;
|
rseg->last_page_no = node_addr.page;
|
||||||
rseg->last_offset = node_addr.boffset;
|
|
||||||
|
|
||||||
const buf_block_t* block = trx_undo_page_get(
|
const buf_block_t* block = trx_undo_page_get(
|
||||||
page_id_t(rseg->space->id, node_addr.page), mtr);
|
page_id_t(rseg->space->id, node_addr.page), mtr);
|
||||||
@@ -524,11 +526,12 @@ trx_rseg_mem_restore(trx_rseg_t* rseg, trx_id_t& max_trx_id, mtr_t* mtr)
|
|||||||
if (id > max_trx_id) {
|
if (id > max_trx_id) {
|
||||||
max_trx_id = id;
|
max_trx_id = id;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
rseg->set_last_commit(node_addr.boffset, id);
|
||||||
unsigned purge = mach_read_from_2(block->frame
|
unsigned purge = mach_read_from_2(block->frame
|
||||||
+ node_addr.boffset
|
+ node_addr.boffset
|
||||||
+ TRX_UNDO_NEEDS_PURGE);
|
+ TRX_UNDO_NEEDS_PURGE);
|
||||||
ut_ad(purge <= 1);
|
ut_ad(purge <= 1);
|
||||||
rseg->set_last_trx_no(id, purge != 0);
|
|
||||||
rseg->needs_purge = purge != 0;
|
rseg->needs_purge = purge != 0;
|
||||||
|
|
||||||
if (rseg->last_page_no != FIL_NULL) {
|
if (rseg->last_page_no != FIL_NULL) {
|
||||||
@@ -538,6 +541,8 @@ trx_rseg_mem_restore(trx_rseg_t* rseg, trx_id_t& max_trx_id, mtr_t* mtr)
|
|||||||
purge_sys.purge_queue.push(*rseg);
|
purge_sys.purge_queue.push(*rseg);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return DB_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Read binlog metadata from the TRX_SYS page, in case we are upgrading
|
/** Read binlog metadata from the TRX_SYS page, in case we are upgrading
|
||||||
@@ -561,9 +566,8 @@ static void trx_rseg_init_binlog_info(const page_t* page)
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Initialize the rollback segments in memory at database startup. */
|
/** Initialize or recover the rollback segments at startup. */
|
||||||
void
|
dberr_t trx_rseg_array_init()
|
||||||
trx_rseg_array_init()
|
|
||||||
{
|
{
|
||||||
trx_id_t max_trx_id = 0;
|
trx_id_t max_trx_id = 0;
|
||||||
|
|
||||||
@@ -575,9 +579,9 @@ trx_rseg_array_init()
|
|||||||
wsrep_sys_xid.null();
|
wsrep_sys_xid.null();
|
||||||
bool wsrep_xid_in_rseg_found = false;
|
bool wsrep_xid_in_rseg_found = false;
|
||||||
#endif
|
#endif
|
||||||
|
mtr_t mtr;
|
||||||
|
|
||||||
for (ulint rseg_id = 0; rseg_id < TRX_SYS_N_RSEGS; rseg_id++) {
|
for (ulint rseg_id = 0; rseg_id < TRX_SYS_N_RSEGS; rseg_id++) {
|
||||||
mtr_t mtr;
|
|
||||||
mtr.start();
|
mtr.start();
|
||||||
if (const buf_block_t* sys = trx_sysf_get(&mtr, false)) {
|
if (const buf_block_t* sys = trx_sysf_get(&mtr, false)) {
|
||||||
if (rseg_id == 0) {
|
if (rseg_id == 0) {
|
||||||
@@ -605,7 +609,11 @@ trx_rseg_array_init()
|
|||||||
ut_ad(rseg->id == rseg_id);
|
ut_ad(rseg->id == rseg_id);
|
||||||
ut_ad(!trx_sys.rseg_array[rseg_id]);
|
ut_ad(!trx_sys.rseg_array[rseg_id]);
|
||||||
trx_sys.rseg_array[rseg_id] = rseg;
|
trx_sys.rseg_array[rseg_id] = rseg;
|
||||||
trx_rseg_mem_restore(rseg, max_trx_id, &mtr);
|
if (dberr_t err = trx_rseg_mem_restore(
|
||||||
|
rseg, max_trx_id, &mtr)) {
|
||||||
|
mtr.commit();
|
||||||
|
return err;
|
||||||
|
}
|
||||||
#ifdef WITH_WSREP
|
#ifdef WITH_WSREP
|
||||||
if (!wsrep_sys_xid.is_null() &&
|
if (!wsrep_sys_xid.is_null() &&
|
||||||
!wsrep_sys_xid.eq(&trx_sys.recovered_wsrep_xid)) {
|
!wsrep_sys_xid.eq(&trx_sys.recovered_wsrep_xid)) {
|
||||||
@@ -632,7 +640,6 @@ trx_rseg_array_init()
|
|||||||
If no rollback segment has a WSREP XID set,
|
If no rollback segment has a WSREP XID set,
|
||||||
we must copy the XID found in TRX_SYS page
|
we must copy the XID found in TRX_SYS page
|
||||||
to rollback segments. */
|
to rollback segments. */
|
||||||
mtr_t mtr;
|
|
||||||
mtr.start();
|
mtr.start();
|
||||||
|
|
||||||
if (!wsrep_xid_in_rseg_found) {
|
if (!wsrep_xid_in_rseg_found) {
|
||||||
@@ -648,6 +655,7 @@ trx_rseg_array_init()
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
trx_sys.init_max_trx_id(max_trx_id + 1);
|
trx_sys.init_max_trx_id(max_trx_id + 1);
|
||||||
|
return DB_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Create a persistent rollback segment.
|
/** Create a persistent rollback segment.
|
||||||
|
|||||||
@@ -658,8 +658,7 @@ trx_resurrect_table_locks(
|
|||||||
|
|
||||||
static void trx_resurrect(trx_undo_t *undo, trx_rseg_t *rseg,
|
static void trx_resurrect(trx_undo_t *undo, trx_rseg_t *rseg,
|
||||||
time_t start_time, ulonglong start_time_micro,
|
time_t start_time, ulonglong start_time_micro,
|
||||||
uint64_t *rows_to_undo,
|
uint64_t *rows_to_undo)
|
||||||
bool is_old_insert)
|
|
||||||
{
|
{
|
||||||
trx_state_t state;
|
trx_state_t state;
|
||||||
/*
|
/*
|
||||||
@@ -682,8 +681,6 @@ static void trx_resurrect(trx_undo_t *undo, trx_rseg_t *rseg,
|
|||||||
state= TRX_STATE_PREPARED;
|
state= TRX_STATE_PREPARED;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
if (is_old_insert && srv_force_recovery < SRV_FORCE_NO_TRX_UNDO)
|
|
||||||
trx_undo_commit_cleanup(undo, false);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -692,11 +689,7 @@ static void trx_resurrect(trx_undo_t *undo, trx_rseg_t *rseg,
|
|||||||
ut_d(trx->start_file= __FILE__);
|
ut_d(trx->start_file= __FILE__);
|
||||||
ut_d(trx->start_line= __LINE__);
|
ut_d(trx->start_line= __LINE__);
|
||||||
|
|
||||||
if (is_old_insert)
|
|
||||||
trx->rsegs.m_redo.old_insert= undo;
|
|
||||||
else
|
|
||||||
trx->rsegs.m_redo.undo= undo;
|
trx->rsegs.m_redo.undo= undo;
|
||||||
|
|
||||||
trx->undo_no= undo->top_undo_no + 1;
|
trx->undo_no= undo->top_undo_no + 1;
|
||||||
trx->rsegs.m_redo.rseg= rseg;
|
trx->rsegs.m_redo.rseg= rseg;
|
||||||
/*
|
/*
|
||||||
@@ -727,8 +720,7 @@ static void trx_resurrect(trx_undo_t *undo, trx_rseg_t *rseg,
|
|||||||
|
|
||||||
|
|
||||||
/** Initialize (resurrect) transactions at startup. */
|
/** Initialize (resurrect) transactions at startup. */
|
||||||
void
|
dberr_t trx_lists_init_at_db_start()
|
||||||
trx_lists_init_at_db_start()
|
|
||||||
{
|
{
|
||||||
ut_a(srv_is_being_started);
|
ut_a(srv_is_being_started);
|
||||||
ut_ad(!srv_was_started);
|
ut_ad(!srv_was_started);
|
||||||
@@ -737,16 +729,18 @@ trx_lists_init_at_db_start()
|
|||||||
/* mariabackup --prepare only deals with
|
/* mariabackup --prepare only deals with
|
||||||
the redo log and the data files, not with
|
the redo log and the data files, not with
|
||||||
transactions or the data dictionary. */
|
transactions or the data dictionary. */
|
||||||
trx_rseg_array_init();
|
return trx_rseg_array_init();
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (srv_force_recovery >= SRV_FORCE_NO_UNDO_LOG_SCAN) {
|
if (srv_force_recovery >= SRV_FORCE_NO_UNDO_LOG_SCAN) {
|
||||||
return;
|
return DB_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
purge_sys.create();
|
purge_sys.create();
|
||||||
trx_rseg_array_init();
|
if (dberr_t err = trx_rseg_array_init()) {
|
||||||
|
ib::info() << "Retry with innodb_force_recovery=5";
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
/* Look from the rollback segments if there exist undo logs for
|
/* Look from the rollback segments if there exist undo logs for
|
||||||
transactions. */
|
transactions. */
|
||||||
@@ -764,17 +758,6 @@ trx_lists_init_at_db_start()
|
|||||||
if (rseg == NULL) {
|
if (rseg == NULL) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Resurrect transactions that were doing inserts
|
|
||||||
using the old separate insert_undo log. */
|
|
||||||
undo = UT_LIST_GET_FIRST(rseg->old_insert_list);
|
|
||||||
while (undo) {
|
|
||||||
trx_undo_t* next = UT_LIST_GET_NEXT(undo_list, undo);
|
|
||||||
trx_resurrect(undo, rseg, start_time, start_time_micro,
|
|
||||||
&rows_to_undo, true);
|
|
||||||
undo = next;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Ressurrect other transactions. */
|
/* Ressurrect other transactions. */
|
||||||
for (undo = UT_LIST_GET_FIRST(rseg->undo_list);
|
for (undo = UT_LIST_GET_FIRST(rseg->undo_list);
|
||||||
undo != NULL;
|
undo != NULL;
|
||||||
@@ -782,8 +765,7 @@ trx_lists_init_at_db_start()
|
|||||||
trx_t *trx = trx_sys.find(0, undo->trx_id, false);
|
trx_t *trx = trx_sys.find(0, undo->trx_id, false);
|
||||||
if (!trx) {
|
if (!trx) {
|
||||||
trx_resurrect(undo, rseg, start_time,
|
trx_resurrect(undo, rseg, start_time,
|
||||||
start_time_micro,
|
start_time_micro, &rows_to_undo);
|
||||||
&rows_to_undo, false);
|
|
||||||
} else {
|
} else {
|
||||||
ut_ad(trx_state_eq(trx, TRX_STATE_ACTIVE) ||
|
ut_ad(trx_state_eq(trx, TRX_STATE_ACTIVE) ||
|
||||||
trx_state_eq(trx, TRX_STATE_PREPARED));
|
trx_state_eq(trx, TRX_STATE_PREPARED));
|
||||||
@@ -808,16 +790,16 @@ trx_lists_init_at_db_start()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (trx_sys.rw_trx_hash.size()) {
|
if (const auto size = trx_sys.rw_trx_hash.size()) {
|
||||||
|
ib::info() << size
|
||||||
ib::info() << trx_sys.rw_trx_hash.size()
|
|
||||||
<< " transaction(s) which must be rolled back or"
|
<< " transaction(s) which must be rolled back or"
|
||||||
" cleaned up in total " << rows_to_undo
|
" cleaned up in total " << rows_to_undo
|
||||||
<< " row operations to undo";
|
<< " row operations to undo";
|
||||||
|
|
||||||
ib::info() << "Trx id counter is " << trx_sys.get_max_trx_id();
|
ib::info() << "Trx id counter is " << trx_sys.get_max_trx_id();
|
||||||
}
|
}
|
||||||
|
|
||||||
purge_sys.clone_oldest_view();
|
purge_sys.clone_oldest_view();
|
||||||
|
return DB_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Assign a persistent rollback segment in a round-robin fashion,
|
/** Assign a persistent rollback segment in a round-robin fashion,
|
||||||
@@ -1090,30 +1072,22 @@ trx_write_serialisation_history(
|
|||||||
trx_rseg_t* rseg = trx->rsegs.m_redo.rseg;
|
trx_rseg_t* rseg = trx->rsegs.m_redo.rseg;
|
||||||
if (!rseg) {
|
if (!rseg) {
|
||||||
ut_ad(!trx->rsegs.m_redo.undo);
|
ut_ad(!trx->rsegs.m_redo.undo);
|
||||||
ut_ad(!trx->rsegs.m_redo.old_insert);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
trx_undo_t*& undo = trx->rsegs.m_redo.undo;
|
trx_undo_t*& undo = trx->rsegs.m_redo.undo;
|
||||||
trx_undo_t*& old_insert = trx->rsegs.m_redo.old_insert;
|
|
||||||
|
|
||||||
if (!undo && !old_insert) {
|
if (!undo) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
ut_ad(!trx->read_only);
|
ut_ad(!trx->read_only);
|
||||||
ut_ad(!undo || undo->rseg == rseg);
|
ut_ad(!undo || undo->rseg == rseg);
|
||||||
ut_ad(!old_insert || old_insert->rseg == rseg);
|
|
||||||
mutex_enter(&rseg->mutex);
|
mutex_enter(&rseg->mutex);
|
||||||
|
|
||||||
/* Assign the transaction serialisation number and add any
|
/* Assign the transaction serialisation number and add any
|
||||||
undo log to the purge queue. */
|
undo log to the purge queue. */
|
||||||
trx_serialise(trx);
|
trx_serialise(trx);
|
||||||
|
|
||||||
if (UNIV_LIKELY_NULL(old_insert)) {
|
|
||||||
UT_LIST_REMOVE(rseg->old_insert_list, old_insert);
|
|
||||||
trx_purge_add_undo_to_history(trx, old_insert, mtr);
|
|
||||||
}
|
|
||||||
if (undo) {
|
if (undo) {
|
||||||
UT_LIST_REMOVE(rseg->undo_list, undo);
|
UT_LIST_REMOVE(rseg->undo_list, undo);
|
||||||
trx_purge_add_undo_to_history(trx, undo, mtr);
|
trx_purge_add_undo_to_history(trx, undo, mtr);
|
||||||
@@ -1381,23 +1355,14 @@ inline void trx_t::commit_in_memory(const mtr_t *mtr)
|
|||||||
ut_ad(rseg->trx_ref_count > 0);
|
ut_ad(rseg->trx_ref_count > 0);
|
||||||
--rseg->trx_ref_count;
|
--rseg->trx_ref_count;
|
||||||
mutex_exit(&rseg->mutex);
|
mutex_exit(&rseg->mutex);
|
||||||
|
|
||||||
if (trx_undo_t *&insert= rsegs.m_redo.old_insert)
|
|
||||||
{
|
|
||||||
ut_ad(insert->rseg == rseg);
|
|
||||||
trx_undo_commit_cleanup(insert, false);
|
|
||||||
insert= nullptr;
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
ut_ad(!rsegs.m_redo.old_insert);
|
|
||||||
|
|
||||||
if (mtr)
|
if (mtr)
|
||||||
{
|
{
|
||||||
if (trx_undo_t *&undo= rsegs.m_noredo.undo)
|
if (trx_undo_t *&undo= rsegs.m_noredo.undo)
|
||||||
{
|
{
|
||||||
ut_ad(undo->rseg == rsegs.m_noredo.rseg);
|
ut_ad(undo->rseg == rsegs.m_noredo.rseg);
|
||||||
trx_undo_commit_cleanup(undo, true);
|
trx_undo_commit_cleanup(undo);
|
||||||
undo= nullptr;
|
undo= nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1480,7 +1445,7 @@ void trx_t::commit_low(mtr_t *mtr)
|
|||||||
{
|
{
|
||||||
ut_ad(!mtr || mtr->is_active());
|
ut_ad(!mtr || mtr->is_active());
|
||||||
ut_d(bool aborted = in_rollback && error_state == DB_DEADLOCK);
|
ut_d(bool aborted = in_rollback && error_state == DB_DEADLOCK);
|
||||||
ut_ad(!mtr == (aborted || !has_logged_or_recovered()));
|
ut_ad(!mtr == (aborted || !has_logged()));
|
||||||
ut_ad(!mtr || !aborted);
|
ut_ad(!mtr || !aborted);
|
||||||
|
|
||||||
/* undo_no is non-zero if we're doing the final commit. */
|
/* undo_no is non-zero if we're doing the final commit. */
|
||||||
@@ -1534,7 +1499,7 @@ void trx_t::commit()
|
|||||||
mtr_t *mtr= nullptr;
|
mtr_t *mtr= nullptr;
|
||||||
mtr_t local_mtr;
|
mtr_t local_mtr;
|
||||||
|
|
||||||
if (has_logged_or_recovered())
|
if (has_logged())
|
||||||
{
|
{
|
||||||
mtr= &local_mtr;
|
mtr= &local_mtr;
|
||||||
local_mtr.start();
|
local_mtr.start();
|
||||||
@@ -1919,11 +1884,8 @@ trx_weight_ge(
|
|||||||
/** Prepare a transaction.
|
/** Prepare a transaction.
|
||||||
@return log sequence number that makes the XA PREPARE durable
|
@return log sequence number that makes the XA PREPARE durable
|
||||||
@retval 0 if no changes needed to be made durable */
|
@retval 0 if no changes needed to be made durable */
|
||||||
static
|
static lsn_t trx_prepare_low(trx_t *trx)
|
||||||
lsn_t
|
|
||||||
trx_prepare_low(trx_t* trx)
|
|
||||||
{
|
{
|
||||||
ut_ad(!trx->rsegs.m_redo.old_insert);
|
|
||||||
ut_ad(!trx->is_recovered);
|
ut_ad(!trx->is_recovered);
|
||||||
|
|
||||||
mtr_t mtr;
|
mtr_t mtr;
|
||||||
|
|||||||
@@ -34,6 +34,7 @@ Created 3/26/1996 Heikki Tuuri
|
|||||||
#include "trx0purge.h"
|
#include "trx0purge.h"
|
||||||
#include "trx0rec.h"
|
#include "trx0rec.h"
|
||||||
#include "trx0rseg.h"
|
#include "trx0rseg.h"
|
||||||
|
#include "log.h"
|
||||||
|
|
||||||
/* How should the old versions in the history list be managed?
|
/* How should the old versions in the history list be managed?
|
||||||
----------------------------------------------------------
|
----------------------------------------------------------
|
||||||
@@ -434,7 +435,7 @@ static uint16_t trx_undo_header_create(buf_block_t *undo_page, trx_id_t trx_id,
|
|||||||
repurposed after upgrading to MariaDB 10.3. */
|
repurposed after upgrading to MariaDB 10.3. */
|
||||||
byte *undo_type= my_assume_aligned<2>
|
byte *undo_type= my_assume_aligned<2>
|
||||||
(TRX_UNDO_PAGE_HDR + TRX_UNDO_PAGE_TYPE + undo_page->frame);
|
(TRX_UNDO_PAGE_HDR + TRX_UNDO_PAGE_TYPE + undo_page->frame);
|
||||||
ut_ad(mach_read_from_2(undo_type) <= TRX_UNDO_UPDATE);
|
ut_ad(mach_read_from_2(undo_type) <= 2);
|
||||||
mtr->write<2,mtr_t::MAYBE_NOP>(*undo_page, undo_type, 0U);
|
mtr->write<2,mtr_t::MAYBE_NOP>(*undo_page, undo_type, 0U);
|
||||||
byte *start= my_assume_aligned<4>(TRX_UNDO_PAGE_HDR + TRX_UNDO_PAGE_START +
|
byte *start= my_assume_aligned<4>(TRX_UNDO_PAGE_HDR + TRX_UNDO_PAGE_START +
|
||||||
undo_page->frame);
|
undo_page->frame);
|
||||||
@@ -790,27 +791,22 @@ done:
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** Frees an undo log segment which is not in the history list.
|
/** Frees an undo log segment which is not in the history list.
|
||||||
@param[in] undo undo log
|
@param undo temporary undo log */
|
||||||
@param[in] noredo whether the undo tablespace is redo logged */
|
static void trx_undo_seg_free(const trx_undo_t *undo)
|
||||||
static void trx_undo_seg_free(const trx_undo_t* undo, bool noredo)
|
|
||||||
{
|
{
|
||||||
ut_ad(undo->id < TRX_RSEG_N_SLOTS);
|
ut_ad(undo->id < TRX_RSEG_N_SLOTS);
|
||||||
|
|
||||||
trx_rseg_t* const rseg = undo->rseg;
|
trx_rseg_t* const rseg = undo->rseg;
|
||||||
bool finished;
|
bool finished;
|
||||||
mtr_t mtr;
|
mtr_t mtr;
|
||||||
|
ut_ad(rseg->space == fil_system.temp_space);
|
||||||
|
|
||||||
do {
|
do {
|
||||||
mtr.start();
|
mtr.start();
|
||||||
|
|
||||||
if (noredo) {
|
|
||||||
mtr.set_log_mode(MTR_LOG_NO_REDO);
|
mtr.set_log_mode(MTR_LOG_NO_REDO);
|
||||||
}
|
|
||||||
|
|
||||||
mutex_enter(&rseg->mutex);
|
|
||||||
|
|
||||||
buf_block_t* block = trx_undo_page_get(
|
buf_block_t* block = trx_undo_page_get(
|
||||||
page_id_t(rseg->space->id, undo->hdr_page_no), &mtr);
|
page_id_t(SRV_TMP_SPACE_ID, undo->hdr_page_no), &mtr);
|
||||||
|
|
||||||
fseg_header_t* file_seg = TRX_UNDO_SEG_HDR
|
fseg_header_t* file_seg = TRX_UNDO_SEG_HDR
|
||||||
+ TRX_UNDO_FSEG_HEADER + block->frame;
|
+ TRX_UNDO_FSEG_HEADER + block->frame;
|
||||||
@@ -822,12 +818,12 @@ static void trx_undo_seg_free(const trx_undo_t* undo, bool noredo)
|
|||||||
buf_block_t* rseg_header = trx_rsegf_get(
|
buf_block_t* rseg_header = trx_rsegf_get(
|
||||||
rseg->space, rseg->page_no, &mtr);
|
rseg->space, rseg->page_no, &mtr);
|
||||||
compile_time_assert(FIL_NULL == 0xffffffff);
|
compile_time_assert(FIL_NULL == 0xffffffff);
|
||||||
mtr.memset(rseg_header, TRX_RSEG + TRX_RSEG_UNDO_SLOTS
|
memset(TRX_RSEG + TRX_RSEG_UNDO_SLOTS
|
||||||
+ undo->id * TRX_RSEG_SLOT_SIZE, 4, 0xff);
|
+ undo->id * TRX_RSEG_SLOT_SIZE +
|
||||||
|
rseg_header->frame, 0xff, 4);
|
||||||
MONITOR_DEC(MONITOR_NUM_UNDO_SLOT_USED);
|
MONITOR_DEC(MONITOR_NUM_UNDO_SLOT_USED);
|
||||||
}
|
}
|
||||||
|
|
||||||
mutex_exit(&rseg->mutex);
|
|
||||||
mtr.commit();
|
mtr.commit();
|
||||||
} while (!finished);
|
} while (!finished);
|
||||||
}
|
}
|
||||||
@@ -839,8 +835,9 @@ static void trx_undo_seg_free(const trx_undo_t* undo, bool noredo)
|
|||||||
@param[in] id rollback segment slot
|
@param[in] id rollback segment slot
|
||||||
@param[in] page_no undo log segment page number
|
@param[in] page_no undo log segment page number
|
||||||
@param[in,out] max_trx_id the largest observed transaction ID
|
@param[in,out] max_trx_id the largest observed transaction ID
|
||||||
@return size of the undo log in pages */
|
@return the undo log
|
||||||
uint32_t
|
@retval nullptr on error */
|
||||||
|
trx_undo_t *
|
||||||
trx_undo_mem_create_at_db_start(trx_rseg_t *rseg, ulint id, uint32_t page_no,
|
trx_undo_mem_create_at_db_start(trx_rseg_t *rseg, ulint id, uint32_t page_no,
|
||||||
trx_id_t &max_trx_id)
|
trx_id_t &max_trx_id)
|
||||||
{
|
{
|
||||||
@@ -852,16 +849,56 @@ trx_undo_mem_create_at_db_start(trx_rseg_t *rseg, ulint id, uint32_t page_no,
|
|||||||
mtr.start();
|
mtr.start();
|
||||||
const buf_block_t* block = trx_undo_page_get(
|
const buf_block_t* block = trx_undo_page_get(
|
||||||
page_id_t(rseg->space->id, page_no), &mtr);
|
page_id_t(rseg->space->id, page_no), &mtr);
|
||||||
const ulint type = mach_read_from_2(
|
const uint16_t type = mach_read_from_2(TRX_UNDO_PAGE_HDR
|
||||||
TRX_UNDO_PAGE_HDR + TRX_UNDO_PAGE_TYPE + block->frame);
|
+ TRX_UNDO_PAGE_TYPE
|
||||||
ut_ad(type == 0 || type == TRX_UNDO_INSERT || type == TRX_UNDO_UPDATE);
|
|
||||||
|
|
||||||
uint16_t state = mach_read_from_2(TRX_UNDO_SEG_HDR + TRX_UNDO_STATE
|
|
||||||
+ block->frame);
|
+ block->frame);
|
||||||
|
switch (type) {
|
||||||
|
case 0:
|
||||||
|
case 2: /* TRX_UNDO_UPDATE */
|
||||||
|
break;
|
||||||
|
case 1: /* TRX_UNDO_INSERT */
|
||||||
|
sql_print_error("InnoDB: upgrade from older version than"
|
||||||
|
" MariaDB 10.3 requires clean shutdown");
|
||||||
|
goto corrupted;
|
||||||
|
default:
|
||||||
|
sql_print_error("InnoDB: unsupported undo header type %u",
|
||||||
|
type);
|
||||||
|
corrupted:
|
||||||
|
mtr.commit();
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
uint16_t offset = mach_read_from_2(TRX_UNDO_SEG_HDR + TRX_UNDO_LAST_LOG
|
uint16_t offset = mach_read_from_2(TRX_UNDO_SEG_HDR + TRX_UNDO_LAST_LOG
|
||||||
+ block->frame);
|
+ block->frame);
|
||||||
|
if (offset < TRX_UNDO_SEG_HDR + TRX_UNDO_SEG_HDR_SIZE ||
|
||||||
|
offset >= srv_page_size - TRX_UNDO_LOG_OLD_HDR_SIZE) {
|
||||||
|
sql_print_error("InnoDB: invalid undo header offset %u",
|
||||||
|
offset);
|
||||||
|
goto corrupted;
|
||||||
|
}
|
||||||
|
|
||||||
const trx_ulogf_t* undo_header = block->frame + offset;
|
const trx_ulogf_t* const undo_header = block->frame + offset;
|
||||||
|
uint16_t state = mach_read_from_2(TRX_UNDO_SEG_HDR + TRX_UNDO_STATE
|
||||||
|
+ block->frame);
|
||||||
|
switch (state) {
|
||||||
|
case TRX_UNDO_ACTIVE:
|
||||||
|
case TRX_UNDO_PREPARED:
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
sql_print_error("InnoDB: unsupported undo header state %u",
|
||||||
|
state);
|
||||||
|
goto corrupted;
|
||||||
|
case TRX_UNDO_TO_PURGE:
|
||||||
|
case TRX_UNDO_CACHED:
|
||||||
|
trx_id_t id = mach_read_from_8(TRX_UNDO_TRX_NO + undo_header);
|
||||||
|
if (id >> 48) {
|
||||||
|
sql_print_error("InnoDB: corrupted TRX_NO %llx", id);
|
||||||
|
goto corrupted;
|
||||||
|
}
|
||||||
|
if (id > max_trx_id) {
|
||||||
|
max_trx_id = id;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* Read X/Open XA transaction identification if it exists, or
|
/* Read X/Open XA transaction identification if it exists, or
|
||||||
set it to NULL. */
|
set it to NULL. */
|
||||||
@@ -873,6 +910,10 @@ trx_undo_mem_create_at_db_start(trx_rseg_t *rseg, ulint id, uint32_t page_no,
|
|||||||
}
|
}
|
||||||
|
|
||||||
trx_id_t trx_id = mach_read_from_8(undo_header + TRX_UNDO_TRX_ID);
|
trx_id_t trx_id = mach_read_from_8(undo_header + TRX_UNDO_TRX_ID);
|
||||||
|
if (trx_id >> 48) {
|
||||||
|
sql_print_error("InnoDB: corrupted TRX_ID %llx", trx_id);
|
||||||
|
goto corrupted;
|
||||||
|
}
|
||||||
if (trx_id > max_trx_id) {
|
if (trx_id > max_trx_id) {
|
||||||
max_trx_id = trx_id;
|
max_trx_id = trx_id;
|
||||||
}
|
}
|
||||||
@@ -881,27 +922,15 @@ trx_undo_mem_create_at_db_start(trx_rseg_t *rseg, ulint id, uint32_t page_no,
|
|||||||
trx_undo_t* undo = trx_undo_mem_create(
|
trx_undo_t* undo = trx_undo_mem_create(
|
||||||
rseg, id, trx_id, &xid, page_no, offset);
|
rseg, id, trx_id, &xid, page_no, offset);
|
||||||
mutex_exit(&rseg->mutex);
|
mutex_exit(&rseg->mutex);
|
||||||
|
if (!undo) {
|
||||||
|
return undo;
|
||||||
|
}
|
||||||
|
|
||||||
undo->dict_operation = undo_header[TRX_UNDO_DICT_TRANS];
|
undo->dict_operation = undo_header[TRX_UNDO_DICT_TRANS];
|
||||||
undo->table_id = mach_read_from_8(undo_header + TRX_UNDO_TABLE_ID);
|
undo->table_id = mach_read_from_8(undo_header + TRX_UNDO_TABLE_ID);
|
||||||
undo->size = flst_get_len(TRX_UNDO_SEG_HDR + TRX_UNDO_PAGE_LIST
|
undo->size = flst_get_len(TRX_UNDO_SEG_HDR + TRX_UNDO_PAGE_LIST
|
||||||
+ block->frame);
|
+ block->frame);
|
||||||
|
|
||||||
if (UNIV_UNLIKELY(state == TRX_UNDO_TO_FREE)) {
|
|
||||||
/* This is an old-format insert_undo log segment that
|
|
||||||
is being freed. The page list is inconsistent. */
|
|
||||||
ut_ad(type == TRX_UNDO_INSERT);
|
|
||||||
state = TRX_UNDO_TO_PURGE;
|
|
||||||
} else {
|
|
||||||
if (state == TRX_UNDO_TO_PURGE
|
|
||||||
|| state == TRX_UNDO_CACHED) {
|
|
||||||
trx_id_t id = mach_read_from_8(TRX_UNDO_TRX_NO
|
|
||||||
+ undo_header);
|
|
||||||
if (id > max_trx_id) {
|
|
||||||
max_trx_id = id;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fil_addr_t last_addr = flst_get_last(
|
fil_addr_t last_addr = flst_get_last(
|
||||||
TRX_UNDO_SEG_HDR + TRX_UNDO_PAGE_LIST + block->frame);
|
TRX_UNDO_SEG_HDR + TRX_UNDO_PAGE_LIST + block->frame);
|
||||||
|
|
||||||
@@ -913,28 +942,25 @@ trx_undo_mem_create_at_db_start(trx_rseg_t *rseg, ulint id, uint32_t page_no,
|
|||||||
|
|
||||||
if (const trx_undo_rec_t* rec = trx_undo_page_get_last_rec(
|
if (const trx_undo_rec_t* rec = trx_undo_page_get_last_rec(
|
||||||
last, page_no, offset)) {
|
last, page_no, offset)) {
|
||||||
undo->top_offset = uint16_t(rec - last->frame);
|
undo->top_offset = static_cast<uint16_t>(rec - last->frame);
|
||||||
undo->top_undo_no = trx_undo_rec_get_undo_no(rec);
|
undo->top_undo_no = trx_undo_rec_get_undo_no(rec);
|
||||||
ut_ad(!undo->empty());
|
ut_ad(!undo->empty());
|
||||||
} else {
|
} else {
|
||||||
undo->top_undo_no = IB_ID_MAX;
|
undo->top_undo_no = IB_ID_MAX;
|
||||||
ut_ad(undo->empty());
|
ut_ad(undo->empty());
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
undo->state = state;
|
undo->state = state;
|
||||||
|
|
||||||
if (state != TRX_UNDO_CACHED) {
|
if (state != TRX_UNDO_CACHED) {
|
||||||
UT_LIST_ADD_LAST(type == TRX_UNDO_INSERT
|
UT_LIST_ADD_LAST(rseg->undo_list, undo);
|
||||||
? rseg->old_insert_list
|
|
||||||
: rseg->undo_list, undo);
|
|
||||||
} else {
|
} else {
|
||||||
UT_LIST_ADD_LAST(rseg->undo_cached, undo);
|
UT_LIST_ADD_LAST(rseg->undo_cached, undo);
|
||||||
MONITOR_INC(MONITOR_NUM_UNDO_SLOT_CACHED);
|
MONITOR_INC(MONITOR_NUM_UNDO_SLOT_CACHED);
|
||||||
}
|
}
|
||||||
|
|
||||||
mtr.commit();
|
mtr.commit();
|
||||||
return undo->size;
|
return undo;
|
||||||
}
|
}
|
||||||
|
|
||||||
/********************************************************************//**
|
/********************************************************************//**
|
||||||
@@ -1304,22 +1330,18 @@ void trx_undo_set_state_at_prepare(trx_t *trx, trx_undo_t *undo, bool rollback,
|
|||||||
trx_undo_write_xid(block, offset, undo->xid, mtr);
|
trx_undo_write_xid(block, offset, undo->xid, mtr);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Free an old insert or temporary undo log after commit or rollback.
|
/** Free temporary undo log after commit or rollback.
|
||||||
The information is not needed after a commit or rollback, therefore
|
The information is not needed after a commit or rollback, therefore
|
||||||
the data can be discarded.
|
the data can be discarded.
|
||||||
@param[in,out] undo undo log
|
@param undo temporary undo log */
|
||||||
@param[in] is_temp whether this is temporary undo log */
|
void trx_undo_commit_cleanup(trx_undo_t *undo)
|
||||||
void
|
|
||||||
trx_undo_commit_cleanup(trx_undo_t* undo, bool is_temp)
|
|
||||||
{
|
{
|
||||||
trx_rseg_t* rseg = undo->rseg;
|
trx_rseg_t* rseg = undo->rseg;
|
||||||
ut_ad(is_temp == !rseg->is_persistent());
|
ut_ad(rseg->space == fil_system.temp_space);
|
||||||
ut_ad(!is_temp || 0 == UT_LIST_GET_LEN(rseg->old_insert_list));
|
|
||||||
|
|
||||||
mutex_enter(&rseg->mutex);
|
mutex_enter(&rseg->mutex);
|
||||||
|
|
||||||
UT_LIST_REMOVE(is_temp ? rseg->undo_list : rseg->old_insert_list,
|
UT_LIST_REMOVE(rseg->undo_list, undo);
|
||||||
undo);
|
|
||||||
|
|
||||||
if (undo->state == TRX_UNDO_CACHED) {
|
if (undo->state == TRX_UNDO_CACHED) {
|
||||||
UT_LIST_ADD_FIRST(rseg->undo_cached, undo);
|
UT_LIST_ADD_FIRST(rseg->undo_cached, undo);
|
||||||
@@ -1328,9 +1350,7 @@ trx_undo_commit_cleanup(trx_undo_t* undo, bool is_temp)
|
|||||||
ut_ad(undo->state == TRX_UNDO_TO_PURGE);
|
ut_ad(undo->state == TRX_UNDO_TO_PURGE);
|
||||||
|
|
||||||
/* Delete first the undo log segment in the file */
|
/* Delete first the undo log segment in the file */
|
||||||
mutex_exit(&rseg->mutex);
|
trx_undo_seg_free(undo);
|
||||||
trx_undo_seg_free(undo, is_temp);
|
|
||||||
mutex_enter(&rseg->mutex);
|
|
||||||
|
|
||||||
ut_ad(rseg->curr_size > undo->size);
|
ut_ad(rseg->curr_size > undo->size);
|
||||||
rseg->curr_size -= undo->size;
|
rseg->curr_size -= undo->size;
|
||||||
@@ -1342,15 +1362,13 @@ trx_undo_commit_cleanup(trx_undo_t* undo, bool is_temp)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** At shutdown, frees the undo logs of a transaction. */
|
/** At shutdown, frees the undo logs of a transaction. */
|
||||||
void
|
void trx_undo_free_at_shutdown(trx_t *trx)
|
||||||
trx_undo_free_at_shutdown(trx_t *trx)
|
|
||||||
{
|
{
|
||||||
if (trx_undo_t*& undo = trx->rsegs.m_redo.undo) {
|
if (trx_undo_t*& undo = trx->rsegs.m_redo.undo) {
|
||||||
switch (undo->state) {
|
switch (undo->state) {
|
||||||
case TRX_UNDO_PREPARED:
|
case TRX_UNDO_PREPARED:
|
||||||
break;
|
break;
|
||||||
case TRX_UNDO_CACHED:
|
case TRX_UNDO_CACHED:
|
||||||
case TRX_UNDO_TO_FREE:
|
|
||||||
case TRX_UNDO_TO_PURGE:
|
case TRX_UNDO_TO_PURGE:
|
||||||
ut_ad(trx_state_eq(trx,
|
ut_ad(trx_state_eq(trx,
|
||||||
TRX_STATE_COMMITTED_IN_MEMORY));
|
TRX_STATE_COMMITTED_IN_MEMORY));
|
||||||
@@ -1371,34 +1389,6 @@ trx_undo_free_at_shutdown(trx_t *trx)
|
|||||||
ut_free(undo);
|
ut_free(undo);
|
||||||
undo = NULL;
|
undo = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (trx_undo_t*& undo = trx->rsegs.m_redo.old_insert) {
|
|
||||||
switch (undo->state) {
|
|
||||||
case TRX_UNDO_PREPARED:
|
|
||||||
break;
|
|
||||||
case TRX_UNDO_CACHED:
|
|
||||||
case TRX_UNDO_TO_FREE:
|
|
||||||
case TRX_UNDO_TO_PURGE:
|
|
||||||
ut_ad(trx_state_eq(trx,
|
|
||||||
TRX_STATE_COMMITTED_IN_MEMORY));
|
|
||||||
/* fall through */
|
|
||||||
case TRX_UNDO_ACTIVE:
|
|
||||||
/* trx_t::commit_state() assigns
|
|
||||||
trx->state = TRX_STATE_COMMITTED_IN_MEMORY. */
|
|
||||||
ut_a(!srv_was_started
|
|
||||||
|| srv_read_only_mode
|
|
||||||
|| srv_force_recovery >= SRV_FORCE_NO_TRX_UNDO
|
|
||||||
|| srv_fast_shutdown);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
ut_error;
|
|
||||||
}
|
|
||||||
|
|
||||||
UT_LIST_REMOVE(trx->rsegs.m_redo.rseg->old_insert_list, undo);
|
|
||||||
ut_free(undo);
|
|
||||||
undo = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (trx_undo_t*& undo = trx->rsegs.m_noredo.undo) {
|
if (trx_undo_t*& undo = trx->rsegs.m_noredo.undo) {
|
||||||
ut_a(undo->state == TRX_UNDO_PREPARED);
|
ut_a(undo->state == TRX_UNDO_PREPARED);
|
||||||
|
|
||||||
|
|||||||
@@ -4286,7 +4286,7 @@ int maria_repair_parallel(HA_CHECK *param, register MARIA_HA *info,
|
|||||||
const char * name, my_bool rep_quick)
|
const char * name, my_bool rep_quick)
|
||||||
{
|
{
|
||||||
int got_error;
|
int got_error;
|
||||||
uint i,key, total_key_length, istep;
|
uint i,key, istep;
|
||||||
ha_rows start_records;
|
ha_rows start_records;
|
||||||
my_off_t new_header_length,del;
|
my_off_t new_header_length,del;
|
||||||
File new_file;
|
File new_file;
|
||||||
@@ -4448,7 +4448,9 @@ int maria_repair_parallel(HA_CHECK *param, register MARIA_HA *info,
|
|||||||
_ma_check_print_error(param,"Not enough memory for key!");
|
_ma_check_print_error(param,"Not enough memory for key!");
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
total_key_length=0;
|
#ifdef USING_SECOND_APPROACH
|
||||||
|
uint total_key_length=0;
|
||||||
|
#endif
|
||||||
rec_per_key_part= param->new_rec_per_key_part;
|
rec_per_key_part= param->new_rec_per_key_part;
|
||||||
share->state.state.records=share->state.state.del=share->state.split=0;
|
share->state.state.records=share->state.state.del=share->state.split=0;
|
||||||
share->state.state.empty=0;
|
share->state.state.empty=0;
|
||||||
@@ -4517,7 +4519,9 @@ int maria_repair_parallel(HA_CHECK *param, register MARIA_HA *info,
|
|||||||
if (keyseg->flag & HA_NULL_PART)
|
if (keyseg->flag & HA_NULL_PART)
|
||||||
sort_param[i].key_length++;
|
sort_param[i].key_length++;
|
||||||
}
|
}
|
||||||
|
#ifdef USING_SECOND_APPROACH
|
||||||
total_key_length+=sort_param[i].key_length;
|
total_key_length+=sort_param[i].key_length;
|
||||||
|
#endif
|
||||||
|
|
||||||
if (sort_param[i].keyinfo->flag & HA_FULLTEXT)
|
if (sort_param[i].keyinfo->flag & HA_FULLTEXT)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -2617,7 +2617,7 @@ int mi_repair_parallel(HA_CHECK *param, register MI_INFO *info,
|
|||||||
const char * name, int rep_quick)
|
const char * name, int rep_quick)
|
||||||
{
|
{
|
||||||
int got_error;
|
int got_error;
|
||||||
uint i,key, total_key_length, istep;
|
uint i,key, istep;
|
||||||
ulong rec_length;
|
ulong rec_length;
|
||||||
ha_rows start_records;
|
ha_rows start_records;
|
||||||
my_off_t new_header_length,del;
|
my_off_t new_header_length,del;
|
||||||
@@ -2803,7 +2803,9 @@ int mi_repair_parallel(HA_CHECK *param, register MI_INFO *info,
|
|||||||
mi_check_print_error(param,"Not enough memory for key!");
|
mi_check_print_error(param,"Not enough memory for key!");
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
total_key_length=0;
|
#ifdef USING_SECOND_APPROACH
|
||||||
|
uint total_key_length=0;
|
||||||
|
#endif
|
||||||
rec_per_key_part= param->rec_per_key_part;
|
rec_per_key_part= param->rec_per_key_part;
|
||||||
info->state->records=info->state->del=share->state.split=0;
|
info->state->records=info->state->del=share->state.split=0;
|
||||||
info->state->empty=0;
|
info->state->empty=0;
|
||||||
@@ -2872,7 +2874,9 @@ int mi_repair_parallel(HA_CHECK *param, register MI_INFO *info,
|
|||||||
if (keyseg->flag & HA_NULL_PART)
|
if (keyseg->flag & HA_NULL_PART)
|
||||||
sort_param[i].key_length++;
|
sort_param[i].key_length++;
|
||||||
}
|
}
|
||||||
|
#ifdef USING_SECOND_APPROACH
|
||||||
total_key_length+=sort_param[i].key_length;
|
total_key_length+=sort_param[i].key_length;
|
||||||
|
#endif
|
||||||
|
|
||||||
if (sort_param[i].keyinfo->flag & HA_FULLTEXT)
|
if (sort_param[i].keyinfo->flag & HA_FULLTEXT)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -4,7 +4,6 @@ package My::Suite::Spider;
|
|||||||
|
|
||||||
return "No Spider engine" unless $ENV{HA_SPIDER_SO};
|
return "No Spider engine" unless $ENV{HA_SPIDER_SO};
|
||||||
return "Not run for embedded server" if $::opt_embedded_server;
|
return "Not run for embedded server" if $::opt_embedded_server;
|
||||||
return "Test needs --big-test" unless $::opt_big_test;
|
|
||||||
|
|
||||||
sub is_default { 1 }
|
sub is_default { 1 }
|
||||||
|
|
||||||
|
|||||||
@@ -4,7 +4,6 @@ package My::Suite::Spider;
|
|||||||
|
|
||||||
return "No Spider engine" unless $ENV{HA_SPIDER_SO};
|
return "No Spider engine" unless $ENV{HA_SPIDER_SO};
|
||||||
return "Not run for embedded server" if $::opt_embedded_server;
|
return "Not run for embedded server" if $::opt_embedded_server;
|
||||||
return "Test needs --big-test" unless $::opt_big_test;
|
|
||||||
|
|
||||||
sub is_default { 1 }
|
sub is_default { 1 }
|
||||||
|
|
||||||
|
|||||||
@@ -22,7 +22,9 @@ USE auto_test_remote;
|
|||||||
--connection child2_1
|
--connection child2_1
|
||||||
--disable_query_log
|
--disable_query_log
|
||||||
echo CHILD2_1_CREATE_TABLES;
|
echo CHILD2_1_CREATE_TABLES;
|
||||||
|
--disable_ps_protocol
|
||||||
eval $CHILD2_1_CREATE_TABLES;
|
eval $CHILD2_1_CREATE_TABLES;
|
||||||
|
--enable_ps_protocol
|
||||||
--enable_query_log
|
--enable_query_log
|
||||||
TRUNCATE TABLE mysql.general_log;
|
TRUNCATE TABLE mysql.general_log;
|
||||||
|
|
||||||
@@ -66,7 +68,9 @@ SELECT a, b, c FROM tbl_a PARTITION (pt2,pt3);
|
|||||||
|
|
||||||
--connection child2_1
|
--connection child2_1
|
||||||
eval $CHILD2_1_SELECT_ARGUMENT1;
|
eval $CHILD2_1_SELECT_ARGUMENT1;
|
||||||
|
--disable_ps_protocol
|
||||||
eval $CHILD2_1_SELECT_TABLES;
|
eval $CHILD2_1_SELECT_TABLES;
|
||||||
|
--enable_ps_protocol
|
||||||
|
|
||||||
--echo
|
--echo
|
||||||
--echo deinit
|
--echo deinit
|
||||||
|
|||||||
@@ -22,7 +22,9 @@ USE auto_test_remote;
|
|||||||
--connection child2_1
|
--connection child2_1
|
||||||
--disable_query_log
|
--disable_query_log
|
||||||
echo CHILD2_1_CREATE_TABLES;
|
echo CHILD2_1_CREATE_TABLES;
|
||||||
|
--disable_ps_protocol
|
||||||
eval $CHILD2_1_CREATE_TABLES;
|
eval $CHILD2_1_CREATE_TABLES;
|
||||||
|
--enable_ps_protocol
|
||||||
--enable_query_log
|
--enable_query_log
|
||||||
TRUNCATE TABLE mysql.general_log;
|
TRUNCATE TABLE mysql.general_log;
|
||||||
|
|
||||||
@@ -78,7 +80,9 @@ SELECT STRAIGHT_JOIN b.a, b.b FROM tb_l a, tbl_a b WHERE a.a = b.a;
|
|||||||
--connection child2_1
|
--connection child2_1
|
||||||
SET NAMES utf8;
|
SET NAMES utf8;
|
||||||
eval $CHILD2_1_SELECT_ARGUMENT1;
|
eval $CHILD2_1_SELECT_ARGUMENT1;
|
||||||
|
--disable_ps_protocol
|
||||||
eval $CHILD2_1_SELECT_TABLES;
|
eval $CHILD2_1_SELECT_TABLES;
|
||||||
|
--enable_ps_protocol
|
||||||
|
|
||||||
--echo
|
--echo
|
||||||
--echo deinit
|
--echo deinit
|
||||||
|
|||||||
@@ -49,6 +49,8 @@ TRUNCATE TABLE mysql.general_log;
|
|||||||
SELECT * FROM tbl_a ORDER BY pkey;
|
SELECT * FROM tbl_a ORDER BY pkey;
|
||||||
|
|
||||||
--connection child2_1
|
--connection child2_1
|
||||||
|
# in --ps a query is logged differently in a general log
|
||||||
|
replace_regex /order by t0.`pkey`/order by `pkey`/;
|
||||||
eval $CHILD2_1_SELECT_ARGUMENT1;
|
eval $CHILD2_1_SELECT_ARGUMENT1;
|
||||||
eval $CHILD2_1_SELECT_TABLES;
|
eval $CHILD2_1_SELECT_TABLES;
|
||||||
|
|
||||||
|
|||||||
@@ -4,7 +4,6 @@ package My::Suite::Spider;
|
|||||||
|
|
||||||
return "No Spider engine" unless $ENV{HA_SPIDER_SO};
|
return "No Spider engine" unless $ENV{HA_SPIDER_SO};
|
||||||
return "Not run for embedded server" if $::opt_embedded_server;
|
return "Not run for embedded server" if $::opt_embedded_server;
|
||||||
return "Test needs --big-test" unless $::opt_big_test;
|
|
||||||
|
|
||||||
sub is_default { 1 }
|
sub is_default { 1 }
|
||||||
|
|
||||||
|
|||||||
@@ -4,7 +4,6 @@ package My::Suite::Spider;
|
|||||||
|
|
||||||
return "No Spider engine" unless $ENV{HA_SPIDER_SO};
|
return "No Spider engine" unless $ENV{HA_SPIDER_SO};
|
||||||
return "Not run for embedded server" if $::opt_embedded_server;
|
return "Not run for embedded server" if $::opt_embedded_server;
|
||||||
return "Test needs --big-test" unless $::opt_big_test;
|
|
||||||
|
|
||||||
sub is_default { 1 }
|
sub is_default { 1 }
|
||||||
|
|
||||||
|
|||||||
@@ -4,7 +4,6 @@ package My::Suite::Spider;
|
|||||||
|
|
||||||
return "No Spider engine" unless $ENV{HA_SPIDER_SO};
|
return "No Spider engine" unless $ENV{HA_SPIDER_SO};
|
||||||
return "Not run for embedded server" if $::opt_embedded_server;
|
return "Not run for embedded server" if $::opt_embedded_server;
|
||||||
return "Test needs --big-test" unless $::opt_big_test;
|
|
||||||
|
|
||||||
sub is_default { 1 }
|
sub is_default { 1 }
|
||||||
|
|
||||||
|
|||||||
@@ -21,8 +21,10 @@ USE auto_test_remote;
|
|||||||
|
|
||||||
--connection child2_1
|
--connection child2_1
|
||||||
--disable_query_log
|
--disable_query_log
|
||||||
|
--disable_ps_protocol
|
||||||
echo CHILD2_1_CREATE_TABLES;
|
echo CHILD2_1_CREATE_TABLES;
|
||||||
eval $CHILD2_1_CREATE_TABLES;
|
eval $CHILD2_1_CREATE_TABLES;
|
||||||
|
--enable_ps_protocol
|
||||||
--enable_query_log
|
--enable_query_log
|
||||||
TRUNCATE TABLE mysql.general_log;
|
TRUNCATE TABLE mysql.general_log;
|
||||||
|
|
||||||
@@ -62,8 +64,10 @@ TRUNCATE TABLE mysql.general_log;
|
|||||||
SELECT a.val, a.akey FROM tbl_a a, tbl_b b WHERE a.akey = b.akey AND b.bkey = 5;
|
SELECT a.val, a.akey FROM tbl_a a, tbl_b b WHERE a.akey = b.akey AND b.bkey = 5;
|
||||||
|
|
||||||
--connection child2_1
|
--connection child2_1
|
||||||
|
--disable_ps_protocol
|
||||||
eval $CHILD2_1_SELECT_ARGUMENT1;
|
eval $CHILD2_1_SELECT_ARGUMENT1;
|
||||||
eval $CHILD2_1_SELECT_TABLES;
|
eval $CHILD2_1_SELECT_TABLES;
|
||||||
|
--enable_ps_protocol
|
||||||
|
|
||||||
--echo
|
--echo
|
||||||
--echo deinit
|
--echo deinit
|
||||||
|
|||||||
@@ -22,7 +22,9 @@ USE auto_test_remote;
|
|||||||
--connection child2_1
|
--connection child2_1
|
||||||
--disable_query_log
|
--disable_query_log
|
||||||
echo CHILD2_1_CREATE_TABLES;
|
echo CHILD2_1_CREATE_TABLES;
|
||||||
|
--disable_ps_protocol
|
||||||
eval $CHILD2_1_CREATE_TABLES;
|
eval $CHILD2_1_CREATE_TABLES;
|
||||||
|
--enable_ps_protocol
|
||||||
--enable_query_log
|
--enable_query_log
|
||||||
TRUNCATE TABLE mysql.general_log;
|
TRUNCATE TABLE mysql.general_log;
|
||||||
|
|
||||||
@@ -62,8 +64,10 @@ TRUNCATE TABLE mysql.general_log;
|
|||||||
SELECT a.val, a.akey FROM tbl_a a, tbl_b b WHERE a.akey = b.akey AND b.bkey = 5;
|
SELECT a.val, a.akey FROM tbl_a a, tbl_b b WHERE a.akey = b.akey AND b.bkey = 5;
|
||||||
|
|
||||||
--connection child2_1
|
--connection child2_1
|
||||||
|
--disable_ps_protocol
|
||||||
eval $CHILD2_1_SELECT_ARGUMENT1;
|
eval $CHILD2_1_SELECT_ARGUMENT1;
|
||||||
eval $CHILD2_1_SELECT_TABLES;
|
eval $CHILD2_1_SELECT_TABLES;
|
||||||
|
--enable_ps_protocol
|
||||||
|
|
||||||
--echo
|
--echo
|
||||||
--echo deinit
|
--echo deinit
|
||||||
|
|||||||
@@ -4,7 +4,6 @@ package My::Suite::Spider;
|
|||||||
|
|
||||||
return "No Spider engine" unless $ENV{HA_SPIDER_SO};
|
return "No Spider engine" unless $ENV{HA_SPIDER_SO};
|
||||||
return "Not run for embedded server" if $::opt_embedded_server;
|
return "Not run for embedded server" if $::opt_embedded_server;
|
||||||
return "Test needs --big-test" unless $::opt_big_test;
|
|
||||||
|
|
||||||
sub is_default { 1 }
|
sub is_default { 1 }
|
||||||
|
|
||||||
|
|||||||
@@ -4,7 +4,6 @@ package My::Suite::Spider;
|
|||||||
|
|
||||||
return "No Spider engine" unless $ENV{HA_SPIDER_SO};
|
return "No Spider engine" unless $ENV{HA_SPIDER_SO};
|
||||||
return "Not run for embedded server" if $::opt_embedded_server;
|
return "Not run for embedded server" if $::opt_embedded_server;
|
||||||
return "Test needs --big-test" unless $::opt_big_test;
|
|
||||||
|
|
||||||
sub is_default { 1 }
|
sub is_default { 1 }
|
||||||
|
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
--source include/no_protocol.inc
|
||||||
--source ../include/partition_mrr_init.inc
|
--source ../include/partition_mrr_init.inc
|
||||||
if (!$HAVE_PARTITION)
|
if (!$HAVE_PARTITION)
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in New Issue
Block a user