1
0
mirror of https://github.com/sqlite/sqlite.git synced 2025-07-27 20:41:58 +03:00

Improve comments and documentation of the asynchronous IO VFS module. (CVS 6543)

FossilOrigin-Name: 92bc6be2a86f8a68ceded2bc08fe7d6ff23b56fb
This commit is contained in:
danielk1977
2009-04-24 09:27:16 +00:00
parent 68d405e25a
commit debcfd2dcb
5 changed files with 356 additions and 117 deletions

View File

@ -10,101 +10,10 @@
**
*************************************************************************
**
** $Id: sqlite3async.c,v 1.1 2009/04/23 14:58:40 danielk1977 Exp $
** $Id: sqlite3async.c,v 1.2 2009/04/24 09:27:16 danielk1977 Exp $
**
** This file contains an example implementation of an asynchronous IO
** backend for SQLite.
**
** WHAT IS ASYNCHRONOUS I/O?
**
** With asynchronous I/O, write requests are handled by a separate thread
** running in the background. This means that the thread that initiates
** a database write does not have to wait for (sometimes slow) disk I/O
** to occur. The write seems to happen very quickly, though in reality
** it is happening at its usual slow pace in the background.
**
** Asynchronous I/O appears to give better responsiveness, but at a price.
** You lose the Durable property. With the default I/O backend of SQLite,
** once a write completes, you know that the information you wrote is
** safely on disk. With the asynchronous I/O, this is not the case. If
** your program crashes or if a power loss occurs after the database
** write but before the asynchronous write thread has completed, then the
** database change might never make it to disk and the next user of the
** database might not see your change.
**
** You lose Durability with asynchronous I/O, but you still retain the
** other parts of ACID: Atomic, Consistent, and Isolated. Many
** appliations get along fine without the Durablity.
**
** HOW IT WORKS
**
** Asynchronous I/O works by creating a special SQLite "vfs" structure
** and registering it with sqlite3_vfs_register(). When files opened via
** this vfs are written to (using sqlite3OsWrite()), the data is not
** written directly to disk, but is placed in the "write-queue" to be
** handled by the background thread.
**
** When files opened with the asynchronous vfs are read from
** (using sqlite3OsRead()), the data is read from the file on
** disk and the write-queue, so that from the point of view of
** the vfs reader the OsWrite() appears to have already completed.
**
** The special vfs is registered (and unregistered) by calls to
** function asyncEnable() (see below).
**
** LIMITATIONS
**
** This demonstration code is deliberately kept simple in order to keep
** the main ideas clear and easy to understand. Real applications that
** want to do asynchronous I/O might want to add additional capabilities.
** For example, in this demonstration if writes are happening at a steady
** stream that exceeds the I/O capability of the background writer thread,
** the queue of pending write operations will grow without bound until we
** run out of memory. Users of this technique may want to keep track of
** the quantity of pending writes and stop accepting new write requests
** when the buffer gets to be too big.
**
** LOCKING + CONCURRENCY
**
** Multiple connections from within a single process that use this
** implementation of asynchronous IO may access a single database
** file concurrently. From the point of view of the user, if all
** connections are from within a single process, there is no difference
** between the concurrency offered by "normal" SQLite and SQLite
** using the asynchronous backend.
**
** If connections from within multiple processes may access the
** database file, the ENABLE_FILE_LOCKING symbol (see below) must be
** defined. If it is not defined, then no locks are established on
** the database file. In this case, if multiple processes access
** the database file, corruption will quickly result.
**
** If ENABLE_FILE_LOCKING is defined (the default), then connections
** from within multiple processes may access a single database file
** without risking corruption. However concurrency is reduced as
** follows:
**
** * When a connection using asynchronous IO begins a database
** transaction, the database is locked immediately. However the
** lock is not released until after all relevant operations
** in the write-queue have been flushed to disk. This means
** (for example) that the database may remain locked for some
** time after a "COMMIT" or "ROLLBACK" is issued.
**
** * If an application using asynchronous IO executes transactions
** in quick succession, other database users may be effectively
** locked out of the database. This is because when a BEGIN
** is executed, a database lock is established immediately. But
** when the corresponding COMMIT or ROLLBACK occurs, the lock
** is not released until the relevant part of the write-queue
** has been flushed through. As a result, if a COMMIT is followed
** by a BEGIN before the write-queue is flushed through, the database
** is never unlocked,preventing other processes from accessing
** the database.
**
** Defining ENABLE_FILE_LOCKING when using an NFS or other remote
** file-system may slow things down, as synchronous round-trips to the
** server may be required to establish database file locks.
** This file contains the implementation of an asynchronous IO backend
** for SQLite.
*/
#if !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_ASYNCIO)
@ -113,12 +22,6 @@
#define ENABLE_FILE_LOCKING
#ifndef SQLITE_AMALGAMATION
# include "sqliteInt.h"
# include <assert.h>
# include <string.h>
#endif
/* Useful macros used in several places */
#define MIN(x,y) ((x)<(y)?(x):(y))
#define MAX(x,y) ((x)>(y)?(x):(y))
@ -255,6 +158,8 @@ static void asyncTrace(const char *zFormat, ...){
#endif
/*
** PORTING FUNCTIONS
**
** There are two definitions of the following functions. One for pthreads
** compatible systems and one for Win32. These functions isolate the OS
** specific code required by each platform.