본문 바로가기
MySQL Internal/InnoDB Internal

[Jeremy Cols's InnoDB] 1. The basics of InnoDB space file layout

by 모모레 2014. 1. 29.

다음의 url 의 내용을 요약한 내용입니다.

http://blog.jcole.us/2013/01/03/the-basics-of-innodb-space-file-layout/



InnoDB의 data storage는 tablespace라고 하는 space 모델을 사용한다. 이것은 file space라고 하기도 한다. 이 space는 물리적은 여러 파일들로 이루어질수 있지만, 논리적으로는 하나의 파일이라고 할 수 있다. InnoDB가 사용하는 space들은 각각 32bit의 Integer space id값을 가진다. 그리고 우리가 system tablespace라고 하는 system space는 space ID가 0인 값을 가진다. 그리고, file-per-table모드인 경우 각각의 테이블스페이스들이 다른 값들을 가진다. 


Pages


각각의 space는 page로 이루어져 있고, 기본적으로 하나의 page는 16KB사이즈로 되어있다. 이 page들도 그 space안에서 32bit integer로 된 page number를 가지고 있고, 이것을 offset이라고 부른다. 이 값은 그 space의 시작으로 부터의 offset인 것이다. 그래서, page가 0인것은 그 파일의 offset 0인 것이고, page1은 file offset 16384인 것이다. (InnoDB 파일 사이즈 제약이 64TB인것은 space의 제약인건데, 이것은 page의 number가 32bit으로 이루어졌기 때문이다. 즉, 232 x 16 KiB = 64 TiB인 것이다.

Page의 내부 모습을 그림으로 그려보면 다음과 같다. 


PAGE의 기본 구조


모든 page는 38-byte의 FIL header와 8-byte의 FIL trailer를 가지고 있다. header는 어떤 field를 포함하고 있는데, 이 field는 page Type을 나타낸다. 그리고 page의 나머지 부분의 구조를 결정한다. 자세한 FIL Header및 trailer의 구조는 다음과 같다.



FIL Header/Trailer


FIL Header와 Trailer는 순서대로는 아니지만 다음의 구조를 포함한다.

  • page의 type은 header에 저장된다. 이것은 page data의 다른 부분들을 parsing하기 위해 필요하다. page들은 file space 관리, extent 관리, transaction system, data dictionary, undo logs, blobs index, table 데이터를 위해 할당된다.
  • Space ID는 header에 저장된다.
  • page number(Offset)은 page가 초기화될때만 header에 저장된다. 파일의 offset의 기본이 되는 header에 저장되어있는 page number를 check하는 것은 이 페이지가 읽어도 되는 것인지 판단하는데 도움을 준다. 그래서, 그 영역을 초기화 하는 것은 page를 초기화 하는 순간에만 진행한다.
  • 32bit의 checksum은 header에 저장되는데, 이전 포맷의 32bit checksum(Old-style Checksum)은 trailer에 저장되었다. 이 영역은 deprecated되었고, 이 공간은 다른 영역으로 사용된다.
  • 논리적으로 이전 페이지와 이후 페이지를 연결하는 포인터정보(Previous Page 와 Next Page)는 header영역에 저장한다. 포인터 정보는 double-linked list로 구성되어있다. 이것은 인덱스 페이지가 같은 레벨의 페이지로 연결되는데 사용된다. 즉, full index scan과 같은 작업시 효율적이게 사용된다.
  • 가장 마지막에 수정된 page를 위한 64bit log sequence number 인 LSN for last page modification은 header에 저장되며, 같은 LSN값이 low 32bit bit로 trailer에 저장된다.
  • 64bit Flush LSN은 header에 저장되는데, 이 값은 전체 시스템에서 단 하나의 페이지에만 값이 저장되는데, 그 영역은 space 0의 page 0인 페이지이다. 이 영역은 전체 시스템에서 flush된 LSN중 가장 높은 값이 저징되고, 이 필드의 값은 나중에 재사용 가능성이 가장 높은 후보군의 값이 된다.


Space files

Space file은 많은 페이지들의 연결이다. 효율적인 관리를 위해, 페이지들은 1 MiB(기본적인 16kbyte의 page의 64개의 연속의 묶음)의 블럭으로 묶여지는다. 그것을 extent라고 부른다. space안에 page들을 할당할때 extent로 연결하여 할당한다.


InnoDB는 모든 페이지와 extent, 그리고 space 자신을 추적하기 위해 내용을 기입하는 것이 필요하다. 그래서, space file은 여러개의 꼭 존재해야 하는 super-structure를 가지고 있다.



Space File Overview

space의 첫번째 페이지 page 0은 항상 file space header나 FSP_HDR page를 가지고 있다.  FSP_HDR 페이지는 혼란스럽지만, FSP header 정보를 가지고 있고, 이것은 space의 공간, free 영역 list, fragemtned list, full extents list와 같은 정보를 가지고 있다.


FSP_HDR페이지는 내부적으로 256 extent(또는 16,384 pages, 256MiB)에 대한 추적 정보를 가지고 있을 만큼만 공간을 가지고 있기 때문에, 추가적인 공간을 확보하기 위해, XDES 페이지에 매 16,384 page에 대한 공간을 예약해 놓아야 한다. XDES와 FSP_HDR 페이지의 정보는 동일하지만, FSP header는 XDES 페이지안에 0으로 채운것만 다르다. 이와 같은 추가적인 페이지들은 자동적으로 space file이 커질때 할당된다.


각 페이지의 third page(page2)는 INODE 페이지이다. 이것은 file segment(fragment page의 array를 포함하여 extent를 묶은것)와 관계된 list를 저장한다. 각 INODE 페이지는 85 INODE entry를 저장할 수 있고, 각 index는 두개의 INODE entry를 요구한다.


FSP_HDR또는 XDES 페이지에 붙어있는 페이지는 IBUF_BITMAP 페이지가 될 것이고, 이것은 insert buffering과 여기서 다루지 않는 것과 연관된 정보를 저장하는데 사용된다. 


The System space

System space(space 0)은 InnoDB에서 사용하는 특별한 영역으로 InnoDB에서 운영하는데 사용하는 매우 중요한 정보를 저장하는데 사용하는 영역으로, 몇몇 페이지를 할당하여 사용한다. system space도 다른 space와 같이 FSP_HDR과 IBUF_BITMAP, INODE 페이지가 있어야 한다. 다음과 같이 구성된다.


ibdata1 File Overview

다음과 같이 할당된다.

  • Page3, type SYS : insert buffering과 관련된 정보화 header정보를 가지고 있다.
  • Page4, type INDEX : insert buffering으로 사용되는 index structure의 root page이다.
  • Page5, type TRX_SYS : InnoDB 트랜잭션 관리에서 사용되는 정보가 포함되어있다. 가장 최근의 transaction ID, binary log 정보, double write buffer extent의 위치정보와 같은 것이 저장되어있다.
  • Page6, type SYS : 첫번째 rollback segment page이다. 추가적인 페이지들은 rollback segment data를 저장할 필요가 생길때 할당된다.
  • Page7, type SYS: data dictionary와 연관된 Header정보를 가지고 있다. 여기에는 data dictionary 정보를 가지고 있는 index의 root page number도 포함하고 있다. 이 정보는 테이블을 찾을때 필요하며, data dictionary정보에 그 테이블의 root page number가 저장되어있다.
  • Pages 64~127 : double write buffer의  64 page의 첫번째 block이다. double write buffer는 InnoDB recovery mechanism의 한 부분으로 사용된다.
  • Pages 128~ 191 : double write buffer의 두번째 블럭이다.

다른 모든 page들은 기본적으로 index, rollback segment, undo log등으로 할당되어 사용된다.


Per-table space files

InnoDB는 file-per-table 모드를 권장하는데, 이것은 테이블마다 각자 사용할 space를 생성하여 사용하는 것이다. 그렇기 때문에 정확하게 말하면 space per table이 더 맞는 말이다. 이 모드를 사용하면 ibd 확장자를 사용하는 파일이 생성되고, 다음과 같은 구조를 가진다.


실시간으로 인덱스를 추가하는 fast index creation을 제외하고, 3개의 초기 pages들 이후의 space에 할당되는 다음 page들은 그 테이블의 각 index 들의 root page들이 된다. 이것은 테이블을 생성할때 정의된다. page 3은 clustered index의 root 가 되고, page 4는 첫번째 secondary index의 root 가 된다.


대부분의InnoDB의 중요한 정보를 가진 구조체들은 system space에 저장되기 때문에 이 영역에 저장되는 대부분의 데이터들은 INDEX와 테이블 데이터 type만 있다.