ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • Real My SQL 8.0 읽고 공부하기 - ⑤-①,② 트랜잭션
    SQL 공부/MySQL 8.0 2023. 8. 27. 11:31

    ● 잠금 

    잠금은 동시성을 제어하기 위한 기능이다. 

    하나의 회원 정보 레코드를 여러 커넥션에서 동시에 변경하려고 하는것을 방지한다.

    이것을 해주지 않으면 해당 레코드 값을 예측해줄 수 없다.

     

     

     


     

     

    1) 트랜잭션

     

    트랜잭션은 작업의 완전성을 보장해주는 것, 논리적인 작업 셋을 완벽히 처리하거나

    처리하지 못할 경우 원상태로 복구해서 작업의 일부만 적용되는 현상(Partial update)이 발생하지 않게 해준다.

     

    ● 격리 수준

    하나의 트랜잭션 내에서 혹은 여러 트랜잭션 간의 작업 내용을 어떻게 공유하고 차단할 것인지 결정하는 레벨

     

    1. MySQL에서의 트랜잭션

     

    트랜잭션은 하나의 논리적인 작업셋에 하나의 쿼리가 있든지, 두 개 이상의 쿼리가 있든 관계없이

    해당 논리적인 작업 셋 자체가 100% 적용 혹은 아무것도 적용되지 않아야 함을 보장하는 것이다.

     

    MyISAM은 트랜잭션을 제공하지 않는다.

    InnoDB와의 차이를 한번 알아보려면

    INSERT INTO test (pk) 
         VALUES (1), (2), (3)

    위와 같은 쿼리를 실행하면

    MyISAM - 만약 3번을 넣다가 실패했을 경우 1,2 가 삽입된다.

    InnoDB - 만약 3번을 넣다가 실패했을 경우 모두 삽입되지 않는다.

     

    얼핏 보면 MyISAM이 좋다고 생각할 수 있지만, 만약 하나라도 실패했을 경우 모두 롤백해야하는 처리를 만들어야한다면..

    쿼리내에서 IF ELSE 처리를 해주어야한다.

     

     

    2. 주의사항

     

    트랜잭션의 범위는 최소화하는 것이좋다.

    여러 쿼리작업을 진행중 쓰기 작업을 하게될때 트랜잭션을 활성화하고 해당 작업에대해서 끝나게되면 트랜잭션을 종료하는 것이 좋다.

    다른작업이 아무리 작은 작업수준이여도 분리해내는 것이좋고, 만약 DB접근외에 외부 API연동, 파일업로드, 네트워크 작업

    시간이 오래걸리는 작업 등등이 존재하게 되면 서버가 높은 부하상태로 빠질 수 있다.

     

     

     


     

    2) MySQL 엔진의 잠금

     

    MySQL의 잠금은 스토리지 엔진 레벨과 MySQL엔진 레벨로 나뉜다. MySQL엔진은 스토리지 엔진을 제외한 나머지 부분이다.

    MySQL엔진의 잠금은 모든 스토리지 엔진에 영향이 가지만, 스토리지 엔진 레벨의 잠금은 서로간에 영향을 미치지 않는다.

     

     

    1. 글로벌 락

     

    글로벌 락은 FLUSH TABLES WITH READ LOCK 명령으로 획득한다. MySQL잠금중 범위가 가장 큰 잠금이다.

    MyISAM 테이블 혹은 MEMORY테이블에 글로벌 락이 걸리면 SELECT를 제외한 대부분 DDL, DML 문장을 실행해도

    대기상태로 남는다.

     

    mysqldump로 일관된 백업을 받으려면 글로벌 락을 사용해야한다. (설정여부에 따라 달라질 수 있음)

     

    InnoDB스토리지 엔진은 트랜잭션을 지원하기 때문에 일관된 데이터 상태를 위해 모든 데이터 변경 작업을 멈출 필요없다.

    8.0 버전부터는 Xtrabackup이나 enterprise Backup과 같은 백업툴들이 안정적인 실행을 위해 백업락이 도입되었다.

     

    백업락의 경우 스키마나 인증관련 정보를 변경할 수 없다.  그러나, 일반적인 테이블의 데이터 변경은 허용된다.

     

    MySQL 서버 구성은 일반적으로 소스 서버와 레플리카 서버로 구성되는데, 주로 백업은 레플리카 서버에서 시행된다.

    레플리카 서버에서 백업 도중 소스서버에서 문제가 생기면 레플리카 서버가 최신상태가 될 때까지 서비스를 멈추어야

    할 수 있다.

     

    DDL명령어 하나로 백업이 실패하면 다시 처음부터 백업을 진행해야하는데 백업 락은 DDL명령이 실행되면 복제를

    일시중지하는 역할을 해준다.

     

     

    2. 테이블 락

     

    테이블락은 명시적으로는 LOCK TABLES table_name [READ | WRITE] 명령으로 얻을 수 있다.

    이는 MyISAM과 InnoDB 동일하게 설정할 수 있으며, UNLOCK TABLES 명령으로 잠금 반납이 가능하다.

     

    묵시적 테이블 락은 MyISAM과 MEMORY테이블에 데이터를 변경하는 쿼리를 실행하면 발생한다.

    하지만 InnoDB 테이블의 경우 레코드 기반의 잠금을 제공하기 때문에 데이터 변경 쿼리로 인해 테이블 락이

    설정되지 않는다. 정확히 말하자면 DML쿼리에서는 테이블락이 무시되지만, DDL의 경우에만 영향을 미친다.

     

     

    3. 네임드 락

     

    특정 문자열에 대하여 GET_LOCK() 함수를 통해 잠금을 설정할 수 있다.

    이 잠금은 데이터베이스 객체가 아닌 사용자가 지정한 문자열에 대해 획득, 반납하는 잠금이다.

     

    여러 클라이언트가 상호 동기화를 처리해야할 때 네임드 락을 이용하면 쉽게 해결할 수 있다.

    또한, 많은 레코드에 대해서 복잡한 요건으로 레코드를 변경하는 트랜잭션에 유용하게 사용할 수 있다.

    배치 프로그램 처럼 한꺼번에 많은 레코드를 변경하는 쿼리는 데드락 원인이 되는데, 동일 데이터를 변경하거나

    참조하는 프로그램 끼리 분류해서 네임드 락을 걸고 쿼리를 실행하면 간단히 해결할 수 있다.

     

     

    4. 메타데이터 락

     

    메타 데이터 락은 데이터 베이스 객체의 이름이나 구조를 변경하는 경우에 획득하는 락이다.

     

    만약 과거 테이블과 새로운 테이블을 교환하려는 경우 (테이블 이름)

    RENATE TABLE table1 TO table1_backup, table2 TO table1 을 통해 table1이 존재하지 않는 순간을 

    발생하지 않고 교환 가능하다.

     

    만약 메타데이터 잠금과 InnoDB의 트랜잭션을 동시에 사용해야 하는 경우가 있으면,

    새로운 구조의 테이블을 생성하고 최근 까지의 데이터는 프라이머리 키값을 범위별로 나누어서 멀티 스레드로

    빠르게 복사한다.

    그리고 최근의 나머지 데이터는 트랜잭션 잠금, 테이블 잠금, RENAME TABLE명령으로 진행하는데

    이때 테이블잠금으로 인해 INSERT를 할수 없게 하여 데이터 손실이 일어나지 않게 한다.

     

    비교적 가장 최근것까지 복사해두어야 잠금시간을 최소화해서 서비스에 미치는 영향을 줄일 수 있다.

     

     

     

     

     

Designed by Tistory.