<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Oracle Berkeley DB 中国研发团队的博客 &#187; example</title>
	<atom:link href="http://www.bdbchina.com/tag/example/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.bdbchina.com</link>
	<description>Oracle Berkeley DB 中国研发团队的博客</description>
	<lastBuildDate>Fri, 09 Jul 2010 06:44:36 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.2</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>在UNIX/Linux平台上应用Berkeley DB 11gR2 SQL</title>
		<link>http://www.bdbchina.com/2010/04/%e5%9c%a8unixlinux%e5%b9%b3%e5%8f%b0%e4%b8%8a%e5%ba%94%e7%94%a8berkeley-db-11gr2-sql/</link>
		<comments>http://www.bdbchina.com/2010/04/%e5%9c%a8unixlinux%e5%b9%b3%e5%8f%b0%e4%b8%8a%e5%ba%94%e7%94%a8berkeley-db-11gr2-sql/#comments</comments>
		<pubDate>Fri, 09 Apr 2010 06:35:08 +0000</pubDate>
		<dc:creator>赵汝聪</dc:creator>
				<category><![CDATA[Berkeley DB]]></category>
		<category><![CDATA[SQL]]></category>
		<category><![CDATA[赵汝聪]]></category>
		<category><![CDATA[DB]]></category>
		<category><![CDATA[example]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[UNIX]]></category>

		<guid isPermaLink="false">http://www.bdbchina.com/?p=1121</guid>
		<description><![CDATA[最新发布的Berkeley DB 11gR2是第一个支持SQL的版本，编译过程与以往版本稍有不同。本文将介绍如何在Linux/UNIX下编译 Berkeley DB SQL 5.0.21(以下简称DBSQL)，并运行DBSQL范例。

下载安装包
从官方网站下载db-5.0.21.tar.gz并解压缩获得db-5.0.21目录。
配置

cd db-5.0.21/build_unix
../dist/configure --enable-sql --enable-sql_compact

选项说明：

--enable-sql_compact：

使dbsql库(libdb_sql-5.0.so)包含db库(libdb-5.0.so)，这样libdb_sql-5.0.so就不依赖于db库，其中dbsql提供了SQL API，db库包含原有的BDB功能，这样应用程序不需要链接两个库，方便使用。编译得到的库与sqlite 3.6.22版本对应。方便使用。编译得到的库与sqlite 3.6.22版本对应。


其它常用配置选项：

只编译静态库：

加上"--disable-shared"。

编译最小库：

加上"--enable-smallbuild --enable-statistics"。
这里的--enable-statistics是必须搭配--enable-smallbuild使用的。因为默认的smallbuild不包含dbsql所需要的statistics组件。
常规编译获得的DBSQL动态库大小为2.2M，而最小方式编译得到的库大小为1.1M。话说回来，对于UNIX/Linux大多数应用来说，多个1M大小不是问题，而且smallbuild会采用Os编译器优化选项(尺寸优先)取代O3选项(速度优先)，性能会有所下降。


编译

make dbsql

对于动态编译方式，实际库文件在build_unix/.libs目录下，文件：

.libs/libdb_sql-5.0.so (动态库文件)
.libs/dbsql (交互式命令行工具)

而对于静态编译方式，库文件在build_unix/目录下，文件：

libdb_sql-5.0.a (静态库文件)
dbsql (交互式命令行工具)

如果你需要使用各种BDB工具(如db_dump, db_load等)，进一步执行编译指令make，你将能够得到BDB所提供的所有的库文件和工具，包括之前make dbsql得到的库，以及除了上述db_dump, db_load之外的其他所有BDB提供的工具，熟悉BDB的用户一定对此不陌生。
最后，如果你需要清除包括Makefile在内的所有编译文件，可执行make distclean。Makefile是由configure生成的，单纯的&#8221;make clean&#8221;不能清除这部分记录。
编译并运行范例
DBSQL的C API完全沿用SQLite的C API，这里是SQLite3 C API列表。sql/examples/目录下有多个参考范例。以下我们以C语言范例sql/examples/c/ex_sql_index.c为例：

make ex_sql_index
./ex_sql_index

程序做了以下几件事情：

1. 把表格university加载到数据库
2. 打印以下SQL语句的Query Plan。我们可以看到Query Plan中的VDBE指令有32条。并且有两条向前跳转的Next指令，表示出现了两次循环迭代。

        SELECT rank, country, name
        from university
   [...]]]></description>
			<content:encoded><![CDATA[<p>最新发布的Berkeley DB 11gR2是第一个支持SQL的版本，编译过程与以往版本稍有不同。本文将介绍如何在Linux/UNIX下编译 Berkeley DB SQL 5.0.21(以下简称DBSQL)，并运行DBSQL范例。<br />
<span id="more-1121"></span></p>
<h2>下载安装包</h2>
<p>从<a href="http://www.oracle.com/technology/software/products/berkeley-db/index.html">官方网站</a>下载db-5.0.21.tar.gz并解压缩获得db-5.0.21目录。</p>
<h2>配置</h2>
<pre name="code" class="java:nogutter">
cd db-5.0.21/build_unix
../dist/configure --enable-sql --enable-sql_compact
</pre>
<p><strong>选项说明：</strong></p>
<ul>
<li><tt>--enable-sql_compact：</tt>
<ul>
<li><tt>使dbsql库(libdb_sql-5.0.so)包含db库(libdb-5.0.so)，这样libdb_sql-5.0.so就不依赖于db库，其中dbsql提供了SQL API，db库包含原有的BDB功能，这样应用程序不需要链接两个库，方便使用。编译得到的库与sqlite 3.6.22版本对应。方便使用。编译得到的库与sqlite 3.6.22版本对应。</tt></li>
</ul>
</ul>
<p><strong>其它常用配置选项：</strong></p>
<ul>
<li><tt>只编译静态库：</tt>
<ul>
<li><tt>加上"--disable-shared"。</tt></li>
</ul>
<li><tt>编译最小库：</tt>
<ul>
<li><tt>加上"--enable-smallbuild --enable-statistics"。</tt></li>
<li><tt>这里的--enable-statistics是必须搭配--enable-smallbuild使用的。因为默认的smallbuild不包含dbsql所需要的statistics组件。</tt></li>
<li><tt>常规编译获得的DBSQL动态库大小为2.2M，而最小方式编译得到的库大小为1.1M。话说回来，对于UNIX/Linux大多数应用来说，多个1M大小不是问题，而且smallbuild会采用Os编译器优化选项(尺寸优先)取代O3选项(速度优先)，性能会有所下降。</tt></li>
</ul>
</ul>
<h2>编译</h2>
<pre name="code" class="java:nogutter">
make dbsql
</pre>
<p>对于动态编译方式，实际库文件在build_unix/.libs目录下，文件：</p>
<pre name="code" class="java:nogutter">
.libs/libdb_sql-5.0.so (动态库文件)
.libs/dbsql (交互式命令行工具)
</pre>
<p>而对于静态编译方式，库文件在build_unix/目录下，文件：</p>
<pre name="code" class="java:nogutter">
libdb_sql-5.0.a (静态库文件)
dbsql (交互式命令行工具)
</pre>
<p>如果你需要使用各种BDB工具(如db_dump, db_load等)，进一步执行编译指令make，你将能够得到BDB所提供的所有的库文件和工具，包括之前make dbsql得到的库，以及除了上述db_dump, db_load之外的其他所有BDB提供的工具，熟悉BDB的用户一定对此不陌生。</p>
<p>最后，如果你需要清除包括Makefile在内的所有编译文件，可执行make distclean。Makefile是由configure生成的，单纯的&#8221;make clean&#8221;不能清除这部分记录。</p>
<h2>编译并运行范例</h2>
<p>DBSQL的C API完全沿用SQLite的C API，<a href='http://www.sqlite.org/c3ref/funclist.html'>这里</a>是SQLite3 C API列表。sql/examples/目录下有多个参考范例。以下我们以C语言范例sql/examples/c/ex_sql_index.c为例：</p>
<pre name="code" class="java:nogutter">
make ex_sql_index
./ex_sql_index
</pre>
<p>程序做了以下几件事情：</p>
<ul>
<li>1. 把表格university加载到数据库</li>
<li>2. 打印以下SQL语句的Query Plan。我们可以看到Query Plan中的VDBE指令有32条。并且有两条向前跳转的Next指令，表示出现了两次循环迭代。
<pre name="code" class="java:nogutter">
        SELECT rank, country, name
        from university
        WHERE region = 'Europe'
        ORDER BY country;
</pre>
</li>
<li>3. 增加关于region, country的索引
<li>4. 再次打印Query Plan。我们可以看到Query Plan中的VDBE指令简化到了21条。并且只有一次向前跳转的Next指令，表示只(在索引上)出现了一次循环迭代。</li>
<li>5. 删除关于region, country的索引</li>
</ul>
<p>以下是程序输出：</p>
<pre name="code" class="java:nogutter">
================================================================================
Load data source ../sql/examples/data/university.csv into database.
Load done.
================================================================================
STEP1. Explain a query expression
SQL:    EXPLAIN
        SELECT rank, country, name
        from university
        WHERE region = 'Europe'
        ORDER BY country;
  0     Trace   0       0       0               00      (null)
  1     OpenEphemeral   1       3       0       keyinfo(1,BINARY)       00      (null)
  2     String8 0       1       0       Europe  00      (null)
  3     Goto    0       29      0               00      (null)
  4     OpenRead        0       3       0       5       00      (null)
  5     Rewind  0       18      0               00      (null)
  6     Column  0       4       2               00      (null)
  7     Ne      1       17      2       collseq(BINARY) 69      (null)
  8     Column  0       0       4               00      (null)
  9     Column  0       3       5               00      (null)
  10    Column  0       1       6               00      (null)
  11    MakeRecord      4       3       2               00      (null)
  12    Column  0       3       7               00      (null)
  13    Sequence        1       8       0               00      (null)
  14    Move    2       9       1               00      (null)
  15    MakeRecord      7       3       3               00      (null)
  16    IdxInsert       1       3       0               00      (null)
  17    Next    0       6       0               01      (null)
  18    Close   0       0       0               00      (null)
  19    OpenPseudo      2       2       3               00      (null)
  20    Sort    1       27      0               00      (null)
  21    Column  1       2       2               00      (null)
  22    Column  2       0       4               20      (null)
  23    Column  2       1       5               00      (null)
  24    Column  2       2       6               00      (null)
  25    ResultRow       4       3       0               00      (null)
  26    Next    1       21      0               00      (null)
  27    Close   2       0       0               00      (null)
  28    Halt    0       0       0               00      (null)
  29    Transaction     0       0       0               00      (null)
  30    VerifyCookie    0       5       0               00      (null)
  31    TableLock       0       3       0       university      00      (null)
  32    Goto    0       4       0               00      (null)
================================================================================
STEP2. Create an index on university(region, country)
SQL:    CREATE INDEX university_geo
        ON university (region, country);
================================================================================
STEP3. Explain the query again, we can see the difference
SQL:    EXPLAIN
        SELECT rank, country, name
        from university
        WHERE region = 'Europe'
        ORDER BY country;
  0     Trace   0       0       0               00      (null)
  1     Noop    0       0       0               00      (null)
  2     String8 0       1       0       Europe  00      (null)
  3     Goto    0       18      0               00      (null)
  4     OpenRead        0       3       0       5       00      (null)
  5     OpenRead        2       4       0       keyinfo(2,BINARY,BINARY)        00      (null)
  6     SeekGe  2       15      1       1       00      (null)
  7     IdxGE   2       15      1       1       01      (null)
  8     IdxRowid        2       2       0               00      (null)
  9     Seek    0       2       0               00      (null)
  10    Column  0       0       3               00      (null)
  11    Column  2       1       4               00      (null)
  12    Column  0       1       5               00      (null)
  13    ResultRow       3       3       0               00      (null)
  14    Next    2       7       0               00      (null)
  15    Close   0       0       0               00      (null)
  16    Close   2       0       0               00      (null)
  17    Halt    0       0       0               00      (null)
  18    Transaction     0       0       0               00      (null)
  19    VerifyCookie    0       6       0               00      (null)
  20    TableLock       0       3       0       university      00      (null)
  21    Goto    0       4       0               00      (null)
================================================================================
STEP4. Drop the index
SQL: DROP INDEX university_geo;
DONE.
</pre>
<h2>使用dbsql shell</h2>
<p>范例运行完后，我们还可以用dbsql shell来查看/操作生成的数据库文件：</p>
<pre name="code" class="java:nogutter">
build_unix$ ./dbsql ex_sql_index.db
Berkeley DB 11g Release 2, library version 11.2.5.0.21: (March 30, 2010)
Enter ".help" for instructions
Enter SQL statements terminated with a ";"
dbsql> .tables
university
dbsql> select * from university;
1|Massachusetts Institute of Technology|mit.edu|us|North America|2|1|1|7
2|Harvard University|harvard.edu|us|North America|7|2|12|1
3|Stanford University|stanford.edu|us|North America|4|4|2|24
4|University of California Berkeley|berkeley.edu|us|North America|8|3|5|32
5|Cornell University|cornell.edu|us|North America|1|5|9|37
6|University of Wisconsin Madison|wisc.edu|us|North America|3|10|6|71
7|University of Minnesota|umn.edu|us|North America|6|15|7|22
8|California Institute of Technology|caltech.edu|us|North America|18|6|20|30
9|University of Illinois Urbana Champaign|uiuc.edu|us|North America|17|7|13|51
10|University of Michigan|umich.edu|us|North America|10|8|18|55
11|University of Texas Austin|utexas.edu|us|North America|12|11|8|44
12|University of Washington|washington.edu|us|North America|22|9|4|94
13|University of Chicago|uchicago.edu|us|North America|42|16|44|2
14|Carnegie Mellon University|cmu.edu|us|North America|5|24|3|93
15|University of Pennsylvania|upenn.edu|us|North America|16|14|33|26
16|Columbia University New York|columbia.edu|us|North America|19|12|21|95
17|Texas A&#038;M University|tamu.edu|us|North America|31|31|11|17
18|University of Maryland|umd.edu|us|North America|37|22|17|52
19|University of California Los Angeles|ucla.edu|us|North America|13|17|26|110
20|Purdue University|purdue.edu|us|North America|14|34|14|46
21|Johns Hopkins University|jhu.edu|us|North America|59|27|49|3
22|University of Cambridge|cam.ac.uk|uk|Europe|26|13|70|86
23|Pennsylvania State University|psu.edu|us|North America|27|29|16|102
24|University of Tokyo|u-tokyo.ac.jp|jp|Asia|32|26|65|31
25|University of Arizona|arizona.edu|us|North America|20|36|19|134
dbsql> .quit
</pre>
<h2>结束语</h2>
<p>以上我们介绍了如何在UNIX/Linux环境下编译DBSQL并运行范例。在这一版本开发中，我们为新增SQL部分增加了十个范例，可作为快速参考:</p>
<pre name="code" class="java:nogutter">
1.ex_sql_load:          create table, insert, load csv files
2.ex_sql_query:         select, order by, group by, subquery, SQL function
3.ex_sql_index:         index, query explain
4.ex_sql_statment:      prepare, iterate results, callback function
5.ex_sql_transaction:   transaction, commit, rollback
6.ex_sql_savepoint:     savepoint
7.ex_sql_multi_thread:  multi-thread, transaction, lock/busy handle
8.ex_sql_binding:       prepare, variable binding, transaction, bulk insert
9.ex_sql_fts3:          full-text search features
10.ex_sql_rtree:        create, maintain, and query r-tree index
</pre>
<p>如果您有什么问题和建议，欢迎与我联系。</p>
]]></content:encoded>
			<wfw:commentRss>http://www.bdbchina.com/2010/04/%e5%9c%a8unixlinux%e5%b9%b3%e5%8f%b0%e4%b8%8a%e5%ba%94%e7%94%a8berkeley-db-11gr2-sql/feed/</wfw:commentRss>
		<slash:comments>17</slash:comments>
		</item>
		<item>
		<title>在Windows平台运行JE-HA示例</title>
		<link>http://www.bdbchina.com/2010/03/%e5%9c%a8windows%e5%b9%b3%e5%8f%b0%e8%bf%90%e8%a1%8cje-ha%e7%a4%ba%e4%be%8b/</link>
		<comments>http://www.bdbchina.com/2010/03/%e5%9c%a8windows%e5%b9%b3%e5%8f%b0%e8%bf%90%e8%a1%8cje-ha%e7%a4%ba%e4%be%8b/#comments</comments>
		<pubDate>Wed, 17 Mar 2010 08:40:54 +0000</pubDate>
		<dc:creator>taozhang</dc:creator>
				<category><![CDATA[Berkeley DB JE]]></category>
		<category><![CDATA[Tao Zhang]]></category>
		<category><![CDATA[example]]></category>
		<category><![CDATA[HA]]></category>

		<guid isPermaLink="false">http://www.bdbchina.com/?p=867</guid>
		<description><![CDATA[JE-HA是JE 4.0推出的一项新特性，本文介绍了JE-HA示例的基本功能和原理，并演示了如何在Windows平台上运行JE-HA的示例代码。]]></description>
			<content:encoded><![CDATA[<p>Oracle Berkeley DB Java Edition (简称JE)从4.0开始推出了高可用(又称集群、HA)功能，从而让用户能够更容易的编写高可靠的、7×24在线的应用程序。随版本一起还发布了很多HA的示例代码。本文的主要目的是示范如何在windows平台上运行这些示例，从而帮助用户更好的理解和使用HA。</p>
<h3>1.下载JE</h3>
<p>用户可以到官方网址<a href="http://www.oracle.com/technology/software/products/berkeley-db/je/index.html">http://www.oracle.com/technology/software/products/berkeley-db/je/index.html</a>下载最新的JE版本，本文使用的是JE 4.0.71. 同时，您也可以到<a href="http://www.oracle.com/technology/documentation/berkeley-db/je/examples/je/rep/quote/package-summary.html">http://www.oracle.com/technology/documentation/berkeley-db/je/examples/je/rep/quote/package-summary.html</a>参考示例的详细英文文档。</p>
<h3>2.编译示例</h3>
<p>请确认您在编译示例之前已经安装好JDK，如果您的机器上没有安装，请到<a href="http://java.sun.com">http://java.sun.com</a>下载JDK。</p>
<p>用户下载示例后，解压缩到当前目录，你会发现一个je-4.0.71的目录，进入该目录，您会在lib目录下发现JE的jar包，HA的示例代码存放在examples/je/rep/quote目录下。将lib下的je-4.0.71.jar拷贝到examples/je/rep/quote下，打开命令行，进入到当前目录，输入如下命令：javac -cp .;je-4.0.71.jar *.java，该目录下的所有java文件都会被编译成class文件。</p>
<h3>3.示例代码概述</h3>
<p>JE-HA的示例代码分为三种：</p>
<ul>
<li>StockQuotes：该示例代码是一个最基本的使用JE-HA应用程序的展示，其主要目的是让您对JE-HA的基本概念有一个了解，并演示了如何使用JE-HA的API创建一个ReplicatedEnvironment和处理读写事务。</li>
<li>RouterDrivenStockQuotes和HARouter：RouterDriverStockQuotes以StockQuotes为基础，展示了如何使用JE Monitor（HARouter）根据应用程序请求的类别（读或写）和结点的状态（Master或Replica），指引请求到正确的结点。该示例的目的是演示如何将负载平衡器与JE-HA结合起来，在该示例中，HARouter扮演负载平衡器的角色。</li>
<li>UpdateForwardingStockQuote和SimpleRouter：UpdateForwardingStockQuote以RouterDrivenStockQuotes为基础，与HARouter不同，SimpleRouter并不关心应用程序的请求类别和结点的状态，只是简单的将请求转发给它所知道的结点，而UpdateForwardingStockQuote使用了StateChangeListener来跟踪当前的Master结点，并将写请求转发给Master，自己处理读请求。这个示例的目的是演示如何将一个负载平衡器嵌入到JE-HA的框架中。</li>
</ul>
<p>本文主要演示如何运行前两个示例，第三个示例的运行方法与第二个基本类似，在这里就不做详细介绍了。<span id="more-867"></span></p>
<h3>4.创建运行环境</h3>
<p>为了演示的方便（截图的原因），我在同一台机器上运行三个HA结点。在开始运行示例代码之前，需要创建每个结点的environment home目录。这里，我在examples目录下创建三个目录，分别为：rep1，rep2，rep3。</p>
<p>因为JE-HA示例代码的包是je.rep.quote，所以命令行需要在examples目录下运行。</p>
<h3>5.运行StockQuotes示例</h3>
<p>(1).启动三个结点，如下图所示：</p>
<p><a href="http://www.bdbchina.com/wp-content/uploads/2010/03/StockQuotes-startup.jpg"><img class="aligncenter size-large wp-image-868" title="StockQuotes-startup" src="http://www.bdbchina.com/wp-content/uploads/2010/03/StockQuotes-startup-1024x483.jpg" alt="" width="1024" height="483" /></a></p>
<p>(2).在Master上写数据，在Replica上读取数据，如下图所示：</p>
<p><a href="http://www.bdbchina.com/wp-content/uploads/2010/03/StockQuotes-writemaster-read-replica.jpg"><img class="aligncenter size-large wp-image-870" title="StockQuotes-writemaster-read-replica" src="http://www.bdbchina.com/wp-content/uploads/2010/03/StockQuotes-writemaster-read-replica-1024x482.jpg" alt="" width="1024" height="482" /></a></p>
<p>（3). 如果在Replica上写数据。由于JE-HA只允许在Master上写数据，因此该操作是非法的，控制台会打印出提示信息，如下图红框内所示：</p>
<p><a href="http://www.bdbchina.com/wp-content/uploads/2010/03/StockQuotes-writereplica.jpg"><img class="aligncenter size-large wp-image-871" title="StockQuotes-writereplica" src="http://www.bdbchina.com/wp-content/uploads/2010/03/StockQuotes-writereplica-1024x484.jpg" alt="" width="1024" height="484" /></a></p>
<p>(4).将Master关闭，JE-HA会在当前集群中重新选举出一个新的Master，只有现存的Replica的数目符合选举策略，如下图红框内所示，node3被选举成为新的Master：</p>
<p><a href="http://www.bdbchina.com/wp-content/uploads/2010/03/StockQuotes-changemaster.jpg"><img class="aligncenter size-large wp-image-872" title="StockQuotes-changemaster" src="http://www.bdbchina.com/wp-content/uploads/2010/03/StockQuotes-changemaster-1024x483.jpg" alt="" width="1024" height="483" /></a></p>
<p>(5).将剩下的Replica也关掉，只剩下Master，这种情况下，应用程序还可以在Master上读取数据，但是已经不能写数据了。这是因为示例的默认事务提交策略是要得到超过半数的Replica的回应的，但是当前没有任何活跃的Replica，所以提交会失败并打印出异常信息。如下两图所示：</p>
<p><a href="http://www.bdbchina.com/wp-content/uploads/2010/03/StockQuotes-printmaster-replicadown.jpg"><img class="aligncenter size-large wp-image-873" title="StockQuotes-printmaster-replicadown" src="http://www.bdbchina.com/wp-content/uploads/2010/03/StockQuotes-printmaster-replicadown-1024x483.jpg" alt="" width="1024" height="483" /></a></p>
<p><a href="http://www.bdbchina.com/wp-content/uploads/2010/03/StockQuotes-writemaster-insufficentreplica1.jpg"><img class="aligncenter size-large wp-image-874" title="StockQuotes-writemaster-insufficentreplica" src="http://www.bdbchina.com/wp-content/uploads/2010/03/StockQuotes-writemaster-insufficentreplica1-1024x483.jpg" alt="" width="1024" height="483" /></a></p>
<h3>6.运行RouterDrivenStockQuotes和HARouter示例</h3>
<p>运行RouterDrivenStockQuotes和HARouter示例与运行StockQuotes示例基本类似，唯一的不同是需要在启动三个RouterDrivenStockQuotes之外再启动一个HARouter。</p>
<p>(1).启动整个HA组，如下图所示：</p>
<p><a href="http://www.bdbchina.com/wp-content/uploads/2010/03/RouterDriven-startup.jpg"><img class="aligncenter size-large wp-image-879" title="RouterDriven-startup" src="http://www.bdbchina.com/wp-content/uploads/2010/03/RouterDriven-startup-1024x585.jpg" alt="" width="1024" height="585" /></a></p>
<p>(2).HARouter指引写请求到Master，如下图所示：</p>
<p><a href="http://www.bdbchina.com/wp-content/uploads/2010/03/RouterDriven-write.jpg"><img class="aligncenter size-large wp-image-880" title="RouterDriven-write" src="http://www.bdbchina.com/wp-content/uploads/2010/03/RouterDriven-write-1024x584.jpg" alt="" width="1024" height="584" /></a></p>
<p>(3).HARouter将读请求指引到目前空闲的结点，如下图所示：</p>
<p><a href="http://www.bdbchina.com/wp-content/uploads/2010/03/RouterDriven-print.jpg"><img class="aligncenter size-large wp-image-877" title="RouterDriven-print" src="http://www.bdbchina.com/wp-content/uploads/2010/03/RouterDriven-print-1024x584.jpg" alt="" width="1024" height="584" /></a></p>
<p>(4).关闭当前的Master，HARouter会自动找到新选出来的Master，如下图所示：</p>
<p><a href="http://www.bdbchina.com/wp-content/uploads/2010/03/RouterDriven-shutdown-master.jpg"><img class="aligncenter size-large wp-image-878" title="RouterDriven-shutdown-master" src="http://www.bdbchina.com/wp-content/uploads/2010/03/RouterDriven-shutdown-master-1024x582.jpg" alt="" width="1024" height="582" /></a></p>
<p>(5).当所有Replica都关闭，只剩下Master还活跃的时候，HARouter会提示写请求是非法的（原因在StockQuotes演示第六步已经介绍了），如下图所示：</p>
<p><a href="http://www.bdbchina.com/wp-content/uploads/2010/03/RouterDriven-insufficentreplicas-write.jpg"><img class="aligncenter size-large wp-image-875" title="RouterDriven-insufficentreplicas-write" src="http://www.bdbchina.com/wp-content/uploads/2010/03/RouterDriven-insufficentreplicas-write-1024x583.jpg" alt="" width="1024" height="583" /></a></p>
<h3>7.总结</h3>
<p>JE-HA是对JE功能的一个巨大提升。希望本文能够让你更好的了解并使用JE-HA。如果您对本文有什么意见或对JE-HA有什么建议，请您站内留言。</p>
]]></content:encoded>
			<wfw:commentRss>http://www.bdbchina.com/2010/03/%e5%9c%a8windows%e5%b9%b3%e5%8f%b0%e8%bf%90%e8%a1%8cje-ha%e7%a4%ba%e4%be%8b/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Berkeley DB示例程序详解 (1)</title>
		<link>http://www.bdbchina.com/2009/02/berkeley-db%e7%a4%ba%e4%be%8b%e7%a8%8b%e5%ba%8f%e8%af%a6%e8%a7%a3-1/</link>
		<comments>http://www.bdbchina.com/2009/02/berkeley-db%e7%a4%ba%e4%be%8b%e7%a8%8b%e5%ba%8f%e8%af%a6%e8%a7%a3-1/#comments</comments>
		<pubDate>Thu, 26 Feb 2009 06:52:10 +0000</pubDate>
		<dc:creator>davidzhao</dc:creator>
				<category><![CDATA[Berkeley DB]]></category>
		<category><![CDATA[David Zhao]]></category>
		<category><![CDATA[程序设计]]></category>
		<category><![CDATA[bdb]]></category>
		<category><![CDATA[example]]></category>

		<guid isPermaLink="false">http://www.bdbchina.com/?p=112</guid>
		<description><![CDATA[本文通过分析Berkeley DB自带的示例程序来详细阐述了使用Berkeley Db基本功能的方法。这之后还将有更多这类文章，我认为通过学习好的例子和已有代码来学习使用berkeley db是很有效的。 ]]></description>
			<content:encoded><![CDATA[<p>本文通过分析Berkeley DB自带的示例程序来详细阐述了使用Berkeley Db基本功能的方法。这之后还将有更多这类文章，我认为通过学习好的例子和已有代码来学习使用berkeley db是很有效的。</p>
<p><span id="more-112"></span></p>
<p>/*<br />
* 这个例子程序是Berkeley DB的示例程序之一(DB/example_cxx/AccessMethod.cpp)，<br />
* 它演示了如何使用Berkeley DB的基本功能，包括打开一个数据库，存入若干个<br />
* key/data pair，然后遍历数据库中的数据，最后关闭数据库。<br />
*<br />
* 原始代码中有一些英文注释，但是对于初学者还是不够详细，我没有删除原来<br />
* 的注释，而且添加了针对每一个Berkeley DB操作的更加详细的说明，请参考。<br />
*<br />
* 代码的非关键部分都已删除，所以这里的内容<br />
* 无法直接编译运行。可以直接编译运行的版本我会放到空间的附件中。<br />
*<br />
*<br />
* 用词约定：<br />
* 本文提到的“数据库”是指Berkeley DB的database，相当于关系数据库的一个表。<br />
* 一个数据库当中保存着很多个key/data pair，相当于关系数据库的一个表当中<br />
* 保存着很多条记录。也就是说一个key/data pair相当于关系数据库的一条记录。<br />
* 而数据库环境(DbEnv)是指Berkeley Db的执行环境，相当于一个关系数据库管理系统。<br />
*/</p>
<p>/* 测试用例类声明 */<br />
class AccessExample<br />
{<br />
public:<br />
AccessExample();<br />
void run(bool removeExistingDatabase, const char *fileName);</p>
<p>private:<br />
// no need for copy and assignment<br />
AccessExample(const AccessExample &amp;);<br />
void operator = (const AccessExample &amp;);<br />
};</p>
<p>/*<br />
* 这个例子程序演示了如何使用Berkeley DB的基本功能，包括打开一个数据库，存入<br />
* 若干个key/data pair，然后遍历数据库中的数据，最后关闭数据库。<br />
*/<br />
int<br />
main(int argc, char *argv[])<br />
{<br />
// Use a try block just to report any errors.<br />
// An alternate approach to using exceptions is to<br />
// use error models (see DbEnv::set_error_model()) so<br />
// that error codes are returned for all Berkeley DB methods.<br />
//<br />
try {<br />
AccessExample app;<br />
app.run((bool)(rflag == 1 ? true : false), database);<br />
return (EXIT_SUCCESS);<br />
}<br />
catch (DbException &amp;dbe) {<br />
cerr &lt;&lt; &#8220;AccessExample: &#8221; &lt;&lt; dbe.what() &lt;&lt; &#8220;n&#8221;;<br />
return (EXIT_FAILURE);<br />
}<br />
}</p>
<p>void AccessExample::run(bool removeExistingDatabase, const char *fileName)<br />
{<br />
// Remove the previous database.<br />
if (removeExistingDatabase)<br />
(void)remove(fileName);</p>
<p>// Create the database object.<br />
// There is no environment for this simple example.<br />
// 这里我们没有指定显式的environment，BerkeleyDB会在内部创建一个专门供<br />
// 这个数据库使用的environment. 同时，第二个参数表明，当出现错误后，<br />
// Berkeley DB会抛出异常。<br />
Db db(0, 0);</p>
<p>// 当出现运行错误后，错误信息写入cerr流。<br />
//<br />
// Berkeley DB在调试模式下，可以可选地输出非常丰富的错误信息和其他运行期信息，<br />
// 大大简化了调试过程。比如，你可以让Berkeley DB把错误信息写到一个文件、<br />
// 一个c++ io流中，或者调用用户注册的回调函数由用户自己处理错误信息，<br />
// 以及在错误信息中前缀某些自定义信息，等等。<br />
//<br />
// 关于错误报告和调试的文档：<br />
// http://www.oracle.com/technology/documentation/berkeley-db/db/ref/debug/runtime.html<br />
// http://www.oracle.com/technology/documentation/berkeley-db/db/ref/am_misc/error.html<br />
// http://www.oracle.com/technology/documentation/berkeley-db/db/ref/env/error.html<br />
// http://www.oracle.com/technology/documentation/berkeley-db/db/ref/program/errorret.html<br />
db.set_error_stream(&amp;cerr);<br />
// 在每个错误信息前缀 &#8220;AccessExample&#8221;<br />
db.set_errpfx(&#8220;AccessExample&#8221;);</p>
<p>// 设置数据库页的size为1024字节。数据库页的设置会在较大程度上影响数据库的性能,<br />
// 这里有关于页设置的说明：<br />
// http://www.oracle.com/technology/documentation/berkeley-db/db/ref/am_conf/pagesize.html<br />
db.set_pagesize(1024);        /* Page size: 1K. */</p>
<p>// 设置cache的大小，数据库的页调入内存后，就放在cache当中，也就是说，cache<br />
// 就是存放调入内存的数据库页面的，如果整个数据库中每一个页面都可以调入<br />
// 内存长期存放，那么数据库的速度自然很快，所以，cache确实是越大越好的，<br />
// 当它大于所有数据库页面所占空间后，对性能就没什么影响了。<br />
//<br />
// 设置cache size的指导 ：<br />
// http://www.oracle.com/technology/documentation/berkeley-db/db/api_cxx/frame.html<br />
//<br />
// 如果cache填满了，数据库会淘汰不用的页面，若这样的页面有改动，会写回<br />
// 数据库文件。腾出空间后再调入目标页面。这涉及很多磁盘操作，所以数据库<br />
// 操作会突然变慢很多，应用程序的性能就会偶尔<br />
// 发生短暂地下降。为了避免这种性能抖动，你可以在一个单独运行的线程当中，<br />
// 定期淘汰页面腾出cache的空间，保证cache总是有一定的空间可用，<br />
// 这叫做memory trickle。<br />
//<br />
// 方法见此链接：<br />
// http://www.oracle.com/technology/documentation/berkeley-db/db/api_cxx/frame.html<br />
db.set_cachesize(0, 32 * 1024, 0);</p>
<p>// 打开数据库。这个函数的文档 ：<br />
// http://www.oracle.com/technology/documentation/berkeley-db/db/api_cxx/frame.html<br />
//<br />
// 这里创建的是一个btree数据库。Berkeley DB支持四种Access Method，也就是<br />
// 数据库文件内部组织数据的方式，包括btree, hash, queue和record number，<br />
// 分别使用DB_BTREE, DB_HASH, DB_QUEUE和DB_RECNO来指定。<br />
//<br />
// 每一种access method都有自己的优点和缺点，适用于某种需求。所以你应该根据自己<br />
// 的应用程序的数据存储需求，数据访问方式来决定使用哪种access method.<br />
// 关于如何选择合适的access method:<br />
// http://www.oracle.com/technology/documentation/berkeley-db/db/ref/am_conf/select.html<br />
db.open(NULL, fileName, NULL, DB_BTREE, DB_CREATE, 0664);</p>
<p>//<br />
// Insert records into the database, where the key is the user<br />
// input and the data is the user input in reverse order.<br />
//<br />
char buf[1024], rbuf[1024];<br />
char *p, *t;<br />
int ret;<br />
u_int32_t len;</p>
<p>// 循环获取用户输入的字符串str, 把str逆序得到str1, 然后存储(str, str1)<br />
// 作为一个key/data pair.<br />
for (;;) {<br />
cout &lt;&lt; &#8220;input&gt; &#8220;;<br />
cout.flush();</p>
<p>cin.getline(buf, sizeof(buf));<br />
if (cin.eof())<br />
break;</p>
<p>if ((len = (u_int32_t)strlen(buf)) &lt;= 0)<br />
continue;<br />
for (t = rbuf, p = buf + (len &#8211; 1); p &gt;= buf;)<br />
*t++ = *p&#8211;;<br />
*t++ = &#8216; &#8217;;</p>
<p>// Dbt类用于存储用户的一个数据项的信息。一个key/data pair是一次存储<br />
// 操作的单位，相当于关系数据库<br />
// 的一个行(row)，key是这行的主键，data是其他各个字段的集合。<br />
//<br />
// Berkeley DB不对data做细分和理解，<br />
// 应用程序自然知道自己存储的数据的结构和意义。<br />
//<br />
// key/data pair中的key和data都是一个数据项，它们各需要一个Dbt对象来描述。<br />
// 由于Berkeley DB存储的是字节串，<br />
// 它不理会数据的更多意义，比如类型等，所关心数据项信息只包括：<br />
// 字节串起始地址，长度，内存管理的flags(约定了在读和写一个key/data pair<br />
// 时，由谁分配和释放Dbt::data所指向的内存），<br />
// 以及用于做分块读取的字段，这个后面再讲。<br />
//<br />
// 这里我们创建的两个对象key和data分别代表要存储的一个key/data pair<br />
// 的key和data。我们把字节串的起始地址和长度传给了它们，Berkeley DB即<br />
// 可得到这两个字节串。<br />
Dbt key(buf, len + 1);<br />
Dbt data(rbuf, len + 1);</p>
<p>// 存储这个key/data pair。DB_NOOVERWRITE 表示如果已经有了这个key，<br />
// 那么不要覆盖那个key/data pair，<br />
// 而是返回错误。Db::put的第四个参数允许你设置若干种flag，来控制插入<br />
// 一个key/data pair的行为。<br />
//<br />
// Db::put的文档：<br />
// http://www.oracle.com/technology/documentation/berkeley-db/db/api_cxx/frame.html<br />
ret = db.put(0, &amp;key, &amp;data, DB_NOOVERWRITE);</p>
<p>// 如上所述，由于不覆盖已有的相同key的key/data pair，如果这样的key<br />
// 真的存在，Db::put就会返回DB_KEYEXIST。<br />
if (ret == DB_KEYEXIST) {<br />
cout &lt;&lt; &#8220;Key &#8221; &lt;&lt; buf &lt;&lt; &#8221; already exists.n&#8221;;<br />
}<br />
}<br />
cout &lt;&lt; &#8220;n&#8221;;</p>
<p>// We put a try block around this section of code<br />
// to ensure that our database is properly closed<br />
// in the event of an error.<br />
//<br />
try {<br />
// Acquire a cursor for the table.<br />
Dbc *dbcp;<br />
// 创建一个游标来遍历数据库。游标的作用与ODBC/JDBC等的游标的意义相同，<br />
// 它指向一个key/data pair，可以<br />
// 更改、读取、删除它所指向的key/data pair，同时具有游标稳定性&#8211;<br />
// 它所指向的key/data pair不会被其他游标修改或者删除。<br />
db.cursor(NULL, &amp;dbcp, 0);</p>
<p>// Walk through the table, printing the key/data pairs.<br />
// 此处我们是要使用游标dbcp遍历整个数据库，所以我们不需要指定key的值，<br />
// key和data都是用来存储返回结果的。<br />
// 并且，在这种默认情况下，用于保存返回结果的内存有Berkeley DB<br />
// 负责分配和释放。<br />
// 你也可以通过指定其他的flag，并且自己分配并且/或者自己释放存储着<br />
// 结果字节串的内存。<br />
//<br />
// 类Dbt的文档：<br />
// http://www.oracle.com/technology/documentation/berkeley-db/db/api_cxx/frame.html<br />
// 里面有所有的flags，以及几种Dbt的内存管理方式。<br />
Dbt key;<br />
Dbt data;</p>
<p>// 循环获取下一条key/data pair。当没有更多的key/data pair时候，<br />
// Dbc::get会返回非0值。一个游标dbcp在创建之初，<br />
// 并不指向任何一条key/data pair，而第一次调用Dbc::get并且传入<br />
// DB_NEXT flag，就会使得dbcp位于第一个key/data pair。<br />
// Dbc::get的文档:<br />
// http://www.oracle.com/technology/documentation/berkeley-db/db/api_cxx/frame.html<br />
//<br />
// key/data pair的顺序是由数据库的存取方式定义的。比如对于btree这种<br />
// 存取方式，key的顺序由它们的大小关系决定。<br />
// 你可以配置key的比较函数来自定义key的比较方式，见文档：<br />
// http://www.oracle.com/technology/documentation/berkeley-db/db/api_cxx/frame.html<br />
while (dbcp-&gt;get(&amp;key, &amp;data, DB_NEXT) == 0) {</p>
<p>// 获取Dbt中的数据，也就是字节串的首地址。由于key和data对象<br />
// 使用了默认的flags，所以它们所引用的内存由Berkeley Db负责<br />
// 分配和回收。你也可以使用其他的内存管理方式。<br />
// 详情Dbt的文档。<br />
char *key_string = (char *)key.get_data();<br />
char *data_string = (char *)data.get_data();<br />
cout &lt;&lt; key_string &lt;&lt; &#8221; : &#8221; &lt;&lt; data_string &lt;&lt; &#8220;n&#8221;;<br />
}</p>
<p>// 关闭游标。 一定别忘了做这个，并且尽早关闭游标。<br />
// 这是因为游标稳定性导致游标所引用的<br />
// 页面被锁定，使用同一个数据库的其他进程或者线程无法访问这些页面。<br />
dbcp-&gt;close();<br />
}<br />
catch (DbException &amp;dbe) {<br />
cerr &lt;&lt; &#8220;AccessExample: &#8221; &lt;&lt; dbe.what() &lt;&lt; &#8220;n&#8221;;<br />
}</p>
<p>// 关闭数据库。<br />
db.close(0);<br />
}</p>
]]></content:encoded>
			<wfw:commentRss>http://www.bdbchina.com/2009/02/berkeley-db%e7%a4%ba%e4%be%8b%e7%a8%8b%e5%ba%8f%e8%af%a6%e8%a7%a3-1/feed/</wfw:commentRss>
		<slash:comments>9</slash:comments>
		</item>
	</channel>
</rss>
Դ