]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Add documentation file ./README-server-edition.html.
authordan <dan@noemail.net>
Mon, 31 Jul 2017 19:55:56 +0000 (19:55 +0000)
committerdan <dan@noemail.net>
Mon, 31 Jul 2017 19:55:56 +0000 (19:55 +0000)
FossilOrigin-Name: fbc4f4ad259cfe04b28d698ef025f179b6708ac788939976c401db2caf8f92c1

README-server-edition.html [new file with mode: 0644]
manifest
manifest.uuid

diff --git a/README-server-edition.html b/README-server-edition.html
new file mode 100644 (file)
index 0000000..65a5e91
--- /dev/null
@@ -0,0 +1,231 @@
+<html>
+
+<center>
+  <h1> The "server-process-edition" Branch</h1>
+</center>
+
+<p>
+The "server-process-edition" branch contains two modifications to stock SQLite
+that work together to provide concurrent read/write transactions using
+page-level-locking provided that:
+
+<ul>
+  <li><p> All clients are in the same process, and
+  <li><p> The application uses "PRAGMA synchronous=off".
+</ul>
+
+<p>
+Up to 16 simultaneous read/write transactions controlled by page-level-locking
+are possible. Additionally, there may be any number of read-only transactions
+started using "BEGIN READONLY" commands. Read-only transactions do not block
+read-write transactions, and read-write transactions do not block read-only
+transactions.
+
+<p>
+The two features on this branch are:
+<ol>
+  <li><p> An alternative layout for the database free-page list. This is intended
+       to reduce contention between writers when allocating new database pages,
+       either from the free-list or by extending the database file.
+
+  <li><p> The "server-mode" extension, which provides the read/write
+       page-level-locking and read-only MVCC concurrency mentioned above.
+</ol>
+
+
+<h2> Alternative Free-List Format </h2>
+
+<p>
+The alternative free-list format is very similar to the current format. It
+differs in the following respects:
+
+<ul>
+  <li><p>The "total number of free pages" field in the db header is not
+       maintained. It is always set to zero.
+  <li><p> Instead of pointing to the first free-list trunk page, the free-list
+       pointer in the db header points to a page known as the "free-list node".
+  <li><p> The free-list node page contains N pointers to free-lists stored in the
+       legacy format (i.e. a linked list of trunk pages each containing
+       pointers to many free leaf pages).
+</ul>
+
+<p>
+This effectively means that a database has N free-lists instead of just one. To
+allocate a free page, a writer only needs to lock one such free-list, and so up
+to N transactions that allocate new pages may proceed concurrently.
+
+<p>
+Allocating pages from the end of the db file still locks out all other
+read/write transactions (because it involves writing to page 1, which every
+transaction needs to read). To minimize the frequency with which this occurs,
+when a page must be allocated from the end of the database file, the file is
+extended by 2048 pages. These are distributed equally between 16 free-lists
+(children of the free-list node page). Additionally, the first trunk page in
+each free list is never reused.  Doing so would require writing to the
+free-list node page - effectively an exclusive lock on the entire
+page-allocation system.
+
+<p>
+The current format used for the free-list can be modified or queried using a
+new pragma:
+
+<pre>
+  PRAGMA [database.]freelist_format;
+  PRAGMA [database.]freelist_format = 1|2;
+</pre>
+
+<p>
+At present, the free-list format may only be modified when the free-list is
+completely empty. Which, as the implementation ensures that a free-list that
+uses the alternative format is never completely emptied, effectively precludes
+changing the format from 2 (alternative) to 1 (legacy).
+
+<h2> Page level locking - "Server Mode" </h2>
+
+<p>
+A database client automatically enters "server mode" if (a) it is using a VFS
+that takes a process-wide exclusive lock on the db file (like "unix-excl"
+does), and (b) there exists a directory named "&lt;database&gt;-journal" in the
+file system alongside the database file "&lt;database&gt;" There is currently no
+provision for creating this directory, although it could be safely done for
+a database in rollback mode using something like:
+
+<pre>
+  PRAGMA journal_mode = off;
+  BEGIN EXCLUSIVE;
+    &lt;create directory&gt;
+  END;
+</pre>
+
+<p>
+To check the status of these two conditions, a new file-control is added -
+SQLITE_FCNTL_SERVER_MODE. SQLite invokes this file-control as part of the
+procedure for detecting a hot journal (after it has established that there is a
+file-system entry named &lt;database&gt;-journal and that no other process
+holds a RESERVED lock). If the VFS does support an exclusive process-wide lock
+and if the directory is present, the VFS indicates that the client should enter
+server mode. If the VFS does not indicate this, or if it returns
+SQLITE_NOTFOUND, then SQLite proceeds with the hot-journal rollback.
+
+<p>
+There is also a new file-control named SQLITE_FCNTL_FILEID, which requests a
+128-bit value that uniquely identifies an open file on disk from the VFS. This
+is used to ensure that all connections to the same database from within a
+process use the same shared state, even if they connect to the db using
+different file-system paths.
+
+<p>
+The heap-memory data structure shared between all connections to the same
+database is protected by a mutex. Clients take and release the mutex each
+time a transaction is opened or closed, and each time a read or write lock
+is taken on a specific database page. Ordinary read/write transactions lock
+each page that they access - each page can support any number of concurrent
+read locks or a single write lock. 
+
+<p>
+Write transactions use a journal file stored in the &lt;database&gt;-journal 
+directory. Journal files are named "&lt;id&gt;-journal", where &lt;id&gt; is an
+integer value betwen 0 and 15, inclusive. A client may use multiple different
+journal files throughout its lifetime.
+
+<p>Before database pages are overwritten in server-mode, entries are added to
+an in-memory hash table containing the old page content. These entries are
+used by read-only transactions to ensure that they access a consistent snapshot
+of the database. Hash table entries are automatically removed when they are
+no longer required.
+
+<p>
+It is not difficult to extend the kind of page level locking used by read/write
+transactions to clients in multiple processes. It might be more difficult to
+extend the read-only MVCC capability though.
+
+<h2> Performance Test </h2>
+
+<p>
+The test uses a single table with the following schema:
+
+<pre>
+  CREATE TABLE t1(a INTEGER PRIMARY KEY, b BLOB(16), c BLOB(16), d BLOB(400));
+  CREATE INDEX i1 ON t1(b);
+  CREATE INDEX i2 ON t1(c);
+</pre>
+
+<p>
+The database initially contains 5,000,000 rows. Values for column "a" are
+between 1 and 5,000,000, inclusive. Other columns are populated with randomly
+generated blob values, each 16, 16, and 400 bytes in size, respectively.
+
+<p>
+Read/write transactions used by the test take the following form. Each such
+transaction modifies approximately 25 pages (5 in the main table and 10 in each
+index), not accounting for tree rebalancing operations.
+
+<pre>
+  BEGIN;
+    REPLACE INTO t1 VALUES(abs(random() % 5000000), randomblob(16), randomblob(16), randomblob(400));
+    REPLACE INTO t1 VALUES(abs(random() % 5000000), randomblob(16), randomblob(16), randomblob(400));
+    REPLACE INTO t1 VALUES(abs(random() % 5000000), randomblob(16), randomblob(16), randomblob(400));
+    REPLACE INTO t1 VALUES(abs(random() % 5000000), randomblob(16), randomblob(16), randomblob(400));
+    REPLACE INTO t1 VALUES(abs(random() % 5000000), randomblob(16), randomblob(16), randomblob(400));
+  COMMIT;
+</pre>
+
+<p>
+Read-only transactions are as follows:
+
+<pre>
+  BEGIN READONLY;
+    SELECT * FROM t1 WHERE a&gt;abs((random()%5000000)) LIMIT 10;
+    SELECT * FROM t1 WHERE a&gt;abs((random()%5000000)) LIMIT 10;
+    SELECT * FROM t1 WHERE a&gt;abs((random()%5000000)) LIMIT 10;
+    SELECT * FROM t1 WHERE a&gt;abs((random()%5000000)) LIMIT 10;
+    SELECT * FROM t1 WHERE a&gt;abs((random()%5000000)) LIMIT 10;
+  END;
+</pre>
+
+<p>
+The performance test features one or more clients executing read/write
+transactions as fast as possible, and zero or more clients executing read-only
+transactions, also as fast as possible. All tests use the "unix-excl" VFS and
+all clients execute in a separate thread within the same process. The database
+is located on a tmpfs file-system.
+
+<p>
+In the table below "rw:" refers to the number of read-write clients, and "ro:"
+the number of read-only clients used by the test. The TPS values in brackets
+are the number of read-only transactions per second. All other values are 
+read-write transactions per second.
+
+<p>
+The collision rate (percentage of attempted transactions that failed due to a
+page-level locking conflict) in all tests was between 1 and 2%. Failed
+transactions are not included in the TPS counts below.
+
+<p>
+<table border=1 width=90% align=center>
+<!--
+  320 jm=persist, rw:1          139675, 135797
+  320 jm=wal, rw:1              120995, 118889
+  begin-concurrent, rw:1        119438, 117580
+  begin-concurrent, rw:2        166923, 166904
+  begin-concurrent, rw:3        180432, 172825
+  begin-concurrent, rw:2,ro:1   150427(347319),152087(351601) 
+  server-mode, rw:1             126592, 126742
+  server-mode, rw:2             228317, 227155
+  server-mode, rw:3             309712, 306218
+  server-mode, rw:2,ro:1        213303(576032),210994(556005) 
+-->
+
+  <tr><th> Configuration <th>TPS per client <th> TPS total
+  <tr><td> 3.20.0, journal_mode=persist, rw:1, ro:0 <td>6886 <td> 6886
+  <tr><td> 3.20.0, journal_mode=wal, rw:1, ro:0 <td>5997 <td> 5997
+  <tr><td> begin-concurrent, rw:1, ro:0<td>5925<td> 5925
+  <tr><td> begin-concurrent, rw:2, ro:0<td>4172 <td> 8345
+  <tr><td> begin-concurrent, rw:3, ro:0<td>2943 <td> 8831
+  <tr><td> begin-concurrent, rw:2, ro:1<td>3781 <td> 7562 (17473)
+  <tr><td> server-mode, rw:1, ro:0 <td>6333 <td> 6333
+  <tr><td> server-mode, rw:2, ro:0<td> 5693 <td> 11386
+  <tr><td> server-mode, rw:3, ro:0<td>5132 <td> 15398
+  <tr><td> server-mode, rw:2, ro:1<td>5303 <td> 10607 (28300)
+</table>
+
index e2abab2c1967ca32d89a1305b9c6377307e2047b..aa980ac04d8c86e1aa027a0b110daa4ba7d62205 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,8 +1,9 @@
-C Merge\slatest\strunk\schanges\swith\sthis\sbranch.
-D 2017-07-29T17:10:37.200
+C Add\sdocumentation\sfile\s./README-server-edition.html.
+D 2017-07-31T19:55:56.996
 F Makefile.in d9873c9925917cca9990ee24be17eb9613a668012c85a343aef7e5536ae266e8
 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434
 F Makefile.msc 02b469e9dcd5b7ee63fc1fb05babc174260ee4cfa4e0ef2e48c3c6801567a016
+F README-server-edition.html 0c6bc6f55191b6900595fe37470bbe5772953ab5c64dae967d07a5d58a0c3508
 F README.md f5c87359573c4d255425e588a56554b50fdcc2afba4e017a2e02a43701456afd
 F VERSION f81232df28e2d3ff049feefad5fbd5489cc33697f6bd2ecf61af7f0dde3b83d0
 F aclocal.m4 a5c22d164aff7ed549d53a90fa56d56955281f50
@@ -1646,7 +1647,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93
 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
 F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
 F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
-P 8299bdb7cbede30c665dda131bdcbd1d260b3ae9bd16d9b414d8c3776b08f1b3 bcec155e0d6c6b17ae09d5a366c080723d01ff40dbc1a0ad0bb669a91db1b850
-R 77ed1cc2fd3110f4b8329af1b4d34a6f
+P b42c87790e2dfdc4e52c42967257decf4b44ded909403ea4ac47fe41acfd7077
+R 0649fc2cf3ba1c03f8e547dfbc16afc9
 U dan
-Z 4686c3424ce70d61f90ed6c1d0cd236d
+Z c48da8fd6893915c8bae54b12ad68f68
index 7741847729b190441dd35442a0f2c3dd77dfe44a..16ed4d7fdda69402badf46b17282fd7d392f947c 100644 (file)
@@ -1 +1 @@
-b42c87790e2dfdc4e52c42967257decf4b44ded909403ea4ac47fe41acfd7077
\ No newline at end of file
+fbc4f4ad259cfe04b28d698ef025f179b6708ac788939976c401db2caf8f92c1
\ No newline at end of file