자꾸 서버가 멈추는 현상이 심해졌는데 그이유가 크롤러와 유저의 증가에 따른 원인으로 보았을때 예상되는 문제가
DB에 락이 걸렸을 가능성이 높아보여 정리하였다
트랜잭션과 락(Transaction, Lock)에 대한 이해
트랜잭션(Transaction):
트랜잭션은 논리적인 작업 단위로, 전체가 성공적으로 처리되거나 실패할 경우 롤백되는 원자성을 보장하는 기능입니다. 주로 데이터베이스에서 여러 쿼리를 묶어 하나의 작업으로 처리할 때 사용됩니다.
락(Lock):
락은 서로 다른 작업에서 동시에 같은 자원을 필요로 할 때, 자원 경쟁을 피하고 순서대로 사용할 수 있도록 하는 기능입니다. MySQL에서 사용되는 락은 MySQL 엔진 레벨의 락과 스토리지 엔진 레벨의 락으로 나눌 수 있습니다.
스토리지 엔진 레벨의 락:
InnoDB 스토리지 엔진에서 제공하는 락은 주로 비관적 락(Pessimistic locking)을 사용합니다. 이는 트랜잭션에서 변경하려는 레코드에 대해 락을 획득하고 쿼리를 수행하는 방식입니다. 스토리지 엔진 레벨의 락에는 레코드 락, 갭 락, 넥스트 키 락, 오토 인크리먼트 락 등이 있습니다.
- 레코드 락 (Record lock): 인덱스 레코드에 락을 걸어서 수정, 삽입, 삭제 등의 다른 트랜잭션을 막습니다.
- 갭 락 (Gap lock): 인덱스 레코드와 인접한 앞/뒤 사이 공간에 락을 거는데, 주로 REPEATABLE_READ 이상의 격리 수준에서 발생합니다.
- 넥스트 키 락 (Next key lock): 레코드 락과 갭 락을 합쳐서 사용하며, 인덱스 레코드와 인덱스 레코드 사이의 갭도 락을 걸어 동시성을 보장합니다.
- 오토 인크리먼트 락 (Auto increment lock): AUTO_INCREMENT 속성을 가진 컬럼의 값을 채번할 때 발생하는 락입니다.
스토리지 엔진 레벨의 락은 주로 비관적 락을 사용하지만, 대규모 트래픽을 처리하는 애플리케이션에서는 성능 이슈를 고려하여 낙관적 락으로 변경하여 사용하기도 합니다.
MySQL 엔진 레벨의 락:
MySQL 엔진 레벨의 락에는 글로벌 락, 테이블 락, 네임 락, 유저 락 등이 있습니다. 이러한 락은 주로 전체 데이터베이스나 특정 테이블에 대한 락을 걸 때 사용되며, 주의해서 사용해야 합니다.
- 글로벌 락 (Global lock): 모든 테이블에 잠금을 걸어 전체를 멈추는 락을 의미합니다. 주로 FLUSH TABLES WITH READ LOCK 명령어를 통해 사용하지만, 서비스 장애로 이어질 수 있어 주의가 필요합니다.
- 테이블 락 (Table lock): 각각의 테이블에 대한 락을 걸어, 주로 DDL 작업 등에서 사용됩니다.
- 네임 락 (Name lock): 테이블 또는 뷰의 이름을 변경하는 경우 자동으로 락을 거는데, rename 명령어를 통해 발생합니다.
- 유저 락 (User lock): 사용자가 지정한 문자열에 락을 걸어 사용됩니다.
정리:
트랜잭션은 데이터베이스에서 원자성을 보장하기 위한 기능이며, 락은 동시성을 보장하는 기능입니다. MySQL에서는 스토리지 엔진 레벨의 락과 MySQL 엔진 레벨의 락을 사용하여 효과적으로 데이터베이스 동작을 조절합니다. 특히, 넥스트 키 락을 주의해서 사용하여 불필요한 레코드에 락이 걸리는 문제를 최소화하는 것이 중요합니다.
'기타' 카테고리의 다른 글
코드작성 스타일 [ 정보 : 함수형 프로그래밍 (선언형 코드) ] (0) | 2022.09.03 |
---|