innodb_flush_method, O_DIRECT에 대한 오해!



innodb_flush_method 설정은 InnoDB가 데이터 파일을 어떤 방식으로 읽고 쓰기를 할것인지


선택할수 있게 해준다.


그중 O_DIRECT 설정값을 흔히 사용하는데 이유를 물어보면 IO 성능향상을 위해서라고 한다.


웹상의 많은 글에도 IO 성능향상을 위해 O_DIRECT를 쓰라는 글이 많아 보이는데 물론 완전히 틀린말은 아니지만


좀 더 정확히 알고 쓰자라는 취지에서 글을 남겨본다.




O_DIRECT


거의 모든 UNIX&Linux 시스템에서는 모든 데이터 읽기/쓰기에 OS 캐시를 사용한다.


이러한 캐시기반에서는 어플리케이션이 데이터를 읽을때 가장 먼저 OS캐시에 원하는 데이터가 있는지 찾아보고


원하는 데이터가 캐시에 있다면 그대로 가져다 쓰고 만약 캐시에 원하는 데이터가 없다면 디스크에서 데이터를 찾아다가


캐시에 먼저 복사한 다음에 어플리케이션에 데이터를 돌려준다. 


O_DIRECT 옵션은 바로 이 OS캐시를 MySQL/MariaDB 에서 사용하지 않겠다라는 선언이다.



[ fdatasync ]

DB -> OS캐시 -> DataFile 



[ O_DIRECT ]

DB -> DataFile



OS캐시를 거치는 과정이 없어졌으므로 IO 과정이 단순화 되어 빨라질꺼라 착각할수 있지만 실제로는 전혀아니다.


캐시=메모리 라는 점을 다시 생각해보면 OS캐시는 느려터진 디스크와 DB간의 완충작용을 해주기 때문에 


O_DIRECT를 쓰게되면 버퍼풀에서 읽어오는 읽기성능은 차치하더라도 쓰기성능은 오히려 더 나빠질수 밖에 없다.  


그렇다면 O_DIRECT를 쓰는 진짜 이유는 무엇일까?




이유 


IO 성능 저하를 감안하면까지 O_DIRECT를 사용하는 가장 큰 이유는 더블버퍼링을 막아 메모리를 효율적으로 쓰기 위함이다.


(더블버퍼링을 더블라이트버퍼(Double Write Buffer)와 헷갈리면 안된다. 더플라이트버퍼는 데이터의 안전성을 위해


디스크상에 중복된 데이터를 이중으로 저장하는 것이고 여기서 말한 더블버퍼링은 메모리상에서의 중복 저장을 의미한다.)


InnoDB는 이미 버퍼풀(Buffer Pool)이라는 훨씬 고도화된 메모리 관리 영역을 가지고 있기 때문에 동일한 데이터를


버퍼풀과 OS캐시에 중복으로 저장해 메모리를 낭비할 필요가 없다.


그리고 두번째 이유는 OS캐시에 대한 무한한 불신(ㅋㅋㅋㅋ) 때문이 아닐까? 사실 OS캐시가 우리가 생각하는것 만큼


똑똑하게 움직여주진 않는다. OS캐시는 되도록 많은 데이터를 캐시하려고 하기 때문에 어느순간 버퍼풀의 데이터가 


스왑으로 빠져버리는 경우도 허다하기 때문이다. 물론 vm.swappiness 를 수정하거나 innodb_buffer_pool_populate 를 


설정할 수 도 있겠으나 해당서버에 DB이외에 다른 어플리케이션이 있을수도 있고 innodb_buffer_pool_populate 는 


아직 MariaDB에서만 지원되며 다른 예외사항이 발생할수 있기 때문에 O_DIRECT를 쓰는게 DB가 OS캐시를 사용할수 없게 


강제할수 있는 가장 쉽고 빠른 방법이 될 수도 있다.




조건


O_DIRECT를 썻다면 쓰기 성능이 나빠지게 되는데 이를 보완해줄수 있는게 RAID 컨트롤러의 캐시다.


OS와는 전혀 별개의 캐시를 IO에 사용하기 때문에 스와핑이나 기타 변수가 발생할 염려없이 쓰기 성능을 


보장해주므로 이런 캐시를 내장한 컨트롤러를 쓴다면 O_DIRECT를 검토하도록 하자. 물론 BBU까지 있다면 금상첨화다!




ETC


O_DIRECT를 쓰더라도 데이터파일에 대해서만 OS캐시를 안쓸뿐이다. 만약 Redo로그에서도 OS캐시를 쓰지 않겠다면


ALL_O_DIRECT를 사용하면 된다.


to Top