Merge 10.5 into 10.6
This commit is contained in:
commit
254bb1c35b
@ -13,6 +13,7 @@
|
|||||||
along with this program; if not, write to the Free Software
|
along with this program; if not, write to the Free Software
|
||||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1335 USA */
|
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1335 USA */
|
||||||
|
|
||||||
|
#pragma once
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
#include <atomic>
|
#include <atomic>
|
||||||
/**
|
/**
|
||||||
|
@ -3,9 +3,11 @@
|
|||||||
|
|
||||||
[strict_crc32]
|
[strict_crc32]
|
||||||
--innodb-checksum-algorithm=strict_crc32
|
--innodb-checksum-algorithm=strict_crc32
|
||||||
|
--innodb-flush-sync=OFF
|
||||||
|
|
||||||
[full_crc32]
|
[full_crc32]
|
||||||
--innodb-checksum-algorithm=full_crc32
|
--innodb-checksum-algorithm=full_crc32
|
||||||
|
|
||||||
[strict_full_crc32]
|
[strict_full_crc32]
|
||||||
--innodb-checksum-algorithm=strict_full_crc32
|
--innodb-checksum-algorithm=strict_full_crc32
|
||||||
|
--innodb-flush-sync=OFF
|
||||||
|
@ -1297,7 +1297,7 @@ SELECT * FROM t1 WHERE
|
|||||||
25 <= a AND b = 23 OR
|
25 <= a AND b = 23 OR
|
||||||
23 <= a;
|
23 <= a;
|
||||||
id select_type table type possible_keys key key_len ref rows Extra
|
id select_type table type possible_keys key key_len ref rows Extra
|
||||||
1 SIMPLE t1 range a a 5 NULL 2 Using where; Using index
|
1 SIMPLE t1 range a a 5 NULL 3 Using where; Using index
|
||||||
SELECT * FROM t1 WHERE
|
SELECT * FROM t1 WHERE
|
||||||
23 <= a AND a <= 25 OR
|
23 <= a AND a <= 25 OR
|
||||||
25 <= a AND b = 23 OR
|
25 <= a AND b = 23 OR
|
||||||
@ -3121,6 +3121,39 @@ a b
|
|||||||
set eq_range_index_dive_limit=default;
|
set eq_range_index_dive_limit=default;
|
||||||
drop table t1;
|
drop table t1;
|
||||||
#
|
#
|
||||||
|
# MDEV-24117: Memory management problem in statistics state...
|
||||||
|
# (just the testcase)
|
||||||
|
#
|
||||||
|
create table t0(a int);
|
||||||
|
insert into t0 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
|
||||||
|
create table t1(a int);
|
||||||
|
insert into t1
|
||||||
|
select A.a + B.a* 10 + C.a * 100 + D.a * 1000
|
||||||
|
from t0 A, t0 B, t0 C, t0 D
|
||||||
|
where D.a<4;
|
||||||
|
create table t2 (
|
||||||
|
a int,
|
||||||
|
b int,
|
||||||
|
key(a)
|
||||||
|
);
|
||||||
|
insert into t2 values (1,1),(2,2),(3,3);
|
||||||
|
set @query=(select group_concat(a) from t1);
|
||||||
|
set @tmp_24117= @@max_session_mem_used;
|
||||||
|
#
|
||||||
|
# On debug build, the usage was
|
||||||
|
# - 2.8M without the bug
|
||||||
|
# - 1G with the bug.
|
||||||
|
set max_session_mem_used=64*1024*1024;
|
||||||
|
set @query=concat('explain select * from t2 where a=1 or a in (', @query, ')');
|
||||||
|
prepare s from @query;
|
||||||
|
# This should not fail with an error:
|
||||||
|
execute s;
|
||||||
|
id select_type table type possible_keys key key_len ref rows Extra
|
||||||
|
1 SIMPLE t2 ALL a NULL NULL NULL 3 Using where
|
||||||
|
set max_session_mem_used=@tmp_24117;
|
||||||
|
deallocate prepare s;
|
||||||
|
drop table t0,t1,t2;
|
||||||
|
#
|
||||||
# MDEV-23811: Both disjunct of WHERE condition contain range conditions
|
# MDEV-23811: Both disjunct of WHERE condition contain range conditions
|
||||||
# for the same index such that the second range condition
|
# for the same index such that the second range condition
|
||||||
# fully covers the first one. Additionally one of the disjuncts
|
# fully covers the first one. Additionally one of the disjuncts
|
||||||
|
@ -2092,6 +2092,52 @@ set eq_range_index_dive_limit=default;
|
|||||||
|
|
||||||
drop table t1;
|
drop table t1;
|
||||||
|
|
||||||
|
--echo #
|
||||||
|
--echo # MDEV-24117: Memory management problem in statistics state...
|
||||||
|
--echo # (just the testcase)
|
||||||
|
--echo #
|
||||||
|
|
||||||
|
create table t0(a int);
|
||||||
|
insert into t0 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
|
||||||
|
|
||||||
|
create table t1(a int);
|
||||||
|
|
||||||
|
# 4K rows
|
||||||
|
insert into t1
|
||||||
|
select A.a + B.a* 10 + C.a * 100 + D.a * 1000
|
||||||
|
from t0 A, t0 B, t0 C, t0 D
|
||||||
|
where D.a<4;
|
||||||
|
|
||||||
|
create table t2 (
|
||||||
|
a int,
|
||||||
|
b int,
|
||||||
|
key(a)
|
||||||
|
);
|
||||||
|
|
||||||
|
insert into t2 values (1,1),(2,2),(3,3);
|
||||||
|
|
||||||
|
set @query=(select group_concat(a) from t1);
|
||||||
|
|
||||||
|
set @tmp_24117= @@max_session_mem_used;
|
||||||
|
|
||||||
|
--echo #
|
||||||
|
--echo # On debug build, the usage was
|
||||||
|
--echo # - 2.8M without the bug
|
||||||
|
--echo # - 1G with the bug.
|
||||||
|
|
||||||
|
set max_session_mem_used=64*1024*1024;
|
||||||
|
|
||||||
|
set @query=concat('explain select * from t2 where a=1 or a in (', @query, ')');
|
||||||
|
|
||||||
|
prepare s from @query;
|
||||||
|
|
||||||
|
--echo # This should not fail with an error:
|
||||||
|
execute s;
|
||||||
|
set max_session_mem_used=@tmp_24117;
|
||||||
|
|
||||||
|
deallocate prepare s;
|
||||||
|
|
||||||
|
drop table t0,t1,t2;
|
||||||
--echo #
|
--echo #
|
||||||
--echo # MDEV-23811: Both disjunct of WHERE condition contain range conditions
|
--echo # MDEV-23811: Both disjunct of WHERE condition contain range conditions
|
||||||
--echo # for the same index such that the second range condition
|
--echo # for the same index such that the second range condition
|
||||||
|
@ -1300,7 +1300,7 @@ SELECT * FROM t1 WHERE
|
|||||||
25 <= a AND b = 23 OR
|
25 <= a AND b = 23 OR
|
||||||
23 <= a;
|
23 <= a;
|
||||||
id select_type table type possible_keys key key_len ref rows Extra
|
id select_type table type possible_keys key key_len ref rows Extra
|
||||||
1 SIMPLE t1 range a a 5 NULL 2 Using where; Using index
|
1 SIMPLE t1 range a a 5 NULL 3 Using where; Using index
|
||||||
SELECT * FROM t1 WHERE
|
SELECT * FROM t1 WHERE
|
||||||
23 <= a AND a <= 25 OR
|
23 <= a AND a <= 25 OR
|
||||||
25 <= a AND b = 23 OR
|
25 <= a AND b = 23 OR
|
||||||
@ -3110,6 +3110,39 @@ a b
|
|||||||
set eq_range_index_dive_limit=default;
|
set eq_range_index_dive_limit=default;
|
||||||
drop table t1;
|
drop table t1;
|
||||||
#
|
#
|
||||||
|
# MDEV-24117: Memory management problem in statistics state...
|
||||||
|
# (just the testcase)
|
||||||
|
#
|
||||||
|
create table t0(a int);
|
||||||
|
insert into t0 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
|
||||||
|
create table t1(a int);
|
||||||
|
insert into t1
|
||||||
|
select A.a + B.a* 10 + C.a * 100 + D.a * 1000
|
||||||
|
from t0 A, t0 B, t0 C, t0 D
|
||||||
|
where D.a<4;
|
||||||
|
create table t2 (
|
||||||
|
a int,
|
||||||
|
b int,
|
||||||
|
key(a)
|
||||||
|
);
|
||||||
|
insert into t2 values (1,1),(2,2),(3,3);
|
||||||
|
set @query=(select group_concat(a) from t1);
|
||||||
|
set @tmp_24117= @@max_session_mem_used;
|
||||||
|
#
|
||||||
|
# On debug build, the usage was
|
||||||
|
# - 2.8M without the bug
|
||||||
|
# - 1G with the bug.
|
||||||
|
set max_session_mem_used=64*1024*1024;
|
||||||
|
set @query=concat('explain select * from t2 where a=1 or a in (', @query, ')');
|
||||||
|
prepare s from @query;
|
||||||
|
# This should not fail with an error:
|
||||||
|
execute s;
|
||||||
|
id select_type table type possible_keys key key_len ref rows Extra
|
||||||
|
1 SIMPLE t2 ALL a NULL NULL NULL 3 Using where
|
||||||
|
set max_session_mem_used=@tmp_24117;
|
||||||
|
deallocate prepare s;
|
||||||
|
drop table t0,t1,t2;
|
||||||
|
#
|
||||||
# MDEV-23811: Both disjunct of WHERE condition contain range conditions
|
# MDEV-23811: Both disjunct of WHERE condition contain range conditions
|
||||||
# for the same index such that the second range condition
|
# for the same index such that the second range condition
|
||||||
# fully covers the first one. Additionally one of the disjuncts
|
# fully covers the first one. Additionally one of the disjuncts
|
||||||
|
@ -86,11 +86,6 @@ flush tables;
|
|||||||
--error 1,ER_TABLE_EXISTS_ERROR
|
--error 1,ER_TABLE_EXISTS_ERROR
|
||||||
--eval CREATE TABLE MDEV_23222 (i INT) DATA DIRECTORY = '$MYSQL_TMP_DIR', ENGINE=Aria TRANSACTIONAL=1;
|
--eval CREATE TABLE MDEV_23222 (i INT) DATA DIRECTORY = '$MYSQL_TMP_DIR', ENGINE=Aria TRANSACTIONAL=1;
|
||||||
DROP TABLE t1;
|
DROP TABLE t1;
|
||||||
--disable_warnings
|
|
||||||
--remove_file $mysqld_datadir/test/MDEV_23222.MAD
|
|
||||||
--replace_result $MYSQL_TMP_DIR MYSQL_TMP_DIR
|
|
||||||
--remove_file $MYSQL_TMP_DIR/MDEV_23222.MAD
|
|
||||||
--enable_warnings
|
|
||||||
|
|
||||||
--echo #
|
--echo #
|
||||||
--echo # End of 10.3 tests
|
--echo # End of 10.3 tests
|
||||||
|
@ -1,16 +1,11 @@
|
|||||||
SET @start_global_value = @@global.innodb_flush_sync;
|
SET @start_global_value = @@global.innodb_flush_sync;
|
||||||
SELECT @start_global_value;
|
|
||||||
@start_global_value
|
|
||||||
1
|
|
||||||
Valid values are 'ON' and 'OFF'
|
Valid values are 'ON' and 'OFF'
|
||||||
select @@global.innodb_flush_sync in (0, 1);
|
select @@global.innodb_flush_sync in (0, 1);
|
||||||
@@global.innodb_flush_sync in (0, 1)
|
@@global.innodb_flush_sync in (0, 1)
|
||||||
1
|
1
|
||||||
select @@global.innodb_flush_sync;
|
|
||||||
@@global.innodb_flush_sync
|
|
||||||
1
|
|
||||||
select @@session.innodb_flush_sync;
|
select @@session.innodb_flush_sync;
|
||||||
ERROR HY000: Variable 'innodb_flush_sync' is a GLOBAL variable
|
ERROR HY000: Variable 'innodb_flush_sync' is a GLOBAL variable
|
||||||
|
SET GLOBAL innodb_flush_sync = ON;
|
||||||
show global variables like 'innodb_flush_sync';
|
show global variables like 'innodb_flush_sync';
|
||||||
Variable_name Value
|
Variable_name Value
|
||||||
innodb_flush_sync ON
|
innodb_flush_sync ON
|
||||||
@ -87,6 +82,3 @@ INNODB_FLUSH_SYNC ON
|
|||||||
set global innodb_flush_sync='AUTO';
|
set global innodb_flush_sync='AUTO';
|
||||||
ERROR 42000: Variable 'innodb_flush_sync' can't be set to the value of 'AUTO'
|
ERROR 42000: Variable 'innodb_flush_sync' can't be set to the value of 'AUTO'
|
||||||
SET @@global.innodb_flush_sync = @start_global_value;
|
SET @@global.innodb_flush_sync = @start_global_value;
|
||||||
SELECT @@global.innodb_flush_sync;
|
|
||||||
@@global.innodb_flush_sync
|
|
||||||
1
|
|
||||||
|
@ -1,16 +1,15 @@
|
|||||||
--source include/have_innodb.inc
|
--source include/have_innodb.inc
|
||||||
|
|
||||||
SET @start_global_value = @@global.innodb_flush_sync;
|
SET @start_global_value = @@global.innodb_flush_sync;
|
||||||
SELECT @start_global_value;
|
|
||||||
|
|
||||||
#
|
#
|
||||||
# exists as global only
|
# exists as global only
|
||||||
#
|
#
|
||||||
--echo Valid values are 'ON' and 'OFF'
|
--echo Valid values are 'ON' and 'OFF'
|
||||||
select @@global.innodb_flush_sync in (0, 1);
|
select @@global.innodb_flush_sync in (0, 1);
|
||||||
select @@global.innodb_flush_sync;
|
|
||||||
--error ER_INCORRECT_GLOBAL_LOCAL_VAR
|
--error ER_INCORRECT_GLOBAL_LOCAL_VAR
|
||||||
select @@session.innodb_flush_sync;
|
select @@session.innodb_flush_sync;
|
||||||
|
SET GLOBAL innodb_flush_sync = ON;
|
||||||
show global variables like 'innodb_flush_sync';
|
show global variables like 'innodb_flush_sync';
|
||||||
show session variables like 'innodb_flush_sync';
|
show session variables like 'innodb_flush_sync';
|
||||||
--disable_warnings
|
--disable_warnings
|
||||||
@ -18,9 +17,6 @@ select * from information_schema.global_variables where variable_name='innodb_fl
|
|||||||
select * from information_schema.session_variables where variable_name='innodb_flush_sync';
|
select * from information_schema.session_variables where variable_name='innodb_flush_sync';
|
||||||
--enable_warnings
|
--enable_warnings
|
||||||
|
|
||||||
#
|
|
||||||
# show that it's writable
|
|
||||||
#
|
|
||||||
set global innodb_flush_sync='OFF';
|
set global innodb_flush_sync='OFF';
|
||||||
select @@global.innodb_flush_sync;
|
select @@global.innodb_flush_sync;
|
||||||
--disable_warnings
|
--disable_warnings
|
||||||
@ -74,4 +70,3 @@ set global innodb_flush_sync='AUTO';
|
|||||||
#
|
#
|
||||||
|
|
||||||
SET @@global.innodb_flush_sync = @start_global_value;
|
SET @@global.innodb_flush_sync = @start_global_value;
|
||||||
SELECT @@global.innodb_flush_sync;
|
|
||||||
|
@ -9619,15 +9619,9 @@ tree_or(RANGE_OPT_PARAM *param,SEL_TREE *tree1,SEL_TREE *tree2)
|
|||||||
}
|
}
|
||||||
bool no_imerge_from_ranges= FALSE;
|
bool no_imerge_from_ranges= FALSE;
|
||||||
|
|
||||||
SEL_TREE *rt1= tree1;
|
|
||||||
SEL_TREE *rt2= tree2;
|
|
||||||
/* Build the range part of the tree for the formula (1) */
|
/* Build the range part of the tree for the formula (1) */
|
||||||
if (sel_trees_can_be_ored(param, tree1, tree2, &ored_keys))
|
if (sel_trees_can_be_ored(param, tree1, tree2, &ored_keys))
|
||||||
{
|
{
|
||||||
if (no_merges1)
|
|
||||||
rt1= new SEL_TREE(tree1, TRUE, param);
|
|
||||||
if (no_merges2)
|
|
||||||
rt2= new SEL_TREE(tree2, TRUE, param);
|
|
||||||
bool must_be_ored= sel_trees_must_be_ored(param, tree1, tree2, ored_keys);
|
bool must_be_ored= sel_trees_must_be_ored(param, tree1, tree2, ored_keys);
|
||||||
no_imerge_from_ranges= must_be_ored;
|
no_imerge_from_ranges= must_be_ored;
|
||||||
|
|
||||||
@ -9685,6 +9679,12 @@ tree_or(RANGE_OPT_PARAM *param,SEL_TREE *tree1,SEL_TREE *tree2)
|
|||||||
else if (!no_ranges1 && !no_ranges2 && !no_imerge_from_ranges)
|
else if (!no_ranges1 && !no_ranges2 && !no_imerge_from_ranges)
|
||||||
{
|
{
|
||||||
/* Build the imerge part of the tree for the formula (1) */
|
/* Build the imerge part of the tree for the formula (1) */
|
||||||
|
SEL_TREE *rt1= tree1;
|
||||||
|
SEL_TREE *rt2= tree2;
|
||||||
|
if (no_merges1)
|
||||||
|
rt1= new SEL_TREE(tree1, TRUE, param);
|
||||||
|
if (no_merges2)
|
||||||
|
rt2= new SEL_TREE(tree2, TRUE, param);
|
||||||
if (!rt1 || !rt2 ||
|
if (!rt1 || !rt2 ||
|
||||||
result->merges.push_back(imerge_from_ranges) ||
|
result->merges.push_back(imerge_from_ranges) ||
|
||||||
imerge_from_ranges->or_sel_tree(param, rt1) ||
|
imerge_from_ranges->or_sel_tree(param, rt1) ||
|
||||||
@ -10350,7 +10350,7 @@ key_or(RANGE_OPT_PARAM *param, SEL_ARG *key1,SEL_ARG *key2)
|
|||||||
if (!tmp->next_key_part)
|
if (!tmp->next_key_part)
|
||||||
{
|
{
|
||||||
SEL_ARG *key2_next= key2->next;
|
SEL_ARG *key2_next= key2->next;
|
||||||
if (key2->use_count)
|
if (key2_shared)
|
||||||
{
|
{
|
||||||
SEL_ARG *key2_cpy= new SEL_ARG(*key2);
|
SEL_ARG *key2_cpy= new SEL_ARG(*key2);
|
||||||
if (!key2_cpy)
|
if (!key2_cpy)
|
||||||
|
@ -3252,10 +3252,19 @@ void mysqld_stmt_execute(THD *thd, char *packet_arg, uint packet_length)
|
|||||||
void mysqld_stmt_bulk_execute(THD *thd, char *packet_arg, uint packet_length)
|
void mysqld_stmt_bulk_execute(THD *thd, char *packet_arg, uint packet_length)
|
||||||
{
|
{
|
||||||
uchar *packet= (uchar*)packet_arg; // GCC 4.0.1 workaround
|
uchar *packet= (uchar*)packet_arg; // GCC 4.0.1 workaround
|
||||||
|
DBUG_ENTER("mysqld_stmt_execute_bulk");
|
||||||
|
|
||||||
|
const uint packet_header_lenght= 4 + 2; //ID & 2 bytes of flags
|
||||||
|
|
||||||
|
if (packet_length < packet_header_lenght)
|
||||||
|
{
|
||||||
|
my_error(ER_MALFORMED_PACKET, MYF(0));
|
||||||
|
DBUG_VOID_RETURN;
|
||||||
|
}
|
||||||
|
|
||||||
ulong stmt_id= uint4korr(packet);
|
ulong stmt_id= uint4korr(packet);
|
||||||
uint flags= (uint) uint2korr(packet + 4);
|
uint flags= (uint) uint2korr(packet + 4);
|
||||||
uchar *packet_end= packet + packet_length;
|
uchar *packet_end= packet + packet_length;
|
||||||
DBUG_ENTER("mysqld_stmt_execute_bulk");
|
|
||||||
|
|
||||||
if (!(thd->client_capabilities &
|
if (!(thd->client_capabilities &
|
||||||
MARIADB_CLIENT_STMT_BULK_OPERATIONS))
|
MARIADB_CLIENT_STMT_BULK_OPERATIONS))
|
||||||
@ -3263,16 +3272,18 @@ void mysqld_stmt_bulk_execute(THD *thd, char *packet_arg, uint packet_length)
|
|||||||
DBUG_PRINT("error",
|
DBUG_PRINT("error",
|
||||||
("An attempt to execute bulk operation without support"));
|
("An attempt to execute bulk operation without support"));
|
||||||
my_error(ER_UNSUPPORTED_PS, MYF(0));
|
my_error(ER_UNSUPPORTED_PS, MYF(0));
|
||||||
|
DBUG_VOID_RETURN;
|
||||||
}
|
}
|
||||||
/* Check for implemented parameters */
|
/* Check for implemented parameters */
|
||||||
if (flags & (~STMT_BULK_FLAG_CLIENT_SEND_TYPES))
|
if (flags & (~STMT_BULK_FLAG_CLIENT_SEND_TYPES))
|
||||||
{
|
{
|
||||||
DBUG_PRINT("error", ("unsupported bulk execute flags %x", flags));
|
DBUG_PRINT("error", ("unsupported bulk execute flags %x", flags));
|
||||||
my_error(ER_UNSUPPORTED_PS, MYF(0));
|
my_error(ER_UNSUPPORTED_PS, MYF(0));
|
||||||
|
DBUG_VOID_RETURN;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* stmt id and two bytes of flags */
|
/* stmt id and two bytes of flags */
|
||||||
packet+= 4 + 2;
|
packet+= packet_header_lenght;
|
||||||
mysql_stmt_execute_common(thd, stmt_id, packet, packet_end, 0, TRUE,
|
mysql_stmt_execute_common(thd, stmt_id, packet, packet_end, 0, TRUE,
|
||||||
(flags & STMT_BULK_FLAG_CLIENT_SEND_TYPES));
|
(flags & STMT_BULK_FLAG_CLIENT_SEND_TYPES));
|
||||||
DBUG_VOID_RETURN;
|
DBUG_VOID_RETURN;
|
||||||
@ -3349,9 +3360,11 @@ stmt_execute_packet_sanity_check(Prepared_statement *stmt,
|
|||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
If there is no parameters, this should be normally already end
|
If there is no parameters, this should be normally already end
|
||||||
of the packet. If it's not - then error
|
of the packet, but it is not a problem if something left (popular
|
||||||
|
mistake in protocol implementation) because we will not read anymore
|
||||||
|
from the buffer.
|
||||||
*/
|
*/
|
||||||
return (packet_end > packet);
|
return false;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -1681,16 +1681,15 @@ ATTRIBUTE_COLD void buf_flush_wait_flushed(lsn_t sync_lsn)
|
|||||||
|
|
||||||
mysql_mutex_lock(&buf_pool.flush_list_mutex);
|
mysql_mutex_lock(&buf_pool.flush_list_mutex);
|
||||||
|
|
||||||
|
if (buf_pool.get_oldest_modification(sync_lsn) < sync_lsn)
|
||||||
|
{
|
||||||
#if 1 /* FIXME: remove this, and guarantee that the page cleaner serves us */
|
#if 1 /* FIXME: remove this, and guarantee that the page cleaner serves us */
|
||||||
if (UNIV_UNLIKELY(!buf_page_cleaner_is_active)
|
if (UNIV_UNLIKELY(!buf_page_cleaner_is_active)
|
||||||
ut_d(|| innodb_page_cleaner_disabled_debug))
|
ut_d(|| innodb_page_cleaner_disabled_debug))
|
||||||
{
|
{
|
||||||
for (;;)
|
do
|
||||||
{
|
{
|
||||||
const lsn_t lsn= buf_pool.get_oldest_modification(sync_lsn);
|
|
||||||
mysql_mutex_unlock(&buf_pool.flush_list_mutex);
|
mysql_mutex_unlock(&buf_pool.flush_list_mutex);
|
||||||
if (lsn >= sync_lsn)
|
|
||||||
return;
|
|
||||||
ulint n_pages= buf_flush_lists(srv_max_io_capacity, sync_lsn);
|
ulint n_pages= buf_flush_lists(srv_max_io_capacity, sync_lsn);
|
||||||
buf_flush_wait_batch_end_acquiring_mutex(false);
|
buf_flush_wait_batch_end_acquiring_mutex(false);
|
||||||
if (n_pages)
|
if (n_pages)
|
||||||
@ -1698,24 +1697,22 @@ ATTRIBUTE_COLD void buf_flush_wait_flushed(lsn_t sync_lsn)
|
|||||||
MONITOR_INC_VALUE_CUMULATIVE(MONITOR_FLUSH_SYNC_TOTAL_PAGE,
|
MONITOR_INC_VALUE_CUMULATIVE(MONITOR_FLUSH_SYNC_TOTAL_PAGE,
|
||||||
MONITOR_FLUSH_SYNC_COUNT,
|
MONITOR_FLUSH_SYNC_COUNT,
|
||||||
MONITOR_FLUSH_SYNC_PAGES, n_pages);
|
MONITOR_FLUSH_SYNC_PAGES, n_pages);
|
||||||
log_checkpoint();
|
|
||||||
}
|
}
|
||||||
MONITOR_INC(MONITOR_FLUSH_SYNC_WAITS);
|
MONITOR_INC(MONITOR_FLUSH_SYNC_WAITS);
|
||||||
mysql_mutex_lock(&buf_pool.flush_list_mutex);
|
mysql_mutex_lock(&buf_pool.flush_list_mutex);
|
||||||
}
|
}
|
||||||
return;
|
while (buf_pool.get_oldest_modification(sync_lsn) < sync_lsn);
|
||||||
|
|
||||||
|
goto try_checkpoint;
|
||||||
}
|
}
|
||||||
else if (UNIV_LIKELY(srv_flush_sync))
|
|
||||||
#endif
|
#endif
|
||||||
{
|
|
||||||
if (buf_flush_sync_lsn < sync_lsn)
|
if (buf_flush_sync_lsn < sync_lsn)
|
||||||
{
|
{
|
||||||
buf_flush_sync_lsn= sync_lsn;
|
buf_flush_sync_lsn= sync_lsn;
|
||||||
mysql_cond_signal(&buf_pool.do_flush_list);
|
mysql_cond_signal(&buf_pool.do_flush_list);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
while (buf_pool.get_oldest_modification(sync_lsn) < sync_lsn)
|
do
|
||||||
{
|
{
|
||||||
tpool::tpool_wait_begin();
|
tpool::tpool_wait_begin();
|
||||||
thd_wait_begin(nullptr, THD_WAIT_DISKIO);
|
thd_wait_begin(nullptr, THD_WAIT_DISKIO);
|
||||||
@ -1725,8 +1722,14 @@ ATTRIBUTE_COLD void buf_flush_wait_flushed(lsn_t sync_lsn)
|
|||||||
|
|
||||||
MONITOR_INC(MONITOR_FLUSH_SYNC_WAITS);
|
MONITOR_INC(MONITOR_FLUSH_SYNC_WAITS);
|
||||||
}
|
}
|
||||||
|
while (buf_pool.get_oldest_modification(sync_lsn) < sync_lsn);
|
||||||
|
}
|
||||||
|
|
||||||
|
try_checkpoint:
|
||||||
mysql_mutex_unlock(&buf_pool.flush_list_mutex);
|
mysql_mutex_unlock(&buf_pool.flush_list_mutex);
|
||||||
|
|
||||||
|
if (UNIV_UNLIKELY(log_sys.last_checkpoint_lsn < sync_lsn))
|
||||||
|
log_checkpoint();
|
||||||
}
|
}
|
||||||
|
|
||||||
/** If innodb_flush_sync=ON, initiate a furious flush.
|
/** If innodb_flush_sync=ON, initiate a furious flush.
|
||||||
@ -1739,8 +1742,7 @@ void buf_flush_ahead(lsn_t lsn)
|
|||||||
if (recv_recovery_is_on())
|
if (recv_recovery_is_on())
|
||||||
recv_sys.apply(true);
|
recv_sys.apply(true);
|
||||||
|
|
||||||
if (buf_flush_sync_lsn < lsn &&
|
if (buf_flush_sync_lsn < lsn)
|
||||||
UNIV_LIKELY(srv_flush_sync) && UNIV_LIKELY(buf_page_cleaner_is_active))
|
|
||||||
{
|
{
|
||||||
mysql_mutex_lock(&buf_pool.flush_list_mutex);
|
mysql_mutex_lock(&buf_pool.flush_list_mutex);
|
||||||
if (buf_flush_sync_lsn < lsn)
|
if (buf_flush_sync_lsn < lsn)
|
||||||
@ -2054,13 +2056,15 @@ static os_thread_ret_t DECLARE_THREAD(buf_flush_page_cleaner)(void*)
|
|||||||
if (UNIV_UNLIKELY(lsn_limit != 0))
|
if (UNIV_UNLIKELY(lsn_limit != 0))
|
||||||
{
|
{
|
||||||
furious_flush:
|
furious_flush:
|
||||||
|
if (UNIV_LIKELY(srv_flush_sync))
|
||||||
|
{
|
||||||
buf_flush_sync_for_checkpoint(lsn_limit);
|
buf_flush_sync_for_checkpoint(lsn_limit);
|
||||||
last_pages= 0;
|
last_pages= 0;
|
||||||
set_timespec(abstime, 1);
|
set_timespec(abstime, 1);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
if (srv_shutdown_state > SRV_SHUTDOWN_INITIATED)
|
else if (srv_shutdown_state > SRV_SHUTDOWN_INITIATED)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
mysql_cond_timedwait(&buf_pool.do_flush_list, &buf_pool.flush_list_mutex,
|
mysql_cond_timedwait(&buf_pool.do_flush_list, &buf_pool.flush_list_mutex,
|
||||||
@ -2070,15 +2074,25 @@ furious_flush:
|
|||||||
lsn_limit= buf_flush_sync_lsn;
|
lsn_limit= buf_flush_sync_lsn;
|
||||||
|
|
||||||
if (UNIV_UNLIKELY(lsn_limit != 0))
|
if (UNIV_UNLIKELY(lsn_limit != 0))
|
||||||
|
{
|
||||||
|
if (UNIV_LIKELY(srv_flush_sync))
|
||||||
goto furious_flush;
|
goto furious_flush;
|
||||||
|
}
|
||||||
if (srv_shutdown_state > SRV_SHUTDOWN_INITIATED)
|
else if (srv_shutdown_state > SRV_SHUTDOWN_INITIATED)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
const ulint dirty_blocks= UT_LIST_GET_LEN(buf_pool.flush_list);
|
const ulint dirty_blocks= UT_LIST_GET_LEN(buf_pool.flush_list);
|
||||||
|
|
||||||
if (!dirty_blocks)
|
if (!dirty_blocks)
|
||||||
|
{
|
||||||
|
if (UNIV_UNLIKELY(lsn_limit != 0))
|
||||||
|
{
|
||||||
|
buf_flush_sync_lsn= 0;
|
||||||
|
/* wake up buf_flush_wait_flushed() */
|
||||||
|
mysql_cond_broadcast(&buf_pool.done_flush_list);
|
||||||
|
}
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
/* We perform dirty reads of the LRU+free list lengths here.
|
/* We perform dirty reads of the LRU+free list lengths here.
|
||||||
Division by zero is not possible, because buf_pool.flush_list is
|
Division by zero is not possible, because buf_pool.flush_list is
|
||||||
@ -2086,19 +2100,29 @@ furious_flush:
|
|||||||
const double dirty_pct= double(dirty_blocks) * 100.0 /
|
const double dirty_pct= double(dirty_blocks) * 100.0 /
|
||||||
double(UT_LIST_GET_LEN(buf_pool.LRU) + UT_LIST_GET_LEN(buf_pool.free));
|
double(UT_LIST_GET_LEN(buf_pool.LRU) + UT_LIST_GET_LEN(buf_pool.free));
|
||||||
|
|
||||||
if (dirty_pct < srv_max_dirty_pages_pct_lwm)
|
if (dirty_pct < srv_max_dirty_pages_pct_lwm && !lsn_limit)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
const lsn_t oldest_lsn= buf_pool.get_oldest_modification(0);
|
const lsn_t oldest_lsn= buf_pool.get_oldest_modification(0);
|
||||||
|
|
||||||
|
if (UNIV_UNLIKELY(lsn_limit != 0) && oldest_lsn >= lsn_limit)
|
||||||
|
buf_flush_sync_lsn= 0;
|
||||||
|
|
||||||
mysql_mutex_unlock(&buf_pool.flush_list_mutex);
|
mysql_mutex_unlock(&buf_pool.flush_list_mutex);
|
||||||
|
|
||||||
ulint n_flushed;
|
ulint n_flushed;
|
||||||
|
|
||||||
if (!srv_adaptive_flushing)
|
if (UNIV_UNLIKELY(lsn_limit != 0))
|
||||||
|
{
|
||||||
|
n_flushed= buf_flush_lists(srv_max_io_capacity, lsn_limit);
|
||||||
|
/* wake up buf_flush_wait_flushed() */
|
||||||
|
mysql_cond_broadcast(&buf_pool.done_flush_list);
|
||||||
|
goto try_checkpoint;
|
||||||
|
}
|
||||||
|
else if (!srv_adaptive_flushing)
|
||||||
{
|
{
|
||||||
n_flushed= buf_flush_lists(srv_io_capacity, LSN_MAX);
|
n_flushed= buf_flush_lists(srv_io_capacity, LSN_MAX);
|
||||||
|
try_checkpoint:
|
||||||
if (n_flushed)
|
if (n_flushed)
|
||||||
{
|
{
|
||||||
MONITOR_INC_VALUE_CUMULATIVE(MONITOR_FLUSH_BACKGROUND_TOTAL_PAGE,
|
MONITOR_INC_VALUE_CUMULATIVE(MONITOR_FLUSH_BACKGROUND_TOTAL_PAGE,
|
||||||
|
@ -18322,24 +18322,6 @@ static struct st_mysql_storage_engine innobase_storage_engine=
|
|||||||
{ MYSQL_HANDLERTON_INTERFACE_VERSION };
|
{ MYSQL_HANDLERTON_INTERFACE_VERSION };
|
||||||
|
|
||||||
#ifdef WITH_WSREP
|
#ifdef WITH_WSREP
|
||||||
void
|
|
||||||
wsrep_abort_slave_trx(
|
|
||||||
/*==================*/
|
|
||||||
wsrep_seqno_t bf_seqno,
|
|
||||||
wsrep_seqno_t victim_seqno)
|
|
||||||
{
|
|
||||||
WSREP_ERROR("Trx %lld tries to abort slave trx %lld. This could be "
|
|
||||||
"caused by:\n\t"
|
|
||||||
"1) unsupported configuration options combination, please check documentation.\n\t"
|
|
||||||
"2) a bug in the code.\n\t"
|
|
||||||
"3) a database corruption.\n Node consistency compromized, "
|
|
||||||
"need to abort. Restart the node to resync with cluster.",
|
|
||||||
(long long)bf_seqno, (long long)victim_seqno);
|
|
||||||
abort();
|
|
||||||
}
|
|
||||||
|
|
||||||
/*******************************************************************//**
|
|
||||||
This function is used to kill one transaction in BF. */
|
|
||||||
|
|
||||||
/** This function is used to kill one transaction.
|
/** This function is used to kill one transaction.
|
||||||
|
|
||||||
@ -18364,10 +18346,7 @@ comparison as in the local certification failure.
|
|||||||
@param[in] bf_thd Brute force (BF) thread
|
@param[in] bf_thd Brute force (BF) thread
|
||||||
@param[in,out] victim_trx Vimtim trx to be killed
|
@param[in,out] victim_trx Vimtim trx to be killed
|
||||||
@param[in] signal Should victim be signaled */
|
@param[in] signal Should victim be signaled */
|
||||||
UNIV_INTERN
|
int wsrep_innobase_kill_one_trx(THD *bf_thd, trx_t *victim_trx, bool signal)
|
||||||
int
|
|
||||||
wsrep_innobase_kill_one_trx(THD* bf_thd, trx_t *victim_trx,
|
|
||||||
bool signal)
|
|
||||||
{
|
{
|
||||||
ut_ad(bf_thd);
|
ut_ad(bf_thd);
|
||||||
ut_ad(victim_trx);
|
ut_ad(victim_trx);
|
||||||
@ -18376,7 +18355,7 @@ wsrep_innobase_kill_one_trx(THD* bf_thd, trx_t *victim_trx,
|
|||||||
|
|
||||||
DBUG_ENTER("wsrep_innobase_kill_one_trx");
|
DBUG_ENTER("wsrep_innobase_kill_one_trx");
|
||||||
|
|
||||||
THD *thd= (THD *) victim_trx->mysql_thd;
|
THD *thd= victim_trx->mysql_thd;
|
||||||
ut_ad(thd);
|
ut_ad(thd);
|
||||||
/* Note that bf_trx might not exist here e.g. on MDL conflict
|
/* Note that bf_trx might not exist here e.g. on MDL conflict
|
||||||
case (test: galera_concurrent_ctas). Similarly, BF thread
|
case (test: galera_concurrent_ctas). Similarly, BF thread
|
||||||
|
@ -6786,6 +6786,7 @@ i_s_tablespaces_encryption_fill_table(
|
|||||||
DBUG_RETURN(0);
|
DBUG_RETURN(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int err = 0;
|
||||||
mutex_enter(&fil_system.mutex);
|
mutex_enter(&fil_system.mutex);
|
||||||
fil_system.freeze_space_list++;
|
fil_system.freeze_space_list++;
|
||||||
|
|
||||||
@ -6795,19 +6796,19 @@ i_s_tablespaces_encryption_fill_table(
|
|||||||
&& !space->is_stopping()) {
|
&& !space->is_stopping()) {
|
||||||
space->reacquire();
|
space->reacquire();
|
||||||
mutex_exit(&fil_system.mutex);
|
mutex_exit(&fil_system.mutex);
|
||||||
if (int err = i_s_dict_fill_tablespaces_encryption(
|
err = i_s_dict_fill_tablespaces_encryption(
|
||||||
thd, space, tables->table)) {
|
thd, space, tables->table);
|
||||||
space->release();
|
|
||||||
DBUG_RETURN(err);
|
|
||||||
}
|
|
||||||
mutex_enter(&fil_system.mutex);
|
mutex_enter(&fil_system.mutex);
|
||||||
space->release();
|
space->release();
|
||||||
|
if (err) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fil_system.freeze_space_list--;
|
fil_system.freeze_space_list--;
|
||||||
mutex_exit(&fil_system.mutex);
|
mutex_exit(&fil_system.mutex);
|
||||||
DBUG_RETURN(0);
|
DBUG_RETURN(err);
|
||||||
}
|
}
|
||||||
/*******************************************************************//**
|
/*******************************************************************//**
|
||||||
Bind the dynamic table INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION
|
Bind the dynamic table INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION
|
||||||
|
@ -217,9 +217,7 @@ innobase_casedn_str(
|
|||||||
char* a); /*!< in/out: string to put in lower case */
|
char* a); /*!< in/out: string to put in lower case */
|
||||||
|
|
||||||
#ifdef WITH_WSREP
|
#ifdef WITH_WSREP
|
||||||
int
|
int wsrep_innobase_kill_one_trx(THD *bf_thd, trx_t *victim_trx, bool signal);
|
||||||
wsrep_innobase_kill_one_trx(THD *bf_thd, trx_t *victim_trx,
|
|
||||||
bool signal);
|
|
||||||
ulint wsrep_innobase_mysql_sort(int mysql_type, uint charset_number,
|
ulint wsrep_innobase_mysql_sort(int mysql_type, uint charset_number,
|
||||||
unsigned char* str, ulint str_length,
|
unsigned char* str, ulint str_length,
|
||||||
unsigned int buf_length);
|
unsigned int buf_length);
|
||||||
|
@ -37,7 +37,7 @@ Created 12/9/1995 Heikki Tuuri
|
|||||||
#include "log0types.h"
|
#include "log0types.h"
|
||||||
#include "os0file.h"
|
#include "os0file.h"
|
||||||
#include "span.h"
|
#include "span.h"
|
||||||
#include <atomic>
|
#include "my_atomic_wrapper.h"
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
@ -615,8 +615,8 @@ public:
|
|||||||
new query step is started */
|
new query step is started */
|
||||||
ib_uint64_t next_checkpoint_no;
|
ib_uint64_t next_checkpoint_no;
|
||||||
/*!< next checkpoint number */
|
/*!< next checkpoint number */
|
||||||
lsn_t last_checkpoint_lsn;
|
/** latest completed checkpoint (protected by log_sys.mutex) */
|
||||||
/*!< latest checkpoint lsn */
|
Atomic_relaxed<lsn_t> last_checkpoint_lsn;
|
||||||
lsn_t next_checkpoint_lsn;
|
lsn_t next_checkpoint_lsn;
|
||||||
/*!< next checkpoint lsn */
|
/*!< next checkpoint lsn */
|
||||||
ulint n_pending_checkpoint_writes;
|
ulint n_pending_checkpoint_writes;
|
||||||
|
@ -4753,7 +4753,7 @@ lock_validate()
|
|||||||
|
|
||||||
lock_mutex_exit();
|
lock_mutex_exit();
|
||||||
|
|
||||||
for (const page_id_t page_id : pages) {
|
for (page_id_t page_id : pages) {
|
||||||
lock_rec_block_validate(page_id);
|
lock_rec_block_validate(page_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -918,7 +918,7 @@ ATTRIBUTE_COLD void log_write_checkpoint_info(lsn_t end_lsn)
|
|||||||
|
|
||||||
DBUG_PRINT("ib_log", ("checkpoint ended at " LSN_PF
|
DBUG_PRINT("ib_log", ("checkpoint ended at " LSN_PF
|
||||||
", flushed to " LSN_PF,
|
", flushed to " LSN_PF,
|
||||||
log_sys.last_checkpoint_lsn,
|
lsn_t{log_sys.last_checkpoint_lsn},
|
||||||
log_sys.get_flushed_lsn()));
|
log_sys.get_flushed_lsn()));
|
||||||
|
|
||||||
MONITOR_INC(MONITOR_NUM_CHECKPOINT);
|
MONITOR_INC(MONITOR_NUM_CHECKPOINT);
|
||||||
@ -1233,7 +1233,7 @@ log_print(
|
|||||||
lsn,
|
lsn,
|
||||||
log_sys.get_flushed_lsn(),
|
log_sys.get_flushed_lsn(),
|
||||||
pages_flushed,
|
pages_flushed,
|
||||||
log_sys.last_checkpoint_lsn);
|
lsn_t{log_sys.last_checkpoint_lsn});
|
||||||
|
|
||||||
current_time = time(NULL);
|
current_time = time(NULL);
|
||||||
|
|
||||||
|
@ -96,13 +96,22 @@ struct log_phys_t : public log_rec_t
|
|||||||
/** start LSN of the mini-transaction (not necessarily of this record) */
|
/** start LSN of the mini-transaction (not necessarily of this record) */
|
||||||
const lsn_t start_lsn;
|
const lsn_t start_lsn;
|
||||||
private:
|
private:
|
||||||
/** length of the record, in bytes */
|
/** @return the start of length and data */
|
||||||
uint16_t len;
|
const byte *start() const
|
||||||
|
{
|
||||||
|
return my_assume_aligned<sizeof(size_t)>
|
||||||
|
(reinterpret_cast<const byte*>(&start_lsn + 1));
|
||||||
|
}
|
||||||
|
/** @return the start of length and data */
|
||||||
|
byte *start()
|
||||||
|
{ return const_cast<byte*>(const_cast<const log_phys_t*>(this)->start()); }
|
||||||
|
/** @return the length of the following record */
|
||||||
|
uint16_t len() const { uint16_t i; memcpy(&i, start(), 2); return i; }
|
||||||
|
|
||||||
/** @return start of the log records */
|
/** @return start of the log records */
|
||||||
byte *begin() { return reinterpret_cast<byte*>(&len + 1); }
|
byte *begin() { return start() + 2; }
|
||||||
/** @return end of the log records */
|
/** @return end of the log records */
|
||||||
byte *end() { byte *e= begin() + len; ut_ad(!*e); return e; }
|
byte *end() { byte *e= begin() + len(); ut_ad(!*e); return e; }
|
||||||
public:
|
public:
|
||||||
/** @return start of the log records */
|
/** @return start of the log records */
|
||||||
const byte *begin() const { return const_cast<log_phys_t*>(this)->begin(); }
|
const byte *begin() const { return const_cast<log_phys_t*>(this)->begin(); }
|
||||||
@ -112,11 +121,7 @@ public:
|
|||||||
/** Determine the allocated size of the object.
|
/** Determine the allocated size of the object.
|
||||||
@param len length of recs, excluding terminating NUL byte
|
@param len length of recs, excluding terminating NUL byte
|
||||||
@return the total allocation size */
|
@return the total allocation size */
|
||||||
static size_t alloc_size(size_t len)
|
static inline size_t alloc_size(size_t len);
|
||||||
{
|
|
||||||
return len + 1 +
|
|
||||||
reinterpret_cast<size_t>(reinterpret_cast<log_phys_t*>(0)->begin());
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Constructor.
|
/** Constructor.
|
||||||
@param start_lsn start LSN of the mini-transaction
|
@param start_lsn start LSN of the mini-transaction
|
||||||
@ -124,11 +129,13 @@ public:
|
|||||||
@param recs the first log record for the page in the mini-transaction
|
@param recs the first log record for the page in the mini-transaction
|
||||||
@param size length of recs, in bytes, excluding terminating NUL byte */
|
@param size length of recs, in bytes, excluding terminating NUL byte */
|
||||||
log_phys_t(lsn_t start_lsn, lsn_t lsn, const byte *recs, size_t size) :
|
log_phys_t(lsn_t start_lsn, lsn_t lsn, const byte *recs, size_t size) :
|
||||||
log_rec_t(lsn), start_lsn(start_lsn), len(static_cast<uint16_t>(size))
|
log_rec_t(lsn), start_lsn(start_lsn)
|
||||||
{
|
{
|
||||||
ut_ad(start_lsn);
|
ut_ad(start_lsn);
|
||||||
ut_ad(start_lsn < lsn);
|
ut_ad(start_lsn < lsn);
|
||||||
|
const uint16_t len= static_cast<uint16_t>(size);
|
||||||
ut_ad(len == size);
|
ut_ad(len == size);
|
||||||
|
memcpy(start(), &len, 2);
|
||||||
reinterpret_cast<byte*>(memcpy(begin(), recs, size))[size]= 0;
|
reinterpret_cast<byte*>(memcpy(begin(), recs, size))[size]= 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -138,8 +145,10 @@ public:
|
|||||||
void append(const byte *recs, size_t size)
|
void append(const byte *recs, size_t size)
|
||||||
{
|
{
|
||||||
ut_ad(start_lsn < lsn);
|
ut_ad(start_lsn < lsn);
|
||||||
|
uint16_t l= len();
|
||||||
reinterpret_cast<byte*>(memcpy(end(), recs, size))[size]= 0;
|
reinterpret_cast<byte*>(memcpy(end(), recs, size))[size]= 0;
|
||||||
len= static_cast<uint16_t>(len + size);
|
l= static_cast<uint16_t>(l + size);
|
||||||
|
memcpy(start(), &l, 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Apply an UNDO_APPEND record.
|
/** Apply an UNDO_APPEND record.
|
||||||
@ -514,6 +523,12 @@ page_corrupted:
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
inline size_t log_phys_t::alloc_size(size_t len)
|
||||||
|
{
|
||||||
|
return len + (1 + 2 + sizeof(log_phys_t));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/** Tablespace item during recovery */
|
/** Tablespace item during recovery */
|
||||||
struct file_name_t {
|
struct file_name_t {
|
||||||
/** Tablespace file name (FILE_MODIFY) */
|
/** Tablespace file name (FILE_MODIFY) */
|
||||||
|
@ -53,15 +53,18 @@ const dtuple_t trx_undo_metadata = {
|
|||||||
/*=========== UNDO LOG RECORD CREATION AND DECODING ====================*/
|
/*=========== UNDO LOG RECORD CREATION AND DECODING ====================*/
|
||||||
|
|
||||||
/** Calculate the free space left for extending an undo log record.
|
/** Calculate the free space left for extending an undo log record.
|
||||||
@param[in] undo_block undo log page
|
@param undo_block undo log page
|
||||||
@param[in] ptr current end of the undo page
|
@param ptr current end of the undo page
|
||||||
@return bytes left */
|
@return bytes left */
|
||||||
static ulint trx_undo_left(const buf_block_t *undo_block, const byte *ptr)
|
static ulint trx_undo_left(const buf_block_t *undo_block, const byte *ptr)
|
||||||
{
|
{
|
||||||
/* The 10 is a safety margin, in case we have some small
|
ut_ad(ptr >= &undo_block->frame[TRX_UNDO_PAGE_HDR + TRX_UNDO_PAGE_HDR_SIZE]);
|
||||||
calculation error below */
|
ut_ad(ptr <= &undo_block->frame[srv_page_size - 10 - FIL_PAGE_DATA_END]);
|
||||||
return srv_page_size - ulint(ptr - undo_block->frame)
|
|
||||||
- (10 + FIL_PAGE_DATA_END);
|
/* The 10 is supposed to be an extra safety margin (and needed for
|
||||||
|
compatibility with older versions) */
|
||||||
|
return srv_page_size - ulint(ptr - undo_block->frame) -
|
||||||
|
(10 + FIL_PAGE_DATA_END);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**********************************************************************//**
|
/**********************************************************************//**
|
||||||
@ -133,17 +136,15 @@ trx_undo_log_v_idx(
|
|||||||
|
|
||||||
ut_ad(!vcol->v_indexes.empty());
|
ut_ad(!vcol->v_indexes.empty());
|
||||||
|
|
||||||
/* Size to reserve, max 5 bytes for each index id and position, plus
|
ulint size = first_v_col ? 1 + 2 : 2;
|
||||||
5 bytes for num of indexes, 2 bytes for write total length.
|
|
||||||
1 byte for undo log record format version marker */
|
|
||||||
ulint size = 5 + 2 + (first_v_col ? 1 : 0);
|
|
||||||
const ulint avail = trx_undo_left(undo_block, ptr);
|
const ulint avail = trx_undo_left(undo_block, ptr);
|
||||||
|
|
||||||
if (avail < size) {
|
/* The mach_write_compressed(ptr, flen) in
|
||||||
|
trx_undo_page_report_modify() will consume additional 1 to 5 bytes. */
|
||||||
|
if (avail < size + 5) {
|
||||||
return(NULL);
|
return(NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
size = 0;
|
|
||||||
ulint n_idx = 0;
|
ulint n_idx = 0;
|
||||||
for (const auto& v_index : vcol->v_indexes) {
|
for (const auto& v_index : vcol->v_indexes) {
|
||||||
n_idx++;
|
n_idx++;
|
||||||
@ -151,12 +152,14 @@ trx_undo_log_v_idx(
|
|||||||
size += mach_get_compressed_size(uint32_t(v_index.index->id));
|
size += mach_get_compressed_size(uint32_t(v_index.index->id));
|
||||||
size += mach_get_compressed_size(v_index.nth_field);
|
size += mach_get_compressed_size(v_index.nth_field);
|
||||||
}
|
}
|
||||||
size += 2 + mach_get_compressed_size(n_idx);
|
|
||||||
|
|
||||||
if (avail < size) {
|
size += mach_get_compressed_size(n_idx);
|
||||||
|
|
||||||
|
if (avail < size + 5) {
|
||||||
return(NULL);
|
return(NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ut_d(const byte* orig_ptr = ptr);
|
||||||
|
|
||||||
if (first_v_col) {
|
if (first_v_col) {
|
||||||
/* write the version marker */
|
/* write the version marker */
|
||||||
@ -179,6 +182,8 @@ trx_undo_log_v_idx(
|
|||||||
ptr += mach_write_compressed(ptr, v_index.nth_field);
|
ptr += mach_write_compressed(ptr, v_index.nth_field);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ut_ad(orig_ptr + size == ptr);
|
||||||
|
|
||||||
mach_write_to_2(old_ptr, ulint(ptr - old_ptr));
|
mach_write_to_2(old_ptr, ulint(ptr - old_ptr));
|
||||||
|
|
||||||
return(ptr);
|
return(ptr);
|
||||||
@ -394,9 +399,6 @@ trx_undo_page_report_insert(
|
|||||||
+ undo_block->frame));
|
+ undo_block->frame));
|
||||||
byte* ptr = undo_block->frame + first_free;
|
byte* ptr = undo_block->frame + first_free;
|
||||||
|
|
||||||
ut_ad(first_free >= TRX_UNDO_PAGE_HDR + TRX_UNDO_PAGE_HDR_SIZE);
|
|
||||||
ut_ad(first_free <= srv_page_size - FIL_PAGE_DATA_END);
|
|
||||||
|
|
||||||
if (trx_undo_left(undo_block, ptr) < 2 + 1 + 11 + 11) {
|
if (trx_undo_left(undo_block, ptr) < 2 + 1 + 11 + 11) {
|
||||||
/* Not enough space for writing the general parameters */
|
/* Not enough space for writing the general parameters */
|
||||||
return(0);
|
return(0);
|
||||||
@ -803,9 +805,6 @@ trx_undo_page_report_modify(
|
|||||||
const uint16_t first_free = mach_read_from_2(ptr_to_first_free);
|
const uint16_t first_free = mach_read_from_2(ptr_to_first_free);
|
||||||
byte *ptr = undo_block->frame + first_free;
|
byte *ptr = undo_block->frame + first_free;
|
||||||
|
|
||||||
ut_ad(first_free >= TRX_UNDO_PAGE_HDR + TRX_UNDO_PAGE_HDR_SIZE);
|
|
||||||
ut_ad(first_free <= srv_page_size - FIL_PAGE_DATA_END);
|
|
||||||
|
|
||||||
if (trx_undo_left(undo_block, ptr) < 50) {
|
if (trx_undo_left(undo_block, ptr) < 50) {
|
||||||
/* NOTE: the value 50 must be big enough so that the general
|
/* NOTE: the value 50 must be big enough so that the general
|
||||||
fields written below fit on the undo log page */
|
fields written below fit on the undo log page */
|
||||||
|
@ -21076,8 +21076,11 @@ static void test_mdev19838()
|
|||||||
" VALUES "
|
" VALUES "
|
||||||
"(0x1111111111111111)", -1);
|
"(0x1111111111111111)", -1);
|
||||||
|
|
||||||
/* Expecting an error if parameters are sent */
|
/*
|
||||||
DIE_UNLESS(rc != 0 || paramCount == 0);
|
We allow junk at the end of the packet in case of
|
||||||
|
no parameters. So it will succeed.
|
||||||
|
*/
|
||||||
|
DIE_UNLESS(rc == 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
mysql_stmt_close(stmt);
|
mysql_stmt_close(stmt);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user