Subject: Additional Chapter for Tutorial

From: Jürgen Purtz <[email-masked]>
Date: Fri, 17 Apr 2020 19:56:08 +0200

Our documentation explains many details about commands, tools, 
parameters in detail and with high accuracy. Nevertheless my impression 
is that we neglect the 'big picture': why certain processes exist and 
what their relation to each other is, summary of strategies, 
visualization of key situations, ... . People with mature knowledge 
don't miss this information because they know all about it. But for 
beginners such explanations would be a great help. In the time before 
GSoD 2019 we had similar discussions.

I plan to extend over time the part 'Tutorial' by an additional chapter 
with an overview about key design decisions and basic features. The 
typical audience should consist of persons with limited pre-knowledge in 
database systems and some interest in PostgreSQL. In the attachment you 
find a patch for the first sub-chapter. Subsequent sub-chapters should 
be: MVCC, transactions, VACUUM, backup, replication, ... - mostly with 
the focus on the PostgreSQL implementation and not on generic topics 
like b-trees.

There is a predecessor of this patch: 
https://www.postgresql.org/message-id/974e09b8-edf5-f38f-2fb5-a5875782ffc9%40purtz.de 
. In the meanwhile its glossary-part is separated and commited. The new 
patch contains two elements: textual descriptions and 4 figures. My 
opinion concerning figures is set out in detail in the previous patch.

Kind regards, Jürgen Purtz

diff --git a/doc/src/sgml/advanced.sgml b/doc/src/sgml/advanced.sgml
index ae5f3fac75..965eb751c0 100644
--- a/doc/src/sgml/advanced.sgml
+++ b/doc/src/sgml/advanced.sgml
@@ -1,7 +1,7 @@
 <!-- doc/src/sgml/advanced.sgml -->
 
  <chapter id="tutorial-advanced">
-  <title>Advanced Features</title>
+  <title>Advanced SQL Features</title>
 
   <sect1 id="tutorial-advanced-intro">
    <title>Introduction</title>
diff --git a/doc/src/sgml/architecture.sgml b/doc/src/sgml/architecture.sgml
new file mode 100644
index 0000000000..bbed0c3466
--- /dev/null
+++ b/doc/src/sgml/architecture.sgml
@@ -0,0 +1,449 @@
+<!-- doc/src/sgml/architecture.sgml -->
+
+ <chapter id="tutorial-architecture">
+  <title>The Architecture</title>
+
+  <para>
+   Every DBMS implements basic strategies to achieve a fast and
+   robust system. This chapter provides an overview of what
+   techniques <productname>PostgreSQL</productname> uses to
+   reach this aim.
+  </para>
+
+  <sect1 id="tutorial-ram-proc-file">
+   <title>Collabortion of Processes, RAM, and Files</title>
+   <para>
+    As is a matter of course, in a client/server architecture
+    clients do not have direct access to the database. Instead,
+    they merely send requests to the server side and receives
+    resulting information from there. In the case of
+    <productname>PostgreSQL</productname>, at the server
+    side there is one process per client, the so-called
+    <glossterm linkend="glossary-backend">Backend process</glossterm>.
+    He acts in close cooperation with the
+    <glossterm linkend="glossary-instance">Instance</glossterm> which
+    is a group of tightly coupled other server side processes plus a
+    <glossterm linkend="glossary-shared-memory">Shared Memory</glossterm>
+    area.
+   </para>
+
+   <para>
+    At start time, an instance is initiated by the
+    <glossterm linkend="glossary-postmaster">Postmaster</glossterm> process.
+    He loads the configuration files, allocates the
+    <firstterm>Shared Memory</firstterm>
+    and starts the comprehensive network of processes:
+    <glossterm linkend="glossary-background-writer">Background Writer</glossterm>,
+    <glossterm linkend="glossary-checkpointer">Checkpointer</glossterm>,
+    <glossterm linkend="glossary-wal-writer">WAL Writer</glossterm>,
+    <glossterm linkend="glossary-wal-archiver">WAL Archiver</glossterm>,
+    <glossterm linkend="glossary-autovacuum">Autovacuum processes</glossterm>,
+    <glossterm linkend="glossary-stats-collector">Statistics Collector</glossterm>,
+    <glossterm linkend="glossary-logger">Logger</glossterm>, and more.
+    <xref linkend="tutorial-ram-proc-file-figure"/> visualizes
+    main aspects of their collaboration.
+   </para>
+
+   <figure id="tutorial-ram-proc-file-figure">
+    <title>Architecture</title>
+    <mediaobject>
+     <imageobject role="html">
+      <!-- attribute 'width=..px' is necessary to keep font-size of SVG text
+           in correlation with font-size of surrounding HTML  -->
+      <imagedata fileref="images/ram-proc-file-raw.svg" format="SVG" width="900px" />
+     </imageobject>
+     <imageobject role="fo">
+      <!-- For PDF attribute 'width=100%' is necessary to keep complete SVG visible
+           on the page, which has a fixed width. Font sizes will be adopted.  -->
+      <imagedata fileref="images/ram-proc-file-raw.svg" format="SVG" width="100%" />
+     </imageobject>
+    </mediaobject>
+   </figure>
+
+   <para>
+    Whenever a client application tries to connect to a
+    <glossterm linkend="glossary-database">database</glossterm>, this request is handled
+    in a first step by the <firstterm>Postmaster
+    process</firstterm>. He checks the authorization, starts a
+    new <firstterm>Backend process</firstterm>,
+    and instructs the client application to connect to him. All further
+    client requests go to this process and are handled
+    by him.
+   </para>
+
+   <para>
+    Client requests (SELECT, UPDATE, ...) usually leads to the
+    necessity to read or write some data. In an first attempt
+    the client's <firstterm>Backend process</firstterm> tries
+    to get the information out of <firstterm>Shared
+    Memory</firstterm>. This <firstterm>Shared
+    Memory</firstterm> is a mirror of parts of the
+    <glossterm linkend="glossary-heap">heap</glossterm> and
+    <glossterm linkend="glossary-index">index</glossterm> files. Because files are
+    much huger than memory, it's likely that
+    the desired information is not (completely) available
+    in the RAM. In this case the <firstterm>Backend process
+    </firstterm> must transfer additional file pages to
+    <firstterm>Shared Memory</firstterm>. Files are physically
+    organized in pages. Every transfer between files and
+    RAM is performed in units of complete pages while retaining
+    their size and layout.
+   </para>
+
+   <para>
+    Reading file pages is notedly slower than reading
+    RAM. This is the main motivation for the existence of
+    <firstterm>Shared Memory</firstterm>. As soon as one
+    of the <firstterm>Backend processes</firstterm> has done
+    the job those pages are available for all other
+    <firstterm>Backend processes</firstterm> for direct
+    access in RAM.
+   </para>
+
+   <para>
+    <firstterm>Shared Memory</firstterm> is limited in size.
+    Sooner or later it is necessary to overwrite old RAM
+    pages. As long as the content of such pages hasn't
+    changed this is not a problem. But in
+    <firstterm>Shared Memory</firstterm> also write
+    actions take place
+    - performed by any of the <firstterm>Backend
+    processes</firstterm> (or an
+    <glossterm linkend="glossary-autovacuum">autovacuum process</glossterm>,
+    or other processes). Such modified pages are called
+    <firstterm>dirty pages</firstterm>.
+    Before <firstterm>dirty pages</firstterm> can be overwritten,
+    they must be transfered back to disk. This is a two-step process.
+   </para>
+
+   <para>
+    First, whenever the content of a page changes, a
+    <glossterm linkend="glossary-wal-record">WAL record</glossterm> is created out
+    of the delta-information (difference between old and
+    new content) and stored in another area of the
+    <firstterm>Shared Memory</firstterm>. These
+    <firstterm>WAL records</firstterm> are read by the
+    <firstterm>WAL Writer</firstterm> process,
+    who runs in parallel to the <firstterm>Backend
+    processes</firstterm> and all other processes of
+    the <firstterm>Instance</firstterm>. He writes
+    the continuously arising <firstterm>WAL records</firstterm> to
+    the end of the current
+    <glossterm linkend="glossary-wal-record">WAL file</glossterm>.
+    Because of the sequential nature of this writing, it is much
+    faster than the more or less random access
+    to data files with <firstterm>heap</firstterm>
+    and <firstterm>index</firstterm> information.
+    As mentioned, this WAL-writing happens
+    in an independent process. Nevertheless all
+    <firstterm>WAL records</firstterm> created out of one
+    <firstterm>dirty page</firstterm> must be transfered
+    to disk before the <firstterm>dirty page</firstterm>
+    itself can be transfered to disk (???).
+   </para>
+
+   <para>
+    Second, the transfer of <firstterm>dirty pages</firstterm>
+    from <firstterm>Shared Memory</firstterm> to files must
+    take place. This is the primarily duty of the
+    <firstterm>Background Writer</firstterm> process. Because
+    huge I/O activities can block other processes significantly,
+    he starts periodically and acts only for a short period.
+    Doing so, his expensive I/O activities are spread over
+    time avoiding huge I/O peaks. Also the <firstterm>
+    Checkpointer</firstterm> process transfers
+    <firstterm>dirty pages</firstterm> to files, see next
+    paragraph.
+   </para>
+
+   <para>
+    The <firstterm>Checkpointer</firstterm> has a special
+    duty. As its name suggests, he has to create
+    <firstterm>Checkpoints</firstterm>. Such a
+    <glossterm linkend="glossary-checkpoint">Checkpoint</glossterm> is a point in time
+    when all older <firstterm>dirty pages</firstterm>,
+    all older <firstterm>WAL records</firstterm>, and
+    lastly a special <firstterm>Checkpoint record
+    </firstterm> have been written and flushed to disk.
+    In consequence, after a <firstterm>Checkpoint</firstterm>
+    data files and <firstterm>WAL files</firstterm> are in sync.
+    In case of a recovery (after a crash of the instance)
+    it is known that the information of all
+    <firstterm>WAL records</firstterm> preceding
+    the last <firstterm>Checkpoint record</firstterm>
+    is already integrated into the data files. This
+    speeds up a possibly occurring recovery.
+   </para>
+
+   <para>
+    In correlation with data changes,
+    <firstterm>WAL records</firstterm> arise and are writen
+    to <firstterm>WAL files</firstterm>.
+    Those <firstterm>WAL files</firstterm> - in combination with
+    a previously taken <firstterm>Base Backup</firstterm> -
+    are necessary to restore a database after a crash of the
+    disk, where data files have been stored. Therefore it is
+    recommended to transfer a copy of the <firstterm>
+    WAL files</firstterm>
+    to a second, independent place. The purpose of the
+    <firstterm>WAL Archiver</firstterm> process is to perform
+    this copy action.
+   </para>
+
+   <para>
+    The <glossterm linkend="glossary-stats-collector">Stats Collector</glossterm>
+    collects counter about accesses to <firstterm>SQL
+    objects</firstterm> like tables, rows, indexes, pages,
+    and others. He stores the obtained information in system
+    tables.
+   </para>
+
+   <para>
+    The <glossterm linkend="glossary-logger">Logger</glossterm> writes
+    text lines about serious and non-serious events which can happen
+    during database access, e.g.: wrong password, no permission,
+    long-running queries, ... .
+   </para>
+
+  </sect1>
+
+  <sect1 id="tutorial-cluster-db-schema">
+   <title>Cluster, Database, Schema</title>
+
+   <para>
+    On a <glossterm linkend="glossary-server">Server</glossterm>
+    exists one or more <glossterm linkend="glossary-cluster">Cluster</glossterm>,
+    each of them contains three or more
+    <glossterm linkend="glossary-database">databases</glossterm>, each
+    database contains many <glossterm linkend="glossary-schema">schema</glossterm>,
+    a schema contains <glossterm linkend="glossary-table">tables</glossterm>,
+    <glossterm linkend="glossary-view">views</glossterm>, and a lot of other objects.
+    Each <firstterm>table</firstterm> or <firstterm>view</firstterm>
+    belongs to a certain <firstterm>schema</firstterm>, they cannot
+    belong to another <firstterm>schema</firstterm>. The same is
+    true for the schema/database and database/cluster relation.
+    <xref linkend="tutorial-cluster-db-schema-figure"/> visualizes
+    this hierarchy.
+   </para>
+
+   <figure id="tutorial-cluster-db-schema-figure">
+    <title>Cluster, Database, Schema</title>
+    <mediaobject>
+     <imageobject role="html">
+      <!-- attribute 'width=..px' is necessary to keep font-size of SVG text
+           in correlation with font-size of surrounding HTML  -->
+      <imagedata fileref="images/cluster-db-schema-raw.svg" format="SVG" width="900px" />
+     </imageobject>
+     <imageobject role="fo">
+      <!-- For PDF attribute 'width=100%' is necessary to keep complete SVG visible
+           on the page, which has a fixed width. Font sizes will be adopted.  -->
+      <imagedata fileref="images/cluster-db-schema-raw.svg" format="SVG" width="100%" />
+     </imageobject>
+    </mediaobject>
+   </figure>
+
+   <para>
+    A <firstterm>Cluster</firstterm> is the outer frame for a
+    collection of databases. Clusters are created by the command
+    <xref linkend="app-initdb"/>.
+   </para>
+
+   <para>
+    <literal>template0</literal> is the very first
+    <firstterm>database</firstterm> of any
+    <firstterm>cluster</firstterm>. C-routines create
+    <literal>template0</literal> during the initialization phase of
+    the <firstterm>cluster</firstterm>.
+    In a second step <literal>template1</literal> is generated
+    as a copy of <literal>template0</literal> and finally
+    <literal>postgres</literal> as a copy of
+    <literal>template1</literal>. All other
+    <glossterm linkend="app-createdb">new databases</glossterm>
+    of this <firstterm>cluster</firstterm>,
+    such as <literal>my_db</literal>, are also copied from
+    <literal>template1</literal>. Due to the special
+    role of <literal>template0</literal> as the origin
+    of all other <firstterm>databases</firstterm>, no client
+    can connect to it.
+   </para>
+
+   <para>
+    Every database contains <glossterm linkend="glossary-schema">
+    schemas</glossterm>, and
+    <firstterm>schemas</firstterm> contain the other
+    <glossterm linkend="glossary-sql-object">SQL Objects</glossterm>.
+    <firstterm>Schemas</firstterm> are namespaces for
+    their <firstterm>SQL objects</firstterm> and ensure - with one
+    exception - that within their scope names are used only once across all
+    types of <firstterm>SQL objects</firstterm>. E.g.: it is not possible
+    to have a table <literal>employee</literal> and a view
+    <literal>employee</literal> within the same
+    <firstterm>schema</firstterm>. But it is possible to have
+    two tables <literal>employee</literal> in different
+    <firstterm>schemas</firstterm>. In this case the two tables
+    are different objects and absolutely independent from each
+    other. The only exception to this cross-type uniqueness is that
+    <glossterm linkend="glossary-unique-constraint">unique constraints
+    </glossterm> and the according <firstterm>unique index</firstterm>
+    use the same name.
+   </para>
+
+   <para>
+    Some <firstterm>schemas</firstterm> are predefined.
+    <literal>public</literal> acts as the default
+    <firstterm>schema</firstterm> and contains all such
+    <firstterm>SQL objects</firstterm>, which are created
+    within <literal>public</literal> or without using any schema
+    name. <literal>public</literal> shall not contain user defined
+    <firstterm>SQL objects</firstterm>. Instead, it is recommended to
+    create a separate <firstterm>schema</firstterm> which
+    holds individual objects like application-specific tables or
+    views. <literal>pg_catalog</literal> is a schema for all tables
+    and views of the <glossterm linkend="glossary-system-catalog">
+    System Catalog</glossterm>.
+    <literal>information_schema</literal> is a schema for several
+    tables and views of the <firstterm>System Catalog</firstterm>
+    in a way which conforms to the SQL standard.
+   </para>
+
+   <para>
+    There are a lot of different <firstterm>SQL object</firstterm>
+    types: <firstterm>database, schema, table, view, materialized
+    view, index, constraint, sequence, function, procedure,
+    trigger, role, data type, operator, tablespace, extension,
+    foreign data wrapper</firstterm>, and more. A few of them, the
+    <glossterm linkend="glossary-global-sql-object">Global SQL Objects</glossterm>,
+    are outside of the strict hierarchy: 
+    All database names, all tablespace names, and all role names
+    are automatically known and available throughout the
+    complete <firstterm>cluster</firstterm>, independent from
+    the database or schema in which they where originally
+    defined. <xref linkend="tutorial-internal-objects-hierarchy-figure"/>
+    shows the relation between the object types.
+   </para>
+
+   <figure id="tutorial-internal-objects-hierarchy-figure">
+    <title>Hierarchy of Internal Objects</title>
+    <mediaobject>
+     <imageobject role="html">
+      <!-- attribute 'width=..px' is necessary to keep font-size of SVG text
+           in correlation with font-size of surrounding HTML  -->
+      <imagedata fileref="images/internal-objects-hierarchy-raw.svg" format="SVG" width="720px" />
+     </imageobject>
+     <imageobject role="fo">
+      <!-- For PDF attribute 'width=100%' is necessary to keep complete SVG visible
+           on the page, which has a fixed width. Font sizes will be adopted.  -->
+      <imagedata fileref="images/internal-objects-hierarchy-raw.svg" format="SVG" width="100%" />
+     </imageobject>
+    </mediaobject>
+   </figure>
+
+  </sect1>
+
+  <sect1 id="tutorial-directories">
+   <title>Directory Structure</title>
+
+   <para>
+    <productname>PostgreSQL</productname> organizes long lasting
+    data as well as volatile state information about transactions
+    or replication actions in the file system. Every
+    <firstterm>Cluster</firstterm> has its own root directory
+    anywhere in the file system. In many cases, the environment
+    variable <literal>PGDATA</literal> points to this directory.
+    The example of the following survey, which is shown in
+    <xref linkend="tutorial-directories-figure"/>, uses
+    <literal>data</literal> as the name of this root directory.
+   </para>
+
+   <figure id="tutorial-directories-figure">
+    <title>Directory Structure</title>
+    <mediaobject>
+     <imageobject role="html">
+      <!-- attribute 'width=..px' is necessary to keep font-size of SVG text
+           in correlation with font-size of surrounding HTML  -->
+      <imagedata fileref="images/directories-raw.svg" format="SVG" width="900px" />
+     </imageobject>
+     <imageobject role="fo">
+      <!-- For PDF attribute 'width=100%' is necessary to keep complete SVG visible
+           on the page, which has a fixed width. Font sizes will be adopted.  -->
+      <imagedata fileref="images/directories-raw.svg" format="SVG" width="100%" />
+     </imageobject>
+    </mediaobject>
+   </figure>
+
+   <para>
+    <literal>data</literal> contains many subdirectories and
+    some files, all of which are necessary to store long lasting
+    as well as temporary data. The following paragraphs
+    describe the files and subdirectories in
+    <literal>data</literal>.
+   </para>
+
+   <para>
+    <literal>base</literal> is a subdirectory in which one
+    subdirectory per <firstterm>database</firstterm> exists.
+    The names of those sudirectories consists of numbers.
+    These are the internal
+    <firstterm>Object Identifiers (OID)</firstterm>, which are
+    numbers to identify the database definition in the
+    <glossterm linkend="glossary-system-catalog">System Catalog</glossterm>.
+   </para>
+
+   <para>
+    Within the <firstterm>database</firstterm>-specific
+    subdirectories there are many files. Primarily they contain
+    the <firstterm>heap</firstterm> and <firstterm>
+    index</firstterm>. But there are also optimization information
+    like <link linkend="storage-fsm">Free Space Maps</link> or
+    <link linkend="storage-vm">Visibility Maps</link>.
+   </para>
+
+   <para>
+    Another important subdirectory is <literal>global</literal>.
+    In analogy to the <firstterm>database</firstterm>-specific
+    subdirectories, there are files containing information about
+    <glossterm linkend="glossary-global-sql-object">Global SQL objects</glossterm>.
+    One type
+ of such <firstterm>Global Objects</firstterm> are
+    <firstterm>tablespaces</firstterm>. In
+    <literal>global</literal> there are information about
+    the <firstterm>tablespaces</firstterm>, not the
+    <firstterm>tablespaces</firstterm> itself.
+   </para>
+
+   <para>
+    The subdirectory <literal>pg_wal</literal> contains the
+    <glossterm linkend="glossary-wal-file">WAL files</glossterm>.
+    They arise and grow parallel to data changes in the
+    <firstterm>cluster</firstterm> and remain alive as long as
+    they are required for recovery, archiving, or replication.
+   </para>
+
+   <para>
+    The subdirectory <literal>pg_xact</literal> contains
+    information about the status of each transaction
+    (IN_PROGRESS, COMMITTED, ABORTED, or SUB_COMMITTED).
+   </para>
+
+   <para>
+    In <literal>pg_tblspc</literal> there are symbolic links
+    that point to directories containing such<firstterm>
+    SQL objects</firstterm> that are created within
+    <firstterm>tablespaces</firstterm>.
+   </para>
+
+   <para>
+    In the directory <literal>data</literal>
+    there are also some files.
+    In many cases, the configuration
+    files of this <firstterm>cluster</firstterm>
+    are stored here. As long as the <firstterm>
+    cluster</firstterm> is up and running, the file
+    <literal>postmaster.pid</literal> exists here
+    and contains the ID of the
+    <firstterm>Postmaster</firstterm> process.
+   </para>
+
+  </sect1>
+
+ </chapter>
diff --git a/doc/src/sgml/filelist.sgml b/doc/src/sgml/filelist.sgml
index 68179f71cd..ca29c8bc4e 100644
--- a/doc/src/sgml/filelist.sgml
+++ b/doc/src/sgml/filelist.sgml
@@ -8,9 +8,10 @@
 <!ENTITY problems   SYSTEM "problems.sgml">
 
 <!-- tutorial -->
-<!ENTITY advanced   SYSTEM "advanced.sgml">
-<!ENTITY query      SYSTEM "query.sgml">
-<!ENTITY start      SYSTEM "start.sgml">
+<!ENTITY start         SYSTEM "start.sgml">
+<!ENTITY architecture  SYSTEM "architecture.sgml">
+<!ENTITY query         SYSTEM "query.sgml">
+<!ENTITY advanced      SYSTEM "advanced.sgml">
 
 <!-- user's guide -->
 <!ENTITY array      SYSTEM "array.sgml">
diff --git a/doc/src/sgml/glossary.sgml b/doc/src/sgml/glossary.sgml
index 8c6cb6e942..25762b7c3a 100644
--- a/doc/src/sgml/glossary.sgml
+++ b/doc/src/sgml/glossary.sgml
@@ -208,15 +208,6 @@
    </glossdef>
   </glossentry>
 
-  <glossentry id="glossary-checkpointer">
-   <glossterm>Checkpointer (process)</glossterm>
-   <glossdef>
-    <para>
-     A specialized process responsible for executing checkpoints.
-    </para>
-   </glossdef>
-  </glossentry>
-
   <glossentry id="glossary-checkpoint">
    <glossterm>Checkpoint</glossterm>
    <glossdef>
@@ -244,6 +235,15 @@
    </glossdef>
   </glossentry>
 
+  <glossentry id="glossary-checkpointer">
+   <glossterm>Checkpointer (process)</glossterm>
+   <glossdef>
+    <para>
+     A specialized process responsible for executing checkpoints.
+    </para>
+   </glossdef>
+  </glossentry>
+
   <glossentry>
    <glossterm>Class (archaic)</glossterm>
    <glosssee otherterm="glossary-relation" />
@@ -761,25 +761,6 @@
    </glossdef>
   </glossentry>
 
-  <glossentry id="glossary-logger">
-   <glossterm>Logger (process)</glossterm>
-   <glossdef>
-    <para>
-     If activated, the
-     <glossterm linkend="glossary-logger">Logger</glossterm> process
-     writes information about database events into the current
-     <glossterm linkend="glossary-log-file">log file</glossterm>.
-     When reaching certain time- or
-     volume-dependent criteria, a new log file is created.
-     Also called <firstterm>syslogger</firstterm>.
-    </para>
-    <para>
-     For more information, see
-     <xref linkend="runtime-config-logging"/>.
-    </para>
-   </glossdef>
-  </glossentry>
-
   <glossentry id="glossary-log-record">
    <glossterm>Log Record</glossterm>
     <glossdef>
@@ -803,6 +784,25 @@
    </glossdef>
   </glossentry>
 
+  <glossentry id="glossary-logger">
+   <glossterm>Logger (process)</glossterm>
+   <glossdef>
+    <para>
+     If activated, the
+     <glossterm linkend="glossary-logger">Logger</glossterm> process
+     writes information about database events into the current
+     <glossterm linkend="glossary-log-file">log file</glossterm>.
+     When reaching certain time- or
+     volume-dependent criteria, a new log file is created.
+     Also called <firstterm>syslogger</firstterm>.
+    </para>
+    <para>
+     For more information, see
+     <xref linkend="runtime-config-logging"/>.
+    </para>
+   </glossdef>
+  </glossentry>
+
   <glossentry>
    <glossterm>Master (server)</glossterm>
    <glosssee otherterm="glossary-primary-server" />
@@ -1651,6 +1651,11 @@
    </glossdef>
   </glossentry>
 
+  <glossentry>
+   <glossterm>WAL</glossterm>
+   <glosssee otherterm="glossary-wal" />
+  </glossentry>
+
   <glossentry id="glossary-wal-archiver">
    <glossterm>WAL Archiver (process)</glossterm>
    <glossdef>
@@ -1696,11 +1701,6 @@
    </glossdef>
   </glossentry>
 
-  <glossentry>
-   <glossterm>WAL</glossterm>
-   <glosssee otherterm="glossary-wal" />
-  </glossentry>
-
   <glossentry id="glossary-wal-record">
    <glossterm>WAL Record</glossterm>
    <glossdef>
@@ -1728,8 +1728,8 @@
   <glossdef>
    <para>
     A process that writes <glossterm linkend="glossary-wal-record">WAL records</glossterm>
-    from <glossterm id="linkend-shared-memory">shared memory</glossterm> to
-    <glossterm id="linkend-wal-file">WAL files</glossterm>.
+    from <glossterm linkend="glossary-shared-memory">shared memory</glossterm> to
+    <glossterm linkend="glossary-wal-file">WAL files</glossterm>.
    </para>
    <para>
     For more information, see
diff --git a/doc/src/sgml/images/cluster-db-schema-ink-svgo.svg b/doc/src/sgml/images/cluster-db-schema-ink-svgo.svg
new file mode 100644
index 0000000000..6acb2b69fe
--- /dev/null
+++ b/doc/src/sgml/images/cluster-db-schema-ink-svgo.svg
@@ -0,0 +1,160 @@
+<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="900" height="685" viewBox="0 0 900 685">
+  <title>
+    Server (Hardware, Container, or VM)
+  </title>
+  <style>
+    .text_normal,.text_small{font-style:normal;font-weight:400;font-family:&quot;Open Sans&quot;,sans-serif;fill:#000}.text_small{font-size:12px}.text_normal{font-size:16px}
+  </style>
+  <defs>
+    <symbol id="rectangles_special_0">
+      <rect width="225" height="155" rx="10" stroke="blue" fill="none"/>
+      <rect x="15" y="40" width="195" height="50" rx="10" stroke="blue" fill="none" stroke-dasharray="4 2"/>
+      <text class="text_normal" x="20" y="60">
+        schema &apos;public&apos;
+      </text>
+      <text class="text_small" x="20" y="80">
+        tables, views, ...
+      </text>
+      <rect x="15" y="105" width="195" height="30" rx="10" stroke="blue" fill="none" stroke-dasharray="4 2"/>
+      <text class="text_small" x="20" y="125">
+        (more system schemas)
+      </text>
+    </symbol>
+    <symbol id="rectangles_special_1">
+      <rect width="245" height="225" rx="10" stroke="blue" fill="none"/>
+      <rect x="15" y="40" width="205" height="50" rx="10" stroke="blue" fill="none" stroke-dasharray="4 2"/>
+      <text class="text_normal" x="20" y="60">
+        schema &apos;public&apos;
+      </text>
+      <text class="text_small" x="20" y="80">
+        tables, views, ...
+      </text>
+      <rect x="15" y="105" width="205" height="50" rx="10" stroke="blue" fill="none" stroke-dasharray="4 2"/>
+      <text class="text_normal" x="20" y="125">
+        &apos;my_schema&apos; (optional)
+      </text>
+      <text class="text_small" x="20" y="145">
+        tables, views, ...
+      </text>
+      <rect x="15" y="170" width="205" height="30" rx="10" stroke="blue" fill="none" stroke-dasharray="4 2"/>
+      <text class="text_small" x="20" y="190">
+        (more system schemas)
+      </text>
+    </symbol>
+    <symbol id="note" stroke="black" fill="lightyellow">
+      <title>
+        UML Note
+      </title>
+      <path d="M450 10v230H0V0h440v10h10L440 0"/>
+    </symbol>
+    <marker id="arrowhead_end" markerWidth="10" markerHeight="10" refX="6" refY="3" orient="auto">
+      <path d="M0 0l6 3-6 3" stroke="black" fill="none"/>
+    </marker>
+  </defs>
+  <rect x="1" y="1" rx="5" width="99%" height="99%" stroke="black" fill="none"/>
+  <text x="270" y="40" font-weight="400" font-size="24" font-family="&quot;Open Sans&quot;,sans-serif">
+    Server (Hardware, Container, or VM)
+  </text>
+  <path stroke="blue" stroke-width="2" fill="none" d="M20 110h790v555H20z"/>
+  <text class="text_normal" x="180" y="25" transform="translate(20 110)">
+    cluster &apos;data&apos; (default, managed by one instance)
+  </text>
+  <path d="M50 110V80h790v555h-30" stroke="blue" stroke-width="2" fill="none"/>
+  <text class="text_normal" x="190" y="-10" transform="translate(45 110)">
+    cluster &apos;cluster_2&apos; (optional, managed by a different instance)
+  </text>
+  <g transform="translate(40 155)">
+    <use xlink:href="#rectangles_special_0"/>
+    <text class="text_normal" x="10" y="25">
+      database &apos;template0&apos;
+    </text>
+  </g>
+  <g transform="translate(290 155)">
+    <use xlink:href="#rectangles_special_0"/>
+    <text class="text_normal" x="10" y="25">
+      database &apos;template1&apos;
+    </text>
+  </g>
+  <g transform="translate(540 155)">
+    <use xlink:href="#rectangles_special_1"/>
+    <text class="text_normal" x="10" y="25">
+      database &apos;postgres&apos;
+    </text>
+  </g>
+  <g transform="translate(40 350)">
+    <use xlink:href="#rectangles_special_1"/>
+    <text class="text_normal" x="10" y="25">
+      database &apos;my_db&apos; (optional)
+    </text>
+  </g>
+  <g transform="translate(320 330)">
+    <rect width="180" height="45" rx="10" stroke="blue" fill="none" stroke-dasharray="10 4 4 4"/>
+    <text class="text_normal" x="15" y="27">
+      Global SQL objects
+    </text>
+    <path d="M0 5l-65-35" stroke="black" fill="none" marker-end="url(#arrowhead_end)"/>
+    <path d="M80 0v-30" stroke="black" fill="none" marker-end="url(#arrowhead_end)"/>
+    <path d="M180 40h50" stroke="black" fill="none" marker-end="url(#arrowhead_end)"/>
+    <path d="M0 40l-45 20" stroke="black" fill="none" marker-end="url(#arrowhead_end)"/>
+  </g>
+  <g transform="translate(335 405)">
+    <use xlink:href="#note"/>
+    <text class="text_small" x="10" y="20">
+      1)
+    </text>
+    <text class="text_small" x="30" y="20">
+      By default, you work in the cluster &apos;data&apos;, database &apos;postgres&apos;,
+    </text>
+    <text class="text_small" x="30" y="35">
+      schema &apos;public&apos;.
+    </text>
+    <text class="text_small" x="10" y="55">
+      2)
+    </text>
+    <text class="text_small" x="30" y="55">
+      More system schemas: pg_catalog, information_schema,
+    </text>
+    <text class="text_small" x="30" y="70">
+      pg_temp, pg_toast.
+    </text>
+    <text class="text_small" x="10" y="90">
+      3)
+    </text>
+    <text class="text_small" x="30" y="90">
+      Global SQL objects: Some SQL objects are automatically active
+    </text>
+    <text class="text_small" x="30" y="105">
+      and known database- or even cluster-wide.
+    </text>
+    <text class="text_small" x="10" y="125">
+      4)
+    </text>
+    <text class="text_small" x="30" y="125">
+      The command &apos;initdb&apos; creates a new cluster with the three
+    </text>
+    <text class="text_small" x="30" y="140">
+      databases &apos;template0&apos;, &apos;template1&apos;, and &apos;postgres&apos;. The command
+    </text>
+    <text class="text_small" x="30" y="155">
+      &apos;createdb&apos; creates a new database.
+    </text>
+    <text class="text_small" x="10" y="175">
+      5)
+    </text>
+    <text class="text_small" x="30" y="175">
+      If multiple clusters are active on one server at the same time,
+    </text>
+    <text class="text_small" x="30" y="190">
+      each one is managed by an individual instance. Each such instance
+    </text>
+    <text class="text_small" x="30" y="205">
+      uses a different port.
+    </text>
+    <text class="text_small" x="10" y="225">
+      6)
+    </text>
+    <text class="text_small" x="30" y="225">
+      No client application is allowed to connect to &apos;template0&apos;.
+    </text>
+  </g>
+</svg>
diff --git a/doc/src/sgml/images/cluster-db-schema-ink.svg b/doc/src/sgml/images/cluster-db-schema-ink.svg
new file mode 100644
index 0000000000..a70fbe2102
--- /dev/null
+++ b/doc/src/sgml/images/cluster-db-schema-ink.svg
@@ -0,0 +1,482 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://creativecommons.org/ns#"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:xlink="http://www.w3.org/1999/xlink"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   version="1.1"
+   width="900px"
+   height="685px"
+   viewBox="0 0 900 685"
+   id="svg147"
+   sodipodi:docname="cluster-db-schema-ink.svg"
+   inkscape:version="0.92.3 (2405546, 2018-03-11)">
+  <metadata
+     id="metadata151">
+    <rdf:RDF>
+      <cc:Work
+         rdf:about="">
+        <dc:format>image/svg+xml</dc:format>
+        <dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+        <dc:title>Server (Hardware, Container, or VM)</dc:title>
+      </cc:Work>
+    </rdf:RDF>
+  </metadata>
+  <sodipodi:namedview
+     pagecolor="#ffffff"
+     bordercolor="#666666"
+     borderopacity="1"
+     objecttolerance="10"
+     gridtolerance="10"
+     guidetolerance="10"
+     inkscape:pageopacity="0"
+     inkscape:pageshadow="2"
+     inkscape:window-width="640"
+     inkscape:window-height="480"
+     id="namedview149"
+     showgrid="false"
+     inkscape:zoom="0.34452555"
+     inkscape:cx="450"
+     inkscape:cy="342.5"
+     inkscape:window-x="61"
+     inkscape:window-y="27"
+     inkscape:window-maximized="0"
+     inkscape:current-layer="svg147" />
+  <title
+     id="title2">Server (Hardware, Container, or VM)</title>
+  <!-- common text classes -->
+  <style
+     type="text/css"
+     id="style4">
+  .text_small   {font-style:normal;
+                 font-weight:normal;
+                 font-size:12px;
+                 font-family:&quot;Open Sans&quot;, sans-serif;
+                 fill:black;
+                }
+  .text_normal  {font-style:normal;
+                 font-weight:normal;
+                 font-size:16px;
+                 font-family:&quot;Open Sans&quot;, sans-serif;
+                 fill:black;
+                }
+  .text_big     {font-style:normal;
+                 font-weight:normal;
+                 font-size:24px;
+                 font-family:&quot;Open Sans&quot;, sans-serif;
+                 fill:black;
+                }
+  </style>
+  <defs
+     id="defs49">
+    <!--  a rectangle with rounded corners and inner definitions for schemas  -->
+    <symbol
+       id="rectangles_special_0">
+      <!--  the database  -->
+      <rect
+         width="225"
+         height="155"
+         rx="10"
+         stroke="blue"
+         fill="none"
+         id="rect6" />
+      <!--  schemas  -->
+      <rect
+         x="15"
+         y="40"
+         width="195"
+         height="50"
+         rx="10"
+         stroke="blue"
+         fill="none"
+         stroke-dasharray="4 2"
+         id="rect8" />
+      <text
+         class="text_normal"
+         x="20"
+         y="60"
+         id="text10">schema 'public'</text>
+      <text
+         class="text_small"
+         x="20"
+         y="80"
+         id="text12">tables, views, ...</text>
+      <rect
+         x="15"
+         y="105"
+         width="195"
+         height="30"
+         rx="10"
+         stroke="blue"
+         fill="none"
+         stroke-dasharray="4 2"
+         id="rect14" />
+      <text
+         class="text_small"
+         x="20"
+         y="125"
+         id="text16">(more system schemas)</text>
+    </symbol>
+    <!--  same as before, but one more schema  -->
+    <symbol
+       id="rectangles_special_1">
+      <!--  the database  -->
+      <rect
+         width="245"
+         height="225"
+         rx="10"
+         stroke="blue"
+         fill="none"
+         id="rect19" />
+      <!--  schemas  -->
+      <rect
+         x="15"
+         y="40"
+         width="205"
+         height="50"
+         rx="10"
+         stroke="blue"
+         fill="none"
+         stroke-dasharray="4 2"
+         id="rect21" />
+      <text
+         class="text_normal"
+         x="20"
+         y="60"
+         id="text23">schema 'public'</text>
+      <text
+         class="text_small"
+         x="20"
+         y="80"
+         id="text25">tables, views, ...</text>
+      <rect
+         x="15"
+         y="105"
+         width="205"
+         height="50"
+         rx="10"
+         stroke="blue"
+         fill="none"
+         stroke-dasharray="4 2"
+         id="rect27" />
+      <text
+         class="text_normal"
+         x="20"
+         y="125"
+         id="text29">'my_schema' (optional)</text>
+      <text
+         class="text_small"
+         x="20"
+         y="145"
+         id="text31">tables, views, ...</text>
+      <rect
+         x="15"
+         y="170"
+         width="205"
+         height="30"
+         rx="10"
+         stroke="blue"
+         fill="none"
+         stroke-dasharray="4 2"
+         id="rect33" />
+      <text
+         class="text_small"
+         x="20"
+         y="190"
+         id="text35">(more system schemas)</text>
+    </symbol>
+    <symbol
+       id="note"
+       stroke="black"
+       fill="lightyellow">
+      <title
+         id="title38">UML Note</title>
+      <path
+         d="M 450,10 v 230 h -450 v -240 h 440 v 10 h 10 l -10,-10"
+         id="path40" />
+    </symbol>
+    <!--  marker start/end -->
+    <marker
+       id="arrowhead_start"
+       markerWidth="10"
+       markerHeight="10"
+       refX="0"
+       refY="3"
+       orient="auto">
+      <path
+         d="M 6,0 l -6,3 l 6,3"
+         stroke="black"
+         fill="none"
+         id="path43" />
+    </marker>
+    <marker
+       id="arrowhead_end"
+       markerWidth="10"
+       markerHeight="10"
+       refX="6"
+       refY="3"
+       orient="auto">
+      <path
+         d="M 0,0 l 6,3 l -6,3"
+         stroke="black"
+         fill="none"
+         id="path46" />
+    </marker>
+  </defs>
+  <!--  start of rendering area  -->
+  <!--  enclosing rectangle  -->
+  <rect
+     x="1"
+     y="1"
+     rx="5"
+     width="99%"
+     height="99%"
+     stroke="black"
+     fill="none"
+     id="rect51" />
+  <text
+     class="text_big"
+     x="270"
+     y="40"
+     id="text53">Server (Hardware, Container, or VM)</text>
+  <!--  two clusters  -->
+  <g
+     transform="translate(20 110)"
+     id="g59">
+    <rect
+       x="0"
+       y="0"
+       width="790"
+       height="555"
+       stroke="blue"
+       stroke-width="2px"
+       fill="none"
+       id="rect55" />
+    <text
+       class="text_normal"
+       x="180"
+       y="25"
+       id="text57">cluster 'data' (default, managed by one instance)</text>
+  </g>
+  <g
+     transform="translate(45 110)"
+     id="g65">
+    <path
+       d="M 5,0 v -30 h 790 v 555 h -30"
+       stroke="blue"
+       stroke-width="2px"
+       fill="none"
+       id="path61" />
+    <text
+       class="text_normal"
+       x="190"
+       y="-10"
+       id="text63">cluster 'cluster_2' (optional, managed by a different instance)</text>
+  </g>
+  <!--  database template 0  -->
+  <g
+     transform="translate(40 155)"
+     id="g71">
+    <use
+       xlink:href="#rectangles_special_0"
+       id="use67" />
+    <text
+       class="text_normal"
+       x="10"
+       y="25"
+       id="text69">database 'template0'</text>
+  </g>
+  <!--  database template 1  -->
+  <g
+     transform="translate(290 155)"
+     id="g77">
+    <use
+       xlink:href="#rectangles_special_0"
+       id="use73" />
+    <text
+       class="text_normal"
+       x="10"
+       y="25"
+       id="text75">database 'template1'</text>
+  </g>
+  <!--  database postgres  -->
+  <g
+     transform="translate(540 155)"
+     id="g83">
+    <use
+       xlink:href="#rectangles_special_1"
+       id="use79" />
+    <text
+       class="text_normal"
+       x="10"
+       y="25"
+       id="text81">database 'postgres'</text>
+  </g>
+  <!--  database my_db  -->
+  <g
+     transform="translate(40 350)"
+     id="g89">
+    <use
+       xlink:href="#rectangles_special_1"
+       id="use85" />
+    <text
+       class="text_normal"
+       x="10"
+       y="25"
+       id="text87">database 'my_db' (optional)</text>
+  </g>
+  <!--  global objects  -->
+  <g
+     transform="translate(320 330)"
+     id="g103">
+    <rect
+       x="0"
+       y="0"
+       width="180"
+       height="45"
+       rx="10"
+       stroke="blue"
+       fill="none"
+       stroke-dasharray="10 4 4 4"
+       id="rect91" />
+    <text
+       class="text_normal"
+       x="15"
+       y="27"
+       id="text93">Global SQL objects</text>
+    <path
+       d="M 0,5 l-65,-35"
+       stroke="black"
+       fill="none"
+       marker-end="url(#arrowhead_end)"
+       id="path95" />
+    <path
+       d="M 80,0 v-30"
+       stroke="black"
+       fill="none"
+       marker-end="url(#arrowhead_end)"
+       id="path97" />
+    <path
+       d="M 180,40 h50"
+       stroke="black"
+       fill="none"
+       marker-end="url(#arrowhead_end)"
+       id="path99" />
+    <path
+       d="M 0,40 l-45,20"
+       stroke="black"
+       fill="none"
+       marker-end="url(#arrowhead_end)"
+       id="path101" />
+  </g>
+  <!--  Some comments  -->
+  <g
+     transform="translate(335 405)"
+     id="g145">
+    <use
+       xlink:href="#note"
+       x="0"
+       y="0"
+       id="use105" />
+    <text
+       class="text_small"
+       x="10"
+       y="20"
+       id="text107">1)</text>
+    <text
+       class="text_small"
+       x="30"
+       y="20"
+       id="text109">By default, you work in the cluster 'data', database 'postgres',</text>
+    <text
+       class="text_small"
+       x="30"
+       y="35"
+       id="text111">schema 'public'.</text>
+    <text
+       class="text_small"
+       x="10"
+       y="55"
+       id="text113">2)</text>
+    <text
+       class="text_small"
+       x="30"
+       y="55"
+       id="text115">More system schemas: pg_catalog, information_schema,</text>
+    <text
+       class="text_small"
+       x="30"
+       y="70"
+       id="text117">pg_temp, pg_toast.</text>
+    <text
+       class="text_small"
+       x="10"
+       y="90"
+       id="text119">3)</text>
+    <text
+       class="text_small"
+       x="30"
+       y="90"
+       id="text121">Global SQL objects: Some SQL objects are automatically active</text>
+    <text
+       class="text_small"
+       x="30"
+       y="105"
+       id="text123">and known database- or even cluster-wide.</text>
+    <text
+       class="text_small"
+       x="10"
+       y="125"
+       id="text125">4)</text>
+    <text
+       class="text_small"
+       x="30"
+       y="125"
+       id="text127">The command 'initdb' creates a new cluster with the three</text>
+    <text
+       class="text_small"
+       x="30"
+       y="140"
+       id="text129">databases 'template0', 'template1', and 'postgres'. The command</text>
+    <text
+       class="text_small"
+       x="30"
+       y="155"
+       id="text131">'createdb' creates a new database.</text>
+    <text
+       class="text_small"
+       x="10"
+       y="175"
+       id="text133">5)</text>
+    <text
+       class="text_small"
+       x="30"
+       y="175"
+       id="text135">If multiple clusters are active on one server at the same time,</text>
+    <text
+       class="text_small"
+       x="30"
+       y="190"
+       id="text137">each one is managed by an individual instance. Each such instance</text>
+    <text
+       class="text_small"
+       x="30"
+       y="205"
+       id="text139">uses a different port.</text>
+    <text
+       class="text_small"
+       x="10"
+       y="225"
+       id="text141">6)</text>
+    <text
+       class="text_small"
+       x="30"
+       y="225"
+       id="text143">No client application is allowed to connect to 'template0'.</text>
+  </g>
+</svg>
diff --git a/doc/src/sgml/images/cluster-db-schema-raw.svg b/doc/src/sgml/images/cluster-db-schema-raw.svg
new file mode 100644
index 0000000000..a4919165e2
--- /dev/null
+++ b/doc/src/sgml/images/cluster-db-schema-raw.svg
@@ -0,0 +1,173 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<svg xmlns="http://www.w3.org/2000/svg"
+     xmlns:xlink="http://www.w3.org/1999/xlink"
+     version="1.1"
+     width="900px" height="685px"
+     viewBox="0 0 900 685" >
+
+  <title>Server (Hardware, Container, or VM)</title>
+
+  <!-- common text classes -->
+  <style type="text/css">
+  .text_small   {font-style:normal;
+                 font-weight:normal;
+                 font-size:12px;
+                 font-family:"Open Sans", sans-serif;
+                 fill:black;
+                }
+  .text_normal  {font-style:normal;
+                 font-weight:normal;
+                 font-size:16px;
+                 font-family:"Open Sans", sans-serif;
+                 fill:black;
+                }
+  .text_big     {font-style:normal;
+                 font-weight:normal;
+                 font-size:24px;
+                 font-family:"Open Sans", sans-serif;
+                 fill:black;
+                }
+  </style>
+
+  <defs>
+    <!--  a rectangle with rounded corners and inner definitions for schemas  -->
+    <symbol id="rectangles_special_0">
+
+      <!--  the database  -->
+      <rect width="225" height="155" rx="10" stroke="blue" fill="none"/>
+
+      <!--  schemas  -->
+      <rect x="15" y="40" width="195" height="50" rx="10" stroke="blue" fill="none" stroke-dasharray="4 2" />
+      <text class="text_normal" x="20" y="60">schema 'public'</text>
+      <text class="text_small"  x="20" y="80">tables, views, ...</text>
+
+      <rect x="15" y="105" width="195" height="30" rx="10" stroke="blue" fill="none" stroke-dasharray="4 2" />
+      <text class="text_small"  x="20" y="125">(more system schemas)</text>
+    </symbol>
+
+    <!--  same as before, but one more schema  -->
+    <symbol id="rectangles_special_1">
+      <!--  the database  -->
+      <rect width="245" height="225" rx="10" stroke="blue" fill="none"/>
+
+      <!--  schemas  -->
+      <rect x="15" y="40" width="205" height="50" rx="10" stroke="blue" fill="none" stroke-dasharray="4 2" />
+      <text class="text_normal" x="20" y="60">schema 'public'</text>
+      <text class="text_small"  x="20" y="80">tables, views, ...</text>
+
+      <rect x="15" y="105" width="205" height="50" rx="10" stroke="blue" fill="none" stroke-dasharray="4 2" />
+      <text class="text_normal" x="20" y="125">'my_schema' (optional)</text>
+      <text class="text_small"  x="20" y="145">tables, views, ...</text>
+
+      <rect x="15" y="170" width="205" height="30" rx="10" stroke="blue" fill="none" stroke-dasharray="4 2" />
+      <text class="text_small"  x="20" y="190">(more system schemas)</text>
+    </symbol>
+
+    <symbol id="note" stroke="black" fill="lightyellow">
+      <title>UML Note</title>
+      <path d="M 450,10 v 230 h -450 v -240 h 440 v 10 h 10 l -10,-10" />
+    </symbol>
+
+    <!--  marker start/end -->
+    <marker id="arrowhead_start"
+            markerWidth="10"
+            markerHeight="10"
+            refX="0"
+            refY="3"
+            orient="auto">
+      <path d="M 6,0 l -6,3 l 6,3" stroke="black" fill="none" />
+    </marker>
+    <marker id="arrowhead_end"
+            markerWidth="10"
+            markerHeight="10"
+            refX="6"
+            refY="3"
+            orient="auto">
+      <path d="M 0,0 l 6,3 l -6,3" stroke="black" fill="none" />
+    </marker>
+
+  </defs>
+
+
+  <!--  start of rendering area  -->
+  <!--  enclosing rectangle  -->
+  <rect x="1" y="1" rx="5" width="99%" height="99%" stroke="black" fill="none" />
+  <text class="text_big" x="270" y="40">Server (Hardware, Container, or VM)</text>
+
+  <!--  two clusters  -->
+  <g transform="translate(20 110)">
+    <rect  x="0" y="0" width="790" height="555" stroke="blue" stroke-width="2px" fill="none" />
+    <text class="text_normal" x="180" y="25">cluster 'data' (default, managed by one instance)</text>
+  </g>
+  <g transform="translate(45 110)">
+    <path d="M 5,0 v -30 h 790 v 555 h -30" stroke="blue" stroke-width="2px" fill="none" />
+    <text class="text_normal" x="190" y="-10">cluster 'cluster_2' (optional, managed by a different instance)</text>
+  </g>
+
+
+  <!--  database template 0  -->
+  <g transform="translate(40 155)">
+    <use xlink:href="#rectangles_special_0" />
+    <text class="text_normal" x="10" y="25">database 'template0'</text>
+  </g>
+
+  <!--  database template 1  -->
+  <g transform="translate(290 155)">
+    <use xlink:href="#rectangles_special_0" />
+    <text class="text_normal" x="10" y="25">database 'template1'</text>
+  </g>
+
+  <!--  database postgres  -->
+  <g transform="translate(540 155)">
+    <use xlink:href="#rectangles_special_1" />
+    <text class="text_normal" x="10" y="25">database 'postgres'</text>
+  </g>
+
+  <!--  database my_db  -->
+  <g transform="translate(40 350)">
+    <use xlink:href="#rectangles_special_1" />
+    <text class="text_normal" x="10" y="25">database 'my_db' (optional)</text>
+  </g>
+
+  <!--  global objects  -->
+  <g transform="translate(320 330)">
+    <rect x="0" y="0" width="180" height="45" rx="10" stroke="blue" fill="none" stroke-dasharray="10 4 4 4" />
+    <text class="text_normal" x="15" y="27">Global SQL objects</text>
+    <path d="M 0,5 l-65,-35" stroke="black" fill="none" marker-end="url(#arrowhead_end)" />
+    <path d="M 80,0 v-30" stroke="black" fill="none" marker-end="url(#arrowhead_end)" />
+    <path d="M 180,40 h50" stroke="black" fill="none" marker-end="url(#arrowhead_end)" />
+    <path d="M 0,40 l-45,20" stroke="black" fill="none" marker-end="url(#arrowhead_end)" />
+  </g>
+
+  <!--  Some comments  -->
+  <g transform="translate(335 405)">
+    <use xlink:href="#note" x="0" y="0" />
+
+    <text class="text_small" x="10" y="20">1)</text>
+    <text class="text_small" x="30" y="20">By default, you work in the cluster 'data', database 'postgres',</text>
+    <text class="text_small" x="30" y="35">schema 'public'.</text>
+
+    <text class="text_small" x="10" y="55">2)</text>
+    <text class="text_small" x="30" y="55">More system schemas: pg_catalog, information_schema,</text>
+    <text class="text_small" x="30" y="70">pg_temp, pg_toast.</text>
+
+    <text class="text_small" x="10" y="90">3)</text>
+    <text class="text_small" x="30" y="90">Global SQL objects: Some SQL objects are automatically active</text>
+    <text class="text_small" x="30" y="105">and known database- or even cluster-wide.</text>
+
+    <text class="text_small" x="10" y="125">4)</text>
+    <text class="text_small" x="30" y="125">The command 'initdb' creates a new cluster with the three</text>
+    <text class="text_small" x="30" y="140">databases 'template0', 'template1', and 'postgres'. The command</text>
+    <text class="text_small" x="30" y="155">'createdb' creates a new database.</text>
+
+    <text class="text_small" x="10" y="175">5)</text>
+    <text class="text_small" x="30" y="175">If multiple clusters are active on one server at the same time,</text>
+    <text class="text_small" x="30" y="190">each one is managed by an individual instance. Each such instance</text>
+    <text class="text_small" x="30" y="205">uses a different port.</text>
+
+    <text class="text_small" x="10" y="225">6)</text>
+    <text class="text_small" x="30" y="225">No client application is allowed to connect to 'template0'.</text>
+
+  </g>
+
+</svg>
diff --git a/doc/src/sgml/images/directories-ink-svgo.svg b/doc/src/sgml/images/directories-ink-svgo.svg
new file mode 100644
index 0000000000..95fa76b9c6
--- /dev/null
+++ b/doc/src/sgml/images/directories-ink-svgo.svg
@@ -0,0 +1,164 @@
+<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="900" height="640" viewBox="0 0 900 640">
+  <title>
+    Directory structure of a cluster
+  </title>
+  <style>
+    .text_normal{font-style:normal;font-weight:400;font-size:16px;font-family:&quot;Open Sans&quot;,sans-serif;fill:#000}
+  </style>
+  <defs>
+    <symbol id="directory" stroke="blue" stroke-width=".3" fill="aqua">
+      <title>
+        Directory
+      </title>
+      <path d="M0 10h110v20H0z"/>
+      <path d="M0 10V8l3-3h35l3 3v2"/>
+    </symbol>
+    <symbol id="file" stroke="black" fill="none">
+      <title>
+        File
+      </title>
+      <path stroke="blue" d="M0 0h40v50H0z"/>
+      <path d="M5 10h20" stroke-dasharray="4 2"/>
+      <path d="M5 17h15" stroke-dasharray="6 2"/>
+      <path d="M5 24h25" stroke-dasharray="4 2"/>
+      <path d="M5 31h20" stroke-dasharray="5 2"/>
+    </symbol>
+  </defs>
+  <rect x="1" y="1" rx="5" width="99%" height="99%" stroke="black" fill="none"/>
+  <text x="200" y="50" font-weight="400" font-size="24" font-family="&quot;Open Sans&quot;,sans-serif">
+    Directory Structure
+  </text>
+  <g transform="translate(20 100)">
+    <use xlink:href="#directory"/>
+    <text x="10" y="26" class="text_normal">
+      ... /pg/
+    </text>
+    <text x="300" y="26" class="text_normal">
+      An arbitrary directory
+    </text>
+  </g>
+  <g transform="translate(70 130)">
+    <use xlink:href="#directory"/>
+    <text x="10" y="26" class="text_normal">
+      data/
+    </text>
+    <text x="250" y="26" class="text_normal">
+      Root of cluster &apos;data&apos; (see: PGDATA)
+    </text>
+  </g>
+  <g transform="translate(120 160)">
+    <use xlink:href="#directory"/>
+    <text x="10" y="26" class="text_normal">
+      base/
+    </text>
+    <text x="200" y="26" class="text_normal">
+      Subdirectory containing per-database subdirectories
+    </text>
+  </g>
+  <g transform="translate(170 190)">
+    <use xlink:href="#directory"/>
+    <text x="10" y="26" class="text_normal">
+      1/
+    </text>
+    <text x="150" y="26" class="text_normal">
+      Subdirectory for data of first database &apos;template0&apos;
+    </text>
+  </g>
+  <g transform="translate(170 220)">
+    <use xlink:href="#directory"/>
+    <text x="10" y="26" class="text_normal">
+      12992/
+    </text>
+    <text x="150" y="26" class="text_normal">
+      Subdirectory for data of second database &apos;template1&apos;
+    </text>
+  </g>
+  <g transform="translate(170 250)">
+    <use xlink:href="#directory"/>
+    <text x="10" y="26" class="text_normal">
+      12999/
+    </text>
+    <text x="150" y="26" class="text_normal">
+      Subdirectory for data of third database &apos;postgres&apos;
+    </text>
+  </g>
+  <g transform="translate(170 280)">
+    <use xlink:href="#directory"/>
+    <text x="10" y="26" class="text_normal">
+      nnnnn/
+    </text>
+    <text x="150" y="26" class="text_normal">
+      Optional: more subdirectories for databases, e.g. &apos;my_db&apos;
+    </text>
+  </g>
+  <g transform="translate(120 310)">
+    <use xlink:href="#directory"/>
+    <text x="10" y="26" class="text_normal">
+      global/
+    </text>
+    <text x="200" y="26" class="text_normal">
+      Subdirectory with information about Global SQL Objects
+    </text>
+  </g>
+  <g transform="translate(120 340)">
+    <use xlink:href="#directory"/>
+    <text x="10" y="26" class="text_normal">
+      pg_wal/
+    </text>
+    <text x="200" y="26" class="text_normal">
+      Subdirectory for Write Ahead Log files (&apos;pg_xlog&apos; before version 10)
+    </text>
+  </g>
+  <g transform="translate(120 370)">
+    <use xlink:href="#directory"/>
+    <text x="10" y="26" class="text_normal">
+      pg_xact/
+    </text>
+    <text x="200" y="26" class="text_normal">
+      Subdirectory for transaction commit status (&apos;pg_clog&apos; before version 10)
+    </text>
+  </g>
+  <g transform="translate(120 400)">
+    <use xlink:href="#directory"/>
+    <text x="10" y="26" class="text_normal">
+      pg_tblspc/
+    </text>
+    <text x="200" y="26" class="text_normal">
+      Subdirectory containing symbolic links to tablespaces
+    </text>
+  </g>
+  <g transform="translate(120 430)">
+    <use xlink:href="#directory"/>
+    <text x="10" y="26" class="text_normal">
+      pg_... /
+    </text>
+    <text x="200" y="26" class="text_normal">
+      Some more subdirectories
+    </text>
+  </g>
+  <g transform="translate(120 465)">
+    <use xlink:href="#file"/>
+    <use xlink:href="#file" x="50"/>
+    <text x="200" y="26" class="text_normal">
+      &apos;postmaster.pid&apos; and other files with cluster-wide relevance
+    </text>
+  </g>
+  <g transform="translate(20 540)">
+    <use xlink:href="#directory"/>
+    <text x="10" y="26" class="text_normal">
+      ... /xyz/
+    </text>
+    <text x="300" y="26" class="text_normal">
+      Same or another arbitrary directory
+    </text>
+  </g>
+  <g transform="translate(70 570)">
+    <use xlink:href="#directory"/>
+    <text x="10" y="26" class="text_normal">
+      cluster_2/
+    </text>
+    <text x="250" y="26" class="text_normal">
+      Root of another cluster &apos;cluster_2&apos;
+    </text>
+  </g>
+</svg>
diff --git a/doc/src/sgml/images/directories-ink.svg b/doc/src/sgml/images/directories-ink.svg
new file mode 100644
index 0000000000..4661ef13fb
--- /dev/null
+++ b/doc/src/sgml/images/directories-ink.svg
@@ -0,0 +1,397 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://creativecommons.org/ns#"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:xlink="http://www.w3.org/1999/xlink"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   version="1.1"
+   width="900px"
+   height="640px"
+   viewBox="0 0 900 640"
+   id="svg303"
+   sodipodi:docname="directories-ink.svg"
+   inkscape:version="0.92.3 (2405546, 2018-03-11)">
+  <metadata
+     id="metadata307">
+    <rdf:RDF>
+      <cc:Work
+         rdf:about="">
+        <dc:format>image/svg+xml</dc:format>
+        <dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+        <dc:title>Directory structure of a cluster</dc:title>
+      </cc:Work>
+    </rdf:RDF>
+  </metadata>
+  <sodipodi:namedview
+     pagecolor="#ffffff"
+     bordercolor="#666666"
+     borderopacity="1"
+     objecttolerance="10"
+     gridtolerance="10"
+     guidetolerance="10"
+     inkscape:pageopacity="0"
+     inkscape:pageshadow="2"
+     inkscape:window-width="640"
+     inkscape:window-height="480"
+     id="namedview305"
+     showgrid="false"
+     inkscape:zoom="0.36875"
+     inkscape:cx="450"
+     inkscape:cy="320"
+     inkscape:window-x="61"
+     inkscape:window-y="27"
+     inkscape:window-maximized="0"
+     inkscape:current-layer="svg303" />
+  <title
+     id="title153">Directory structure of a cluster</title>
+  <style
+     type="text/css"
+     id="style155">
+  .text_normal  {font-style:normal;
+                 font-weight:normal;
+                 font-size:16px;
+                 font-family:&quot;Open Sans&quot;, sans-serif;
+                 fill:black;
+                }
+  .text_big     {font-style:normal;
+                 font-weight:normal;
+                 font-size:24px;
+                 font-family:&quot;Open Sans&quot;, sans-serif;
+                 fill:black;
+                }
+  </style>
+  <defs
+     id="defs177">
+    <!--  Directory  -->
+    <symbol
+       id="directory"
+       stroke="blue"
+       stroke-width="0.3px"
+       fill="aqua">
+      <title
+         id="title157">Directory</title>
+      <rect
+         x="0"
+         y="10"
+         width="110"
+         height="20"
+         id="rect159" />
+      <path
+         d="M 0,10 l 0,-2 3,-3 35,0, 3,3  0,2"
+         id="path161" />
+    </symbol>
+    <!--  File  -->
+    <symbol
+       id="file"
+       stroke="black"
+       fill="none">
+      <title
+         id="title164">File</title>
+      <rect
+         x="0"
+         y="0"
+         width="40"
+         height="50"
+         stroke="blue"
+         id="rect166" />
+      <path
+         d="M 5,10 h 20"
+         stroke-dasharray="4 2"
+         id="path168" />
+      <path
+         d="M 5,17 h 15"
+         stroke-dasharray="6 2"
+         id="path170" />
+      <path
+         d="M 5,24 h 25"
+         stroke-dasharray="4 2"
+         id="path172" />
+      <path
+         d="M 5,31 h 20"
+         stroke-dasharray="5 2"
+         id="path174" />
+    </symbol>
+  </defs>
+  <!--  start of rendering area  -->
+  <!--  enclosing rectangle  -->
+  <rect
+     x="1"
+     y="1"
+     rx="5"
+     width="99%"
+     height="99%"
+     stroke="black"
+     fill="none"
+     id="rect179" />
+  <!--  caption  -->
+  <text
+     x="200"
+     y="50"
+     class="text_big"
+     id="text181">Directory Structure</text>
+  <!--  the directories  -->
+  <g
+     transform="translate(20, 100)"
+     id="g189">
+    <use
+       xlink:href="#directory"
+       id="use183" />
+    <text
+       x="10"
+       y="26"
+       class="text_normal"
+       id="text185">... /pg/</text>
+    <text
+       x="300"
+       y="26"
+       class="text_normal"
+       id="text187">An arbitrary directory</text>
+  </g>
+  <g
+     transform="translate(70, 130)"
+     id="g197">
+    <use
+       xlink:href="#directory"
+       id="use191" />
+    <text
+       x="10"
+       y="26"
+       class="text_normal"
+       id="text193">data/</text>
+    <text
+       x="250"
+       y="26"
+       class="text_normal"
+       id="text195">Root of cluster 'data' (see: PGDATA)</text>
+  </g>
+  <g
+     transform="translate(120, 160)"
+     id="g205">
+    <use
+       xlink:href="#directory"
+       id="use199" />
+    <text
+       x="10"
+       y="26"
+       class="text_normal"
+       id="text201">base/</text>
+    <text
+       x="200"
+       y="26"
+       class="text_normal"
+       id="text203">Subdirectory containing per-database subdirectories</text>
+  </g>
+  <!--  -->
+  <g
+     transform="translate(170, 190)"
+     id="g213">
+    <use
+       xlink:href="#directory"
+       id="use207" />
+    <text
+       x="10"
+       y="26"
+       class="text_normal"
+       id="text209">1/</text>
+    <text
+       x="150"
+       y="26"
+       class="text_normal"
+       id="text211">Subdirectory for data of first database 'template0'</text>
+  </g>
+  <g
+     transform="translate(170, 220)"
+     id="g221">
+    <use
+       xlink:href="#directory"
+       id="use215" />
+    <text
+       x="10"
+       y="26"
+       class="text_normal"
+       id="text217">12992/</text>
+    <text
+       x="150"
+       y="26"
+       class="text_normal"
+       id="text219">Subdirectory for data of second database 'template1'</text>
+  </g>
+  <g
+     transform="translate(170, 250)"
+     id="g229">
+    <use
+       xlink:href="#directory"
+       id="use223" />
+    <text
+       x="10"
+       y="26"
+       class="text_normal"
+       id="text225">12999/</text>
+    <text
+       x="150"
+       y="26"
+       class="text_normal"
+       id="text227">Subdirectory for data of third database 'postgres'</text>
+  </g>
+  <g
+     transform="translate(170, 280)"
+     id="g237">
+    <use
+       xlink:href="#directory"
+       id="use231" />
+    <text
+       x="10"
+       y="26"
+       class="text_normal"
+       id="text233">nnnnn/</text>
+    <text
+       x="150"
+       y="26"
+       class="text_normal"
+       id="text235">Optional: more subdirectories for databases, e.g. 'my_db'</text>
+  </g>
+  <g
+     transform="translate(120, 310)"
+     id="g245">
+    <use
+       xlink:href="#directory"
+       id="use239" />
+    <text
+       x="10"
+       y="26"
+       class="text_normal"
+       id="text241">global/</text>
+    <text
+       x="200"
+       y="26"
+       class="text_normal"
+       id="text243">Subdirectory with information about Global SQL Objects</text>
+  </g>
+  <g
+     transform="translate(120, 340)"
+     id="g253">
+    <use
+       xlink:href="#directory"
+       id="use247" />
+    <text
+       x="10"
+       y="26"
+       class="text_normal"
+       id="text249">pg_wal/</text>
+    <text
+       x="200"
+       y="26"
+       class="text_normal"
+       id="text251">Subdirectory for Write Ahead Log files ('pg_xlog' before version 10)</text>
+  </g>
+  <g
+     transform="translate(120, 370)"
+     id="g261">
+    <use
+       xlink:href="#directory"
+       id="use255" />
+    <text
+       x="10"
+       y="26"
+       class="text_normal"
+       id="text257">pg_xact/</text>
+    <text
+       x="200"
+       y="26"
+       class="text_normal"
+       id="text259">Subdirectory for transaction commit status ('pg_clog' before version 10)</text>
+  </g>
+  <g
+     transform="translate(120, 400)"
+     id="g269">
+    <use
+       xlink:href="#directory"
+       id="use263" />
+    <text
+       x="10"
+       y="26"
+       class="text_normal"
+       id="text265">pg_tblspc/</text>
+    <text
+       x="200"
+       y="26"
+       class="text_normal"
+       id="text267">Subdirectory containing symbolic links to tablespaces</text>
+  </g>
+  <g
+     transform="translate(120, 430)"
+     id="g277">
+    <use
+       xlink:href="#directory"
+       id="use271" />
+    <text
+       x="10"
+       y="26"
+       class="text_normal"
+       id="text273">pg_... /</text>
+    <text
+       x="200"
+       y="26"
+       class="text_normal"
+       id="text275">Some more subdirectories</text>
+  </g>
+  <g
+     transform="translate(120, 465)"
+     id="g285">
+    <use
+       xlink:href="#file"
+       x="0"
+       y="0"
+       id="use279" />
+    <use
+       xlink:href="#file"
+       x="50"
+       y="0"
+       id="use281" />
+    <text
+       x="200"
+       y="26"
+       class="text_normal"
+       id="text283">'postmaster.pid' and other files with cluster-wide relevance</text>
+  </g>
+  <!--  next cluster  -->
+  <g
+     transform="translate(20, 540)"
+     id="g293">
+    <use
+       xlink:href="#directory"
+       id="use287" />
+    <text
+       x="10"
+       y="26"
+       class="text_normal"
+       id="text289">... /xyz/</text>
+    <text
+       x="300"
+       y="26"
+       class="text_normal"
+       id="text291">Same or another arbitrary directory</text>
+  </g>
+  <g
+     transform="translate(70, 570)"
+     id="g301">
+    <use
+       xlink:href="#directory"
+       id="use295" />
+    <text
+       x="10"
+       y="26"
+       class="text_normal"
+       id="text297">cluster_2/</text>
+    <text
+       x="250"
+       y="26"
+       class="text_normal"
+       id="text299">Root of another cluster 'cluster_2'</text>
+  </g>
+</svg>
diff --git a/doc/src/sgml/images/directories-raw.svg b/doc/src/sgml/images/directories-raw.svg
new file mode 100644
index 0000000000..8869eb9390
--- /dev/null
+++ b/doc/src/sgml/images/directories-raw.svg
@@ -0,0 +1,144 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<svg xmlns="http://www.w3.org/2000/svg"
+     xmlns:xlink="http://www.w3.org/1999/xlink"
+     version="1.1"
+     width="900px" height="640px"
+     viewBox="0 0 900 640">
+
+  <title>Directory structure of a cluster</title>
+
+  <style type="text/css">
+  .text_normal  {font-style:normal;
+                 font-weight:normal;
+                 font-size:16px;
+                 font-family:"Open Sans", sans-serif;
+                 fill:black;
+                }
+  .text_big     {font-style:normal;
+                 font-weight:normal;
+                 font-size:24px;
+                 font-family:"Open Sans", sans-serif;
+                 fill:black;
+                }
+  </style>
+
+  <defs>
+
+    <!--  Directory  -->
+    <symbol id="directory" stroke="blue" stroke-width="0.3px" fill="aqua">
+      <title>Directory</title>
+      <rect x="0" y="10" width="110" height="20" />
+      <path d="M 0,10 l 0,-2 3,-3 35,0, 3,3  0,2" />
+    </symbol>
+
+    <!--  File  -->
+    <symbol id="file" stroke="black" fill="none" >
+      <title>File</title>
+      <rect x="0" y="0" width="40" height="50" stroke="blue" />
+      <path d="M 5,10 h 20" stroke-dasharray="4 2" />
+      <path d="M 5,17 h 15" stroke-dasharray="6 2" />
+      <path d="M 5,24 h 25" stroke-dasharray="4 2" />
+      <path d="M 5,31 h 20" stroke-dasharray="5 2" />
+    </symbol>
+
+  </defs>
+
+
+  <!--  start of rendering area  -->
+  <!--  enclosing rectangle  -->
+  <rect x="1" y="1" rx="5" width="99%" height="99%" stroke="black" fill="none" />
+
+  <!--  caption  -->
+  <text x="200" y="50"  class="text_big">Directory Structure</text>
+
+  <!--  the directories  -->
+  <g transform="translate(20, 100)">
+    <use xlink:href="#directory" />
+    <text x="10"  y="26" class="text_normal">... /pg/</text>
+    <text x="300" y="26" class="text_normal">An arbitrary directory</text>
+  </g>
+
+  <g transform="translate(70, 130)">
+    <use xlink:href="#directory" />
+    <text x="10"  y="26" class="text_normal">data/</text>
+    <text x="250" y="26" class="text_normal">Root of cluster 'data' (see: PGDATA)</text>
+  </g>
+
+  <g transform="translate(120, 160)">
+    <use xlink:href="#directory" />
+    <text x="10"  y="26" class="text_normal">base/</text>
+    <text x="200" y="26" class="text_normal">Subdirectory containing per-database subdirectories</text>
+  </g>
+
+  <!--  -->
+  <g transform="translate(170, 190)">
+    <use xlink:href="#directory" />
+    <text x="10"  y="26" class="text_normal">1/</text>
+    <text x="150" y="26" class="text_normal">Subdirectory for data of first database 'template0'</text>
+  </g>
+  <g transform="translate(170, 220)">
+    <use xlink:href="#directory" />
+    <text x="10"  y="26" class="text_normal">12992/</text>
+    <text x="150" y="26" class="text_normal">Subdirectory for data of second database 'template1'</text>
+  </g>
+  <g transform="translate(170, 250)">
+    <use xlink:href="#directory" />
+    <text x="10"  y="26" class="text_normal">12999/</text>
+    <text x="150" y="26" class="text_normal">Subdirectory for data of third database 'postgres'</text>
+  </g>
+  <g transform="translate(170, 280)">
+    <use xlink:href="#directory" />
+    <text x="10"  y="26" class="text_normal">nnnnn/</text>
+    <text x="150" y="26" class="text_normal">Optional: more subdirectories for databases, e.g. 'my_db'</text>
+  </g>
+
+  <g transform="translate(120, 310)">
+    <use xlink:href="#directory" />
+    <text x="10"  y="26" class="text_normal">global/</text>
+    <text x="200" y="26" class="text_normal">Subdirectory with information about Global SQL Objects</text>
+  </g>
+
+  <g transform="translate(120, 340)">
+    <use xlink:href="#directory" />
+    <text x="10"  y="26" class="text_normal">pg_wal/</text>
+    <text x="200" y="26" class="text_normal">Subdirectory for Write Ahead Log files ('pg_xlog' before version 10)</text>
+  </g>
+
+  <g transform="translate(120, 370)">
+    <use xlink:href="#directory" />
+    <text x="10"  y="26" class="text_normal">pg_xact/</text>
+    <text x="200" y="26" class="text_normal">Subdirectory for transaction commit status ('pg_clog' before version 10)</text>
+  </g>
+
+  <g transform="translate(120, 400)">
+    <use xlink:href="#directory" />
+    <text x="10"  y="26" class="text_normal">pg_tblspc/</text>
+    <text x="200" y="26" class="text_normal">Subdirectory containing symbolic links to tablespaces</text>
+  </g>
+
+  <g transform="translate(120, 430)">
+    <use xlink:href="#directory" />
+    <text x="10"  y="26" class="text_normal">pg_... /</text>
+    <text x="200" y="26" class="text_normal">Some more subdirectories</text>
+  </g>
+
+  <g transform="translate(120, 465)">
+    <use xlink:href="#file" x="0"   y="0"  />
+    <use xlink:href="#file" x="50"  y="0"  />
+    <text x="200" y="26" class="text_normal">'postmaster.pid' and other files with cluster-wide relevance</text>
+  </g>
+
+  <!--  next cluster  -->
+  <g transform="translate(20, 540)">
+    <use xlink:href="#directory" />
+    <text x="10"  y="26" class="text_normal">... /xyz/</text>
+    <text x="300" y="26" class="text_normal">Same or another arbitrary directory</text>
+  </g>
+
+  <g transform="translate(70, 570)">
+    <use xlink:href="#directory" />
+    <text x="10"  y="26" class="text_normal">cluster_2/</text>
+    <text x="250" y="26" class="text_normal">Root of another cluster 'cluster_2'</text>
+  </g>
+
+</svg>
diff --git a/doc/src/sgml/images/internal-objects-hierarchy-ink-svgo.svg b/doc/src/sgml/images/internal-objects-hierarchy-ink-svgo.svg
new file mode 100644
index 0000000000..4156bbc834
--- /dev/null
+++ b/doc/src/sgml/images/internal-objects-hierarchy-ink-svgo.svg
@@ -0,0 +1,83 @@
+<svg xmlns="http://www.w3.org/2000/svg" width="720" height="430" viewBox="0 0 720 430">
+  <title>
+    Hierarchy of Internal Objects
+  </title>
+  <style>
+    .text_normal{font-style:normal;font-weight:400;font-size:16px;font-family:&quot;Open Sans&quot;,sans-serif;fill:#000}
+  </style>
+  <rect x="1" y="1" rx="5" width="99%" height="99%" stroke="black" fill="none"/>
+  <text x="200" y="40" font-weight="400" font-size="24" font-family="&quot;Open Sans&quot;,sans-serif">
+    Hierarchy of Internal Objects
+  </text>
+  <g fill="none">
+    <g transform="translate(350 240)">
+      <ellipse rx="320" ry="170" stroke="blue"/>
+      <text class="text_normal" x="-140" y="-130">
+        Cluster
+      </text>
+      <g transform="translate(40 -125)">
+        <ellipse rx="80" ry="20" stroke="blue"/>
+        <text class="text_normal" x="-60" y="5">
+          Database Names
+        </text>
+      </g>
+      <g transform="translate(180 -70)">
+        <ellipse rx="60" ry="20" stroke="blue"/>
+        <text class="text_normal" x="-40" y="5">
+          Tablespace
+        </text>
+      </g>
+      <g transform="translate(230 -5)">
+        <ellipse rx="80" ry="20" stroke="blue"/>
+        <text class="text_normal" x="-70" y="5">
+          Replication Origins
+        </text>
+      </g>
+      <g transform="translate(200 70)">
+        <ellipse rx="78" ry="27" stroke="blue"/>
+        <text class="text_normal" x="-60" y="-3">
+          Subscription for
+        </text>
+        <text class="text_normal" x="-68" y="10">
+          Logical Replication
+        </text>
+      </g>
+      <g transform="translate(100 120)">
+        <ellipse rx="40" ry="20" stroke="blue"/>
+        <text class="text_normal" x="-15" y="5">
+          Role
+        </text>
+      </g>
+    </g>
+    <g transform="translate(270 250)">
+      <ellipse rx="220" ry="110" stroke="blue" stroke-width="2"/>
+      <text class="text_normal" x="-60" y="-80">
+        Database
+      </text>
+      <g transform="translate(-150 -30)">
+        <ellipse rx="50" ry="20" stroke="blue"/>
+        <text class="text_normal" x="-35" y="5">
+          Extension
+        </text>
+      </g>
+      <g transform="translate(-155 35)">
+        <ellipse rx="40" ry="20" stroke="blue"/>
+        <text class="text_normal" x="-35" y="5">
+          Collation
+        </text>
+      </g>
+      <g transform="translate(30 20)">
+        <ellipse rx="140" ry="70" stroke="blue"/>
+        <text class="text_normal" x="-80" y="-35">
+          Schema
+        </text>
+        <g transform="translate(20 10)">
+          <ellipse rx="90" ry="30" stroke="blue"/>
+          <text class="text_normal" x="-50" y="5">
+            Table, View, ...
+          </text>
+        </g>
+      </g>
+    </g>
+  </g>
+</svg>
diff --git a/doc/src/sgml/images/internal-objects-hierarchy-ink.svg b/doc/src/sgml/images/internal-objects-hierarchy-ink.svg
new file mode 100644
index 0000000000..cf03d6a701
--- /dev/null
+++ b/doc/src/sgml/images/internal-objects-hierarchy-ink.svg
@@ -0,0 +1,255 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://creativecommons.org/ns#"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   version="1.1"
+   width="720px"
+   height="430px"
+   viewBox="0 0 720 430"
+   id="svg389"
+   sodipodi:docname="internal-objects-hierarchy-ink.svg"
+   inkscape:version="0.92.3 (2405546, 2018-03-11)">
+  <metadata
+     id="metadata395">
+    <rdf:RDF>
+      <cc:Work
+         rdf:about="">
+        <dc:format>image/svg+xml</dc:format>
+        <dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+        <dc:title>Hierarchy of Internal Objects</dc:title>
+      </cc:Work>
+    </rdf:RDF>
+  </metadata>
+  <defs
+     id="defs393" />
+  <sodipodi:namedview
+     pagecolor="#ffffff"
+     bordercolor="#666666"
+     borderopacity="1"
+     objecttolerance="10"
+     gridtolerance="10"
+     guidetolerance="10"
+     inkscape:pageopacity="0"
+     inkscape:pageshadow="2"
+     inkscape:window-width="906"
+     inkscape:window-height="678"
+     id="namedview391"
+     showgrid="false"
+     inkscape:zoom="0.51944444"
+     inkscape:cx="360"
+     inkscape:cy="215"
+     inkscape:window-x="502"
+     inkscape:window-y="91"
+     inkscape:window-maximized="0"
+     inkscape:current-layer="svg389" />
+  <title
+     id="title309">Hierarchy of Internal Objects</title>
+  <!-- common text classes -->
+  <style
+     type="text/css"
+     id="style311">
+  .text_normal  {font-style:normal;
+                 font-weight:normal;
+                 font-size:16px;
+                 font-family:&quot;Open Sans&quot;, sans-serif;
+                 fill:black;
+                }
+  .text_big     {font-style:normal;
+                 font-weight:normal;
+                 font-size:24px;
+                 font-family:&quot;Open Sans&quot;, sans-serif;
+                 fill:black;
+                }
+  </style>
+  <!--  start of rendering area  -->
+  <!--  enclosing rectangle  -->
+  <rect
+     x="1"
+     y="1"
+     rx="5"
+     width="99%"
+     height="99%"
+     stroke="black"
+     fill="none"
+     id="rect313" />
+  <text
+     class="text_big"
+     x="200"
+     y="40"
+     id="text315">Hierarchy of Internal Objects</text>
+  <!--  set centre of figure and default values -->
+  <g
+     transform="translate(350 240)"
+     fill="none"
+     id="g387">
+    <g
+       id="g353">
+      <ellipse
+         rx="320"
+         ry="170"
+         stroke="blue"
+         id="ellipse317" />
+      <text
+         class="text_normal"
+         x="-140"
+         y="-130"
+         id="text319">Cluster</text>
+      <g
+         transform="translate(40 -125)"
+         id="g325">
+        <ellipse
+           rx="80"
+           ry="20"
+           stroke="blue"
+           id="ellipse321" />
+        <text
+           class="text_normal"
+           x="-60"
+           y="5"
+           id="text323">Database Names</text>
+      </g>
+      <g
+         transform="translate(180 -70)"
+         id="g331">
+        <ellipse
+           rx="60"
+           ry="20"
+           stroke="blue"
+           id="ellipse327" />
+        <text
+           class="text_normal"
+           x="-40"
+           y="5"
+           id="text329">Tablespace</text>
+      </g>
+      <g
+         transform="translate(230 -5)"
+         id="g337">
+        <ellipse
+           rx="80"
+           ry="20"
+           stroke="blue"
+           id="ellipse333" />
+        <text
+           class="text_normal"
+           x="-70"
+           y="5"
+           id="text335">Replication Origins</text>
+      </g>
+      <g
+         transform="translate(200 70)"
+         id="g345">
+        <ellipse
+           rx="78"
+           ry="27"
+           stroke="blue"
+           id="ellipse339" />
+        <text
+           class="text_normal"
+           x="-60"
+           y="-3"
+           id="text341">Subscription for</text>
+        <text
+           class="text_normal"
+           x="-68"
+           y="10"
+           id="text343">Logical Replication</text>
+      </g>
+      <g
+         transform="translate(100 120)"
+         id="g351">
+        <ellipse
+           rx="40"
+           ry="20"
+           stroke="blue"
+           id="ellipse347" />
+        <text
+           class="text_normal"
+           x="-15"
+           y="5"
+           id="text349">Role</text>
+      </g>
+    </g>
+    <g
+       transform="translate(-80 10)"
+       id="g385">
+      <ellipse
+         rx="220"
+         ry="110"
+         stroke="blue"
+         stroke-width="2px"
+         id="ellipse355" />
+      <text
+         class="text_normal"
+         x="-60"
+         y="-80"
+         id="text357">Database</text>
+      <g
+         transform="translate(-120 -50)"
+         id="g383">
+        <g
+           transform="translate(-30 20)"
+           id="g363">
+          <ellipse
+             rx="50"
+             ry="20"
+             stroke="blue"
+             id="ellipse359" />
+          <text
+             class="text_normal"
+             x="-35"
+             y="5"
+             id="text361">Extension</text>
+        </g>
+        <g
+           transform="translate(-35 85)"
+           id="g369">
+          <ellipse
+             rx="40"
+             ry="20"
+             stroke="blue"
+             id="ellipse365" />
+          <text
+             class="text_normal"
+             x="-35"
+             y="5"
+             id="text367">Collation</text>
+        </g>
+        <g
+           transform="translate(150 70)"
+           id="g381">
+          <ellipse
+             rx="140"
+             ry="70"
+             stroke="blue"
+             id="ellipse371" />
+          <text
+             class="text_normal"
+             x="-80"
+             y="-35"
+             id="text373">Schema</text>
+          <g
+             transform="translate(20 10)"
+             id="g379">
+            <ellipse
+               rx="90"
+               ry="30"
+               stroke="blue"
+               id="ellipse375" />
+            <text
+               class="text_normal"
+               x="-50"
+               y="5"
+               id="text377">Table, View, ...</text>
+          </g>
+        </g>
+      </g>
+    </g>
+  </g>
+</svg>
diff --git a/doc/src/sgml/images/internal-objects-hierarchy-raw.svg b/doc/src/sgml/images/internal-objects-hierarchy-raw.svg
new file mode 100644
index 0000000000..45387bbd9b
--- /dev/null
+++ b/doc/src/sgml/images/internal-objects-hierarchy-raw.svg
@@ -0,0 +1,95 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<svg xmlns="http://www.w3.org/2000/svg"
+     xmlns:xlink="http://www.w3.org/1999/xlink"
+     version="1.1"
+     width="720px" height="430px"
+     viewBox="0 0 720 430" >
+
+  <title>Hierarchy of Internal Objects</title>
+
+  <!-- common text classes -->
+  <style type="text/css">
+  .text_normal  {font-style:normal;
+                 font-weight:normal;
+                 font-size:16px;
+                 font-family:"Open Sans", sans-serif;
+                 fill:black;
+                }
+  .text_big     {font-style:normal;
+                 font-weight:normal;
+                 font-size:24px;
+                 font-family:"Open Sans", sans-serif;
+                 fill:black;
+                }
+  </style>
+
+  <!--  start of rendering area  -->
+  <!--  enclosing rectangle  -->
+  <rect x="1" y="1" rx="5" width="99%" height="99%" stroke="black" fill="none" />
+  <text class="text_big" x="200" y="40">Hierarchy of Internal Objects</text>
+
+
+  <!--  set centre of figure and default values -->
+  <g transform="translate(350 240)" fill="none">
+
+    <g>
+      <ellipse rx="320" ry="170" stroke="blue" />
+      <text class="text_normal" x="-140" y="-130">Cluster</text>
+
+      <g transform="translate(40 -125)">
+        <ellipse rx="80" ry="20" stroke="blue" />
+        <text class="text_normal" x="-60" y="5">Database Names</text>
+      </g>
+
+      <g transform="translate(180 -70)">
+        <ellipse rx="60" ry="20" stroke="blue" />
+        <text class="text_normal" x="-40" y="5">Tablespace</text>
+      </g>
+
+      <g transform="translate(230 -5)">
+        <ellipse rx="80" ry="20" stroke="blue" />
+        <text class="text_normal" x="-70" y="5">Replication Origins</text>
+      </g>
+
+      <g transform="translate(200 70)">
+        <ellipse rx="78" ry="27" stroke="blue" />
+        <text class="text_normal" x="-60" y="-3">Subscription for</text>
+        <text class="text_normal" x="-68" y="10">Logical Replication</text>
+      </g>
+
+      <g transform="translate(100 120)">
+        <ellipse rx="40" ry="20" stroke="blue" />
+        <text class="text_normal" x="-15" y="5">Role</text>
+      </g>
+
+    </g>
+
+    <g transform="translate(-80 10)">
+      <ellipse rx="220" ry="110" stroke="blue" stroke-width="2px" />
+      <text class="text_normal" x="-60" y="-80">Database</text>
+
+      <g transform="translate(-120 -50)">
+        <g transform="translate(-30 20)">
+          <ellipse rx="50" ry="20" stroke="blue" />
+          <text class="text_normal" x="-35" y="5">Extension</text>
+        </g>
+
+        <g transform="translate(-35 85)">
+          <ellipse rx="40" ry="20" stroke="blue" />
+          <text class="text_normal" x="-35" y="5">Collation</text>
+        </g>
+
+        <g transform="translate(150 70)">
+          <ellipse rx="140" ry="70" stroke="blue" />
+          <text class="text_normal" x="-80" y="-35">Schema</text>
+
+          <g  transform="translate(20 10)">
+            <ellipse rx="90" ry="30" stroke="blue" />
+            <text class="text_normal" x="-50" y="5">Table, View, ...</text>
+          </g>
+        </g>
+      </g>
+    </g>
+  </g>
+
+</svg>
diff --git a/doc/src/sgml/images/ram-proc-file-ink-svgo.svg b/doc/src/sgml/images/ram-proc-file-ink-svgo.svg
new file mode 100644
index 0000000000..bf638f6c63
--- /dev/null
+++ b/doc/src/sgml/images/ram-proc-file-ink-svgo.svg
@@ -0,0 +1,285 @@
+<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="900" height="600" viewBox="0 0 900 600">
+  <title>
+    PG Overall Server Architecture
+  </title>
+  <style>
+    .text_big{font-style:normal}.text_big,.text_comment,.text_normal,.text_small{font-weight:400;font-family:&quot;Open Sans&quot;,sans-serif;fill:#000}.text_normal,.text_small{font-style:normal}.text_small{font-size:12px}.text_normal{font-size:16px}.text_big{font-size:24px}.text_comment{font-style:italic;font-size:16px}
+  </style>
+  <defs>
+    <symbol id="note_200x20" stroke="black" fill="lightyellow">
+      <title>
+        UML Note (200 x 20 px)
+      </title>
+      <path d="M200 10v10H0V0h190v10h10L190 0"/>
+    </symbol>
+    <symbol id="note_250x20" stroke="black" fill="lightyellow">
+      <title>
+        UML Note (250 x 20 px)
+      </title>
+      <path d="M250 10v10H0V0h240v10h10L240 0"/>
+    </symbol>
+    <symbol id="note_100x35" stroke="black" fill="lightyellow">
+      <title>
+        UML Note (100 x 35 px)
+      </title>
+      <path d="M100 10v25H0V0h90v10h10L90 0"/>
+    </symbol>
+    <symbol id="note_170x50" stroke="black" fill="lightyellow">
+      <title>
+        UML Note (170 x 50 px)
+      </title>
+      <path d="M170 10v40H0V0h160v10h10L160 0"/>
+    </symbol>
+    <symbol id="state_300x120">
+      <title>
+        UML State, big
+      </title>
+      <rect width="300" height="120" rx="10" stroke="blue" fill="none"/>
+    </symbol>
+    <symbol id="state_350x120">
+      <title>
+        UML State, big
+      </title>
+      <rect width="350" height="120" rx="10" stroke="blue" fill="none"/>
+    </symbol>
+    <symbol id="disc" stroke="blue" fill="none">
+      <title>
+        Disc
+      </title>
+      <ellipse cx="51" cy="13" rx="50" ry="12"/>
+      <path d="M1 13v60"/>
+      <path d="M101 13v60"/>
+      <path d="M1 73a50 12 0 00100 0"/>
+    </symbol>
+    <symbol id="laptop" stroke="black" fill="none">
+      <title>
+        Laptop
+      </title>
+      <path d="M20 40V0h54v40l15 15H5l15-15h54"/>
+      <path d="M23 3h48v34H23z"/>
+      <path d="M30 10h20"/>
+      <path d="M30 15h25"/>
+      <path d="M30 20h10"/>
+      <path d="M30 30h20"/>
+      <path d="M25 50h45l2 2H22z"/>
+    </symbol>
+    <marker id="arrowhead_start" markerWidth="10" markerHeight="10" refX="0" refY="3" orient="auto">
+      <path d="M6 0L0 3l6 3" stroke="black" fill="none"/>
+    </marker>
+    <marker id="arrowhead_end" markerWidth="10" markerHeight="10" refX="6" refY="3" orient="auto">
+      <path d="M0 0l6 3-6 3" stroke="black" fill="none"/>
+    </marker>
+  </defs>
+  <rect x="1" y="1" rx="5" width="99%" height="99%" stroke="black" fill="none"/>
+  <text x="15" y="40" class="text_big">
+    Client
+  </text>
+  <text x="140" y="40" class="text_big">
+    Server
+  </text>
+  <use xlink:href="#laptop" x="5" y="210"/>
+  <g transform="translate(130 70)">
+    <use xlink:href="#state_350x120"/>
+    <text x="5" y="20" class="text_normal">
+      maintenance_work_mem (per connection)
+    </text>
+    <text x="5" y="45" class="text_normal">
+      work_mem (per query operation)
+    </text>
+    <text x="5" y="70" class="text_normal">
+      autovacuum_work_mem (per worker process)
+    </text>
+    <text x="5" y="95" class="text_normal">
+      temp_buffer (per connection)
+    </text>
+    <text x="5" y="110" class="text_normal">
+      ...
+    </text>
+    <use xlink:href="#note_200x20" x="140" y="-15"/>
+    <text x="150" class="text_comment">
+      Individual Memory
+    </text>
+  </g>
+  <g transform="translate(520 70)">
+    <use xlink:href="#state_300x120"/>
+    <text x="10" y="30" class="text_normal">
+      shared_buffers (heap and index)
+    </text>
+    <text x="10" y="70" class="text_normal">
+      wal_buffers (WAL records)
+    </text>
+    <text x="10" y="100" class="text_normal">
+      ...
+    </text>
+    <use xlink:href="#note_250x20" x="40" y="-15"/>
+    <text x="50" class="text_comment">
+      Shared Memory (per Cluster)
+    </text>
+  </g>
+  <path stroke="blue" fill="none" d="M190 215h200v30H190z"/>
+  <text x="10" y="20" class="text_normal" transform="translate(190 215)">
+    Postmaster process
+  </text>
+  <path d="M90 230h85" stroke="black" fill="none" marker-end="url(#arrowhead_end)"/>
+  <g transform="translate(140 230)">
+    <circle r="8" stroke="black" fill="lightyellow"/>
+    <text x="-4" y="4" class="text_small">
+      1
+    </text>
+  </g>
+  <path stroke="blue" fill="none" d="M150 315h370v30H150z"/>
+  <text x="10" y="20" class="text_normal" transform="translate(150 315)">
+    Backend processes (one per connection)
+  </text>
+  <path d="M155 315v-5h370v30h-5" stroke="blue" fill="none"/>
+  <path d="M160 310v-5h370v30h-5" stroke="blue" fill="none"/>
+  <path d="M90 240l63 63" stroke="black" fill="none" marker-start="url(#arrowhead_start)" marker-end="url(#arrowhead_end)"/>
+  <g transform="translate(140 290)">
+    <circle r="8" stroke="black" fill="lightyellow"/>
+    <text x="-4" y="4" class="text_small">
+      3
+    </text>
+  </g>
+  <path d="M360 250v50" stroke="black" fill="none" marker-end="url(#arrowhead_end)"/>
+  <g transform="translate(190 255)">
+    <use xlink:href="#note_250x20"/>
+    <text x="10" y="15" class="text_comment">
+      Creates backend processes
+    </text>
+  </g>
+  <g transform="translate(360 281)">
+    <circle r="8" stroke="black" fill="lightyellow"/>
+    <text x="-4" y="4" class="text_small">
+      2
+    </text>
+  </g>
+  <path d="M460 300V200" stroke="black" fill="none" marker-start="url(#arrowhead_start)" marker-end="url(#arrowhead_end)"/>
+  <path d="M498 300V95h30" stroke="black" fill="none" marker-start="url(#arrowhead_start)" marker-end="url(#arrowhead_end)"/>
+  <path d="M508 300V135h20" stroke="black" fill="none" marker-end="url(#arrowhead_end)"/>
+  <path stroke="blue" fill="none" d="M550 220h120v30H550z"/>
+  <text x="10" y="20" class="text_normal" transform="translate(550 220)">
+    WAL Writer
+  </text>
+  <path d="M590 150v65" stroke="black" fill="none" marker-end="url(#arrowhead_end)"/>
+  <path d="M590 255v230" stroke="black" fill="none" marker-end="url(#arrowhead_end)"/>
+  <path stroke="blue" fill="none" d="M610 340h140v30H610z"/>
+  <text x="10" y="20" class="text_normal" transform="translate(610 340)">
+    Checkpointer
+  </text>
+  <path d="M740 110v220" stroke="black" fill="none" marker-end="url(#arrowhead_end)"/>
+  <path d="M605 355H475v130" stroke="black" fill="none" marker-end="url(#arrowhead_end)"/>
+  <path d="M700 330V150" stroke="black" fill="none" marker-end="url(#arrowhead_end)"/>
+  <g transform="translate(570 330)">
+    <use xlink:href="#note_100x35" x="50" y="-50"/>
+    <text x="60" y="-35" class="text_comment">
+      Checkpoint
+    </text>
+    <text x="60" y="-20" class="text_comment">
+      Record
+    </text>
+  </g>
+  <path stroke="blue" fill="none" d="M610 380h180v30H610z"/>
+  <text x="10" y="20" class="text_normal" transform="translate(610 380)">
+    Background Writer
+  </text>
+  <path d="M770 110v260" stroke="black" fill="none" marker-end="url(#arrowhead_end)"/>
+  <path d="M605 395H485v90" stroke="black" fill="none" marker-end="url(#arrowhead_end)"/>
+  <path stroke="blue" fill="none" d="M610 420h180v30H610z"/>
+  <text x="10" y="20" class="text_normal" transform="translate(610 420)">
+    WAL Archiver
+  </text>
+  <path d="M620 485l30-30" stroke="black" fill="none" marker-end="url(#arrowhead_end)"/>
+  <path d="M740 455v30" stroke="black" fill="none" marker-end="url(#arrowhead_end)"/>
+  <path stroke="blue" fill="none" d="M135 380h120v30H135z"/>
+  <text x="10" y="20" class="text_normal" transform="translate(135 380)">
+    AutoVacuum
+  </text>
+  <path d="M140 380v-5h120v30h-5" stroke="blue" fill="none"/>
+  <path d="M145 375v-5h120v30h-5" stroke="blue" fill="none"/>
+  <path stroke="blue" fill="none" d="M135 430h120v30H135z"/>
+  <text x="10" y="20" class="text_normal" transform="translate(135 430)">
+    Log Writer
+  </text>
+  <path stroke="blue" fill="none" d="M290 370h140v30H290z"/>
+  <text x="10" y="20" class="text_normal" transform="translate(290 370)">
+    Stats Collector
+  </text>
+  <g transform="translate(145 490)">
+    <use xlink:href="#disc"/>
+    <text x="35" y="45" class="text_normal">
+      Log
+    </text>
+    <text x="20" y="60" class="text_small">
+      text lines,
+    </text>
+    <text x="20" y="75" class="text_small">
+      sequential
+    </text>
+  </g>
+  <path d="M195 465v20" stroke="black" fill="none" marker-end="url(#arrowhead_end)"/>
+  <g transform="translate(410 490)">
+    <use xlink:href="#disc"/>
+    <text x="10" y="40" class="text_normal">
+      Heap and
+    </text>
+    <text x="25" y="55" class="text_normal">
+      Index
+    </text>
+    <text x="15" y="70" class="text_small">
+      binary blocks,
+    </text>
+    <text x="30" y="80" class="text_small">
+      random
+    </text>
+  </g>
+  <path d="M450 485V350" stroke="black" fill="none" marker-end="url(#arrowhead_end)"/>
+  <g transform="translate(295 420)">
+    <use xlink:href="#note_170x50"/>
+    <text x="5" y="15" class="text_comment">
+      Read heap and index
+    </text>
+    <text x="5" y="30" class="text_comment">
+      pages and transfer
+    </text>
+    <text x="5" y="45" class="text_comment">
+      them to shared_buffers
+    </text>
+  </g>
+  <g transform="translate(550 490)">
+    <use xlink:href="#disc"/>
+    <text x="30" y="45" class="text_normal">
+      WAL
+    </text>
+    <text x="10" y="60" class="text_small">
+      binary records,
+    </text>
+    <text x="20" y="75" class="text_small">
+      sequential
+    </text>
+  </g>
+  <g transform="translate(690 490)">
+    <use xlink:href="#disc"/>
+    <text x="16" y="45" class="text_normal">
+      Archived
+    </text>
+    <text x="36" y="60" class="text_normal">
+      WAL
+    </text>
+  </g>
+  <path d="M110 20v550" stroke="black" fill="none"/>
+  <g transform="rotate(90 -33.5 156.5)">
+    <use xlink:href="#note_200x20"/>
+    <text class="text_comment" x="10" y="15">
+      Via TCP/IP or socket
+    </text>
+  </g>
+  <text class="text_big" x="95" transform="rotate(90 425 425)">
+    RAM
+  </text>
+  <text class="text_big" x="250" transform="rotate(90 425 425)">
+    PROCESSES
+  </text>
+  <text class="text_big" x="500" transform="rotate(90 425 425)">
+    FILES
+  </text>
+</svg>
diff --git a/doc/src/sgml/images/ram-proc-file-ink.svg b/doc/src/sgml/images/ram-proc-file-ink.svg
new file mode 100644
index 0000000000..6c960702a0
--- /dev/null
+++ b/doc/src/sgml/images/ram-proc-file-ink.svg
@@ -0,0 +1,841 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://creativecommons.org/ns#"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:xlink="http://www.w3.org/1999/xlink"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   version="1.1"
+   width="900px"
+   height="600px"
+   viewBox="0 0 900 600"
+   id="svg701"
+   sodipodi:docname="ram-proc-file-ink.svg"
+   inkscape:version="0.92.3 (2405546, 2018-03-11)">
+  <metadata
+     id="metadata705">
+    <rdf:RDF>
+      <cc:Work
+         rdf:about="">
+        <dc:format>image/svg+xml</dc:format>
+        <dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+        <dc:title>PG Overall Server Architecture</dc:title>
+      </cc:Work>
+    </rdf:RDF>
+  </metadata>
+  <sodipodi:namedview
+     pagecolor="#ffffff"
+     bordercolor="#666666"
+     borderopacity="1"
+     objecttolerance="10"
+     gridtolerance="10"
+     guidetolerance="10"
+     inkscape:pageopacity="0"
+     inkscape:pageshadow="2"
+     inkscape:window-width="846"
+     inkscape:window-height="675"
+     id="namedview703"
+     showgrid="false"
+     inkscape:zoom="0.39333333"
+     inkscape:cx="450"
+     inkscape:cy="300"
+     inkscape:window-x="503"
+     inkscape:window-y="91"
+     inkscape:window-maximized="0"
+     inkscape:current-layer="svg701" />
+  <title
+     id="title397">PG Overall Server Architecture</title>
+  <style
+     type="text/css"
+     id="style399">
+  .text_small   {font-style:normal;
+                 font-weight:normal;
+                 font-size:12px;
+                 font-family:&quot;Open Sans&quot;, sans-serif;
+                 fill:black;
+                }
+  .text_normal  {font-style:normal;
+                 font-weight:normal;
+                 font-size:16px;
+                 font-family:&quot;Open Sans&quot;, sans-serif;
+                 fill:black;
+                }
+  .text_big     {font-style:normal;
+                 font-weight:normal;
+                 font-size:24px;
+                 font-family:&quot;Open Sans&quot;, sans-serif;
+                 fill:black;
+                }
+  .text_comment {font-style:italic;
+                 font-weight:normal;
+                 font-size:16px;
+                 font-family:&quot;Open Sans&quot;, sans-serif;
+                 fill:black;
+                }
+  </style>
+  <defs
+     id="defs465">
+    <!-- Some notes in different sizes  -->
+    <symbol
+       id="note_200x20"
+       stroke="black"
+       fill="lightyellow">
+      <title
+         id="title401">UML Note (200 x 20 px)</title>
+      <path
+         d="M 200,10 v 10 h -200 v -20 h 190 v 10 h 10 l -10,-10"
+         id="path403" />
+    </symbol>
+    <symbol
+       id="note_250x20"
+       stroke="black"
+       fill="lightyellow">
+      <title
+         id="title406">UML Note (250 x 20 px)</title>
+      <path
+         d="M 250,10 v 10 h -250 v -20 h 240 v 10 h 10 l -10,-10"
+         id="path408" />
+    </symbol>
+    <symbol
+       id="note_100x35"
+       stroke="black"
+       fill="lightyellow">
+      <title
+         id="title411">UML Note (100 x 35 px)</title>
+      <path
+         d="M 100,10 v 25 h -100 v -35 h 90 v 10 h 10 l -10,-10"
+         id="path413" />
+    </symbol>
+    <symbol
+       id="note_170x50"
+       stroke="black"
+       fill="lightyellow">
+      <title
+         id="title416">UML Note (170 x 50 px)</title>
+      <path
+         d="M 170,10 v 40 h -170 v -50 h 160 v 10 h 10 l -10,-10"
+         id="path418" />
+    </symbol>
+    <!--  UML states (used for buffers) -->
+    <symbol
+       id="state_300x120">
+      <title
+         id="title421">UML State, big</title>
+      <rect
+         x="0"
+         y="0"
+         width="300"
+         height="120"
+         rx="10"
+         stroke="blue"
+         fill="none"
+         id="rect423" />
+    </symbol>
+    <symbol
+       id="state_350x120">
+      <title
+         id="title426">UML State, big</title>
+      <rect
+         x="0"
+         y="0"
+         width="350"
+         height="120"
+         rx="10"
+         stroke="blue"
+         fill="none"
+         id="rect428" />
+    </symbol>
+    <!-- Discs  -->
+    <symbol
+       id="disc"
+       stroke="blue"
+       fill="none">
+      <title
+         id="title431">Disc</title>
+      <ellipse
+         cx="51"
+         cy="13"
+         rx="50"
+         ry="12"
+         id="ellipse433" />
+      <!-- top -->
+      <path
+         d="M 1,13 v 60"
+         id="path435" />
+      <!-- left -->
+      <path
+         d="M 101,13 v 60"
+         id="path437" />
+      <!-- right -->
+      <path
+         d="M 1,73 A 50, 12, 0, 0, 0, 101,73"
+         id="path439" />
+      <!-- bottom -->
+    </symbol>
+    <!--  Laptop  -->
+    <symbol
+       id="laptop"
+       stroke="black"
+       fill="none">
+      <title
+         id="title442">Laptop</title>
+      <path
+         d="M 20,40 v -40 h 54 v 40 l 15,15 h -84 l 15,-15 h 54"
+         id="path444" />
+      <rect
+         x="23"
+         y="3"
+         width="48"
+         height="34"
+         id="rect446" />
+      <!-- symbolize some lines -->
+      <path
+         d="M 30,10 h 20"
+         id="path448" />
+      <path
+         d="M 30,15 h 25"
+         id="path450" />
+      <path
+         d="M 30,20 h 10"
+         id="path452" />
+      <path
+         d="M 30,30 h 20"
+         id="path454" />
+      <!-- symbolize keyboard -->
+      <path
+         d="M 25,50 h 45 l 2,2 h -50 z "
+         id="path456" />
+    </symbol>
+    <!--  marker start/end -->
+    <marker
+       id="arrowhead_start"
+       markerWidth="10"
+       markerHeight="10"
+       refX="0"
+       refY="3"
+       orient="auto">
+      <path
+         d="M 6,0 l -6,3 l 6,3"
+         stroke="black"
+         fill="none"
+         id="path459" />
+    </marker>
+    <marker
+       id="arrowhead_end"
+       markerWidth="10"
+       markerHeight="10"
+       refX="6"
+       refY="3"
+       orient="auto">
+      <path
+         d="M 0,0 l 6,3 l -6,3"
+         stroke="black"
+         fill="none"
+         id="path462" />
+    </marker>
+  </defs>
+  <!--  start of rendering area  -->
+  <!--  enclosing rectangle  -->
+  <rect
+     x="1"
+     y="1"
+     rx="5"
+     width="99%"
+     height="99%"
+     stroke="black"
+     fill="none"
+     id="rect467" />
+  <!-- caption, client side -->
+  <text
+     x="15"
+     y="40"
+     class="text_big"
+     id="text469">Client</text>
+  <text
+     x="140"
+     y="40"
+     class="text_big"
+     id="text471">Server</text>
+  <use
+     xlink:href="#laptop"
+     x="5"
+     y="210"
+     id="use473" />
+  <!--  individual memory -->
+  <g
+     transform="translate(130, 70)"
+     id="g491">
+    <use
+       xlink:href="#state_350x120"
+       x="0"
+       y="0"
+       id="use475" />
+    <text
+       x="5"
+       y="20"
+       class="text_normal"
+       id="text477">maintenance_work_mem (per connection)</text>
+    <text
+       x="5"
+       y="45"
+       class="text_normal"
+       id="text479">work_mem (per query operation)</text>
+    <text
+       x="5"
+       y="70"
+       class="text_normal"
+       id="text481">autovacuum_work_mem (per worker process)</text>
+    <text
+       x="5"
+       y="95"
+       class="text_normal"
+       id="text483">temp_buffer (per connection)</text>
+    <text
+       x="5"
+       y="110"
+       class="text_normal"
+       id="text485">...</text>
+    <use
+       xlink:href="#note_200x20"
+       x="140"
+       y="-15"
+       id="use487" />
+    <text
+       x="150"
+       y="0"
+       class="text_comment"
+       id="text489">Individual Memory</text>
+  </g>
+  <!--  shared memory -->
+  <g
+     transform="translate(520, 70)"
+     id="g505">
+    <use
+       xlink:href="#state_300x120"
+       x="0"
+       y="0"
+       id="use493" />
+    <text
+       x="10"
+       y="30"
+       class="text_normal"
+       id="text495">shared_buffers (heap and index)</text>
+    <text
+       x="10"
+       y="70"
+       class="text_normal"
+       id="text497">wal_buffers (WAL records)</text>
+    <text
+       x="10"
+       y="100"
+       class="text_normal"
+       id="text499">...</text>
+    <use
+       xlink:href="#note_250x20"
+       x="40"
+       y="-15"
+       id="use501" />
+    <text
+       x="50"
+       y="0"
+       class="text_comment"
+       id="text503">Shared Memory (per Cluster)</text>
+  </g>
+  <!-- postmaster  -->
+  <g
+     transform="translate(190, 215)"
+     id="g511">
+    <rect
+       width="200"
+       height="30"
+       stroke="blue"
+       fill="none"
+       id="rect507" />
+    <text
+       x="10"
+       y="20"
+       class="text_normal"
+       id="text509">Postmaster process</text>
+  </g>
+  <path
+     d="M 90,230 h 85"
+     stroke="black"
+     fill="none"
+     marker-end="url(#arrowhead_end)"
+     id="path513" />
+  <g
+     transform="translate(140, 230)"
+     id="g519">
+    <circle
+       r="8"
+       stroke="black"
+       fill="lightyellow"
+       id="circle515" />
+    <text
+       x="-4"
+       y="4"
+       class="text_small"
+       id="text517">1</text>
+  </g>
+  <!-- backend processes -->
+  <g
+     transform="translate(150, 315)"
+     id="g529">
+    <rect
+       width="370"
+       height="30"
+       stroke="blue"
+       fill="none"
+       id="rect521" />
+    <text
+       x="10"
+       y="20"
+       class="text_normal"
+       id="text523">Backend processes (one per connection)</text>
+    <path
+       d="M 5,0 v -5 h 370 v 30 h -5"
+       stroke="blue"
+       fill="none"
+       id="path525" />
+    <path
+       d="M 10,-5 v -5 h 370 v 30 h -5"
+       stroke="blue"
+       fill="none"
+       id="path527" />
+  </g>
+  <path
+     d="M 90,240 153,303"
+     stroke="black"
+     fill="none"
+     marker-start="url(#arrowhead_start)"
+     marker-end="url(#arrowhead_end)"
+     id="path531" />
+  <g
+     transform="translate(140, 290)"
+     id="g537">
+    <circle
+       r="8"
+       stroke="black"
+       fill="lightyellow"
+       id="circle533" />
+    <text
+       x="-4"
+       y="4"
+       class="text_small"
+       id="text535">3</text>
+  </g>
+  <!-- connection between postmaster and backend processes  -->
+  <path
+     d="M 360,250 v 50"
+     stroke="black"
+     fill="none"
+     marker-end="url(#arrowhead_end)"
+     id="path539" />
+  <g
+     transform="translate(190, 255)"
+     id="g545">
+    <use
+       xlink:href="#note_250x20"
+       id="use541" />
+    <text
+       x="10"
+       y="15"
+       class="text_comment"
+       id="text543">Creates backend processes</text>
+  </g>
+  <g
+     transform="translate(360, 281)"
+     id="g551">
+    <circle
+       r="8"
+       stroke="black"
+       fill="lightyellow"
+       id="circle547" />
+    <text
+       x="-4"
+       y="4"
+       class="text_small"
+       id="text549">2</text>
+  </g>
+  <!-- backend process' access to individual memory -->
+  <path
+     d="M 460,300 v -100"
+     stroke="black"
+     fill="none"
+     marker-start="url(#arrowhead_start)"
+     marker-end="url(#arrowhead_end)"
+     id="path553" />
+  <!-- its access to shared buffers and WAL buffers -->
+  <path
+     d="M 498,300 v -205 h 30"
+     stroke="black"
+     fill="none"
+     marker-start="url(#arrowhead_start)"
+     marker-end="url(#arrowhead_end)"
+     id="path555" />
+  <path
+     d="M 508,300 v -165 h 20"
+     stroke="black"
+     fill="none"
+     marker-end="url(#arrowhead_end)"
+     id="path557" />
+  <!-- WAL writer  -->
+  <g
+     transform="translate(550, 220)"
+     id="g563">
+    <rect
+       width="120"
+       height="30"
+       stroke="blue"
+       fill="none"
+       id="rect559" />
+    <text
+       x="10"
+       y="20"
+       class="text_normal"
+       id="text561">WAL Writer</text>
+  </g>
+  <path
+     d="M 590,150 v 65"
+     stroke="black"
+     fill="none"
+     marker-end="url(#arrowhead_end)"
+     id="path565" />
+  <path
+     d="M 590,255 v 230"
+     stroke="black"
+     fill="none"
+     marker-end="url(#arrowhead_end)"
+     id="path567" />
+  <!-- Checkpoiner -->
+  <g
+     transform="translate(610, 340)"
+     id="g573">
+    <rect
+       width="140"
+       height="30"
+       stroke="blue"
+       fill="none"
+       id="rect569" />
+    <text
+       x="10"
+       y="20"
+       class="text_normal"
+       id="text571">Checkpointer</text>
+  </g>
+  <path
+     d="M 740,110 v 220"
+     stroke="black"
+     fill="none"
+     marker-end="url(#arrowhead_end)"
+     id="path575" />
+  <path
+     d="M 605,355 h -130 v 130"
+     stroke="black"
+     fill="none"
+     marker-end="url(#arrowhead_end)"
+     id="path577" />
+  <path
+     d="M 700,330 v -180"
+     stroke="black"
+     fill="none"
+     marker-end="url(#arrowhead_end)"
+     id="path579" />
+  <g
+     transform="translate(570, 330)"
+     id="g587">
+    <use
+       xlink:href="#note_100x35"
+       x="50"
+       y="-50"
+       id="use581" />
+    <text
+       x="60"
+       y="-35"
+       class="text_comment"
+       id="text583">Checkpoint</text>
+    <text
+       x="60"
+       y="-20"
+       class="text_comment"
+       id="text585">Record</text>
+  </g>
+  <!-- BG writer  -->
+  <g
+     transform="translate(610, 380)"
+     id="g593">
+    <rect
+       width="180"
+       height="30"
+       stroke="blue"
+       fill="none"
+       id="rect589" />
+    <text
+       x="10"
+       y="20"
+       class="text_normal"
+       id="text591">Background Writer</text>
+  </g>
+  <path
+     d="M 770,110 v 260"
+     stroke="black"
+     fill="none"
+     marker-end="url(#arrowhead_end)"
+     id="path595" />
+  <path
+     d="M 605,395 h -120 v 90"
+     stroke="black"
+     fill="none"
+     marker-end="url(#arrowhead_end)"
+     id="path597" />
+  <!-- Archiver  -->
+  <g
+     transform="translate(610, 420)"
+     id="g603">
+    <rect
+       width="180"
+       height="30"
+       stroke="blue"
+       fill="none"
+       id="rect599" />
+    <text
+       x="10"
+       y="20"
+       class="text_normal"
+       id="text601">WAL Archiver</text>
+  </g>
+  <path
+     d="M 620,485 l 30,-30"
+     stroke="black"
+     fill="none"
+     marker-end="url(#arrowhead_end)"
+     id="path605" />
+  <path
+     d="M 740,455 v 30"
+     stroke="black"
+     fill="none"
+     marker-end="url(#arrowhead_end)"
+     id="path607" />
+  <!-- Vacuum  -->
+  <g
+     transform="translate(135, 380)"
+     id="g617">
+    <rect
+       width="120"
+       height="30"
+       stroke="blue"
+       fill="none"
+       id="rect609" />
+    <text
+       x="10"
+       y="20"
+       class="text_normal"
+       id="text611">AutoVacuum</text>
+    <path
+       d="M 5,0 v -5 h 120 v 30 h -5"
+       stroke="blue"
+       fill="none"
+       id="path613" />
+    <path
+       d="M 10,-5 v -5 h 120 v 30 h -5"
+       stroke="blue"
+       fill="none"
+       id="path615" />
+  </g>
+  <!-- Log Writer -->
+  <g
+     transform="translate(135, 430)"
+     id="g623">
+    <rect
+       width="120"
+       height="30"
+       stroke="blue"
+       fill="none"
+       id="rect619" />
+    <text
+       x="10"
+       y="20"
+       class="text_normal"
+       id="text621">Log Writer</text>
+  </g>
+  <!-- Stats Collector (135, 460) -->
+  <g
+     transform="translate(290, 370)"
+     id="g629">
+    <rect
+       width="140"
+       height="30"
+       stroke="blue"
+       fill="none"
+       id="rect625" />
+    <text
+       x="10"
+       y="20"
+       class="text_normal"
+       id="text627">Stats Collector</text>
+  </g>
+  <!--       -->
+  <!-- files -->
+  <!--       -->
+  <g
+     transform="translate(145, 490)"
+     id="g639">
+    <use
+       xlink:href="#disc"
+       id="use631" />
+    <text
+       x="35"
+       y="45"
+       class="text_normal"
+       id="text633">Log</text>
+    <text
+       x="20"
+       y="60"
+       class="text_small"
+       id="text635">text lines,</text>
+    <text
+       x="20"
+       y="75"
+       class="text_small"
+       id="text637">sequential</text>
+  </g>
+  <path
+     d="M 195,465 v 20"
+     stroke="black"
+     fill="none"
+     marker-end="url(#arrowhead_end)"
+     id="path641" />
+  <g
+     transform="translate(410, 490)"
+     id="g653">
+    <use
+       xlink:href="#disc"
+       id="use643" />
+    <text
+       x="10"
+       y="40"
+       class="text_normal"
+       id="text645">Heap and</text>
+    <text
+       x="25"
+       y="55"
+       class="text_normal"
+       id="text647">Index</text>
+    <text
+       x="15"
+       y="70"
+       class="text_small"
+       id="text649">binary blocks,</text>
+    <text
+       x="30"
+       y="80"
+       class="text_small"
+       id="text651">random</text>
+  </g>
+  <path
+     d="M 450,485 v -135"
+     stroke="black"
+     fill="none"
+     marker-end="url(#arrowhead_end)"
+     id="path655" />
+  <g
+     transform="translate(295, 420)"
+     id="g665">
+    <use
+       xlink:href="#note_170x50"
+       id="use657" />
+    <text
+       x="5"
+       y="15"
+       class="text_comment"
+       id="text659">Read heap and index</text>
+    <text
+       x="5"
+       y="30"
+       class="text_comment"
+       id="text661">pages and transfer</text>
+    <text
+       x="5"
+       y="45"
+       class="text_comment"
+       id="text663">them to shared_buffers</text>
+  </g>
+  <g
+     transform="translate(550, 490)"
+     id="g675">
+    <use
+       xlink:href="#disc"
+       id="use667" />
+    <text
+       x="30"
+       y="45"
+       class="text_normal"
+       id="text669">WAL</text>
+    <text
+       x="10"
+       y="60"
+       class="text_small"
+       id="text671">binary records,</text>
+    <text
+       x="20"
+       y="75"
+       class="text_small"
+       id="text673">sequential</text>
+  </g>
+  <g
+     transform="translate(690, 490)"
+     id="g683">
+    <use
+       xlink:href="#disc"
+       id="use677" />
+    <text
+       x="16"
+       y="45"
+       class="text_normal"
+       id="text679">Archived</text>
+    <text
+       x="36"
+       y="60"
+       class="text_normal"
+       id="text681">WAL</text>
+  </g>
+  <!-- boarder between client and server side -->
+  <path
+     d="M 110,20 v 550"
+     stroke="black"
+     fill="none"
+     id="path685" />
+  <g
+     transform="translate(123, 190) rotate(90)"
+     id="g691">
+    <use
+       xlink:href="#note_200x20"
+       id="use687" />
+    <text
+       class="text_comment"
+       x="10"
+       y="15"
+       id="text689">Via TCP/IP or socket</text>
+  </g>
+  <!-- right side -->
+  <g
+     transform="translate(850, 0) rotate(90)"
+     id="g699">
+    <text
+       class="text_big"
+       x="95"
+       id="text693">RAM</text>
+    <text
+       class="text_big"
+       x="250"
+       id="text695">PROCESSES</text>
+    <text
+       class="text_big"
+       x="500"
+       id="text697">FILES</text>
+  </g>
+</svg>
diff --git a/doc/src/sgml/images/ram-proc-file-raw.svg b/doc/src/sgml/images/ram-proc-file-raw.svg
new file mode 100644
index 0000000000..26eacde411
--- /dev/null
+++ b/doc/src/sgml/images/ram-proc-file-raw.svg
@@ -0,0 +1,301 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<svg xmlns="http://www.w3.org/2000/svg"
+     xmlns:xlink="http://www.w3.org/1999/xlink"
+     version="1.1"
+     width="900px" height="600px"
+     viewBox="0 0 900 600">
+
+  <title>PG Overall Server Architecture</title>
+
+  <style type="text/css">
+  .text_small   {font-style:normal;
+                 font-weight:normal;
+                 font-size:12px;
+                 font-family:"Open Sans", sans-serif;
+                 fill:black;
+                }
+  .text_normal  {font-style:normal;
+                 font-weight:normal;
+                 font-size:16px;
+                 font-family:"Open Sans", sans-serif;
+                 fill:black;
+                }
+  .text_big     {font-style:normal;
+                 font-weight:normal;
+                 font-size:24px;
+                 font-family:"Open Sans", sans-serif;
+                 fill:black;
+                }
+  .text_comment {font-style:italic;
+                 font-weight:normal;
+                 font-size:16px;
+                 font-family:"Open Sans", sans-serif;
+                 fill:black;
+                }
+  </style>
+
+  <defs>
+
+    <!-- Some notes in different sizes  -->
+    <symbol id="note_200x20" stroke="black" fill="lightyellow">
+      <title>UML Note (200 x 20 px)</title>
+      <path d="M 200,10 v 10 h -200 v -20 h 190 v 10 h 10 l -10,-10" />
+    </symbol>
+    <symbol id="note_250x20" stroke="black" fill="lightyellow">
+      <title>UML Note (250 x 20 px)</title>
+      <path d="M 250,10 v 10 h -250 v -20 h 240 v 10 h 10 l -10,-10" />
+    </symbol>
+    <symbol id="note_100x35" stroke="black" fill="lightyellow">
+      <title>UML Note (100 x 35 px)</title>
+      <path d="M 100,10 v 25 h -100 v -35 h 90 v 10 h 10 l -10,-10" />
+    </symbol>
+    <symbol id="note_170x50" stroke="black" fill="lightyellow">
+      <title>UML Note (170 x 50 px)</title>
+      <path d="M 170,10 v 40 h -170 v -50 h 160 v 10 h 10 l -10,-10" />
+    </symbol>
+
+    <!--  UML states (used for buffers) -->
+    <symbol id="state_300x120">
+      <title>UML State, big</title>
+      <rect x="0" y="0" width="300" height="120" rx="10" stroke="blue" fill="none"/>
+    </symbol>
+    <symbol id="state_350x120">
+      <title>UML State, big</title>
+      <rect x="0" y="0" width="350" height="120" rx="10" stroke="blue" fill="none"/>
+    </symbol>
+
+    <!-- Discs  -->
+    <symbol id="disc" stroke="blue" fill="none" >
+      <title>Disc</title>
+      <ellipse cx="51" cy="13" rx="50" ry="12" />      <!-- top -->
+      <path    d="M 1,13 v 60" />                      <!-- left -->
+      <path    d="M 101,13 v 60" />                    <!-- right -->
+      <path    d="M 1,73 A 50, 12, 0, 0, 0, 101,73" /> <!-- bottom -->
+    </symbol>
+
+    <!--  Laptop  -->
+    <symbol id="laptop" stroke="black" fill="none" >
+      <title>Laptop</title>
+      <path d="M 20,40 v -40 h 54 v 40 l 15,15 h -84 l 15,-15 h 54" />
+      <rect x="23" y="3" width="48" height="34" />
+      <!-- symbolize some lines -->
+      <path d="M 30,10 h 20" />
+      <path d="M 30,15 h 25" />
+      <path d="M 30,20 h 10" />
+      <path d="M 30,30 h 20" />
+      <!-- symbolize keyboard -->
+      <path d="M 25,50 h 45 l 2,2 h -50 z " />
+    </symbol>
+
+    <!--  marker start/end -->
+    <marker id="arrowhead_start"
+            markerWidth="10"
+            markerHeight="10"
+            refX="0"
+            refY="3"
+            orient="auto">
+      <path d="M 6,0 l -6,3 l 6,3" stroke="black" fill="none" />
+    </marker>
+    <marker id="arrowhead_end"
+            markerWidth="10"
+            markerHeight="10"
+            refX="6"
+            refY="3"
+            orient="auto">
+      <path d="M 0,0 l 6,3 l -6,3" stroke="black" fill="none" />
+    </marker>
+
+  </defs>
+
+
+  <!--  start of rendering area  -->
+  <!--  enclosing rectangle  -->
+  <rect x="1" y="1" rx="5" width="99%" height="99%" stroke="black" fill="none" />
+
+  <!-- caption, client side -->
+  <text x="15" y="40"  class="text_big">Client</text>
+  <text x="140" y="40" class="text_big">Server</text>
+  <use xlink:href="#laptop" x="5" y="210" />
+
+
+  <!--  individual memory -->
+  <g transform="translate(130, 70)">
+    <use xlink:href="#state_350x120" x="0" y="0" />
+    <text x="5" y="20"  class="text_normal">maintenance_work_mem (per connection)</text>
+    <text x="5" y="45"  class="text_normal">work_mem (per query operation)</text>
+    <text x="5" y="70"  class="text_normal">autovacuum_work_mem (per worker process)</text>
+    <text x="5" y="95" class="text_normal">temp_buffer (per connection)</text>
+    <text x="5" y="110" class="text_normal">...</text>
+    <use xlink:href="#note_200x20" x="140" y="-15" />
+    <text x="150" y="0"  class="text_comment">Individual Memory</text>
+  </g>
+
+  <!--  shared memory -->
+  <g transform="translate(520, 70)">
+    <use xlink:href="#state_300x120" x="0" y="0" />
+    <text x="10" y="30" class="text_normal">shared_buffers (heap and index)</text>
+    <text x="10" y="70" class="text_normal">wal_buffers (WAL records)</text>
+    <text x="10" y="100" class="text_normal">...</text>
+    <use xlink:href="#note_250x20" x="40" y="-15" />
+    <text x="50" y="0"  class="text_comment">Shared Memory (per Cluster)</text>
+  </g>
+
+  <!-- postmaster  -->
+  <g transform="translate(190, 215)">
+    <rect width="200" height="30" stroke="blue" fill="none" />
+    <text x="10" y="20" class="text_normal">Postmaster process</text>
+  </g>
+  <path d="M 90,230 h 85" stroke="black" fill="none" marker-end="url(#arrowhead_end)"/>
+  <g transform="translate(140, 230)">
+    <circle r="8" stroke="black" fill="lightyellow" />
+    <text x="-4" y="4" class="text_small">1</text>
+  </g>
+
+  <!-- backend processes -->
+  <g transform="translate(150, 315)">
+    <rect width="370" height="30" stroke="blue" fill="none" />
+    <text x="10" y="20" class="text_normal">Backend processes (one per connection)</text>
+    <path d="M 5,0 v -5 h 370 v 30 h -5" stroke="blue" fill="none" />
+    <path d="M 10,-5 v -5 h 370 v 30 h -5" stroke="blue" fill="none" />
+  </g>
+
+  <path d="M 90,240 153,303" stroke="black" fill="none"
+        marker-start="url(#arrowhead_start)" marker-end="url(#arrowhead_end)"/>
+  <g transform="translate(140, 290)">
+    <circle r="8" stroke="black" fill="lightyellow" />
+    <text x="-4" y="4" class="text_small">3</text>
+  </g>
+
+  <!-- connection between postmaster and backend processes  -->
+  <path d="M 360,250 v 50" stroke="black" fill="none" marker-end="url(#arrowhead_end)"/>
+  <g transform="translate(190, 255)">
+    <use xlink:href="#note_250x20" />
+    <text x="10" y="15" class="text_comment">Creates backend processes</text>
+  </g>
+  <g transform="translate(360, 281)">
+    <circle r="8" stroke="black" fill="lightyellow" />
+    <text x="-4" y="4" class="text_small">2</text>
+  </g>
+
+  <!-- backend process' access to individual memory -->
+  <path d="M 460,300 v -100" stroke="black" fill="none"
+        marker-start="url(#arrowhead_start)" marker-end="url(#arrowhead_end)"/>
+  <!-- its access to shared buffers and WAL buffers -->
+  <path d="M 498,300 v -205 h 30" stroke="black" fill="none"
+        marker-start="url(#arrowhead_start)" marker-end="url(#arrowhead_end)"/>
+  <path d="M 508,300 v -165 h 20" stroke="black" fill="none"
+        marker-end="url(#arrowhead_end)"/>
+
+  <!-- WAL writer  -->
+  <g transform="translate(550, 220)">
+    <rect width="120" height="30" stroke="blue" fill="none" />
+    <text x="10" y="20" class="text_normal">WAL Writer</text>
+  </g>
+  <path d="M 590,150 v 65" stroke="black" fill="none" marker-end="url(#arrowhead_end)"/>
+  <path d="M 590,255 v 230" stroke="black" fill="none" marker-end="url(#arrowhead_end)"/>
+
+  <!-- Checkpoiner -->
+  <g transform="translate(610, 340)">
+    <rect width="140" height="30" stroke="blue" fill="none" />
+    <text x="10" y="20" class="text_normal">Checkpointer</text>
+  </g>
+  <path d="M 740,110 v 220" stroke="black" fill="none" marker-end="url(#arrowhead_end)"/>
+  <path d="M 605,355 h -130 v 130" stroke="black" fill="none" marker-end="url(#arrowhead_end)"/>
+  <path d="M 700,330 v -180" stroke="black" fill="none" marker-end="url(#arrowhead_end)"/>
+  <g transform="translate(570, 330)">
+    <use xlink:href="#note_100x35" x="50" y="-50" />
+    <text x="60" y="-35"  class="text_comment">Checkpoint</text>
+    <text x="60" y="-20"  class="text_comment">Record</text>
+  </g>
+
+  <!-- BG writer  -->
+  <g transform="translate(610, 380)">
+    <rect width="180" height="30" stroke="blue" fill="none" />
+    <text x="10" y="20" class="text_normal">Background Writer</text>
+  </g>
+  <path d="M 770,110 v 260" stroke="black" fill="none" marker-end="url(#arrowhead_end)"/>
+  <path d="M 605,395 h -120 v 90" stroke="black" fill="none" marker-end="url(#arrowhead_end)"/>
+
+  <!-- Archiver  -->
+  <g transform="translate(610, 420)">
+    <rect width="180" height="30" stroke="blue" fill="none" />
+    <text x="10" y="20" class="text_normal">WAL Archiver</text>
+  </g>
+  <path d="M 620,485 l 30,-30" stroke="black" fill="none" marker-end="url(#arrowhead_end)"/>
+  <path d="M 740,455 v 30" stroke="black" fill="none" marker-end="url(#arrowhead_end)"/>
+
+  <!-- Vacuum  -->
+  <g transform="translate(135, 380)">
+    <rect width="120" height="30" stroke="blue" fill="none" />
+    <text x="10" y="20" class="text_normal">AutoVacuum</text>
+    <path d="M 5,0 v -5 h 120 v 30 h -5" stroke="blue" fill="none" />
+    <path d="M 10,-5 v -5 h 120 v 30 h -5" stroke="blue" fill="none" />
+  </g>
+
+  <!-- Log Writer -->
+  <g transform="translate(135, 430)">
+    <rect width="120" height="30" stroke="blue" fill="none" />
+    <text x="10" y="20" class="text_normal">Log Writer</text>
+  </g>
+
+  <!-- Stats Collector (135, 460) -->
+  <g transform="translate(290, 370)">
+    <rect width="140" height="30" stroke="blue" fill="none" />
+    <text x="10" y="20" class="text_normal">Stats Collector</text>
+  </g>
+
+  <!--       -->
+  <!-- files -->
+  <!--       -->
+  <g transform="translate(145, 490)">
+    <use xlink:href="#disc" />
+    <text x="35" y="45" class="text_normal">Log</text>
+    <text x="20" y="60" class="text_small">text lines,</text>
+    <text x="20" y="75" class="text_small">sequential</text>
+  </g>
+  <path d="M 195,465 v 20" stroke="black" fill="none" marker-end="url(#arrowhead_end)"/>
+
+  <g transform="translate(410, 490)">
+    <use xlink:href="#disc" />
+    <text x="10" y="40" class="text_normal">Heap and</text>
+    <text x="25" y="55" class="text_normal">Index</text>
+    <text x="15" y="70" class="text_small">binary blocks,</text>
+    <text x="30" y="80" class="text_small">random</text>
+  </g>
+  <path d="M 450,485 v -135" stroke="black" fill="none" marker-end="url(#arrowhead_end)"/>
+
+  <g transform="translate(295, 420)">
+    <use xlink:href="#note_170x50" />
+    <text x="5" y="15" class="text_comment">Read heap and index</text>
+    <text x="5" y="30" class="text_comment">pages and transfer</text>
+    <text x="5" y="45" class="text_comment">them to shared_buffers</text>
+  </g>
+
+  <g transform="translate(550, 490)">
+    <use xlink:href="#disc" />
+    <text x="30" y="45" class="text_normal">WAL</text>
+    <text x="10" y="60" class="text_small">binary records,</text>
+    <text x="20" y="75" class="text_small">sequential</text>
+  </g>
+
+  <g transform="translate(690, 490)">
+    <use xlink:href="#disc" />
+    <text x="16" y="45" class="text_normal">Archived</text>
+    <text x="36" y="60" class="text_normal">WAL</text>
+  </g>
+
+  <!-- boarder between client and server side -->
+  <path d="M 110,20 v 550" stroke="black" fill="none" />
+  <g transform="translate(123, 190) rotate(90)">
+    <use xlink:href="#note_200x20"  />
+    <text class="text_comment" x="10" y ="15">Via TCP/IP or socket</text>
+  </g>
+
+  <!-- right side -->
+  <g transform="translate(850, 0) rotate(90)">
+    <text class="text_big" x="95">RAM</text>
+    <text class="text_big" x="250">PROCESSES</text>
+    <text class="text_big" x="500">FILES</text>
+  </g>
+
+</svg>
diff --git a/doc/src/sgml/postgres.sgml b/doc/src/sgml/postgres.sgml
index c41ce9499b..6254bf9376 100644
--- a/doc/src/sgml/postgres.sgml
+++ b/doc/src/sgml/postgres.sgml
@@ -60,6 +60,7 @@ break is not needed in a wider output rendering.
   </partintro>
 
   &start;
+  &architecture;
   &query;
   &advanced;

---

From: Corey Huinker <[email-masked]>
Date: Fri, 17 Apr 2020 14:18:17 -0400

> the focus on the PostgreSQL implementation and not on generic topics

+1

---

From: Erik Rijkers <[email-masked]>
Date: Fri, 17 Apr 2020 20:40:32 +0200

On 2020-04-17 19:56, Jürgen Purtz wrote:
> parameters in detail and with high accuracy. Nevertheless my
> impression is that we neglect the 'big picture': why certain processes

> [0001-architecture.patch]

Very good stuff, and useful. I think.

I mean that but nevertheless here is a lot of comment :)

(I didn't fully compile as docs, just read the 'text' from the patch 
file)

Collabortion
Collaboration

drop 'resulting'

He acts in close cooperation with the
It acts in close cooperation with the

He loads the configuration files, allocates the
It loads the configuration files, allocates the

process</firstterm>. He checks the authorization, starts a
process</firstterm>. it checks the authorization, starts a

and instructs the client application to connect to him. All further
and instructs the client application to connect to it. All further

by him.
by it.

In an first attempt
In a first attempt

much huger than memory, it's likely that
much larger than memory, it's likely that

RAM is performed in units of complete pages while retaining
RAM is performed in units of complete pages, retaining

Sooner or later it is necessary to overwrite old RAM
Sooner or later it becomes necessary to overwrite old RAM

transfered
transferred
   (multiple times)

who runs
which runs

He writes
it writes

This is the primarily duty of the
This is primarily the duty of the
   or possibly:
This is the primary duty of the

he starts periodically
it starts periodically

speeds up a possibly occurring recovery.
can speed up recovery.

writen
written

collects counter about accesses
collects counters about accesses

and others. He stores the obtained information in system
and more. It stores the obtained information in system

sudirectories consists
subdirectories consist  <-- plural, no -s

there are information
there is information

and contains the ID of the
and contains the ID (pid) of the

( IMHO, it is conventional (and therefore easier to read) to have 'e.g.' 
followed by a comma, and not by a semi-colon, although obviously that's 
not really wrong either. )

Thanks,

Erik Rijkers

---

From: Jürgen Purtz <[email-masked]>
Date: Mon, 20 Apr 2020 10:30:20 +0200

> (I didn't fully compile as docs, just read the 'text' from the patch 

Thanks. Added nearly all of the suggestions.

--

Jürgen Purtz

 
index 0000000000..81dedc90b4
+   <title>Collaboration of Processes, RAM, and Files</title>
+    according information from there. In the case of
+    It acts in close cooperation with the
+    It loads the configuration files, allocates the
+    process</firstterm>. It checks the authorization, starts a
+    and instructs the client application to connect to it. All further
+    by it.
+    necessity to read or write some data. In a first attempt
+    much larger than memory, it's likely that
+    RAM is performed in units of complete pages, retaining
+    Sooner or later it becomes necessary to overwrite old RAM
+    they must be transferred back to disk. This is a two-step process.
+    which runs in parallel to the <firstterm>Backend
+    the <firstterm>Instance</firstterm>. It writes
+    <firstterm>dirty page</firstterm> must be transferred
+    itself can be transferred to disk (???).
+    take place. This is the primary duty of the
+    it starts periodically and acts only for a short period.
+    <firstterm>WAL records</firstterm> arise and are written
+    collects counters about accesses to <firstterm>SQL
+    and more. It stores the obtained information in system
+    types of <firstterm>SQL objects</firstterm>. E.g., it is not possible
+    The names of those subdirectories consist of numbers.
+    <literal>global</literal> there is information about
+    and contains the ID (pid) of the
 
 <!-- tutorial -->
 
 <!-- user's guide -->

 

+  <glossentry>
 
-  <glossentry>
 
   &start;
+  &architecture;
   &query;
   &advanced;

---

From: Jürgen Purtz <[email-masked]>
Date: Wed, 29 Apr 2020 16:13:46 +0200

> Thanks. Added nearly all of the suggestions.
What is new? Added two sub-chapters 'mvcc' and 'vacuum' plus graphics. 
Made some modifications in previous sub-chapters and in existing titles. 
Added some glossary entries.

--

Jürgen Purtz

index f6c4627c3e..be04972bd7 100644

   <sect1 id="tutorial-advanced-intro">
    <title>Introduction</title>
diff --git a/doc/src/sgml/architecture.sgml b/doc/src/sgml/architecture.sgml
new file mode 100644
index 0000000000..014a1172b6
--- /dev/null
+++ b/doc/src/sgml/architecture.sgml
@@ -0,0 +1,1159 @@
+<!-- doc/src/sgml/architecture.sgml -->
+
+ <chapter id="tutorial-architecture">
+  <title>Architecture of <productname>PostgreSQL</productname></title>
+
+  <para>
+   Every DBMS implements basic strategies to achieve a fast and
+   robust system. This chapter provides an overview of what
+   techniques <productname>PostgreSQL</productname> uses to
+   reach this aim.
+  </para>
+
+  <sect1 id="tutorial-ram-proc-file">
+   <title>Collaboration of Processes, RAM, and Files</title>
+   <para>
+    As is a matter of course, in a client/server architecture
+    clients do not have direct access to the database. Instead,
+    they merely send requests to the server side and receives
+    according information from there. In the case of
+    <productname>PostgreSQL</productname>, at the server
+    side there is one process per client, the so-called
+    <glossterm linkend="glossary-backend">Backend process</glossterm>.
+    It acts in close cooperation with the
+    <glossterm linkend="glossary-instance">Instance</glossterm> which
+    is a group of tightly coupled other server side processes plus a
+    <glossterm linkend="glossary-shared-memory">Shared Memory</glossterm>
+    area.
+   </para>
+
+   <para>
+    At start time, an instance is initiated by the
+    <glossterm linkend="glossary-postgres">Postgres</glossterm>
+    (or: Postmaster) process.
+    It loads the configuration files, allocates the
+    <glossterm linkend="glossary-shared-memory">Shared Memory</glossterm>
+    and starts the comprehensive network of processes:
+    <glossterm linkend="glossary-background-writer">Background Writer</glossterm>,
+    <glossterm linkend="glossary-checkpointer">Checkpointer</glossterm>,
+    <glossterm linkend="glossary-wal-writer">WAL Writer</glossterm>,
+    <glossterm linkend="glossary-wal-archiver">WAL Archiver</glossterm>,
+    <glossterm linkend="glossary-autovacuum">Autovacuum processes</glossterm>,
+    <glossterm linkend="glossary-stats-collector">Statistics Collector</glossterm>,
+    <glossterm linkend="glossary-logger">Logger</glossterm>, and more.
+    <xref linkend="tutorial-ram-proc-file-figure"/> visualizes
+    main aspects of their collaboration.
+   </para>
+
+   <figure id="tutorial-ram-proc-file-figure">
+    <title>Architecture</title>
+    <mediaobject>
+     <imageobject role="html">
+      <!-- attribute 'width=..px' is necessary to keep font-size of SVG text
+           in correlation with font-size of surrounding HTML  -->
+      <imagedata fileref="images/ram-proc-file-raw.svg" format="SVG" width="900px" />
+     </imageobject>
+     <imageobject role="fo">
+      <!-- For PDF attribute 'width=100%' is necessary to keep complete SVG visible
+           on the page, which has a fixed width. Font sizes will be adopted.  -->
+      <imagedata fileref="images/ram-proc-file-raw.svg" format="SVG" width="100%" />
+     </imageobject>
+    </mediaobject>
+   </figure>
+
+   <para>
+    Whenever a client application tries to connect to a
+    <glossterm linkend="glossary-database">database</glossterm>,
+    this request is handled in a first step by the <firstterm>
+    Postgres process</firstterm>. It checks the authorization,
+    starts a new <firstterm>Backend process</firstterm>,
+    and instructs the client application to connect to it. All
+    further client requests go to this process and are handled
+    by it.
+   </para>
+
+   <para>
+    Client requests (SELECT, UPDATE, ...) usually leads to the
+    necessity to read or write some data. In a first attempt
+    the client's <firstterm>Backend process</firstterm> tries
+    to get the information out of <firstterm>Shared
+    Memory</firstterm>. This <firstterm>Shared
+    Memory</firstterm> is a mirror of parts of the
+    <glossterm linkend="glossary-heap">heap</glossterm> and
+    <glossterm linkend="glossary-index">index</glossterm> files.
+    Because files are much larger than memory, it's likely that
+    the desired information is not (completely) available
+    in the RAM. In this case the <firstterm>Backend process
+    </firstterm> must transfer additional file pages to
+    <firstterm>Shared Memory</firstterm>. Files are physically
+    organized in pages. Every transfer between files and
+    RAM is performed in units of complete pages, retaining
+    their size and layout.
+   </para>
+
+   <para>
+    Reading file pages is notedly slower than reading
+    RAM. This is the main motivation for the existence of
+    <firstterm>Shared Memory</firstterm>. As soon as one
+    of the <firstterm>Backend processes</firstterm> has done
+    the job those pages are available for all other
+    <firstterm>Backend processes</firstterm> for direct
+    access in RAM.
+   </para>
+
+   <para>
+    <firstterm>Shared Memory</firstterm> is limited in size.
+    Sooner or later it becomes necessary to overwrite old RAM
+    pages. As long as the content of such pages hasn't
+    changed this is not a problem. But in
+    <firstterm>Shared Memory</firstterm> also write
+    actions take place
+    - performed by any of the <firstterm>Backend
+    processes</firstterm> (or an
+    <glossterm linkend="glossary-autovacuum">autovacuum process</glossterm>,
+    or other processes). Such modified pages are called
+    <firstterm>dirty pages</firstterm>.
+    Before <firstterm>dirty pages</firstterm> can be overwritten,
+    they must be transferred back to disk. This is a two-step process.
+   </para>
+
+   <para>
+    First, whenever the content of a page changes, a
+    <glossterm linkend="glossary-wal-record">WAL record</glossterm>
+    is created out
+    of the delta-information (difference between old and
+    new content) and stored in another area of the
+    <firstterm>Shared Memory</firstterm>. These
+    <firstterm>WAL records</firstterm> are read by the
+    <firstterm>WAL Writer</firstterm> process,
+    which runs in parallel to the <firstterm>Backend
+    processes</firstterm> and all other processes of
+    the <firstterm>Instance</firstterm>. It writes
+    the continuously arising <firstterm>WAL records</firstterm> to
+    the end of the current
+    <glossterm linkend="glossary-wal-record">WAL file</glossterm>.
+    Because of the sequential nature of this writing, it is much
+    faster than the more or less random access
+    to data files with <firstterm>heap</firstterm>
+    and <firstterm>index</firstterm> information.
+    As mentioned, this WAL-writing happens
+    in an independent process. Nevertheless all
+    <firstterm>WAL records</firstterm> created out of one
+    <firstterm>dirty page</firstterm> must be transferred
+    to disk before the <firstterm>dirty page</firstterm>
+    itself can be transferred to disk.
+   </para>
+
+   <para>
+    Second, the transfer of <firstterm>dirty buffers</firstterm>
+    from <firstterm>Shared Memory</firstterm> to files must
+    take place. This is the primary duty of the
+    <firstterm>Background Writer</firstterm> process. Because
+    huge I/O activities can block other processes significantly,
+    it starts periodically and acts only for a short period.
+    Doing so, his expensive I/O activities are spread over
+    time avoiding huge I/O peaks. Also the <firstterm>
+    Checkpointer</firstterm> process transfers
+    <firstterm>dirty buffers</firstterm> to files, see next
+    paragraph.
+   </para>
+
+   <para>
+    The <firstterm>Checkpointer</firstterm> has a special
+    duty. As its name suggests, he has to create
+    <firstterm>Checkpoints</firstterm>. Such a
+    <glossterm linkend="glossary-checkpoint">Checkpoint</glossterm>
+    is a point in time when all older <firstterm>dirty buffers</firstterm>,
+    all older <firstterm>WAL records</firstterm>, and
+    lastly a special <firstterm>Checkpoint record
+    </firstterm> have been written and flushed to disk.
+    In consequence, after a <firstterm>Checkpoint</firstterm>
+    data files and <firstterm>WAL files</firstterm> are in sync.
+    In case of a recovery (after a crash of the instance)
+    it is known that the information of all
+    <firstterm>WAL records</firstterm> preceding
+    the last <firstterm>Checkpoint record</firstterm>
+    is already integrated into the data files. This
+    speeds up a possibly occurring recovery.
+   </para>
+
+   <para>
+    In correlation with data changes,
+    <firstterm>WAL records</firstterm> arise and are written
+    to <firstterm>WAL files</firstterm>.
+    Those <firstterm>WAL files</firstterm> - in combination with
+    a previously taken <firstterm>Base Backup</firstterm> -
+    are necessary to restore a database after a crash of the
+    disk, where data files have been stored. Therefore it is
+    recommended to transfer a copy of the <firstterm>
+    WAL files</firstterm>
+    to a second, independent place. The purpose of the
+    <firstterm>WAL Archiver</firstterm> process is to perform
+    this copy action.
+   </para>
+
+   <para>
+    The <glossterm linkend="glossary-stats-collector">Stats Collector</glossterm>
+    collects counters about accesses to <firstterm>SQL
+    objects</firstterm> like tables, rows, indexes, pages,
+    and more. It stores the obtained information in system
+    tables.
+   </para>
+
+   <para>
+    The <glossterm linkend="glossary-logger">Logger</glossterm> writes
+    text lines about serious and non-serious events which can happen
+    during database access, e.g.: wrong password, no permission,
+    long-running queries, ... .
+   </para>
+
+  </sect1>
+
+  <sect1 id="tutorial-cluster-db-schema">
+   <title>The logical Perspective: Cluster, Database, Schema</title>
+
+   <para>
+    On a <glossterm linkend="glossary-server">Server</glossterm>
+    exists one or more <glossterm linkend="glossary-cluster">Cluster</glossterm>,
+    each of them contains three or more
+    <glossterm linkend="glossary-database">databases</glossterm>, each
+    database contains many <glossterm linkend="glossary-schema">schema</glossterm>,
+    a schema contains <glossterm linkend="glossary-table">tables</glossterm>,
+    <glossterm linkend="glossary-view">views</glossterm>, and a lot of other objects.
+    Each <firstterm>table</firstterm> or <firstterm>view</firstterm>
+    belongs to a certain <firstterm>schema</firstterm>, they cannot
+    belong to another <firstterm>schema</firstterm>. The same is
+    true for the schema/database and database/cluster relation.
+    <xref linkend="tutorial-cluster-db-schema-figure"/> visualizes
+    this hierarchy.
+   </para>
+
+   <figure id="tutorial-cluster-db-schema-figure">
+    <title>Cluster, Database, Schema</title>
+    <mediaobject>
+     <imageobject role="html">
+      <!-- attribute 'width=..px' is necessary to keep font-size of SVG text
+           in correlation with font-size of surrounding HTML  -->
+      <imagedata fileref="images/cluster-db-schema-raw.svg" format="SVG" width="900px" />
+     </imageobject>
+     <imageobject role="fo">
+      <!-- For PDF attribute 'width=100%' is necessary to keep complete SVG visible
+           on the page, which has a fixed width. Font sizes will be adopted.  -->
+      <imagedata fileref="images/cluster-db-schema-raw.svg" format="SVG" width="100%" />
+     </imageobject>
+    </mediaobject>
+   </figure>
+
+   <para>
+    A <firstterm>Cluster</firstterm> is the outer frame for a
+    collection of databases. Clusters are created by the command
+    <xref linkend="app-initdb"/>.
+   </para>
+
+   <para>
+    <literal>template0</literal> is the very first
+    <firstterm>database</firstterm> of any
+    <firstterm>cluster</firstterm>. C-routines create
+    <literal>template0</literal> during the initialization phase of
+    the <firstterm>cluster</firstterm>.
+    In a second step <literal>template1</literal> is generated
+    as a copy of <literal>template0</literal> and finally
+    <literal>postgres</literal> as a copy of
+    <literal>template1</literal>. All other
+    <glossterm linkend="app-createdb">new databases</glossterm>
+    of this <firstterm>cluster</firstterm>,
+    such as <literal>my_db</literal>, are also copied from
+    <literal>template1</literal>. Due to the special
+    role of <literal>template0</literal> as the origin
+    of all other <firstterm>databases</firstterm>, no client
+    can connect to it.
+   </para>
+
+   <para>
+    Every database contains <glossterm linkend="glossary-schema">
+    schemas</glossterm>, and
+    <firstterm>schemas</firstterm> contain the other
+    <glossterm linkend="glossary-sql-object">SQL Objects</glossterm>.
+    <firstterm>Schemas</firstterm> are namespaces for
+    their <firstterm>SQL objects</firstterm> and ensure - with one
+    exception - that within their scope names are used only once across all
+    types of <firstterm>SQL objects</firstterm>. E.g., it is not possible
+    to have a table <literal>employee</literal> and a view
+    <literal>employee</literal> within the same
+    <firstterm>schema</firstterm>. But it is possible to have
+    two tables <literal>employee</literal> in different
+    <firstterm>schemas</firstterm>. In this case the two tables
+    are different objects and absolutely independent from each
+    other. The only exception to this cross-type uniqueness is that
+    <glossterm linkend="glossary-unique-constraint">unique constraints
+    </glossterm> and the according <firstterm>unique index</firstterm>
+    use the same name.
+   </para>
+
+   <para>
+    Some <firstterm>schemas</firstterm> are predefined.
+    <literal>public</literal> acts as the default
+    <firstterm>schema</firstterm> and contains all such
+    <firstterm>SQL objects</firstterm>, which are created
+    within <literal>public</literal> or without using any schema
+    name. <literal>public</literal> shall not contain user defined
+    <firstterm>SQL objects</firstterm>. Instead, it is recommended to
+    create a separate <firstterm>schema</firstterm> which
+    holds individual objects like application-specific tables or
+    views. <literal>pg_catalog</literal> is a schema for all tables
+    and views of the <glossterm linkend="glossary-system-catalog">
+    System Catalog</glossterm>.
+    <literal>information_schema</literal> is a schema for several
+    tables and views of the <firstterm>System Catalog</firstterm>
+    in a way which conforms to the SQL standard.
+   </para>
+
+   <para>
+    There are a lot of different <firstterm>SQL object</firstterm>
+    types: <firstterm>database, schema, table, view, materialized
+    view, index, constraint, sequence, function, procedure,
+    trigger, role, data type, operator, tablespace, extension,
+    foreign data wrapper</firstterm>, and more. A few of them, the
+    <glossterm linkend="glossary-global-sql-object">Global SQL Objects</glossterm>,
+    are outside of the strict hierarchy:
+    All database names, all tablespace names, and all role names
+    are automatically known and available throughout the
+    complete <firstterm>cluster</firstterm>, independent from
+    the database or schema in which they where originally
+    defined. <xref linkend="tutorial-internal-objects-hierarchy-figure"/>
+    shows the relation between the object types.
+   </para>
+
+   <figure id="tutorial-internal-objects-hierarchy-figure">
+    <title>Hierarchy of Internal Objects</title>
+    <mediaobject>
+     <imageobject role="html">
+      <!-- attribute 'width=..px' is necessary to keep font-size of SVG text
+           in correlation with font-size of surrounding HTML  -->
+      <imagedata fileref="images/internal-objects-hierarchy-raw.svg" format="SVG" width="720px" />
+     </imageobject>
+     <imageobject role="fo">
+      <!-- For PDF attribute 'width=100%' is necessary to keep complete SVG visible
+           on the page, which has a fixed width. Font sizes will be adopted.  -->
+      <imagedata fileref="images/internal-objects-hierarchy-raw.svg" format="SVG" width="100%" />
+     </imageobject>
+    </mediaobject>
+   </figure>
+
+  </sect1>
+
+  <sect1 id="tutorial-directories">
+   <title>The physical Perspective: Directories and Files</title>
+
+   <para>
+    <productname>PostgreSQL</productname> organizes long lasting
+    data as well as volatile state information about transactions
+    or replication actions in the file system. Every
+    <firstterm>Cluster</firstterm> has its own root directory
+    anywhere in the file system. In many cases, the environment
+    variable <literal>PGDATA</literal> points to this directory.
+    The example of the following survey, which is shown in
+    <xref linkend="tutorial-directories-figure"/>, uses
+    <literal>data</literal> as the name of this root directory.
+   </para>
+
+   <figure id="tutorial-directories-figure">
+    <title>Directory Structure</title>
+    <mediaobject>
+     <imageobject role="html">
+      <!-- attribute 'width=..px' is necessary to keep font-size of SVG text
+           in correlation with font-size of surrounding HTML  -->
+      <imagedata fileref="images/directories-raw.svg" format="SVG" width="900px" />
+     </imageobject>
+     <imageobject role="fo">
+      <!-- For PDF attribute 'width=100%' is necessary to keep complete SVG visible
+           on the page, which has a fixed width. Font sizes will be adopted.  -->
+      <imagedata fileref="images/directories-raw.svg" format="SVG" width="100%" />
+     </imageobject>
+    </mediaobject>
+   </figure>
+
+   <para>
+    <literal>data</literal> contains many subdirectories and
+    some files, all of which are necessary to store long lasting
+    as well as temporary data. The following paragraphs
+    describe the files and subdirectories in
+    <literal>data</literal>.
+   </para>
+
+   <para>
+    <literal>base</literal> is a subdirectory in which one
+    subdirectory per <firstterm>database</firstterm> exists.
+    The names of those subdirectories consist of numbers.
+    These are the internal
+    <firstterm>Object Identifiers (OID)</firstterm>, which are
+    numbers to identify the database definition in the
+    <glossterm linkend="glossary-system-catalog">System Catalog</glossterm>.
+   </para>
+
+   <para>
+    Within the <firstterm>database</firstterm>-specific
+    subdirectories there are many files: one or more for
+    every table and every index to store <firstterm>heap</firstterm>
+    and <firstterm>index</firstterm> data. Those files are
+    accompanied by files for the
+    <link linkend="storage-fsm">Free Space Maps</link>
+    (extension <literal>_fsm</literal>) and
+    <link linkend="storage-vm">Visibility Maps</link>
+    (extension <literal>_vm</literal>), which contain optimization information.
+   </para>
+
+   <para>
+    Another important subdirectory is <literal>global</literal>.
+    In analogy to the <firstterm>database</firstterm>-specific
+    subdirectories, there are files containing information about
+    <glossterm linkend="glossary-global-sql-object">Global SQL objects</glossterm>.
+    One type of such <firstterm>Global Objects</firstterm> are
+    <firstterm>tablespaces</firstterm>. In
+    <literal>global</literal> there is information about
+    the <firstterm>tablespaces</firstterm>, not the
+    <firstterm>tablespaces</firstterm> itself.
+   </para>
+
+   <para>
+    The subdirectory <literal>pg_wal</literal> contains the
+    <glossterm linkend="glossary-wal-file">WAL files</glossterm>.
+    They arise and grow parallel to data changes in the
+    <firstterm>cluster</firstterm> and remain alive as long as
+    they are required for recovery, archiving, or replication.
+   </para>
+
+   <para>
+    The subdirectory <literal>pg_xact</literal> contains
+    information about the status of each transaction
+    (IN_PROGRESS, COMMITTED, ABORTED, or SUB_COMMITTED).
+   </para>
+
+   <para>
+    In <literal>pg_tblspc</literal> there are symbolic links
+    that point to directories containing such<firstterm>
+    SQL objects</firstterm> that are created within
+    <firstterm>tablespaces</firstterm>.
+   </para>
+
+   <para>
+    In the root directory <literal>data</literal>
+    there are also some files.
+    In many cases, the configuration
+    files of this <firstterm>cluster</firstterm>
+    are stored here. As long as the <firstterm>
+    cluster</firstterm> is up and running, the file
+    <literal>postmaster.pid</literal> exists here
+    and contains the ID (pid) of the
+    <firstterm>Postgres</firstterm> (respectively
+    <firstterm>Postmaster</firstterm>) process.
+   </para>
+
+   <para>
+    For more details about the physical implementation
+    of database objects, see <xref linkend="storage"/>.
+   </para>
+
+  </sect1>
+
+  <sect1 id="tutorial-mvcc">
+   <title>MVCC</title>
+
+   <para>
+    In most cases, <productname>PostgreSQL</productname> based applications
+    support many clients at the same time. Therefore, it is necessary to
+    protect simultaneously running requests from unwanted overwriting
+    of other's data as well as from reading inconsistent data. Imagine an
+    online shop offering the last copy of an article. Two clients show the
+    article at their user interface. After a while, but at the same time,
+    both users decide to put it to their shopping cart or even to buy it.
+    The dabase must take a sensible decision to prevent the application
+    from promising delivery of the single article to both clients.
+   </para>
+
+   <para>
+    A first approach may be the locking of critical rows. There are
+    two main categories of such techniques: <emphasis>Optimistic Concurrency
+    Control</emphasis> (OCC) and <emphasis>Two Phase Locking</emphasis> (2PL).
+    <productname>PostgreSQL</productname> implements the more sophisticated
+    technique <firstterm>Multiversion Concurrency Control</firstterm> (MVCC).
+    The crucial advantage of MVCC over other technologies gets evident
+    in multiuser OLTP environments with a huge number of concurrent write
+    actions. There, MVCC generally performs better than solutions using locks.
+    In a <productname>PostgreSQL</productname> database reading never blocks
+    writing and writing never blocks reading, even in the strictest level of
+    transaction isolation.
+   </para>
+
+   <para>
+    Instead of locking rows, the <firstterm>MVCC</firstterm> technique creates
+    a new version of the same row when any data-change takes place. In order
+    to distinct between these versions as well as to track the timeline
+    of the row, each of the versions contain, in additon to their user
+    defined columns, two special system columns, which are not visible
+    for the usual <command>SELECT * FROM ...</command> command.
+    The column <command>xmin</command> contains the transaction ID (xid)
+    of the transaction which creates this version of the row. Accordingly,
+    <command>xmax</command> contains the xid of the transaction which has
+    deleted this version respectively a zero, if the version is not
+    deleted. You can read both with the command
+    <command>SELECT xmin, xmax, * FROM ... </command>.
+   </para>
+
+   <para>
+    When we speak about transaction IDs, you need to know that xids are like
+    sequences. Every new transaction receives the next number as its ID.
+    Therefore, this flow of xids represents the flow of transaction
+    start events over time. But keep in mind that xids are independent from
+    any real time messurement - in milliseconds or whatever. If you dive
+    deeper into <productname>PostgreSQL</productname>, you will recognize
+    parameters with names such as 'xxx_age'. Despite of their names,
+    these '_age' parameters do not specify a period of time but represent
+    a certain number of transactions, e.g. 100 millions.
+   </para>
+
+   <para>
+    Please note that the description in this chapter simplifies the facts
+    by omitting details. When many transactions are running simultaneously,
+    things can get very complicated. Sometimes they get aborted via
+    ROLLBACK immediately or after a lot of other activities, sometimes
+    a single row is involved in more than one transaction, sometimes
+    a client crashes, sometimes the sequence of xids restarts
+    from zero, ... . Therefore, every version of a row contains more
+    system columns and flags, not only xmin and xmax.
+   </para>
+
+   <para>
+    So, what's going on in detail when write accesses take place?
+    <xref linkend="tutorial-mvcc-figure"/> shows details concerning
+    xmin, xmax, and the user data.
+   </para>
+
+   <figure id="tutorial-mvcc-figure">
+    <title>Multiversion Concurrency Control</title>
+    <mediaobject>
+     <imageobject role="html">
+      <imagedata fileref="images/mvcc-raw.svg" format="SVG" width="900px" />
+     </imageobject>
+     <imageobject role="fo">
+      <!-- For PDF attribute 'width=100%' is necessary to keep complete SVG visible
+           on the page, which has a fixed width. Font sizes will be adopted.  -->
+      <imagedata fileref="images/mvcc-raw.svg" format="SVG" width="100%" />
+     </imageobject>
+    </mediaobject>
+   </figure>
+
+   <para>
+    An <command>INSERT</command> command creates the first
+    version of a row. Beside its user data <literal>'x'</literal>,
+    this version contains the ID of the creating transaction <literal>123</literal>
+    in xmin and <literal>0</literal> in xmax. xmin indicates that the version
+    exists since transaction <literal>123</literal> and xmax indicates that
+    it is currently not deleted.
+   </para>
+
+   <para>
+    Somewhat later, transaction <literal>135</literal> executes an
+    <command>UPDATE</command> of this row, intending to change the user data
+    from <literal>'x'</literal> to <literal>'y'</literal>. According to
+    the MVCC principles, the data in the old version of the row does not
+    change! The value <literal>'x'</literal> keeps as it was before.
+    Only xmax changes to <literal>135</literal>. Now this version
+    is treated as valid exclusively for transactions with xids from
+    <literal>123</literal> to <literal>134</literal>. As a substitute
+    for the non-ocurring change of data in the old version, the
+    <command>UPDATE</command> creates a new version of the row with
+    its xid in xmin, 0 in xmax, and <literal>'y'</literal> in the
+    user data (plus all the other user data from the old version).
+    This version is now valid for all comming transactions.
+   </para>
+
+   <para>
+    All subsequent <command>UPDATE</command> commands behave in the
+    same way as the first one: they put their
+    xid to xmax of the current version, create the next version
+    with their xid in xmin, 0 in xmax, and the new user data.
+   </para>
+
+   <para>
+    Finally, a row may be deleted by a <command>DELETE</command>.
+    Even in this case all versions of the row keep as
+    before, nothing is thrown away! Only xmax of the last
+    version changes to the xid of the  <command>DELETE</command>
+    transaction, which indicates that it is only valid for
+    transactions with xids older than its own (from
+    <literal>142</literal> to <literal>820</literal> in this
+    example).
+   </para>
+
+   <para>
+    In summary, the MVCC technology creates more and more versions
+    of the same row in a table's heap file and leaves them there,
+    even with a DELETE command. The youngest version is relevant
+    for all future transactions. But the system must also preserve
+    some of the older ones for a certain amount of time as there
+    is the possiblility that they are or could become relevant
+    for any of the pending transactions. Over time, also the
+    older ones get out of scope for ALL transactions and therefore
+    becomes unnecessary. Nevertheless, they exist physically on
+    the disk and occupy space.
+   </para>
+
+   <para>
+    Please keep in mind:
+   </para>
+   <itemizedlist spacing="compact" mark="opencircle">
+
+    <listitem>
+     <simpara>
+      xmin and xmax indicate the range from where to where
+      row versions are valid (visible) for transactions.
+      This range doesn't imply any direct temporal meaning,
+      the sequence of xids reflects only the sequence of
+      transaction begin events. As
+      xids grow, old row versions get out of scope over time.
+      If an old row version is no longer valid for ALL existing
+      transactions, it's called <firstterm>dead</firstterm>. The
+      space occupied by the sum of all dead row versions is
+      called <firstterm>bloat</firstterm>.
+     </simpara>
+    </listitem>
+
+    <listitem>
+     <simpara>
+      Internally, an <command>UPDATE</command> command acts in the
+      same way as a <command>DELETE</command> command followed by
+      an <command>INSERT</command> command.
+     </simpara>
+    </listitem>
+
+    <listitem>
+     <simpara>
+      Nothing gets wiped away - with the consequence that the database
+      occupies more and more disc space. It is obvious that
+      this behaviour has to be automatically corrected in some
+      way. The next chapter explains how AUTOVACUUM fulfills
+      this task.
+     </simpara>
+    </listitem>
+
+   </itemizedlist>
+
+  </sect1>
+
+  <sect1 id="tutorial-vacuum">
+   <title>Vacuum</title>
+
+   <para>
+    As we have seen in the previous chapter, the database tends to occupy
+    more and more disc space, the <firstterm>bloat</firstterm>.
+    This chapter explains how the SQL command
+    <firstterm>VACUUM</firstterm> and the automatically running
+    <firstterm>AUTOVACUUM</firstterm> processes clear the situation.
+   </para>
+
+   <para>
+    Client processes can issue the SQL command VACUUM at arbitrary
+    points in time. DBAs do this when they recognize special situations
+    or they start it in batch jobs which run on a regular basis.
+    AUTOVACUUM processes run as part of the
+    <link linkend="glossary-instance">Instance</link> at the server.
+    There is an constantly running AUTOVACUUM daemon. He permantly
+    controlls the state of all databases based on values which are
+    collected by the <link linkend="glossary-stats-collector">
+    Statistics Collector</link> and starts
+    AUTOVACUUM processes whenever he detects certain situations.
+    Thus, it's a dynamic behavior of <productname>PostgreSQL</productname>
+    with the intention to tidy up - not always, but whenever it
+    is appropriate.
+   </para>
+
+   <para>
+    VACUUM as well as AUTOVACUUM don't just eliminate bloat.
+    They perform additional tasks to minimizing future
+    I/O activities of themselves as well as of other processes.
+    This additional work can be done in a very efficient way,
+    since in most cases the expensive physical access to pages
+    has taken place anyway for the purpose of eliminating bloat.
+    The additional operations are:
+   </para>
+
+   <itemizedlist spacing="compact" mark="opencircle">
+
+    <listitem>
+     <simpara>
+      <firstterm>Freeze</firstterm>: Mark the jungest row version
+      as frozen. This means that the version
+      is always treated as valid (visible) independent from
+      the <firstterm>wraparound problematic</firstterm> (see below).
+     </simpara>
+    </listitem>
+
+    <listitem>
+     <simpara>
+      <firstterm>Visibility Map</firstterm> and
+      <firstterm>Free Space Map</firstterm>: Log information about
+      the state of the handled pages in two additional files, the
+      Visibility Map and the Free Space Map.
+     </simpara>
+    </listitem>
+
+    <listitem>
+     <simpara>
+      <emphasis>Statistics</emphasis>: Collect statistics about the
+      number of rows per table, the distribution of values, and so on,
+      as the basis for query planners decision making.
+     </simpara>
+    </listitem>
+
+   </itemizedlist>
+
+   <para>
+    The eagerness - you can call it 'agressivity' - of the
+    operations <emphasis>eliminating bloat</emphasis> and
+    <emphasis>freeze</emphasis> is controlled by configuration
+    parameters, runtime flags and in extreme situations by
+    themselves. Because vacuum operations typically are I/O
+    intensive, which can hinder other activities, AUTOVACUUM
+    avoids to perform many vacuum operations in a bulk. Instead,
+    it carries out many short actions with time gaps in between.
+    The SQL command VACUUM runs immediately without any
+    time gaps.
+   </para>
+
+   <sect2>
+    <title>Eliminate Bloat</title>
+
+    <para>
+     To determine which of the row versions are superfluous, the
+     elimination operation must evaluate xmax against several criterias
+     which all must apply:
+    </para>
+    <itemizedlist spacing="compact" mark="opencircle">
+
+     <listitem>
+      <simpara>
+       xmax must be different from zero because a value of zero
+       indicates that the row version is still valid.
+      </simpara>
+     </listitem>
+
+     <listitem>
+      <simpara>
+       xmax must contain an xid which is older than the oldest xid of all
+       currently running transactions (min(pg_stat_activity.backend_xmin)).
+       This criterion guarantees that no existing or upcomming transaction
+       will have read or write access this row version.
+      </simpara>
+     </listitem>
+
+     <listitem>
+      <simpara>
+       The transaction of xmax must be commited. If it was rollback-ed,
+       this row version is treated as valid.
+      </simpara>
+     </listitem>
+
+     <listitem>
+      <simpara>
+       If there is the situation that the row version is part of
+       multiple transactions, special care and some more actions
+       must be taken, see: <xref linkend="vacuum-for-multixact-wraparound"/>.
+      </simpara>
+     </listitem>
+
+    </itemizedlist>
+
+    <para>
+     After the vacuum operation detects a superflous row version, it
+     marks its space as free for future use of writing
+     actions. Only in rare situations (or in the case of VACUUM FULL)
+     this space is released to the operating system. In most cases
+     it keeps occupied by PostgreSQL and will be used by future
+     INSERT or UPDATE commands concerning this or a completely
+     different row.
+    </para>
+
+    <para>
+     Which actions start the elimination of bloat?
+
+    <itemizedlist spacing="compact" mark="opencircle">
+
+      <listitem>
+       <simpara>
+        When a client issues the SQL command VACUUM in its default format,
+        i.e. without any option. To boost performance, in this and the
+        next case VACUUM does not read and act on all pages of the heap.
+        The Visibility Map, which is very compact and therefore has a small
+        size, contains information about pages, where bloat-candidates might
+        be found. Only such pages are processed.
+       </simpara>
+      </listitem>
+
+      <listitem>
+       <simpara>
+        When a client issues the SQL command VACUUM with the option FREEZE.
+       (In this case it undertakes much more actions, see
+       <xref linkend="tutorial-freeze"/>).
+       </simpara>
+      </listitem>
+
+      <listitem>
+       <simpara>
+        When a client issues the SQL command VACUUM with the option FULL.
+        Also in this mode the bloat disappears, but the used strategy
+        is very different: In this case the complete table is copied
+        to a different file skipping all outdated row versions. This
+        leads to a significant reduction of used disc space because
+        the new file contains only the actual data and the old file
+        is deleted.
+       </simpara>
+      </listitem>
+
+      <listitem>
+       <simpara>
+        When an AUTOVACUUM process acts. For optimization
+        purposes he considers the Visiblility Map in the same way as
+        VACUUM. Additionally, he ignores tables with few modifications,
+        see <xref linkend="guc-autovacuum-vacuum-threshold"/>
+        which defaults to 50 rows and
+        <xref linkend="guc-autovacuum-vacuum-scale-factor"/>
+        which defaults to 20%.
+       </simpara>
+      </listitem>
+
+     </itemizedlist>
+    </para>
+
+    <para>
+     This logic only applies to row versions of the heap. Index entries
+     don't use xmin/xmax. Nevertheless such index entries, which would
+     lead to outdated row versions, are released accordingly.
+     (??? more explanations ???)
+    </para>
+
+    <para>
+     The above descriptions omit the fact that xids on a real computer
+     have a limited size. They count up in the same way as sequences and after
+     a certain number of new transactions they are forced to restart
+     from the beginning, which is called <firstterm>wraparound</firstterm>.
+     Therefore the terms 'old transaction' / 'young transaction' does
+     not always correlate with low / hight values of xids. Near to the
+     wraparound point there are cases where xmin has a highter value
+     than xmax, although their meaning is said to be older than xmax.
+    </para>
+
+    <figure id="tutorial-wraparound-figure">
+     <title>Cyclic usage of XIDs</title>
+     <mediaobject>
+      <imageobject role="html">
+       <!-- attribute 'width=..px' is necessary to keep font-size of SVG text
+            in correlation with font-size of surrounding HTML  -->
+       <imagedata fileref="images/wraparound-raw.svg" format="SVG" width="850px" />
+      </imageobject>
+      <imageobject role="fo">
+       <!-- For PDF attribute 'width=100%' is necessary to keep complete SVG visible
+            on the page, which has a fixed width. Font sizes will be adopted.  -->
+       <imagedata fileref="images/wraparound-raw.svg" format="SVG" width="100%" />
+      </imageobject>
+     </mediaobject>
+    </figure>
+
+   </sect2>
+
+   <sect2 id="tutorial-freeze">
+    <title>Freeze Row Versions</title>
+
+    <para>
+     The use of a limited range of IDs for transactions leads
+     to the necessity to restart the sequence sooner or later.
+     This does not only have the rare consequence previously
+     described that sometimes xmin is huger than xmax. The far
+     more important problem is, that whenever the system has
+     to evaluate a WHERE condition, it must decide which row
+     versions are valid (visible) from the perspective of the
+     transaction of this query. If a wraparound couldn't happen,
+     this decision would be relative easy: the xid
+     must be between xmin and xmax, and the corresponding
+     transactions of xmin and xmax must be commited. However,
+     PostgeSQL has to consider the possiblity of wraparounds.
+     Therefore the decision becomes more complex. The general
+     idea of the solution is, to use the 'between xmin and xmax'
+     comparision only during the youngest period of the row
+     versions livetime and afterwards replace it with a
+    'valid forever' flag in its header.
+    </para>
+
+    <itemizedlist spacing="compact" mark="opencircle">
+
+     <listitem>
+      <simpara>
+       In a first step, PostgreSQL divides the complete range of
+       possible xids into two halfs with the two splitt-points
+       'txid_current' and 'txid_current + 2^31'. The half behind
+       'txid_current' is considered to represent xids of the
+       'past' and the half ahead of 'txid_current' those of the
+       'future'. Those of the 'past' are valid (visible) and those
+       of the 'future' not.
+      </simpara>
+     </listitem>
+
+     <listitem>
+      <simpara>
+       Over time the two splitt-points move forward. When
+       'txid_current + 2^31' would reach a row version with
+       xmin equal to that value, it would immediately jump
+       from 'past' to 'future' and would be no longer visible!
+      </simpara>
+     </listitem>
+
+     <listitem>
+      <simpara>
+       To avoid this unacceptable extinction of data the vacuum
+       operation <firstterm>freeze</firstterm> clears the situation
+       long before the splitt-point is reached. It sets a flag
+       in the header of the row version, which eliminates
+       completely the future use of xmin/xmax and indicates
+       that the version is valid not only in the 'past'-half
+       but also in the 'future'-half as well as in all comming
+       <glossterm linkend="glossary-epoch">epochs</glossterm>.
+      </simpara>
+     </listitem>
+    </itemizedlist>
+
+    <para>
+     Which row versions can be frozen by the vacuum operation?
+     Again, serveral criterias must be checked and all must be met.
+
+     <itemizedlist spacing="compact" mark="opencircle">
+
+      <listitem>
+       <simpara>
+        xmax must be zero because only non-deleted rows can be
+        visible 'forever'.
+       </simpara>
+      </listitem>
+
+      <listitem>
+       <simpara>
+        xmin must be older than all currently existing transactions.
+        This guarantees that no existing transaction can modify or
+        delete the version.
+       </simpara>
+      </listitem>
+
+      <listitem>
+       <simpara>
+        The transaction of xmin must be commited.
+       </simpara>
+      </listitem>
+     </itemizedlist>
+    </para>
+
+    <para>
+     At what point in time the freeze operation will take place?
+
+     <itemizedlist spacing="compact" mark="opencircle">
+      <listitem>
+       <simpara>
+        When a client issues the SQL command VACUUM with its
+        FREEZE option. In this case all such pages are
+        processed that are marked in the Visibility Map
+        to potentially have unfrozen rows.
+       </simpara>
+      </listitem>
+
+      <listitem>
+       <simpara>
+        When a client issues the SQL command VACUUM without any
+        option, but finds that there are xids older than
+        <xref linkend="guc-vacuum-freeze-table-age"/>
+        (default: 150 million) minus
+        <xref linkend="guc-vacuum-freeze-min-age"/>
+        (default: 50 million).
+        As before, all such pages are processed that are
+        marked in the Visibility Map to potentially have unfrozen
+        rows.
+       </simpara>
+      </listitem>
+
+      <listitem>
+       <simpara>
+        When an AUTOVACUUM process runs. Such a process acts
+        in one of two modes:
+       </simpara>
+
+       <itemizedlist spacing="compact" mark="opencircle">
+        <listitem>
+         <simpara>
+          In the <emphasis>normal mode</emphasis> he skips
+          pages with row versions that are younger than
+          <xref linkend="guc-vacuum-freeze-min-age"/>
+          (default: 50 million) and works only on pages where
+          all xids are older. The skipping of jung xids prevents
+          work on such pages, which are likely to be changed
+          by one of the future SQL commands.
+         </simpara>
+        </listitem>
+
+        <listitem>
+         <simpara>
+          The process switches
+          to an <emphasis>aggressive mode</emphasis>, if he recognize
+          that for the processed table their oldest xid exceeds
+          <xref linkend="guc-autovacuum-freeze-max-age"/>
+          (default: 200 million). The value of the oldest unfrozen
+          xid is stored per table in <emphasis>pg_class.relfrozenxid</emphasis>.
+          In this <emphasis>aggressive mode</emphasis> mode AUTOVACUUM
+          processes all such pages of the selected table that are marked
+          in the Visibility Map to potentially have bloat or unfrozen rows.
+         </simpara>
+        </listitem>
+
+       </itemizedlist>
+      </listitem>
+     </itemizedlist>
+    </para>
+
+    <para>
+     In the first two cases and with autovacuum in
+     <emphasis>aggressive mode</emphasis>, the system knowns
+     to which value the oldest unfrozen xid has moved forward and
+     logs the value in <emphasis>pg_class.relfrozenxid</emphasis>.
+     The distance between this value and the 'txid_current' split
+     point becomes smaller and the distance to 'txid_current + 2^31'
+     larger than before.
+    </para>
+
+    <figure id="tutorial-freeze-figure">
+     <title>Freeze</title>
+     <mediaobject>
+      <imageobject role="html">
+       <!-- attribute 'width=..px' is necessary to keep font-size of SVG text
+            in correlation with font-size of surrounding HTML  -->
+       <imagedata fileref="images/freeze-raw.svg" format="SVG" width="850px" />
+      </imageobject>
+      <imageobject role="fo">
+       <!-- For PDF attribute 'width=100%' is necessary to keep complete SVG visible
+            on the page, which has a fixed width. Font sizes will be adopted.  -->
+       <imagedata fileref="images/freeze-raw.svg" format="SVG" width="100%" />
+      </imageobject>
+     </mediaobject>
+    </figure>
+
+   </sect2>
+
+   <sect2>
+    <title>Protection against Wraparound Failure</title>
+
+    <para>
+     The AUTOVACUUM processes are initiated by the constantly
+     running <firstterm>autovacuum daemon</firstterm>. If the
+     daemon detects that for a table <firstterm>
+     autovacuum_freeze_max_age</firstterm> is exceeded, it starts
+     an AUTOVACUUM process in the <emphasis>aggressive mode</emphasis>
+     (see above) - even if AUTOVACUUM is disabled.
+    </para>
+   </sect2>
+
+   <sect2>
+    <title>Visibility Map and Free Space Map</title>
+
+    <para>
+     The <xref linkend="glossary-visibility-map"/> (VM)
+     contains two flags - stored as
+     two bits - for each page of the heap. If the first bit
+     is set, it indicates that the associated page does not
+     contain any bloat. If the second one is set, it indicates
+     that the page contains only frozen rows.
+    </para>
+
+    <para>
+      Please consider two details. First, usually a page
+      contains many rows, each of them in many versions.
+      However, the flags are associated with the page,
+      not with a row or a row version! The flags are set
+      only under the condition that they are valid for ALL
+      row versions of the page. Second, since there
+      are only two bits per page, the VM is considerably
+      smaller than the heap. Therefore it is buffered
+      in RAM in almost all cases.
+    </para>
+
+    <para>
+     The setting of the flags is silently done by VACUUM
+     and AUTOVACUUM during their bloat and freeze operations.
+     This is done to accelerate future vacuum actions,
+     regular accesses to heap pages, and some accesses to
+     the index. The flags are cleared with every data-modifying
+     operation on any row version of the page.
+    </para>
+
+    <para>
+     The <xref linkend="glossary-free-space-map"/> (FSM)
+     tracks the amount of free space per page. It is
+     organized as a highly condensed b-tree of (rounded) sizes.
+     As long as VACUUM or AUTOVACUUM change the free space
+     on any processed page, they log the new values in
+     the FSM in the same way as all other writing
+     processes.
+    </para>
+
+   </sect2>
+
+   <sect2>
+    <title>Statistics</title>
+
+    <para>
+     Statistic information helps the <link
+     linkend="planner-stats">Query Planner</link> to take optimal
+     decisions for the generation of execution plans. This
+     information can be gathered with the SQL commands ANALYZE
+     or VACUUM ANALYZE. But also autovacuum processes gather
+     such information. Depending on the percentage of changed rows
+     per table <xref linkend="guc-autovacuum-analyze-scale-factor"/>
+     the autovacuum daemon starts autovacuum processes to collect
+     statistics per table. This dynamic invocation of analyze
+     operations allows <productname>PostgreSQL</productname> to
+     adopt queries to changing circumstances.
+    </para>
+
+    <para>
+     For more details about vacuum operations, especially for its
+     numerous parameters, see <xref linkend="routine-vacuuming"/>.
+    </para>
+
+   </sect2>
+  </sect1>
+
+<!-- ToDo
+
+  <sect1 id="tutorial-transactions-mvcc">
+   <title>Transactions</title>
+
+   <para>
+...
+   </para>
+
+  </sect1>
+
+  <sect1 id="tutorial-backup">
+   <title>Backup</title>
+
+   <para>
+...
+   </para>
+
+  </sect1>
+
+  <sect1 id="tutorial-replication">
+   <title>Replication</title>
+
+   <para>
+...
+   </para>
+
+  </sect1>
+-->
+
+ </chapter>
diff --git a/doc/src/sgml/filelist.sgml b/doc/src/sgml/filelist.sgml
index 68179f71cd..ca29c8bc4e 100644
--- a/doc/src/sgml/filelist.sgml
+++ b/doc/src/sgml/filelist.sgml
@@ -8,9 +8,10 @@
 <!ENTITY problems   SYSTEM "problems.sgml">
 
 <!-- tutorial -->
 
 <!-- user's guide -->
 <!ENTITY array      SYSTEM "array.sgml">
diff --git a/doc/src/sgml/glossary.sgml b/doc/src/sgml/glossary.sgml
index 8c6cb6e942..ff2355a10c 100644
--- a/doc/src/sgml/glossary.sgml
+++ b/doc/src/sgml/glossary.sgml
@@ -141,7 +141,8 @@
    <glossterm>Background Writer (process)</glossterm>
    <glossdef>
     <para>
-     A process that continuously writes dirty pages from
+     A process that continuously writes
+     <glossterm linkend="glossary-dirty-buffer">dirty buffers</glossterm> from
      <glossterm linkend="glossary-shared-memory">shared memory</glossterm> to
      the file system.  It wakes up periodically, but works only for a short
      period in order to distribute its expensive <acronym>I/O</acronym>
@@ -155,6 +156,16 @@
    </glossdef>
   </glossentry>
 
+  <glossentry id="glossary-bloat">
+   <glossterm>Bloat</glossterm>
+   <glossdef>
+    <para>
+     Bloat is disk or RAM space, which does not contain relevant
+     data, e.g.: free space within blocks or outdated row versions.
+    </para>
+   </glossdef>
+  </glossentry>
+
   <glossentry id="glossary-cast">
    <glossterm>Cast</glossterm>
    <glossdef>
@@ -208,15 +219,6 @@
    </glossdef>
   </glossentry>
 
@@ -244,6 +246,15 @@
    </glossdef>
   </glossentry>
 
@@ -446,6 +457,26 @@
    </glossdef>
   </glossentry>
 
+  <glossentry id="glossary-dirty-buffer">
+   <glossterm>Dirty Buffer</glossterm>
+   <glossdef>
+    <para>
+     File pages are mirrored in RAM (<glossterm
+     linkend="glossary-shared-memory">Shared Memory</glossterm>).
+     Data changes happens in a first step in RAM and are
+     transfered to disk at a later point in time. During the period
+     from the buffer change to its tranfer to disk, he is
+     called a dirty buffer. Sometimes people use the term
+     <glossterm linkend="glossary-dirty-page">dirty page</glossterm>.
+    </para>
+   </glossdef>
+  </glossentry>
+
+  <glossentry id="glossary-dirty-page">
+   <glossterm>Dirty Page</glossterm>
+   <glosssee otherterm="glossary-dirty-buffer" />
+  </glossentry>
+
   <glossentry id="glossary-durability">
    <glossterm>Durability</glossterm>
    <glossdef>
@@ -459,6 +490,23 @@
    </glossdef>
   </glossentry>
 
+  <glossentry id="glossary-epoch">
+   <glossterm>Epoch</glossterm>
+   <glossdef>
+    <para>
+     In a time-related context: The number of seconds since
+     00:00:00 UTC on 1 January 1970, minus leap seconds.
+    </para>
+    <para>
+     In reference to transaction IDs: The number of available
+     <glossterm linkend="glossary-xid">xids</glossterm> is limited
+     because they use a 32-bit integer. Sooner or later the
+     sequence must restart from the beginning. Every such roundtrip
+     is called an epoch.
+    </para>
+   </glossdef>
+  </glossentry>
+
   <glossentry id="glossary-extension">
    <glossterm>Extension</glossterm>
    <glossdef>
@@ -564,6 +612,38 @@
    </glossdef>
   </glossentry>
 
+  <glossentry id="glossary-fork">
+   <glossterm>Fork</glossterm>
+   <glossdef>
+    <para>
+     Each table and index has three so-called forks to
+     store data, Free Space Map, and Visibility Map in
+     separate files. The forks are called
+     <literal>'main'</literal>, <literal>'fsm'</literal>,
+     and <literal>'vm'</literal>. An unlogged table has
+     the additional fork <literal>'init'</literal> to
+     initialize the table in case of a crash.
+    </para>
+   </glossdef>
+  </glossentry>
+
+  <glossentry id="glossary-free-space-map">
+   <glossterm>Free Space Map</glossterm>
+   <glossdef>
+    <para>
+     For each table and index exists an assigned file, the
+     Free Space Map. It tracks the amount of free space
+     per page. It is organized as a highly condensed b-tree
+     of (rounded) size.
+    </para>
+
+    <para>
+     For more information, see
+     <xref linkend="storage-fsm"/>.
+    </para>
+   </glossdef>
+  </glossentry>
+
   <glossentry id="glossary-function">
    <glossterm>Function</glossterm>
    <glossdef>
@@ -761,25 +841,6 @@
    </glossdef>
   </glossentry>
 
@@ -803,6 +864,25 @@
    </glossdef>
   </glossentry>
 
@@ -929,8 +1009,8 @@
    </glossdef>
   </glossentry>
 
-  <glossentry id="glossary-postmaster">
-   <glossterm>Postmaster (process)</glossterm>
+  <glossentry id="glossary-postgres">
+   <glossterm>Postgres (process)</glossterm>
    <glossdef>
     <para>
       The very first process of an <glossterm linkend="glossary-instance">instance</glossterm>.
@@ -945,6 +1025,16 @@
    </glossdef>
   </glossentry>
 
+  <glossentry id="glossary-postmaster">
+   <glossterm>Postmaster (process)</glossterm>
+   <glossdef>
+    <para>
+      An outdated term for the <glossterm
+      linkend="glossary-postgres"> Postgres</glossterm> process.
+    </para>
+   </glossdef>
+  </glossentry>
+
   <glossentry id="glossary-primary-server">
    <glossterm>Primary (server)</glossterm>
    <glossdef>
@@ -1188,11 +1278,13 @@
     <para>
      A schema is a namespace for <glossterm linkend="glossary-sql-object">SQL objects</glossterm>,
      which all reside in the same
-     <glossterm linkend="glossary-database">database</glossterm>.  Each
+     <glossterm linkend="glossary-database">database</glossterm>. Each
      SQL object must reside in exactly one schema.
     </para>
     <para>
-     The names of SQL objects of the same type in the same schema are enforced unique.
+     The names of SQL objects in the same schema are enforced unique.
+     This applies across all object types with a single exception:
+     Unique constraints and the according unique index use the same name.
      There is no restriction on reusing a name in multiple schemas.
     </para>
     <para>
@@ -1651,6 +1743,24 @@
    </glossdef>
   </glossentry>
 
+  <glossentry id="glossary-visibility-map">
+   <glossterm>Visiblility Map</glossterm>
+   <glossdef>
+    <para>
+     For each table exists an assigned file, the Visibliltiy Map,
+     which contains two bit per file page. If the first bit
+     is set, it indicates that the associated page does not
+     contain any bloat. If the second one is set, it indicates
+     that the page contains only frozen rows.
+    </para>
+   </glossdef>
+  </glossentry>
+
+  <glossentry>
+   <glossterm>WAL</glossterm>
+   <glosssee otherterm="glossary-wal" />
+  </glossentry>
+
   <glossentry id="glossary-wal-archiver">
    <glossterm>WAL Archiver (process)</glossterm>
    <glossdef>
@@ -1696,11 +1806,6 @@
    </glossdef>
   </glossentry>
 
-  <glossentry>
-   <glossterm>WAL</glossterm>
-   <glosssee otherterm="glossary-wal" />
-  </glossentry>
-
   <glossentry id="glossary-wal-record">
    <glossterm>WAL Record</glossterm>
    <glossdef>
@@ -1728,8 +1833,8 @@
   <glossdef>
    <para>
     A process that writes <glossterm linkend="glossary-wal-record">WAL records</glossterm>
-    from <glossterm id="linkend-shared-memory">shared memory</glossterm> to
-    <glossterm id="linkend-wal-file">WAL files</glossterm>.
+    from <glossterm linkend="glossary-shared-memory">shared memory</glossterm> to
+    <glossterm linkend="glossary-wal-file">WAL files</glossterm>.
    </para>
    <para>
     For more information, see
@@ -1771,5 +1876,45 @@
     </para>
    </glossdef>
   </glossentry>
+
+  <glossentry id="glossary-xid">
+   <glossterm>Transaction ID (xid)</glossterm>
+   <glossdef>
+    <para>
+     Like other objects, transactions need to have an unique
+     ID to identify them. The transaction manager creates
+     the sequence of xids. Because xids are stored in a 32-bit
+     integer, the available range is limited. Sooner or later
+     the sequence of xids must restart from the beginning.
+    </para>
+    <para>
+     There are three special xids:
+    </para>
+     <itemizedlist spacing="compact" mark="none">
+      <listitem>
+       <simpara>
+        <literal>0 (InvalidTransactionId)</literal>: is used for
+        xids of relations which are not a table.
+       </simpara>
+      </listitem>
+      <listitem>
+       <simpara>
+        <literal>1 (BootstrapTransactionId)</literal>: represents
+        transactions used during the first phase of cluster
+        initialization, see: <xref linkend="app-initdb"/>
+       </simpara>
+      </listitem>
+      <listitem>
+       <simpara>
+        <literal>2 (FrozenTransactionId)</literal>: indicates a
+        frozen transaction. This value is no longer used. Instead,
+        the system uses a flag in the header of each row version
+        to mark them as frozen.
+       </simpara>
+      </listitem>
+     </itemizedlist>
+   </glossdef>
+  </glossentry>
+
  </glosslist>
 </appendix>
diff --git a/doc/src/sgml/images/cluster-db-schema-ink-svgo.svg b/doc/src/sgml/images/cluster-db-schema-ink-svgo.svg
new file mode 100644
index 0000000000..7e13753d48
--- /dev/null
+++ b/doc/src/sgml/images/cluster-db-schema-ink-svgo.svg
@@ -0,0 +1,160 @@
+<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="900" height="685" viewBox="0 0 900 685">
+  <title>
+    Server (Hardware, Container, or VM)
+  </title>
+  <style>
+    .text_normal,.text_small{font-style:normal;font-weight:400;font-family:&quot;Open Sans&quot;,sans-serif;fill:#000}.text_small{font-size:12px}.text_normal{font-size:16px}
+  </style>
+  <defs>
+    <symbol id="rectangle_special_0">
+      <rect width="225" height="155" rx="10" stroke="blue" fill="none"/>
+      <rect x="15" y="40" width="195" height="50" rx="10" stroke="blue" fill="none" stroke-dasharray="4 2"/>
+      <text class="text_normal" x="20" y="60">
+        schema &apos;public&apos;
+      </text>
+      <text class="text_small" x="20" y="80">
+        tables, views, ...
+      </text>
+      <rect x="15" y="105" width="195" height="30" rx="10" stroke="blue" fill="none" stroke-dasharray="4 2"/>
+      <text class="text_small" x="20" y="125">
+        (more system schemas)
+      </text>
+    </symbol>
+    <symbol id="rectangle_special_1">
+      <rect width="245" height="225" rx="10" stroke="blue" fill="none"/>
+      <rect x="15" y="40" width="205" height="50" rx="10" stroke="blue" fill="none" stroke-dasharray="4 2"/>
+      <text class="text_normal" x="20" y="60">
+        schema &apos;public&apos;
+      </text>
+      <text class="text_small" x="20" y="80">
+        tables, views, ...
+      </text>
+      <rect x="15" y="105" width="205" height="50" rx="10" stroke="blue" fill="none" stroke-dasharray="4 2"/>
+      <text class="text_normal" x="20" y="125">
+        &apos;my_schema&apos; (optional)
+      </text>
+      <text class="text_small" x="20" y="145">
+        tables, views, ...
+      </text>
+      <rect x="15" y="170" width="205" height="30" rx="10" stroke="blue" fill="none" stroke-dasharray="4 2"/>
+      <text class="text_small" x="20" y="190">
+        (more system schemas)
+      </text>
+    </symbol>
+    <symbol id="note" stroke="black" fill="lightyellow">
+      <title>
+        UML Note
+      </title>
+      <path d="M450 10v230H0V0h440v10h10L440 0"/>
+    </symbol>
+    <marker id="arrowhead_end" markerWidth="10" markerHeight="10" refX="6" refY="3" orient="auto">
+      <path d="M0 0l6 3-6 3" stroke="black" fill="none"/>
+    </marker>
+  </defs>
+  <rect x="1" y="1" rx="5" width="99%" height="99%" stroke="black" fill="none"/>
+  <text x="270" y="40" font-weight="400" font-size="24" font-family="&quot;Open Sans&quot;,sans-serif">
+    Server (Hardware, Container, or VM)
+  </text>
+  <path stroke="blue" stroke-width="2" fill="none" d="M20 110h790v555H20z"/>
+  <text class="text_normal" x="180" y="25" transform="translate(20 110)">
+    cluster &apos;data&apos; (default, managed by one instance)
+  </text>
+  <path d="M50 110V80h790v555h-30" stroke="blue" stroke-width="2" fill="none"/>
+  <text class="text_normal" x="190" y="-10" transform="translate(45 110)">
+    cluster &apos;cluster_2&apos; (optional, managed by a different instance)
+  </text>
+  <g transform="translate(40 155)">
+    <use xlink:href="#rectangle_special_0"/>
+    <text class="text_normal" x="10" y="25">
+      database &apos;template0&apos;
+    </text>
+  </g>
+  <g transform="translate(290 155)">
+    <use xlink:href="#rectangle_special_0"/>
+    <text class="text_normal" x="10" y="25">
+      database &apos;template1&apos;
+    </text>
+  </g>
+  <g transform="translate(540 155)">
+    <use xlink:href="#rectangle_special_1"/>
+    <text class="text_normal" x="10" y="25">
+      database &apos;postgres&apos;
+    </text>
+  </g>
+  <g transform="translate(40 350)">
+    <use xlink:href="#rectangle_special_1"/>
+    <text class="text_normal" x="10" y="25">
+      database &apos;my_db&apos; (optional)
+    </text>
+  </g>
+  <g transform="translate(320 330)">
+    <rect width="180" height="45" rx="10" stroke="blue" fill="none" stroke-dasharray="10 4 4 4"/>
+    <text class="text_normal" x="15" y="27">
+      Global SQL objects
+    </text>
+    <path d="M0 5l-65-35" stroke="black" fill="none" marker-end="url(#arrowhead_end)"/>
+    <path d="M80 0v-30" stroke="black" fill="none" marker-end="url(#arrowhead_end)"/>
+    <path d="M180 40h50" stroke="black" fill="none" marker-end="url(#arrowhead_end)"/>
+    <path d="M0 40l-45 20" stroke="black" fill="none" marker-end="url(#arrowhead_end)"/>
+  </g>
+  <g transform="translate(335 405)">
+    <use xlink:href="#note"/>
+    <text class="text_small" x="10" y="20">
+      1)
+    </text>
+    <text class="text_small" x="30" y="20">
+      By default, you work in the cluster &apos;data&apos;, database &apos;postgres&apos;,
+    </text>
+    <text class="text_small" x="30" y="35">
+      schema &apos;public&apos;.
+    </text>
+    <text class="text_small" x="10" y="55">
+      2)
+    </text>
+    <text class="text_small" x="30" y="55">
+      More system schemas: pg_catalog, information_schema,
+    </text>
+    <text class="text_small" x="30" y="70">
+      pg_temp, pg_toast.
+    </text>
+    <text class="text_small" x="10" y="90">
+      3)
+    </text>
+    <text class="text_small" x="30" y="90">
+      Global SQL objects: Some SQL objects are automatically active
+    </text>
+    <text class="text_small" x="30" y="105">
+      and known database- or even cluster-wide.
+    </text>
+    <text class="text_small" x="10" y="125">
+      4)
+    </text>
+    <text class="text_small" x="30" y="125">
+      The command &apos;initdb&apos; creates a new cluster with the three
+    </text>
+    <text class="text_small" x="30" y="140">
+      databases &apos;template0&apos;, &apos;template1&apos;, and &apos;postgres&apos;. The command
+    </text>
+    <text class="text_small" x="30" y="155">
+      &apos;createdb&apos; creates a new database.
+    </text>
+    <text class="text_small" x="10" y="175">
+      5)
+    </text>
+    <text class="text_small" x="30" y="175">
+      If multiple clusters are active on one server at the same time,
+    </text>
+    <text class="text_small" x="30" y="190">
+      each one is managed by an individual instance. Each such instance
+    </text>
+    <text class="text_small" x="30" y="205">
+      uses a different port.
+    </text>
+    <text class="text_small" x="10" y="225">
+      6)
+    </text>
+    <text class="text_small" x="30" y="225">
+      No client application is allowed to connect to &apos;template0&apos;.
+    </text>
+  </g>
+</svg>
diff --git a/doc/src/sgml/images/cluster-db-schema-ink.svg b/doc/src/sgml/images/cluster-db-schema-ink.svg
new file mode 100644
index 0000000000..58405ae685
--- /dev/null
+++ b/doc/src/sgml/images/cluster-db-schema-ink.svg
@@ -0,0 +1,482 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://creativecommons.org/ns#"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:xlink="http://www.w3.org/1999/xlink"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   version="1.1"
+   width="900px"
+   height="685px"
+   viewBox="0 0 900 685"
+   id="svg147"
+   sodipodi:docname="cluster-db-schema-ink.svg"
+   inkscape:version="0.92.3 (2405546, 2018-03-11)">
+  <metadata
+     id="metadata151">
+    <rdf:RDF>
+      <cc:Work
+         rdf:about="">
+        <dc:format>image/svg+xml</dc:format>
+        <dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+        <dc:title>Server (Hardware, Container, or VM)</dc:title>
+      </cc:Work>
+    </rdf:RDF>
+  </metadata>
+  <sodipodi:namedview
+     pagecolor="#ffffff"
+     bordercolor="#666666"
+     borderopacity="1"
+     objecttolerance="10"
+     gridtolerance="10"
+     guidetolerance="10"
+     inkscape:pageopacity="0"
+     inkscape:pageshadow="2"
+     inkscape:window-width="640"
+     inkscape:window-height="480"
+     id="namedview149"
+     showgrid="false"
+     inkscape:zoom="0.34452555"
+     inkscape:cx="450"
+     inkscape:cy="342.5"
+     inkscape:window-x="61"
+     inkscape:window-y="27"
+     inkscape:window-maximized="0"
+     inkscape:current-layer="svg147" />
+  <title
+     id="title2">Server (Hardware, Container, or VM)</title>
+  <!-- common text classes -->
+  <style
+     type="text/css"
+     id="style4">
+  .text_small   {font-style:normal;
+                 font-weight:normal;
+                 font-size:12px;
+                 font-family:&quot;Open Sans&quot;, sans-serif;
+                 fill:black;
+                }
+  .text_normal  {font-style:normal;
+                 font-weight:normal;
+                 font-size:16px;
+                 font-family:&quot;Open Sans&quot;, sans-serif;
+                 fill:black;
+                }
+  .text_big     {font-style:normal;
+                 font-weight:normal;
+                 font-size:24px;
+                 font-family:&quot;Open Sans&quot;, sans-serif;
+                 fill:black;
+                }
+  </style>
+  <defs
+     id="defs49">
+    <!-- a rectangle with rounded corners and inner definitions for schemas -->
+    <symbol
+       id="rectangle_special_0">
+      <!-- the database -->
+      <rect
+         width="225"
+         height="155"
+         rx="10"
+         stroke="blue"
+         fill="none"
+         id="rect6" />
+      <!-- schemas -->
+      <rect
+         x="15"
+         y="40"
+         width="195"
+         height="50"
+         rx="10"
+         stroke="blue"
+         fill="none"
+         stroke-dasharray="4 2"
+         id="rect8" />
+      <text
+         class="text_normal"
+         x="20"
+         y="60"
+         id="text10">schema 'public'</text>
+      <text
+         class="text_small"
+         x="20"
+         y="80"
+         id="text12">tables, views, ...</text>
+      <rect
+         x="15"
+         y="105"
+         width="195"
+         height="30"
+         rx="10"
+         stroke="blue"
+         fill="none"
+         stroke-dasharray="4 2"
+         id="rect14" />
+      <text
+         class="text_small"
+         x="20"
+         y="125"
+         id="text16">(more system schemas)</text>
+    </symbol>
+    <!-- same as before, but one more schema -->
+    <symbol
+       id="rectangle_special_1">
+      <!-- the database -->
+      <rect
+         width="245"
+         height="225"
+         rx="10"
+         stroke="blue"
+         fill="none"
+         id="rect19" />
+      <!-- schemas -->
+      <rect
+         x="15"
+         y="40"
+         width="205"
+         height="50"
+         rx="10"
+         stroke="blue"
+         fill="none"
+         stroke-dasharray="4 2"
+         id="rect21" />
+      <text
+         class="text_normal"
+         x="20"
+         y="60"
+         id="text23">schema 'public'</text>
+      <text
+         class="text_small"
+         x="20"
+         y="80"
+         id="text25">tables, views, ...</text>
+      <rect
+         x="15"
+         y="105"
+         width="205"
+         height="50"
+         rx="10"
+         stroke="blue"
+         fill="none"
+         stroke-dasharray="4 2"
+         id="rect27" />
+      <text
+         class="text_normal"
+         x="20"
+         y="125"
+         id="text29">'my_schema' (optional)</text>
+      <text
+         class="text_small"
+         x="20"
+         y="145"
+         id="text31">tables, views, ...</text>
+      <rect
+         x="15"
+         y="170"
+         width="205"
+         height="30"
+         rx="10"
+         stroke="blue"
+         fill="none"
+         stroke-dasharray="4 2"
+         id="rect33" />
+      <text
+         class="text_small"
+         x="20"
+         y="190"
+         id="text35">(more system schemas)</text>
+    </symbol>
+    <symbol
+       id="note"
+       stroke="black"
+       fill="lightyellow">
+      <title
+         id="title38">UML Note</title>
+      <path
+         d="M 450,10 v 230 h -450 v -240 h 440 v 10 h 10 l -10,-10"
+         id="path40" />
+    </symbol>
+    <!-- marker start/end -->
+    <marker
+       id="arrowhead_start"
+       markerWidth="10"
+       markerHeight="10"
+       refX="0"
+       refY="3"
+       orient="auto">
+      <path
+         d="M 6,0 l -6,3 l 6,3"
+         stroke="black"
+         fill="none"
+         id="path43" />
+    </marker>
+    <marker
+       id="arrowhead_end"
+       markerWidth="10"
+       markerHeight="10"
+       refX="6"
+       refY="3"
+       orient="auto">
+      <path
+         d="M 0,0 l 6,3 l -6,3"
+         stroke="black"
+         fill="none"
+         id="path46" />
+    </marker>
+  </defs>
+  <!-- start of rendering area -->
+  <!-- enclosing rectangle -->
+  <rect
+     x="1"
+     y="1"
+     rx="5"
+     width="99%"
+     height="99%"
+     stroke="black"
+     fill="none"
+     id="rect51" />
+  <text
+     class="text_big"
+     x="270"
+     y="40"
+     id="text53">Server (Hardware, Container, or VM)</text>
+  <!-- two clusters -->
+  <g
+     transform="translate(20 110)"
+     id="g59">
+    <rect
+       x="0"
+       y="0"
+       width="790"
+       height="555"
+       stroke="blue"
+       stroke-width="2px"
+       fill="none"
+       id="rect55" />
+    <text
+       class="text_normal"
+       x="180"
+       y="25"
+       id="text57">cluster 'data' (default, managed by one instance)</text>
+  </g>
+  <g
+     transform="translate(45 110)"
+     id="g65">
+    <path
+       d="M 5,0 v -30 h 790 v 555 h -30"
+       stroke="blue"
+       stroke-width="2px"
+       fill="none"
+       id="path61" />
+    <text
+       class="text_normal"
+       x="190"
+       y="-10"
+       id="text63">cluster 'cluster_2' (optional, managed by a different instance)</text>
+  </g>
+  <!-- database template 0 -->
+  <g
+     transform="translate(40 155)"
+     id="g71">
+    <use
+       xlink:href="#rectangle_special_0"
+       id="use67" />
+    <text
+       class="text_normal"
+       x="10"
+       y="25"
+       id="text69">database 'template0'</text>
+  </g>
+  <!-- database template 1 -->
+  <g
+     transform="translate(290 155)"
+     id="g77">
+    <use
+       xlink:href="#rectangle_special_0"
+       id="use73" />
+    <text
+       class="text_normal"
+       x="10"
+       y="25"
+       id="text75">database 'template1'</text>
+  </g>
+  <!-- database postgres -->
+  <g
+     transform="translate(540 155)"
+     id="g83">
+    <use
+       xlink:href="#rectangle_special_1"
+       id="use79" />
+    <text
+       class="text_normal"
+       x="10"
+       y="25"
+       id="text81">database 'postgres'</text>
+  </g>
+  <!-- database my_db -->
+  <g
+     transform="translate(40 350)"
+     id="g89">
+    <use
+       xlink:href="#rectangle_special_1"
+       id="use85" />
+    <text
+       class="text_normal"
+       x="10"
+       y="25"
+       id="text87">database 'my_db' (optional)</text>
+  </g>
+  <!-- global objects -->
+  <g
+     transform="translate(320 330)"
+     id="g103">
+    <rect
+       x="0"
+       y="0"
+       width="180"
+       height="45"
+       rx="10"
+       stroke="blue"
+       fill="none"
+       stroke-dasharray="10 4 4 4"
+       id="rect91" />
+    <text
+       class="text_normal"
+       x="15"
+       y="27"
+       id="text93">Global SQL objects</text>
+    <path
+       d="M 0,5 l-65,-35"
+       stroke="black"
+       fill="none"
+       marker-end="url(#arrowhead_end)"
+       id="path95" />
+    <path
+       d="M 80,0 v-30"
+       stroke="black"
+       fill="none"
+       marker-end="url(#arrowhead_end)"
+       id="path97" />
+    <path
+       d="M 180,40 h50"
+       stroke="black"
+       fill="none"
+       marker-end="url(#arrowhead_end)"
+       id="path99" />
+    <path
+       d="M 0,40 l-45,20"
+       stroke="black"
+       fill="none"
+       marker-end="url(#arrowhead_end)"
+       id="path101" />
+  </g>
+  <!-- Some comments -->
+  <g
+     transform="translate(335 405)"
+     id="g145">
+    <use
+       xlink:href="#note"
+       x="0"
+       y="0"
+       id="use105" />
+    <text
+       class="text_small"
+       x="10"
+       y="20"
+       id="text107">1)</text>
+    <text
+       class="text_small"
+       x="30"
+       y="20"
+       id="text109">By default, you work in the cluster 'data', database 'postgres',</text>
+    <text
+       class="text_small"
+       x="30"
+       y="35"
+       id="text111">schema 'public'.</text>
+    <text
+       class="text_small"
+       x="10"
+       y="55"
+       id="text113">2)</text>
+    <text
+       class="text_small"
+       x="30"
+       y="55"
+       id="text115">More system schemas: pg_catalog, information_schema,</text>
+    <text
+       class="text_small"
+       x="30"
+       y="70"
+       id="text117">pg_temp, pg_toast.</text>
+    <text
+       class="text_small"
+       x="10"
+       y="90"
+       id="text119">3)</text>
+    <text
+       class="text_small"
+       x="30"
+       y="90"
+       id="text121">Global SQL objects: Some SQL objects are automatically active</text>
+    <text
+       class="text_small"
+       x="30"
+       y="105"
+       id="text123">and known database- or even cluster-wide.</text>
+    <text
+       class="text_small"
+       x="10"
+       y="125"
+       id="text125">4)</text>
+    <text
+       class="text_small"
+       x="30"
+       y="125"
+       id="text127">The command 'initdb' creates a new cluster with the three</text>
+    <text
+       class="text_small"
+       x="30"
+       y="140"
+       id="text129">databases 'template0', 'template1', and 'postgres'. The command</text>
+    <text
+       class="text_small"
+       x="30"
+       y="155"
+       id="text131">'createdb' creates a new database.</text>
+    <text
+       class="text_small"
+       x="10"
+       y="175"
+       id="text133">5)</text>
+    <text
+       class="text_small"
+       x="30"
+       y="175"
+       id="text135">If multiple clusters are active on one server at the same time,</text>
+    <text
+       class="text_small"
+       x="30"
+       y="190"
+       id="text137">each one is managed by an individual instance. Each such instance</text>
+    <text
+       class="text_small"
+       x="30"
+       y="205"
+       id="text139">uses a different port.</text>
+    <text
+       class="text_small"
+       x="10"
+       y="225"
+       id="text141">6)</text>
+    <text
+       class="text_small"
+       x="30"
+       y="225"
+       id="text143">No client application is allowed to connect to 'template0'.</text>
+  </g>
+</svg>
diff --git a/doc/src/sgml/images/cluster-db-schema-raw.svg b/doc/src/sgml/images/cluster-db-schema-raw.svg
new file mode 100644
index 0000000000..af50c07330
--- /dev/null
+++ b/doc/src/sgml/images/cluster-db-schema-raw.svg
@@ -0,0 +1,173 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<svg xmlns="http://www.w3.org/2000/svg"
+     xmlns:xlink="http://www.w3.org/1999/xlink"
+     version="1.1"
+     width="900px" height="685px"
+     viewBox="0 0 900 685" >
+
+  <title>Server (Hardware, Container, or VM)</title>
+
+  <!-- common text classes -->
+  <style type="text/css">
+  .text_small   {font-style:normal;
+                 font-weight:normal;
+                 font-size:12px;
+                 font-family:"Open Sans", sans-serif;
+                 fill:black;
+                }
+  .text_normal  {font-style:normal;
+                 font-weight:normal;
+                 font-size:16px;
+                 font-family:"Open Sans", sans-serif;
+                 fill:black;
+                }
+  .text_big     {font-style:normal;
+                 font-weight:normal;
+                 font-size:24px;
+                 font-family:"Open Sans", sans-serif;
+                 fill:black;
+                }
+  </style>
+
+  <defs>
+    <!-- a rectangle with rounded corners and inner definitions for schemas -->
+    <symbol id="rectangle_special_0">
+
+      <!-- the database -->
+      <rect width="225" height="155" rx="10" stroke="blue" fill="none"/>
+
+      <!-- schemas -->
+      <rect x="15" y="40" width="195" height="50" rx="10" stroke="blue" fill="none" stroke-dasharray="4 2" />
+      <text class="text_normal" x="20" y="60">schema 'public'</text>
+      <text class="text_small"  x="20" y="80">tables, views, ...</text>
+
+      <rect x="15" y="105" width="195" height="30" rx="10" stroke="blue" fill="none" stroke-dasharray="4 2" />
+      <text class="text_small"  x="20" y="125">(more system schemas)</text>
+    </symbol>
+
+    <!-- same as before, but one more schema -->
+    <symbol id="rectangle_special_1">
+      <!-- the database -->
+      <rect width="245" height="225" rx="10" stroke="blue" fill="none"/>
+
+      <!-- schemas -->
+      <rect x="15" y="40" width="205" height="50" rx="10" stroke="blue" fill="none" stroke-dasharray="4 2" />
+      <text class="text_normal" x="20" y="60">schema 'public'</text>
+      <text class="text_small"  x="20" y="80">tables, views, ...</text>
+
+      <rect x="15" y="105" width="205" height="50" rx="10" stroke="blue" fill="none" stroke-dasharray="4 2" />
+      <text class="text_normal" x="20" y="125">'my_schema' (optional)</text>
+      <text class="text_small"  x="20" y="145">tables, views, ...</text>
+
+      <rect x="15" y="170" width="205" height="30" rx="10" stroke="blue" fill="none" stroke-dasharray="4 2" />
+      <text class="text_small"  x="20" y="190">(more system schemas)</text>
+    </symbol>
+
+    <symbol id="note" stroke="black" fill="lightyellow">
+      <title>UML Note</title>
+      <path d="M 450,10 v 230 h -450 v -240 h 440 v 10 h 10 l -10,-10" />
+    </symbol>
+
+    <!-- marker start/end -->
+    <marker id="arrowhead_start"
+            markerWidth="10"
+            markerHeight="10"
+            refX="0"
+            refY="3"
+            orient="auto">
+      <path d="M 6,0 l -6,3 l 6,3" stroke="black" fill="none" />
+    </marker>
+    <marker id="arrowhead_end"
+            markerWidth="10"
+            markerHeight="10"
+            refX="6"
+            refY="3"
+            orient="auto">
+      <path d="M 0,0 l 6,3 l -6,3" stroke="black" fill="none" />
+    </marker>
+
+  </defs>
+
+
+  <!-- start of rendering area -->
+  <!-- enclosing rectangle -->
+  <rect x="1" y="1" rx="5" width="99%" height="99%" stroke="black" fill="none" />
+  <text class="text_big" x="270" y="40">Server (Hardware, Container, or VM)</text>
+
+  <!-- two clusters -->
+  <g transform="translate(20 110)">
+    <rect  x="0" y="0" width="790" height="555" stroke="blue" stroke-width="2px" fill="none" />
+    <text class="text_normal" x="180" y="25">cluster 'data' (default, managed by one instance)</text>
+  </g>
+  <g transform="translate(45 110)">
+    <path d="M 5,0 v -30 h 790 v 555 h -30" stroke="blue" stroke-width="2px" fill="none" />
+    <text class="text_normal" x="190" y="-10">cluster 'cluster_2' (optional, managed by a different instance)</text>
+  </g>
+
+
+  <!-- database template 0 -->
+  <g transform="translate(40 155)">
+    <use xlink:href="#rectangle_special_0" />
+    <text class="text_normal" x="10" y="25">database 'template0'</text>
+  </g>
+
+  <!-- database template 1 -->
+  <g transform="translate(290 155)">
+    <use xlink:href="#rectangle_special_0" />
+    <text class="text_normal" x="10" y="25">database 'template1'</text>
+  </g>
+
+  <!-- database postgres -->
+  <g transform="translate(540 155)">
+    <use xlink:href="#rectangle_special_1" />
+    <text class="text_normal" x="10" y="25">database 'postgres'</text>
+  </g>
+
+  <!-- database my_db -->
+  <g transform="translate(40 350)">
+    <use xlink:href="#rectangle_special_1" />
+    <text class="text_normal" x="10" y="25">database 'my_db' (optional)</text>
+  </g>
+
+  <!-- global objects -->
+  <g transform="translate(320 330)">
+    <rect x="0" y="0" width="180" height="45" rx="10" stroke="blue" fill="none" stroke-dasharray="10 4 4 4" />
+    <text class="text_normal" x="15" y="27">Global SQL objects</text>
+    <path d="M 0,5 l-65,-35" stroke="black" fill="none" marker-end="url(#arrowhead_end)" />
+    <path d="M 80,0 v-30" stroke="black" fill="none" marker-end="url(#arrowhead_end)" />
+    <path d="M 180,40 h50" stroke="black" fill="none" marker-end="url(#arrowhead_end)" />
+    <path d="M 0,40 l-45,20" stroke="black" fill="none" marker-end="url(#arrowhead_end)" />
+  </g>
+
+  <!-- Some comments -->
+  <g transform="translate(335 405)">
+    <use xlink:href="#note" x="0" y="0" />
+
+    <text class="text_small" x="10" y="20">1)</text>
+    <text class="text_small" x="30" y="20">By default, you work in the cluster 'data', database 'postgres',</text>
+    <text class="text_small" x="30" y="35">schema 'public'.</text>
+
+    <text class="text_small" x="10" y="55">2)</text>
+    <text class="text_small" x="30" y="55">More system schemas: pg_catalog, information_schema,</text>
+    <text class="text_small" x="30" y="70">pg_temp, pg_toast.</text>
+
+    <text class="text_small" x="10" y="90">3)</text>
+    <text class="text_small" x="30" y="90">Global SQL objects: Some SQL objects are automatically active</text>
+    <text class="text_small" x="30" y="105">and known database- or even cluster-wide.</text>
+
+    <text class="text_small" x="10" y="125">4)</text>
+    <text class="text_small" x="30" y="125">The command 'initdb' creates a new cluster with the three</text>
+    <text class="text_small" x="30" y="140">databases 'template0', 'template1', and 'postgres'. The command</text>
+    <text class="text_small" x="30" y="155">'createdb' creates a new database.</text>
+
+    <text class="text_small" x="10" y="175">5)</text>
+    <text class="text_small" x="30" y="175">If multiple clusters are active on one server at the same time,</text>
+    <text class="text_small" x="30" y="190">each one is managed by an individual instance. Each such instance</text>
+    <text class="text_small" x="30" y="205">uses a different port.</text>
+
+    <text class="text_small" x="10" y="225">6)</text>
+    <text class="text_small" x="30" y="225">No client application is allowed to connect to 'template0'.</text>
+
+  </g>
+
+</svg>
diff --git a/doc/src/sgml/images/directories-ink-svgo.svg b/doc/src/sgml/images/directories-ink-svgo.svg
new file mode 100644
index 0000000000..95fa76b9c6
--- /dev/null
+++ b/doc/src/sgml/images/directories-ink-svgo.svg
@@ -0,0 +1,164 @@
+<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="900" height="640" viewBox="0 0 900 640">
+  <title>
+    Directory structure of a cluster
+  </title>
+  <style>
+    .text_normal{font-style:normal;font-weight:400;font-size:16px;font-family:&quot;Open Sans&quot;,sans-serif;fill:#000}
+  </style>
+  <defs>
+    <symbol id="directory" stroke="blue" stroke-width=".3" fill="aqua">
+      <title>
+        Directory
+      </title>
+      <path d="M0 10h110v20H0z"/>
+      <path d="M0 10V8l3-3h35l3 3v2"/>
+    </symbol>
+    <symbol id="file" stroke="black" fill="none">
+      <title>
+        File
+      </title>
+      <path stroke="blue" d="M0 0h40v50H0z"/>
+      <path d="M5 10h20" stroke-dasharray="4 2"/>
+      <path d="M5 17h15" stroke-dasharray="6 2"/>
+      <path d="M5 24h25" stroke-dasharray="4 2"/>
+      <path d="M5 31h20" stroke-dasharray="5 2"/>
+    </symbol>
+  </defs>
+  <rect x="1" y="1" rx="5" width="99%" height="99%" stroke="black" fill="none"/>
+  <text x="200" y="50" font-weight="400" font-size="24" font-family="&quot;Open Sans&quot;,sans-serif">
+    Directory Structure
+  </text>
+  <g transform="translate(20 100)">
+    <use xlink:href="#directory"/>
+    <text x="10" y="26" class="text_normal">
+      ... /pg/
+    </text>
+    <text x="300" y="26" class="text_normal">
+      An arbitrary directory
+    </text>
+  </g>
+  <g transform="translate(70 130)">
+    <use xlink:href="#directory"/>
+    <text x="10" y="26" class="text_normal">
+      data/
+    </text>
+    <text x="250" y="26" class="text_normal">
+      Root of cluster &apos;data&apos; (see: PGDATA)
+    </text>
+  </g>
+  <g transform="translate(120 160)">
+    <use xlink:href="#directory"/>
+    <text x="10" y="26" class="text_normal">
+      base/
+    </text>
+    <text x="200" y="26" class="text_normal">
+      Subdirectory containing per-database subdirectories
+    </text>
+  </g>
+  <g transform="translate(170 190)">
+    <use xlink:href="#directory"/>
+    <text x="10" y="26" class="text_normal">
+      1/
+    </text>
+    <text x="150" y="26" class="text_normal">
+      Subdirectory for data of first database &apos;template0&apos;
+    </text>
+  </g>
+  <g transform="translate(170 220)">
+    <use xlink:href="#directory"/>
+    <text x="10" y="26" class="text_normal">
+      12992/
+    </text>
+    <text x="150" y="26" class="text_normal">
+      Subdirectory for data of second database &apos;template1&apos;
+    </text>
+  </g>
+  <g transform="translate(170 250)">
+    <use xlink:href="#directory"/>
+    <text x="10" y="26" class="text_normal">
+      12999/
+    </text>
+    <text x="150" y="26" class="text_normal">
+      Subdirectory for data of third database &apos;postgres&apos;
+    </text>
+  </g>
+  <g transform="translate(170 280)">
+    <use xlink:href="#directory"/>
+    <text x="10" y="26" class="text_normal">
+      nnnnn/
+    </text>
+    <text x="150" y="26" class="text_normal">
+      Optional: more subdirectories for databases, e.g. &apos;my_db&apos;
+    </text>
+  </g>
+  <g transform="translate(120 310)">
+    <use xlink:href="#directory"/>
+    <text x="10" y="26" class="text_normal">
+      global/
+    </text>
+    <text x="200" y="26" class="text_normal">
+      Subdirectory with information about Global SQL Objects
+    </text>
+  </g>
+  <g transform="translate(120 340)">
+    <use xlink:href="#directory"/>
+    <text x="10" y="26" class="text_normal">
+      pg_wal/
+    </text>
+    <text x="200" y="26" class="text_normal">
+      Subdirectory for Write Ahead Log files (&apos;pg_xlog&apos; before version 10)
+    </text>
+  </g>
+  <g transform="translate(120 370)">
+    <use xlink:href="#directory"/>
+    <text x="10" y="26" class="text_normal">
+      pg_xact/
+    </text>
+    <text x="200" y="26" class="text_normal">
+      Subdirectory for transaction commit status (&apos;pg_clog&apos; before version 10)
+    </text>
+  </g>
+  <g transform="translate(120 400)">
+    <use xlink:href="#directory"/>
+    <text x="10" y="26" class="text_normal">
+      pg_tblspc/
+    </text>
+    <text x="200" y="26" class="text_normal">
+      Subdirectory containing symbolic links to tablespaces
+    </text>
+  </g>
+  <g transform="translate(120 430)">
+    <use xlink:href="#directory"/>
+    <text x="10" y="26" class="text_normal">
+      pg_... /
+    </text>
+    <text x="200" y="26" class="text_normal">
+      Some more subdirectories
+    </text>
+  </g>
+  <g transform="translate(120 465)">
+    <use xlink:href="#file"/>
+    <use xlink:href="#file" x="50"/>
+    <text x="200" y="26" class="text_normal">
+      &apos;postmaster.pid&apos; and other files with cluster-wide relevance
+    </text>
+  </g>
+  <g transform="translate(20 540)">
+    <use xlink:href="#directory"/>
+    <text x="10" y="26" class="text_normal">
+      ... /xyz/
+    </text>
+    <text x="300" y="26" class="text_normal">
+      Same or another arbitrary directory
+    </text>
+  </g>
+  <g transform="translate(70 570)">
+    <use xlink:href="#directory"/>
+    <text x="10" y="26" class="text_normal">
+      cluster_2/
+    </text>
+    <text x="250" y="26" class="text_normal">
+      Root of another cluster &apos;cluster_2&apos;
+    </text>
+  </g>
+</svg>
diff --git a/doc/src/sgml/images/directories-ink.svg b/doc/src/sgml/images/directories-ink.svg
new file mode 100644
index 0000000000..5cc9d48e20
--- /dev/null
+++ b/doc/src/sgml/images/directories-ink.svg
@@ -0,0 +1,397 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://creativecommons.org/ns#"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:xlink="http://www.w3.org/1999/xlink"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   version="1.1"
+   width="900px"
+   height="640px"
+   viewBox="0 0 900 640"
+   id="svg303"
+   sodipodi:docname="directories-ink.svg"
+   inkscape:version="0.92.3 (2405546, 2018-03-11)">
+  <metadata
+     id="metadata307">
+    <rdf:RDF>
+      <cc:Work
+         rdf:about="">
+        <dc:format>image/svg+xml</dc:format>
+        <dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+        <dc:title>Directory structure of a cluster</dc:title>
+      </cc:Work>
+    </rdf:RDF>
+  </metadata>
+  <sodipodi:namedview
+     pagecolor="#ffffff"
+     bordercolor="#666666"
+     borderopacity="1"
+     objecttolerance="10"
+     gridtolerance="10"
+     guidetolerance="10"
+     inkscape:pageopacity="0"
+     inkscape:pageshadow="2"
+     inkscape:window-width="640"
+     inkscape:window-height="480"
+     id="namedview305"
+     showgrid="false"
+     inkscape:zoom="0.36875"
+     inkscape:cx="450"
+     inkscape:cy="320"
+     inkscape:window-x="61"
+     inkscape:window-y="27"
+     inkscape:window-maximized="0"
+     inkscape:current-layer="svg303" />
+  <title
+     id="title153">Directory structure of a cluster</title>
+  <style
+     type="text/css"
+     id="style155">
+  .text_normal  {font-style:normal;
+                 font-weight:normal;
+                 font-size:16px;
+                 font-family:&quot;Open Sans&quot;, sans-serif;
+                 fill:black;
+                }
+  .text_big     {font-style:normal;
+                 font-weight:normal;
+                 font-size:24px;
+                 font-family:&quot;Open Sans&quot;, sans-serif;
+                 fill:black;
+                }
+  </style>
+  <defs
+     id="defs177">
+    <!-- Directory -->
+    <symbol
+       id="directory"
+       stroke="blue"
+       stroke-width="0.3px"
+       fill="aqua">
+      <title
+         id="title157">Directory</title>
+      <rect
+         x="0"
+         y="10"
+         width="110"
+         height="20"
+         id="rect159" />
+      <path
+         d="M 0,10 l 0,-2 3,-3 35,0, 3,3  0,2"
+         id="path161" />
+    </symbol>
+    <!-- File -->
+    <symbol
+       id="file"
+       stroke="black"
+       fill="none">
+      <title
+         id="title164">File</title>
+      <rect
+         x="0"
+         y="0"
+         width="40"
+         height="50"
+         stroke="blue"
+         id="rect166" />
+      <path
+         d="M 5,10 h 20"
+         stroke-dasharray="4 2"
+         id="path168" />
+      <path
+         d="M 5,17 h 15"
+         stroke-dasharray="6 2"
+         id="path170" />
+      <path
+         d="M 5,24 h 25"
+         stroke-dasharray="4 2"
+         id="path172" />
+      <path
+         d="M 5,31 h 20"
+         stroke-dasharray="5 2"
+         id="path174" />
+    </symbol>
+  </defs>
+  <!-- start of rendering area -->
+  <!-- enclosing rectangle -->
+  <rect
+     x="1"
+     y="1"
+     rx="5"
+     width="99%"
+     height="99%"
+     stroke="black"
+     fill="none"
+     id="rect179" />
+  <!-- caption -->
+  <text
+     x="200"
+     y="50"
+     class="text_big"
+     id="text181">Directory Structure</text>
+  <!-- the directories -->
+  <g
+     transform="translate(20, 100)"
+     id="g189">
+    <use
+       xlink:href="#directory"
+       id="use183" />
+    <text
+       x="10"
+       y="26"
+       class="text_normal"
+       id="text185">... /pg/</text>
+    <text
+       x="300"
+       y="26"
+       class="text_normal"
+       id="text187">An arbitrary directory</text>
+  </g>
+  <g
+     transform="translate(70, 130)"
+     id="g197">
+    <use
+       xlink:href="#directory"
+       id="use191" />
+    <text
+       x="10"
+       y="26"
+       class="text_normal"
+       id="text193">data/</text>
+    <text
+       x="250"
+       y="26"
+       class="text_normal"
+       id="text195">Root of cluster 'data' (see: PGDATA)</text>
+  </g>
+  <g
+     transform="translate(120, 160)"
+     id="g205">
+    <use
+       xlink:href="#directory"
+       id="use199" />
+    <text
+       x="10"
+       y="26"
+       class="text_normal"
+       id="text201">base/</text>
+    <text
+       x="200"
+       y="26"
+       class="text_normal"
+       id="text203">Subdirectory containing per-database subdirectories</text>
+  </g>
+  <!--  -->
+  <g
+     transform="translate(170, 190)"
+     id="g213">
+    <use
+       xlink:href="#directory"
+       id="use207" />
+    <text
+       x="10"
+       y="26"
+       class="text_normal"
+       id="text209">1/</text>
+    <text
+       x="150"
+       y="26"
+       class="text_normal"
+       id="text211">Subdirectory for data of first database 'template0'</text>
+  </g>
+  <g
+     transform="translate(170, 220)"
+     id="g221">
+    <use
+       xlink:href="#directory"
+       id="use215" />
+    <text
+       x="10"
+       y="26"
+       class="text_normal"
+       id="text217">12992/</text>
+    <text
+       x="150"
+       y="26"
+       class="text_normal"
+       id="text219">Subdirectory for data of second database 'template1'</text>
+  </g>
+  <g
+     transform="translate(170, 250)"
+     id="g229">
+    <use
+       xlink:href="#directory"
+       id="use223" />
+    <text
+       x="10"
+       y="26"
+       class="text_normal"
+       id="text225">12999/</text>
+    <text
+       x="150"
+       y="26"
+       class="text_normal"
+       id="text227">Subdirectory for data of third database 'postgres'</text>
+  </g>
+  <g
+     transform="translate(170, 280)"
+     id="g237">
+    <use
+       xlink:href="#directory"
+       id="use231" />
+    <text
+       x="10"
+       y="26"
+       class="text_normal"
+       id="text233">nnnnn/</text>
+    <text
+       x="150"
+       y="26"
+       class="text_normal"
+       id="text235">Optional: more subdirectories for databases, e.g. 'my_db'</text>
+  </g>
+  <g
+     transform="translate(120, 310)"
+     id="g245">
+    <use
+       xlink:href="#directory"
+       id="use239" />
+    <text
+       x="10"
+       y="26"
+       class="text_normal"
+       id="text241">global/</text>
+    <text
+       x="200"
+       y="26"
+       class="text_normal"
+       id="text243">Subdirectory with information about Global SQL Objects</text>
+  </g>
+  <g
+     transform="translate(120, 340)"
+     id="g253">
+    <use
+       xlink:href="#directory"
+       id="use247" />
+    <text
+       x="10"
+       y="26"
+       class="text_normal"
+       id="text249">pg_wal/</text>
+    <text
+       x="200"
+       y="26"
+       class="text_normal"
+       id="text251">Subdirectory for Write Ahead Log files ('pg_xlog' before version 10)</text>
+  </g>
+  <g
+     transform="translate(120, 370)"
+     id="g261">
+    <use
+       xlink:href="#directory"
+       id="use255" />
+    <text
+       x="10"
+       y="26"
+       class="text_normal"
+       id="text257">pg_xact/</text>
+    <text
+       x="200"
+       y="26"
+       class="text_normal"
+       id="text259">Subdirectory for transaction commit status ('pg_clog' before version 10)</text>
+  </g>
+  <g
+     transform="translate(120, 400)"
+     id="g269">
+    <use
+       xlink:href="#directory"
+       id="use263" />
+    <text
+       x="10"
+       y="26"
+       class="text_normal"
+       id="text265">pg_tblspc/</text>
+    <text
+       x="200"
+       y="26"
+       class="text_normal"
+       id="text267">Subdirectory containing symbolic links to tablespaces</text>
+  </g>
+  <g
+     transform="translate(120, 430)"
+     id="g277">
+    <use
+       xlink:href="#directory"
+       id="use271" />
+    <text
+       x="10"
+       y="26"
+       class="text_normal"
+       id="text273">pg_... /</text>
+    <text
+       x="200"
+       y="26"
+       class="text_normal"
+       id="text275">Some more subdirectories</text>
+  </g>
+  <g
+     transform="translate(120, 465)"
+     id="g285">
+    <use
+       xlink:href="#file"
+       x="0"
+       y="0"
+       id="use279" />
+    <use
+       xlink:href="#file"
+       x="50"
+       y="0"
+       id="use281" />
+    <text
+       x="200"
+       y="26"
+       class="text_normal"
+       id="text283">'postmaster.pid' and other files with cluster-wide relevance</text>
+  </g>
+  <!-- next cluster -->
+  <g
+     transform="translate(20, 540)"
+     id="g293">
+    <use
+       xlink:href="#directory"
+       id="use287" />
+    <text
+       x="10"
+       y="26"
+       class="text_normal"
+       id="text289">... /xyz/</text>
+    <text
+       x="300"
+       y="26"
+       class="text_normal"
+       id="text291">Same or another arbitrary directory</text>
+  </g>
+  <g
+     transform="translate(70, 570)"
+     id="g301">
+    <use
+       xlink:href="#directory"
+       id="use295" />
+    <text
+       x="10"
+       y="26"
+       class="text_normal"
+       id="text297">cluster_2/</text>
+    <text
+       x="250"
+       y="26"
+       class="text_normal"
+       id="text299">Root of another cluster 'cluster_2'</text>
+  </g>
+</svg>
diff --git a/doc/src/sgml/images/directories-raw.svg b/doc/src/sgml/images/directories-raw.svg
new file mode 100644
index 0000000000..6d16a03169
--- /dev/null
+++ b/doc/src/sgml/images/directories-raw.svg
@@ -0,0 +1,144 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<svg xmlns="http://www.w3.org/2000/svg"
+     xmlns:xlink="http://www.w3.org/1999/xlink"
+     version="1.1"
+     width="900px" height="640px"
+     viewBox="0 0 900 640">
+
+  <title>Directory structure of a cluster</title>
+
+  <style type="text/css">
+  .text_normal  {font-style:normal;
+                 font-weight:normal;
+                 font-size:16px;
+                 font-family:"Open Sans", sans-serif;
+                 fill:black;
+                }
+  .text_big     {font-style:normal;
+                 font-weight:normal;
+                 font-size:24px;
+                 font-family:"Open Sans", sans-serif;
+                 fill:black;
+                }
+  </style>
+
+  <defs>
+
+    <!-- Directory -->
+    <symbol id="directory" stroke="blue" stroke-width="0.3px" fill="aqua">
+      <title>Directory</title>
+      <rect x="0" y="10" width="110" height="20" />
+      <path d="M 0,10 l 0,-2 3,-3 35,0, 3,3  0,2" />
+    </symbol>
+
+    <!-- File -->
+    <symbol id="file" stroke="black" fill="none" >
+      <title>File</title>
+      <rect x="0" y="0" width="40" height="50" stroke="blue" />
+      <path d="M 5,10 h 20" stroke-dasharray="4 2" />
+      <path d="M 5,17 h 15" stroke-dasharray="6 2" />
+      <path d="M 5,24 h 25" stroke-dasharray="4 2" />
+      <path d="M 5,31 h 20" stroke-dasharray="5 2" />
+    </symbol>
+
+  </defs>
+
+
+  <!-- start of rendering area -->
+  <!-- enclosing rectangle -->
+  <rect x="1" y="1" rx="5" width="99%" height="99%" stroke="black" fill="none" />
+
+  <!-- caption -->
+  <text x="200" y="50"  class="text_big">Directory Structure</text>
+
+  <!-- the directories -->
+  <g transform="translate(20, 100)">
+    <use xlink:href="#directory" />
+    <text x="10"  y="26" class="text_normal">... /pg/</text>
+    <text x="300" y="26" class="text_normal">An arbitrary directory</text>
+  </g>
+
+  <g transform="translate(70, 130)">
+    <use xlink:href="#directory" />
+    <text x="10"  y="26" class="text_normal">data/</text>
+    <text x="250" y="26" class="text_normal">Root of cluster 'data' (see: PGDATA)</text>
+  </g>
+
+  <g transform="translate(120, 160)">
+    <use xlink:href="#directory" />
+    <text x="10"  y="26" class="text_normal">base/</text>
+    <text x="200" y="26" class="text_normal">Subdirectory containing per-database subdirectories</text>
+  </g>
+
+  <!--  -->
+  <g transform="translate(170, 190)">
+    <use xlink:href="#directory" />
+    <text x="10"  y="26" class="text_normal">1/</text>
+    <text x="150" y="26" class="text_normal">Subdirectory for data of first database 'template0'</text>
+  </g>
+  <g transform="translate(170, 220)">
+    <use xlink:href="#directory" />
+    <text x="10"  y="26" class="text_normal">12992/</text>
+    <text x="150" y="26" class="text_normal">Subdirectory for data of second database 'template1'</text>
+  </g>
+  <g transform="translate(170, 250)">
+    <use xlink:href="#directory" />
+    <text x="10"  y="26" class="text_normal">12999/</text>
+    <text x="150" y="26" class="text_normal">Subdirectory for data of third database 'postgres'</text>
+  </g>
+  <g transform="translate(170, 280)">
+    <use xlink:href="#directory" />
+    <text x="10"  y="26" class="text_normal">nnnnn/</text>
+    <text x="150" y="26" class="text_normal">Optional: more subdirectories for databases, e.g. 'my_db'</text>
+  </g>
+
+  <g transform="translate(120, 310)">
+    <use xlink:href="#directory" />
+    <text x="10"  y="26" class="text_normal">global/</text>
+    <text x="200" y="26" class="text_normal">Subdirectory with information about Global SQL Objects</text>
+  </g>
+
+  <g transform="translate(120, 340)">
+    <use xlink:href="#directory" />
+    <text x="10"  y="26" class="text_normal">pg_wal/</text>
+    <text x="200" y="26" class="text_normal">Subdirectory for Write Ahead Log files ('pg_xlog' before version 10)</text>
+  </g>
+
+  <g transform="translate(120, 370)">
+    <use xlink:href="#directory" />
+    <text x="10"  y="26" class="text_normal">pg_xact/</text>
+    <text x="200" y="26" class="text_normal">Subdirectory for transaction commit status ('pg_clog' before version 10)</text>
+  </g>
+
+  <g transform="translate(120, 400)">
+    <use xlink:href="#directory" />
+    <text x="10"  y="26" class="text_normal">pg_tblspc/</text>
+    <text x="200" y="26" class="text_normal">Subdirectory containing symbolic links to tablespaces</text>
+  </g>
+
+  <g transform="translate(120, 430)">
+    <use xlink:href="#directory" />
+    <text x="10"  y="26" class="text_normal">pg_... /</text>
+    <text x="200" y="26" class="text_normal">Some more subdirectories</text>
+  </g>
+
+  <g transform="translate(120, 465)">
+    <use xlink:href="#file" x="0"   y="0"  />
+    <use xlink:href="#file" x="50"  y="0"  />
+    <text x="200" y="26" class="text_normal">'postmaster.pid' and other files with cluster-wide relevance</text>
+  </g>
+
+  <!-- next cluster -->
+  <g transform="translate(20, 540)">
+    <use xlink:href="#directory" />
+    <text x="10"  y="26" class="text_normal">... /xyz/</text>
+    <text x="300" y="26" class="text_normal">Same or another arbitrary directory</text>
+  </g>
+
+  <g transform="translate(70, 570)">
+    <use xlink:href="#directory" />
+    <text x="10"  y="26" class="text_normal">cluster_2/</text>
+    <text x="250" y="26" class="text_normal">Root of another cluster 'cluster_2'</text>
+  </g>
+
+</svg>
diff --git a/doc/src/sgml/images/freeze-ink-svgo.svg b/doc/src/sgml/images/freeze-ink-svgo.svg
new file mode 100644
index 0000000000..158a2e731c
--- /dev/null
+++ b/doc/src/sgml/images/freeze-ink-svgo.svg
@@ -0,0 +1,84 @@
+<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="850" height="320" viewBox="0 0 850 320">
+  <title>
+    Freeze
+  </title>
+  <style>
+    .text_normal{font-style:normal;font-weight:400;font-size:16px;font-family:&quot;Open Sans&quot;,sans-serif;fill:#000}
+  </style>
+  <defs>
+    <path id="Path_080" d="M-80 0A80 80 0 1180 0 80 80 0 11-80 0"/>
+    <path id="Path_095" d="M-95 0A95 95 0 1195 0 95 95 0 11-95 0"/>
+    <path id="Path_120" d="M-120 0a120 120 0 11240 0 120 120 0 11-240 0"/>
+    <circle id="frozenPoint" r="3" stroke="green" fill="green" transform="translate(-100)"/>
+    <circle id="unfrozenPoint" r="3" stroke="green" fill="none" transform="translate(-100)"/>
+  </defs>
+  <rect x="1" y="1" rx="5" width="99%" height="99%" stroke="black" fill="none"/>
+  <text x="70" y="40" font-weight="400" font-size="24" font-family="&quot;Open Sans&quot;,sans-serif,Helvetica">
+    <tspan font-style="italic" font-weight="700">Freeze</tspan> to keep alive
+  </text>
+  <g fill="none" transform="translate(170 190)">
+    <circle r="100" stroke="blue"/>
+    <text class="text_normal">
+      <textPath xlink:href="#Path_095" startOffset=".5%">|</textPath> <textPath xlink:href="#Path_120" startOffset="0%">(0)</textPath> <textPath xlink:href="#Path_080" startOffset="1%" stroke="blue" stroke-width=".5"> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - &gt;</textPath> <textPath xlink:href="#Path_120" startOffset="11.2%">(1)</textPath> <textPath xlink:href="#Path_120" startOffset="61.2%">(5)</textPath> <textPath xlink:href="#Path_095" stroke="red" stroke-width="3" startOffset="34%">|</textPath> <textPath xlink:href="#Path_120" startOffset="34%">(2)</textPath> <textPath xlink:href="#Path_095" stroke="black" stroke-width="3" startOffset="45%">|</textPath> <textPath xlink:href="#Path_120" startOffset="45%">(3)</textPath> <textPath xlink:href="#Path_095" stroke="green" stroke-width="3" startOffset="55%">|</textPath> <textPath xlink:href="#Path_120" startOffset="55%">(4)</textPath>
+    </text>
+    <path d="M-80-80L80 80" stroke="black"/>
+    <text class="text_normal" letter-spacing="12" transform="rotate(45 40.78 -38.1)">
+      PAST
+    </text>
+    <text class="text_normal" letter-spacing="12" transform="rotate(-135 27.43 23.79)">
+      FUTURE
+    </text>
+    <use xlink:href="#frozenPoint" transform="rotate(10)"/>
+    <use xlink:href="#frozenPoint" transform="rotate(25)"/>
+    <use xlink:href="#frozenPoint" transform="rotate(40)"/>
+    <use xlink:href="#frozenPoint" transform="rotate(55)"/>
+    <use xlink:href="#frozenPoint" transform="rotate(70)"/>
+    <use xlink:href="#frozenPoint" transform="rotate(85)"/>
+    <use xlink:href="#frozenPoint" transform="rotate(100)"/>
+    <use xlink:href="#frozenPoint" transform="rotate(115)"/>
+    <use xlink:href="#frozenPoint" transform="rotate(130)"/>
+    <use xlink:href="#unfrozenPoint" transform="rotate(145)"/>
+    <use xlink:href="#frozenPoint" transform="rotate(160)"/>
+    <use xlink:href="#frozenPoint" transform="rotate(175)"/>
+    <use xlink:href="#unfrozenPoint" transform="rotate(190)"/>
+    <use xlink:href="#unfrozenPoint" transform="rotate(205)"/>
+    <use xlink:href="#unfrozenPoint" transform="rotate(220)"/>
+  </g>
+  <g class="text_normal" transform="translate(380 30)">
+    <text>
+      0: 0 .. 2 <tspan dy="-5">^</tspan> <tspan dy="5">32</tspan> - 1
+    </text>
+    <text y="25">
+      1: txid_current + 2 ^ 31 (splitt-point)
+    </text>
+    <text y="50">
+      2: autovacuum_freeze_max_age (200 mio.)
+    </text>
+    <text y="75">
+      3: vacuum_freeze_table_age (150 mio.)
+    </text>
+    <text y="100">
+      4: vacuum_freeze_min_age (50 mio.)
+    </text>
+    <text y="125">
+      5: txid_current (splitt-point, jungest xid)
+    </text>
+    <text y="155">
+      per table: pg_class.relfrozenxid <tspan font-weight="700">must</tspan> be between (1) and (5);
+    </text>
+    <text y="175" x="75">
+      normally it is between (3) and (4)
+    </text>
+    <use xlink:href="#unfrozenPoint" transform="translate(106 200)"/>
+    <text y="205" x="20">
+      Unfrozen xid
+    </text>
+    <use xlink:href="#frozenPoint" transform="translate(106 224)"/>
+    <text y="230" x="20">
+      Frozen xid
+    </text>
+    <text y="260">
+      (figure is out of scale)
+    </text>
+  </g>
+</svg>
diff --git a/doc/src/sgml/images/freeze-ink.svg b/doc/src/sgml/images/freeze-ink.svg
new file mode 100644
index 0000000000..9c16fc7b5b
--- /dev/null
+++ b/doc/src/sgml/images/freeze-ink.svg
@@ -0,0 +1,365 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://creativecommons.org/ns#"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:xlink="http://www.w3.org/1999/xlink"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   version="1.1"
+   width="850px"
+   height="320px"
+   viewBox="0 0 850 320"
+   id="svg454"
+   sodipodi:docname="freeze-ink.svg"
+   inkscape:version="0.92.3 (2405546, 2018-03-11)">
+  <metadata
+     id="metadata458">
+    <rdf:RDF>
+      <cc:Work
+         rdf:about="">
+        <dc:format>image/svg+xml</dc:format>
+        <dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+        <dc:title>Freeze</dc:title>
+      </cc:Work>
+    </rdf:RDF>
+  </metadata>
+  <sodipodi:namedview
+     pagecolor="#ffffff"
+     bordercolor="#666666"
+     borderopacity="1"
+     objecttolerance="10"
+     gridtolerance="10"
+     guidetolerance="10"
+     inkscape:pageopacity="0"
+     inkscape:pageshadow="2"
+     inkscape:window-width="640"
+     inkscape:window-height="480"
+     id="namedview456"
+     showgrid="false"
+     inkscape:zoom="0.44"
+     inkscape:cx="425"
+     inkscape:cy="160"
+     inkscape:window-x="61"
+     inkscape:window-y="27"
+     inkscape:window-maximized="0"
+     inkscape:current-layer="svg454" />
+  <title
+     id="title309">Freeze</title>
+  <!-- common text classes -->
+  <style
+     type="text/css"
+     id="style311">
+  .text_normal  {font-style:normal;
+                 font-weight:normal;
+                 font-size:16px;
+                 font-family:&quot;Open Sans&quot;, sans-serif;
+                 fill:black;
+                }
+  .text_big     {font-style:normal;
+                 font-weight:normal;
+                 font-size:24px;
+                 font-family:&quot;Open Sans&quot;, sans-serif, Helvetica;
+                 fill:black;
+                }
+  </style>
+  <defs
+     id="defs318">
+    <!-- SVG 1.x supports <texPath> only in combination with <path>. SVG 2 allows it with
+         every shape element, especially with <circle>. As of 2020 we must restrict ourselves
+         to SVG 1. Therefore we simulate a circle by defining two arcs, each of them is
+         a half-circle.
+    -->
+    <path
+       id="Path_080"
+       d="m -80 0                            a 80 80 0 1 1  160 0                            a 80 80 0 1 1 -160 0" />
+    <path
+       id="Path_095"
+       d="m -95 0                            a 95 95 0 1 1  190 0                            a 95 95 0 1 1 -190 0" />
+    <path
+       id="Path_120"
+       d="m -120 0                            a 120 120 0 1 1  240 0                            a 120 120 0 1 1 -240 0" />
+    <!-- split transform="translate(x y) rotate(arc)" into two steps for clarity -->
+    <circle
+       id="frozenPoint"
+       r="3"
+       stroke="green"
+       fill="green"
+       transform="translate(-100, 0)" />
+    <circle
+       id="unfrozenPoint"
+       r="3"
+       stroke="green"
+       fill="none"
+       transform="translate(-100, 0)" />
+  </defs>
+  <!-- start of rendering area -->
+  <!-- enclosing rectangle -->
+  <rect
+     x="1"
+     y="1"
+     rx="5"
+     width="99%"
+     height="99%"
+     stroke="black"
+     fill="none"
+     id="rect320" />
+  <text
+     class="text_big"
+     x="70"
+     y="40"
+     id="text324"><tspan
+   style="font-style:italic;font-weight:bold"
+   id="tspan322">
+        Freeze</tspan>
+ to keep alive</text>
+  <!-- set default values -->
+  <g
+     fill="none"
+     transform="translate(170 190)"
+     id="g418">
+    <circle
+       r="100"
+       stroke="blue"
+       id="circle326" />
+    <text
+       class="text_normal"
+       id="text350">
+      <textPath
+         xlink:href="#Path_095"
+         startOffset="0.5%"
+         id="textPath328">|</textPath>
+      <textPath
+         xlink:href="#Path_120"
+         startOffset="00%"
+         id="textPath330">(0)</textPath>
+      <textPath
+         xlink:href="#Path_080"
+         startOffset="01%"
+         stroke="blue"
+         stroke-width="0.5px"
+         id="textPath332">
+        - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - &gt;</textPath>
+      <textPath
+         xlink:href="#Path_120"
+         startOffset="11.2%"
+         id="textPath334">(1)</textPath>
+      <textPath
+         xlink:href="#Path_120"
+         startOffset="61.2%"
+         id="textPath336">(5)</textPath>
+      <textPath
+         xlink:href="#Path_095"
+         stroke="red"
+         stroke-width="3"
+         startOffset="34%"
+         id="textPath338">|</textPath>
+      <textPath
+         xlink:href="#Path_120"
+         startOffset="34%"
+         id="textPath340">(2)</textPath>
+      <textPath
+         xlink:href="#Path_095"
+         stroke="black"
+         stroke-width="3"
+         startOffset="45%"
+         id="textPath342">|</textPath>
+      <textPath
+         xlink:href="#Path_120"
+         startOffset="45%"
+         id="textPath344">(3)</textPath>
+      <textPath
+         xlink:href="#Path_095"
+         stroke="green"
+         stroke-width="3"
+         startOffset="55%"
+         id="textPath346">|</textPath>
+      <textPath
+         xlink:href="#Path_120"
+         startOffset="55%"
+         id="textPath348">(4)</textPath>
+    </text>
+    <!-- split it into 'past' and 'future' -->
+    <path
+       d="M -80 -80 l 160 160"
+       stroke="black"
+       id="path352" />
+    <text
+       class="text_normal"
+       letter-spacing="12"
+       transform="translate(-15, -40) rotate(45)"
+       id="text354">PAST</text>
+    <text
+       class="text_normal"
+       letter-spacing="12"
+       transform="translate(30, 60) rotate(225)"
+       id="text356">FUTURE</text>
+    <g
+       transform="rotate(10)"
+       id="g360">
+      <use
+         xlink:href="#frozenPoint"
+         id="use358" />
+    </g>
+    <g
+       transform="rotate(25)"
+       id="g364">
+      <use
+         xlink:href="#frozenPoint"
+         id="use362" />
+    </g>
+    <g
+       transform="rotate(40)"
+       id="g368">
+      <use
+         xlink:href="#frozenPoint"
+         id="use366" />
+    </g>
+    <g
+       transform="rotate(55)"
+       id="g372">
+      <use
+         xlink:href="#frozenPoint"
+         id="use370" />
+    </g>
+    <g
+       transform="rotate(70)"
+       id="g376">
+      <use
+         xlink:href="#frozenPoint"
+         id="use374" />
+    </g>
+    <g
+       transform="rotate(85)"
+       id="g380">
+      <use
+         xlink:href="#frozenPoint"
+         id="use378" />
+    </g>
+    <g
+       transform="rotate(100)"
+       id="g384">
+      <use
+         xlink:href="#frozenPoint"
+         id="use382" />
+    </g>
+    <g
+       transform="rotate(115)"
+       id="g388">
+      <use
+         xlink:href="#frozenPoint"
+         id="use386" />
+    </g>
+    <g
+       transform="rotate(130)"
+       id="g392">
+      <use
+         xlink:href="#frozenPoint"
+         id="use390" />
+    </g>
+    <g
+       transform="rotate(145)"
+       id="g396">
+      <use
+         xlink:href="#unfrozenPoint"
+         id="use394" />
+    </g>
+    <g
+       transform="rotate(160)"
+       id="g400">
+      <use
+         xlink:href="#frozenPoint"
+         id="use398" />
+    </g>
+    <g
+       transform="rotate(175)"
+       id="g404">
+      <use
+         xlink:href="#frozenPoint"
+         id="use402" />
+    </g>
+    <g
+       transform="rotate(190)"
+       id="g408">
+      <use
+         xlink:href="#unfrozenPoint"
+         id="use406" />
+    </g>
+    <g
+       transform="rotate(205)"
+       id="g412">
+      <use
+         xlink:href="#unfrozenPoint"
+         id="use410" />
+    </g>
+    <g
+       transform="rotate(220)"
+       id="g416">
+      <use
+         xlink:href="#unfrozenPoint"
+         id="use414" />
+    </g>
+  </g>
+  <!-- legend -->
+  <g
+     class="text_normal"
+     transform="translate(380 30)"
+     id="g452">
+    <text
+       id="text424">0: 0 .. 2  <tspan
+   dy="-5"
+   id="tspan420">^</tspan>
+<tspan
+   dy="5"
+   id="tspan422">32</tspan>
+ - 1</text>
+    <text
+       y="25"
+       id="text426">1: txid_current + 2 ^ 31 (splitt-point)</text>
+    <text
+       y="50"
+       id="text428">2: autovacuum_freeze_max_age (200 mio.)</text>
+    <text
+       y="75"
+       id="text430">3: vacuum_freeze_table_age (150 mio.)</text>
+    <text
+       y="100"
+       id="text432">4: vacuum_freeze_min_age (50 mio.)</text>
+    <text
+       y="125"
+       id="text434">5: txid_current (splitt-point, jungest xid)</text>
+    <text
+       y="155"
+       id="text438">per table: pg_class.relfrozenxid
+          <tspan
+   style="font-weight:bold"
+   id="tspan436">must</tspan>
+ be between (1) and (5);</text>
+    <text
+       y="175"
+       x="75"
+       id="text440">normally it is between (3) and (4)</text>
+    <use
+       xlink:href="#unfrozenPoint"
+       transform="translate(106, 200)"
+       id="use442" />
+    <text
+       y="205"
+       x="20"
+       id="text444">Unfrozen xid</text>
+    <use
+       xlink:href="#frozenPoint"
+       transform="translate(106, 224)"
+       id="use446" />
+    <text
+       y="230"
+       x="20"
+       id="text448">Frozen xid</text>
+    <text
+       y="260"
+       id="text450">(figure is out of scale)</text>
+  </g>
+</svg>
diff --git a/doc/src/sgml/images/freeze-raw.svg b/doc/src/sgml/images/freeze-raw.svg
new file mode 100644
index 0000000000..4816569fbb
--- /dev/null
+++ b/doc/src/sgml/images/freeze-raw.svg
@@ -0,0 +1,123 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<svg xmlns="http://www.w3.org/2000/svg"
+     xmlns:xlink="http://www.w3.org/1999/xlink"
+     version="1.1"
+     width="850px" height="320px"
+     viewBox="0 0 850 320" >
+
+  <title>Freeze</title>
+
+  <!-- common text classes -->
+  <style type="text/css">
+  .text_normal  {font-style:normal;
+                 font-weight:normal;
+                 font-size:16px;
+                 font-family:"Open Sans", sans-serif;
+                 fill:black;
+                }
+  .text_big     {font-style:normal;
+                 font-weight:normal;
+                 font-size:24px;
+                 font-family:"Open Sans", sans-serif, Helvetica;
+                 fill:black;
+                }
+  </style>
+
+  <defs>
+    <!-- SVG 1.x supports <texPath> only in combination with <path>. SVG 2 allows it with
+         every shape element, especially with <circle>. As of 2020 we must restrict ourselves
+         to SVG 1. Therefore we simulate a circle by defining two arcs, each of them is
+         a half-circle.
+    -->
+    <path id="Path_080" d="m -80 0
+                           a 80 80 0 1 1  160 0
+                           a 80 80 0 1 1 -160 0"/>
+    <path id="Path_095" d="m -95 0
+                           a 95 95 0 1 1  190 0
+                           a 95 95 0 1 1 -190 0"/>
+    <path id="Path_120" d="m -120 0
+                           a 120 120 0 1 1  240 0
+                           a 120 120 0 1 1 -240 0"/>
+
+    <!-- split transform="translate(x y) rotate(arc)" into two steps for clarity -->
+    <circle id="frozenPoint"   r="3" stroke="green" fill="green" transform="translate(-100, 0)"/>
+    <circle id="unfrozenPoint" r="3" stroke="green" fill="none"  transform="translate(-100, 0)"/>
+
+  </defs>
+
+
+  <!-- start of rendering area -->
+  <!-- enclosing rectangle -->
+  <rect x="1" y="1" rx="5" width="99%" height="99%" stroke="black" fill="none" />
+  <text class="text_big" x="70" y="40"><tspan style="font-style:italic;font-weight:bold">
+        Freeze</tspan> to keep alive</text>
+
+  <!-- set default values -->
+  <g fill="none" transform="translate(170 190)">
+
+    <circle r="100" stroke="blue" />
+
+    <text class="text_normal">
+      <textPath xlink:href="#Path_095" startOffset="0.5%" >|</textPath>
+      <textPath xlink:href="#Path_120" startOffset="00%" >(0)</textPath>
+      <textPath xlink:href="#Path_080" startOffset="01%" stroke="blue" stroke-width="0.5px" >
+        - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ></textPath>
+      <textPath xlink:href="#Path_120" startOffset="11.2%" >(1)</textPath>
+      <textPath xlink:href="#Path_120" startOffset="61.2%" >(5)</textPath>
+
+      <textPath xlink:href="#Path_095" stroke="red" stroke-width="3" startOffset="34%" >|</textPath>
+      <textPath xlink:href="#Path_120" startOffset="34%" >(2)</textPath>
+
+      <textPath xlink:href="#Path_095" stroke="black" stroke-width="3" startOffset="45%" >|</textPath>
+      <textPath xlink:href="#Path_120" startOffset="45%" >(3)</textPath>
+
+      <textPath xlink:href="#Path_095" stroke="green" stroke-width="3" startOffset="55%" >|</textPath>
+      <textPath xlink:href="#Path_120" startOffset="55%" >(4)</textPath>
+
+    </text>
+
+    <!-- split it into 'past' and 'future' -->
+    <path d="M -80 -80 l 160 160" stroke="black" />
+    <text class="text_normal" letter-spacing="12" transform="translate(-15, -40) rotate(45)">PAST</text>
+    <text class="text_normal" letter-spacing="12" transform="translate(30, 60) rotate(225)">FUTURE</text>
+
+    <g transform="rotate(10)"><use xlink:href="#frozenPoint"/></g>
+    <g transform="rotate(25)"><use xlink:href="#frozenPoint"/></g>
+    <g transform="rotate(40)"><use xlink:href="#frozenPoint"/></g>
+    <g transform="rotate(55)"><use xlink:href="#frozenPoint"/></g>
+    <g transform="rotate(70)"><use xlink:href="#frozenPoint"/></g>
+    <g transform="rotate(85)"><use xlink:href="#frozenPoint"/></g>
+    <g transform="rotate(100)"><use xlink:href="#frozenPoint"/></g>
+    <g transform="rotate(115)"><use xlink:href="#frozenPoint"/></g>
+    <g transform="rotate(130)"><use xlink:href="#frozenPoint"/></g>
+    <g transform="rotate(145)"><use xlink:href="#unfrozenPoint"/></g>
+    <g transform="rotate(160)"><use xlink:href="#frozenPoint"/></g>
+    <g transform="rotate(175)"><use xlink:href="#frozenPoint"/></g>
+    <g transform="rotate(190)"><use xlink:href="#unfrozenPoint"/></g>
+    <g transform="rotate(205)"><use xlink:href="#unfrozenPoint"/></g>
+    <g transform="rotate(220)"><use xlink:href="#unfrozenPoint"/></g>
+
+  </g>
+
+  <!-- legend -->
+  <g class="text_normal" transform="translate(380 30)">
+    <text>0: 0 .. 2  <tspan dy="-5">^</tspan> <tspan dy="5">32</tspan> - 1</text>
+    <text y="25">1: txid_current + 2 ^ 31 (splitt-point)</text>
+    <text y="50">2: autovacuum_freeze_max_age (200 mio.)</text>
+    <text y="75">3: vacuum_freeze_table_age (150 mio.)</text>
+    <text y="100">4: vacuum_freeze_min_age (50 mio.)</text>
+    <text y="125">5: txid_current (splitt-point, jungest xid)</text>
+    <text y="155">per table: pg_class.relfrozenxid
+          <tspan style="font-weight:bold">must</tspan> be between (1) and (5);</text>
+    <text y="175" x="75">normally it is between (3) and (4)</text>
+
+    <use xlink:href="#unfrozenPoint" transform="translate(106, 200)"/>
+    <text y="205" x="20">Unfrozen xid</text>
+
+    <use xlink:href="#frozenPoint" transform="translate(106, 224)"/>
+    <text y="230" x="20">Frozen xid</text>
+
+    <text y="260">(figure is out of scale)</text>
+  </g>
+
+</svg>
diff --git a/doc/src/sgml/images/internal-objects-hierarchy-ink-svgo.svg b/doc/src/sgml/images/internal-objects-hierarchy-ink-svgo.svg
new file mode 100644
index 0000000000..26bce6176d
--- /dev/null
+++ b/doc/src/sgml/images/internal-objects-hierarchy-ink-svgo.svg
@@ -0,0 +1,83 @@
+<svg xmlns="http://www.w3.org/2000/svg" width="720" height="430" viewBox="0 0 720 430">
+  <title>
+    Hierarchy of Internal Objects
+  </title>
+  <style>
+    .text_normal{font-style:normal;font-weight:400;font-size:16px;font-family:&quot;Open Sans&quot;,sans-serif;fill:#000}
+  </style>
+  <rect x="1" y="1" rx="5" width="99%" height="99%" stroke="black" fill="none"/>
+  <text x="200" y="40" font-weight="400" font-size="24" font-family="&quot;Open Sans&quot;,sans-serif">
+    Hierarchy of internal Objects
+  </text>
+  <g fill="none">
+    <g transform="translate(350 240)">
+      <ellipse rx="320" ry="170" stroke="blue"/>
+      <text class="text_normal" x="-140" y="-130">
+        Cluster
+      </text>
+      <g transform="translate(40 -125)">
+        <ellipse rx="80" ry="20" stroke="blue"/>
+        <text class="text_normal" x="-60" y="5">
+          Database Names
+        </text>
+      </g>
+      <g transform="translate(180 -70)">
+        <ellipse rx="60" ry="20" stroke="blue"/>
+        <text class="text_normal" x="-40" y="5">
+          Tablespace
+        </text>
+      </g>
+      <g transform="translate(230 -5)">
+        <ellipse rx="80" ry="20" stroke="blue"/>
+        <text class="text_normal" x="-70" y="5">
+          Replication Origins
+        </text>
+      </g>
+      <g transform="translate(200 70)">
+        <ellipse rx="78" ry="27" stroke="blue"/>
+        <text class="text_normal" x="-60" y="-3">
+          Subscription for
+        </text>
+        <text class="text_normal" x="-68" y="10">
+          Logical Replication
+        </text>
+      </g>
+      <g transform="translate(100 120)">
+        <ellipse rx="40" ry="20" stroke="blue"/>
+        <text class="text_normal" x="-15" y="5">
+          Role
+        </text>
+      </g>
+    </g>
+    <g transform="translate(270 250)">
+      <ellipse rx="220" ry="110" stroke="blue" stroke-width="2"/>
+      <text class="text_normal" x="-60" y="-80">
+        Database
+      </text>
+      <g transform="translate(-150 -30)">
+        <ellipse rx="50" ry="20" stroke="blue"/>
+        <text class="text_normal" x="-35" y="5">
+          Extension
+        </text>
+      </g>
+      <g transform="translate(-155 35)">
+        <ellipse rx="40" ry="20" stroke="blue"/>
+        <text class="text_normal" x="-35" y="5">
+          Collation
+        </text>
+      </g>
+      <g transform="translate(30 20)">
+        <ellipse rx="140" ry="70" stroke="blue"/>
+        <text class="text_normal" x="-80" y="-35">
+          Schema
+        </text>
+        <g transform="translate(20 10)">
+          <ellipse rx="90" ry="30" stroke="blue"/>
+          <text class="text_normal" x="-50" y="5">
+            Table, View, ...
+          </text>
+        </g>
+      </g>
+    </g>
+  </g>
+</svg>
diff --git a/doc/src/sgml/images/internal-objects-hierarchy-ink.svg b/doc/src/sgml/images/internal-objects-hierarchy-ink.svg
new file mode 100644
index 0000000000..638ba83c4f
--- /dev/null
+++ b/doc/src/sgml/images/internal-objects-hierarchy-ink.svg
@@ -0,0 +1,255 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://creativecommons.org/ns#"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   version="1.1"
+   width="720px"
+   height="430px"
+   viewBox="0 0 720 430"
+   id="svg540"
+   sodipodi:docname="internal-objects-hierarchy-ink.svg"
+   inkscape:version="0.92.3 (2405546, 2018-03-11)">
+  <metadata
+     id="metadata546">
+    <rdf:RDF>
+      <cc:Work
+         rdf:about="">
+        <dc:format>image/svg+xml</dc:format>
+        <dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+        <dc:title>Hierarchy of Internal Objects</dc:title>
+      </cc:Work>
+    </rdf:RDF>
+  </metadata>
+  <defs
+     id="defs544" />
+  <sodipodi:namedview
+     pagecolor="#ffffff"
+     bordercolor="#666666"
+     borderopacity="1"
+     objecttolerance="10"
+     gridtolerance="10"
+     guidetolerance="10"
+     inkscape:pageopacity="0"
+     inkscape:pageshadow="2"
+     inkscape:window-width="640"
+     inkscape:window-height="480"
+     id="namedview542"
+     showgrid="false"
+     inkscape:zoom="0.51944444"
+     inkscape:cx="360"
+     inkscape:cy="215"
+     inkscape:window-x="61"
+     inkscape:window-y="27"
+     inkscape:window-maximized="0"
+     inkscape:current-layer="svg540" />
+  <title
+     id="title460">Hierarchy of Internal Objects</title>
+  <!-- common text classes -->
+  <style
+     type="text/css"
+     id="style462">
+  .text_normal  {font-style:normal;
+                 font-weight:normal;
+                 font-size:16px;
+                 font-family:&quot;Open Sans&quot;, sans-serif;
+                 fill:black;
+                }
+  .text_big     {font-style:normal;
+                 font-weight:normal;
+                 font-size:24px;
+                 font-family:&quot;Open Sans&quot;, sans-serif;
+                 fill:black;
+                }
+  </style>
+  <!-- start of rendering area -->
+  <!-- enclosing rectangle -->
+  <rect
+     x="1"
+     y="1"
+     rx="5"
+     width="99%"
+     height="99%"
+     stroke="black"
+     fill="none"
+     id="rect464" />
+  <text
+     class="text_big"
+     x="200"
+     y="40"
+     id="text466">Hierarchy of internal Objects</text>
+  <!-- set centre of figure and default values -->
+  <g
+     transform="translate(350 240)"
+     fill="none"
+     id="g538">
+    <g
+       id="g504">
+      <ellipse
+         rx="320"
+         ry="170"
+         stroke="blue"
+         id="ellipse468" />
+      <text
+         class="text_normal"
+         x="-140"
+         y="-130"
+         id="text470">Cluster</text>
+      <g
+         transform="translate(40 -125)"
+         id="g476">
+        <ellipse
+           rx="80"
+           ry="20"
+           stroke="blue"
+           id="ellipse472" />
+        <text
+           class="text_normal"
+           x="-60"
+           y="5"
+           id="text474">Database Names</text>
+      </g>
+      <g
+         transform="translate(180 -70)"
+         id="g482">
+        <ellipse
+           rx="60"
+           ry="20"
+           stroke="blue"
+           id="ellipse478" />
+        <text
+           class="text_normal"
+           x="-40"
+           y="5"
+           id="text480">Tablespace</text>
+      </g>
+      <g
+         transform="translate(230 -5)"
+         id="g488">
+        <ellipse
+           rx="80"
+           ry="20"
+           stroke="blue"
+           id="ellipse484" />
+        <text
+           class="text_normal"
+           x="-70"
+           y="5"
+           id="text486">Replication Origins</text>
+      </g>
+      <g
+         transform="translate(200 70)"
+         id="g496">
+        <ellipse
+           rx="78"
+           ry="27"
+           stroke="blue"
+           id="ellipse490" />
+        <text
+           class="text_normal"
+           x="-60"
+           y="-3"
+           id="text492">Subscription for</text>
+        <text
+           class="text_normal"
+           x="-68"
+           y="10"
+           id="text494">Logical Replication</text>
+      </g>
+      <g
+         transform="translate(100 120)"
+         id="g502">
+        <ellipse
+           rx="40"
+           ry="20"
+           stroke="blue"
+           id="ellipse498" />
+        <text
+           class="text_normal"
+           x="-15"
+           y="5"
+           id="text500">Role</text>
+      </g>
+    </g>
+    <g
+       transform="translate(-80 10)"
+       id="g536">
+      <ellipse
+         rx="220"
+         ry="110"
+         stroke="blue"
+         stroke-width="2px"
+         id="ellipse506" />
+      <text
+         class="text_normal"
+         x="-60"
+         y="-80"
+         id="text508">Database</text>
+      <g
+         transform="translate(-120 -50)"
+         id="g534">
+        <g
+           transform="translate(-30 20)"
+           id="g514">
+          <ellipse
+             rx="50"
+             ry="20"
+             stroke="blue"
+             id="ellipse510" />
+          <text
+             class="text_normal"
+             x="-35"
+             y="5"
+             id="text512">Extension</text>
+        </g>
+        <g
+           transform="translate(-35 85)"
+           id="g520">
+          <ellipse
+             rx="40"
+             ry="20"
+             stroke="blue"
+             id="ellipse516" />
+          <text
+             class="text_normal"
+             x="-35"
+             y="5"
+             id="text518">Collation</text>
+        </g>
+        <g
+           transform="translate(150 70)"
+           id="g532">
+          <ellipse
+             rx="140"
+             ry="70"
+             stroke="blue"
+             id="ellipse522" />
+          <text
+             class="text_normal"
+             x="-80"
+             y="-35"
+             id="text524">Schema</text>
+          <g
+             transform="translate(20 10)"
+             id="g530">
+            <ellipse
+               rx="90"
+               ry="30"
+               stroke="blue"
+               id="ellipse526" />
+            <text
+               class="text_normal"
+               x="-50"
+               y="5"
+               id="text528">Table, View, ...</text>
+          </g>
+        </g>
+      </g>
+    </g>
+  </g>
+</svg>
diff --git a/doc/src/sgml/images/internal-objects-hierarchy-raw.svg b/doc/src/sgml/images/internal-objects-hierarchy-raw.svg
new file mode 100644
index 0000000000..f0dc890f6b
--- /dev/null
+++ b/doc/src/sgml/images/internal-objects-hierarchy-raw.svg
@@ -0,0 +1,95 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<svg xmlns="http://www.w3.org/2000/svg"
+     xmlns:xlink="http://www.w3.org/1999/xlink"
+     version="1.1"
+     width="720px" height="430px"
+     viewBox="0 0 720 430" >
+
+  <title>Hierarchy of Internal Objects</title>
+
+  <!-- common text classes -->
+  <style type="text/css">
+  .text_normal  {font-style:normal;
+                 font-weight:normal;
+                 font-size:16px;
+                 font-family:"Open Sans", sans-serif;
+                 fill:black;
+                }
+  .text_big     {font-style:normal;
+                 font-weight:normal;
+                 font-size:24px;
+                 font-family:"Open Sans", sans-serif;
+                 fill:black;
+                }
+  </style>
+
+  <!-- start of rendering area -->
+  <!-- enclosing rectangle -->
+  <rect x="1" y="1" rx="5" width="99%" height="99%" stroke="black" fill="none" />
+  <text class="text_big" x="200" y="40">Hierarchy of internal Objects</text>
+
+
+  <!-- set centre of figure and default values -->
+  <g transform="translate(350 240)" fill="none">
+
+    <g>
+      <ellipse rx="320" ry="170" stroke="blue" />
+      <text class="text_normal" x="-140" y="-130">Cluster</text>
+
+      <g transform="translate(40 -125)">
+        <ellipse rx="80" ry="20" stroke="blue" />
+        <text class="text_normal" x="-60" y="5">Database Names</text>
+      </g>
+
+      <g transform="translate(180 -70)">
+        <ellipse rx="60" ry="20" stroke="blue" />
+        <text class="text_normal" x="-40" y="5">Tablespace</text>
+      </g>
+
+      <g transform="translate(230 -5)">
+        <ellipse rx="80" ry="20" stroke="blue" />
+        <text class="text_normal" x="-70" y="5">Replication Origins</text>
+      </g>
+
+      <g transform="translate(200 70)">
+        <ellipse rx="78" ry="27" stroke="blue" />
+        <text class="text_normal" x="-60" y="-3">Subscription for</text>
+        <text class="text_normal" x="-68" y="10">Logical Replication</text>
+      </g>
+
+      <g transform="translate(100 120)">
+        <ellipse rx="40" ry="20" stroke="blue" />
+        <text class="text_normal" x="-15" y="5">Role</text>
+      </g>
+
+    </g>
+
+    <g transform="translate(-80 10)">
+      <ellipse rx="220" ry="110" stroke="blue" stroke-width="2px" />
+      <text class="text_normal" x="-60" y="-80">Database</text>
+
+      <g transform="translate(-120 -50)">
+        <g transform="translate(-30 20)">
+          <ellipse rx="50" ry="20" stroke="blue" />
+          <text class="text_normal" x="-35" y="5">Extension</text>
+        </g>
+
+        <g transform="translate(-35 85)">
+          <ellipse rx="40" ry="20" stroke="blue" />
+          <text class="text_normal" x="-35" y="5">Collation</text>
+        </g>
+
+        <g transform="translate(150 70)">
+          <ellipse rx="140" ry="70" stroke="blue" />
+          <text class="text_normal" x="-80" y="-35">Schema</text>
+
+          <g  transform="translate(20 10)">
+            <ellipse rx="90" ry="30" stroke="blue" />
+            <text class="text_normal" x="-50" y="5">Table, View, ...</text>
+          </g>
+        </g>
+      </g>
+    </g>
+  </g>
+
+</svg>
diff --git a/doc/src/sgml/images/mvcc-ink-svgo.svg b/doc/src/sgml/images/mvcc-ink-svgo.svg
new file mode 100644
index 0000000000..6a1aa9ffdf
--- /dev/null
+++ b/doc/src/sgml/images/mvcc-ink-svgo.svg
@@ -0,0 +1,151 @@
+<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="850" height="150" viewBox="0 0 850 150">
+  <title>
+    MVCC
+  </title>
+  <style>
+    .text_small{font-style:normal;font-weight:400;font-size:10px;font-family:&quot;Open Sans&quot;,sans-serif;fill:#000}
+  </style>
+  <defs>
+    <marker id="triangle_1" markerWidth="10" markerHeight="10" refX="5" refY="5" orient="auto" stroke="black" fill="none">
+      <path d="M0 0l10 5-10 5"/>
+    </marker>
+    <path id="arrow" d="M0 0q20-15 40 0" stroke="black" marker-end="url(#triangle_1)"/>
+    <g id="tuple" stroke="black">
+      <path d="M80 0H0v20h80M29 0v20M60 0v20"/>
+      <path d="M80 0h15M80 20h15" stroke-dasharray="2 1"/>
+    </g>
+  </defs>
+  <rect x="1" y="1" rx="5" width="99%" height="99%" stroke="black" fill="none"/>
+  <g fill="none">
+    <g transform="translate(20 40)">
+      <text class="text_small" transform="translate(0 -18)">
+        T <tspan dx="-3" dy="5" font-size="8">123</tspan> <tspan dx="-2" dy="-5">: INSERT</tspan>
+      </text>
+      <use xlink:href="#arrow" transform="translate(5)"/>
+      <use xlink:href="#tuple" transform="translate(60 70)"/>
+      <text class="text_small" transform="translate(65 83)" fill="#00f">
+        123
+      </text>
+      <text class="text_small" transform="translate(95 83)" fill="#00f">
+        0
+      </text>
+      <text class="text_small" transform="translate(125 83)" fill="#00f">
+        &apos;x&apos;
+      </text>
+    </g>
+    <g transform="translate(185 40)">
+      <text class="text_small" transform="translate(0 -18)">
+        T <tspan dx="-3" dy="5" font-size="8">135</tspan> <tspan dx="-2" dy="-5">: UPDATE</tspan>
+      </text>
+      <use xlink:href="#arrow" transform="translate(5)"/>
+      <use xlink:href="#tuple" transform="translate(60 40)"/>
+      <text class="text_small" transform="translate(65 53)" fill="#00f">
+        135
+      </text>
+      <text class="text_small" transform="translate(95 53)" fill="#00f">
+        0
+      </text>
+      <text class="text_small" transform="translate(125 53)" fill="#00f">
+        &apos;y&apos;
+      </text>
+      <use xlink:href="#tuple" transform="translate(60 70)"/>
+      <text class="text_small" transform="translate(65 83)">
+        123
+      </text>
+      <text class="text_small" transform="translate(95 83)" fill="#00f">
+        135
+      </text>
+      <text class="text_small" transform="translate(125 83)">
+        &apos;x&apos;
+      </text>
+    </g>
+    <g transform="translate(350 40)">
+      <text class="text_small" transform="translate(0 -18)">
+        T <tspan dx="-3" dy="5" font-size="8">142</tspan> <tspan dx="-2" dy="-5">: UPDATE</tspan>
+      </text>
+      <use xlink:href="#arrow" transform="translate(5)"/>
+      <use xlink:href="#tuple" transform="translate(60 10)"/>
+      <text class="text_small" transform="translate(65 23)" fill="#00f">
+        142
+      </text>
+      <text class="text_small" transform="translate(95 23)" fill="#00f">
+        0
+      </text>
+      <text class="text_small" transform="translate(125 23)" fill="#00f">
+        &apos;z&apos;
+      </text>
+      <use xlink:href="#tuple" transform="translate(60 40)"/>
+      <text class="text_small" transform="translate(65 53)">
+        135
+      </text>
+      <text class="text_small" transform="translate(95 53)" fill="#00f">
+        142
+      </text>
+      <text class="text_small" transform="translate(125 53)">
+        &apos;y&apos;
+      </text>
+      <use xlink:href="#tuple" transform="translate(60 70)"/>
+      <text class="text_small" transform="translate(65 83)">
+        123
+      </text>
+      <text class="text_small" transform="translate(95 83)">
+        135
+      </text>
+      <text class="text_small" transform="translate(125 83)">
+        &apos;x&apos;
+      </text>
+    </g>
+    <g transform="translate(515 40)">
+      <text class="text_small" transform="translate(0 -18)">
+        T <tspan dx="-3" dy="5" font-size="8">821</tspan> <tspan dx="-2" dy="-5">: DELTE</tspan>
+      </text>
+      <use xlink:href="#arrow" transform="translate(5)"/>
+      <use xlink:href="#tuple" transform="translate(60 10)"/>
+      <text class="text_small" transform="translate(65 23)">
+        142
+      </text>
+      <text class="text_small" transform="translate(95 23)" fill="#00f">
+        821
+      </text>
+      <text class="text_small" transform="translate(125 23)">
+        &apos;z&apos;
+      </text>
+      <use xlink:href="#tuple" transform="translate(60 40)"/>
+      <text class="text_small" transform="translate(65 53)">
+        135
+      </text>
+      <text class="text_small" transform="translate(95 53)">
+        142
+      </text>
+      <text class="text_small" transform="translate(125 53)">
+        &apos;y&apos;
+      </text>
+      <use xlink:href="#tuple" transform="translate(60 70)"/>
+      <text class="text_small" transform="translate(65 83)">
+        123
+      </text>
+      <text class="text_small" transform="translate(95 83)">
+        135
+      </text>
+      <text class="text_small" transform="translate(125 83)">
+        &apos;x&apos;
+      </text>
+    </g>
+    <g transform="translate(740 110)">
+      <path d="M102-20H-18v90" stroke="black"/>
+      <text font-weight="400" font-size="16" font-family="&quot;Open Sans&quot;,sans-serif" fill="#000">
+        Legend
+      </text>
+      <use xlink:href="#tuple" transform="translate(0 10)"/>
+      <text class="text_small" transform="translate(3 23)">
+        xmin
+      </text>
+      <text class="text_small" transform="translate(32 23)">
+        xmax
+      </text>
+      <text class="text_small" transform="translate(65 23)">
+        data
+      </text>
+    </g>
+  </g>
+</svg>
diff --git a/doc/src/sgml/images/mvcc-ink.svg b/doc/src/sgml/images/mvcc-ink.svg
new file mode 100644
index 0000000000..aeb499f674
--- /dev/null
+++ b/doc/src/sgml/images/mvcc-ink.svg
@@ -0,0 +1,398 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://creativecommons.org/ns#"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:xlink="http://www.w3.org/1999/xlink"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   version="1.1"
+   width="850px"
+   height="150px"
+   viewBox="0 0 850 150"
+   id="svg693"
+   sodipodi:docname="mvcc-ink.svg"
+   inkscape:version="0.92.3 (2405546, 2018-03-11)">
+  <metadata
+     id="metadata697">
+    <rdf:RDF>
+      <cc:Work
+         rdf:about="">
+        <dc:format>image/svg+xml</dc:format>
+        <dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+        <dc:title>MVCC</dc:title>
+      </cc:Work>
+    </rdf:RDF>
+  </metadata>
+  <sodipodi:namedview
+     pagecolor="#ffffff"
+     bordercolor="#666666"
+     borderopacity="1"
+     objecttolerance="10"
+     gridtolerance="10"
+     guidetolerance="10"
+     inkscape:pageopacity="0"
+     inkscape:pageshadow="2"
+     inkscape:window-width="640"
+     inkscape:window-height="480"
+     id="namedview695"
+     showgrid="false"
+     inkscape:zoom="0.44"
+     inkscape:cx="425"
+     inkscape:cy="75"
+     inkscape:window-x="81"
+     inkscape:window-y="27"
+     inkscape:window-maximized="0"
+     inkscape:current-layer="svg693" />
+  <title
+     id="title548">MVCC</title>
+  <!-- common text classes -->
+  <style
+     type="text/css"
+     id="style550">
+  .text_normal  {font-style:normal;
+                 font-weight:normal;
+                 font-size:16px;
+                 font-family:&quot;Open Sans&quot;, sans-serif;
+                 fill:black;
+                }
+  .text_small   {font-style:normal;
+                 font-weight:normal;
+                 font-size:10px;
+                 font-family:&quot;Open Sans&quot;, sans-serif;
+                 fill:black;
+                }
+  </style>
+  <defs
+     id="defs561">
+    <marker
+       id="triangle_1"
+       markerWidth="10"
+       markerHeight="10"
+       refX="5"
+       refY="5"
+       orient="auto"
+       stroke="black"
+       fill="none">
+      <path
+         d="M 0,0 L 10,5 L 0,10"
+         id="path552" />
+    </marker>
+    <g
+       id="tuple">
+      <!-- an rectangle, open at the right side -->
+      <path
+         d="M 80 0 h -80 v 20 h 80 M 29 0 v 20 M 60 0 v 20"
+         stroke="black"
+         id="path555" />
+      <!-- prolong the rectangle -->
+      <path
+         d="M 80 0 h 15 M 80 20 h 15"
+         stroke="black"
+         stroke-dasharray="2 1"
+         id="path557" />
+    </g>
+    <!-- an arrow in the form of a quadratic bezier curve -->
+    <path
+       id="arrow"
+       d="M 0 0 Q 20 -15 40 0"
+       stroke="black"
+       marker-end="url(#triangle_1)" />
+  </defs>
+  <!-- start of rendering area -->
+  <!-- enclosing rectangle -->
+  <rect
+     x="1"
+     y="1"
+     rx="5"
+     width="99%"
+     height="99%"
+     stroke="black"
+     fill="none"
+     id="rect563" />
+  <!-- set default values -->
+  <g
+     fill="none"
+     id="g691">
+    <!-- start plus first INSERT -->
+    <g
+       transform="translate(20, 40)"
+       id="g581">
+      <text
+         class="text_small"
+         transform="translate(0, -18)"
+         id="text569">T
+        <tspan
+   style="font-size:8px"
+   dx="-3"
+   dy="5"
+   id="tspan565">123</tspan>
+<tspan
+   dx="-2"
+   dy="-5"
+   id="tspan567">: INSERT</tspan>
+</text>
+      <use
+         xlink:href="#arrow"
+         transform="translate(5, 0)"
+         id="use571" />
+      <use
+         xlink:href="#tuple"
+         transform="translate(60, 70)"
+         id="use573" />
+      <text
+         class="text_small"
+         transform="translate(65, 83)"
+         style="fill:blue"
+         id="text575">123</text>
+      <text
+         class="text_small"
+         transform="translate(95, 83)"
+         style="fill:blue"
+         id="text577">0</text>
+      <text
+         class="text_small"
+         transform="translate(125, 83)"
+         style="fill:blue"
+         id="text579">'x'</text>
+    </g>
+    <!-- first UPDATE -->
+    <g
+       transform="translate(185, 40)"
+       id="g607">
+      <text
+         class="text_small"
+         transform="translate(0, -18)"
+         id="text587">T
+        <tspan
+   style="font-size:8px"
+   dx="-3"
+   dy="5"
+   id="tspan583">135</tspan>
+<tspan
+   dx="-2"
+   dy="-5"
+   id="tspan585">: UPDATE</tspan>
+</text>
+      <use
+         xlink:href="#arrow"
+         transform="translate(5, 0)"
+         id="use589" />
+      <use
+         xlink:href="#tuple"
+         transform="translate(60, 40)"
+         id="use591" />
+      <text
+         class="text_small"
+         transform="translate(65, 53)"
+         style="fill:blue"
+         id="text593">135</text>
+      <text
+         class="text_small"
+         transform="translate(95, 53)"
+         style="fill:blue"
+         id="text595">0</text>
+      <text
+         class="text_small"
+         transform="translate(125, 53)"
+         style="fill:blue"
+         id="text597">'y'</text>
+      <use
+         xlink:href="#tuple"
+         transform="translate(60, 70)"
+         id="use599" />
+      <text
+         class="text_small"
+         transform="translate(65, 83)"
+         id="text601">123</text>
+      <text
+         class="text_small"
+         transform="translate(95, 83)"
+         style="fill:blue"
+         id="text603">135</text>
+      <text
+         class="text_small"
+         transform="translate(125, 83)"
+         id="text605">'x'</text>
+    </g>
+    <!-- next UPDATE -->
+    <g
+       transform="translate(350, 40)"
+       id="g641">
+      <text
+         class="text_small"
+         transform="translate(0, -18)"
+         id="text613">T
+        <tspan
+   style="font-size:8px"
+   dx="-3"
+   dy="5"
+   id="tspan609">142</tspan>
+<tspan
+   dx="-2"
+   dy="-5"
+   id="tspan611">: UPDATE</tspan>
+</text>
+      <use
+         xlink:href="#arrow"
+         transform="translate(5, 0)"
+         id="use615" />
+      <use
+         xlink:href="#tuple"
+         transform="translate(60, 10)"
+         id="use617" />
+      <text
+         class="text_small"
+         transform="translate(65, 23)"
+         style="fill:blue"
+         id="text619">142</text>
+      <text
+         class="text_small"
+         transform="translate(95, 23)"
+         style="fill:blue"
+         id="text621">0</text>
+      <text
+         class="text_small"
+         transform="translate(125, 23)"
+         style="fill:blue"
+         id="text623">'z'</text>
+      <use
+         xlink:href="#tuple"
+         transform="translate(60, 40)"
+         id="use625" />
+      <text
+         class="text_small"
+         transform="translate(65, 53)"
+         id="text627">135</text>
+      <text
+         class="text_small"
+         transform="translate(95, 53)"
+         style="fill:blue"
+         id="text629">142</text>
+      <text
+         class="text_small"
+         transform="translate(125, 53)"
+         id="text631">'y'</text>
+      <use
+         xlink:href="#tuple"
+         transform="translate(60, 70)"
+         id="use633" />
+      <text
+         class="text_small"
+         transform="translate(65, 83)"
+         id="text635">123</text>
+      <text
+         class="text_small"
+         transform="translate(95, 83)"
+         id="text637">135</text>
+      <text
+         class="text_small"
+         transform="translate(125, 83)"
+         id="text639">'x'</text>
+    </g>
+    <!-- DELETE -->
+    <g
+       transform="translate(515, 40)"
+       id="g675">
+      <text
+         class="text_small"
+         transform="translate(0, -18)"
+         id="text647">T
+        <tspan
+   style="font-size:8px"
+   dx="-3"
+   dy="5"
+   id="tspan643">821</tspan>
+<tspan
+   dx="-2"
+   dy="-5"
+   id="tspan645">: DELTE</tspan>
+</text>
+      <use
+         xlink:href="#arrow"
+         transform="translate(5, 0)"
+         id="use649" />
+      <use
+         xlink:href="#tuple"
+         transform="translate(60, 10)"
+         id="use651" />
+      <text
+         class="text_small"
+         transform="translate(65, 23)"
+         id="text653">142</text>
+      <text
+         class="text_small"
+         transform="translate(95, 23)"
+         style="fill:blue"
+         id="text655">821</text>
+      <text
+         class="text_small"
+         transform="translate(125, 23)"
+         id="text657">'z'</text>
+      <use
+         xlink:href="#tuple"
+         transform="translate(60, 40)"
+         id="use659" />
+      <text
+         class="text_small"
+         transform="translate(65, 53)"
+         id="text661">135</text>
+      <text
+         class="text_small"
+         transform="translate(95, 53)"
+         id="text663">142</text>
+      <text
+         class="text_small"
+         transform="translate(125, 53)"
+         id="text665">'y'</text>
+      <use
+         xlink:href="#tuple"
+         transform="translate(60, 70)"
+         id="use667" />
+      <text
+         class="text_small"
+         transform="translate(65, 83)"
+         id="text669">123</text>
+      <text
+         class="text_small"
+         transform="translate(95, 83)"
+         id="text671">135</text>
+      <text
+         class="text_small"
+         transform="translate(125, 83)"
+         id="text673">'x'</text>
+    </g>
+    <!-- LEGEND -->
+    <g
+       transform="translate(740, 110)"
+       id="g689">
+      <path
+         d="M 102 -20 h -120 v 90"
+         stroke="black"
+         id="path677" />
+      <text
+         class="text_normal"
+         transform="translate(0, 0)"
+         id="text679">Legend</text>
+      <use
+         xlink:href="#tuple"
+         transform="translate(0, 10)"
+         id="use681" />
+      <text
+         class="text_small"
+         transform="translate(3, 23)"
+         id="text683">xmin</text>
+      <text
+         class="text_small"
+         transform="translate(32, 23)"
+         id="text685">xmax</text>
+      <text
+         class="text_small"
+         transform="translate(65, 23)"
+         id="text687">data</text>
+    </g>
+  </g>
+</svg>
diff --git a/doc/src/sgml/images/mvcc-raw.svg b/doc/src/sgml/images/mvcc-raw.svg
new file mode 100644
index 0000000000..c5005db37d
--- /dev/null
+++ b/doc/src/sgml/images/mvcc-raw.svg
@@ -0,0 +1,145 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<svg xmlns="http://www.w3.org/2000/svg"
+     xmlns:xlink="http://www.w3.org/1999/xlink"
+     version="1.1"
+     width="850px" height="150px"
+     viewBox="0 0 850 150" >
+
+  <title>MVCC</title>
+
+  <!-- common text classes -->
+  <style type="text/css">
+  .text_normal  {font-style:normal;
+                 font-weight:normal;
+                 font-size:16px;
+                 font-family:"Open Sans", sans-serif;
+                 fill:black;
+                }
+  .text_small   {font-style:normal;
+                 font-weight:normal;
+                 font-size:10px;
+                 font-family:"Open Sans", sans-serif;
+                 fill:black;
+                }
+  </style>
+
+  <defs>
+    <marker id="triangle_1"
+            markerWidth="10"
+            markerHeight="10"
+            refX="5"
+            refY="5"
+            orient="auto" stroke="black" fill="none">
+      <path d="M 0,0 L 10,5 L 0,10" />
+    </marker>
+
+    <g id="tuple">
+      <!-- an rectangle, open at the right side -->
+      <path d="M 80 0 h -80 v 20 h 80 M 29 0 v 20 M 60 0 v 20" stroke="black"/>
+      <!-- prolong the rectangle -->
+      <path d="M 80 0 h 15 M 80 20 h 15" stroke="black" stroke-dasharray="2 1"/>
+    </g>
+
+    <!-- an arrow in the form of a quadratic bezier curve -->
+    <path id="arrow" d="M 0 0 Q 20 -15 40 0" stroke="black" marker-end="url(#triangle_1)"/>
+
+  </defs>
+
+
+  <!-- start of rendering area -->
+  <!-- enclosing rectangle -->
+  <rect x="1" y="1" rx="5" width="99%" height="99%" stroke="black" fill="none" />
+
+  <!-- set default values -->
+  <g fill="none">
+
+    <!-- start plus first INSERT -->
+    <g transform="translate(20, 40)">
+
+      <text class="text_small"      transform="translate(0, -18)">T
+        <tspan style="font-size:8px" dx="-3" dy="5">123</tspan>
+        <tspan dx="-2" dy="-5">: INSERT</tspan>
+      </text>
+      <use xlink:href="#arrow"      transform="translate(5, 0)"/>
+
+      <use xlink:href="#tuple"      transform="translate(60, 70)"/>
+      <text class="text_small"      transform="translate(65, 83)" style="fill:blue">123</text>
+      <text class="text_small"      transform="translate(95, 83)" style="fill:blue">0</text>
+      <text class="text_small"      transform="translate(125, 83)" style="fill:blue">'x'</text>
+    </g>
+
+    <!-- first UPDATE -->
+    <g transform="translate(185, 40)">
+      <text class="text_small"      transform="translate(0, -18)">T
+        <tspan style="font-size:8px" dx="-3" dy="5">135</tspan>
+        <tspan dx="-2" dy="-5">: UPDATE</tspan>
+      </text>
+      <use xlink:href="#arrow"      transform="translate(5, 0)"/>
+
+      <use xlink:href="#tuple"      transform="translate(60, 40)"/>
+      <text class="text_small"      transform="translate(65, 53)" style="fill:blue">135</text>
+      <text class="text_small"      transform="translate(95, 53)" style="fill:blue">0</text>
+      <text class="text_small"      transform="translate(125, 53)" style="fill:blue">'y'</text>
+      <use xlink:href="#tuple"      transform="translate(60, 70)"/>
+      <text class="text_small"      transform="translate(65, 83)">123</text>
+      <text class="text_small"      transform="translate(95, 83)" style="fill:blue">135</text>
+      <text class="text_small"      transform="translate(125, 83)">'x'</text>
+    </g>
+
+    <!-- next UPDATE -->
+    <g transform="translate(350, 40)">
+      <text class="text_small"      transform="translate(0, -18)">T
+        <tspan style="font-size:8px" dx="-3" dy="5">142</tspan>
+        <tspan dx="-2" dy="-5">: UPDATE</tspan>
+      </text>
+      <use xlink:href="#arrow"      transform="translate(5, 0)"/>
+
+      <use xlink:href="#tuple"      transform="translate(60, 10)"/>
+      <text class="text_small"      transform="translate(65, 23)" style="fill:blue">142</text>
+      <text class="text_small"      transform="translate(95, 23)" style="fill:blue">0</text>
+      <text class="text_small"      transform="translate(125, 23)" style="fill:blue">'z'</text>
+      <use xlink:href="#tuple"      transform="translate(60, 40)"/>
+      <text class="text_small"      transform="translate(65, 53)">135</text>
+      <text class="text_small"      transform="translate(95, 53)" style="fill:blue">142</text>
+      <text class="text_small"      transform="translate(125, 53)">'y'</text>
+      <use xlink:href="#tuple"      transform="translate(60, 70)"/>
+      <text class="text_small"      transform="translate(65, 83)">123</text>
+      <text class="text_small"      transform="translate(95, 83)">135</text>
+      <text class="text_small"      transform="translate(125, 83)">'x'</text>
+    </g>
+
+    <!-- DELETE -->
+    <g transform="translate(515, 40)">
+      <text class="text_small"      transform="translate(0, -18)">T
+        <tspan style="font-size:8px" dx="-3" dy="5">821</tspan>
+        <tspan dx="-2" dy="-5">: DELTE</tspan>
+      </text>
+      <use xlink:href="#arrow"      transform="translate(5, 0)"/>
+
+      <use xlink:href="#tuple"      transform="translate(60, 10)"/>
+      <text class="text_small"      transform="translate(65, 23)">142</text>
+      <text class="text_small"      transform="translate(95, 23)" style="fill:blue">821</text>
+      <text class="text_small"      transform="translate(125, 23)">'z'</text>
+      <use xlink:href="#tuple"      transform="translate(60, 40)"/>
+      <text class="text_small"      transform="translate(65, 53)">135</text>
+      <text class="text_small"      transform="translate(95, 53)">142</text>
+      <text class="text_small"      transform="translate(125, 53)">'y'</text>
+      <use xlink:href="#tuple"      transform="translate(60, 70)"/>
+      <text class="text_small"      transform="translate(65, 83)">123</text>
+      <text class="text_small"      transform="translate(95, 83)">135</text>
+      <text class="text_small"      transform="translate(125, 83)">'x'</text>
+    </g>
+
+    <!-- LEGEND -->
+    <g transform="translate(740, 110)">
+      <path d="M 102 -20 h -120 v 90" stroke="black"/>
+      <text class="text_normal"     transform="translate(0, 0)">Legend</text>
+      <use xlink:href="#tuple"      transform="translate(0, 10)"/>
+      <text class="text_small"      transform="translate(3, 23)">xmin</text>
+      <text class="text_small"      transform="translate(32, 23)">xmax</text>
+      <text class="text_small"      transform="translate(65, 23)">data</text>
+    </g>
+
+  </g>
+
+</svg>
diff --git a/doc/src/sgml/images/ram-proc-file-ink-svgo.svg b/doc/src/sgml/images/ram-proc-file-ink-svgo.svg
new file mode 100644
index 0000000000..15353bf307
--- /dev/null
+++ b/doc/src/sgml/images/ram-proc-file-ink-svgo.svg
@@ -0,0 +1,285 @@
+<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="900" height="600" viewBox="0 0 900 600">
+  <title>
+    PG Overall Server Architecture
+  </title>
+  <style>
+    .text_big{font-style:normal}.text_big,.text_comment,.text_normal,.text_small{font-weight:400;font-family:&quot;Open Sans&quot;,sans-serif;fill:#000}.text_normal,.text_small{font-style:normal}.text_small{font-size:12px}.text_normal{font-size:16px}.text_big{font-size:24px}.text_comment{font-style:italic;font-size:16px}
+  </style>
+  <defs>
+    <symbol id="note_200x20" stroke="black" fill="lightyellow">
+      <title>
+        UML Note (200 x 20 px)
+      </title>
+      <path d="M200 10v10H0V0h190v10h10L190 0"/>
+    </symbol>
+    <symbol id="note_250x20" stroke="black" fill="lightyellow">
+      <title>
+        UML Note (250 x 20 px)
+      </title>
+      <path d="M250 10v10H0V0h240v10h10L240 0"/>
+    </symbol>
+    <symbol id="note_100x35" stroke="black" fill="lightyellow">
+      <title>
+        UML Note (100 x 35 px)
+      </title>
+      <path d="M100 10v25H0V0h90v10h10L90 0"/>
+    </symbol>
+    <symbol id="note_170x50" stroke="black" fill="lightyellow">
+      <title>
+        UML Note (170 x 50 px)
+      </title>
+      <path d="M170 10v40H0V0h160v10h10L160 0"/>
+    </symbol>
+    <symbol id="state_300x120">
+      <title>
+        UML State (300x120)
+      </title>
+      <rect width="300" height="120" rx="10" stroke="blue" fill="none"/>
+    </symbol>
+    <symbol id="state_350x120">
+      <title>
+        UML State (350x120)
+      </title>
+      <rect width="350" height="120" rx="10" stroke="blue" fill="none"/>
+    </symbol>
+    <symbol id="disc" stroke="blue" fill="none">
+      <title>
+        Disc
+      </title>
+      <ellipse cx="51" cy="13" rx="50" ry="12"/>
+      <path d="M1 13v60"/>
+      <path d="M101 13v60"/>
+      <path d="M1 73a50 12 0 00100 0"/>
+    </symbol>
+    <symbol id="laptop" stroke="black" fill="none">
+      <title>
+        Laptop
+      </title>
+      <path d="M20 40V0h54v40l15 15H5l15-15h54"/>
+      <path d="M23 3h48v34H23z"/>
+      <path d="M30 10h20"/>
+      <path d="M30 15h25"/>
+      <path d="M30 20h10"/>
+      <path d="M30 30h20"/>
+      <path d="M25 50h45l2 2H22z"/>
+    </symbol>
+    <marker id="arrowhead_start" markerWidth="10" markerHeight="10" refX="0" refY="3" orient="auto">
+      <path d="M6 0L0 3l6 3" stroke="black" fill="none"/>
+    </marker>
+    <marker id="arrowhead_end" markerWidth="10" markerHeight="10" refX="6" refY="3" orient="auto">
+      <path d="M0 0l6 3-6 3" stroke="black" fill="none"/>
+    </marker>
+  </defs>
+  <rect x="1" y="1" rx="5" width="99%" height="99%" stroke="black" fill="none"/>
+  <text x="15" y="40" class="text_big">
+    Client
+  </text>
+  <text x="140" y="40" class="text_big">
+    Server
+  </text>
+  <use xlink:href="#laptop" x="5" y="210"/>
+  <g transform="translate(130 70)">
+    <use xlink:href="#state_350x120"/>
+    <text x="5" y="20" class="text_normal">
+      maintenance_work_mem (per connection)
+    </text>
+    <text x="5" y="45" class="text_normal">
+      work_mem (per query operation)
+    </text>
+    <text x="5" y="70" class="text_normal">
+      autovacuum_work_mem (per worker process)
+    </text>
+    <text x="5" y="95" class="text_normal">
+      temp_buffer (per connection)
+    </text>
+    <text x="5" y="110" class="text_normal">
+      ...
+    </text>
+    <use xlink:href="#note_200x20" x="140" y="-15"/>
+    <text x="150" class="text_comment">
+      Individual Memory
+    </text>
+  </g>
+  <g transform="translate(520 70)">
+    <use xlink:href="#state_300x120"/>
+    <text x="10" y="30" class="text_normal">
+      shared_buffers (heap and index)
+    </text>
+    <text x="10" y="70" class="text_normal">
+      wal_buffers (WAL records)
+    </text>
+    <text x="10" y="100" class="text_normal">
+      ...
+    </text>
+    <use xlink:href="#note_250x20" x="40" y="-15"/>
+    <text x="50" class="text_comment">
+      Shared Memory (per Cluster)
+    </text>
+  </g>
+  <path stroke="blue" fill="none" d="M160 215h295v30H160z"/>
+  <text x="10" y="20" class="text_normal" transform="translate(160 215)">
+    Postgres (outdated term: Postmaster)
+  </text>
+  <path d="M90 230h69" stroke="black" fill="none" marker-end="url(#arrowhead_end)"/>
+  <g transform="translate(140 230)">
+    <circle r="8" stroke="black" fill="lightyellow"/>
+    <text x="-4" y="4" class="text_small">
+      1
+    </text>
+  </g>
+  <path stroke="blue" fill="none" d="M150 315h370v30H150z"/>
+  <text x="10" y="20" class="text_normal" transform="translate(150 315)">
+    Backend processes (one per connection)
+  </text>
+  <path d="M155 315v-5h370v30h-5" stroke="blue" fill="none"/>
+  <path d="M160 310v-5h370v30h-5" stroke="blue" fill="none"/>
+  <path d="M90 240l63 63" stroke="black" fill="none" marker-start="url(#arrowhead_start)" marker-end="url(#arrowhead_end)"/>
+  <g transform="translate(140 290)">
+    <circle r="8" stroke="black" fill="lightyellow"/>
+    <text x="-4" y="4" class="text_small">
+      3
+    </text>
+  </g>
+  <path d="M360 250v50" stroke="black" fill="none" marker-end="url(#arrowhead_end)"/>
+  <g transform="translate(180 255)">
+    <use xlink:href="#note_250x20"/>
+    <text x="10" y="15" class="text_comment">
+      Creates backend processes
+    </text>
+  </g>
+  <g transform="translate(360 281)">
+    <circle r="8" stroke="black" fill="lightyellow"/>
+    <text x="-4" y="4" class="text_small">
+      2
+    </text>
+  </g>
+  <path d="M460 300V200" stroke="black" fill="none" marker-start="url(#arrowhead_start)" marker-end="url(#arrowhead_end)"/>
+  <path d="M498 300V95h30" stroke="black" fill="none" marker-start="url(#arrowhead_start)" marker-end="url(#arrowhead_end)"/>
+  <path d="M508 300V135h20" stroke="black" fill="none" marker-end="url(#arrowhead_end)"/>
+  <path stroke="blue" fill="none" d="M550 220h120v30H550z"/>
+  <text x="10" y="20" class="text_normal" transform="translate(550 220)">
+    WAL Writer
+  </text>
+  <path d="M590 150v65" stroke="black" fill="none" marker-end="url(#arrowhead_end)"/>
+  <path d="M590 255v230" stroke="black" fill="none" marker-end="url(#arrowhead_end)"/>
+  <path stroke="blue" fill="none" d="M610 340h140v30H610z"/>
+  <text x="10" y="20" class="text_normal" transform="translate(610 340)">
+    Checkpointer
+  </text>
+  <path d="M740 110v220" stroke="black" fill="none" marker-end="url(#arrowhead_end)"/>
+  <path d="M605 355H475v130" stroke="black" fill="none" marker-end="url(#arrowhead_end)"/>
+  <path d="M700 330V150" stroke="black" fill="none" marker-end="url(#arrowhead_end)"/>
+  <g transform="translate(570 330)">
+    <use xlink:href="#note_100x35" x="50" y="-50"/>
+    <text x="60" y="-35" class="text_comment">
+      Checkpoint
+    </text>
+    <text x="60" y="-20" class="text_comment">
+      Record
+    </text>
+  </g>
+  <path stroke="blue" fill="none" d="M610 380h180v30H610z"/>
+  <text x="10" y="20" class="text_normal" transform="translate(610 380)">
+    Background Writer
+  </text>
+  <path d="M770 110v260" stroke="black" fill="none" marker-end="url(#arrowhead_end)"/>
+  <path d="M605 395H485v90" stroke="black" fill="none" marker-end="url(#arrowhead_end)"/>
+  <path stroke="blue" fill="none" d="M610 420h180v30H610z"/>
+  <text x="10" y="20" class="text_normal" transform="translate(610 420)">
+    WAL Archiver
+  </text>
+  <path d="M620 485l30-30" stroke="black" fill="none" marker-end="url(#arrowhead_end)"/>
+  <path d="M740 455v30" stroke="black" fill="none" marker-end="url(#arrowhead_end)"/>
+  <path stroke="blue" fill="none" d="M135 380h120v30H135z"/>
+  <text x="10" y="20" class="text_normal" transform="translate(135 380)">
+    AutoVacuum
+  </text>
+  <path d="M140 380v-5h120v30h-5" stroke="blue" fill="none"/>
+  <path d="M145 375v-5h120v30h-5" stroke="blue" fill="none"/>
+  <path stroke="blue" fill="none" d="M135 430h120v30H135z"/>
+  <text x="10" y="20" class="text_normal" transform="translate(135 430)">
+    Log Writer
+  </text>
+  <path stroke="blue" fill="none" d="M290 370h140v30H290z"/>
+  <text x="10" y="20" class="text_normal" transform="translate(290 370)">
+    Stats Collector
+  </text>
+  <g transform="translate(145 490)">
+    <use xlink:href="#disc"/>
+    <text x="35" y="45" class="text_normal">
+      Log
+    </text>
+    <text x="20" y="60" class="text_small">
+      text lines,
+    </text>
+    <text x="20" y="75" class="text_small">
+      sequential
+    </text>
+  </g>
+  <path d="M195 465v20" stroke="black" fill="none" marker-end="url(#arrowhead_end)"/>
+  <g transform="translate(410 490)">
+    <use xlink:href="#disc"/>
+    <text x="10" y="40" class="text_normal">
+      Heap and
+    </text>
+    <text x="25" y="55" class="text_normal">
+      Index
+    </text>
+    <text x="15" y="70" class="text_small">
+      binary blocks,
+    </text>
+    <text x="30" y="80" class="text_small">
+      random
+    </text>
+  </g>
+  <path d="M450 485V350" stroke="black" fill="none" marker-end="url(#arrowhead_end)"/>
+  <g transform="translate(295 420)">
+    <use xlink:href="#note_170x50"/>
+    <text x="5" y="15" class="text_comment">
+      Read heap and index
+    </text>
+    <text x="5" y="30" class="text_comment">
+      pages and transfer
+    </text>
+    <text x="5" y="45" class="text_comment">
+      them to shared_buffers
+    </text>
+  </g>
+  <g transform="translate(550 490)">
+    <use xlink:href="#disc"/>
+    <text x="30" y="45" class="text_normal">
+      WAL
+    </text>
+    <text x="10" y="60" class="text_small">
+      binary records,
+    </text>
+    <text x="20" y="75" class="text_small">
+      sequential
+    </text>
+  </g>
+  <g transform="translate(690 490)">
+    <use xlink:href="#disc"/>
+    <text x="16" y="45" class="text_normal">
+      Archived
+    </text>
+    <text x="36" y="60" class="text_normal">
+      WAL
+    </text>
+  </g>
+  <path d="M110 20v550" stroke="black" fill="none"/>
+  <g transform="rotate(90 -33.5 156.5)">
+    <use xlink:href="#note_200x20"/>
+    <text class="text_comment" x="10" y="15">
+      Via TCP/IP or socket
+    </text>
+  </g>
+  <text class="text_big" x="95" transform="rotate(90 425 425)">
+    RAM
+  </text>
+  <text class="text_big" x="250" transform="rotate(90 425 425)">
+    PROCESSES
+  </text>
+  <text class="text_big" x="500" transform="rotate(90 425 425)">
+    FILES
+  </text>
+</svg>
diff --git a/doc/src/sgml/images/ram-proc-file-ink.svg b/doc/src/sgml/images/ram-proc-file-ink.svg
new file mode 100644
index 0000000000..6fe6ea7ef1
--- /dev/null
+++ b/doc/src/sgml/images/ram-proc-file-ink.svg
@@ -0,0 +1,841 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://creativecommons.org/ns#"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:xlink="http://www.w3.org/1999/xlink"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   version="1.1"
+   width="900px"
+   height="600px"
+   viewBox="0 0 900 600"
+   id="svg1003"
+   sodipodi:docname="ram-proc-file-ink.svg"
+   inkscape:version="0.92.3 (2405546, 2018-03-11)">
+  <metadata
+     id="metadata1007">
+    <rdf:RDF>
+      <cc:Work
+         rdf:about="">
+        <dc:format>image/svg+xml</dc:format>
+        <dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+        <dc:title>PG Overall Server Architecture</dc:title>
+      </cc:Work>
+    </rdf:RDF>
+  </metadata>
+  <sodipodi:namedview
+     pagecolor="#ffffff"
+     bordercolor="#666666"
+     borderopacity="1"
+     objecttolerance="10"
+     gridtolerance="10"
+     guidetolerance="10"
+     inkscape:pageopacity="0"
+     inkscape:pageshadow="2"
+     inkscape:window-width="883"
+     inkscape:window-height="645"
+     id="namedview1005"
+     showgrid="false"
+     inkscape:zoom="0.39333333"
+     inkscape:cx="450"
+     inkscape:cy="300"
+     inkscape:window-x="468"
+     inkscape:window-y="125"
+     inkscape:window-maximized="0"
+     inkscape:current-layer="svg1003" />
+  <title
+     id="title699">PG Overall Server Architecture</title>
+  <style
+     type="text/css"
+     id="style701">
+  .text_small   {font-style:normal;
+                 font-weight:normal;
+                 font-size:12px;
+                 font-family:&quot;Open Sans&quot;, sans-serif;
+                 fill:black;
+                }
+  .text_normal  {font-style:normal;
+                 font-weight:normal;
+                 font-size:16px;
+                 font-family:&quot;Open Sans&quot;, sans-serif;
+                 fill:black;
+                }
+  .text_big     {font-style:normal;
+                 font-weight:normal;
+                 font-size:24px;
+                 font-family:&quot;Open Sans&quot;, sans-serif;
+                 fill:black;
+                }
+  .text_comment {font-style:italic;
+                 font-weight:normal;
+                 font-size:16px;
+                 font-family:&quot;Open Sans&quot;, sans-serif;
+                 fill:black;
+                }
+  </style>
+  <defs
+     id="defs767">
+    <!-- Some notes in different sizes -->
+    <symbol
+       id="note_200x20"
+       stroke="black"
+       fill="lightyellow">
+      <title
+         id="title703">UML Note (200 x 20 px)</title>
+      <path
+         d="M 200,10 v 10 h -200 v -20 h 190 v 10 h 10 l -10,-10"
+         id="path705" />
+    </symbol>
+    <symbol
+       id="note_250x20"
+       stroke="black"
+       fill="lightyellow">
+      <title
+         id="title708">UML Note (250 x 20 px)</title>
+      <path
+         d="M 250,10 v 10 h -250 v -20 h 240 v 10 h 10 l -10,-10"
+         id="path710" />
+    </symbol>
+    <symbol
+       id="note_100x35"
+       stroke="black"
+       fill="lightyellow">
+      <title
+         id="title713">UML Note (100 x 35 px)</title>
+      <path
+         d="M 100,10 v 25 h -100 v -35 h 90 v 10 h 10 l -10,-10"
+         id="path715" />
+    </symbol>
+    <symbol
+       id="note_170x50"
+       stroke="black"
+       fill="lightyellow">
+      <title
+         id="title718">UML Note (170 x 50 px)</title>
+      <path
+         d="M 170,10 v 40 h -170 v -50 h 160 v 10 h 10 l -10,-10"
+         id="path720" />
+    </symbol>
+    <!-- UML states (used for buffers) -->
+    <symbol
+       id="state_300x120">
+      <title
+         id="title723">UML State (300x120)</title>
+      <rect
+         x="0"
+         y="0"
+         width="300"
+         height="120"
+         rx="10"
+         stroke="blue"
+         fill="none"
+         id="rect725" />
+    </symbol>
+    <symbol
+       id="state_350x120">
+      <title
+         id="title728">UML State (350x120)</title>
+      <rect
+         x="0"
+         y="0"
+         width="350"
+         height="120"
+         rx="10"
+         stroke="blue"
+         fill="none"
+         id="rect730" />
+    </symbol>
+    <!-- Discs -->
+    <symbol
+       id="disc"
+       stroke="blue"
+       fill="none">
+      <title
+         id="title733">Disc</title>
+      <ellipse
+         cx="51"
+         cy="13"
+         rx="50"
+         ry="12"
+         id="ellipse735" />
+      <!-- top -->
+      <path
+         d="M 1,13 v 60"
+         id="path737" />
+      <!-- left -->
+      <path
+         d="M 101,13 v 60"
+         id="path739" />
+      <!-- right -->
+      <path
+         d="M 1,73 A 50, 12, 0, 0, 0, 101,73"
+         id="path741" />
+      <!-- bottom -->
+    </symbol>
+    <!-- Laptop -->
+    <symbol
+       id="laptop"
+       stroke="black"
+       fill="none">
+      <title
+         id="title744">Laptop</title>
+      <path
+         d="M 20,40 v -40 h 54 v 40 l 15,15 h -84 l 15,-15 h 54"
+         id="path746" />
+      <rect
+         x="23"
+         y="3"
+         width="48"
+         height="34"
+         id="rect748" />
+      <!-- symbolize some lines -->
+      <path
+         d="M 30,10 h 20"
+         id="path750" />
+      <path
+         d="M 30,15 h 25"
+         id="path752" />
+      <path
+         d="M 30,20 h 10"
+         id="path754" />
+      <path
+         d="M 30,30 h 20"
+         id="path756" />
+      <!-- symbolize keyboard -->
+      <path
+         d="M 25,50 h 45 l 2,2 h -50 z "
+         id="path758" />
+    </symbol>
+    <!-- marker start/end -->
+    <marker
+       id="arrowhead_start"
+       markerWidth="10"
+       markerHeight="10"
+       refX="0"
+       refY="3"
+       orient="auto">
+      <path
+         d="M 6,0 l -6,3 l 6,3"
+         stroke="black"
+         fill="none"
+         id="path761" />
+    </marker>
+    <marker
+       id="arrowhead_end"
+       markerWidth="10"
+       markerHeight="10"
+       refX="6"
+       refY="3"
+       orient="auto">
+      <path
+         d="M 0,0 l 6,3 l -6,3"
+         stroke="black"
+         fill="none"
+         id="path764" />
+    </marker>
+  </defs>
+  <!-- start of rendering area -->
+  <!-- enclosing rectangle -->
+  <rect
+     x="1"
+     y="1"
+     rx="5"
+     width="99%"
+     height="99%"
+     stroke="black"
+     fill="none"
+     id="rect769" />
+  <!-- caption, client side -->
+  <text
+     x="15"
+     y="40"
+     class="text_big"
+     id="text771">Client</text>
+  <text
+     x="140"
+     y="40"
+     class="text_big"
+     id="text773">Server</text>
+  <use
+     xlink:href="#laptop"
+     x="5"
+     y="210"
+     id="use775" />
+  <!-- individual memory -->
+  <g
+     transform="translate(130, 70)"
+     id="g793">
+    <use
+       xlink:href="#state_350x120"
+       x="0"
+       y="0"
+       id="use777" />
+    <text
+       x="5"
+       y="20"
+       class="text_normal"
+       id="text779">maintenance_work_mem (per connection)</text>
+    <text
+       x="5"
+       y="45"
+       class="text_normal"
+       id="text781">work_mem (per query operation)</text>
+    <text
+       x="5"
+       y="70"
+       class="text_normal"
+       id="text783">autovacuum_work_mem (per worker process)</text>
+    <text
+       x="5"
+       y="95"
+       class="text_normal"
+       id="text785">temp_buffer (per connection)</text>
+    <text
+       x="5"
+       y="110"
+       class="text_normal"
+       id="text787">...</text>
+    <use
+       xlink:href="#note_200x20"
+       x="140"
+       y="-15"
+       id="use789" />
+    <text
+       x="150"
+       y="0"
+       class="text_comment"
+       id="text791">Individual Memory</text>
+  </g>
+  <!-- shared memory -->
+  <g
+     transform="translate(520, 70)"
+     id="g807">
+    <use
+       xlink:href="#state_300x120"
+       x="0"
+       y="0"
+       id="use795" />
+    <text
+       x="10"
+       y="30"
+       class="text_normal"
+       id="text797">shared_buffers (heap and index)</text>
+    <text
+       x="10"
+       y="70"
+       class="text_normal"
+       id="text799">wal_buffers (WAL records)</text>
+    <text
+       x="10"
+       y="100"
+       class="text_normal"
+       id="text801">...</text>
+    <use
+       xlink:href="#note_250x20"
+       x="40"
+       y="-15"
+       id="use803" />
+    <text
+       x="50"
+       y="0"
+       class="text_comment"
+       id="text805">Shared Memory (per Cluster)</text>
+  </g>
+  <!-- postmaster -->
+  <g
+     transform="translate(160, 215)"
+     id="g813">
+    <rect
+       width="295"
+       height="30"
+       stroke="blue"
+       fill="none"
+       id="rect809" />
+    <text
+       x="10"
+       y="20"
+       class="text_normal"
+       id="text811">Postgres (outdated term: Postmaster)</text>
+  </g>
+  <path
+     d="M 90,230 h 69"
+     stroke="black"
+     fill="none"
+     marker-end="url(#arrowhead_end)"
+     id="path815" />
+  <g
+     transform="translate(140, 230)"
+     id="g821">
+    <circle
+       r="8"
+       stroke="black"
+       fill="lightyellow"
+       id="circle817" />
+    <text
+       x="-4"
+       y="4"
+       class="text_small"
+       id="text819">1</text>
+  </g>
+  <!-- backend processes -->
+  <g
+     transform="translate(150, 315)"
+     id="g831">
+    <rect
+       width="370"
+       height="30"
+       stroke="blue"
+       fill="none"
+       id="rect823" />
+    <text
+       x="10"
+       y="20"
+       class="text_normal"
+       id="text825">Backend processes (one per connection)</text>
+    <path
+       d="M 5,0 v -5 h 370 v 30 h -5"
+       stroke="blue"
+       fill="none"
+       id="path827" />
+    <path
+       d="M 10,-5 v -5 h 370 v 30 h -5"
+       stroke="blue"
+       fill="none"
+       id="path829" />
+  </g>
+  <path
+     d="M 90,240 153,303"
+     stroke="black"
+     fill="none"
+     marker-start="url(#arrowhead_start)"
+     marker-end="url(#arrowhead_end)"
+     id="path833" />
+  <g
+     transform="translate(140, 290)"
+     id="g839">
+    <circle
+       r="8"
+       stroke="black"
+       fill="lightyellow"
+       id="circle835" />
+    <text
+       x="-4"
+       y="4"
+       class="text_small"
+       id="text837">3</text>
+  </g>
+  <!-- connection between postmaster and backend processes -->
+  <path
+     d="M 360,250 v 50"
+     stroke="black"
+     fill="none"
+     marker-end="url(#arrowhead_end)"
+     id="path841" />
+  <g
+     transform="translate(180, 255)"
+     id="g847">
+    <use
+       xlink:href="#note_250x20"
+       id="use843" />
+    <text
+       x="10"
+       y="15"
+       class="text_comment"
+       id="text845">Creates backend processes</text>
+  </g>
+  <g
+     transform="translate(360, 281)"
+     id="g853">
+    <circle
+       r="8"
+       stroke="black"
+       fill="lightyellow"
+       id="circle849" />
+    <text
+       x="-4"
+       y="4"
+       class="text_small"
+       id="text851">2</text>
+  </g>
+  <!-- backend process' access to individual memory -->
+  <path
+     d="M 460,300 v -100"
+     stroke="black"
+     fill="none"
+     marker-start="url(#arrowhead_start)"
+     marker-end="url(#arrowhead_end)"
+     id="path855" />
+  <!-- its access to shared buffers and WAL buffers -->
+  <path
+     d="M 498,300 v -205 h 30"
+     stroke="black"
+     fill="none"
+     marker-start="url(#arrowhead_start)"
+     marker-end="url(#arrowhead_end)"
+     id="path857" />
+  <path
+     d="M 508,300 v -165 h 20"
+     stroke="black"
+     fill="none"
+     marker-end="url(#arrowhead_end)"
+     id="path859" />
+  <!-- WAL writer -->
+  <g
+     transform="translate(550, 220)"
+     id="g865">
+    <rect
+       width="120"
+       height="30"
+       stroke="blue"
+       fill="none"
+       id="rect861" />
+    <text
+       x="10"
+       y="20"
+       class="text_normal"
+       id="text863">WAL Writer</text>
+  </g>
+  <path
+     d="M 590,150 v 65"
+     stroke="black"
+     fill="none"
+     marker-end="url(#arrowhead_end)"
+     id="path867" />
+  <path
+     d="M 590,255 v 230"
+     stroke="black"
+     fill="none"
+     marker-end="url(#arrowhead_end)"
+     id="path869" />
+  <!-- Checkpoiner -->
+  <g
+     transform="translate(610, 340)"
+     id="g875">
+    <rect
+       width="140"
+       height="30"
+       stroke="blue"
+       fill="none"
+       id="rect871" />
+    <text
+       x="10"
+       y="20"
+       class="text_normal"
+       id="text873">Checkpointer</text>
+  </g>
+  <path
+     d="M 740,110 v 220"
+     stroke="black"
+     fill="none"
+     marker-end="url(#arrowhead_end)"
+     id="path877" />
+  <path
+     d="M 605,355 h -130 v 130"
+     stroke="black"
+     fill="none"
+     marker-end="url(#arrowhead_end)"
+     id="path879" />
+  <path
+     d="M 700,330 v -180"
+     stroke="black"
+     fill="none"
+     marker-end="url(#arrowhead_end)"
+     id="path881" />
+  <g
+     transform="translate(570, 330)"
+     id="g889">
+    <use
+       xlink:href="#note_100x35"
+       x="50"
+       y="-50"
+       id="use883" />
+    <text
+       x="60"
+       y="-35"
+       class="text_comment"
+       id="text885">Checkpoint</text>
+    <text
+       x="60"
+       y="-20"
+       class="text_comment"
+       id="text887">Record</text>
+  </g>
+  <!-- BG writer -->
+  <g
+     transform="translate(610, 380)"
+     id="g895">
+    <rect
+       width="180"
+       height="30"
+       stroke="blue"
+       fill="none"
+       id="rect891" />
+    <text
+       x="10"
+       y="20"
+       class="text_normal"
+       id="text893">Background Writer</text>
+  </g>
+  <path
+     d="M 770,110 v 260"
+     stroke="black"
+     fill="none"
+     marker-end="url(#arrowhead_end)"
+     id="path897" />
+  <path
+     d="M 605,395 h -120 v 90"
+     stroke="black"
+     fill="none"
+     marker-end="url(#arrowhead_end)"
+     id="path899" />
+  <!-- Archiver -->
+  <g
+     transform="translate(610, 420)"
+     id="g905">
+    <rect
+       width="180"
+       height="30"
+       stroke="blue"
+       fill="none"
+       id="rect901" />
+    <text
+       x="10"
+       y="20"
+       class="text_normal"
+       id="text903">WAL Archiver</text>
+  </g>
+  <path
+     d="M 620,485 l 30,-30"
+     stroke="black"
+     fill="none"
+     marker-end="url(#arrowhead_end)"
+     id="path907" />
+  <path
+     d="M 740,455 v 30"
+     stroke="black"
+     fill="none"
+     marker-end="url(#arrowhead_end)"
+     id="path909" />
+  <!-- Vacuum -->
+  <g
+     transform="translate(135, 380)"
+     id="g919">
+    <rect
+       width="120"
+       height="30"
+       stroke="blue"
+       fill="none"
+       id="rect911" />
+    <text
+       x="10"
+       y="20"
+       class="text_normal"
+       id="text913">AutoVacuum</text>
+    <path
+       d="M 5,0 v -5 h 120 v 30 h -5"
+       stroke="blue"
+       fill="none"
+       id="path915" />
+    <path
+       d="M 10,-5 v -5 h 120 v 30 h -5"
+       stroke="blue"
+       fill="none"
+       id="path917" />
+  </g>
+  <!-- Log Writer -->
+  <g
+     transform="translate(135, 430)"
+     id="g925">
+    <rect
+       width="120"
+       height="30"
+       stroke="blue"
+       fill="none"
+       id="rect921" />
+    <text
+       x="10"
+       y="20"
+       class="text_normal"
+       id="text923">Log Writer</text>
+  </g>
+  <!-- Stats Collector -->
+  <g
+     transform="translate(290, 370)"
+     id="g931">
+    <rect
+       width="140"
+       height="30"
+       stroke="blue"
+       fill="none"
+       id="rect927" />
+    <text
+       x="10"
+       y="20"
+       class="text_normal"
+       id="text929">Stats Collector</text>
+  </g>
+  <!--       -->
+  <!-- files -->
+  <!--       -->
+  <g
+     transform="translate(145, 490)"
+     id="g941">
+    <use
+       xlink:href="#disc"
+       id="use933" />
+    <text
+       x="35"
+       y="45"
+       class="text_normal"
+       id="text935">Log</text>
+    <text
+       x="20"
+       y="60"
+       class="text_small"
+       id="text937">text lines,</text>
+    <text
+       x="20"
+       y="75"
+       class="text_small"
+       id="text939">sequential</text>
+  </g>
+  <path
+     d="M 195,465 v 20"
+     stroke="black"
+     fill="none"
+     marker-end="url(#arrowhead_end)"
+     id="path943" />
+  <g
+     transform="translate(410, 490)"
+     id="g955">
+    <use
+       xlink:href="#disc"
+       id="use945" />
+    <text
+       x="10"
+       y="40"
+       class="text_normal"
+       id="text947">Heap and</text>
+    <text
+       x="25"
+       y="55"
+       class="text_normal"
+       id="text949">Index</text>
+    <text
+       x="15"
+       y="70"
+       class="text_small"
+       id="text951">binary blocks,</text>
+    <text
+       x="30"
+       y="80"
+       class="text_small"
+       id="text953">random</text>
+  </g>
+  <path
+     d="M 450,485 v -135"
+     stroke="black"
+     fill="none"
+     marker-end="url(#arrowhead_end)"
+     id="path957" />
+  <g
+     transform="translate(295, 420)"
+     id="g967">
+    <use
+       xlink:href="#note_170x50"
+       id="use959" />
+    <text
+       x="5"
+       y="15"
+       class="text_comment"
+       id="text961">Read heap and index</text>
+    <text
+       x="5"
+       y="30"
+       class="text_comment"
+       id="text963">pages and transfer</text>
+    <text
+       x="5"
+       y="45"
+       class="text_comment"
+       id="text965">them to shared_buffers</text>
+  </g>
+  <g
+     transform="translate(550, 490)"
+     id="g977">
+    <use
+       xlink:href="#disc"
+       id="use969" />
+    <text
+       x="30"
+       y="45"
+       class="text_normal"
+       id="text971">WAL</text>
+    <text
+       x="10"
+       y="60"
+       class="text_small"
+       id="text973">binary records,</text>
+    <text
+       x="20"
+       y="75"
+       class="text_small"
+       id="text975">sequential</text>
+  </g>
+  <g
+     transform="translate(690, 490)"
+     id="g985">
+    <use
+       xlink:href="#disc"
+       id="use979" />
+    <text
+       x="16"
+       y="45"
+       class="text_normal"
+       id="text981">Archived</text>
+    <text
+       x="36"
+       y="60"
+       class="text_normal"
+       id="text983">WAL</text>
+  </g>
+  <!-- boarder between client and server side -->
+  <path
+     d="M 110,20 v 550"
+     stroke="black"
+     fill="none"
+     id="path987" />
+  <g
+     transform="translate(123, 190) rotate(90)"
+     id="g993">
+    <use
+       xlink:href="#note_200x20"
+       id="use989" />
+    <text
+       class="text_comment"
+       x="10"
+       y="15"
+       id="text991">Via TCP/IP or socket</text>
+  </g>
+  <!-- right side -->
+  <g
+     transform="translate(850, 0) rotate(90)"
+     id="g1001">
+    <text
+       class="text_big"
+       x="95"
+       id="text995">RAM</text>
+    <text
+       class="text_big"
+       x="250"
+       id="text997">PROCESSES</text>
+    <text
+       class="text_big"
+       x="500"
+       id="text999">FILES</text>
+  </g>
+</svg>
diff --git a/doc/src/sgml/images/ram-proc-file-raw.svg b/doc/src/sgml/images/ram-proc-file-raw.svg
new file mode 100644
index 0000000000..814ff6dff1
--- /dev/null
+++ b/doc/src/sgml/images/ram-proc-file-raw.svg
@@ -0,0 +1,301 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<svg xmlns="http://www.w3.org/2000/svg"
+     xmlns:xlink="http://www.w3.org/1999/xlink"
+     version="1.1"
+     width="900px" height="600px"
+     viewBox="0 0 900 600">
+
+  <title>PG Overall Server Architecture</title>
+
+  <style type="text/css">
+  .text_small   {font-style:normal;
+                 font-weight:normal;
+                 font-size:12px;
+                 font-family:"Open Sans", sans-serif;
+                 fill:black;
+                }
+  .text_normal  {font-style:normal;
+                 font-weight:normal;
+                 font-size:16px;
+                 font-family:"Open Sans", sans-serif;
+                 fill:black;
+                }
+  .text_big     {font-style:normal;
+                 font-weight:normal;
+                 font-size:24px;
+                 font-family:"Open Sans", sans-serif;
+                 fill:black;
+                }
+  .text_comment {font-style:italic;
+                 font-weight:normal;
+                 font-size:16px;
+                 font-family:"Open Sans", sans-serif;
+                 fill:black;
+                }
+  </style>
+
+  <defs>
+
+    <!-- Some notes in different sizes -->
+    <symbol id="note_200x20" stroke="black" fill="lightyellow">
+      <title>UML Note (200 x 20 px)</title>
+      <path d="M 200,10 v 10 h -200 v -20 h 190 v 10 h 10 l -10,-10" />
+    </symbol>
+    <symbol id="note_250x20" stroke="black" fill="lightyellow">
+      <title>UML Note (250 x 20 px)</title>
+      <path d="M 250,10 v 10 h -250 v -20 h 240 v 10 h 10 l -10,-10" />
+    </symbol>
+    <symbol id="note_100x35" stroke="black" fill="lightyellow">
+      <title>UML Note (100 x 35 px)</title>
+      <path d="M 100,10 v 25 h -100 v -35 h 90 v 10 h 10 l -10,-10" />
+    </symbol>
+    <symbol id="note_170x50" stroke="black" fill="lightyellow">
+      <title>UML Note (170 x 50 px)</title>
+      <path d="M 170,10 v 40 h -170 v -50 h 160 v 10 h 10 l -10,-10" />
+    </symbol>
+
+    <!-- UML states (used for buffers) -->
+    <symbol id="state_300x120">
+      <title>UML State (300x120)</title>
+      <rect x="0" y="0" width="300" height="120" rx="10" stroke="blue" fill="none"/>
+    </symbol>
+    <symbol id="state_350x120">
+      <title>UML State (350x120)</title>
+      <rect x="0" y="0" width="350" height="120" rx="10" stroke="blue" fill="none"/>
+    </symbol>
+
+    <!-- Discs -->
+    <symbol id="disc" stroke="blue" fill="none" >
+      <title>Disc</title>
+      <ellipse cx="51" cy="13" rx="50" ry="12" />      <!-- top -->
+      <path    d="M 1,13 v 60" />                      <!-- left -->
+      <path    d="M 101,13 v 60" />                    <!-- right -->
+      <path    d="M 1,73 A 50, 12, 0, 0, 0, 101,73" /> <!-- bottom -->
+    </symbol>
+
+    <!-- Laptop -->
+    <symbol id="laptop" stroke="black" fill="none" >
+      <title>Laptop</title>
+      <path d="M 20,40 v -40 h 54 v 40 l 15,15 h -84 l 15,-15 h 54" />
+      <rect x="23" y="3" width="48" height="34" />
+      <!-- symbolize some lines -->
+      <path d="M 30,10 h 20" />
+      <path d="M 30,15 h 25" />
+      <path d="M 30,20 h 10" />
+      <path d="M 30,30 h 20" />
+      <!-- symbolize keyboard -->
+      <path d="M 25,50 h 45 l 2,2 h -50 z " />
+    </symbol>
+
+    <!-- marker start/end -->
+    <marker id="arrowhead_start"
+            markerWidth="10"
+            markerHeight="10"
+            refX="0"
+            refY="3"
+            orient="auto">
+      <path d="M 6,0 l -6,3 l 6,3" stroke="black" fill="none" />
+    </marker>
+    <marker id="arrowhead_end"
+            markerWidth="10"
+            markerHeight="10"
+            refX="6"
+            refY="3"
+            orient="auto">
+      <path d="M 0,0 l 6,3 l -6,3" stroke="black" fill="none" />
+    </marker>
+
+  </defs>
+
+
+  <!-- start of rendering area -->
+  <!-- enclosing rectangle -->
+  <rect x="1" y="1" rx="5" width="99%" height="99%" stroke="black" fill="none" />
+
+  <!-- caption, client side -->
+  <text x="15" y="40"  class="text_big">Client</text>
+  <text x="140" y="40" class="text_big">Server</text>
+  <use xlink:href="#laptop" x="5" y="210" />
+
+
+  <!-- individual memory -->
+  <g transform="translate(130, 70)">
+    <use xlink:href="#state_350x120" x="0" y="0" />
+    <text x="5" y="20"  class="text_normal">maintenance_work_mem (per connection)</text>
+    <text x="5" y="45"  class="text_normal">work_mem (per query operation)</text>
+    <text x="5" y="70"  class="text_normal">autovacuum_work_mem (per worker process)</text>
+    <text x="5" y="95" class="text_normal">temp_buffer (per connection)</text>
+    <text x="5" y="110" class="text_normal">...</text>
+    <use xlink:href="#note_200x20" x="140" y="-15" />
+    <text x="150" y="0"  class="text_comment">Individual Memory</text>
+  </g>
+
+  <!-- shared memory -->
+  <g transform="translate(520, 70)">
+    <use xlink:href="#state_300x120" x="0" y="0" />
+    <text x="10" y="30" class="text_normal">shared_buffers (heap and index)</text>
+    <text x="10" y="70" class="text_normal">wal_buffers (WAL records)</text>
+    <text x="10" y="100" class="text_normal">...</text>
+    <use xlink:href="#note_250x20" x="40" y="-15" />
+    <text x="50" y="0"  class="text_comment">Shared Memory (per Cluster)</text>
+  </g>
+
+  <!-- postmaster -->
+  <g transform="translate(160, 215)">
+    <rect width="295" height="30" stroke="blue" fill="none" />
+    <text x="10" y="20" class="text_normal">Postgres (outdated term: Postmaster)</text>
+  </g>
+  <path d="M 90,230 h 69" stroke="black" fill="none" marker-end="url(#arrowhead_end)"/>
+  <g transform="translate(140, 230)">
+    <circle r="8" stroke="black" fill="lightyellow" />
+    <text x="-4" y="4" class="text_small">1</text>
+  </g>
+
+  <!-- backend processes -->
+  <g transform="translate(150, 315)">
+    <rect width="370" height="30" stroke="blue" fill="none" />
+    <text x="10" y="20" class="text_normal">Backend processes (one per connection)</text>
+    <path d="M 5,0 v -5 h 370 v 30 h -5" stroke="blue" fill="none" />
+    <path d="M 10,-5 v -5 h 370 v 30 h -5" stroke="blue" fill="none" />
+  </g>
+
+  <path d="M 90,240 153,303" stroke="black" fill="none"
+        marker-start="url(#arrowhead_start)" marker-end="url(#arrowhead_end)"/>
+  <g transform="translate(140, 290)">
+    <circle r="8" stroke="black" fill="lightyellow" />
+    <text x="-4" y="4" class="text_small">3</text>
+  </g>
+
+  <!-- connection between postmaster and backend processes -->
+  <path d="M 360,250 v 50" stroke="black" fill="none" marker-end="url(#arrowhead_end)"/>
+  <g transform="translate(180, 255)">
+    <use xlink:href="#note_250x20" />
+    <text x="10" y="15" class="text_comment">Creates backend processes</text>
+  </g>
+  <g transform="translate(360, 281)">
+    <circle r="8" stroke="black" fill="lightyellow" />
+    <text x="-4" y="4" class="text_small">2</text>
+  </g>
+
+  <!-- backend process' access to individual memory -->
+  <path d="M 460,300 v -100" stroke="black" fill="none"
+        marker-start="url(#arrowhead_start)" marker-end="url(#arrowhead_end)"/>
+  <!-- its access to shared buffers and WAL buffers -->
+  <path d="M 498,300 v -205 h 30" stroke="black" fill="none"
+        marker-start="url(#arrowhead_start)" marker-end="url(#arrowhead_end)"/>
+  <path d="M 508,300 v -165 h 20" stroke="black" fill="none"
+        marker-end="url(#arrowhead_end)"/>
+
+  <!-- WAL writer -->
+  <g transform="translate(550, 220)">
+    <rect width="120" height="30" stroke="blue" fill="none" />
+    <text x="10" y="20" class="text_normal">WAL Writer</text>
+  </g>
+  <path d="M 590,150 v 65" stroke="black" fill="none" marker-end="url(#arrowhead_end)"/>
+  <path d="M 590,255 v 230" stroke="black" fill="none" marker-end="url(#arrowhead_end)"/>
+
+  <!-- Checkpoiner -->
+  <g transform="translate(610, 340)">
+    <rect width="140" height="30" stroke="blue" fill="none" />
+    <text x="10" y="20" class="text_normal">Checkpointer</text>
+  </g>
+  <path d="M 740,110 v 220" stroke="black" fill="none" marker-end="url(#arrowhead_end)"/>
+  <path d="M 605,355 h -130 v 130" stroke="black" fill="none" marker-end="url(#arrowhead_end)"/>
+  <path d="M 700,330 v -180" stroke="black" fill="none" marker-end="url(#arrowhead_end)"/>
+  <g transform="translate(570, 330)">
+    <use xlink:href="#note_100x35" x="50" y="-50" />
+    <text x="60" y="-35"  class="text_comment">Checkpoint</text>
+    <text x="60" y="-20"  class="text_comment">Record</text>
+  </g>
+
+  <!-- BG writer -->
+  <g transform="translate(610, 380)">
+    <rect width="180" height="30" stroke="blue" fill="none" />
+    <text x="10" y="20" class="text_normal">Background Writer</text>
+  </g>
+  <path d="M 770,110 v 260" stroke="black" fill="none" marker-end="url(#arrowhead_end)"/>
+  <path d="M 605,395 h -120 v 90" stroke="black" fill="none" marker-end="url(#arrowhead_end)"/>
+
+  <!-- Archiver -->
+  <g transform="translate(610, 420)">
+    <rect width="180" height="30" stroke="blue" fill="none" />
+    <text x="10" y="20" class="text_normal">WAL Archiver</text>
+  </g>
+  <path d="M 620,485 l 30,-30" stroke="black" fill="none" marker-end="url(#arrowhead_end)"/>
+  <path d="M 740,455 v 30" stroke="black" fill="none" marker-end="url(#arrowhead_end)"/>
+
+  <!-- Vacuum -->
+  <g transform="translate(135, 380)">
+    <rect width="120" height="30" stroke="blue" fill="none" />
+    <text x="10" y="20" class="text_normal">AutoVacuum</text>
+    <path d="M 5,0 v -5 h 120 v 30 h -5" stroke="blue" fill="none" />
+    <path d="M 10,-5 v -5 h 120 v 30 h -5" stroke="blue" fill="none" />
+  </g>
+
+  <!-- Log Writer -->
+  <g transform="translate(135, 430)">
+    <rect width="120" height="30" stroke="blue" fill="none" />
+    <text x="10" y="20" class="text_normal">Log Writer</text>
+  </g>
+
+  <!-- Stats Collector -->
+  <g transform="translate(290, 370)">
+    <rect width="140" height="30" stroke="blue" fill="none" />
+    <text x="10" y="20" class="text_normal">Stats Collector</text>
+  </g>
+
+  <!--       -->
+  <!-- files -->
+  <!--       -->
+  <g transform="translate(145, 490)">
+    <use xlink:href="#disc" />
+    <text x="35" y="45" class="text_normal">Log</text>
+    <text x="20" y="60" class="text_small">text lines,</text>
+    <text x="20" y="75" class="text_small">sequential</text>
+  </g>
+  <path d="M 195,465 v 20" stroke="black" fill="none" marker-end="url(#arrowhead_end)"/>
+
+  <g transform="translate(410, 490)">
+    <use xlink:href="#disc" />
+    <text x="10" y="40" class="text_normal">Heap and</text>
+    <text x="25" y="55" class="text_normal">Index</text>
+    <text x="15" y="70" class="text_small">binary blocks,</text>
+    <text x="30" y="80" class="text_small">random</text>
+  </g>
+  <path d="M 450,485 v -135" stroke="black" fill="none" marker-end="url(#arrowhead_end)"/>
+
+  <g transform="translate(295, 420)">
+    <use xlink:href="#note_170x50" />
+    <text x="5" y="15" class="text_comment">Read heap and index</text>
+    <text x="5" y="30" class="text_comment">pages and transfer</text>
+    <text x="5" y="45" class="text_comment">them to shared_buffers</text>
+  </g>
+
+  <g transform="translate(550, 490)">
+    <use xlink:href="#disc" />
+    <text x="30" y="45" class="text_normal">WAL</text>
+    <text x="10" y="60" class="text_small">binary records,</text>
+    <text x="20" y="75" class="text_small">sequential</text>
+  </g>
+
+  <g transform="translate(690, 490)">
+    <use xlink:href="#disc" />
+    <text x="16" y="45" class="text_normal">Archived</text>
+    <text x="36" y="60" class="text_normal">WAL</text>
+  </g>
+
+  <!-- boarder between client and server side -->
+  <path d="M 110,20 v 550" stroke="black" fill="none" />
+  <g transform="translate(123, 190) rotate(90)">
+    <use xlink:href="#note_200x20"  />
+    <text class="text_comment" x="10" y ="15">Via TCP/IP or socket</text>
+  </g>
+
+  <!-- right side -->
+  <g transform="translate(850, 0) rotate(90)">
+    <text class="text_big" x="95">RAM</text>
+    <text class="text_big" x="250">PROCESSES</text>
+    <text class="text_big" x="500">FILES</text>
+  </g>
+
+</svg>
diff --git a/doc/src/sgml/images/wraparound-ink-svgo.svg b/doc/src/sgml/images/wraparound-ink-svgo.svg
new file mode 100644
index 0000000000..9882d2be23
--- /dev/null
+++ b/doc/src/sgml/images/wraparound-ink-svgo.svg
@@ -0,0 +1,40 @@
+<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="850" height="280" viewBox="0 0 850 280">
+  <title>
+    Cyclic usage of XIDs
+  </title>
+  <style>
+    .text_normal{font-style:normal;font-weight:400;font-size:16px;font-family:&quot;Open Sans&quot;,sans-serif;fill:#000}
+  </style>
+  <defs>
+    <path id="Path_080" d="M-80 0A80 80 0 1180 0 80 80 0 11-80 0"/>
+    <path id="Path_095" d="M-95 0A95 95 0 1195 0 95 95 0 11-95 0"/>
+    <path id="Path_120" d="M-120 0a120 120 0 11240 0 120 120 0 11-240 0"/>
+  </defs>
+  <rect x="1" y="1" rx="5" width="99%" height="99%" stroke="black" fill="none"/>
+  <text x="370" y="40" font-weight="400" font-size="24" font-family="&quot;Open Sans&quot;,sans-serif,Helvetica">
+    Cyclic usage of XIDs modulo 2 <tspan dy="-5">^</tspan> <tspan dy="5">32</tspan>
+  </text>
+  <g fill="none" transform="translate(170 150)">
+    <circle r="100" stroke="blue"/>
+    <text class="text_normal">
+      <textPath xlink:href="#Path_095" startOffset=".5%">|</textPath> <textPath xlink:href="#Path_120" startOffset="0%">(0)</textPath> <textPath xlink:href="#Path_080" startOffset="1%" stroke="blue" stroke-width=".5"> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - &gt;</textPath> <textPath xlink:href="#Path_095" startOffset="30.5%">|</textPath> <textPath xlink:href="#Path_120" startOffset="30%">(1)</textPath> <textPath xlink:href="#Path_095" startOffset="45.5%">|</textPath> <textPath xlink:href="#Path_120" startOffset="45%">(2)</textPath> <textPath xlink:href="#Path_095" startOffset="50.5%">|</textPath> <textPath xlink:href="#Path_120" startOffset="50%">(3)</textPath> <textPath xlink:href="#Path_095" startOffset="62.5%">|</textPath> <textPath xlink:href="#Path_120" startOffset="62%">(4)</textPath>
+    </text>
+  </g>
+  <g class="text_normal">
+    <text transform="translate(400 130)">
+      0: 0 .. 2 <tspan dy="-5">^</tspan> <tspan dy="5">32</tspan> - 1
+    </text>
+    <text y="25" transform="translate(400 130)">
+      1: oldest <tspan font-weight="700">active</tspan> xid (pg_stat_activity.backend_xmin)
+    </text>
+    <text y="50" transform="translate(400 130)">
+      2: xmin of one row version
+    </text>
+    <text y="75" transform="translate(400 130)">
+      3: xmax of the same row version
+    </text>
+    <text y="100" transform="translate(400 130)">
+      4: jungest xid (txid_current)
+    </text>
+  </g>
+</svg>
diff --git a/doc/src/sgml/images/wraparound-ink.svg b/doc/src/sgml/images/wraparound-ink.svg
new file mode 100644
index 0000000000..ca5e45ac2b
--- /dev/null
+++ b/doc/src/sgml/images/wraparound-ink.svg
@@ -0,0 +1,198 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://creativecommons.org/ns#"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:xlink="http://www.w3.org/1999/xlink"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   version="1.1"
+   width="850px"
+   height="280px"
+   viewBox="0 0 850 280"
+   id="svg1072"
+   sodipodi:docname="wraparound-ink.svg"
+   inkscape:version="0.92.3 (2405546, 2018-03-11)">
+  <metadata
+     id="metadata1076">
+    <rdf:RDF>
+      <cc:Work
+         rdf:about="">
+        <dc:format>image/svg+xml</dc:format>
+        <dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+        <dc:title>Cyclic usage of XIDs</dc:title>
+      </cc:Work>
+    </rdf:RDF>
+  </metadata>
+  <sodipodi:namedview
+     pagecolor="#ffffff"
+     bordercolor="#666666"
+     borderopacity="1"
+     objecttolerance="10"
+     gridtolerance="10"
+     guidetolerance="10"
+     inkscape:pageopacity="0"
+     inkscape:pageshadow="2"
+     inkscape:window-width="860"
+     inkscape:window-height="644"
+     id="namedview1074"
+     showgrid="false"
+     inkscape:zoom="0.44"
+     inkscape:cx="425"
+     inkscape:cy="140"
+     inkscape:window-x="346"
+     inkscape:window-y="93"
+     inkscape:window-maximized="0"
+     inkscape:current-layer="svg1072" />
+  <title
+     id="title1009">Cyclic usage of XIDs</title>
+  <!-- common text classes -->
+  <style
+     type="text/css"
+     id="style1011">
+  .text_normal  {font-style:normal;
+                 font-weight:normal;
+                 font-size:16px;
+                 font-family:&quot;Open Sans&quot;, sans-serif;
+                 fill:black;
+                }
+  .text_big     {font-style:normal;
+                 font-weight:normal;
+                 font-size:24px;
+                 font-family:&quot;Open Sans&quot;, sans-serif, Helvetica;
+                 fill:black;
+                }
+  </style>
+  <defs
+     id="defs1016">
+    <!-- SVG 1.x supports <texPath> only in combination with <path>. SVG 2 allows the
+         combination with every shape element, especially with <circle>. As of 2020
+         we must restrict ourselves to SVG 1. Therefore: we simulate a circle by
+         defining two arcs, each of them is a half-circle.
+    -->
+    <path
+       id="Path_080"
+       d="m -80 0                            a 80 80 0 1 1  160 0                            a 80 80 0 1 1 -160 0" />
+    <path
+       id="Path_095"
+       d="m -95 0                            a 95 95 0 1 1  190 0                            a 95 95 0 1 1 -190 0" />
+    <path
+       id="Path_120"
+       d="m -120 0                            a 120 120 0 1 1  240 0                            a 120 120 0 1 1 -240 0" />
+  </defs>
+  <!-- start of rendering area -->
+  <!-- enclosing rectangle -->
+  <rect
+     x="1"
+     y="1"
+     rx="5"
+     width="99%"
+     height="99%"
+     stroke="black"
+     fill="none"
+     id="rect1018" />
+  <text
+     class="text_big"
+     x="370"
+     y="40"
+     id="text1024">Cyclic usage of XIDs modulo 2
+        <tspan
+   dy="-5"
+   id="tspan1020">^</tspan>
+<tspan
+   dy="5"
+   id="tspan1022">32</tspan>
+</text>
+  <!-- set default values -->
+  <g
+     fill="none"
+     transform="translate(170 150)"
+     id="g1052">
+    <circle
+       r="100"
+       stroke="blue"
+       id="circle1026" />
+    <text
+       class="text_normal"
+       id="text1050">
+      <textPath
+         xlink:href="#Path_095"
+         startOffset="0.5%"
+         id="textPath1028">|</textPath>
+      <textPath
+         xlink:href="#Path_120"
+         startOffset="00%"
+         id="textPath1030">(0)</textPath>
+      <textPath
+         xlink:href="#Path_080"
+         startOffset="01%"
+         stroke="blue"
+         stroke-width="0.5px"
+         id="textPath1032">
+        - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - &gt;</textPath>
+      <textPath
+         xlink:href="#Path_095"
+         startOffset="30.5%"
+         id="textPath1034">|</textPath>
+      <textPath
+         xlink:href="#Path_120"
+         startOffset="30%"
+         id="textPath1036">(1)</textPath>
+      <textPath
+         xlink:href="#Path_095"
+         startOffset="45.5%"
+         id="textPath1038">|</textPath>
+      <textPath
+         xlink:href="#Path_120"
+         startOffset="45%"
+         id="textPath1040">(2)</textPath>
+      <textPath
+         xlink:href="#Path_095"
+         startOffset="50.5%"
+         id="textPath1042">|</textPath>
+      <textPath
+         xlink:href="#Path_120"
+         startOffset="50%"
+         id="textPath1044">(3)</textPath>
+      <textPath
+         xlink:href="#Path_095"
+         startOffset="62.5%"
+         id="textPath1046">|</textPath>
+      <textPath
+         xlink:href="#Path_120"
+         startOffset="62%"
+         id="textPath1048">(4)</textPath>
+    </text>
+  </g>
+  <g
+     class="text_normal"
+     transform="translate(400 130)"
+     id="g1070">
+    <text
+       id="text1058">0: 0 .. 2  <tspan
+   dy="-5"
+   id="tspan1054">^</tspan>
+<tspan
+   dy="5"
+   id="tspan1056">32</tspan>
+ - 1</text>
+    <text
+       y="25"
+       id="text1062">1: oldest <tspan
+   style="font-weight:bold"
+   id="tspan1060">active</tspan>
+ xid (pg_stat_activity.backend_xmin)</text>
+    <text
+       y="50"
+       id="text1064">2: xmin of one row version</text>
+    <text
+       y="75"
+       id="text1066">3: xmax of the same row version</text>
+    <text
+       y="100"
+       id="text1068">4: jungest xid (txid_current)</text>
+  </g>
+</svg>
diff --git a/doc/src/sgml/images/wraparound-raw.svg b/doc/src/sgml/images/wraparound-raw.svg
new file mode 100644
index 0000000000..9406f52970
--- /dev/null
+++ b/doc/src/sgml/images/wraparound-raw.svg
@@ -0,0 +1,79 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<svg xmlns="http://www.w3.org/2000/svg"
+     xmlns:xlink="http://www.w3.org/1999/xlink"
+     version="1.1"
+     width="850px" height="280px"
+     viewBox="0 0 850 280" >
+
+  <title>Cyclic usage of XIDs</title>
+
+  <!-- common text classes -->
+  <style type="text/css">
+  .text_normal  {font-style:normal;
+                 font-weight:normal;
+                 font-size:16px;
+                 font-family:"Open Sans", sans-serif;
+                 fill:black;
+                }
+  .text_big     {font-style:normal;
+                 font-weight:normal;
+                 font-size:24px;
+                 font-family:"Open Sans", sans-serif, Helvetica;
+                 fill:black;
+                }
+  </style>
+
+  <defs>
+    <!-- SVG 1.x supports <texPath> only in combination with <path>. SVG 2 allows the
+         combination with every shape element, especially with <circle>. As of 2020
+         we must restrict ourselves to SVG 1. Therefore: we simulate a circle by
+         defining two arcs, each of them is a half-circle.
+    -->
+    <path id="Path_080" d="m -80 0
+                           a 80 80 0 1 1  160 0
+                           a 80 80 0 1 1 -160 0"/>
+    <path id="Path_095" d="m -95 0
+                           a 95 95 0 1 1  190 0
+                           a 95 95 0 1 1 -190 0"/>
+    <path id="Path_120" d="m -120 0
+                           a 120 120 0 1 1  240 0
+                           a 120 120 0 1 1 -240 0"/>
+  </defs>
+
+
+  <!-- start of rendering area -->
+  <!-- enclosing rectangle -->
+  <rect x="1" y="1" rx="5" width="99%" height="99%" stroke="black" fill="none" />
+  <text class="text_big" x="370" y="40">Cyclic usage of XIDs modulo 2
+        <tspan dy="-5">^</tspan> <tspan dy="5">32</tspan></text>
+
+  <!-- set default values -->
+  <g fill="none" transform="translate(170 150)">
+
+    <circle r="100" stroke="blue" />
+
+    <text class="text_normal">
+      <textPath xlink:href="#Path_095" startOffset="0.5%" >|</textPath>
+      <textPath xlink:href="#Path_120" startOffset="00%" >(0)</textPath>
+      <textPath xlink:href="#Path_080" startOffset="01%"  stroke="blue" stroke-width="0.5px" >
+        - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ></textPath>
+      <textPath xlink:href="#Path_095" startOffset="30.5%" >|</textPath>
+      <textPath xlink:href="#Path_120" startOffset="30%" >(1)</textPath>
+      <textPath xlink:href="#Path_095" startOffset="45.5%" >|</textPath>
+      <textPath xlink:href="#Path_120" startOffset="45%" >(2)</textPath>
+      <textPath xlink:href="#Path_095" startOffset="50.5%" >|</textPath>
+      <textPath xlink:href="#Path_120" startOffset="50%" >(3)</textPath>
+      <textPath xlink:href="#Path_095" startOffset="62.5%" >|</textPath>
+      <textPath xlink:href="#Path_120" startOffset="62%" >(4)</textPath>
+    </text>
+  </g>
+
+  <g class="text_normal" transform="translate(400 130)">
+    <text>0: 0 .. 2  <tspan dy="-5">^</tspan> <tspan dy="5">32</tspan> - 1</text>
+    <text y="25">1: oldest <tspan style="font-weight:bold">active</tspan> xid (pg_stat_activity.backend_xmin)</text>
+    <text y="50">2: xmin of one row version</text>
+    <text y="75">3: xmax of the same row version</text>
+    <text y="100">4: jungest xid (txid_current)</text>
+  </g>
+
+</svg>
diff --git a/doc/src/sgml/postgres.sgml b/doc/src/sgml/postgres.sgml
index c41ce9499b..6254bf9376 100644
--- a/doc/src/sgml/postgres.sgml
+++ b/doc/src/sgml/postgres.sgml
@@ -60,6 +60,7 @@ break is not needed in a wider output rendering.
   </partintro>
 
   &start;
+  &architecture;
   &query;
   &advanced;
 
diff --git a/doc/src/sgml/query.sgml b/doc/src/sgml/query.sgml
index c0889743c4..870349780f 100644
--- a/doc/src/sgml/query.sgml
+++ b/doc/src/sgml/query.sgml
@@ -1,7 +1,7 @@
 <!-- doc/src/sgml/query.sgml -->
 
  <chapter id="tutorial-sql">
-  <title>The <acronym>SQL</acronym> Language</title>
+  <title>Basics of the <acronym>SQL</acronym> Language</title>
 
   <sect1 id="tutorial-sql-intro">
    <title>Introduction</title>
diff --git a/doc/src/sgml/start.sgml b/doc/src/sgml/start.sgml
index 5b73557835..b9184feb39 100644
--- a/doc/src/sgml/start.sgml
+++ b/doc/src/sgml/start.sgml
@@ -53,7 +53,7 @@

   <sect1 id="tutorial-arch">
-   <title>Architectural Fundamentals</title>
+   <title>Client/Server Model</title>
 
    <para>
     Before we proceed, you should understand the basic
@@ -65,37 +65,59 @@
 
    <para>
     In database jargon, <productname>PostgreSQL</productname> uses a
-    client/server model.  A <productname>PostgreSQL</productname>
+    client/server model. A <productname>PostgreSQL</productname>
     session consists of the following cooperating processes
     (programs):
+   </para>
 
-    <itemizedlist>
-     <listitem>
-      <para>
-       A server process, which manages the database files, accepts
-       connections to the database from client applications, and
-       performs database actions on behalf of the clients.  The
-       database server program is called
-       <filename>postgres</filename>.
-       <indexterm><primary>postgres</primary></indexterm>
-      </para>
-     </listitem>
+   <itemizedlist>
+    <listitem>
+     <para>
+      A process at the server site with the name
+      <glossterm linkend="glossary-postmaster">
+      postgres (outdated term: Postmaster)</glossterm>
+      <indexterm><primary>postgres</primary></indexterm>.
+      It accepts connection requests from client applications, starts
+      (<quote>forks</quote>) a new <glossterm linkend="glossary-backend">
+      Backend process</glossterm> for each of them, and passes
+      the connection to it. From that point on, the client and the new
+      <firstterm>Backend process</firstterm>
+      communicate directly without intervention by the original
+      <firstterm>postgres</firstterm> process. Thus, the
+      <firstterm>postgres</firstterm> process is always running, waiting
+      for new client connections, whereas clients and associated
+      <firstterm>Backend processes</firstterm> come and go.
+      (All of this is of course invisible to the user. We only mention it
+      here for completeness.)
+     </para>
+    </listitem>
 
-     <listitem>
-      <para>
-       The user's client (frontend) application that wants to perform
-       database operations.  Client applications can be very diverse
-       in nature:  a client could be a text-oriented tool, a graphical
-       application, a web server that accesses the database to
-       display web pages, or a specialized database maintenance tool.
-       Some client applications are supplied with the
-       <productname>PostgreSQL</productname> distribution; most are
-       developed by users.
-      </para>
-     </listitem>
+    <listitem>
+     <para>
+      A group of processes at the server site, the <glossterm
+      linkend="glossary-instance">instance</glossterm>, to which also the
+      <firstterm>postgres</firstterm> process belongs. Their duties are
+      handling of central, common database activities like file access,
+      vacuum, <glossterm linkend="glossary-checkpoint">checkpoints</glossterm>,
+      replication, and more. The mentioned <firstterm>Backend processes</firstterm>
+      delegate those actions to the <firstterm>instance</firstterm>.
+     </para>
+    </listitem>
 
-    </itemizedlist>
-   </para>
+    <listitem>
+     <para>
+      The user's client (frontend) application that wants to perform
+      database operations.  Client applications can be very diverse
+      in nature:  a client could be a text-oriented tool, a graphical
+      application, a web server that accesses the database to
+      display web pages, or a specialized database maintenance tool.
+      Some client applications are supplied with the
+      <productname>PostgreSQL</productname> distribution; most are
+      developed by users.
+     </para>
+    </listitem>
+
+   </itemizedlist>
 
    <para>
     As is typical of client/server applications, the client and the
@@ -106,18 +128,6 @@
     file name) on the database server machine.
    </para>
 
-   <para>
-    The <productname>PostgreSQL</productname> server can handle
-    multiple concurrent connections from clients.  To achieve this it
-    starts (<quote>forks</quote>) a new process for each connection.
-    From that point on, the client and the new server process
-    communicate without intervention by the original
-    <filename>postgres</filename> process.  Thus, the
-    master server process is always running, waiting for
-    client connections, whereas client and associated server processes
-    come and go.  (All of this is of course invisible to the user.  We
-    only mention it here for completeness.)
-   </para>
   </sect1>

---

From: Erik Rijkers <[email-masked]>
Date: Wed, 29 Apr 2020 17:35:22 +0200

On 2020-04-29 16:13, Jürgen Purtz wrote:
> Made some modifications in previous sub-chapters and in existing
> titles. Added some glossary entries.

> [0003-architecture.patch]

Hi Jürgen,

Here are again some suggested changes, up to line 600 (of the patch - 
that is around start of the new NVCC paragraph)

I may have repeated some thing you have already rejected (it was too 
much work to go back and check).  I am not a native speaker of english.

One general remark: in my humble opinion, you write too many capitalized 
words.  It's not really a problem but overall it's becomes bit too much. 
  But I have not marked these. perhaps some future iteration.

I'll probably read through the latter part of the patch later (probably 
tomorrow).

Thanks,

Erik Rijkers

they merely send requests to the server side and receives
they merely send requests to the server side and receive

is a group of tightly coupled other server side processes plus a
is a group of tightly coupled other server-side processes plus a

Client requests (SELECT, UPDATE, ...) usually leads to the
Client requests (SELECT, UPDATE, ...) usually lead to the

Because files are much larger than memory, it's likely that
Because files are often larger than memory, it's likely that

RAM is performed in units of complete pages, retaining their size and 
layout.
RAM is performed in units of complete pages.

Reading file pages is notedly slower than reading
Reading file pages is slower than reading

of the <firstterm>Backend processes</firstterm> has done the job those 
pages are available for all other
of the <firstterm>Backend processes</firstterm> has read pages into 
memory those pages are available for all other

they must be transferred back to disk. This is a two-step process.
they must be written back to disk. This is a two-step process.

Because of the sequential nature of this writing, it is much
Because of this writing is sequential, it is much

in an independent process. Nevertheless all
in an independent process. Nevertheless, all

huge I/O activities can block other processes significantly,
I/O activities can block other processes,

it starts periodically and acts only for a short period.
it starts periodically and is active only for a short period.

duty. As its name suggests, he has to create
duty. As its name suggests, it has to create

In consequence, after a <firstterm>Checkpoint</firstterm>
After a <firstterm>Checkpoint</firstterm>,

In correlation with data changes,
As a result of data changes,

text lines about serious and non-serious events which can happen
text lines about serious and less serious events which can happen

database contains many <glossterm 
linkend="glossary-schema">schema</glossterm>,
database contains many <glossterm 
linkend="glossary-schema">schemas</glossterm>,

belongs to a certain <firstterm>schema</firstterm>, they cannot
belongs to a single <firstterm>schema</firstterm>, they cannot

A <firstterm>Cluster</firstterm> is the outer frame for a
A <firstterm>Cluster</firstterm> is the outer container for a

<literal>postgres</literal> as a copy of
<literal>postgres</literal> is generated as a copy of

role of <literal>template0</literal> as the origin
role of <literal>template0</literal> as the pristine origin

are different objects and absolutely independent from each
are different objects and independent from each

complete <firstterm>cluster</firstterm>, independent from
<firstterm>cluster</firstterm>, independent from

anywhere in the file system. In many cases, the environment
somewhere in the file system. In many cases, the environment

some files, all of which are necessary to store long lasting
some files, all of which are necessary to store long-lasting

<firstterm>tablespaces</firstterm> itself.
<firstterm>tablespaces</firstterm> themselves.

<firstterm>Postgres</firstterm> (respectively 
<firstterm>Postmaster</firstterm>) process.
<firstterm>Postgres</firstterm> process (also known as 
<firstterm>Postmaster</firstterm>).

<title>MVCC</title>
<title>MVCC - Multiversion Concurrency Control</title>

The dabase must take a sensible decision to prevent the application
The database must take a sensible decision to prevent the application

# this sentence I just don't understand - can you please elucidate?
The database must take a sensible decision to prevent the application
from promising delivery of the single article to both clients.

---

From: Peter Eisentraut <[email-masked]>
Date: Wed, 29 Apr 2020 21:12:25 +0200

> Added some glossary entries.

I don't see this really as belonging into the tutorial.  The tutorial 
should be hands-on, how do you get started, how do you get some results.

Your material is more of an overview of the whole system.  What's a new 
user supposed to do with that?

-- 
Peter Eisentraut              http://www.2ndQuadrant.com/
PostgreSQL Development, 24x7 Support, Remote DBA, Training & Services

---

From: Jürgen Purtz <[email-masked]>
Date: Thu, 30 Apr 2020 14:31:10 +0200

> should be hands-on, how do you get started, how do you get some results.
Yes, the tutorial should be a short overview and give instructions how 
to start. IMO the first 4 sub-chapters fulfill this expectation. Indeed, 
the fifth (VACUUM) is extensive and offers many details.

During the inspection of the existing documentation I recognized that 
there are many details about VACUUM, AUTOVACUUM, all of their parameters 
as well as their behavior. But the information is spread across many 
pages: Automatic Vacuuming, Client Connection Defaults, Routine 
Vacuuming, Resource Consumption, VACUUM. Even for a person with some 
pre-knowledge it is hard to get an overview how this fits together and 
why things are solved in exactly this way. In the end we have very good 
descriptions of all details but I miss the 'big picture'. Therefore I 
summarized central aspects and tried to give an answer to the question 
'why is it done in this way?'. I do not dispute that the current version 
of the page is not adequate for beginners. But at some place we should 
have such a summary about vacuuming and freezing.

How to proceed?

- Remove the page and add a short paragraph to the MVCC page instead.

- Cut down the page to a tiny portion.

- Divide it into two parts: a) a short introduction and b) the rest 
after a statement like 'The following offers more details and parameters 
that are more interesting for an experienced user than for a beginner. 
You can easily skip it.'

> Your material is more of an overview of the whole system.  What's a 
> new user supposed to do with that?

When I dive into a new subject, I'm more interested in its architecture 
than in its details. We shall offer an overview about the major PG 
components and strategies to beginners.

--

Jürgen Purtz

---

From: Jürgen Purtz <[email-masked]>
Date: Tue, 2 Jun 2020 17:01:31 +0200

On 30.04.20 14:31, Jürgen Purtz wrote:
> to start. IMO the first 4 sub-chapters fulfill this expectation. 
> Indeed, the fifth (VACUUM) is extensive and offers many details.
>
> there are many details about VACUUM, AUTOVACUUM, all of their 
> parameters as well as their behavior. But the information is spread 
> across many pages: Automatic Vacuuming, Client Connection Defaults, 
> Routine Vacuuming, Resource Consumption, VACUUM. Even for a person 
> with some pre-knowledge it is hard to get an overview how this fits 
> together and why things are solved in exactly this way. In the end we 
> have very good descriptions of all details but I miss the 'big 
> picture'. Therefore I summarized central aspects and tried to give an 
> answer to the question 'why is it done in this way?'. I do not dispute 
> that the current version of the page is not adequate for beginners. 
> But at some place we should have such a summary about vacuuming and 
> freezing.
>
> How to proceed?
>
> after a statement like 'The following offers more details and 
> parameters that are more interesting for an experienced user than for 
> a beginner. You can easily skip it.'
>
>
> When I dive into a new subject, I'm more interested in its 
> architecture than in its details. We shall offer an overview about the 
> major PG components and strategies to beginners.
>
>
In comparison with to previous patch this one contains:

- Position and title changed to reflect its intention and importance.

- A <note> delimits VACUUM basics from details. This is done because I 
cannot find another suitable place for such a summarizing description.

- Three additional sub-chapters.

--

Jürgen Purtz

 
   <sect1 id="tutorial-advanced-intro">
    <title>Introduction</title>
diff --git a/doc/src/sgml/architecture.sgml b/doc/src/sgml/architecture.sgml
new file mode 100644
index 0000000000..1a2117f42a
--- /dev/null
+++ b/doc/src/sgml/architecture.sgml
@@ -0,0 +1,1549 @@
+<!-- doc/src/sgml/architecture.sgml -->
+
+ <chapter id="tutorial-architecture">
+  <title>Architectural and implementational Cornerstones</title>
+
+  <para>
+   Every DBMS implements basic strategies to achieve a fast and
+   robust system. This chapter provides an overview of what
+   techniques <productname>PostgreSQL</productname> uses to
+   reach this aim.
+  </para>
+
+  <sect1 id="tutorial-ram-proc-file">
+   <title>Collaboration of Processes, RAM, and Files</title>
+   <para>
+    As is a matter of course, in a client/server architecture
+    clients do not have direct access to the database. Instead,
+    they merely send requests to the server-side and receive
+    according information from there. In the case of
+    <productname>PostgreSQL</productname>, at the server-side
+    there is one process per client, the so-called
+    <glossterm linkend="glossary-backend">Backend process</glossterm>.
+    It acts in close cooperation with the
+    <glossterm linkend="glossary-instance">Instance</glossterm> which
+    is a group of tightly coupled other server-side processes plus a
+    <glossterm linkend="glossary-shared-memory">Shared Memory</glossterm>
+    area.
+   </para>
+
+   <para>
+    At start time, an instance is initiated by the
+    <glossterm linkend="glossary-postmaster">Postmaster</glossterm>
+    process.
+    It loads the configuration files, allocates the
+    <glossterm linkend="glossary-shared-memory">Shared Memory</glossterm>,
+    and starts the comprehensive network of processes:
+    <glossterm linkend="glossary-background-writer">Background Writer</glossterm>,
+    <glossterm linkend="glossary-checkpointer">Checkpointer</glossterm>,
+    <glossterm linkend="glossary-wal-writer">WAL Writer</glossterm>,
+    <glossterm linkend="glossary-wal-archiver">WAL Archiver</glossterm>,
+    <glossterm linkend="glossary-autovacuum">Autovacuum processes</glossterm>,
+    <glossterm linkend="glossary-stats-collector">Statistics Collector</glossterm>,
+    <glossterm linkend="glossary-logger">Logger</glossterm>, and more.
+    <xref linkend="tutorial-ram-proc-file-figure"/> visualizes
+    the main aspects of their collaboration.
+   </para>
+
+   <figure id="tutorial-ram-proc-file-figure">
+    <title>Architecture</title>
+    <mediaobject>
+     <imageobject role="html">
+      <!-- attribute 'width=..px' is necessary to keep font-size of SVG text
+           in correlation with font-size of surrounding HTML  -->
+      <imagedata fileref="images/ram-proc-file-raw.svg" format="SVG" width="900px" />
+     </imageobject>
+     <imageobject role="fo">
+      <!-- For PDF attribute 'width=100%' is necessary to keep complete SVG visible
+           on the page, which has a fixed width. Font sizes will be adopted.  -->
+      <imagedata fileref="images/ram-proc-file-raw.svg" format="SVG" width="100%" />
+     </imageobject>
+    </mediaobject>
+   </figure>
+
+   <para>
+    Whenever a client application tries to connect to a
+    <glossterm linkend="glossary-database">database</glossterm>,
+    this request is handled in a first step by the <firstterm>
+    Postgres process</firstterm>. It checks the authorization,
+    starts a new <firstterm>Backend process</firstterm>,
+    and instructs the client application to connect to it. All
+    further client requests go to this process and are handled
+    by it.
+   </para>
+
+   <para>
+    Client requests (SELECT, UPDATE, ...) usually lead to the
+    necessity to read or write some data. In a first attempt
+    the client's <firstterm>Backend process</firstterm> tries
+    to get the information out of <firstterm>Shared
+    Memory</firstterm>. This <firstterm>Shared
+    Memory</firstterm> is a mirror of parts of the
+    <glossterm linkend="glossary-heap">heap</glossterm> and
+    <glossterm linkend="glossary-index">index</glossterm> files.
+    Because files are often larger than memory, it's likely that
+    the desired information is not (completely) available
+    in the RAM. In this case the <firstterm>Backend process</firstterm>
+    must transfer additional file pages to
+    <firstterm>Shared Memory</firstterm>. Files are physically
+    organized in pages. Every transfer between files and
+    RAM is performed in units of complete pages. Such transfers
+    don't change the size or layout of pages.
+   </para>
+
+   <para>
+    Reading file pages is notedly slower than reading
+    RAM. This is the primary motivation for the existence of
+    <firstterm>Shared Memory</firstterm>. As soon as one
+    of the <firstterm>Backend processes</firstterm> has
+    read pages into memory, those pages are available for all
+    other <firstterm>Backend processes</firstterm> for direct
+    access in RAM.
+   </para>
+
+   <para>
+    <firstterm>Shared Memory</firstterm> is limited in size.
+    Sooner or later, it becomes necessary to overwrite old RAM
+    pages. As long as the content of such pages hasn't
+    changed, this is not a problem. But in
+    <firstterm>Shared Memory</firstterm> also write
+    actions take place
+    &mdash; performed by any of the <firstterm>Backend
+    processes</firstterm> (or an
+    <glossterm linkend="glossary-autovacuum">autovacuum process</glossterm>,
+    or other processes). Such modified pages are called
+    <firstterm>dirty pages</firstterm>.
+    Before <firstterm>dirty pages</firstterm> can be overwritten,
+    they must be written back to disk. This is a two-step process.
+   </para>
+
+   <para>
+    First, whenever the content of a page changes, a
+    <glossterm linkend="glossary-wal-record">WAL record</glossterm>
+    is created out
+    of the delta-information (difference between old and
+    new content) and stored in another area of the
+    <firstterm>Shared Memory</firstterm>. These
+    <firstterm>WAL records</firstterm> are read by the
+    <firstterm>WAL Writer</firstterm> process,
+    which runs in parallel to the <firstterm>Backend
+    processes</firstterm> and all other processes of
+    the <firstterm>Instance</firstterm>. It writes
+    the continuously arising <firstterm>WAL records</firstterm> to
+    the end of the current
+    <glossterm linkend="glossary-wal-record">WAL file</glossterm>.
+    Because this writing is sequential, it is much
+    faster than the more or less random access
+    to data files with <firstterm>heap</firstterm>
+    and <firstterm>index</firstterm> information.
+    As mentioned, this WAL-writing happens
+    in an independent process. Nevertheless, all
+    <firstterm>WAL records</firstterm> created out of one
+    <firstterm>dirty page</firstterm> must be transferred
+    to disk before the <firstterm>dirty page</firstterm>
+    itself can be transferred to disk.
+   </para>
+
+   <para>
+    Second, the transfer of <firstterm>dirty buffers</firstterm>
+    from <firstterm>Shared Memory</firstterm> to files must
+    take place. This is the primary duty of the
+    <firstterm>Background Writer</firstterm> process. Because
+    I/O activities can block other processes significantly,
+    it starts periodically and acts only for a short period.
+    Doing so, his expensive I/O activities are spread over
+    time, avoiding huge I/O peaks. Also, the <firstterm>
+    Checkpointer</firstterm> process transfers
+    <firstterm>dirty buffers</firstterm> to files &mdash;
+    see next paragraph.
+   </para>
+
+   <para>
+    The <firstterm>Checkpointer</firstterm> has a special
+    duty. As its name suggests, it has to create
+    <firstterm>Checkpoints</firstterm>. Such a
+    <glossterm linkend="glossary-checkpoint">Checkpoint</glossterm>
+    is a point in time when all older <firstterm>dirty buffers</firstterm>,
+    all older <firstterm>WAL records</firstterm>, and
+    finally a special <firstterm>Checkpoint record</firstterm>
+    have been written and flushed to disk.
+    After a <firstterm>Checkpoint</firstterm>,
+    data files and <firstterm>WAL files</firstterm> are in sync.
+    In case of a recovery (after a crash of the instance)
+    it is known that the information of all
+    <firstterm>WAL records</firstterm> preceding
+    the last <firstterm>Checkpoint record</firstterm>
+    is already integrated into the data files. This
+    speeds up a possibly occurring recovery.
+   </para>
+
+   <para>
+    As a result of data changes,
+    <firstterm>WAL records</firstterm> arise and get written
+    to <firstterm>WAL files</firstterm>.
+    Those <firstterm>WAL files</firstterm> &mdash; in combination with
+    a previously taken <firstterm>Base Backup</firstterm> &mdash;
+    are necessary to restore a database after a crash of the
+    disk, where data files have been stored. Therefore it is
+    recommended to transfer a copy of the <firstterm>
+    WAL files</firstterm>
+    to a second, independent place. The purpose of the
+    <firstterm>WAL Archiver</firstterm> process is to perform
+    this copy action.
+   </para>
+
+   <para>
+    The <glossterm linkend="glossary-stats-collector">Stats Collector</glossterm>
+    collects counters about accesses to <firstterm>SQL
+    objects</firstterm> like tables, rows, indexes, pages,
+    and more. It stores the obtained information in system
+    tables.
+   </para>
+
+   <para>
+    The <glossterm linkend="glossary-logger">Logger</glossterm> writes
+    text lines about serious and less serious events which can happen
+    during database access, e.g., wrong password, no permission,
+    long-running queries, ... .
+   </para>
+
+  </sect1>
+
+  <sect1 id="tutorial-cluster-db-schema">
+   <title>The logical Perspective: Cluster, Database, Schema</title>
+
+   <para>
+<!-- TODO: Link to cluster -->
+    On a <glossterm linkend="glossary-server">Server</glossterm>
+    exists one or more <glossterm linkend="glossary-instance">Cluster</glossterm>,
+    each of them contains three or more
+    <glossterm linkend="glossary-database">databases</glossterm>, each
+    database contains many <glossterm linkend="glossary-schema">schemas</glossterm>,
+    a schema contains <glossterm linkend="glossary-table">tables</glossterm>,
+    <glossterm linkend="glossary-view">views</glossterm>, and a lot of other objects.
+    Each <firstterm>table</firstterm> or <firstterm>view</firstterm>
+    belongs to a single <firstterm>schema</firstterm>; they cannot
+    belong to another <firstterm>schema</firstterm>. The same is
+    true for the schema/database and database/cluster relation.
+    <xref linkend="tutorial-cluster-db-schema-figure"/> visualizes
+    this hierarchy.
+   </para>
+
+   <figure id="tutorial-cluster-db-schema-figure">
+    <title>Cluster, Database, Schema</title>
+    <mediaobject>
+     <imageobject role="html">
+      <!-- attribute 'width=..px' is necessary to keep font-size of SVG text
+           in correlation with font-size of surrounding HTML  -->
+      <imagedata fileref="images/cluster-db-schema-raw.svg" format="SVG" width="900px" />
+     </imageobject>
+     <imageobject role="fo">
+      <!-- For PDF attribute 'width=100%' is necessary to keep complete SVG visible
+           on the page, which has a fixed width. Font sizes will be adopted.  -->
+      <imagedata fileref="images/cluster-db-schema-raw.svg" format="SVG" width="100%" />
+     </imageobject>
+    </mediaobject>
+   </figure>
+
+   <para>
+    A <firstterm>Cluster</firstterm> is the outer container for a
+    collection of databases. Clusters are created by the command
+    <xref linkend="app-initdb"/>.
+   </para>
+
+   <para>
+    <literal>template0</literal> is the very first
+    <firstterm>database</firstterm> of any
+    <firstterm>cluster</firstterm>. C-routines create
+    <literal>template0</literal> during the initialization phase of
+    the <firstterm>cluster</firstterm>.
+    In a second step, <literal>template1</literal> is generated
+    as a copy of <literal>template0</literal>, and finally
+    <literal>postgres</literal> is generated as a copy of
+    <literal>template1</literal>. All other
+    <glossterm linkend="app-createdb">new databases</glossterm>
+    of this <firstterm>cluster</firstterm>,
+    such as <literal>my_db</literal>, are also copied from
+    <literal>template1</literal>. Due to the unique
+    role of <literal>template0</literal> as the pristine origin
+    of all other <firstterm>databases</firstterm>, no client
+    can connect to it.
+   </para>
+
+   <para>
+    Every database contains <glossterm linkend="glossary-schema">
+    schemas</glossterm>, and
+    <firstterm>schemas</firstterm> contain the other
+    <glossterm linkend="glossary-sql-object">SQL Objects</glossterm>.
+    <firstterm>Schemas</firstterm> are namespaces for
+    their <firstterm>SQL objects</firstterm> and ensure &mdash; with one
+    exception &mdash; that within their scope names are used only once across all
+    types of <firstterm>SQL objects</firstterm>. E.g., it is not possible
+    to have a table <literal>employee</literal> and a view
+    <literal>employee</literal> within the same
+    <firstterm>schema</firstterm>. But it is possible to have
+    two tables <literal>employee</literal> in different
+    <firstterm>schemas</firstterm>. In this case, the two tables
+    are separate objects and independent of each
+    other. The only exception to this cross-type uniqueness is that
+    <glossterm linkend="glossary-unique-constraint">unique constraints
+    </glossterm> and the according <firstterm>unique index</firstterm>
+    use the same name.
+   </para>
+
+   <para>
+    Some <firstterm>schemas</firstterm> are predefined.
+    <literal>public</literal> acts as the default
+    <firstterm>schema</firstterm> and contains all such
+    <firstterm>SQL objects</firstterm>, which are created
+    within <literal>public</literal> or without using any schema
+    name. <literal>public</literal> shall not contain user-defined
+    <firstterm>SQL objects</firstterm>. Instead, it is recommended to
+    create a separate <firstterm>schema</firstterm> that
+    holds individual objects like application-specific tables or
+    views. <literal>pg_catalog</literal> is a schema for all tables
+    and views of the <glossterm linkend="glossary-system-catalog">
+    System Catalog</glossterm>.
+    <literal>information_schema</literal> is a schema for several
+    tables and views of the <firstterm>System Catalog</firstterm>
+    in a way that conforms to the SQL standard.
+   </para>
+
+   <para>
+    There are a lot of different <firstterm>SQL object</firstterm>
+    types: <firstterm>database, schema, table, view, materialized
+    view, index, constraint, sequence, function, procedure,
+    trigger, role, data type, operator, tablespace, extension,
+    foreign data wrapper</firstterm>, and more. A few of them, the
+    <firstterm>Global SQL Objects</firstterm>,
+    are outside of the strict hierarchy:
+    All database names, all tablespace names, and all role names
+    are automatically known and available throughout the
+    <firstterm>cluster</firstterm>, independent from
+    the database or schema in which they where defined originally.
+    <xref linkend="tutorial-internal-objects-hierarchy-figure"/>
+    shows the relation between the object types.
+   </para>
+
+   <figure id="tutorial-internal-objects-hierarchy-figure">
+    <title>Hierarchy of Internal Objects</title>
+    <mediaobject>
+     <imageobject role="html">
+      <!-- attribute 'width=..px' is necessary to keep font-size of SVG text
+           in correlation with font-size of surrounding HTML  -->
+      <imagedata fileref="images/internal-objects-hierarchy-raw.svg" format="SVG" width="720px" />
+     </imageobject>
+     <imageobject role="fo">
+      <!-- For PDF attribute 'width=100%' is necessary to keep complete SVG visible
+           on the page, which has a fixed width. Font sizes will be adopted.  -->
+      <imagedata fileref="images/internal-objects-hierarchy-raw.svg" format="SVG" width="100%" />
+     </imageobject>
+    </mediaobject>
+   </figure>
+
+  </sect1>
+
+  <sect1 id="tutorial-directories">
+   <title>The physical Perspective: Directories and Files</title>
+
+   <para>
+    <productname>PostgreSQL</productname> organizes long-lasting
+    data as well as volatile state information about transactions
+    or replication actions in the file system. Every
+    <firstterm>Cluster</firstterm> has its root directory
+    somewhere in the file system. In many cases, the environment
+    variable <literal>PGDATA</literal> points to this directory.
+    The example of the survey shown in
+    <xref linkend="tutorial-directories-figure"/> uses
+    <literal>data</literal> as the name of this root directory.
+   </para>
+
+   <figure id="tutorial-directories-figure">
+    <title>Directory Structure</title>
+    <mediaobject>
+     <imageobject role="html">
+      <!-- attribute 'width=..px' is necessary to keep font-size of SVG text
+           in correlation with font-size of surrounding HTML  -->
+      <imagedata fileref="images/directories-raw.svg" format="SVG" width="900px" />
+     </imageobject>
+     <imageobject role="fo">
+      <!-- For PDF attribute 'width=100%' is necessary to keep complete SVG visible
+           on the page, which has a fixed width. Font sizes will be adopted.  -->
+      <imagedata fileref="images/directories-raw.svg" format="SVG" width="100%" />
+     </imageobject>
+    </mediaobject>
+   </figure>
+
+   <para>
+    <literal>data</literal> contains many subdirectories and
+    some files, all of which are necessary to store long-lasting
+    as well as temporary data. The following paragraphs
+    describe the files and subdirectories in
+    <literal>data</literal>.
+   </para>
+
+   <para>
+    <literal>base</literal> is a subdirectory in which one
+    subdirectory per <firstterm>database</firstterm> exists.
+    The names of those subdirectories consist of numbers.
+    These are the internal
+    <firstterm>Object Identifiers (OID)</firstterm>, which are
+    numbers to identify the database definition in the
+    <glossterm linkend="glossary-system-catalog">System Catalog</glossterm>.
+   </para>
+
+   <para>
+    Within the <firstterm>database</firstterm>-specific
+    subdirectories, there are many files: one or more for
+    every table and every index to store <firstterm>heap</firstterm>
+    and <firstterm>index</firstterm> data. Those files are
+    accompanied by files for the
+    <link linkend="storage-fsm">Free Space Maps</link>
+    (extension <literal>_fsm</literal>) and
+    <link linkend="storage-vm">Visibility Maps</link>
+    (extension <literal>_vm</literal>), which contain optimization information.
+   </para>
+
+   <para>
+    Another prominent subdirectory is <literal>global</literal>.
+    In analogy to the <firstterm>database</firstterm>-specific
+    subdirectories, there are files containing information about
+    <glossterm linkend="glossary-sql-object">Global SQL objects</glossterm>.
+    One type of such <firstterm>Global Objects</firstterm> are
+    <firstterm>tablespaces</firstterm>. In
+    <literal>global</literal> there is information about
+    the <firstterm>tablespaces</firstterm>, not the
+    <firstterm>tablespaces</firstterm> themselves.
+   </para>
+
+   <para>
+    The subdirectory <literal>pg_wal</literal> contains the
+    <glossterm linkend="glossary-wal-file">WAL files</glossterm>.
+    They arise and grow parallel to data changes in the
+    <firstterm>cluster</firstterm> and remain alive as long as
+    they are required for recovery, archiving, or replication.
+   </para>
+
+   <para>
+    The subdirectory <literal>pg_xact</literal> contains
+    information about the status of each transaction
+    (IN_PROGRESS, COMMITTED, ABORTED, or SUB_COMMITTED).
+   </para>
+
+   <para>
+    In <literal>pg_tblspc</literal>, there are symbolic links
+    that point to directories containing such<firstterm>
+    SQL objects</firstterm> that are created within
+    <firstterm>tablespaces</firstterm>.
+   </para>
+
+   <para>
+    In the root directory <literal>data</literal>
+    there are also some files. In many cases, the configuration
+    files of this <firstterm>cluster</firstterm> are stored
+    here. As long as the <firstterm>instance</firstterm>
+    is up and running, the file
+    <literal>postmaster.pid</literal> exists here
+    and contains the ID (pid) of the
+    <firstterm>Postmaster</firstterm> process which
+    has started the instance.
+   </para>
+
+   <para>
+    For more details about the physical implementation
+    of database objects, see <xref linkend="storage"/>.
+   </para>
+
+  </sect1>
+
+  <sect1 id="tutorial-mvcc">
+   <title>MVCC &mdash; Multiversion Concurrency Control</title>
+
+   <para>
+    In most cases, <productname>PostgreSQL</productname> based applications
+    support many clients at the same time. Therefore, it is necessary to
+    protect concurrently running requests from unwanted overwriting
+    of other's data as well as from reading inconsistent data. Imagine an
+    online shop offering the last copy of an article. Two clients show the
+    article at their user interface. After a while, but at the same time,
+    both users decide to put it to their shopping cart or even to buy it.
+    Both have seen the article, but only one can be allowed to get it.
+    The database must bring the two requests in a row, permit the access
+    to one of them, block the other, and inform this one about the
+    situation that the data was changed by a different process.
+   </para>
+
+   <para>
+    A first approach to implement protections against concurrent
+    accesses to the same data may be the locking of critical
+    rows. There are two main categories of such techniques:
+    <emphasis>Optimistic Concurrency Control</emphasis> (OCC)
+    and <emphasis>Two Phase Locking</emphasis> (2PL).
+    <productname>PostgreSQL</productname> implements the more
+    sophisticated technique <firstterm>Multiversion Concurrency
+    Control</firstterm> (MVCC). The crucial advantage of MVCC
+    over other technologies gets evident in multiuser OLTP
+    environments with a massive number of concurrent write
+    actions. There, MVCC generally performs better than solutions
+    using locks. In a <productname>PostgreSQL</productname>
+    database reading never blocks writing and writing never
+    blocks reading, even in the strictest level of transaction
+    isolation.
+   </para>
+
+   <para>
+    Instead of locking rows, the <firstterm>MVCC</firstterm> technique creates
+    a new version of the same row when any data-change takes place. To
+    distinguish between these versions as well as to track the timeline
+    of the row, each of the versions contains, in addition to their user-defined
+    columns, two special system columns, which are not visible
+    for the usual <command>SELECT * FROM ...</command> command.
+    The column <literal>xmin</literal> contains the transaction ID (xid)
+    of the transaction, which creates this version of the row. Accordingly,
+    <literal>xmax</literal> contains the xid of the transaction, which has
+    deleted this version, respectively a zero, if the version is not
+    deleted. You can read both with the command
+    <command>SELECT xmin, xmax, * FROM ... </command>.
+   </para>
+
+   <para>
+    When we speak about transaction IDs, you need to know that xids are like
+    sequences. Every new transaction receives the next number as its ID.
+    Therefore, this flow of xids represents the flow of transaction
+    start events over time. But keep in mind that xids are independent of
+    any time measurement &mdash; in milliseconds or whatever. If you dive
+    deeper into <productname>PostgreSQL</productname>, you will recognize
+    parameters with names such as 'xxx_age'. Despite their names,
+    these '_age' parameters do not specify a period of time but represent
+    a certain number of transactions, e.g., 100 million.
+   </para>
+
+   <para>
+    Please note that the description in this chapter simplifies the situation
+    by omitting details. When many transactions are running simultaneously,
+    things can get very complicated. Sometimes they get aborted via
+    ROLLBACK immediately or after a lot of other activities, sometimes
+    a single row is involved in more than one transaction, sometimes
+    a client crashes, sometimes the sequence of xids restarts
+    from zero, ... . Therefore, every version of a row contains more
+    system columns and flags, not only <literal>xmin</literal>
+    and <literal>xmax</literal>.
+   </para>
+
+   <para>
+    So, what's going on in detail when write accesses take place?
+    <xref linkend="tutorial-mvcc-figure"/> shows details concerning
+    <literal>xmin</literal>, <literal>xmax</literal>, and user data.
+   </para>
+
+   <figure id="tutorial-mvcc-figure">
+    <title>Multiversion Concurrency Control</title>
+    <mediaobject>
+     <imageobject role="html">
+      <imagedata fileref="images/mvcc-raw.svg" format="SVG" width="900px" />
+     </imageobject>
+     <imageobject role="fo">
+      <!-- For PDF attribute 'width=100%' is necessary to keep complete SVG visible
+           on the page, which has a fixed width. Font sizes will be adopted.  -->
+      <imagedata fileref="images/mvcc-raw.svg" format="SVG" width="100%" />
+     </imageobject>
+    </mediaobject>
+   </figure>
+
+   <para>
+    An <command>INSERT</command> command creates the first
+    version of a row. Besides its user data <literal>'x'</literal>,
+    this version contains the ID of the creating transaction
+    <literal>123</literal> in <literal>xmin</literal> and
+    <literal>0</literal> in <literal>xmax</literal>.
+    <literal>xmin</literal> indicates that the version
+    exists since transaction <literal>123</literal> and
+    <literal>xmax</literal> that it is currently not deleted.
+   </para>
+
+   <para>
+    Somewhat later, transaction <literal>135</literal>
+    executes an <command>UPDATE</command> of this row by
+    changing the user data from <literal>'x'</literal> to
+    <literal>'y'</literal>. According to the MVCC principles,
+    the data in the old version of the row does not change!
+    The value <literal>'x'</literal> keeps as it was before.
+    Only <literal>xmax</literal> changes to <literal>135</literal>.
+    Now, this version is treated as valid exclusively for
+    transactions with xids from <literal>123</literal> to
+    <literal>134</literal>. As a substitute for the non-occurring
+    data change in the old version, the <command>UPDATE</command>
+    creates a new version of the row with its xid in
+    <literal>xmin</literal>, <literal>0</literal> in
+    <literal>xmax</literal>, and <literal>'y'</literal> in the
+    user data (plus all the other user data from the old version).
+    This version is now valid for all coming transactions.
+   </para>
+
+   <para>
+    All subsequent <command>UPDATE</command> commands behave
+    in the same way as the first one: they put their xid to
+    <literal>xmax</literal> of the current version, create
+    the next version with their xid in <literal>xmin</literal>,
+    <literal>0</literal> in <literal>xmax</literal>, and the
+    new user data.
+   </para>
+
+   <para>
+    Finally, a row may be deleted by a <command>DELETE</command>
+    command. Even in this case, all versions of the row keep as
+    before. Nothing is thrown away so far! Only <literal>xmax</literal>
+    of the last version changes to the xid of the <command>DELETE</command>
+    transaction, which indicates that it is only valid for
+    transactions with xids older than its own (from
+    <literal>142</literal> to <literal>820</literal> in this
+    example).
+   </para>
+
+   <para>
+    In summary, the MVCC technology creates more and more versions
+    of the same row in the table's heap file and leaves them there,
+    even with a <command>DELETE</command> command. The youngest
+    version is relevant for all future transactions. But the
+    system must also preserve some of the older ones for a
+    certain amount of time because the possiblility exists that
+    they are or could become relevant for any of the pending
+    transactions. Over time, also the older ones get out of scope
+    for ALL transactions and therefore become unnecessary.
+    Nevertheless, they exist physically on the disk and occupy
+   space.
+   </para>
+
+   <para>
+    Please keep in mind:
+   </para>
+   <itemizedlist>
+
+    <listitem>
+     <simpara>
+      <literal>xmin</literal> and <literal>xmax</literal> indicate the range from where to where
+      row versions are valid (visible) for transactions.
+      This range doesn't imply any direct temporal meaning;
+      the sequence of xids reflects only the sequence of
+      transaction begin events. As
+      xids grow, old row versions get out of scope over time.
+      If an old row version is no longer valid for ALL existing
+      transactions, it's called <firstterm>dead</firstterm>. The
+      space occupied by the sum of all dead row versions is
+      called <firstterm>bloat</firstterm>.
+     </simpara>
+    </listitem>
+
+    <listitem>
+     <simpara>
+      Internally, an <command>UPDATE</command> command acts in the
+      same way as a <command>DELETE</command> command, followed by
+      an <command>INSERT</command> command.
+     </simpara>
+    </listitem>
+
+    <listitem>
+     <simpara>
+      Nothing gets wiped away &mdash; with the consequence that the database
+      occupies more and more disk space. It is obvious that
+      this behavior has to be automatically corrected in some
+      way. The next chapter explains how AUTOVACUUM fulfills
+      this task.
+     </simpara>
+    </listitem>
+
+   </itemizedlist>
+
+  </sect1>
+
+  <sect1 id="tutorial-vacuum">
+   <title>Vacuum</title>
+
+   <para>
+    As we have seen in the previous chapter, the database tends to occupy
+    more and more disk space, the <firstterm>bloat</firstterm>.
+    This chapter explains how the SQL command
+    <firstterm>VACUUM</firstterm> and the automatically running
+    <firstterm>AUTOVACUUM</firstterm> processes clear the situation
+    by eliminating <firstterm>bloat</firstterm>.
+   </para>
+
+   <note>
+    <para>
+     <firstterm>AUTOVACUUM</firstterm> runs automatically by
+     default. Its default parameters as well as such for
+     <firstterm>VACUUM</firstterm> fits well for most standard
+     situations. Therefore a novice database manager can
+     easily skip the rest of this chapter, which explains
+     a lot of details.
+    </para>
+   </note>
+
+   <para>
+    Client processes can issue the SQL command VACUUM at arbitrary
+    points in time. DBAs do this when they recognize special situations,
+    or they start it in batch jobs, which run periodically.
+    AUTOVACUUM processes run as part of the
+    <link linkend="glossary-instance">Instance</link> at the server.
+    There is a constantly running AUTOVACUUM daemon. He permanently
+    controls the state of all databases based on values that are
+    collected by the <link linkend="glossary-stats-collector">
+    Statistics Collector</link> and starts
+    AUTOVACUUM processes whenever he detects certain situations.
+    Thus, it's a dynamic behavior of <productname>PostgreSQL</productname>
+    with the intention to tidy up &mdash; not always, but whenever it
+    is appropriate.
+   </para>
+
+   <para>
+    VACUUM, as well as AUTOVACUUM, don't just eliminate bloat.
+    They perform additional tasks for minimizing future
+    I/O activities of themselves as well as of other processes.
+    This extra work can be done in a very efficient way
+    since in most cases the expensive physical access to pages
+    has taken place anyway to eliminate bloat.
+    The additional operations are:
+   </para>
+
+   <itemizedlist>
+
+    <listitem>
+     <simpara>
+      <firstterm>Freeze</firstterm>: Mark the youngest row version
+      as frozen. This means that the version
+      is always treated as valid (visible) independent from
+      the <firstterm>wraparound problematic</firstterm> (see below).
+     </simpara>
+    </listitem>
+
+    <listitem>
+     <simpara>
+      <firstterm>Visibility Map</firstterm> and
+      <firstterm>Free Space Map</firstterm>: Log information about
+      the state of the handled pages in two additional files, the
+      Visibility Map and the Free Space Map.
+     </simpara>
+    </listitem>
+
+    <listitem>
+     <simpara>
+      <emphasis>Statistics</emphasis>: Collect statistics about the
+      number of rows per table, the distribution of values, and so on,
+      as the basis for query planner's decision making.
+     </simpara>
+    </listitem>
+
+   </itemizedlist>
+
+   <para>
+    The eagerness &mdash; you can call it 'aggressivity' &mdash; of the
+    operations <emphasis>eliminating bloat</emphasis> and
+    <emphasis>freeze</emphasis> is controlled by configuration
+    parameters, runtime flags, and in extreme situations by
+    themselves. Because vacuum operations typically are I/O
+    intensive, which can hinder other activities, AUTOVACUUM
+    avoids performing many vacuum operations in bulk. Instead,
+    it carries out many small actions with time gaps in between.
+    The SQL command VACUUM runs immediately without any
+    time gaps.
+   </para>
+
+   <bridgehead renderas="sect2">Eliminate Bloat</bridgehead>
+
+   <para>
+    To determine which of the row versions are superfluous, the
+    elimination operation must evaluate xmax against several criteria
+    which all must apply:
+   </para>
+   <itemizedlist>
+
+    <listitem>
+     <simpara>
+      xmax must be different from zero because a value of zero
+      indicates that the row version is still valid.
+     </simpara>
+    </listitem>
+
+    <listitem>
+     <simpara>
+      xmax must contain an xid which is older than the oldest xid of all
+      currently running transactions (min(pg_stat_activity.backend_xmin)).
+      This criterion guarantees that no existing or upcoming transaction
+      will have read or write access to this row version.
+     </simpara>
+    </listitem>
+
+    <listitem>
+     <simpara>
+      The transaction of xmax must be committed. If it was rollback-ed,
+      this row version is treated as valid.
+     </simpara>
+    </listitem>
+
+    <listitem>
+     <simpara>
+      If there is the situation that the row version is part of
+      multiple transactions, special care and some more actions
+      must be taken, see: <xref linkend="vacuum-for-multixact-wraparound"/>.
+     </simpara>
+    </listitem>
+
+   </itemizedlist>
+
+   <para>
+    After the vacuum operation detects a superfluous row version, it
+    marks its space as free for future use of writing
+    actions. Only in rare situations (or in the case of VACUUM FULL),
+    this space is released to the operating system. In most cases,
+    it keeps occupied by PostgreSQL and will be used by future
+    <command>INSERT</command> or <command>UPDATE</command>
+    commands concerning this row or a completely different one.
+   </para>
+
+   <para>
+    Which actions start the elimination of bloat?
+
+    <itemizedlist>
+
+     <listitem>
+      <simpara>
+       When a client issues the SQL command VACUUM in its default format,
+       i.e., without any option. To boost performance, in this and the
+       next case VACUUM does not read and act on all pages of the heap.
+       The Visibility Map, which is very compact and therefore has a small
+       size, contains information about pages, where bloat-candidates might
+       be found. Only such pages are processed.
+      </simpara>
+     </listitem>
+
+     <listitem>
+      <simpara>
+       When a client issues the SQL command VACUUM with the option
+       FREEZE. (In this case, it undertakes much more actions, see
+       <link linkend="tutorial-freeze">Freeze Row Versions</link>.)
+      </simpara>
+     </listitem>
+
+     <listitem>
+      <simpara>
+       When a client issues the SQL command VACUUM with the option FULL.
+       Also, in this mode, the bloat disappears, but the used strategy
+       is very different: In this case, the complete table is copied
+       to a different file skipping all outdated row versions. This
+       leads to a significant reduction of used disk space because
+       the new file contains only the actual data. The old file
+       is deleted.
+      </simpara>
+     </listitem>
+
+     <listitem>
+      <simpara>
+       When an AUTOVACUUM process acts. For optimization
+       purposes, he considers the Visibility Map in the same way as
+       VACUUM. Additionally, he ignores tables with few modifications;
+       see <xref linkend="guc-autovacuum-vacuum-threshold"/>,
+       which defaults to 50 rows and
+       <xref linkend="guc-autovacuum-vacuum-scale-factor"/>,
+       which defaults to 20%.
+      </simpara>
+     </listitem>
+
+    </itemizedlist>
+   </para>
+
+   <para>
+    This logic only applies to row versions of the heap. Index entries
+    don't use xmin/xmax. Nevertheless, such index entries, which would
+    lead to outdated row versions, are released accordingly.
+    (??? more explanations ???)
+   </para>
+
+   <para>
+    The above descriptions omit the fact that xids on a real computer
+    have a limited size. They count up in the same way as sequences, and after
+    a certain number of new transactions they are forced to restart
+    from the beginning, which is called <firstterm>wraparound</firstterm>.
+    Therefore the terms 'old transaction' / 'young transaction' does
+    not always correlate with low / hight values of xids. Near to the
+    wraparound point, there are cases where xmin has a higher value
+    than xmax, although their meaning is said to be older than xmax.
+   </para>
+
+   <figure id="tutorial-wraparound-figure">
+    <title>Cyclic usage of XIDs</title>
+    <mediaobject>
+     <imageobject role="html">
+      <!-- attribute 'width=..px' is necessary to keep font-size of SVG text
+           in correlation with font-size of surrounding HTML  -->
+      <imagedata fileref="images/wraparound-raw.svg" format="SVG" width="850px" />
+     </imageobject>
+     <imageobject role="fo">
+      <!-- For PDF attribute 'width=100%' is necessary to keep complete SVG visible
+           on the page, which has a fixed width. Font sizes will be adopted.  -->
+      <imagedata fileref="images/wraparound-raw.svg" format="SVG" width="100%" />
+     </imageobject>
+    </mediaobject>
+   </figure>
+
+   <bridgehead renderas="sect2" id="tutorial-freeze">Freeze Row Versions</bridgehead>
+
+   <para>
+    The use of a limited range of IDs for transactions leads
+    to the necessity to restart the sequence sooner or later.
+    This does not only have the rare consequence previously
+    described that sometimes xmin is huger than xmax. The far
+    more critical problem is that whenever the system has
+    to evaluate a WHERE condition, it must decide which row
+    versions are valid (visible) from the perspective of the
+    transaction of this query. If a wraparound couldn't happen,
+    this decision would be relatively easy: the xid
+    must be between xmin and xmax, and the corresponding
+    transactions of xmin and xmax must be committed. However,
+    PostgreSQL has to consider the possibility of wraparounds.
+    Therefore the decision becomes more complex. The general
+    idea of the solution is to use the 'between xmin and xmax'
+    comparison only during the youngest period of the row
+    versions lifetime and afterward replace it with a
+   'valid forever' flag in its header.
+   </para>
+
+   <itemizedlist>
+
+    <listitem>
+     <simpara>
+      In a first step, PostgreSQL divides the complete range of
+      possible xids into two halves with the two split-points
+      'txid_current' and 'txid_current + 2^31'. The half behind
+      'txid_current' is considered to represent xids of the
+      'past' and the half ahead of 'txid_current' those of the
+      'future'. Those of the 'past' are valid (visible) and those
+      of the 'future' not.
+     </simpara>
+    </listitem>
+
+    <listitem>
+     <simpara>
+      With each newly created transaction the two split-points
+      move forward. When 'txid_current + 2^31' would reach a
+      row version with xmin equal to that value, it would
+      immediately jump from 'past' to 'future' and would be
+      no longer visible!
+     </simpara>
+    </listitem>
+
+    <listitem>
+     <simpara>
+      To avoid this unacceptable extinction of data, the vacuum
+      operation <firstterm>freeze</firstterm> clears the situation
+      long before the split-point is reached. It sets a flag
+      in the header of the row version, which completely eliminates
+      the future use of xmin/xmax and indicates
+      that the version is valid not only in the 'past'-half
+      but also in the 'future'-half as well as in all coming
+      <glossterm linkend="glossary-xid">epochs</glossterm>.
+     </simpara>
+    </listitem>
+   </itemizedlist>
+
+   <para>
+    Which row versions can be frozen by the vacuum operation?
+    Again, several criteria must be checked, and all must be met.
+
+    <itemizedlist>
+
+     <listitem>
+      <simpara>
+       xmax must be zero because only non-deleted rows can be
+       visible 'forever'.
+      </simpara>
+     </listitem>
+
+     <listitem>
+      <simpara>
+       xmin must be older than all currently existing transactions.
+       This guarantees that no existing transaction can modify or
+       delete the version.
+      </simpara>
+     </listitem>
+
+     <listitem>
+      <simpara>
+       The transaction of xmin must be committed.
+      </simpara>
+     </listitem>
+    </itemizedlist>
+   </para>
+
+   <para>
+    At what point in time the freeze operation will take place?
+
+    <itemizedlist>
+     <listitem>
+      <simpara>
+       When a client issues the SQL command VACUUM with its
+       FREEZE option. In this case, all such pages are
+       processed that are marked in the Visibility Map
+       to potentially have unfrozen rows.
+      </simpara>
+     </listitem>
+     <listitem>
+      <simpara>
+       When a client issues the SQL command VACUUM without any
+       option but finds that there are xids older than
+       <xref linkend="guc-vacuum-freeze-table-age"/>
+       (default: 150 million) minus
+       <xref linkend="guc-vacuum-freeze-min-age"/>
+       (default: 50 million).
+       As before, all such pages are processed that are
+       marked in the Visibility Map to potentially have unfrozen
+       rows.
+      </simpara>
+     </listitem>
+     <listitem>
+      <simpara>
+       When an AUTOVACUUM process runs. Such a process acts
+       in one of two modes:
+      </simpara>
+
+      <itemizedlist>
+       <listitem>
+        <simpara>
+         In the <emphasis>normal mode</emphasis>, he skips
+         pages with row versions that are younger than
+         <xref linkend="guc-vacuum-freeze-min-age"/>
+         (default: 50 million) and works only on pages where
+         all xids are older. The skipping of jung xids prevents
+         work on such pages, which are likely to be changed
+         by one of the future SQL commands.
+        </simpara>
+       </listitem>
+       <listitem>
+        <simpara>
+         The process switches
+         to an <emphasis>aggressive mode</emphasis> if he recognizes
+         that for the processed table their oldest xid exceeds
+         <xref linkend="guc-autovacuum-freeze-max-age"/>
+         (default: 200 million). The value of the oldest unfrozen
+         xid is stored per table in <emphasis>pg_class.relfrozenxid</emphasis>.
+         In this <emphasis>aggressive mode</emphasis> AUTOVACUUM
+         processes all such pages of the selected table that are marked
+         in the Visibility Map to potentially have bloat or unfrozen rows.
+        </simpara>
+       </listitem>
+
+      </itemizedlist>
+     </listitem>
+    </itemizedlist>
+   </para>
+
+   <para>
+    In the first two cases and with autovacuum in
+    <emphasis>aggressive mode</emphasis>, the system knowns
+    to which value the oldest unfrozen xid has moved forward and
+    logs the value in <emphasis>pg_class.relfrozenxid</emphasis>.
+    The distance between this value and the 'txid_current' split
+    point becomes smaller, and the distance to 'txid_current + 2^31'
+    larger than before.
+   </para>
+
+   <figure id="tutorial-freeze-figure">
+    <title>Freeze</title>
+    <mediaobject>
+     <imageobject role="html">
+      <!-- attribute 'width=..px' is necessary to keep font-size of SVG text
+           in correlation with font-size of surrounding HTML  -->
+      <imagedata fileref="images/freeze-raw.svg" format="SVG" width="850px" />
+     </imageobject>
+     <imageobject role="fo">
+      <!-- For PDF attribute 'width=100%' is necessary to keep complete SVG visible
+           on the page, which has a fixed width. Font sizes will be adopted.  -->
+      <imagedata fileref="images/freeze-raw.svg" format="SVG" width="100%" />
+     </imageobject>
+    </mediaobject>
+   </figure>
+
+   <bridgehead renderas="sect2">Protection against Wraparound Failure</bridgehead>
+
+   <para>
+    The AUTOVACUUM processes are initiated by the constantly
+    running <firstterm>autovacuum daemon</firstterm>. If the
+    daemon detects that for a table <firstterm>
+    autovacuum_freeze_max_age</firstterm> is exceeded, it starts
+    an AUTOVACUUM process in the <emphasis>aggressive mode</emphasis>
+    (see above) &mdash; even if AUTOVACUUM is disabled.
+   </para>
+
+   <bridgehead renderas="sect2">Visibility Map and Free Space Map</bridgehead>
+
+   <para>
+    The <link linkend="glossary-vm">Visibility Map</link>
+    (VM) contains two flags &mdash; stored as
+    two bits &mdash; for each page of the heap. If the first bit
+    is set, it indicates that the associated page does not
+    contain any bloat. If the second one is set, it indicates
+    that the page contains only frozen rows.
+   </para>
+
+   <para>
+     Please consider two details. First, in most cases a page
+     contains many rows, some of them in many versions.
+     However, the flags are associated with the page,
+     not with a row or a row version! The flags are set
+     only under the condition that they are valid for ALL
+     row versions of the page. Second, since there
+     are only two bits per page, the VM is considerably
+     smaller than the heap. Therefore it is buffered
+     in RAM in almost all cases.
+   </para>
+
+   <para>
+    The setting of the flags is silently done by VACUUM
+    and AUTOVACUUM during their bloat and freeze operations.
+    This is done to accelerate future vacuum actions,
+    regular accesses to heap pages, and some accesses to
+    the index. Every data-modifying operation on any row
+    version of the page clears the flags.
+   </para>
+
+   <para>
+    The <link linkend="glossary-fsm">Free Space Map</link>
+    (FSM) tracks the amount of free space per page. It is
+    organized as a highly condensed b-tree of (rounded) sizes.
+    As long as VACUUM or AUTOVACUUM change the free space
+    on any processed page, they log the new values in
+    the FSM in the same way as all other writing
+    processes.
+   </para>
+
+   <bridgehead renderas="sect2">Statistics</bridgehead>
+
+   <para>
+    Statistic information helps the <link
+    linkend="planner-stats">Query Planner</link> to make optimal
+    decisions for the generation of execution plans. This
+    information can be gathered with the SQL commands ANALYZE
+    or VACUUM ANALYZE. But also autovacuum processes gather
+    such information. Depending on the percentage of changed rows
+    per table <xref linkend="guc-autovacuum-analyze-scale-factor"/>,
+    the autovacuum daemon starts autovacuum processes to collect
+    statistics per table. This dynamic invocation of analyze
+    operations allows <productname>PostgreSQL</productname> to
+    adopt queries to changing circumstances.
+   </para>
+
+   <para>
+    For more details about vacuum operations, especially for its
+    numerous parameters, see <xref linkend="routine-vacuuming"/>.
+   </para>
+
+  </sect1>
+
+  <sect1 id="tutorial-transactions-mvcc">
+   <title>Transactions</title>
+   <para>
+    <link linkend="tutorial-transactions">Transactions</link>
+    are a fundamental concept of relational database systems.
+    Their essential point is that they bundle multiple
+    read- or write-operations into a single, all-or-nothing
+    operation. Furthermore, they separate and protect concurrent
+    actions of different connections from each other. Thereby
+    they implement the ACID paradigm.
+   </para>
+
+   <para>
+    In <productname>PostgreSQL</productname> there are two ways
+    to establish a transaction. The explicite way uses the keywords
+    <link linkend="sql-begin">BEGIN</link> and
+    <link linkend="sql-commit">COMMIT</link> (respectively
+    <link linkend="sql-rollback">ROLLBACK</link>) before
+    and after a sequence of SQL statements. The keywords mark
+    the transaction's start- and end-point. On the other hand, you
+    can omit the keywords. This is the implicit way, where
+    every single SQL command automatically establishes a new
+    transaction.
+
+    <programlisting>
+BEGIN; -- establish a new transaction
+UPDATE accounts SET balance = balance - 100.00 WHERE name = 'Alice';
+UPDATE accounts SET balance = balance + 100.00 WHERE name = 'Bob';
+COMMIT; -- finish the transaction
+
+-- this UPDATE runs as the only command of a separate transaction ...
+UPDATE accounts SET balance = balance - 100.00 WHERE name = 'Alice';
+
+-- ... and this one runs in another transaction
+UPDATE accounts SET balance = balance + 100.00 WHERE name = 'Bob';
+    </programlisting>
+   </para>
+
+   <para>
+    As mentioned, the primary property of a transaction is its
+    atomicity: either all or none of its operations succeed,
+    regardless of the fact that it may consist of a lot of
+    different write-operations, and each such operation may
+    affect thousands or millions of rows. As soon as one of the
+    operations fails, all previous operations fail also, which
+    means that all modified rows retain their values as of the
+    beginning of the transaction.
+   </para>
+
+   <para>
+    The atomicity also affects the visibility of changes. All
+    connections running simultaneously to a data modifying
+    transaction will never see any change before the
+    transaction successfully executes a <command>COMMIT</command>
+    &mdash; even in the lowest
+    <link linkend="transaction-iso">isolation level</link>
+    of transactions. <productname>PostgreSQL</productname>
+    does never show uncommitted changes to other connections.
+   </para>
+
+   <para>
+    The situation regarding visibility is somewhat different
+    from the point of view of the modifying transaction.
+    <command>SELECT</command> commands issued inside the
+    transaction delivers all changes done so far by this
+    transaction.
+   </para>
+
+   <bridgehead renderas="sect2">How does it work?</bridgehead>
+
+   <para>
+    Every <command>INSERT</command>, <command>UPDATE</command>,
+    and <command>DELETE</command> command creates new row
+    versions &mdash; according to the MVCC rules. This
+    creates the risk that other transactions may see the
+    new row versions, and after a while and some more
+    activities of the modifying transaction they may see the
+    next row versions. Results would be a kind of 'moving
+    target' in absolute contrast to the all-or-nothing
+    principle.
+   </para>
+
+   <para>
+    <productname>PostgreSQL</productname> overcomes the
+    problem by showing only such row versions to other
+    transactions whose originating transaction is
+    successfully committed. It skips all row versions of
+    uncommitted transactions. And
+    <productname>PostgreSQL</productname> solves one more
+    problem. Even the single <command>COMMIT</command>
+    command needs a short time interval for its execution.
+    Therefor its critical 'dead-or-survival' phase
+    runs in a priviledged mode where it cannot be
+    interupted by other processes.
+   </para>
+
+   <bridgehead renderas="sect2">What are the benefits?</bridgehead>
+
+   <para>
+    Transactions relieve applications from many standard
+    actions that must be implemented for nearly every use case.
+   </para>
+
+   <para>
+    Business logic often contains strong, but for a computer,
+    relative abstract requirements. The above example shows
+    the transfers of some money from one account to another.
+    It is obvious
+    that the decrease of the one and the increase of the
+    other are impartible. Nevertheless, there is no particular
+    need for an application to do something to ensure the
+    <glossterm linkend="glossary-atomicity">atomicity</glossterm>
+    of its behavior. It's enough to surround them with
+    <command>BEGIN</command> and <command>COMMIT</command>.
+   </para>
+
+   <para>
+    Applications often demand the feature of 'undoing'
+    previously taken actions under some application-specific
+    conditions. In such cases, the application simply issues a
+    <command>ROLLBACK</command> command instead of a
+    <command>COMMIT</command>. The <command>ROLLBACK</command>
+    cancels the transaction, and all changes made so far retain
+    invisible forever; it's like they never happened. There
+    is no need for the application to log its activities and
+    undo every single step.
+   </para>
+
+   <para>
+    Transactions ensure that the
+    <glossterm linkend="glossary-consistency">consistency</glossterm>
+    of the complete database always keeps valid. Declarative
+    rules like
+    <link linkend="ddl-constraints-primary-keys">primary</link>- or
+    <link linkend="ddl-constraints-fk">foreign keys</link>,
+    <link linkend="ddl-constraints-check-constraints">checks</link>,
+    other constraints, or
+    <link linkend="trigger-definition">triggers</link>
+    are part of the all-or-nothing nature of transactions.
+   </para>
+
+   <para>
+    Also, all self-evident &mdash; but possibly not obvious
+    &mdash; low-level demands on the database system are
+    ensured; e.g., index entries for rows must become
+    visible at the same moment as the rows themselves.
+   </para>
+
+   <para>
+    There is an additional feature which defines transactions'
+    <link linkend="transaction-iso">isolation level</link>
+    to each other in a declarative way. It automatically
+    prevents applications from some strange situations.
+   </para>
+
+   <para>
+    Lastly, it is worth to notice that changes done by a
+    committed transaction will survive all future application,
+    instance, or hardware failures. The next chapter
+    explains this
+    <glossterm linkend="glossary-durability">durability</glossterm>.
+   </para>
+  </sect1>
+
+  <sect1 id="tutorial-reliability">
+   <title>Reliability</title>
+
+   <para>
+    Nothing is perfect and failures inevitably happen.
+    However, the most common types of failures are
+    well known and <productname>PostgreSQL</productname>
+    implements strategies to overcome them.
+    Such strategies use parts of the previously presented
+    techniques MVCC and transaction-rollback, plus additional
+    features.
+   </para>
+
+   <bridgehead renderas="sect2">Failures at the client side</bridgehead>
+   <para>
+    A <glossterm linkend="glossary-client">client</glossterm>
+    can fail in different ways. Its hardware can get damaged,
+    the power supply can fail, the network connection to the
+    server can break, or the client application may run into
+    a severe software error like a null pointer exception.
+    Because <productname>PostgreSQL</productname> uses a
+    client/server architecture, no direct problem for the
+    database will occur. In all of this cases, the
+    <glossterm linkend="glossary-backend">backend process</glossterm>,
+    which is the client's counterpart at the server-side,
+    may recognize that the network connection is no longer
+    working, or it may run into a timeout after a while. It
+    terminates, and there is no harm to the database. As
+    usual, uncommitted data changes initiated by this client
+    are not visible to any other client.
+   </para>
+
+   <bridgehead renderas="sect2">Failures at the server-side</bridgehead>
+
+   <bridgehead renderas="sect3">Instance failure</bridgehead>
+   <para>
+    The instance may suddenly fail because of <emphasis>power off</emphasis>
+    or other problems. This will affect all running processes, the RAM,
+    and possibly the consistency of disk files.
+   </para>
+   <para>
+    After a restart, <productname>PostgreSQL</productname>
+    automatically recognizes that the last shutdown of the
+    instance did not happen as expected: files might not be
+    closed properly and the <firstterm>postmaster.pid</firstterm>
+    file exists. <productname>PostgreSQL</productname>
+    tries to clean up the situation. This is possible because
+    all changes in the database are stored twice. First,
+    the WAL files contain them as a chronology of
+    <glossterm linkend="glossary-wal-record">WAL records</glossterm>,
+    which include the new data values and information about commit
+    actions. The WAL records are written first. Second,
+    the data itself shall exist in the heap and index files.
+    In opposite to the WAL records, this part may or may
+    not be transferred entirely from shared buffers to the files.
+   </para>
+   <para>
+    The automatic recovery searches within the WAL files for
+    the latest
+    <glossterm linkend="glossary-checkpoint">checkpoint</glossterm>.
+    This checkpoint signals that the database files are in
+    a consistent state, especially that all WAL records up to
+    this point were successfully stored in heap and index. Starting
+    here, the recovery process copies the following WAL records
+    to heap and index. As a result, the files contain all
+    changes and reach a consistent state. Changes of committed
+    transactions are visible; those of uncommited transactions
+    are also in the files, but - as usual - they are never seen
+    by any of the following transactions because uncommited
+    changes are never shown. Such recovery actions run
+    completely automatically, it is not necessary that you
+    configure or start anything by yourself.
+   </para>
+
+   <bridgehead renderas="sect3">Disk crash</bridgehead>
+   <para>
+    If a disk crashes, the course of actions described previously
+    cannot work. It is likely that the WAL files and/or the
+    data and index files are no longer available. You need
+    to take special actions to overcome such situations.
+   </para>
+   <para>
+    You obviously need a backup. How to take such a backup
+    and use it as a starting point for a recovery of the
+    cluster is explained in more detail in the next
+    <link linkend="tutorial-backup">chapter</link>.
+   </para>
+
+   <bridgehead renderas="sect3">Disk full</bridgehead>
+   <para>
+    It is conceivable that over time the disk gets full,
+    and there is no room for additional data. In this case,
+    <productname>PostgreSQL</productname> stops accepting
+    commands which change the data or even terminates
+    completely. No data loss or data corruption will
+    occur.
+   </para>
+   <para>
+    To come out of such a situation, you should remove
+    unused files from this disk. But you should never
+    delete files from the
+    <glossterm linkend="glossary-data-directory">data directory</glossterm>.
+    Nearly all of them are necessary for the consistency
+    of the database.
+   </para>
+
+   <bridgehead renderas="sect2">High availability</bridgehead>
+   <para>
+    Database servers can work together to allow a second
+    server to quickly take over the workload if the
+    primary server fails for whatever reason
+    (<link linkend="high-availability">high availability</link>),
+    or to allow several computers to serve the same data
+    for the purpose of load balancing.
+   </para>
+
+  </sect1>
+
+  <sect1 id="tutorial-backup">
+   <title>Backup</title>
+
+   <para>
+    Taking backups is a basic task of database maintenance.
+    <productname>PostgreSQL</productname> supports
+    three different strategies; each has its own
+    strengths and weaknesses.
+    <itemizedlist>
+     <listitem>
+      <simpara>
+       File system level backup
+      </simpara>
+     </listitem>
+     <listitem>
+      <simpara>
+       Logical backup via pg_dump
+      </simpara>
+     </listitem>
+     <listitem>
+      <simpara>
+       Continuous archiving based on pg_basebackup and WAL files
+      </simpara>
+     </listitem>
+    </itemizedlist>
+   </para>
+
+   <bridgehead renderas="sect2">File system level backup</bridgehead>
+   <para>
+    You can use any appropriate OS tool to create a
+    <link linkend="backup-file">copy</link>
+    of the cluster's directory structure and files. In
+    case of severe problems such a copy can serve as
+    the source of a recovery. But in order to get a
+    <emphasis>USABLE</emphasis> backup by this method,
+    the database server <emphasis>MUST</emphasis> be
+    shut down during the complete runtime of the copy
+    command!
+   </para>
+   <para>
+    The apparent disadvantage of this method is that there
+    is a downtime where no user interaction is possible.
+   </para>
+
+   <bridgehead renderas="sect2">Logical backup via pg_dump</bridgehead>
+   <para>
+    The tool <command>pg_dump</command> is able to take a
+    <link linkend="backup-dump">copy</link>
+    of the complete cluster or certain parts of it. It stores
+    the copy in the form of SQL <command>CREATE</command> and
+    <command>INSERT</command> commands. It runs in
+    parallel to other processes in its own transaction.
+   </para>
+   <para>
+    The output of <command>pg_dump</command> may be used as
+    input of <command>psql</command> to restore the data
+    (or to copy it to another database).
+   </para>
+   <para>
+    The main advantage over the other two methods is that it
+    can pick parts of the cluster, e.g. a single table or one
+    database. The other two methods work only at the level of
+    the complete cluster.
+   </para>
+
+   <bridgehead renderas="sect2">Continuous archiving based on pg_basebackup and WAL files</bridgehead>
+   <para>
+    This <link linkend="continuous-archiving">method</link>
+    is the most sophisticated and complex one. It
+    consists of two phases.
+   </para>
+   <para>
+    First, you need to create a so called
+    <firstterm>basebackup</firstterm> with the tool
+    <command>pg_basebackup</command>. The result is a
+    directory structure plus files which contains a
+    consistent copy of the original cluster.
+    <command>pg_basebackup</command> runs in
+    parallel to other processes in its own transaction.
+   </para>
+   <para>
+    The second step is recommended but not necessary. All
+    changes to the data are stored in WAL files. If you
+    continuously save such WAL files, you have the history
+    of the cluster. This history can be applied to a
+    basebackup in order to recreate any state of the
+    cluster between the time of
+    <command>pg_basebackup</command>'s start time and
+    any later point in time. This technique
+    is called 'Point-in-Time Recovery (PITR)'.
+   </para>
+   <para>
+    If configured, the
+    <glossterm linkend="glossary-wal-archiver">Archiver process</glossterm>
+    will automatically copy every single WAL file to a save location.
+    <link linkend="backup-archiving-wal">It's configuration</link>
+    consists mainly of a string, which contains a copy command
+    in the operating system's syntax. In order to protect your
+    data against a disk crash, the destination location
+    of a <firstterm>basebackup</firstterm> as well as of the
+    <firstterm>archived WAL files</firstterm> should be on a
+    disk which is different from the data disk.
+   </para>
+   <para>
+    If it gets necessary to restore the cluster, you have to
+    copy the <firstterm>basebackup</firstterm> and the
+    <firstterm>archived WAL files</firstterm> to
+    their original directories. The configuration of this
+    <link linkend="backup-pitr-recovery">recovery procedure</link>
+    contains a string with the reverse copy command: from
+    archive location to database location.
+   </para>
+
+  </sect1>
+
+<!-- ToDo
+  <sect1 id="tutorial-replication">
+   <title>Replication</title>
+
+   <para>
+...
+   </para>
+
+  </sect1>
+-->
+
+ </chapter>
diff --git a/doc/src/sgml/filelist.sgml b/doc/src/sgml/filelist.sgml
index 68179f71cd..4bc68f2da0 100644
--- a/doc/src/sgml/filelist.sgml
+++ b/doc/src/sgml/filelist.sgml
@@ -8,9 +8,10 @@
 <!ENTITY problems   SYSTEM "problems.sgml">
 
 <!-- tutorial -->
 
 <!-- user's guide -->
index 0000000000..1fffb9737a
+     inkscape:window-width="1129"
+     inkscape:window-height="922"
+     inkscape:zoom="0.68905109"
+     inkscape:cx="737.16805"
+     inkscape:cy="342.1375"
index 0000000000..8151cf583a
+     inkscape:window-width="1083"
+     inkscape:window-height="808"
index 0000000000..6fedfb7633
+    <tspan font-style="italic" font-weight="700">Freeze</tspan> to keep visible
+      1: txid_current + 2 ^ 31 (split-point)
+      5: txid_current (split-point, jungest xid)
index 0000000000..009cfe4b41
+     inkscape:window-width="979"
+     inkscape:window-height="857"
+ to keep visible</text>
+       id="text426">1: txid_current + 2 ^ 31 (split-point)</text>
+       id="text434">5: txid_current (split-point, jungest xid)</text>
index 0000000000..2d1d256184
+        Freeze</tspan> to keep visible</text>
+    <text y="25">1: txid_current + 2 ^ 31 (split-point)</text>
+    <text y="125">5: txid_current (split-point, jungest xid)</text>
index 0000000000..e5745818d9
+     inkscape:window-width="1050"
+     inkscape:window-height="838"
index 0000000000..8e67da93d1
+      <path d="M102-20H-18v60" stroke="black"/>
index 0000000000..f4161b3e79
+     inkscape:window-width="1256"
+     inkscape:window-height="801"
+     id="title2">MVCC</title>
+     id="defs15">
+         id="path6" />
+         id="path9" />
+         id="path11" />
+     id="rect17" />
+       id="g35">
+         id="text23">T
+   id="tspan19">123</tspan>
+   id="tspan21">: INSERT</tspan>
+         id="use25" />
+         id="use27" />
+         id="text29">123</text>
+         id="text31">0</text>
+         id="text33">'x'</text>
+       id="g61">
+         id="text41">T
+   id="tspan37">135</tspan>
+   id="tspan39">: UPDATE</tspan>
+         id="use43" />
+         id="use45" />
+         id="text47">135</text>
+         id="text49">0</text>
+         id="text51">'y'</text>
+         id="use53" />
+         id="text55">123</text>
+         id="text57">135</text>
+         id="text59">'x'</text>
+       id="g95">
+         id="text67">T
+   id="tspan63">142</tspan>
+   id="tspan65">: UPDATE</tspan>
+         id="use69" />
+         id="use71" />
+         id="text73">142</text>
+         id="text75">0</text>
+         id="text77">'z'</text>
+         id="text81">135</text>
+         id="text83">142</text>
+         id="text85">'y'</text>
+         id="use87" />
+         id="text89">123</text>
+         id="text91">135</text>
+         id="text93">'x'</text>
+       id="g129">
+         id="text101">T
+   id="tspan97">821</tspan>
+   id="tspan99">: DELTE</tspan>
+         id="use103" />
+         id="text107">142</text>
+         id="text109">821</text>
+         id="text111">'z'</text>
+         id="use113" />
+         id="text115">135</text>
+         id="text117">142</text>
+         id="text119">'y'</text>
+         id="use121" />
+         id="text123">123</text>
+         id="text125">135</text>
+         id="text127">'x'</text>
+       id="g143">
+         d="M 102 -20 h -120 v 60"
+         id="path131" />
+         id="text133">Legend</text>
+         id="use135" />
+         id="text137">xmin</text>
+         id="text139">xmax</text>
+         id="text141">data</text>
index 0000000000..0481c4c938
+      <path d="M 102 -20 h -120 v 60" stroke="black"/>
index 0000000000..262275f05c
+      Shared Memory (per Instance)
+  <path stroke="blue" fill="none" d="M180 215h250v30H180z"/>
+  <text x="10" y="20" class="text_normal" transform="translate(180 215)">
+    Postmaster
+  <path d="M90 230h75" stroke="black" fill="none" marker-end="url(#arrowhead_end)"/>
+  <path d="M690 455l30 30" stroke="black" fill="none" marker-end="url(#arrowhead_end)"/>
index 0000000000..067920b99e
+     inkscape:window-width="1177"
+     inkscape:window-height="869"
+       id="text805">Shared Memory (per Instance)</text>
+     transform="translate(180, 215)"
+       width="250"
+       id="text811">Postmaster</text>
+     d="M 90,230 h 75"
+     d="M 690,455 l 30, 30"
index 0000000000..8169295584
+    <text x="50" y="0"  class="text_comment">Shared Memory (per Instance)</text>
+  <g transform="translate(180, 215)">
+    <rect width="250" height="30" stroke="blue" fill="none" />
+    <text x="10" y="20" class="text_normal">Postmaster</text>
+  <path d="M 90,230 h 75" stroke="black" fill="none" marker-end="url(#arrowhead_end)"/>
+  <path d="M 690,455 l 30, 30" stroke="black" fill="none" marker-end="url(#arrowhead_end)"/>
index 0000000000..a9c51f4e43
+     inkscape:window-width="1193"
+     inkscape:window-height="788"
index c41ce9499b..7913f45897 100644
@@ -62,6 +62,7 @@ break is not needed in a wider output rendering.
   &start;
   &query;
   &advanced;
+  &architecture;
 
  </part>
 
index c0889743c4..b1906c6e36 100644
 
  <chapter id="tutorial-sql">
-  <title>The <acronym>SQL</acronym> Language</title>
+  <title>Fundamentals of the <acronym>SQL</acronym> Language</title>
 
index 2a47f69079..9a703702f1 100644

    <para>
     Before we proceed, you should understand the basic
@@ -68,34 +68,55 @@
     client/server model.  A <productname>PostgreSQL</productname>
     session consists of the following cooperating processes
     (programs):
+   </para>
 
-    <itemizedlist>
-     <listitem>
-      <para>
+      <glossterm linkend="glossary-postmaster">Postmaster</glossterm>.
+      <indexterm><primary>postgres</primary></indexterm>
 
-     <listitem>
-      <para>
 
-    </itemizedlist>
-   </para>
+    <listitem>
+     <para>
 
    <para>
@@ -106,18 +127,6 @@
 
-   <para>

---

From: Daniel Gustafsson <[email-masked]>
Date: Sun, 12 Jul 2020 22:45:28 +0200

> On 2 Jun 2020, at 17:01, Jürgen Purtz <[email-masked]> wrote:

> - A <note> delimits VACUUM basics from details. This is done because I cannot find another suitable place for such a summarizing description.
> 

This patch no longer applies, due to conflicts in start.sgml, can you please
submit a rebased version?

cheers ./daniel

---

From: Jürgen Purtz <[email-masked]>
Date: Mon, 13 Jul 2020 08:15:20 +0200

> submit a rebased version?

ok. but I need some days.  juergen

---

From: Naresh gandi <[email-masked]>
Date: Mon, 13 Jul 2020 17:50:51 +0530

Which version is this application for?

I tried for v12 and v13 Beta, both failed.

Regards,
Naresh G

---

From: Daniel Gustafsson <[email-masked]>
Date: Mon, 13 Jul 2020 14:24:43 +0200

> On 13 Jul 2020, at 14:20, Naresh gandi <[email-masked]> wrote:

(please avoid top-posting)

> I tried for v12 and v13 Beta, both failed.

Unless being a bugfix, all patches are only considered against the main
development branch in Git. As this is new material, it would be for v14.

cheers ./daniel

---

From: Jürgen Purtz <[email-masked]>
Date: Fri, 17 Jul 2020 11:32:50 +0200

> submit a rebased version?
New version attached.

--

Jürgen Purtz

 
index 64b5da0070..a9eac872f0 100644
 
 <!-- tutorial -->
 
 <!-- user's guide -->
 
  </part>

 
index 9bb5c1a6d5..8751410179 100644

    <para>
 
-    <itemizedlist>
-     <listitem>
-      <para>
 
-     <listitem>
-      <para>
 
-    </itemizedlist>
-   </para>
+    <listitem>
+     <para>
 
    <para>

---

From: Erik Rijkers <[email-masked]>
Date: Sat, 18 Jul 2020 19:17:50 +0200

On 2020-07-17 11:32, Jürgen Purtz wrote:
> [0005-architecture.patch]

Hi,

I went through the architecture.sgml file once, and accumulated the 
attached edits.

There are still far too many Unneeded Capitals On Words for my taste but 
I have not changed many of those. We could use some more opinions on 
that, I suppose. (if it becomes too silent maybe include the 
pgsql-hackers again?)

Thanks,

Erik Rijkers

--- doc/src/sgml/architecture.sgml.orig	2020-07-17 16:24:04.345941142 +0200
+++ doc/src/sgml/architecture.sgml	2020-07-18 19:04:30.694039877 +0200
@@ -4,36 +4,36 @@
   <title>Architectural and implementational Cornerstones</title>
 
   <para>
-   Every DBMS implements basic strategies to achieve a fast and
+   Every DBMS implements basic strategies for a fast and
    robust system. This chapter provides an overview of what
    techniques <productname>PostgreSQL</productname> uses to
-   reach this aim.
+   achieve this.
   </para>
 
   <sect1 id="tutorial-ram-proc-file">
    <title>Collaboration of Processes, RAM, and Files</title>
    <para>
-    As is a matter of course, in a client/server architecture
+    In a client/server architecture
     clients do not have direct access to the database. Instead,
-    they merely send requests to the server-side and receive
-    according information from there. In the case of
+    they send requests to the server and receive
+    the requested information. In the case of
     <productname>PostgreSQL</productname>, at the server-side
     there is one process per client, the so-called
     <glossterm linkend="glossary-backend">Backend process</glossterm>.
     It acts in close cooperation with the
     <glossterm linkend="glossary-instance">Instance</glossterm> which
-    is a group of tightly coupled other server-side processes plus a
+    is a group of server-side processes plus a
     <glossterm linkend="glossary-shared-memory">Shared Memory</glossterm>
     area.
    </para>
 
    <para>
-    At start time, an instance is initiated by the
-    <glossterm linkend="glossary-postmaster">Postmaster</glossterm>
+    At startup time, an instance is initiated by the
+    <glossterm linkend="glossary-postmaster">postmaster</glossterm>
     process.
-    It loads the configuration files, allocates the
+    The postmaster process loads the configuration files, allocates
     <glossterm linkend="glossary-shared-memory">Shared Memory</glossterm>,
-    and starts the comprehensive network of processes:
+    and starts a network of processes:
     <glossterm linkend="glossary-background-writer">Background Writer</glossterm>,
     <glossterm linkend="glossary-checkpointer">Checkpointer</glossterm>,
     <glossterm linkend="glossary-wal-writer">WAL Writer</glossterm>,
@@ -65,8 +65,8 @@
     Whenever a client application tries to connect to a
     <glossterm linkend="glossary-database">database</glossterm>,
     this request is handled in a first step by the <firstterm>
-    Postgres process</firstterm>. It checks the authorization,
-    starts a new <firstterm>Backend process</firstterm>,
+    postgres process</firstterm>. It checks authorization,
+    starts a new <firstterm>backend process</firstterm>,
     and instructs the client application to connect to it. All
     further client requests go to this process and are handled
     by it.
@@ -83,20 +83,20 @@
     <glossterm linkend="glossary-index">index</glossterm> files.
     Because files are often larger than memory, it's likely that
     the desired information is not (completely) available
-    in the RAM. In this case the <firstterm>Backend process</firstterm>
+    in RAM. In this case the <firstterm>Backend process</firstterm>
     must transfer additional file pages to
     <firstterm>Shared Memory</firstterm>. Files are physically
     organized in pages. Every transfer between files and
-    RAM is performed in units of complete pages. Such transfers
-    don't change the size or layout of pages.
+    RAM is performed in units of complete pages; such transfers
+    do not change the size or layout of pages.
    </para>
 
    <para>
-    Reading file pages is notedly slower than reading
-    RAM. This is the primary motivation for the existence of
+    Reading file pages is much slower than reading
+    RAM. This is the primary motivation for the usage of
     <firstterm>Shared Memory</firstterm>. As soon as one
     of the <firstterm>Backend processes</firstterm> has
-    read pages into memory, those pages are available for all
+    read pages into memory, those pages become available for all
     other <firstterm>Backend processes</firstterm> for direct
     access in RAM.
    </para>
@@ -121,13 +121,13 @@
     First, whenever the content of a page changes, a
     <glossterm linkend="glossary-wal-record">WAL record</glossterm>
     is created out
-    of the delta-information (difference between old and
-    new content) and stored in another area of the
+    of the delta-information (difference between the old and
+    the new content) and stored in another area of
     <firstterm>Shared Memory</firstterm>. These
     <firstterm>WAL records</firstterm> are read by the
     <firstterm>WAL Writer</firstterm> process,
     which runs in parallel to the <firstterm>Backend
-    processes</firstterm> and all other processes of
+    processes</firstterm> and other processes of
     the <firstterm>Instance</firstterm>. It writes
     the continuously arising <firstterm>WAL records</firstterm> to
     the end of the current
@@ -137,7 +137,7 @@
     to data files with <firstterm>heap</firstterm>
     and <firstterm>index</firstterm> information.
     As mentioned, this WAL-writing happens
-    in an independent process. Nevertheless, all
+    in an independent process. All
     <firstterm>WAL records</firstterm> created out of one
     <firstterm>dirty page</firstterm> must be transferred
     to disk before the <firstterm>dirty page</firstterm>
@@ -146,35 +146,34 @@
 
    <para>
     Second, the transfer of <firstterm>dirty buffers</firstterm>
-    from <firstterm>Shared Memory</firstterm> to files must
-    take place. This is the primary duty of the
+    from <firstterm>Shared Memory</firstterm> to file must
+    take place. This is the primary task of the
     <firstterm>Background Writer</firstterm> process. Because
     I/O activities can block other processes significantly,
     it starts periodically and acts only for a short period.
-    Doing so, his expensive I/O activities are spread over
-    time, avoiding huge I/O peaks. Also, the <firstterm>
+    Doing so, its expensive I/O activities are spread over
+    time, avoiding debilitating I/O peaks. Also, the <firstterm>
     Checkpointer</firstterm> process transfers
-    <firstterm>dirty buffers</firstterm> to files &mdash;
+    <firstterm>dirty buffers</firstterm> to file &mdash;
     see next paragraph.
    </para>
 
    <para>
-    The <firstterm>Checkpointer</firstterm> has a special
-    duty. As its name suggests, it has to create
-    <firstterm>Checkpoints</firstterm>. Such a
+    The <firstterm>Checkpointer</firstterm> creates
+    <firstterm>Checkpoints</firstterm>.  A
     <glossterm linkend="glossary-checkpoint">Checkpoint</glossterm>
     is a point in time when all older <firstterm>dirty buffers</firstterm>,
     all older <firstterm>WAL records</firstterm>, and
     finally a special <firstterm>Checkpoint record</firstterm>
     have been written and flushed to disk.
-    After a <firstterm>Checkpoint</firstterm>,
+    After a <firstterm>Checkpoint</firstterm>, we say
     data files and <firstterm>WAL files</firstterm> are in sync.
     In case of a recovery (after a crash of the instance)
-    it is known that the information of all
+    it can be relied upon that the information of all
     <firstterm>WAL records</firstterm> preceding
     the last <firstterm>Checkpoint record</firstterm>
-    is already integrated into the data files. This
-    speeds up a possibly occurring recovery.
+    were already integrated into the data files. This
+    speeds up the recovery.
    </para>
 
    <para>
@@ -184,7 +183,7 @@
     Those <firstterm>WAL files</firstterm> &mdash; in combination with
     a previously taken <firstterm>Base Backup</firstterm> &mdash;
     are necessary to restore a database after a crash of the
-    disk, where data files have been stored. Therefore it is
+    disk on which data files have been stored. Therefore it is
     recommended to transfer a copy of the <firstterm>
     WAL files</firstterm>
     to a second, independent place. The purpose of the
@@ -201,10 +200,10 @@
    </para>
 
    <para>
-    The <glossterm linkend="glossary-logger">Logger</glossterm> writes
+    The <glossterm linkend="glossary-logger">Logger</glossterm> process writes
     text lines about serious and less serious events which can happen
-    during database access, e.g., wrong password, no permission,
-    long-running queries, ... .
+    during database access, e.g. wrong password, no permission,
+    long-running queries, etc.
    </para>
 
   </sect1>
@@ -214,16 +213,17 @@
 
    <para>
 <!-- TODO: Link to cluster -->
-    On a <glossterm linkend="glossary-server">Server</glossterm>
-    exists one or more <glossterm linkend="glossary-instance">Cluster</glossterm>,
-    each of them contains three or more
-    <glossterm linkend="glossary-database">databases</glossterm>, each
-    database contains many <glossterm linkend="glossary-schema">schemas</glossterm>,
-    a schema contains <glossterm linkend="glossary-table">tables</glossterm>,
+    A <glossterm linkend="glossary-server">Server</glossterm>
+    contains one or more <glossterm linkend="glossary-instance">Clusters</glossterm>.
+    Each cluster contains three or more
+    <glossterm linkend="glossary-database">databases</glossterm>.  Each
+    database can contain many <glossterm linkend="glossary-schema">schemas</glossterm>
+    (one schema, 'public', is provided by default).
+    A schema can contain <glossterm linkend="glossary-table">tables</glossterm>,
     <glossterm linkend="glossary-view">views</glossterm>, and a lot of other objects.
     Each <firstterm>table</firstterm> or <firstterm>view</firstterm>
-    belongs to a single <firstterm>schema</firstterm>; they cannot
-    belong to another <firstterm>schema</firstterm>. The same is
+    belongs to a single <firstterm>schema</firstterm> only; they cannot
+    belong to another <firstterm>schema</firstterm> as well. The same is
     true for the schema/database and database/cluster relation.
     <xref linkend="tutorial-cluster-db-schema-figure"/> visualizes
     this hierarchy.
@@ -254,30 +254,30 @@
    <para>
     <literal>template0</literal> is the very first
     <firstterm>database</firstterm> of any
-    <firstterm>cluster</firstterm>. C-routines create
-    <literal>template0</literal> during the initialization phase of
-    the <firstterm>cluster</firstterm>.
-    In a second step, <literal>template1</literal> is generated
-    as a copy of <literal>template0</literal>, and finally
+    <firstterm>cluster</firstterm>.  
+    Database <literal>template0</literal> is created during the
+    initialization phase of the <firstterm>cluster</firstterm>.
+    In a second step, database <literal>template1</literal> is generated
+    as a copy of <literal>template0</literal>, and finally database
     <literal>postgres</literal> is generated as a copy of
-    <literal>template1</literal>. All other
+    <literal>template1</literal>. Any 
     <glossterm linkend="app-createdb">new databases</glossterm>
-    of this <firstterm>cluster</firstterm>,
-    such as <literal>my_db</literal>, are also copied from
-    <literal>template1</literal>. Due to the unique
-    role of <literal>template0</literal> as the pristine origin
+    of the <firstterm>cluster</firstterm> that a user might need,
+    such as <literal>my_db</literal>, will be copied from the
+    <literal>template1</literal> database. Due to the unique
+    role of <literal>template0</literal> as the pristine original
     of all other <firstterm>databases</firstterm>, no client
     can connect to it.
    </para>
 
    <para>
-    Every database contains <glossterm linkend="glossary-schema">
-    schemas</glossterm>, and
+    Every database must contain <glossterm linkend="glossary-schema">
+    at least one schema</glossterm> because
     <firstterm>schemas</firstterm> contain the other
     <glossterm linkend="glossary-sql-object">SQL Objects</glossterm>.
     <firstterm>Schemas</firstterm> are namespaces for
     their <firstterm>SQL objects</firstterm> and ensure &mdash; with one
-    exception &mdash; that within their scope names are used only once across all
+    exception &mdash; that within their scope, names are used only once across all
     types of <firstterm>SQL objects</firstterm>. E.g., it is not possible
     to have a table <literal>employee</literal> and a view
     <literal>employee</literal> within the same
@@ -294,10 +294,10 @@
    <para>
     Some <firstterm>schemas</firstterm> are predefined.
     <literal>public</literal> acts as the default
-    <firstterm>schema</firstterm> and contains all such
-    <firstterm>SQL objects</firstterm>, which are created
-    within <literal>public</literal> or without using any schema
-    name. <literal>public</literal> shall not contain user-defined
+    <firstterm>schema</firstterm> and contains all
+    <firstterm>SQL objects</firstterm> which are created
+    within <literal>public</literal> or without using an explicit schema
+    name. <literal>public</literal> should not contain user-defined
     <firstterm>SQL objects</firstterm>. Instead, it is recommended to
     create a separate <firstterm>schema</firstterm> that
     holds individual objects like application-specific tables or
@@ -310,7 +310,7 @@
    </para>
 
    <para>
-    There are a lot of different <firstterm>SQL object</firstterm>
+    There are many different <firstterm>SQL object</firstterm>
     types: <firstterm>database, schema, table, view, materialized
     view, index, constraint, sequence, function, procedure,
     trigger, role, data type, operator, tablespace, extension,
@@ -353,7 +353,7 @@
     <firstterm>Cluster</firstterm> has its root directory
     somewhere in the file system. In many cases, the environment
     variable <literal>PGDATA</literal> points to this directory.
-    The example of the survey shown in
+    The example shown in
     <xref linkend="tutorial-directories-figure"/> uses
     <literal>data</literal> as the name of this root directory.
    </para>
@@ -405,7 +405,7 @@
    </para>
 
    <para>
-    Another prominent subdirectory is <literal>global</literal>.
+    Another subdirectory is <literal>global</literal>.
     In analogy to the <firstterm>database</firstterm>-specific
     subdirectories, there are files containing information about
     <glossterm linkend="glossary-sql-object">Global SQL objects</glossterm>.
@@ -440,12 +440,12 @@
    <para>
     In the root directory <literal>data</literal>
     there are also some files. In many cases, the configuration
-    files of this <firstterm>cluster</firstterm> are stored
+    files of the <firstterm>cluster</firstterm> are stored
     here. As long as the <firstterm>instance</firstterm>
     is up and running, the file
     <literal>postmaster.pid</literal> exists here
     and contains the ID (pid) of the
-    <firstterm>Postmaster</firstterm> process which
+    <firstterm>postmaster</firstterm> process which
     has started the instance.
    </para>
 
@@ -464,23 +464,23 @@
     support many clients at the same time. Therefore, it is necessary to
     protect concurrently running requests from unwanted overwriting
     of other's data as well as from reading inconsistent data. Imagine an
-    online shop offering the last copy of an article. Two clients show the
-    article at their user interface. After a while, but at the same time,
+    online shop offering the last copy of an article. Two clients have the
+    article displayed at their user interface. After a while, but at the same time,
     both users decide to put it to their shopping cart or even to buy it.
     Both have seen the article, but only one can be allowed to get it.
     The database must bring the two requests in a row, permit the access
-    to one of them, block the other, and inform this one about the
-    situation that the data was changed by a different process.
+    to one of them, block the other, and inform the blocked client 
+    that the data was changed by a different process.
    </para>
 
    <para>
     A first approach to implement protections against concurrent
     accesses to the same data may be the locking of critical
-    rows. There are two main categories of such techniques:
+    rows. Two such techniques are:
     <emphasis>Optimistic Concurrency Control</emphasis> (OCC)
     and <emphasis>Two Phase Locking</emphasis> (2PL).
-    <productname>PostgreSQL</productname> implements the more
-    sophisticated technique <firstterm>Multiversion Concurrency
+    <productname>PostgreSQL</productname> implements a third, more
+    sophisticated technique: <firstterm>Multiversion Concurrency
     Control</firstterm> (MVCC). The crucial advantage of MVCC
     over other technologies gets evident in multiuser OLTP
     environments with a massive number of concurrent write
@@ -493,15 +493,15 @@
 
    <para>
     Instead of locking rows, the <firstterm>MVCC</firstterm> technique creates
-    a new version of the same row when any data-change takes place. To
-    distinguish between these versions as well as to track the timeline
+    a new version of the row when a data-change takes place. To
+    distinguish between these two versions and to track the timeline
     of the row, each of the versions contains, in addition to their user-defined
     columns, two special system columns, which are not visible
     for the usual <command>SELECT * FROM ...</command> command.
     The column <literal>xmin</literal> contains the transaction ID (xid)
-    of the transaction, which creates this version of the row. Accordingly,
+    of the transaction, which created this version of the row. Accordingly,
     <literal>xmax</literal> contains the xid of the transaction, which has
-    deleted this version, respectively a zero, if the version is not
+    deleted this version, or zero, if the version is not
     deleted. You can read both with the command
     <command>SELECT xmin, xmax, * FROM ... </command>.
    </para>
@@ -519,9 +519,9 @@
    </para>
 
    <para>
-    Please note that the description in this chapter simplifies the situation
-    by omitting details. When many transactions are running simultaneously,
-    things can get very complicated. Sometimes they get aborted via
+    The description in this chapter simplifies by omitting detail.
+    When many transactions are running simultaneously,
+    things can get complicated. Sometimes transactions get aborted via
     ROLLBACK immediately or after a lot of other activities, sometimes
     a single row is involved in more than one transaction, sometimes
     a client crashes, sometimes the sequence of xids restarts
@@ -567,7 +567,7 @@
     changing the user data from <literal>'x'</literal> to
     <literal>'y'</literal>. According to the MVCC principles,
     the data in the old version of the row does not change!
-    The value <literal>'x'</literal> keeps as it was before.
+    The value <literal>'x'</literal> remains as it was before.
     Only <literal>xmax</literal> changes to <literal>135</literal>.
     Now, this version is treated as valid exclusively for
     transactions with xids from <literal>123</literal> to
@@ -591,7 +591,7 @@
 
    <para>
     Finally, a row may be deleted by a <command>DELETE</command>
-    command. Even in this case, all versions of the row keep as
+    command. Even in this case, all versions of the row remain as
     before. Nothing is thrown away so far! Only <literal>xmax</literal>
     of the last version changes to the xid of the <command>DELETE</command>
     transaction, which indicates that it is only valid for
@@ -603,14 +603,14 @@
    <para>
     In summary, the MVCC technology creates more and more versions
     of the same row in the table's heap file and leaves them there,
-    even with a <command>DELETE</command> command. The youngest
+    even after a <command>DELETE</command> command. Only the youngest
     version is relevant for all future transactions. But the
     system must also preserve some of the older ones for a
-    certain amount of time because the possiblility exists that
-    they are or could become relevant for any of the pending
+    certain amount of time because the possibility exists that
+    they are or could become relevant for any pending
     transactions. Over time, also the older ones get out of scope
     for ALL transactions and therefore become unnecessary.
-    Nevertheless, they exist physically on the disk and occupy
+    Nevertheless, they do exist physically on the disk and occupy
    space.
    </para>
 
@@ -629,7 +629,7 @@
       xids grow, old row versions get out of scope over time.
       If an old row version is no longer valid for ALL existing
       transactions, it's called <firstterm>dead</firstterm>. The
-      space occupied by the sum of all dead row versions is
+      space occupied by all dead row versions is
       called <firstterm>bloat</firstterm>.
      </simpara>
     </listitem>
@@ -637,7 +637,7 @@
     <listitem>
      <simpara>
       Internally, an <command>UPDATE</command> command acts in the
-      same way as a <command>DELETE</command> command, followed by
+      same way as a <command>DELETE</command> command followed by
       an <command>INSERT</command> command.
      </simpara>
     </listitem>
@@ -646,7 +646,7 @@
      <simpara>
       Nothing gets wiped away &mdash; with the consequence that the database
       occupies more and more disk space. It is obvious that
-      this behavior has to be automatically corrected in some
+      this behavior has to be corrected in some
       way. The next chapter explains how AUTOVACUUM fulfills
       this task.
      </simpara>
@@ -664,7 +664,7 @@
     more and more disk space, the <firstterm>bloat</firstterm>.
     This chapter explains how the SQL command
     <firstterm>VACUUM</firstterm> and the automatically running
-    <firstterm>AUTOVACUUM</firstterm> processes clear the situation
+    <firstterm>AUTOVACUUM</firstterm> processes clean up
     by eliminating <firstterm>bloat</firstterm>.
    </para>
 
@@ -672,9 +672,9 @@
     <para>
      <firstterm>AUTOVACUUM</firstterm> runs automatically by
      default. Its default parameters as well as such for
-     <firstterm>VACUUM</firstterm> fits well for most standard
+     <firstterm>VACUUM</firstterm> fit well for most standard
      situations. Therefore a novice database manager can
-     easily skip the rest of this chapter, which explains
+     easily skip the rest of this chapter which explains
      a lot of details.
     </para>
    </note>
@@ -682,16 +682,16 @@
    <para>
     Client processes can issue the SQL command VACUUM at arbitrary
     points in time. DBAs do this when they recognize special situations,
-    or they start it in batch jobs, which run periodically.
+    or they start it in batch jobs which run periodically.
     AUTOVACUUM processes run as part of the
     <link linkend="glossary-instance">Instance</link> at the server.
-    There is a constantly running AUTOVACUUM daemon. He permanently
+    There is a constantly running AUTOVACUUM daemon. It permanently
     controls the state of all databases based on values that are
     collected by the <link linkend="glossary-stats-collector">
     Statistics Collector</link> and starts
-    AUTOVACUUM processes whenever he detects certain situations.
+    AUTOVACUUM processes whenever it detects certain situations.
     Thus, it's a dynamic behavior of <productname>PostgreSQL</productname>
-    with the intention to tidy up &mdash; not always, but whenever it
+    with the intention to tidy up &mdash; whenever it
     is appropriate.
    </para>
 
@@ -712,7 +712,7 @@
       <firstterm>Freeze</firstterm>: Mark the youngest row version
       as frozen. This means that the version
       is always treated as valid (visible) independent from
-      the <firstterm>wraparound problematic</firstterm> (see below).
+      the <firstterm>wraparound problem</firstterm> (see below).
      </simpara>
     </listitem>
 
@@ -729,22 +729,22 @@
      <simpara>
       <emphasis>Statistics</emphasis>: Collect statistics about the
       number of rows per table, the distribution of values, and so on,
-      as the basis for query planner's decision making.
+      as the basis for decisions of the query planner.
      </simpara>
     </listitem>
 
    </itemizedlist>
 
    <para>
-    The eagerness &mdash; you can call it 'aggressivity' &mdash; of the
+    The eagerness &mdash; you can call it 'aggression' &mdash; of the
     operations <emphasis>eliminating bloat</emphasis> and
     <emphasis>freeze</emphasis> is controlled by configuration
     parameters, runtime flags, and in extreme situations by
-    themselves. Because vacuum operations typically are I/O
+    the processes themselves. Because vacuum operations typically are I/O
     intensive, which can hinder other activities, AUTOVACUUM
     avoids performing many vacuum operations in bulk. Instead,
     it carries out many small actions with time gaps in between.
-    The SQL command VACUUM runs immediately without any
+    The SQL command VACUUM runs immediately and without any
     time gaps.
    </para>
 
@@ -794,8 +794,8 @@
     After the vacuum operation detects a superfluous row version, it
     marks its space as free for future use of writing
     actions. Only in rare situations (or in the case of VACUUM FULL),
-    this space is released to the operating system. In most cases,
-    it keeps occupied by PostgreSQL and will be used by future
+    is this space released to the operating system. In most cases,
+    it remains occupied by PostgreSQL and will be used by future
     <command>INSERT</command> or <command>UPDATE</command>
     commands concerning this row or a completely different one.
    </para>
@@ -827,7 +827,7 @@
      <listitem>
       <simpara>
        When a client issues the SQL command VACUUM with the option FULL.
-       Also, in this mode, the bloat disappears, but the used strategy
+       Also, in this mode, the bloat disappears, but the strategy used
        is very different: In this case, the complete table is copied
        to a different file skipping all outdated row versions. This
        leads to a significant reduction of used disk space because
@@ -839,8 +839,8 @@
      <listitem>
       <simpara>
        When an AUTOVACUUM process acts. For optimization
-       purposes, he considers the Visibility Map in the same way as
-       VACUUM. Additionally, he ignores tables with few modifications;
+       purposes, it considers the Visibility Map in the same way as
+       VACUUM. Additionally, it ignores tables with few modifications;
        see <xref linkend="guc-autovacuum-vacuum-threshold"/>,
        which defaults to 50 rows and
        <xref linkend="guc-autovacuum-vacuum-scale-factor"/>,
@@ -864,7 +864,7 @@
     a certain number of new transactions they are forced to restart
     from the beginning, which is called <firstterm>wraparound</firstterm>.
     Therefore the terms 'old transaction' / 'young transaction' does
-    not always correlate with low / hight values of xids. Near to the
+    not always correlate with low / high values of xids. Near to the
     wraparound point, there are cases where xmin has a higher value
     than xmax, although their meaning is said to be older than xmax.
    </para>
@@ -891,10 +891,10 @@
     The use of a limited range of IDs for transactions leads
     to the necessity to restart the sequence sooner or later.
     This does not only have the rare consequence previously
-    described that sometimes xmin is huger than xmax. The far
+    described that sometimes xmin is higher than xmax. The far
     more critical problem is that whenever the system has
     to evaluate a WHERE condition, it must decide which row
-    versions are valid (visible) from the perspective of the
+    version is valid (visible) from the perspective of the
     transaction of this query. If a wraparound couldn't happen,
     this decision would be relatively easy: the xid
     must be between xmin and xmax, and the corresponding
@@ -911,7 +911,7 @@
 
     <listitem>
      <simpara>
-      In a first step, PostgreSQL divides the complete range of
+      As a first step, PostgreSQL divides the complete range of
       possible xids into two halves with the two split-points
       'txid_current' and 'txid_current + 2^31'. The half behind
       'txid_current' is considered to represent xids of the
@@ -975,13 +975,13 @@
    </para>
 
    <para>
-    At what point in time the freeze operation will take place?
+    At what point in time does the freeze operation take place?
 
     <itemizedlist>
      <listitem>
       <simpara>
        When a client issues the SQL command VACUUM with its
-       FREEZE option. In this case, all such pages are
+       FREEZE option. In this case, all pages are
        processed that are marked in the Visibility Map
        to potentially have unfrozen rows.
       </simpara>
@@ -989,12 +989,12 @@
      <listitem>
       <simpara>
        When a client issues the SQL command VACUUM without any
-       option but finds that there are xids older than
+       options but finds that there are xids older than
        <xref linkend="guc-vacuum-freeze-table-age"/>
        (default: 150 million) minus
        <xref linkend="guc-vacuum-freeze-min-age"/>
        (default: 50 million).
-       As before, all such pages are processed that are
+       As before, all pages are processed that are
        marked in the Visibility Map to potentially have unfrozen
        rows.
       </simpara>
@@ -1008,11 +1008,11 @@
       <itemizedlist>
        <listitem>
         <simpara>
-         In the <emphasis>normal mode</emphasis>, he skips
+         In the <emphasis>normal mode</emphasis>, it skips
          pages with row versions that are younger than
          <xref linkend="guc-vacuum-freeze-min-age"/>
          (default: 50 million) and works only on pages where
-         all xids are older. The skipping of jung xids prevents
+         all xids are older. The skipping of young xids prevents
          work on such pages, which are likely to be changed
          by one of the future SQL commands.
         </simpara>
@@ -1020,7 +1020,7 @@
        <listitem>
         <simpara>
          The process switches
-         to an <emphasis>aggressive mode</emphasis> if he recognizes
+         to an <emphasis>aggressive mode</emphasis> if it recognizes
          that for the processed table their oldest xid exceeds
          <xref linkend="guc-autovacuum-freeze-max-age"/>
          (default: 200 million). The value of the oldest unfrozen
@@ -1038,12 +1038,12 @@
 
    <para>
     In the first two cases and with autovacuum in
-    <emphasis>aggressive mode</emphasis>, the system knowns
+    <emphasis>aggressive mode</emphasis>, the system knows
     to which value the oldest unfrozen xid has moved forward and
     logs the value in <emphasis>pg_class.relfrozenxid</emphasis>.
     The distance between this value and the 'txid_current' split
     point becomes smaller, and the distance to 'txid_current + 2^31'
-    larger than before.
+    becomes larger than before.
    </para>
 
    <figure id="tutorial-freeze-figure">
@@ -1069,7 +1069,7 @@
     running <firstterm>autovacuum daemon</firstterm>. If the
     daemon detects that for a table <firstterm>
     autovacuum_freeze_max_age</firstterm> is exceeded, it starts
-    an AUTOVACUUM process in the <emphasis>aggressive mode</emphasis>
+    an AUTOVACUUM process in <emphasis>aggressive mode</emphasis>
     (see above) &mdash; even if AUTOVACUUM is disabled.
    </para>
 
@@ -1079,8 +1079,8 @@
     The <link linkend="glossary-vm">Visibility Map</link>
     (VM) contains two flags &mdash; stored as
     two bits &mdash; for each page of the heap. If the first bit
-    is set, it indicates that the associated page does not
-    contain any bloat. If the second one is set, it indicates
+    is set, that indicates that the associated page does not
+    contain any bloat. If the second one is set, that indicates
     that the page contains only frozen rows.
    </para>
 
@@ -1099,7 +1099,7 @@
    <para>
     The setting of the flags is silently done by VACUUM
     and AUTOVACUUM during their bloat and freeze operations.
-    This is done to accelerate future vacuum actions,
+    This is done to speed up future vacuum actions,
     regular accesses to heap pages, and some accesses to
     the index. Every data-modifying operation on any row
     version of the page clears the flags.
@@ -1122,7 +1122,7 @@
     linkend="planner-stats">Query Planner</link> to make optimal
     decisions for the generation of execution plans. This
     information can be gathered with the SQL commands ANALYZE
-    or VACUUM ANALYZE. But also autovacuum processes gather
+    or VACUUM ANALYZE. But autovacuum processes also gather
     such information. Depending on the percentage of changed rows
     per table <xref linkend="guc-autovacuum-analyze-scale-factor"/>,
     the autovacuum daemon starts autovacuum processes to collect
@@ -1144,7 +1144,7 @@
     <link linkend="tutorial-transactions">Transactions</link>
     are a fundamental concept of relational database systems.
     Their essential point is that they bundle multiple
-    read- or write-operations into a single, all-or-nothing
+    read- or write-operations into a single all-or-nothing
     operation. Furthermore, they separate and protect concurrent
     actions of different connections from each other. Thereby
     they implement the ACID paradigm.
@@ -1152,7 +1152,7 @@
 
    <para>
     In <productname>PostgreSQL</productname> there are two ways
-    to establish a transaction. The explicite way uses the keywords
+    to establish a transaction. The explicit way uses the keywords
     <link linkend="sql-begin">BEGIN</link> and
     <link linkend="sql-commit">COMMIT</link> (respectively
     <link linkend="sql-rollback">ROLLBACK</link>) before
@@ -1188,9 +1188,9 @@
    </para>
 
    <para>
-    The atomicity also affects the visibility of changes. All
+    The atomicity also affects the visibility of changes. No
     connections running simultaneously to a data modifying
-    transaction will never see any change before the
+    transaction will ever see any change before the
     transaction successfully executes a <command>COMMIT</command>
     &mdash; even in the lowest
     <link linkend="transaction-iso">isolation level</link>
@@ -1221,7 +1221,7 @@
    </para>
 
    <para>
-    <productname>PostgreSQL</productname> overcomes the
+    <productname>PostgreSQL</productname> overcomes this
     problem by showing only such row versions to other
     transactions whose originating transaction is
     successfully committed. It skips all row versions of
@@ -1229,9 +1229,9 @@
     <productname>PostgreSQL</productname> solves one more
     problem. Even the single <command>COMMIT</command>
     command needs a short time interval for its execution.
-    Therefor its critical 'dead-or-survival' phase
+    Therefore its critical 'dead-or-survival' phase
     runs in a priviledged mode where it cannot be
-    interupted by other processes.
+    interrupted by other processes.
    </para>
 
    <bridgehead renderas="sect2">What are the benefits?</bridgehead>
@@ -1247,10 +1247,10 @@
     the transfers of some money from one account to another.
     It is obvious
     that the decrease of the one and the increase of the
-    other are impartible. Nevertheless, there is no particular
+    other must be indivisible. Nevertheless, there is no particular
     need for an application to do something to ensure the
     <glossterm linkend="glossary-atomicity">atomicity</glossterm>
-    of its behavior. It's enough to surround them with
+    of this behavior. It's enough to surround them with
     <command>BEGIN</command> and <command>COMMIT</command>.
    </para>
 
@@ -1260,10 +1260,10 @@
     conditions. In such cases, the application simply issues a
     <command>ROLLBACK</command> command instead of a
     <command>COMMIT</command>. The <command>ROLLBACK</command>
-    cancels the transaction, and all changes made so far retain
+    cancels the transaction, and all changes made so far remain
     invisible forever; it's like they never happened. There
     is no need for the application to log its activities and
-    undo every single step.
+    undo every step of the transaction separately.
    </para>
 
    <para>
@@ -1282,7 +1282,7 @@
    <para>
     Also, all self-evident &mdash; but possibly not obvious
     &mdash; low-level demands on the database system are
-    ensured; e.g., index entries for rows must become
+    ensured; e.g. index entries for rows must become
     visible at the same moment as the rows themselves.
    </para>
 
@@ -1307,7 +1307,7 @@
 
    <para>
     Nothing is perfect and failures inevitably happen.
-    However, the most common types of failures are
+    However, the most common types of failure are
     well known and <productname>PostgreSQL</productname>
     implements strategies to overcome them.
     Such strategies use parts of the previously presented
@@ -1356,7 +1356,7 @@
     actions. The WAL records are written first. Second,
     the data itself shall exist in the heap and index files.
     In opposite to the WAL records, this part may or may
-    not be transferred entirely from shared buffers to the files.
+    not have been transferred entirely from shared buffers (=RAM) to the files.
    </para>
    <para>
     The automatic recovery searches within the WAL files for
@@ -1378,7 +1378,7 @@
 
    <bridgehead renderas="sect3">Disk crash</bridgehead>
    <para>
-    If a disk crashes, the course of actions described previously
+    If a disk crashes, the course of action described previously
     cannot work. It is likely that the WAL files and/or the
     data and index files are no longer available. You need
     to take special actions to overcome such situations.
@@ -1453,14 +1453,14 @@
     <link linkend="backup-file">copy</link>
     of the cluster's directory structure and files. In
     case of severe problems such a copy can serve as
-    the source of a recovery. But in order to get a
+    the source of recovery. But in order to get a
     <emphasis>USABLE</emphasis> backup by this method,
     the database server <emphasis>MUST</emphasis> be
     shut down during the complete runtime of the copy
     command!
    </para>
    <para>
-    The apparent disadvantage of this method is that there
+    The obvious disadvantage of this method is that there
     is a downtime where no user interaction is possible.
    </para>
 
@@ -1515,7 +1515,7 @@
     If configured, the
     <glossterm linkend="glossary-wal-archiver">Archiver process</glossterm>
     will automatically copy every single WAL file to a save location.
-    <link linkend="backup-archiving-wal">It's configuration</link>
+    <link linkend="backup-archiving-wal">Its configuration</link>
     consists mainly of a string, which contains a copy command
     in the operating system's syntax. In order to protect your
     data against a disk crash, the destination location

---

From: Jürgen Purtz <[email-masked]>
Date: Tue, 21 Jul 2020 13:51:07 +0200

On 18.07.20 19:17, Erik Rijkers wrote:
> There are still far too many Unneeded Capitals On Words for my taste 
> but I have not changed many of those. We could use some more opinions 
> on that, I suppose. (if it becomes too silent maybe include the 
> pgsql-hackers again?)
>
> Thanks,
>
>
> Erik Rijkers

The attached patch contains:

- integration of Erik's suggestions

- coordination of terms in text, graphic and glossary

- some changes in upper-case usage

- fewer usage of <firstterm> with two exceptions: The first chapter 4.1 
emphasize all important terms to help beginners in their learning 
process; chapter 4.5. emphasize the term 'autovacuum' to straighten the 
fact that - despite its similarities - the tool autovacuum is something 
else than the SQL command vacuum.

--

Jürgen Purtz

 
index 0000000000..2be9898d98
@@ -0,0 +1,1563 @@
+    <glossterm linkend="glossary-instance">instance</glossterm> which
+    is a group of tightly coupled server-side processes plus a
+    At startup time, an <firstterm>instance</firstterm> is initiated by the
+    The <firstterm>Postmaster</firstterm> process loads the
+    configuration files, allocates
+    <firstterm>Shared Memory</firstterm>,
+    <glossterm linkend="glossary-autovacuum">Autovacuum</glossterm>,
+    this request is handled in a first step by the
+    <firstterm>Postmaster</firstterm> process. It checks authorization,
+    Client requests like <command>SELECT</command> or
+    <command>UPDATE</command> usually lead to the
+    <firstterm>autovacuum</firstterm> process,
+    <glossterm linkend="glossary-checkpoint">Checkpoints</glossterm>.
+    A <firstterm>Checkpoint</firstterm>
+    recommended to transfer a copy of the
+    <firstterm> WAL files</firstterm>
+    The <firstterm>Statistics Collector</firstterm> collects
+    counters about accesses to <firstterm>SQL objects</firstterm>
+    like tables, rows, indexes, pages, and more. It stores the
+    obtained information in system tables.
+    The <firstterm>Logger</firstterm> writes
+    A <glossterm linkend="glossary-server">server</glossterm> contains one or more
+    <glossterm linkend="glossary-db-cluster">database clusters</glossterm>
+    (<glossterm linkend="glossary-db-cluster">clusters</glossterm>
+    for short). Each cluster contains three or more
+    <glossterm linkend="glossary-database">databases</glossterm>.
+    Each database can contain many
+    <glossterm linkend="glossary-schema">schemas</glossterm>.
+    A schema can contain
+    <glossterm linkend="glossary-table">tables</glossterm>,
+    <glossterm linkend="glossary-view">views</glossterm>, and a lot
+    of other objects. Each table or view belongs to a single schema
+    only; they cannot belong to another schema as well. The same is
+    A cluster is the outer container for a
+    database of any cluster. Database <literal>template0</literal>
+    is created during the initialization phase of the cluster.
+    of the cluster that a user might need,
+    of all other databases, no client
+    schemas contain the other
+    Schemas are namespaces for
+    their SQL objects and ensure &mdash; with one
+    types of SQL objects. E.g., it is not possible
+    schema. But it is possible to have
+    schemas. In this case, the two tables
+    Some schemas are predefined. <literal>public</literal>
+    acts as the default schema and contains all
+    SQL objects. Instead, it is recommended to
+    create a separate schema that
+    There are many different SQL object
+    cluster, independent from
+    subdirectory per database exists. The names of those
+    subdirectories consist of numbers. These are the internal
+    Object Identifiers (OID), which are numbers to identify
+    the database definition in the
+    Within the database-specific
+    every table and every index to store heap and index
+    data. Those files are accompanied by files for the
+    In analogy to the database-specific
+    <glossterm linkend="glossary-sql-object">Global SQL Objects</glossterm>.
+    One type of such Global SQL Objects are
+    the tablespaces, not the tablespaces themselves.
+    cluster and remain alive as long as
+    information about the status of each transaction:
+    in_progress, committed, aborted, or sub_committed.
+    tablespaces.
+    files of the cluster are stored here. As long as the
+    instance is up and running, the file
+    and contains the process ID (pid) of the
+    Postmaster which has started the instance.
+    When many transactions are running simultaneously, things can
+    get complicated. Sometimes transactions get aborted via
+    <command>ROLLBACK</command> immediately or after a lot of other activities, sometimes
+      <literal>xmin</literal> and <literal>xmax</literal>
+      indicate the range from where to where
+      space occupied by all dead row versions is called
+      <glossterm linkend="glossary-bloat">bloat</glossterm>.
+      way. The next chapter explains how <firstterm>autovacuum</firstterm>
+      fulfills this task.
+    As we have seen in the previous chapter, the database
+    tends to occupy more and more disk space, the
+    <glossterm linkend="glossary-bloat">bloat</glossterm>.
+    <command>VACUUM</command> and the automatically running
+    <firstterm>autovacuum</firstterm> processes clean up
+    by eliminating bloat.
+     <firstterm>Autovacuum</firstterm> runs automatically by
+     <command>VACUUM</command> fit well for most standard
+    Client processes can issue the SQL command <command>VACUUM</command> at arbitrary
+    <firstterm>Autovacuum</firstterm> processes run as part of the
+    <link linkend="glossary-instance">instance</link> at the server.
+    There is a constantly running <firstterm>autovacuum</firstterm> daemon.
+    It permanently controls the state of all databases based on values that
+    are collected by the
+    <link linkend="glossary-stats-collector">Statistics Collector</link>
+    and starts <firstterm>autovacuum</firstterm> processes whenever it detects
+    certain situations. Thus, it's a dynamic behavior of
+    <productname>PostgreSQL</productname> with the intention to tidy
+    up &mdash; whenever it is appropriate.
+    <command>VACUUM</command>, as well as
+    <firstterm>autovacuum</firstterm>, don't just eliminate bloat.
+    intensive, which can hinder other activities, <firstterm>autovacuum</firstterm>
+    The SQL command <command>VACUUM</command> runs immediately
+    and without any time gaps.
+    elimination operation must evaluate <literal>xmax</literal>
+    against several criteria which all must apply:
+      <literal>xmax</literal> must be different from zero because a
+      value of zero indicates that the row version is still valid.
+      <literal>xmax</literal> must contain an xid which is older
+      than the oldest xid of all
+      The transaction of <literal>xmax</literal> must be committed. If it was rollback-ed,
+    actions. Only in rare situations (or in the case of <command>VACUUM FULL</command>),
+    it remains occupied by <productname>PostgreSQL</productname>
+    and will be used by future <command>INSERT</command> or
+    <command>UPDATE</command> commands concerning this row or a
+    completely different one.
+       When a client issues the SQL command <command>VACUUM</command>
+       in its default format, i.e., without any option. To boost performance,
+       in this and the next case <command>VACUUM</command> does not
+       read and act on all pages of the heap.
+       When a client issues the SQL command <command>VACUUM</command>
+       with the option <command>FREEZE</command>. (In this case,
+       it undertakes much more actions, see
+       When a client issues the SQL command <command>VACUUM</command>
+       with the option <command>FULL</command>.
+       When an <firstterm>autovacuum</firstterm> process acts. For optimization
+       <command>VACUUM</command>. Additionally, it ignores tables with few modifications;
+    don't use <literal>xmin/xmax</literal>. Nevertheless, such index
+    entries, which would lead to outdated row versions, are released
+    accordingly.       (??? more explanations ???)
+    wraparound point, there are cases where <literal>xmin</literal> has
+    a higher value than <literal>xmax</literal>, although their meaning
+    is said to be older than <literal>xmax</literal>.
+    described that sometimes <literal>xmin</literal> is
+    higher than <literal>xmax</literal>. The far
+    must be between <literal>xmin</literal> and <literal>xmax</literal>,
+    and the corresponding transactions of <literal>xmin</literal>
+    and <literal>xmax</literal> must be committed. However,
+    <productname>PostgreSQL</productname> has to consider the
+    possibility of wraparounds.
+    idea of the solution is to use the 'between
+    <literal>xmin</literal> and <literal>xmax</literal>'
+      As a first step, <productname>PostgreSQL</productname>
+      divides the complete range of
+      row version with <literal>xmin</literal> equal to that value, it would
+      the future use of <literal>xmin/xmax</literal> and indicates
+       <literal>xmax</literal> must be zero because only
+       non-deleted rows can be visible 'forever'.
+       <literal>xmin</literal> must be older than all currently
+       existing transactions. This guarantees that no existing
+       transaction can modify or delete the version.
+       The transaction of <literal>xmin</literal> must be committed.
+       When a client issues the SQL command <command>VACUUM</command>
+       with its <command>FREEZE</command> option. In this case, all
+       pages are processed that are marked in the Visibility Map
+       When a client issues the SQL command <command>VACUUM</command> without
+       any options but finds that there are xids older than
+       When an <firstterm>autovacuum</firstterm> process runs. Such
+       a process acts in one of two modes:
+         xid is stored per table in <literal>pg_class.relfrozenxid</literal>.
+         In this <emphasis>aggressive mode</emphasis> <firstterm>autovacuum</firstterm>
+    In the first two cases and with <firstterm>autovacuum</firstterm> in
+    logs the value in <literal>pg_class.relfrozenxid</literal>.
+    The <firstterm>autovacuum</firstterm> processes are initiated by the
+    constantly running <firstterm>autovacuum</firstterm> daemon.
+    If the daemon detects that for a table
+    <firstterm>autovacuum_freeze_max_age</firstterm> is exceeded, it
+    starts an <firstterm>autovacuum</firstterm> process in
+    <emphasis>aggressive mode</emphasis>
+    (see above) &mdash; even if <firstterm>autovacuum</firstterm> is disabled.
+     not with a row or a row version. The flags are set
+    The setting of the flags is silently done by <command>VACUUM</command>
+    and <firstterm>autovacuum</firstterm> during their bloat and freeze operations.
+    As long as <command>VACUUM</command> or
+    <firstterm>autovacuum</firstterm> change the free space
+    information can be gathered with the SQL commands
+    <command>ANALYZE</command> or <command>VACUUM ANALYZE</command>.
+    But <firstterm>autovacuum</firstterm> processes also gather
+    the <firstterm>autovacuum</firstterm> daemon starts
+    <firstterm>autovacuum</firstterm> processes to collect
+    <command>SELECT</command> commands issued inside a
+    <glossterm linkend="glossary-backend">Backend process</glossterm>,
+    closed properly and the <literal>postmaster.pid</literal>
+    not have been transferred entirely from Shared Memory
+    to the files.
+       Logical backup via <command>pg_dump</command>
+       Continuous archiving based on <command>pg_basebackup</command>
+       and WAL files
+    The other two strategies run during regular operating
+    times.
+    <link linkend="continuous-archiving">This method</link>
+    basebackup in order to recreate
+    any state of the cluster between the time of
+    of a basebackup as well as of the
+    copy the basebackup and the
+    archived WAL files to
+<!-- ToDo: replication, index-types, extension mechanism, ...
 
 <!-- tutorial -->
 
 <!-- user's guide -->
index 0000000000..723d67bd8d
+    Autovacuum
+    Logger
index 0000000000..4490bf51e1
+   id="svg306"
+     id="metadata310">
+     inkscape:window-width="1048"
+     inkscape:window-height="771"
+     id="namedview308"
+     inkscape:current-layer="svg306" />
+     id="title2">PG Overall Server Architecture</title>
+     id="defs70">
+         id="title6">UML Note (200 x 20 px)</title>
+         id="path8" />
+         id="title11">UML Note (250 x 20 px)</title>
+         id="path13" />
+         id="title16">UML Note (100 x 35 px)</title>
+         id="path18" />
+         id="title21">UML Note (170 x 50 px)</title>
+         id="path23" />
+         id="title26">UML State (300x120)</title>
+         id="rect28" />
+         id="title31">UML State (350x120)</title>
+         id="title36">Disc</title>
+         id="ellipse38" />
+         id="path42" />
+         id="path44" />
+         id="title47">Laptop</title>
+         id="path49" />
+         id="path53" />
+         id="path55" />
+         id="path57" />
+         id="path59" />
+         id="path64" />
+         id="path67" />
+     id="rect72" />
+     id="text74">Client</text>
+     id="text76">Server</text>
+     id="use78" />
+     id="g96">
+       id="use80" />
+       id="text82">maintenance_work_mem (per connection)</text>
+       id="text84">work_mem (per query operation)</text>
+       id="text86">autovacuum_work_mem (per worker process)</text>
+       id="text88">temp_buffer (per connection)</text>
+       id="text90">...</text>
+       id="use92" />
+       id="text94">Individual Memory</text>
+     id="g110">
+       id="use98" />
+       id="text100">shared_buffers (heap and index)</text>
+       id="text102">wal_buffers (WAL records)</text>
+       id="text104">...</text>
+       id="use106" />
+       id="text108">Shared Memory (per Instance)</text>
+     id="g116">
+       id="rect112" />
+       id="text114">Postmaster</text>
+     id="path118" />
+     id="g124">
+       id="circle120" />
+       id="text122">1</text>
+     id="g134">
+       id="rect126" />
+       id="text128">Backend processes (one per connection)</text>
+       id="path130" />
+       id="path132" />
+     id="path136" />
+     id="g142">
+       id="circle138" />
+       id="text140">3</text>
+     id="path144" />
+     id="g150">
+       id="use146" />
+       id="text148">Creates backend processes</text>
+     id="g156">
+       id="circle152" />
+       id="text154">2</text>
+     id="path158" />
+     id="path160" />
+     id="path162" />
+     id="g168">
+       id="rect164" />
+       id="text166">WAL Writer</text>
+     id="g178">
+       id="rect174" />
+       id="text176">Checkpointer</text>
+     id="path180" />
+     id="path182" />
+     id="path184" />
+     id="g192">
+       id="use186" />
+       id="text188">Checkpoint</text>
+       id="text190">Record</text>
+     id="g198">
+       id="rect194" />
+       id="text196">Background Writer</text>
+     id="path200" />
+     id="path202" />
+     id="g208">
+       id="rect204" />
+       id="text206">WAL Archiver</text>
+     id="path210" />
+     id="path212" />
+     id="g222">
+       id="rect214" />
+       id="text216">Autovacuum</text>
+       id="path218" />
+       id="path220" />
+     id="g228">
+       id="rect224" />
+       id="text226">Logger</text>
+     id="g234">
+       id="rect230" />
+       id="text232">Stats Collector</text>
+     id="g244">
+       id="use236" />
+       id="text238">Log</text>
+       id="text240">text lines,</text>
+       id="text242">sequential</text>
+     id="path246" />
+     id="g258">
+       id="use248" />
+       id="text250">Heap and</text>
+       id="text252">Index</text>
+       id="text254">binary blocks,</text>
+       id="text256">random</text>
+     id="path260" />
+     id="g270">
+       id="use262" />
+       id="text264">Read heap and index</text>
+       id="text266">pages and transfer</text>
+       id="text268">them to shared_buffers</text>
+     id="g280">
+       id="use272" />
+       id="text274">WAL</text>
+       id="text276">binary records,</text>
+       id="text278">sequential</text>
+     id="g288">
+       id="use282" />
+       id="text284">Archived</text>
+       id="text286">WAL</text>
+     id="path290" />
+     id="g296">
+       id="use292" />
+       id="text294">Via TCP/IP or socket</text>
+     id="g304">
+       id="text298">RAM</text>
+       id="text300">PROCESSES</text>
+       id="text302">FILES</text>
index 0000000000..aec5811c54
+    <text x="10" y="20" class="text_normal">Autovacuum</text>
+    <text x="10" y="20" class="text_normal">Logger</text>
 
  </part>

 

    <para>
 
-    <itemizedlist>
-     <listitem>
-      <para>
 
-     <listitem>
-      <para>
 
-    </itemizedlist>
-   </para>
+    <listitem>
+     <para>
 
    <para>

---

From: PASCAL CROZET <[email-masked]>
Date: Tue, 21 Jul 2020 23:49:08 +0000

Hi all,

I want to import XML file into PG database table.

I've find functions to get the XML content of a cell after imported an XML file with the pg_get_file function.

But, I want to explode the XML content to colums. How can I do this ?

PG 10 under Ubuntu 18

_________________________________

Cordialement, Pascal CROZET

DBA - Qualis Consulting

• 300 Route Nationale 6 – 69760 LIMONEST

_________________________________

---

From: Peter Eisentraut <[email-masked]>
Date: Tue, 1 Sep 2020 23:30:11 +0200

Again, I don't see how this belongs into the tutorial.  It is mostly 
advanced low-level information that is irrelevant for someone starting 
up, it is not hands-on, so quite unlike the rest of the tutorial, and 
for the most part the information just duplicates what is already 
explained elsewhere.

---

From: Jürgen Purtz <[email-masked]>
Date: Wed, 2 Sep 2020 09:04:38 +0200

On 01.09.20 23:30, Peter Eisentraut wrote:
> It is mostly advanced low-level information that is irrelevant for 
> someone starting up,

That applies only to the VACUUM chapter. VACUUM and AUTOVACUUM are 
controlled by a lot of parameters. Therefor the current documentation 
concerning the two mechanism spreads the description across different 
pages (20.4, 25.1, VACUUM command). Because of the structure of our 
documentation that's ok. But we should have a summary page somewhere - 
not necessarily in the tutorial.

> the most part the information just duplicates what is already 
> explained elsewhere.

That is the nature of a tutorial respectively a summary.

--

J. Purtz

---

From: Peter Eisentraut <[email-masked]>
Date: Thu, 10 Sep 2020 18:26:59 +0200

> not necessarily in the tutorial.

There is probably room for improvement, but the section numbers you 
mention are not about VACUUM, AFAICT, so I can't really comment on what 
you have in mind.

---

From: Jürgen Purtz <[email-masked]>
Date: Fri, 11 Sep 2020 09:49:23 +0200

On 10.09.20 18:26, Peter Eisentraut wrote:
> mention are not about VACUUM, AFAICT, so I can't really comment on 
> what you have in mind.
>
Because of the additional chapter for the 'tutorial' on my local 
computer, the numbers increased for me. The regular chapter numbers are 
19.4 and 24.1. Sorry for the confusion. In detail:

19.4: parameters to configure the server, especially five parameters 
'vacuum_cost_xxx'.

19.10: parameters to configure autovacuum.

19.11: parameters to configure client connections, especially five 
parameters 'vacuum_xxx' concerning their freeze-behavior.

24.1: explains the general necessity of (auto)vacuum and their strategies.

The page about the SQL command VACUUM explains the different options 
(FULL, FREEZE, ..) and their meaning.

--

Jürgen Purtz

---

From: "David G. Johnston" <[email-masked]>
Date: Wed, 21 Oct 2020 13:33:54 -0700

> That is the nature of a tutorial respectively a summary.
I've begun looking at this and have included quite a few html comments
within the patch.  However, the two main items that I have found so far are:

One, I agree with Peter that this seems misplaced in Tutorial.  I would
create a new Internals Chapter and place this material there, or maybe
consider a sub-chapter under "Overview of PostgreSQL Internals".  If this
is deemed to be of a more primary importance than the content in the
Internals section I would recommend placing it in Reference.  I feel it
does fit there and given the general importance of that section readers
will be inclined to click into it and skim over its content.

Two, I find the amount of detail being provided here to be on the too-much
side.  A bit more judicious use of links into the appropriate detail
chapters seems warranted.

I took a pretty heavy hand to the original section though aside from the
scope comment it can probably be considered a bit weighted toward style
preferences.  Though I did note/rewrite a couple of things that seemed
factually incorrect - and seemingly not done intentionally in the interest
of simplification.  Specifically the client connection process and, I
think, the relationship between the checkpointer and background writer.

I do like the idea and the general flow of the material so far - though I
haven't really looked at the overall structure yet, just started reading
and editing from the top of the new file.

I've attached the original 0007 patch and my diff against it applied to
HEAD.

Took a quick peek at the image (at the end) and while I will need a second
pass over this section regardless I figured I'd provide this subset of
feedback now in order to move things along a bit.

David J.

---

From: Jürgen Purtz <[email-masked]>
Date: Fri, 23 Oct 2020 15:58:46 +0200

On 21.10.20 22:33, David G. Johnston wrote:
> One, I agree with Peter that this seems misplaced in Tutorial.  I 
> would create a new Internals Chapter and place this material there, or 
> maybe consider a sub-chapter under "Overview of PostgreSQL 
> Internals".  If this is deemed to be of a more primary importance than 
> the content in the Internals section I would recommend placing it in 
> Reference.  I feel it does fit there and given the general importance 
> of that section readers will be inclined to click into it and skim 
> over its content.

I like the idea of dividing the material into two different chapters. 
The existing part "I. Tutorial" contains the first concrete steps: 
installation, creating database and database objects, using SQL basic 
and advanced features. Its typical audience consists of persons doing 
their first steps with PG. The new material is aimed at persons 
interested in implementation aspects of PG. Therefore, the part "VII. 
Internals" seems to be the natural place to integrate it, something like 
"Architecture and Implementation Aspects" or "Architecture and 
Implementation Cornerstones".

Creating such a chapter in "VII. Internals" will increase the existing 
chapter numbers 50 - 71, which may lead to some confusion. On the other 
hand the content can possibly be applied to all supported PG versions at 
the same time, which will lead to a consistent behavior. Extending one 
of the existing chapters won't work because all of them handle their own 
topic, eg.: "50. Overview of PostgreSQL Internals" (misleading title?) 
focuses on the handling of SQL statements from parsing to execution.

What are your thoughts?

--

J. Purtz

---

From: "David G. Johnston" <[email-masked]>
Date: Fri, 23 Oct 2020 09:15:14 -0700

On Fri, Oct 23, 2020 at 6:58 AM Jürgen Purtz <[email-masked]> wrote:

> the same time, which will lead to a consistent behavior. Extending one of
> the existing chapters won't work because all of them handle their own
v14 has already added a new chapter, installation from binaries.  It was
not back-patched.  To my knowledge no one brought up these points - numbers
changing or back-patching the new material.  I don't see that this
enhancement needs to be treated any differently.

David J.

---

From: Jürgen Purtz <[email-masked]>
Date: Mon, 26 Oct 2020 14:33:35 +0100

On 21.10.20 22:33, David G. Johnston wrote:
> Two, I find the amount of detail being provided here to be on the 
> too-much side.  A bit more judicious use of links into the appropriate 
> detail chapters seems warranted.
>
> I took a pretty heavy hand to the original section though aside from 
> the scope comment it can probably be considered a bit weighted toward 
> style preferences.  Though I did note/rewrite a couple of things that 
> seemed factually incorrect - and seemingly not done intentionally in 
> the interest of simplification.  Specifically the client connection 
> process and, I think, the relationship between the checkpointer and 
> background writer.
>
> I do like the idea and the general flow of the material so far - 
> though I haven't really looked at the overall structure yet, just 
> started reading and editing from the top of the new file.
>
> I've attached the original 0007 patch and my diff against it applied 
> to HEAD.
>
> Took a quick peek at the image (at the end) and while I will need a 
> second pass over this section regardless I figured I'd provide this 
> subset of feedback now in order to move things along a bit.
>
> David J.

The attached patch is an intermediate, mostly formal step. It includes:

- Moving the chapter to "Part VII. Internals".

- Changing the title of the current chapter "Chapter 50. Overview of 
PostgreSQL Internals" to "Overview of Query Handling" because the old 
title is too generic. This chapter is focused on the handling of queries.

- Integration of David's smaller suggestions. For the more important 
suggestions I need some days.

The patch is intended to give every interested person an overall 
impression of the chapter within its new position. Because it has moved 
from part 'Tutorial' to 'Internals' the text should be very accurate 
concerning technical issues - like all the other chapters in this part. 
A tutorial chapter has a more superficial nature.

--

J. Purtz

index 2d4ab85d45..5c3245c0ec 100644

   <sect1 id="tutorial-advanced-intro">
    <title>Introduction</title>
diff --git a/doc/src/sgml/arch-dev.sgml b/doc/src/sgml/arch-dev.sgml
index 7883c3cd82..9db0ae2c78 100644
--- a/doc/src/sgml/arch-dev.sgml
+++ b/doc/src/sgml/arch-dev.sgml
@@ -1,7 +1,7 @@
 <!-- doc/src/sgml/arch-dev.sgml -->
 
  <chapter id="overview">
-  <title>Overview of PostgreSQL Internals</title>
+  <title>Overview of Query Handling</title>
 
   <note>
    <title>Author</title>
index 0000000000..b6c0eb4a31
@@ -0,0 +1,1585 @@
+  <title>Overview of Architecture and Implementation</title>
+   Every DBMS implements basic strategies to ensure a fast
+   and robust system. This chapter provides an overview of the
+    clients do not have direct access to stored data. Instead,
+    the requested data in response. In the case of
+    <productname>PostgreSQL</productname>, the server launches a
+    single process for each connected client, referred to as a
+    <!-- DGJ: this whole next paragraph bothers me but I cannot justify
+         simply removing it nor have a possibly better suggestion.
+         In particular I disagree with categorizing this is a
+         "close" and "tightly-coupled" relationship -->
+    area located in RAM.
+    Notably, PostgreSQL does not utilize application threading within its
+    implementation.
+     <!-- DGJ: I've gotten the impression firstterm 
+          is overused, probably as a result of copy-paste -->
+    During <firstterm>instance</firstterm> startup time, the
+    process loads the
+    and starts supporting background processes:
+    <!-- DGJ: This is detailed, but wrong.  Either use less detail or correct detail.
+              See header of postmaster.c
+    When a client application tries to connect to a
+    this request is handled initially by the
+    can pick parts of the cluster, e.g., a single table or one
index 38e8aa0bbf..7490d3c9c2 100644
@@ -80,6 +80,7 @@
 %allfiles;
 
 <!-- developer's guide -->
 <!ENTITY arch-dev   SYSTEM "arch-dev.sgml">
 <!ENTITY bki        SYSTEM "bki.sgml">
 <!ENTITY catalogs   SYSTEM "catalogs.sgml">
index 730d5fdc34..e9e9f9495f 100644
@@ -248,6 +248,7 @@ break is not needed in a wider output rendering.
    </para>
   </partintro>
 
+  &architecture;
   &arch-dev;
   &catalogs;
   &protocol;

    <para>
 
-    <itemizedlist>
-     <listitem>
-      <para>
 
-     <listitem>
-      <para>
 
-    </itemizedlist>
-   </para>
+    <listitem>
+     <para>
 
    <para>

---

From: "David G. Johnston" <[email-masked]>
Date: Mon, 26 Oct 2020 07:53:43 -0700

Removing -docs as moderation won’t let me cross-post.

On Monday, October 26, 2020, David G. Johnston <[email-masked]>
wrote:

> On Monday, October 26, 2020, Jürgen Purtz <[email-masked]> wrote:
>
>> concerning technical issues - like all the other chapters in this part. A
>> tutorial chapter has a more superficial nature.
>>
> Haven’t reviewed the patches yet but...
>
> I still think that my comment applies even with the move to internals.
> The value here is putting together a coherent narrative and making deeper
> implementation details accessible.  If those details are already covered
> elsewhere in the documentation (not source code) links should be given
> serious consideration.
>
> David J.
>
>

---

From: Jürgen Purtz <[email-masked]>
Date: Fri, 30 Oct 2020 11:57:04 +0100

On 26.10.20 15:53, David G. Johnston wrote:
> On Monday, October 26, 2020, David G. Johnston 
> <[email-masked] <mailto:[email-masked]>> wrote:
>
>     On Monday, October 26, 2020, Jürgen Purtz <[email-masked]
>     <mailto:[email-masked]>> wrote:
>
>>         Two, I find the amount of detail being provided here to be on
>>         the too-much side.  A bit more judicious use of links into
>>         the appropriate detail chapters seems warranted.
>>
>         The patch is intended to give every interested person an
>         overall impression of the chapter within its new position.
>         Because it has moved from part 'Tutorial' to 'Internals' the
>         text should be very accurate concerning technical issues -
>         like all the other chapters in this part. A tutorial chapter
>         has a more superficial nature.
>
>     I still think that my comment applies even with the move to
>     internals.  The value here is putting together a coherent
>     narrative and making deeper implementation details accessible.  If
>     those details are already covered elsewhere in the documentation
>     (not source code) links should be given serious consideration.
>
>     David J.
>
Please find the new patch in the attachment after integrating David's 
suggestions: a) versus the last patch and b) versus master.

Notably it contains

  * nearly all of his suggestions (see sgml file for comments 'DGJ')
  * reduction of <firstterm>. This was a hangover from the
    pre-glossary-times. I tried to emphasis standard terms. This is no
    longer necessary because nowadays they are clearly defined in the
    glossary.

--

J. Purtz

diff --git a/doc/src/sgml/architecture.sgml b/doc/src/sgml/architecture.sgml
index b6c0eb4a31..e547a87d08 100644
--- a/doc/src/sgml/architecture.sgml
+++ b/doc/src/sgml/architecture.sgml
@@ -13,42 +13,26 @@
   <sect1 id="tutorial-ram-proc-file">
    <title>Collaboration of Processes, RAM, and Files</title>
    <para>
-    In a client/server architecture
-    clients do not have direct access to stored data. Instead,
-    they send requests to the server and receive
-    the requested data in response. In the case of
-    <productname>PostgreSQL</productname>, the server launches a
-    single process for each connected client, referred to as a
-    <glossterm linkend="glossary-backend">Backend process</glossterm>.
-
-
-    <!-- DGJ: this whole next paragraph bothers me but I cannot justify
-         simply removing it nor have a possibly better suggestion.
-         In particular I disagree with categorizing this is a
-         "close" and "tightly-coupled" relationship -->
-
-
-    It acts in close cooperation with the
-    <glossterm linkend="glossary-instance">instance</glossterm> which
-    is a group of tightly coupled server-side processes plus a
-    <glossterm linkend="glossary-shared-memory">Shared Memory</glossterm>
-    area located in RAM.
-    Notably, PostgreSQL does not utilize application threading within its
-    implementation.
-   </para>
-
-
-     <!-- DGJ: I've gotten the impression firstterm 
-          is overused, probably as a result of copy-paste -->
-
-
-   <para>
-    During <firstterm>instance</firstterm> startup time, the
-    <glossterm linkend="glossary-postmaster">Postmaster</glossterm>
-    process loads the
-    configuration files, allocates
-    <firstterm>Shared Memory</firstterm>,
-    and starts supporting background processes:
+    In a client/server architecture clients do not have direct access
+    to database files and the data stored in them. Instead, they send
+    requests to the server and receive the requested data in the response.
+    In the case of <productname>PostgreSQL</productname>, the server
+    launches a single process for each client connection, referred to as a
+    <glossterm linkend="glossary-backend">Backend</glossterm> process.
+    Those Backend processes handle the client's requests by acting on the
+    <glossterm linkend="glossary-shared-memory">Shared Memory</glossterm>.
+    This leads to other activities (file access, WAL, vacuum, ...) of the
+    <glossterm linkend="glossary-instance">Instance</glossterm>. The
+    Instance is a group of server-side processes acting on a common
+    Shared Memory. Notably, PostgreSQL does not utilize application
+    threading within its implementation.
+   </para>
+
+   <para>
+    The first step in an Instance start is the start of the
+    <glossterm linkend="glossary-postmaster">Postmaster</glossterm>.
+    He loads the configuration files, allocates Shared Memory, and
+    starts the other processes of the Instance:
     <glossterm linkend="glossary-background-writer">Background Writer</glossterm>,
     <glossterm linkend="glossary-checkpointer">Checkpointer</glossterm>,
     <glossterm linkend="glossary-wal-writer">WAL Writer</glossterm>,
@@ -56,8 +40,11 @@
     <glossterm linkend="glossary-autovacuum">Autovacuum</glossterm>,
     <glossterm linkend="glossary-stats-collector">Statistics Collector</glossterm>,
     <glossterm linkend="glossary-logger">Logger</glossterm>, and more.
-    <xref linkend="tutorial-ram-proc-file-figure"/> visualizes
-    the main aspects of their collaboration.
+    Later, the Postmaster starts
+    <glossterm linkend="glossary-backend">Backend</glossterm> processes
+    which communicate with clients and handle their requests.
+    <xref linkend="tutorial-ram-proc-file-figure"/> visualizes the processes
+    of an Instance and the main aspects of their collaboration.
    </para>
 
    <figure id="tutorial-ram-proc-file-figure">
@@ -77,155 +64,110 @@
    </figure>
 
    <para>
-
-
-    <!-- DGJ: This is detailed, but wrong.  Either use less detail or correct detail.
-              See header of postmaster.c
-    -->
-
-
     When a client application tries to connect to a
     <glossterm linkend="glossary-database">database</glossterm>,
-    this request is handled initially by the
-    <firstterm>Postmaster</firstterm> process. It checks authorization,
-    starts a new <firstterm>Backend process</firstterm>,
-    and instructs the client application to connect to it. All
-    further client requests go to this process and are handled
-    by it.
+    this request is handled initially by the Postmaster. He
+    starts a new Backend process and instructs the client
+    application to connect to it. All further client requests
+    go to this process and are handled by it.
    </para>
 
    <para>
     Client requests like <command>SELECT</command> or
     <command>UPDATE</command> usually lead to the
-    necessity to read or write some data. In a first attempt
-    the client's <firstterm>Backend process</firstterm> tries
-    to get the information out of <firstterm>Shared
-    Memory</firstterm>. This <firstterm>Shared
-    Memory</firstterm> is a mirror of parts of the
-    <glossterm linkend="glossary-heap">heap</glossterm> and
-    <glossterm linkend="glossary-index">index</glossterm> files.
-    Because files are often larger than memory, it's likely that
-    the desired information is not (completely) available
-    in RAM. In this case the <firstterm>Backend process</firstterm>
-    must transfer additional file pages to
-    <firstterm>Shared Memory</firstterm>. Files are physically
-    organized in pages. Every transfer between files and
-    RAM is performed in units of complete pages; such transfers
-    do not change the size or layout of pages.
-   </para>
-
-   <para>
-    Reading file pages is much slower than reading
-    RAM. This is the primary motivation for the usage of
-    <firstterm>Shared Memory</firstterm>. As soon as one
-    of the <firstterm>Backend processes</firstterm> has
-    read pages into memory, those pages become available for all
-    other <firstterm>Backend processes</firstterm> for direct
-    access in RAM.
-   </para>
-
-   <para>
-    <firstterm>Shared Memory</firstterm> is limited in size.
-    Sooner or later, it becomes necessary to overwrite old RAM
-    pages. As long as the content of such pages hasn't
-    changed, this is not a problem. But in
-    <firstterm>Shared Memory</firstterm> also write
-    actions take place
-    &mdash; performed by any of the <firstterm>Backend
-    processes</firstterm> (or an
-    <firstterm>autovacuum</firstterm> process,
-    or other processes). Such modified pages are called
-    <firstterm>dirty pages</firstterm>.
-    Before <firstterm>dirty pages</firstterm> can be overwritten,
-    they must be written back to disk. This is a two-step process.
-   </para>
+    necessity to read or write some data. This is carried out
+    by the client's backend process. Reads involve a page-level
+    cache housed in Shared Memory (for details see:
+    <xref linkend="sysvipc"/>) for the benefit of all processes
+    in the instance. Writes also involve this cache, in additional
+    to a journal, called a write-ahead-log or WAL.
+   </para>
+
+   <para>
+    Shared Memory is limited in size. Thus, it becomes necessary
+    to evict pages. As long as the content of such pages hasn't
+    changed, this is not a problem. But in Shared Memory also
+    write actions take place. Modified pages are called dirty
+    pages or dirty buffers and before they can be evicted they
+    must be written back to disk. This happens regularly by the
+    Background Writer and the Checkpointer process to ensure
+    that the disk version of the pages are kept up-to-date.
+    The synchronisation from RAM to disk consists of two steps.
+   </para>
+
+<!-- DGJ: WAL should already be done well before page
+          eviction/overwriting comes into play.
+          This is good material but seems misplaced.
+     JuP: Really misplaced? Don't think so.
+-->
 
    <para>
     First, whenever the content of a page changes, a
     <glossterm linkend="glossary-wal-record">WAL record</glossterm>
-    is created out
-    of the delta-information (difference between the old and
-    the new content) and stored in another area of
-    <firstterm>Shared Memory</firstterm>. These
-    <firstterm>WAL records</firstterm> are read by the
-    <firstterm>WAL Writer</firstterm> process,
-    which runs in parallel to the <firstterm>Backend
-    processes</firstterm> and other processes of
-    the <firstterm>Instance</firstterm>. It writes
-    the continuously arising <firstterm>WAL records</firstterm> to
-    the end of the current
+    is created out of the delta-information (difference between the
+    old and the new content) and stored in another area of
+    Shared Memory. The parallel running WAL Writer process
+    reads them and appends them to the end of the current
     <glossterm linkend="glossary-wal-record">WAL file</glossterm>.
-    Because this writing is sequential, it is much
-    faster than the more or less random access
-    to data files with <firstterm>heap</firstterm>
-    and <firstterm>index</firstterm> information.
-    As mentioned, this WAL-writing happens
-    in an independent process. All
-    <firstterm>WAL records</firstterm> created out of one
-    <firstterm>dirty page</firstterm> must be transferred
-    to disk before the <firstterm>dirty page</firstterm>
-    itself can be transferred to disk.
-   </para>
-
-   <para>
-    Second, the transfer of <firstterm>dirty buffers</firstterm>
-    from <firstterm>Shared Memory</firstterm> to file must
-    take place. This is the primary task of the
-    <firstterm>Background Writer</firstterm> process. Because
-    I/O activities can block other processes significantly,
-    it starts periodically and acts only for a short period.
-    Doing so, its expensive I/O activities are spread over
-    time, avoiding debilitating I/O peaks. Also, the <firstterm>
-    Checkpointer</firstterm> process transfers
-    <firstterm>dirty buffers</firstterm> to file &mdash;
-    see next paragraph.
-   </para>
-
-   <para>
-    The <firstterm>Checkpointer</firstterm> creates
+    Such sequential writes are much faster than writes to random
+    positions of heap and index files. All WAL records created
+    out of one dirty page must be transferred to disk before the
+    dirty page itself can be transferred to disk in the second step.
+   </para>
+
+   <para>
+    Second, the transfer of dirty buffers from Shared Memory to
+    files must take place. This is the primary task of the
+    Background Writer process. Because I/O activities can block
+    other processes significantly, it starts periodically and
+    acts only for a short period. Doing so, its extensive (and
+    expensive) I/O activities are spread over time, avoiding
+    debilitating I/O peaks. Also, the Checkpointer process
+    transfers dirty buffers to file.
+   </para>
+
+   <para>
+    The Checkpointer creates
     <glossterm linkend="glossary-checkpoint">Checkpoints</glossterm>.
-    A <firstterm>Checkpoint</firstterm>
-    is a point in time when all older <firstterm>dirty buffers</firstterm>,
-    all older <firstterm>WAL records</firstterm>, and
-    finally a special <firstterm>Checkpoint record</firstterm>
-    have been written and flushed to disk.
-    After a <firstterm>Checkpoint</firstterm>, we say
-    data files and <firstterm>WAL files</firstterm> are in sync.
-    In case of a recovery (after a crash of the instance)
-    it can be relied upon that the information of all
-    <firstterm>WAL records</firstterm> preceding
-    the last <firstterm>Checkpoint record</firstterm>
-    were already integrated into the data files. This
-    speeds up the recovery.
+    A Checkpoint is a point in time when all older dirty buffers,
+    all older WAL records, and finally a special Checkpoint record
+    have been written and flushed to disk. Heap and index files
+    on the one hand and WAL files on the other hand are in sync.
+    Previous WAL is no longer required. In other words,
+    a possibly occurring recovery, which integrates the delta
+    information of WAL into heap and index files, will happen
+    by replaying only WAL past the last recorded checkpoint
+    on top of the current heap and files. This speeds up recovery.
    </para>
 
    <para>
-    As a result of data changes,
-    <firstterm>WAL records</firstterm> arise and get written
-    to <firstterm>WAL files</firstterm>.
-    Those <firstterm>WAL files</firstterm> &mdash; in combination with
-    a previously taken <firstterm>Base Backup</firstterm> &mdash;
-    are necessary to restore a database after a crash of the
-    disk on which data files have been stored. Therefore it is
-    recommended to transfer a copy of the
-    <firstterm> WAL files</firstterm>
-    to a second, independent place. The purpose of the
-    <firstterm>WAL Archiver</firstterm> process is to perform
-    this copy action.
+    While the Checkpointer ensures that a running system can crash
+    and restart itself in a valid state, the administrator needs
+    to handle the case where the heap and files themselves become
+    corrupted (and possibly the locally written WAL, though that is
+    less common). The options and details are covered extensively
+    in the backup and restore section (<xref linkend="backup"/>).
+    For our purposes here, note just that the WAL Archiver process
+    can be enabled and configured to run a script on filled WAL
+    files &mdash; usually to copy them to a remote location.
    </para>
 
+
+<!-- DGJ: after the heavy focus on client processes and data these two
+          seem to come out of left field.  Skipping over for now.
+     JuP: Don't skip, we want to explain all elements of the graphic.
+-->
+
    <para>
-    The <firstterm>Statistics Collector</firstterm> collects
-    counters about accesses to <firstterm>SQL objects</firstterm>
-    like tables, rows, indexes, pages, and more. It stores the
-    obtained information in system tables.
+    The Statistics Collector collects counters about accesses to
+    SQL objects like tables, rows, indexes, pages, and more. It
+    stores the obtained information in system tables.
    </para>
 
    <para>
-    The <firstterm>Logger</firstterm> writes
-    text lines about serious and less serious events which can happen
-    during database access, e.g., wrong password, no permission,
-    long-running queries, etc.
+    The Logger writes text lines about serious and less serious
+    events which can happen during database access, e.g., wrong
+    password, no permission, long-running queries, etc.
    </para>
 
   </sect1>
@@ -286,46 +228,40 @@
     such as <literal>my_db</literal>, will be copied from the
     <literal>template1</literal> database. Due to the unique
     role of <literal>template0</literal> as the pristine original
-    of all other databases, no client
-    can connect to it.
+    of all other databases, no client can connect to it.
    </para>
 
    <para>
-    Every database must contain <glossterm linkend="glossary-schema">
-    at least one schema</glossterm> because
-    schemas contain the other
-    <glossterm linkend="glossary-sql-object">SQL Objects</glossterm>.
-    Schemas are namespaces for
-    their SQL objects and ensure &mdash; with one
-    exception &mdash; that within their scope, names are used only once across all
-    types of SQL objects. E.g., it is not possible
+    Every database must contain at least one schema because all
+    <glossterm linkend="glossary-sql-object">SQL Objects</glossterm>
+    are contained in a schema.
+    Schemas are namespaces for their SQL objects and ensure
+    (with one exception) that within their scope names are used
+    only once across all types of SQL objects. E.g., it is not possible
     to have a table <literal>employee</literal> and a view
-    <literal>employee</literal> within the same
-    schema. But it is possible to have
-    two tables <literal>employee</literal> in different
-    schemas. In this case, the two tables
+    <literal>employee</literal> within the same schema. But it is
+    possible to have two tables <literal>employee</literal> in
+    different schemas. In this case, the two tables
     are separate objects and independent of each
     other. The only exception to this cross-type uniqueness is that
     <glossterm linkend="glossary-unique-constraint">unique constraints
-    </glossterm> and the according <firstterm>unique index</firstterm>
-    use the same name.
+    </glossterm> and the according unique index
+    (<xref linkend="indexes-unique"/>) use the same name.
    </para>
 
    <para>
     Some schemas are predefined. <literal>public</literal>
-    acts as the default schema and contains all
-    <firstterm>SQL objects</firstterm> which are created
-    within <literal>public</literal> or without using an explicit schema
-    name. <literal>public</literal> should not contain user-defined
-    SQL objects. Instead, it is recommended to
-    create a separate schema that
-    holds individual objects like application-specific tables or
-    views. <literal>pg_catalog</literal> is a schema for all tables
-    and views of the <glossterm linkend="glossary-system-catalog">
-    System Catalog</glossterm>.
+    acts as the default schema and contains all SQL objects
+    which are created within <literal>public</literal> or
+    without using an explicit schema name. <literal>public</literal>
+    should not contain user-defined SQL objects. Instead, it is
+    recommended to create a separate schema that holds individual
+    objects like application-specific tables or views.
+    <literal>pg_catalog</literal> is a schema for all tables and views of the
+    <glossterm linkend="glossary-system-catalog">System Catalog</glossterm>.
     <literal>information_schema</literal> is a schema for several
-    tables and views of the <firstterm>System Catalog</firstterm>
-    in a way that conforms to the SQL standard.
+    tables and views of the System Catalog in a way that conforms
+    to the SQL standard.
    </para>
 
    <para>
@@ -334,11 +270,11 @@
     view, index, constraint, sequence, function, procedure,
     trigger, role, data type, operator, tablespace, extension,
     foreign data wrapper</firstterm>, and more. A few of them, the
-    <firstterm>Global SQL Objects</firstterm>,
-    are outside of the strict hierarchy:
-    All database names, all tablespace names, and all role names
-    are automatically known and available throughout the
-    cluster, independent from
+    <firstterm>Global SQL Objects</firstterm>, are outside of the
+    strict hierarchy: All <firstterm>database names</firstterm>,
+    all <firstterm>tablespace names</firstterm>, and all
+    <firstterm>role names</firstterm> are automatically known and
+    available throughout the cluster, independent from
     the database or schema in which they where defined originally.
     <xref linkend="tutorial-internal-objects-hierarchy-figure"/>
     shows the relation between the object types.
@@ -369,7 +305,7 @@
     <productname>PostgreSQL</productname> organizes long-lasting
     data as well as volatile state information about transactions
     or replication actions in the file system. Every
-    <firstterm>Cluster</firstterm> has its root directory
+    <xref linkend="glossary-db-cluster"/> has its root directory
     somewhere in the file system. In many cases, the environment
     variable <literal>PGDATA</literal> points to this directory.
     The example shown in
@@ -427,8 +363,8 @@
     subdirectories, there are files containing information about
     <glossterm linkend="glossary-sql-object">Global SQL Objects</glossterm>.
     One type of such Global SQL Objects are
-    <firstterm>tablespaces</firstterm>. In
-    <literal>global</literal> there is information about
+    <glossterm linkend="glossary-tablespace">tablespaces</glossterm>.
+    In <literal>global</literal> there is information about
     the tablespaces, not the tablespaces themselves.
    </para>
 
@@ -443,14 +379,14 @@
    <para>
     The subdirectory <literal>pg_xact</literal> contains
     information about the status of each transaction:
-    in_progress, committed, aborted, or sub_committed.
+    <literal>in_progress</literal>, <literal>committed</literal>,
+    <literal>aborted</literal>, or <literal>sub_committed</literal>.
    </para>
 
    <para>
     In <literal>pg_tblspc</literal>, there are symbolic links
-    that point to directories containing such<firstterm>
-    SQL objects</firstterm> that are created within
-    tablespaces.
+    that point to directories containing such SQL objects
+    that are created within tablespaces.
    </para>
 
    <para>
@@ -474,7 +410,7 @@
    <title>MVCC &mdash; Multiversion Concurrency Control</title>
 
    <para>
-    In most cases, <productname>PostgreSQL</productname> based applications
+    In most cases, <productname>PostgreSQL</productname> databases
     support many clients at the same time. Therefore, it is necessary to
     protect concurrently running requests from unwanted overwriting
     of other's data as well as from reading inconsistent data. Imagine an
@@ -533,7 +469,7 @@
    </para>
 
    <para>
-    The description in this chapter simplifies by omitting detail.
+    The description in this chapter simplifies by omitting some details.
     When many transactions are running simultaneously, things can
     get complicated. Sometimes transactions get aborted via
     <command>ROLLBACK</command> immediately or after a lot of other activities, sometimes
@@ -644,7 +580,7 @@
       xids grow, old row versions get out of scope over time.
       If an old row version is no longer valid for ALL existing
       transactions, it's called <firstterm>dead</firstterm>. The
-      space occupied by all dead row versions is called
+      space occupied by dead row versions is part of the
       <glossterm linkend="glossary-bloat">bloat</glossterm>.
      </simpara>
     </listitem>
@@ -680,13 +616,13 @@
     <glossterm linkend="glossary-bloat">bloat</glossterm>.
     This chapter explains how the SQL command
     <command>VACUUM</command> and the automatically running
-    <firstterm>autovacuum</firstterm> processes clean up
+    <firstterm>Autovacuum</firstterm> processes clean up
     by eliminating bloat.
    </para>
 
    <note>
     <para>
-     <firstterm>Autovacuum</firstterm> runs automatically by
+     Autovacuum runs automatically by
      default. Its default parameters as well as such for
      <command>VACUUM</command> fit well for most standard
      situations. Therefore a novice database manager can
@@ -696,30 +632,27 @@
    </note>
 
    <para>
-    Client processes can issue the SQL command <command>VACUUM</command> at arbitrary
-    points in time. DBAs do this when they recognize special situations,
-    or they start it in batch jobs which run periodically.
-    <firstterm>Autovacuum</firstterm> processes run as part of the
-    <link linkend="glossary-instance">instance</link> at the server.
-    There is a constantly running <firstterm>autovacuum</firstterm> daemon.
-    It permanently controls the state of all databases based on values that
-    are collected by the
+    Client processes can issue the SQL command <command>VACUUM</command>
+    at arbitrary points in time. DBAs do this when they recognize
+    special situations, or they start it in batch jobs which run
+    periodically. Autovacuum processes run as part of the
+    <link linkend="glossary-instance">Instance</link> at the server.
+    There is a constantly running Autovacuum daemon. It permanently
+    controls the state of all databases based on values that are collected by the
     <link linkend="glossary-stats-collector">Statistics Collector</link>
-    and starts <firstterm>autovacuum</firstterm> processes whenever it detects
+    and starts Autovacuum processes whenever it detects
     certain situations. Thus, it's a dynamic behavior of
     <productname>PostgreSQL</productname> with the intention to tidy
     up &mdash; whenever it is appropriate.
    </para>
 
    <para>
-    <command>VACUUM</command>, as well as
-    <firstterm>autovacuum</firstterm>, don't just eliminate bloat.
-    They perform additional tasks for minimizing future
+    <command>VACUUM</command>, as well as Autovacuum, don't just eliminate
+    bloat. They perform additional tasks for minimizing future
     I/O activities of themselves as well as of other processes.
-    This extra work can be done in a very efficient way
-    since in most cases the expensive physical access to pages
-    has taken place anyway to eliminate bloat.
-    The additional operations are:
+    This extra work can be done in a very efficient way since in most
+    cases the expensive physical access to pages has taken place anyway
+    to eliminate bloat. The additional operations are:
    </para>
 
    <itemizedlist>
@@ -758,7 +691,7 @@
     <emphasis>freeze</emphasis> is controlled by configuration
     parameters, runtime flags, and in extreme situations by
     the processes themselves. Because vacuum operations typically are I/O
-    intensive, which can hinder other activities, <firstterm>autovacuum</firstterm>
+    intensive, which can hinder other activities, Autovacuum
     avoids performing many vacuum operations in bulk. Instead,
     it carries out many small actions with time gaps in between.
     The SQL command <command>VACUUM</command> runs immediately
@@ -784,8 +717,8 @@
     <listitem>
      <simpara>
       <literal>xmax</literal> must contain an xid which is older
-      than the oldest xid of all
-      currently running transactions (min(pg_stat_activity.backend_xmin)).
+      than the oldest xid of all currently running transactions
+      <literal>(min(pg_stat_activity.backend_xmin))</literal>.
       This criterion guarantees that no existing or upcoming transaction
       will have read or write access to this row version.
      </simpara>
@@ -810,9 +743,9 @@
 
    <para>
     After the vacuum operation detects a superfluous row version, it
-    marks its space as free for future use of writing
-    actions. Only in rare situations (or in the case of <command>VACUUM FULL</command>),
-    is this space released to the operating system. In most cases,
+    marks its space as free for future use of writing actions. Only
+    in rare situations (or in the case of <command>VACUUM FULL</command>),
+    this space is released to the operating system. In most cases,
     it remains occupied by <productname>PostgreSQL</productname>
     and will be used by future <command>INSERT</command> or
     <command>UPDATE</command> commands concerning this row or a
@@ -860,7 +793,7 @@
 
      <listitem>
       <simpara>
-       When an <firstterm>autovacuum</firstterm> process acts. For optimization
+       When an Autovacuum process acts. For optimization
        purposes, it considers the Visibility Map in the same way as
        <command>VACUUM</command>. Additionally, it ignores tables with few modifications;
        see <xref linkend="guc-autovacuum-vacuum-threshold"/>,
@@ -877,7 +810,7 @@
     This logic only applies to row versions of the heap. Index entries
     don't use <literal>xmin/xmax</literal>. Nevertheless, such index
     entries, which would lead to outdated row versions, are released
-    accordingly.       (??? more explanations ???)
+    accordingly.
    </para>
 
    <para>
@@ -996,7 +929,8 @@
 
      <listitem>
       <simpara>
-       The transaction of <literal>xmin</literal> must be committed.
+       The transactions of <literal>xmin</literal> and
+       <literal>xmax</literal> must be committed.
       </simpara>
      </listitem>
     </itemizedlist>
@@ -1029,8 +963,8 @@
      </listitem>
      <listitem>
       <simpara>
-       When an <firstterm>autovacuum</firstterm> process runs. Such
-       a process acts in one of two modes:
+       When an Autovacuum process runs. Such a process acts in one
+       of two modes:
       </simpara>
 
       <itemizedlist>
@@ -1053,7 +987,7 @@
          <xref linkend="guc-autovacuum-freeze-max-age"/>
          (default: 200 million). The value of the oldest unfrozen
          xid is stored per table in <literal>pg_class.relfrozenxid</literal>.
-         In this <emphasis>aggressive mode</emphasis> <firstterm>autovacuum</firstterm>
+         In this <emphasis>aggressive mode</emphasis> Autovacuum
          processes all such pages of the selected table that are marked
          in the Visibility Map to potentially have bloat or unfrozen rows.
         </simpara>
@@ -1065,7 +999,7 @@
    </para>
 
    <para>
-    In the first two cases and with <firstterm>autovacuum</firstterm> in
+    In the first two cases and with Autovacuum in
     <emphasis>aggressive mode</emphasis>, the system knows
     to which value the oldest unfrozen xid has moved forward and
     logs the value in <literal>pg_class.relfrozenxid</literal>.
@@ -1093,13 +1027,11 @@
    <bridgehead renderas="sect2">Protection against Wraparound Failure</bridgehead>
 
    <para>
-    The <firstterm>autovacuum</firstterm> processes are initiated by the
-    constantly running <firstterm>autovacuum</firstterm> daemon.
-    If the daemon detects that for a table
-    <firstterm>autovacuum_freeze_max_age</firstterm> is exceeded, it
-    starts an <firstterm>autovacuum</firstterm> process in
-    <emphasis>aggressive mode</emphasis>
-    (see above) &mdash; even if <firstterm>autovacuum</firstterm> is disabled.
+    The Autovacuum processes are initiated by the constantly running
+    Autovacuum daemon. If the daemon detects that for a table
+    <literal>autovacuum_freeze_max_age</literal> is exceeded, it
+    starts an Autovacuum process in <emphasis>aggressive mode</emphasis>
+    (see above) &mdash; even if Autovacuum is disabled.
    </para>
 
    <bridgehead renderas="sect2">Visibility Map and Free Space Map</bridgehead>
@@ -1127,7 +1059,7 @@
 
    <para>
     The setting of the flags is silently done by <command>VACUUM</command>
-    and <firstterm>autovacuum</firstterm> during their bloat and freeze operations.
+    and Autovacuum during their bloat and freeze operations.
     This is done to speed up future vacuum actions,
     regular accesses to heap pages, and some accesses to
     the index. Every data-modifying operation on any row
@@ -1138,10 +1070,9 @@
     The <link linkend="glossary-fsm">Free Space Map</link>
     (FSM) tracks the amount of free space per page. It is
     organized as a highly condensed b-tree of (rounded) sizes.
-    As long as <command>VACUUM</command> or
-    <firstterm>autovacuum</firstterm> change the free space
-    on any processed page, they log the new values in
-    the FSM in the same way as all other writing
+    As long as <command>VACUUM</command> or Autovacuum change
+    the free space on any processed page, they log the new
+    values in the FSM in the same way as all other writing
     processes.
    </para>
 
@@ -1153,11 +1084,10 @@
     decisions for the generation of execution plans. This
     information can be gathered with the SQL commands
     <command>ANALYZE</command> or <command>VACUUM ANALYZE</command>.
-    But <firstterm>autovacuum</firstterm> processes also gather
+    But also Autovacuum processes gather
     such information. Depending on the percentage of changed rows
     per table <xref linkend="guc-autovacuum-analyze-scale-factor"/>,
-    the <firstterm>autovacuum</firstterm> daemon starts
-    <firstterm>autovacuum</firstterm> processes to collect
+    the Autovacuum daemon starts Autovacuum processes to collect
     statistics per table. This dynamic invocation of analyze
     operations allows <productname>PostgreSQL</productname> to
     adopt queries to changing circumstances.
@@ -1221,7 +1151,7 @@ UPDATE accounts SET balance = balance + 100.00 WHERE name = 'Bob';
 
    <para>
     The atomicity also affects the visibility of changes. No
-    connections running simultaneously to a data modifying
+    connection running simultaneously to a data modifying
     transaction will ever see any change before the
     transaction successfully executes a <command>COMMIT</command>
     &mdash; even in the lowest
@@ -1293,7 +1223,7 @@ UPDATE accounts SET balance = balance + 100.00 WHERE name = 'Bob';
     <command>ROLLBACK</command> command instead of a
     <command>COMMIT</command>. The <command>ROLLBACK</command>
     cancels the transaction, and all changes made so far remain
-    invisible forever; it's like they never happened. There
+    invisible forever; it is as if they had never happened. There
     is no need for the application to log its activities and
     undo every step of the transaction separately.
    </para>
@@ -1319,10 +1249,11 @@ UPDATE accounts SET balance = balance + 100.00 WHERE name = 'Bob';
    </para>
 
    <para>
-    There is an additional feature which defines transactions'
-    <link linkend="transaction-iso">isolation level</link>
-    to each other in a declarative way. It automatically
-    prevents applications from some strange situations.
+    There is the additional feature
+    '<link linkend="transaction-iso">isolation level</link>',
+    which separates transactions from each other in certain ways.
+    It automatically prevents applications from some strange
+    situations.
    </para>
 
    <para>
@@ -1405,19 +1336,21 @@ UPDATE accounts SET balance = balance + 100.00 WHERE name = 'Bob';
     are also in the files, but - as usual - they are never seen
     by any of the following transactions because uncommited
     changes are never shown. Such recovery actions run
-    completely automatically, it is not necessary that you
-    configure or start anything by yourself.
+    completely automatically, it is not necessary that a
+    database administrator configure or start anything by
+    himself.
    </para>
 
    <bridgehead renderas="sect3">Disk crash</bridgehead>
    <para>
     If a disk crashes, the course of action described previously
     cannot work. It is likely that the WAL files and/or the
-    data and index files are no longer available. You need
-    to take special actions to overcome such situations.
+    data and index files are no longer available. The
+    database administrator must take special actions to
+    overcome such situations.
    </para>
    <para>
-    You obviously need a backup. How to take such a backup
+    He obviously needs a backup. How to take such a backup
     and use it as a starting point for a recovery of the
     cluster is explained in more detail in the next
     <link linkend="tutorial-backup">chapter</link>.
@@ -1428,13 +1361,12 @@ UPDATE accounts SET balance = balance + 100.00 WHERE name = 'Bob';
     It is conceivable that over time the disk gets full,
     and there is no room for additional data. In this case,
     <productname>PostgreSQL</productname> stops accepting
-    commands which change the data or even terminates
-    completely. No data loss or data corruption will
-    occur.
+    data-modifying commands or even terminates completely.
+    No data loss or data corruption will occur.
    </para>
    <para>
-    To come out of such a situation, you should remove
-    unused files from this disk. But you should never
+    To come out of such a situation, the administrator should
+    remove unused files from this disk. But he should never
     delete files from the
     <glossterm linkend="glossary-data-directory">data directory</glossterm>.
     Nearly all of them are necessary for the consistency
diff --git a/doc/src/sgml/start.sgml b/doc/src/sgml/start.sgml
index 8751410179..abb61445f2 100644
--- a/doc/src/sgml/start.sgml
+++ b/doc/src/sgml/start.sgml
@@ -76,30 +76,27 @@
       A process at the server site with the name
       <glossterm linkend="glossary-postmaster">Postmaster</glossterm>.
       <indexterm><primary>postgres</primary></indexterm>
+      <indexterm><primary>postmaster</primary></indexterm>
       It accepts connection requests from client applications, starts
       (<quote>forks</quote>) a new <glossterm linkend="glossary-backend">
-      Backend process</glossterm> for each of them, and passes
+      Backend</glossterm> process for each of them, and passes
       the connection to it. From that point on, the client and the new
-      <firstterm>Backend process</firstterm>
-      communicate directly without intervention by the original
-      <firstterm>postgres</firstterm> process. Thus, the
-      <firstterm>postgres</firstterm> process is always running, waiting
-      for new client connections, whereas clients and associated
-      <firstterm>Backend processes</firstterm> come and go.
-      (All of this is of course invisible to the user. We only mention it
-      here for completeness.)
+      Backend process communicate directly without intervention by the original
+      Postmaster process. Thus, the Postmaster process is always running,
+      waiting for new client connections, whereas clients and associated
+      Backend processes come and go. (All of this is of course invisible
+      to the user. We only mention it here for completeness.)
      </para>
     </listitem>
 
     <listitem>
      <para>
       A group of processes at the server site, the <glossterm
-      linkend="glossary-instance">instance</glossterm>, to which also the
-      <firstterm>postgres</firstterm> process belongs. Their duties are
-      handling of central, common database activities like file access,
-      vacuum, <glossterm linkend="glossary-checkpoint">checkpoints</glossterm>,
-      replication, and more. The mentioned <firstterm>Backend processes</firstterm>
-      delegate those actions to the <firstterm>instance</firstterm>.
+      linkend="glossary-instance">Instance</glossterm>, to which also
+      the Postmaster process belongs. Their duties are handling of
+      central, common database activities like file access, transaction
+      handling, vacuum, checkpoints, replication, and more. The mentioned
+      Backend processes delegate those actions to the instance.
      </para>
     </listitem>
 
@@ -127,18 +124,6 @@
 
-   <para>
-    supervisor server process is always running, waiting for

 
 
  <chapter id="overview">
 
   <note>
    <title>Author</title>
index 0000000000..e547a87d08
@@ -0,0 +1,1517 @@
+    In a client/server architecture clients do not have direct access
+    to database files and the data stored in them. Instead, they send
+    requests to the server and receive the requested data in the response.
+    In the case of <productname>PostgreSQL</productname>, the server
+    launches a single process for each client connection, referred to as a
+    <glossterm linkend="glossary-backend">Backend</glossterm> process.
+    Those Backend processes handle the client's requests by acting on the
+    <glossterm linkend="glossary-shared-memory">Shared Memory</glossterm>.
+    This leads to other activities (file access, WAL, vacuum, ...) of the
+    <glossterm linkend="glossary-instance">Instance</glossterm>. The
+    Instance is a group of server-side processes acting on a common
+    Shared Memory. Notably, PostgreSQL does not utilize application
+    threading within its implementation.
+    The first step in an Instance start is the start of the
+    He loads the configuration files, allocates Shared Memory, and
+    starts the other processes of the Instance:
+    Later, the Postmaster starts
+    <glossterm linkend="glossary-backend">Backend</glossterm> processes
+    which communicate with clients and handle their requests.
+    <xref linkend="tutorial-ram-proc-file-figure"/> visualizes the processes
+    of an Instance and the main aspects of their collaboration.
+    this request is handled initially by the Postmaster. He
+    starts a new Backend process and instructs the client
+    application to connect to it. All further client requests
+    go to this process and are handled by it.
+    necessity to read or write some data. This is carried out
+    by the client's backend process. Reads involve a page-level
+    cache housed in Shared Memory (for details see:
+    <xref linkend="sysvipc"/>) for the benefit of all processes
+    in the instance. Writes also involve this cache, in additional
+    to a journal, called a write-ahead-log or WAL.
+    Shared Memory is limited in size. Thus, it becomes necessary
+    to evict pages. As long as the content of such pages hasn't
+    changed, this is not a problem. But in Shared Memory also
+    write actions take place. Modified pages are called dirty
+    pages or dirty buffers and before they can be evicted they
+    must be written back to disk. This happens regularly by the
+    Background Writer and the Checkpointer process to ensure
+    that the disk version of the pages are kept up-to-date.
+    The synchronisation from RAM to disk consists of two steps.
+<!-- DGJ: WAL should already be done well before page
+          eviction/overwriting comes into play.
+          This is good material but seems misplaced.
+     JuP: Really misplaced? Don't think so.
+    is created out of the delta-information (difference between the
+    old and the new content) and stored in another area of
+    Shared Memory. The parallel running WAL Writer process
+    reads them and appends them to the end of the current
+    Such sequential writes are much faster than writes to random
+    positions of heap and index files. All WAL records created
+    out of one dirty page must be transferred to disk before the
+    dirty page itself can be transferred to disk in the second step.
+    Second, the transfer of dirty buffers from Shared Memory to
+    files must take place. This is the primary task of the
+    Background Writer process. Because I/O activities can block
+    other processes significantly, it starts periodically and
+    acts only for a short period. Doing so, its extensive (and
+    expensive) I/O activities are spread over time, avoiding
+    debilitating I/O peaks. Also, the Checkpointer process
+    transfers dirty buffers to file.
+    The Checkpointer creates
+    A Checkpoint is a point in time when all older dirty buffers,
+    all older WAL records, and finally a special Checkpoint record
+    have been written and flushed to disk. Heap and index files
+    on the one hand and WAL files on the other hand are in sync.
+    Previous WAL is no longer required. In other words,
+    a possibly occurring recovery, which integrates the delta
+    information of WAL into heap and index files, will happen
+    by replaying only WAL past the last recorded checkpoint
+    on top of the current heap and files. This speeds up recovery.
+    While the Checkpointer ensures that a running system can crash
+    and restart itself in a valid state, the administrator needs
+    to handle the case where the heap and files themselves become
+    corrupted (and possibly the locally written WAL, though that is
+    less common). The options and details are covered extensively
+    in the backup and restore section (<xref linkend="backup"/>).
+    For our purposes here, note just that the WAL Archiver process
+    can be enabled and configured to run a script on filled WAL
+    files &mdash; usually to copy them to a remote location.
+<!-- DGJ: after the heavy focus on client processes and data these two
+          seem to come out of left field.  Skipping over for now.
+     JuP: Don't skip, we want to explain all elements of the graphic.
+    The Statistics Collector collects counters about accesses to
+    SQL objects like tables, rows, indexes, pages, and more. It
+    stores the obtained information in system tables.
+    The Logger writes text lines about serious and less serious
+    events which can happen during database access, e.g., wrong
+    password, no permission, long-running queries, etc.
+    of all other databases, no client can connect to it.
+    Every database must contain at least one schema because all
+    <glossterm linkend="glossary-sql-object">SQL Objects</glossterm>
+    are contained in a schema.
+    Schemas are namespaces for their SQL objects and ensure
+    (with one exception) that within their scope names are used
+    only once across all types of SQL objects. E.g., it is not possible
+    <literal>employee</literal> within the same schema. But it is
+    possible to have two tables <literal>employee</literal> in
+    different schemas. In this case, the two tables
+    </glossterm> and the according unique index
+    (<xref linkend="indexes-unique"/>) use the same name.
+    acts as the default schema and contains all SQL objects
+    which are created within <literal>public</literal> or
+    without using an explicit schema name. <literal>public</literal>
+    should not contain user-defined SQL objects. Instead, it is
+    recommended to create a separate schema that holds individual
+    objects like application-specific tables or views.
+    <literal>pg_catalog</literal> is a schema for all tables and views of the
+    tables and views of the System Catalog in a way that conforms
+    to the SQL standard.
+    <firstterm>Global SQL Objects</firstterm>, are outside of the
+    strict hierarchy: All <firstterm>database names</firstterm>,
+    all <firstterm>tablespace names</firstterm>, and all
+    <firstterm>role names</firstterm> are automatically known and
+    available throughout the cluster, independent from
+    <xref linkend="glossary-db-cluster"/> has its root directory
+    <glossterm linkend="glossary-tablespace">tablespaces</glossterm>.
+    In <literal>global</literal> there is information about
+    <literal>in_progress</literal>, <literal>committed</literal>,
+    <literal>aborted</literal>, or <literal>sub_committed</literal>.
+    that point to directories containing such SQL objects
+    that are created within tablespaces.
+    In most cases, <productname>PostgreSQL</productname> databases
+    The description in this chapter simplifies by omitting some details.
+      space occupied by dead row versions is part of the
+    <firstterm>Autovacuum</firstterm> processes clean up
+     Autovacuum runs automatically by
+    Client processes can issue the SQL command <command>VACUUM</command>
+    at arbitrary points in time. DBAs do this when they recognize
+    special situations, or they start it in batch jobs which run
+    periodically. Autovacuum processes run as part of the
+    There is a constantly running Autovacuum daemon. It permanently
+    controls the state of all databases based on values that are collected by the
+    and starts Autovacuum processes whenever it detects
+    <command>VACUUM</command>, as well as Autovacuum, don't just eliminate
+    bloat. They perform additional tasks for minimizing future
+    This extra work can be done in a very efficient way since in most
+    cases the expensive physical access to pages has taken place anyway
+    to eliminate bloat. The additional operations are:
+    intensive, which can hinder other activities, Autovacuum
+      than the oldest xid of all currently running transactions
+      <literal>(min(pg_stat_activity.backend_xmin))</literal>.
+    marks its space as free for future use of writing actions. Only
+    in rare situations (or in the case of <command>VACUUM FULL</command>),
+       When an Autovacuum process acts. For optimization
+    accordingly.
+       The transactions of <literal>xmin</literal> and
+       <literal>xmax</literal> must be committed.
+       When an Autovacuum process runs. Such a process acts in one
+       of two modes:
+         In this <emphasis>aggressive mode</emphasis> Autovacuum
+    In the first two cases and with Autovacuum in
+    The Autovacuum processes are initiated by the constantly running
+    Autovacuum daemon. If the daemon detects that for a table
+    <literal>autovacuum_freeze_max_age</literal> is exceeded, it
+    starts an Autovacuum process in <emphasis>aggressive mode</emphasis>
+    (see above) &mdash; even if Autovacuum is disabled.
+    and Autovacuum during their bloat and freeze operations.
+    As long as <command>VACUUM</command> or Autovacuum change
+    the free space on any processed page, they log the new
+    values in the FSM in the same way as all other writing
+    But also Autovacuum processes gather
+    the Autovacuum daemon starts Autovacuum processes to collect
+    connection running simultaneously to a data modifying
+    invisible forever; it is as if they had never happened. There
+    There is the additional feature
+    '<link linkend="transaction-iso">isolation level</link>',
+    which separates transactions from each other in certain ways.
+    It automatically prevents applications from some strange
+    situations.
+    completely automatically, it is not necessary that a
+    database administrator configure or start anything by
+    himself.
+    data and index files are no longer available. The
+    database administrator must take special actions to
+    overcome such situations.
+    He obviously needs a backup. How to take such a backup
+    data-modifying commands or even terminates completely.
+    No data loss or data corruption will occur.
+    To come out of such a situation, the administrator should
+    remove unused files from this disk. But he should never

+  &architecture;
   &arch-dev;
   &catalogs;
   &protocol;
diff --git a/doc/src/sgml/start.sgml b/doc/src/sgml/start.sgml
index 9bb5c1a6d5..abb61445f2 100644
--- a/doc/src/sgml/start.sgml
+++ b/doc/src/sgml/start.sgml
@@ -53,7 +53,7 @@

    <para>
@@ -68,34 +68,52 @@
 
-    <itemizedlist>
-     <listitem>
-      <para>
-       A server process, which manages the database files, accepts
-       connections to the database from client applications, and
-       performs database actions on behalf of the clients.  The
-       database server program is called
-       <filename>postgres</filename>.
-       <indexterm><primary>postgres</primary></indexterm>
-      </para>
-     </listitem>
+   <itemizedlist>
+    <listitem>
+     <para>
+      A process at the server site with the name
+      <glossterm linkend="glossary-postmaster">Postmaster</glossterm>.
+      <indexterm><primary>postgres</primary></indexterm>
+      <indexterm><primary>postmaster</primary></indexterm>
+      It accepts connection requests from client applications, starts
+      (<quote>forks</quote>) a new <glossterm linkend="glossary-backend">
+      Backend</glossterm> process for each of them, and passes
+      the connection to it. From that point on, the client and the new
+      Backend process communicate directly without intervention by the original
+      Postmaster process. Thus, the Postmaster process is always running,
+      waiting for new client connections, whereas clients and associated
+      Backend processes come and go. (All of this is of course invisible
+      to the user. We only mention it here for completeness.)
+     </para>
+    </listitem>
 
-     <listitem>
-      <para>
-       The user's client (frontend) application that wants to perform
-       database operations.  Client applications can be very diverse
-       in nature:  a client could be a text-oriented tool, a graphical
-       application, a web server that accesses the database to
-       display web pages, or a specialized database maintenance tool.
-       Some client applications are supplied with the
-       <productname>PostgreSQL</productname> distribution; most are
-       developed by users.
-      </para>
-     </listitem>
+    <listitem>
+     <para>
+      A group of processes at the server site, the <glossterm
+      linkend="glossary-instance">Instance</glossterm>, to which also
+      the Postmaster process belongs. Their duties are handling of
+      central, common database activities like file access, transaction
+      handling, vacuum, checkpoints, replication, and more. The mentioned
+      Backend processes delegate those actions to the instance.
+     </para>
+    </listitem>
 
-    </itemizedlist>
-   </para>
+    <listitem>
+     <para>
 
    <para>
@@ -106,18 +124,6 @@
 
-   <para>
-    supervisor server process is always running, waiting for

---

From: Erik Rijkers <[email-masked]>
Date: Fri, 30 Oct 2020 17:45:00 +0100

Hi,

I applied 0009-architecture-vs-master.patch to head
and went through architecture.sgml (only that file),
then produced the attached .diff

And I wrote down some separate items:

1.
'Two Phase Locking' and 'TPL' should be, I think,
'Two-Phase Commit'. Please someone confirm.
(no changes made)

2.
To compare xid to sequence because they similarly 'count up' seems a bad 
idea.
(I don't think it's always true in the case of sequences)
(no changes made)

3.
'accesses' seems a somewhat strange word most of the time just 'access' 
may be better.  Not sure - native speaker wanted. (no changes made)

4.
'heap', in postgres, means often (always?) files. But more generally, 
the meaning is more associated with memory.  Therefore it would be good 
I think to explicitly use 'heap file' at least in the beginning once to 
make clear that heap implies 'safely written away to disk'.  Again, I'm 
not quite sure if my understanding is correct - I have made no changes 
in this regard.

Erik Rijkers
--- doc/src/sgml/architecture.sgml.orig	2020-10-30 15:19:54.469275256 +0100
+++ doc/src/sgml/architecture.sgml	2020-10-30 17:28:24.835233482 +0100
@@ -19,19 +19,18 @@
     In the case of <productname>PostgreSQL</productname>, the server
     launches a single process for each client connection, referred to as a
     <glossterm linkend="glossary-backend">Backend</glossterm> process.
-    Those Backend processes handle the client's requests by acting on the
+    Such a Backend process handles the client's requests by acting on the
     <glossterm linkend="glossary-shared-memory">Shared Memory</glossterm>.
     This leads to other activities (file access, WAL, vacuum, ...) of the
     <glossterm linkend="glossary-instance">Instance</glossterm>. The
     Instance is a group of server-side processes acting on a common
-    Shared Memory. Notably, PostgreSQL does not utilize application
-    threading within its implementation.
+    Shared Memory. PostgreSQL does not utilize threading.
    </para>
 
    <para>
-    The first step in an Instance start is the start of the
+    The first step when an Instance starts is the start of the
     <glossterm linkend="glossary-postmaster">Postmaster</glossterm>.
-    He loads the configuration files, allocates Shared Memory, and
+    It loads the configuration files, allocates Shared Memory, and
     starts the other processes of the Instance:
     <glossterm linkend="glossary-background-writer">Background Writer</glossterm>,
     <glossterm linkend="glossary-checkpointer">Checkpointer</glossterm>,
@@ -66,32 +65,32 @@
    <para>
     When a client application tries to connect to a
     <glossterm linkend="glossary-database">database</glossterm>,
-    this request is handled initially by the Postmaster. He
+    this request is handled initially by the Postmaster. It
     starts a new Backend process and instructs the client
     application to connect to it. All further client requests
-    go to this process and are handled by it.
+    are handled by this process.
    </para>
 
    <para>
     Client requests like <command>SELECT</command> or
     <command>UPDATE</command> usually lead to the
-    necessity to read or write some data. This is carried out
+    necessity to read or write data. This is carried out
     by the client's backend process. Reads involve a page-level
-    cache housed in Shared Memory (for details see:
+    cache, located in Shared Memory (for details see:
     <xref linkend="sysvipc"/>) for the benefit of all processes
-    in the instance. Writes also involve this cache, in additional
+    in the instance. Writes also use this cache, in addition
     to a journal, called a write-ahead-log or WAL.
    </para>
 
    <para>
-    Shared Memory is limited in size. Thus, it becomes necessary
+    Shared Memory is limited in size and it can become necessary
     to evict pages. As long as the content of such pages hasn't
     changed, this is not a problem. But in Shared Memory also
     write actions take place. Modified pages are called dirty
     pages or dirty buffers and before they can be evicted they
-    must be written back to disk. This happens regularly by the
+    must be written to disk. This happens regularly by the
     Background Writer and the Checkpointer process to ensure
-    that the disk version of the pages are kept up-to-date.
+    that the disk version of the pages are up-to-date.
     The synchronisation from RAM to disk consists of two steps.
    </para>
 
@@ -109,7 +108,7 @@
     Shared Memory. The parallel running WAL Writer process
     reads them and appends them to the end of the current
     <glossterm linkend="glossary-wal-record">WAL file</glossterm>.
-    Such sequential writes are much faster than writes to random
+    Such sequential writes are faster than writes to random
     positions of heap and index files. All WAL records created
     out of one dirty page must be transferred to disk before the
     dirty page itself can be transferred to disk in the second step.
@@ -119,19 +118,19 @@
     Second, the transfer of dirty buffers from Shared Memory to
     files must take place. This is the primary task of the
     Background Writer process. Because I/O activities can block
-    other processes significantly, it starts periodically and
+    other processes, it starts periodically and
     acts only for a short period. Doing so, its extensive (and
     expensive) I/O activities are spread over time, avoiding
-    debilitating I/O peaks. Also, the Checkpointer process
-    transfers dirty buffers to file.
+    debilitating I/O peaks. The Checkpointer process
+    also transfers dirty buffers to file.
    </para>
 
    <para>
-    The Checkpointer creates
+    The Checkpointer process creates
     <glossterm linkend="glossary-checkpoint">Checkpoints</glossterm>.
     A Checkpoint is a point in time when all older dirty buffers,
     all older WAL records, and finally a special Checkpoint record
-    have been written and flushed to disk. Heap and index files
+    are written and flushed to disk. Heap and index files
     on the one hand and WAL files on the other hand are in sync.
     Previous WAL is no longer required. In other words,
     a possibly occurring recovery, which integrates the delta
@@ -141,13 +140,13 @@
    </para>
 
    <para>
-    While the Checkpointer ensures that a running system can crash
+    While the Checkpointer ensures that the database system can crash
     and restart itself in a valid state, the administrator needs
     to handle the case where the heap and files themselves become
     corrupted (and possibly the locally written WAL, though that is
     less common). The options and details are covered extensively
     in the backup and restore section (<xref linkend="backup"/>).
-    For our purposes here, note just that the WAL Archiver process
+    For our purposes here, just note that the WAL Archiver process
     can be enabled and configured to run a script on filled WAL
     files &mdash; usually to copy them to a remote location.
    </para>
@@ -234,13 +233,13 @@
    <para>
     Every database must contain at least one schema because all
     <glossterm linkend="glossary-sql-object">SQL Objects</glossterm>
-    are contained in a schema.
-    Schemas are namespaces for their SQL objects and ensure
-    (with one exception) that within their scope names are used
-    only once across all types of SQL objects. E.g., it is not possible
+    must be contained in a schema.
+    Schemas are namespaces for SQL objects and ensure
+    (with one exception) that the SQL object names are used only once within
+    their scope across all types of SQL objects. E.g., it is not possible
     to have a table <literal>employee</literal> and a view
     <literal>employee</literal> within the same schema. But it is
-    possible to have two tables <literal>employee</literal> in
+    possible to have two tables <literal>employee</literal> in two
     different schemas. In this case, the two tables
     are separate objects and independent of each
     other. The only exception to this cross-type uniqueness is that
@@ -273,7 +272,7 @@
     <firstterm>Global SQL Objects</firstterm>, are outside of the
     strict hierarchy: All <firstterm>database names</firstterm>,
     all <firstterm>tablespace names</firstterm>, and all
-    <firstterm>role names</firstterm> are automatically known and
+    <firstterm>role names</firstterm> are automatically
     available throughout the cluster, independent from
     the database or schema in which they where defined originally.
     <xref linkend="tutorial-internal-objects-hierarchy-figure"/>
@@ -302,7 +301,7 @@
    <title>The physical Perspective: Directories and Files</title>
 
    <para>
-    <productname>PostgreSQL</productname> organizes long-lasting
+    <productname>PostgreSQL</productname> organizes long-lasting (persistent)
     data as well as volatile state information about transactions
     or replication actions in the file system. Every
     <xref linkend="glossary-db-cluster"/> has its root directory
@@ -352,20 +351,19 @@
     every table and every index to store heap and index
     data. Those files are accompanied by files for the
     <link linkend="storage-fsm">Free Space Maps</link>
-    (extension <literal>_fsm</literal>) and
+    (suffixed <literal>_fsm</literal>) and
     <link linkend="storage-vm">Visibility Maps</link>
-    (extension <literal>_vm</literal>), which contain optimization information.
+    (suffixed <literal>_vm</literal>), which contain optimization information.
    </para>
 
    <para>
-    Another subdirectory is <literal>global</literal>.
-    In analogy to the database-specific
-    subdirectories, there are files containing information about
+    Another subdirectory is <literal>global</literal> which 
+    contains files with information about
     <glossterm linkend="glossary-sql-object">Global SQL Objects</glossterm>.
     One type of such Global SQL Objects are
     <glossterm linkend="glossary-tablespace">tablespaces</glossterm>.
     In <literal>global</literal> there is information about
-    the tablespaces, not the tablespaces themselves.
+    the tablespaces; not the tablespaces themselves.
    </para>
 
    <para>
@@ -392,11 +390,11 @@
    <para>
     In the root directory <literal>data</literal>
     there are also some files. In many cases, the configuration
-    files of the cluster are stored here. As long as the
+    files of the cluster are stored here. If the
     instance is up and running, the file
     <literal>postmaster.pid</literal> exists here
     and contains the process ID (pid) of the
-    Postmaster which has started the instance.
+    Postmaster which started the instance.
    </para>
 
    <para>
@@ -411,7 +409,7 @@
 
    <para>
     In most cases, <productname>PostgreSQL</productname> databases
-    support many clients at the same time. Therefore, it is necessary to
+    support many clients at the same time which makes it necessary to
     protect concurrently running requests from unwanted overwriting
     of other's data as well as from reading inconsistent data. Imagine an
     online shop offering the last copy of an article. Two clients have the
@@ -432,11 +430,11 @@
     <productname>PostgreSQL</productname> implements a third, more
     sophisticated technique: <firstterm>Multiversion Concurrency
     Control</firstterm> (MVCC). The crucial advantage of MVCC
-    over other technologies gets evident in multiuser OLTP
+    over other technologies becomes evident in multiuser OLTP
     environments with a massive number of concurrent write
     actions. There, MVCC generally performs better than solutions
     using locks. In a <productname>PostgreSQL</productname>
-    database reading never blocks writing and writing never
+    database, reading never blocks writing and writing never
     blocks reading, even in the strictest level of transaction
     isolation.
    </para>
@@ -444,14 +442,14 @@
    <para>
     Instead of locking rows, the <firstterm>MVCC</firstterm> technique creates
     a new version of the row when a data-change takes place. To
-    distinguish between these two versions and to track the timeline
+    distinguish between these two versions, and to track the timeline
     of the row, each of the versions contains, in addition to their user-defined
     columns, two special system columns, which are not visible
     for the usual <command>SELECT * FROM ...</command> command.
     The column <literal>xmin</literal> contains the transaction ID (xid)
-    of the transaction, which created this version of the row. Accordingly,
-    <literal>xmax</literal> contains the xid of the transaction, which has
-    deleted this version, or zero, if the version is not
+    of the transaction which created this version of the row.
+    <literal>xmax</literal> contains the xid of the transaction which has
+    deleted this version, or zero if the version is not
     deleted. You can read both with the command
     <command>SELECT xmin, xmax, * FROM ... </command>.
    </para>
@@ -469,7 +467,7 @@
    </para>
 
    <para>
-    The description in this chapter simplifies by omitting some details.
+    The description in this chapter simplifies by omitting details.
     When many transactions are running simultaneously, things can
     get complicated. Sometimes transactions get aborted via
     <command>ROLLBACK</command> immediately or after a lot of other activities, sometimes
@@ -526,8 +524,8 @@
     creates a new version of the row with its xid in
     <literal>xmin</literal>, <literal>0</literal> in
     <literal>xmax</literal>, and <literal>'y'</literal> in the
-    user data (plus all the other user data from the old version).
-    This version is now valid for all coming transactions.
+    user data (plus all other user data from the old version).
+    This version is now valid for all future transactions.
    </para>
 
    <para>
@@ -624,9 +622,9 @@
     <para>
      Autovacuum runs automatically by
      default. Its default parameters as well as such for
-     <command>VACUUM</command> fit well for most standard
+     <command>VACUUM</command> are appropriate for most standard
      situations. Therefore a novice database manager can
-     easily skip the rest of this chapter which explains
+     skip the rest of this chapter which explains
      a lot of details.
     </para>
    </note>
@@ -687,7 +685,7 @@
 
    <para>
     The eagerness &mdash; you can call it 'aggression' &mdash; of the
-    operations <emphasis>eliminating bloat</emphasis> and
+    operations for <emphasis>eliminating bloat</emphasis> and
     <emphasis>freeze</emphasis> is controlled by configuration
     parameters, runtime flags, and in extreme situations by
     the processes themselves. Because vacuum operations typically are I/O
@@ -783,7 +781,7 @@
        When a client issues the SQL command <command>VACUUM</command>
        with the option <command>FULL</command>.
        Also, in this mode, the bloat disappears, but the strategy used
-       is very different: In this case, the complete table is copied
+       is very different: in this case, the complete table is copied
        to a different file skipping all outdated row versions. This
        leads to a significant reduction of used disk space because
        the new file contains only the actual data. The old file
@@ -1143,7 +1141,7 @@
     atomicity: either all or none of its operations succeed,
     regardless of the fact that it may consist of a lot of
     different write-operations, and each such operation may
-    affect thousands or millions of rows. As soon as one of the
+    affect many rows. As soon as one of the
     operations fails, all previous operations fail also, which
     means that all modified rows retain their values as of the
     beginning of the transaction.
@@ -1157,14 +1155,14 @@
     &mdash; even in the lowest
     <link linkend="transaction-iso">isolation level</link>
     of transactions. <productname>PostgreSQL</productname>
-    does never show uncommitted changes to other connections.
+    never shows uncommitted changes to other connections.
    </para>
 
    <para>
     The situation regarding visibility is somewhat different
     from the point of view of the modifying transaction.
-    <command>SELECT</command> commands issued inside a
-    transaction delivers all changes done so far by this
+    A <command>SELECT</command> command issued inside a
+    transaction shows all changes done so far by this
     transaction.
    </para>
 
@@ -1231,7 +1229,7 @@
    <para>
     Transactions ensure that the
     <glossterm linkend="glossary-consistency">consistency</glossterm>
-    of the complete database always keeps valid. Declarative
+    of the complete database always remains valid. Declarative
     rules like
     <link linkend="ddl-constraints-primary-keys">primary</link>- or
     <link linkend="ddl-constraints-fk">foreign keys</link>,
@@ -1242,13 +1240,6 @@
    </para>
 
    <para>
-    Also, all self-evident &mdash; but possibly not obvious
-    &mdash; low-level demands on the database system are
-    ensured; e.g. index entries for rows must become
-    visible at the same moment as the rows themselves.
-   </para>
-
-   <para>
     There is the additional feature
     '<link linkend="transaction-iso">isolation level</link>',
     which separates transactions from each other in certain ways.
@@ -1287,7 +1278,7 @@
     a severe software error like a null pointer exception.
     Because <productname>PostgreSQL</productname> uses a
     client/server architecture, no direct problem for the
-    database will occur. In all of this cases, the
+    database will occur. In all of these cases, the
     <glossterm linkend="glossary-backend">Backend process</glossterm>,
     which is the client's counterpart at the server-side,
     may recognize that the network connection is no longer
@@ -1310,7 +1301,7 @@
     automatically recognizes that the last shutdown of the
     instance did not happen as expected: files might not be
     closed properly and the <literal>postmaster.pid</literal>
-    file exists. <productname>PostgreSQL</productname>
+    file unexpectedly exists. <productname>PostgreSQL</productname>
     tries to clean up the situation. This is possible because
     all changes in the database are stored twice. First,
     the WAL files contain them as a chronology of
@@ -1328,8 +1319,8 @@
     <glossterm linkend="glossary-checkpoint">checkpoint</glossterm>.
     This checkpoint signals that the database files are in
     a consistent state, especially that all WAL records up to
-    this point were successfully stored in heap and index. Starting
-    here, the recovery process copies the following WAL records
+    this point were successfully stored in heap and index files. Starting
+    here, the recovery process copies the remaining WAL records
     to heap and index. As a result, the files contain all
     changes and reach a consistent state. Changes of committed
     transactions are visible; those of uncommited transactions
@@ -1344,10 +1335,10 @@
    <bridgehead renderas="sect3">Disk crash</bridgehead>
    <para>
     If a disk crashes, the course of action described previously
-    cannot work. It is likely that the WAL files and/or the
+    cannot work: it is likely that the WAL files and/or the
     data and index files are no longer available. The
     database administrator must take special actions to
-    overcome such situations.
+    prepare for such a situation.
    </para>
    <para>
     He obviously needs a backup. How to take such a backup
@@ -1427,7 +1418,7 @@
    </para>
    <para>
     The obvious disadvantage of this method is that there
-    is a downtime where no user interaction is possible.
+    is a downtime.
     The other two strategies run during regular operating
     times.
    </para>
@@ -1456,14 +1447,14 @@
    <bridgehead renderas="sect2">Continuous archiving based on pg_basebackup and WAL files</bridgehead>
    <para>
     <link linkend="continuous-archiving">This method</link>
-    is the most sophisticated and complex one. It
+    is the most sophisticated and most complex one. It
     consists of two phases.
    </para>
    <para>
-    First, you need to create a so called
+    First, you need to create a so-called
     <firstterm>basebackup</firstterm> with the tool
     <command>pg_basebackup</command>. The result is a
-    directory structure plus files which contains a
+    directory structure plus files which contain a
     consistent copy of the original cluster.
     <command>pg_basebackup</command> runs in
     parallel to other processes in its own transaction.
@@ -1484,7 +1475,7 @@
     <glossterm linkend="glossary-wal-archiver">Archiver process</glossterm>
     will automatically copy every single WAL file to a save location.
     <link linkend="backup-archiving-wal">Its configuration</link>
-    consists mainly of a string, which contains a copy command
+    consists mainly of a string that contains a copy command
     in the operating system's syntax. In order to protect your
     data against a disk crash, the destination location
     of a basebackup as well as of the
@@ -1492,9 +1483,8 @@
     disk which is different from the data disk.
    </para>
    <para>
-    If it gets necessary to restore the cluster, you have to
-    copy the basebackup and the
-    archived WAL files to
+    If it becomes necessary to restore the cluster, you have to
+    copy the basebackup and the archived WAL files to
     their original directories. The configuration of this
     <link linkend="backup-pitr-recovery">recovery procedure</link>
     contains a string with the reverse copy command: from

---

From: Justin Pryzby <[email-masked]>
Date: Sat, 31 Oct 2020 16:34:44 -0500

> then produced the attached .diff

Now I applied 0009 as well as Erik's changes and made some more of my own :)

I'm including all patches so CFBOT is happy.

> 3.
> 'accesses' seems a somewhat strange word most of the time just 'access' may
> be better.  Not sure - native speaker wanted. (no changes made)

You're right, and I included that part.

-- 
Justin

---

From: Jürgen Purtz <[email-masked]>
Date: Sun, 1 Nov 2020 16:38:43 +0100

On 30.10.20 17:45, Erik Rijkers wrote:
> To compare xid to sequence because they similarly 'count up' seems a 
> bad idea.
> 'accesses' seems a somewhat strange word most of the time just 
> 'access' may be better.  Not sure - native speaker wanted. (no changes 
> made)
>
> 4.
> the meaning is more associated with memory.  Therefore it would be 
> good I think to explicitly use 'heap file' at least in the beginning 
> once to make clear that heap implies 'safely written away to disk'.  
> Again, I'm not quite sure if my understanding is correct - I have made 
> no changes in this regard.
>
>
>
> Erik Rijkers

All suggestions so far are summarized in the attached patch with the 
following exceptions:

- 'Two Phase Locking' is the intended term.

- Not adopted:

      Second, the transfer of dirty buffers from Shared Memory to
      files must take place. This is the primary task of the
-    Background Writer process. Because I/O activities can block
+    Checkpointer process. Because I/O activities can block
      other processes, it starts periodically and

Partly adopted:

-    the data in the old version of the row does not change! ...

-    before. Nothing is thrown away so far! Only <literal>xmax</literal> ...

--

J. Purtz

 
 
  <chapter id="overview">
 
   <note>
    <title>Author</title>
index 0000000000..0c663a9d80
@@ -0,0 +1,1507 @@
+    starts a new Backend process, which handles all further
+    client's requests.
+    Checkpointer and the Background Writer processes to ensure
+    by replaying only WAL past the last recorded checkpoint.
+    This limits the amount of WAL which needs to be replayed
+    during recovery in the event of a crash.
+    to handle the case where the heap or other files become
+    The Statistics Collector collects counters about access to
+    They arise and grow in parallel with data changes in the
+    cluster and remain as long as
+    that point to directories containing SQL objects
+    that exist within a non-default tablespace.
+    access to the same data may be the locking of critical
+    any time measurement &mdash; in milliseconds or otherwise. If you dive
+    So, what's going on in detail when write access takes place?
+    the data in the old version of the row is not changed!
+    <literal>134</literal>. In addition to the non-occurring
+    This new row version is visible to all future transactions.
+    (Internally, an <command>UPDATE</command> command acts
+    as a <command>DELETE</command> command followed by
+    an <command>INSERT</command> command.)
+    in the same way as the first one: they put their xid in
+    a new version with their xid in <literal>xmin</literal> and
+    before. Nothing is thrown away! Only <literal>xmax</literal>
+    of the last version is set to the xid of the <command>DELETE</command>
+    transaction, which indicates that (if committed) it is only visible to
+    transactions with xids older than that (from
+    system must also preserve some of the older ones for
+    awhile, because they could still be needed by
+    transactions which started before the deleting transaction commits.
+    Over time, also the older ones get out of scope
+      <firstterm>row versions</firstterm> are valid (visible) for transactions.
+      If an old row version is no longer relevant for ANY existing
+      transactions, it can be marked <firstterm>dead</firstterm>. The
+    tends to occupy more and more disk space, caused by
+    and avoid continued growth.
+    There is a constantly running Autovacuum daemon. It continuously
+    monitors the state of all databases based on values that are collected by the
+      <firstterm>Freeze</firstterm>: Mark certain row versions
+      as frozen. This means that they
+      are always treated as valid (visible) independent from
+    The eagerness &mdash; you can call it 'aggressiveness' &mdash; of the
+    it carries out many small actions with delay points in between.
+    and without any time delay.
+    To determine which of the row versions are no longer needed, the
+    After the vacuum operation detects an unused row version, it
+    <command>UPDATE</command> commands to this table.
+       read and act on all pages of the heap file.
+       The Visibility Map, which is very compact and therefore fast to read,
+       contains information about which pages have no deleted row versions, and
+       can be skipped by <command>VACUUM</command>.
+       it undertakes many more actions, see
+       In this mode, an exclusive lock is taken, and
+       the whole table is copied to a different file, skipping all outdated row
+       versions.  All bloat is thereby eliminated, which
+       may lead to a significant reduction of used disk space.
+       The old file is deleted.
+    entries, which would lead to outdated row versions, are cleaned up
+    have a limited size, and after
+    a certain number of transactions they are forced to restart
+    not always correlate with low / high values of xids. Near to
+    possibility of wraparound.
+      move forward. If 'txid_current + 2^31' reached a
+      If not handled in some way, data inserted many transactions ago
+      would become invisibile. The vacuum operation <firstterm>freeze</firstterm>
+      avoids this long before the split-point is reached by setting
+      a flag in the header of the row version which avoids
+      future comparison of its <literal>xmin/xmax</literal> and indicates
+       as potentially having unfrozen rows.
+       any options but there are xids older than
+       marked in the Visibility Map to potentially having unfrozen
+         that for the processed table the oldest xid exceeds
+    two bits &mdash; for each page of the heap file. The
+    first bit indicates that the associated page does
+    not contain any bloat. The second bit indicates
+    that the page contains only frozen row versions.
+     contains many rows or row versions.
+     not with an individual row version. The flags are set
+     smaller than the heap.
+    regular access to heap pages, and some access to
+    Whenever <command>VACUUM</command> or Autovacuum changes
+    Statistical information helps the <link
+    But Autovacuum processes also gather
+    <xref linkend="guc-autovacuum-analyze-scale-factor"/>,
+    and minimum number of changed rows <xref linkend="guc-autovacuum-analyze-threshold"/>,
+    statistics per table. The automatic analysis
+    allows <productname>PostgreSQL</productname> to
+    adapt query execution to changing circumstances.
+    connection running simultaneously with a data modifying
+    database always remains
+    <glossterm linkend="glossary-consistency">consistent</glossterm>.
+    Declarative rules like
+    Lastly, it is worth noticing that changes done by a
+    committed transaction will survive all failures in the application or
+    database cluster. The next chapter explains the
+    <glossterm linkend="glossary-durability">durability</glossterm>
+    guarantees.
+    In constrast with the WAL records, this part may or may
+    to heap and index. As a result, the heap files contain all
+    changes recorded to the WAL and reach a consistent state. Changes of committed
+    transactions are visible; those of uncommitted transactions
+    by any of the following transactions because uncommitted
+    They obviously needs a backup. How to take such a backup
+    Committed data is neither lost nor corrupted.
+    To recover from such a situation, the administrator should
+    remove unused files from this disk. But they should never
+    the copy in the form of SQL commands like <command>CREATE</command>
+    and <command>COPY</command>. It runs in
+    parallel with other processes in its own transaction.
+    parallel with other processes in its own transaction.

+  &architecture;
   &arch-dev;
   &catalogs;
   &protocol;

    <para>
 
-    <itemizedlist>
-     <listitem>
-      <para>
 
-     <listitem>
-      <para>
 
-    </itemizedlist>
-   </para>
+    <listitem>
+     <para>
 
    <para>
 
-   <para>

index e547a87d08..0c663a9d80 100644
 
    <para>
@@ -66,32 +65,31 @@
-    starts a new Backend process and instructs the client
-    application to connect to it. All further client requests
+    starts a new Backend process, which handles all further
+    client's requests.
    </para>
 
    <para>
 
    <para>
-    Background Writer and the Checkpointer process to ensure
+    Checkpointer and the Background Writer processes to ensure
 
@@ -109,7 +107,7 @@
@@ -119,35 +117,36 @@
 
    <para>
-    The Checkpointer creates
+    The Checkpointer process creates
     <glossterm linkend="glossary-checkpoint">Checkpoints</glossterm>.
     A Checkpoint is a point in time when all older dirty buffers,
     all older WAL records, and finally a special Checkpoint record
-    have been written and flushed to disk. Heap and index files
+    are written and flushed to disk. Heap and index files
     on the one hand and WAL files on the other hand are in sync.
     Previous WAL is no longer required. In other words,
     a possibly occurring recovery, which integrates the delta
     information of WAL into heap and index files, will happen
-    by replaying only WAL past the last recorded checkpoint
-    on top of the current heap and files. This speeds up recovery.
+    by replaying only WAL past the last recorded checkpoint.
+    This limits the amount of WAL which needs to be replayed
+    during recovery in the event of a crash.
    </para>
 
    <para>
-    to handle the case where the heap and files themselves become
+    to handle the case where the heap or other files become
@@ -159,7 +158,7 @@
 -->
 
    <para>
-    The Statistics Collector collects counters about accesses to
+    The Statistics Collector collects counters about access to
     SQL objects like tables, rows, indexes, pages, and more. It
     stores the obtained information in system tables.
    </para>
@@ -234,13 +233,13 @@
    <para>
 
    <para>
@@ -352,27 +351,26 @@
 
    <para>
 
    <para>
     The subdirectory <literal>pg_wal</literal> contains the
     <glossterm linkend="glossary-wal-file">WAL files</glossterm>.
-    They arise and grow parallel to data changes in the
-    cluster and remain alive as long as
+    They arise and grow in parallel with data changes in the
+    cluster and remain as long as
     they are required for recovery, archiving, or replication.
    </para>
 
@@ -385,18 +383,18 @@
 
    <para>
     In <literal>pg_tblspc</literal>, there are symbolic links
-    that point to directories containing such SQL objects
-    that are created within tablespaces.
+    that point to directories containing SQL objects
+    that exist within a non-default tablespace.
    </para>
 
    <para>
 
    <para>
@@ -411,7 +409,7 @@
 
    <para>
@@ -425,18 +423,18 @@
 
    <para>
     A first approach to implement protections against concurrent
-    accesses to the same data may be the locking of critical
+    access to the same data may be the locking of critical
     rows. Two such techniques are:
     <emphasis>Optimistic Concurrency Control</emphasis> (OCC)
     and <emphasis>Two Phase Locking</emphasis> (2PL).
     <productname>PostgreSQL</productname> implements a third, more
     sophisticated technique: <firstterm>Multiversion Concurrency
     Control</firstterm> (MVCC). The crucial advantage of MVCC
-    over other technologies gets evident in multiuser OLTP
+    over other technologies becomes evident in multiuser OLTP
     environments with a massive number of concurrent write
     actions. There, MVCC generally performs better than solutions
     using locks. In a <productname>PostgreSQL</productname>
-    database reading never blocks writing and writing never
+    database, reading never blocks writing and writing never
     blocks reading, even in the strictest level of transaction
     isolation.
    </para>
@@ -444,14 +442,14 @@
    <para>
     Instead of locking rows, the <firstterm>MVCC</firstterm> technique creates
     a new version of the row when a data-change takes place. To
-    distinguish between these two versions and to track the timeline
+    distinguish between these two versions, and to track the timeline
     of the row, each of the versions contains, in addition to their user-defined
     columns, two special system columns, which are not visible
     for the usual <command>SELECT * FROM ...</command> command.
     The column <literal>xmin</literal> contains the transaction ID (xid)
-    of the transaction, which created this version of the row. Accordingly,
-    <literal>xmax</literal> contains the xid of the transaction, which has
-    deleted this version, or zero, if the version is not
+    of the transaction which created this version of the row.
+    <literal>xmax</literal> contains the xid of the transaction which has
+    deleted this version, or zero if the version is not
     deleted. You can read both with the command
     <command>SELECT xmin, xmax, * FROM ... </command>.
    </para>
@@ -461,7 +459,7 @@
     sequences. Every new transaction receives the next number as its ID.
     Therefore, this flow of xids represents the flow of transaction
     start events over time. But keep in mind that xids are independent of
-    any time measurement &mdash; in milliseconds or whatever. If you dive
+    any time measurement &mdash; in milliseconds or otherwise. If you dive
     deeper into <productname>PostgreSQL</productname>, you will recognize
     parameters with names such as 'xxx_age'. Despite their names,
     these '_age' parameters do not specify a period of time but represent
@@ -469,7 +467,7 @@
    </para>
 
    <para>
@@ -481,7 +479,7 @@
    </para>
 
    <para>
-    So, what's going on in detail when write accesses take place?
+    So, what's going on in detail when write access takes place?
     <xref linkend="tutorial-mvcc-figure"/> shows details concerning
     <literal>xmin</literal>, <literal>xmax</literal>, and user data.
    </para>
@@ -516,36 +514,38 @@
     executes an <command>UPDATE</command> of this row by
     changing the user data from <literal>'x'</literal> to
     <literal>'y'</literal>. According to the MVCC principles,
-    the data in the old version of the row does not change!
+    the data in the old version of the row is not changed!
     The value <literal>'x'</literal> remains as it was before.
     Only <literal>xmax</literal> changes to <literal>135</literal>.
     Now, this version is treated as valid exclusively for
     transactions with xids from <literal>123</literal> to
-    <literal>134</literal>. As a substitute for the non-occurring
+    <literal>134</literal>. In addition to the non-occurring
     data change in the old version, the <command>UPDATE</command>
     creates a new version of the row with its xid in
     <literal>xmin</literal>, <literal>0</literal> in
     <literal>xmax</literal>, and <literal>'y'</literal> in the
-    user data (plus all the other user data from the old version).
-    This version is now valid for all coming transactions.
+    user data (plus all other user data from the old version).
+    This new row version is visible to all future transactions.
+    (Internally, an <command>UPDATE</command> command acts
+    as a <command>DELETE</command> command followed by
+    an <command>INSERT</command> command.)
    </para>
 
    <para>
     All subsequent <command>UPDATE</command> commands behave
-    in the same way as the first one: they put their xid to
+    in the same way as the first one: they put their xid in
     <literal>xmax</literal> of the current version, create
-    the next version with their xid in <literal>xmin</literal>,
-    <literal>0</literal> in <literal>xmax</literal>, and the
-    new user data.
+    a new version with their xid in <literal>xmin</literal> and
+    <literal>0</literal> in <literal>xmax</literal>.
    </para>
 
    <para>
     Finally, a row may be deleted by a <command>DELETE</command>
     command. Even in this case, all versions of the row remain as
-    before. Nothing is thrown away so far! Only <literal>xmax</literal>
-    of the last version changes to the xid of the <command>DELETE</command>
-    transaction, which indicates that it is only valid for
-    transactions with xids older than its own (from
+    before. Nothing is thrown away! Only <literal>xmax</literal>
+    of the last version is set to the xid of the <command>DELETE</command>
+    transaction, which indicates that (if committed) it is only visible to
+    transactions with xids older than that (from
     <literal>142</literal> to <literal>820</literal> in this
     example).
    </para>
@@ -555,10 +555,10 @@
     of the same row in the table's heap file and leaves them there,
     even after a <command>DELETE</command> command. Only the youngest
     version is relevant for all future transactions. But the
-    system must also preserve some of the older ones for a
-    certain amount of time because the possibility exists that
-    they are or could become relevant for any pending
-    transactions. Over time, also the older ones get out of scope
+    system must also preserve some of the older ones for
+    awhile, because they could still be needed by
+    transactions which started before the deleting transaction commits.
+    Over time, also the older ones get out of scope
     for ALL transactions and therefore become unnecessary.
     Nevertheless, they do exist physically on the disk and occupy
    space.
@@ -573,13 +573,13 @@
      <simpara>
       <literal>xmin</literal> and <literal>xmax</literal>
       indicate the range from where to where
-      row versions are valid (visible) for transactions.
+      <firstterm>row versions</firstterm> are valid (visible) for transactions.
       This range doesn't imply any direct temporal meaning;
       the sequence of xids reflects only the sequence of
       transaction begin events. As
       xids grow, old row versions get out of scope over time.
-      If an old row version is no longer valid for ALL existing
-      transactions, it's called <firstterm>dead</firstterm>. The
+      If an old row version is no longer relevant for ANY existing
+      transactions, it can be marked <firstterm>dead</firstterm>. The
       space occupied by dead row versions is part of the
       <glossterm linkend="glossary-bloat">bloat</glossterm>.
      </simpara>
@@ -612,21 +612,21 @@
 
    <para>
     As we have seen in the previous chapter, the database
-    tends to occupy more and more disk space, the
+    tends to occupy more and more disk space, caused by
     <glossterm linkend="glossary-bloat">bloat</glossterm>.
     This chapter explains how the SQL command
     <command>VACUUM</command> and the automatically running
     <firstterm>Autovacuum</firstterm> processes clean up
-    by eliminating bloat.
+    and avoid continued growth.
    </para>
 
    <note>
     <para>
      Autovacuum runs automatically by
      default. Its default parameters as well as such for
-     <command>VACUUM</command> fit well for most standard
+     <command>VACUUM</command> are appropriate for most standard
      situations. Therefore a novice database manager can
-     easily skip the rest of this chapter which explains
+     skip the rest of this chapter which explains
      a lot of details.
     </para>
    </note>
@@ -637,8 +637,8 @@
     special situations, or they start it in batch jobs which run
     periodically. Autovacuum processes run as part of the
     <link linkend="glossary-instance">Instance</link> at the server.
-    There is a constantly running Autovacuum daemon. It permanently
-    controls the state of all databases based on values that are collected by the
+    There is a constantly running Autovacuum daemon. It continuously
+    monitors the state of all databases based on values that are collected by the
     <link linkend="glossary-stats-collector">Statistics Collector</link>
     and starts Autovacuum processes whenever it detects
     certain situations. Thus, it's a dynamic behavior of
@@ -659,9 +659,9 @@
 
     <listitem>
      <simpara>
-      <firstterm>Freeze</firstterm>: Mark the youngest row version
-      as frozen. This means that the version
-      is always treated as valid (visible) independent from
+      <firstterm>Freeze</firstterm>: Mark certain row versions
+      as frozen. This means that they
+      are always treated as valid (visible) independent from
       the <firstterm>wraparound problem</firstterm> (see below).
      </simpara>
     </listitem>
@@ -686,22 +686,22 @@
    </itemizedlist>
 
    <para>
-    The eagerness &mdash; you can call it 'aggression' &mdash; of the
-    operations <emphasis>eliminating bloat</emphasis> and
+    The eagerness &mdash; you can call it 'aggressiveness' &mdash; of the
+    operations for <emphasis>eliminating bloat</emphasis> and
     <emphasis>freeze</emphasis> is controlled by configuration
     parameters, runtime flags, and in extreme situations by
     the processes themselves. Because vacuum operations typically are I/O
     intensive, which can hinder other activities, Autovacuum
     avoids performing many vacuum operations in bulk. Instead,
-    it carries out many small actions with time gaps in between.
+    it carries out many small actions with delay points in between.
     The SQL command <command>VACUUM</command> runs immediately
-    and without any time gaps.
+    and without any time delay.
    </para>
 
    <bridgehead renderas="sect2">Eliminate Bloat</bridgehead>
 
    <para>
-    To determine which of the row versions are superfluous, the
+    To determine which of the row versions are no longer needed, the
     elimination operation must evaluate <literal>xmax</literal>
     against several criteria which all must apply:
    </para>
@@ -742,14 +742,13 @@
    </itemizedlist>
 
    <para>
-    After the vacuum operation detects a superfluous row version, it
+    After the vacuum operation detects an unused row version, it
     marks its space as free for future use of writing actions. Only
     in rare situations (or in the case of <command>VACUUM FULL</command>),
-    this space is released to the operating system. In most cases,
+    is this space released to the operating system. In most cases,
     it remains occupied by <productname>PostgreSQL</productname>
     and will be used by future <command>INSERT</command> or
-    <command>UPDATE</command> commands concerning this row or a
-    completely different one.
+    <command>UPDATE</command> commands to this table.
    </para>
 
    <para>
@@ -762,10 +761,10 @@
        When a client issues the SQL command <command>VACUUM</command>
        in its default format, i.e., without any option. To boost performance,
        in this and the next case <command>VACUUM</command> does not
-       read and act on all pages of the heap.
-       The Visibility Map, which is very compact and therefore has a small
-       size, contains information about pages, where bloat-candidates might
-       be found. Only such pages are processed.
+       read and act on all pages of the heap file.
+       The Visibility Map, which is very compact and therefore fast to read,
+       contains information about which pages have no deleted row versions, and
+       can be skipped by <command>VACUUM</command>.
       </simpara>
      </listitem>
 
@@ -773,7 +772,7 @@
       <simpara>
        When a client issues the SQL command <command>VACUUM</command>
        with the option <command>FREEZE</command>. (In this case,
-       it undertakes much more actions, see
+       it undertakes many more actions, see
        <link linkend="tutorial-freeze">Freeze Row Versions</link>.)
       </simpara>
      </listitem>
@@ -782,12 +781,11 @@
       <simpara>
        When a client issues the SQL command <command>VACUUM</command>
        with the option <command>FULL</command>.
-       Also, in this mode, the bloat disappears, but the strategy used
-       is very different: In this case, the complete table is copied
-       to a different file skipping all outdated row versions. This
-       leads to a significant reduction of used disk space because
-       the new file contains only the actual data. The old file
-       is deleted.
+       In this mode, an exclusive lock is taken, and
+       the whole table is copied to a different file, skipping all outdated row
+       versions.  All bloat is thereby eliminated, which
+       may lead to a significant reduction of used disk space.
+       The old file is deleted.
       </simpara>
      </listitem>
 
@@ -809,17 +807,17 @@
    <para>
     This logic only applies to row versions of the heap. Index entries
     don't use <literal>xmin/xmax</literal>. Nevertheless, such index
-    entries, which would lead to outdated row versions, are released
+    entries, which would lead to outdated row versions, are cleaned up
     accordingly.
    </para>
 
    <para>
     The above descriptions omit the fact that xids on a real computer
-    have a limited size. They count up in the same way as sequences, and after
-    a certain number of new transactions they are forced to restart
+    have a limited size, and after
+    a certain number of transactions they are forced to restart
     from the beginning, which is called <firstterm>wraparound</firstterm>.
     Therefore the terms 'old transaction' / 'young transaction' does
-    not always correlate with low / high values of xids. Near to the
+    not always correlate with low / high values of xids. Near to
     wraparound point, there are cases where <literal>xmin</literal> has
     a higher value than <literal>xmax</literal>, although their meaning
     is said to be older than <literal>xmax</literal>.
@@ -858,7 +856,7 @@
     and the corresponding transactions of <literal>xmin</literal>
     and <literal>xmax</literal> must be committed. However,
     <productname>PostgreSQL</productname> has to consider the
-    possibility of wraparounds.
+    possibility of wraparound.
     Therefore the decision becomes more complex. The general
     idea of the solution is to use the 'between
     <literal>xmin</literal> and <literal>xmax</literal>'
@@ -885,7 +883,7 @@
     <listitem>
      <simpara>
       With each newly created transaction the two split-points
-      move forward. When 'txid_current + 2^31' would reach a
+      move forward. If 'txid_current + 2^31' reached a
       row version with <literal>xmin</literal> equal to that value, it would
       immediately jump from 'past' to 'future' and would be
       no longer visible!
@@ -894,11 +892,11 @@
 
     <listitem>
      <simpara>
-      To avoid this unacceptable extinction of data, the vacuum
-      operation <firstterm>freeze</firstterm> clears the situation
-      long before the split-point is reached. It sets a flag
-      in the header of the row version, which completely eliminates
-      the future use of <literal>xmin/xmax</literal> and indicates
+      If not handled in some way, data inserted many transactions ago
+      would become invisibile. The vacuum operation <firstterm>freeze</firstterm>
+      avoids this long before the split-point is reached by setting
+      a flag in the header of the row version which avoids
+      future comparison of its <literal>xmin/xmax</literal> and indicates
       that the version is valid not only in the 'past'-half
       but also in the 'future'-half as well as in all coming
       <glossterm linkend="glossary-xid">epochs</glossterm>.
@@ -945,19 +943,19 @@
        When a client issues the SQL command <command>VACUUM</command>
        with its <command>FREEZE</command> option. In this case, all
        pages are processed that are marked in the Visibility Map
-       to potentially have unfrozen rows.
+       as potentially having unfrozen rows.
       </simpara>
      </listitem>
      <listitem>
       <simpara>
        When a client issues the SQL command <command>VACUUM</command> without
-       any options but finds that there are xids older than
+       any options but there are xids older than
        <xref linkend="guc-vacuum-freeze-table-age"/>
        (default: 150 million) minus
        <xref linkend="guc-vacuum-freeze-min-age"/>
        (default: 50 million).
        As before, all pages are processed that are
-       marked in the Visibility Map to potentially have unfrozen
+       marked in the Visibility Map to potentially having unfrozen
        rows.
       </simpara>
      </listitem>
@@ -983,7 +981,7 @@
         <simpara>
          The process switches
          to an <emphasis>aggressive mode</emphasis> if it recognizes
-         that for the processed table their oldest xid exceeds
+         that for the processed table the oldest xid exceeds
          <xref linkend="guc-autovacuum-freeze-max-age"/>
          (default: 200 million). The value of the oldest unfrozen
          xid is stored per table in <literal>pg_class.relfrozenxid</literal>.
@@ -1039,29 +1037,28 @@
    <para>
     The <link linkend="glossary-vm">Visibility Map</link>
     (VM) contains two flags &mdash; stored as
-    two bits &mdash; for each page of the heap. If the first bit
-    is set, that indicates that the associated page does not
-    contain any bloat. If the second one is set, that indicates
-    that the page contains only frozen rows.
+    two bits &mdash; for each page of the heap file. The
+    first bit indicates that the associated page does
+    not contain any bloat. The second bit indicates
+    that the page contains only frozen row versions.
    </para>
 
    <para>
      Please consider two details. First, in most cases a page
-     contains many rows, some of them in many versions.
+     contains many rows or row versions.
      However, the flags are associated with the page,
-     not with a row or a row version. The flags are set
+     not with an individual row version. The flags are set
      only under the condition that they are valid for ALL
      row versions of the page. Second, since there
      are only two bits per page, the VM is considerably
-     smaller than the heap. Therefore it is buffered
-     in RAM in almost all cases.
+     smaller than the heap.
    </para>
 
    <para>
     The setting of the flags is silently done by <command>VACUUM</command>
     and Autovacuum during their bloat and freeze operations.
     This is done to speed up future vacuum actions,
-    regular accesses to heap pages, and some accesses to
+    regular access to heap pages, and some access to
     the index. Every data-modifying operation on any row
     version of the page clears the flags.
    </para>
@@ -1070,7 +1067,7 @@
     The <link linkend="glossary-fsm">Free Space Map</link>
     (FSM) tracks the amount of free space per page. It is
     organized as a highly condensed b-tree of (rounded) sizes.
-    As long as <command>VACUUM</command> or Autovacuum change
+    Whenever <command>VACUUM</command> or Autovacuum changes
     the free space on any processed page, they log the new
     values in the FSM in the same way as all other writing
     processes.
@@ -1079,18 +1076,19 @@
    <bridgehead renderas="sect2">Statistics</bridgehead>
 
    <para>
-    Statistic information helps the <link
+    Statistical information helps the <link
     linkend="planner-stats">Query Planner</link> to make optimal
     decisions for the generation of execution plans. This
     information can be gathered with the SQL commands
     <command>ANALYZE</command> or <command>VACUUM ANALYZE</command>.
-    But also Autovacuum processes gather
+    But Autovacuum processes also gather
     such information. Depending on the percentage of changed rows
-    per table <xref linkend="guc-autovacuum-analyze-scale-factor"/>,
+    <xref linkend="guc-autovacuum-analyze-scale-factor"/>,
+    and minimum number of changed rows <xref linkend="guc-autovacuum-analyze-threshold"/>,
     the Autovacuum daemon starts Autovacuum processes to collect
-    statistics per table. This dynamic invocation of analyze
-    operations allows <productname>PostgreSQL</productname> to
-    adopt queries to changing circumstances.
+    statistics per table. The automatic analysis
+    allows <productname>PostgreSQL</productname> to
+    adapt query execution to changing circumstances.
    </para>
 
    <para>
@@ -1143,7 +1141,7 @@ UPDATE accounts SET balance = balance + 100.00 WHERE name = 'Bob';
@@ -1151,20 +1149,20 @@ UPDATE accounts SET balance = balance + 100.00 WHERE name = 'Bob';
 
    <para>
-    connection running simultaneously to a data modifying
+    connection running simultaneously with a data modifying
 
    <para>
 
@@ -1230,9 +1228,9 @@ UPDATE accounts SET balance = balance + 100.00 WHERE name = 'Bob';
 
    <para>
     Transactions ensure that the
-    <glossterm linkend="glossary-consistency">consistency</glossterm>
-    of the complete database always keeps valid. Declarative
-    rules like
+    database always remains
+    <glossterm linkend="glossary-consistency">consistent</glossterm>.
+    Declarative rules like
     <link linkend="ddl-constraints-primary-keys">primary</link>- or
     <link linkend="ddl-constraints-fk">foreign keys</link>,
     <link linkend="ddl-constraints-check-constraints">checks</link>,
@@ -1241,13 +1239,6 @@ UPDATE accounts SET balance = balance + 100.00 WHERE name = 'Bob';
     are part of the all-or-nothing nature of transactions.
    </para>
 
-   <para>
@@ -1257,11 +1248,11 @@ UPDATE accounts SET balance = balance + 100.00 WHERE name = 'Bob';
    </para>
 
    <para>
-    Lastly, it is worth to notice that changes done by a
-    committed transaction will survive all future application,
-    instance, or hardware failures. The next chapter
-    explains this
-    <glossterm linkend="glossary-durability">durability</glossterm>.
+    Lastly, it is worth noticing that changes done by a
+    committed transaction will survive all failures in the application or
+    database cluster. The next chapter explains the
+    <glossterm linkend="glossary-durability">durability</glossterm>
+    guarantees.
    </para>
   </sect1>
 
@@ -1287,7 +1278,7 @@ UPDATE accounts SET balance = balance + 100.00 WHERE name = 'Bob';
     a severe software error like a null pointer exception.
     Because <productname>PostgreSQL</productname> uses a
     client/server architecture, no direct problem for the
-    database will occur. In all of this cases, the
+    database will occur. In all of these cases, the
     <glossterm linkend="glossary-backend">Backend process</glossterm>,
     which is the client's counterpart at the server-side,
     may recognize that the network connection is no longer
@@ -1310,7 +1301,7 @@ UPDATE accounts SET balance = balance + 100.00 WHERE name = 'Bob';
     automatically recognizes that the last shutdown of the
     instance did not happen as expected: files might not be
     closed properly and the <literal>postmaster.pid</literal>
-    file exists. <productname>PostgreSQL</productname>
+    file unexpectedly exists. <productname>PostgreSQL</productname>
     tries to clean up the situation. This is possible because
     all changes in the database are stored twice. First,
     the WAL files contain them as a chronology of
@@ -1318,7 +1309,7 @@ UPDATE accounts SET balance = balance + 100.00 WHERE name = 'Bob';
     which include the new data values and information about commit
     actions. The WAL records are written first. Second,
     the data itself shall exist in the heap and index files.
-    In opposite to the WAL records, this part may or may
+    In constrast with the WAL records, this part may or may
     not have been transferred entirely from Shared Memory
     to the files.
    </para>
@@ -1328,13 +1319,13 @@ UPDATE accounts SET balance = balance + 100.00 WHERE name = 'Bob';
     <glossterm linkend="glossary-checkpoint">checkpoint</glossterm>.
     This checkpoint signals that the database files are in
     a consistent state, especially that all WAL records up to
-    this point were successfully stored in heap and index. Starting
-    here, the recovery process copies the following WAL records
-    to heap and index. As a result, the files contain all
-    changes and reach a consistent state. Changes of committed
-    transactions are visible; those of uncommited transactions
+    this point were successfully stored in heap and index files. Starting
+    here, the recovery process copies the remaining WAL records
+    to heap and index. As a result, the heap files contain all
+    changes recorded to the WAL and reach a consistent state. Changes of committed
+    transactions are visible; those of uncommitted transactions
     are also in the files, but - as usual - they are never seen
-    by any of the following transactions because uncommited
+    by any of the following transactions because uncommitted
     changes are never shown. Such recovery actions run
     completely automatically, it is not necessary that a
     database administrator configure or start anything by
@@ -1344,13 +1335,13 @@ UPDATE accounts SET balance = balance + 100.00 WHERE name = 'Bob';
    <bridgehead renderas="sect3">Disk crash</bridgehead>
    <para>
     If a disk crashes, the course of action described previously
-    cannot work. It is likely that the WAL files and/or the
+    cannot work: it is likely that the WAL files and/or the
     data and index files are no longer available. The
     database administrator must take special actions to
-    overcome such situations.
+    prepare for such a situation.
    </para>
    <para>
-    He obviously needs a backup. How to take such a backup
+    They obviously needs a backup. How to take such a backup
     and use it as a starting point for a recovery of the
     cluster is explained in more detail in the next
     <link linkend="tutorial-backup">chapter</link>.
@@ -1362,11 +1353,11 @@ UPDATE accounts SET balance = balance + 100.00 WHERE name = 'Bob';
     and there is no room for additional data. In this case,
     <productname>PostgreSQL</productname> stops accepting
     data-modifying commands or even terminates completely.
-    No data loss or data corruption will occur.
+    Committed data is neither lost nor corrupted.
    </para>
    <para>
-    To come out of such a situation, the administrator should
-    remove unused files from this disk. But he should never
+    To recover from such a situation, the administrator should
+    remove unused files from this disk. But they should never
     delete files from the
     <glossterm linkend="glossary-data-directory">data directory</glossterm>.
     Nearly all of them are necessary for the consistency
@@ -1427,7 +1418,7 @@ UPDATE accounts SET balance = balance + 100.00 WHERE name = 'Bob';
    </para>
    <para>
     The obvious disadvantage of this method is that there
-    is a downtime where no user interaction is possible.
+    is a downtime.
     The other two strategies run during regular operating
     times.
    </para>
@@ -1437,9 +1428,9 @@ UPDATE accounts SET balance = balance + 100.00 WHERE name = 'Bob';
     The tool <command>pg_dump</command> is able to take a
     <link linkend="backup-dump">copy</link>
     of the complete cluster or certain parts of it. It stores
-    the copy in the form of SQL <command>CREATE</command> and
-    <command>INSERT</command> commands. It runs in
-    parallel to other processes in its own transaction.
+    the copy in the form of SQL commands like <command>CREATE</command>
+    and <command>COPY</command>. It runs in
+    parallel with other processes in its own transaction.
    </para>
    <para>
     The output of <command>pg_dump</command> may be used as
@@ -1456,17 +1447,17 @@ UPDATE accounts SET balance = balance + 100.00 WHERE name = 'Bob';
    <bridgehead renderas="sect2">Continuous archiving based on pg_basebackup and WAL files</bridgehead>
    <para>
     <link linkend="continuous-archiving">This method</link>
-    is the most sophisticated and complex one. It
+    is the most sophisticated and most complex one. It
     consists of two phases.
    </para>
    <para>
-    First, you need to create a so called
+    First, you need to create a so-called
     <firstterm>basebackup</firstterm> with the tool
     <command>pg_basebackup</command>. The result is a
-    directory structure plus files which contains a
+    directory structure plus files which contain a
     consistent copy of the original cluster.
     <command>pg_basebackup</command> runs in
-    parallel to other processes in its own transaction.
+    parallel with other processes in its own transaction.
    </para>
    <para>
     The second step is recommended but not necessary. All
@@ -1484,7 +1475,7 @@ UPDATE accounts SET balance = balance + 100.00 WHERE name = 'Bob';
     <glossterm linkend="glossary-wal-archiver">Archiver process</glossterm>
     will automatically copy every single WAL file to a save location.
     <link linkend="backup-archiving-wal">Its configuration</link>
-    consists mainly of a string, which contains a copy command
+    consists mainly of a string that contains a copy command
     in the operating system's syntax. In order to protect your
     data against a disk crash, the destination location
     of a basebackup as well as of the
@@ -1492,9 +1483,8 @@ UPDATE accounts SET balance = balance + 100.00 WHERE name = 'Bob';
     disk which is different from the data disk.
    </para>
    <para>
-    If it gets necessary to restore the cluster, you have to
-    copy the basebackup and the
-    archived WAL files to
+    If it becomes necessary to restore the cluster, you have to
+    copy the basebackup and the archived WAL files to
     their original directories. The configuration of this
     <link linkend="backup-pitr-recovery">recovery procedure</link>
     contains a string with the reverse copy command: from

---

From: Erik Rijkers <[email-masked]>
Date: Mon, 02 Nov 2020 07:15:28 +0100

> - 'Two Phase Locking' is the intended term.

OK, so what is 'Two Phase Locking'?  The term is not explained, and not 
used anywhere else in the manual.  You propose to introduce it here, in 
the tutorial.  I don't know what it means, and I am not really a 
beginner.

'Two Phase Locking' should be explained somewhere, and how it relates 
(or not) to Two-Phase Commit (2PC), don't you agree?

Erik Rijkers

---

From: Jürgen Purtz <[email-masked]>
Date: Mon, 2 Nov 2020 09:26:27 +0100

On 02.11.20 07:15, Erik Rijkers wrote:
> OK, so what is 'Two Phase Locking'?  The term is not explained, and 
> not used anywhere else in the manual.  You propose to introduce it 
> here, in the tutorial.  I don't know what it means, and I am not 
> really a beginner.
>
It may be possible to explain OCC and 2PL in two or three sentences 
within the glossary. But I think, we shall not try to explain such 
general strategies. They are not specific to PG and even not 
implemented. Instead, if the paragraph is too detailed, we can use a 
more general formulation without explicitly naming locking strategies.

OLD:

     A first approach to implement protections against concurrent
     access to the same data may be the locking of critical
     rows. Two such techniques are:
     <emphasis>Optimistic Concurrency Control</emphasis> (OCC)
     and <emphasis>Two Phase Locking</emphasis> (2PL).
     <productname>PostgreSQL</productname> implements a third, more
     sophisticated technique: <firstterm>Multiversion Concurrency
     Control</firstterm> (MVCC). The crucial advantage of MVCC ...

Proposal:

     A first approach to implement protections against concurrent
     access to the same data may be the locking of critical
     rows.
     <productname>PostgreSQL</productname> implements a more
     sophisticated technique which avoids any locking: 
<firstterm>Multiversion Concurrency
     Control</firstterm> (MVCC). The crucial advantage of MVCC ...

Any thoughts or other suggestions?

--

J. Purtz

---

From: Erik Rijkers <[email-masked]>
Date: Mon, 02 Nov 2020 09:44:54 +0100

> Any thoughts or other suggestions?

Yes, just leave it out. Much better, as far as I'm concerned.

Erik

---

From: Jürgen Purtz <[email-masked]>
Date: Sat, 7 Nov 2020 13:24:53 +0100

> Yes, just leave it out. Much better, as far as I'm concerned.
Because there have been no more comments in the last days I created a 
consolidated patch. It contains Erik's suggestion and some tweaks for 
the text size within graphics.

--

J. Purtz

 
 
  <chapter id="overview">
 
   <note>
    <title>Author</title>
index 0000000000..b3446c2ea1
@@ -0,0 +1,1504 @@
+      <!-- distinction html/pdf is necessary to keep font-size of SVG text
+      <imagedata fileref="images/ram-proc-file-raw.svg" format="SVG" />
+      <!-- distinction html/pdf is necessary to keep font-size of SVG text
+      <imagedata fileref="images/cluster-db-schema-raw.svg" format="SVG" />
+      <!-- distinction html/pdf is necessary to keep font-size of SVG text
+      <imagedata fileref="images/internal-objects-hierarchy-raw.svg" format="SVG" />
+      <!-- distinction html/pdf is necessary to keep font-size of SVG text
+      <imagedata fileref="images/directories-raw.svg" format="SVG" />
+    access to the same data may be the locking of critical rows.
+    <productname>PostgreSQL</productname> implements a more
+    sophisticated technique which avoids any locking:
+    <firstterm>Multiversion Concurrency Control</firstterm> (MVCC).
+    The crucial advantage of MVCC
+      <!-- distinction html/pdf is necessary to keep font-size of SVG text
+      <imagedata fileref="images/mvcc-raw.svg" format="SVG" />
+      <!-- distinction html/pdf is necessary to keep font-size of SVG text
+      <imagedata fileref="images/wraparound-raw.svg" format="SVG" />
+      <!-- distinction html/pdf is necessary to keep font-size of SVG text
+      <imagedata fileref="images/freeze-raw.svg" format="SVG" />
 
index 0000000000..bdbfc38387
+    .text_normal,.text_small{font-style:normal;font-weight:400;font-family:&quot;Open Sans&quot;,sans-serif;fill:#000}.text_small{font-size:12px}.text_normal{font-size:14px}
index 0000000000..86f878a12d
+   inkscape:version="0.92.5 (2060ec1f9f, 2020-04-08)">
+     inkscape:window-x="66"
+                 font-size:14px;
index 0000000000..022bc45560
+                 font-size:14px;
index 0000000000..c03c2607ee
+    .text_normal{font-style:normal;font-weight:400;font-size:14px;font-family:&quot;Open Sans&quot;,sans-serif;fill:#000}
index 0000000000..238905cde8
+   id="svg4006"
+   inkscape:version="0.92.5 (2060ec1f9f, 2020-04-08)">
+     id="metadata4010">
+     id="namedview4008"
+     inkscape:window-x="66"
+     inkscape:current-layer="svg4006" />
+     id="title3856">Directory structure of a cluster</title>
+     id="style3858">
+                 font-size:14px;
+     id="defs3880">
+         id="title3860">Directory</title>
+         id="rect3862" />
+         id="path3864" />
+         id="title3867">File</title>
+         id="rect3869" />
+         id="path3871" />
+         id="path3873" />
+         id="path3875" />
+         id="path3877" />
+     id="rect3882" />
+     id="text3884">Directory Structure</text>
+     id="g3892">
+       id="use3886" />
+       id="text3888">... /pg/</text>
+       id="text3890">An arbitrary directory</text>
+     id="g3900">
+       id="use3894" />
+       id="text3896">data/</text>
+       id="text3898">Root of cluster 'data' (see: PGDATA)</text>
+     id="g3908">
+       id="use3902" />
+       id="text3904">base/</text>
+       id="text3906">Subdirectory containing per-database subdirectories</text>
+     id="g3916">
+       id="use3910" />
+       id="text3912">1/</text>
+       id="text3914">Subdirectory for data of first database 'template0'</text>
+     id="g3924">
+       id="use3918" />
+       id="text3920">12992/</text>
+       id="text3922">Subdirectory for data of second database 'template1'</text>
+     id="g3932">
+       id="use3926" />
+       id="text3928">12999/</text>
+       id="text3930">Subdirectory for data of third database 'postgres'</text>
+     id="g3940">
+       id="use3934" />
+       id="text3936">nnnnn/</text>
+       id="text3938">Optional: more subdirectories for databases, e.g. 'my_db'</text>
+     id="g3948">
+       id="use3942" />
+       id="text3944">global/</text>
+       id="text3946">Subdirectory with information about Global SQL Objects</text>
+     id="g3956">
+       id="use3950" />
+       id="text3952">pg_wal/</text>
+       id="text3954">Subdirectory for Write Ahead Log files ('pg_xlog' before version 10)</text>
+     id="g3964">
+       id="use3958" />
+       id="text3960">pg_xact/</text>
+       id="text3962">Subdirectory for transaction commit status ('pg_clog' before version 10)</text>
+     id="g3972">
+       id="use3966" />
+       id="text3968">pg_tblspc/</text>
+       id="text3970">Subdirectory containing symbolic links to tablespaces</text>
+     id="g3980">
+       id="use3974" />
+       id="text3976">pg_... /</text>
+       id="text3978">Some more subdirectories</text>
+     id="g3988">
+       id="use3982" />
+       id="use3984" />
+       id="text3986">'postmaster.pid' and other files with cluster-wide relevance</text>
+     id="g3996">
+       id="use3990" />
+       id="text3992">... /xyz/</text>
+       id="text3994">Same or another arbitrary directory</text>
+     id="g4004">
+       id="use3998" />
+       id="text4000">cluster_2/</text>
+       id="text4002">Root of another cluster 'cluster_2'</text>
index 0000000000..757342a554
+                 font-size:14px;
index 0000000000..fecefbeaf3
+    .text_normal{font-style:normal;font-weight:400;font-size:14px;font-family:&quot;Open Sans&quot;,sans-serif;fill:#000}
+      <textPath xlink:href="#Path_095" startOffset=".5%">|</textPath> <textPath xlink:href="#Path_120" startOffset="0%">(0)</textPath> <textPath xlink:href="#Path_080" startOffset="1%" stroke="blue" stroke-width=".5"> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - &gt;</textPath> <textPath xlink:href="#Path_120" startOffset="11.2%">(1)</textPath> <textPath xlink:href="#Path_120" startOffset="61.2%">(5)</textPath> <textPath xlink:href="#Path_095" stroke="red" stroke-width="3" startOffset="34%">|</textPath> <textPath xlink:href="#Path_120" startOffset="34%">(2)</textPath> <textPath xlink:href="#Path_095" stroke="black" stroke-width="3" startOffset="45%">|</textPath> <textPath xlink:href="#Path_120" startOffset="45%">(3)</textPath> <textPath xlink:href="#Path_095" stroke="green" stroke-width="3" startOffset="55%">|</textPath> <textPath xlink:href="#Path_120" startOffset="55%">(4)</textPath>
index 0000000000..da1f510a5c
+   id="svg4157"
+   inkscape:version="0.92.5 (2060ec1f9f, 2020-04-08)">
+     id="metadata4161">
+     id="namedview4159"
+     inkscape:zoom="0.44470588"
+     inkscape:window-x="66"
+     inkscape:current-layer="svg4157" />
+     id="title4012">Freeze</title>
+     id="style4014">
+                 font-size:14px;
+     id="defs4021">
+     id="rect4023" />
+     id="text4027"><tspan
+   id="tspan4025">
+     id="g4121">
+       id="circle4029" />
+       id="text4053">
+         id="textPath4031">|</textPath>
+         id="textPath4033">(0)</textPath>
+         id="textPath4035">
+        - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - &gt;</textPath>
+         id="textPath4037">(1)</textPath>
+         id="textPath4039">(5)</textPath>
+         id="textPath4041">|</textPath>
+         id="textPath4043">(2)</textPath>
+         id="textPath4045">|</textPath>
+         id="textPath4047">(3)</textPath>
+         id="textPath4049">|</textPath>
+         id="textPath4051">(4)</textPath>
+       id="path4055" />
+       id="text4057">PAST</text>
+       id="text4059">FUTURE</text>
+       id="g4063">
+         id="use4061" />
+       id="g4067">
+         id="use4065" />
+       id="g4071">
+         id="use4069" />
+       id="g4075">
+         id="use4073" />
+       id="g4079">
+         id="use4077" />
+       id="g4083">
+         id="use4081" />
+       id="g4087">
+         id="use4085" />
+       id="g4091">
+         id="use4089" />
+       id="g4095">
+         id="use4093" />
+       id="g4099">
+         id="use4097" />
+       id="g4103">
+         id="use4101" />
+       id="g4107">
+         id="use4105" />
+       id="g4111">
+         id="use4109" />
+       id="g4115">
+         id="use4113" />
+       id="g4119">
+         id="use4117" />
+     id="g4155">
+       id="text4127">0: 0 .. 2  <tspan
+   id="tspan4123">^</tspan>
+   id="tspan4125">32</tspan>
+       id="text4129">1: txid_current + 2 ^ 31 (split-point)</text>
+       id="text4131">2: autovacuum_freeze_max_age (200 mio.)</text>
+       id="text4133">3: vacuum_freeze_table_age (150 mio.)</text>
+       id="text4135">4: vacuum_freeze_min_age (50 mio.)</text>
+       id="text4137">5: txid_current (split-point, jungest xid)</text>
+       id="text4141">per table: pg_class.relfrozenxid
+   id="tspan4139">must</tspan>
+       id="text4143">normally it is between (3) and (4)</text>
+       id="use4145" />
+       id="text4147">Unfrozen xid</text>
+       id="use4149" />
+       id="text4151">Frozen xid</text>
+       id="text4153">(figure is out of scale)</text>
index 0000000000..7e556add2f
+                 font-size:14px;
+        - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ></textPath>
index 0000000000..b5cdec9553
+    .text_normal{font-style:normal;font-weight:400;font-size:14px;font-family:&quot;Open Sans&quot;,sans-serif;fill:#000}
index 0000000000..1571df24fe
+   id="svg4243"
+   inkscape:version="0.92.5 (2060ec1f9f, 2020-04-08)">
+     id="metadata4249">
+     id="defs4247" />
+     id="namedview4245"
+     inkscape:zoom="0.525"
+     inkscape:window-x="66"
+     inkscape:current-layer="svg4243" />
+     id="title4163">Hierarchy of Internal Objects</title>
+     id="style4165">
+                 font-size:14px;
+     id="rect4167" />
+     id="text4169">Hierarchy of internal Objects</text>
+     id="g4241">
+       id="g4207">
+         id="ellipse4171" />
+         id="text4173">Cluster</text>
+         id="g4179">
+           id="ellipse4175" />
+           id="text4177">Database Names</text>
+         id="g4185">
+           id="ellipse4181" />
+           id="text4183">Tablespace</text>
+         id="g4191">
+           id="ellipse4187" />
+           id="text4189">Replication Origins</text>
+         id="g4199">
+           id="ellipse4193" />
+           id="text4195">Subscription for</text>
+           id="text4197">Logical Replication</text>
+         id="g4205">
+           id="ellipse4201" />
+           id="text4203">Role</text>
+       id="g4239">
+         id="ellipse4209" />
+         id="text4211">Database</text>
+         id="g4237">
+           id="g4217">
+             id="ellipse4213" />
+             id="text4215">Extension</text>
+           id="g4223">
+             id="ellipse4219" />
+             id="text4221">Collation</text>
+           id="g4235">
+             id="ellipse4225" />
+             id="text4227">Schema</text>
+             id="g4233">
+               id="ellipse4229" />
+               id="text4231">Table, View, ...</text>
index 0000000000..a58f334fe3
+                 font-size:14px;
index 0000000000..6ff6a4da79
+      <text font-weight="400" font-size="14" font-family="&quot;Open Sans&quot;,sans-serif" fill="#000">
index 0000000000..80ae8d29e0
+   id="svg4396"
+   inkscape:version="0.92.5 (2060ec1f9f, 2020-04-08)">
+     id="metadata4400">
+     inkscape:window-width="1266"
+     id="namedview4398"
+     inkscape:zoom="0.44470588"
+     inkscape:cy="68.253968"
+     inkscape:window-x="66"
+     inkscape:current-layer="svg4396" />
+     id="title4251">MVCC</title>
+     id="style4253">
+                 font-size:14px;
+     id="defs4264">
+         id="path4255" />
+         id="path4258" />
+         id="path4260" />
+     id="rect4266" />
+     id="g4394">
+       id="g4284">
+         id="text4272">T
+   id="tspan4268">123</tspan>
+   id="tspan4270">: INSERT</tspan>
+         id="use4274" />
+         id="use4276" />
+         id="text4278">123</text>
+         id="text4280">0</text>
+         id="text4282">'x'</text>
+       id="g4310">
+         id="text4290">T
+   id="tspan4286">135</tspan>
+   id="tspan4288">: UPDATE</tspan>
+         id="use4292" />
+         id="use4294" />
+         id="text4296">135</text>
+         id="text4298">0</text>
+         id="text4300">'y'</text>
+         id="use4302" />
+         id="text4304">123</text>
+         id="text4306">135</text>
+         id="text4308">'x'</text>
+       id="g4344">
+         id="text4316">T
+   id="tspan4312">142</tspan>
+   id="tspan4314">: UPDATE</tspan>
+         id="use4318" />
+         id="use4320" />
+         id="text4322">142</text>
+         id="text4324">0</text>
+         id="text4326">'z'</text>
+         id="use4328" />
+         id="text4330">135</text>
+         id="text4332">142</text>
+         id="text4334">'y'</text>
+         id="use4336" />
+         id="text4338">123</text>
+         id="text4340">135</text>
+         id="text4342">'x'</text>
+       id="g4378">
+         id="text4350">T
+   id="tspan4346">821</tspan>
+   id="tspan4348">: DELTE</tspan>
+         id="use4352" />
+         id="use4354" />
+         id="text4356">142</text>
+         id="text4358">821</text>
+         id="text4360">'z'</text>
+         id="use4362" />
+         id="text4364">135</text>
+         id="text4366">142</text>
+         id="text4368">'y'</text>
+         id="use4370" />
+         id="text4372">123</text>
+         id="text4374">135</text>
+         id="text4376">'x'</text>
+       id="g4392">
+         id="path4380" />
+         id="text4382">Legend</text>
+         id="use4384" />
+         id="text4386">xmin</text>
+         id="text4388">xmax</text>
+         id="text4390">data</text>
index 0000000000..ee27e3df7b
+                 font-size:14px;
index 0000000000..aa0445352d
+    .text_big{font-style:normal}.text_big,.text_comment,.text_normal,.text_small{font-weight:400;font-family:&quot;Open Sans&quot;,sans-serif;fill:#000}.text_normal,.text_small{font-style:normal}.text_small{font-size:12px}.text_normal{font-size:14px}.text_big{font-size:24px}.text_comment{font-style:italic;font-size:14px}
index 0000000000..9ef89639c4
+   id="svg4706"
+   inkscape:version="0.92.5 (2060ec1f9f, 2020-04-08)">
+     id="metadata4710">
+     inkscape:window-width="1282"
+     inkscape:window-height="733"
+     id="namedview4708"
+     inkscape:cy="292.37288"
+     inkscape:window-x="66"
+     inkscape:current-layer="svg4706" />
+     id="title4402">PG Overall Server Architecture</title>
+     id="style4404">
+                 font-size:14px;
+                 font-size:14px;
+     id="defs4470">
+         id="title4406">UML Note (200 x 20 px)</title>
+         id="path4408" />
+         id="title4411">UML Note (250 x 20 px)</title>
+         id="path4413" />
+         id="title4416">UML Note (100 x 35 px)</title>
+         id="path4418" />
+         id="title4421">UML Note (170 x 50 px)</title>
+         id="path4423" />
+         id="title4426">UML State (300x120)</title>
+         id="rect4428" />
+         id="title4431">UML State (350x120)</title>
+         id="rect4433" />
+         id="title4436">Disc</title>
+         id="ellipse4438" />
+         id="path4440" />
+         id="path4442" />
+         id="path4444" />
+         id="title4447">Laptop</title>
+         id="path4449" />
+         id="rect4451" />
+         id="path4453" />
+         id="path4455" />
+         id="path4457" />
+         id="path4459" />
+         id="path4461" />
+         id="path4464" />
+         id="path4467" />
+     id="rect4472" />
+     id="text4474">Client</text>
+     id="text4476">Server</text>
+     id="use4478" />
+     id="g4496">
+       id="use4480" />
+       id="text4482">maintenance_work_mem (per connection)</text>
+       id="text4484">work_mem (per query operation)</text>
+       id="text4486">autovacuum_work_mem (per worker process)</text>
+       id="text4488">temp_buffer (per connection)</text>
+       id="text4490">...</text>
+       id="use4492" />
+       id="text4494">Individual Memory</text>
+     id="g4510">
+       id="use4498" />
+       id="text4500">shared_buffers (heap and index)</text>
+       id="text4502">wal_buffers (WAL records)</text>
+       id="text4504">...</text>
+       id="use4506" />
+       id="text4508">Shared Memory (per Instance)</text>
+     id="g4516">
+       id="rect4512" />
+       id="text4514">Postmaster</text>
+     id="path4518" />
+     id="g4524">
+       id="circle4520" />
+       id="text4522">1</text>
+     id="g4534">
+       id="rect4526" />
+       id="text4528">Backend processes (one per connection)</text>
+       id="path4530" />
+       id="path4532" />
+     id="path4536" />
+     id="g4542">
+       id="circle4538" />
+       id="text4540">3</text>
+     id="path4544" />
+     id="g4550">
+       id="use4546" />
+       id="text4548">Creates backend processes</text>
+     id="g4556">
+       id="circle4552" />
+       id="text4554">2</text>
+     id="path4558" />
+     id="path4560" />
+     id="path4562" />
+     id="g4568">
+       id="rect4564" />
+       id="text4566">WAL Writer</text>
+     id="path4570" />
+     id="path4572" />
+     id="g4578">
+       id="rect4574" />
+       id="text4576">Checkpointer</text>
+     id="path4580" />
+     id="path4582" />
+     id="path4584" />
+     id="g4592">
+       id="use4586" />
+       id="text4588">Checkpoint</text>
+       id="text4590">Record</text>
+     id="g4598">
+       id="rect4594" />
+       id="text4596">Background Writer</text>
+     id="path4600" />
+     id="path4602" />
+     id="g4608">
+       id="rect4604" />
+       id="text4606">WAL Archiver</text>
+     id="path4610" />
+     id="path4612" />
+     id="g4622">
+       id="rect4614" />
+       id="text4616">Autovacuum</text>
+       id="path4618" />
+       id="path4620" />
+     id="g4628">
+       id="rect4624" />
+       id="text4626">Logger</text>
+     id="g4634">
+       id="rect4630" />
+       id="text4632">Stats Collector</text>
+     id="g4644">
+       id="use4636" />
+       id="text4638">Log</text>
+       id="text4640">text lines,</text>
+       id="text4642">sequential</text>
+     id="path4646" />
+     id="g4658">
+       id="use4648" />
+       id="text4650">Heap and</text>
+       id="text4652">Index</text>
+       id="text4654">binary blocks,</text>
+       id="text4656">random</text>
+     id="path4660" />
+     id="g4670">
+       id="use4662" />
+       id="text4664">Read heap and index</text>
+       id="text4666">pages and transfer</text>
+       id="text4668">them to shared_buffers</text>
+     id="g4680">
+       id="use4672" />
+       id="text4674">WAL</text>
+       id="text4676">binary records,</text>
+       id="text4678">sequential</text>
+     id="g4688">
+       id="use4682" />
+       id="text4684">Archived</text>
+       id="text4686">WAL</text>
+     id="path4690" />
+     id="g4696">
+       id="use4692" />
+       id="text4694">Via TCP/IP or socket</text>
+     id="g4704">
+       id="text4698">RAM</text>
+       id="text4700">PROCESSES</text>
+       id="text4702">FILES</text>
index 0000000000..775ba91571
+                 font-size:14px;
+                 font-size:14px;
index 0000000000..440394d577
+    .text_normal{font-style:normal;font-weight:400;font-size:14px;font-family:&quot;Open Sans&quot;,sans-serif;fill:#000}
index 0000000000..8240ec7d59
+   id="svg4775"
+   inkscape:version="0.92.5 (2060ec1f9f, 2020-04-08)">
+     id="metadata4779">
+     inkscape:window-width="1348"
+     inkscape:window-height="810"
+     id="namedview4777"
+     inkscape:zoom="0.44470588"
+     inkscape:cy="133.25397"
+     inkscape:window-x="66"
+     inkscape:current-layer="svg4775" />
+     id="title4712">Cyclic usage of XIDs</title>
+     id="style4714">
+                 font-size:14px;
+     id="defs4719">
+     id="rect4721" />
+     id="text4727">Cyclic usage of XIDs modulo 2
+   id="tspan4723">^</tspan>
+   id="tspan4725">32</tspan>
+     id="g4755">
+       id="circle4729" />
+       id="text4753">
+         id="textPath4731">|</textPath>
+         id="textPath4733">(0)</textPath>
+         id="textPath4735">
+         id="textPath4737">|</textPath>
+         id="textPath4739">(1)</textPath>
+         id="textPath4741">|</textPath>
+         id="textPath4743">(2)</textPath>
+         id="textPath4745">|</textPath>
+         id="textPath4747">(3)</textPath>
+         id="textPath4749">|</textPath>
+         id="textPath4751">(4)</textPath>
+     id="g4773">
+       id="text4761">0: 0 .. 2  <tspan
+   id="tspan4757">^</tspan>
+   id="tspan4759">32</tspan>
+       id="text4765">1: oldest <tspan
+   id="tspan4763">active</tspan>
+       id="text4767">2: xmin of one row version</text>
+       id="text4769">3: xmax of the same row version</text>
+       id="text4771">4: jungest xid (txid_current)</text>
index 0000000000..c6e86fd488
+                 font-size:14px;
 
+  &architecture;
   &arch-dev;
   &catalogs;
   &protocol;

    <para>
 
-    <itemizedlist>
-     <listitem>
-      <para>
 
-     <listitem>
-      <para>
 
-    </itemizedlist>
-   </para>
+    <listitem>
+     <para>
 
    <para>
 
-   <para>

---

From: Erik Rijkers <[email-masked]>
Date: Sat, 07 Nov 2020 20:15:07 +0100

On 2020-11-07 13:24, Jürgen Purtz wrote:
> [0011-architecture.patch]

Hi,

I went through architecture.sgml once more; some proposed changes 
attached.

And in some .svg files I noticed 'jungest' which should be 'youngest', I 
suppose.
I did not change them but below is filelist of  grep -l 'jung'.

./doc/src/sgml/images/freeze-ink.svg
./doc/src/sgml/images/freeze-ink-svgo.svg
./doc/src/sgml/images/freeze-raw.svg
./doc/src/sgml/images/wraparound-ink.svg
./doc/src/sgml/images/wraparound-ink-svgo.svg
./doc/src/sgml/images/wraparound-raw.svg

Thanks,

Erik

--- doc/src/sgml/architecture.sgml.orig	2020-11-07 14:05:50.188396026 +0100
+++ doc/src/sgml/architecture.sgml	2020-11-07 20:04:27.890983873 +0100
@@ -24,7 +24,7 @@
     This leads to other activities (file access, WAL, vacuum, ...) of the
     <glossterm linkend="glossary-instance">Instance</glossterm>. The
     Instance is a group of server-side processes acting on a common
-    Shared Memory. PostgreSQL does not utilize threading.
+    Shared Memory. PostgreSQL does not use threading.
    </para>
 
    <para>
@@ -78,7 +78,7 @@
     cache, located in Shared Memory (for details see:
     <xref linkend="sysvipc"/>) for the benefit of all processes
     in the instance. Writes also use this cache, in addition
-    to a journal, called a write-ahead-log or WAL.
+    to a journal, called the write-ahead-log or WAL.
    </para>
 
    <para>
@@ -90,20 +90,20 @@
     must be written to disk. This happens regularly by the
     Checkpointer and the Background Writer processes to ensure
     that the disk version of the pages are up-to-date.
-    The synchronisation from RAM to disk consists of two steps.
+    The synchronization from RAM to disk consists of two steps.
    </para>
 
    <para>
     First, whenever the content of a page changes, a
     <glossterm linkend="glossary-wal-record">WAL record</glossterm>
-    is created out of the delta-information (difference between the
+    is created from the delta-information (difference between the
     old and the new content) and stored in another area of
     Shared Memory. The parallel running WAL Writer process
     reads them and appends them to the end of the current
     <glossterm linkend="glossary-wal-record">WAL file</glossterm>.
     Such sequential writes are faster than writes to random
     positions of heap and index files. All WAL records created
-    out of one dirty page must be transferred to disk before the
+    from one dirty page must be transferred to disk before the
     dirty page itself can be transferred to disk in the second step.
    </para>
 
@@ -123,22 +123,22 @@
     <glossterm linkend="glossary-checkpoint">Checkpoints</glossterm>.
     A Checkpoint is a point in time when all older dirty buffers,
     all older WAL records, and finally a special Checkpoint record
-    are written and flushed to disk. Heap and index files
-    on the one hand and WAL files on the other hand are in sync.
-    Previous WAL is no longer required. In other words,
+    are written and flushed to disk. Heap and index files,
+    and WAL files are now in sync.
+    Older WAL is no longer required. In other words,
     a possibly occurring recovery, which integrates the delta
     information of WAL into heap and index files, will happen
-    by replaying only WAL past the last recorded checkpoint.
-    This limits the amount of WAL which needs to be replayed
+    by replaying only WAL past the last-recorded checkpoint.
+    This limits the amount of WAL to be replayed
     during recovery in the event of a crash.
    </para>
 
    <para>
-    While the Checkpointer ensures that the database system can crash
-    and restart itself in a valid state, the administrator needs
+    While the Checkpointer ensures that the database system can,
+    after a crash, restart itself in a valid state, the administrator needs
     to handle the case where the heap or other files become
     corrupted (and possibly the locally written WAL, though that is
-    less common). The options and details are covered extensively
+    less common). Options and details are covered
     in the backup and restore section (<xref linkend="backup"/>).
     For our purposes here, just note that the WAL Archiver process
     can be enabled and configured to run a script on filled WAL
@@ -153,7 +153,7 @@
 
    <para>
     The Logger writes text lines about serious and less serious
-    events which can happen during database access, e.g., wrong
+    events that may happen during database access, e.g., wrong
     password, no permission, long-running queries, etc.
    </para>
 
@@ -262,7 +262,7 @@
     all <firstterm>tablespace names</firstterm>, and all
     <firstterm>role names</firstterm> are automatically
     available throughout the cluster, independent from
-    the database or schema in which they where defined originally.
+    the database or schema in which they were defined originally.
     <xref linkend="tutorial-internal-objects-hierarchy-figure"/>
     shows the relation between the object types.
    </para>
@@ -410,13 +410,11 @@
    </para>
 
    <para>
-    A first approach to implement protections against concurrent
-    access to the same data may be the locking of critical rows.
-    <productname>PostgreSQL</productname> implements a more
-    sophisticated technique which avoids any locking:
+    <productname>PostgreSQL</productname> implements a
+    sophisticated technique which avoids locking:
     <firstterm>Multiversion Concurrency Control</firstterm> (MVCC).
-    The crucial advantage of MVCC
-    over other technologies becomes evident in multiuser OLTP
+    The advantage of MVCC
+    over technologies that use row locks becomes evident in multiuser OLTP
     environments with a massive number of concurrent write
     actions. There, MVCC generally performs better than solutions
     using locks. In a <productname>PostgreSQL</productname>
@@ -455,7 +453,7 @@
    <para>
     The description in this chapter simplifies by omitting details.
     When many transactions are running simultaneously, things can
-    get complicated. Sometimes transactions get aborted via
+    get complicated. Sometimes transactions are aborted via
     <command>ROLLBACK</command> immediately or after a lot of other activities, sometimes
     a single row is involved in more than one transaction, sometimes
     a client crashes, sometimes the sequence of xids restarts
@@ -551,14 +549,14 @@
    </para>
 
    <para>
-    Please keep in mind:
+    Keep in mind:
    </para>
    <itemizedlist>
 
     <listitem>
      <simpara>
       <literal>xmin</literal> and <literal>xmax</literal>
-      indicate the range from where to where
+      indicate the range in which
       <firstterm>row versions</firstterm> are valid (visible) for transactions.
       This range doesn't imply any direct temporal meaning;
       the sequence of xids reflects only the sequence of
@@ -581,7 +579,7 @@
 
     <listitem>
      <simpara>
-      Nothing gets wiped away &mdash; with the consequence that the database
+      Nothing is removed &mdash; with the consequence that the database
       occupies more and more disk space. It is obvious that
       this behavior has to be corrected in some
       way. The next chapter explains how <firstterm>autovacuum</firstterm>
@@ -609,7 +607,7 @@
    <note>
     <para>
      Autovacuum runs automatically by
-     default. Its default parameters as well as such for
+     default. Its default parameters as well as those for
      <command>VACUUM</command> are appropriate for most standard
      situations. Therefore a novice database manager can
      skip the rest of this chapter which explains
@@ -629,7 +627,7 @@
     and starts Autovacuum processes whenever it detects
     certain situations. Thus, it's a dynamic behavior of
     <productname>PostgreSQL</productname> with the intention to tidy
-    up &mdash; whenever it is appropriate.
+    up whenever it is appropriate.
    </para>
 
    <para>
@@ -672,7 +670,7 @@
    </itemizedlist>
 
    <para>
-    The eagerness &mdash; you can call it 'aggressiveness' &mdash; of the
+    The eagerness &mdash; or 'aggressiveness' &mdash; of the
     operations for <emphasis>eliminating bloat</emphasis> and
     <emphasis>freeze</emphasis> is controlled by configuration
     parameters, runtime flags, and in extreme situations by
@@ -689,7 +687,7 @@
    <para>
     To determine which of the row versions are no longer needed, the
     elimination operation must evaluate <literal>xmax</literal>
-    against several criteria which all must apply:
+    against several criteria which must all apply:
    </para>
    <itemizedlist>
 
@@ -830,13 +828,13 @@
    <para>
     The use of a limited range of IDs for transactions leads
     to the necessity to restart the sequence sooner or later.
-    This does not only have the rare consequence previously
-    described that sometimes <literal>xmin</literal> is
-    higher than <literal>xmax</literal>. The far
+    This not only has the rare consequence, previously
+    described, that sometimes <literal>xmin</literal> is
+    higher than <literal>xmax</literal>. A far
     more critical problem is that whenever the system has
     to evaluate a WHERE condition, it must decide which row
     version is valid (visible) from the perspective of the
-    transaction of this query. If a wraparound couldn't happen,
+    transaction of the query. If a wraparound couldn't happen,
     this decision would be relatively easy: the xid
     must be between <literal>xmin</literal> and <literal>xmax</literal>,
     and the corresponding transactions of <literal>xmin</literal>
@@ -884,7 +882,7 @@
       a flag in the header of the row version which avoids
       future comparison of its <literal>xmin/xmax</literal> and indicates
       that the version is valid not only in the 'past'-half
-      but also in the 'future'-half as well as in all coming
+      but also in the 'future'-half, as well as in all coming
       <glossterm linkend="glossary-xid">epochs</glossterm>.
      </simpara>
     </listitem>
@@ -1162,21 +1160,21 @@
     new row versions, and after a while and some more
     activities of the modifying transaction they may see the
     next row versions. Results would be a kind of 'moving
-    target' in absolute contrast to the all-or-nothing
+    target' which would be contrary to the all-or-nothing
     principle.
    </para>
 
    <para>
     <productname>PostgreSQL</productname> overcomes this
     problem by showing only such row versions to other
-    transactions whose originating transaction is
+    transactions whose originating transaction has
     successfully committed. It skips all row versions of
     uncommitted transactions. And
     <productname>PostgreSQL</productname> solves one more
     problem. Even the single <command>COMMIT</command>
     command needs a short time interval for its execution.
     Therefore its critical 'dead-or-survival' phase
-    runs in a priviledged mode where it cannot be
+    runs in a privileged mode that cannot be
     interrupted by other processes.
    </para>
 
@@ -1184,7 +1182,7 @@
 
    <para>
     Transactions relieve applications from many standard
-    actions that must be implemented for nearly every use case.
+    actions that would otherwise need to be implemented for nearly every use case.
    </para>
 
    <para>
@@ -1192,7 +1190,7 @@
     relative abstract requirements. The above example shows
     the transfers of some money from one account to another.
     It is obvious
-    that the decrease of the one and the increase of the
+    that the decrease of the one account and the increase of the
     other must be indivisible. Nevertheless, there is no particular
     need for an application to do something to ensure the
     <glossterm linkend="glossary-atomicity">atomicity</glossterm>
@@ -1266,7 +1264,7 @@
     client/server architecture, no direct problem for the
     database will occur. In all of these cases, the
     <glossterm linkend="glossary-backend">Backend process</glossterm>,
-    which is the client's counterpart at the server-side,
+    which is the client's counterpart at the server side,
     may recognize that the network connection is no longer
     working, or it may run into a timeout after a while. It
     terminates, and there is no harm to the database. As
@@ -1294,9 +1292,9 @@
     the WAL files contain them as a chronology of
     <glossterm linkend="glossary-wal-record">WAL records</glossterm>,
     which include the new data values and information about commit
-    actions. The WAL records are written first. Second,
-    the data itself shall exist in the heap and index files.
-    In constrast with the WAL records, this part may or may
+    actions. The WAL records are written first. Only then is
+    the data itself written to the heap and index files.
+    In contrast to the WAL records, this part may or may
     not have been transferred entirely from Shared Memory
     to the files.
    </para>
@@ -1308,14 +1306,14 @@
     This checkpoint signals that the database files are in
     a consistent state, especially that all WAL records up to
     this point were successfully stored in heap and index files. Starting
-    here, the recovery process copies the remaining WAL records
-    to heap and index. As a result, the heap files contain all
+    here, the recovery process copies any remaining WAL records
+    to heap and index. The result is that the heap files contain all
     changes recorded to the WAL and reach a consistent state. Changes of committed
     transactions are visible; those of uncommitted transactions
     are also in the files, but - as usual - they are never seen
     by any of the following transactions because uncommitted
-    changes are never shown. Such recovery actions run
-    completely automatically, it is not necessary that a
+    changes are never shown. These recovery actions run
+    automatically; it is not necessary that a
     database administrator configure or start anything by
     himself.
    </para>
@@ -1330,7 +1328,7 @@
    </para>
 
    <para>
-    They obviously needs a backup. How to take such a backup
+    They obviously need a backup. How to take such a backup
     and use it as a starting point for a recovery of the
     cluster is explained in more detail in the next
     <link linkend="tutorial-backup">chapter</link>.
@@ -1421,7 +1419,7 @@
     of the complete cluster or certain parts of it. It stores
     the copy in the form of SQL commands like <command>CREATE</command>
     and <command>COPY</command>. It runs in
-    parallel with other processes in its own transaction.
+    parallel with other processes, in its own transaction.
    </para>
 
    <para>
@@ -1484,7 +1482,7 @@
     copy the basebackup and the archived WAL files to
     their original directories. The configuration of this
     <link linkend="backup-pitr-recovery">recovery procedure</link>
-    contains a string with the reverse copy command: from
+    contains a string with the reversed copy command: from
     archive location to database location.
    </para>

---

From: Jürgen Purtz <[email-masked]>
Date: Sun, 8 Nov 2020 16:55:56 +0100

On 07.11.20 20:15, Erik Rijkers wrote:
> And in some .svg files I noticed 'jungest' which should be 'youngest', 
> I suppose.
Good catches. Everything applied.

--

J. Purtz

 
 
  <chapter id="overview">
 
   <note>
    <title>Author</title>
index 0000000000..b7589f9a4f
@@ -0,0 +1,1502 @@
 
index 0000000000..b1543ffae5
+      5: txid_current (split-point, youngest xid)
index 0000000000..316703d069
+     inkscape:window-width="1295"
+     inkscape:window-height="803"
+     inkscape:cy="153.18182"
+     inkscape:window-x="0"
+     id="title2">Freeze</title>
+     id="defs11">
+     id="rect13" />
+     id="text17"><tspan
+   id="tspan15">
+     id="g111">
+       id="circle19" />
+       id="text43">
+         id="textPath21">|</textPath>
+         id="textPath23">(0)</textPath>
+         id="textPath25">
+         id="textPath27">(1)</textPath>
+         id="textPath29">(5)</textPath>
+         id="textPath31">|</textPath>
+         id="textPath33">(2)</textPath>
+         id="textPath35">|</textPath>
+         id="textPath37">(3)</textPath>
+         id="textPath39">|</textPath>
+         id="textPath41">(4)</textPath>
+       id="path45" />
+       id="text47">PAST</text>
+       id="text49">FUTURE</text>
+       id="g53">
+         id="use51" />
+       id="g57">
+         id="use55" />
+         id="use59" />
+         id="use63" />
+       id="g69">
+       id="g73">
+         id="use75" />
+       id="g81">
+       id="g85">
+         id="use83" />
+       id="g93">
+         id="use91" />
+       id="g97">
+         id="use95" />
+       id="g101">
+         id="use99" />
+       id="g105">
+       id="g109">
+         id="use107" />
+       id="text117">0: 0 .. 2  <tspan
+   id="tspan113">^</tspan>
+   id="tspan115">32</tspan>
+       id="text119">1: txid_current + 2 ^ 31 (split-point)</text>
+       id="text121">2: autovacuum_freeze_max_age (200 mio.)</text>
+       id="text123">3: vacuum_freeze_table_age (150 mio.)</text>
+       id="text125">4: vacuum_freeze_min_age (50 mio.)</text>
+       id="text127">5: txid_current (split-point, youngest xid)</text>
+       id="text131">per table: pg_class.relfrozenxid
+   id="tspan129">must</tspan>
+       id="text133">normally it is between (3) and (4)</text>
+       id="text137">Unfrozen xid</text>
+       id="use139" />
+       id="text141">Frozen xid</text>
+       id="text143">(figure is out of scale)</text>
index 0000000000..9482167c3f
+    <text y="125">5: txid_current (split-point, youngest xid)</text>
index 0000000000..d5af6ce0b8
+      4: youngest xid (txid_current)
index 0000000000..51d35a9f85
+   id="svg216"
+     id="metadata220">
+     inkscape:window-width="1247"
+     inkscape:window-height="650"
+     id="namedview218"
+     inkscape:window-x="0"
+     inkscape:current-layer="svg216" />
+     id="title153">Cyclic usage of XIDs</title>
+     id="defs160">
+     id="rect162" />
+     id="text168">Cyclic usage of XIDs modulo 2
+   id="tspan164">^</tspan>
+   id="tspan166">32</tspan>
+     id="g196">
+       id="circle170" />
+       id="text194">
+         id="textPath172">|</textPath>
+         id="textPath174">(0)</textPath>
+         id="textPath176">
+         id="textPath178">|</textPath>
+         id="textPath180">(1)</textPath>
+         id="textPath182">|</textPath>
+         id="textPath184">(2)</textPath>
+         id="textPath186">|</textPath>
+         id="textPath188">(3)</textPath>
+         id="textPath190">|</textPath>
+         id="textPath192">(4)</textPath>
+     id="g214">
+       id="text202">0: 0 .. 2  <tspan
+   id="tspan198">^</tspan>
+   id="tspan200">32</tspan>
+       id="text206">1: oldest <tspan
+   id="tspan204">active</tspan>
+       id="text208">2: xmin of one row version</text>
+       id="text210">3: xmax of the same row version</text>
+       id="text212">4: youngest xid (txid_current)</text>
index 0000000000..637e68bb82
+    <text y="100">4: youngest xid (txid_current)</text>
 
+  &architecture;
   &arch-dev;
   &catalogs;
   &protocol;

    <para>
 
-    <itemizedlist>
-     <listitem>
-      <para>
 
-     <listitem>
-      <para>
 
-    </itemizedlist>
-   </para>
+    <listitem>
+     <para>
 
    <para>
 
-   <para>

---

From: "David G. Johnston" <[email-masked]>
Date: Mon, 9 Nov 2020 16:14:57 -0700

> Good catches. Everything applied.

Reviewed the first three sections.

template0 - I would remove the schema portions of this and simply note this
as being a pristine recovery database in the diagram.

I would drop the word "more" and just say "system schemas".  I would drop
pg_toast from the list of system schema and focus on the three user-facing
ones.

Instead of "my_schema" (optional) I would do "my_schema" (example)

Server Graphic
#3 Global SQL Objects: Objects which are shared among all databases within
a cluster.
#6 Client applications are prohibited from connecting to template0
#1 If by you we mean "the client" saying that you work "in the cluster
data" doesn't really help.  I would emphasize the point that the client
sees an endpoint the Postmaster publishes as a port or socket file and that
plus the database name defines the endpoint the client connects to (meld
with #5)

In lieu of some of the existing detail provided about structure I would add
information about configuration and search_path at this level.

I like the object type enumeration - I would suggest grouping them by type
in a manner consistent with the documentation and making each one a link to
its "primary" section - the SQL Command reference if all else fails.

The "i" in internal in 51.3 (the image) needs capitalization).

You correctly add both Extension and Collation as database-level objects
but they are not mentioned anywhere else.  They do belong here and need to
be tied in properly in the text.

The whole thing needs a good pass focused on capitalization.  Both for
typos and to decide when various primary concepts like Instance should be
capitalized and when not.

51.4 - When you look at the diagram seeing /pg/data/base looks really cool,
but when reading the prose where both the "pg" and the "base" are omitted
and all you get are repeated references to "data", the directory name
choice becomes an issue IMO.  I suggest (and changed the attached) to name
the actual root directory "pgdata".  You should change the /pg/ directory
name to something like ".../tutorial_project/".

Since you aren't following alphabetical order anyway I would place
pg_tblspc after globals since tablespaces are globals and thus proximity
links them here - and pointing out that pg_tblspc holds the data makes
stating that global doesn't contain tablespace data unnecessary.

Maybe point out somewhere the the "base/databaseOID" directory represents
the default tablespace for each database, which isn't "global", only the
non-default tablespaces are considered globals (or just get rid of the
mentioned on "non-default tablespace" for now).

David J.

---

From: "David G. Johnston" <[email-masked]>
Date: Tue, 10 Nov 2020 14:58:26 -0700

> Good catches. Everything applied.

MVCC Section

The first paragraph and example in the MVCC section is a good example but
seems misplaced - its relationship to MVCC generally is tenuous, rather I
would expect a discussion of the serializable isolation mode to follow.

I'm not sure how much detail this section wants to get into given the
coverage of concurrency elsewhere in the documentation.  "Not much" would
be my baseline.

I would suggest spelling out what "OLTP" stands for and ideally pointing
the user to the glossary for the term.

Tending more toward a style gripe but the amount of leader phrases and
redundancy are at a level that I am noticing them when I read this but do
not have the same impression having read large portions of documentation.
In particular:

"When we speak about transaction IDs, you need to know that xids are like
sequences."

"But keep in mind that xids are independent of any time measurement — in
milliseconds or otherwise. If you dive deeper into PostgreSQL, you will
recognize parameters with names such as 'xxx_age'. Despite their names,
these '_age' parameters do not specify a period of time but represent a
certain number of transactions, e.g., 100 million."

Could just be:  xids are sequences and age computations involving them
measure a transaction count as opposed to a time interval.

Then I would consider adding a bit more detail/context here.

xids are 32bit sequences, with a reserved value to handle wrap-around.
There are 4 billion values in the sequence but wrap-around handling must
occur every 2 billion transactions. Age computations involving xids measure
a transaction count as opposed to a time interval.

I would move the mentioning of "vacuum" to the main paragraph about delete
and not solely as a "keep in mind" note.

The part before the diagram seems like it should be much shorter, concise,
and provide links to the excellent documentation.  The part after the
image, and the image itself, are good material, though possibly should be
in a main administration chapter instead of an internals chapter.

The first bullet of "keep in mind" is both wordy and wrong - in particular
"as xids grow old row versions get out of scope over time" doesn't make
sense (or rather it only does in the context of wrap-around, not normal
visibility).  Having the only mention of bloat be here is also not ideal,
it too should be weaved into the main narrative.  The "keep in mind"
section here should be a recap of already covered material in a succinct
form, nothing should be new to someone who just read the entire section.

I don't think that usage of exclamation marks (!) is warranted here, though
emphasis on the key phrase wouldn't hurt.

Vacuum Section

avoid -> prevent (continued growth)

Autovacuum is enabled by default.  The whole note needs commas.

I'd try to get rid of "at arbitrary point in time"

"Instance." we've already described where instances are previously ("on the
server")

The other sections - these seem misplaced for the tutorial, update the main
documentation if this information is wholly missing or lacking.  The MVCC
chapter can incorporate overview information as it is a strict consequence
of that implementation.

Statistics belong elsewhere - the tutorial should not use poor command
implementation choices as a guide for user education.

In short, this whole section should not exist and its content moved to more
appropriate areas (mainly MVCC).  Vacuum is a tool that one must use but
the narrative should be about the system generally.

David J.

---

From: Jürgen Purtz <[email-masked]>
Date: Sun, 15 Nov 2020 19:45:35 +0100

On 10.11.20 00:14, David G. Johnston wrote:
> template0 - I would remove the schema portions of this and simply note 
> this as being a pristine recovery database in the diagram.
ok
>
> I would drop the word "more" and just say "system schemas".  I would 
> drop pg_toast from the list of system schema and focus on the three 
> user-facing ones.
ok
> Instead of "my_schema" (optional) I would do "my_schema" (example)
The terms 'optional' and 'default' are used at various places with their 
literal meaning. We shall not change them.
>
> Server Graphic
> #3 Global SQL Objects: Objects which are shared among all databases 
> within a cluster.
ok
> data" doesn't really help.  I would emphasize the point that the 
> client sees an endpoint the Postmaster publishes as a port or socket 
> file and that plus the database name defines the endpoint the client 
> connects to (meld with #5)
ok, with some changes.
>
> In lieu of some of the existing detail provided about structure I 
> would add information about configuration and search_path at this level.
Search path appended. But IMO configuration questions are out of scope 
of this sub-chapter.
>
> I like the object type enumeration - I would suggest grouping them by 
> type in a manner consistent with the documentation and making each one 
> a link to its "primary" section - the SQL Command reference if all 
> else fails.
ok. But don't how to group them in a better way.
> The "i" in internal in 51.3 (the image) needs capitalization).
ok
>
> You correctly add both Extension and Collation as database-level 
> objects but they are not mentioned anywhere else.  They do belong here 
> and need to be tied in properly in the text.
Have some courage to the gap, it's an introductory chapter.
> typos and to decide when various primary concepts like Instance should 
> be capitalized and when not.
'Instance' and 'Cluster' are now uppercase because of their importance, 
everything else lowercase for better reading.
>
> 51.4 - When you look at the diagram seeing /pg/data/base looks really 
> cool, but when reading the prose where both the "pg" and the "base" 
> are omitted and all you get are repeated references to "data", the 
> directory name choice becomes an issue IMO.  I suggest (and changed 
> the attached) to name the actual root directory "pgdata".  You should 
> change the /pg/ directory name to something like ".../tutorial_project/".

The graphic shall reflect the default behavior of PG. Without the 
parameter -D, initdb creates the new cluster in the directory where 
PGDATA points to. This is in many cases |/var/lib/pgsql/data|. Therefore 
'data' and its subdirectory 'base' are not my invention but reflects the 
default situation.

(Diving a little deeper into this issue I noticed that there is a 
parameter 'cluster_name' in the config file. But it does not change the 
name of the cluster's root directory, it only changes the names of the 
running processes. Choosing 'instance_name' instead of 'cluster_name' as 
the parameter's name would be a better choice imo - but that is not what 
we are speaking about in the context of the new chapter).

I changed the very first directory in the graphic to visualize the 
standard behavior; I reverted your recommendation to use 'pgdata' 
instead of 'data' in the text part.

> pg_tblspc after globals since tablespaces are globals and thus 
> proximity links them here - and pointing out that pg_tblspc holds the 
> data makes stating that global doesn't contain tablespace data 
> unnecessary.
ok
>
> Maybe point out somewhere the the "base/databaseOID" directory 
> represents the default tablespace for each database, which isn't 
> "global", only the non-default tablespaces are considered globals (or 
> just get rid of the mentioned on "non-default tablespace" for now).

ok

more:

1) some changes concerning the nature of connections (52.2: logical 
perspective). IMO accessing multiple databases within one connection is 
not a question of configuring, you have to take more actions. But I'm 
not sure we should mention this at all.

2) you propose to cancel or trim down the paragraphs behind figure 51.2. 
(cluster, database, schema). I believe that a textual description of 
this hierarchy is essential for the understanding of the system. Because 
it isn't described explicitly at a different place, it should remain.

--- snipp -------- from other e-mail ----

> MVCC Section
>
> The first paragraph and example in the MVCC section is a good example 
> but seems misplaced - its relationship to MVCC generally is tenuous, 
> rather I would expect a discussion of the serializable isolation mode 
> to follow.
>
> coverage of concurrency elsewhere in the documentation.  "Not much" 
> would be my baseline.
The paragraph focus on the fact that new row versions are generated 
instead of locking something. Explaining serialization isolation modes 
is imo very complicate and out of the scope of this subchapter. If we 
want to give an overview - in addition to the exiting documentation - it 
should be a separate subchapter.
>
> I would suggest spelling out what "OLTP" stands for and ideally 
> pointing the user to the glossary for the term.
ok, but not added to glossary. The given explanation "... with a massive 
number of concurrent write actions" should be sufficient.
> redundancy are at a level that I am noticing them when I read this but 
> do not have the same impression having read large portions of 
> documentation. In particular:
Because I'm not a native English speaker, orthographic and style hits 
are always welcome.
>
> "When we speak about transaction IDs, you need to know that xids are 
> like sequences."
>
> "But keep in mind that xids are independent of any time measurement — 
> in milliseconds or otherwise. If you dive deeper into PostgreSQL, you 
> will recognize parameters with names such as 'xxx_age'. Despite their 
> names, these '_age' parameters do not specify a period of time but 
> represent a certain number of transactions, e.g., 100 million."
>
ok
> xids are 32bit sequences, with a reserved value to handle 
> wrap-around.  There are 4 billion values in the sequence but 
> wrap-around handling must occur every 2 billion transactions. Age 
> computations involving xids measure a transaction count as opposed to 
> a time interval.
>
> I would move the mentioning of "vacuum" to the main paragraph about 
> delete and not solely as a "keep in mind" note.
The mentioning here at the food of the page is a crossover to the next 
subchapter.
>
> The part before the diagram seems like it should be much shorter, 
> concise, and provide links to the excellent documentation.  The part 
> after the image, and the image itself, are good material, though 
> possibly should be in a main administration chapter instead of an 
> internals chapter.

vacuum: The problem - and one reason for the existence of this 
subchapter - is that vacuum's documentation is scattered across may pages:

Because of the structure of our documentation as well as the complexity 
of the issue that's ok. The existing documentation describes every 
parameter very well, but I'm missing a page where the 'big picture' of 
vacuum is explained (not necessarily here). It shall show the 
relationship between the huge number of parameters and an explanation 
*why* they exists. As far as we don't have such a page within the vacuum 
documentation the proposed subchapter fills the gap. (The provided 
graphics can be included multiple times without generating redundancies 
- here and at arbitrary other places.)

>
> The first bullet of "keep in mind" is both wordy and wrong - in 
> particular "as xids grow old row versions get out of scope over time" 
> doesn't make sense (or rather it only does in the context of 
> wrap-around, not normal visibility).  Having the only mention of bloat 
> be here is also not ideal, it too should be weaved into the main 
> narrative.  The "keep in mind" section here should be a recap of 
> already covered material in a succinct form, nothing should be new to 
> someone who just read the entire section.
ok.
>
> I don't think that usage of exclamation marks (!) is warranted here, 
> though emphasis on the key phrase wouldn't hurt.
ok
> avoid -> prevent (continued growth)
ok
> Autovacuum is enabled by default.  The whole note needs commas.
ok
> I'd try to get rid of "at arbitrary point in time"
ok
>
> "Instance." we've already described where instances are previously 
> ("on the server")
ok
>
> The other sections - these seem misplaced for the tutorial, update the 
> main documentation if this information is wholly missing or lacking.  
> The MVCC chapter can incorporate overview information as it is a 
> strict consequence of that implementation.
>
> In short, this whole section should not exist and its content moved to 
> more appropriate areas (mainly MVCC).  Vacuum is a tool that one must 
> use but the narrative should be about the system generally.
>
>
concerning vacuum section: see my comments above

concerning 'the other sections' (transactions, reliability, backup 
(plus: someone should add 'replication', I'm not familiar with this 
issue)): The intention of the chapter is to give a *summary* about PG's 
essential architecture and about central implementation aspects. This 
implies that the chapters does not present any new information. They 
shall only show (or repeat) essential things in their context and 
explain *why* they are used. In this sense the three chapters may be 
reasonable. Concerning this, I like to hear some comments from other people.

Attachments:

0013-architecture.patch: complete patch vs. master

0013-architecture.sgml.diff: changes in file architecture.sgml since 0012

0013-images.diff: changes in files *-raw.svg since 0012

-- 

J. Purtz

 
 
  <chapter id="overview">
 
   <note>
    <title>Author</title>
index 0000000000..4bbd6abb8a
@@ -0,0 +1,1524 @@
+   basic techniques <productname>PostgreSQL</productname> uses to
+   achieve this aim. It does not offer anything which exceeds
+   the information content of other pages. Instead, it tries to
+   explain <emphasis>why</emphasis> certain implementation
+   decisions have been taken.
+    All aspects of an Instance are launched and managed using a single primary
+    process termed the
+    It loads configuration files, allocates Shared Memory, and
+    starts the other collaborating processes of the Instance:
+    Later, the Postmaster listens on its configured system port and in response
+    to client connection attempts launches
+    to which it delegates authentication, communication, and the handling of their requests.
+    in the Instance. Writes also use this cache, in addition
+    changed, this is not a problem. But writes directly modify
+    the pages in Shared Memory. Modified pages are called dirty
+    pages (or dirty buffers) and before they can be evicted they
+    Shared Memory. The concurrently running WAL Writer process
+    Second, the Instance transfers dirty buffers from Shared Memory to
+    files. This is the primary task of the
+    are written and flushed to disk.
+    Older WAL files are no longer required to recover the system from a crash.
+    can be enabled and configured to run a script on completed WAL
+    files &mdash; usually to copy them to a remote location. Note
+    that when a Checkpoint record is written to the WAL the current
+    file is immediately completed.
+    A <glossterm linkend="glossary-server">Server</glossterm> contains one or more
+    <glossterm linkend="glossary-db-cluster">Database Clusters</glossterm>
+    (<glossterm linkend="glossary-db-cluster">Clusters</glossterm>
+    for short). By default each newly initialized Cluster contains three
+    <glossterm linkend="glossary-database">databases</glossterm>
+    (one interactive and two templates, see <xref linkend="app-initdb"/>).
+    Each database can contain many user-writable
+    <glossterm linkend="glossary-schema">schemas</glossterm>
+    (public, by name and permissiveness, by default), the system
+    generated user-facing schemas <literal>pg_catalog</literal>,
+    <literal>pg_temp</literal>, and <literal>information_schema</literal>,
+    and some more system schemas.
+    <glossterm linkend="glossary-table">Tables</glossterm>,
+    of other objects uniquely reside in a single schema.
+    <!-- is the para helpful at this position? -->
+    Client connections act at the database level and can access
+    its schemas simultaneously. Special techniques like
+    <link linkend="sql-createforeigndatawrapper">foreing data wrapper</link>
+    or <link linkend="dblink">dblink</link> are required
+    to access multiple databases, even within the same Cluster,
+    from a single client connection.
+    A Cluster is the outer container for a
+    database of any Cluster. It
+    is created during the initialization phase of the Cluster.
+    of the Cluster that a user might need,
+    of all other databases, no client is allowed to connect to it.
+    objects like application-specific tables or views. To access
+    objects in such a schema they can be fully qualified, e.g.
+    <literal>my_schema.my_table</literal>, or by changing the
+    <link linkend="ddl-schemas-path">schema search path</link>.
+    <literal>information_schema</literal> is a similar schema. It
+    contains several tables and views of the System Catalog in a
+    way that conforms to the SQL standard.
+    There are many different SQL object types:
+    <glossterm linkend="glossary-schema">schema</glossterm>,
+    <glossterm linkend="glossary-table">table</glossterm>,
+    <glossterm linkend="glossary-view">view</glossterm>,
+    <glossterm linkend="glossary-materialized-view">materialized view</glossterm>,
+    <glossterm linkend="glossary-index">index</glossterm>,
+    <glossterm linkend="glossary-constraint">constraint</glossterm>,
+    <glossterm linkend="glossary-sequence">sequence</glossterm>,
+    <glossterm linkend="glossary-function">function</glossterm>,
+    <glossterm linkend="glossary-procedure">procedure</glossterm>,
+    <glossterm linkend="glossary-trigger">trigger</glossterm>,
+    <glossterm linkend="glossary-role">role</glossterm>,
+    <glossterm linkend="datatype">data type</glossterm>,
+    <glossterm linkend="functions">operator</glossterm>,
+    <glossterm linkend="glossary-tablespace">tablespace</glossterm>,
+    <glossterm linkend="glossary-extension">extension</glossterm>,
+    <glossterm linkend="glossary-foreign-data-wrapper">foreign data wrapper</glossterm>,
+    and more. A few of them, the
+    available throughout the Cluster, not just the database in which
+    the SQL command was executed.
+   <title>The Physical Perspective: Directories and Files</title>
+    <literal>data</literal> as the name of the cluster's root directory.
+    The cluster's root directory contains many subdirectories and
+    as well as temporary data. The root's name can be selected
+    as desired, but the names of its subdirectories and files
+    are more or less fix and detertermined by
+    <productname>PostgreSQL</productname>. The following
+    paragraphs describe the most important subdirectories
+    and files.
+    <literal>base</literal> contains one
+    subdirectory per database. The names of those
+    their definition in the
+    Within the database-specific subdirectories of <literal>base</literal>
+    there are many files: one or more for every table
+    and every index. Those files are accompanied by files for the
+    Another subdirectory is <literal>global</literal>. It
+    that point to directories that are outside of the root
+    directory tree, e.g. at a different disc. Files for tables
+    and indexes of non-default tablespaces reside there. As
+    previously mentioned, those defined within the default
+    tablespace reside in the database-specific subdirectories.
+    Cluster and remain as long as
+    In the root directory
+    files of the Cluster are stored here. If the
+    Instance is up and running, the file
+    (by default)
+    Postmaster which started the Instance.
+    The advantage of MVCC over technologies that use row locks
+    becomes evident in multiuser Online Transaction Processing (OLTP)
+    Xids are sequences (with a reserved value to handle wrap-around
+    in pre-9.4 <productname>PostgreSQL</productname> versions).
+    Age computations involving them measure a transaction
+    count as opposed to a time interval (in milliseconds or otherwise).
+    If you dive deeper into <productname>PostgreSQL</productname>,
+    you will recognize parameters with names such as 'xxx_age'.
+    Despite their names, these '_age' parameters do not specify
+    a period of time but represent a certain number of transactions,
+    e.g., 100 million.
+    the data in the old version of the row is not changed.
+    before; nothing is thrown away. Only <literal>xmax</literal>
+    space. They are called <firstterm>dead rows</firstterm> and are part
+    of the <glossterm linkend="glossary-bloat">bloat</glossterm>.
+      transaction begin events.
+      this behavior has to be corrected in some way. The next
+      chapter explains how <firstterm>vacuum</firstterm> and
+      <firstterm>autovacuum</firstterm> fulfill this task.
+    and prevent continued growth.
+     Autovacuum runs automatically, by
+    at any time. DBAs do this when they recognize
+    periodically. Additionally, there is a constantly running
+    Autovacuum daemon which is part of the
+    <link linkend="glossary-instance">Instance</link>. It continuously
+    the Database Cluster. The next chapter explains the
+    The Instance may suddenly fail because of <emphasis>power off</emphasis>
+    Instance did not happen as expected: files might not be
+    Cluster is explained in more detail in the next
+    of the Cluster's directory structure and files. In
+    of the complete Cluster or certain parts of it. It stores
+    can pick parts of the Cluster, e.g., a single table or one
+    the complete Cluster.
+    consistent copy of the original Cluster.
+    of the Cluster. This history can be applied to a
+    any state of the Cluster between the time of
+    If it becomes necessary to restore the Cluster, you have to
 
index 0000000000..487eec47e1
@@ -0,0 +1,184 @@
+      <text class="text_small" x="25" y="80">
+        System schemas
+    <symbol id="rectangle_special_2">
+      <text class="text_small" x="25" y="80">
+      <rect x="15" y="105" width="205" height="30" rx="10" stroke="blue" fill="none" stroke-dasharray="4 2"/>
+        System schemas
+      <rect x="15" y="150" width="205" height="50" rx="10" stroke="blue" fill="none" stroke-dasharray="4 2"/>
+      <text class="text_normal" x="20" y="170">
+      <text class="text_small" x="25" y="185">
+    <symbol id="note_0" stroke="black" fill="lightyellow">
+      <path d="M190 10v70H0V0h180v10h10L180 0"/>
+    <symbol id="note_1" stroke="black" fill="lightyellow">
+      <path d="M450 10v240H0V0h440v10h10L440 0"/>
+    <use xlink:href="#note_0" x="20" y="40"/>
+    <text class="text_small" x="30" y="60">
+      &apos;template0&apos; is a pristine
+    <text class="text_small" x="30" y="75">
+      and unchangeable template.
+      It is used to generate
+      database &apos;template1&apos;.
+    <use xlink:href="#rectangle_special_2"/>
+    <use xlink:href="#rectangle_special_2"/>
+    <use xlink:href="#note_1"/>
+      By default, clients connect via port &apos;5432&apos; to Cluster &apos;data&apos;,
+      database &apos;postgres&apos;, schema &apos;public&apos;. Of course, they can
+    <text class="text_small" x="30" y="50">
+      specify other connection properties.
+    <text class="text_small" x="10" y="70">
+      System schemas: pg_catalog, information_schema,
+    <text class="text_small" x="30" y="85">
+      pg_temp, ...
+    <text class="text_small" x="10" y="105">
+      Global SQL objects: Objects which are shared among all
+    <text class="text_small" x="30" y="120">
+      databases within a Cluster.
+    <text class="text_small" x="10" y="140">
+    <text class="text_small" x="30" y="170">
+    <text class="text_small" x="10" y="190">
+    <text class="text_small" x="30" y="220">
+    <text class="text_small" x="10" y="240">
+    <text class="text_small" x="30" y="240">
+      Client application are prohibited from connecting to &apos;template0&apos;.
index 0000000000..05623a4092
@@ -0,0 +1,528 @@
+   id="svg165"
+     id="metadata169">
+     inkscape:window-width="780"
+     id="namedview167"
+     inkscape:current-layer="svg165" />
+     id="defs57">
+         id="rect9" />
+         id="rect11" />
+         id="text13">schema 'public'</text>
+         id="text15">tables, views, ...</text>
+         id="text19">System schemas</text>
+       id="rectangle_special_2">
+         id="rect22" />
+         id="rect24" />
+         id="text26">schema 'public'</text>
+         id="text28">tables, views, ...</text>
+         id="rect30" />
+         id="text32">System schemas</text>
+         y="150"
+         id="rect34" />
+         id="text36">'my_schema' (optional)</text>
+         y="185"
+         id="text38">tables, views, ...</text>
+       id="note_0"
+         id="title41">UML Note</title>
+         d="M 190,10 v 70 h -190 v -80 h 180 v 10 h 10 l -10,-10"
+       id="note_1"
+         id="title46">UML Note</title>
+         d="M 450,10 v 240 h -450 v -250 h 440 v 10 h 10 l -10,-10"
+         id="path48" />
+         id="path51" />
+         id="path54" />
+     id="rect59" />
+     id="text61">Server (Hardware, Container, or VM)</text>
+     id="g67">
+       id="rect63" />
+       id="text65">cluster 'data' (default, managed by one instance)</text>
+       id="path69" />
+       id="text71">cluster 'cluster_2' (optional, managed by a different instance)</text>
+       id="text77">database 'template0'</text>
+       xlink:href="#note_0"
+       id="text81">'template0' is a pristine</text>
+       id="text83">and unchangeable template.</text>
+       id="text85">It is used to generate</text>
+       id="text87">database 'template1'.</text>
+       id="text93">database 'template1'</text>
+       xlink:href="#rectangle_special_2"
+       id="use97" />
+       id="text99">database 'postgres'</text>
+     id="g107">
+       xlink:href="#rectangle_special_2"
+       id="text105">database 'my_db' (optional)</text>
+     id="g119">
+       id="rect109" />
+       id="text111">Global SQL objects</text>
+       id="path113" />
+       id="path115" />
+       id="path117" />
+     id="g163">
+       xlink:href="#note_1"
+       id="text123">1)</text>
+       id="text125">By default, clients connect via port '5432' to Cluster 'data',</text>
+       id="text127">database 'postgres', schema 'public'. Of course, they can</text>
+       id="text129">specify other connection properties.</text>
+       id="text131">2)</text>
+       id="text133">System schemas: pg_catalog, information_schema,</text>
+       y="85"
+       id="text135">pg_temp, ...</text>
+       id="text137">3)</text>
+       id="text139">Global SQL objects: Objects which are shared among all</text>
+       y="120"
+       id="text141">databases within a Cluster.</text>
+       id="text143">4)</text>
+       id="text145">The command 'initdb' creates a new cluster with the three</text>
+       id="text147">databases 'template0', 'template1', and 'postgres'. The command</text>
+       id="text149">'createdb' creates a new database.</text>
+       id="text151">5)</text>
+       id="text153">If multiple clusters are active on one server at the same time,</text>
+       id="text155">each one is managed by an individual instance. Each such instance</text>
+       y="220"
+       id="text157">uses a different port.</text>
+       y="240"
+       id="text159">6)</text>
+       y="240"
+       id="text161">Client application are prohibited from connecting to 'template0'.</text>
index 0000000000..8534b18ec2
@@ -0,0 +1,191 @@
+      <text class="text_small"  x="25" y="80">tables, views, ...</text>
+      <text class="text_small"  x="20" y="125">System schemas</text>
+    <symbol id="rectangle_special_2">
+      <text class="text_small"  x="25" y="80">tables, views, ...</text>
+      <rect x="15" y="105" width="205" height="30" rx="10" stroke="blue" fill="none" stroke-dasharray="4 2" />
+      <text class="text_small"  x="20" y="125">System schemas</text>
+      <rect x="15" y="150" width="205" height="50" rx="10" stroke="blue" fill="none" stroke-dasharray="4 2" />
+      <text class="text_normal" x="20" y="170">'my_schema' (optional)</text>
+      <text class="text_small"  x="25" y="185">tables, views, ...</text>
+    <symbol id="note_0" stroke="black" fill="lightyellow">
+      <path d="M 190,10 v 70 h -190 v -80 h 180 v 10 h 10 l -10,-10" />
+    <symbol id="note_1" stroke="black" fill="lightyellow">
+      <path d="M 450,10 v 240 h -450 v -250 h 440 v 10 h 10 l -10,-10" />
+    <use xlink:href="#note_0" x="20" y="40" />
+    <text class="text_small"  x="30" y="60">'template0' is a pristine</text>
+    <text class="text_small"  x="30" y="75">and unchangeable template.</text>
+    <text class="text_small"  x="30" y="90">It is used to generate</text>
+    <text class="text_small"  x="30" y="105">database 'template1'.</text>
+    <use xlink:href="#rectangle_special_2" />
+    <use xlink:href="#rectangle_special_2" />
+    <use xlink:href="#note_1" x="0" y="0" />
+    <text class="text_small" x="30" y="20">By default, clients connect via port '5432' to Cluster 'data',</text>
+    <text class="text_small" x="30" y="35">database 'postgres', schema 'public'. Of course, they can</text>
+    <text class="text_small" x="30" y="50">specify other connection properties.</text>
+    <text class="text_small" x="10" y="70">2)</text>
+    <text class="text_small" x="30" y="70">System schemas: pg_catalog, information_schema,</text>
+    <text class="text_small" x="30" y="85">pg_temp, ...</text>
+    <text class="text_small" x="10" y="105">3)</text>
+    <text class="text_small" x="30" y="105">Global SQL objects: Objects which are shared among all</text>
+    <text class="text_small" x="30" y="120">databases within a Cluster.</text>
+    <text class="text_small" x="10" y="140">4)</text>
+    <text class="text_small" x="30" y="140">The command 'initdb' creates a new cluster with the three</text>
+    <text class="text_small" x="30" y="155">databases 'template0', 'template1', and 'postgres'. The command</text>
+    <text class="text_small" x="30" y="170">'createdb' creates a new database.</text>
+    <text class="text_small" x="10" y="190">5)</text>
+    <text class="text_small" x="30" y="190">If multiple clusters are active on one server at the same time,</text>
+    <text class="text_small" x="30" y="205">each one is managed by an individual instance. Each such instance</text>
+    <text class="text_small" x="30" y="220">uses a different port.</text>
+    <text class="text_small" x="10" y="240">6)</text>
+    <text class="text_small" x="30" y="240">Client application are prohibited from connecting to 'template0'.</text>
index 0000000000..a59198c66f
+    .text_italic,.text_normal{font-weight:400;font-size:14px;font-family:&quot;Open Sans&quot;,sans-serif}.text_normal{font-style:normal;fill:#000}.text_italic{font-style:italic;fill:silver}
+    <text x="10" y="26" class="text_italic">
+      /var/lib/pgsql/
+    <text x="10" y="26" class="text_italic">
+      Cluster&apos;s root directory (with an arbitrary name; see: PGDATA)
+      Subdirectory for data in default-tablespace of first database &apos;template0&apos;
+      Subdirectory for data in default-tablespace of second database &apos;template1&apos;
+      Subdirectory for data in default-tablespace of third database &apos;postgres&apos;
+      Optional: one subdirectory for each new database, e.g. &apos;23456&apos; for &apos;my_db&apos;
+      Subdirectory for information about Global SQL Objects
+      Subdirectory for symbolic links to non-default tablespaces
+    <text x="10" y="26" class="text_italic">
+    <text x="10" y="26" class="text_italic">
+      Root of another cluster
index 0000000000..615a6d214a
@@ -0,0 +1,403 @@
+   id="svg329"
+     id="metadata333">
+     inkscape:window-width="1106"
+     inkscape:window-height="813"
+     id="namedview331"
+     inkscape:cy="311.86441"
+     inkscape:current-layer="svg329" />
+     id="title179">Directory structure of a cluster</title>
+     id="style181">
+  .text_italic  {font-style:italic;
+                 fill:silver;
+     id="defs203">
+         id="title183">Directory</title>
+         id="rect185" />
+         id="path187" />
+         id="title190">File</title>
+         id="rect192" />
+         id="path194" />
+         id="path196" />
+         id="path198" />
+     id="rect205" />
+     id="text207">Directory Structure</text>
+     id="g215">
+       id="use209" />
+       class="text_italic"
+       id="text211">/var/lib/pgsql/</text>
+       id="text213">An arbitrary directory</text>
+     id="g223">
+       id="use217" />
+       class="text_italic"
+       id="text219">data/</text>
+       id="text221">Cluster's root directory (with an arbitrary name; see: PGDATA)</text>
+     id="g231">
+       id="use225" />
+       id="text227">base/</text>
+       id="text229">Subdirectory containing per-database subdirectories</text>
+     id="g239">
+       id="use233" />
+       id="text235">1/</text>
+       id="text237">Subdirectory for data in default-tablespace of first database 'template0'</text>
+     id="g247">
+       id="use241" />
+       id="text243">12992/</text>
+       id="text245">Subdirectory for data in default-tablespace of second database 'template1'</text>
+     id="g255">
+       id="use249" />
+       id="text251">12999/</text>
+       id="text253">Subdirectory for data in default-tablespace of third database 'postgres'</text>
+     id="g263">
+       id="use257" />
+       id="text259">nnnnn/</text>
+       id="text261">Optional: one subdirectory for each new database, e.g. '23456' for 'my_db'</text>
+     id="g271">
+       id="use265" />
+       id="text267">global/</text>
+       id="text269">Subdirectory for information about Global SQL Objects</text>
+     id="g279">
+       id="use273" />
+       id="text275">pg_tblspc/</text>
+       id="text277">Subdirectory for symbolic links to non-default tablespaces</text>
+     id="g287">
+       id="text283">pg_wal/</text>
+       id="text285">Subdirectory for Write Ahead Log files ('pg_xlog' before version 10)</text>
+     id="g295">
+       id="use289" />
+       id="text291">pg_xact/</text>
+       id="text293">Subdirectory for transaction commit status ('pg_clog' before version 10)</text>
+     id="g303">
+       id="use297" />
+       id="text299">pg_... /</text>
+       id="text301">Some more subdirectories</text>
+     id="g311">
+       id="use305" />
+       id="use307" />
+       id="text309">'postmaster.pid' and other files with cluster-wide relevance</text>
+     id="g319">
+       id="use313" />
+       class="text_italic"
+       id="text315">...</text>
+       id="text317">Same or another arbitrary directory</text>
+     id="g327">
+       id="use321" />
+       class="text_italic"
+       id="text323">cluster_2/</text>
+       id="text325">Root of another cluster</text>
index 0000000000..5cce551b0c
@@ -0,0 +1,150 @@
+  .text_italic  {font-style:italic;
+                 fill:silver;
+    <text x="10"  y="26" class="text_italic">/var/lib/pgsql/</text>
+    <text x="10"  y="26" class="text_italic">data/</text>
+    <text x="250" y="26" class="text_normal">Cluster's root directory (with an arbitrary name; see: PGDATA)</text>
+    <text x="150" y="26" class="text_normal">Subdirectory for data in default-tablespace of first database 'template0'</text>
+    <text x="150" y="26" class="text_normal">Subdirectory for data in default-tablespace of second database 'template1'</text>
+    <text x="150" y="26" class="text_normal">Subdirectory for data in default-tablespace of third database 'postgres'</text>
+    <text x="150" y="26" class="text_normal">Optional: one subdirectory for each new database, e.g. '23456' for 'my_db'</text>
+    <text x="200" y="26" class="text_normal">Subdirectory for information about Global SQL Objects</text>
+    <text x="200" y="26" class="text_normal">Subdirectory for symbolic links to non-default tablespaces</text>
+    <text x="10"  y="26" class="text_italic">...</text>
+    <text x="10"  y="26" class="text_italic">cluster_2/</text>
+    <text x="250" y="26" class="text_normal">Root of another cluster</text>
index 0000000000..e353ce4d87
index 0000000000..3429266782
+   id="svg82"
+     id="metadata88">
+     id="defs86" />
+     inkscape:window-width="919"
+     inkscape:window-height="528"
+     id="namedview84"
+     inkscape:current-layer="svg82" />
+     id="title2">Hierarchy of Internal Objects</title>
+     id="text8">Hierarchy of Internal Objects</text>
+     id="g80">
+       id="g46">
+         id="ellipse10" />
+         id="text12">Cluster</text>
+         id="g18">
+           id="ellipse14" />
+           id="text16">Database Names</text>
+         id="g24">
+           id="ellipse20" />
+           id="text22">Tablespace</text>
+         id="g30">
+           id="ellipse26" />
+           id="text28">Replication Origins</text>
+         id="g38">
+           id="ellipse32" />
+           id="text34">Subscription for</text>
+           id="text36">Logical Replication</text>
+         id="g44">
+           id="ellipse40" />
+           id="text42">Role</text>
+       id="g78">
+         id="ellipse48" />
+         id="text50">Database</text>
+         id="g76">
+           id="g56">
+             id="ellipse52" />
+             id="text54">Extension</text>
+           id="g62">
+             id="ellipse58" />
+             id="text60">Collation</text>
+           id="g74">
+             id="ellipse64" />
+             id="text66">Schema</text>
+             id="g72">
+               id="ellipse68" />
+               id="text70">Table, View, ...</text>
index 0000000000..78850283d9
 
+  &architecture;
   &arch-dev;
   &catalogs;
   &protocol;

    <para>
 
-    <itemizedlist>
-     <listitem>
-      <para>
 
-     <listitem>
-      <para>
 
-    </itemizedlist>
-   </para>
+    <listitem>
+     <para>
 
    <para>
 
-   <para>

diff --git a/doc/src/sgml/architecture.sgml b/doc/src/sgml/architecture.sgml
index b7589f9a4f..4bbd6abb8a 100644
--- a/doc/src/sgml/architecture.sgml
+++ b/doc/src/sgml/architecture.sgml
@@ -6,8 +6,11 @@
   <para>
    Every DBMS implements basic strategies to ensure a fast
    and robust system. This chapter provides an overview of the
-   techniques <productname>PostgreSQL</productname> uses to
-   achieve this.
+   basic techniques <productname>PostgreSQL</productname> uses to
+   achieve this aim. It does not offer anything which exceeds
+   the information content of other pages. Instead, it tries to
+   explain <emphasis>why</emphasis> certain implementation
+   decisions have been taken.
   </para>
 
@@ -28,10 +31,11 @@
    </para>
 
    <para>
-    The first step when an Instance starts is the start of the
+    All aspects of an Instance are launched and managed using a single primary
+    process termed the
     <glossterm linkend="glossary-postmaster">Postmaster</glossterm>.
-    It loads the configuration files, allocates Shared Memory, and
-    starts the other processes of the Instance:
+    It loads configuration files, allocates Shared Memory, and
+    starts the other collaborating processes of the Instance:
     <glossterm linkend="glossary-background-writer">Background Writer</glossterm>,
     <glossterm linkend="glossary-checkpointer">Checkpointer</glossterm>,
     <glossterm linkend="glossary-wal-writer">WAL Writer</glossterm>,
@@ -39,9 +43,10 @@
     <glossterm linkend="glossary-autovacuum">Autovacuum</glossterm>,
     <glossterm linkend="glossary-stats-collector">Statistics Collector</glossterm>,
     <glossterm linkend="glossary-logger">Logger</glossterm>, and more.
-    Later, the Postmaster starts
+    Later, the Postmaster listens on its configured system port and in response
+    to client connection attempts launches
     <glossterm linkend="glossary-backend">Backend</glossterm> processes
-    which communicate with clients and handle their requests.
+    to which it delegates authentication, communication, and the handling of their requests.
     <xref linkend="tutorial-ram-proc-file-figure"/> visualizes the processes
     of an Instance and the main aspects of their collaboration.
    </para>
@@ -62,14 +67,6 @@
     </mediaobject>
    </figure>
 
-   <para>
-    When a client application tries to connect to a
-    <glossterm linkend="glossary-database">database</glossterm>,
-    this request is handled initially by the Postmaster. It
-    starts a new Backend process, which handles all further
-    client's requests.
-   </para>
-
    <para>
     Client requests like <command>SELECT</command> or
     <command>UPDATE</command> usually lead to the
@@ -77,16 +74,16 @@
     by the client's backend process. Reads involve a page-level
     cache, located in Shared Memory (for details see:
     <xref linkend="sysvipc"/>) for the benefit of all processes
-    in the instance. Writes also use this cache, in addition
+    in the Instance. Writes also use this cache, in addition
     to a journal, called the write-ahead-log or WAL.
    </para>
 
    <para>
     Shared Memory is limited in size and it can become necessary
     to evict pages. As long as the content of such pages hasn't
-    changed, this is not a problem. But in Shared Memory also
-    write actions take place. Modified pages are called dirty
-    pages or dirty buffers and before they can be evicted they
+    changed, this is not a problem. But writes directly modify
+    the pages in Shared Memory. Modified pages are called dirty
+    pages (or dirty buffers) and before they can be evicted they
     must be written to disk. This happens regularly by the
     Checkpointer and the Background Writer processes to ensure
     that the disk version of the pages are up-to-date.
@@ -98,7 +95,7 @@
     <glossterm linkend="glossary-wal-record">WAL record</glossterm>
     is created from the delta-information (difference between the
     old and the new content) and stored in another area of
-    Shared Memory. The parallel running WAL Writer process
+    Shared Memory. The concurrently running WAL Writer process
     reads them and appends them to the end of the current
     <glossterm linkend="glossary-wal-record">WAL file</glossterm>.
     Such sequential writes are faster than writes to random
@@ -108,8 +105,8 @@
    </para>
 
    <para>
-    Second, the transfer of dirty buffers from Shared Memory to
-    files must take place. This is the primary task of the
+    Second, the Instance transfers dirty buffers from Shared Memory to
+    files. This is the primary task of the
     Background Writer process. Because I/O activities can block
     other processes, it starts periodically and
     acts only for a short period. Doing so, its extensive (and
@@ -123,14 +120,8 @@
     <glossterm linkend="glossary-checkpoint">Checkpoints</glossterm>.
     A Checkpoint is a point in time when all older dirty buffers,
     all older WAL records, and finally a special Checkpoint record
-    are written and flushed to disk. Heap and index files,
-    and WAL files are now in sync.
-    Older WAL is no longer required. In other words,
-    a possibly occurring recovery, which integrates the delta
-    information of WAL into heap and index files, will happen
-    by replaying only WAL past the last-recorded checkpoint.
-    This limits the amount of WAL to be replayed
-    during recovery in the event of a crash.
+    are written and flushed to disk.
+    Older WAL files are no longer required to recover the system from a crash.
    </para>
 
    <para>
@@ -141,8 +132,10 @@
     less common). Options and details are covered
     in the backup and restore section (<xref linkend="backup"/>).
     For our purposes here, just note that the WAL Archiver process
-    can be enabled and configured to run a script on filled WAL
-    files &mdash; usually to copy them to a remote location.
+    can be enabled and configured to run a script on completed WAL
+    files &mdash; usually to copy them to a remote location. Note
+    that when a Checkpoint record is written to the WAL the current
+    file is immediately completed.
    </para>
 
    <para>
@@ -163,23 +156,35 @@
    <title>The logical Perspective: Cluster, Database, Schema</title>
 
    <para>
-    A <glossterm linkend="glossary-server">server</glossterm> contains one or more
-    <glossterm linkend="glossary-db-cluster">database clusters</glossterm>
-    (<glossterm linkend="glossary-db-cluster">clusters</glossterm>
-    for short). Each cluster contains three or more
-    <glossterm linkend="glossary-database">databases</glossterm>.
-    Each database can contain many
-    <glossterm linkend="glossary-schema">schemas</glossterm>.
-    A schema can contain
-    <glossterm linkend="glossary-table">tables</glossterm>,
+    A <glossterm linkend="glossary-server">Server</glossterm> contains one or more
+    <glossterm linkend="glossary-db-cluster">Database Clusters</glossterm>
+    (<glossterm linkend="glossary-db-cluster">Clusters</glossterm>
+    for short). By default each newly initialized Cluster contains three
+    <glossterm linkend="glossary-database">databases</glossterm>
+    (one interactive and two templates, see <xref linkend="app-initdb"/>).
+    Each database can contain many user-writable
+    <glossterm linkend="glossary-schema">schemas</glossterm>
+    (public, by name and permissiveness, by default), the system
+    generated user-facing schemas <literal>pg_catalog</literal>,
+    <literal>pg_temp</literal>, and <literal>information_schema</literal>,
+    and some more system schemas.
+    <glossterm linkend="glossary-table">Tables</glossterm>,
     <glossterm linkend="glossary-view">views</glossterm>, and a lot
-    of other objects. Each table or view belongs to a single schema
-    only; they cannot belong to another schema as well. The same is
-    true for the schema/database and database/cluster relation.
+    of other objects uniquely reside in a single schema.
     <xref linkend="tutorial-cluster-db-schema-figure"/> visualizes
     this hierarchy.
    </para>
 
+   <para>
+    <!-- is the para helpful at this position? -->
+    Client connections act at the database level and can access
+    its schemas simultaneously. Special techniques like
+    <link linkend="sql-createforeigndatawrapper">foreing data wrapper</link>
+    or <link linkend="dblink">dblink</link> are required
+    to access multiple databases, even within the same Cluster,
+    from a single client connection.
+   </para>
+
    <figure id="tutorial-cluster-db-schema-figure">
     <title>Cluster, Database, Schema</title>
     <mediaobject>
@@ -197,31 +202,30 @@
    </figure>
 
    <para>
-    A cluster is the outer container for a
+    A Cluster is the outer container for a
     collection of databases. Clusters are created by the command
     <xref linkend="app-initdb"/>.
    </para>
 
    <para>
     <literal>template0</literal> is the very first
-    database of any cluster. Database <literal>template0</literal>
-    is created during the initialization phase of the cluster.
+    database of any Cluster. It
+    is created during the initialization phase of the Cluster.
     In a second step, database <literal>template1</literal> is generated
     as a copy of <literal>template0</literal>, and finally database
     <literal>postgres</literal> is generated as a copy of
     <literal>template1</literal>. Any
     <glossterm linkend="app-createdb">new databases</glossterm>
-    of the cluster that a user might need,
+    of the Cluster that a user might need,
     such as <literal>my_db</literal>, will be copied from the
     <literal>template1</literal> database. Due to the unique
     role of <literal>template0</literal> as the pristine original
-    of all other databases, no client can connect to it.
+    of all other databases, no client is allowed to connect to it.
    </para>
 
    <para>
-    Every database must contain at least one schema because all
     <glossterm linkend="glossary-sql-object">SQL Objects</glossterm>
-    must be contained in a schema.
+    are contained in a schema.
     Schemas are namespaces for SQL objects and ensure
     (with one exception) that the SQL object names are used only once within
     their scope across all types of SQL objects. E.g., it is not possible
@@ -243,26 +247,46 @@
     without using an explicit schema name. <literal>public</literal>
     should not contain user-defined SQL objects. Instead, it is
     recommended to create a separate schema that holds individual
-    objects like application-specific tables or views.
+    objects like application-specific tables or views. To access
+    objects in such a schema they can be fully qualified, e.g.
+    <literal>my_schema.my_table</literal>, or by changing the
+    <link linkend="ddl-schemas-path">schema search path</link>.
+   </para>
+
+   <para>
     <literal>pg_catalog</literal> is a schema for all tables and views of the
     <glossterm linkend="glossary-system-catalog">System Catalog</glossterm>.
-    <literal>information_schema</literal> is a schema for several
-    tables and views of the System Catalog in a way that conforms
-    to the SQL standard.
+    <literal>information_schema</literal> is a similar schema. It
+    contains several tables and views of the System Catalog in a
+    way that conforms to the SQL standard.
    </para>
 
    <para>
-    There are many different SQL object
-    types: <firstterm>database, schema, table, view, materialized
-    view, index, constraint, sequence, function, procedure,
-    trigger, role, data type, operator, tablespace, extension,
-    foreign data wrapper</firstterm>, and more. A few of them, the
+    There are many different SQL object types:
+    <glossterm linkend="glossary-database">database</glossterm>,
+    <glossterm linkend="glossary-schema">schema</glossterm>,
+    <glossterm linkend="glossary-table">table</glossterm>,
+    <glossterm linkend="glossary-view">view</glossterm>,
+    <glossterm linkend="glossary-materialized-view">materialized view</glossterm>,
+    <glossterm linkend="glossary-index">index</glossterm>,
+    <glossterm linkend="glossary-constraint">constraint</glossterm>,
+    <glossterm linkend="glossary-sequence">sequence</glossterm>,
+    <glossterm linkend="glossary-function">function</glossterm>,
+    <glossterm linkend="glossary-procedure">procedure</glossterm>,
+    <glossterm linkend="glossary-trigger">trigger</glossterm>,
+    <glossterm linkend="glossary-role">role</glossterm>,
+    <glossterm linkend="datatype">data type</glossterm>,
+    <glossterm linkend="functions">operator</glossterm>,
+    <glossterm linkend="glossary-tablespace">tablespace</glossterm>,
+    <glossterm linkend="glossary-extension">extension</glossterm>,
+    <glossterm linkend="glossary-foreign-data-wrapper">foreign data wrapper</glossterm>,
+    and more. A few of them, the
     <firstterm>Global SQL Objects</firstterm>, are outside of the
     strict hierarchy: All <firstterm>database names</firstterm>,
     all <firstterm>tablespace names</firstterm>, and all
     <firstterm>role names</firstterm> are automatically
-    available throughout the cluster, independent from
-    the database or schema in which they were defined originally.
+    available throughout the Cluster, not just the database in which
+    the SQL command was executed.
     <xref linkend="tutorial-internal-objects-hierarchy-figure"/>
     shows the relation between the object types.
    </para>
@@ -286,7 +310,7 @@
   </sect1>
 
   <sect1 id="tutorial-directories">
-   <title>The physical Perspective: Directories and Files</title>
+   <title>The Physical Perspective: Directories and Files</title>
 
    <para>
     <productname>PostgreSQL</productname> organizes long-lasting (persistent)
@@ -297,7 +321,7 @@
     variable <literal>PGDATA</literal> points to this directory.
     The example shown in
     <xref linkend="tutorial-directories-figure"/> uses
-    <literal>data</literal> as the name of this root directory.
+    <literal>data</literal> as the name of the cluster's root directory.
    </para>
 
    <figure id="tutorial-directories-figure">
@@ -317,27 +341,29 @@
    </figure>
 
    <para>
-    <literal>data</literal> contains many subdirectories and
+    The cluster's root directory contains many subdirectories and
     some files, all of which are necessary to store long-lasting
-    as well as temporary data. The following paragraphs
-    describe the files and subdirectories in
-    <literal>data</literal>.
+    as well as temporary data. The root's name can be selected
+    as desired, but the names of its subdirectories and files
+    are more or less fix and detertermined by
+    <productname>PostgreSQL</productname>. The following
+    paragraphs describe the most important subdirectories
+    and files.
    </para>
 
    <para>
-    <literal>base</literal> is a subdirectory in which one
-    subdirectory per database exists. The names of those
+    <literal>base</literal> contains one
+    subdirectory per database. The names of those
     subdirectories consist of numbers. These are the internal
     Object Identifiers (OID), which are numbers to identify
-    the database definition in the
+    their definition in the
     <glossterm linkend="glossary-system-catalog">System Catalog</glossterm>.
    </para>
 
    <para>
-    Within the database-specific
-    subdirectories, there are many files: one or more for
-    every table and every index to store heap and index
-    data. Those files are accompanied by files for the
+    Within the database-specific subdirectories of <literal>base</literal>
+    there are many files: one or more for every table
+    and every index. Those files are accompanied by files for the
     <link linkend="storage-fsm">Free Space Maps</link>
     (suffixed <literal>_fsm</literal>) and
     <link linkend="storage-vm">Visibility Maps</link>
@@ -345,20 +371,25 @@
    </para>
 
    <para>
-    Another subdirectory is <literal>global</literal> which
+    Another subdirectory is <literal>global</literal>. It
     contains files with information about
     <glossterm linkend="glossary-sql-object">Global SQL Objects</glossterm>.
-    One type of such Global SQL Objects are
-    <glossterm linkend="glossary-tablespace">tablespaces</glossterm>.
-    In <literal>global</literal> there is information about
-    the tablespaces; not the tablespaces themselves.
+   </para>
+
+   <para>
+    In <literal>pg_tblspc</literal>, there are symbolic links
+    that point to directories that are outside of the root
+    directory tree, e.g. at a different disc. Files for tables
+    and indexes of non-default tablespaces reside there. As
+    previously mentioned, those defined within the default
+    tablespace reside in the database-specific subdirectories.
    </para>
 
    <para>
     The subdirectory <literal>pg_wal</literal> contains the
     <glossterm linkend="glossary-wal-file">WAL files</glossterm>.
     They arise and grow in parallel with data changes in the
-    cluster and remain as long as
+    Cluster and remain as long as
     they are required for recovery, archiving, or replication.
    </para>
 
@@ -370,19 +401,14 @@
    </para>
 
    <para>
-    In <literal>pg_tblspc</literal>, there are symbolic links
-    that point to directories containing SQL objects
-    that exist within a non-default tablespace.
-   </para>
-
-   <para>
-    In the root directory <literal>data</literal>
+    In the root directory
     there are also some files. In many cases, the configuration
-    files of the cluster are stored here. If the
-    instance is up and running, the file
+    files of the Cluster are stored here. If the
+    Instance is up and running, the file
     <literal>postmaster.pid</literal> exists here
+    (by default)
     and contains the process ID (pid) of the
-    Postmaster which started the instance.
+    Postmaster which started the Instance.
    </para>
 
    <para>
@@ -413,8 +439,8 @@
     <productname>PostgreSQL</productname> implements a
     sophisticated technique which avoids locking:
     <firstterm>Multiversion Concurrency Control</firstterm> (MVCC).
-    The advantage of MVCC
-    over technologies that use row locks becomes evident in multiuser OLTP
+    The advantage of MVCC over technologies that use row locks
+    becomes evident in multiuser Online Transaction Processing (OLTP)
     environments with a massive number of concurrent write
     actions. There, MVCC generally performs better than solutions
     using locks. In a <productname>PostgreSQL</productname>
@@ -439,15 +465,15 @@
    </para>
 
    <para>
-    When we speak about transaction IDs, you need to know that xids are like
-    sequences. Every new transaction receives the next number as its ID.
-    Therefore, this flow of xids represents the flow of transaction
-    start events over time. But keep in mind that xids are independent of
-    any time measurement &mdash; in milliseconds or otherwise. If you dive
-    deeper into <productname>PostgreSQL</productname>, you will recognize
-    parameters with names such as 'xxx_age'. Despite their names,
-    these '_age' parameters do not specify a period of time but represent
-    a certain number of transactions, e.g., 100 million.
+    Xids are sequences (with a reserved value to handle wrap-around
+    in pre-9.4 <productname>PostgreSQL</productname> versions).
+    Age computations involving them measure a transaction
+    count as opposed to a time interval (in milliseconds or otherwise).
+    If you dive deeper into <productname>PostgreSQL</productname>,
+    you will recognize parameters with names such as 'xxx_age'.
+    Despite their names, these '_age' parameters do not specify
+    a period of time but represent a certain number of transactions,
+    e.g., 100 million.
    </para>
 
    <para>
@@ -498,7 +524,7 @@
     executes an <command>UPDATE</command> of this row by
     changing the user data from <literal>'x'</literal> to
     <literal>'y'</literal>. According to the MVCC principles,
-    the data in the old version of the row is not changed!
+    the data in the old version of the row is not changed.
     The value <literal>'x'</literal> remains as it was before.
     Only <literal>xmax</literal> changes to <literal>135</literal>.
     Now, this version is treated as valid exclusively for
@@ -526,7 +552,7 @@
    <para>
     Finally, a row may be deleted by a <command>DELETE</command>
     command. Even in this case, all versions of the row remain as
-    before. Nothing is thrown away! Only <literal>xmax</literal>
+    before; nothing is thrown away. Only <literal>xmax</literal>
     of the last version is set to the xid of the <command>DELETE</command>
     transaction, which indicates that (if committed) it is only visible to
     transactions with xids older than that (from
@@ -545,7 +571,8 @@
     Over time, also the older ones get out of scope
     for ALL transactions and therefore become unnecessary.
     Nevertheless, they do exist physically on the disk and occupy
-   space.
+    space. They are called <firstterm>dead rows</firstterm> and are part
+    of the <glossterm linkend="glossary-bloat">bloat</glossterm>.
    </para>
 
    <para>
@@ -560,12 +587,7 @@
       <firstterm>row versions</firstterm> are valid (visible) for transactions.
       This range doesn't imply any direct temporal meaning;
       the sequence of xids reflects only the sequence of
-      transaction begin events. As
-      xids grow, old row versions get out of scope over time.
-      If an old row version is no longer relevant for ANY existing
-      transactions, it can be marked <firstterm>dead</firstterm>. The
-      space occupied by dead row versions is part of the
-      <glossterm linkend="glossary-bloat">bloat</glossterm>.
+      transaction begin events.
      </simpara>
     </listitem>
 
@@ -581,9 +603,9 @@
      <simpara>
       Nothing is removed &mdash; with the consequence that the database
       occupies more and more disk space. It is obvious that
-      this behavior has to be corrected in some
-      way. The next chapter explains how <firstterm>autovacuum</firstterm>
-      fulfills this task.
+      this behavior has to be corrected in some way. The next
+      chapter explains how <firstterm>vacuum</firstterm> and
+      <firstterm>autovacuum</firstterm> fulfill this task.
      </simpara>
     </listitem>
 
@@ -601,12 +623,12 @@
     This chapter explains how the SQL command
     <command>VACUUM</command> and the automatically running
     <firstterm>Autovacuum</firstterm> processes clean up
-    and avoid continued growth.
+    and prevent continued growth.
    </para>
 
    <note>
     <para>
-     Autovacuum runs automatically by
+     Autovacuum runs automatically, by
      default. Its default parameters as well as those for
      <command>VACUUM</command> are appropriate for most standard
      situations. Therefore a novice database manager can
@@ -617,11 +639,11 @@
 
    <para>
     Client processes can issue the SQL command <command>VACUUM</command>
-    at arbitrary points in time. DBAs do this when they recognize
+    at any time. DBAs do this when they recognize
     special situations, or they start it in batch jobs which run
-    periodically. Autovacuum processes run as part of the
-    <link linkend="glossary-instance">Instance</link> at the server.
-    There is a constantly running Autovacuum daemon. It continuously
+    periodically. Additionally, there is a constantly running
+    Autovacuum daemon which is part of the
+    <link linkend="glossary-instance">Instance</link>. It continuously
     monitors the state of all databases based on values that are collected by the
     <link linkend="glossary-stats-collector">Statistics Collector</link>
     and starts Autovacuum processes whenever it detects
@@ -1234,7 +1256,7 @@ UPDATE accounts SET balance = balance + 100.00 WHERE name = 'Bob';
    <para>
     Lastly, it is worth noticing that changes done by a
     committed transaction will survive all failures in the application or
-    database cluster. The next chapter explains the
+    the Database Cluster. The next chapter explains the
     <glossterm linkend="glossary-durability">durability</glossterm>
     guarantees.
    </para>
@@ -1276,7 +1298,7 @@ UPDATE accounts SET balance = balance + 100.00 WHERE name = 'Bob';
 
    <bridgehead renderas="sect3">Instance failure</bridgehead>
    <para>
-    The instance may suddenly fail because of <emphasis>power off</emphasis>
+    The Instance may suddenly fail because of <emphasis>power off</emphasis>
     or other problems. This will affect all running processes, the RAM,
     and possibly the consistency of disk files.
    </para>
@@ -1284,7 +1306,7 @@ UPDATE accounts SET balance = balance + 100.00 WHERE name = 'Bob';
    <para>
     After a restart, <productname>PostgreSQL</productname>
     automatically recognizes that the last shutdown of the
-    instance did not happen as expected: files might not be
+    Instance did not happen as expected: files might not be
     closed properly and the <literal>postmaster.pid</literal>
     file unexpectedly exists. <productname>PostgreSQL</productname>
     tries to clean up the situation. This is possible because
@@ -1330,7 +1352,7 @@ UPDATE accounts SET balance = balance + 100.00 WHERE name = 'Bob';
    <para>
     They obviously need a backup. How to take such a backup
     and use it as a starting point for a recovery of the
-    cluster is explained in more detail in the next
+    Cluster is explained in more detail in the next
     <link linkend="tutorial-backup">chapter</link>.
    </para>
 
@@ -1396,7 +1418,7 @@ UPDATE accounts SET balance = balance + 100.00 WHERE name = 'Bob';
    <para>
     You can use any appropriate OS tool to create a
     <link linkend="backup-file">copy</link>
-    of the cluster's directory structure and files. In
+    of the Cluster's directory structure and files. In
     case of severe problems such a copy can serve as
     the source of recovery. But in order to get a
     <emphasis>USABLE</emphasis> backup by this method,
@@ -1416,7 +1438,7 @@ UPDATE accounts SET balance = balance + 100.00 WHERE name = 'Bob';
    <para>
     The tool <command>pg_dump</command> is able to take a
     <link linkend="backup-dump">copy</link>
-    of the complete cluster or certain parts of it. It stores
+    of the complete Cluster or certain parts of it. It stores
     the copy in the form of SQL commands like <command>CREATE</command>
     and <command>COPY</command>. It runs in
     parallel with other processes, in its own transaction.
@@ -1430,9 +1452,9 @@ UPDATE accounts SET balance = balance + 100.00 WHERE name = 'Bob';
 
    <para>
     The main advantage over the other two methods is that it
-    can pick parts of the cluster, e.g., a single table or one
+    can pick parts of the Cluster, e.g., a single table or one
     database. The other two methods work only at the level of
-    the complete cluster.
+    the complete Cluster.
    </para>
 
    <bridgehead renderas="sect2">Continuous archiving based on pg_basebackup and WAL files</bridgehead>
@@ -1447,7 +1469,7 @@ UPDATE accounts SET balance = balance + 100.00 WHERE name = 'Bob';
     <firstterm>basebackup</firstterm> with the tool
     <command>pg_basebackup</command>. The result is a
     directory structure plus files which contain a
-    consistent copy of the original cluster.
+    consistent copy of the original Cluster.
     <command>pg_basebackup</command> runs in
     parallel with other processes in its own transaction.
    </para>
@@ -1456,9 +1478,9 @@ UPDATE accounts SET balance = balance + 100.00 WHERE name = 'Bob';
     The second step is recommended but not necessary. All
     changes to the data are stored in WAL files. If you
     continuously save such WAL files, you have the history
-    of the cluster. This history can be applied to a
+    of the Cluster. This history can be applied to a
     basebackup in order to recreate
-    any state of the cluster between the time of
+    any state of the Cluster between the time of
     <command>pg_basebackup</command>'s start time and
     any later point in time. This technique
     is called 'Point-in-Time Recovery (PITR)'.
@@ -1478,7 +1500,7 @@ UPDATE accounts SET balance = balance + 100.00 WHERE name = 'Bob';
    </para>
 
    <para>
-    If it becomes necessary to restore the cluster, you have to
+    If it becomes necessary to restore the Cluster, you have to
     copy the basebackup and the archived WAL files to
     their original directories. The configuration of this
     <link linkend="backup-pitr-recovery">recovery procedure</link>
diff --git a/doc/src/sgml/images/cluster-db-schema-raw.svg b/doc/src/sgml/images/cluster-db-schema-raw.svg
index 022bc45560..8534b18ec2 100644
--- a/doc/src/sgml/images/cluster-db-schema-raw.svg
+++ b/doc/src/sgml/images/cluster-db-schema-raw.svg
@@ -36,36 +36,49 @@
       <!-- the database -->
       <rect width="225" height="155" rx="10" stroke="blue" fill="none"/>
 
+    </symbol>
+
+    <!-- a rectangle with rounded corners and inner definitions for schemas -->
+    <symbol id="rectangle_special_1">
+
+      <!-- the database -->
+      <rect width="225" height="155" rx="10" stroke="blue" fill="none"/>
+
       <!-- schemas -->
       <rect x="15" y="40" width="195" height="50" rx="10" stroke="blue" fill="none" stroke-dasharray="4 2" />
       <text class="text_normal" x="20" y="60">schema 'public'</text>
-      <text class="text_small"  x="20" y="80">tables, views, ...</text>
+      <text class="text_small"  x="25" y="80">tables, views, ...</text>
 
       <rect x="15" y="105" width="195" height="30" rx="10" stroke="blue" fill="none" stroke-dasharray="4 2" />
-      <text class="text_small"  x="20" y="125">(more system schemas)</text>
+      <text class="text_small"  x="20" y="125">System schemas</text>
     </symbol>
 
     <!-- same as before, but one more schema -->
-    <symbol id="rectangle_special_1">
+    <symbol id="rectangle_special_2">
       <!-- the database -->
       <rect width="245" height="225" rx="10" stroke="blue" fill="none"/>
 
       <!-- schemas -->
       <rect x="15" y="40" width="205" height="50" rx="10" stroke="blue" fill="none" stroke-dasharray="4 2" />
       <text class="text_normal" x="20" y="60">schema 'public'</text>
-      <text class="text_small"  x="20" y="80">tables, views, ...</text>
+      <text class="text_small"  x="25" y="80">tables, views, ...</text>
 
-      <rect x="15" y="105" width="205" height="50" rx="10" stroke="blue" fill="none" stroke-dasharray="4 2" />
-      <text class="text_normal" x="20" y="125">'my_schema' (optional)</text>
-      <text class="text_small"  x="20" y="145">tables, views, ...</text>
+      <rect x="15" y="105" width="205" height="30" rx="10" stroke="blue" fill="none" stroke-dasharray="4 2" />
+      <text class="text_small"  x="20" y="125">System schemas</text>
 
-      <rect x="15" y="170" width="205" height="30" rx="10" stroke="blue" fill="none" stroke-dasharray="4 2" />
-      <text class="text_small"  x="20" y="190">(more system schemas)</text>
+      <rect x="15" y="150" width="205" height="50" rx="10" stroke="blue" fill="none" stroke-dasharray="4 2" />
+      <text class="text_normal" x="20" y="170">'my_schema' (optional)</text>
+      <text class="text_small"  x="25" y="185">tables, views, ...</text>
     </symbol>
 
-    <symbol id="note" stroke="black" fill="lightyellow">
+    <symbol id="note_0" stroke="black" fill="lightyellow">
       <title>UML Note</title>
-      <path d="M 450,10 v 230 h -450 v -240 h 440 v 10 h 10 l -10,-10" />
+      <path d="M 190,10 v 70 h -190 v -80 h 180 v 10 h 10 l -10,-10" />
+    </symbol>
+
+    <symbol id="note_1" stroke="black" fill="lightyellow">
+      <title>UML Note</title>
+      <path d="M 450,10 v 240 h -450 v -250 h 440 v 10 h 10 l -10,-10" />
     </symbol>
 
     <!-- marker start/end -->
@@ -109,23 +122,28 @@
   <g transform="translate(40 155)">
     <use xlink:href="#rectangle_special_0" />
     <text class="text_normal" x="10" y="25">database 'template0'</text>
+    <use xlink:href="#note_0" x="20" y="40" />
+    <text class="text_small"  x="30" y="60">'template0' is a pristine</text>
+    <text class="text_small"  x="30" y="75">and unchangeable template.</text>
+    <text class="text_small"  x="30" y="90">It is used to generate</text>
+    <text class="text_small"  x="30" y="105">database 'template1'.</text>
   </g>
 
   <!-- database template 1 -->
   <g transform="translate(290 155)">
-    <use xlink:href="#rectangle_special_0" />
+    <use xlink:href="#rectangle_special_1" />
     <text class="text_normal" x="10" y="25">database 'template1'</text>
   </g>
 
   <!-- database postgres -->
   <g transform="translate(540 155)">
-    <use xlink:href="#rectangle_special_1" />
+    <use xlink:href="#rectangle_special_2" />
     <text class="text_normal" x="10" y="25">database 'postgres'</text>
   </g>
 
   <!-- database my_db -->
   <g transform="translate(40 350)">
-    <use xlink:href="#rectangle_special_1" />
+    <use xlink:href="#rectangle_special_2" />
     <text class="text_normal" x="10" y="25">database 'my_db' (optional)</text>
   </g>
 
@@ -133,7 +151,6 @@
   <g transform="translate(320 330)">
     <rect x="0" y="0" width="180" height="45" rx="10" stroke="blue" fill="none" stroke-dasharray="10 4 4 4" />
     <text class="text_normal" x="15" y="27">Global SQL objects</text>
-    <path d="M 0,5 l-65,-35" stroke="black" fill="none" marker-end="url(#arrowhead_end)" />
     <path d="M 80,0 v-30" stroke="black" fill="none" marker-end="url(#arrowhead_end)" />
     <path d="M 180,40 h50" stroke="black" fill="none" marker-end="url(#arrowhead_end)" />
     <path d="M 0,40 l-45,20" stroke="black" fill="none" marker-end="url(#arrowhead_end)" />
@@ -141,32 +158,33 @@
 
   <!-- Some comments -->
   <g transform="translate(335 405)">
-    <use xlink:href="#note" x="0" y="0" />
+    <use xlink:href="#note_1" x="0" y="0" />
 
     <text class="text_small" x="10" y="20">1)</text>
-    <text class="text_small" x="30" y="20">By default, you work in the cluster 'data', database 'postgres',</text>
-    <text class="text_small" x="30" y="35">schema 'public'.</text>
-
-    <text class="text_small" x="10" y="55">2)</text>
-    <text class="text_small" x="30" y="55">More system schemas: pg_catalog, information_schema,</text>
-    <text class="text_small" x="30" y="70">pg_temp, pg_toast.</text>
-
-    <text class="text_small" x="10" y="90">3)</text>
-    <text class="text_small" x="30" y="90">Global SQL objects: Some SQL objects are automatically active</text>
-    <text class="text_small" x="30" y="105">and known database- or even cluster-wide.</text>
-
-    <text class="text_small" x="10" y="125">4)</text>
-    <text class="text_small" x="30" y="125">The command 'initdb' creates a new cluster with the three</text>
-    <text class="text_small" x="30" y="140">databases 'template0', 'template1', and 'postgres'. The command</text>
-    <text class="text_small" x="30" y="155">'createdb' creates a new database.</text>
-
-    <text class="text_small" x="10" y="175">5)</text>
-    <text class="text_small" x="30" y="175">If multiple clusters are active on one server at the same time,</text>
-    <text class="text_small" x="30" y="190">each one is managed by an individual instance. Each such instance</text>
-    <text class="text_small" x="30" y="205">uses a different port.</text>
-
-    <text class="text_small" x="10" y="225">6)</text>
-    <text class="text_small" x="30" y="225">No client application is allowed to connect to 'template0'.</text>
+    <text class="text_small" x="30" y="20">By default, clients connect via port '5432' to Cluster 'data',</text>
+    <text class="text_small" x="30" y="35">database 'postgres', schema 'public'. Of course, they can</text>
+    <text class="text_small" x="30" y="50">specify other connection properties.</text>
+
+    <text class="text_small" x="10" y="70">2)</text>
+    <text class="text_small" x="30" y="70">System schemas: pg_catalog, information_schema,</text>
+    <text class="text_small" x="30" y="85">pg_temp, ...</text>
+
+    <text class="text_small" x="10" y="105">3)</text>
+    <text class="text_small" x="30" y="105">Global SQL objects: Objects which are shared among all</text>
+    <text class="text_small" x="30" y="120">databases within a Cluster.</text>
+
+    <text class="text_small" x="10" y="140">4)</text>
+    <text class="text_small" x="30" y="140">The command 'initdb' creates a new cluster with the three</text>
+    <text class="text_small" x="30" y="155">databases 'template0', 'template1', and 'postgres'. The command</text>
+    <text class="text_small" x="30" y="170">'createdb' creates a new database.</text>
+
+    <text class="text_small" x="10" y="190">5)</text>
+    <text class="text_small" x="30" y="190">If multiple clusters are active on one server at the same time,</text>
+    <text class="text_small" x="30" y="205">each one is managed by an individual instance. Each such instance</text>
+    <text class="text_small" x="30" y="220">uses a different port.</text>
+
+    <text class="text_small" x="10" y="240">6)</text>
+    <text class="text_small" x="30" y="240">Client application are prohibited from connecting to 'template0'.</text>
 
   </g>
 
diff --git a/doc/src/sgml/images/directories-raw.svg b/doc/src/sgml/images/directories-raw.svg
index 757342a554..5cce551b0c 100644
--- a/doc/src/sgml/images/directories-raw.svg
+++ b/doc/src/sgml/images/directories-raw.svg
@@ -14,6 +14,12 @@
                  font-family:"Open Sans", sans-serif;
                  fill:black;
                 }
+  .text_italic  {font-style:italic;
+                 font-weight:normal;
+                 font-size:14px;
+                 font-family:"Open Sans", sans-serif;
+                 fill:silver;
+                }
   .text_big     {font-style:normal;
                  font-weight:normal;
                  font-size:24px;
@@ -54,14 +60,14 @@
   <!-- the directories -->
   <g transform="translate(20, 100)">
     <use xlink:href="#directory" />
-    <text x="10"  y="26" class="text_normal">... /pg/</text>
+    <text x="10"  y="26" class="text_italic">/var/lib/pgsql/</text>
     <text x="300" y="26" class="text_normal">An arbitrary directory</text>
   </g>
 
   <g transform="translate(70, 130)">
     <use xlink:href="#directory" />
-    <text x="10"  y="26" class="text_normal">data/</text>
-    <text x="250" y="26" class="text_normal">Root of cluster 'data' (see: PGDATA)</text>
+    <text x="10"  y="26" class="text_italic">data/</text>
+    <text x="250" y="26" class="text_normal">Cluster's root directory (with an arbitrary name; see: PGDATA)</text>
   </g>
 
   <g transform="translate(120, 160)">
@@ -74,46 +80,46 @@
   <g transform="translate(170, 190)">
     <use xlink:href="#directory" />
     <text x="10"  y="26" class="text_normal">1/</text>
-    <text x="150" y="26" class="text_normal">Subdirectory for data of first database 'template0'</text>
+    <text x="150" y="26" class="text_normal">Subdirectory for data in default-tablespace of first database 'template0'</text>
   </g>
   <g transform="translate(170, 220)">
     <use xlink:href="#directory" />
     <text x="10"  y="26" class="text_normal">12992/</text>
-    <text x="150" y="26" class="text_normal">Subdirectory for data of second database 'template1'</text>
+    <text x="150" y="26" class="text_normal">Subdirectory for data in default-tablespace of second database 'template1'</text>
   </g>
   <g transform="translate(170, 250)">
     <use xlink:href="#directory" />
     <text x="10"  y="26" class="text_normal">12999/</text>
-    <text x="150" y="26" class="text_normal">Subdirectory for data of third database 'postgres'</text>
+    <text x="150" y="26" class="text_normal">Subdirectory for data in default-tablespace of third database 'postgres'</text>
   </g>
   <g transform="translate(170, 280)">
     <use xlink:href="#directory" />
     <text x="10"  y="26" class="text_normal">nnnnn/</text>
-    <text x="150" y="26" class="text_normal">Optional: more subdirectories for databases, e.g. 'my_db'</text>
+    <text x="150" y="26" class="text_normal">Optional: one subdirectory for each new database, e.g. '23456' for 'my_db'</text>
   </g>
 
   <g transform="translate(120, 310)">
     <use xlink:href="#directory" />
     <text x="10"  y="26" class="text_normal">global/</text>
-    <text x="200" y="26" class="text_normal">Subdirectory with information about Global SQL Objects</text>
+    <text x="200" y="26" class="text_normal">Subdirectory for information about Global SQL Objects</text>
   </g>
 
   <g transform="translate(120, 340)">
     <use xlink:href="#directory" />
-    <text x="10"  y="26" class="text_normal">pg_wal/</text>
-    <text x="200" y="26" class="text_normal">Subdirectory for Write Ahead Log files ('pg_xlog' before version 10)</text>
+    <text x="10"  y="26" class="text_normal">pg_tblspc/</text>
+    <text x="200" y="26" class="text_normal">Subdirectory for symbolic links to non-default tablespaces</text>
   </g>
 
   <g transform="translate(120, 370)">
     <use xlink:href="#directory" />
-    <text x="10"  y="26" class="text_normal">pg_xact/</text>
-    <text x="200" y="26" class="text_normal">Subdirectory for transaction commit status ('pg_clog' before version 10)</text>
+    <text x="10"  y="26" class="text_normal">pg_wal/</text>
+    <text x="200" y="26" class="text_normal">Subdirectory for Write Ahead Log files ('pg_xlog' before version 10)</text>
   </g>
 
   <g transform="translate(120, 400)">
     <use xlink:href="#directory" />
-    <text x="10"  y="26" class="text_normal">pg_tblspc/</text>
-    <text x="200" y="26" class="text_normal">Subdirectory containing symbolic links to tablespaces</text>
+    <text x="10"  y="26" class="text_normal">pg_xact/</text>
+    <text x="200" y="26" class="text_normal">Subdirectory for transaction commit status ('pg_clog' before version 10)</text>
   </g>
 
   <g transform="translate(120, 430)">
@@ -131,14 +137,14 @@
   <!-- next cluster -->
   <g transform="translate(20, 540)">
     <use xlink:href="#directory" />
-    <text x="10"  y="26" class="text_normal">... /xyz/</text>
+    <text x="10"  y="26" class="text_italic">...</text>
     <text x="300" y="26" class="text_normal">Same or another arbitrary directory</text>
   </g>
 
   <g transform="translate(70, 570)">
     <use xlink:href="#directory" />
-    <text x="10"  y="26" class="text_normal">cluster_2/</text>
-    <text x="250" y="26" class="text_normal">Root of another cluster 'cluster_2'</text>
+    <text x="10"  y="26" class="text_italic">cluster_2/</text>
+    <text x="250" y="26" class="text_normal">Root of another cluster</text>
   </g>
 
 </svg>
diff --git a/doc/src/sgml/images/internal-objects-hierarchy-raw.svg b/doc/src/sgml/images/internal-objects-hierarchy-raw.svg
index a58f334fe3..78850283d9 100644
--- a/doc/src/sgml/images/internal-objects-hierarchy-raw.svg
+++ b/doc/src/sgml/images/internal-objects-hierarchy-raw.svg
@@ -26,7 +26,7 @@
   <!-- start of rendering area -->
   <!-- enclosing rectangle -->
   <rect x="1" y="1" rx="5" width="99%" height="99%" stroke="black" fill="none" />
-  <text class="text_big" x="200" y="40">Hierarchy of internal Objects</text>
+  <text class="text_big" x="200" y="40">Hierarchy of Internal Objects</text>

   <!-- set centre of figure and default values -->

---

From: Erik Rijkers <[email-masked]>
Date: Fri, 20 Nov 2020 22:52:32 +0100

On 2020-11-15 19:45, Jürgen Purtz wrote:

(smallish) Changes to arch-dev.sgml

Erik
--- ./doc/src/sgml/arch-dev.sgml.orig	2020-11-20 19:14:21.576775798 +0100
+++ ./doc/src/sgml/arch-dev.sgml	2020-11-20 21:43:10.435370787 +0100
@@ -7,7 +7,7 @@
    <title>Author</title>
    <para>
     This chapter originated as part of
-    <xref linkend="sim98"/>, Stefan Simkovics'
+    <xref linkend="sim98"/> Stefan Simkovics'
     Master's Thesis prepared at Vienna University of Technology under the direction
     of O.Univ.Prof.Dr. Georg Gottlob and Univ.Ass. Mag. Katrin Seyr.
    </para>
@@ -17,10 +17,7 @@
    This chapter gives an overview of the internal structure of the
    backend of <productname>PostgreSQL</productname>.  After having
    read the following sections you should have an idea of how a query
-   is processed. This chapter does not aim to provide a detailed
-   description of the internal operation of
-   <productname>PostgreSQL</productname>, as such a document would be
-   very extensive. Rather, this chapter is intended to help the reader
+   is processed.  This chapter is intended to help the reader
    understand the general sequence of operations that occur within the
    backend from the point at which a query is received, to the point
    at which the results are returned to the client.
@@ -30,8 +27,8 @@
    <title>The Path of a Query</title>
 
    <para>
-    Here we give a short overview of the stages a query has to pass in
-    order to obtain a result.
+    Here we give a short overview of the stages a query has to pass 
+    to obtain a result.
    </para>
 
    <procedure>
@@ -125,7 +122,7 @@
     use a <firstterm>supervisor process</firstterm> (also
     <firstterm>master process</firstterm>) that spawns a new
     server process every time a connection is requested. This supervisor
-    process is called <literal>postgres</literal> and listens at a
+    process is called <literal>postgres</literal> (formerly 'postmaster') and listens at a
     specified TCP/IP port for incoming connections. Whenever a request
     for a connection is detected the <literal>postgres</literal>
     process spawns a new server process. The server tasks
@@ -230,7 +227,7 @@
     <para>
      A detailed description of <application>bison</application> or
      the grammar rules given in <filename>gram.y</filename> would be
-     beyond the scope of this paper. There are many books and
+     beyond the scope of this manual. There are many books and
      documents dealing with <application>flex</application> and
      <application>bison</application>. You should be familiar with
      <application>bison</application> before you start to study the
@@ -343,8 +340,8 @@
    <note>
     <para>
      In some situations, examining each possible way in which a query
-     can be executed would take an excessive amount of time and memory
-     space. In particular, this occurs when executing queries
+     can be executed would take an excessive amount of time and memory.
+     In particular, this occurs when executing queries
      involving large numbers of join operations. In order to determine
      a reasonable (not necessarily optimal) query plan in a reasonable amount
      of time, <productname>PostgreSQL</productname> uses a <firstterm>Genetic
@@ -411,7 +408,7 @@
         <firstterm>merge join</firstterm>: Each relation is sorted on the join
         attributes before the join starts. Then the two relations are
         scanned in parallel, and matching rows are combined to form
-        join rows. This kind of join is more
+        join rows. This kind of join is
         attractive because each relation has to be scanned only once.
         The required sorting might be achieved either by an explicit sort
         step, or by scanning the relation in the proper order using an
@@ -442,7 +439,7 @@
      If the query uses fewer than <xref linkend="guc-geqo-threshold"/>
      relations, a near-exhaustive search is conducted to find the best
      join sequence.  The planner preferentially considers joins between any
-     two relations for which there exist a corresponding join clause in the
+     two relations for which there exists a corresponding join clause in the
      <literal>WHERE</literal> qualification (i.e., for
      which a restriction like <literal>where rel1.attr1=rel2.attr2</literal>
      exists). Join pairs with no join clause are considered only when there

---

From: Heikki Linnakangas <[email-masked]>
Date: Mon, 18 Jan 2021 16:13:22 +0200

I believe we still call it the postmaster process. We renamed the binary 
a long time ago (commit 5266f221a2), and the above text was changed as 
part of that commit. I think that was a mistake, and this should say simply:

... This supervisor process is called <literal>postmaster</literal> and ...

like it did before we renamed the binary.

Barring objections, I'll commit this with that change (as attached).

- Heikki
index ade0ad97d8..a27c8477c2 100644
 
    <para>
 
    <procedure>
@@ -125,9 +122,9 @@
+    process is called <literal>postmaster</literal> and listens at a
-    for a connection is detected the <literal>postgres</literal>
+    for a connection is detected the <literal>postmaster</literal>
     communicate with each other using <firstterm>semaphores</firstterm> and
     <firstterm>shared memory</firstterm> to ensure data integrity

---

From: Jürgen Purtz <[email-masked]>
Date: Tue, 19 Jan 2021 07:37:25 +0100

On 18.01.21 15:13, Heikki Linnakangas wrote:
> I believe we still call it the postmaster process. We renamed the 
> binary a long time ago (commit 5266f221a2), and the above text was 
> changed as part of that commit. I think that was a mistake, and this 
> should say simply:
>

I fear that the patch 'Additional chapter for Tutorial' grows beyond 
manageable limits. It runs since nearly one year, the size of 228 KB is 
very huge, many people havemade significant contributions. But a commit 
seems to be in far distance. Having said that, I'm pleased with Heikki's 
proposal to split changes in the existing file 'arch-dev.sgml' from the 
rest of the patch and commit them separately.

But I have some concerns with the chapter '51.2. How Connections Are 
Established'. It uses central terms like 'client process', 'server 
process','supervisor process', 'master process', 'server tasks', 
'backend (server)', 'frontend (client)', 'server', 'client'. Some month 
ago, we have cleared his terminology in the new chapter 'glossary'. As 
long as it leads to readable text, we shall use the glossary-terms 
instead of the current ones. And we shall include some links to the 
glossary.

I propose to start a new thread which contains only changes to 
'arch-dev.sgml'. In pgsql-hackers or in pgsql-docs list? Initialized by 
Heikki or by me?

--

Jürgen Purtz

---

From: Jürgen Purtz <[email-masked]>
Date: Thu, 21 Jan 2021 13:38:26 +0100

> Barring objections, I'll commit this with that change (as attached).

Some additional changes in 51.2:

  - smaller number of different terms

  - aligning with Glossary

  - active voice instead of passive voice

  - commas

---

J. Purtz

index ade0ad97d8..7ced927c9d 100644
 
    <para>
 
    <procedure>
@@ -117,21 +114,28 @@
    <title>How Connections Are Established</title>
 
    <para>
-    <productname>PostgreSQL</productname> is implemented using a
-    simple <quote>process per user</quote> client/server model.  In this model
-    there is one <firstterm>client process</firstterm> connected to
-    exactly one <firstterm>server process</firstterm>.  As we do not
+    <productname>PostgreSQL</productname> implements a
+    <quote>process per user</quote> client/server model.
+    In this model, every
+    <glossterm linkend="glossary-client">client process</glossterm>
+    connects to exactly one
+    <glossterm linkend="glossary-backend">backend process</glossterm>.
+    As we do not
     know ahead of time how many connections will be made, we have to
-    use a <firstterm>supervisor process</firstterm> (also
-    <firstterm>master process</firstterm>) that spawns a new
-    server process every time a connection is requested. This supervisor
-    process is called <literal>postgres</literal> and listens at a
-    specified TCP/IP port for incoming connections. Whenever a request
-    for a connection is detected the <literal>postgres</literal>
-    process spawns a new server process. The server tasks
-    communicate with each other using <firstterm>semaphores</firstterm> and
-    <firstterm>shared memory</firstterm> to ensure data integrity
-    throughout concurrent data access.
+    use a <quote>supervisor process</quote>
+    that spawns a new
+    backend process every time a connection is requested. This supervisor
+    process is called
+    <glossterm linkend="glossary-postmaster">postmaster</glossterm> 
+    and listens at a
+    specified TCP/IP port for incoming connections. Whenever he detects
+    a request for a connection, he spawns a new backend process.
+    Those backend processes communicate with each other and with other
+    processes of the
+    <glossterm linkend="glossary-instance">instance</glossterm>
+    using <firstterm>semaphores</firstterm> and
+    <glossterm linkend="glossary-shared-memory">shared memory</glossterm>
+    to ensure data integrity throughout concurrent data access.
    </para>
 
    <para>
@@ -144,11 +148,11 @@
    </para>
 
    <para>
-    Once a connection is established the client process can send a query
-    to the <firstterm>backend</firstterm> (server). The query is transmitted using plain text,
-    i.e., there is no parsing done in the <firstterm>frontend</firstterm> (client). The
-    server parses the query, creates an <firstterm>execution plan</firstterm>,
-    executes the plan and returns the retrieved rows to the client
+    Once a connection is established, the client process can send a query
+    to his backend process. The query is transmitted using plain text,
+    i.e., there is no parsing done in the client. The backend 
+    process parses the query, creates an <firstterm>execution plan</firstterm>,
+    executes the plan, and returns the retrieved rows to the client
     by transmitting them over the established connection.
    </para>
   </sect1>
@@ -230,7 +234,7 @@
     <para>
      A detailed description of <application>bison</application> or
      the grammar rules given in <filename>gram.y</filename> would be
-     beyond the scope of this paper. There are many books and
+     beyond the scope of this manual. There are many books and
      documents dealing with <application>flex</application> and
      <application>bison</application>. You should be familiar with
      <application>bison</application> before you start to study the
@@ -343,8 +347,8 @@
    <note>
     <para>
      In some situations, examining each possible way in which a query
-     can be executed would take an excessive amount of time and memory
-     space. In particular, this occurs when executing queries
+     can be executed would take an excessive amount of time and memory.
+     In particular, this occurs when executing queries
      involving large numbers of join operations. In order to determine
      a reasonable (not necessarily optimal) query plan in a reasonable amount
      of time, <productname>PostgreSQL</productname> uses a <firstterm>Genetic
@@ -411,7 +415,7 @@
         <firstterm>merge join</firstterm>: Each relation is sorted on the join
         attributes before the join starts. Then the two relations are
         scanned in parallel, and matching rows are combined to form
-        join rows. This kind of join is more
+        join rows. This kind of join is
         attractive because each relation has to be scanned only once.
         The required sorting might be achieved either by an explicit sort
         step, or by scanning the relation in the proper order using an
@@ -442,7 +446,7 @@
      If the query uses fewer than <xref linkend="guc-geqo-threshold"/>
      relations, a near-exhaustive search is conducted to find the best
      join sequence.  The planner preferentially considers joins between any
-     two relations for which there exist a corresponding join clause in the
+     two relations for which there exists a corresponding join clause in the
      <literal>WHERE</literal> qualification (i.e., for
      which a restriction like <literal>where rel1.attr1=rel2.attr2</literal>
      exists). Join pairs with no join clause are considered only when there

---

From: Heikki Linnakangas <[email-masked]>
Date: Fri, 22 Jan 2021 11:15:40 +0200

On 21/01/2021 14:38, Jürgen Purtz wrote:
> This supervisor process is called <glossterm
> linkend="glossary-postmaster">postmaster</glossterm> and listens at
> a specified TCP/IP port for incoming connections. Whenever he
> detects a request for a connection, he spawns a new backend process.

It sounds weird to refer to a process with "he". I left out this hunk, 
and the other with similar changes.

Committed the rest, thanks!.

- Heikki

---

From: David Steele <[email-masked]>
Date: Thu, 25 Mar 2021 09:00:11 -0400

> Committed the rest, thanks!.

So it looks like this was committed. Is there anything left to do?

If not, we should close the CF entry.

Regards,
-- 
-David
[email-masked]

---

From: Alvaro Herrera <[email-masked]>
Date: Sat, 3 Apr 2021 10:39:55 -0300

> So it looks like this was committed. Is there anything left to do?

Yes, there is.  AFAICS Heikki committed a small wordsmithing patch --
not the large patch with the additional chapter.

-- 
Álvaro Herrera                            39°49'30"S 73°17'W
"Ed is the standard text editor."
      http://groups.google.com/group/alt.religion.emacs/msg/8d94ddab6a9b0ad3

---

From: Jürgen Purtz <[email-masked]>
Date: Sat, 3 Apr 2021 19:43:48 +0200

> not the large patch with the additional chapter.

What can i do to move the matter forward?

--

J. Purtz

---

From: Alvaro Herrera <[email-masked]>
Date: Sat, 3 Apr 2021 16:01:10 -0300

> What can i do to move the matter forward?

Please post a version that applies to the current sources.  If the
latest version posted does, please state so.

---

From: Jürgen Purtz <[email-masked]>
Date: Sun, 4 Apr 2021 11:07:55 +0200

> latest version posted does, please state so.
The small patch 'arch-dev.sgml.20210121.diff' contains only some 
clearing up concerning the used terminology and its alignments with the 
glossary. The patch was rejected by Heikki.

The latest version of the huge patch '0013-architecture.patch' is valid 
and doesn't contain merge conflicts.

--
Jürgen Purtz

---

From: Alvaro Herrera <[email-masked]>
Date: Sun, 4 Apr 2021 13:02:48 -0400

On 2021-Apr-04, Jürgen Purtz wrote:

> The small patch 'arch-dev.sgml.20210121.diff' contains only some clearing up
> concerning the used terminology and its alignments with the glossary. The
> patch was rejected by Heikki.

This comment is not helpful, because it's not obvious where would I find
that patch.  Also, you say "the patch was rejected by Heikki" but
upthread he said he committed it.  His comment was that he left out some
paragraphs because of a style issue.  Did you re-post that patch after
fixing the style issues?  If you did, I couldn't find it.

> The latest version of the huge patch '0013-architecture.patch' is valid and
> doesn't contain merge conflicts.

Yeah, OK, but I have to dive deep in the thread to find it.  Please post
it again.  When you have a patch series, please post it as a whole every
time -- that makes it easier for a committer to review it.

You seem to be making your life hard by not using git to assist you.  Do
you know you can have several commits in a branch of your own, rebase it
to latest master, merge master to it, rebase on top of master, commit
fixups, "rebase -i" and change commit ordering to remove unnecessary
fixup commits, and so on?  Such techniques are extremely helpful when
dealing with a patch series.  When you want to post a new version to the
list, you can just do "git format-patch -v14 origin/master" to produce a
set of patch files.  You don't need to manually give names to your patch
files, or come up with a versioning scheme.  Just increment the argument
to -v by +1 each time you (or somebody else) posts a new version of the
patch series.

-- 
Álvaro Herrera       Valdivia, Chile

---

From: Jürgen Purtz <[email-masked]>
Date: Mon, 5 Apr 2021 15:18:44 +0200

> to -v by +1 each time you (or somebody else) posts a new version of the
The thread contains a sequence of files '0001_architecture.patch' to 
'0013_architecture.patch' (with gaps in the numbering) created by me and 
other authors over the last 12 month. This is what I call the 'huge 
patch'. Indeed, the files are created more or less manually without the 
format-patch option. I welcome the reference to rebase and format-patch 
and I'm considering to use it in the future.

In addition to this chain Erik introduced in November within the same 
thread some changes to the chapter "Overview of Query Handling", which 
subsequently was expanded by Heikki and me with the sequence of 
'arch-dev.sgml.xxxxx.diff' files. This is what I call the 'small patch'. 
It's independent from the 'huge patch'. That 'small patch' is partly 
committed by Heikki. In case that a committer gives the uncommitted part 
a second chance, I append a patch. Because I'm not a native English 
speaker, every improvement in the linguistic is highly welcome.

--

Jürgen Purtz

 
 
  <chapter id="overview">
 
   <note>
    <title>Author</title>

+  &architecture;
   &arch-dev;
   &catalogs;
   &protocol;

    <para>
 
-    <itemizedlist>
-     <listitem>
-      <para>
 
-     <listitem>
-      <para>
 
-    </itemizedlist>
-   </para>
+    <listitem>
+     <para>
 
    <para>
 
-   <para>

---

From: Alvaro Herrera <[email-masked]>
Date: Mon, 5 Apr 2021 11:48:14 -0400

On 2021-Apr-05, Jürgen Purtz wrote:

> In addition to this chain Erik introduced in November within the same thread
> some changes to the chapter "Overview of Query Handling", which subsequently
> was expanded by Heikki and me with the sequence of
> committed by Heikki. In case that a committer gives the uncommitted part a
> second chance, I append a patch. Because I'm not a native English speaker,
> every improvement in the linguistic is highly welcome.

Pushed this one with cosmetic adjustments.

-- 
Álvaro Herrera       Valdivia, Chile
"Cuando mañana llegue pelearemos segun lo que mañana exija" (Mowgli)

---

From: Erik Rijkers <[email-masked]>
Date: Thu, 20 May 2021 23:02:30 +0200

Hi Jürgen,

What's going to happen with this work?

If you intend to have it eventually committed, I think it will be 
necessary to make the patches smaller, and bring them into the 
commitfest app, so that others can follow progress.

I for one, cannot see/remember/understand what has been done, or even 
whether you intend to continue with it.

Thanks,

Erik

---

From: Jürgen Purtz <[email-masked]>
Date: Fri, 21 May 2021 08:47:15 +0200

> whether you intend to continue with it.
Peter changed the status to 'Returned with feedback' at the end of the 
last commit fest. I'm not absolutely sure, but my understanding is that 
the patch is rejected.

--

Jürgen Purtz

---

From: Laurenz Albe <[email-masked]>
Date: Fri, 21 May 2021 10:52:42 +0200

> last commit fest. I'm not absolutely sure, but my understanding is that 

There is a different status for that.

"Returned with feedback" means: there was review, and further work by
the author is needed, or we need more discussion if we want that or not
or how it should be, but there hasn't been a lot of feedback from the author
lately, so it seems that just moving it on to the next commitfest is not
the right thing to do.

You are welcome to re-submit the patch if you address the feedback.

Yours,
Laurenz Albe