티스토리 뷰

336x280(권장), 300x250(권장), 250x250, 200x200 크기의 광고 코드만 넣을 수 있습니다.

MySQL MyISAM과 InnoDB 엔진 활용

MySQL MyISAM과 InnoDB 엔진 활용


MySQL MyISAM과 InnoDB 엔진 활용




데이터베이스 부문에 몸담은 사람이라면 누구나 알고 있듯이 MySQL은 무료로 다운로드해 설치 가능하면서 성능 면에서도 좋은 평가를 받아 세계적으로 가장 많이 쓰이는 DBMS 중 하나다. 그런데 막상 MySQL을 설치해 이용하는 경우라도 그 기능의 많은 부분을 놓치고 있는 경우가 많은 게 사실이다. 따라서 이 글에서는 MySQL의 몇 가지 기능들 가운데 MySQL의 기본 엔진이 되는 MyISAM과 InnoDB라는 엔진의 활용법에 대해 이야기해 보고자 한다.


현재 MySQL에서 제공하는 엔진 타입은 약 10가지 종류며 그 중에서 가장 대중적으로 쓰이는 것은 아마도 MyISAM, InnoDB, ndbcluster가 아닐까라고 생각해 본다. 참고로 ndbcluster는 MySQL Cluster(이중화)에서 사용하는 엔진으로 이해하면 된다. MySQL을 사용하는 사람들 중에는 자신이 무슨 엔진을 쓰는지조차 모르고 사용하는 경우가 적지 않다. 또는 당연한 듯이 자신의 시스템은 MyISAM 타입의 엔진을 쓰는 것으로 착각하고 있을지도 모른다. 그러나 자신이 MySQL을 설치하고 TABLE 생성 시 엔진타입에 아무런 설정을 하지 않았다면 MyISAM 타입이 된다. 그러면 어떻게 엔진 타입을 선택하고 MyISAM과 InnoDB를 사용하는지 알아보도록 하겠다.
MySQL의 독특한 특징 가운데 하나는 각각의 TABLE마다 엔진타입을 생성 또는 변경할 수 있다는 것이다. 생성 방법은 TABLE 생성 시 마지막에 ENGINE=MYISAM 또는 ENGINE=InnoDB로 옵션을 사용해 엔진을 정의하는 것이다. 즉, 하나의 데이터베이스 안에 있는 여러 TABLE의 엔진타입을 임의대로 선정할 수 있고 사용할 수 있다는 의미다. 그럼 MyISAM과 InnoDB의 선택 기준은 어떻게 될까?

트랜잭션의 사용 여부에 따른 선택

트랜잭션은 어떤 작업을 수행할 때 작업에 실패하더라도 일부 잘못된 작업이 실질적으로 수행해야 할 작업에는 영향을 미치지 않도록 하는 기능이라 볼 수 있다. 어찌 보면 DBMS의 가장 중요한 기능으로 여겨지는 트랜잭션 기능이 MySQL의 MyISAM 엔진에는 누락되어 있다. 왜 그럴까? 
MySQL의 개발 목적은 아마도 다양한 유저들에게 입맛에 맞는 엔진을 선택하게 함으로써 다양하게 쓸 수 있는 기회를 제공하는 데 있는 것 같다. 그래서 MyISAM은 트랜잭션이 필요 없는 사이트에 사용되며 DML 중 Select가 주인 업무에 적합하다고 보면 된다. 어떻게 보면 데이터 실무에서 트랜잭션을 지원하지 않는 것은 말이 되지 않는 상황이지만 나름 필요한 용도가 있고 또한 현재까지 MySQL에서 이 엔진을 기본 엔진으로 고집하는 이유가 있기 때문에 사용하는 것 아닐까 생각된다. 
트랜잭션을 지원하지 않는 것은 곧 데이터의 일관성이 무시된다는 뜻이 되기도 한다. 한마디로 MySQL의 MyISAM 엔진에 대한 생각은 이런 것 같다. 많은 트랜잭션은 시스템 자원을 많이 소모해 전체 성능을 떨어뜨릴 수 있기 때문에 이런 로직을 거부함으로써 다른 어떤 DB보다도 빠른 조회를 할 수 있도록 하는 부분을 강점으로 내세운 것이다. 그 대신 다음에 설명할 LOCK TABLES/UNLOCK TABLES를 이용해 트랜잭션과 같은 일을 할 수 있도록 구현되었다. 
결과적으로 보면, MyISAM은 트랜잭션의 무 지원으로 인해 트랜잭션을 요하는 은행, 쇼핑몰 등의 금융 거래가 오가는 사이트에 부적합하므로 이와 같은 사이트에는 InnoDB 또는 트랜잭션 기능이 있는 엔진을 이용하는 방향으로 고려해야 할 것이다.

LOCKING 방식에 따른 선택

MyISAM은 LOCKING 타입이 TABLE 단위 LOCKING이고, InnoDB는 오라클과 유사한 ROW 단위의 LOCKING 방식 로직을 사용하고 있다. MyISAM 엔진은 INSERT, UPDATE, DELETE 수행 시 해당 액세스하는 TABLE 전체에 LOCKING이 걸리는 방식이다. 이 말은 TABLE에서의 Row 수가 증가하면 증가할수록 다른 TABLE을 조인해 데이터 수정 작업을 하는 경우 수행 결과가 느려질 것이고 기다리는 시간만큼 TABLE Lock이 걸려있기 때문에 다음 수행을 진행할 수 없는 결과를 초래한다. 이를 해결하기 위해서는 MySQL 역시 쿼리에 대한 튜닝을 진행해 각 SQL이 1초 이내로 수행될 수 있도록 해야 할 것이다. 
반면에 InnoDB는 ROW 단위의 LOCKING 방식을 사용하고 있으므로 MyISAM의 LOCKING 방식을 보안할 수 있는 엔진임에 틀림없다. 물론 MySQL은 공개 DBMS라는 특징이 있고 오라클처럼 우수한 LOCKING 아키텍처를 가지고 있지는 않으므로 동시에 몇 백 개의 트랜잭션이 들어왔을 때 성능이 급격히 떨어지는 것을 주변에서 흔히 볼 수 있다. 이 부분은 구조적으로 보완해야 할 부분으로 판단되며 데이터량이 급증하는 시대적 흐름을 따라가기 위해서는 구조 개선이 필요하지 않을까 생각된다.

메모리 관리 방식에 따른 선택

무엇보다 InnoDB는 별도의 Buffer Pool을 가지고 있기 때문에 MyISAM 엔진처럼 OS 자체의 Buffer Cache 사이즈를 OS가 자동으로 동적 할당하지 않고 별도의 데이터를 위한 쓰기 버퍼 메모리를 가지고 있어 디스크를 직접 쓰지 않아도 되는 메모리에서 액세스되는 논리적인 읽기를 하게 된다. 
MyISAM에서 사용하는 Buffer Cache 중 Key Buffer Cache는 TABLE 중 인덱스만을 키 버퍼(메모리)에 캐시하게 된다. 그래서 TABLE의 데이터를 가져오기 위해서는 OS에서 캐시 된 데이터를 가져와야 하기 때문에 값비싼 시스템 콜을 호출해야 한다. 반면 InnoDB 엔진은 오라클처럼 별도의 데이터를 위한 읽기 쓰기 버퍼 캐시 메모리를 가지고 있으므로 인덱스와 데이터에 대한 캐시 데이터를 가지고 있다. 이미 알고 있겠지만 쿼리로 질의하면 대부분의 DBMS는 Buffer Pool에서 데이터를 검색하고 없을 경우 디스크에서 읽어서 Buffer Pool에 올려놓으며 이것을 Physical Read라 한다. 반대로 이미 Buffer Pool에 데이터가 존재해 디스크를 직접 읽지 않아도 되는 경우를 Logical Read라 한다. 즉, Logical Read가 Physical Read에 비해 읽기 성능이 빠르기 때문에 OS의 메모리 상태 비율에 맞춘 적절한 Buffer Pool을 잡아준다면 성능 향상에 도움을 줄 것이다.

MySQL 운영에서 발생하는 장애 복구 방법에 따른 선택

우선 MySQL의 장애 원인을 들어보면 다섯 가지 정도로 정리할 수 있다. 1) 데이터가 Write되는 중간에 MySQL 프로세스가 죽었을 때 2) 의도하지 않은 시스템의 다운 시 3) 하드웨어적인 오류 4) 외부 프로그램에 의해 TABLE을 변경하는 시점에 서버에서 변경 작업이 이뤄졌을 때 5) MySQL의 버그 등이다. 
MySQL의 데이터 깨짐 현상은 다른 상용 DBMS보다 흔하게 발생되지만 데이터가 없어지거나 복구가 불가능하지는 않다는 것은 MySQL의 공식입장이나 필자의 경험에 비춰 보면 충분히 완전복구가 가능하다는 것으로 받아들여진다. 그러나 완전복구가 가능하더라도 복구방법이 어렵기만 하다면 사용자들은 장애 시 크나큰 어려움을 겪게 될 것이다. 그렇다면 각 엔진의 복구방법에 대해 간단히 살펴보자.
MyISAM은 TABLE 손상 시 myisamchk, repair table, check table 같은 명령어를 사용해 TABLE을 대부분 수동 복구시키는 반면에 InnoDB는 MyISAM TABLE에 비해 Double Write, Checksum, Validation 로직들과 버그 보안으로 TABLE 손상이 거의 발생되지 않는 장점이 있어 별도의 복구 도구를 제공하지 않고 자동복구 모드를 사용해 관리된다. 물론 MyISAM에서의 자동복구 옵션이 존재하긴 하지만 2차 데이터 손상에 대한 위험이 있을 수 있으므로 자동복구 옵션을 권장하고 싶지는 않다.

지금껏 얘기한 네 가지 차이점은 두 가지 엔진이 가지고 있는 독특한 특징이라고 볼 수 있다. MySQL은 5.5 버전부터 InnoDB 엔진타입을 기본 스토리지 엔진으로 채택해서 배포 중이다. 그만큼 InnoDB의 기능이 스토리지, 관리, 효율성 측면에서 많이 향상됐음을 보여주는 결과다. 특히 오라클의 MySQL 인수 이후 발표된 5.5 버전의 스레드 동시성 처리, 메모리 할당 제어, LOCKING 알고리즘, 복구 성능 등의 향상은 이용자들의 호평을 받았다. 5.5 버전이 출시되면서 InnoDB가 재설계되어 그 동안 MySQL의 기본 엔진이었던 MyISAM이 InnoDB로 변경되어 등장한 것은 특히 눈여겨볼 부분. 이는 앞으로 오라클에서 InnoDB를 기본 스토리지 엔진으로 사용할 것이고 MyISAM도 여전히 이용은 가능하지만 앞으로는 MyISAM 엔진의 획기적인 성능 향상이 없을 것임을 내비치는 암시일지도 모른다. 현재 자신의 시스템이 MyISAM이고 성능상에 다소 문제가 있다고 판단된다면 InnoDB를 한번쯤 고려해 보길 권한다.

'DEVELOPE > MYSQL&MARIADB' 카테고리의 다른 글

MYSQL 조인의 종류  (0) 2017.02.06
mysql 프로시저  (0) 2017.02.01
mysql 포트변경후 외부접속방법  (0) 2017.02.01
mysql 포트 변경법  (0) 2017.02.01
mysql 포트 변경후 접속법  (1) 2017.02.01
댓글