언두 로그 InnoDB 스토리지 엔진은 트랜잭션과 격리수준을 보장하기 위해 DML(INSERT, UPDATE, DELETE)로 변경되기 이전 버전의 데이터를 별도로 백업한다. 백업된 데이터를 언두로그(Undo Log)라 한다. 언두로그가 어떻게 사용되는지 간단히 살펴보자. 트랜잭션 보장 트랜잭션이 롤백되면 트랜잭션 도중 변경된 데이터를 변경 전 데이터로 복구해야 한다. 이때 언두 로그를 사용한다. 격리 수준 보장 특정 커넥션에서 데이터를 변경하는 도중 다른 커넥션에서 데이터를 조회하면 트랜잭션 격리 수준에 맞게 변경 중인 레코드를 읽지 않고 언두로그의 데이터를 읽어서 반환한다. 즉, 격리 수준에 따라 보여주는 데이터가 다르다. 언두 로그 모니터링 대용량 데이터 처리 MySQL 5.5 이전 버전에서는 언두..
InnoDB 버퍼 풀 디스크의 파일이나 인덱스 정보를 메모리에 캐시해두는 공간이다. 쓰기 지연을 위한 버퍼로도 사용된다. DML을 통한 데이터 변경은 디스크의 여러 곳에 저장된 레코드를 변경한다. 이는 디스크의 랜덤 I/O를 발생시킨다. 따라서 쓰기 지연을 통해 랜덤 I/O를 줄여 성능을 향샹시킬 수 있다. 데이터 페이지 InnoDB가 디스크와 데이터를 주고 받는 최소 단위를 데이터 페이지라 한다. 데이터 페이지에는 최소 하나의 행이 포함될 수 있다. 하나의 행이 너무 크다면 다음 페이지를 포인터로 쪼개서 데이터 페이지는 전송한다. 구조 InnoDB 버퍼 풀은 메모리 공간을 페이지 단위로 쪼개서 관리한다. 쪼개진 조각을 관리하기 위해 LRU 리스트, Flush 리스트, Free 리스트라는 3개의 자료구조..
InnoDB는 테이블 기반의 잠금이 아닌 레코드 기반의 잠금을 제공한다. 그때문에 높은 동시성 처리가 가능하고 안정적이며 성능이 뛰어나다. PK에 의한 클러스터링 InnoDB의 모든 테이블은 PK 값의 순서대로 클러스터링되어 저장된다. 모든 세컨더리 인덱스는 레코드 주소 대신 PK의 값을 논리적인 주소로 사용한다. 테이블이 PK 순서대로 저장되어 있기 때문에 PK를 이용한 레인지 스캔이 상당히 빠르다. 결과적으로 실행계획에서 PK는 기본적으로 다른 보조 인덱스에 비해 비중이 높게 설정된다. MVCC(Multi Version Concurrency Control) 잠금을 사용하지 않는 일관된 읽기 제공을 위해 하나의 레코드에 대해 여러 개의 버전이 동시에 관리된다. InnoDB는 언두 로그를 이용해 이 기능..
쿼리 캐시 동일 SQL 쿼리가 실행되면 테이블을 읽지 않고 캐시 데이터를 반환한다. 하지만 테이블의 데이터가 변경되면 캐시에 저장된 데이터 중 변경 사항과 관련된 것들을 모두 삭제해야한다. 이는 심각학 동시 처리 성능 저하를 유발한다. 결국 MySQL 8.0에서부터 쿼리 캐시 기능은 완전히 제거 되었다. 쿼리 파서 쿼리 문장을 토큰으로 분리해 트리 형태의 구조로 만든다. 쿼리 문장의 기본 문법 오류를 발견하고 오류 메시지를 전달한다. 전처리기 파싱된 쿼리 문장에서 구조적인 문제점을 확인한다. 각 토큰을 테이블 이름이나 칼럼 이름, 내장 함수와 같은 객체를 매핑한다. 해당 객체의 존재 여부와 객체의 접근 권한 등을 확인한다. 실제 존재하지 않거나 권한상 사용할 수 없는 경우 오류가 발생한다. 옵티마이저 쿼..
MySQL 아키텍처 MySQL 커넥터 다양한 방식으로 다양한 언어에서 SQL을 사용할 수 있도록 도와준다. MySQL C API, JDBC, ODBC, .NET 표준 드라이버 등이 있다. MySQL 엔진 MySQL의 두뇌 역할은 한다. SQL 문장을 분석하거나 최적화한다. 커넥션 핸들러, SQL 파서 및 전처리기, 옵티마이저가 중심을 이룬다. MySQL 스토리지 엔진 MySQL의 손발 역할을 한다. MySQL 엔진이 SQL을 분석하고 실행계획을 작성하면 MySQL 스토리지 엔진은 그것에 맞게 실제 데이터를 디스크 스토리지에 저장하거나 가져온다. 대표적으로 InnoDB와 MyISAM이 있다. 핸들러 API MySQL이 스토리지 엔진에게 읽기 또는 쓰기 요청을 보내는 것을 핸들러 요청이라 한다. 이때 사용되..
JOIN이란 두 테이블을 묶어서 하나의 결과 집합을 만드는 것이다. 서브 쿼리를 통해 두 개 이상의 테이블도 조인 가능하다. INNER JOIN 일반적으로 JOIN을 이야기 하면 INNER JOIN이다. 교집합을 생각하면 된다. SELECT FROM [INNER] JOIN ON [WHERE ]; 기준 테이블의 row와 참조 테이블의 row 중 조인 조건이 맞는 row끼리 묶는다. 선택 열은 테이블 간 동일한 이름의 열을 가지고 있을 수 있어 테이블명.속성명으로 명시해줘야한다. 테이블 명에 Alias(별칭)을 사용하면 좀 더 간결하게 작성 가능하다. 조인 조건은 기준 테이블의 row가 참조 테이블의 어떤 row와 병합되어야 하는지 속성의 기준으로 명시한다. 테이블A.fkey = 테이블B.pkey 예시 SE..