Commit acc58fd8 authored by Marko Mäkelä's avatar Marko Mäkelä

Merge 10.2 into 10.3

parents 2cae58f8 ca9276e3
# Copyright (c) 2006, 2017, Oracle and/or its affiliates. # Copyright (c) 2006, 2017, Oracle and/or its affiliates.
# Copyright (c) 2008, 2019, MariaDB Corporation. # Copyright (c) 2008, 2020, MariaDB Corporation.
# #
# This program is free software; you can redistribute it and/or modify # This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by # it under the terms of the GNU General Public License as published by
...@@ -183,6 +183,7 @@ ENDIF() ...@@ -183,6 +183,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)
...@@ -245,7 +246,7 @@ IF(NOT WITH_TSAN) ...@@ -245,7 +246,7 @@ IF(NOT WITH_TSAN)
ENDIF() ENDIF()
# 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()
......
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()
...@@ -855,4 +855,28 @@ drop table t1; ...@@ -855,4 +855,28 @@ drop table t1;
# please keep this at the last # please keep this at the last
set @@global.histogram_size=@save_histogram_size; set @@global.histogram_size=@save_histogram_size;
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;
--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';
...@@ -9,4 +10,23 @@ set optimizer_switch='extended_keys=on'; ...@@ -9,4 +10,23 @@ set optimizer_switch='extended_keys=on';
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;
...@@ -4734,8 +4734,10 @@ static int init_common_variables() ...@@ -4734,8 +4734,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)
...@@ -4752,7 +4754,7 @@ static int init_common_variables() ...@@ -4752,7 +4754,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);
} }
} }
...@@ -4763,7 +4765,7 @@ static int init_common_variables() ...@@ -4763,7 +4765,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
......
...@@ -2106,8 +2106,8 @@ int alloc_statistics_for_table(THD* thd, TABLE *table) ...@@ -2106,8 +2106,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++)
...@@ -2152,7 +2152,7 @@ int alloc_statistics_for_table(THD* thd, TABLE *table) ...@@ -2152,7 +2152,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;
...@@ -2268,14 +2268,14 @@ static int alloc_statistics_for_table_share(THD* thd, TABLE_SHARE *table_share) ...@@ -2268,14 +2268,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;
......
...@@ -267,7 +267,9 @@ class Table_statistics ...@@ -267,7 +267,9 @@ class Table_statistics
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 */
}; };
...@@ -319,7 +321,7 @@ class Column_statistics ...@@ -319,7 +321,7 @@ class Column_statistics
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,
...@@ -327,7 +329,7 @@ class Column_statistics ...@@ -327,7 +329,7 @@ class Column_statistics
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:
...@@ -377,12 +379,12 @@ class Column_statistics ...@@ -377,12 +379,12 @@ class Column_statistics
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()
...@@ -421,11 +423,11 @@ class Index_statistics ...@@ -421,11 +423,11 @@ class Index_statistics
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; }
...@@ -436,7 +438,7 @@ class Index_statistics ...@@ -436,7 +438,7 @@ class Index_statistics
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);
} }
}; };
......
...@@ -563,7 +563,7 @@ buf_dblwr_process() ...@@ -563,7 +563,7 @@ 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 if the tablespace /* Do not report the warning if the tablespace
is scheduled for truncation or was truncated is scheduled for truncation or was truncated
...@@ -571,10 +571,12 @@ buf_dblwr_process() ...@@ -571,10 +571,12 @@ buf_dblwr_process()
if (!srv_is_tablespace_truncated(space_id) if (!srv_is_tablespace_truncated(space_id)
&& !srv_was_tablespace_truncated(space) && !srv_was_tablespace_truncated(space)
&& !srv_is_undo_tablespace(space_id)) { && !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;
} }
......
...@@ -1393,9 +1393,11 @@ buf_flush_try_neighbors( ...@@ -1393,9 +1393,11 @@ buf_flush_try_neighbors(
} }
} }
const ulint space_size = fil_space_get_size(page_id.space()); if (fil_space_t *s = fil_space_acquire_for_io(page_id.space())) {
if (high > space_size) { high = s->max_page_number_for_io(high);
high = space_size; s->release_for_io();
} else {
return 0;
} }
DBUG_PRINT("ib_buf", ("flush %u:%u..%u", DBUG_PRINT("ib_buf", ("flush %u:%u..%u",
......
...@@ -279,11 +279,7 @@ buf_read_ahead_random( ...@@ -279,11 +279,7 @@ buf_read_ahead_random(
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;
/* Remember the tablespace version before we ask the tablespace size
below: 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;
...@@ -301,9 +297,7 @@ buf_read_ahead_random( ...@@ -301,9 +297,7 @@ buf_read_ahead_random(
} }
#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);
...@@ -580,13 +574,10 @@ buf_read_ahead_linear( ...@@ -580,13 +574,10 @@ buf_read_ahead_linear(
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) {
......
...@@ -365,34 +365,6 @@ fil_space_get( ...@@ -365,34 +365,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));
}
/** Note that the tablespace has been imported. /** Note that the tablespace has been imported.
Initially, purpose=FIL_TYPE_IMPORT so that no redo log is Initially, purpose=FIL_TYPE_IMPORT so that no redo log is
written while the space ID is being updated in each page. */ written while the space ID is being updated in each page. */
...@@ -563,13 +535,17 @@ bool fil_node_t::read_page0(bool first) ...@@ -563,13 +535,17 @@ bool fil_node_t::read_page0(bool first)
} }
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);
...@@ -1090,6 +1066,9 @@ fil_mutex_enter_and_prepare_for_io( ...@@ -1090,6 +1066,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
......
...@@ -408,7 +408,7 @@ xdes_get_descriptor_with_space_hdr( ...@@ -408,7 +408,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 */
...@@ -552,7 +552,7 @@ xdes_lst_get_descriptor( ...@@ -552,7 +552,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));
ut_ad(page_size.equals_to(page_size_t(space->flags))); ut_ad(page_size.equals_to(page_size_t(space->flags)));
return(fut_get_ptr(space->id, page_size, lst_node, RW_SX_LATCH, mtr) return(fut_get_ptr(space->id, page_size, lst_node, RW_SX_LATCH, mtr)
- XDES_FLST_NODE); - XDES_FLST_NODE);
...@@ -1014,42 +1014,22 @@ fsp_fill_free_list( ...@@ -1014,42 +1014,22 @@ 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);
/* Avoid logging while truncate table
fix-up is active. */
if (srv_is_tablespace_truncated(space->id)) {
mtr_set_log_mode(
&ibuf_mtr, MTR_LOG_NO_REDO);
}
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, page_size, &ibuf_mtr); page_id, page_size, mtr);
buf_page_get( buf_page_get(
page_id, page_size, RW_SX_LATCH, page_id, page_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);
ibuf_bitmap_page_init(block, &ibuf_mtr);
mtr_commit(&ibuf_mtr); ibuf_bitmap_page_init(block, mtr);
} }
} }
...@@ -1471,7 +1451,7 @@ fsp_free_extent( ...@@ -1471,7 +1451,7 @@ fsp_free_extent(
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, page_size, mtr); header = fsp_get_space_header(space, page_size, mtr);
......
...@@ -130,6 +130,8 @@ struct fil_space_t : ilist_node<unflushed_spaces_tag_t>, ...@@ -130,6 +130,8 @@ struct fil_space_t : ilist_node<unflushed_spaces_tag_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 */
ulint committed_size;
ulint flags; /*!< FSP_SPACE_FLAGS and FSP_FLAGS_MEM_ flags; ulint flags; /*!< FSP_SPACE_FLAGS and FSP_FLAGS_MEM_ flags;
see fsp0types.h, see fsp0types.h,
fsp_flags_is_valid(), fsp_flags_is_valid(),
...@@ -184,6 +186,15 @@ struct fil_space_t : ilist_node<unflushed_spaces_tag_t>, ...@@ -184,6 +186,15 @@ struct fil_space_t : ilist_node<unflushed_spaces_tag_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
{ {
...@@ -676,15 +687,6 @@ extern fil_system_t fil_system; ...@@ -676,15 +687,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
......
...@@ -2,7 +2,7 @@ ...@@ -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
...@@ -307,7 +307,8 @@ struct mtr_t { ...@@ -307,7 +307,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.
......
/***************************************************************************** /*****************************************************************************
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) ...@@ -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
......
/***************************************************************************** /*****************************************************************************
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
...@@ -267,7 +267,10 @@ enum mtr_memo_type_t { ...@@ -267,7 +267,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 */
......
/***************************************************************************** /*****************************************************************************
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) ...@@ -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 { ...@@ -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;
......
...@@ -526,14 +526,6 @@ class AbstractCallback ...@@ -526,14 +526,6 @@ class AbstractCallback
/** 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;
...@@ -591,7 +583,6 @@ AbstractCallback::init( ...@@ -591,7 +583,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);
......
...@@ -691,6 +691,7 @@ static bool srv_undo_tablespace_open(const char* name, ulint space_id, ...@@ -691,6 +691,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) {
...@@ -2022,6 +2023,8 @@ dberr_t srv_start(bool create_new_db) ...@@ -2022,6 +2023,8 @@ dberr_t srv_start(bool create_new_db)
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), univ_page_size, page_id_t(0, 0), univ_page_size,
RW_SX_LATCH, &mtr); RW_SX_LATCH, &mtr);
......
/***************************************************************************** /*****************************************************************************
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
...@@ -299,7 +299,7 @@ trx_rseg_header_create( ...@@ -299,7 +299,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 */
......
/***************************************************************************** /*****************************************************************************
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
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment