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 1 4
|
||||||
2 2 5
|
2 2 5
|
||||||
drop table t1;
|
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
|
End of 11.1 tests
|
||||||
|
|
|
@ -667,31 +667,4 @@ select *from t1;
|
||||||
|
|
||||||
drop table 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
|
--echo End of 11.1 tests
|
||||||
|
|
|
@ -24,3 +24,49 @@ SELECT * FROM t1;
|
||||||
c1
|
c1
|
||||||
SET sort_buffer_size=@save_sort_buffer_size;
|
SET sort_buffer_size=@save_sort_buffer_size;
|
||||||
DROP TABLE t1;
|
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_innodb.inc
|
||||||
--source include/have_sequence.inc
|
--source include/have_sequence.inc
|
||||||
|
|
||||||
|
--source include/innodb_stable_estimates.inc
|
||||||
|
|
||||||
--echo # Tests for delete with INNODB
|
--echo # Tests for delete with INNODB
|
||||||
|
|
||||||
--echo #
|
--echo #
|
||||||
|
@ -20,3 +22,31 @@ SELECT * FROM t1;
|
||||||
|
|
||||||
SET sort_buffer_size=@save_sort_buffer_size;
|
SET sort_buffer_size=@save_sort_buffer_size;
|
||||||
DROP TABLE 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
|
||||||
|
|
|
@ -895,3 +895,12 @@ REGEXP_INSTR('a_kollision', 'o([lm])\\1')
|
||||||
4
|
4
|
||||||
SELECT a FROM (SELECT "aa" a) t WHERE a REGEXP '[0-9]';
|
SELECT a FROM (SELECT "aa" a) t WHERE a REGEXP '[0-9]';
|
||||||
a
|
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]';
|
SELECT a FROM (SELECT "aa" a) t WHERE a REGEXP '[0-9]';
|
||||||
--enable_service_connection
|
--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;
|
set global innodb_buf_flush_list_now = 1;
|
||||||
|
|
||||||
--let CLEANUP_IF_CHECKPOINT=drop table t1, unexpected_checkpoint;
|
--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
|
--source ../include/no_checkpoint_end.inc
|
||||||
|
|
||||||
--echo # Make the 1st page (page_no=0) and 2nd page (page_no=1)
|
--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
|
from performance_schema.threads
|
||||||
where PROCESSLIST_ID = @slave_sql_pid;
|
where PROCESSLIST_ID = @slave_sql_pid;
|
||||||
NAME TYPE PROCESSLIST_COMMAND PROCESSLIST_STATE
|
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
|
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
|
from performance_schema.threads
|
||||||
where PROCESSLIST_ID = @slave_sql_pid;
|
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
|
--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.
|
// Convert text data to utf-8.
|
||||||
m_library_charset= data_charset == &my_charset_bin ?
|
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) &&
|
m_conversion_is_needed= (data_charset != &my_charset_bin) &&
|
||||||
!my_charset_same(data_charset, m_library_charset);
|
!my_charset_same(data_charset, m_library_charset);
|
||||||
|
|
|
@ -3055,7 +3055,7 @@ public:
|
||||||
m_pcre(NULL), m_pcre_match_data(NULL),
|
m_pcre(NULL), m_pcre_match_data(NULL),
|
||||||
m_conversion_is_needed(true), m_is_const(0),
|
m_conversion_is_needed(true), m_is_const(0),
|
||||||
m_library_flags(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();
|
int default_regex_flags();
|
||||||
void init(CHARSET_INFO *data_charset, int extra_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
|
void
|
||||||
TC_LOG_BINLOG::set_status_variables(THD *thd)
|
TC_LOG_BINLOG::set_status_variables(THD *thd)
|
||||||
{
|
{
|
||||||
binlog_cache_mngr *cache_mngr;
|
bool have_snapshot= false;
|
||||||
|
|
||||||
if (thd && opt_bin_log)
|
if (thd && opt_bin_log)
|
||||||
cache_mngr= thd->binlog_get_cache_mngr();
|
{
|
||||||
else
|
mysql_mutex_lock(&thd->LOCK_thd_data);
|
||||||
cache_mngr= 0;
|
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);
|
mysql_mutex_lock(&LOCK_commit_ordered);
|
||||||
binlog_status_var_num_commits= this->num_commits;
|
binlog_status_var_num_commits= this->num_commits;
|
||||||
binlog_status_var_num_group_commits= this->num_group_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_timeout= this->group_commit_trigger_timeout;
|
||||||
binlog_status_group_commit_trigger_lock_wait= this->group_commit_trigger_lock_wait;
|
binlog_status_group_commit_trigger_lock_wait= this->group_commit_trigger_lock_wait;
|
||||||
mysql_mutex_unlock(&LOCK_prepare_ordered);
|
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());
|
ut_ad(space->referenced());
|
||||||
|
|
||||||
const auto s= state();
|
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)
|
if (s < UNFIXED)
|
||||||
{
|
{
|
||||||
|
ut_a(s >= FREED);
|
||||||
if (UNIV_LIKELY(space->purpose == FIL_TYPE_TABLESPACE))
|
if (UNIV_LIKELY(space->purpose == FIL_TYPE_TABLESPACE))
|
||||||
{
|
{
|
||||||
const lsn_t lsn=
|
freed:
|
||||||
mach_read_from_8(my_assume_aligned<8>
|
|
||||||
(FIL_PAGE_LSN + (zip.data ? zip.data : frame)));
|
|
||||||
ut_ad(lsn >= oldest_modification());
|
|
||||||
if (lsn > log_sys.get_flushed_lsn())
|
if (lsn > log_sys.get_flushed_lsn())
|
||||||
{
|
{
|
||||||
mysql_mutex_unlock(&buf_pool.mutex);
|
mysql_mutex_unlock(&buf_pool.mutex);
|
||||||
|
@ -775,6 +779,12 @@ bool buf_page_t::flush(bool evict, fil_space_t *space)
|
||||||
return false;
|
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_d(const auto f=) zip.fix.fetch_add(WRITE_FIX - UNFIXED);
|
||||||
ut_ad(f >= UNFIXED);
|
ut_ad(f >= UNFIXED);
|
||||||
ut_ad(f < READ_FIX);
|
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 ((s & LRU_MASK) == REINIT || !space->use_doublewrite())
|
||||||
{
|
{
|
||||||
if (UNIV_LIKELY(space->purpose == FIL_TYPE_TABLESPACE))
|
if (UNIV_LIKELY(space->purpose == FIL_TYPE_TABLESPACE) &&
|
||||||
{
|
lsn > log_sys.get_flushed_lsn())
|
||||||
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());
|
|
||||||
log_write_up_to(lsn, true);
|
log_write_up_to(lsn, true);
|
||||||
}
|
|
||||||
space->io(IORequest{type, this, slot}, physical_offset(), size,
|
space->io(IORequest{type, this, slot}, physical_offset(), size,
|
||||||
write_frame, this);
|
write_frame, this);
|
||||||
}
|
}
|
||||||
|
@ -1057,11 +1061,25 @@ static ulint buf_flush_try_neighbors(fil_space_t *space,
|
||||||
bool contiguous, bool evict,
|
bool contiguous, bool evict,
|
||||||
ulint n_flushed, ulint n_to_flush)
|
ulint n_flushed, ulint n_to_flush)
|
||||||
{
|
{
|
||||||
mysql_mutex_unlock(&buf_pool.mutex);
|
|
||||||
|
|
||||||
ut_ad(space->id == page_id.space());
|
ut_ad(space->id == page_id.space());
|
||||||
ut_ad(bpage->id() == page_id);
|
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;
|
ulint count= 0;
|
||||||
page_id_t id= page_id;
|
page_id_t id= page_id;
|
||||||
page_id_t high= buf_flush_check_neighbors(*space, id, contiguous, evict);
|
page_id_t high= buf_flush_check_neighbors(*space, id, contiguous, evict);
|
||||||
|
@ -2434,9 +2452,9 @@ static void buf_flush_page_cleaner()
|
||||||
|
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
DBUG_EXECUTE_IF("ib_log_checkpoint_avoid", continue;);
|
IF_DBUG(if (_db_keyword_(nullptr, "ib_log_checkpoint_avoid", 1) ||
|
||||||
DBUG_EXECUTE_IF("ib_log_checkpoint_avoid_hard", continue;);
|
_db_keyword_(nullptr, "ib_log_checkpoint_avoid_hard", 1))
|
||||||
|
continue,);
|
||||||
if (!recv_recovery_is_on() &&
|
if (!recv_recovery_is_on() &&
|
||||||
!srv_startup_is_before_trx_rollback_phase &&
|
!srv_startup_is_before_trx_rollback_phase &&
|
||||||
srv_operation <= SRV_OPERATION_EXPORT_RESTORED)
|
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(UT_LIST_GET_LAST(space->chain) == node);
|
||||||
ut_ad(size >= FIL_IBD_FILE_INITIAL_SIZE);
|
ut_ad(size >= FIL_IBD_FILE_INITIAL_SIZE);
|
||||||
ut_ad(node->space == space);
|
ut_ad(node->space == space);
|
||||||
ut_ad(space->referenced() || space->is_being_truncated);
|
ut_ad(space->referenced());
|
||||||
|
|
||||||
*success = space->size >= size;
|
*success = space->size >= size;
|
||||||
|
|
||||||
|
@ -653,8 +653,7 @@ fil_space_extend_must_retry(
|
||||||
default:
|
default:
|
||||||
ut_ad(space->purpose == FIL_TYPE_TABLESPACE
|
ut_ad(space->purpose == FIL_TYPE_TABLESPACE
|
||||||
|| space->purpose == FIL_TYPE_IMPORT);
|
|| space->purpose == FIL_TYPE_IMPORT);
|
||||||
if (space->purpose == FIL_TYPE_TABLESPACE
|
if (space->purpose == FIL_TYPE_TABLESPACE) {
|
||||||
&& !space->is_being_truncated) {
|
|
||||||
goto do_flush;
|
goto do_flush;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -754,12 +753,10 @@ bool fil_space_extend(fil_space_t *space, uint32_t size)
|
||||||
bool success= false;
|
bool success= false;
|
||||||
const bool acquired= space->acquire();
|
const bool acquired= space->acquire();
|
||||||
mysql_mutex_lock(&fil_system.mutex);
|
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),
|
while (fil_space_extend_must_retry(space, UT_LIST_GET_LAST(space->chain),
|
||||||
size, &success))
|
size, &success))
|
||||||
mysql_mutex_lock(&fil_system.mutex);
|
mysql_mutex_lock(&fil_system.mutex);
|
||||||
}
|
|
||||||
mysql_mutex_unlock(&fil_system.mutex);
|
mysql_mutex_unlock(&fil_system.mutex);
|
||||||
if (acquired)
|
if (acquired)
|
||||||
space->release();
|
space->release();
|
||||||
|
@ -3135,11 +3132,9 @@ fil_space_validate_for_mtr_commit(
|
||||||
ut_ad(!is_predefined_tablespace(space->id));
|
ut_ad(!is_predefined_tablespace(space->id));
|
||||||
|
|
||||||
/* We are serving mtr_commit(). While there is an active
|
/* 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. */
|
guaranteed by meta-data locks or transactional locks. */
|
||||||
ut_ad(!space->is_stopping()
|
ut_ad(!space->is_stopping() || space->referenced());
|
||||||
|| space->is_being_truncated /* fil_truncate_prepare() */
|
|
||||||
|| space->referenced());
|
|
||||||
}
|
}
|
||||||
#endif /* UNIV_DEBUG */
|
#endif /* UNIV_DEBUG */
|
||||||
|
|
||||||
|
|
|
@ -41,8 +41,6 @@ Created 11/29/1995 Heikki Tuuri
|
||||||
#include "fsp0types.h"
|
#include "fsp0types.h"
|
||||||
#include "log.h"
|
#include "log.h"
|
||||||
|
|
||||||
typedef uint32_t page_no_t;
|
|
||||||
|
|
||||||
/** Returns the first extent descriptor for a segment.
|
/** Returns the first extent descriptor for a segment.
|
||||||
We think of the extent lists of the segment catenated in the order
|
We think of the extent lists of the segment catenated in the order
|
||||||
FSEG_FULL -> FSEG_NOT_FULL -> FSEG_FREE.
|
FSEG_FULL -> FSEG_NOT_FULL -> FSEG_FREE.
|
||||||
|
@ -331,7 +329,7 @@ xdes_t*
|
||||||
xdes_get_descriptor_with_space_hdr(
|
xdes_get_descriptor_with_space_hdr(
|
||||||
buf_block_t* header,
|
buf_block_t* header,
|
||||||
const fil_space_t* space,
|
const fil_space_t* space,
|
||||||
page_no_t offset,
|
uint32_t offset,
|
||||||
mtr_t* mtr,
|
mtr_t* mtr,
|
||||||
dberr_t* err = nullptr,
|
dberr_t* err = nullptr,
|
||||||
buf_block_t** desc_block = 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] err error code
|
||||||
@param[out] xdes extent descriptor page
|
@param[out] xdes extent descriptor page
|
||||||
@return the extent descriptor */
|
@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,
|
mtr_t *mtr, dberr_t *err= nullptr,
|
||||||
buf_block_t **xdes= nullptr)
|
buf_block_t **xdes= nullptr)
|
||||||
{
|
{
|
||||||
|
@ -841,8 +839,7 @@ fsp_fill_free_list(
|
||||||
if (i)
|
if (i)
|
||||||
{
|
{
|
||||||
buf_block_t *f= buf_LRU_get_free_block(have_no_mutex);
|
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),
|
buf_block_t *block= buf_page_create(space, i, zip_size, mtr, f);
|
||||||
zip_size, mtr, f);
|
|
||||||
if (UNIV_UNLIKELY(block != f))
|
if (UNIV_UNLIKELY(block != f))
|
||||||
buf_pool.free_block(f);
|
buf_pool.free_block(f);
|
||||||
fsp_init_file_page(space, block, mtr);
|
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 *f= buf_LRU_get_free_block(have_no_mutex);
|
||||||
buf_block_t *block=
|
buf_block_t *block=
|
||||||
buf_page_create(space, static_cast<uint32_t>(i + 1),
|
buf_page_create(space, i + 1, zip_size, mtr, f);
|
||||||
zip_size, mtr, f);
|
|
||||||
if (UNIV_UNLIKELY(block != f))
|
if (UNIV_UNLIKELY(block != f))
|
||||||
buf_pool.free_block(f);
|
buf_pool.free_block(f);
|
||||||
/* The zero-initialization will reset the change buffer bitmap bits
|
/* 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] offset page number of the allocated page
|
||||||
@param[in,out] mtr mini-transaction
|
@param[in,out] mtr mini-transaction
|
||||||
@return block, initialized */
|
@return block, initialized */
|
||||||
static
|
static buf_block_t* fsp_page_create(fil_space_t *space, uint32_t offset,
|
||||||
buf_block_t*
|
mtr_t *mtr)
|
||||||
fsp_page_create(fil_space_t *space, page_no_t offset, mtr_t *mtr)
|
|
||||||
{
|
{
|
||||||
buf_block_t *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(space->is_being_truncated))
|
if (UNIV_UNLIKELY(block != free_block))
|
||||||
{
|
buf_pool.free_block(free_block);
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
fsp_init_file_page(space, block, mtr);
|
fsp_init_file_page(space, block, mtr);
|
||||||
return block;
|
return block;
|
||||||
}
|
}
|
||||||
|
@ -1224,7 +1153,7 @@ MY_ATTRIBUTE((nonnull, warn_unused_result))
|
||||||
@param[in] offset page number in the extent
|
@param[in] offset page number in the extent
|
||||||
@param[in,out] mtr mini-transaction
|
@param[in,out] mtr mini-transaction
|
||||||
@return error code */
|
@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)
|
mtr_t* mtr)
|
||||||
{
|
{
|
||||||
ut_ad(space->is_owner());
|
ut_ad(space->is_owner());
|
||||||
|
@ -1261,7 +1190,7 @@ The page is marked as free and clean.
|
||||||
@param[in] offset page number
|
@param[in] offset page number
|
||||||
@param[in,out] mtr mini-transaction
|
@param[in,out] mtr mini-transaction
|
||||||
@return error code */
|
@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;
|
xdes_t* descr;
|
||||||
ulint frag_n_used;
|
ulint frag_n_used;
|
||||||
|
@ -1801,7 +1730,6 @@ page_alloc:
|
||||||
|
|
||||||
ut_d(const auto x = block->page.lock.x_lock_count());
|
ut_d(const auto x = block->page.lock.x_lock_count());
|
||||||
ut_ad(x || block->page.lock.not_recursive());
|
ut_ad(x || block->page.lock.not_recursive());
|
||||||
ut_ad(x == 1 || space->is_being_truncated);
|
|
||||||
ut_ad(x <= 2);
|
ut_ad(x <= 2);
|
||||||
ut_ad(!fil_page_get_type(block->page.frame));
|
ut_ad(!fil_page_get_type(block->page.frame));
|
||||||
mtr->write<1>(*block, FIL_PAGE_TYPE + 1 + 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,
|
fseg_inode_t* seg_inode,
|
||||||
buf_block_t* iblock,
|
buf_block_t* iblock,
|
||||||
fil_space_t* space,
|
fil_space_t* space,
|
||||||
page_no_t offset,
|
uint32_t offset,
|
||||||
mtr_t* mtr
|
mtr_t* mtr
|
||||||
#ifdef BTR_CUR_HASH_ADAPT
|
#ifdef BTR_CUR_HASH_ADAPT
|
||||||
,bool ahi=false
|
,bool ahi=false
|
||||||
|
@ -2904,7 +2832,7 @@ fseg_free_step(
|
||||||
return true;
|
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
|
if (fseg_free_page_low(inode, iblock, space, page_no, mtr
|
||||||
#ifdef BTR_CUR_HASH_ADAPT
|
#ifdef BTR_CUR_HASH_ADAPT
|
||||||
|
@ -3699,28 +3627,13 @@ mtr_max:
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
mysql_mutex_lock(&fil_system.mutex);
|
|
||||||
|
|
||||||
space->size= last_used_extent;
|
|
||||||
if (space->free_limit > 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(
|
mtr.commit_shrink(*space, last_used_extent);
|
||||||
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);
|
|
||||||
sql_print_information("InnoDB: System tablespace truncated successfully");
|
sql_print_information("InnoDB: System tablespace truncated successfully");
|
||||||
srv_use_doublewrite_buf= old_dblwr_buf;
|
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)
|
if (s)
|
||||||
buf_flush_sync();
|
buf_flush_sync();
|
||||||
else
|
else
|
||||||
|
{
|
||||||
while (buf_flush_list_space(fil_system.sys_space, nullptr));
|
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);
|
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,
|
10 << 20, 10 << 20,
|
||||||
1ULL << (32 + UNIV_PAGE_SIZE_SHIFT_MAX), 0);
|
1ULL << (32 + UNIV_PAGE_SIZE_SHIFT_MAX), 0);
|
||||||
|
|
||||||
|
static ulong innodb_purge_rseg_truncate_frequency;
|
||||||
|
|
||||||
static MYSQL_SYSVAR_ULONG(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,
|
PLUGIN_VAR_OPCMDARG | PLUGIN_VAR_DEPRECATED,
|
||||||
"Deprecated parameter with no effect",
|
"Deprecated parameter with no effect",
|
||||||
NULL, NULL, 128, 1, 128, 0);
|
NULL, NULL, 128, 1, 128, 0);
|
||||||
|
|
|
@ -330,8 +330,6 @@ struct fil_space_t final
|
||||||
lsn_t max_lsn;
|
lsn_t max_lsn;
|
||||||
/** tablespace identifier */
|
/** tablespace identifier */
|
||||||
uint32_t id;
|
uint32_t id;
|
||||||
/** whether undo tablespace truncation is in progress */
|
|
||||||
bool is_being_truncated;
|
|
||||||
fil_type_t purpose;/*!< purpose */
|
fil_type_t purpose;/*!< purpose */
|
||||||
UT_LIST_BASE_NODE_T(fil_node_t) chain;
|
UT_LIST_BASE_NODE_T(fil_node_t) chain;
|
||||||
/*!< base node for the file chain */
|
/*!< base node for the file chain */
|
||||||
|
@ -411,6 +409,8 @@ private:
|
||||||
/** LSN of freeing last page; protected by freed_range_mutex */
|
/** LSN of freeing last page; protected by freed_range_mutex */
|
||||||
lsn_t last_freed_lsn;
|
lsn_t last_freed_lsn;
|
||||||
|
|
||||||
|
/** LSN of undo tablespace creation or 0; protected by latch */
|
||||||
|
lsn_t create_lsn;
|
||||||
public:
|
public:
|
||||||
/** @return whether doublewrite buffering is needed */
|
/** @return whether doublewrite buffering is needed */
|
||||||
inline bool use_doublewrite() const;
|
inline bool use_doublewrite() const;
|
||||||
|
@ -418,6 +418,12 @@ public:
|
||||||
/** @return whether a page has been freed */
|
/** @return whether a page has been freed */
|
||||||
inline bool is_freed(uint32_t page);
|
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.
|
/** Apply freed_ranges to the file.
|
||||||
@param writable whether the file is writable
|
@param writable whether the file is writable
|
||||||
@return number of pages written or hole-punched */
|
@return number of pages written or hole-punched */
|
||||||
|
@ -495,9 +501,6 @@ public:
|
||||||
/** Note that operations on the tablespace must stop. */
|
/** Note that operations on the tablespace must stop. */
|
||||||
inline void set_stopping();
|
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
|
/** Drop the tablespace and wait for any pending operations to cease
|
||||||
@param id tablespace identifier
|
@param id tablespace identifier
|
||||||
@param detached_handle pointer to file to be closed later, or nullptr
|
@param detached_handle pointer to file to be closed later, or nullptr
|
||||||
|
@ -1542,14 +1545,6 @@ inline void fil_space_t::set_stopping()
|
||||||
#endif
|
#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. */
|
/** Flush pending writes from the file system cache to the file. */
|
||||||
template<bool have_reference> inline void fil_space_t::flush()
|
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); }
|
{ auto s= m_memo.size(); rollback_to_savepoint(s - 1, s); }
|
||||||
|
|
||||||
/** Commit a mini-transaction that is shrinking a tablespace.
|
/** Commit a mini-transaction that is shrinking a tablespace.
|
||||||
@param space tablespace that is being shrunk */
|
@param space tablespace that is being shrunk
|
||||||
ATTRIBUTE_COLD void commit_shrink(fil_space_t &space);
|
@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.
|
/** Commit a mini-transaction that is deleting or renaming a file.
|
||||||
@param space tablespace that is being renamed or deleted
|
@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;
|
||||||
extern uint srv_n_fil_crypt_threads_started;
|
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. */
|
/** Enable or Disable Truncate of UNDO tablespace. */
|
||||||
extern my_bool srv_undo_log_truncate;
|
extern my_bool srv_undo_log_truncate;
|
||||||
|
|
||||||
/** Default size of UNDO tablespace (10MiB for innodb_page_size=16k) */
|
/** 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;
|
UNIV_PAGE_SIZE_DEF;
|
||||||
|
|
||||||
extern char* srv_log_group_home_dir;
|
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);
|
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.
|
/** Commit a mini-transaction that is shrinking a tablespace.
|
||||||
@param space tablespace that is being shrunk */
|
@param space tablespace that is being shrunk
|
||||||
void mtr_t::commit_shrink(fil_space_t &space)
|
@param size new size in pages */
|
||||||
|
void mtr_t::commit_shrink(fil_space_t &space, uint32_t size)
|
||||||
{
|
{
|
||||||
ut_ad(is_active());
|
ut_ad(is_active());
|
||||||
ut_ad(!high_level_read_only);
|
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;
|
const lsn_t start_lsn= do_write().first;
|
||||||
ut_d(m_log.erase());
|
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. */
|
/* Durably write the reduced FSP_SIZE before truncating the data file. */
|
||||||
log_write_and_flush();
|
log_write_and_flush();
|
||||||
#ifndef SUX_LOCK_GENERIC
|
#ifndef SUX_LOCK_GENERIC
|
||||||
ut_ad(log_sys.latch.is_write_locked());
|
ut_ad(log_sys.latch.is_write_locked());
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
os_file_truncate(
|
os_file_truncate(file->name, file->handle,
|
||||||
space.chain.end->name, space.chain.end->handle,
|
os_offset_t{file->size} << srv_page_size_shift, true);
|
||||||
os_offset_t{space.chain.end->size} << srv_page_size_shift, true);
|
|
||||||
|
|
||||||
space.clear_freed_ranges();
|
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;
|
size_t modified= 0;
|
||||||
auto it= m_memo.rbegin();
|
auto it= m_memo.rbegin();
|
||||||
mysql_mutex_lock(&buf_pool.flush_list_mutex);
|
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();
|
log_sys.latch.wr_unlock();
|
||||||
m_latch_ex= false;
|
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();
|
||||||
release_resources();
|
release_resources();
|
||||||
}
|
}
|
||||||
|
@ -998,10 +1017,9 @@ std::pair<lsn_t,mtr_t::page_flush_ahead> mtr_t::do_write()
|
||||||
#ifndef DBUG_OFF
|
#ifndef DBUG_OFF
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
if (m_log_mode != MTR_LOG_ALL)
|
if (m_log_mode != MTR_LOG_ALL ||
|
||||||
|
_db_keyword_(nullptr, "skip_page_checksum", 1))
|
||||||
continue;
|
continue;
|
||||||
DBUG_EXECUTE_IF("skip_page_checksum", continue;);
|
|
||||||
|
|
||||||
for (const mtr_memo_slot_t& slot : m_memo)
|
for (const mtr_memo_slot_t& slot : m_memo)
|
||||||
if (slot.type & MTR_MEMO_MODIFY)
|
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. */
|
any of the rollback-segment based on configuration used. */
|
||||||
uint32_t srv_undo_tablespaces_active;
|
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.
|
/** Enable or Disable Truncate of UNDO tablespace.
|
||||||
Note: If enabled then UNDO tablespace will be selected for truncate.
|
Note: If enabled then UNDO tablespace will be selected for truncate.
|
||||||
While Server waits for undo-tablespace to truncate if user disables
|
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 "dict0load.h"
|
||||||
#include <mysql/service_thd_mdl.h>
|
#include <mysql/service_thd_mdl.h>
|
||||||
#include <mysql/service_wsrep.h>
|
#include <mysql/service_wsrep.h>
|
||||||
|
#include "log.h"
|
||||||
|
|
||||||
/** Maximum allowable purge history length. <=0 means 'infinite'. */
|
/** Maximum allowable purge history length. <=0 means 'infinite'. */
|
||||||
ulong srv_max_purge_lag = 0;
|
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);
|
ut_ad(rseg_hdr->page.id() == rseg_hdr_id);
|
||||||
block->page.lock.x_lock();
|
block->page.lock.x_lock();
|
||||||
ut_ad(block->page.id() == id);
|
ut_ad(block->page.id() == id);
|
||||||
mtr.memo_push(rseg_hdr, MTR_MEMO_PAGE_X_MODIFY);
|
mtr.memo_push(rseg_hdr, MTR_MEMO_PAGE_X_FIX);
|
||||||
mtr.memo_push(block, MTR_MEMO_PAGE_X_MODIFY);
|
mtr.memo_push(block, MTR_MEMO_PAGE_X_FIX);
|
||||||
}
|
}
|
||||||
|
|
||||||
while (!fseg_free_step(TRX_UNDO_SEG_HDR + TRX_UNDO_FSEG_HEADER +
|
while (!fseg_free_step(TRX_UNDO_SEG_HDR + TRX_UNDO_FSEG_HEADER +
|
||||||
|
@ -500,7 +501,7 @@ loop:
|
||||||
mtr.start();
|
mtr.start();
|
||||||
rseg_hdr->page.lock.x_lock();
|
rseg_hdr->page.lock.x_lock();
|
||||||
ut_ad(rseg_hdr->page.id() == rseg.page_id());
|
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;
|
goto loop;
|
||||||
}
|
}
|
||||||
|
@ -667,16 +668,9 @@ not_free:
|
||||||
rseg.latch.rd_unlock();
|
rseg.latch.rd_unlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
ib::info() << "Truncating " << file->name;
|
sql_print_information("InnoDB: Truncating %s", file->name);
|
||||||
trx_purge_cleanse_purge_queue(space);
|
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.
|
/* Lock all modified pages of the tablespace.
|
||||||
|
|
||||||
During truncation, we do not want any writes to the file.
|
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
|
discarding the to-be-trimmed pages without flushing would
|
||||||
break crash recovery. */
|
break crash recovery. */
|
||||||
|
|
||||||
rescan:
|
|
||||||
if (UNIV_UNLIKELY(srv_shutdown_state != SRV_SHUTDOWN_NONE) &&
|
if (UNIV_UNLIKELY(srv_shutdown_state != SRV_SHUTDOWN_NONE) &&
|
||||||
srv_fast_shutdown)
|
srv_fast_shutdown)
|
||||||
{
|
|
||||||
fast_shutdown:
|
|
||||||
mtr.commit();
|
|
||||||
return;
|
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. */
|
/* Adjust the tablespace metadata. */
|
||||||
mysql_mutex_lock(&fil_system.mutex);
|
mysql_mutex_lock(&fil_system.mutex);
|
||||||
space.set_stopping();
|
|
||||||
space.is_being_truncated= true;
|
|
||||||
if (space.crypt_data)
|
if (space.crypt_data)
|
||||||
{
|
{
|
||||||
space.reacquire();
|
space.reacquire();
|
||||||
|
@ -776,26 +696,20 @@ not_free:
|
||||||
else
|
else
|
||||||
mysql_mutex_unlock(&fil_system.mutex);
|
mysql_mutex_unlock(&fil_system.mutex);
|
||||||
|
|
||||||
for (auto i= 6000; space.referenced();
|
/* Re-initialize tablespace, in a single mini-transaction. */
|
||||||
std::this_thread::sleep_for(std::chrono::milliseconds(10)))
|
const uint32_t size= SRV_UNDO_TABLESPACE_SIZE_IN_PAGES;
|
||||||
{
|
|
||||||
if (!--i)
|
|
||||||
{
|
|
||||||
mtr.commit();
|
|
||||||
ib::error() << "Failed to freeze UNDO tablespace " << file->name;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
log_free_check();
|
||||||
|
|
||||||
|
mtr_t mtr;
|
||||||
|
mtr.start();
|
||||||
|
mtr.x_lock_space(&space);
|
||||||
/* Associate the undo tablespace with mtr.
|
/* Associate the undo tablespace with mtr.
|
||||||
During mtr::commit_shrink(), InnoDB can use the undo
|
During mtr::commit_shrink(), InnoDB can use the undo
|
||||||
tablespace object to clear all freed ranges */
|
tablespace object to clear all freed ranges */
|
||||||
mtr.set_named_space(&space);
|
mtr.set_named_space(&space);
|
||||||
mtr.trim_pages(page_id_t(space.id, size));
|
mtr.trim_pages(page_id_t(space.id, size));
|
||||||
ut_a(fsp_header_init(&space, size, &mtr) == DB_SUCCESS);
|
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)
|
for (auto &rseg : trx_sys.rseg_array)
|
||||||
{
|
{
|
||||||
|
@ -821,7 +735,7 @@ not_free:
|
||||||
rseg.reinit(rblock->page.id().page_no());
|
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. */
|
/* No mutex; this is only updated by the purge coordinator. */
|
||||||
export_vars.innodb_undo_truncations++;
|
export_vars.innodb_undo_truncations++;
|
||||||
|
@ -838,11 +752,12 @@ not_free:
|
||||||
purge_sys.next_stored= false;
|
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();
|
log_buffer_flush_to_disk();
|
||||||
DBUG_SUICIDE(););
|
DBUG_SUICIDE(););
|
||||||
|
|
||||||
ib::info() << "Truncated " << file->name;
|
sql_print_information("InnoDB: Truncated %s", file->name);
|
||||||
purge_sys.truncate.last= purge_sys.truncate.current;
|
purge_sys.truncate.last= purge_sys.truncate.current;
|
||||||
ut_ad(&space == purge_sys.truncate.current);
|
ut_ad(&space == purge_sys.truncate.current);
|
||||||
purge_sys.truncate.current= nullptr;
|
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(). */
|
/* 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;
|
m_materialized= true;
|
||||||
ret= 0;
|
ret= 0;
|
||||||
|
@ -354,7 +355,8 @@ int PFS_system_variable_cache::do_materialize_session(PFS_thread *pfs_thread)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Release lock taken in get_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;
|
m_materialized= true;
|
||||||
ret= 0;
|
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(). */
|
/* 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;
|
m_materialized= true;
|
||||||
ret= 0;
|
ret= 0;
|
||||||
|
@ -458,7 +461,8 @@ int PFS_system_variable_cache::do_materialize_session(THD *unsafe_thd)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Release lock taken in get_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;
|
m_materialized= true;
|
||||||
ret= 0;
|
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);
|
manifest(m_safe_thd, m_show_var_array.front(), status_vars, "", false, false);
|
||||||
|
|
||||||
/* Release lock taken in get_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;
|
m_materialized= true;
|
||||||
ret= 0;
|
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);
|
manifest(m_safe_thd, m_show_var_array.front(), status_vars, "", false, true);
|
||||||
|
|
||||||
/* Release lock taken in get_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;
|
m_materialized= true;
|
||||||
ret= 0;
|
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);
|
manifest(m_safe_thd, m_show_var_array.front(), status_vars, "", false, true);
|
||||||
|
|
||||||
/* Release lock taken in get_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;
|
m_materialized= true;
|
||||||
ret= 0;
|
ret= 0;
|
||||||
|
|
|
@ -211,8 +211,12 @@ public:
|
||||||
if (thd != m_unsafe_thd)
|
if (thd != m_unsafe_thd)
|
||||||
return false;
|
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;
|
return true;
|
||||||
}
|
}
|
||||||
void set_unsafe_thd(THD *unsafe_thd) { m_unsafe_thd= unsafe_thd; }
|
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; \
|
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");
|
DBUG_ENTER("spider_direct_update");
|
||||||
var->type = SHOW_LONGLONG;
|
var->type = SHOW_LONGLONG;
|
||||||
if ((trx = spider_get_trx(thd, TRUE, &error_num)))
|
var->value= buff;
|
||||||
var->value = (char *) &trx->direct_update_count;
|
if (thd != current_thd)
|
||||||
DBUG_RETURN(error_num);
|
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)
|
static int spider_direct_delete(THD *thd, SHOW_VAR *var, char *buff)
|
||||||
{
|
{
|
||||||
int error_num = 0;
|
|
||||||
SPIDER_TRX *trx;
|
|
||||||
DBUG_ENTER("spider_direct_delete");
|
DBUG_ENTER("spider_direct_delete");
|
||||||
var->type = SHOW_LONGLONG;
|
spider_trx_status_var(thd, var, buff, &SPIDER_TRX::direct_delete_count);
|
||||||
if ((trx = spider_get_trx(thd, TRUE, &error_num)))
|
DBUG_RETURN(0);
|
||||||
var->value = (char *) &trx->direct_delete_count;
|
|
||||||
DBUG_RETURN(error_num);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int spider_direct_order_limit(THD *thd, SHOW_VAR *var, char *buff)
|
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");
|
DBUG_ENTER("spider_direct_order_limit");
|
||||||
var->type = SHOW_LONGLONG;
|
spider_trx_status_var(thd, var, buff, &SPIDER_TRX::direct_order_limit_count);
|
||||||
if ((trx = spider_get_trx(thd, TRUE, &error_num)))
|
DBUG_RETURN(0);
|
||||||
var->value = (char *) &trx->direct_order_limit_count;
|
|
||||||
DBUG_RETURN(error_num);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int spider_direct_aggregate(THD *thd, SHOW_VAR *var, char *buff)
|
static int spider_direct_aggregate(THD *thd, SHOW_VAR *var, char *buff)
|
||||||
{
|
{
|
||||||
int error_num = 0;
|
|
||||||
SPIDER_TRX *trx;
|
|
||||||
DBUG_ENTER("spider_direct_aggregate");
|
DBUG_ENTER("spider_direct_aggregate");
|
||||||
var->type = SHOW_LONGLONG;
|
spider_trx_status_var(thd, var, buff, &SPIDER_TRX::direct_aggregate_count);
|
||||||
if ((trx = spider_get_trx(thd, TRUE, &error_num)))
|
DBUG_RETURN(0);
|
||||||
var->value = (char *) &trx->direct_aggregate_count;
|
|
||||||
DBUG_RETURN(error_num);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int spider_parallel_search(THD *thd, SHOW_VAR *var, char *buff)
|
static int spider_parallel_search(THD *thd, SHOW_VAR *var, char *buff)
|
||||||
{
|
{
|
||||||
int error_num = 0;
|
|
||||||
SPIDER_TRX *trx;
|
|
||||||
DBUG_ENTER("spider_parallel_search");
|
DBUG_ENTER("spider_parallel_search");
|
||||||
var->type = SHOW_LONGLONG;
|
spider_trx_status_var(thd, var, buff, &SPIDER_TRX::parallel_search_count);
|
||||||
if ((trx = spider_get_trx(thd, TRUE, &error_num)))
|
DBUG_RETURN(0);
|
||||||
var->value = (char *) &trx->parallel_search_count;
|
|
||||||
DBUG_RETURN(error_num);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
struct st_mysql_show_var spider_status_variables[] =
|
struct st_mysql_show_var spider_status_variables[] =
|
||||||
|
|
Loading…
Reference in a new issue