ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • MySQL ACID Compliant
    Database 2023. 5. 8. 06:25
    728x90
    반응형

    소개

    InnoDB 스토리지 엔진ACID Compliant 트랜잭션을 보장합니다.
    트랜잭션은 데이터의 접근과 저장 측면에서 안정성을 보장해주는데요.

    A : atomicity
    C : Consistency
    I : Isolation
    D: Durability

    위 4가지 방식으로 대표되는 신뢰성을 제공합니다.


    Atomicity

    atomic 하다는 표현은 여러 개의 작업을 하나의 작업으로 묶이는 것을 의미합니다.
    예를 들어,
    1. 데이터를 생성한 후,
    2. 생성된 데이터를 기반으로 수정이 발생하는 경우에
    두번째 작업인 수정 작업이 실패하면 첫번째 단계인 데이터 생성 또한 무효화됩니다.

    create table member (
    	id int primary key,
    	name varchar(32),
    )
    
    start transaction
    
    insert into member (id, name)
    values (1, 'lee')
    
    insert into member (id, name)
    values (1, 'kim')
    
    rollback

     
    위 예시에서 primary key 제약조건에 위배되는 2개의 insert 쿼리가 진행되며,
    위의 케이스에서 Atomic 을 보장하기 위하여 모두 Rollback 됩니다.
     

    Consistency

    consistency 는 데이터의 결함을 최소화해주는 안정성을 의미합니다.
    Constraint 라고 불리는 제약사항으로부터 데이터의 무결성이 지켜지는데요.

    Not Null, Unique 과 같이 field 에 적용되는 제약조건,
    Foreign key 처럼 테이블 간의 관계에 대한 제약조건들로부터 데이터의 일관성이 지켜집니다.

    대개 데이터베이스의 query parser 와 같은 preprocessing 단계에서 해당 처리가 수행됩니다.

    <Foreign Table Truncate 시 발생하는 Integrity Error>

    create table member
    (
        id    int primary key,
        name  varchar(32),
        grade int,
        FOREIGN KEY (grade) REFERENCES grade(id)
    )
    
    create table grade
    (
        id   int primary key,
        score int,
        level int
    )
    
    truncate table grade
    
    // Cannot truncate a table referenced in a foreign key constraint (`mysql`.`member`, CONSTRAINT `member_ibfk_1`)



    Isolation

    고립 또는 격리 상태를 뜻하는 isolation 은 트랜잭션의 격리 수준을 의미합니다.
    실제 환경에서 데이터들은 많은 수의 요청대상이 될 수 있습니다.
    하나의 데이터를 읽거나 수정하는 다수의 요청이 동시다발적으로 발생할 수 있습니다.
    이때, 각각의 트랜잭션들이 얼마나 독립성을 보장받는지에 대한 내용이 isolation 입니다.

    mysql 에서 isolation 은 네가지가 존재합니다.

    read uncommitted
    read cummitted
    repeatable read
    serializable

    각 격리수준에 따라 트랜잭션 간의 영향도가 다릅니다.

    Undo log

    격리수준를 이해하기 위해서 buffer pool 과 undo log 에 대한 선이해가 필요합니다.
    InnoDB 스토리지 엔진은 효율성을 위하여 디스크 상에 파일로 존재하는 데이터들을 메모리에 올려둡니다.
    이 영역을 버퍼풀이라고 합니다.
    그리고 트랜잭션 시에 변경 전 상태를 임시적으로 기록해두는 곳을 Undo log 라고 합니다.

    단순한 데이터 변경이 발생했다고 가정해보겠습니다.

    insert into member (id, name)
    values (1, ‘lee’)
    
    update member
    set name ‘kim’
    where id = 1


    이때, 버퍼풀에 id : 1, name : lee 인 데이터가 생성되고, 최종적으로 name : kim 으로 변경된 데이터가 남게 됩니다.


    만약 아래처럼 commit 이나 rollback 이 되지 않을 채, 실행 중인 트랜잭션에선

    begin
    
    update member
    set name ‘park’
    where id = 1


    buffer pool 에는 id : 1 인 member 는 name : park 으로 변경되고,
    undo log 에는 id : 1, name : kim 인 member 가 남습니다.

    rollback 시에는 undo log 의 내용을 기반으로 버퍼풀이 변경됩니다.


    Read Uncommitted

    Read Uncommitted 는 가장 낮은 수준의 격리수준입니다.
    다른 트랜잭션에서 변경 중인 상태의 데이터를 읽을 수 있습니다.
    Commit 이나 Rollback 되지 않은 중간 상태의 데이터를 읽을 수 없어 Dirty Read 의 위험도가 존재합니다.
    보통 InnoDB 스토리지 엔진은 데이터를 메모리와 디스크에 저장합니다.
    디스크에 파일 형식으로 저장되는 모든 데이터는 효율성을 위하여 메모리의 버퍼풀에서 보관되는데요.
    Read Uncommitted 는 버퍼풀이나 디스크의 파일을 읽기 때문에 트랜잭션이 완료되지 않은 상태의 데이터에 접근이 가능합니다.
    (참고로 트랜잭션이 반영되지 않은 데이터는 Undo 영역에 저장됩니다.)

    Read Uncommitted 라는 의미적으로 바라보았을 때, Uncommitted 상태의 데이터를 읽는다는 의미로
    버퍼풀에 존재하는 Uncommitted 상태의 데이터를 읽을 수 있습니다.

    Read Committed

    Read Committed 는 Read Uncommitted 격리수준보다 한단계 높은 격리수준입니다.
    Read Committed 는 Undo log 영역의 데이터를 읽어들이기 때문에 다른 트랜잭션에서 진행중인 Atomic 한 상태를 보존해줍니다.

    그래서 반드시 다른 트랜잭션의 데이터 처리 전과 후의 상태만을 접근할 수 있습니다.

    Read Committed 는 다른 트랜잭션의 원자성을 보존해주기 때문에 Dirty Read 는 발생하지 않습니다.
    하지만 Non-Repeatable Read 와 Phantom Read 문제가 남아있습니다.

    이 둘은 단순히 다른 트랜잭션에 의해서 반복적인 읽기가 힘들어지는 상태입니다.

    다른 트랜잭션에 의해서 변경된 상태의 데이터를 읽을 수 있게 되는 문제입니다.

    예를 들어,

    Transaction 1
    
    begin 
    
    update member
    set name = ‘kim’
    where id = 1
    
    commit
    
    Transaction 2
     
    begin 
    
    insert into member (id, name)
    values (1, ‘lee’)
    
    select name
    from member
    where id = 1
    
    —-> kim
    
    // transaction 1 완료
    
    select name
    from member
    where id = 1
    
    —> lee


    연속된 읽기가 불가능합니다.

    Repeatable Read

    Repeatable ReadRead Committed 보다 한 단계 높은 격리수준입니다.
    Repeatable ReadNon-Repeatable ReadPhantom Read 문제를 해결합니다.
     
    Read Committed 에서 Undo Log 를 기반으로 데이터 접근이 발생했는데,
    Repeatable Read 는 스냅샷을 기반으로 데이터에 접근합니다.
    트랜잭션이 시작하는 시점의 데이터 스냅샷을 기준으로 데이터를 조회하기 때문에 다른 트랜잭션에 의해서 변경된 데이터를 알 수 없습니다.
    이로써 Non-Rerepeatable Read 와 Phantom Read 의 문제를 해결합니다.

     

    반응형

    'Database' 카테고리의 다른 글

    MySQL my.cnf  (0) 2023.09.11
    MySQL mysqldump 알아보기  (0) 2023.05.18
    Mysql Procedure  (0) 2023.05.15
    MySQL Tablespace 알아보기  (0) 2023.05.12
    mysql connection  (0) 2023.02.15
Designed by Tistory.