1.2.子系统的介绍 1)数据存取子系统 数据存取子系统提供多种存取数据库文件的方法:1)B树、2)HASH文件、3)定长记录以及4)变长记录。 对于这四种不同的存取类型,BDB系统提供几乎一致的接口。比如,要打开一个数据库,都使用DB->open。 有些情况下,为更快的存取效率而不使用事务子系统,数据存取子系统可以单独使用,从而提供更快的存取速度(见图1.2)。 2)事务子系统 事务子系统允许将一系统的操作看作为一个原子操作,或者全部完成,或者全部取消。可以根据应用的具体情况,设置事务的隔离级别。 事务子系统可以单独使用,适用于需要符合事务特性的应用。 3)锁子系统 锁子系统为BDB提供锁机制,为系统提供读、写控制。可以允许多用户同时进行读操作,只允许单用户进行排它的修改操作。通过子系统,申请读、写权限,一旦申请成功,便可进行相关操作。事务子系统利用锁机制来实现多个事务的并发控制。 锁子系统可以被应用程序单独使用,为应用提供一个灵活的、快速的、可设置的锁管理。 4)内存池管理子系统 该子系统为多进程(或多线程)共享存取数据提供可能。需要页数据时,如果数据已经缓冲在内存池中,则直接使用,否则将新的页读到内存池*用户使用。在必要的时候,将修改的页数据进行刷盘操作。 该子系统可以被应用程序单独使用。内存池管理子系统为应用提供灵活的、面向页、数据缓冲管理。 5)日志子系统 该子系统采用先写日志先写数据的策略,用于支持事务子系统进行数据恢复,保证数据一致性。该子系统不能被应用程单独使用,只能做为事务子系统的调用模块。 二:BDB环境(Environment) 2.1.概述 BDB环境是对一个或多个数据库、日志文件以及区域文件的一个封装。区域文件可以理解为共享内存池,用来保存类似缓冲页的BDB环境信息。只有数据库文件是平*立的,可以在不同的byte-order机器上进行移动。日志文件可以在同byte-order的机器上进行移动。但是,区域文件对特定的机器是唯一的,不能与其它类型机器进行日志文件的移动,甚至对于不同版本的操作系统,虽然机器类型相同却也不能移动。 管理BDB环境最简单的方法就是创建一个home目录,在该目录中存储需要共享环境的文件。如果需要使用home目录(比如目录myhome),必须在应用程序运行之前创建好该目录(比如在工作目录下创建一个命令为myhome的文件夹),因为BDB本身不会为用户创建home目录。BDB环境通过目录名进行标识。 一个环境可以被多进程以及多线程共享。一个环境可以引用系统其它目录的资源,应用程序常常选择将资源分布到不同的目录或者磁盘,以此来提升程序性能。尽管如此,在默认情况下,数据库文件、共享区域(包括锁、日志缓冲区、内存池、事务共享内存区域)以及日志文件存储在一个同层次目录中(home目录中,可以包括其它的比如,比如在其中创建一个mydata目录用来存储用户的数据库文件)。 共享同一个环境的所有应用,它们彼此之间是互相信任的。它们能互相访问对方的数据,因为这些数据都是放在共享区域中的。它们共享类似于buffer以及锁之类的资源。与此同时,如果多个应用想要使用同一个数据库,并且需要它们之间保持一致性,则必须共享同一个环境。 2.2.创建BDB环境 BDB环境是通过db_env_create以及DB_ENV->open接口来创建和描述的。在需要定制的地方,比如将日志文件存储到一个单独的磁盘,或者选择一个特定的值做为cache的大小,应用通过环境配置文件或者将参数传递给DB_ENV处理函数来实现定制。 一旦一个环境被创建,被指定相关路径的数据库文件,都将相对环境的home目录来创建。用相对路径允许整个环境的轻易的移动。简化了在不同目录和不同系统中重建和恢复的步骤。 一旦应用程序首先通过db_env_create方法获得一个环境句柄,然后调用DB_ENV->open来创建或加入数据库环境。这里有很多选项你可以在调用DB_ENV->open时来定制你的环境。这些选项大致可以分为四类: 1)子系统初始化选项: 这些标志指明哪些bdb子系统将因为环境被初始化,和哪些操作将自动发生当数据库在环境中被访问的时候。这些标志包括DB_INIT_CDB,DB_INIT_LOCK,DB_INIT_LOG,DB_INIT_MPOOL,以及DB_INIT_TXN。DB_INIT_CDB标志为bdb并发数据存储做初始化工作。其它标志初始化单个子系统。比如,当DB_INIT_LOCK标志被指定,应用程序读写在这个环境中打开的数据库时,将使用locking子系统以确保它们不覆盖对方的对数据的改动。 2)恢复选项: 这些标志包括DB_RECOVER和DB_RECOVER_FATAL,它们表明在环境被打开且在正常使用之前,恢复将要进行。 3)命名选项: 这些标志包括DB_USE_ENVIRON和DB_USE_ENVIRON_ROOT,修改如何在环境给文件命名。 4)混杂选项: 除非前面的三类之外,还有一些混杂选项,比如,DB_CREATE选项使底数据库文件被创建时是必需的。 对于大多数应用,或者仅仅指定DB_INIT_MPOOL,或者指定所有的四个子系统的初始化标志(DB_INIT_MPOOL,DB_INIT_LOCK,DB_INIT_LOG以及DB_INIT_TXN)。 前者只是想简单用一些基本的访问方法以及一个共享缓冲池,没有考虑应用程序或系统出现故障时的可恢复性。后者是一些需要提供可恢复性的应用。在一些罕见的情况下,也有可能是其它的初始化标志的组合。 DB_RECOVER标志在当应用启动运行时做一些必需的数据库恢复的时候被指定。也就是说,在上一次运行过程中如果系统或应用程序出现故障,打算在再次运行前将数据恢复到一致性状态。不过,在没有任何数据需要恢复的情况下,指定这个标志也不为错。 DB_RECOVER_FATAL标志有更特殊的用途。它执行灾难性的数据库恢复,通常需要做一些初始化的安排;也就是说归档日志文件被带回到文件系统。应用程序通常不指定该标志。做为替代,在这种罕见的情况,应该使用db_recover函数。 下面是一个简单的为事务程序打开一个数据库环境的例子: DB_ENV * db_setup(home, data_dir, errfp, progname) char *home, *data_dir, *progname; FILE *errfp; { DB_ENV *dbenv; int ret; /* * Create an environment and initialize it for additional error * reporting. */ if ((ret = db_env_create(&dbenv, 0)) != 0) { fprintf(errfp, "%s: %s/n", progname, db_strerror(ret)); return (NULL); } dbenv->set_errfile(dbenv, errfp); dbenv->set_errpfx(dbenv, progname); /* * Specify the shared memory buffer pool cachesize: 5MB. * Databases are in a subdirectory of the environment home. */ if ((ret = dbenv->set_cachesize(dbenv, 0, 5 * 1024 * 1024, 0)) != 0) { dbenv->err(dbenv, ret, "set_cachesize"); goto err; } if ((ret = dbenv->set_data_dir(dbenv, data_dir)) != 0) { dbenv->err(dbenv, ret, "set_data_dir: %s", data_dir); goto err; } /* Open the environment with full transactional support. */ if ((ret = dbenv->open(dbenv, home, DB_CREATE | DB_INIT_LOG | DB_INIT_LOCK | DB_INIT_MPOOL | DB_INIT_TXN, 0)) != 0) { dbenv->err(dbenv, ret, "environment open: %s", home); goto err; } return (dbenv); err: (void)dbenv->close(dbenv, 0); return (NULL); }
深入理解mysql之BDB系列(1)---BDB相关基础知识(摘自老杨)
一:BDB体系结构
1.1.BDB体系结构
BDB整体的体系结构如图1.1所示,包含五个子系统(见图1.1中相关数)。1)数据存取子系统,2)事务子系统,3)锁子系统,4)内存池管理子系统,5)日志子系统。
在一个应用程序中,并不一定需要完全具备这5大子系统。
如果程序只使用了数据存取子系统,它的体系结构如图1.2。在图1.2中,我们只使了两个子系统:数据存取以及内存池子系统。(备注:另外三个子系统在BDB系统中隐式调用)