summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarko Mäkelä <marko.makela@mariadb.com>2018-03-27 13:56:39 +0300
committerMarko Mäkelä <marko.makela@mariadb.com>2018-03-29 20:47:43 +0300
commitc02c329a8e9e024c1dc2399284b29a13d8d85783 (patch)
treef75055d42600d64d1434da4a7743ed94d147f3cf
parent330ecb906d0aa416a67a93332ef3ef446cfd0f32 (diff)
downloadmariadb-git-c02c329a8e9e024c1dc2399284b29a13d8d85783.tar.gz
MDEV-12266: Skip a lookup when checking free space
fsp_get_available_space_in_free_extents(): Declare the function static in the only caller, and take const fil_space_t& as a parameter.
-rw-r--r--storage/innobase/fsp/fsp0fsp.cc63
-rw-r--r--storage/innobase/handler/ha_innodb.cc126
-rw-r--r--storage/innobase/include/fsp0fsp.h18
3 files changed, 65 insertions, 142 deletions
diff --git a/storage/innobase/fsp/fsp0fsp.cc b/storage/innobase/fsp/fsp0fsp.cc
index cefcbaadc03..452f814fc29 100644
--- a/storage/innobase/fsp/fsp0fsp.cc
+++ b/storage/innobase/fsp/fsp0fsp.cc
@@ -2815,69 +2815,6 @@ try_to_extend:
return(false);
}
-/** Calculate how many KiB of new data we will be able to insert to the
-tablespace without running out of space.
-@param[in] space_id tablespace ID
-@return available space in KiB
-@retval UINTMAX_MAX if unknown */
-uintmax_t
-fsp_get_available_space_in_free_extents(
- ulint space_id)
-{
- FilSpace space(space_id);
- if (space() == NULL) {
- return(UINTMAX_MAX);
- }
-
- return(fsp_get_available_space_in_free_extents(space));
-}
-
-/** Calculate how many KiB of new data we will be able to insert to the
-tablespace without running out of space. Start with a space object that has
-been acquired by the caller who holds it for the calculation,
-@param[in] space tablespace object from fil_space_acquire()
-@return available space in KiB */
-uintmax_t
-fsp_get_available_space_in_free_extents(
- const fil_space_t* space)
-{
- ut_ad(space->n_pending_ops > 0);
-
- ulint size_in_header = space->size_in_header;
- if (size_in_header < FSP_EXTENT_SIZE) {
- return(0); /* TODO: count free frag pages and
- return a value based on that */
- }
-
- /* Below we play safe when counting free extents above the free limit:
- some of them will contain extent descriptor pages, and therefore
- will not be free extents */
- ut_ad(size_in_header >= space->free_limit);
- ulint n_free_up =
- (size_in_header - space->free_limit) / FSP_EXTENT_SIZE;
-
- page_size_t page_size(space->flags);
- if (n_free_up > 0) {
- n_free_up--;
- n_free_up -= n_free_up / (page_size.physical()
- / FSP_EXTENT_SIZE);
- }
-
- /* We reserve 1 extent + 0.5 % of the space size to undo logs
- and 1 extent + 0.5 % to cleaning operations; NOTE: this source
- code is duplicated in the function above! */
-
- ulint reserve = 2 + ((size_in_header / FSP_EXTENT_SIZE) * 2) / 200;
- ulint n_free = space->free_len + n_free_up;
-
- if (reserve > n_free) {
- return(0);
- }
-
- return(static_cast<uintmax_t>(n_free - reserve)
- * FSP_EXTENT_SIZE * (page_size.physical() / 1024));
-}
-
/********************************************************************//**
Marks a page used. The page must reside within the extents of the given
segment. */
diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc
index 83738630772..92d0648dfaf 100644
--- a/storage/innobase/handler/ha_innodb.cc
+++ b/storage/innobase/handler/ha_innodb.cc
@@ -13823,6 +13823,50 @@ innodb_rec_per_key(
return(rec_per_key);
}
+/** Calculate how many KiB of new data we will be able to insert to the
+tablespace without running out of space. Start with a space object that has
+been acquired by the caller who holds it for the calculation,
+@param[in] space tablespace object from fil_space_acquire()
+@return available space in KiB */
+static uintmax_t
+fsp_get_available_space_in_free_extents(const fil_space_t& space)
+{
+ ut_ad(space.n_pending_ops > 0);
+
+ ulint size_in_header = space.size_in_header;
+ if (size_in_header < FSP_EXTENT_SIZE) {
+ return 0; /* TODO: count free frag pages and
+ return a value based on that */
+ }
+
+ /* Below we play safe when counting free extents above the free limit:
+ some of them will contain extent descriptor pages, and therefore
+ will not be free extents */
+ ut_ad(size_in_header >= space.free_limit);
+ ulint n_free_up =
+ (size_in_header - space.free_limit) / FSP_EXTENT_SIZE;
+
+ const ulint size = page_size_t(space.flags).physical();
+ if (n_free_up > 0) {
+ n_free_up--;
+ n_free_up -= n_free_up / (size / FSP_EXTENT_SIZE);
+ }
+
+ /* We reserve 1 extent + 0.5 % of the space size to undo logs
+ and 1 extent + 0.5 % to cleaning operations; NOTE: this source
+ code is duplicated in the function above! */
+
+ ulint reserve = 2 + ((size_in_header / FSP_EXTENT_SIZE) * 2) / 200;
+ ulint n_free = space.free_len + n_free_up;
+
+ if (reserve > n_free) {
+ return(0);
+ }
+
+ return(static_cast<uintmax_t>(n_free - reserve)
+ * FSP_EXTENT_SIZE * (size / 1024));
+}
+
/*********************************************************************//**
Returns statistics information of the table to the MySQL interpreter,
in various fields of the handle object.
@@ -13949,67 +13993,23 @@ ha_innobase::info_low(
m_prebuilt->autoinc_last_value = 0;
}
- const page_size_t& page_size
- = dict_table_page_size(ib_table);
-
stats.records = (ha_rows) n_rows;
stats.deleted = 0;
- stats.data_file_length
- = ((ulonglong) stat_clustered_index_size)
- * page_size.physical();
- stats.index_file_length
- = ((ulonglong) stat_sum_of_other_index_sizes)
- * page_size.physical();
-
- /* Since fsp_get_available_space_in_free_extents() is
- acquiring latches inside InnoDB, we do not call it if we
- are asked by MySQL to avoid locking. Another reason to
- avoid the call is that it uses quite a lot of CPU.
- See Bug#38185. */
- if (flag & HA_STATUS_NO_LOCK
- || !(flag & HA_STATUS_VARIABLE_EXTRA)) {
- /* We do not update delete_length if no
- locking is requested so the "old" value can
- remain. delete_length is initialized to 0 in
- the ha_statistics' constructor. Also we only
- need delete_length to be set when
- HA_STATUS_VARIABLE_EXTRA is set */
- } else if (srv_force_recovery >= SRV_FORCE_NO_IBUF_MERGE) {
- /* Avoid accessing the tablespace if
- innodb_crash_recovery is set to a high value. */
- stats.delete_length = 0;
- } else {
- uintmax_t avail_space;
-
- avail_space = fsp_get_available_space_in_free_extents(
- ib_table->space);
-
- if (avail_space == UINTMAX_MAX) {
- THD* thd;
- char errbuf[MYSYS_STRERROR_SIZE];
-
- thd = ha_thd();
-
- push_warning_printf(
- thd,
- Sql_condition::WARN_LEVEL_WARN,
- ER_CANT_GET_STAT,
- "InnoDB: Trying to get the free"
- " space for table %s but its"
- " tablespace has been discarded or"
- " the .ibd file is missing. Setting"
- " the free space to zero."
- " (errno: %d - %s)",
- ib_table->name.m_name, errno,
- my_strerror(errbuf, sizeof(errbuf),
- errno));
-
- stats.delete_length = 0;
- } else {
- stats.delete_length = avail_space * 1024;
- }
+ if (fil_space_t* space = fil_space_acquire_silent(
+ ib_table->space)) {
+ const ulint size = page_size_t(space->flags)
+ .physical();
+ stats.data_file_length
+ = ulonglong(stat_clustered_index_size)
+ * size;
+ stats.index_file_length
+ = ulonglong(stat_sum_of_other_index_sizes)
+ * size;
+ stats.delete_length = 1024
+ * fsp_get_available_space_in_free_extents(
+ *space);
+ fil_space_release(space);
}
-
stats.check_time = 0;
stats.mrr_length_per_rec= (uint)ref_length + 8; // 8 = max(sizeof(void *));
@@ -14701,9 +14701,13 @@ ha_innobase::update_table_comment(
#define SSTR( x ) reinterpret_cast< std::ostringstream & >( \
( std::ostringstream() << std::dec << x ) ).str()
- fk_str.append("InnoDB free: ");
- fk_str.append(SSTR(fsp_get_available_space_in_free_extents(
- m_prebuilt->table->space)));
+ if (fil_space_t* space = fil_space_acquire_silent(
+ m_prebuilt->table->space)) {
+ fk_str.append("InnoDB free: ");
+ fk_str.append(SSTR(fsp_get_available_space_in_free_extents(
+ *space)));
+ fil_space_release(space);
+ }
fk_str.append(dict_print_info_on_foreign_keys(
FALSE, m_prebuilt->trx,
diff --git a/storage/innobase/include/fsp0fsp.h b/storage/innobase/include/fsp0fsp.h
index 96f846a71f2..e1bd0a5ce6e 100644
--- a/storage/innobase/include/fsp0fsp.h
+++ b/storage/innobase/include/fsp0fsp.h
@@ -527,24 +527,6 @@ fsp_reserve_free_extents(
mtr_t* mtr,
ulint n_pages = 2);
-/** Calculate how many KiB of new data we will be able to insert to the
-tablespace without running out of space.
-@param[in] space_id tablespace ID
-@return available space in KiB
-@retval UINTMAX_MAX if unknown */
-uintmax_t
-fsp_get_available_space_in_free_extents(
- ulint space_id);
-
-/** Calculate how many KiB of new data we will be able to insert to the
-tablespace without running out of space. Start with a space object that has
-been acquired by the caller who holds it for the calculation,
-@param[in] space tablespace object from fil_space_acquire()
-@return available space in KiB */
-uintmax_t
-fsp_get_available_space_in_free_extents(
- const fil_space_t* space);
-
/**********************************************************************//**
Frees a single page of a segment. */
void