mysql에서 데이터 flush를 하는 기본 순서는
1. 버퍼 풀 or log buffer에 있는 내용을 flush하면
2. mySQL 안의 버퍼에 있던 내용을 메모리 상의 OS cache로 이동(write)
3. OS cache 안의 내용을 디스크상의 데이터 파일로 이동(flush)
인데, innodb storage engine에서는 innodb_flush_method 변수를 통해 flush 방법을 설정할 수 있다.
fsync: default로 설정되어 있는 방법. 버퍼 풀과 로그 버퍼 모두 OS cache를 이용하고, fsync()를 통해 OS cache에서 디스크로 데이터를 이동한다.
O_DSYNC: 로그 버퍼에서 write를 할 때(2번 단계) 자동적으로 데이터 파일에 fsync()까지 한 번에 동기화되는 방법. log buffer의 데이터는 O_SYNC를 이용해서 log file을 열면서 flush하고, fsync()를 이용해서 OS cache에 남은(버퍼 풀에서 write하면서 이동한) data file을 flush한다.
O_DIRECT: OS cache를 이용하지 않고 버퍼에서 바로 데이터 파일로 flush하는 방법이나, buffer pool에 있는 데이터 중 metadata는 OS cache와 fsync()를 이용하여 데이터 파일로 flush한다.
O_DIRECT_NO_FSYNC: fsync() 호출도 하지 않고(OS cache 사용 X) 온전히 mysql buffer와 disk file간에만 데이터를 이동시키는 방법
mySQL을 사용하는 대부분의 상용DB에서는 O_DIRECT 모드를 사용하고 있으며, mySQL 공식 document에서도 O_DIRECT mode를 권장하고 있다. (5.7.25버전 이후)
Prior to MySQL 5.7.25, this setting is not suitable for file systems such as XFS and EXT4, which require an fsync() system call to synchronize file system metadata changes. If you are not sure whether your file system requires an fsync() system call to synchronize file system metadata changes, use O_DIRECT instead.
As of MySQL 5.7.25, fsync() is called after creating a new file, after increasing file size, and after closing a file, to ensure that file system metadata changes are synchronized. The fsync() system call is still skipped after each write operation.
Data loss is possible if redo log files and data files reside on different storage devices, and an unexpected exit occurs before data file writes are flushed from a device cache that is not battery-backed. If you use or intend to use different storage devices for redo log files and data files, and your data files reside on a device with a cache that is not battery-backed, use O_DIRECT instead.
OS cache를 사용하면 더 빨라져서 성능이 좋아질 것 같음에도 불구하고 DIRECT mode를 사용하는 이유는 무엇일까?
현재 메모리의 사용량을 확인해보면 알 수 있다. 터미널에서 free [options] 명령어로 현재 메모리 현황을 확인해보았다.
$ free -m -t
OS cache를 사용해서 flush를 진행하는 경우, page cleaner thread에 의해 메모리에서 데이터 flush가 되더라도 OS cache에 쌓인 파일은 디스크로 flush를 하지 않는다. 현재 2.9G정도가 os cache에서 지워지지 않고 사용되고 있다. 트래픽이 증가할수록 OS cache에 쌓이는 파일의 양도 증가할 것이고, 전체 메모리 크기는 한정적이기 때문에 결과적으로 buffer pool보다 OS cache를 더 많이 사용하게 되며 DB의 성능이 저하될 것이다. 따라서 innodb_flush_method = O_DIRECT 로 설정하는 것을 권장한다.
* AWS RDS에서도 innodb_flush_method 를 변경할 수 있도록 해 두었당! (몇몇 변수는 AWS에서 수정하지 못하도록 고정되어 있어서...ㅠ확인 작업이 필요하다)
'MySQL' 카테고리의 다른 글
[MacOS] MySQL 8.0 Debug 환경 Xcode로 만들기 (0) | 2022.05.31 |
---|---|
Character set & Collation (0) | 2021.09.09 |
[Collation] UTF8 charset & collation 비교 (0) | 2021.02.26 |
Year 2038 Problem (0) | 2021.02.26 |
[data type]CHAR형의 pad_char_to_full_length 옵션과 VARCHAR형 비교 (0) | 2021.02.26 |