Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
P
Postgres FD Implementation
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Abuhujair Javed
Postgres FD Implementation
Commits
a37ab1d3
Commit
a37ab1d3
authored
Oct 11, 2000
by
Tom Lane
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Improve MVCC discussion.
parent
6fec2160
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
146 additions
and
97 deletions
+146
-97
doc/src/sgml/mvcc.sgml
doc/src/sgml/mvcc.sgml
+146
-97
No files found.
doc/src/sgml/mvcc.sgml
View file @
a37ab1d3
<!--
<!--
$Header: /cvsroot/pgsql/doc/src/sgml/mvcc.sgml,v 2.
8 2000/09/29 20:21:34 petere
Exp $
$Header: /cvsroot/pgsql/doc/src/sgml/mvcc.sgml,v 2.
9 2000/10/11 17:38:36 tgl
Exp $
-->
-->
<chapter id="mvcc">
<chapter id="mvcc">
...
@@ -70,7 +70,8 @@ $Header: /cvsroot/pgsql/doc/src/sgml/mvcc.sgml,v 2.8 2000/09/29 20:21:34 petere
...
@@ -70,7 +70,8 @@ $Header: /cvsroot/pgsql/doc/src/sgml/mvcc.sgml,v 2.8 2000/09/29 20:21:34 petere
<listitem>
<listitem>
<para>
<para>
A transaction re-reads data it has previously read and finds that data
A transaction re-reads data it has previously read and finds that data
has been modified by another committed transaction.
has been modified by another transaction (that committed since the
initial read).
</para>
</para>
</listitem>
</listitem>
</varlistentry>
</varlistentry>
...
@@ -82,8 +83,8 @@ $Header: /cvsroot/pgsql/doc/src/sgml/mvcc.sgml,v 2.8 2000/09/29 20:21:34 petere
...
@@ -82,8 +83,8 @@ $Header: /cvsroot/pgsql/doc/src/sgml/mvcc.sgml,v 2.8 2000/09/29 20:21:34 petere
<listitem>
<listitem>
<para>
<para>
A transaction re-executes a query returning a set of rows that satisfy a
A transaction re-executes a query returning a set of rows that satisfy a
search condition and finds that
additional
rows satisfying the condition
search condition and finds that
the set of
rows satisfying the condition
has
been inserted by another
committed transaction.
has
changed due to another recently-
committed transaction.
</para>
</para>
</listitem>
</listitem>
</varlistentry>
</varlistentry>
...
@@ -175,7 +176,9 @@ $Header: /cvsroot/pgsql/doc/src/sgml/mvcc.sgml,v 2.8 2000/09/29 20:21:34 petere
...
@@ -175,7 +176,9 @@ $Header: /cvsroot/pgsql/doc/src/sgml/mvcc.sgml,v 2.8 2000/09/29 20:21:34 petere
</tbody>
</tbody>
</tgroup>
</tgroup>
</table>
</table>
</para>
<para>
<productname>Postgres</productname>
<productname>Postgres</productname>
offers the read committed and serializable isolation levels.
offers the read committed and serializable isolation levels.
</para>
</para>
...
@@ -187,32 +190,40 @@ $Header: /cvsroot/pgsql/doc/src/sgml/mvcc.sgml,v 2.8 2000/09/29 20:21:34 petere
...
@@ -187,32 +190,40 @@ $Header: /cvsroot/pgsql/doc/src/sgml/mvcc.sgml,v 2.8 2000/09/29 20:21:34 petere
<para>
<para>
<firstterm>Read Committed</firstterm>
<firstterm>Read Committed</firstterm>
is the default isolation level in <productname>Postgres</productname>.
is the default isolation level in <productname>Postgres</productname>.
When a transaction runs on this isolation level, a query sees only
When a transaction runs on this isolation level,
data committed before the query began and never sees either dirty data or
a <command>SELECT</command> query sees only data committed before the
concurrent transaction changes committed during query execution.
transaction began and never sees either dirty data or concurrent
transaction changes committed during transaction execution. (However, the
<command>SELECT</command> does see the effects of previous updates
executed within this same transaction.)
</para>
</para>
<para>
<para>
If a
row returne
d by a query while executing an
If a
target row foun
d by a query while executing an
<command>UPDATE</command> statement
<command>UPDATE</command> statement
(or <command>DELETE</command>
(or <command>DELETE</command> or <command>SELECT FOR UPDATE</command>)
or <command>SELECT FOR UPDATE</command>)
has already been updated by a
is being updated by a
concurrent uncommitted transaction then the second transaction
concurrent uncommitted transaction then the second transaction
that tries to update this row will wait for the other transaction to
that tries to update this row will wait for the other transaction to
commit or rollback. In the case of rollback, the waiting transaction
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
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
row still exists; i.e. was not deleted by the other transaction), the
query will be re-executed for this row to check that new row
query will be re-executed for this row to check that the new row
version satisfies query search condition. If the new row version
version still satisfies the query search condition. If the new row version
satisfies the query search condition then row will be
satisfies the query search condition then the row will be
updated (or deleted or marked for update).
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.
</para>
</para>
<para>
<para>
Note that the results of execution of <command>SELECT</command>
The partial transaction isolation provided by Read Committed level is
or <command>INSERT</command> (with a query)
adequate for many applications, and this level is fast and simple to use.
statements will not be affected by concurrent transactions.
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>
</para>
</sect1>
</sect1>
...
@@ -220,22 +231,29 @@ $Header: /cvsroot/pgsql/doc/src/sgml/mvcc.sgml,v 2.8 2000/09/29 20:21:34 petere
...
@@ -220,22 +231,29 @@ $Header: /cvsroot/pgsql/doc/src/sgml/mvcc.sgml,v 2.8 2000/09/29 20:21:34 petere
<title>Serializable Isolation Level</title>
<title>Serializable Isolation Level</title>
<para>
<para>
<firstterm>Serializable</firstterm> provides the highest transaction isolation.
<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.
</para>
<para>
When a transaction is on the serializable level,
When a transaction is on the serializable level,
a
query sees only data
a
<command>SELECT</command> query sees only data committed before the
committed before the transaction began and never see either dirty data
transaction began and never sees either dirty data or concurrent
or concurrent transaction changes committed during transaction
transaction changes committed during transaction execution. (However, the
execution. So, this level emulates serial transaction execution,
<command>SELECT</command> does see the effects of previous updates
as if transactions would be executed one after another, serially,
executed within this same transaction.) This is the same behavior as
rather than concurrently
.
for Read Committed level
.
</para>
</para>
<para>
<para>
If a
row returned by query while executing a
If a
target row found by a query while executing an
<command>UPDATE</command>
<command>UPDATE</command>
statement
(or <command>DELETE</command> or <command>SELECT FOR UPDATE</command>)
(or <command>DELETE</command> or <command>SELECT FOR UPDATE</command>)
statement is being updated by
has already been updated by a
a
concurrent uncommitted transaction then the second transaction
concurrent uncommitted transaction then the second transaction
that tries to update this row will wait for the other transaction to
that tries to update this row will wait for the other transaction to
commit or rollback. In the case of rollback, the waiting transaction
commit or rollback. In the case of rollback, the waiting transaction
can proceed to change the row. In the case of a concurrent
can proceed to change the row. In the case of a concurrent
...
@@ -250,13 +268,75 @@ ERROR: Can't serialize access due to concurrent update
...
@@ -250,13 +268,75 @@ ERROR: Can't serialize access due to concurrent update
other transactions after the serializable transaction began.
other transactions after the serializable transaction began.
</para>
</para>
<note>
<para>
<para>
When the application receives this error message, it should abort
Note that results of execution of <command>SELECT</command>
the current transaction and then retry the whole transaction from
or <command>INSERT</command> (with a query)
the beginning. The second time through, the transaction sees the
will not be affected by concurrent transactions.
previously-committed change as part of its initial view of the database,
</para>
so there is no logical conflict in using the new version of the row
</note>
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.
</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 it may give wrong answers in Read Committed
level.
</para>
</sect1>
<sect1 id="applevel-consistency">
<title>Data consistency checks at the application level</title>
<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.
</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.
<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.
</para>
</note>
</para>
</sect1>
</sect1>
<sect1 id="locking-tables">
<sect1 id="locking-tables">
...
@@ -268,17 +348,11 @@ ERROR: Can't serialize access due to concurrent update
...
@@ -268,17 +348,11 @@ ERROR: Can't serialize access due to concurrent update
access to data in tables. Some of these lock modes are acquired by
access to data in tables. Some of these lock modes are acquired by
<productname>Postgres</productname>
<productname>Postgres</productname>
automatically before statement execution, while others are
automatically before statement execution, while others are
provided to be used by applications. All lock modes
(except for
provided to be used by applications. All lock modes
acquired in a
AccessShareLock) acquired in a transaction are held for the duration
transaction are held for the duration
of the transaction.
of the transaction.
</para>
</para>
<para>
In addition to locks, short-term share/exclusive latches are used
to control read/write access to table pages in shared buffer pool.
Latches are released immediately after a tuple is fetched or updated.
</para>
<sect2>
<sect2>
<title>Table-level locks</title>
<title>Table-level locks</title>
...
@@ -290,10 +364,8 @@ ERROR: Can't serialize access due to concurrent update
...
@@ -290,10 +364,8 @@ ERROR: Can't serialize access due to concurrent update
</term>
</term>
<listitem>
<listitem>
<para>
<para>
An internal lock mode acquiring automatically over tables
A read-lock mode acquired automatically on tables
being queried. <productname>Postgres</productname>
being queried.
releases these locks after statement is
done.
</para>
</para>
<para>
<para>
...
@@ -425,22 +497,28 @@ ERROR: Can't serialize access due to concurrent update
...
@@ -425,22 +497,28 @@ ERROR: Can't serialize access due to concurrent update
<title>Row-level locks</title>
<title>Row-level locks</title>
<para>
<para>
These locks are acquired when internal
These locks are acquired when rows are being updated (or deleted or
fields of a row are being updated (or deleted or marked for update).
marked for update).
<productname>Postgres</productname>
Row-level locks don't affect data querying. They block
doesn't remember any information about modified rows in memory and
writers to <emphasis>the same row</emphasis> only.
so has no limit to the number of rows locked without lock escalation.
</para>
</para>
<para>
<para>
However, take into account that <command>SELECT FOR UPDATE</command> will modify
<productname>Postgres</productname>
selected rows to mark them and so will results in disk writes.
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.
</para>
</para>
<para>
<para>
Row-level locks don't affect data querying. They are used to block
In addition to table and row locks, short-term share/exclusive locks are
writers to <emphasis>the same row</emphasis> only.
used to control read/write access to table pages in the shared buffer
</para>
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.
</para>
</sect2>
</sect2>
</sect1>
</sect1>
...
@@ -449,9 +527,9 @@ ERROR: Can't serialize access due to concurrent update
...
@@ -449,9 +527,9 @@ ERROR: Can't serialize access due to concurrent update
<para>
<para>
Though <productname>Postgres</productname>
Though <productname>Postgres</productname>
provides
u
nblocking read/write access to table
provides
no
nblocking read/write access to table
data,
unblocked read/write access is not provid
ed for every
data,
nonblocking read/write access is not currently offer
ed for every
index access method
s
implemented
index access method implemented
in <productname>Postgres</productname>.
in <productname>Postgres</productname>.
</para>
</para>
...
@@ -482,7 +560,7 @@ ERROR: Can't serialize access due to concurrent update
...
@@ -482,7 +560,7 @@ ERROR: Can't serialize access due to concurrent update
</para>
</para>
<para>
<para>
Page-level locks pro
duces
better concurrency than index-level ones
Page-level locks pro
vide
better concurrency than index-level ones
but are subject to deadlocks.
but are subject to deadlocks.
</para>
</para>
</listitem>
</listitem>
...
@@ -490,13 +568,13 @@ ERROR: Can't serialize access due to concurrent update
...
@@ -490,13 +568,13 @@ ERROR: Can't serialize access due to concurrent update
<varlistentry>
<varlistentry>
<term>
<term>
Btree
Btree
indices
</term>
</term>
<listitem>
<listitem>
<para>
<para>
Short-term share/exclusive page-level l
atche
s are used for
Short-term share/exclusive page-level l
ock
s are used for
read/write access. L
atches are released immediately after the
index
read/write access. L
ocks are released immediately after each
index
tuple is
inserted/fetch
ed.
tuple is
fetched/insert
ed.
</para>
</para>
<para>
<para>
...
@@ -507,39 +585,10 @@ ERROR: Can't serialize access due to concurrent update
...
@@ -507,39 +585,10 @@ ERROR: Can't serialize access due to concurrent update
</varlistentry>
</varlistentry>
</variablelist>
</variablelist>
</para>
</para>
</sect1>
<sect1 id="applevel-consistency">
<title>Data consistency checks at the application level</title>
<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. In the other words, if a row is returned
by <command>SELECT</command> it doesn't mean that this row really
exists at the time it is returned (i.e. sometime after the
statement or transaction began) nor
that the row is protected from deletion or update by concurrent
transactions before the current transaction does a commit or rollback.
</para>
<para>
<para>
To ensure the actual existance of a row and protect it against
In short, btree indices are the recommended index type for concurrent
concurrent updates one must use <command>SELECT FOR UPDATE</command> or
applications.
an appropriate <command>LOCK TABLE</command> statement.
This should be taken into account when porting applications using
serializable mode to <productname>Postgres</productname> from other environments.
<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.
</para>
</note>
</para>
</para>
</sect1>
</sect1>
</chapter>
</chapter>
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment