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.