mirror of
https://github.com/MariaDB/server.git
synced 2025-01-16 03:52:35 +01:00
Merge 11.1 into 11.2
This commit is contained in:
commit
e4cb1e3295
30 changed files with 358 additions and 408 deletions
|
@ -610,49 +610,4 @@ c1 c2 c3
|
|||
2 1 4
|
||||
2 2 5
|
||||
drop table t1;
|
||||
#
|
||||
# MDEV-32212 DELETE with ORDER BY and semijoin optimization causing crash
|
||||
#
|
||||
CREATE TABLE t1 (c1 INT) ENGINE=InnoDB;
|
||||
CREATE TABLE t2 (c2 INT) ENGINE=InnoDB;
|
||||
INSERT INTO t1 values (1),(2),(3),(4),(5),(6);
|
||||
INSERT INTO t2 values (2);
|
||||
DELETE FROM t1 WHERE c1 IN (select c2 from t2);
|
||||
select * from t1;
|
||||
c1
|
||||
1
|
||||
3
|
||||
4
|
||||
5
|
||||
6
|
||||
truncate t1;
|
||||
truncate t2;
|
||||
INSERT INTO t1 values (1),(2),(3),(4),(5),(6);
|
||||
INSERT INTO t2 values (2);
|
||||
check sj optimization with order-by
|
||||
analyze DELETE FROM t1 WHERE c1 IN (select c2 from t2) ORDER BY c1;
|
||||
id select_type table type possible_keys key key_len ref rows r_rows filtered r_filtered Extra
|
||||
1 PRIMARY t1 ALL NULL NULL NULL NULL 6 6.00 100.00 100.00 Using filesort
|
||||
1 PRIMARY t2 ALL NULL NULL NULL NULL 1 1.00 100.00 16.67 Using where; FirstMatch(t1)
|
||||
select * from t1;
|
||||
c1
|
||||
1
|
||||
3
|
||||
4
|
||||
5
|
||||
6
|
||||
truncate t2;
|
||||
INSERT INTO t2 values (3);
|
||||
disallows sj optimization
|
||||
analyze DELETE FROM t1 WHERE c1 IN (select c2 from t2) ORDER BY c1 limit 1;
|
||||
id select_type table type possible_keys key key_len ref rows r_rows filtered r_filtered Extra
|
||||
1 PRIMARY t1 ALL NULL NULL NULL NULL 5 1.00 100.00 100.00 Using where; Using filesort
|
||||
2 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 1 1.00 100.00 20.00 Using where
|
||||
select * from t1;
|
||||
c1
|
||||
1
|
||||
4
|
||||
5
|
||||
6
|
||||
DROP TABLE t1, t2;
|
||||
End of 11.1 tests
|
||||
|
|
|
@ -667,31 +667,4 @@ select *from t1;
|
|||
|
||||
drop table t1;
|
||||
|
||||
--echo #
|
||||
--echo # MDEV-32212 DELETE with ORDER BY and semijoin optimization causing crash
|
||||
--echo #
|
||||
--source include/have_innodb.inc
|
||||
|
||||
CREATE TABLE t1 (c1 INT) ENGINE=InnoDB;
|
||||
CREATE TABLE t2 (c2 INT) ENGINE=InnoDB;
|
||||
INSERT INTO t1 values (1),(2),(3),(4),(5),(6);
|
||||
INSERT INTO t2 values (2);
|
||||
|
||||
DELETE FROM t1 WHERE c1 IN (select c2 from t2);
|
||||
select * from t1;
|
||||
truncate t1;
|
||||
truncate t2;
|
||||
INSERT INTO t1 values (1),(2),(3),(4),(5),(6);
|
||||
INSERT INTO t2 values (2);
|
||||
--echo check sj optimization with order-by
|
||||
analyze DELETE FROM t1 WHERE c1 IN (select c2 from t2) ORDER BY c1;
|
||||
select * from t1;
|
||||
truncate t2;
|
||||
INSERT INTO t2 values (3);
|
||||
--echo disallows sj optimization
|
||||
analyze DELETE FROM t1 WHERE c1 IN (select c2 from t2) ORDER BY c1 limit 1;
|
||||
select * from t1;
|
||||
|
||||
DROP TABLE t1, t2;
|
||||
|
||||
--echo End of 11.1 tests
|
||||
|
|
|
@ -24,3 +24,49 @@ SELECT * FROM t1;
|
|||
c1
|
||||
SET sort_buffer_size=@save_sort_buffer_size;
|
||||
DROP TABLE t1;
|
||||
#
|
||||
# MDEV-32212 DELETE with ORDER BY and semijoin optimization causing crash
|
||||
#
|
||||
CREATE TABLE t1 (c1 INT) ENGINE=InnoDB;
|
||||
CREATE TABLE t2 (c2 INT) ENGINE=InnoDB;
|
||||
INSERT INTO t1 values (1),(2),(3),(4),(5),(6);
|
||||
INSERT INTO t2 values (2);
|
||||
DELETE FROM t1 WHERE c1 IN (select c2 from t2);
|
||||
select * from t1;
|
||||
c1
|
||||
1
|
||||
3
|
||||
4
|
||||
5
|
||||
6
|
||||
truncate t1;
|
||||
truncate t2;
|
||||
INSERT INTO t1 values (1),(2),(3),(4),(5),(6);
|
||||
INSERT INTO t2 values (2);
|
||||
check sj optimization with order-by
|
||||
analyze DELETE FROM t1 WHERE c1 IN (select c2 from t2) ORDER BY c1;
|
||||
id select_type table type possible_keys key key_len ref rows r_rows filtered r_filtered Extra
|
||||
1 PRIMARY t1 ALL NULL NULL NULL NULL 6 6.00 100.00 100.00 Using filesort
|
||||
1 PRIMARY t2 ALL NULL NULL NULL NULL 1 1.00 100.00 16.67 Using where; FirstMatch(t1)
|
||||
select * from t1;
|
||||
c1
|
||||
1
|
||||
3
|
||||
4
|
||||
5
|
||||
6
|
||||
truncate t2;
|
||||
INSERT INTO t2 values (3);
|
||||
disallows sj optimization
|
||||
analyze DELETE FROM t1 WHERE c1 IN (select c2 from t2) ORDER BY c1 limit 1;
|
||||
id select_type table type possible_keys key key_len ref rows r_rows filtered r_filtered Extra
|
||||
1 PRIMARY t1 ALL NULL NULL NULL NULL 5 1.00 100.00 100.00 Using where; Using filesort
|
||||
2 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 1 1.00 100.00 20.00 Using where
|
||||
select * from t1;
|
||||
c1
|
||||
1
|
||||
4
|
||||
5
|
||||
6
|
||||
DROP TABLE t1, t2;
|
||||
End of 11.1 tests
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
--source include/have_innodb.inc
|
||||
--source include/have_sequence.inc
|
||||
|
||||
--source include/innodb_stable_estimates.inc
|
||||
|
||||
--echo # Tests for delete with INNODB
|
||||
|
||||
--echo #
|
||||
|
@ -20,3 +22,31 @@ SELECT * FROM t1;
|
|||
|
||||
SET sort_buffer_size=@save_sort_buffer_size;
|
||||
DROP TABLE t1;
|
||||
|
||||
--echo #
|
||||
--echo # MDEV-32212 DELETE with ORDER BY and semijoin optimization causing crash
|
||||
--echo #
|
||||
--source include/have_innodb.inc
|
||||
|
||||
CREATE TABLE t1 (c1 INT) ENGINE=InnoDB;
|
||||
CREATE TABLE t2 (c2 INT) ENGINE=InnoDB;
|
||||
INSERT INTO t1 values (1),(2),(3),(4),(5),(6);
|
||||
INSERT INTO t2 values (2);
|
||||
|
||||
DELETE FROM t1 WHERE c1 IN (select c2 from t2);
|
||||
select * from t1;
|
||||
truncate t1;
|
||||
truncate t2;
|
||||
INSERT INTO t1 values (1),(2),(3),(4),(5),(6);
|
||||
INSERT INTO t2 values (2);
|
||||
--echo check sj optimization with order-by
|
||||
analyze DELETE FROM t1 WHERE c1 IN (select c2 from t2) ORDER BY c1;
|
||||
select * from t1;
|
||||
truncate t2;
|
||||
INSERT INTO t2 values (3);
|
||||
--echo disallows sj optimization
|
||||
analyze DELETE FROM t1 WHERE c1 IN (select c2 from t2) ORDER BY c1 limit 1;
|
||||
select * from t1;
|
||||
|
||||
DROP TABLE t1, t2;
|
||||
--echo End of 11.1 tests
|
||||
|
|
|
@ -895,3 +895,12 @@ REGEXP_INSTR('a_kollision', 'o([lm])\\1')
|
|||
4
|
||||
SELECT a FROM (SELECT "aa" a) t WHERE a REGEXP '[0-9]';
|
||||
a
|
||||
#
|
||||
# MDEV-11777 REGEXP_REPLACE converts utf8mb4 supplementary characters to '?'
|
||||
#
|
||||
select hex(regexp_replace(cast(x'F09F9881' as char character set 'utf8mb4'), _utf8mb4'a', _utf8mb4'b')) as Text;
|
||||
Text
|
||||
F09F9881
|
||||
#
|
||||
# End of 10.6 tests
|
||||
#
|
||||
|
|
|
@ -470,3 +470,11 @@ SELECT REGEXP_INSTR('a_kollision', 'o([lm])\\1');
|
|||
#
|
||||
SELECT a FROM (SELECT "aa" a) t WHERE a REGEXP '[0-9]';
|
||||
--enable_service_connection
|
||||
|
||||
--echo #
|
||||
--echo # MDEV-11777 REGEXP_REPLACE converts utf8mb4 supplementary characters to '?'
|
||||
--echo #
|
||||
select hex(regexp_replace(cast(x'F09F9881' as char character set 'utf8mb4'), _utf8mb4'a', _utf8mb4'b')) as Text;
|
||||
--echo #
|
||||
--echo # End of 10.6 tests
|
||||
--echo #
|
||||
|
|
|
@ -61,17 +61,6 @@ set global innodb_fil_make_page_dirty_debug = 0;
|
|||
set global innodb_buf_flush_list_now = 1;
|
||||
|
||||
--let CLEANUP_IF_CHECKPOINT=drop table t1, unexpected_checkpoint;
|
||||
# Occasionally, a checkpoint would occur on the MSAN builder.
|
||||
# We do not know the reason, because the failure can only be reproduced if there is
|
||||
# enough load in that environment.
|
||||
# Therefore, we allow the test to be skipped when run on MSAN.
|
||||
# In other environments, we want the test to fail if a checkpoint occurs,
|
||||
# so that we would catch it if it starts to happen regularly.
|
||||
if (`select count(*) from information_schema.system_variables where variable_name='have_sanitizer' and global_value like "MSAN%"`)
|
||||
{
|
||||
--let CLEANUP_IF_CHECKPOINT=drop table t1;
|
||||
}
|
||||
|
||||
--source ../include/no_checkpoint_end.inc
|
||||
|
||||
--echo # Make the 1st page (page_no=0) and 2nd page (page_no=1)
|
||||
|
|
20
mysql-test/suite/perfschema/r/misc_session_status.result
Normal file
20
mysql-test/suite/perfschema/r/misc_session_status.result
Normal file
|
@ -0,0 +1,20 @@
|
|||
#
|
||||
# MDEV-33150 double-locking of LOCK_thd_kill in performance_schema.session_status
|
||||
#
|
||||
set @old_innodb_io_capacity=@@global.innodb_io_capacity;
|
||||
set @old_innodb_io_capacity_max=@@global.innodb_io_capacity_max;
|
||||
select * from performance_schema.session_status limit 0;
|
||||
VARIABLE_NAME VARIABLE_VALUE
|
||||
set max_session_mem_used=32768;
|
||||
select * from performance_schema.session_status;
|
||||
ERROR HY000: The MariaDB server is running with the --max-session-mem-used=32768 option so it cannot execute this statement
|
||||
set global innodb_io_capacity_max=100;
|
||||
Warnings:
|
||||
Warning 1210 Setting innodb_io_capacity_max 100 lower than innodb_io_capacity 200.
|
||||
Warning 1210 Setting innodb_io_capacity to 100
|
||||
set max_session_mem_used=default;
|
||||
set global innodb_io_capacity=@old_innodb_io_capacity;
|
||||
Warnings:
|
||||
Warning 1210 Setting innodb_io_capacity to 200 higher than innodb_io_capacity_max 100
|
||||
Warning 1210 Setting innodb_max_io_capacity to 400
|
||||
set global innodb_io_capacity_max=@old_innodb_io_capacity_max;
|
|
@ -52,4 +52,10 @@ select NAME, TYPE, PROCESSLIST_COMMAND, PROCESSLIST_STATE
|
|||
from performance_schema.threads
|
||||
where PROCESSLIST_ID = @slave_sql_pid;
|
||||
NAME TYPE PROCESSLIST_COMMAND PROCESSLIST_STATE
|
||||
#
|
||||
# MDEV-33031 Assertion failure upon reading from performance schema with binlog enabled
|
||||
#
|
||||
select variable_name, variable_value from performance_schema.status_by_thread
|
||||
where variable_name like '%impossible%';
|
||||
variable_name variable_value
|
||||
include/rpl_end.inc
|
||||
|
|
18
mysql-test/suite/perfschema/t/misc_session_status.test
Normal file
18
mysql-test/suite/perfschema/t/misc_session_status.test
Normal file
|
@ -0,0 +1,18 @@
|
|||
--source include/not_embedded.inc
|
||||
--source include/have_perfschema.inc
|
||||
--echo #
|
||||
--echo # MDEV-33150 double-locking of LOCK_thd_kill in performance_schema.session_status
|
||||
--echo #
|
||||
source include/have_innodb.inc;
|
||||
set @old_innodb_io_capacity=@@global.innodb_io_capacity;
|
||||
set @old_innodb_io_capacity_max=@@global.innodb_io_capacity_max;
|
||||
select * from performance_schema.session_status limit 0; # discover the table
|
||||
set max_session_mem_used=32768;
|
||||
--error ER_OPTION_PREVENTS_STATEMENT
|
||||
# this used to crash, when OOM happened under LOCK_thd_kill
|
||||
select * from performance_schema.session_status;
|
||||
# this used to cause mutex lock order violation when OOM happened under LOCK_global_system_variables
|
||||
set global innodb_io_capacity_max=100;
|
||||
set max_session_mem_used=default;
|
||||
set global innodb_io_capacity=@old_innodb_io_capacity;
|
||||
set global innodb_io_capacity_max=@old_innodb_io_capacity_max;
|
|
@ -81,5 +81,11 @@ select NAME, TYPE, PROCESSLIST_COMMAND, PROCESSLIST_STATE
|
|||
from performance_schema.threads
|
||||
where PROCESSLIST_ID = @slave_sql_pid;
|
||||
|
||||
--echo #
|
||||
--echo # MDEV-33031 Assertion failure upon reading from performance schema with binlog enabled
|
||||
--echo #
|
||||
select variable_name, variable_value from performance_schema.status_by_thread
|
||||
where variable_name like '%impossible%'; # should not crash
|
||||
|
||||
--source include/rpl_end.inc
|
||||
|
||||
|
|
|
@ -6090,7 +6090,7 @@ void Regexp_processor_pcre::init(CHARSET_INFO *data_charset, int extra_flags)
|
|||
|
||||
// Convert text data to utf-8.
|
||||
m_library_charset= data_charset == &my_charset_bin ?
|
||||
&my_charset_bin : &my_charset_utf8mb3_general_ci;
|
||||
&my_charset_bin : &my_charset_utf8mb4_general_ci;
|
||||
|
||||
m_conversion_is_needed= (data_charset != &my_charset_bin) &&
|
||||
!my_charset_same(data_charset, m_library_charset);
|
||||
|
|
|
@ -3055,7 +3055,7 @@ public:
|
|||
m_pcre(NULL), m_pcre_match_data(NULL),
|
||||
m_conversion_is_needed(true), m_is_const(0),
|
||||
m_library_flags(0),
|
||||
m_library_charset(&my_charset_utf8mb3_general_ci)
|
||||
m_library_charset(&my_charset_utf8mb4_general_ci)
|
||||
{}
|
||||
int default_regex_flags();
|
||||
void init(CHARSET_INFO *data_charset, int extra_flags);
|
||||
|
|
23
sql/log.cc
23
sql/log.cc
|
@ -11886,14 +11886,21 @@ set_binlog_snapshot_file(const char *src)
|
|||
void
|
||||
TC_LOG_BINLOG::set_status_variables(THD *thd)
|
||||
{
|
||||
binlog_cache_mngr *cache_mngr;
|
||||
bool have_snapshot= false;
|
||||
|
||||
if (thd && opt_bin_log)
|
||||
cache_mngr= thd->binlog_get_cache_mngr();
|
||||
else
|
||||
cache_mngr= 0;
|
||||
{
|
||||
mysql_mutex_lock(&thd->LOCK_thd_data);
|
||||
auto cache_mngr= thd->binlog_get_cache_mngr();
|
||||
have_snapshot= cache_mngr && cache_mngr->last_commit_pos_file[0];
|
||||
if (have_snapshot)
|
||||
{
|
||||
set_binlog_snapshot_file(cache_mngr->last_commit_pos_file);
|
||||
binlog_snapshot_position= cache_mngr->last_commit_pos_offset;
|
||||
}
|
||||
mysql_mutex_unlock(&thd->LOCK_thd_data);
|
||||
}
|
||||
|
||||
bool have_snapshot= (cache_mngr && cache_mngr->last_commit_pos_file[0] != 0);
|
||||
mysql_mutex_lock(&LOCK_commit_ordered);
|
||||
binlog_status_var_num_commits= this->num_commits;
|
||||
binlog_status_var_num_group_commits= this->num_group_commits;
|
||||
|
@ -11908,12 +11915,6 @@ TC_LOG_BINLOG::set_status_variables(THD *thd)
|
|||
binlog_status_group_commit_trigger_timeout= this->group_commit_trigger_timeout;
|
||||
binlog_status_group_commit_trigger_lock_wait= this->group_commit_trigger_lock_wait;
|
||||
mysql_mutex_unlock(&LOCK_prepare_ordered);
|
||||
|
||||
if (have_snapshot)
|
||||
{
|
||||
set_binlog_snapshot_file(cache_mngr->last_commit_pos_file);
|
||||
binlog_snapshot_position= cache_mngr->last_commit_pos_offset;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -754,16 +754,20 @@ bool buf_page_t::flush(bool evict, fil_space_t *space)
|
|||
ut_ad(space->referenced());
|
||||
|
||||
const auto s= state();
|
||||
ut_a(s >= FREED);
|
||||
|
||||
const lsn_t lsn=
|
||||
mach_read_from_8(my_assume_aligned<8>
|
||||
(FIL_PAGE_LSN + (zip.data ? zip.data : frame)));
|
||||
ut_ad(lsn
|
||||
? lsn >= oldest_modification() || oldest_modification() == 2
|
||||
: space->purpose != FIL_TYPE_TABLESPACE);
|
||||
|
||||
if (s < UNFIXED)
|
||||
{
|
||||
ut_a(s >= FREED);
|
||||
if (UNIV_LIKELY(space->purpose == FIL_TYPE_TABLESPACE))
|
||||
{
|
||||
const lsn_t lsn=
|
||||
mach_read_from_8(my_assume_aligned<8>
|
||||
(FIL_PAGE_LSN + (zip.data ? zip.data : frame)));
|
||||
ut_ad(lsn >= oldest_modification());
|
||||
freed:
|
||||
if (lsn > log_sys.get_flushed_lsn())
|
||||
{
|
||||
mysql_mutex_unlock(&buf_pool.mutex);
|
||||
|
@ -775,6 +779,12 @@ bool buf_page_t::flush(bool evict, fil_space_t *space)
|
|||
return false;
|
||||
}
|
||||
|
||||
if (UNIV_UNLIKELY(lsn < space->get_create_lsn()))
|
||||
{
|
||||
ut_ad(space->purpose == FIL_TYPE_TABLESPACE);
|
||||
goto freed;
|
||||
}
|
||||
|
||||
ut_d(const auto f=) zip.fix.fetch_add(WRITE_FIX - UNFIXED);
|
||||
ut_ad(f >= UNFIXED);
|
||||
ut_ad(f < READ_FIX);
|
||||
|
@ -869,15 +879,9 @@ bool buf_page_t::flush(bool evict, fil_space_t *space)
|
|||
|
||||
if ((s & LRU_MASK) == REINIT || !space->use_doublewrite())
|
||||
{
|
||||
if (UNIV_LIKELY(space->purpose == FIL_TYPE_TABLESPACE))
|
||||
{
|
||||
const lsn_t lsn=
|
||||
mach_read_from_8(my_assume_aligned<8>(FIL_PAGE_LSN +
|
||||
(write_frame ? write_frame
|
||||
: frame)));
|
||||
ut_ad(lsn >= oldest_modification());
|
||||
if (UNIV_LIKELY(space->purpose == FIL_TYPE_TABLESPACE) &&
|
||||
lsn > log_sys.get_flushed_lsn())
|
||||
log_write_up_to(lsn, true);
|
||||
}
|
||||
space->io(IORequest{type, this, slot}, physical_offset(), size,
|
||||
write_frame, this);
|
||||
}
|
||||
|
@ -1057,11 +1061,25 @@ static ulint buf_flush_try_neighbors(fil_space_t *space,
|
|||
bool contiguous, bool evict,
|
||||
ulint n_flushed, ulint n_to_flush)
|
||||
{
|
||||
mysql_mutex_unlock(&buf_pool.mutex);
|
||||
|
||||
ut_ad(space->id == page_id.space());
|
||||
ut_ad(bpage->id() == page_id);
|
||||
|
||||
{
|
||||
const lsn_t lsn=
|
||||
mach_read_from_8(my_assume_aligned<8>
|
||||
(FIL_PAGE_LSN +
|
||||
(bpage->zip.data ? bpage->zip.data : bpage->frame)));
|
||||
ut_ad(lsn >= bpage->oldest_modification());
|
||||
if (UNIV_UNLIKELY(lsn < space->get_create_lsn()))
|
||||
{
|
||||
ut_a(!bpage->flush(evict, space));
|
||||
mysql_mutex_unlock(&buf_pool.mutex);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
mysql_mutex_unlock(&buf_pool.mutex);
|
||||
|
||||
ulint count= 0;
|
||||
page_id_t id= page_id;
|
||||
page_id_t high= buf_flush_check_neighbors(*space, id, contiguous, evict);
|
||||
|
@ -2434,9 +2452,9 @@ static void buf_flush_page_cleaner()
|
|||
|
||||
do
|
||||
{
|
||||
DBUG_EXECUTE_IF("ib_log_checkpoint_avoid", continue;);
|
||||
DBUG_EXECUTE_IF("ib_log_checkpoint_avoid_hard", continue;);
|
||||
|
||||
IF_DBUG(if (_db_keyword_(nullptr, "ib_log_checkpoint_avoid", 1) ||
|
||||
_db_keyword_(nullptr, "ib_log_checkpoint_avoid_hard", 1))
|
||||
continue,);
|
||||
if (!recv_recovery_is_on() &&
|
||||
!srv_startup_is_before_trx_rollback_phase &&
|
||||
srv_operation <= SRV_OPERATION_EXPORT_RESTORED)
|
||||
|
|
|
@ -564,7 +564,7 @@ fil_space_extend_must_retry(
|
|||
ut_ad(UT_LIST_GET_LAST(space->chain) == node);
|
||||
ut_ad(size >= FIL_IBD_FILE_INITIAL_SIZE);
|
||||
ut_ad(node->space == space);
|
||||
ut_ad(space->referenced() || space->is_being_truncated);
|
||||
ut_ad(space->referenced());
|
||||
|
||||
*success = space->size >= size;
|
||||
|
||||
|
@ -653,8 +653,7 @@ fil_space_extend_must_retry(
|
|||
default:
|
||||
ut_ad(space->purpose == FIL_TYPE_TABLESPACE
|
||||
|| space->purpose == FIL_TYPE_IMPORT);
|
||||
if (space->purpose == FIL_TYPE_TABLESPACE
|
||||
&& !space->is_being_truncated) {
|
||||
if (space->purpose == FIL_TYPE_TABLESPACE) {
|
||||
goto do_flush;
|
||||
}
|
||||
break;
|
||||
|
@ -754,12 +753,10 @@ bool fil_space_extend(fil_space_t *space, uint32_t size)
|
|||
bool success= false;
|
||||
const bool acquired= space->acquire();
|
||||
mysql_mutex_lock(&fil_system.mutex);
|
||||
if (acquired || space->is_being_truncated)
|
||||
{
|
||||
if (acquired)
|
||||
while (fil_space_extend_must_retry(space, UT_LIST_GET_LAST(space->chain),
|
||||
size, &success))
|
||||
mysql_mutex_lock(&fil_system.mutex);
|
||||
}
|
||||
mysql_mutex_unlock(&fil_system.mutex);
|
||||
if (acquired)
|
||||
space->release();
|
||||
|
@ -3135,11 +3132,9 @@ fil_space_validate_for_mtr_commit(
|
|||
ut_ad(!is_predefined_tablespace(space->id));
|
||||
|
||||
/* We are serving mtr_commit(). While there is an active
|
||||
mini-transaction, we should have !space->stop_new_ops. This is
|
||||
mini-transaction, we should have !space->is_stopping(). This is
|
||||
guaranteed by meta-data locks or transactional locks. */
|
||||
ut_ad(!space->is_stopping()
|
||||
|| space->is_being_truncated /* fil_truncate_prepare() */
|
||||
|| space->referenced());
|
||||
ut_ad(!space->is_stopping() || space->referenced());
|
||||
}
|
||||
#endif /* UNIV_DEBUG */
|
||||
|
||||
|
|
|
@ -41,8 +41,6 @@ Created 11/29/1995 Heikki Tuuri
|
|||
#include "fsp0types.h"
|
||||
#include "log.h"
|
||||
|
||||
typedef uint32_t page_no_t;
|
||||
|
||||
/** Returns the first extent descriptor for a segment.
|
||||
We think of the extent lists of the segment catenated in the order
|
||||
FSEG_FULL -> FSEG_NOT_FULL -> FSEG_FREE.
|
||||
|
@ -331,7 +329,7 @@ xdes_t*
|
|||
xdes_get_descriptor_with_space_hdr(
|
||||
buf_block_t* header,
|
||||
const fil_space_t* space,
|
||||
page_no_t offset,
|
||||
uint32_t offset,
|
||||
mtr_t* mtr,
|
||||
dberr_t* err = nullptr,
|
||||
buf_block_t** desc_block = nullptr,
|
||||
|
@ -395,7 +393,7 @@ try to add new extents to the space free list
|
|||
@param[out] err error code
|
||||
@param[out] xdes extent descriptor page
|
||||
@return the extent descriptor */
|
||||
static xdes_t *xdes_get_descriptor(const fil_space_t *space, page_no_t offset,
|
||||
static xdes_t *xdes_get_descriptor(const fil_space_t *space, uint32_t offset,
|
||||
mtr_t *mtr, dberr_t *err= nullptr,
|
||||
buf_block_t **xdes= nullptr)
|
||||
{
|
||||
|
@ -841,8 +839,7 @@ fsp_fill_free_list(
|
|||
if (i)
|
||||
{
|
||||
buf_block_t *f= buf_LRU_get_free_block(have_no_mutex);
|
||||
buf_block_t *block= buf_page_create(space, static_cast<uint32_t>(i),
|
||||
zip_size, mtr, f);
|
||||
buf_block_t *block= buf_page_create(space, i, zip_size, mtr, f);
|
||||
if (UNIV_UNLIKELY(block != f))
|
||||
buf_pool.free_block(f);
|
||||
fsp_init_file_page(space, block, mtr);
|
||||
|
@ -854,8 +851,7 @@ fsp_fill_free_list(
|
|||
{
|
||||
buf_block_t *f= buf_LRU_get_free_block(have_no_mutex);
|
||||
buf_block_t *block=
|
||||
buf_page_create(space, static_cast<uint32_t>(i + 1),
|
||||
zip_size, mtr, f);
|
||||
buf_page_create(space, i + 1, zip_size, mtr, f);
|
||||
if (UNIV_UNLIKELY(block != f))
|
||||
buf_pool.free_block(f);
|
||||
/* The zero-initialization will reset the change buffer bitmap bits
|
||||
|
@ -1033,80 +1029,13 @@ fsp_alloc_from_free_frag(buf_block_t *header, buf_block_t *xdes, xdes_t *descr,
|
|||
@param[in] offset page number of the allocated page
|
||||
@param[in,out] mtr mini-transaction
|
||||
@return block, initialized */
|
||||
static
|
||||
buf_block_t*
|
||||
fsp_page_create(fil_space_t *space, page_no_t offset, mtr_t *mtr)
|
||||
static buf_block_t* fsp_page_create(fil_space_t *space, uint32_t offset,
|
||||
mtr_t *mtr)
|
||||
{
|
||||
buf_block_t *block;
|
||||
|
||||
if (UNIV_UNLIKELY(space->is_being_truncated))
|
||||
{
|
||||
const page_id_t page_id{space->id, offset};
|
||||
uint32_t state;
|
||||
block= mtr->get_already_latched(page_id, MTR_MEMO_PAGE_X_FIX);
|
||||
if (block)
|
||||
goto have_latch;
|
||||
else
|
||||
{
|
||||
buf_pool_t::hash_chain &chain=
|
||||
buf_pool.page_hash.cell_get(page_id.fold());
|
||||
mysql_mutex_lock(&buf_pool.mutex);
|
||||
block= reinterpret_cast<buf_block_t*>
|
||||
(buf_pool.page_hash.get(page_id, chain));
|
||||
if (!block)
|
||||
{
|
||||
mysql_mutex_unlock(&buf_pool.mutex);
|
||||
goto create;
|
||||
}
|
||||
}
|
||||
|
||||
if (!mtr->have_x_latch(*block))
|
||||
{
|
||||
const bool got{block->page.lock.x_lock_try()};
|
||||
mysql_mutex_unlock(&buf_pool.mutex);
|
||||
if (!got)
|
||||
{
|
||||
block->page.lock.x_lock();
|
||||
const page_id_t id{block->page.id()};
|
||||
if (UNIV_UNLIKELY(id != page_id))
|
||||
{
|
||||
ut_ad(id.is_corrupted());
|
||||
block->page.lock.x_unlock();
|
||||
goto create;
|
||||
}
|
||||
}
|
||||
state= block->page.fix() + 1;
|
||||
mtr->memo_push(block, MTR_MEMO_PAGE_X_FIX);
|
||||
}
|
||||
else
|
||||
{
|
||||
mysql_mutex_unlock(&buf_pool.mutex);
|
||||
have_latch:
|
||||
state= block->page.state();
|
||||
}
|
||||
|
||||
ut_ad(state > buf_page_t::FREED);
|
||||
ut_ad(state < buf_page_t::READ_FIX);
|
||||
ut_ad(block->page.lock.x_lock_count() == 1);
|
||||
ut_ad(block->page.frame);
|
||||
#ifdef BTR_CUR_HASH_ADAPT
|
||||
ut_ad(!block->index);
|
||||
#endif
|
||||
|
||||
block->page.set_reinit(state < buf_page_t::UNFIXED
|
||||
? buf_page_t::FREED
|
||||
: (state & buf_page_t::LRU_MASK));
|
||||
}
|
||||
else
|
||||
{
|
||||
create:
|
||||
buf_block_t *free_block= buf_LRU_get_free_block(have_no_mutex);
|
||||
block= buf_page_create(space, static_cast<uint32_t>(offset),
|
||||
space->zip_size(), mtr, free_block);
|
||||
if (UNIV_UNLIKELY(block != free_block))
|
||||
buf_pool.free_block(free_block);
|
||||
}
|
||||
|
||||
buf_block_t *free_block= buf_LRU_get_free_block(have_no_mutex),
|
||||
*block= buf_page_create(space, offset, space->zip_size(), mtr, free_block);
|
||||
if (UNIV_UNLIKELY(block != free_block))
|
||||
buf_pool.free_block(free_block);
|
||||
fsp_init_file_page(space, block, mtr);
|
||||
return block;
|
||||
}
|
||||
|
@ -1224,7 +1153,7 @@ MY_ATTRIBUTE((nonnull, warn_unused_result))
|
|||
@param[in] offset page number in the extent
|
||||
@param[in,out] mtr mini-transaction
|
||||
@return error code */
|
||||
static dberr_t fsp_free_extent(fil_space_t* space, page_no_t offset,
|
||||
static dberr_t fsp_free_extent(fil_space_t* space, uint32_t offset,
|
||||
mtr_t* mtr)
|
||||
{
|
||||
ut_ad(space->is_owner());
|
||||
|
@ -1261,7 +1190,7 @@ The page is marked as free and clean.
|
|||
@param[in] offset page number
|
||||
@param[in,out] mtr mini-transaction
|
||||
@return error code */
|
||||
static dberr_t fsp_free_page(fil_space_t *space, page_no_t offset, mtr_t *mtr)
|
||||
static dberr_t fsp_free_page(fil_space_t *space, uint32_t offset, mtr_t *mtr)
|
||||
{
|
||||
xdes_t* descr;
|
||||
ulint frag_n_used;
|
||||
|
@ -1801,7 +1730,6 @@ page_alloc:
|
|||
|
||||
ut_d(const auto x = block->page.lock.x_lock_count());
|
||||
ut_ad(x || block->page.lock.not_recursive());
|
||||
ut_ad(x == 1 || space->is_being_truncated);
|
||||
ut_ad(x <= 2);
|
||||
ut_ad(!fil_page_get_type(block->page.frame));
|
||||
mtr->write<1>(*block, FIL_PAGE_TYPE + 1 + block->page.frame,
|
||||
|
@ -2538,7 +2466,7 @@ fseg_free_page_low(
|
|||
fseg_inode_t* seg_inode,
|
||||
buf_block_t* iblock,
|
||||
fil_space_t* space,
|
||||
page_no_t offset,
|
||||
uint32_t offset,
|
||||
mtr_t* mtr
|
||||
#ifdef BTR_CUR_HASH_ADAPT
|
||||
,bool ahi=false
|
||||
|
@ -2904,7 +2832,7 @@ fseg_free_step(
|
|||
return true;
|
||||
}
|
||||
|
||||
page_no_t page_no = fseg_get_nth_frag_page_no(inode, n);
|
||||
uint32_t page_no = fseg_get_nth_frag_page_no(inode, n);
|
||||
|
||||
if (fseg_free_page_low(inode, iblock, space, page_no, mtr
|
||||
#ifdef BTR_CUR_HASH_ADAPT
|
||||
|
@ -3699,28 +3627,13 @@ mtr_max:
|
|||
return;
|
||||
}
|
||||
}
|
||||
mysql_mutex_lock(&fil_system.mutex);
|
||||
|
||||
space->size= last_used_extent;
|
||||
if (space->free_limit > last_used_extent)
|
||||
space->free_limit= space->size;
|
||||
space->free_limit= last_used_extent;
|
||||
space->free_len= flst_get_len(FSP_HEADER_OFFSET + FSP_FREE +
|
||||
header->page.frame);
|
||||
|
||||
space->free_len= flst_get_len(
|
||||
FSP_HEADER_OFFSET + FSP_FREE+ header->page.frame);
|
||||
|
||||
/* Last file new size after truncation */
|
||||
uint32_t new_last_file_size=
|
||||
last_used_extent -
|
||||
(fixed_size - srv_sys_space.m_files.at(
|
||||
srv_sys_space.m_files.size() - 1).param_size());
|
||||
|
||||
space->size_in_header= space->size;
|
||||
space->is_being_truncated= true;
|
||||
space->set_stopping();
|
||||
space->chain.end->size= new_last_file_size;
|
||||
srv_sys_space.set_last_file_size(new_last_file_size);
|
||||
mysql_mutex_unlock(&fil_system.mutex);
|
||||
mtr.commit_shrink(*space);
|
||||
mtr.commit_shrink(*space, last_used_extent);
|
||||
sql_print_information("InnoDB: System tablespace truncated successfully");
|
||||
srv_use_doublewrite_buf= old_dblwr_buf;
|
||||
}
|
||||
|
|
|
@ -18184,7 +18184,10 @@ buf_flush_list_now_set(THD*, st_mysql_sys_var*, void*, const void* save)
|
|||
if (s)
|
||||
buf_flush_sync();
|
||||
else
|
||||
{
|
||||
while (buf_flush_list_space(fil_system.sys_space, nullptr));
|
||||
os_aio_wait_until_no_pending_writes(true);
|
||||
}
|
||||
mysql_mutex_lock(&LOCK_global_system_variables);
|
||||
}
|
||||
|
||||
|
@ -19263,8 +19266,10 @@ static MYSQL_SYSVAR_ULONGLONG(max_undo_log_size, srv_max_undo_log_size,
|
|||
10 << 20, 10 << 20,
|
||||
1ULL << (32 + UNIV_PAGE_SIZE_SHIFT_MAX), 0);
|
||||
|
||||
static ulong innodb_purge_rseg_truncate_frequency;
|
||||
|
||||
static MYSQL_SYSVAR_ULONG(purge_rseg_truncate_frequency,
|
||||
srv_purge_rseg_truncate_frequency,
|
||||
innodb_purge_rseg_truncate_frequency,
|
||||
PLUGIN_VAR_OPCMDARG | PLUGIN_VAR_DEPRECATED,
|
||||
"Deprecated parameter with no effect",
|
||||
NULL, NULL, 128, 1, 128, 0);
|
||||
|
|
|
@ -330,8 +330,6 @@ struct fil_space_t final
|
|||
lsn_t max_lsn;
|
||||
/** tablespace identifier */
|
||||
uint32_t id;
|
||||
/** whether undo tablespace truncation is in progress */
|
||||
bool is_being_truncated;
|
||||
fil_type_t purpose;/*!< purpose */
|
||||
UT_LIST_BASE_NODE_T(fil_node_t) chain;
|
||||
/*!< base node for the file chain */
|
||||
|
@ -411,6 +409,8 @@ private:
|
|||
/** LSN of freeing last page; protected by freed_range_mutex */
|
||||
lsn_t last_freed_lsn;
|
||||
|
||||
/** LSN of undo tablespace creation or 0; protected by latch */
|
||||
lsn_t create_lsn;
|
||||
public:
|
||||
/** @return whether doublewrite buffering is needed */
|
||||
inline bool use_doublewrite() const;
|
||||
|
@ -418,6 +418,12 @@ public:
|
|||
/** @return whether a page has been freed */
|
||||
inline bool is_freed(uint32_t page);
|
||||
|
||||
/** Set create_lsn. */
|
||||
inline void set_create_lsn(lsn_t lsn);
|
||||
|
||||
/** @return the latest tablespace rebuild LSN, or 0 */
|
||||
lsn_t get_create_lsn() const { return create_lsn; }
|
||||
|
||||
/** Apply freed_ranges to the file.
|
||||
@param writable whether the file is writable
|
||||
@return number of pages written or hole-punched */
|
||||
|
@ -495,9 +501,6 @@ public:
|
|||
/** Note that operations on the tablespace must stop. */
|
||||
inline void set_stopping();
|
||||
|
||||
/** Note that operations on the tablespace can resume after truncation */
|
||||
inline void clear_stopping();
|
||||
|
||||
/** Drop the tablespace and wait for any pending operations to cease
|
||||
@param id tablespace identifier
|
||||
@param detached_handle pointer to file to be closed later, or nullptr
|
||||
|
@ -1542,14 +1545,6 @@ inline void fil_space_t::set_stopping()
|
|||
#endif
|
||||
}
|
||||
|
||||
inline void fil_space_t::clear_stopping()
|
||||
{
|
||||
mysql_mutex_assert_owner(&fil_system.mutex);
|
||||
static_assert(STOPPING_WRITES == 1U << 30, "compatibility");
|
||||
ut_d(auto n=) n_pending.fetch_sub(STOPPING_WRITES, std::memory_order_relaxed);
|
||||
ut_ad((n & STOPPING) == STOPPING_WRITES);
|
||||
}
|
||||
|
||||
/** Flush pending writes from the file system cache to the file. */
|
||||
template<bool have_reference> inline void fil_space_t::flush()
|
||||
{
|
||||
|
|
|
@ -89,8 +89,9 @@ struct mtr_t {
|
|||
{ auto s= m_memo.size(); rollback_to_savepoint(s - 1, s); }
|
||||
|
||||
/** Commit a mini-transaction that is shrinking a tablespace.
|
||||
@param space tablespace that is being shrunk */
|
||||
ATTRIBUTE_COLD void commit_shrink(fil_space_t &space);
|
||||
@param space tablespace that is being shrunk
|
||||
@param size new size in pages */
|
||||
ATTRIBUTE_COLD void commit_shrink(fil_space_t &space, uint32_t size);
|
||||
|
||||
/** Commit a mini-transaction that is deleting or renaming a file.
|
||||
@param space tablespace that is being renamed or deleted
|
||||
|
|
|
@ -210,14 +210,11 @@ extern unsigned long long srv_max_undo_log_size;
|
|||
extern uint srv_n_fil_crypt_threads;
|
||||
extern uint srv_n_fil_crypt_threads_started;
|
||||
|
||||
/** Rate at which UNDO records should be purged. */
|
||||
extern ulong srv_purge_rseg_truncate_frequency;
|
||||
|
||||
/** Enable or Disable Truncate of UNDO tablespace. */
|
||||
extern my_bool srv_undo_log_truncate;
|
||||
|
||||
/** Default size of UNDO tablespace (10MiB for innodb_page_size=16k) */
|
||||
constexpr ulint SRV_UNDO_TABLESPACE_SIZE_IN_PAGES= (10U << 20) /
|
||||
constexpr uint32_t SRV_UNDO_TABLESPACE_SIZE_IN_PAGES= (10U << 20) /
|
||||
UNIV_PAGE_SIZE_DEF;
|
||||
|
||||
extern char* srv_log_group_home_dir;
|
||||
|
|
|
@ -508,9 +508,20 @@ void mtr_t::rollback_to_savepoint(ulint begin, ulint end)
|
|||
m_memo.erase(m_memo.begin() + begin, m_memo.begin() + end);
|
||||
}
|
||||
|
||||
/** Set create_lsn. */
|
||||
inline void fil_space_t::set_create_lsn(lsn_t lsn)
|
||||
{
|
||||
#ifndef SUX_LOCK_GENERIC
|
||||
/* Concurrent log_checkpoint_low() must be impossible. */
|
||||
ut_ad(latch.is_write_locked());
|
||||
#endif
|
||||
create_lsn= lsn;
|
||||
}
|
||||
|
||||
/** Commit a mini-transaction that is shrinking a tablespace.
|
||||
@param space tablespace that is being shrunk */
|
||||
void mtr_t::commit_shrink(fil_space_t &space)
|
||||
@param space tablespace that is being shrunk
|
||||
@param size new size in pages */
|
||||
void mtr_t::commit_shrink(fil_space_t &space, uint32_t size)
|
||||
{
|
||||
ut_ad(is_active());
|
||||
ut_ad(!high_level_read_only);
|
||||
|
@ -528,19 +539,34 @@ void mtr_t::commit_shrink(fil_space_t &space)
|
|||
const lsn_t start_lsn= do_write().first;
|
||||
ut_d(m_log.erase());
|
||||
|
||||
fil_node_t *file= UT_LIST_GET_LAST(space.chain);
|
||||
mysql_mutex_lock(&fil_system.mutex);
|
||||
ut_ad(file->is_open());
|
||||
ut_ad(space.size >= size);
|
||||
ut_ad(file->size >= space.size - size);
|
||||
file->size-= space.size - size;
|
||||
space.size= space.size_in_header= size;
|
||||
|
||||
if (space.id == TRX_SYS_SPACE)
|
||||
srv_sys_space.set_last_file_size(file->size);
|
||||
|
||||
space.set_create_lsn(m_commit_lsn);
|
||||
mysql_mutex_unlock(&fil_system.mutex);
|
||||
|
||||
space.clear_freed_ranges();
|
||||
|
||||
/* Durably write the reduced FSP_SIZE before truncating the data file. */
|
||||
log_write_and_flush();
|
||||
#ifndef SUX_LOCK_GENERIC
|
||||
ut_ad(log_sys.latch.is_write_locked());
|
||||
#endif
|
||||
|
||||
os_file_truncate(
|
||||
space.chain.end->name, space.chain.end->handle,
|
||||
os_offset_t{space.chain.end->size} << srv_page_size_shift, true);
|
||||
os_file_truncate(file->name, file->handle,
|
||||
os_offset_t{file->size} << srv_page_size_shift, true);
|
||||
|
||||
space.clear_freed_ranges();
|
||||
|
||||
const page_id_t high{space.id, space.size};
|
||||
const page_id_t high{space.id, size};
|
||||
size_t modified= 0;
|
||||
auto it= m_memo.rbegin();
|
||||
mysql_mutex_lock(&buf_pool.flush_list_mutex);
|
||||
|
@ -601,13 +627,6 @@ void mtr_t::commit_shrink(fil_space_t &space)
|
|||
log_sys.latch.wr_unlock();
|
||||
m_latch_ex= false;
|
||||
|
||||
mysql_mutex_lock(&fil_system.mutex);
|
||||
ut_ad(space.is_being_truncated);
|
||||
ut_ad(space.is_stopping_writes());
|
||||
space.clear_stopping();
|
||||
space.is_being_truncated= false;
|
||||
mysql_mutex_unlock(&fil_system.mutex);
|
||||
|
||||
release();
|
||||
release_resources();
|
||||
}
|
||||
|
@ -998,10 +1017,9 @@ std::pair<lsn_t,mtr_t::page_flush_ahead> mtr_t::do_write()
|
|||
#ifndef DBUG_OFF
|
||||
do
|
||||
{
|
||||
if (m_log_mode != MTR_LOG_ALL)
|
||||
if (m_log_mode != MTR_LOG_ALL ||
|
||||
_db_keyword_(nullptr, "skip_page_checksum", 1))
|
||||
continue;
|
||||
DBUG_EXECUTE_IF("skip_page_checksum", continue;);
|
||||
|
||||
for (const mtr_memo_slot_t& slot : m_memo)
|
||||
if (slot.type & MTR_MEMO_MODIFY)
|
||||
{
|
||||
|
|
|
@ -104,9 +104,6 @@ segment). It is quite possible that some of the tablespaces doesn't host
|
|||
any of the rollback-segment based on configuration used. */
|
||||
uint32_t srv_undo_tablespaces_active;
|
||||
|
||||
/** Rate at which UNDO records should be purged. */
|
||||
ulong srv_purge_rseg_truncate_frequency;
|
||||
|
||||
/** Enable or Disable Truncate of UNDO tablespace.
|
||||
Note: If enabled then UNDO tablespace will be selected for truncate.
|
||||
While Server waits for undo-tablespace to truncate if user disables
|
||||
|
|
|
@ -41,6 +41,7 @@ Created 3/26/1996 Heikki Tuuri
|
|||
#include "dict0load.h"
|
||||
#include <mysql/service_thd_mdl.h>
|
||||
#include <mysql/service_wsrep.h>
|
||||
#include "log.h"
|
||||
|
||||
/** Maximum allowable purge history length. <=0 means 'infinite'. */
|
||||
ulong srv_max_purge_lag = 0;
|
||||
|
@ -376,8 +377,8 @@ static void trx_purge_free_segment(buf_block_t *rseg_hdr, buf_block_t *block,
|
|||
ut_ad(rseg_hdr->page.id() == rseg_hdr_id);
|
||||
block->page.lock.x_lock();
|
||||
ut_ad(block->page.id() == id);
|
||||
mtr.memo_push(rseg_hdr, MTR_MEMO_PAGE_X_MODIFY);
|
||||
mtr.memo_push(block, MTR_MEMO_PAGE_X_MODIFY);
|
||||
mtr.memo_push(rseg_hdr, MTR_MEMO_PAGE_X_FIX);
|
||||
mtr.memo_push(block, MTR_MEMO_PAGE_X_FIX);
|
||||
}
|
||||
|
||||
while (!fseg_free_step(TRX_UNDO_SEG_HDR + TRX_UNDO_FSEG_HEADER +
|
||||
|
@ -500,7 +501,7 @@ loop:
|
|||
mtr.start();
|
||||
rseg_hdr->page.lock.x_lock();
|
||||
ut_ad(rseg_hdr->page.id() == rseg.page_id());
|
||||
mtr.memo_push(rseg_hdr, MTR_MEMO_PAGE_X_MODIFY);
|
||||
mtr.memo_push(rseg_hdr, MTR_MEMO_PAGE_X_FIX);
|
||||
|
||||
goto loop;
|
||||
}
|
||||
|
@ -667,16 +668,9 @@ not_free:
|
|||
rseg.latch.rd_unlock();
|
||||
}
|
||||
|
||||
ib::info() << "Truncating " << file->name;
|
||||
sql_print_information("InnoDB: Truncating %s", file->name);
|
||||
trx_purge_cleanse_purge_queue(space);
|
||||
|
||||
log_free_check();
|
||||
|
||||
mtr_t mtr;
|
||||
mtr.start();
|
||||
mtr.x_lock_space(&space);
|
||||
const auto space_id= space.id;
|
||||
|
||||
/* Lock all modified pages of the tablespace.
|
||||
|
||||
During truncation, we do not want any writes to the file.
|
||||
|
@ -686,86 +680,12 @@ not_free:
|
|||
discarding the to-be-trimmed pages without flushing would
|
||||
break crash recovery. */
|
||||
|
||||
rescan:
|
||||
if (UNIV_UNLIKELY(srv_shutdown_state != SRV_SHUTDOWN_NONE) &&
|
||||
srv_fast_shutdown)
|
||||
{
|
||||
fast_shutdown:
|
||||
mtr.commit();
|
||||
return;
|
||||
}
|
||||
|
||||
mysql_mutex_lock(&buf_pool.flush_list_mutex);
|
||||
for (buf_page_t *bpage= UT_LIST_GET_LAST(buf_pool.flush_list); bpage; )
|
||||
{
|
||||
ut_ad(bpage->oldest_modification());
|
||||
ut_ad(bpage->in_file());
|
||||
|
||||
buf_page_t *prev= UT_LIST_GET_PREV(list, bpage);
|
||||
|
||||
if (bpage->oldest_modification() > 2 && bpage->id().space() == space_id)
|
||||
{
|
||||
ut_ad(bpage->frame);
|
||||
bpage->fix();
|
||||
{
|
||||
/* Try to acquire an exclusive latch while the cache line is
|
||||
fresh after fix(). */
|
||||
const bool got_lock{bpage->lock.x_lock_try()};
|
||||
buf_pool.flush_hp.set(prev);
|
||||
mysql_mutex_unlock(&buf_pool.flush_list_mutex);
|
||||
if (!got_lock)
|
||||
bpage->lock.x_lock();
|
||||
}
|
||||
|
||||
#ifdef BTR_CUR_HASH_ADAPT
|
||||
/* There is no AHI on undo tablespaces. */
|
||||
ut_ad(!reinterpret_cast<buf_block_t*>(bpage)->index);
|
||||
#endif
|
||||
ut_ad(!bpage->is_io_fixed());
|
||||
ut_ad(bpage->id().space() == space_id);
|
||||
|
||||
if (bpage->oldest_modification() > 2 &&
|
||||
!mtr.have_x_latch(*reinterpret_cast<buf_block_t*>(bpage)))
|
||||
mtr.memo_push(reinterpret_cast<buf_block_t*>(bpage),
|
||||
MTR_MEMO_PAGE_X_FIX);
|
||||
else
|
||||
{
|
||||
bpage->unfix();
|
||||
bpage->lock.x_unlock();
|
||||
}
|
||||
|
||||
mysql_mutex_lock(&buf_pool.flush_list_mutex);
|
||||
|
||||
if (prev != buf_pool.flush_hp.get())
|
||||
{
|
||||
/* The functions buf_pool_t::release_freed_page() or
|
||||
buf_do_flush_list_batch() may be right now holding
|
||||
buf_pool.mutex and waiting to acquire
|
||||
buf_pool.flush_list_mutex. Ensure that they can proceed,
|
||||
to avoid extreme waits. */
|
||||
mysql_mutex_unlock(&buf_pool.flush_list_mutex);
|
||||
mysql_mutex_lock(&buf_pool.mutex);
|
||||
mysql_mutex_unlock(&buf_pool.mutex);
|
||||
goto rescan;
|
||||
}
|
||||
}
|
||||
|
||||
bpage= prev;
|
||||
}
|
||||
|
||||
mysql_mutex_unlock(&buf_pool.flush_list_mutex);
|
||||
|
||||
if (UNIV_UNLIKELY(srv_shutdown_state != SRV_SHUTDOWN_NONE) &&
|
||||
srv_fast_shutdown)
|
||||
goto fast_shutdown;
|
||||
|
||||
/* Re-initialize tablespace, in a single mini-transaction. */
|
||||
const ulint size= SRV_UNDO_TABLESPACE_SIZE_IN_PAGES;
|
||||
|
||||
/* Adjust the tablespace metadata. */
|
||||
mysql_mutex_lock(&fil_system.mutex);
|
||||
space.set_stopping();
|
||||
space.is_being_truncated= true;
|
||||
if (space.crypt_data)
|
||||
{
|
||||
space.reacquire();
|
||||
|
@ -776,26 +696,20 @@ not_free:
|
|||
else
|
||||
mysql_mutex_unlock(&fil_system.mutex);
|
||||
|
||||
for (auto i= 6000; space.referenced();
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(10)))
|
||||
{
|
||||
if (!--i)
|
||||
{
|
||||
mtr.commit();
|
||||
ib::error() << "Failed to freeze UNDO tablespace " << file->name;
|
||||
return;
|
||||
}
|
||||
}
|
||||
/* Re-initialize tablespace, in a single mini-transaction. */
|
||||
const uint32_t size= SRV_UNDO_TABLESPACE_SIZE_IN_PAGES;
|
||||
|
||||
log_free_check();
|
||||
|
||||
mtr_t mtr;
|
||||
mtr.start();
|
||||
mtr.x_lock_space(&space);
|
||||
/* Associate the undo tablespace with mtr.
|
||||
During mtr::commit_shrink(), InnoDB can use the undo
|
||||
tablespace object to clear all freed ranges */
|
||||
mtr.set_named_space(&space);
|
||||
mtr.trim_pages(page_id_t(space.id, size));
|
||||
ut_a(fsp_header_init(&space, size, &mtr) == DB_SUCCESS);
|
||||
mysql_mutex_lock(&fil_system.mutex);
|
||||
space.size= file->size= size;
|
||||
mysql_mutex_unlock(&fil_system.mutex);
|
||||
|
||||
for (auto &rseg : trx_sys.rseg_array)
|
||||
{
|
||||
|
@ -821,7 +735,7 @@ not_free:
|
|||
rseg.reinit(rblock->page.id().page_no());
|
||||
}
|
||||
|
||||
mtr.commit_shrink(space);
|
||||
mtr.commit_shrink(space, size);
|
||||
|
||||
/* No mutex; this is only updated by the purge coordinator. */
|
||||
export_vars.innodb_undo_truncations++;
|
||||
|
@ -838,11 +752,12 @@ not_free:
|
|||
purge_sys.next_stored= false;
|
||||
}
|
||||
|
||||
DBUG_EXECUTE_IF("ib_undo_trunc", ib::info() << "ib_undo_trunc";
|
||||
DBUG_EXECUTE_IF("ib_undo_trunc",
|
||||
sql_print_information("InnoDB: ib_undo_trunc");
|
||||
log_buffer_flush_to_disk();
|
||||
DBUG_SUICIDE(););
|
||||
|
||||
ib::info() << "Truncated " << file->name;
|
||||
sql_print_information("InnoDB: Truncated %s", file->name);
|
||||
purge_sys.truncate.last= purge_sys.truncate.current;
|
||||
ut_ad(&space == purge_sys.truncate.current);
|
||||
purge_sys.truncate.current= nullptr;
|
||||
|
|
|
@ -254,7 +254,8 @@ int PFS_system_variable_cache::do_materialize_all(THD *unsafe_thd)
|
|||
}
|
||||
|
||||
/* Release lock taken in get_THD(). */
|
||||
mysql_mutex_unlock(&m_safe_thd->LOCK_thd_kill);
|
||||
if (m_safe_thd != current_thd)
|
||||
mysql_mutex_unlock(&m_safe_thd->LOCK_thd_kill);
|
||||
|
||||
m_materialized= true;
|
||||
ret= 0;
|
||||
|
@ -354,7 +355,8 @@ int PFS_system_variable_cache::do_materialize_session(PFS_thread *pfs_thread)
|
|||
}
|
||||
|
||||
/* Release lock taken in get_THD(). */
|
||||
mysql_mutex_unlock(&m_safe_thd->LOCK_thd_kill);
|
||||
if (m_safe_thd != current_thd)
|
||||
mysql_mutex_unlock(&m_safe_thd->LOCK_thd_kill);
|
||||
|
||||
m_materialized= true;
|
||||
ret= 0;
|
||||
|
@ -407,7 +409,8 @@ int PFS_system_variable_cache::do_materialize_session(PFS_thread *pfs_thread, ui
|
|||
}
|
||||
|
||||
/* Release lock taken in get_THD(). */
|
||||
mysql_mutex_unlock(&m_safe_thd->LOCK_thd_kill);
|
||||
if (m_safe_thd != current_thd)
|
||||
mysql_mutex_unlock(&m_safe_thd->LOCK_thd_kill);
|
||||
|
||||
m_materialized= true;
|
||||
ret= 0;
|
||||
|
@ -458,7 +461,8 @@ int PFS_system_variable_cache::do_materialize_session(THD *unsafe_thd)
|
|||
}
|
||||
|
||||
/* Release lock taken in get_THD(). */
|
||||
mysql_mutex_unlock(&m_safe_thd->LOCK_thd_kill);
|
||||
if (m_safe_thd != current_thd)
|
||||
mysql_mutex_unlock(&m_safe_thd->LOCK_thd_kill);
|
||||
|
||||
m_materialized= true;
|
||||
ret= 0;
|
||||
|
@ -984,7 +988,8 @@ int PFS_status_variable_cache::do_materialize_all(THD* unsafe_thd)
|
|||
manifest(m_safe_thd, m_show_var_array.front(), status_vars, "", false, false);
|
||||
|
||||
/* Release lock taken in get_THD(). */
|
||||
mysql_mutex_unlock(&m_safe_thd->LOCK_thd_kill);
|
||||
if (m_safe_thd != current_thd)
|
||||
mysql_mutex_unlock(&m_safe_thd->LOCK_thd_kill);
|
||||
|
||||
m_materialized= true;
|
||||
ret= 0;
|
||||
|
@ -1027,7 +1032,8 @@ int PFS_status_variable_cache::do_materialize_session(THD* unsafe_thd)
|
|||
manifest(m_safe_thd, m_show_var_array.front(), status_vars, "", false, true);
|
||||
|
||||
/* Release lock taken in get_THD(). */
|
||||
mysql_mutex_unlock(&m_safe_thd->LOCK_thd_kill);
|
||||
if (m_safe_thd != current_thd)
|
||||
mysql_mutex_unlock(&m_safe_thd->LOCK_thd_kill);
|
||||
|
||||
m_materialized= true;
|
||||
ret= 0;
|
||||
|
@ -1067,7 +1073,8 @@ int PFS_status_variable_cache::do_materialize_session(PFS_thread *pfs_thread)
|
|||
manifest(m_safe_thd, m_show_var_array.front(), status_vars, "", false, true);
|
||||
|
||||
/* Release lock taken in get_THD(). */
|
||||
mysql_mutex_unlock(&m_safe_thd->LOCK_thd_kill);
|
||||
if (m_safe_thd != current_thd)
|
||||
mysql_mutex_unlock(&m_safe_thd->LOCK_thd_kill);
|
||||
|
||||
m_materialized= true;
|
||||
ret= 0;
|
||||
|
|
|
@ -211,8 +211,12 @@ public:
|
|||
if (thd != m_unsafe_thd)
|
||||
return false;
|
||||
|
||||
/* Hold this lock to keep THD during materialization. */
|
||||
mysql_mutex_lock(&thd->LOCK_thd_kill);
|
||||
/*
|
||||
Hold this lock to keep THD during materialization.
|
||||
But don't lock current_thd (to be able to use set_killed() later
|
||||
*/
|
||||
if (thd != current_thd)
|
||||
mysql_mutex_lock(&thd->LOCK_thd_kill);
|
||||
return true;
|
||||
}
|
||||
void set_unsafe_thd(THD *unsafe_thd) { m_unsafe_thd= unsafe_thd; }
|
||||
|
|
11
storage/spider/mysql-test/spider/bugfix/r/perfschema.result
Normal file
11
storage/spider/mysql-test/spider/bugfix/r/perfschema.result
Normal file
|
@ -0,0 +1,11 @@
|
|||
#
|
||||
# MDEV-33031 Assertion failure upon reading from performance schema with binlog enabled
|
||||
#
|
||||
connect foo,localhost,root;
|
||||
select variable_name, variable_value from performance_schema.status_by_thread
|
||||
where variable_name like '%spider_direct_aggregate%';
|
||||
variable_name variable_value
|
||||
Spider_direct_aggregate 0
|
||||
Spider_direct_aggregate 0
|
||||
disconnect foo;
|
||||
connection default;
|
1
storage/spider/mysql-test/spider/bugfix/t/perfschema.opt
Normal file
1
storage/spider/mysql-test/spider/bugfix/t/perfschema.opt
Normal file
|
@ -0,0 +1 @@
|
|||
--performance-schema
|
15
storage/spider/mysql-test/spider/bugfix/t/perfschema.test
Normal file
15
storage/spider/mysql-test/spider/bugfix/t/perfschema.test
Normal file
|
@ -0,0 +1,15 @@
|
|||
disable_query_log;
|
||||
source ../../include/init_spider.inc;
|
||||
enable_query_log;
|
||||
|
||||
--echo #
|
||||
--echo # MDEV-33031 Assertion failure upon reading from performance schema with binlog enabled
|
||||
--echo #
|
||||
connect foo,localhost,root;
|
||||
select variable_name, variable_value from performance_schema.status_by_thread
|
||||
where variable_name like '%spider_direct_aggregate%';
|
||||
disconnect foo;
|
||||
connection default;
|
||||
|
||||
disable_query_log;
|
||||
source ../../include/deinit_spider.inc;
|
|
@ -109,59 +109,56 @@ extern volatile ulonglong spider_mon_table_cache_version_req;
|
|||
MYSQL_SYSVAR_NAME(param_name).def_val; \
|
||||
}
|
||||
|
||||
static int spider_direct_update(THD *thd, SHOW_VAR *var, char *buff)
|
||||
extern handlerton *spider_hton_ptr;
|
||||
static void spider_trx_status_var(THD *thd, SHOW_VAR *var, char *buff,
|
||||
ulonglong SPIDER_TRX::*counter)
|
||||
{
|
||||
int error_num = 0;
|
||||
SPIDER_TRX *trx;
|
||||
DBUG_ENTER("spider_direct_update");
|
||||
var->type = SHOW_LONGLONG;
|
||||
if ((trx = spider_get_trx(thd, TRUE, &error_num)))
|
||||
var->value = (char *) &trx->direct_update_count;
|
||||
DBUG_RETURN(error_num);
|
||||
var->value= buff;
|
||||
if (thd != current_thd)
|
||||
mysql_mutex_lock(&thd->LOCK_thd_data);
|
||||
SPIDER_TRX *trx = (SPIDER_TRX*)thd_get_ha_data(thd, spider_hton_ptr);
|
||||
*(ulonglong*)buff= trx ? trx->*counter : 0;
|
||||
if (thd != current_thd)
|
||||
mysql_mutex_unlock(&thd->LOCK_thd_data);
|
||||
DBUG_VOID_RETURN;
|
||||
}
|
||||
|
||||
|
||||
static int spider_direct_update(THD *thd, SHOW_VAR *var, char *buff)
|
||||
{
|
||||
DBUG_ENTER("spider_direct_update");
|
||||
spider_trx_status_var(thd, var, buff, &SPIDER_TRX::direct_update_count);
|
||||
DBUG_RETURN(0);
|
||||
}
|
||||
|
||||
static int spider_direct_delete(THD *thd, SHOW_VAR *var, char *buff)
|
||||
{
|
||||
int error_num = 0;
|
||||
SPIDER_TRX *trx;
|
||||
DBUG_ENTER("spider_direct_delete");
|
||||
var->type = SHOW_LONGLONG;
|
||||
if ((trx = spider_get_trx(thd, TRUE, &error_num)))
|
||||
var->value = (char *) &trx->direct_delete_count;
|
||||
DBUG_RETURN(error_num);
|
||||
spider_trx_status_var(thd, var, buff, &SPIDER_TRX::direct_delete_count);
|
||||
DBUG_RETURN(0);
|
||||
}
|
||||
|
||||
static int spider_direct_order_limit(THD *thd, SHOW_VAR *var, char *buff)
|
||||
{
|
||||
int error_num = 0;
|
||||
SPIDER_TRX *trx;
|
||||
DBUG_ENTER("spider_direct_order_limit");
|
||||
var->type = SHOW_LONGLONG;
|
||||
if ((trx = spider_get_trx(thd, TRUE, &error_num)))
|
||||
var->value = (char *) &trx->direct_order_limit_count;
|
||||
DBUG_RETURN(error_num);
|
||||
spider_trx_status_var(thd, var, buff, &SPIDER_TRX::direct_order_limit_count);
|
||||
DBUG_RETURN(0);
|
||||
}
|
||||
|
||||
static int spider_direct_aggregate(THD *thd, SHOW_VAR *var, char *buff)
|
||||
{
|
||||
int error_num = 0;
|
||||
SPIDER_TRX *trx;
|
||||
DBUG_ENTER("spider_direct_aggregate");
|
||||
var->type = SHOW_LONGLONG;
|
||||
if ((trx = spider_get_trx(thd, TRUE, &error_num)))
|
||||
var->value = (char *) &trx->direct_aggregate_count;
|
||||
DBUG_RETURN(error_num);
|
||||
spider_trx_status_var(thd, var, buff, &SPIDER_TRX::direct_aggregate_count);
|
||||
DBUG_RETURN(0);
|
||||
}
|
||||
|
||||
static int spider_parallel_search(THD *thd, SHOW_VAR *var, char *buff)
|
||||
{
|
||||
int error_num = 0;
|
||||
SPIDER_TRX *trx;
|
||||
DBUG_ENTER("spider_parallel_search");
|
||||
var->type = SHOW_LONGLONG;
|
||||
if ((trx = spider_get_trx(thd, TRUE, &error_num)))
|
||||
var->value = (char *) &trx->parallel_search_count;
|
||||
DBUG_RETURN(error_num);
|
||||
spider_trx_status_var(thd, var, buff, &SPIDER_TRX::parallel_search_count);
|
||||
DBUG_RETURN(0);
|
||||
}
|
||||
|
||||
struct st_mysql_show_var spider_status_variables[] =
|
||||
|
|
Loading…
Reference in a new issue