InnoDB Plugin
1.0
|
#include "univ.i"
#include "mtr0mtr.h"
#include "fut0lst.h"
#include "ut0byte.h"
#include "page0types.h"
#include "fsp0types.h"
#include "fsp0fsp.ic"
Go to the source code of this file.
Macros | |
#define | FSP_FLAGS_WIDTH_POST_ANTELOPE 1 |
#define | FSP_FLAGS_WIDTH_ZIP_SSIZE 4 |
#define | FSP_FLAGS_WIDTH_ATOMIC_BLOBS 1 |
#define | FSP_FLAGS_WIDTH_PAGE_SSIZE 4 |
#define | FSP_FLAGS_WIDTH_DATA_DIR 1 |
#define | FSP_FLAGS_WIDTH |
#define | FSP_FLAGS_MASK (~(~0 << FSP_FLAGS_WIDTH)) |
#define | FSP_FLAGS_POS_POST_ANTELOPE 0 |
#define | FSP_FLAGS_POS_ZIP_SSIZE |
#define | FSP_FLAGS_POS_ATOMIC_BLOBS |
#define | FSP_FLAGS_POS_PAGE_SSIZE |
#define | FSP_FLAGS_POS_DATA_DIR |
#define | FSP_FLAGS_POS_UNUSED |
#define | FSP_FLAGS_MASK_POST_ANTELOPE |
#define | FSP_FLAGS_MASK_ZIP_SSIZE |
#define | FSP_FLAGS_MASK_ATOMIC_BLOBS |
#define | FSP_FLAGS_MASK_PAGE_SSIZE |
#define | FSP_FLAGS_MASK_DATA_DIR |
#define | FSP_FLAGS_GET_POST_ANTELOPE(flags) |
#define | FSP_FLAGS_GET_ZIP_SSIZE(flags) |
#define | FSP_FLAGS_HAS_ATOMIC_BLOBS(flags) |
#define | FSP_FLAGS_GET_PAGE_SSIZE(flags) |
#define | FSP_FLAGS_HAS_DATA_DIR(flags) |
#define | FSP_FLAGS_GET_UNUSED(flags) (flags >> FSP_FLAGS_POS_UNUSED) |
#define | FSP_FLAGS_SET_PAGE_SSIZE(flags, ssize) (flags | (ssize << FSP_FLAGS_POS_PAGE_SSIZE)) |
#define | FSP_HEADER_OFFSET FIL_PAGE_DATA |
#define | FSP_SPACE_ID 0 /* space id */ |
#define | FSP_NOT_USED |
#define | FSP_SIZE |
#define | FSP_FREE_LIMIT |
#define | FSP_SPACE_FLAGS |
#define | FSP_FRAG_N_USED |
#define | FSP_FREE 24 /* list of free extents */ |
#define | FSP_FREE_FRAG (24 + FLST_BASE_NODE_SIZE) |
#define | FSP_FULL_FRAG (24 + 2 * FLST_BASE_NODE_SIZE) |
#define | FSP_SEG_ID (24 + 3 * FLST_BASE_NODE_SIZE) |
#define | FSP_SEG_INODES_FULL (32 + 3 * FLST_BASE_NODE_SIZE) |
#define | FSP_SEG_INODES_FREE (32 + 4 * FLST_BASE_NODE_SIZE) |
#define | FSP_HEADER_SIZE (32 + 5 * FLST_BASE_NODE_SIZE) |
#define | FSP_FREE_ADD |
#define | FSEG_INODE_PAGE_NODE FSEG_PAGE_DATA |
#define | FSEG_ARR_OFFSET (FSEG_PAGE_DATA + FLST_NODE_SIZE) |
#define | FSEG_ID |
#define | FSEG_NOT_FULL_N_USED 8 |
#define | FSEG_FREE 12 |
#define | FSEG_NOT_FULL (12 + FLST_BASE_NODE_SIZE) |
#define | FSEG_FULL (12 + 2 * FLST_BASE_NODE_SIZE) |
#define | FSEG_MAGIC_N (12 + 3 * FLST_BASE_NODE_SIZE) |
#define | FSEG_FRAG_ARR (16 + 3 * FLST_BASE_NODE_SIZE) |
#define | FSEG_FRAG_ARR_N_SLOTS (FSP_EXTENT_SIZE / 2) |
#define | FSEG_FRAG_SLOT_SIZE |
#define | FSEG_INODE_SIZE |
#define | FSP_SEG_INODES_PER_PAGE(zip_size) |
#define | FSEG_MAGIC_N_VALUE 97937874 |
#define | FSEG_FILLFACTOR |
#define | FSEG_FRAG_LIMIT FSEG_FRAG_ARR_N_SLOTS |
#define | FSEG_FREE_LIST_LIMIT |
#define | FSEG_FREE_LIST_MAX_LEN 4 |
#define | XDES_ID |
#define | XDES_FLST_NODE |
#define | XDES_STATE (FLST_NODE_SIZE + 8) |
#define | XDES_BITMAP (FLST_NODE_SIZE + 12) |
#define | XDES_BITS_PER_PAGE 2 /* How many bits are there per page */ |
#define | XDES_FREE_BIT |
#define | XDES_CLEAN_BIT |
#define | XDES_FREE 1 /* extent is in free list of space */ |
#define | XDES_FREE_FRAG |
#define | XDES_FULL_FRAG |
#define | XDES_FSEG 4 /* extent belongs to a segment */ |
#define | XDES_SIZE |
#define | XDES_SIZE_MAX |
#define | XDES_SIZE_MIN |
#define | XDES_ARR_OFFSET (FSP_HEADER_OFFSET + FSP_HEADER_SIZE) |
#define | fseg_alloc_free_page(seg_header, hint, direction, mtr) |
Typedefs | |
typedef byte | fsp_header_t |
typedef byte | xdes_t |
typedef byte | fseg_inode_t |
Functions | |
UNIV_INTERN void | fsp_init (void) |
UNIV_INTERN ulint | fsp_header_get_tablespace_size (void) |
UNIV_INTERN ulint | fsp_get_size_low (page_t *page) |
UNIV_INTERN ulint | fsp_header_get_space_id (const page_t *page) |
UNIV_INTERN ulint | fsp_header_get_flags (const page_t *page) |
UNIV_INTERN ulint | fsp_header_get_zip_size (const page_t *page) |
UNIV_INTERN void | fsp_header_init_fields (page_t *page, ulint space_id, ulint flags) |
UNIV_INTERN void | fsp_header_init (ulint space, ulint size, mtr_t *mtr) |
UNIV_INTERN void | fsp_header_inc_size (ulint space, ulint size_inc, mtr_t *mtr) |
UNIV_INTERN buf_block_t * | fseg_create (ulint space, ulint page, ulint byte_offset, mtr_t *mtr) |
UNIV_INTERN buf_block_t * | fseg_create_general (ulint space, ulint page, ulint byte_offset, ibool has_done_reservation, mtr_t *mtr) |
UNIV_INTERN ulint | fseg_n_reserved_pages (fseg_header_t *header, ulint *used, mtr_t *mtr) |
UNIV_INTERN buf_block_t * | fseg_alloc_free_page_general (fseg_header_t *seg_header, ulint hint, byte direction, ibool has_done_reservation, mtr_t *mtr, mtr_t *init_mtr)) |
UNIV_INTERN ibool | fsp_reserve_free_extents (ulint *n_reserved, ulint space, ulint n_ext, ulint alloc_type, mtr_t *mtr) |
UNIV_INTERN ullint | fsp_get_available_space_in_free_extents (ulint space) |
UNIV_INTERN void | fseg_free_page (fseg_header_t *seg_header, ulint space, ulint page, mtr_t *mtr) |
UNIV_INTERN bool | fseg_page_is_free (fseg_header_t *seg_header, ulint space, ulint page)) |
UNIV_INTERN ibool | fseg_free_step (fseg_header_t *header, mtr_t *mtr) |
UNIV_INTERN ibool | fseg_free_step_not_header (fseg_header_t *header, mtr_t *mtr) |
UNIV_INLINE ibool | fsp_descr_page (ulint zip_size, ulint page_no) |
UNIV_INTERN byte * | fsp_parse_init_file_page (byte *ptr, byte *end_ptr, buf_block_t *block) |
UNIV_INTERN ibool | fsp_validate (ulint space) |
UNIV_INTERN void | fsp_print (ulint space) |
UNIV_INTERN ibool | fseg_validate (fseg_header_t *header, mtr_t *mtr) |
UNIV_INLINE bool | fsp_flags_is_valid (ulint flags)) |
UNIV_INLINE ibool | fsp_flags_is_compressed (ulint flags) |
UNIV_INLINE ulint | xdes_calc_descriptor_index (ulint zip_size, ulint offset) |
UNIV_INLINE ibool | xdes_get_bit (const xdes_t *descr, ulint bit, ulint offset) |
UNIV_INLINE ulint | xdes_calc_descriptor_page (ulint zip_size, ulint offset) |
UNIV_INLINE ulint | fsp_flags_get_zip_size (ulint flags) |
UNIV_INLINE ulint | fsp_flags_get_page_size (ulint flags) |
File space management
Created 12/18/1995 Heikki Tuuri
#define fseg_alloc_free_page | ( | seg_header, | |
hint, | |||
direction, | |||
mtr | |||
) |
Allocates a single free page from a segment. This function implements the intelligent allocation strategy which tries to minimize file space fragmentation.
in/out] | seg_header segment header | |
[in] | hint | hint of which page would be desirable |
[in] | direction | if the new page is needed because of an index page split, and records are inserted there in order, into which direction they go alphabetically: FSP_DOWN, FSP_UP, FSP_NO_DIR |
in/out] | mtr mini-transaction |
#define FSEG_FILLFACTOR |
#define FSEG_FRAG_SLOT_SIZE |
#define FSEG_FREE_LIST_LIMIT |
#define FSEG_ID |
#define FSEG_INODE_SIZE |
#define FSP_FLAGS_GET_PAGE_SSIZE | ( | flags | ) |
Return the value of the PAGE_SSIZE field
#define FSP_FLAGS_GET_POST_ANTELOPE | ( | flags | ) |
Return the value of the POST_ANTELOPE field
#define FSP_FLAGS_GET_UNUSED | ( | flags | ) | (flags >> FSP_FLAGS_POS_UNUSED) |
Return the contents of the UNUSED bits
#define FSP_FLAGS_GET_ZIP_SSIZE | ( | flags | ) |
Return the value of the ZIP_SSIZE field
#define FSP_FLAGS_HAS_ATOMIC_BLOBS | ( | flags | ) |
Return the value of the ATOMIC_BLOBS field
#define FSP_FLAGS_HAS_DATA_DIR | ( | flags | ) |
Return the value of the DATA_DIR field
#define FSP_FLAGS_MASK (~(~0 << FSP_FLAGS_WIDTH)) |
A mask of all the known/used bits in tablespace flags
#define FSP_FLAGS_MASK_ATOMIC_BLOBS |
Bit mask of the ATOMIC_BLOBS field
#define FSP_FLAGS_MASK_DATA_DIR |
Bit mask of the DATA_DIR field
#define FSP_FLAGS_MASK_PAGE_SSIZE |
Bit mask of the PAGE_SSIZE field
#define FSP_FLAGS_MASK_POST_ANTELOPE |
Bit mask of the POST_ANTELOPE field
#define FSP_FLAGS_MASK_ZIP_SSIZE |
Bit mask of the ZIP_SSIZE field
#define FSP_FLAGS_POS_ATOMIC_BLOBS |
Zero relative shift position of the ATOMIC_BLOBS field
#define FSP_FLAGS_POS_DATA_DIR |
Zero relative shift position of the start of the UNUSED bits
#define FSP_FLAGS_POS_PAGE_SSIZE |
Zero relative shift position of the PAGE_SSIZE field
#define FSP_FLAGS_POS_POST_ANTELOPE 0 |
Zero relative shift position of the POST_ANTELOPE field
#define FSP_FLAGS_POS_UNUSED |
Zero relative shift position of the start of the UNUSED bits
#define FSP_FLAGS_POS_ZIP_SSIZE |
Zero relative shift position of the ZIP_SSIZE field
#define FSP_FLAGS_SET_PAGE_SSIZE | ( | flags, | |
ssize | |||
) | (flags | (ssize << FSP_FLAGS_POS_PAGE_SSIZE)) |
Set a PAGE_SSIZE into the correct bits in a given
tablespace flags.
#define FSP_FLAGS_WIDTH |
Width of all the currently known tablespace flags
#define FSP_FLAGS_WIDTH_ATOMIC_BLOBS 1 |
Width of the ATOMIC_BLOBS flag. The ability to break up a long
column into an in-record prefix and an externally stored part is available to the two Barracuda row formats COMPRESSED and DYNAMIC.
#define FSP_FLAGS_WIDTH_DATA_DIR 1 |
Width of the DATA_DIR flag. This flag indicates that the tablespace
is found in a remote location, not the default data directory.
#define FSP_FLAGS_WIDTH_PAGE_SSIZE 4 |
Number of flag bits used to indicate the tablespace page size
#define FSP_FLAGS_WIDTH_POST_ANTELOPE 1 |
Width of the POST_ANTELOPE flag
#define FSP_FLAGS_WIDTH_ZIP_SSIZE 4 |
Number of flag bits used to indicate the tablespace zip page size
#define FSP_FRAG_N_USED |
#define FSP_FREE_ADD |
#define FSP_FREE_LIMIT |
#define FSP_HEADER_OFFSET FIL_PAGE_DATA |
Offset of the space header within a file page
#define FSP_NOT_USED |
#define FSP_SEG_INODES_PER_PAGE | ( | zip_size | ) |
#define FSP_SIZE |
#define FSP_SPACE_FLAGS |
#define XDES_ARR_OFFSET (FSP_HEADER_OFFSET + FSP_HEADER_SIZE) |
Offset of the descriptor array on a descriptor page
#define XDES_CLEAN_BIT |
#define XDES_FLST_NODE |
#define XDES_FREE_BIT |
#define XDES_FREE_FRAG |
#define XDES_FULL_FRAG |
#define XDES_ID |
#define XDES_SIZE |
File extent data structure size in bytes.
#define XDES_SIZE_MAX |
File extent data structure size in bytes for MAX page size.
#define XDES_SIZE_MIN |
File extent data structure size in bytes for MIN page size.
UNIV_INTERN buf_block_t* fseg_alloc_free_page_general | ( | fseg_header_t * | seg_header, |
ulint | hint, | ||
byte | direction, | ||
ibool | has_done_reservation, | ||
mtr_t * | mtr, | ||
mtr_t * | init_mtr | ||
) |
Allocates a single free page from a segment. This function implements the intelligent allocation strategy which tries to minimize file space fragmentation.
NULL | if no page could be allocated |
block,rw_lock_x_lock_count(&block->lock) | == 1 if allocation succeeded (init_mtr == mtr, or the page was not previously freed in mtr) |
block | (not allocated or initialized) otherwise |
seg_header | in/out: segment header |
hint | in: hint of which page would be desirable |
direction | in: if the new page is needed because of an index page split, and records are inserted there in order, into which direction they go alphabetically: FSP_DOWN, FSP_UP, FSP_NO_DIR |
has_done_reservation | in: TRUE if the caller has already done the reservation for the page with fsp_reserve_free_extents, then there is no need to do the check for this individual page |
mtr | in/out: mini-transaction |
init_mtr | in/out: mtr or another mini-transaction in which the page should be initialized. If init_mtr!=mtr, but the page is already latched in mtr, do not initialize the page. |
UNIV_INTERN buf_block_t* fseg_create | ( | ulint | space, |
ulint | page, | ||
ulint | byte_offset, | ||
mtr_t * | mtr | ||
) |
Creates a new segment.
space | in: space id |
page | in: page where the segment header is placed: if this is != 0, the page must belong to another segment, if this is 0, a new page will be allocated and it will belong to the created segment |
byte_offset | in: byte offset of the created segment header on the page |
UNIV_INTERN buf_block_t* fseg_create_general | ( | ulint | space, |
ulint | page, | ||
ulint | byte_offset, | ||
ibool | has_done_reservation, | ||
mtr_t * | mtr | ||
) |
Creates a new segment.
space | in: space id |
page | in: page where the segment header is placed: if this is != 0, the page must belong to another segment, if this is 0, a new page will be allocated and it will belong to the created segment |
byte_offset | in: byte offset of the created segment header on the page |
has_done_reservation | in: TRUE if the caller has already done the reservation for the pages with fsp_reserve_free_extents (at least 2 extents: one for the inode and the other for the segment) then there is no need to do the check for this individual operation |
UNIV_INTERN void fseg_free_page | ( | fseg_header_t * | seg_header, |
ulint | space, | ||
ulint | page, | ||
mtr_t * | mtr | ||
) |
Frees a single page of a segment. in/out: mini-transaction
seg_header | in: segment header |
space | in: space id |
page | in: page offset |
Frees part of a segment. This function can be used to free a segment by repeatedly calling this function in different mini-transactions. Doing the freeing in a single mini-transaction might result in too big a mini-transaction.
header | in, own: segment header; NOTE: if the header resides on the first page of the frag list of the segment, this pointer becomes obsolete after the last freeing step |
Frees part of a segment. Differs from fseg_free_step because this function leaves the header page unfreed.
header | in: segment header which must reside on the first fragment page of the segment |
UNIV_INTERN ulint fseg_n_reserved_pages | ( | fseg_header_t * | header, |
ulint * | used, | ||
mtr_t * | mtr | ||
) |
Calculates the number of pages reserved by a segment, and how many pages are currently used.
header | in: segment header |
used | out: number of pages used (<= reserved) |
UNIV_INTERN bool fseg_page_is_free | ( | fseg_header_t * | seg_header, |
ulint | space, | ||
ulint | page | ||
) |
Checks if a single page of a segment is free.
seg_header | in: segment header |
space | in: space id |
page | in: page offset |
Validates a segment.
header | in: segment header |
UNIV_INLINE ibool fsp_descr_page | ( | ulint | zip_size, |
ulint | page_no | ||
) |
Checks if a page address is an extent descriptor page address.
Checks if a page address is an extent descriptor page address.
zip_size | in: compressed page size in bytes; 0 for uncompressed pages |
page_no | in: page number |
UNIV_INLINE ulint fsp_flags_get_page_size | ( | ulint | flags | ) |
Extract the page size from tablespace flags.
Extract the page size from tablespace flags.
flags | in: tablespace flags |
UNIV_INLINE ulint fsp_flags_get_zip_size | ( | ulint | flags | ) |
Extract the zip size from tablespace flags. A tablespace has only one physical page size whether that page is compressed or not.
Extract the zip size from tablespace flags.
flags | in: tablespace flags |
UNIV_INLINE ibool fsp_flags_is_compressed | ( | ulint | flags | ) |
Determine if the tablespace is compressed from dict_table_t::flags.
Determine if the tablespace is compressed from dict_table_t::flags.
flags | in: tablespace flags |
UNIV_INLINE bool fsp_flags_is_valid | ( | ulint | flags | ) |
Validate and return the tablespace flags, which are stored in the tablespace header at offset FSP_SPACE_FLAGS. They should be 0 for ROW_FORMAT=COMPACT and ROW_FORMAT=REDUNDANT. The newer row formats, COMPRESSED and DYNAMIC, use a file format > Antelope so they should have a file format number plus the DICT_TF_COMPACT bit set.
flags | in: tablespace flags |
UNIV_INTERN ullint fsp_get_available_space_in_free_extents | ( | ulint | space | ) |
This function should be used to get information on how much we still will be able to insert new data to the database without running out the tablespace. Only free extents are taken into account and we also subtract the safety margin required by the above function fsp_reserve_free_extents.
UNIV_INTERN ulint fsp_get_size_low | ( | page_t * | page | ) |
Reads the file space size stored in the header page.
UNIV_INTERN ulint fsp_header_get_flags | ( | const page_t * | page | ) |
Reads the space flags from the first page of a tablespace.
UNIV_INTERN ulint fsp_header_get_space_id | ( | const page_t * | page | ) |
Reads the space id from the first page of a tablespace.
UNIV_INTERN ulint fsp_header_get_tablespace_size | ( | void | ) |
Gets the size of the system tablespace from the tablespace header. If we do not have an auto-extending data file, this should be equal to the size of the data files. If there is an auto-extending data file, this can be smaller.
UNIV_INTERN ulint fsp_header_get_zip_size | ( | const page_t * | page | ) |
Reads the compressed page size from the first page of a tablespace.
UNIV_INTERN void fsp_header_inc_size | ( | ulint | space, |
ulint | size_inc, | ||
mtr_t * | mtr | ||
) |
Increases the space size field of a space. in/out: mini-transaction
space | in: space id |
size_inc | in: size increment in pages |
UNIV_INTERN void fsp_header_init | ( | ulint | space, |
ulint | size, | ||
mtr_t * | mtr | ||
) |
Initializes the space header of a new created space and creates also the insert buffer tree root if space == 0. in/out: mini-transaction
space | in: space id |
size | in: current size in blocks |
UNIV_INTERN void fsp_header_init_fields | ( | page_t * | page, |
ulint | space_id, | ||
ulint | flags | ||
) |
Writes the space id and flags to a tablespace header. The flags contain row type, physical/compressed page size, and logical/uncompressed page size of the tablespace. in: tablespace flags (FSP_SPACE_FLAGS): 0, or table->flags if newer than COMPACT
page | in/out: first page in the space |
space_id | in: space id |
UNIV_INTERN void fsp_init | ( | void | ) |
Initializes the file space system.
UNIV_INTERN byte* fsp_parse_init_file_page | ( | byte * | ptr, |
byte * | end_ptr, | ||
buf_block_t * | block | ||
) |
Parses a redo log record of a file page init.
ptr | in: buffer |
end_ptr | in: buffer end |
UNIV_INTERN void fsp_print | ( | ulint | space | ) |
Prints info of a file space. in: space id
UNIV_INTERN ibool fsp_reserve_free_extents | ( | ulint * | n_reserved, |
ulint | space, | ||
ulint | n_ext, | ||
ulint | alloc_type, | ||
mtr_t * | mtr | ||
) |
Reserves free pages from a tablespace. All mini-transactions which may use several pages from the tablespace should call this function beforehand and reserve enough free extents so that they certainly will be able to do their operation, like a B-tree page split, fully. Reservations must be released with function fil_space_release_free_extents!
The alloc_type below has the following meaning: FSP_NORMAL means an operation which will probably result in more space usage, like an insert in a B-tree; FSP_UNDO means allocation to undo logs: if we are deleting rows, then this allocation will in the long run result in less space usage (after a purge); FSP_CLEANING means allocation done in a physical record delete (like in a purge) or other cleaning operation which will result in less space usage in the long run. We prefer the latter two types of allocation: when space is scarce, FSP_NORMAL allocations will not succeed, but the latter two allocations will succeed, if possible. The purpose is to avoid dead end where the database is full but the user cannot free any space because these freeing operations temporarily reserve some space.
Single-table tablespaces whose size is < 32 pages are a special case. In this function we would liberally reserve several 64 page extents for every page split or merge in a B-tree. But we do not want to waste disk space if the table only occupies < 32 pages. That is why we apply different rules in that special case, just ensuring that there are 3 free pages available.
n_reserved | out: number of extents actually reserved; if we return TRUE and the tablespace size is < 64 pages, then this can be 0, otherwise it is n_ext |
space | in: space id |
n_ext | in: number of extents to reserve |
alloc_type | in: FSP_NORMAL, FSP_UNDO, or FSP_CLEANING |
UNIV_INTERN ibool fsp_validate | ( | ulint | space | ) |
Validates the file space system and its segments.
UNIV_INLINE ulint xdes_calc_descriptor_index | ( | ulint | zip_size, |
ulint | offset | ||
) |
Calculates the descriptor index within a descriptor page.
Calculates the descriptor index within a descriptor page.
zip_size | in: compressed page size in bytes; 0 for uncompressed pages |
offset | in: page offset |
UNIV_INLINE ulint xdes_calc_descriptor_page | ( | ulint | zip_size, |
ulint | offset | ||
) |
Calculates the page where the descriptor of a page resides.
Calculates the page where the descriptor of a page resides.
zip_size | in: compressed page size in bytes; 0 for uncompressed pages |
offset | in: page offset |
UNIV_INLINE ibool xdes_get_bit | ( | const xdes_t * | descr, |
ulint | bit, | ||
ulint | offset | ||
) |
Gets a descriptor bit of a page.
Gets a descriptor bit of a page.
descr | in: descriptor |
bit | in: XDES_FREE_BIT or XDES_CLEAN_BIT |
offset | in: page offset within extent: 0 ... FSP_EXTENT_SIZE - 1 |