mirror of
https://github.com/berkeleydb/libdb.git
synced 2024-11-16 09:06:25 +00:00
250 lines
14 KiB
HTML
250 lines
14 KiB
HTML
<?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>Transaction tuning</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="Berkeley DB Programmer's Reference Guide" />
|
||
<link rel="up" href="transapp.html" title="Chapter 11. Berkeley DB Transactional Data Store Applications" />
|
||
<link rel="prev" href="transapp_reclimit.html" title="Berkeley DB recoverability" />
|
||
<link rel="next" href="transapp_throughput.html" title="Transaction throughput" />
|
||
</head>
|
||
<body>
|
||
<div xmlns="" class="navheader">
|
||
<div class="libver">
|
||
<p>Library Version 11.2.5.3</p>
|
||
</div>
|
||
<table width="100%" summary="Navigation header">
|
||
<tr>
|
||
<th colspan="3" align="center">Transaction tuning</th>
|
||
</tr>
|
||
<tr>
|
||
<td width="20%" align="left"><a accesskey="p" href="transapp_reclimit.html">Prev</a> </td>
|
||
<th width="60%" align="center">Chapter 11.
|
||
Berkeley DB Transactional Data Store Applications
|
||
</th>
|
||
<td width="20%" align="right"> <a accesskey="n" href="transapp_throughput.html">Next</a></td>
|
||
</tr>
|
||
</table>
|
||
<hr />
|
||
</div>
|
||
<div class="sect1" lang="en" xml:lang="en">
|
||
<div class="titlepage">
|
||
<div>
|
||
<div>
|
||
<h2 class="title" style="clear: both"><a id="transapp_tune"></a>Transaction tuning</h2>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<p>There are a few different issues to consider when tuning the performance
|
||
of Berkeley DB transactional applications. First, you should review
|
||
<a class="xref" href="am_misc_tune.html" title="Access method tuning">Access method tuning</a>, as the
|
||
tuning issues for access method applications are applicable to
|
||
transactional applications as well. The following are additional tuning
|
||
issues for Berkeley DB transactional applications:</p>
|
||
<div class="variablelist">
|
||
<dl>
|
||
<dt>
|
||
<span class="term">access method</span>
|
||
</dt>
|
||
<dd>Highly concurrent applications should use the Queue access method, where
|
||
possible, as it provides finer-granularity of locking than the other
|
||
access methods. Otherwise, applications usually see better concurrency
|
||
when using the Btree access method than when using either the Hash or
|
||
Recno access methods.</dd>
|
||
<dt>
|
||
<span class="term">record numbers</span>
|
||
</dt>
|
||
<dd>Using record numbers outside of the Queue access method will often slow
|
||
down concurrent applications as they limit the degree of concurrency
|
||
available in the database. Using the Recno access method, or the Btree
|
||
access method with retrieval by record number configured can slow
|
||
applications down.</dd>
|
||
<dt>
|
||
<span class="term">Btree database size</span>
|
||
</dt>
|
||
<dd>When using the Btree access method, applications supporting concurrent
|
||
access may see excessive numbers of deadlocks in small databases. There
|
||
are two different approaches to resolving this problem. First, as the
|
||
Btree access method uses page-level locking, decreasing the database
|
||
page size can result in fewer lock conflicts. Second, in the case of
|
||
databases that are cyclically growing and shrinking, turning off reverse
|
||
splits (with <a href="../api_reference/C/dbset_flags.html#dbset_flags_DB_REVSPLITOFF" class="olink">DB_REVSPLITOFF</a>) can leave the database with enough
|
||
pages that there will be fewer lock conflicts.</dd>
|
||
<dt>
|
||
<span class="term">read locks</span>
|
||
</dt>
|
||
<dd>Performing all read operations outside of transactions or at
|
||
<a class="xref" href="transapp_read.html" title="Degrees of isolation">Degrees of isolation</a> can often
|
||
significantly increase application throughput. In addition, limiting
|
||
the lifetime of non-transactional cursors will reduce the length of
|
||
times locks are held, thereby improving concurrency.</dd>
|
||
<dt>
|
||
<span class="term"><a href="../api_reference/C/envset_flags.html#set_flags_DB_DIRECT_DB" class="olink">DB_DIRECT_DB</a>, <a href="../api_reference/C/envlog_set_config.html#log_set_config_DB_LOG_DIRECT" class="olink">DB_LOG_DIRECT</a></span>
|
||
</dt>
|
||
<dd>
|
||
On some systems, avoiding caching in the operating system can improve
|
||
write throughput and allow the creation of larger Berkeley DB caches.</dd>
|
||
<dt>
|
||
<span class="term"><a href="../api_reference/C/dbopen.html#dbopen_DB_READ_UNCOMMITTED" class="olink">DB_READ_UNCOMMITTED</a>, <a href="../api_reference/C/dbcget.html#dbcget_DB_READ_COMMITTED" class="olink">DB_READ_COMMITTED</a></span>
|
||
</dt>
|
||
<dd>
|
||
<p>
|
||
Consider decreasing the level of isolation of transaction using
|
||
the <a href="../api_reference/C/dbopen.html#dbopen_DB_READ_UNCOMMITTED" class="olink">DB_READ_UNCOMMITTED</a>, or <a href="../api_reference/C/dbcget.html#dbcget_DB_READ_COMMITTED" class="olink">DB_READ_COMMITTED</a> flags for
|
||
transactions or cursors or the <a href="../api_reference/C/dbopen.html#dbopen_DB_READ_UNCOMMITTED" class="olink">DB_READ_UNCOMMITTED</a> flag on
|
||
individual read operations. The <a href="../api_reference/C/dbcget.html#dbcget_DB_READ_COMMITTED" class="olink">DB_READ_COMMITTED</a> flag will
|
||
release read locks on cursors as soon as the data page is
|
||
nolonger referenced. This is also called
|
||
<span class="emphasis"><em> degree 2 isolation</em></span>. This will
|
||
tend to block write operations for shorter periods for
|
||
applications that do not need to have repeatable reads for
|
||
cursor operations.
|
||
</p>
|
||
<p>
|
||
The <a href="../api_reference/C/dbcget.html#dbcget_DB_READ_COMMITTED" class="olink">DB_READ_COMMITTED</a> flag will allow read operations to
|
||
potentially return data which has been modified but not yet
|
||
committed, and can significantly increase application
|
||
throughput in applications that do not require data be
|
||
guaranteed to be permanent in the database. This is also
|
||
called <span class="emphasis"><em>degree 1 isolation</em></span>,
|
||
or <span class="emphasis"><em>dirty reads</em></span>.
|
||
</p>
|
||
</dd>
|
||
<dt>
|
||
<span class="term">
|
||
<a href="../api_reference/C/dbcget.html#dbcget_DB_RMW" class="olink">DB_RMW</a>
|
||
</span>
|
||
</dt>
|
||
<dd> If there are many deadlocks, consider
|
||
using the <a href="../api_reference/C/dbcget.html#dbcget_DB_RMW" class="olink">DB_RMW</a> flag to
|
||
immediately acquire write locks when reading data items that will
|
||
subsequently be modified. Although this flag may increase contention
|
||
(because write locks are held longer than they would otherwise be), it
|
||
may decrease the number of deadlocks that occur.</dd>
|
||
<dt>
|
||
<span class="term"><a href="../api_reference/C/envset_flags.html#set_flags_DB_TXN_WRITE_NOSYNC" class="olink">DB_TXN_WRITE_NOSYNC</a>, <a href="../api_reference/C/envset_flags.html#envset_flags_DB_TXN_NOSYNC" class="olink">DB_TXN_NOSYNC</a></span>
|
||
</dt>
|
||
<dd>By default, transactional commit in Berkeley DB implies durability, that is,
|
||
all committed operations will be present in the database after recovery
|
||
from any application or system failure. For applications not requiring
|
||
that level of certainty, specifying the <a href="../api_reference/C/envset_flags.html#envset_flags_DB_TXN_NOSYNC" class="olink">DB_TXN_NOSYNC</a> flag will
|
||
often provide a significant performance improvement. In this case, the
|
||
database will still be fully recoverable, but some number of committed
|
||
transactions might be lost after application or system failure.</dd>
|
||
<dt>
|
||
<span class="term">access databases in order</span>
|
||
</dt>
|
||
<dd>When modifying multiple databases in a single transaction, always access
|
||
physical files and databases within physical files, in the same order
|
||
where possible. In addition, avoid returning to a physical file or
|
||
database, that is, avoid accessing a database, moving on to another
|
||
database and then returning to the first database. This can
|
||
significantly reduce the chance of deadlock between threads of
|
||
control.</dd>
|
||
<dt>
|
||
<span class="term">large key/data items</span>
|
||
</dt>
|
||
<dd>Transactional protections in Berkeley DB are guaranteed by before and after
|
||
physical image logging. This means applications modifying large
|
||
key/data items also write large log records, and, in the case of the
|
||
default transaction commit, threads of control must wait until those
|
||
log records have been flushed to disk. Applications supporting
|
||
concurrent access should try and keep key/data items small wherever
|
||
possible.</dd>
|
||
<dt>
|
||
<span class="term">mutex selection</span>
|
||
</dt>
|
||
<dd>
|
||
<p>
|
||
During configuration, Berkeley DB selects a mutex implementation
|
||
for the architecture. Berkeley DB normally prefers blocking-mutex
|
||
implementations over non-blocking ones. For example, Berkeley DB
|
||
will select POSIX pthread mutex interfaces rather than
|
||
assembly-code test-and-set spin mutexes because pthread mutexes are
|
||
usually more efficient and less likely to waste CPU cycles spinning
|
||
without getting any work accomplished.
|
||
</p>
|
||
<p>
|
||
For some applications and systems (generally highly concurrent
|
||
applications on large multiprocessor systems), Berkeley DB makes
|
||
the wrong choice. In some cases, better performance can be
|
||
achieved by configuring with the <a href="../installation/build_unix_conf.html#build_unix_conf.--with-mutex" class="olink">--with-mutex</a>
|
||
argument and selecting a different mutex implementation than the
|
||
one selected by Berkeley DB. When a test-and-set spin mutex
|
||
implementation is selected, it may be useful to tune the number of
|
||
spins made before yielding the processor and sleeping. For more
|
||
information, see the <a href="../api_reference/C/mutexset_tas_spins.html" class="olink">DB_ENV->mutex_set_tas_spins()</a> method.
|
||
</p>
|
||
<p>
|
||
Finally, Berkeley DB may put multiple mutexes on individual cache
|
||
lines. When tuning Berkeley DB for large multiprocessor systems,
|
||
it may be useful to tune mutex alignment using the <a href="../api_reference/C/mutexset_align.html" class="olink">DB_ENV->mutex_set_align()</a>
|
||
method.
|
||
</p>
|
||
</dd>
|
||
<dt>
|
||
<span class="term">
|
||
<a href="../installation/build_unix_conf.html#build_unix_conf.--enable-posixmutexes" class="olink">--enable-posix-mutexes</a>
|
||
</span>
|
||
</dt>
|
||
<dd>By default, the Berkeley DB library will only select the POSIX pthread mutex
|
||
implementation if it supports mutexes shared between multiple processes.
|
||
If your application does not share its database environment between
|
||
processes and your system's POSIX mutex support was not selected because
|
||
it did not support inter-process mutexes, you may be able to increase
|
||
performance and transactional throughput by configuring with the
|
||
<a href="../installation/build_unix_conf.html#build_unix_conf.--enable-posixmutexes" class="olink">--enable-posix-mutexes</a> argument.</dd>
|
||
<dt>
|
||
<span class="term">log buffer size</span>
|
||
</dt>
|
||
<dd>Berkeley DB internally maintains a buffer of log writes. The buffer is
|
||
written to disk at transaction commit, by default, or, whenever it
|
||
is filled. If it is consistently being filled before transaction
|
||
commit, it will be written multiple times per transaction, costing
|
||
application performance. In these cases, increasing the size of the
|
||
log buffer can increase application throughput.</dd>
|
||
<dt>
|
||
<span class="term">log file location</span>
|
||
</dt>
|
||
<dd>If the database environment's log files are on the same disk as the
|
||
databases, the disk arms will have to seek back-and-forth between the
|
||
two. Placing the log files and the databases on different disk arms
|
||
can often increase application throughput.</dd>
|
||
<dt>
|
||
<span class="term">trickle write</span>
|
||
</dt>
|
||
<dd>In some applications, the cache is sufficiently active and dirty that
|
||
readers frequently need to write a dirty page in order to have space in
|
||
which to read a new page from the backing database file. You can use
|
||
the <a href="../api_reference/C/db_stat.html" class="olink">db_stat</a> utility (or the statistics returned by the
|
||
<a href="../api_reference/C/mempstat.html" class="olink">DB_ENV->memp_stat()</a> method) to see how often this is happening in your
|
||
application's cache. In this case, using a separate thread of control
|
||
and the <a href="../api_reference/C/memptrickle.html" class="olink">DB_ENV->memp_trickle()</a> method to trickle-write pages can often increase
|
||
the overall throughput of the application.</dd>
|
||
</dl>
|
||
</div>
|
||
</div>
|
||
<div class="navfooter">
|
||
<hr />
|
||
<table width="100%" summary="Navigation footer">
|
||
<tr>
|
||
<td width="40%" align="left"><a accesskey="p" href="transapp_reclimit.html">Prev</a> </td>
|
||
<td width="20%" align="center">
|
||
<a accesskey="u" href="transapp.html">Up</a>
|
||
</td>
|
||
<td width="40%" align="right"> <a accesskey="n" href="transapp_throughput.html">Next</a></td>
|
||
</tr>
|
||
<tr>
|
||
<td width="40%" align="left" valign="top">Berkeley DB recoverability </td>
|
||
<td width="20%" align="center">
|
||
<a accesskey="h" href="index.html">Home</a>
|
||
</td>
|
||
<td width="40%" align="right" valign="top"> Transaction throughput</td>
|
||
</tr>
|
||
</table>
|
||
</div>
|
||
</body>
|
||
</html>
|