InnoDB는 트랜잭션 데이터를 커밋하기 전에 어디에 저장합니까?


12

나는 몇 가지 테스트를 사용하여 수행 한 READ_COMMITTEDREAD_UNCOMMITTED가정에서, JDBC 기술을 사용합니다.

READ_UNCOMMITTED커밋되지 않은 데이터, 예를 들어 아직 커밋되지 않은 일부 트랜잭션의 데이터를 실제로 읽을 수 있음을 알 수 있습니다 (UPDATE 쿼리를 수행 할 수 있음).

질문

  • READ_UNCOMMITTED트랜잭션이 다른 트랜잭션에서 커밋되지 않은 데이터를 읽을 수 있도록 커밋되지 않은 데이터는 어디에 저장 됩니까?
  • READ_COMMITTED트랜잭션이 커밋되지 않은 데이터, 즉 "더티 읽기"를 수행 할 수없는 이유는 무엇 입니까? 이 제한을 시행하는 메커니즘은 무엇입니까?

답변:


11

" READ_UNCOMMITTED 트랜잭션이 다른 트랜잭션에서 커밋되지 않은 데이터를 읽을 수 있도록 커밋되지 않은 데이터가 어디에 저장됩니까? "

새로운 커밋되지 않은 레코드 (클러스터 PK) 버전은 페이지의 레코드의 "현재"버전으로 취급됩니다. 따라서 버퍼 풀 및 / 또는 테이블 공간 (예 : tablename.ibd)에 저장 될 수 있습니다. 그런 다음 READ-UNCOMMITTED 이외의 항목으로 스냅 샷 / 뷰를 작성해야하는 트랜잭션은 시스템 테이블 스페이스에 저장된 UNDO 레코드를 사용하여 이전 버전의 행 (히스토리 목록에 따라)을 구성해야합니다 . 커밋되지 않은 레코드를 읽을 때 InnoDB는 변경 버퍼 에서 커밋되지 않은 보조 인덱스 레코드를 읽고 레코드를 다시 사용자에게 제시하기 전에 적용해야 할 수도 있습니다.

InnoDB에서 롤백을 상대적으로 비싸게 만들 수있는 것이 바로이 동작입니다. 업데이트 된 레코드를 보유하고있는 장기 실행 유휴 트랜잭션으로 인해 잠재적 인 성능 문제를 유발할 수있는 가장 큰 요인입니다. 이러한 트랜잭션은 제거 작업을 차단하고 이전 레코드 버전의 히스토리 목록이 커지고 이전 버전을 다시 빌드하는 데 필요한 UNDO 레코드입니다. 주문형, 계속 성장할 것입니다. 오래되고 커밋 된 버전의 레코드를 읽을 필요가있는 새로운 트랜잭션을 느리게합니다. UNDO 레코드의 단일 링크 목록 인 더 길고 더 긴 히스토리 목록을 탐색하고 재구성하기 위해 더 많은 작업을 수행해야하기 때문입니다. 이전 버전의 레코드 따라서 많은 CPU 사이클을 사용하게됩니다 (내부 잠금 프리미티브는 말할 것도 없습니다 : 뮤텍스, rw_locks, 세마포어 등).

잘만되면 그것은 의미가 있습니까? :)

참고 로 MySQL 5.7에서는 UNDO 테이블 스페이스를 이동하고 시스템 테이블 스페이스 에서 로그 아웃 하여 자동으로 잘릴 수 있습니다. 제거 조작을 막는 장기 실행 트랜잭션이있는 경우 상당히 길어질 수 있으며 히스토리 목록 길이가 매우 길고 증가합니다. 그것들을 시스템 테이블 스페이스에 저장하는 것은 거대한 / 증가하는 ibdata1 파일의 가장 일반적인 원인으로, 나중에 해당 공간을 회수하기 위해 잘 리거나 축소 / 진공 할 수 없습니다.


4

당신은 물었다

READ_UNCOMMITTED 트랜잭션이 다른 트랜잭션에서 커밋되지 않은 데이터를 읽을 수 있도록 커밋되지 않은 데이터는 어디에 저장됩니까?

질문에 대답하려면 InnoDB 아키텍처가 어떻게 보이는지 알아야합니다.

다음 그림은 Percona CTO Vadim Tkachenko에 의해 몇 년 전에 작성되었습니다.

InnoDB 아키텍처

InnoDB 트랜잭션 모델 및 잠금대한 MySQL 문서에 따르면

COMMIT는 현재 트랜잭션에서 작성된 변경 사항이 영구적이며 다른 세션에서 볼 수 있음을 의미합니다. 반면에 ROLLBACK 문은 현재 트랜잭션에 의해 작성된 모든 수정 사항을 취소합니다. COMMIT 및 ROLLBACK은 현재 트랜잭션 중에 설정된 모든 InnoDB 잠금을 해제합니다.

COMMIT 및 ROLLBACK은 데이터 가시성을 제어하므로 READ COMMITTED 및 READ UNCOMMITTED는 변경 사항을 기록하는 구조 및 메커니즘에 의존해야합니다.

  1. 롤백 세그먼트 / 실행 취소 공간
  2. 재실행 로그
  3. 관련된 테이블에 대한 간격 잠금

롤백 세그먼트 및 실행 취소 공간은 변경 사항이 적용되기 전에 변경된 데이터의 모양을 알 수 있습니다. Redo Logs는 데이터가 업데이트 된 것으로 보이기 위해 어떤 변경 사항을 롤 포워드할지 알고 있습니다.

당신은 또한 물었다

READ_COMMITTED 트랜잭션이 커밋되지 않은 데이터를 읽을 수없는 이유, 즉 "더티 읽기"를 수행 할 수없는 이유는 무엇입니까? 이 제한을 시행하는 메커니즘은 무엇입니까?

재실행 로그, 실행 취소 공간 및 잠금 행이 작동합니다. 또한 InnoDB 버퍼 풀 ( innodb_max_dirty_pages_pct , innodb_buffer_pool_pages_dirtyinnodb_buffer_pool_bytes_dirty로 더티 페이지를 측정 할 수 있음)도 고려해야합니다 .

이것에 비추어, READ COMMITTED는 어떤 데이터가 영구적으로 나타나는지 알 것입니다. 따라서 커밋되지 않은 더티 페이지를 찾을 필요가 없습니다. READ COMMITED는 더티 읽기가 커밋 된 것 이상입니다. READ UNCOMMITTED는 데이터를 표시하기 위해 어떤 행을 잠글 것인지, 어떤 리두 로그를 읽거나 무시했는지를 계속 알고있을 것입니다.

격리 관리를위한 행 잠금을 완전히 이해하려면 InnoDB 트랜잭션 모델 및 잠금을 읽으십시오 .


1
먼저, 내 게시물에 대한 답변과 수정에 감사드립니다 ... 커밋 전에 시스템의 다른 사용자에게는 변경 사항이 보이지 않습니까? 여기서 사용자는 말 그대로 거래를 의미합니다. 커밋되지 않은 읽기는 커밋되지 않은 데이터를 읽을 수 있으므로이 격리 수준은이 데이터를 어디에서 읽습니까? 데이터베이스의 특정 데이터 항목에 대해 커미트되지 않은 데이터 소스가 둘 이상있을 수 있습니까? 그렇다면 어떤 커밋되지 않은 데이터를 읽을 수 있습니까?
Shuzheng
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.