Äú¿ÉÒÔ¾èÖú£¬Ö§³ÖÎÒÃǵĹ«ÒæÊÂÒµ¡£

1Ôª 10Ôª 50Ôª





ÈÏÖ¤Â룺  ÑéÖ¤Âë,¿´²»Çå³þ?Çëµã»÷Ë¢ÐÂÑéÖ¤Âë ±ØÌî



  ÇóÖª ÎÄÕ ÎÄ¿â Lib ÊÓÆµ iPerson ¿Î³Ì ÈÏÖ¤ ×Éѯ ¹¤¾ß ½²×ù Model Center   Code  
»áÔ±   
   
 
     
   
 ¶©ÔÄ
  ¾èÖú
MYSQL INNODBÊý¾Ý´æ´¢½á¹¹
 
  3331  次浏览      27
 2019-8-20
 
±à¼­ÍƼö:
±¾ÎÄÀ´×ÔÓÚcsdn£¬±¾ÎĽéÉÜÁËInnoDB±í¿Õ¼äÎļþÖеÄÖ÷Òª×éÖ¯½á¹¹¶Î£¬Çø/´Ø£¬Ò³µÈÏà¹Ø¸ÅÄÒÔ¼°innodbµÄÎļþ¹ÜÀí·½Ê½£¬Ï£Íû¶ÔÄúÄÜÓÐËù°ïÖú¡£

Ò» Ðò£º

ÔÚÕûÀíInnoDB´æ´¢ÒýÇæµÄË÷ÒýµÄʱºò£¬·¢ÏÖB+Ê÷ÊÇÀë²»¿ªÒ³ÃæpageµÄ¡£ËùÒÔÏÈÕûÀíInnoDBµÄÊý¾Ý´æ´¢½á¹¹¡£

¹Ø¼ü´Ê£ºPages, Extents, Segments, and Tablespaces

ÈçºÎ´æ´¢±í

MySQL ʹÓà InnoDB ´æ´¢±íʱ£¬»á½«±íµÄ¶¨ÒåºÍÊý¾ÝË÷ÒýµÈÐÅÏ¢·Ö¿ª´æ´¢£¬ÆäÖÐǰÕß´æ´¢ÔÚ .frm ÎļþÖУ¬ºóÕß´æ´¢ÔÚ .ibd ÎļþÖУ¬ÕâÒ»½Ú¾Í»á¶ÔÕâÁ½ÖÖ²»Í¬µÄÎļþ·Ö±ð½øÐнéÉÜ¡£

.frm

ÎÞÂÛÔÚ MySQL ÖÐÑ¡ÔñÁËÄĸö´æ´¢ÒýÇæ£¬ËùÓÐµÄ MySQL ±í¶¼»áÔÚÓ²ÅÌÉÏ´´½¨Ò»¸ö .frm ÎļþÓÃÀ´ÃèÊö±íµÄ¸ñʽ»òÕß˵¶¨Ò壻 .frm ÎļþµÄ¸ñʽÔÚ²»Í¬µÄƽ̨É϶¼ÊÇÏàͬµÄ¡£

.ibd Îļþ

InnoDB ÖÐÓÃÓÚ´æ´¢Êý¾ÝµÄÎļþ×ܹ²ÓÐÁ½¸ö²¿·Ö£¬Ò»ÊÇϵͳ±í¿Õ¼äÎļþ£¬°üÀ¨ ibdata1¡¢ ibdata2 µÈÎļþ£¬ÆäÖд洢ÁË InnoDB ϵͳÐÅÏ¢ºÍÓû§Êý¾Ý¿â±íÊý¾ÝºÍË÷Òý£¬ÊÇËùÓÐ±í¹«Óõġ£

µ±´ò¿ª innodb_file_per_table Ñ¡Ïîʱ£¬ .ibd Îļþ¾ÍÊÇÿһ¸ö±í¶ÀÓеıí¿Õ¼ä£¬Îļþ´æ´¢Á˵±Ç°±íµÄÊý¾ÝºÍÏà¹ØµÄË÷ÒýÊý¾Ý¡£

±í¿Õ¼ä

innodb´æ´¢ÒýÇæÔÚ´æ´¢Éè¼ÆÉÏÄ£·ÂÁËOracleµÄ´æ´¢½á¹¹£¬ÆäÊý¾ÝÊǰ´ÕÕ±í¿Õ¼ä½øÐйÜÀíµÄ¡£Ð½¨Ò»¸öÊý¾Ý¿âʱ£¬innodb´æ´¢ÒýÇæ»á³õʼ»¯Ò»¸öÃûΪibdata1 µÄ±í¿Õ¼äÎļþ£¬Ä¬ÈÏÇé¿öÏ£¬Õâ¸öÎļþ»á´æ´¢ËùÓбíµÄÊý¾Ý£¬ÒÔ¼°ÎÒÃÇËùÊìÖªµ«¿´²»µ½µÄϵͳ±ísys_tables¡¢sys_columns¡¢sys_indexes ¡¢sys_fieldsµÈ¡£´ËÍ⣬»¹»á´æ´¢ÓÃÀ´±£Ö¤Êý¾ÝÍêÕûÐԵĻعö¶ÎÊý¾Ý£¬µ±È»Õⲿ·ÖÊý¾ÝÔÚа汾µÄMySQLÖУ¬ÒѾ­¿ÉÒÔͨ¹ý²ÎÊýÀ´ÉèÖûعö¶ÎµÄ´æ´¢Î»ÖÃÁË£»

¿´Ï¹ÙÍøµÄ½éÉÜ£º

A data file that can hold data for one or more InnoDB tables and associated indexes.

The system tablespace contains the InnoDB data dictionary, and prior to MySQL 5.6 holds all other InnoDB tables by default.

The innodb_file_per_table option, enabled by default in MySQL 5.6 and higher, allows tables to be created in their own tablespaces. File-per-table tablespaces support features such as efficient storage of off-page columns, table compression, and transportable tablespaces. See Section 14.7.4, ¡°InnoDB File-Per-Table Tablespaces¡± for details.

innodb´æ´¢ÒýÇæµÄÉè¼ÆºÜÁé»î£¬¿ÉÒÔͨ¹ý²ÎÊýinnodb_file_per_tableÀ´ÉèÖã¬Ê¹µÃÿһ¸ö±í¶¼¶ÔÓ¦Ò»¸ö×Ô¼ºµÄ¶ÀÁ¢±í¿Õ¼äÎļþ£¬¶ø²»ÊÇ´æ´¢µ½¹«¹²µÄibdata1ÎļþÖС£¶ÀÁ¢µÄ±í¿Õ¼äÎļþÖ®´æ´¢¶ÔÓ¦±íµÄB+Ê÷Êý¾Ý¡¢Ë÷ÒýºÍ²åÈ뻺³åµÈÐÅÏ¢£¬ÆäÓàÐÅÏ¢»¹ÊÇ´æ´¢ÔÚĬÈϱí¿Õ¼äÖС£

Õâ¸öÎļþËù´æ´¢µÄÄÚÈÝÖ÷Òª¾ÍÊÇB+Ê÷£¨Ë÷Òý£©£¬Ò»¸ö±í¿ÉÒÔÓжà¸öË÷Òý£¬Ò²¾ÍÊÇÔÚÒ»¸öÎļþÖУ¬¿ÉÒÔ´æ´¢¶à¸öË÷Òý£¬¶øÈç¹ûÒ»¸ö±íûÓÐË÷ÒýµÄ»°£¬ÓÃÀ´´æ´¢Êý¾ÝµÄ±»³ÆÎª¾Û´ØË÷Òý£¬Ò²¾ÍÊÇ˵ÕâÒ²ÊÇÒ»¸öË÷Òý¡£×îÖյĽáÂÛÊÇ£¬ibdÎļþ´æ´¢µÄ¾ÍÊÇÒ»¸ö±íµÄËùÓÐË÷ÒýÊý¾Ý¡£ Ë÷ÒýÎļþÓжΣ¨segment£©,´Ø£¨extends£©£¨ÓеÄÎÄÕ·­ÒëÎªÇø£©£¬Ò³Ã棨page£©×é³É¡£

¹ØÓÚÐмǼ¸ñʽ£¬µ¥¶ÀÕûÀíһƪ¡£

¶þ ¶Î£¨segment£©

¶ÎÊDZí¿Õ¼äÎļþÖеÄÖ÷Òª×éÖ¯½á¹¹£¬ËüÊÇÒ»¸öÂß¼­¸ÅÄÓÃÀ´¹ÜÀíÎïÀíÎļþ£¬Êǹ¹³ÉË÷Òý¡¢±í¡¢»Ø¹ö¶ÎµÄ»ù±¾ÔªËØ¡£

ÉÏͼÖÐÏÔʾÁ˱í¿Õ¼äÊÇÓɸ÷¸ö¶Î×é³ÉµÄ£¬³£¼ûµÄ¶ÎÓÐÊý¾Ý¶Î¡¢Ë÷Òý¶Î¡¢»Ø¹ö¶ÎµÈ¡£InnoDB´æ´¢ÒýÇæ±íÊÇË÷Òý×éÖ¯µÄ£¨index organized£©£¬Òò´ËÊý¾Ý¼´Ë÷Òý£¬Ë÷Òý¼´Êý¾Ý¡£ÄÇôÊý¾Ý¶Î¼´ÎªB+Ê÷µÄÒ³½Úµã£¨ÉÏͼµÄleaf node segment£©£¬Ë÷Òý¶Î¼´ÎªB+Ê÷µÄ·ÇË÷Òý½Úµã£¨ÉÏͼµÄnon-leaf node segment£©¡£

´´½¨Ò»¸öË÷Òý£¨B+Ê÷£©Ê±»áͬʱ´´½¨Á½¸ö¶Î£¬·Ö±ðÊÇÄÚ½Úµã¶ÎºÍÒ¶×ӶΣ¬ÄÚ½Úµã¶ÎÓÃÀ´¹ÜÀí£¨´æ´¢£©B+Ê÷·ÇÒ¶×Ó£¨Ò³Ã棩µÄÊý¾Ý£¬Ò¶×Ó¶ÎÓÃÀ´¹ÜÀí£¨´æ´¢£©B+Ê÷Ò¶×Ó½ÚµãµÄÊý¾Ý£»Ò²¾ÍÊÇ˵£¬ÔÚË÷ÒýÊý¾ÝÁ¿Ò»Ö±Ôö³¤µÄ¹ý³ÌÖУ¬ËùÓÐеĴ洢¿Õ¼äµÄÉêÇ룬¶¼ÊÇ´Ó¡°¶Î¡±Õâ¸ö¸ÅÄîÖÐÉêÇëµÄ¡£

ΪÁ˽éÉÜË÷ÒýΪĿµÄ£¬ËùÒÔ²»Õ¹¿ª½éÉܻعö¶ÎµÈÄÚÈÝ¡£

Èý Çø/´Ø£¨extents£©

¶ÎÊǸöÂß¼­¸ÅÄinnodbÒýÈëÁ˴صĸÅÄÔÚ´úÂëÖб»³ÆÎªextent£»

´ØÊÇÓÉ64¸öÁ¬ÐøµÄÒ³×é³ÉµÄ£¬Ã¿¸öÒ³´óСΪ16KB£¬¼´Ã¿¸ö´ØµÄ´óСΪ1MB¡£´ØÊǹ¹³É¶ÎµÄ»ù±¾ÔªËØ£¬Ò»¸ö¶ÎÓÉÈô¸É¸ö´Ø¹¹³É¡£Ò»¸ö´ØÊÇÎïÀíÉÏÁ¬Ðø·ÖÅäµÄÒ»¸ö¶Î¿Õ¼ä£¬Ã¿Ò»¸ö¶ÎÖÁÉÙ»áÓÐÒ»¸ö´Ø£¬ÔÚ´´½¨Ò»¸ö¶Îʱ»á´´½¨Ò»¸öĬÈϵĴء£Èç¹û´æ´¢Êý¾Ýʱ£¬Ò»¸ö´ØÒѾ­²»×ãÒÔ·Åϸü¶àµÄÊý¾Ý£¬´ËʱÐèÒª´ÓÕâ¸ö¶ÎÖзÖÅäÒ»¸öеĴØÀ´´æ·ÅеÄÊý¾Ý¡£Ò»¸ö¶ÎËù¹ÜÀíµÄ¿Õ¼ä´óСÊÇÎÞÏ޵ģ¬¿ÉÒÔÒ»Ö±À©Õ¹ÏÂÈ¥£¬µ«ÊÇÀ©Õ¹µÄ×îСµ¥Î»¾ÍÊÇ´Ø¡£

ËÄ Ò³£¨page£©

InnoDBÓÐÒ³£¨page£©µÄ¸ÅÄ¿ÉÒÔÀí½âΪ´ØµÄϸ»¯¡£Ò³ÊÇInnoDB´ÅÅ̹ÜÀíµÄ×îСµ¥Î»¡£

³£¼ûµÄÒ³ÀàÐÍÓУº

Êý¾ÝÒ³£¨B-tree Node£©¡£

UndoÒ³£¨Undo Log Page£©¡£

ϵͳҳ£¨System Page£©¡£

ÊÂÎñÊý¾ÝÒ³£¨Transaction system Page£©¡£

²åÈ뻺³åλͼҳ£¨Insert Buffer Bitmap£©¡£

²åÈ뻺³å¿ÕÏÐÁбíÒ³£¨Insert Buffer Free List£©¡£

δѹËõµÄ¶þ½øÖÆ´ó¶ÔÏóÒ³£¨Uncompressed BLOB Page£©¡£

ѹËõµÄ¶þ½øÖÆ´ó¶ÔÏóÒ³£¨Compressed BLOB Page£©¡£

ÔÚÂß¼­ÉÏ£¨Ò³ÃæºÅ¶¼ÊÇ´ÓСµ½´óÁ¬ÐøµÄ£©¼°ÎïÀíÉ϶¼ÊÇÁ¬ÐøµÄ¡£ÔÚÏò±íÖвåÈëÊý¾Ýʱ£¬Èç¹ûÒ»¸öÒ³ÃæÒѾ­±»Ð´Í꣬ϵͳ»á´Óµ±Ç°´ØÖзÖÅäÒ»¸öеĿÕÏÐÒ³Ãæ´¦ÀíʹÓã¬Èç¹ûµ±Ç°´ØÖеÄ64¸öÒ³Ãæ¶¼±»·ÖÅäÍ꣬ϵͳ»á´Óµ±Ç°Ò³ÃæËùÔÚ¶ÎÖзÖÅäÒ»¸öеĴأ¬È»ºóÔÙ´ÓÕâ¸ö´ØÖзÖÅäÒ»¸öеÄÒ³ÃæÀ´Ê¹Óã»

¿´Ï¹ÙÍøµÄ½éÉÜ£º

Pages, Extents, Segments, and Tablespaces

Each tablespace consists of database?pages. Every tablespace in a MySQL instance has the same?page size. By default, all tablespaces have a page size of 16KB; you can reduce the page size to 8KB or 4KB by specifying the?innodb_page_size?option when you create the MySQL instance. You can also increase the page size to 32KB or 64KB. For more information, refer to the?innodb_page_sizedocumentation.

The pages are grouped into?extents?of size 1MB for pages up to 16KB in size (64 consecutive 16KB pages, or 128 8KB pages, or 256 4KB pages). For a page size of 32KB, extent size is 2MB. For page size of 64KB, extent size is 4MB. The?¡°files¡±?inside a tablespace are called?segments?in?InnoDB. (These segments are different from the?rollback segment, which actually contains many tablespace segments.)

When a segment grows inside the tablespace,?InnoDB?allocates the first 32 pages to it one at a time. After that,?InnoDB?starts to allocate whole extents to the segment.?InnoDB?can add up to 4 extents at a time to a large segment to ensure good sequentiality of data.

Two segments are allocated for each index in?InnoDB. One is for nonleaf nodes of the?B-tree, the other is for the leaf nodes. Keeping the leaf nodes contiguous on disk enables better sequential I/O operations, because these leaf nodes contain the actual table data.

Some pages in the tablespace contain bitmaps of other pages, and therefore a few extents in an?InnoDB?tablespace cannot be allocated to segments as a whole, but only as individual pages.

Îå ×éÖ¯½á¹¹

ÕâÀïÔÚ¡¶MySQLÔËάÄڲΡ·ËµµÄ²»ÊÇÌØ±ðϸ£ºÒ»¸ö±í¿Õ¼ä¿ÉÒÔÓжà¸öÎļþ£¬Ã¿¸öÎļþ¶¼Óи÷×ԵıàºÅ£¬´´½¨Ò»¸ö±í¿Õ¼äʱ£¬ÖÁÉÙÓÐÒ»¸öÎļþ£¬Õâ¸öÎļþ±»³ÆÎª¡°0ºÅÎļþ¡±¡£Ò»¸öÎļþÊDZ»ÇиîΪµÈ³¤¡°Ä¬ÈÏ16KB¡±µÄ¿é£¬Õâ¸ö¿éͨ³£±»³ÆÎªÒ³Ã棬ÄÇôÔÚ¡°0ºÅÎļþ¡±µÄµÚÒ»¸öÒ³Ãæ£¨page_noΪ0£©ÖУ¬´æ´¢ÁËÕâ¸ö±í¿Õ¼äÖÐËùÓжδØÒ²¹ÜÀíµÄÈë¿Ú£¬ÄÇôÔÚÕâ¸öÒ³Ãæ´æ´¢µÄÊý¾Ý¾ÍÊÇ16KB£¬µ«Í¨³£»áÓÐÒ³ÃæÍ·ÐÅÏ¢»áÕ¼ÓÃһЩ¿Õ¼ä£¬ÕæÕýµÄ¹ÜÀíÐÅÏ¢Êý¾ÝÊÇ´ÓÒ³ÃæÆ«ÒÆÎªfil_page_data(38)µÄλÖÿªÊ¼µÄ£¬Õâ¸öλÖô洢Á˱í¿Õ¼äµÄÃèÊöÐÅÏ¢£»

ÌÔ±¦µÄmysql¸ø³öÁ˸üÏêϸ£ºÏÈ¿´Õâ¸öͼ£¬Óиö´ó¸Å¸ÅÄÔÙÍùÏ¿´¡£

5.1 FSP_HDR PAGE

Êý¾ÝÎļþµÄµÚÒ»¸öPageÀàÐÍΪFIL_PAGE_TYPE_FSP_HDR£¬ÔÚ´´½¨Ò»¸öеıí¿Õ¼äʱ½øÐгõʼ»¯(fsp_header_init)£¬¸ÃpageͬʱÓÃÓÚ¸ú×ÙËæºóµÄ256¸öExtent(Ô¼256MBÎļþ´óС)µÄ¿Õ¼ä¹ÜÀí£¬ËùÒÔÿ¸ô256MB¾ÍÒª´´½¨Ò»¸öÀàËÆµÄÊý¾ÝÒ³£¬ÀàÐÍΪFIL_PAGE_TYPE_XDES?£¬XDES Page³ýÁËÎļþÍ·²¿Í⣬ÆäËû¶¼ºÍFSP_HDRÒ³¾ßÓÐÏàͬµÄÊý¾Ý½á¹¹£¬¿ÉÒÔ³ÆÖ®ÎªExtentÃèÊöÒ³£¬Ã¿¸öExtentÕ¼ÓÃ40¸ö×Ö½Ú£¬Ò»¸öXDES Page×î¶àÃèÊö256¸öExtent¡£

FSP_HDRÒ³µÄÍ·²¿Ê¹ÓÃFSP_HEADER_SIZE¸ö×Ö½ÚÀ´¼Ç¼ÎļþµÄÏà¹ØÐÅÏ¢£¬¾ßÌåµÄ°üÀ¨£º

´Ø»òÕß·ÖÇø£¨extent£©ÊǶεÄ×é³ÉÔªËØ£¬ÔÚÎļþͷʹÓÃFLAGÃèÊöÁË´´½¨±íÐÅÏ¢£¬³ý´ËÖ®ÍâÆäËû²¿·ÖµÄÊý¾Ý½á¹¹ºÍXDES PAGE¶¼ÊÇÏàͬµÄ£¬Ê¹ÓÃÁ¬ÐøÊý×éµÄ·½Ê½£¬Ã¿¸öXDES PAGE×î¶à´æ´¢256¸öXDES Entry£¬Ã¿¸öEntryÕ¼ÓÃ40¸ö×Ö½Ú£¬ÃèÊö64¸öPage£¨¼´Ò»¸öExtent£©¡£¸ñʽÈçÏ£º

XDES_STATE±íʾ¸ÃExtentµÄËÄÖÖ²»Í¬×´Ì¬£º

ͨ¹ýXDES_STATEÐÅÏ¢£¬ÎÒÃÇÖ»ÐèÒªÒ»¸öFLIST_NODE½Úµã¾Í¿ÉÒÔά»¤Ã¿¸öExtentµÄÐÅÏ¢£¬ÊÇ´¦ÓÚÈ«¾Ö±í¿Õ¼äµÄÁ´±íÉÏ£¬»¹ÊÇij¸öbtree segmentµÄÁ´±íÉÏ¡£

IBUF BITMAP PAGE Ò²¾ÍÊÇpageÀàÐÍΪFIL_PAGE_IBUF_BITMAP²»Õ¹¿ª£¬´ýµ¥¶ÀÕûÀí¡£ÔÙ¿´¶ÎµÄ¡£

5.2 INODE PAGE

Êý¾ÝÎļþµÄµÚ3¸öpageµÄÀàÐÍΪFIL_PAGE_INODE£¬ÓÃÓÚ¹ÜÀíÊý¾ÝÎļþÖеÄsegement£¬Ã¿¸öË÷ÒýÕ¼ÓÃ2¸ösegment£¬·Ö±ðÓÃÓÚ¹ÜÀíÒ¶×Ó½ÚµãºÍ·ÇÒ¶×ӽڵ㡣ÿ¸öinodeÒ³¿ÉÒÔ´æ´¢FSP_SEG_INODES_PER_PAGE£¨Ä¬ÈÏΪ85£©¸ö¼Ç¼¡£

ÿ¸öInode EntryµÄ½á¹¹ÈçϱíËùʾ£º

¿´µ½ÕâÀÉÏÃæµÄͼӦ¸ÃÊÇÀí½âÁË£¬µ±È»ÊéÉÏ»¹ÊǸøÁËÒ»¸ö¼ò»¯µÄͼ£º

5.3 Îļþά»¤

´ÓÉÏÎÄÎÒÃÇ¿ÉÒÔ¿´µ½£¬InnoDBͨ¹ýInode EntryÀ´¹ÜÀíÿ¸öSegmentÕ¼ÓõÄÊý¾ÝÒ³£¬Ã¿¸ösegment¿ÉÒÔ¿´×öÒ»¸öÎļþҳά»¤µ¥Ôª¡£Inode EntryËùÔÚµÄinode pageÓпÉÄÜ´æ·ÅÂú£¬Òò´ËÓÖͨ¹ýÍ·Pageά»¤ÁËInode PageÁ´±í¡£

ÔÚibdµÄµÚÒ»¸öPageÖл¹Î¬»¤Á˱í¿Õ¼äÄÚExtentµÄFREE¡¢FREE_FRAG¡¢FULL_FRAGÈý¸öExtentÁ´±í£»¶øÃ¿¸öInode EntryҲά»¤Á˶ÔÓ¦µÄFREE¡¢NOT_FULL¡¢FULLÈý¸öExtentÁ´±í¡£ÕâЩÁ´±íÖ®¼ä´æÔÚ×Åת»»¹ØÏµ£¬ÒÔ¸ßЧµÄÀûÓÃÊý¾ÝÎļþ¿Õ¼ä¡£×¢ÒâÇø±ð£º±í¿Õ¼äÖеÄÁ´±í¹ÜÀíµÄÊÇÕû¸ö±í¿Õ¼äÖÐËùÓеĴأ¬°üÀ¨Âú´Ø¡¢°ëÂú´Ø¼°¿ÕÏдأ¬¶ø¶ÎµÄiNodeÐÅÏ¢ÖйÜÀíµÄÊÇÊôÓÚ×Ô¼º¶ÎÖеÄÂú´Ø¡¢°ëÂú´Ø¼°¿ÕÏдء£

µ±´´½¨Ò»¸öеÄË÷Òýʱ£¬Êµ¼ÊÉϹ¹½¨Ò»¸öеÄbtree(btr_create)£¬ÏÈΪ·ÇÒ¶×Ó½ÚµãSegment·ÖÅäÒ»¸öinode entry£¬ÔÙ´´½¨root page£¬²¢½«¸ÃsegmentµÄλÖüǼµ½root pageÖУ¬È»ºóÔÙ·ÖÅäleaf segmentµÄInode entry£¬²¢¼Ç¼µ½root pageÖС£µ±É¾³ýij¸öË÷Òýºó£¬¸ÃË÷ÒýÕ¼ÓõĿռäÐèÒªÄܱ»ÖØÐÂÀûÓÃÆðÀ´¡£

´´½¨Ò»¸ösegment£º

º¯ÊýÈë¿Ú£ºfseg_create_general£¬ºóÃæÌùһϴúÂ룬Ö÷ÒªÊÇÊéÉϵĽâÊÍ¡£

1.¸ù¾Ý¿Õ¼äidµÃµ½±í¿Õ¼äÍ·ÐÅÏ¢¡£

2. ´ÓµÃµ½µÄ±í¿Õ¼äÍ·ÐÅÏ¢·ÖÅäInode:¾ßÌåʵÏÖΪ¶ÁÈ¡ÎļþÍ·Page²¢¼ÓËø£¨fsp_get_space_header£©£¬È»ºó¿ªÊ¼ÎªÆä·ÖÅäInode Entry(fsp_alloc_seg_inode)¡£

ΪÁ˹ÜÀíInode Page£¬ÔÚÎļþÍ·´æ´¢ÁËÁ½¸öInode PageÁ´±í£¬Ò»¸öÁ´½ÓÒѾ­ÓÃÂúµÄinode page£¬Ò»¸öÁ´½ÓÉÐδÓÃÂúµÄinode page¡£Èç¹ûµ±Ç°Inode PageµÄ¿Õ¼äʹÓÃÍêÁË£¬¾ÍÐèÒªÔÙ·ÖÅäÒ»¸öinode page£¬²¢¼ÓÈëµ½FSP_SEG_INODES_FREEÁ´±íÉÏ(fsp_alloc_seg_inode_page)¡£¶ÔÓÚ¶ÀÁ¢±í¿Õ¼ä£¬Í¨³£Ò»¸öinode page¾Í×ã¹»ÁË¡£

ÏÂÃæ¿´¾ßÌå²éÕÒinode Page¹ý³Ì£ºÊ×ÏÈÅжÏFSP_SEG_INODES_FREEÁ´±íÊÇ·ñ»¹ÓпÕÏÐÒ³Ãæ£¬Èç¹ûÓУ¬Ôò´ÓÒ³ÃæµÄÊý¾Ý´æ´¢Î»ÖÿªÊ¼É¨Ã裬ûÕÒÒ»¸öInode£¬ÏÈÅжÏÊÇ·ñ¿ÕÏУ¨¿ÕÏбíʾÆä²»¹éÊôÈκÎsegment£¬¼´FSEG_IDÖÃΪ0£©¡£ÕÒµ½Ôò·µ»Ø¡£ÕÒµ½Õâ¸öÇÒÕâ¸öInodeΪÕâ¸öÒ³×îºóÒ»¸öInode.Ôò¸Ãinode pageÖеļǼÓÃÂúÁË£¬¾Í´ÓFSP_SEG_INODES_FREEÁ´±íÉÏ×ªÒÆµ½FSP_SEG_INODES_FULLÁ´±í¡£Èç¹ûFSP_SEG_INODES_FREEûÓпÕÏеÄInodeÒ³Ãæ£¬ÔòÖØÐ·ÖÅäÒ»¸öinodeÒ³Ãæ£¬·ÖÅäºó°ÑËùÓÐÃèÊö·ûÀïÃæµÄFSEG_IDÖÃΪ0£¬Öظ´ÉÏÃæ¹ý³Ì¡£

3.¸øÐ·ÖÅäµÄInodeÉèÖÃSEG_ID. Õâ¸öIDºÅÒª´Ó±í¿Õ¼äÍ·ÐÅÏ¢µÄFSP_SEG_ID×÷Ϊµ±Ç°segmentµÄseg idдÈëµ½inode entryÖС£Í¬Ê±¸üÐÂFSP_SEG_IDµÄֵΪID+1£¬×÷ΪÏÂÒ»¸ö¶ÎµÄIDºÅ¡£

4.ÔÚÍê³Éinode entryµÄÌáÈ¡ºó£¬³õʼ»¯Õâ¸öInodeÐÅÏ¢¡£°ÑFSEG_NOT_FULL_N_USEDÖÃΪ0£¬³õʼ»¯FSEG_FREE¡¢FSEG_NOT_FULL£¬FSEG_FULL¡£

5. ´ÓÕâ¸ö¶Î·ÖÅä³öÒ»¸öÒ³Ãæ¡££¨Õâ¿éÂß¼­²»Ì«¶®£©

6.·ÖÅäºÃÒ³Ãæºó£¬Í¨¹ý»º´æÕÒµ½¶ÎµÄÊ×Ò³Ãæ£¨Ò³ÃæºÅΪpage+index£©¡£¾Í½«¸Ãinode entryËùÔÚinode pageµÄλÖü°Ò³ÄÚÆ«ÒÆÁ¿´æ´¢µ½¶ÎÊ×Ò³£¬10¸ö×Ö½ÚµÄinodeÐÅÏ¢°üÀ¨£º

ÖÁ´Ë¶Î¾Í·ÖÅäÍê³ÉÁË£¬ÒÔºóÈç¹ûÐèÒªÔÚÕâ¸ö¶ÎÖзÖÅä¿Õ¼ä£¬Ö»ÐèÒªÕÒµ½ÆäÊ×Ò³£¬È»ºó¸ù¾Ý¶ÔÓ¦µÄInode·ÖÅä¿Õ¼ä¡£

Creates a new segment.
@return the block where the segment header is placed, x-latched, NULL
if could not create segment because of lack of space */
UNIV_INTERN
buf_block_t*
fseg_create_general(
/*================*/
ulint space, /*!< in: space id */
ulint 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 */
ulint byte_offset, /*!< in: byte offset of the created segment header
on the page */
ibool 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 */
mtr_t* mtr) /*!< in: mtr */
{
ulint flags;
ulint zip_size;
fsp_header_t* space_header;
fseg_inode_t* inode; //typedef byte fseg_inode_t;
ib_id_t seg_id;
buf_block_t* block = 0; /* remove warning */
fseg_header_t* header = 0; /* remove warning */
rw_lock_t* latch;
ibool success;
ulint n_reserved;
ulint i;

ut_ad(mtr);
ut_ad(byte_offset + FSEG_HEADER_SIZE
<= UNIV_PAGE_SIZE - FIL_PAGE_DATA_END);

latch = fil_space_get_latch(space, &flags);
zip_size = dict_table_flags_to_zip_size(flags);

if (page != 0) {
block = buf_page_get(space, zip_size, page, RW_X_LATCH, mtr);
header = byte_offset + buf_block_get_frame(block);
}

ut_ad(!mutex_own(&kernel_mutex)
|| mtr_memo_contains(mtr, latch, MTR_MEMO_X_LOCK));

mtr_x_lock(latch, mtr);

if (rw_lock_get_x_lock_count(latch) == 1) {
/* This thread did not own the latch before this call: free
excess pages from the insert buffer free list */

if (space == IBUF_SPACE_ID) {
ibuf_free_excess_pages();
}
}

if (!has_done_reservation) {
success = fsp_reserve_free_extents(&n_reserved, space, 2,
FSP_NORMAL, mtr);
if (!success) {
return(NULL);
}
}

space_header = fsp_get_space_header (space, zip_size, mtr);//Ïê¼û

inode = fsp_alloc_seg_inode(space_header, mtr); //ÉêÇëinode entry Ïê¼û if (inode == NULL) {

goto funct_exit;
}

/* Read the next segment id from space header and increment the
value in space header */

seg_id = mach_read_from_8(space_header + FSP_SEG_ID); //ÉèÖÃÏÂÒ»ÏÂseg id

mlog_write_ull(space_header + FSP_SEG_ID, seg_id + 1, mtr);

/**
*#define FSEG_ID 0
*#define FSEG_NOT_FULL_N_USED 8
*#define FSEG_FREE 12

*#define FSEG_NOT_FULL (12 + FLST_BASE_NODE_SIZE)
*#define FLST_BASE_NODE_SIZE (4 + 2 * FIL_ADDR_SIZE)
*#define FIL_ADDR_SIZE 6
*
*#define FSEG_FULL (12 + 2 * FLST_BASE_NODE_SIZE)
*
*/
mlog_write_ull(inode + FSEG_ID, seg_id, mtr);
mlog_write_ulint(inode + FSEG_NOT_FULL_N_USED, 0, MLOG_4BYTES, mtr);

flst_init(inode + FSEG_FREE, mtr); //³õʼ»¯inodeÖеÄseg list Ïê¼û
flst_init(inode + FSEG_NOT_FULL, mtr);
flst_init(inode + FSEG_FULL, mtr);

mlog_write_ulint(inode + FSEG_MAGIC_N, FSEG_MAGIC_N_VALUE,
MLOG_4BYTES, mtr);

//#define FSEG_FRAG_ARR_N_SLOTS (FSP_EXTENT_SIZE / 2) 64/2=32 for (i = 0; i < FSEG_FRAG_ARR_N_SLOTS; i++) {
fseg_set_nth_frag_page_no(inode, i, FIL_NULL, mtr); //ÉèÖÃfrag Ë鯬 Ïê¼û
}

if (page == 0) {
block = fseg_alloc_free_page_low(space, zip_size,
inode, 0, FSP_UP, mtr, mtr);

if (block == NULL) {

fsp_free_seg_inode(space, zip_size, inode, mtr);

goto funct_exit;
}

ut_ad(rw_lock_get_x_lock_count(&block->lock) == 1);

header = byte_offset + buf_block_get_frame(block);
mlog_write_ulint(buf_block_get_frame(block) + FIL_PAGE_TYPE,
FIL_PAGE_TYPE_SYS, MLOG_2BYTES, mtr);
}

//ÉèÖÃfset_headerÐÅÏ¢
mlog_write_ulint(header + FSEG_HDR_OFFSET ,page_offset(inode), MLOG_2BYTES, mtr);

mlog_write_ulint(header + FSEG_HDR_PAGE_NO,page_get_page_no(page_align(inode)), MLOG_4BYTES, mtr);

mlog_write_ulint(header + FSEG_HDR_SPACE, space, MLOG_4BYTES, mtr);

funct_exit:
if (!has_done_reservation) {

fil_space_release_free_extents(space, n_reserved);
}

return(block);
}

·ÖÅäÊý¾ÝÒ³º¯Êý fsp_alloc_free_page

±í¿Õ¼äExtentµÄ·ÖÅ亯Êýfsp_alloc_free_extent £¬²»ÔÚ´ËÕ¹¿ª¡£

¶ÔÓ¦µÄ»¹ÓÐÊÍ·ÅSegment µ±ÎÒÃÇɾ³ýË÷Òý»òÕß±íʱ£¬ÐèҪɾ³ýbtree£¨btr_free_if_exists£©£¬ÏÈɾ³ý³ýÁËroot½ÚµãÍâµÄÆäËû²¿·Ö(btr_free_but_not_root)£¬ÔÙɾ³ýroot½Úµã(btr_free_root)

ÓÉÓÚÊý¾Ý²Ù×÷¶¼ÐèÒª¼Ç¼redo£¬ÎªÁ˱ÜÃâ²úÉú·Ç³£´óµÄredo log£¬leaf segmentͨ¹ý·´¸´µ÷Óú¯Êýfseg_free_stepÀ´ÊÍ·ÅÆäÕ¼ÓõÄÊý¾ÝÒ³¡£

Áù ´´½¨B+Ë÷Òý

ÉÏÃæÎÒÃÇÒѾ­´ó¸ÅÁ˽âÁËinnodbµÄÎļþ¹ÜÀí·½Ê½£¬ºËÐÄÄ¿µÄÊÇΪÁ˹ÜÀíºÃB+Ë÷Òý¡£

ibdÎļþÖÐÕæÕý¹¹½¨ÆðÓû§Êý¾ÝµÄ½á¹¹ÊÇBTREE£¬ÔÚÄã´´½¨Ò»¸ö±íʱ£¬ÒѾ­»ùÓÚÏÔʽ»òÒþʽ¶¨ÒåµÄÖ÷¼ü¹¹½¨ÁËÒ»¸öbtree£¬ÆäÒ¶×Ó½ÚµãÉϼǼÁËÐеÄÈ«²¿ÁÐÊý¾Ý£¨¼ÓÉÏÊÂÎñidÁм°»Ø¹ö¶ÎÖ¸ÕëÁУ©£»Èç¹ûÄãÔÚ±íÉÏ´´½¨Á˶þ¼¶Ë÷Òý£¬ÆäÒ¶×Ó½Úµã´æ´¢Á˼üÖµ¼ÓÉϾۼ¯Ë÷Òý¼üÖµ¡£ËùÒÔÊéÉÏÌùÒ»¶Î´´½¨B+Ë÷ÒýµÄ´úÂë¡£ÍøÉÏÕÒÁË5.6.15°æ±¾µÄ¡£Õâ¸öº¯Êý¾ÍÊÇ´´½¨Ò»¸öB+Ê÷£¬Ö»ÊǸÅÄîÉϵ쬻¹Ã»ÓÐÕæÕýµÄÊý¾ÝдÈë¡£

Ïà¹ØÖªÊ¶µã£ºB+Ê÷£¬Ë÷Òý£¬¶Î£¬Çø/´Ø£¨extent£©,Ò³ ÒѾ­´®ÆðÀ´ÁË¡£

Creates the root node for a new index tree.
@return page number of the created root, FIL_NULL if did not succeed */
UNIV_INTERN
ulint
btr_create(
/*=======*/
ulint type, /*!< in: type of the index */
ulint space, /*!< in: space where created */
ulint zip_size,/*!< in: compressed page size in bytes
or 0 for uncompressed pages */
index_id_t index_id,/*!< in: index id */
dict_index_t* index, /*!< in: index */
mtr_t* mtr) /*!< in: mini-transaction handle */
{
ulint page_no;
buf_block_t* block;
buf_frame_t* frame;
page_t* page;
page_zip_des_t* page_zip;

/* Create the two new segments (one, in the case of an ibuf tree) for
the index tree; the segment headers are put on the allocated root page
(for an ibuf tree, not in the root, but on a separate ibuf header
page) */

if (type & DICT_IBUF) {
/* Allocate first the ibuf header page */
buf_block_t* ibuf_hdr_block = fseg_create(
space, 0,
IBUF_HEADER + IBUF_TREE_SEG_HEADER, mtr);

buf_block_dbg_add_level(
ibuf_hdr_block, SYNC_IBUF_TREE_NODE_NEW);

ut_ad(buf_block_get_page_no(ibuf_hdr_block)
== IBUF_HEADER_PAGE_NO);
/* Allocate then the next page to the segment: it will be the
tree root page */

block = fseg_alloc_free_page(
buf_block_get_frame(ibuf_hdr_block)
+ IBUF_HEADER + IBUF_TREE_SEG_HEADER,
IBUF_TREE_ROOT_PAGE_NO,
FSP_UP, mtr);
ut_ad(buf_block_get_page_no(block) == IBUF_TREE_ROOT_PAGE_NO);
} else {
#ifdef UNIV_BLOB_DEBUG
if ((type & DICT_CLUSTERED) && !index->blobs) {
mutex_create(PFS_NOT_INSTRUMENTED,
&index->blobs_mutex, SYNC_ANY_LATCH);
index->blobs = rbt_create(sizeof(btr_blob_dbg_t),
btr_blob_dbg_cmp);
}
#endif /* UNIV_BLOB_DEBUG */
block = fseg_create(space, 0,
PAGE_HEADER + PAGE_BTR_SEG_TOP, mtr);
}

if (block == NULL) {

return(FIL_NULL);
}

page_no = buf_block_get_page_no(block);
frame = buf_block_get_frame(block);

if (type & DICT_IBUF) {
/* It is an insert buffer tree: initialize the free list */
buf_block_dbg_add_level(block, SYNC_IBUF_TREE_NODE_NEW);

ut_ad(page_no == IBUF_TREE_ROOT_PAGE_NO);

flst_init(frame + PAGE_HEADER + PAGE_BTR_IBUF_FREE_LIST, mtr);
} else {
/* It is a non-ibuf tree: create a file segment for leaf
pages */
buf_block_dbg_add_level(block, SYNC_TREE_NODE_NEW);

if (!fseg_create(space, page_no,
PAGE_HEADER + PAGE_BTR_SEG_LEAF, mtr)) {
/* Not enough space for new segment, free root
segment before return. */
btr_free_root(space, zip_size, page_no, mtr);

return(FIL_NULL);
}

/* The fseg create acquires a second latch on the page,
therefore we must declare it: */
buf_block_dbg_add_level(block, SYNC_TREE_NODE_NEW);
}

/* Create a new index page on the allocated segment page */
page_zip = buf_block_get_page_zip(block);

if (page_zip) {
page = page_create_zip(block, index, 0, 0, mtr);
} else {
page = page_create(block, mtr,
dict_table_is_comp(index->table));
/* Set the level of the new index page */
btr_page_set_level(page, NULL, 0, mtr);
}

block->check_index_page_at_flush = TRUE;

/* Set the index id of the page */
btr_page_set_index_id(page, page_zip, index_id, mtr);

/* Set the next node and previous node fields */
btr_page_set_next(page, page_zip, FIL_NULL, mtr);
btr_page_set_prev(page, page_zip, FIL_NULL, mtr);

/* We reset the free bits for the page to allow creation of several
trees in the same mtr, otherwise the latch on a bitmap page would
prevent it because of the latching order */

if (!(type & DICT_CLUSTERED)) {
ibuf_reset_free_bits(block);
}

/* In the following assertion we test that two records of maximum
allowed size fit on the root page: this fact is needed to ensure
correctness of split algorithms */

ut_ad(page_get_max_insert_size(page, 2) > 2 * BTR_PAGE_MAX_REC_SIZE);

return(page_no);
}

 

   
3331 ´Îä¯ÀÀ       27
Ïà¹ØÎÄÕÂ

»ùÓÚEAµÄÊý¾Ý¿â½¨Ä£
Êý¾ÝÁ÷½¨Ä££¨EAÖ¸ÄÏ£©
¡°Êý¾Ýºþ¡±£º¸ÅÄî¡¢ÌØÕ÷¡¢¼Ü¹¹Óë°¸Àý
ÔÚÏßÉ̳ÇÊý¾Ý¿âϵͳÉè¼Æ ˼·+Ч¹û
 
Ïà¹ØÎĵµ

GreenplumÊý¾Ý¿â»ù´¡Åàѵ
MySQL5.1ÐÔÄÜÓÅ»¯·½°¸
ijµçÉÌÊý¾ÝÖÐ̨¼Ü¹¹Êµ¼ù
MySQL¸ßÀ©Õ¹¼Ü¹¹Éè¼Æ
Ïà¹Ø¿Î³Ì

Êý¾ÝÖÎÀí¡¢Êý¾Ý¼Ü¹¹¼°Êý¾Ý±ê×¼
MongoDBʵս¿Î³Ì
²¢·¢¡¢´óÈÝÁ¿¡¢¸ßÐÔÄÜÊý¾Ý¿âÉè¼ÆÓëÓÅ»¯
PostgreSQLÊý¾Ý¿âʵսÅàѵ