Merge 10.3 into 10.4

This commit is contained in:
Marko Mäkelä 2020-07-20 15:34:59 +03:00
commit 4b959bd8df
25 changed files with 195 additions and 115 deletions

View File

@ -189,6 +189,7 @@ ENDIF()
OPTION(NOT_FOR_DISTRIBUTION "Allow linking with GPLv2-incompatible system libraries. Only set it you never plan to distribute the resulting binaries" OFF) OPTION(NOT_FOR_DISTRIBUTION "Allow linking with GPLv2-incompatible system libraries. Only set it you never plan to distribute the resulting binaries" OFF)
INCLUDE(check_compiler_flag) INCLUDE(check_compiler_flag)
INCLUDE(check_linker_flag)
OPTION(WITH_ASAN "Enable address sanitizer" OFF) OPTION(WITH_ASAN "Enable address sanitizer" OFF)
@ -239,7 +240,7 @@ OPTION(SECURITY_HARDENED "Use security-enhancing compiler features (stack protec
IF(SECURITY_HARDENED AND NOT WITH_ASAN AND NOT WITH_UBSAN AND NOT WITH_TSAN) IF(SECURITY_HARDENED AND NOT WITH_ASAN AND NOT WITH_UBSAN AND NOT WITH_TSAN)
# security-enhancing flags # security-enhancing flags
MY_CHECK_AND_SET_COMPILER_FLAG("-pie -fPIC") MY_CHECK_AND_SET_COMPILER_FLAG("-pie -fPIC")
MY_CHECK_AND_SET_COMPILER_FLAG("-Wl,-z,relro,-z,now") MY_CHECK_AND_SET_LINKER_FLAG("-Wl,-z,relro,-z,now")
MY_CHECK_AND_SET_COMPILER_FLAG("-fstack-protector --param=ssp-buffer-size=4") MY_CHECK_AND_SET_COMPILER_FLAG("-fstack-protector --param=ssp-buffer-size=4")
MY_CHECK_AND_SET_COMPILER_FLAG("-D_FORTIFY_SOURCE=2" RELEASE RELWITHDEBINFO) MY_CHECK_AND_SET_COMPILER_FLAG("-D_FORTIFY_SOURCE=2" RELEASE RELWITHDEBINFO)
ENDIF() ENDIF()

View File

@ -0,0 +1,27 @@
include(CheckCXXSourceCompiles)
FUNCTION(MY_CHECK_AND_SET_LINKER_FLAG flag_to_set)
# Let's avoid expensive compiler tests on Windows:
IF(WIN32)
RETURN()
ENDIF()
STRING(REGEX REPLACE "[-,= +]" "_" result "HAVE_LINK_FLAG_${flag_to_set}")
SET(SAVE_CMAKE_REQUIRED_LINK_OPTIONS "${CMAKE_REQUIRED_LINK_OPTIONS}")
STRING(REGEX REPLACE "^-Wno-" "-W" flag_to_check ${flag_to_set})
SET(CMAKE_REQUIRED_LINK_OPTIONS ${CMAKE_REQUIRED_LINK_OPTIONS} ${flag_to_check})
CHECK_CXX_SOURCE_COMPILES("int main(void) { return 0; }" ${result})
SET(CMAKE_REQUIRED_LINK_OPTIONS "${SAVE_CMAKE_REQUIRED_LINK_OPTIONS}")
IF (${result})
FOREACH(linktype SHARED MODULE EXE)
IF(ARGN)
FOREACH(type ${ARGN})
SET(CMAKE_${linktype}_LINKER_FLAGS_${type}
"${CMAKE_${linktype}_LINKER_FLAGS_${type}} ${flag_to_set}" PARENT_SCOPE)
ENDFOREACH()
ELSE()
SET(CMAKE_${linktype}_LINKER_FLAGS
"${CMAKE_${linktype}_LINKER_FLAGS} ${flag_to_set}" PARENT_SCOPE)
ENDIF()
ENDFOREACH()
ENDIF()
ENDFUNCTION()

View File

@ -1897,6 +1897,24 @@ ALTER TABLE t1 EXCHANGE PARTITION p0 WITH TABLE t2;
SELECT * FROM t1 PARTITION (p0); SELECT * FROM t1 PARTITION (p0);
i i
UNLOCK TABLES; UNLOCK TABLES;
DROP TABLE t1;
#
# MDEV-18371 Server crashes in ha_innobase::cmp_ref upon UPDATE with PARTITION clause.
#
CREATE TABLE t1 (a INT, b INT, KEY (a)) ENGINE=InnoDB PARTITION BY KEY(b) PARTITIONS 4;
INSERT INTO t1 VALUES (3,0),(8,2),(7,8),(3,4),(2,4),(0,7),(4,3),(3,6);
FLUSH TABLES;
UPDATE t1 PARTITION (p3,p1) SET a = 2 WHERE a = 3;
SELECT * FROM t1;
a b
2 0
7 8
2 4
2 4
0 7
4 3
8 2
2 6
DROP TABLE t1, t2; DROP TABLE t1, t2;
# #
# MDEV-18982: INSERT using explicit patition pruning with column list # MDEV-18982: INSERT using explicit patition pruning with column list

View File

@ -874,6 +874,18 @@ SELECT * FROM t1 PARTITION (p0);
ALTER TABLE t1 EXCHANGE PARTITION p0 WITH TABLE t2; ALTER TABLE t1 EXCHANGE PARTITION p0 WITH TABLE t2;
SELECT * FROM t1 PARTITION (p0); SELECT * FROM t1 PARTITION (p0);
UNLOCK TABLES; UNLOCK TABLES;
DROP TABLE t1;
--echo #
--echo # MDEV-18371 Server crashes in ha_innobase::cmp_ref upon UPDATE with PARTITION clause.
--echo #
CREATE TABLE t1 (a INT, b INT, KEY (a)) ENGINE=InnoDB PARTITION BY KEY(b) PARTITIONS 4;
INSERT INTO t1 VALUES (3,0),(8,2),(7,8),(3,4),(2,4),(0,7),(4,3),(3,6);
FLUSH TABLES;
UPDATE t1 PARTITION (p3,p1) SET a = 2 WHERE a = 3;
SELECT * FROM t1;
# Cleanup # Cleanup
DROP TABLE t1, t2; DROP TABLE t1, t2;

View File

@ -926,4 +926,28 @@ set global innodb_stats_persistent= @innodb_stats_persistent_save;
set global innodb_stats_persistent_sample_pages= set global innodb_stats_persistent_sample_pages=
@innodb_stats_persistent_sample_pages_save; @innodb_stats_persistent_sample_pages_save;
set optimizer_switch=@save_optimizer_switch_for_stat_tables_test; set optimizer_switch=@save_optimizer_switch_for_stat_tables_test;
#
# MDEV-22851: Engine independent index statistics are incorrect for large tables on Windows.
#
CREATE TABLE t1(a INT) ENGINE=INNODB;
INSERT INTO t1 SELECT 1 FROM seq_1_to_60000;
SET @save_use_stat_tables= @@use_stat_tables;
SET use_stat_tables= preferably;
SELECT count(*) FROM t1;
count(*)
60000
CREATE INDEX idx ON t1(a);
ANALYZE TABLE t1 PERSISTENT FOR COLUMNS (a) INDEXES (idx);
Table Op Msg_type Msg_text
test.t1 analyze status Engine-independent statistics collected
test.t1 analyze status OK
SELECT * FROM mysql.index_stats where table_name='t1';
db_name table_name index_name prefix_arity avg_frequency
test t1 idx 1 60000.0000
SELECT * FROM mysql.column_stats where table_name='t1';
db_name table_name column_name min_value max_value nulls_ratio avg_length avg_frequency hist_size hist_type histogram
test t1 a 1 1 0.0000 4.0000 60000.0000 0 NULL NULL
SET use_stat_tables= @save_use_stat_tables;
DROP TABLE t1;
# end of 10.1 tests
SET SESSION STORAGE_ENGINE=DEFAULT; SET SESSION STORAGE_ENGINE=DEFAULT;

View File

@ -1,4 +1,5 @@
--source include/have_innodb.inc --source include/have_innodb.inc
--source include/have_sequence.inc
SET SESSION STORAGE_ENGINE='InnoDB'; SET SESSION STORAGE_ENGINE='InnoDB';
@ -18,4 +19,23 @@ set global innodb_stats_persistent_sample_pages=
set optimizer_switch=@save_optimizer_switch_for_stat_tables_test; set optimizer_switch=@save_optimizer_switch_for_stat_tables_test;
--echo #
--echo # MDEV-22851: Engine independent index statistics are incorrect for large tables on Windows.
--echo #
CREATE TABLE t1(a INT) ENGINE=INNODB;
INSERT INTO t1 SELECT 1 FROM seq_1_to_60000;
SET @save_use_stat_tables= @@use_stat_tables;
SET use_stat_tables= preferably;
SELECT count(*) FROM t1;
CREATE INDEX idx ON t1(a);
ANALYZE TABLE t1 PERSISTENT FOR COLUMNS (a) INDEXES (idx);
SELECT * FROM mysql.index_stats where table_name='t1';
SELECT * FROM mysql.column_stats where table_name='t1';
SET use_stat_tables= @save_use_stat_tables;
DROP TABLE t1;
--echo # end of 10.1 tests
SET SESSION STORAGE_ENGINE=DEFAULT; SET SESSION STORAGE_ENGINE=DEFAULT;

View File

@ -5621,8 +5621,9 @@ extern "C" int cmp_key_rowid_part_id(void *ptr, uchar *ref1, uchar *ref2)
{ {
return res; return res;
} }
if ((res= file->m_file[0]->cmp_ref(ref1 + PARTITION_BYTES_IN_POS + file->m_rec_length, if ((res= file->get_open_file_sample()->cmp_ref(ref1 +
ref2 + PARTITION_BYTES_IN_POS + file->m_rec_length))) PARTITION_BYTES_IN_POS + file->m_rec_length,
ref2 + PARTITION_BYTES_IN_POS + file->m_rec_length)))
{ {
return res; return res;
} }
@ -9654,7 +9655,7 @@ uint8 ha_partition::table_cache_type()
{ {
DBUG_ENTER("ha_partition::table_cache_type"); DBUG_ENTER("ha_partition::table_cache_type");
DBUG_RETURN(m_file[0]->table_cache_type()); DBUG_RETURN(get_open_file_sample()->table_cache_type());
} }

View File

@ -4444,8 +4444,10 @@ static int init_common_variables()
get corrupted if accesses with names of different case. get corrupted if accesses with names of different case.
*/ */
DBUG_PRINT("info", ("lower_case_table_names: %d", lower_case_table_names)); DBUG_PRINT("info", ("lower_case_table_names: %d", lower_case_table_names));
if(mysql_real_data_home_ptr == NULL || *mysql_real_data_home_ptr == 0)
mysql_real_data_home_ptr= mysql_real_data_home;
SYSVAR_AUTOSIZE(lower_case_file_system, SYSVAR_AUTOSIZE(lower_case_file_system,
test_if_case_insensitive(mysql_real_data_home)); test_if_case_insensitive(mysql_real_data_home_ptr));
if (!lower_case_table_names && lower_case_file_system == 1) if (!lower_case_table_names && lower_case_file_system == 1)
{ {
if (lower_case_table_names_used) if (lower_case_table_names_used)
@ -4462,7 +4464,7 @@ static int init_common_variables()
{ {
if (global_system_variables.log_warnings) if (global_system_variables.log_warnings)
sql_print_warning("Setting lower_case_table_names=2 because file " sql_print_warning("Setting lower_case_table_names=2 because file "
"system for %s is case insensitive", mysql_real_data_home); "system for %s is case insensitive", mysql_real_data_home_ptr);
SYSVAR_AUTOSIZE(lower_case_table_names, 2); SYSVAR_AUTOSIZE(lower_case_table_names, 2);
} }
} }
@ -4473,7 +4475,7 @@ static int init_common_variables()
sql_print_warning("lower_case_table_names was set to 2, even though your " sql_print_warning("lower_case_table_names was set to 2, even though your "
"the file system '%s' is case sensitive. Now setting " "the file system '%s' is case sensitive. Now setting "
"lower_case_table_names to 0 to avoid future problems.", "lower_case_table_names to 0 to avoid future problems.",
mysql_real_data_home); mysql_real_data_home_ptr);
SYSVAR_AUTOSIZE(lower_case_table_names, 0); SYSVAR_AUTOSIZE(lower_case_table_names, 0);
} }
else else

View File

@ -2118,8 +2118,8 @@ int alloc_statistics_for_table(THD* thd, TABLE *table)
sizeof(Index_statistics) * keys); sizeof(Index_statistics) * keys);
uint key_parts= table->s->ext_key_parts; uint key_parts= table->s->ext_key_parts;
ulong *idx_avg_frequency= (ulong*) alloc_root(&table->mem_root, ulonglong *idx_avg_frequency= (ulonglong*) alloc_root(&table->mem_root,
sizeof(ulong) * key_parts); sizeof(ulonglong) * key_parts);
uint columns= 0; uint columns= 0;
for (field_ptr= table->field; *field_ptr; field_ptr++) for (field_ptr= table->field; *field_ptr; field_ptr++)
@ -2164,7 +2164,7 @@ int alloc_statistics_for_table(THD* thd, TABLE *table)
} }
} }
memset(idx_avg_frequency, 0, sizeof(ulong) * key_parts); memset(idx_avg_frequency, 0, sizeof(ulonglong) * key_parts);
KEY *key_info, *end; KEY *key_info, *end;
for (key_info= table->key_info, end= key_info + table->s->keys; for (key_info= table->key_info, end= key_info + table->s->keys;
@ -2280,14 +2280,14 @@ static int alloc_statistics_for_table_share(THD* thd, TABLE_SHARE *table_share)
} }
uint key_parts= table_share->ext_key_parts; uint key_parts= table_share->ext_key_parts;
ulong *idx_avg_frequency= table_stats->idx_avg_frequency; ulonglong *idx_avg_frequency= table_stats->idx_avg_frequency;
if (!idx_avg_frequency) if (!idx_avg_frequency)
{ {
idx_avg_frequency= (ulong*) alloc_root(&stats_cb->mem_root, idx_avg_frequency= (ulonglong*) alloc_root(&stats_cb->mem_root,
sizeof(ulong) * key_parts); sizeof(ulonglong) * key_parts);
if (idx_avg_frequency) if (idx_avg_frequency)
{ {
memset(idx_avg_frequency, 0, sizeof(ulong) * key_parts); memset(idx_avg_frequency, 0, sizeof(ulonglong) * key_parts);
table_stats->idx_avg_frequency= idx_avg_frequency; table_stats->idx_avg_frequency= idx_avg_frequency;
for (key_info= table_share->key_info, end= key_info + keys; for (key_info= table_share->key_info, end= key_info + keys;
key_info < end; key_info < end;

View File

@ -294,7 +294,9 @@ public:
uchar *min_max_record_buffers; /* Record buffers for min/max values */ uchar *min_max_record_buffers; /* Record buffers for min/max values */
Column_statistics *column_stats; /* Array of statistical data for columns */ Column_statistics *column_stats; /* Array of statistical data for columns */
Index_statistics *index_stats; /* Array of statistical data for indexes */ Index_statistics *index_stats; /* Array of statistical data for indexes */
ulong *idx_avg_frequency; /* Array of records per key for index prefixes */
/* Array of records per key for index prefixes */
ulonglong *idx_avg_frequency;
uchar *histograms; /* Sequence of histograms */ uchar *histograms; /* Sequence of histograms */
}; };
@ -346,7 +348,7 @@ private:
CHAR values are stripped of trailing spaces. CHAR values are stripped of trailing spaces.
Flexible values are stripped of their length prefixes. Flexible values are stripped of their length prefixes.
*/ */
ulong avg_length; ulonglong avg_length;
/* /*
The ratio N/D multiplied by the scale factor Scale_factor_avg_frequency, The ratio N/D multiplied by the scale factor Scale_factor_avg_frequency,
@ -354,7 +356,7 @@ private:
N is the number of rows with not null value in the column, N is the number of rows with not null value in the column,
D the number of distinct values among them D the number of distinct values among them
*/ */
ulong avg_frequency; ulonglong avg_frequency;
public: public:
@ -404,12 +406,12 @@ public:
void set_avg_length (double val) void set_avg_length (double val)
{ {
avg_length= (ulong) (val * Scale_factor_avg_length); avg_length= (ulonglong) (val * Scale_factor_avg_length);
} }
void set_avg_frequency (double val) void set_avg_frequency (double val)
{ {
avg_frequency= (ulong) (val * Scale_factor_avg_frequency); avg_frequency= (ulonglong) (val * Scale_factor_avg_frequency);
} }
bool min_max_values_are_provided() bool min_max_values_are_provided()
@ -448,11 +450,11 @@ private:
in the first k components, and D is the number of distinct in the first k components, and D is the number of distinct
k-component prefixes among them k-component prefixes among them
*/ */
ulong *avg_frequency; ulonglong *avg_frequency;
public: public:
void init_avg_frequency(ulong *ptr) { avg_frequency= ptr; } void init_avg_frequency(ulonglong *ptr) { avg_frequency= ptr; }
bool avg_frequency_is_inited() { return avg_frequency != NULL; } bool avg_frequency_is_inited() { return avg_frequency != NULL; }
@ -463,7 +465,7 @@ public:
void set_avg_frequency(uint i, double val) void set_avg_frequency(uint i, double val)
{ {
avg_frequency[i]= (ulong) (val * Scale_factor_avg_frequency); avg_frequency[i]= (ulonglong) (val * Scale_factor_avg_frequency);
} }
}; };

View File

@ -564,15 +564,17 @@ buf_dblwr_process()
const ulint page_no = page_get_page_no(page); const ulint page_no = page_get_page_no(page);
const page_id_t page_id(space_id, page_no); const page_id_t page_id(space_id, page_no);
if (page_no >= space->size) { if (UNIV_UNLIKELY(page_no >= space->size)) {
/* Do not report the warning for undo /* Do not report the warning for undo
tablespaces, because they can be truncated in place. */ tablespaces, because they can be truncated in place. */
if (!srv_is_undo_tablespace(space_id)) { if (!srv_is_undo_tablespace(space_id)) {
ib::warn() << "A copy of page " << page_id ib::warn() << "A copy of page " << page_no
<< " in the doublewrite buffer slot " << " in the doublewrite buffer slot "
<< page_no_dblwr << page_no_dblwr
<< " is not within space bounds"; << " is beyond the end of tablespace "
<< space->name
<< " (" << space->size << " pages)";
} }
continue; continue;
} }

View File

@ -1359,9 +1359,7 @@ buf_flush_try_neighbors(
} }
} }
if (high > space->size) { high = space->max_page_number_for_io(high);
high = space->size;
}
DBUG_PRINT("ib_buf", ("flush %u:%u..%u", DBUG_PRINT("ib_buf", ("flush %u:%u..%u",
page_id.space(), page_id.space(),

View File

@ -264,10 +264,7 @@ buf_read_ahead_random(const page_id_t page_id, ulint zip_size, bool ibuf)
high = (page_id.page_no() / buf_read_ahead_random_area + 1) high = (page_id.page_no() / buf_read_ahead_random_area + 1)
* buf_read_ahead_random_area; * buf_read_ahead_random_area;
/* If DISCARD + IMPORT changes the actual .ibd file meanwhile, we
do not try to read outside the bounds of the tablespace! */
if (fil_space_t* space = fil_space_acquire(page_id.space())) { if (fil_space_t* space = fil_space_acquire(page_id.space())) {
#ifdef UNIV_DEBUG #ifdef UNIV_DEBUG
if (srv_file_per_table) { if (srv_file_per_table) {
ulint size = 0; ulint size = 0;
@ -286,9 +283,7 @@ buf_read_ahead_random(const page_id_t page_id, ulint zip_size, bool ibuf)
} }
#endif /* UNIV_DEBUG */ #endif /* UNIV_DEBUG */
if (high > space->size) { high = space->max_page_number_for_io(high);
high = space->size;
}
space->release(); space->release();
} else { } else {
return(0); return(0);
@ -549,13 +544,10 @@ buf_read_ahead_linear(const page_id_t page_id, ulint zip_size, bool ibuf)
return(0); return(0);
} }
/* Remember the tablespace version before we ask te tablespace size
below: if DISCARD + IMPORT changes the actual .ibd file meanwhile, we
do not try to read outside the bounds of the tablespace! */
ulint space_size; ulint space_size;
if (fil_space_t* space = fil_space_acquire(page_id.space())) { if (fil_space_t* space = fil_space_acquire(page_id.space())) {
space_size = space->size; space_size = space->committed_size;
space->release(); space->release();
if (high > space_size) { if (high > space_size) {

View File

@ -358,34 +358,6 @@ fil_space_get(
return(space); return(space);
} }
/** Returns the latch of a file space.
@param[in] id space id
@param[out] flags tablespace flags
@return latch protecting storage allocation */
rw_lock_t*
fil_space_get_latch(
ulint id,
ulint* flags)
{
fil_space_t* space;
ut_ad(fil_system.is_initialised());
mutex_enter(&fil_system.mutex);
space = fil_space_get_by_id(id);
ut_a(space);
if (flags) {
*flags = space->flags;
}
mutex_exit(&fil_system.mutex);
return(&(space->latch));
}
/**********************************************************************//** /**********************************************************************//**
Checks if all the file nodes in a space are flushed. Checks if all the file nodes in a space are flushed.
@return true if all are flushed */ @return true if all are flushed */
@ -981,6 +953,9 @@ fil_mutex_enter_and_prepare_for_io(
ut_a(success); ut_a(success);
/* InnoDB data files cannot shrink. */ /* InnoDB data files cannot shrink. */
ut_a(space->size >= size); ut_a(space->size >= size);
if (size > space->committed_size) {
space->committed_size = size;
}
/* There could be multiple concurrent I/O requests for /* There could be multiple concurrent I/O requests for
this tablespace (multiple threads trying to extend this tablespace (multiple threads trying to extend

View File

@ -386,7 +386,7 @@ xdes_get_descriptor_with_space_hdr(
ulint size; ulint size;
ulint descr_page_no; ulint descr_page_no;
page_t* descr_page; page_t* descr_page;
ut_ad(mtr_memo_contains(mtr, &space->latch, MTR_MEMO_X_LOCK)); ut_ad(mtr_memo_contains(mtr, space, MTR_MEMO_SPACE_X_LOCK));
ut_ad(mtr_memo_contains_page(mtr, sp_header, MTR_MEMO_PAGE_SX_FIX)); ut_ad(mtr_memo_contains_page(mtr, sp_header, MTR_MEMO_PAGE_SX_FIX));
ut_ad(page_offset(sp_header) == FSP_HEADER_OFFSET); ut_ad(page_offset(sp_header) == FSP_HEADER_OFFSET);
/* Read free limit and space size */ /* Read free limit and space size */
@ -523,7 +523,7 @@ xdes_lst_get_descriptor(
fil_addr_t lst_node, fil_addr_t lst_node,
mtr_t* mtr) mtr_t* mtr)
{ {
ut_ad(mtr_memo_contains(mtr, &space->latch, MTR_MEMO_X_LOCK)); ut_ad(mtr_memo_contains(mtr, space, MTR_MEMO_SPACE_X_LOCK));
return fut_get_ptr(space->id, space->zip_size(), return fut_get_ptr(space->id, space->zip_size(),
lst_node, RW_SX_LATCH, mtr) lst_node, RW_SX_LATCH, mtr)
- XDES_FLST_NODE; - XDES_FLST_NODE;
@ -977,35 +977,23 @@ fsp_fill_free_list(
MLOG_2BYTES, mtr); MLOG_2BYTES, mtr);
} }
/* Initialize the ibuf bitmap page in a separate
mini-transaction because it is low in the latching
order, and we must be able to release its latch.
Note: Insert-Buffering is disabled for tables that
reside in the temp-tablespace. */
if (space->purpose != FIL_TYPE_TEMPORARY) { if (space->purpose != FIL_TYPE_TEMPORARY) {
mtr_t ibuf_mtr;
mtr_start(&ibuf_mtr);
ibuf_mtr.set_named_space(space);
const page_id_t page_id( const page_id_t page_id(
space->id, space->id,
i + FSP_IBUF_BITMAP_OFFSET); i + FSP_IBUF_BITMAP_OFFSET);
block = buf_page_create( block = buf_page_create(
page_id, zip_size, &ibuf_mtr); page_id, zip_size, mtr);
buf_page_get( buf_page_get(
page_id, zip_size, RW_SX_LATCH, page_id, zip_size, RW_SX_LATCH, mtr);
&ibuf_mtr);
buf_block_dbg_add_level(block, SYNC_FSP_PAGE); buf_block_dbg_add_level(block, SYNC_FSP_PAGE);
fsp_init_file_page(space, block, &ibuf_mtr); fsp_init_file_page(space, block, mtr);
mlog_write_ulint(block->frame + FIL_PAGE_TYPE, mlog_write_ulint(block->frame + FIL_PAGE_TYPE,
FIL_PAGE_IBUF_BITMAP, FIL_PAGE_IBUF_BITMAP,
MLOG_2BYTES, &ibuf_mtr); MLOG_2BYTES, mtr);
mtr_commit(&ibuf_mtr);
} }
} }
@ -1413,7 +1401,7 @@ static void fsp_free_extent(fil_space_t* space, page_no_t offset, mtr_t* mtr)
fsp_header_t* header; fsp_header_t* header;
xdes_t* descr; xdes_t* descr;
ut_ad(mtr_memo_contains(mtr, &space->latch, MTR_MEMO_X_LOCK)); ut_ad(mtr_memo_contains(mtr, space, MTR_MEMO_SPACE_X_LOCK));
header = fsp_get_space_header(space, mtr); header = fsp_get_space_header(space, mtr);

View File

@ -134,6 +134,8 @@ struct fil_space_t
/*!< recovered tablespace size in pages; /*!< recovered tablespace size in pages;
0 if no size change was read from the redo log, 0 if no size change was read from the redo log,
or if the size change was implemented */ or if the size change was implemented */
/** the committed size of the tablespace in pages */
Atomic_relaxed<ulint> committed_size;
ulint n_reserved_extents; ulint n_reserved_extents;
/*!< number of reserved free extents for /*!< number of reserved free extents for
ongoing operations like B-tree page split */ ongoing operations like B-tree page split */
@ -184,6 +186,15 @@ struct fil_space_t
/** @return whether the tablespace is about to be dropped */ /** @return whether the tablespace is about to be dropped */
bool is_stopping() const { return stop_new_ops; } bool is_stopping() const { return stop_new_ops; }
/** Clamp a page number for batched I/O, such as read-ahead.
@param offset page number limit
@return offset clamped to the tablespace size */
ulint max_page_number_for_io(ulint offset) const
{
const ulint limit= committed_size;
return limit > offset ? offset : limit;
}
/** @return whether doublewrite buffering is needed */ /** @return whether doublewrite buffering is needed */
bool use_doublewrite() const bool use_doublewrite() const
{ {
@ -994,15 +1005,6 @@ extern fil_system_t fil_system;
#include "fil0crypt.h" #include "fil0crypt.h"
/** Returns the latch of a file space.
@param[in] id space id
@param[out] flags tablespace flags
@return latch protecting storage allocation */
rw_lock_t*
fil_space_get_latch(
ulint id,
ulint* flags);
/** Create a space memory object and put it to the fil_system hash table. /** Create a space memory object and put it to the fil_system hash table.
Error messages are issued to the server log. Error messages are issued to the server log.
@param[in] name tablespace name @param[in] name tablespace name

View File

@ -2,7 +2,7 @@
Copyright (c) 1995, 2017, Oracle and/or its affiliates. All Rights Reserved. Copyright (c) 1995, 2017, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2012, Facebook Inc. Copyright (c) 2012, Facebook Inc.
Copyright (c) 2013, 2019, MariaDB Corporation. Copyright (c) 2013, 2020, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify it under This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software the terms of the GNU General Public License as published by the Free Software
@ -296,7 +296,8 @@ struct mtr_t {
ut_ad(space->purpose == FIL_TYPE_TEMPORARY ut_ad(space->purpose == FIL_TYPE_TEMPORARY
|| space->purpose == FIL_TYPE_IMPORT || space->purpose == FIL_TYPE_IMPORT
|| space->purpose == FIL_TYPE_TABLESPACE); || space->purpose == FIL_TYPE_TABLESPACE);
x_lock(&space->latch, file, line); memo_push(space, MTR_MEMO_SPACE_X_LOCK);
rw_lock_x_lock_inline(&space->latch, 0, file, line);
} }
/** Release an object in the memo stack. /** Release an object in the memo stack.

View File

@ -1,7 +1,7 @@
/***************************************************************************** /*****************************************************************************
Copyright (c) 1995, 2014, Oracle and/or its affiliates. All Rights Reserved. Copyright (c) 1995, 2014, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2017, 2019, MariaDB Corporation. Copyright (c) 2017, 2020, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify it under This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software the terms of the GNU General Public License as published by the Free Software
@ -48,7 +48,7 @@ mtr_t::memo_push(void* object, mtr_memo_type_t type)
ut_ad(is_active()); ut_ad(is_active());
ut_ad(object != NULL); ut_ad(object != NULL);
ut_ad(type >= MTR_MEMO_PAGE_S_FIX); ut_ad(type >= MTR_MEMO_PAGE_S_FIX);
ut_ad(type <= MTR_MEMO_SX_LOCK); ut_ad(type <= MTR_MEMO_SPACE_X_LOCK);
ut_ad(ut_is_2pow(type)); ut_ad(ut_is_2pow(type));
/* If this mtr has x-fixed a clean page then we set /* If this mtr has x-fixed a clean page then we set

View File

@ -1,7 +1,7 @@
/***************************************************************************** /*****************************************************************************
Copyright (c) 1995, 2015, Oracle and/or its affiliates. All Rights Reserved. Copyright (c) 1995, 2015, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2017, 2019, MariaDB Corporation. Copyright (c) 2017, 2020, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify it under This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software the terms of the GNU General Public License as published by the Free Software
@ -274,7 +274,10 @@ enum mtr_memo_type_t {
MTR_MEMO_X_LOCK = RW_X_LATCH << 5, MTR_MEMO_X_LOCK = RW_X_LATCH << 5,
MTR_MEMO_SX_LOCK = RW_SX_LATCH << 5 MTR_MEMO_SX_LOCK = RW_SX_LATCH << 5,
/** acquire X-latch on fil_space_t::latch */
MTR_MEMO_SPACE_X_LOCK = MTR_MEMO_SX_LOCK << 1
}; };
#endif /* !UNIV_CHECKSUM */ #endif /* !UNIV_CHECKSUM */

View File

@ -1,7 +1,7 @@
/***************************************************************************** /*****************************************************************************
Copyright (c) 1995, 2017, Oracle and/or its affiliates. All Rights Reserved. Copyright (c) 1995, 2017, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2017, 2019, MariaDB Corporation. Copyright (c) 2017, 2020, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify it under This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software the terms of the GNU General Public License as published by the Free Software
@ -218,6 +218,13 @@ static void memo_slot_release(mtr_memo_slot_t *slot)
case MTR_MEMO_SX_LOCK: case MTR_MEMO_SX_LOCK:
rw_lock_sx_unlock(reinterpret_cast<rw_lock_t*>(slot->object)); rw_lock_sx_unlock(reinterpret_cast<rw_lock_t*>(slot->object));
break; break;
case MTR_MEMO_SPACE_X_LOCK:
{
fil_space_t *space= static_cast<fil_space_t*>(slot->object);
space->committed_size= space->size;
rw_lock_x_unlock(&space->latch);
}
break;
case MTR_MEMO_X_LOCK: case MTR_MEMO_X_LOCK:
rw_lock_x_unlock(reinterpret_cast<rw_lock_t*>(slot->object)); rw_lock_x_unlock(reinterpret_cast<rw_lock_t*>(slot->object));
break; break;
@ -251,6 +258,13 @@ struct ReleaseLatches {
case MTR_MEMO_S_LOCK: case MTR_MEMO_S_LOCK:
rw_lock_s_unlock(reinterpret_cast<rw_lock_t*>(slot->object)); rw_lock_s_unlock(reinterpret_cast<rw_lock_t*>(slot->object));
break; break;
case MTR_MEMO_SPACE_X_LOCK:
{
fil_space_t *space= static_cast<fil_space_t*>(slot->object);
space->committed_size= space->size;
rw_lock_x_unlock(&space->latch);
}
break;
case MTR_MEMO_X_LOCK: case MTR_MEMO_X_LOCK:
rw_lock_x_unlock(reinterpret_cast<rw_lock_t*>(slot->object)); rw_lock_x_unlock(reinterpret_cast<rw_lock_t*>(slot->object));
break; break;

View File

@ -7839,13 +7839,17 @@ invalid:
space->flags = (space->flags & FSP_FLAGS_MEM_MASK) | flags; space->flags = (space->flags & FSP_FLAGS_MEM_MASK) | flags;
this->size = ulint(size_bytes / psize); this->size = ulint(size_bytes / psize);
space->size += this->size; space->committed_size = space->size += this->size;
} else if (space->id != TRX_SYS_SPACE || space->size_in_header) { } else if (space->id != TRX_SYS_SPACE || space->size_in_header) {
/* If this is not the first-time open, do nothing. /* If this is not the first-time open, do nothing.
For the system tablespace, we always get invoked as For the system tablespace, we always get invoked as
first=false, so we detect the true first-time-open based first=false, so we detect the true first-time-open based
on size_in_header and proceed to initiailze the data. */ on size_in_header and proceed to initialize the data. */
return true; return true;
} else {
/* Initialize the size of predefined tablespaces
to FSP_SIZE. */
space->committed_size = size;
} }
ut_ad(space->free_limit == 0 || space->free_limit == free_limit); ut_ad(space->free_limit == 0 || space->free_limit == free_limit);

View File

@ -530,14 +530,6 @@ protected:
/** Space id of the file being iterated over. */ /** Space id of the file being iterated over. */
ulint m_space; ulint m_space;
/** Minimum page number for which the free list has not been
initialized: the pages >= this limit are, by definition, free;
note that in a single-table tablespace where size < 64 pages,
this number is 64, i.e., we have initialized the space about
the first extent, but have not physically allocted those pages
to the file. @see FSP_LIMIT. */
ulint m_free_limit;
/** Current size of the space in pages */ /** Current size of the space in pages */
ulint m_size; ulint m_size;
@ -597,7 +589,6 @@ AbstractCallback::init(
} }
m_size = mach_read_from_4(page + FSP_SIZE); m_size = mach_read_from_4(page + FSP_SIZE);
m_free_limit = mach_read_from_4(page + FSP_FREE_LIMIT);
if (m_space == ULINT_UNDEFINED) { if (m_space == ULINT_UNDEFINED) {
m_space = mach_read_from_4(FSP_HEADER_OFFSET + FSP_SPACE_ID m_space = mach_read_from_4(FSP_HEADER_OFFSET + FSP_SPACE_ID
+ page); + page);

View File

@ -699,6 +699,7 @@ static bool srv_undo_tablespace_open(const char* name, ulint space_id,
if (create_new_db) { if (create_new_db) {
space->size = file->size = ulint(size >> srv_page_size_shift); space->size = file->size = ulint(size >> srv_page_size_shift);
space->size_in_header = SRV_UNDO_TABLESPACE_SIZE_IN_PAGES; space->size_in_header = SRV_UNDO_TABLESPACE_SIZE_IN_PAGES;
space->committed_size = SRV_UNDO_TABLESPACE_SIZE_IN_PAGES;
} else { } else {
success = file->read_page0(true); success = file->read_page0(true);
if (!success) { if (!success) {
@ -1920,6 +1921,8 @@ files_checked:
if (sum_of_new_sizes > 0) { if (sum_of_new_sizes > 0) {
/* New data file(s) were added */ /* New data file(s) were added */
mtr.start(); mtr.start();
mtr.x_lock_space(fil_system.sys_space,
__FILE__, __LINE__);
buf_block_t* block = buf_page_get( buf_block_t* block = buf_page_get(
page_id_t(0, 0), 0, page_id_t(0, 0), 0,
RW_SX_LATCH, &mtr); RW_SX_LATCH, &mtr);

View File

@ -1,7 +1,7 @@
/***************************************************************************** /*****************************************************************************
Copyright (c) 1996, 2016, Oracle and/or its affiliates. All Rights Reserved. Copyright (c) 1996, 2016, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2017, 2019, MariaDB Corporation. Copyright (c) 2017, 2020, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify it under This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software the terms of the GNU General Public License as published by the Free Software
@ -308,7 +308,7 @@ trx_rseg_header_create(
{ {
buf_block_t* block; buf_block_t* block;
ut_ad(mtr_memo_contains(mtr, &space->latch, MTR_MEMO_X_LOCK)); ut_ad(mtr_memo_contains(mtr, space, MTR_MEMO_SPACE_X_LOCK));
ut_ad(!sys_header == (space == fil_system.temp_space)); ut_ad(!sys_header == (space == fil_system.temp_space));
/* Allocate a new file segment for the rollback segment */ /* Allocate a new file segment for the rollback segment */

View File

@ -1,7 +1,7 @@
/***************************************************************************** /*****************************************************************************
Copyright (c) 1996, 2017, Oracle and/or its affiliates. All Rights Reserved. Copyright (c) 1996, 2017, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2017, 2019, MariaDB Corporation. Copyright (c) 2017, 2020, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify it under This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software the terms of the GNU General Public License as published by the Free Software