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

Code clean-up related to MDEV-13167

xdes_get_descriptor_const(): New function, to get read-only access to
the allocation descriptor.

fseg_page_is_free(): Only acquire a shared latch on the tablespace,
not an exclusive latch. Calculate the descriptor page address before
acquiring the tablespace latch. If the page number is out of bounds,
return without fetching any page. Access only one descriptor page.

fsp_page_is_free(), fsp_page_is_free_func(): Remove.
Use fseg_page_is_free() instead.

fsp_init_file_page(): Move the debug parameter into a separate function.

btr_validate_level(): Remove the unused variable "seg".
parent 59caf2c3
...@@ -4846,7 +4846,6 @@ btr_validate_level( ...@@ -4846,7 +4846,6 @@ btr_validate_level(
bool ret = true; bool ret = true;
mtr_t mtr; mtr_t mtr;
mem_heap_t* heap = mem_heap_create(256); mem_heap_t* heap = mem_heap_create(256);
fseg_header_t* seg;
ulint* offsets = NULL; ulint* offsets = NULL;
ulint* offsets2= NULL; ulint* offsets2= NULL;
#ifdef UNIV_ZIP_DEBUG #ifdef UNIV_ZIP_DEBUG
...@@ -4870,7 +4869,6 @@ btr_validate_level( ...@@ -4870,7 +4869,6 @@ btr_validate_level(
block = btr_root_block_get(index, RW_SX_LATCH, &mtr); block = btr_root_block_get(index, RW_SX_LATCH, &mtr);
page = buf_block_get_frame(block); page = buf_block_get_frame(block);
seg = page + PAGE_HEADER + PAGE_BTR_SEG_TOP;
#ifdef UNIV_DEBUG #ifdef UNIV_DEBUG
if (dict_index_is_spatial(index)) { if (dict_index_is_spatial(index)) {
...@@ -4879,7 +4877,7 @@ btr_validate_level( ...@@ -4879,7 +4877,7 @@ btr_validate_level(
} }
#endif #endif
const fil_space_t* space = fil_space_get(index->space); fil_space_t* space = fil_space_get(index->space);
const page_size_t table_page_size( const page_size_t table_page_size(
dict_table_page_size(index->table)); dict_table_page_size(index->table));
const page_size_t space_page_size(space->flags); const page_size_t space_page_size(space->flags);
...@@ -4897,9 +4895,7 @@ btr_validate_level( ...@@ -4897,9 +4895,7 @@ btr_validate_level(
while (level != btr_page_get_level(page, &mtr)) { while (level != btr_page_get_level(page, &mtr)) {
const rec_t* node_ptr; const rec_t* node_ptr;
if (fseg_page_is_free(seg, if (fseg_page_is_free(space, block->page.id.page_no())) {
block->page.id.space(),
block->page.id.page_no())) {
btr_validate_report1(index, level, block); btr_validate_report1(index, level, block);
...@@ -4959,11 +4955,6 @@ btr_validate_level( ...@@ -4959,11 +4955,6 @@ btr_validate_level(
/* Now we are on the desired level. Loop through the pages on that /* Now we are on the desired level. Loop through the pages on that
level. */ level. */
if (level == 0) {
/* Leaf pages are managed in their own file segment. */
seg -= PAGE_BTR_SEG_TOP - PAGE_BTR_SEG_LEAF;
}
loop: loop:
mem_heap_empty(heap); mem_heap_empty(heap);
offsets = offsets2 = NULL; offsets = offsets2 = NULL;
...@@ -4982,9 +4973,7 @@ btr_validate_level( ...@@ -4982,9 +4973,7 @@ btr_validate_level(
ut_a(block->page.id.space() == index->space); ut_a(block->page.id.space() == index->space);
if (fseg_page_is_free(seg, if (fseg_page_is_free(space, block->page.id.page_no())) {
block->page.id.space(),
block->page.id.page_no())) {
btr_validate_report1(index, level, block); btr_validate_report1(index, level, block);
......
...@@ -1723,7 +1723,7 @@ btr_scrub_get_block_and_allocation_status( ...@@ -1723,7 +1723,7 @@ btr_scrub_get_block_and_allocation_status(
mtr_start(&local_mtr); mtr_start(&local_mtr);
*allocation_status = fsp_page_is_free(space->id, offset, &local_mtr) ? *allocation_status = fseg_page_is_free(space, offset) ?
BTR_SCRUB_PAGE_FREE : BTR_SCRUB_PAGE_FREE :
BTR_SCRUB_PAGE_ALLOCATED; BTR_SCRUB_PAGE_ALLOCATED;
......
...@@ -506,6 +506,51 @@ xdes_get_descriptor( ...@@ -506,6 +506,51 @@ xdes_get_descriptor(
sp_header, space, offset, mtr)); sp_header, space, offset, mtr));
} }
/** Get the extent descriptor of a page.
The page where the extent descriptor resides is x-locked. If the page
offset is equal to the free limit of the space, we will add new
extents from above the free limit to the space free list, if not free
limit == space size. This adding is necessary to make the descriptor
defined, as they are uninitialized above the free limit.
@param[in] space tablespace
@param[in] page descriptor page offset
@param[in] offset page offset
@param[in] page_size page size
@param[in,out] mtr mini-transaction
@return the extent descriptor
@retval NULL if the descriptor is not available */
MY_ATTRIBUTE((warn_unused_result))
static
const xdes_t*
xdes_get_descriptor_const(
const fil_space_t* space,
page_no_t page,
page_no_t offset,
const page_size_t& page_size,
mtr_t* mtr)
{
ut_ad(mtr_memo_contains(mtr, &space->latch, MTR_MEMO_S_LOCK));
ut_ad(offset < space->free_limit);
ut_ad(offset < space->size_in_header);
if (buf_block_t* block = buf_page_get(page_id_t(space->id, page),
page_size, RW_S_LATCH, mtr)) {
buf_block_dbg_add_level(block, SYNC_FSP_PAGE);
ut_ad(page != 0 || space->free_limit == mach_read_from_4(
FSP_FREE_LIMIT + FSP_HEADER_OFFSET
+ block->frame));
ut_ad(page != 0 || space->size_in_header == mach_read_from_4(
FSP_SIZE + FSP_HEADER_OFFSET
+ block->frame));
return(block->frame + XDES_ARR_OFFSET + XDES_SIZE
* xdes_calc_descriptor_index(page_size, offset));
}
return(NULL);
}
/** Get a pointer to the extent descriptor. The page where the /** Get a pointer to the extent descriptor. The page where the
extent descriptor resides is x-locked. extent descriptor resides is x-locked.
@param[in] space tablespace @param[in] space tablespace
...@@ -611,25 +656,31 @@ fsp_space_modify_check( ...@@ -611,25 +656,31 @@ fsp_space_modify_check(
#endif /* UNIV_DEBUG */ #endif /* UNIV_DEBUG */
/** Initialize a file page. /** Initialize a file page.
@param[in] space tablespace
@param[in,out] block file page @param[in,out] block file page
@param[in,out] mtr mini-transaction */ @param[in,out] mtr mini-transaction */
MY_ATTRIBUTE((nonnull))
static static
void void
fsp_init_file_page( fsp_init_file_page(buf_block_t* block, mtr_t* mtr)
const fil_space_t* space MY_ATTRIBUTE((unused)),
buf_block_t* block,
mtr_t* mtr)
{ {
ut_d(fsp_space_modify_check(space, mtr));
ut_ad(space->id == block->page.id.space());
fsp_init_file_page_low(block); fsp_init_file_page_low(block);
mlog_write_initial_log_record(buf_block_get_frame(block), mlog_write_initial_log_record(buf_block_get_frame(block),
MLOG_INIT_FILE_PAGE2, mtr); MLOG_INIT_FILE_PAGE2, mtr);
} }
#ifdef UNIV_DEBUG
static
void
fsp_init_file_page(const fil_space_t* space, buf_block_t* block, mtr_t* mtr)
{
ut_d(fsp_space_modify_check(space, mtr));
ut_ad(space->id == block->page.id.space());
fsp_init_file_page(block, mtr);
}
#else /* UNIV_DEBUG */
# define fsp_init_file_page(space, block, mtr) fsp_init_file_page(block, mtr)
#endif
/***********************************************************//** /***********************************************************//**
Parses a redo log record of a file page init. Parses a redo log record of a file page init.
@return end of log record or NULL */ @return end of log record or NULL */
...@@ -3149,39 +3200,31 @@ fseg_free_page_func( ...@@ -3149,39 +3200,31 @@ fseg_free_page_func(
DBUG_VOID_RETURN; DBUG_VOID_RETURN;
} }
/**********************************************************************//** /** Determine whether a page is free.
Checks if a single page of a segment is free. @param[in,out] space tablespace
@return true if free */ @param[in] page page number
@return whether the page is marked as free */
bool bool
fseg_page_is_free( fseg_page_is_free(fil_space_t* space, unsigned page)
/*==============*/
fseg_header_t* seg_header, /*!< in: segment header */
ulint space_id, /*!< in: space id */
ulint page) /*!< in: page offset */
{ {
bool is_free;
mtr_t mtr; mtr_t mtr;
ibool is_free; page_size_t page_size(space->flags);
xdes_t* descr; page_no_t dpage = xdes_calc_descriptor_page(page_size, page);
fseg_inode_t* seg_inode;
mtr_start(&mtr);
const fil_space_t* space = mtr_x_lock_space(space_id, &mtr);
const page_size_t page_size(space->flags);
seg_inode = fseg_inode_get(seg_header, space_id, page_size, &mtr);
ut_a(seg_inode);
ut_ad(mach_read_from_4(seg_inode + FSEG_MAGIC_N)
== FSEG_MAGIC_N_VALUE);
ut_ad(!((page_offset(seg_inode) - FSEG_ARR_OFFSET) % FSEG_INODE_SIZE));
descr = xdes_get_descriptor(space, page, page_size, &mtr);
ut_a(descr);
is_free = xdes_mtr_get_bit( mtr.start();
descr, XDES_FREE_BIT, page % FSP_EXTENT_SIZE, &mtr); mtr_s_lock(&space->latch, &mtr);
mtr_commit(&mtr); if (page >= space->free_limit || page >= space->size_in_header) {
is_free = true;
} else if (const xdes_t* descr = xdes_get_descriptor_const(
space, dpage, page, page_size, &mtr)) {
is_free = xdes_get_bit(descr, XDES_FREE_BIT,
page % FSP_EXTENT_SIZE);
} else {
is_free = true;
}
mtr.commit();
return(is_free); return(is_free);
} }
...@@ -3563,28 +3606,3 @@ fseg_header::to_stream(std::ostream& out) const ...@@ -3563,28 +3606,3 @@ fseg_header::to_stream(std::ostream& out) const
return(out); return(out);
} }
#endif /* UNIV_DEBUG */ #endif /* UNIV_DEBUG */
/**********************************************************************//**
Checks if a single page is free.
@return true if free */
UNIV_INTERN
bool
fsp_page_is_free_func(
/*==============*/
ulint space_id, /*!< in: space id */
ulint page_no, /*!< in: page offset */
mtr_t* mtr, /*!< in/out: mini-transaction */
const char *file,
unsigned line)
{
ut_ad(mtr);
fil_space_t* space = mtr_x_lock_space(space_id, mtr);
const page_size_t page_size(space->flags);
xdes_t* descr = xdes_get_descriptor(space, page_no, page_size, mtr);
ut_a(descr);
return xdes_mtr_get_bit(
descr, XDES_FREE_BIT, page_no % FSP_EXTENT_SIZE, mtr);
}
/***************************************************************************** /*****************************************************************************
Copyright (c) 1995, 2016, Oracle and/or its affiliates. All Rights Reserved. Copyright (c) 1995, 2016, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2013, 2017, MariaDB Corporation. All Rights Reserved. Copyright (c) 2013, 2017, 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
...@@ -588,15 +588,12 @@ fseg_free_page_func( ...@@ -588,15 +588,12 @@ fseg_free_page_func(
# define fseg_free_page(header, space_id, page, ahi, mtr) \ # define fseg_free_page(header, space_id, page, ahi, mtr) \
fseg_free_page_func(header, space_id, page, mtr) fseg_free_page_func(header, space_id, page, mtr)
#endif /* BTR_CUR_HASH_ADAPT */ #endif /* BTR_CUR_HASH_ADAPT */
/**********************************************************************//** /** Determine whether a page is free.
Checks if a single page of a segment is free. @param[in,out] space tablespace
@return true if free */ @param[in] page page number
@return whether the page is marked as free */
bool bool
fseg_page_is_free( fseg_page_is_free(fil_space_t* space, unsigned page)
/*==============*/
fseg_header_t* seg_header, /*!< in: segment header */
ulint space_id, /*!< in: space id */
ulint page) /*!< in: page offset */
MY_ATTRIBUTE((nonnull, warn_unused_result)); MY_ATTRIBUTE((nonnull, warn_unused_result));
/**********************************************************************//** /**********************************************************************//**
Frees part of a segment. This function can be used to free a segment Frees part of a segment. This function can be used to free a segment
...@@ -834,22 +831,6 @@ xdes_calc_descriptor_page( ...@@ -834,22 +831,6 @@ xdes_calc_descriptor_page(
const page_size_t& page_size, const page_size_t& page_size,
ulint offset); ulint offset);
/**********************************************************************//**
Checks if a single page is free.
@return true if free */
UNIV_INTERN
bool
fsp_page_is_free_func(
/*==============*/
ulint space, /*!< in: space id */
ulint page, /*!< in: page offset */
mtr_t* mtr, /*!< in/out: mini-transaction */
const char *file,
unsigned line);
#define fsp_page_is_free(space,page,mtr) \
fsp_page_is_free_func(space,page,mtr, __FILE__, __LINE__)
#endif /* UNIV_INNOCHECKSUM */ #endif /* UNIV_INNOCHECKSUM */
#include "fsp0fsp.ic" #include "fsp0fsp.ic"
......
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