summaryrefslogtreecommitdiff
path: root/storage/innobase/fil/fil0fil.cc
diff options
context:
space:
mode:
Diffstat (limited to 'storage/innobase/fil/fil0fil.cc')
-rw-r--r--storage/innobase/fil/fil0fil.cc109
1 files changed, 59 insertions, 50 deletions
diff --git a/storage/innobase/fil/fil0fil.cc b/storage/innobase/fil/fil0fil.cc
index 7a169c0bf2c..ce417b1e511 100644
--- a/storage/innobase/fil/fil0fil.cc
+++ b/storage/innobase/fil/fil0fil.cc
@@ -306,7 +306,9 @@ fil_write(
}
/*******************************************************************//**
-Returns the table space by a given id, NULL if not found. */
+Returns the table space by a given id, NULL if not found.
+It is unsafe to dereference the returned pointer. It is fine to check
+for NULL. */
fil_space_t*
fil_space_get_by_id(
/*================*/
@@ -2276,7 +2278,7 @@ for concurrency control.
@param[in] silent whether to silently ignore missing tablespaces
@return the tablespace
@retval NULL if missing or being deleted or truncated */
-inline
+UNIV_INTERN
fil_space_t*
fil_space_acquire_low(ulint id, bool silent)
{
@@ -2302,30 +2304,6 @@ fil_space_acquire_low(ulint id, bool silent)
return(space);
}
-/** Acquire a tablespace when it could be dropped concurrently.
-Used by background threads that do not necessarily hold proper locks
-for concurrency control.
-@param[in] id tablespace ID
-@return the tablespace
-@retval NULL if missing or being deleted or truncated */
-fil_space_t*
-fil_space_acquire(ulint id)
-{
- return(fil_space_acquire_low(id, false));
-}
-
-/** Acquire a tablespace that may not exist.
-Used by background threads that do not necessarily hold proper locks
-for concurrency control.
-@param[in] id tablespace ID
-@return the tablespace
-@retval NULL if missing or being deleted */
-fil_space_t*
-fil_space_acquire_silent(ulint id)
-{
- return(fil_space_acquire_low(id, true));
-}
-
/** Release a tablespace acquired with fil_space_acquire().
@param[in,out] space tablespace to release */
void
@@ -3102,7 +3080,7 @@ checked @return whether the table is accessible */
bool
fil_table_accessible(const dict_table_t* table)
{
- if (UNIV_UNLIKELY(table->ibd_file_missing || table->corrupted)) {
+ if (UNIV_UNLIKELY(!table->is_readable() || table->corrupted)) {
return(false);
}
@@ -3816,7 +3794,7 @@ fil_ibd_create(
ulint flags,
ulint size,
fil_encryption_t mode,
- ulint key_id)
+ uint32_t key_id)
{
os_file_t file;
dberr_t err;
@@ -3880,17 +3858,21 @@ fil_ibd_create(
success= false;
#ifdef HAVE_POSIX_FALLOCATE
- /*
- Extend the file using posix_fallocate(). This is required by
- FusionIO HW/Firmware but should also be the prefered way to extend
- a file.
- */
- int ret = posix_fallocate(file, 0, size * UNIV_PAGE_SIZE);
-
- if (ret == 0) {
+ /*
+ Extend the file using posix_fallocate(). This is required by
+ FusionIO HW/Firmware but should also be the prefered way to extend
+ a file.
+ */
+ int ret;
+ do {
+ ret = posix_fallocate(file, 0, size * UNIV_PAGE_SIZE);
+ } while (ret == EINTR
+ && srv_shutdown_state == SRV_SHUTDOWN_NONE);
+
+ if (ret == 0) {
success = true;
} else if (ret != EINVAL) {
- ib::error() <<
+ ib::error() <<
"posix_fallocate(): Failed to preallocate"
" data for file " << path
<< ", desired size "
@@ -4791,7 +4773,7 @@ fsp_flags_try_adjust(ulint space_id, ulint flags)
ut_ad(fsp_flags_is_valid(flags));
mtr_t mtr;
- mtr_start(&mtr);
+ mtr.start();
if (buf_block_t* b = buf_page_get(
page_id_t(space_id, 0), page_size_t(flags),
RW_X_LATCH, &mtr)) {
@@ -4805,12 +4787,13 @@ fsp_flags_try_adjust(ulint space_id, ulint flags)
<< " to " << ib::hex(flags);
}
if (f != flags) {
+ mtr.set_named_space(space_id);
mlog_write_ulint(FSP_HEADER_OFFSET
+ FSP_SPACE_FLAGS + b->frame,
flags, MLOG_4BYTES, &mtr);
}
}
- mtr_commit(&mtr);
+ mtr.commit();
}
/** Determine if a matching tablespace exists in the InnoDB tablespace
@@ -4921,7 +4904,7 @@ fil_space_for_table_exists_in_mem(
" deleted or moved .ibd files?";
}
error_exit:
- ib::warn() << TROUBLESHOOT_DATADICT_MSG;
+ ib::info() << TROUBLESHOOT_DATADICT_MSG;
valid = false;
goto func_exit;
}
@@ -5509,6 +5492,8 @@ fil_aio_wait(
mutex_enter(&fil_system->mutex);
fil_node_complete_io(node, type);
+ const fil_type_t purpose = node->space->purpose;
+ const ulint space_id = node->space->id;
mutex_exit(&fil_system->mutex);
@@ -5520,7 +5505,11 @@ fil_aio_wait(
deadlocks in the i/o system. We keep tablespace 0 data files always
open, and use a special i/o thread to serve insert buffer requests. */
- switch (node->space->purpose) {
+ switch (purpose) {
+ case FIL_TYPE_LOG:
+ srv_set_io_thread_op_info(segment, "complete io for log");
+ log_io_complete(static_cast<log_group_t*>(message));
+ return;
case FIL_TYPE_TABLESPACE:
case FIL_TYPE_TEMPORARY:
case FIL_TYPE_IMPORT:
@@ -5528,13 +5517,32 @@ fil_aio_wait(
/* async single page writes from the dblwr buffer don't have
access to the page */
- if (message != NULL) {
- buf_page_io_complete(static_cast<buf_page_t*>(message));
+ buf_page_t* bpage = static_cast<buf_page_t*>(message);
+ if (!bpage) {
+ return;
+ }
+
+ ulint offset = bpage->id.page_no();
+ dberr_t err = buf_page_io_complete(bpage);
+ if (err == DB_SUCCESS) {
+ return;
+ }
+
+ ut_ad(type.is_read());
+ if (recv_recovery_is_on() && !srv_force_recovery) {
+ recv_sys->found_corrupt_fs = true;
+ }
+
+ if (fil_space_t* space = fil_space_acquire_for_io(space_id)) {
+ if (space == node->space) {
+ ib::error() << "Failed to read file '"
+ << node->name
+ << "' at offset " << offset
+ << ": " << ut_strerr(err);
+ }
+
+ fil_space_release_for_io(space);
}
- return;
- case FIL_TYPE_LOG:
- srv_set_io_thread_op_info(segment, "complete io for log");
- log_io_complete(static_cast<log_group_t*>(message));
return;
}
@@ -6920,8 +6928,8 @@ fil_space_keyrotate_next(
or dropped or truncated. Note that rotation_list contains only
space->purpose == FIL_TYPE_TABLESPACE. */
while (space != NULL
- && (UT_LIST_GET_LEN(space->chain) == 0
- || space->is_stopping())) {
+ && (UT_LIST_GET_LEN(space->chain) == 0
+ || space->is_stopping())) {
old = space;
space = UT_LIST_GET_NEXT(rotation_list, space);
@@ -6952,9 +6960,10 @@ fil_space_get_block_size(const fil_space_t* space, unsigned offset)
node = UT_LIST_GET_NEXT(chain, node)) {
block_size = node->block_size;
if (node->size > offset) {
+ ut_ad(node->size <= 0xFFFFFFFFU);
break;
}
- offset -= node->size;
+ offset -= static_cast<unsigned>(node->size);
}
/* Currently supporting block size up to 4K,