/** @return the PAGE_SSIZE flags for the current innodb_page_size */ #define FSP_FLAGS_PAGE_SSIZE() \
((srv_page_size == UNIV_PAGE_SIZE_ORIG) ? \ 0U : (srv_page_size_shift - UNIV_ZIP_SIZE_SHIFT_MIN + 1) \
<< FSP_FLAGS_POS_PAGE_SSIZE)
/** @return the PAGE_SSIZE flags for the current innodb_page_size in
full checksum format */ #define FSP_FLAGS_FCRC32_PAGE_SSIZE() \
((srv_page_size_shift - UNIV_ZIP_SIZE_SHIFT_MIN + 1) \
<< FSP_FLAGS_FCRC32_POS_PAGE_SSIZE)
/* @defgroup Compatibility macros for MariaDB 10.1.0 through 10.1.20;
see the table in fsp0types.h @{ */ /** Zero relative shift position of the PAGE_COMPRESSION field */ #define FSP_FLAGS_POS_PAGE_COMPRESSION_MARIADB101 \
(FSP_FLAGS_POS_ATOMIC_BLOBS \
+ FSP_FLAGS_WIDTH_ATOMIC_BLOBS) /** Zero relative shift position of the PAGE_COMPRESSION_LEVEL field */ #define FSP_FLAGS_POS_PAGE_COMPRESSION_LEVEL_MARIADB101 \
(FSP_FLAGS_POS_PAGE_COMPRESSION_MARIADB101 + 1) /** Zero relative shift position of the ATOMIC_WRITES field */ #define FSP_FLAGS_POS_ATOMIC_WRITES_MARIADB101 \
(FSP_FLAGS_POS_PAGE_COMPRESSION_LEVEL_MARIADB101 + 4) /** Zero relative shift position of the PAGE_SSIZE field */ #define FSP_FLAGS_POS_PAGE_SSIZE_MARIADB101 \
(FSP_FLAGS_POS_ATOMIC_WRITES_MARIADB101 + 2)
/** Bit mask of the PAGE_COMPRESSION field */ #define FSP_FLAGS_MASK_PAGE_COMPRESSION_MARIADB101 \
(1U << FSP_FLAGS_POS_PAGE_COMPRESSION_MARIADB101) /** Bit mask of the PAGE_COMPRESSION_LEVEL field */ #define FSP_FLAGS_MASK_PAGE_COMPRESSION_LEVEL_MARIADB101 \
(15U << FSP_FLAGS_POS_PAGE_COMPRESSION_LEVEL_MARIADB101) /** Bit mask of the ATOMIC_WRITES field */ #define FSP_FLAGS_MASK_ATOMIC_WRITES_MARIADB101 \
(3U << FSP_FLAGS_POS_ATOMIC_WRITES_MARIADB101) /** Bit mask of the PAGE_SSIZE field */ #define FSP_FLAGS_MASK_PAGE_SSIZE_MARIADB101 \
(15U << FSP_FLAGS_POS_PAGE_SSIZE_MARIADB101)
/** Return the value of the PAGE_COMPRESSION field */ #define FSP_FLAGS_GET_PAGE_COMPRESSION_MARIADB101(flags) \
((flags & FSP_FLAGS_MASK_PAGE_COMPRESSION_MARIADB101) \
>> FSP_FLAGS_POS_PAGE_COMPRESSION_MARIADB101) /** Return the value of the PAGE_COMPRESSION_LEVEL field */ #define FSP_FLAGS_GET_PAGE_COMPRESSION_LEVEL_MARIADB101(flags) \
((flags & FSP_FLAGS_MASK_PAGE_COMPRESSION_LEVEL_MARIADB101) \
>> FSP_FLAGS_POS_PAGE_COMPRESSION_LEVEL_MARIADB101) /** Return the value of the PAGE_SSIZE field */ #define FSP_FLAGS_GET_PAGE_SSIZE_MARIADB101(flags) \
((flags & FSP_FLAGS_MASK_PAGE_SSIZE_MARIADB101) \
>> FSP_FLAGS_POS_PAGE_SSIZE_MARIADB101)
/* @} */
/* @defgroup Tablespace Header Constants (moved from fsp0fsp.c) @{ */
/** Offset of the space header within a file page */ #define FSP_HEADER_OFFSET FIL_PAGE_DATA
/* The data structures in files are defined just as byte strings in C */ typedef byte xdes_t;
/* SPACE HEADER ============
Filespaceheaderdatastructure:thisdatastructureiscontainedinthe firstpageofaspace.Thespaceforthisheaderisreservedineveryextent
descriptor page, but used only in the first. */
/*-------------------------------------*/ #define FSP_SPACE_ID 0/* space id */ #define FSP_NOT_USED 4/* this field contained a value up to whichweknowthatthemodifications inthedatabasehavebeenflushedto
the file space; not used now */ #define FSP_SIZE 8/* Current size of the space in
pages */ #define FSP_FREE_LIMIT 12/* Minimum page number for which the freelisthasnotbeeninitialized: thepages>=thislimitare,by definition,free;notethatina single-tabletablespacewheresize <64pages,thisnumberis64,i.e., wehaveinitializedthespace aboutthefirstextent,buthavenot physicallyallocatedthosepagestothe
file */ #define FSP_SPACE_FLAGS 16/* fsp_space_t.flags, similar to
dict_table_t::flags */ #define FSP_FRAG_N_USED 20/* number of used pages in the
FSP_FREE_FRAG list */ #define FSP_FREE 24/* list of free extents */ #define FSP_FREE_FRAG (24 + FLST_BASE_NODE_SIZE) /* list of partially free extents not
belonging to any segment */ #define FSP_FULL_FRAG (24 + 2 * FLST_BASE_NODE_SIZE) /* list of full extents not belonging
to any segment */ #define FSP_SEG_ID (24 + 3 * FLST_BASE_NODE_SIZE) /* 8 bytes which give the first unused
segment id */ #define FSP_SEG_INODES_FULL (32 + 3 * FLST_BASE_NODE_SIZE) /* list of pages containing segment headers,whereallthesegmentinode
slots are reserved */ #define FSP_SEG_INODES_FREE (32 + 4 * FLST_BASE_NODE_SIZE) /* list of pages containing segment headers,wherenotallthesegment
header slots are reserved */ /*-------------------------------------*/ /* File space header size */ #define FSP_HEADER_SIZE (32 + 5 * FLST_BASE_NODE_SIZE)
#define FSP_FREE_ADD 4/* this many free extents are added tothefreelistfromabove
FSP_FREE_LIMIT at a time */ /* @} */
#define FSEG_INODE_PAGE_NODE FSEG_PAGE_DATA /* the list node for linking
segment inode pages */
#define FSEG_ARR_OFFSET (FSEG_PAGE_DATA + FLST_NODE_SIZE) /*-------------------------------------*/ #define FSEG_ID 0/* 8 bytes of segment id: if this is 0,
it means that the header is unused */ #define FSEG_NOT_FULL_N_USED 8 /* number of used segment pages in
the FSEG_NOT_FULL list */ #define FSEG_FREE 12 /* list of free extents of this
segment */ #define FSEG_NOT_FULL (12 + FLST_BASE_NODE_SIZE) /* list of partially free extents */ #define FSEG_FULL (12 + 2 * FLST_BASE_NODE_SIZE) /* list of full extents */ #define FSEG_MAGIC_N (12 + 3 * FLST_BASE_NODE_SIZE) /* magic number used in debugging */ #define FSEG_FRAG_ARR (16 + 3 * FLST_BASE_NODE_SIZE) /* array of individual pages belongingtothissegmentinfsp
fragment extent lists */ #define FSEG_FRAG_ARR_N_SLOTS (FSP_EXTENT_SIZE / 2) /* number of slots in the array for
the fragment pages */ #define FSEG_FRAG_SLOT_SIZE 4/* a fragment page slot contains its pagenumberwithinspace,FIL_NULL
means that the slot is not in use */ /*-------------------------------------*/ #define FSEG_INODE_SIZE \
(16 + 3 * FLST_BASE_NODE_SIZE \
+ FSEG_FRAG_ARR_N_SLOTS * FSEG_FRAG_SLOT_SIZE)
#define FSEG_FREE_LIST_LIMIT 40/* If the reserved size of a segment isatleastthismanyextents,we allowextentstobeputtothefree listoftheextent:atmost
FSEG_FREE_LIST_MAX_LEN many */ #define FSEG_FREE_LIST_MAX_LEN 4 /* @} */
/* @defgroup Extent Descriptor Constants (moved from fsp0fsp.c) @{ */
/* EXTENT DESCRIPTOR =================
Fileextentdescriptordatastructure:containsbitstotellwhichpagesin
the extent are free and which contain old tuple version to clean. */
/*-------------------------------------*/ #define XDES_ID 0/* The identifier of the segment
to which this extent belongs */ #define XDES_FLST_NODE 8/* The list node data structure
for the descriptors */ #define XDES_STATE (FLST_NODE_SIZE + 8) /* contains state information
of the extent */ #define XDES_BITMAP (FLST_NODE_SIZE + 12) /* Descriptor bitmap of the pages
in the extent */ /*-------------------------------------*/
#define XDES_BITS_PER_PAGE 2/* How many bits are there per page */ #define XDES_FREE_BIT 0/* Index of the bit which tells if
the page is free */ #define XDES_CLEAN_BIT 1/* NOTE: currently not used! Indexofthebitwhichtellsif thereareoldversionsoftuples
on the page */ /* States of a descriptor */ #define XDES_FREE 1/* extent is in free list of space */ #define XDES_FREE_FRAG 2/* extent is in free fragment list of
space */ #define XDES_FULL_FRAG 3/* extent is in full fragment list of
space */ #define XDES_FSEG 4/* extent belongs to a segment */
/** File extent data structure size in bytes. */ #define XDES_SIZE \
(XDES_BITMAP \
+ UT_BITS_IN_BYTES(FSP_EXTENT_SIZE * XDES_BITS_PER_PAGE))
/** File extent data structure size in bytes for MAX page size. */ #define XDES_SIZE_MAX \
(XDES_BITMAP \
+ UT_BITS_IN_BYTES(FSP_EXTENT_SIZE_MAX * XDES_BITS_PER_PAGE))
/** File extent data structure size in bytes for MIN page size. */ #define XDES_SIZE_MIN \
(XDES_BITMAP \
+ UT_BITS_IN_BYTES(FSP_EXTENT_SIZE_MIN * XDES_BITS_PER_PAGE))
/** Offset of the descriptor array on a descriptor page */ #define XDES_ARR_OFFSET (FSP_HEADER_OFFSET + FSP_HEADER_SIZE)
/** Read a tablespace header field. @param[in]pagefirstpageofatablespace @param[in]fieldtheheaderfield
@return the contents of the header field */ inline uint32_t fsp_header_get_field(const page_t* page, ulint field)
{ return mach_read_from_4(FSP_HEADER_OFFSET + field +
my_assume_aligned<UNIV_ZIP_SIZE_MIN>(page));
}
/** Read the flags from the tablespace header page. @param[in]pagefirstpageofatablespace
@return the contents of FSP_SPACE_FLAGS */ inline uint32_t fsp_header_get_flags(const page_t *page)
{ return fsp_header_get_field(page, FSP_SPACE_FLAGS);
}
/** Get the byte offset of encryption information in page 0. @param[in]zip_sizeROW_FORMAT=COMPRESSEDpagesize,or0
@return byte offset relative to FSP_HEADER_OFFSET */ inline MY_ATTRIBUTE((pure, warn_unused_result))
ulint fsp_header_get_encryption_offset(ulint zip_size)
{ return zip_size
? XDES_ARR_OFFSET + XDES_SIZE * zip_size / FSP_EXTENT_SIZE
: XDES_ARR_OFFSET + (XDES_SIZE << srv_page_size_shift)
/ FSP_EXTENT_SIZE;
}
/** Check the encryption key from the first page of a tablespace. @param[in]fsp_flagstablespaceflags @param[in]pagefirstpageofatablespace
@return true if success */ bool
fsp_header_check_encryption_key(
ulint fsp_flags,
page_t* page);
/** Create a new segment. @paramspacetablespace @parambyte_offsetbyteoffsetofthecreatedsegmentheader @parammtrmini-transaction @paramerrerrorcode @paramhas_done_reservationwhetherfsp_reserve_free_extents()wasinvoked @paramblockblockwheresegmentheaderisplaced, orNULLtoallocateanadditionalpageforthat @returntheblockwherethesegmentheaderisplaced,x-latched
@retval nullptr if could not create segment */
buf_block_t*
fseg_create(fil_space_t *space, ulint byte_offset, mtr_t *mtr, dberr_t *err, bool has_done_reservation= false, buf_block_t *block= nullptr)
MY_ATTRIBUTE((nonnull(1,3,4), warn_unused_result));
/** Calculate the number of pages reserved by a segment, andhowmanypagesarecurrentlyused. @param[in]blockbufferblockcontainingthefilesegmentheader @param[in]headerfilesegmentheader @param[out]usednumberofpagesthatareused(notmorethanreserved) @param[in,out]mtrmini-transaction
@return number of reserved pages */
uint32_t fseg_n_reserved_pages(const buf_block_t &block, const fseg_header_t *header, uint32_t *used,
mtr_t *mtr) noexcept
MY_ATTRIBUTE((nonnull)); /**********************************************************************//**
Allocates a single free page from a segment. This function implements
the intelligent allocation strategy which tries to minimize file space
fragmentation.
@retval NULL if no page could be allocated */
buf_block_t*
fseg_alloc_free_page_general( /*=========================*/
fseg_header_t* seg_header,/*!< in/out: segment header */
uint32_t hint, /*!< in: hint of which page would be
desirable */
byte direction,/*!< in: if the new page is needed because ofanindexpagesplit,andrecordsare insertedthereinorder,intowhich directiontheygoalphabetically:FSP_DOWN,
FSP_UP, FSP_NO_DIR */ bool has_done_reservation, /*!< in: true if the caller has alreadydonethereservationforthepage withfsp_reserve_free_extents,thenthere isnoneedtodothecheckforthisindividual
page */
mtr_t* mtr, /*!< in/out: mini-transaction */
mtr_t* init_mtr,/*!< in/out: mtr or another mini-transaction
in which the page should be initialized. */
dberr_t* err) /*!< out: error code */
MY_ATTRIBUTE((warn_unused_result, nonnull));
/** Reserves free pages from a tablespace. All mini-transactions which may useseveralpagesfromthetablespaceshouldcallthisfunctionbeforehand andreserveenoughfreeextentssothattheycertainlywillbeable todotheiroperation,likeaB-treepagesplit,fully.Reservations mustbereleasedwithfunctionfil_space_t::release_free_extents()!
/** Determine whether a page is allocated. @parammtrmini-transaction @paramspacetablespace @parampagepagenumber @returnerrorcode @retvalDB_SUCCESSifthepageismarkedasfree
@retval DB_SUCCESS_LOCKED_REC if the page is marked as allocated */
dberr_t fseg_page_is_allocated(mtr_t *mtr, fil_space_t *space, unsigned page)
noexcept
MY_ATTRIBUTE((nonnull(1), warn_unused_result));
MY_ATTRIBUTE((nonnull, warn_unused_result)) /** Frees part of a segment. This function can be used to free asegmentbyrepeatedlycallingthisfunctionindifferent mini-transactions.Doingthefreeinginasinglemini-transaction mightresultintoobigamini-transaction. @paramblocksegmentheaderblock @paramheadersegmentheaderoffsetintheblock; NOTE:iftheheaderresidesonfirstpageofthefraglistofthesegment, thispointerbecomesobsoleteafterthelastfreeingstep @parammtrmini-transaction
@return whether the freeing was completed */ bool fseg_free_step(buf_block_t *block, size_t header, mtr_t *mtr #ifdef BTR_CUR_HASH_ADAPT
, bool ahi=false/*!< whether to drop the AHI */ #endif/* BTR_CUR_HASH_ADAPT */
) noexcept;
MY_ATTRIBUTE((nonnull, warn_unused_result)) /** Frees part of a segment. Differs from fseg_free_step because thisfunctionleavestheheaderpageunfreed. @paramblocksegmentheaderblock;mustresideonthefirst fragmentpageofthesegment @paramheadersegmentheaderoffsetintheblock @parammtrmini-transaction
@return whether the freeing was completed, except for the header page */ bool fseg_free_step_not_header(buf_block_t *block, size_t header, mtr_t *mtr #ifdef BTR_CUR_HASH_ADAPT
, bool ahi=false/*!< whether to drop the AHI */ #endif/* BTR_CUR_HASH_ADAPT */
) noexcept;
/** Checks if a page address is an extent descriptor page address. @param[in]page_idpageid @param[in]physical_sizepagesize
@return whether a descriptor page */ inlinebool fsp_descr_page(const page_id_t page_id, ulint physical_size)
{ return (page_id.page_no() & (physical_size - 1)) == FSP_XDES_OFFSET;
}
/** Initialize a file page whose prior contents should be ignored.
@param[in,out] block buffer pool block */ void fsp_apply_init_file_page(buf_block_t *block);
#ifdef UNIV_BTR_PRINT /*******************************************************************//**
Writes info of a segment. */ void
fseg_print( /*=======*/
fseg_header_t* header, /*!< in: segment header */
mtr_t* mtr); /*!< in/out: mini-transaction */ #endif/* UNIV_BTR_PRINT */
/** Convert FSP_SPACE_FLAGS from the buggy MariaDB 10.1.0..10.1.20 format. @param[in]flagsthecontentsofFSP_SPACE_FLAGS @returntheflagscorrectedfromthebuggyMariaDB10.1format
@retval UINT32_MAX if the flags are not in the buggy 10.1 format */
MY_ATTRIBUTE((warn_unused_result, const)) inline uint32_t fsp_flags_convert_from_101(uint32_t flags)
{
DBUG_EXECUTE_IF("fsp_flags_is_valid_failure", return UINT32_MAX;); if (flags == 0 || fil_space_t::full_crc32(flags)) { return(flags);
}
if (flags >> 18) { /* The most significant FSP_SPACE_FLAGS bit that was ever set byMariaDB10.1.0to10.1.20wasbit17(misplacedDATA_DIRflag).
The flags must be less than 1<<18 in order to be valid. */ return UINT32_MAX;
}
if ((flags & (FSP_FLAGS_MASK_POST_ANTELOPE | FSP_FLAGS_MASK_ATOMIC_BLOBS))
== FSP_FLAGS_MASK_ATOMIC_BLOBS) { /* If the "atomic blobs" flag (indicating ROW_FORMAT=DYNAMICorROW_FORMAT=COMPRESSED)flag isset,thenthe"postAntelope"(ROW_FORMAT!=REDUNDANT)flag
must also be set. */ return UINT32_MAX;
}
/* Bits 6..10 denote compression in MariaDB 10.1.0 to 10.1.20. Theymustbeeither0b00000or0b00011through0b10011. Incorrectversions,thesebitswouldbe 0bd0ssswheredistheDATA_DIRflag(garbagebit)and sssisthePAGE_SSIZE(3,4,6,or7).
-0by1zzz:impossible(thebit4mustbeclean;seeabove) -0b101xx:DATA_DIR,innodb_page_size>4k:invalid(COMPRESSION_LEVEL>9) +0bx0011:innodb_page_size=4k: !!!MisinterpretedasCOMPRESSION_LEVEL=9or1,COMPRESSION=1. -0bx0010:impossible,becausesssmustbe0b011or0b1xx -0bx0001:impossible,becausesssmustbe0b011or0b1xx -0b10000:DATA_DIR,innodb_page_size=16: invalid(COMPRESSION_LEVEL=8butCOMPRESSION=0) +0b00111:noDATA_DIR,innodb_page_size=64k: !!!MisinterpretedasCOMPRESSION_LEVEL=3,COMPRESSION=1. -0b00101:impossible,becausesssmustbe0for16k,not0b101 -0b001x0:noDATA_DIR,innodb_page_size=32kor8k: invalid(COMPRESSION_LEVEL=3butCOMPRESSION=0) +0b00000:innodb_page_size=16k(lookslikeCOMPRESSION=0)
??? Could actually be compressed; see PAGE_SSIZE below */ const uint32_t level = FSP_FLAGS_GET_PAGE_COMPRESSION_LEVEL_MARIADB101(
flags); if (FSP_FLAGS_GET_PAGE_COMPRESSION_MARIADB101(flags) != (level != 0)
|| level > 9) { /* The compression flags are not in the buggy MariaDB
10.1 format. */ return UINT32_MAX;
} if (!(~flags & FSP_FLAGS_MASK_ATOMIC_WRITES_MARIADB101)) { /* The ATOMIC_WRITES flags cannot be 0b11. (Thebits11..12shouldactuallyneverbe0b11,
because in MySQL they would be SHARED|TEMPORARY.) */ return UINT32_MAX;
}
/* Bits 13..16 are the wrong position for PAGE_SSIZE, and they shouldcontainoneofthevalues3,4,6,7,thatis,beoftheform 0b0011or0b01xx(except0b0101). Incorrectversions,thesebitsshouldbe0bc0se wherecistheMariaDBCOMPRESSEDflag andeistheMySQL5.7ENCRYPTIONflag andsistheMySQL8.0SDIflag.MariaDBcanonlysupports=0,e=0.
Compressedinnodb_page_size=16ktableswithcorrectFSP_SPACE_FLAGS willbeproperlyrejectedbyolderMariaDB10.1.xbecausethey
would read as PAGE_SSIZE>=8 which is not valid. */
const uint32_t ssize = FSP_FLAGS_GET_PAGE_SSIZE_MARIADB101(flags); if (ssize == 1 || ssize == 2 || ssize == 5 || ssize & 8) { /* the page_size is not between 4k and 64k;
16k should be encoded as 0, not 5 */ return UINT32_MAX;
} const uint32_t zssize = FSP_FLAGS_GET_ZIP_SSIZE(flags); if (zssize == 0) { /* not ROW_FORMAT=COMPRESSED */
} elseif (zssize > (ssize ? ssize : 5)) { /* invalid KEY_BLOCK_SIZE */ return UINT32_MAX;
} elseif (~flags & (FSP_FLAGS_MASK_POST_ANTELOPE
| FSP_FLAGS_MASK_ATOMIC_BLOBS)) { /* both these flags should be set for
ROW_FORMAT=COMPRESSED */ return UINT32_MAX;
}
/** Determine if FSP_SPACE_FLAGS are from an incompatible MySQL format. @paramflagsthecontentsofFSP_SPACE_FLAGS @returnMySQLflagsshifted.
@retval 0, if not a MySQL incompatible format. */
MY_ATTRIBUTE((warn_unused_result, const)) inline uint32_t fsp_flags_is_incompatible_mysql(uint32_t flags)
{ /* MySQL-8.0SDIflag(bit14), orMySQL5.7Encryptionflag(bit13)
*/ return flags >> 13 & 3;
}
/** Determine the descriptor index within a descriptor page. @param[in]zip_sizeROW_FORMAT=COMPRESSEDpagesize,or0 @param[in]offsetpageoffset
@return descriptor index */ inline ulint xdes_calc_descriptor_index(ulint zip_size, ulint offset)
{ return ut_2pow_remainder<ulint>(offset,
zip_size ? zip_size : srv_page_size)
/ FSP_EXTENT_SIZE;
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.