<!--
$Header: /usr/prj/pg/cvsroot/doc/doc/src/sgml/mvcc.sgml,v 1.14 2001/09/07 11:52:11 i-kaori Exp $
-->

 <chapter id="mvcc">
  <!--<title>Multi-Version Concurrency Control</title>-->
  <title>MVCC（多版型同時実行制御）</title>
<indexterm><primary>MVCC</primary></indexterm>
<indexterm><primary sortas="たばんがたどうじじっこうせいぎょ">多版型同時実行制御</primary></indexterm>

  <abstract>
   <para>
    <!--Multi-Version Concurrency Control
    (MVCC)
    is an advanced technique for improving database performance in a
    multi-user environment. 
    Vadim Mikheev (<email>vadim@krs.ru</email>) provided
    the implementation for <productname>Postgres</productname>.-->

    MVCC（Multi-Version Concurrency Control：多版型同時実行制御）とは、マルチユーザー環境におけるデータベースの性能を向上させる高度な技術です。<productname>Postgres</productname>のために、Vadim Mikheev（<email>vadim@krs.ru</email>）が実装したものを貢献してくれました。
   </para>
  </abstract>

  <sect1 id="mvcc-intro">
   <!--<title>Introduction</title>-->
   <title>はじめに</title>

   <para>
    <!--Unlike most other database systems which use locks for concurrency control,
    <productname>Postgres</productname>
    maintains data consistency by using a multiversion model. 
    This means that while querying a database each transaction sees
    a snapshot of data (a <firstterm>database version</firstterm>)
    as it was some
    time ago, regardless of the current state of the underlying data.
    This protects the transaction from viewing inconsistent data that
    could be caused by (other) concurrent transaction updates on the same
    data rows, providing <firstterm>transaction isolation</firstterm>
    for each database session.-->

多くのデータベースシステムでは、同時実行制御のためにロック機構を使用していますが、<productname>Postgres</productname>ではデータ整合性の維持に多版方式を使用しています。つまり、データベースへの問い合わせ実行の際、各トランザクションは処理の基礎となるデータの現在の状態を関知せず、現在から遡ったある時点におけるスナップショット（<firstterm>データベースバージョン</firstterm>）を参照する、というものです。これは、並行するトランザクション同士が同じ行を更新することによって引き起こる整合性を欠いたデータの参照からトランザクションを保護し、個々のデータベースセッションに対して<firstterm>トランザクションの隔離</firstterm>を提供するものです。<indexterm><primary sortas="でーたべーすばーじょん">データベースバージョン</primary></indexterm><indexterm><primary>MVCC</primary><secondary sortas="でーたべーすばーじょん">データベースバージョン</secondary></indexterm><indexterm><primary sortas="とらんざくしょんのかくり">トランザクションの隔離</primary></indexterm><indexterm><primary>MVCC</primary><secondary sortas="とらんざくしょんのかくり">トランザクションの隔離</secondary></indexterm>
   </para>

   <para>
    <!--The main difference between multiversion and lock models is that
    in MVCC locks acquired for querying (reading) data don't conflict
    with locks acquired for writing data and so reading never blocks
    writing and writing never blocks reading.-->

    多版方式とロック方式との最大の相違点は、MVCCでは問い合わせ（読み込み）ロックの獲得と、書き込みロックの獲得が競合しないことです。したがって、読み込みは書き込みを絶対にブロックしませんし、書き込みも読み込みをブロックすることがありません。
   </para>
  </sect1>

  <sect1 id="transaction-iso">
   <!--<title>Transaction Isolation</title>-->
   <title>トランザクションの隔離</title>
<indexterm><primary sortas="とらんざくしょんのかくり">トランザクションの隔離</primary></indexterm><indexterm><primary>MVCC</primary><secondary sortas="とらんざくしょんのかくり">トランザクションの隔離</secondary></indexterm>
   <para>
    <!--The <acronym>ANSI</acronym>/<acronym>ISO</acronym> <acronym>SQL</acronym>
    standard defines four levels of transaction
    isolation in terms of three phenomena that must be prevented 
    between concurrent transactions.
    These undesirable phenomena are:-->

    <acronym>ANSI</acronym>/<acronym>ISO</acronym> <acronym>SQL</acronym>規格は、
    同時に実行されるトランザクション間で防ぐべき3つの現象ごとに、トランザクション隔離のレベルを4レベルに分けて定義しています。3つの望ましくない現象とは下記のものです。</para>


    <variablelist>
     <varlistentry>
      <term>
       ダーティ読み取り（dirty reads）<indexterm><primary sortas="だーてぃよみとり">ダーティ読み取り</primary></indexterm><indexterm><primary>MVCC</primary><secondary sortas="だーてぃよみとり">ダーティ読み取り</secondary></indexterm>
      </term>
     <listitem>
      <para>
	<!--A transaction reads data written by concurrent uncommitted transaction.-->
         同時に実行されている他のトランザクションが書き込んだ、まだコミットされていないデータを読み込んでしまう。
       </para>
      </listitem>
     </varlistentry>

     <varlistentry>
      <term>
       反復不能読み取り（non-repeatable reads）<indexterm><primary sortas="はんぷくふのうよみとり">反復不能読み取り</primary></indexterm><indexterm><primary>MVCC</primary><secondary sortas="はんぷくふのうよみとり">反復不能読み取り</secondary></indexterm>
      </term>
     <listitem>
      <para>
	<!--A transaction re-reads data it has previously read and finds that data
	has been modified by another transaction (that committed since the
	initial read).-->
        トランザクションが、以前読み込んだデータを再度読み込む際、そのデータを別のトランザクションが更新しコミットしたことによって、以前のデータではなく、新しいデータを得てしまう。
       </para>
      </listitem>
     </varlistentry>

     <varlistentry>
      <term>
       ファントム（phantom read）<indexterm><primary sortas="ふぉんとむ">ファントム</primary></indexterm><indexterm><primary>MVCC</primary><secondary sortas="ふぁんとむ">ファントム</secondary></indexterm>
      </term>
     <listitem>
      <para>
	<!--A transaction re-executes a query returning a set of rows that satisfy a
	search condition and finds that the set of rows satisfying the condition
	has changed due to another recently-committed transaction.-->
        トランザクションが、ある行の集合を返す検索条件で問い合わせを再実行したとき、別のトランザクションがその問い合わせ条件を満たす行を変更し、コミットしてしまったために、同じ検索条件で問い合わせを実行しても異なる結果を得てしまう。   
       </para>
      </listitem>
     </varlistentry>
    </variablelist>

   <para>
    <!--The four isolation levels and the corresponding behaviors are described below.-->
     4つの隔離レベルと対応する動作は次の表のようになります。</para>

    <table tocentry="1">
     <!--<title><acronym>ANSI</acronym>/<acronym>ISO</acronym> <acronym>SQL</acronym> Isolation Levels</title>-->
     <title><acronym>ANSI</acronym>/<acronym>ISO</acronym> <acronym>SQL</acronym>隔離レベル</title>
<indexterm><primary>MVCC</primary><secondary sortas="ANSIISOSQLかくりれべる">ANSI/ISO SQL隔離レベル</secondary></indexterm>
<!--     <titleabbrev><!&bsol;-&bsol;-Isolation Levels&bsol;-&bsol;->隔離レベル</titleabbrev>-->

     <tgroup cols="4">
      <thead>
       <row>
	<entry>隔離レベル
	</entry>
	<entry>ダーティ読み取り
	</entry>
	<entry><!--Non-Repeatable Read-->反復不能読み取り
	</entry>
	<entry>ファントム
	</entry>
       </row>
      </thead>
      <tbody>
       <row>
	<entry><!--Read uncommitted-->Read uncommitted（コミットされていない読み取り）
	</entry>
	<entry><!--Possible-->可能性あり
	</entry>
	<entry><!--Possible-->可能性あり
	</entry>
	<entry><!--Possible-->可能性あり
	</entry>
       </row>

       <row>
	<entry><!--Read committed-->Read committed（コミットされた読み取り）
	</entry>
	<entry><!--Not possible-->安全
	</entry>
	<entry><!--Possible-->可能性あり
	</entry>
	<entry><!--Possible-->可能性あり
	</entry>
       </row>

       <row>
	<entry><!--Repeatable read-->Repeatable read（繰り返し可能な読み取り）
	</entry>
	<entry><!--Not possible-->安全
	</entry>
	<entry><!--Not possible-->安全
	</entry>
	<entry><!--Possible-->可能性あり
	</entry>
       </row>

       <row>
	<entry><!--Serializable-->Serializable（シリアライザブル）
	</entry>
	<entry><!--Not possible-->安全
	</entry>
	<entry><!--Not possible-->安全
	</entry>
	<entry><!--Not possible-->安全
	</entry>
       </row>
      </tbody>
     </tgroup>
    </table>

   <para>
    <!--<productname>Postgres</productname>
    offers the read committed and serializable isolation levels.-->

    <productname>Postgres</productname>は「Read Committed」と「Serializable」の2つの隔離レベルを備えています。
   </para>
  </sect1>

  <sect1 id="xact-read-committed">
   <!--<title>Read Committed Isolation Level</title>-->
   <title>Read Committed（コミットされた読み取り）隔離レベル</title>
<indexterm><primary>MVCC</primary><secondary sortas="かくりれべる">隔離レベル</secondary><tertiary sortas="こみっとずみ">コミット済み</tertiary></indexterm>
   <para>
    <!--<firstterm>Read Committed</firstterm>
    is the default isolation level in <productname>Postgres</productname>. 
    When a transaction runs on this isolation level,
    a <command>SELECT</command> query sees only data committed before the
    query began and never sees either uncommitted data or changes committed
    during query execution by concurrent transactions.  (However, the
    <command>SELECT</command> does see the effects of previous updates
    executed within this same transaction, even though they are not yet
    committed.)  Notice that two successive <command>SELECT</command>s can see different data,
    even though they are within a single transaction, when other transactions
    commit changes during execution of the first <command>SELECT</command>.-->

    <productname>Postgres</productname>では、<firstterm>Read Committed</firstterm>がデフォルトの隔離レベルに設定されています。トランザクションがこのレベルで実行された場合、<command>SELECT</command>文はこの問い合わせが開始される直前までにコミットされたデータのみであり、コミットされていないデータや、このトランザクションと同時に実行されてデータが変更になったものなどは参照しません（しかし、コミットされていないものでも、同じトランザクションで行われた更新の結果は参照します）。したがって、<command>SELECT</command>文を同じ1つのトランザクションで2回連続実行したとき、もし他のトランザクションが1つ目の<command>SELECT</command>文の最中に変更がコミットされたら、違う結果を返すことに注意してください。
    
   </para>

   <para>
    <!--If a target row found by a query while executing an
    <command>UPDATE</command> statement
    (or <command>DELETE</command> or <command>SELECT FOR UPDATE</command>)
    has already been updated by a
    concurrent uncommitted transaction then the second transaction
    that tries to update this row will wait for the other transaction to
    commit or rollback. In the case of rollback, the waiting transaction
    can proceed to change the row. In the case of commit (and if the
    row still exists; i.e. was not deleted by the other transaction), the
    query will be re-executed for this row to check that the new row
    version still satisfies the query search condition. If the new row version
    satisfies the query search condition then the row will be
    updated (or deleted or marked for update).  Note that the starting point
    for the update will be the new row version; moreover, after the update
    the doubly-updated row is visible to subsequent <command>SELECT</command>s
    in the current transaction.  Thus, the current transaction is able to see
    the effects of the other transaction for this specific row.-->

    <command>UPDATE</command>文、<command>DELETE</command>文、<command>SELECT FOR UPDATE</command>文を実行しようとした際、その条件に該当する列が、同時に実行されている別のトランザクションによってすでに更新されていてしかしまだコミットされていない場合は、後の方のトランザクションは、前のトランザクションがコミットされるかロールバックされるまで待ちます。ロールバックの後のトランザクションは列を更新することができます。前の実行がコミットされ、（なおかつその列がまだ存在する場合、すなわち他のトランザクションによって削除されなかった場合）問い合わせはこの行に対して問い合わせをもう一度実行し、「新しい行」が問い合わせ条件を満たすかどうか確認します。「新しい行」が問い合わせの条件を満たす場合、その行は更新されます（あるいは削除されるか更新マークが付けられます）。「新しい行」のバージョンが今後の更新の対象となります。さらに、その後、2重に更新された行は、同じトランザクションでの<command>SELECT</command>で最新の情報が表示されます。したがって、現在のトランザクションでも別のトランザクションがある特定の行に対して行った更新も表示されます。
   </para>

   <para>
    <!--The partial transaction isolation provided by Read Committed level is
    adequate for many applications, and this level is fast and simple to use.
    However, for applications that do complex queries and updates, it may
    be necessary to guarantee a more rigorously consistent view of the
    database than Read Committed level provides.-->

    リードコミッティドレベルで提供されている部分的なトランザクション隔離は多くのアプリケーションにとって十分なもので、このレベルは高速で使用も容易です。しかし、複雑な問い合わせや更新を行うアプリケーションでは、リードコミッティド隔離レベルで提供される以上にデータベースに対して厳密に一貫性のある見え方を保障する必要があるかもしれません。
   </para>
  </sect1>

  <sect1 id="xact-serializable">
   <!--<title>Serializable Isolation Level</title>-->
   <title>シリアライザブル隔離レベル</title>
<indexterm><primary>MVCC</primary><secondary sortas="かくりれべる">隔離レベル</secondary><tertiary sortas="しりあらいざぶる">シリアライザブル</tertiary></indexterm>
   <para>
    <!--<firstterm>Serializable</firstterm> provides the highest transaction
    isolation.  This level emulates serial transaction execution,
    as if transactions had been executed one after another, serially,
    rather than concurrently.  However, applications using this level must
    be prepared to retry transactions due to serialization failures.-->

    <firstterm>シリアライザブル隔離レベル</firstterm>は、トランザクションの隔離としては最も厳密なものです。このレベルではトランザクションが同時にではなく、次から次へと、あたかも順に実行されているように遂次的なトランザクションの実行を模倣します。しかし、このレベルを使ったアプリケーションでは、直列化の失敗のためにトランザクションを再実行しなければいけないかもしれなくなる情况を考慮しなければなりません。
   </para>

   <para>
    <!--When a transaction is on the serializable level,
    a <command>SELECT</command> query sees only data committed before the
    transaction began and never sees either uncommitted data or changes
    committed
    during transaction execution by concurrent transactions.  (However, the
    <command>SELECT</command> does see the effects of previous updates
    executed within this same transaction, even though they are not yet
    committed.)  This is different from Read Committed in that the
    <command>SELECT</command>
    sees a snapshot as of the start of the transaction, not as of the start
    of the current query within the transaction.-->

    トランザクションがシリアライザブル隔離レベルにあるときに<command>SELECT</command>文を実行したら、トランザクションが開始される前までにコミットされたデータのみを参照し、コミットされていないデータやトランザクション中に別のトランザクションで更新されたデータは参照しません（しかし、<command>SELECT</command>文では同じトランザクションで行われたまだコミットされていないデータを参照します）。<command>SELECT</command>文では、トランザクション内のこの問い合わせが行われ始めた状態ではなく、トランザクションそのものの始まったときの状態のスナップショットで参照するという点でリードコミッティドレベルとは異なっています。

   </para>

   <para>
    <!--If a target row found by a query while executing an
    <command>UPDATE</command> statement
    (or <command>DELETE</command> or <command>SELECT FOR UPDATE</command>)
    has already been updated by a
    concurrent uncommitted transaction then the second transaction
    that tries to update this row will wait for the other transaction to
    commit or rollback. In the case of rollback, the waiting transaction
    can proceed to change the row. In the case of a concurrent
    transaction commit, a serializable transaction will be rolled back
    with the message-->

    <command>UPDATE</command>文、<command>DELETE</command>文、<command>SELECT FOR UPDATE</command>文の処理対象行が同時に実行されている、まだコミットされていないトランザクションによって更新されている場合、後のトランザクションは前のトランザクションが終了してコミットされるか、ロールバックされるまで待ちます。ロールバックされた場合、次に待機しているトランザクションは該当するデータを更新できます。実行がコミットされた場合は、シリアライザブルトランザクションは下記のメッセージを表示してロールバックします。</para>

<programlisting>
ERROR:  Can't serialize access due to concurrent update
</programlisting>

    <!--because a serializable transaction cannot modify rows changed by
    other transactions after the serializable transaction began.-->

<para>これは、シリアライザブルトランザクションでは、トランザクションが実行された後に別のトランザクションによって更新されたデータは更新できないためです。
   </para>

   <para>
    <!--When the application receives this error message, it should abort
    the current transaction and then retry the whole transaction from
    the beginning.  The second time through, the transaction sees the
    previously-committed change as part of its initial view of the database,
    so there is no logical conflict in using the new version of the row
    as the starting point for the new transaction's update.
    Note that only updating transactions may need to be retried - read-only
    transactions never have serialization conflicts.-->

    アプリケーションがこのメッセージを受け取った場合、現在のトランザクションを中断して、すべてのトランザクションを始めからやり直されなければなりません。2回目では、更新トランザクションはコミットされた変更含めてをデータベースの最初の状態とみなすので、新しい行をトランザクションの始点としても、論理的矛盾は起こりません。更新トランザクションのみ再実行する必要があります。読み込み専用トランザクションではシリアライズの衝突は決して起こりません。
   </para>

   <para>
    <!--Serializable transaction level provides a rigorous guarantee that each
    transaction sees a wholly consistent view of the database.  However,
    the application has to be prepared to retry transactions when concurrent
    updates make it impossible to sustain the illusion of serial execution,
    and the cost of redoing complex transactions may be significant.  So
    this level is recommended only when update queries contain logic
    sufficiently complex that they may give wrong answers in Read Committed
    level.-->

    シリアライザブルトランザクションレベルは、すべてのトランザクションが一貫したデータベースの状態を参照できることを保障します。しかし、同時に実行されているトランザクションの更新が、遂次実行の幻想を維持できなくなり、トランザクションを再実行しなければならなくなること、複雑なトランザクションの再実行はかなり手間がかかるかもしれないことを考慮しなければなりません。したがって、このレベルは、リードコミッティドでは誤った結果を表示させてしまう可能性がある、論理的にかなり複雑な問い合わせを実行するときのみに使用することをお勧めします。

   </para>
  </sect1>

  <sect1 id="applevel-consistency">
   <!--<title>Data consistency checks at the application level</title>-->
   <title>アプリケーションレベルでのデータの一貫性チェック</title>
<indexterm><primary>MVCC</primary><secondary sortas="でーたのいっかんせいちぇっく">データの一貫性チェック</secondary></indexterm>
   <para>
    <!--Because readers in <productname>Postgres</productname>
    don't lock data, regardless of
    transaction isolation level, data read by one transaction can be
    overwritten by another concurrent transaction. In other words,
    if a row is returned by <command>SELECT</command> it doesn't mean that
    the row still exists at the time it is returned (i.e. sometime after the
    current transaction began); the row might have been modified or deleted
    by an already-committed transaction that committed after this one started.
    Even if the row is still valid "now", it could be changed or deleted
    before the current transaction does a commit or rollback.-->

    <productname>Postgres</productname>ではreaderデータをロックしないので、トランザクションのレベルに関係なく、あるトランザクションで読み込まれたデータは、同時に実行されているもう一方のトランザクションによって書き変えられる可能性があります。つまり、<command>SELECT</command>で得た行は、その行が返ってきたとき（現在のトランザクションが開始されたあとのある時点）にも存在しているということを意味していません。このトランザクションが開始した後に、その行は別のトランザクションによって更新、または削除され、コミットされている可能性があります。「今」そのデータが有効であっても、現在実行中のトランザクションがコミットする、またはロールバックするまでに変更されたり、削除される可能性があります。
   </para>

   <para>
    <!--Another way to think about it is that each
    transaction sees a snapshot of the database contents, and concurrently
    executing transactions may very well see different snapshots.  So the
    whole concept of "now" is somewhat suspect anyway.  This is not normally
    a big problem if the client applications are isolated from each other,
    but if the clients can communicate via channels outside the database
    then serious confusion may ensue.-->

    また、各々のトランザクションはデータベースの内容のスナップショットを参照していて、同時に実行されているトランザクションでも、違ったスナップショットを参照している可能性があります。したがって、どちらにしても「今」という概念は少々疑わしいものとなります。これは、クライアントアプリケーションが隔離されている場合は大きな問題ではありませんが、クライアントがデータベースの外の世界で何かのチャンネルを使用して通信できる場合は大きな問題となります。
   </para>

   <para>
    <!--To ensure the current existence of a row and protect it against
    concurrent updates one must use <command>SELECT FOR UPDATE</command> or
    an appropriate <command>LOCK TABLE</command> statement.
    (<command>SELECT FOR UPDATE</command> locks just the returned rows against
    concurrent updates, while <command>LOCK TABLE</command> protects the
    whole table.)
    This should be taken into account when porting applications to
    <productname>Postgres</productname> from other environments.-->

    現在存在する行を確実なものとし、同時に起こりうる更新を避けるためには、<command>SELECT FOR UPDATE</command>文や、適切な<command>LOCK TABLE</command>文を使用する必要があります（<command>SELECT FOR UPDATE</command>文は返ってきたデータのみを同時に起こる更新から保護し、<command>LOCK TABLE</command>はテーブル全体を保護します）。これは<productname>Postgres</productname>に他の環境からアプリケーションを移植するときに考慮される必要があります。</para>


    <note>
     <para>
      <!--Before version 6.5 <productname>Postgres</productname>
      used read-locks and so the
      above consideration is also the case
      when upgrading to 6.5 (or higher) from previous
      <productname>Postgres</productname> versions.-->

      <productname>Postgres</productname>バージョン6.5以前のものでは読み込みロックを使用しているので、<productname>Postgres</productname>のバージョン6.5以前のものからバージョンアップする際にも上記の考慮が必要となります。
     </para>
    </note>
  </sect1>

  <sect1 id="locking-tables">
   <!--<title>Locking and Tables</title>-->
   <title>ロックとテーブル</title>
<indexterm><primary>MVCC</primary><secondary sortas="ろっくとてーぶる">ロックとテーブル</secondary></indexterm>
<indexterm><primary sortas="てーぶる">テーブル</primary><secondary sortas="ろっく">ロック</secondary></indexterm>
   <para>
    <!--<productname>Postgres</productname>
    provides various lock modes to control concurrent
    access to data in tables. Some of these lock modes are acquired by
    <productname>Postgres</productname>
    automatically before statement execution, while others are
    provided to be used by applications. All lock modes acquired in a
    transaction are held for the duration 
    of the transaction.-->

    <productname>Postgres</productname>は、テーブル内のデータに対する同時アクセスを制御するためにさまざまな種類のロックモードを備えています。これらのロックの一部は、文の実行前に<productname>Postgres</productname>が自動的に行います。それ以外はアプリケーションで使用します。トランザクション実行時に獲得されたすべてのロックモードは、そのトランザクションが終了されるまで維持されます。
   </para>

   <sect2>
    <!--<title>Table-level locks</title>-->
    <title>テーブルレベルロック</title>
<indexterm><primary>MVCC</primary><secondary sortas="てーぶるれべるろっく">テーブルレベルロック</secondary></indexterm>
     <variablelist>
      <varlistentry>
       <term>
	AccessShareLock
       </term>
       <listitem>
	<para>
	<!--A read-lock mode acquired automatically on tables
	 being queried.-->

         読み込みロックは、テーブルで問い合わせが行われたときに自動的に獲得されます。
	</para>

	<para>
	<!--Conflicts with AccessExclusiveLock only.-->
         AccessExclusiveLockモードのみコンフリクトします。
	</para>
       </listitem>
      </varlistentry>

      <varlistentry>
       <term>
	RowShareLock
       </term>
       <listitem>
	<para>
	<!--Acquired by <command>SELECT FOR UPDATE</command>
	 and <command>LOCK TABLE</command>
	 for <option>IN ROW SHARE MODE</option> statements.-->

         <command>SELECT FOR UPDATE</command>文と、<option>IN ROW SHARE MODE</option>の<command>LOCK TABLE</command>文によって獲得されます。
	</para>

	<para>
	<!--Conflicts with ExclusiveLock and AccessExclusiveLock modes.-->
         ExclusiveLockモード、AccessExclusiveLockモードとコンフリクトします。
	</para>
       </listitem>
      </varlistentry>

      <varlistentry>
       <term>
	RowExclusiveLock
       </term>
       <listitem>
	<para>
	<!--Acquired by <command>UPDATE</command>, <command>DELETE</command>,
	 <command>INSERT</command> and <command>LOCK TABLE</command>
	 for <option>IN ROW EXCLUSIVE MODE</option> statements.-->

         <command>UPDATE</command>、<command>DELETE</command>、<command>INSERT</command>、<command>LOCK TABLE</command>の<option>IN ROW EXCLUSIVE MODE</option>によって獲得されます。
	</para>

	<para>
	<!--Conflicts with ShareLock, ShareRowExclusiveLock, ExclusiveLock and
	 AccessExclusiveLock modes.-->
         ShareLock、ShareRowExclusiveLock、ExclusiveLock、AccessExclusiveLockとコンフリクトします。
	</para>
       </listitem>
      </varlistentry>

      <varlistentry>
       <term>
	ShareLock
       </term>
       <listitem>
	<para>
	<!--Acquired by <command>CREATE INDEX</command>
	 and <command>LOCK TABLE</command> table
	 for <option>IN SHARE MODE</option>
	 statements.-->
         <command>CREATE INDEX</command>、<command>LOCK TABLE</command>テーブルの<option>IN SHARE MODE</option>によって獲得されます。
	</para>

	<para>
	<!--Conflicts with RowExclusiveLock, ShareRowExclusiveLock,
	 ExclusiveLock and AccessExclusiveLock modes.-->
         ExclusiveLock、ShareRowExclusiveLock、ExclusiveLock、AccessExclusiveLockとコンフリクトします。
	</para>
       </listitem>
      </varlistentry>

      <varlistentry>
       <term>
	ShareRowExclusiveLock
       </term>
       <listitem>
	<para>
	<!--Acquired by <command>LOCK TABLE</command> for
	 <option>IN SHARE ROW EXCLUSIVE MODE</option> statements.-->
         <command>LOCK TABLE</command>の<option>IN SHARE ROW EXCLUSIVE MODE</option>によって獲得します。
	</para>

	<para>
	<!--Conflicts with RowExclusiveLock, ShareLock, ShareRowExclusiveLock,
	 ExclusiveLock and AccessExclusiveLock modes.-->
         RowExclusiveLock、ShareLock、ShareRowExclusiveLock、ExclusiveLock、ShareLock、ShareRowExclusiveLockとコンフリクトします。
	</para>
       </listitem>
      </varlistentry>

      <varlistentry>
       <term>
	ExclusiveLock
       </term>
       <listitem>
	<para>
	<!--Acquired by <command>LOCK TABLE</command> table 
	 for <option>IN EXCLUSIVE MODE</option> statements.-->
         <command>LOCK TABLE</command>テーブルの<option>IN EXCLUSIVE MODE</option>によって獲得します。
	</para>

	<para>
	<!--Conflicts with RowShareLock, RowExclusiveLock, ShareLock,
	 ShareRowExclusiveLock, ExclusiveLock and AccessExclusiveLock
	 modes.-->
         RowShareLock、RowExclusiveLock、ShareLock、ShareRowExclusiveLock、ExclusiveLock、AccessExclusiveLockとコンフリクトします。
	</para>
       </listitem>
      </varlistentry>

      <varlistentry>
       <term>
	AccessExclusiveLock
       </term>
       <listitem>
	<para>
	<!--Acquired by <command>ALTER TABLE</command>,
	 <command>DROP TABLE</command>,
	 <command>VACUUM</command> and <command>LOCK TABLE</command>
	 statements.-->
         <command>ALTER TABLE</command>、<command>DROP TABLE</command>、<command>VACUUM</command>、<command>LOCK TABLE</command>によって獲得します。
	</para>

	<para>
	<!--Conflicts with all modes (AccessShareLock, RowShareLock,
	 RowExclusiveLock, ShareLock,
	 ShareRowExclusiveLock, ExclusiveLock and AccessExclusiveLock).-->
         すべてのモード（AccessShareLock、RowShareLock、RowExclusiveLock、ShareLock、ShareRowExclusiveLock、ExclusiveLock、AccessExclusiveLock）とコンフリクトします。
	</para>
       </listitem>
      </varlistentry>
     </variablelist>

     <note>
      <para>
       <!--Only AccessExclusiveLock blocks <command>SELECT</command> (without
       <option>FOR UPDATE</option>) statement.-->
       AccessExclusiveLockだけが<command>SELECT</command>（<option>FOR UPDATE</option>なし）をブロックします。

      </para>
     </note>
   </sect2>

   <sect2>
    <title>行レベルロック（Row-level locks）</title>
<indexterm><primary>MVCC</primary><secondary sortas="ぎょうれべるろっく">行レベルロック</secondary></indexterm>
    <para>
     <!--These locks are acquired when rows are being updated (or deleted or
     marked for update).
     Row-level locks don't affect data querying. They block
     writers to <emphasis>the same row</emphasis> only.-->

     行レベルロックは、行が更新されたとき（または削除、更新のために印が付けられたとき）に獲得されます。行レベルロックはデータの問い合わせに影響を与えません。<emphasis>同じ行</emphasis>への書き込みのみを阻止します。
    </para>

    <para>
     <!--<productname>Postgres</productname>
     doesn't remember any information about modified rows in memory and
     so has no limit to the number of rows locked at one time.  However,
     locking a row may cause a disk write; thus, for example,
     <command>SELECT FOR UPDATE</command> will modify
     selected rows to mark them and so will result in disk writes.-->

     <productname>Postgres</productname>は、メモリに変更された行の情報を記憶してませんので、同時にロックできる行数の上限はありません。しかし、行をロックする際に、ディスクに書き込む作業が発生するかもしれません。したがって、たとえば<command>SELECT FOR UPDATE</command>は選択された行に、印を付けるように変更させ、ディスクにそのことを書き込むことになります。
    </para>

    <para>
    <!--In addition to table and row locks, short-term share/exclusive locks are
    used to control read/write access to table pages in the shared buffer
    pool.  These locks are released immediately after a tuple is fetched or
    updated.  Application writers normally need not be concerned with
    page-level locks, but we mention them for completeness.-->
    テーブルと行ロックに加え、短期の共有/排他ロック（share/exclusive lock）があり、これらは共有バッファプールにあるテーブルページへの読み書きのアクセスを管理するために使用されます。これらのロックはタプルが取得されたときや更新されたときに、即座に解除されます。アプリケーション開発者は特にページレベルロックを考慮する必要はありません。
   </para>
   </sect2>
  </sect1>

  <sect1 id="locking-indices">
   <!--<title>Locking and Indices</title>-->
   <title>ロックとインデックス</title>
<indexterm><primary>MVCC</primary><secondary sortas="ろっくといんでっくす">ロックとインデックス</secondary></indexterm>
   <para>
    <!--Though <productname>Postgres</productname>
    provides nonblocking read/write access to table
    data, nonblocking read/write access is not currently offered for every
    index access method implemented
    in <productname>Postgres</productname>.-->

    <productname>Postgres</productname>は、テーブルデータへの「ノンブロック読み込み/書き込みアクセス」を備えています。しかし現在、この機能は<productname>Postgres</productname>で実装されているすべてのインデックスアクセスメソッドに対して実装されているわけではありません。
   </para>

   <para>
    <!--The various index types are handled as follows:-->
    あらゆるインデックス型は下記のように扱われます。
</para>

    <variablelist>
     <varlistentry>
      <term>
       <!--GiST and R-Tree indices-->
       GiSTとR-Treeインデックス
      </term>
      <listitem>
       <para>
	<!--Share/exclusive index-level locks are used for read/write access.
	Locks are released after statement is done.-->
        読み込み／書き込みアクセスに共有／排他モードのインデックスレベルロックを使います。ロックは文の処理完了後に解放されます。
       </para>
      </listitem>
     </varlistentry>

     <varlistentry>
      <term>
       <!--Hash indices-->
       ハッシュインデックス
      </term>
      <listitem>
       <para>
	<!--Share/exclusive page-level locks are used for read/write access.
	Locks are released after page is processed.-->
        読み込み/書き込みアクセスに共有/排他モードのページレベルロックを使います。ロックはページ処理後に解放されます。
       </para>

       <para>
	<!--Page-level locks provide better concurrency than index-level ones
	but are subject to deadlocks.-->
        ページレベルロックは、インデックスレベルのロックよりも同時実行性に優れていますが、デッドロックも起きやすくなります。
       </para>
      </listitem>
     </varlistentry>

     <varlistentry>
      <term>
       <!--Btree indices-->
       B-treeインデックス
      </term>
      <listitem>
       <para>
	<!--Short-term share/exclusive page-level locks are used for
	read/write access. Locks are released immediately after each index
	tuple is fetched/inserted.-->

        読み込み/書き込みアクセスに共有/排他モードのページレベルラッチを使います。ラッチはインデックスのタプルが挿入/取り出しされるとただちに解放されます。
       </para>

       <para>
	<!--Btree indices provide the highest concurrency without deadlock
	conditions.-->
        B-treeインデックスは、デッドロック状態になることなく、最も高い同時実行性を提供します。
       </para>
      </listitem>
     </varlistentry>
    </variablelist>

   <para>
    <!--In short, btree indices are the recommended index type for concurrent
    applications.-->
    つまり、B-treeインデックスは並列実行アプリケーションに推奨されます。
   </para>
  </sect1>
 </chapter>

<!-- Keep this comment at the end of the file
Local variables:
mode:sgml
sgml-omittag:nil
sgml-shorttag:t
sgml-minimize-attributes:nil
sgml-always-quote-attributes:t
sgml-indent-step:1
sgml-indent-data:t
sgml-parent-document:nil
sgml-default-dtd-file:"./reference.ced"
sgml-exposed-tags:nil
sgml-local-catalogs:("/usr/lib/sgml/catalog")
sgml-local-ecat-files:nil
End:
-->
