je/docs/GettingStartedGuide/env.html

413 lines
19 KiB
HTML
Raw Normal View History

2021-06-06 17:46:45 +00:00
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<title>Chapter 2. Database Environments</title>
<link rel="stylesheet" href="gettingStarted.css" type="text/css" />
<meta name="generator" content="DocBook XSL Stylesheets V1.73.2" />
<link rel="start" href="index.html" title="Getting Started with Berkeley DB Java Edition" />
<link rel="up" href="index.html" title="Getting Started with Berkeley DB Java Edition" />
<link rel="prev" href="logfilesrevealed.html" title="Six Things Everyone Should Know about JE Log Files" />
<link rel="next" href="envclose.html" title="Closing Database Environments" />
</head>
<body>
<div xmlns="" class="navheader">
<div class="libver">
<p>Library Version 12.2.7.5</p>
</div>
<table width="100%" summary="Navigation header">
<tr>
<th colspan="3" align="center">Chapter 2. Database Environments</th>
</tr>
<tr>
<td width="20%" align="left"><a accesskey="p" href="logfilesrevealed.html">Prev</a> </td>
<th width="60%" align="center"> </th>
<td width="20%" align="right"> <a accesskey="n" href="envclose.html">Next</a></td>
</tr>
</table>
<hr />
</div>
<div class="chapter" lang="en" xml:lang="en">
<div class="titlepage">
<div>
<div>
<h2 class="title"><a id="env"></a>Chapter 2. Database Environments</h2>
</div>
</div>
</div>
<div class="toc">
<p>
<b>Table of Contents</b>
</p>
<dl>
<dt>
<span class="sect1">
<a href="env.html#envopen">Opening Database Environments</a>
</span>
</dt>
<dd>
<dl>
<dt>
<span class="sect2">
<a href="env.html#multienv">Multiple Environments</a>
</span>
</dt>
<dt>
<span class="sect2">
<a href="env.html#multisubdir">Multiple Environment Subdirectories</a>
</span>
</dt>
<dt>
<span class="sect2">
<a href="env.html#multienvsharedcache">Configuring a Shared Cache for Multiple Environments</a>
</span>
</dt>
</dl>
</dd>
<dt>
<span class="sect1">
<a href="envclose.html">Closing Database Environments</a>
</span>
</dt>
<dt>
<span class="sect1">
<a href="EnvProps.html">Environment Properties</a>
</span>
</dt>
<dd>
<dl>
<dt>
<span class="sect2">
<a href="EnvProps.html#envconfig">The EnvironmentConfig Class</a>
</span>
</dt>
<dt>
<span class="sect2">
<a href="EnvProps.html#envhandleconfig">EnvironmentMutableConfig</a>
</span>
</dt>
</dl>
</dd>
<dt>
<span class="sect1">
<a href="envStats.html">Environment Statistics</a>
</span>
</dt>
<dt>
<span class="sect1">
<a href="dbenvUsageExample.html">Database Environment Management Example</a>
</span>
</dt>
</dl>
</div>
<p>
Regardless of whether you are using the DPL or the base API, you must use a database
environment. Database environments encapsulate one or more databases. This encapsulation
provides your threads with efficient access to your databases by allowing a single in-memory
cache to be used for each of the databases contained in the environment. This encapsulation
also allows you to group operations performed against multiple databases inside a single
transaction (see the <em class="citetitle">Berkeley DB, Java Edition Getting Started with Transaction Processing</em> guide for more information).
</p>
<p>
If you are using the base API, most commonly you use database environments to create and
open databases (you close individual databases using the individual database handles). You
can also use environments to delete and rename databases. For transactional applications,
you use the environment to start transactions. For non-transactional applications, you use
the environment to sync your in-memory cache to disk.
</p>
<p>
If you are using the DPL, all of these things are still being done, but the DPL takes
care of it for you. Under the DPL, the most common thing you will explicitly use an
environment for is to obtain transaction handles.
</p>
<p>
Regardless of the API that you use, you also use the database environment for
administrative and configuration activities related to your database log files and the
in-memory cache.
See <a class="xref" href="administration.html" title="Chapter 12. Administering Berkeley DB Java Edition Applications">Administering Berkeley DB Java Edition Applications</a> for
more information.
</p>
<p>
To find out how to use environments with a transaction-protected application, see the
<em class="citetitle">Berkeley DB, Java Edition Getting Started with Transaction Processing</em> guide.
</p>
<div class="sect1" lang="en" xml:lang="en">
<div class="titlepage">
<div>
<div>
<h2 class="title" style="clear: both"><a id="envopen"></a>Opening Database Environments</h2>
</div>
</div>
</div>
<div class="toc">
<dl>
<dt>
<span class="sect2">
<a href="env.html#multienv">Multiple Environments</a>
</span>
</dt>
<dt>
<span class="sect2">
<a href="env.html#multisubdir">Multiple Environment Subdirectories</a>
</span>
</dt>
<dt>
<span class="sect2">
<a href="env.html#multienvsharedcache">Configuring a Shared Cache for Multiple Environments</a>
</span>
</dt>
</dl>
</div>
<p>
You open a database environment by instantiating an <code class="classname">Environment</code>
object. You must provide to the constructor the name of the on-disk directory where the
environment is to reside. This directory location must exist or the open will fail.
</p>
<p>
By default, the environment is not created for you if it does not exist. Set the <a class="link" href="EnvProps.html" title="Environment Properties">creation property</a> to <code class="literal">true</code> if you
want the environment to be created. For example:
</p>
<pre class="programlisting">package je.gettingStarted;
import com.sleepycat.je.DatabaseException;
import com.sleepycat.je.Environment;
import com.sleepycat.je.EnvironmentConfig;
import java.io.File;
...
// Open the environment. Allow it to be created if it does not
// already exist.
Environment myDbEnvironment = null;
try {
EnvironmentConfig envConfig = new EnvironmentConfig();
envConfig.setAllowCreate(true);
myDbEnvironment = new Environment(new File("/export/dbEnv"),
envConfig);
} catch (DatabaseException dbe) {
// Exception handling goes here
} </pre>
<p>
Opening an environment usually causes some background threads to be started. JE uses
these threads for log file cleaning and some administrative tasks. However, these
threads will only be opened once per process, so if you open the same environment more
than once from within the same process, there is no performance impact on your
application. Also, if you open the environment as read-only, then the background
threads (with the exception of the evictor thread) are not started.
</p>
<p>
Note that opening your environment causes normal recovery to be run. This
causes your databases to be brought into a consistent state relative to the
changed data found in your log files.
See <a class="xref" href="backuprestore.html#databaselogs" title="Databases and Log Files">Databases and Log Files</a>
for more information.
</p>
<div class="sect2" lang="en" xml:lang="en">
<div class="titlepage">
<div>
<div>
<h3 class="title"><a id="multienv"></a>Multiple Environments</h3>
</div>
</div>
</div>
<p>
Most JE applications only need a single database environment because any
number of databases can be created in a single environment, and the
total size of the data in an environment is not limited. That said,
your application can open and use as many environments as you have disk and
memory to manage. Also, you can instantiate
multiple <code class="classname">Environment</code> objects
for the same physical environment.
</p>
<p>
The main reason for multiple environments is that an application must manage
multiple unique data sets. By placing each data set in a separate environment,
the application can gain real advantages in manageability of the data, and with
application performance. By placing each data set in a unique environment,
a separate set of log files is created and maintained in a separate directory,
and so you can manipulate the log files for each data set separately.
That is, you can:
</p>
<div class="itemizedlist">
<ul type="disc">
<li>
<p>
Backup, restore or delete a single data set
separately by copying or removing the files for its environment.
</p>
</li>
<li>
<p>
Balance the load between machines by moving the files for a
single data set from one machine to another.
</p>
</li>
<li>
<p>
Improve I/O performance by placing each data set on a separate
physical disk.
</p>
</li>
<li>
<p>
Delete individual data sets very efficiently by removing the
environment's log files. This is much more efficient than
deleting individual database records and is also move
efficient than removing databases, and so can be a real benefit
if you are managing large temporary data sets that must be
frequently deleted.
</p>
</li>
</ul>
</div>
<p>
Be aware that there is a downside to using multiple environments. In particular,
understand that a single transaction cannot include changes
made in more than one environment. If you need to perform a set of
operations in more than one data set atomically (with a single
transaction), use a single environment and distinguish the data sets
using some other method.
</p>
<p>
For example, an application running a hosted service for multiple clients may
wish to keep each client's data set separate. You can do this with multiple
environments, but then you can operate on all data sets atomically. If you need
to wrap operations for multiple data sets in a single transaction, consider some
other approach to keeping the data sets separate.
</p>
<p>
You can, for example, distinguish each data set using a unique key range within
a single database. Or you can create a secondary key that identifies the data
set. Or you could use separate databases for each dataset. All of these
approaches allow you to maintain multiple distinct dataset within a single
environment, but each obviously adds a level of complexity to your code over
what is required to simply use a unique environment for each data set.
</p>
</div>
<div class="sect2" lang="en" xml:lang="en">
<div class="titlepage">
<div>
<div>
<h3 class="title"><a id="multisubdir"></a>Multiple Environment Subdirectories</h3>
</div>
</div>
</div>
<p>
You can spread your JE environment across multiple subdirectories. This allows you
to improve data throughput by spreading disk I/O across multiple disks or filesystems.
Environment subdirectories reside in the environment home directory and are named
<code class="literal">data001/</code> through <code class="literal">dataNNN/</code>, consecutively, where
<code class="literal">NNN</code> is the number of subdirectories that you want to use. Typically,
each of the <code class="literal">dataNNN/</code> names are symbolic links to actual directories
which reside on separate file systems or disks. Alternatively, each subdirectory can
be mount points for filesystems which reside on different disk drives.
</p>
<p>
You control the number of subdirectories you want to use with the
<code class="literal">je.log.nDataDirectories</code> property in the
<code class="literal">je.properties</code> file. This value must be set prior to opening the
environment, and the subdirectories must already exist at that time. The value set for
this property can not change over the course of the environment's lifetime, or an
exception is thrown when you attempt to open the environment.
</p>
<p>
The default value for <code class="literal">je.log.nDataDirectories</code> is 0, and this means no
subdirectories are in use for the environment. A value greater than 0 indicates the
number of subdirectories to use, and that number of subdirectories must exist prior to
opening the environment.
</p>
<p>
For example, if you set <code class="literal">je.log.nDataDirectories</code> to 3, then the first
time you open the environment (and for every environment open after that) your
environment home directory must contain three subdirectories named
<code class="literal">data001</code>, <code class="literal">data002</code> and <code class="literal">data003</code>.
This causes your JE log files (the <code class="literal">*.jdb</code> files) to be spread
evenly across those three subdirectories. Finally, if you change the value of
<code class="literal">je.log.nDataDirectories</code> without first completely deleting your
environment, then your application will throw exceptions when you open your environment.
</p>
</div>
<div class="sect2" lang="en" xml:lang="en">
<div class="titlepage">
<div>
<div>
<h3 class="title"><a id="multienvsharedcache"></a>Configuring a Shared Cache for Multiple Environments</h3>
</div>
</div>
</div>
<p>
By default, each distinct JE environment has a separate, private
in-memory cache. If a single JVM process will keep open multiple
environments at the same time, it is strongly recommended that all such
environments are configured to use a shared cache. A shared cache makes
much more efficient use of memory than separate private caches.
</p>
<p>
For example, imagine that you open 5 environments in a single process
and a total of 500 MB of memory is available for caching. Using private
caches, you could configure each cache to be 100 MB. If one of the
environments has a larger active data set than the others, it will
not be able to take advantage of unused memory in the other environment
caches. By using a shared cache, multiple open environments will make
better use of memory because the cache LRU algorithm is applied across
all information in all enviornments sharing the cache.
</p>
<p>
In order to configure an environment to use a shared cache, set
<code class="methodname">EnvironmentConfig.setSharedCache()</code>
to <code class="literal">true</code>. This must be set for every environment in the
process that you want to use the shared cache. For example:
</p>
<pre class="programlisting">package je.gettingStarted;
import com.sleepycat.je.DatabaseException;
import com.sleepycat.je.Environment;
import com.sleepycat.je.EnvironmentConfig;
import java.io.File;
...
// Open the environment. Allow it to be created if it does not
// already exist.
Environment myEnv1 = null;
Environment myEnv2 = null;
try {
EnvironmentConfig envConfig = new EnvironmentConfig();
envConfig.setAllowCreate(true);
envConfig.setSharedCache(true);
myEnv1 = new Environment(new File("/export/dbEnv1"), envConfig);
myEnv2 = new Environment(new File("/export/dbEnv2"), envConfig);
} catch (DatabaseException dbe) {
// Exception handling goes here
} </pre>
</div>
</div>
</div>
<div class="navfooter">
<hr />
<table width="100%" summary="Navigation footer">
<tr>
<td width="40%" align="left"><a accesskey="p" href="logfilesrevealed.html">Prev</a> </td>
<td width="20%" align="center"> </td>
<td width="40%" align="right"> <a accesskey="n" href="envclose.html">Next</a></td>
</tr>
<tr>
<td width="40%" align="left" valign="top">Six Things Everyone Should Know about JE Log Files </td>
<td width="20%" align="center">
<a accesskey="h" href="index.html">Home</a>
</td>
<td width="40%" align="right" valign="top"> Closing Database Environments</td>
</tr>
</table>
</div>
</body>
</html>