Commit 536112dd authored by Jan Lindström's avatar Jan Lindström

MDEV-8195: InnoDB: Error: trying to access tablespace 11262 page no. 7,...

MDEV-8195: InnoDB: Error: trying to access tablespace 11262 page no. 7, InnoDB: but the tablespace does not exist or is just being dropped.

Analysis: Problem was that we did try to read from tablespace
that was being dropped.

Fixed by introducing a new function to find a tablespace only
if it is not being dropped currently and adding this check
before trying to read pages from tablespace.
parent 8635c4b4
...@@ -1067,7 +1067,7 @@ fil_crypt_start_encrypting_space( ...@@ -1067,7 +1067,7 @@ fil_crypt_start_encrypting_space(
do do
{ {
if (fil_crypt_is_closing(space) || if (fil_crypt_is_closing(space) ||
fil_tablespace_is_being_deleted(space)) { fil_space_found_by_id(space)) {
break; break;
} }
...@@ -1085,7 +1085,7 @@ fil_crypt_start_encrypting_space( ...@@ -1085,7 +1085,7 @@ fil_crypt_start_encrypting_space(
&mtr); &mtr);
if (fil_crypt_is_closing(space) || if (fil_crypt_is_closing(space) ||
fil_tablespace_is_being_deleted(space)) { fil_space_found_by_id(space) == NULL) {
mtr_commit(&mtr); mtr_commit(&mtr);
break; break;
} }
...@@ -1107,7 +1107,7 @@ fil_crypt_start_encrypting_space( ...@@ -1107,7 +1107,7 @@ fil_crypt_start_encrypting_space(
mtr_commit(&mtr); mtr_commit(&mtr);
if (fil_crypt_is_closing(space) || if (fil_crypt_is_closing(space) ||
fil_tablespace_is_being_deleted(space)) { fil_space_found_by_id(space) == NULL) {
break; break;
} }
...@@ -1129,7 +1129,7 @@ fil_crypt_start_encrypting_space( ...@@ -1129,7 +1129,7 @@ fil_crypt_start_encrypting_space(
sum_pages += n_pages; sum_pages += n_pages;
} while (!success && } while (!success &&
!fil_crypt_is_closing(space) && !fil_crypt_is_closing(space) &&
!fil_tablespace_is_being_deleted(space)); !fil_space_found_by_id(space));
/* try to reacquire pending op */ /* try to reacquire pending op */
if (fil_inc_pending_ops(space, true)) { if (fil_inc_pending_ops(space, true)) {
...@@ -1140,7 +1140,7 @@ fil_crypt_start_encrypting_space( ...@@ -1140,7 +1140,7 @@ fil_crypt_start_encrypting_space(
pending_op = true; pending_op = true;
if (fil_crypt_is_closing(space) || if (fil_crypt_is_closing(space) ||
fil_tablespace_is_being_deleted(space)) { fil_space_found_by_id(space) == NULL) {
break; break;
} }
...@@ -1219,7 +1219,10 @@ fil_crypt_space_needs_rotation( ...@@ -1219,7 +1219,10 @@ fil_crypt_space_needs_rotation(
bool* recheck) /*!< out: needs recheck ? */ bool* recheck) /*!< out: needs recheck ? */
{ {
ulint space = state->space; ulint space = state->space;
if (fil_space_get_type(space) != FIL_TABLESPACE) {
/* Make sure that tablespace is found and it is normal tablespace */
if (fil_space_found_by_id(space) == NULL ||
fil_space_get_type(space) != FIL_TABLESPACE) {
return false; return false;
} }
...@@ -1553,11 +1556,6 @@ fil_crypt_start_rotate_space( ...@@ -1553,11 +1556,6 @@ fil_crypt_start_rotate_space(
if (crypt_data->rotate_state.active_threads == 0) { if (crypt_data->rotate_state.active_threads == 0) {
/* only first thread needs to init */ /* only first thread needs to init */
if (crypt_data->encryption == FIL_SPACE_ENCRYPTION_OFF) {
crypt_data->type = CRYPT_SCHEME_UNENCRYPTED;
} else {
crypt_data->type = CRYPT_SCHEME_1;
}
crypt_data->rotate_state.next_offset = 1; // skip page 0 crypt_data->rotate_state.next_offset = 1; // skip page 0
/* no need to rotate beyond current max /* no need to rotate beyond current max
* if space extends, it will be encrypted with newer version */ * if space extends, it will be encrypted with newer version */
...@@ -1568,6 +1566,13 @@ fil_crypt_start_rotate_space( ...@@ -1568,6 +1566,13 @@ fil_crypt_start_rotate_space(
key_state->key_version; key_state->key_version;
crypt_data->rotate_state.start_time = time(0); crypt_data->rotate_state.start_time = time(0);
if (crypt_data->type == CRYPT_SCHEME_UNENCRYPTED &&
crypt_data->encryption != FIL_SPACE_ENCRYPTION_OFF &&
key_state->key_version != 0) {
/* this is rotation unencrypted => encrypted */
crypt_data->type = CRYPT_SCHEME_1;
}
} }
/* count active threads in space */ /* count active threads in space */
...@@ -1688,6 +1693,14 @@ fil_crypt_get_page_throttle_func( ...@@ -1688,6 +1693,14 @@ fil_crypt_get_page_throttle_func(
return block; return block;
} }
/* Before reading from tablespace we need to make sure that
tablespace exists and is not is just being dropped. */
if (fil_crypt_is_closing(space) ||
fil_space_found_by_id(space) == NULL) {
return NULL;
}
state->crypt_stat.pages_read_from_disk++; state->crypt_stat.pages_read_from_disk++;
ullint start = ut_time_us(NULL); ullint start = ut_time_us(NULL);
...@@ -1795,7 +1808,7 @@ fil_crypt_rotate_page( ...@@ -1795,7 +1808,7 @@ fil_crypt_rotate_page(
ulint sleeptime_ms = 0; ulint sleeptime_ms = 0;
/* check if tablespace is closing before reading page */ /* check if tablespace is closing before reading page */
if (fil_crypt_is_closing(space)) { if (fil_crypt_is_closing(space) || fil_space_found_by_id(space) == NULL) {
return; return;
} }
...@@ -1811,125 +1824,131 @@ fil_crypt_rotate_page( ...@@ -1811,125 +1824,131 @@ fil_crypt_rotate_page(
offset, &mtr, offset, &mtr,
&sleeptime_ms); &sleeptime_ms);
bool modified = false; if (block) {
int needs_scrubbing = BTR_SCRUB_SKIP_PAGE;
lsn_t block_lsn = block->page.newest_modification;
uint kv = block->page.key_version;
/* check if tablespace is closing after reading page */ bool modified = false;
if (!fil_crypt_is_closing(space)) { int needs_scrubbing = BTR_SCRUB_SKIP_PAGE;
byte* frame = buf_block_get_frame(block); lsn_t block_lsn = block->page.newest_modification;
fil_space_crypt_t *crypt_data = fil_space_get_crypt_data(space); uint kv = block->page.key_version;
if (kv == 0 && /* check if tablespace is closing after reading page */
fil_crypt_is_page_uninitialized(frame, zip_size)) { if (!fil_crypt_is_closing(space)) {
; byte* frame = buf_block_get_frame(block);
} else if (fil_crypt_needs_rotation( fil_space_crypt_t *crypt_data = fil_space_get_crypt_data(space);
crypt_data->encryption,
kv, key_state->key_version,
key_state->rotate_key_age)) {
/* page can be "fresh" i.e never written in case if (kv == 0 &&
* kv == 0 or it should have a key version at least fil_crypt_is_page_uninitialized(frame, zip_size)) {
* as big as the space minimum key version*/ ;
ut_a(kv == 0 || kv >= crypt_data->min_key_version); } else if (fil_crypt_needs_rotation(
crypt_data->encryption,
kv, key_state->key_version,
key_state->rotate_key_age)) {
modified = true; /* page can be "fresh" i.e never written in case
* kv == 0 or it should have a key version at least
* as big as the space minimum key version*/
ut_a(kv == 0 || kv >= crypt_data->min_key_version);
/* force rotation by dummy updating page */ modified = true;
mlog_write_ulint(frame +
FIL_PAGE_ARCH_LOG_NO_OR_SPACE_ID,
space, MLOG_4BYTES, &mtr);
/* update block */ /* force rotation by dummy updating page */
block->page.key_version = key_state->key_version; mlog_write_ulint(frame +
FIL_PAGE_ARCH_LOG_NO_OR_SPACE_ID,
space, MLOG_4BYTES, &mtr);
/* statistics */ /* update block */
state->crypt_stat.pages_modified++; block->page.key_version = key_state->key_version;
} else {
if (crypt_data->encryption != FIL_SPACE_ENCRYPTION_OFF) { /* statistics */
ut_a(kv >= crypt_data->min_key_version || state->crypt_stat.pages_modified++;
(kv == 0 && key_state->key_version == 0)); } else {
if (crypt_data->encryption != FIL_SPACE_ENCRYPTION_OFF) {
ut_a(kv >= crypt_data->min_key_version ||
(kv == 0 && key_state->key_version == 0));
if (kv < state->min_key_version_found) { if (kv < state->min_key_version_found) {
state->min_key_version_found = kv; state->min_key_version_found = kv;
}
} }
} }
}
needs_scrubbing = btr_page_needs_scrubbing(
&state->scrub_data, block,
BTR_SCRUB_PAGE_ALLOCATION_UNKNOWN);
}
mtr_commit(&mtr);
lsn_t end_lsn = mtr.end_lsn;
if (needs_scrubbing == BTR_SCRUB_PAGE) { needs_scrubbing = btr_page_needs_scrubbing(
mtr_start(&mtr); &state->scrub_data, block,
/* BTR_SCRUB_PAGE_ALLOCATION_UNKNOWN);
* refetch page and allocation status }
*/
btr_scrub_page_allocation_status_t allocated;
block = btr_scrub_get_block_and_allocation_status(
state, space, zip_size, offset, &mtr,
&allocated,
&sleeptime_ms);
/* get required table/index and index-locks */ mtr_commit(&mtr);
needs_scrubbing = btr_scrub_recheck_page( lsn_t end_lsn = mtr.end_lsn;
&state->scrub_data, block, allocated, &mtr);
if (needs_scrubbing == BTR_SCRUB_PAGE) { if (needs_scrubbing == BTR_SCRUB_PAGE) {
/* we need to refetch it once more now that we have mtr_start(&mtr);
* index locked */ /*
* refetch page and allocation status
*/
btr_scrub_page_allocation_status_t allocated;
block = btr_scrub_get_block_and_allocation_status( block = btr_scrub_get_block_and_allocation_status(
state, space, zip_size, offset, &mtr, state, space, zip_size, offset, &mtr,
&allocated, &allocated,
&sleeptime_ms); &sleeptime_ms);
needs_scrubbing = btr_scrub_page(&state->scrub_data, if (block) {
block, allocated,
&mtr);
}
/* NOTE: mtr is committed inside btr_scrub_recheck_page() /* get required table/index and index-locks */
* and/or btr_scrub_page. This is to make sure that needs_scrubbing = btr_scrub_recheck_page(
* locks & pages are latched in corrected order, &state->scrub_data, block, allocated, &mtr);
* the mtr is in some circumstances restarted.
* (mtr_commit() + mtr_start())
*/
}
if (needs_scrubbing != BTR_SCRUB_PAGE) { if (needs_scrubbing == BTR_SCRUB_PAGE) {
/* if page didn't need scrubbing it might be that cleanups /* we need to refetch it once more now that we have
are needed. do those outside of any mtr to prevent deadlocks. * index locked */
block = btr_scrub_get_block_and_allocation_status(
state, space, zip_size, offset, &mtr,
&allocated,
&sleeptime_ms);
the information what kinds of cleanups that are needed are needs_scrubbing = btr_scrub_page(&state->scrub_data,
encoded inside the needs_scrubbing, but this is opaque to block, allocated,
this function (except the value BTR_SCRUB_PAGE) */ &mtr);
btr_scrub_skip_page(&state->scrub_data, needs_scrubbing); }
}
if (needs_scrubbing == BTR_SCRUB_TURNED_OFF) { /* NOTE: mtr is committed inside btr_scrub_recheck_page()
/* if we just detected that scrubbing was turned off * and/or btr_scrub_page. This is to make sure that
* update global state to reflect this */ * locks & pages are latched in corrected order,
fil_space_crypt_t *crypt_data = fil_space_get_crypt_data(space); * the mtr is in some circumstances restarted.
ut_ad(crypt_data); * (mtr_commit() + mtr_start())
mutex_enter(&crypt_data->mutex); */
crypt_data->rotate_state.scrubbing.is_active = false; }
mutex_exit(&crypt_data->mutex); }
}
if (modified) { if (needs_scrubbing != BTR_SCRUB_PAGE) {
/* if we modified page, we take lsn from mtr */ /* if page didn't need scrubbing it might be that cleanups
ut_a(end_lsn > state->end_lsn); are needed. do those outside of any mtr to prevent deadlocks.
ut_a(end_lsn > block_lsn);
state->end_lsn = end_lsn; the information what kinds of cleanups that are needed are
} else { encoded inside the needs_scrubbing, but this is opaque to
/* if we did not modify page, check for max lsn */ this function (except the value BTR_SCRUB_PAGE) */
if (block_lsn > state->end_lsn) { btr_scrub_skip_page(&state->scrub_data, needs_scrubbing);
state->end_lsn = block_lsn; }
if (needs_scrubbing == BTR_SCRUB_TURNED_OFF) {
/* if we just detected that scrubbing was turned off
* update global state to reflect this */
fil_space_crypt_t *crypt_data = fil_space_get_crypt_data(space);
ut_ad(crypt_data);
mutex_enter(&crypt_data->mutex);
crypt_data->rotate_state.scrubbing.is_active = false;
mutex_exit(&crypt_data->mutex);
}
if (modified) {
/* if we modified page, we take lsn from mtr */
ut_a(end_lsn > state->end_lsn);
ut_a(end_lsn > block_lsn);
state->end_lsn = end_lsn;
} else {
/* if we did not modify page, check for max lsn */
if (block_lsn > state->end_lsn) {
state->end_lsn = block_lsn;
}
} }
} }
......
...@@ -341,6 +341,26 @@ fil_space_get_by_id( ...@@ -341,6 +341,26 @@ fil_space_get_by_id(
return(space); return(space);
} }
/*******************************************************************//**
Returns the table space by a given id, NULL if not found. */
fil_space_t*
fil_space_found_by_id(
/*==================*/
ulint id) /*!< in: space id */
{
fil_space_t* space = NULL;
mutex_enter(&fil_system->mutex);
space = fil_space_get_by_id(id);
/* Not found if space is being deleted */
if (space && space->stop_new_ops) {
space = NULL;
}
mutex_exit(&fil_system->mutex);
return space;
}
/****************************************************************//** /****************************************************************//**
Get space id from fil node */ Get space id from fil node */
ulint ulint
......
...@@ -1252,6 +1252,13 @@ fil_system_exit(void); ...@@ -1252,6 +1252,13 @@ fil_system_exit(void);
/*==================*/ /*==================*/
#ifndef UNIV_INNOCHECKSUM #ifndef UNIV_INNOCHECKSUM
/*******************************************************************//**
Returns the table space by a given id, NULL if not found. */
fil_space_t*
fil_space_found_by_id(
/*==================*/
ulint id); /*!< in: space id */
/*******************************************************************//** /*******************************************************************//**
Returns the table space by a given id, NULL if not found. */ Returns the table space by a given id, NULL if not found. */
fil_space_t* fil_space_t*
......
...@@ -1067,7 +1067,7 @@ fil_crypt_start_encrypting_space( ...@@ -1067,7 +1067,7 @@ fil_crypt_start_encrypting_space(
do do
{ {
if (fil_crypt_is_closing(space) || if (fil_crypt_is_closing(space) ||
fil_tablespace_is_being_deleted(space)) { fil_space_found_by_id(space) == NULL) {
break; break;
} }
...@@ -1085,7 +1085,7 @@ fil_crypt_start_encrypting_space( ...@@ -1085,7 +1085,7 @@ fil_crypt_start_encrypting_space(
&mtr); &mtr);
if (fil_crypt_is_closing(space) || if (fil_crypt_is_closing(space) ||
fil_tablespace_is_being_deleted(space)) { fil_space_found_by_id(space) == NULL) {
mtr_commit(&mtr); mtr_commit(&mtr);
break; break;
} }
...@@ -1107,7 +1107,7 @@ fil_crypt_start_encrypting_space( ...@@ -1107,7 +1107,7 @@ fil_crypt_start_encrypting_space(
mtr_commit(&mtr); mtr_commit(&mtr);
if (fil_crypt_is_closing(space) || if (fil_crypt_is_closing(space) ||
fil_tablespace_is_being_deleted(space)) { fil_space_found_by_id(space) == NULL) {
break; break;
} }
...@@ -1129,7 +1129,7 @@ fil_crypt_start_encrypting_space( ...@@ -1129,7 +1129,7 @@ fil_crypt_start_encrypting_space(
sum_pages += n_pages; sum_pages += n_pages;
} while (!success && } while (!success &&
!fil_crypt_is_closing(space) && !fil_crypt_is_closing(space) &&
!fil_tablespace_is_being_deleted(space)); !fil_space_found_by_id(space));
/* try to reacquire pending op */ /* try to reacquire pending op */
if (fil_inc_pending_ops(space, true)) { if (fil_inc_pending_ops(space, true)) {
...@@ -1140,7 +1140,7 @@ fil_crypt_start_encrypting_space( ...@@ -1140,7 +1140,7 @@ fil_crypt_start_encrypting_space(
pending_op = true; pending_op = true;
if (fil_crypt_is_closing(space) || if (fil_crypt_is_closing(space) ||
fil_tablespace_is_being_deleted(space)) { fil_space_found_by_id(space) == NULL) {
break; break;
} }
...@@ -1219,7 +1219,10 @@ fil_crypt_space_needs_rotation( ...@@ -1219,7 +1219,10 @@ fil_crypt_space_needs_rotation(
bool* recheck) /*!< out: needs recheck ? */ bool* recheck) /*!< out: needs recheck ? */
{ {
ulint space = state->space; ulint space = state->space;
if (fil_space_get_type(space) != FIL_TABLESPACE) {
/* Make sure that tablespace is found and it is normal tablespace */
if (fil_space_found_by_id(space) == NULL ||
fil_space_get_type(space) != FIL_TABLESPACE) {
return false; return false;
} }
...@@ -1553,11 +1556,6 @@ fil_crypt_start_rotate_space( ...@@ -1553,11 +1556,6 @@ fil_crypt_start_rotate_space(
if (crypt_data->rotate_state.active_threads == 0) { if (crypt_data->rotate_state.active_threads == 0) {
/* only first thread needs to init */ /* only first thread needs to init */
if (crypt_data->encryption == FIL_SPACE_ENCRYPTION_OFF) {
crypt_data->type = CRYPT_SCHEME_UNENCRYPTED;
} else {
crypt_data->type = CRYPT_SCHEME_1;
}
crypt_data->rotate_state.next_offset = 1; // skip page 0 crypt_data->rotate_state.next_offset = 1; // skip page 0
/* no need to rotate beyond current max /* no need to rotate beyond current max
* if space extends, it will be encrypted with newer version */ * if space extends, it will be encrypted with newer version */
...@@ -1568,6 +1566,13 @@ fil_crypt_start_rotate_space( ...@@ -1568,6 +1566,13 @@ fil_crypt_start_rotate_space(
key_state->key_version; key_state->key_version;
crypt_data->rotate_state.start_time = time(0); crypt_data->rotate_state.start_time = time(0);
if (crypt_data->type == CRYPT_SCHEME_UNENCRYPTED &&
crypt_data->encryption != FIL_SPACE_ENCRYPTION_OFF &&
key_state->key_version != 0) {
/* this is rotation unencrypted => encrypted */
crypt_data->type = CRYPT_SCHEME_1;
}
} }
/* count active threads in space */ /* count active threads in space */
...@@ -1688,6 +1693,14 @@ fil_crypt_get_page_throttle_func( ...@@ -1688,6 +1693,14 @@ fil_crypt_get_page_throttle_func(
return block; return block;
} }
/* Before reading from tablespace we need to make sure that
tablespace exists and is not is just being dropped. */
if (fil_crypt_is_closing(space) ||
fil_space_found_by_id(space) == NULL) {
return NULL;
}
state->crypt_stat.pages_read_from_disk++; state->crypt_stat.pages_read_from_disk++;
ullint start = ut_time_us(NULL); ullint start = ut_time_us(NULL);
...@@ -1795,7 +1808,7 @@ fil_crypt_rotate_page( ...@@ -1795,7 +1808,7 @@ fil_crypt_rotate_page(
ulint sleeptime_ms = 0; ulint sleeptime_ms = 0;
/* check if tablespace is closing before reading page */ /* check if tablespace is closing before reading page */
if (fil_crypt_is_closing(space)) { if (fil_crypt_is_closing(space) || fil_space_found_by_id(space) == NULL) {
return; return;
} }
...@@ -1811,125 +1824,131 @@ fil_crypt_rotate_page( ...@@ -1811,125 +1824,131 @@ fil_crypt_rotate_page(
offset, &mtr, offset, &mtr,
&sleeptime_ms); &sleeptime_ms);
bool modified = false; if (block) {
int needs_scrubbing = BTR_SCRUB_SKIP_PAGE;
lsn_t block_lsn = block->page.newest_modification;
uint kv = block->page.key_version;
/* check if tablespace is closing after reading page */ bool modified = false;
if (!fil_crypt_is_closing(space)) { int needs_scrubbing = BTR_SCRUB_SKIP_PAGE;
byte* frame = buf_block_get_frame(block); lsn_t block_lsn = block->page.newest_modification;
fil_space_crypt_t *crypt_data = fil_space_get_crypt_data(space); uint kv = block->page.key_version;
if (kv == 0 && /* check if tablespace is closing after reading page */
fil_crypt_is_page_uninitialized(frame, zip_size)) { if (!fil_crypt_is_closing(space)) {
; byte* frame = buf_block_get_frame(block);
} else if (fil_crypt_needs_rotation( fil_space_crypt_t *crypt_data = fil_space_get_crypt_data(space);
crypt_data->encryption,
kv, key_state->key_version,
key_state->rotate_key_age)) {
/* page can be "fresh" i.e never written in case if (kv == 0 &&
* kv == 0 or it should have a key version at least fil_crypt_is_page_uninitialized(frame, zip_size)) {
* as big as the space minimum key version*/ ;
ut_a(kv == 0 || kv >= crypt_data->min_key_version); } else if (fil_crypt_needs_rotation(
crypt_data->encryption,
kv, key_state->key_version,
key_state->rotate_key_age)) {
modified = true; /* page can be "fresh" i.e never written in case
* kv == 0 or it should have a key version at least
* as big as the space minimum key version*/
ut_a(kv == 0 || kv >= crypt_data->min_key_version);
/* force rotation by dummy updating page */ modified = true;
mlog_write_ulint(frame +
FIL_PAGE_ARCH_LOG_NO_OR_SPACE_ID,
space, MLOG_4BYTES, &mtr);
/* update block */ /* force rotation by dummy updating page */
block->page.key_version = key_state->key_version; mlog_write_ulint(frame +
FIL_PAGE_ARCH_LOG_NO_OR_SPACE_ID,
space, MLOG_4BYTES, &mtr);
/* statistics */ /* update block */
state->crypt_stat.pages_modified++; block->page.key_version = key_state->key_version;
} else {
if (crypt_data->encryption != FIL_SPACE_ENCRYPTION_OFF) { /* statistics */
ut_a(kv >= crypt_data->min_key_version || state->crypt_stat.pages_modified++;
(kv == 0 && key_state->key_version == 0)); } else {
if (crypt_data->encryption != FIL_SPACE_ENCRYPTION_OFF) {
ut_a(kv >= crypt_data->min_key_version ||
(kv == 0 && key_state->key_version == 0));
if (kv < state->min_key_version_found) { if (kv < state->min_key_version_found) {
state->min_key_version_found = kv; state->min_key_version_found = kv;
}
} }
} }
}
needs_scrubbing = btr_page_needs_scrubbing(
&state->scrub_data, block,
BTR_SCRUB_PAGE_ALLOCATION_UNKNOWN);
}
mtr_commit(&mtr);
lsn_t end_lsn = mtr.end_lsn;
if (needs_scrubbing == BTR_SCRUB_PAGE) { needs_scrubbing = btr_page_needs_scrubbing(
mtr_start(&mtr); &state->scrub_data, block,
/* BTR_SCRUB_PAGE_ALLOCATION_UNKNOWN);
* refetch page and allocation status }
*/
btr_scrub_page_allocation_status_t allocated;
block = btr_scrub_get_block_and_allocation_status(
state, space, zip_size, offset, &mtr,
&allocated,
&sleeptime_ms);
/* get required table/index and index-locks */ mtr_commit(&mtr);
needs_scrubbing = btr_scrub_recheck_page( lsn_t end_lsn = mtr.end_lsn;
&state->scrub_data, block, allocated, &mtr);
if (needs_scrubbing == BTR_SCRUB_PAGE) { if (needs_scrubbing == BTR_SCRUB_PAGE) {
/* we need to refetch it once more now that we have mtr_start(&mtr);
* index locked */ /*
* refetch page and allocation status
*/
btr_scrub_page_allocation_status_t allocated;
block = btr_scrub_get_block_and_allocation_status( block = btr_scrub_get_block_and_allocation_status(
state, space, zip_size, offset, &mtr, state, space, zip_size, offset, &mtr,
&allocated, &allocated,
&sleeptime_ms); &sleeptime_ms);
needs_scrubbing = btr_scrub_page(&state->scrub_data, if (block) {
block, allocated,
&mtr);
}
/* NOTE: mtr is committed inside btr_scrub_recheck_page() /* get required table/index and index-locks */
* and/or btr_scrub_page. This is to make sure that needs_scrubbing = btr_scrub_recheck_page(
* locks & pages are latched in corrected order, &state->scrub_data, block, allocated, &mtr);
* the mtr is in some circumstances restarted.
* (mtr_commit() + mtr_start())
*/
}
if (needs_scrubbing != BTR_SCRUB_PAGE) { if (needs_scrubbing == BTR_SCRUB_PAGE) {
/* if page didn't need scrubbing it might be that cleanups /* we need to refetch it once more now that we have
are needed. do those outside of any mtr to prevent deadlocks. * index locked */
block = btr_scrub_get_block_and_allocation_status(
state, space, zip_size, offset, &mtr,
&allocated,
&sleeptime_ms);
the information what kinds of cleanups that are needed are needs_scrubbing = btr_scrub_page(&state->scrub_data,
encoded inside the needs_scrubbing, but this is opaque to block, allocated,
this function (except the value BTR_SCRUB_PAGE) */ &mtr);
btr_scrub_skip_page(&state->scrub_data, needs_scrubbing); }
}
if (needs_scrubbing == BTR_SCRUB_TURNED_OFF) { /* NOTE: mtr is committed inside btr_scrub_recheck_page()
/* if we just detected that scrubbing was turned off * and/or btr_scrub_page. This is to make sure that
* update global state to reflect this */ * locks & pages are latched in corrected order,
fil_space_crypt_t *crypt_data = fil_space_get_crypt_data(space); * the mtr is in some circumstances restarted.
ut_ad(crypt_data); * (mtr_commit() + mtr_start())
mutex_enter(&crypt_data->mutex); */
crypt_data->rotate_state.scrubbing.is_active = false; }
mutex_exit(&crypt_data->mutex); }
}
if (modified) { if (needs_scrubbing != BTR_SCRUB_PAGE) {
/* if we modified page, we take lsn from mtr */ /* if page didn't need scrubbing it might be that cleanups
ut_a(end_lsn > state->end_lsn); are needed. do those outside of any mtr to prevent deadlocks.
ut_a(end_lsn > block_lsn);
state->end_lsn = end_lsn; the information what kinds of cleanups that are needed are
} else { encoded inside the needs_scrubbing, but this is opaque to
/* if we did not modify page, check for max lsn */ this function (except the value BTR_SCRUB_PAGE) */
if (block_lsn > state->end_lsn) { btr_scrub_skip_page(&state->scrub_data, needs_scrubbing);
state->end_lsn = block_lsn; }
if (needs_scrubbing == BTR_SCRUB_TURNED_OFF) {
/* if we just detected that scrubbing was turned off
* update global state to reflect this */
fil_space_crypt_t *crypt_data = fil_space_get_crypt_data(space);
ut_ad(crypt_data);
mutex_enter(&crypt_data->mutex);
crypt_data->rotate_state.scrubbing.is_active = false;
mutex_exit(&crypt_data->mutex);
}
if (modified) {
/* if we modified page, we take lsn from mtr */
ut_a(end_lsn > state->end_lsn);
ut_a(end_lsn > block_lsn);
state->end_lsn = end_lsn;
} else {
/* if we did not modify page, check for max lsn */
if (block_lsn > state->end_lsn) {
state->end_lsn = block_lsn;
}
} }
} }
......
...@@ -344,6 +344,26 @@ fil_space_get_by_id( ...@@ -344,6 +344,26 @@ fil_space_get_by_id(
return(space); return(space);
} }
/*******************************************************************//**
Returns the table space by a given id, NULL if not found. */
fil_space_t*
fil_space_found_by_id(
/*==================*/
ulint id) /*!< in: space id */
{
fil_space_t* space = NULL;
mutex_enter(&fil_system->mutex);
space = fil_space_get_by_id(id);
/* Not found if space is being deleted */
if (space && space->stop_new_ops) {
space = NULL;
}
mutex_exit(&fil_system->mutex);
return space;
}
/****************************************************************//** /****************************************************************//**
Get space id from fil node */ Get space id from fil node */
ulint ulint
......
...@@ -1280,6 +1280,13 @@ fil_system_exit(void); ...@@ -1280,6 +1280,13 @@ fil_system_exit(void);
/*==================*/ /*==================*/
#ifndef UNIV_INNOCHECKSUM #ifndef UNIV_INNOCHECKSUM
/*******************************************************************//**
Returns the table space by a given id, NULL if not found. */
fil_space_t*
fil_space_found_by_id(
/*==================*/
ulint id); /*!< in: space id */
/*******************************************************************//** /*******************************************************************//**
Returns the table space by a given id, NULL if not found. */ Returns the table space by a given id, NULL if not found. */
fil_space_t* fil_space_t*
......
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