⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 app.so

📁 berkeley db 4.6.21的源码。berkeley db是一个简单的数据库管理系统
💻 SO
字号:
m4_comment([$Id: app.so,v 10.9 2005/12/01 03:18:51 bostic Exp $])m4_ref_title(m4_cam Applications,    Architecting Data Store and Concurrent Data Store applications,,    cam/fail, transapp/intro)m4_p([dnlWhen building Data Store and Concurrent Data Store applications, thearchitecture decisions involve application startup (cleaning up anyexisting databases, the removal of any existing database environmentand creation of a new environment), and handling system or applicationfailure.  "Cleaning up" databases involves removal and re-creationof the database, restoration from an archival copy and/or verificationand optional salvage, as described in m4_link(fail, [Handling failurein Data Store and Concurrent Data Store applications]).])m4_p([dnlData Store or Concurrent Data Store applications without databaseenvironments are single process, by definition.  These applicationsshould start up, re-create, restore, or verify and optionally salvagetheir databases and run until eventual exit or application or systemfailure.  After system or application failure, that process can simplyrepeat this procedure.  This document will not discuss the case of theseapplications further.])m4_p([dnlOtherwise, the first question of Data Store and Concurrent Data Storearchitecture is the cleaning up existing databases and the removal ofexisting database environments, and the subsequent creation of a newenvironment.  For obvious reasons, the application must serialize there-creation, restoration, or verification and optional salvage of itsdatabases.  Further, environment removal and creation must besingle-threaded, that is, one thread of control (where a thread ofcontrol is either a true thread or a process) must remove and re-createthe environment before any other thread of control can use the newenvironment.  It may simplify matters that m4_db serializes creation ofthe environment, so multiple threads of control attempting to create aenvironment will serialize behind a single creating thread.])m4_p([dnlRemoving a database environment will first mark the environment as"failed", causing any threads of control still running in theenvironment to fail and return to the application.  This feature allowsapplications to remove environments without concern for threads ofcontrol that might still be running in the removed environment.])m4_p([dnlOne consideration in removing a database environment which may be in useby another thread, is the type of mutex being used by the m4_db library.In the case of database environment failure when using test-and-setmutexes, threads of control waiting on a mutex when the environment ismarked "failed" will quickly notice the failure and will return an errorfrom the m4_db API.  In the case of environment failure when usingblocking mutexes, where the underlying system mutex implementation doesnot unblock mutex waiters after the thread of control holding the mutexdies, threads waiting on a mutex when an environment is recovered mighthang forever.  Applications blocked on events (for example, anapplication blocked on a network socket or a GUI event) may also failto notice environment recovery within a reasonable amount of time.Systems with such mutex implementations are rare, but do exist;applications on such systems should use an application architecturewhere the thread recovering the database environment can explicitlyterminate any process using the failed environment, or configure m4_dbfor test-and-set mutexes, or incorporate some form of long-running timeror watchdog process to wake or kill blocked processes should they blockfor too long.])m4_p([dnlRegardless, it makes little sense for multiple threads of control tosimultaneously attempt to remove and re-create a environment, since thelast one to run will remove all environments created by the threads ofcontrol that ran before it.  However, for some few applications, it maymake sense for applications to have a single thread of control thatchecks the existing databases and removes the environment, after whichthe application launches a number of processes, any of which are ableto create the environment.])m4_p([dnlWith respect to cleaning up existing databases, the database environmentmust be removed before the databases are cleaned up.  Removing theenvironment causes any m4_db library calls made by threads of controlrunning in the failed environment to return failure to the application.Removing the database environment first ensures the threads of controlin the old environment do not race with the threads of control cleaningup the databases, possibly overwriting them after the cleanup hasfinished.  Where the application architecture and system permit, manyapplications kill all threads of control running in the failed databaseenvironment before removing the failed database environment, on generalprinciples as well as to minimize overall system resource usage.  Itdoes not matter if the new environment is created before or after thedatabases are cleaned up.])m4_p([dnlAfter having dealt with database and database environment recovery afterfailure, the next issue to manage is application failure.  As describedin m4_link(fail, [Handling failure in Data Store and Concurrent DataStore applications]), when a thread of control in a Data Store orConcurrent Data Store application fails, it may exit holding datastructure mutexes or logical database locks.  These mutexes and locksmust be released to avoid the remaining threads of control hangingbehind the failed thread of control's mutexes or locks.])m4_p([dnlThere are three common ways to architect m4_db Data Store and ConcurrentData Store applications.  The one chosen is usually based on whether ornot the application is comprised of a single process or group ofprocesses descended from a single process (for example, a server startedwhen the system first boots), or if the application is comprised ofunrelated processes (for example, processes started by web connectionsor users logging into the system).])m4_nlistbeginm4_nlist([dnlThe first way to architect Data Store and Concurrent Data Storeapplications is as a single process (the process may or may not bemultithreaded.)m4_p([dnlWhen this process starts, it removes any existing database environmentand creates a new environment.  It then cleans up the databases andopens those databases in the environment.  The application cansubsequently create new threads of control as it chooses.  Those threadsof control can either share already open m4_db m4_ref(DbEnv) andm4_ref(Db) handles, or create their own.  In this architecture,databases are rarely opened or closed when more than a single thread ofcontrol is running; that is, they are opened when only a single threadis running, and closed after all threads but one have exited.  The lastthread of control to exit closes the databases and the databaseenvironment.])m4_p([dnlThis architecture is simplest to implement because thread serializationis easy and failure detection does not require monitoring multipleprocesses.])m4_p([dnlIf the application's thread model allows the process to continue afterthread failure, the m4_refT(dbenv_failchk) can be used to determine ifthe database environment is usable after the failure.  If theapplication does not call m4_ref(dbenv_failchk), orm4_ref(dbenv_failchk) returns m4_ref(DB_RUNRECOVERY), the applicationmust behave as if there has been a system failure, removing theenvironment and creating a new environment, and cleaning up anydatabases it wants to continue to use.  Once these actions have beentaken, other threads of control can continue (as long as all existingm4_db handles are first discarded), or restarted.])])m4_nlist([dnlThe second way to architect Data Store and Concurrent Data Storeapplications is as a group of related processes (the processes may ormay not be multithreaded).m4_p([dnlThis architecture requires the order in which threads of control arecreated be controlled to serialize database environment removal andcreation, and database cleanup.])m4_p([dnlIn addition, this architecture requires that threads of control bemonitored.  If any thread of control exits with open m4_db handles, theapplication may call the m4_refT(dbenv_failchk) to determine if thedatabase environment is usable after the exit.  If the application doesnot call m4_ref(dbenv_failchk), or m4_ref(dbenv_failchk) returnsm4_ref(DB_RUNRECOVERY), the application must behave as if there has beena system failure, removing the environment and creating a newenvironment, and cleaning up any databases it wants to continue to use.Once these actions have been taken, other threads of control cancontinue (as long as all existing m4_db handles are first discarded),or restarted.])m4_p([dnlThe easiest way to structure groups of related processes is to firstcreate a single "watcher" process (often a script) that starts when thesystem first boots, removes and creates the database environment, cleansup the databases and then creates the processes or threads that willactually perform work.  The initial thread has no furtherresponsibilities other than to wait on the threads of control it hasstarted, to ensure none of them unexpectedly exit.  If a thread ofcontrol exits, the watcher process optionally calls them4_refT(dbenv_failchk).  If the application does not callm4_ref(dbenv_failchk) or if m4_ref(dbenv_failchk) returnsm4_ref(DB_RUNRECOVERY), the environment can no longer be used, thewatcher kills all of the threads of control using the failedenvironment, cleans up, and starts new threads of control to performwork.])])m4_nlist([dnlThe third way to architect Data Store and Concurrent Data Storeapplications is as a group of unrelated processes (the processes may ormay not be multithreaded).  This is the most difficult architecture toimplement because of the level of difficulty in some systems of findingand monitoring unrelated processes.m4_p([dnlOne solution is to log a thread of control ID when a new m4_db handleis opened.  For example, an initial "watcher" process could open/createthe database environment, clean up the databases and then create asentinel file.  Any "worker" process wanting to use the environmentwould check for the sentinel file.  If the sentinel file does not exist,the worker would fail or wait for the sentinel file to be created.  Oncethe sentinel file exists, the worker would register its process ID withthe watcher (via shared memory, IPC or some other registry mechanism),and then the worker would open its m4_ref(DbEnv) handles and proceed.When the worker finishes using the environment, it would unregister itsprocess ID with the watcher.  The watcher periodically checks to ensurethat no worker has failed while using the environment.  If a workerfails while using the environment, the watcher removes the sentinelfile, kills all of the workers currently using the environment, cleansup the environment and databases, and finally creates a new sentinelfile.])m4_p([dnlThe weakness of this approach is that, on some systems, it is difficultto determine if an unrelated process is still running.  For example,POSIX systems generally disallow sending signals to unrelated processes.The trick to monitoring unrelated processes is to find a system resourceheld by the process that will be modified if the process dies.  On POSIXsystems, flock- or fcntl-style locking will work, as will LockFile onWindows systems.  Other systems may have to use other process-relatedinformation such as file reference counts or modification times.  In theworst case, threads of control can be required to periodicallyre-register with the watcher process: if the watcher has not heard froma thread of control in a specified period of time, the watcher will takeaction, cleaning up the environment.])m4_p([dnlIf it is not practical to monitor the processes sharing a databaseenvironment, it may be possible to monitor the environment to detect ifa thread of control has failed holding open m4_db handles.  This wouldbe done by having a "watcher" process periodically call them4_refT(dbenv_failchk).  If m4_ref(dbenv_failchk) returnsm4_ref(DB_RUNRECOVERY), the watcher would then take action, cleaning upthe environment.])m4_p([dnlThe weakness of this approach is that all threads of control using theenvironment must specify an "ID" function and an "is-alive" functionusing the m4_refT(dbenv_set_thread_id).  (In other words, the m4_dblibrary must be able to assign a unique ID to each thread of control,and additionally determine if the thread of control is still running.It can be difficult to portably provide that information in applicationsusing a variety of different programming languages and running on avariety of different platforms.)])]) m4_nlistendm4_p([dnlObviously, when implementing a process to monitor other threads ofcontrol, it is important the watcher process' code be as simple andwell-tested as possible, because the application may hang if it fails.])m4_page_footer

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -