mirror of
https://github.com/MariaDB/server.git
synced 2025-01-17 12:32:27 +01:00
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".
This commit is contained in:
parent
59caf2c3c1
commit
e52dd13c2e
4 changed files with 89 additions and 101 deletions
|
@ -4846,7 +4846,6 @@ btr_validate_level(
|
|||
bool ret = true;
|
||||
mtr_t mtr;
|
||||
mem_heap_t* heap = mem_heap_create(256);
|
||||
fseg_header_t* seg;
|
||||
ulint* offsets = NULL;
|
||||
ulint* offsets2= NULL;
|
||||
#ifdef UNIV_ZIP_DEBUG
|
||||
|
@ -4870,7 +4869,6 @@ btr_validate_level(
|
|||
|
||||
block = btr_root_block_get(index, RW_SX_LATCH, &mtr);
|
||||
page = buf_block_get_frame(block);
|
||||
seg = page + PAGE_HEADER + PAGE_BTR_SEG_TOP;
|
||||
|
||||
#ifdef UNIV_DEBUG
|
||||
if (dict_index_is_spatial(index)) {
|
||||
|
@ -4879,7 +4877,7 @@ btr_validate_level(
|
|||
}
|
||||
#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(
|
||||
dict_table_page_size(index->table));
|
||||
const page_size_t space_page_size(space->flags);
|
||||
|
@ -4897,9 +4895,7 @@ btr_validate_level(
|
|||
while (level != btr_page_get_level(page, &mtr)) {
|
||||
const rec_t* node_ptr;
|
||||
|
||||
if (fseg_page_is_free(seg,
|
||||
block->page.id.space(),
|
||||
block->page.id.page_no())) {
|
||||
if (fseg_page_is_free(space, block->page.id.page_no())) {
|
||||
|
||||
btr_validate_report1(index, level, block);
|
||||
|
||||
|
@ -4959,11 +4955,6 @@ btr_validate_level(
|
|||
/* Now we are on the desired level. Loop through the pages on that
|
||||
level. */
|
||||
|
||||
if (level == 0) {
|
||||
/* Leaf pages are managed in their own file segment. */
|
||||
seg -= PAGE_BTR_SEG_TOP - PAGE_BTR_SEG_LEAF;
|
||||
}
|
||||
|
||||
loop:
|
||||
mem_heap_empty(heap);
|
||||
offsets = offsets2 = NULL;
|
||||
|
@ -4982,9 +4973,7 @@ loop:
|
|||
|
||||
ut_a(block->page.id.space() == index->space);
|
||||
|
||||
if (fseg_page_is_free(seg,
|
||||
block->page.id.space(),
|
||||
block->page.id.page_no())) {
|
||||
if (fseg_page_is_free(space, block->page.id.page_no())) {
|
||||
|
||||
btr_validate_report1(index, level, block);
|
||||
|
||||
|
|
|
@ -1723,7 +1723,7 @@ btr_scrub_get_block_and_allocation_status(
|
|||
|
||||
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_ALLOCATED;
|
||||
|
||||
|
|
|
@ -506,6 +506,51 @@ xdes_get_descriptor(
|
|||
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
|
||||
extent descriptor resides is x-locked.
|
||||
@param[in] space tablespace
|
||||
|
@ -611,25 +656,31 @@ fsp_space_modify_check(
|
|||
#endif /* UNIV_DEBUG */
|
||||
|
||||
/** Initialize a file page.
|
||||
@param[in] space tablespace
|
||||
@param[in,out] block file page
|
||||
@param[in,out] mtr mini-transaction */
|
||||
MY_ATTRIBUTE((nonnull))
|
||||
static
|
||||
void
|
||||
fsp_init_file_page(
|
||||
const fil_space_t* space MY_ATTRIBUTE((unused)),
|
||||
buf_block_t* block,
|
||||
mtr_t* mtr)
|
||||
fsp_init_file_page(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);
|
||||
|
||||
mlog_write_initial_log_record(buf_block_get_frame(block),
|
||||
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.
|
||||
@return end of log record or NULL */
|
||||
|
@ -3149,39 +3200,31 @@ fseg_free_page_func(
|
|||
DBUG_VOID_RETURN;
|
||||
}
|
||||
|
||||
/**********************************************************************//**
|
||||
Checks if a single page of a segment is free.
|
||||
@return true if free */
|
||||
/** Determine whether a page is free.
|
||||
@param[in,out] space tablespace
|
||||
@param[in] page page number
|
||||
@return whether the page is marked as free */
|
||||
bool
|
||||
fseg_page_is_free(
|
||||
/*==============*/
|
||||
fseg_header_t* seg_header, /*!< in: segment header */
|
||||
ulint space_id, /*!< in: space id */
|
||||
ulint page) /*!< in: page offset */
|
||||
fseg_page_is_free(fil_space_t* space, unsigned page)
|
||||
{
|
||||
bool is_free;
|
||||
mtr_t mtr;
|
||||
ibool is_free;
|
||||
xdes_t* descr;
|
||||
fseg_inode_t* seg_inode;
|
||||
page_size_t page_size(space->flags);
|
||||
page_no_t dpage = xdes_calc_descriptor_page(page_size, page);
|
||||
|
||||
mtr_start(&mtr);
|
||||
const fil_space_t* space = mtr_x_lock_space(space_id, &mtr);
|
||||
const page_size_t page_size(space->flags);
|
||||
mtr.start();
|
||||
mtr_s_lock(&space->latch, &mtr);
|
||||
|
||||
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(
|
||||
descr, XDES_FREE_BIT, page % FSP_EXTENT_SIZE, &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);
|
||||
}
|
||||
|
@ -3563,28 +3606,3 @@ fseg_header::to_stream(std::ostream& out) const
|
|||
return(out);
|
||||
}
|
||||
#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);
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/*****************************************************************************
|
||||
|
||||
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
|
||||
the terms of the GNU General Public License as published by the Free Software
|
||||
|
@ -588,15 +588,12 @@ fseg_free_page_func(
|
|||
# define fseg_free_page(header, space_id, page, ahi, mtr) \
|
||||
fseg_free_page_func(header, space_id, page, mtr)
|
||||
#endif /* BTR_CUR_HASH_ADAPT */
|
||||
/**********************************************************************//**
|
||||
Checks if a single page of a segment is free.
|
||||
@return true if free */
|
||||
/** Determine whether a page is free.
|
||||
@param[in,out] space tablespace
|
||||
@param[in] page page number
|
||||
@return whether the page is marked as free */
|
||||
bool
|
||||
fseg_page_is_free(
|
||||
/*==============*/
|
||||
fseg_header_t* seg_header, /*!< in: segment header */
|
||||
ulint space_id, /*!< in: space id */
|
||||
ulint page) /*!< in: page offset */
|
||||
fseg_page_is_free(fil_space_t* space, unsigned page)
|
||||
MY_ATTRIBUTE((nonnull, warn_unused_result));
|
||||
/**********************************************************************//**
|
||||
Frees part of a segment. This function can be used to free a segment
|
||||
|
@ -834,22 +831,6 @@ xdes_calc_descriptor_page(
|
|||
const page_size_t& page_size,
|
||||
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 */
|
||||
|
||||
#include "fsp0fsp.ic"
|
||||
|
|
Loading…
Reference in a new issue