SQLite 공유 캐시 모드

DB 2017. 8. 24. 22:43
728x90
728x170
http://www.sqlite.org/sharedcache.html

번역

 

 1. SQLite 공유 캐시 모드

 버전 3.3.0 (2006-01-11)부터 SQLite는 임베디드 서버에서 사용하기위한 특별한 "공유 캐시"모드 (기본적으로 비활성화 됨)를 포함합니다.  공유 캐시 모드가 사용 가능하고 스레드가 동일한 데이터베이스에 대한 다중 연결을 설정하면 연결은 단일 데이터 및 스키마 캐시를 공유합니다.  이렇게하면 시스템에 필요한 메모리 및 IO의 양을 크게 줄일 수 있습니다.

 버전 3.5.0 (2007-09-04)에서는 공유 캐시 모드가 수정되어 단일 스레드 내에서가 아닌 전체 프로세스에서 동일한 캐시를 공유 할 수 있습니다.  이 변경 이전에는 스레드간에 데이터베이스 연결을 전달하는 데 제한이있었습니다.  이러한 제한 사항은 3.5.0 업데이트에서 제외되었습니다.  이 문서는 3.5.0 버전의 공유 캐시 모드에 대해 설명합니다.

 공유 캐시 모드는 경우에 따라 잠금 모델의 의미를 변경합니다.  자세한 내용은이 문서에서 설명합니다.  일반적인 SQLite 잠금 모델에 대한 기본적인 이해가 있습니다 (자세한 내용은 SQLite 버전 3의 파일 잠금 및 동시성 참조).

 2. 공유 캐시 잠금 모델

 외부 적으로는 다른 프로세스 또는 스레드의 관점에서 볼 때 공유 캐시를 사용하는 둘 이상의 데이터베이스 연결 이 단일 연결로 나타납니다.  여러 공유 캐시 또는 일반 데이터베이스 사용자간에 중재하는 데 사용되는 잠금 프로토콜은 다른 곳에서 설명합니다.

 

 그림 1

 그림 1은 세 개의 데이터베이스 연결이 설정된 런타임 구성 예제를 보여줍니다.  연결 1은 일반적인 SQLite 데이터베이스 연결입니다.  연결 2와 3은 캐시를 공유합니다. 일반 잠금 프로토콜은 연결 1과 공유 캐시 간의 데이터베이스 액세스를 직렬화하는 데 사용됩니다.  연결 2와 3에 의한 공유 캐시에 대한 직렬화 (또는 아래의 "읽기 - 미 확정적 격리 모드"참조)에 사용되는 내부 프로토콜은이 절의 나머지 부분에서 설명합니다.

 공유 캐시 잠금 모델, 트랜잭션 수준 잠금, 테이블 수준 잠금 및 스키마 수준 잠금의 세 가지 수준이 있습니다.  그것들은 다음의 세 가지 하위 섹션에서 설명합니다.

 2.1.  트랜잭션 수준 잠금

 SQLite 연결은 두 종류의 트랜잭션, 읽기 및 쓰기 트랜잭션을 열 수 있습니다.  이것은 명시 적으로 수행되지 않고 트랜잭션은 암시 적으로 데이터베이스 트랜잭션 테이블에 쓰기 전까지는 암시 적으로 읽기 트랜잭션입니다.이 시점에서 트랜잭션은 쓰기 트랜잭션이됩니다.

 최대 하나의 공유 캐시에 대한 연결은 한 번에 쓰기 트랜잭션을 열 수 있습니다.  이것은 임의의 수의 읽기 트랜잭션과 공존 할 수 있습니다.

 2.2.  테이블 수준 잠금

 둘 이상의 연결에서 공유 캐시를 사용하는 경우 잠금은 테이블 당 동시 액세스 시도를 직렬화하는 데 사용됩니다.  테이블은 두 가지 유형의 잠금 "읽기 잠금"과 "쓰기 잠금"을 지원합니다.  잠금은 연결에 부여됩니다. 각 데이터베이스 연결에는 읽기 잠금, 쓰기 잠금 또는 각 데이터베이스 테이블에 대한 잠금이 없습니다.

 한 번에 하나의 테이블에 여러 개의 활성 읽기 잠금 또는 단일 활성 쓰기 잠금이있을 수 있습니다.  데이터를 테이블로 읽으려면 먼저 연결에서 읽기 잠금을 얻어야합니다.  테이블에 쓰려면 연결에서 해당 테이블에 대한 쓰기 잠금을 얻어야합니다.  필요한 테이블 잠금을 얻을 수 없으면 쿼리가 실패하고 SQLITE_LOCKED가 호출자에게 반환됩니다.

 일단 연결이 테이블 잠금을 얻으면 현재 트랜잭션 (읽기 또는 쓰기)이 끝날 때까지 해제되지 않습니다.

 2.2.1.  읽기 커밋되지 않은 격리 모드

 위에서 설명한 동작은 read_uncommitted pragma를 사용하여 격리 수준을 serialize (기본값)에서 read-uncommitted로 변경하여 약간 수정할 수 있습니다.

 읽기 - 확약되지 않은 모드의 데이터베이스 연결은 위에서 설명한대로 데이터베이스 테이블에서 읽기 전에 읽기 잠금을 얻으려고 시도하지 않습니다.  이로 인해 다른 데이터베이스 연결이 읽는 동안 테이블을 수정하더라도 일관성없는 쿼리 결과가 발생할 수 있지만 읽기 연결되지 않은 모드에서 연결에 의해 열린 읽기 트랜잭션이 다른 연결에 의해 차단되거나 차단되지 않을 수도 있습니다.

 읽기 - 커밋되지 않은 모드는 데이터베이스 테이블에 쓰는 데 필요한 잠금에 영향을주지 않습니다 (즉, 읽기 - 커밋되지 않은 연결은 쓰기 잠금을 가져야하므로 데이터베이스 쓰기는 여전히 차단되거나 차단 될 수 있음).  또한 read-uncommitted 모드는 아래 열거 된 규칙 ( "스키마 (sqlite_master) 레벨 잠금"절 참조)에서 요구하는 sqlite_master 잠금에 영향을 미치지 않습니다.

   / * read-uncommitted 플래그의 값을 설정합니다 :
   **
   ** True -> 읽기 - 커밋되지 않은 모드로 연결을 설정합니다.
   ** 거짓 -> 연결을 직렬화 (기본값) 모드로 설정하십시오.
   * /
   PRAGMA read_uncommitted = <boolean>;

   / * read-uncommitted 플래그의 현재 값 검색 * /
   PRAGMA read_uncommitted;


 2.3.  스키마 (sqlite_master) 수준 잠금

 sqlite_master 테이블은 다른 모든 데이터베이스 테이블과 동일한 방식으로 공유 캐시 읽기 및 쓰기 잠금을 지원합니다 (위의 설명 참조).  다음 특별 규정이 적용됩니다.
•  연결은 데이터베이스 테이블에 액세스하거나 다른 읽기 또는 쓰기 잠금을 얻기 전에 sqlite_master 에서 읽기 잠금을 가져와야 합니다.
•  데이터베이스 스키마 (예 : CREATE 또는 DROP TABLE 문)를 수정하는 명령문을 실행하기 전에 sqlite_master 에서 쓰기 잠금을 가져와야 합니다.
•  다른 연결에서 연결된 데이터베이스 (기본 데이터베이스 "main"포함)의 sqlite_master 테이블에 쓰기 잠금이있는 경우 연결에서 SQL 문을 컴파일하지 못할 수 있습니다.

 3. 스레드 관련 문제

 SQLite 버전 3.3.0에서 3.4.2까지 공유 캐시 모드를 사용하는 경우 sqlite3_open () 을 호출 한 스레드에서만 데이터베이스 연결을 사용할 수 있습니다.  그리고 연결은 동일한 스레드의 다른 연결과 캐시를 공유 할 수있었습니다.  이러한 제한 사항은 SQLite 버전 3.5.0 (2007-09-04)부터 삭제되었습니다.

 4. 공유 캐시 및 가상 테이블

 이전 버전의 SQLite에서는 공유 캐시 모드를 가상 테이블과 함께 사용할 수 없었습니다.  이 제한 사항은 SQLite 버전 3.6.17 (2009-08-10)에서 제거되었습니다.

 5. 공유 캐시 모드 활성화

 공유 캐시 모드는 프로세스별로 사용할 수 있습니다.  C 인터페이스를 사용하여 다음 API를 사용하여 공유 캐시 모드를 전역 적으로 활성화 또는 비활성화 할 수 있습니다.

 int sqlite3_enable_shared_cache (int);


 sqlite3_enable_shared_cache ()를 호출 할 때마다 sqlite3_open () , sqlite3_open16 () 또는 sqlite3_open_v2 ()를 사용하여 생성 된 후속 데이터베이스 연결에 영향을줍니다.  이미 존재하는 데이터베이스 연결은 영향을받지 않습니다.  sqlite3_enable_shared_cache ()를 호출 할 때마다 동일한 프로세스 내의 모든 이전 호출이 무시됩니다.

 sqlite3_open_v2 ()를 사용하여 생성 된 개별 데이터베이스 연결은 세 번째 매개 변수 인 SQLITE_OPEN_SHAREDCACHE 또는 SQLITE_OPEN_PRIVATECACHE 플래그를 사용하여 공유 캐시 모드에 참여하거나 참여하지 않도록 선택할 수 있습니다.  이러한 플래그 중 하나를 사용하면 sqlite3_enable_shared_cache ()가 설정 한 전역 공유 캐시 모드 설정이 무시됩니다.  플래그 중 하나만 사용해야합니다.  sqlite3_open_v2 () 의 세 번째 인수에서 SQLITE_OPEN_SHAREDCACHE 및 SQLITE_OPEN_PRIVATECACHE 플래그가 모두 사용되는 경우 동작은 정의되지 않습니다.

 URI 파일 이름 이 사용되면 "cache"쿼리 매개 변수를 사용하여 데이터베이스에서 공유 캐시를 사용할지 여부를 지정할 수 있습니다.  공유 캐시를 사용하려면 "cache = shared"를 사용하고 공유 캐시를 사용하지 않으려면 "cache = private"을 사용하십시오.  URI 쿼리 매개 변수를 사용하여 데이터베이스 연결의 캐시 공유 동작을 지정하는 기능을 사용하면 ATTACH 문에서 캐시 공유를 제어 할 수 있습니다.  예 :

 ATTACH의 파일 : aux.db? cache = shared 'aux;


  6. 공유 캐시 및 메모리 데이터베이스

 SQLite 버전 3.7.13 (2012-06-06)부터 데이터베이스가 URI 파일 이름을 사용하여 생성 된 경우 메모리 내 데이터베이스에서 공유 캐시를 사용할 수 있습니다.  이전 버전과의 호환성을 위해 공유되지 않은 이름 ": memory :"가 데이터베이스를 여는 데 사용되는 경우 공유 메모리는 메모리 내 데이터베이스에서 항상 비활성화됩니다.  버전 3.7.13 이전에는 사용 된 데이터베이스 이름, 현재 시스템 공유 캐시 설정 또는 쿼리 매개 변수 또는 플래그와 상관없이 메모리 내 데이터베이스에 대한 공유 캐시가 항상 비활성화되었습니다.

 메모리 내 데이터베이스에 공유 캐시를 사용하면 같은 프로세스의 두 개 이상의 데이터베이스 연결이 동일한 메모리 내 데이터베이스에 액세스 할 수 있습니다.  공유 캐시에있는 메모리 내 데이터베이스는 자동으로 삭제되고 해당 데이터베이스에 대한 마지막 연결이 닫히면 메모리가 회수됩니다.

728x90
그리드형

'DB' 카테고리의 다른 글

(SQLite) insert 쿼리 수행 속도 높이기  (3) 2018.01.20
SQLite 참고 링크 모음  (1) 2017.11.23
[Oracle] 시간 타입 컬럼 시분초 형태로 결과보기 (nls_date)  (0) 2017.06.28
ORACLE vs DB2  (0) 2017.05.30
(SQLite) SQLite with GPU  (0) 2017.04.30
Posted by kjun
,