Berkeley DB Reference Guide:
Berkeley DB Concurrent Data Store Applications

PrevRefNext

Berkeley DB Concurrent Data Store applications

It is often desirable to have concurrent read-write access to a database when there is no need for full recoverability or transaction semantics. For this class of applications, Berkeley DB provides interfaces supporting deadlock-free, multiple-reader/single writer access to the database. This means that at any instant in time, there may be either multiple readers accessing data or a single writer modifying data. The application is entirely unaware of which is happening, and Berkeley DB implements the necessary locking and blocking to ensure this behavior.

(트랜젝션과 복구에 대한 필요가 없을때 디비에 대한 동시적 읽기-쓰기를 원할것이다.이러한 요구를 가진 애플를 위해 버클리디비는 데드락-프리,멀티플 리더/싱글 라이터를 지원하는 인터페이스를 제공한다.이것이 의미하는 것은 어떠한 시간에 데이타를 접근하는 여러 리더와 단일 라이터가 존재한다는 것을 의미한다.애플리케이션은 어떤것이 발생했는지 전체적으로 인식하지 못하고 버클리디비는 이러한 행위를 지원하기 위해 필요한 락과 블럭킹을 지원한다.)

To create Berkeley DB Concurrent Data Store applications, you must first initialize an environment by calling DB_ENV->open. You must specify the DB_INIT_CDB and DB_INIT_MPOOL flags to that method. It is an error to specify any of the other DB_ENV->open subsystem or recovery configuration flags, for example, DB_INIT_LOCK, DB_INIT_TXN, or DB_RECOVER. All databases must, of course, be created in this environment by using the db_create function or Db constructor, and specifying the environment as an argument.

(Berkeley DB Concurrent Data Store applications을 생성하기 위해서 여러분은  DB_ENV->open(DB_INIT_CDB와 DB_INIT_MPOOL)로 환경을 초기화 해야 하고 이 함수를 호출할때 서브시스템이아 복구설정 플래그(예를들어: DB_INIT_LOCK, DB_INIT_TXN, or DB_RECOVER)를 설정하는것은 에러다.물론 이환경에서 모든 디비는 생성되어야 하고 db_create function or Db constructor 사용시 환경을 인자로 설정해야 한다.)

Berkeley DB performs appropriate locking so that safe enforcement of the deadlock-free, multiple-reader/single-writer semantic is transparent to the application. However, a basic understanding of Berkeley DB Concurrent Data Store locking behavior is helpful when writing Berkeley DB Concurrent Data Store applications.

(버클리 디비는 적절한 락을 실행하여 데드락-프리,멀티리더/싱글라이터에 대한 실행이 애플리케이션에 대해 투명성있게 한다.그러나 Berkeley DB Concurrent Data Store 락 행동에 대한 기본적인 이해는 Berkeley DB Concurrent Data Store 애플리케이션을 작성할때 도움을 준다.)

Berkeley DB Concurrent Data Store avoids deadlocks without the need for a deadlock detector by performing all locking on an entire database at once (or on an entire environment in the case of the DB_CDB_ALLDB flag), and by ensuring that at any given time only one thread of control is allowed to simultaneously hold a read (shared) lock and attempt to acquire a write (exclusive) lock.

(Berkeley DB Concurrent Data Store은 하나의 전체 디비 또는 전체환경( DB_CDB_ALLDB flag일경우)에 대해 모두 락을 실행함으로써 데드락 디텍터없이도 데드락을 피할수 있다.그리고 어떤순간에 오직 하나의 쓰레드만이 읽기락을 가지면서 동시에 배타적 쓰기락을 얻기위한 시도가 허용시킨다.)

All open Berkeley DB cursors hold a read lock, which serves as a guarantee that the database will not change beneath them; likewise, all non-cursor DB->get operations temporarily acquire and release a read lock that is held during the actual traversal of the database. Because read locks will not conflict with each other, any number of cursors in any number of threads of control may be open simultaneously, and any number of DB->get operations may be concurrently in progress.

(모든 열려있는 버클리디비 커서는 하나의 읽기락을 가지고 있고 디비의 변경되지 않음을 보증하게 된다.모든 커서를 사용하지 않는 DB->get 오퍼레이션은 디비순회를 할동안에 임시로 읽기락을 건후에 릴리즈한다. 읽기락이 서로 충돌하지 않기때문에 커서는 여러쓰레드에서 동시에 여러개가 열리수가 있고 여러개의 DB->get 오퍼레이션이 동시에 진행될수 있다.)

To enforce the rule that only one thread of control at a time can attempt to upgrade a read lock to a write lock, however, Berkeley DB must forbid multiple cursors from attempting to write concurrently. This is done using the DB_WRITECURSOR flag to the DB->cursor method. This is the only difference between access method calls in Berkeley DB Concurrent Data Store and in the other Berkeley DB products. The DB_WRITECURSOR flag causes the newly created cursor to be a "write" cursor; that is, a cursor capable of performing writes as well as reads. Only cursors thus created are permitted to perform write operations (either deletes or puts), and only one such cursor can exist at any given time.

(그러나 어떤순간에 오직 하나의 쓰레드가 읽기락을 쓰기락으로 업그레이드시키는 룰을 강제하기 위해 버클리 디비는 여러커서가 동시에 쓰기를 시도하는것을 금지해야 한다.이것은 DB->cursor(DB_WRITECURSOR flag )를 사용하여 강제화시킬수 있고 Berkeley DB Concurrent Data Store와 다른 버클리 디비 프러덕트의 액세스메소드 콜에서의 유일한 차이점이다. DB_WRITECURSOR flag는 새로 생성되는 커서가 쓰기커서가 되게 한다.즉 읽기뿐만 아니라 쓰기도 되는 커서가 생성된다.이와같이 생성된 커서들만이 쓰기 오퍼레이션either deletes or puts) 실행이 허용되고 어떤순간에 오직 하나의 커서만이 exit될수 있다.)

Any attempt to create a second write cursor or to perform a non-cursor write operation while a write cursor is open will block until that write cursor is closed. Read cursors may open and perform reads without blocking while a write cursor is extant. However, any attempts to actually perform a write, either using the write cursor or directly using the DB->put or DB->del methods, will block until all read cursors are closed. This is how the multiple-reader/single-writer semantic is enforced, and prevents reads from seeing an inconsistent database state that may be an intermediate stage of a write operation.

(쓰기커서가 열려있을때는 다른 쓰기커서의 생성또는 커서없이 쓰기 동작을 실행하는것은 쓰기커서가 닫힐때까지 블럭킹된다.쓰기커서가 있는중에도 읽기커서들은 열리수 있고 읽기를 실행할 수 있다.그러나 쓰기커서나 DB->put or DB->del 의 직접호출로 쓰기 실행을 시도하면 모든 읽기커서가 닫힐때까지 쓰기실행은 블럭킹된다.이것이 멀티리터/싱글라이터의 구동방식이고 쓰기동작에 의한 불일치 상태를 읽지 않도록 하게 한다.)

 

With these behaviors, Berkeley DB can guarantee deadlock-free concurrent database access, so that multiple threads of control are free to perform reads and writes without needing to handle synchronization themselves or having to run a deadlock detector. Because Berkeley DB has no knowledge of which cursors belong to which threads, however, some care must be taken to ensure that applications do not inadvertently block themselves, causing the application to hang and be unable to proceed. Some common mistakes include the following:

(이러한 행위들로 버클리디비는 데드락-프리 디비 동시접근을 보증하여 멀티쓰레드가 동기화나 데드락탐지기 실행없이도 읽기,쓰기를 실행할 수 있게 한다.그러나 버클리디비는 어떤 커서가 어떤쓰레드에 소속되는지를 알수 없기때문에 쓰레드가 우연히 서로 블럭시키지 않도록 주의를 기울여야 한다.이런 애플리케이션의 hang을 발생시키는 일반적인 실수는 다음과 같다.)

 

  1. Keeping a cursor open while issuing a DB->put or DB->del access method call.

    (DB->put or DB->del 메소드를 호출시 어떤 커서가 열려있다.(역자주:읽기락이 걸려있어 블럭킹된다.))

  2. Attempting to open a write cursor while a write cursor is already being held open by the same thread of control. Note that it is correct operation for one thread of control to attempt to open a write cursor or to perform a non-cursor write (DB->put or DB->del) while a write cursor is already active in another thread. It is only a problem if these things are done within a single thread of control -- in which case that thread will block and never be able to release the lock that is blocking it.

    (어떤 쓰기커서를 오픈한 쓰레드에서 또다시 쓰기락 오픈을 시도할때... note: 다른쓰레드에서 쓰기 커서가 이미 활동중일때 어떤 또다른 쓰레드에서 쓰기커서를 열기를 시도하고 커서없는 쓰기(DB->put or DB->del )를 시도하는것은 올바른 동작이다.)

  3. Keeping a write cursor open for an extended period of time.

    (장기간에 걸쳐 쓰기락이 오픈된상태로 있을때)

  4. Not testing Berkeley DB error return codes (if any cursor operation returns an unexpected error, that cursor must still be closed).

    (만약 어떤커서 오퍼레이션이 에러를 리턴하면 이 커서는 닫아져야 한다.그런데 애플에서 버클리디비의 리턴코드를 테스트하지 않을때..)

     

  5. By default, Berkeley DB Concurrent Data Store does locking on a per-database basis. For this reason, accessing multiple databases in different orders in different threads or processes, or leaving cursors open on one database while accessing another database, can cause an application to hang. If this behavior is a requirement for the application, Berkeley DB should be configured to do locking on an environment-wide basis. See the DB_CDB_ALLDB flag of the DB_ENV->set_flags function for more information.

     (디폴트로.. Berkeley DB Concurrent Data Store 는 디비단위로 락을 건다.이같은 이유로 여러다른 쓰레드나 프로세스가 다른 순서로 여러 디비를 액세스하거나 다른 디비를 액세스하면서 어떤 디비에 대한 커서를 열린상태로 두는것은 애플리케이션이 hang될 수 있다.만약 이 행위가 애플리케이션에서 필요하면 버클리디비는 환경 단위로 락킹되도록 설정되어야 한다.(DB_CDB_ALLDB flag of the DB_ENV->set_flags 참조))


PrevRefNext

Copyright (c) 1996-2003 Sleepycat Software, Inc. - All rights reserved.